/* ══════════════════════════════════════════════════════════════════════════
   Loading feedback
   static/site_assets/css/loading.css  ·  driven by js/loading.js

   Nothing used to happen visibly between clicking "Search" and the next page
   painting. On a slow connection - or on a page the server needs a second or
   two to build, like the QR slips - that reads as "the button is broken", so
   people tap it again, and again. Three signals, escalating:

     1. the button itself goes busy immediately (you clicked THIS one)
     2. a thin progress bar at the top of the screen (something is in flight)
     3. after 1.2s a soft veil with a spinner (it is slow, and further taps
        will not help - the veil also swallows them)

   The button must NEVER be set disabled: fourteen submit buttons in this app
   carry name="action" with a value the view reads, and a disabled control is
   left out of the form data entirely. Clicks are blocked with pointer-events
   and a re-entry guard in the JS instead.
   ══════════════════════════════════════════════════════════════════════════ */

:root {
  --idp-load-1: #1b84ff;   /* theme primary */
  --idp-load-2: #f5325c;   /* the brand red the tab bar FAB uses */
  --idp-load-3: #ff3131;
}

@keyframes idp-spin { to { transform: rotate(360deg); } }
@keyframes idp-veil-in { from { opacity: 0; transform: translateY(6px) scale(.97); } }


/* ── 1. the busy button ────────────────────────────────────────────────── */

.idp-busy {
  position: relative;
  pointer-events: none;               /* not `disabled` - see the header note */
  color: transparent !important;      /* keeps the button's exact width */
  text-shadow: none !important;
  cursor: progress;
}

/* text nodes cannot be hidden on their own, hence `color: transparent` above;
   element children (icons, labels) need this as well */
.idp-busy > * { visibility: hidden; }

.idp-busy::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 1.15em;
  height: 1.15em;
  margin: -.575em 0 0 -.575em;
  border: 2px solid var(--idp-spin, #fff);   /* JS copies the button's own
                                                colour here before hiding it,
                                                so this reads on a light
                                                button and a solid one alike */
  border-right-color: transparent;
  border-radius: 50%;
  animation: idp-spin .6s linear infinite;
}


/* ── 2. the top progress bar ───────────────────────────────────────────── */

.idp-progress {
  position: fixed;
  top: 0;
  left: 0;
  width: 0;
  height: 3px;
  z-index: 2147483000;                /* over the drawer (110) and modals (1055) */
  background: linear-gradient(90deg, var(--idp-load-1), var(--idp-load-2) 65%, var(--idp-load-3));
  box-shadow: 0 0 10px rgba(245, 50, 92, .55);
  opacity: 0;
  pointer-events: none;
  transition: width .3s cubic-bezier(.2, .8, .3, 1), opacity .25s ease;
}

.idp-progress.idp-on { opacity: 1; }

/* a soft head on the bar so it reads as motion, not a static rule */
.idp-progress::after {
  content: "";
  position: absolute;
  right: 0;
  top: 0;
  height: 100%;
  width: 80px;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .8));
}


/* ── 3. the veil, for waits long enough to worry about ─────────────────── */

.idp-veil {
  position: fixed;
  inset: 0;
  z-index: 2147482000;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(249, 250, 252, .62);
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);
  opacity: 0;
  visibility: hidden;
  transition: opacity .2s ease, visibility .2s ease;
}

.idp-veil.idp-on {
  opacity: 1;
  visibility: visible;                /* absorbs the extra taps as well */
}

.idp-veil-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  padding: 26px 34px;
  border-radius: 18px;
  background: #fff;
  box-shadow: 0 18px 50px -18px rgba(16, 24, 40, .35);
  animation: idp-veil-in .25s ease both;
}

/* a gradient ring rather than a plain border spinner - the mask punches the
   middle out. Without mask support this degrades to a spinning disc, which
   still reads as "working". */
.idp-veil-ring {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: conic-gradient(from 90deg, rgba(245, 50, 92, 0), var(--idp-load-2) 70%, var(--idp-load-3));
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 4px), #000 calc(100% - 4px));
  mask: radial-gradient(farthest-side, transparent calc(100% - 4px), #000 calc(100% - 4px));
  animation: idp-spin .9s linear infinite;
}

.idp-veil-text {
  font-size: .92rem;
  font-weight: 600;
  color: #3f4d6b;
  text-align: center;
  line-height: 1.5;
}


/* ── reduced motion ────────────────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
  .idp-busy::after,
  .idp-veil-ring { animation-duration: 2s; }
  .idp-veil-card { animation: none; }
  .idp-progress { transition: opacity .25s ease; }
}
