/* ═══════════════════════════════════════════════════════════════
   PENDING STATE — one progress bar for every in-flight request, plus
   the shared "this control is working" vocabulary.
   Driven by app/javascript/pending.js.
   ═══════════════════════════════════════════════════════════════ */

/* Turbo ships its own 3px blue bar. pending.js pushes progressBarDelay out of
   reach so it's never installed; this is the backstop if that config surface
   ever changes. Our <link> comes after Turbo's injected <style> (which it puts
   at head.firstChild), so equal specificity would already win — !important
   just documents the intent. */
.turbo-progress-bar { display: none !important; }

/* ── The bar ────────────────────────────────────────── */
/* Above everything, including the 56px topbar. The app's highest z-index is
   .panel-layer at 40; 2147483647 matches Turbo's own choice for the same reason.
   Width (not transform: scaleX) is animated on purpose — scaling squashes the
   three-stop gradient into whatever fraction is visible instead of revealing it
   left to right. On a fixed, childless, contained 3px element it costs nothing. */
.pending-bar {
  position: fixed;
  top: 0;
  left: 0;
  width: 0;
  height: 3px;
  z-index: 2147483647;
  background: linear-gradient(135deg, var(--brand-golden) 0%, var(--brand-orange) 50%, var(--brand-red) 100%);
  opacity: 0;
  pointer-events: none;
  contain: layout paint style;
  transition: width 220ms var(--ease-out), opacity 250ms linear;
}
/* Fade in fast (80ms) so the bar feels responsive, out slow (250ms) so it settles. */
.pending-bar--visible { opacity: 1; transition: width 220ms var(--ease-out), opacity 80ms linear; }
.pending-bar--done { opacity: 0; transition: width 120ms linear, opacity 250ms linear; }

/* Trailing glow — reads as motion even while the width trickles slowly. */
.pending-bar::after {
  content: '';
  position: absolute;
  right: 0;
  top: 0;
  height: 100%;
  width: 120px;
  box-shadow: 0 0 12px var(--brand-orange), 0 0 6px var(--brand-red);
  opacity: 0.8;
}

@media (prefers-reduced-motion: reduce) {
  .pending-bar,
  .pending-bar--visible,
  .pending-bar--done { transition: none; }
  .pending-bar::after { display: none; }
}

/* ── "Working" / "unavailable" ───────────────────────
   One vocabulary, three producers:
     · Turbo sets aria-disabled on a form's submitter between
       FormSubmission#requestStarted and #requestFinished (config.forms.submitter,
       set to "aria-disabled" in pending.js);
     · pending.js sets data-pending on the element that started a frame load;
     · the _pagination partials already ship aria-disabled on a .btn span.
   Bare button/input selectors are needed for the unclassed submits on the Drive
   checklist and the auth screens — .btn alone wouldn't reach them. */
button[aria-disabled="true"],
button:disabled,
input[type="submit"][aria-disabled="true"],
input[type="submit"]:disabled,
.btn[aria-disabled="true"],
[data-pending] {
  opacity: 0.5;
  pointer-events: none;
  cursor: not-allowed;
}
/* An in-flight request is "working", not "unavailable". */
[data-pending] { cursor: progress; }
/* Pagination arrows with nowhere to go are genuinely unavailable — keep the
   dimmer opacity and neutral cursor they had before this file existed. Both
   classes are needed: .btn[aria-disabled="true"] above is (0,2,0) and would
   otherwise outrank a lone .pagination__disabled regardless of source order.
   Every _pagination partial renders the pair together. */
.btn.pagination__disabled { opacity: 0.4; cursor: default; }

/* ── Detail slide-over dim ───────────────────────────
   No JavaScript: Turbo's FrameController marks the frame [busy] on every frame
   navigation and clears it from perform()'s finally — so on success, HTTP error,
   network error and abort alike. transition-delay applies only in the busy
   state, which gates the fade IN (loads under 200ms never dim) while letting it
   snap back at delay 0. Nothing to leak.
   Scoped to .panel-layer, never turbo-frame[busy] — roster frames carry [busy]
   too, and dimming those would strobe the table on every debounced keystroke. */
.panel-layer .panel-sheet { transition: opacity var(--duration-fast) var(--ease-out); }
.panel-layer[busy] .panel-sheet {
  opacity: 0.5;
  pointer-events: none;
  transition-delay: 200ms;
}
@media (prefers-reduced-motion: reduce) {
  /* Keep the 200ms gate, drop the fade. */
  .panel-layer .panel-sheet { transition: opacity 1ms linear; }
}

/* ── Reorder list mid-PATCH ──────────────────────────
   sortable_controller sets aria-busy while its raw fetch is in flight. Mirrors
   the [data-editing] single-edit lock in application.css. */
.sheet-list[aria-busy="true"] { opacity: 0.6; pointer-events: none; }
