@charset "utf-8";
/* ============================================================================
   STRATAMIZE — "THE LEDGER" · FEEDBACK + OVERLAYS  (feedback-overlays.css)
   ----------------------------------------------------------------------------
   The system's voice when it needs to SAY something or stand IN FRONT of the
   work: inline alerts + page banners, the toast stack, badges, status pills +
   chips (incl. the payment lifecycle: approved / declined / pending / refunded
   / voided), modals & dialogs, drawers & bottom sheets, tooltips, and the
   loading vocabulary (skeletons + spinners + indeterminate rails).

   Every value derives from a semantic token in tokens.css, so the SAME classes
   render the dark operator cockpit ([data-theme="dark"]) and the light customer
   paper ([data-theme="light"]). This is the file that makes a "Card declined"
   on an operator grid and a "Paid in full" on a customer receipt read as ONE
   instrument.

   RULES OBEYED
     • Tokens only. No hex literals, no new --vars (locals are --_scoped).
     • Mint is the single live signal — reserved for the live toast rail, the
       "approved/paid" dot and the one .is-live pulse; never sprayed.
     • Status is DOUBLE-ENCODED (shape + color): dot ● / diamond ◆ / triangle ▲
       / cross ✕ / dash – — survives a glance and color-vision deficiency.
     • Every interactive affordance has hover / focus-visible / active states.
     • Motion is compositor-only (transform / opacity). prefers-reduced-motion
       zeroes entrances, stops the live pulse, and calms the spinner.

   Load order: tokens.css → feedback-overlays.css  (alongside the other slices)
   MAP
     1  alerts (inline) + page banners
     2  toasts + toast region
     3  badges + count badges
     4  status pills (CVD shape+color) + the payment lifecycle
     5  chips (static / removable / selectable filter)
     6  modal / dialog (scrim, sizes, head/body/foot, danger)
     7  drawer (side) + bottom sheet
     8  tooltip (positions)
     9  skeleton (shimmer placeholders)
    10  spinner + indeterminate rail + inline busy
    11  reduced-motion + forced-colors guards
   ============================================================================ */

/* ════════════════════════════════════════════════════════════════════════
   1 · ALERTS (inline) + PAGE BANNERS
   ----------------------------------------------------------------------------
   A signal-rail left edge marks the message; the leading glyph is shape-coded
   so meaning survives without color. Tonal wash + status edge, never card-soup.
   ════════════════════════════════════════════════════════════════════════ */
.alert{
  --_tone: var(--ink-3);              /* neutral default; variants re-point this */
  --_wash: var(--surface-sunken);
  display:grid;
  grid-template-columns:auto 1fr auto;
  gap:var(--s-3) var(--s-4);
  align-items:start;
  padding:var(--s-4) var(--s-5);
  border:1px solid var(--hairline-strong);
  border-inline-start:var(--rail-w) solid var(--_tone);
  border-radius:var(--r-3);
  background:var(--_wash);
  color:var(--ink-2);
  box-shadow:var(--shadow-1);
}
/* leading marker — shape-encoded, color from --_tone */
.alert > .alert-mark{
  inline-size:1.25rem;block-size:1.25rem;
  display:grid;place-items:center;
  color:var(--_tone);
  font:600 var(--fs-sm)/1 var(--font-mono);
  flex:none;
}
.alert > .alert-mark::before{content:""}
.alert-body{min-inline-size:0}
.alert .alert-title{
  font:600 var(--fs-base)/1.35 var(--font-text);color:var(--ink);
  margin-block-end:2px;
}
.alert .alert-text{font:400 var(--fs-sm)/1.55 var(--font-text);color:var(--ink-2)}
.alert .alert-text a{color:var(--accent-text)}
/* trailing action cluster (links / small buttons supplied by actions slice) */
.alert .alert-actions{
  grid-column:2;display:flex;flex-wrap:wrap;gap:var(--s-2);margin-block-start:var(--s-3);
}
/* dismiss affordance */
.alert .alert-x{
  grid-row:1;grid-column:3;
  inline-size:1.5rem;block-size:1.5rem;flex:none;
  display:grid;place-items:center;
  border:0;border-radius:var(--r-2);background:transparent;color:var(--ink-4);
  font:400 1rem/1 var(--font-text);cursor:pointer;
  transition:color var(--dur-1) var(--ease-out),background-color var(--dur-1) var(--ease-out);
}
.alert .alert-x::before{content:"✕"}
.alert .alert-x:hover{color:var(--ink);background:color-mix(in oklab,var(--ink) 8%,transparent)}
.alert .alert-x:active{transform:translateY(0.5px)}
.alert .alert-x:focus-visible{outline:none;box-shadow:var(--ring)}

/* variants — tone + the shape-coded marker glyph */
.alert--info   { --_tone:var(--info);    --_wash:var(--info-wash) }
.alert--success{ --_tone:var(--success); --_wash:var(--accent-wash) }
.alert--warn   { --_tone:var(--warn);    --_wash:var(--warn-wash) }
.alert--danger { --_tone:var(--danger);  --_wash:var(--danger-wash) }
.alert--info    > .alert-mark::before{content:"◆"}   /* diamond  */
.alert--success > .alert-mark::before{content:"●"}   /* dot      */
.alert--warn    > .alert-mark::before{content:"▲"}   /* triangle */
.alert--danger  > .alert-mark::before{content:"✕"}   /* cross    */

/* PAGE BANNER — full-bleed strip variant for the top of a view (squared edges,
   horizontal layout). Reuses the same tones/markers. */
.banner{
  display:flex;align-items:center;gap:var(--s-3);
  inline-size:100%;
  padding:var(--s-3) var(--gutter);
  border:0;border-block-end:1px solid var(--hairline-strong);
  border-inline-start:var(--rail-w) solid var(--_tone, var(--ink-3));
  background:var(--_wash, var(--surface-header));
  color:var(--ink-2);
  font:500 var(--fs-sm)/1.4 var(--font-text);
}
.banner > .alert-mark{flex:none}
.banner .banner-text{min-inline-size:0}
.banner .banner-text strong{color:var(--ink);font-weight:600}
.banner .spacer{margin-inline-start:auto}
.banner--info   { --_tone:var(--info);    --_wash:var(--info-wash) }
.banner--success{ --_tone:var(--success); --_wash:var(--accent-wash) }
.banner--warn   { --_tone:var(--warn);    --_wash:var(--warn-wash) }
.banner--danger { --_tone:var(--danger);  --_wash:var(--danger-wash) }
.banner--info    > .alert-mark{color:var(--info)}    .banner--info    > .alert-mark::before{content:"◆"}
.banner--success > .alert-mark{color:var(--success)} .banner--success > .alert-mark::before{content:"●"}
.banner--warn    > .alert-mark{color:var(--warn)}    .banner--warn    > .alert-mark::before{content:"▲"}
.banner--danger  > .alert-mark{color:var(--danger)}  .banner--danger  > .alert-mark::before{content:"✕"}

/* ════════════════════════════════════════════════════════════════════════
   2 · TOASTS + TOAST REGION
   ----------------------------------------------------------------------------
   The live rail is the mint signal; status toasts re-point it. Enter via
   transform+opacity (compositor). A scaleX progress bar shows time-to-dismiss
   without reflowing anything.
   ════════════════════════════════════════════════════════════════════════ */
.toast-region{
  position:fixed;z-index:var(--z-toast);
  display:flex;flex-direction:column;gap:var(--s-3);
  inline-size:min(380px,calc(100vw - 2*var(--gutter)));
  pointer-events:none;                 /* region is click-through; toasts opt back in */
}
.toast-region > *{pointer-events:auto}
.toast-region--tr{ top:var(--gutter); right:var(--gutter) }
.toast-region--tl{ top:var(--gutter); left:var(--gutter) }
.toast-region--br{ bottom:var(--gutter); right:var(--gutter); flex-direction:column-reverse }
.toast-region--bl{ bottom:var(--gutter); left:var(--gutter); flex-direction:column-reverse }

.toast{
  --_tone: var(--accent);
  position:relative;
  display:grid;
  grid-template-columns:auto auto 1fr auto;
  gap:var(--s-3);
  align-items:start;
  padding:var(--s-4);
  background:var(--surface-raised);
  border:1px solid var(--hairline-strong);
  border-radius:var(--r-3);
  box-shadow:var(--shadow-3);
  overflow:hidden;
  animation:toast-in var(--dur-3) var(--ease-out);
}
/* the live signal rail down the left edge */
.toast > .toast-rail{
  grid-row:1 / -1;
  inline-size:var(--rail-w);align-self:stretch;
  border-radius:var(--r-full);
  background:var(--_tone);
}
.toast > .toast-mark{
  inline-size:1.1rem;block-size:1.1rem;display:grid;place-items:center;
  color:var(--_tone);font:600 var(--fs-meta)/1 var(--font-mono);flex:none;
}
.toast .toast-body{min-inline-size:0}
.toast .toast-title{font:600 var(--fs-sm)/1.3 var(--font-text);color:var(--ink)}
.toast .toast-text{font:400 var(--fs-meta)/1.5 var(--font-text);color:var(--ink-3);margin-block-start:2px}
.toast .toast-text .mono,.toast .toast-text [data-mono]{color:var(--ink-2)}
.toast .toast-x{
  inline-size:1.4rem;block-size:1.4rem;flex:none;
  display:grid;place-items:center;border:0;border-radius:var(--r-2);
  background:transparent;color:var(--ink-4);font:400 0.95rem/1 var(--font-text);cursor:pointer;
  transition:color var(--dur-1) var(--ease-out),background-color var(--dur-1) var(--ease-out);
}
.toast .toast-x::before{content:"✕"}
.toast .toast-x:hover{color:var(--ink);background:color-mix(in oklab,var(--ink) 8%,transparent)}
.toast .toast-x:focus-visible{outline:none;box-shadow:var(--ring)}
/* auto-dismiss progress — scaleX from a left origin (compositor-friendly) */
.toast .toast-progress{
  position:absolute;inset-inline:0;inset-block-end:0;block-size:2px;
  background:var(--_tone);opacity:0.55;
  transform-origin:left center;
  animation:toast-progress var(--_ttl,5s) linear forwards;
}
.toast--info    { --_tone:var(--info) }    .toast--info    > .toast-mark::before{content:"◆"}
.toast--success { --_tone:var(--success) } .toast--success > .toast-mark::before{content:"●"}
.toast--warn    { --_tone:var(--warn) }    .toast--warn    > .toast-mark::before{content:"▲"}
.toast--danger  { --_tone:var(--danger) }  .toast--danger  > .toast-mark::before{content:"✕"}
/* default (live) toast marker */
.toast > .toast-mark::before{content:"●"}

@keyframes toast-in{
  from{opacity:0;transform:translateY(8px) scale(0.98)}
}
@keyframes toast-progress{
  from{transform:scaleX(1)} to{transform:scaleX(0)}
}

/* ════════════════════════════════════════════════════════════════════════
   3 · BADGES + COUNT BADGES
   ----------------------------------------------------------------------------
   Quiet metadata tags. Numerals ride mono+tabular. Tonal variants stay subtle
   (wash + text), never compete with the live signal.
   ════════════════════════════════════════════════════════════════════════ */
.badge{
  display:inline-flex;align-items:center;gap:var(--s-1);
  padding:2px var(--s-2);
  font:600 var(--fs-meta)/1.4 var(--font-text);
  border:1px solid var(--hairline);border-radius:var(--r-1);
  background:var(--surface-sunken);color:var(--ink-2);
  white-space:nowrap;
}
.badge .num,.badge[data-mono]{font-family:var(--font-mono);font-variant-numeric:tabular-nums}
.badge--sm{padding:1px var(--s-1);font-size:var(--fs-kicker)}
.badge--lg{padding:var(--s-1) var(--s-3);font-size:var(--fs-sm)}
/* solid accent badge — the one loud variant, used sparingly (e.g. "LIVE") */
.badge--accent{background:var(--accent);color:var(--on-accent-solid);border-color:var(--accent)}
.badge--info   {color:var(--info);   background:var(--info-wash);   border-color:var(--info-edge)}
.badge--success{color:var(--success);background:var(--accent-wash); border-color:var(--accent-edge)}
.badge--warn   {color:var(--warn);   background:var(--warn-wash);   border-color:var(--warn-edge)}
.badge--danger {color:var(--danger); background:var(--danger-wash); border-color:var(--danger-edge)}
.badge--outline{background:transparent}
/* count badge — circular numeric indicator that hugs a nav item / button */
.badge--count{
  min-inline-size:1.25rem;block-size:1.25rem;padding:0 5px;
  justify-content:center;border-radius:var(--r-full);
  font:600 var(--fs-kicker)/1 var(--font-mono);font-variant-numeric:tabular-nums;
  background:var(--danger);color:var(--surface-page);border-color:transparent;
}
.badge--count.is-accent{background:var(--accent);color:var(--on-accent-solid)}

/* ════════════════════════════════════════════════════════════════════════
   4 · STATUS PILLS — CVD-safe shape + color  ·  THE PAYMENT LIFECYCLE
   ----------------------------------------------------------------------------
   Shape is meaning, color is reinforcement. Five primitives carried verbatim
   from the system vocabulary: dot ● / diamond ◆ / triangle ▲ / cross ✕ / dash –
   ════════════════════════════════════════════════════════════════════════ */
.pill{
  display:inline-flex;align-items:center;gap:6px;
  padding:2px var(--s-3);
  font:600 var(--fs-meta)/1.5 var(--font-text);
  text-transform:uppercase;letter-spacing:0.04em;white-space:nowrap;
  border:1px solid currentColor;border-radius:var(--r-1);
  background:var(--surface-sunken);
}
.pill::before{content:"";inline-size:7px;block-size:7px;flex:none}
.pill .pill-meta{
  font:500 var(--fs-kicker)/1 var(--font-mono);font-variant-numeric:tabular-nums;
  letter-spacing:0;opacity:0.85;
}
/* generic semantic states */
.pill--success{color:var(--success);background:var(--accent-wash)}
.pill--success::before{border-radius:var(--r-full);background:currentColor}                 /* ● dot */
.pill--info{color:var(--info);background:var(--info-wash)}
.pill--info::before{transform:rotate(45deg);background:currentColor}                         /* ◆ diamond */
.pill--warn{color:var(--warn);background:var(--warn-wash)}
.pill--warn::before{clip-path:polygon(50% 0,100% 100%,0 100%);background:currentColor}       /* ▲ triangle */
.pill--danger{color:var(--danger);background:var(--danger-wash)}
.pill--danger::before{background:currentColor;
  clip-path:polygon(20% 0,0 20%,30% 50%,0 80%,20% 100%,50% 70%,80% 100%,100% 80%,70% 50%,100% 20%,80% 0,50% 30%)} /* ✕ */
.pill--rare{color:var(--rare);background:var(--rare-wash)}
.pill--rare::before{background:currentColor;clip-path:polygon(50% 0,100% 38%,82% 100%,18% 100%,0 38%)} /* ⬠ pentagon — ≤1/view */
.pill--neutral{color:var(--ink-3);background:var(--surface-sunken)}
.pill--neutral::before{block-size:2px;align-self:center;background:currentColor}             /* – dash */

/* ---- PAYMENT LIFECYCLE — locked mapping (shape is the constant) ----------- */
/* approved / paid — settled & authorized → mint dot (the live signal) */
.pill--approved{color:var(--success);background:var(--accent-wash)}
.pill--approved::before{border-radius:var(--r-full);background:currentColor}                 /* ● */
/* declined — hard fail → red cross */
.pill--declined{color:var(--danger);background:var(--danger-wash)}
.pill--declined::before{background:currentColor;
  clip-path:polygon(20% 0,0 20%,30% 50%,0 80%,20% 100%,50% 70%,80% 100%,100% 80%,70% 50%,100% 20%,80% 0,50% 30%)} /* ✕ */
/* pending / processing — in flight → amber triangle (optionally .is-live pulse) */
.pill--pending{color:var(--warn);background:var(--warn-wash)}
.pill--pending::before{background:currentColor;clip-path:polygon(50% 0,100% 100%,0 100%)}     /* ▲ */
/* refunded — money returned → cyan diamond (info, not failure) */
.pill--refunded{color:var(--info);background:var(--info-wash)}
.pill--refunded::before{transform:rotate(45deg);background:currentColor}                      /* ◆ */
/* voided — authorization cancelled before settlement → neutral dash (struck) */
.pill--voided{color:var(--ink-3);background:var(--surface-sunken)}
.pill--voided::before{block-size:2px;align-self:center;background:currentColor}               /* – */

/* the single rationed live pulse — opacity only, stops under reduced-motion */
.pill.is-live::before{animation:pill-pulse var(--blink) ease-in-out infinite}
@keyframes pill-pulse{50%{opacity:0.35}}

/* solid emphasis pill (e.g. the customer "PAID" stamp) — true mint fill */
.pill--stamp{
  color:var(--on-accent-solid);background:var(--accent);border-color:var(--accent);
  padding:var(--s-1) var(--s-3);font-size:var(--fs-sm);letter-spacing:var(--tracking-caps);
}
.pill--stamp::before{background:var(--on-accent-solid);border-radius:var(--r-full)}

/* ════════════════════════════════════════════════════════════════════════
   5 · CHIPS — static / removable input / selectable filter
   ════════════════════════════════════════════════════════════════════════ */
.chip{
  display:inline-flex;align-items:center;gap:6px;
  padding:3px var(--s-3);
  font:600 var(--fs-meta)/1.4 var(--font-text);
  border:1px solid var(--hairline-strong);border-radius:var(--r-full);
  background:var(--surface-sunken);color:var(--ink-2);
  cursor:default;
}
.chip .glyph{font-size:0.7em;line-height:0;color:var(--ink-4)}
.chip .chip-avatar{
  inline-size:1.1rem;block-size:1.1rem;border-radius:var(--r-full);
  background:var(--accent-wash);color:var(--accent-text);
  display:grid;place-items:center;font:600 var(--fs-kicker)/1 var(--font-mono);margin-inline-start:-4px;
}
/* removable — trailing ✕ button */
.chip .chip-x{
  inline-size:1rem;block-size:1rem;margin-inline-end:-4px;flex:none;
  display:grid;place-items:center;border:0;border-radius:var(--r-full);
  background:transparent;color:var(--ink-4);font:400 0.7rem/1 var(--font-text);cursor:pointer;
  transition:color var(--dur-1) var(--ease-out),background-color var(--dur-1) var(--ease-out);
}
.chip .chip-x::before{content:"✕"}
.chip .chip-x:hover{color:var(--ink);background:color-mix(in oklab,var(--ink) 10%,transparent)}
.chip .chip-x:focus-visible{outline:none;box-shadow:var(--ring)}
/* selectable filter chip — a real button/checkbox; active = mint edge */
.chip--select{cursor:pointer;color:var(--ink-3);
  transition:color var(--dur-1) var(--ease-out),border-color var(--dur-1) var(--ease-out),
             background-color var(--dur-1) var(--ease-out)}
.chip--select:hover{color:var(--ink);border-color:var(--accent-edge)}
.chip--select:active{transform:translateY(0.5px)}
.chip--select:focus-visible{outline:none;box-shadow:var(--ring)}
.chip--select[aria-pressed="true"],
.chip--select.is-selected{
  color:var(--accent-text);background:var(--accent-wash);border-color:var(--accent-edge);
}
.chip--select[aria-pressed="true"]::before,
.chip--select.is-selected::before{content:"✓";font-size:0.8em;color:var(--accent-text)}

/* ════════════════════════════════════════════════════════════════════════
   6 · MODAL / DIALOG
   ----------------------------------------------------------------------------
   Scrim dims the cockpit (page-tinted, blurred); the dialog is a raised panel
   with hairline structure. Sizes are width caps. .modal--danger re-points the
   header rail for destructive confirms.
   ════════════════════════════════════════════════════════════════════════ */
.scrim{
  position:fixed;inset:0;z-index:var(--z-overlay);
  display:grid;place-items:center;padding:var(--gutter);
  background:color-mix(in oklab,var(--surface-page) 72%,transparent);
  -webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px);
  animation:scrim-in var(--dur-2) var(--ease-out);
}
.scrim--top{align-items:start;padding-block-start:12vh}
.modal{
  position:relative;z-index:var(--z-modal);
  inline-size:min(560px,100%);max-block-size:calc(100svh - 2*var(--gutter));
  display:flex;flex-direction:column;
  background:var(--surface-raised);
  border:1px solid var(--hairline-strong);border-radius:var(--r-lg);
  box-shadow:var(--shadow-3);overflow:hidden;
  animation:modal-in var(--dur-3) var(--ease-out);
}
.modal--sm{inline-size:min(420px,100%)}
.modal--lg{inline-size:min(760px,100%)}
.modal--xl{inline-size:min(960px,100%)}
.modal-head{
  display:flex;justify-content:space-between;align-items:flex-start;gap:var(--s-4);
  padding:var(--s-6) var(--s-6) var(--s-5);
  border-block-end:1px solid var(--hairline);
}
.modal-head .modal-eyebrow{
  font:600 var(--fs-kicker)/1 var(--font-text);text-transform:uppercase;
  letter-spacing:var(--tracking-kicker);color:var(--ink-3);margin-block-end:var(--s-2);
}
.modal-title{font:600 var(--fs-h4)/1.2 var(--font-display);color:var(--ink);letter-spacing:var(--tracking-tight)}
.modal-sub{font:400 var(--fs-sm)/1.5 var(--font-text);color:var(--ink-3);margin-block-start:var(--s-2)}
.modal-x{
  inline-size:2rem;block-size:2rem;flex:none;
  display:grid;place-items:center;border:1px solid transparent;border-radius:var(--r-2);
  background:transparent;color:var(--ink-3);font:400 1.1rem/1 var(--font-text);cursor:pointer;
  transition:color var(--dur-1) var(--ease-out),background-color var(--dur-1) var(--ease-out),
             border-color var(--dur-1) var(--ease-out);
}
.modal-x::before{content:"✕"}
.modal-x:hover{color:var(--ink);background:color-mix(in oklab,var(--ink) 8%,transparent)}
.modal-x:active{transform:translateY(0.5px)}
.modal-x:focus-visible{outline:none;box-shadow:var(--ring)}
.modal-body{padding:var(--s-6);overflow:auto;color:var(--ink-2);font-size:var(--fs-sm);line-height:1.6}
.modal-foot{
  display:flex;gap:var(--s-3);justify-content:flex-end;align-items:center;flex-wrap:wrap;
  padding:var(--s-5) var(--s-6);
  border-block-start:1px solid var(--hairline);background:var(--surface-header);
}
.modal-foot .spacer{margin-inline-end:auto}
/* danger confirm — header carries the danger rail + marker */
.modal--danger .modal-head{border-block-end-color:var(--danger-edge);
  box-shadow:inset var(--rail-w) 0 0 0 var(--danger)}
.modal--danger .modal-title{color:var(--ink)}

@keyframes scrim-in{from{opacity:0}}
@keyframes modal-in{from{opacity:0;transform:translateY(10px) scale(0.985)}}

/* ════════════════════════════════════════════════════════════════════════
   7 · DRAWER (side) + BOTTOM SHEET
   ════════════════════════════════════════════════════════════════════════ */
.drawer{
  position:fixed;inset-block:0;inset-inline-end:0;z-index:var(--z-drawer);
  inline-size:min(440px,100%);
  display:flex;flex-direction:column;
  background:var(--surface-raised);
  border-inline-start:1px solid var(--hairline-strong);
  box-shadow:var(--shadow-3);
  animation:drawer-in-right var(--dur-3) var(--ease-edit);
}
.drawer--left{inset-inline:0 auto;border-inline:0 1px solid var(--hairline-strong);
  animation-name:drawer-in-left}
.drawer--wide{inline-size:min(620px,100%)}
.drawer-head{
  display:flex;justify-content:space-between;align-items:center;gap:var(--s-4);
  padding:var(--s-5) var(--s-6);border-block-end:1px solid var(--hairline);
  background:var(--surface-header);
}
.drawer-title{font:600 var(--fs-h4)/1.2 var(--font-display);color:var(--ink)}
.drawer-body{padding:var(--s-6);overflow:auto;flex:1;color:var(--ink-2)}
.drawer-foot{
  display:flex;gap:var(--s-3);justify-content:flex-end;
  padding:var(--s-5) var(--s-6);border-block-start:1px solid var(--hairline);
  background:var(--surface-header);
}
.drawer .drawer-x{
  inline-size:2rem;block-size:2rem;flex:none;display:grid;place-items:center;
  border:0;border-radius:var(--r-2);background:transparent;color:var(--ink-3);
  font:400 1.1rem/1 var(--font-text);cursor:pointer;
  transition:color var(--dur-1) var(--ease-out),background-color var(--dur-1) var(--ease-out);
}
.drawer .drawer-x::before{content:"✕"}
.drawer .drawer-x:hover{color:var(--ink);background:color-mix(in oklab,var(--ink) 8%,transparent)}
.drawer .drawer-x:focus-visible{outline:none;box-shadow:var(--ring)}

/* bottom sheet — mobile/customer surface; grab handle + rounded top */
.sheet{
  position:fixed;inset-inline:0;inset-block-end:0;z-index:var(--z-drawer);
  max-block-size:88svh;display:flex;flex-direction:column;
  background:var(--surface-raised);
  border-block-start:1px solid var(--hairline-strong);
  border-start-start-radius:var(--r-xl);border-start-end-radius:var(--r-xl);
  box-shadow:var(--shadow-3);
  animation:sheet-in var(--dur-3) var(--ease-edit);
}
.sheet::before{
  content:"";inline-size:36px;block-size:4px;border-radius:var(--r-full);
  background:var(--hairline-strong);margin:var(--s-3) auto var(--s-1);
}
.sheet-body{padding:var(--s-5) var(--gutter) var(--s-8);overflow:auto;color:var(--ink-2)}

@keyframes drawer-in-right{from{transform:translateX(100%)}}
@keyframes drawer-in-left{from{transform:translateX(-100%)}}
@keyframes sheet-in{from{transform:translateY(100%)}}

/* ════════════════════════════════════════════════════════════════════════
   8 · TOOLTIP — hover/focus, four positions, near-instant
   ════════════════════════════════════════════════════════════════════════ */
.tooltip{position:relative;display:inline-flex}
.tooltip > .tip{
  position:absolute;z-index:var(--z-tooltip);
  inset-block-end:calc(100% + 8px);inset-inline-start:50%;
  transform:translateX(-50%) translateY(4px);
  max-inline-size:min(260px,60vw);
  padding:var(--s-2) var(--s-3);
  background:var(--surface-inverse);color:var(--on-inverse);
  font:500 var(--fs-meta)/1.35 var(--font-text);
  border-radius:var(--r-2);box-shadow:var(--shadow-2);
  white-space:normal;text-align:center;
  opacity:0;pointer-events:none;
  transition:opacity var(--dur-2) var(--ease-out),transform var(--dur-2) var(--ease-out);
}
.tooltip > .tip .mono,.tooltip > .tip [data-mono]{font-family:var(--font-mono)}
/* little caret on the tip */
.tooltip > .tip::after{
  content:"";position:absolute;inset-block-start:100%;inset-inline-start:50%;
  inline-size:8px;block-size:8px;background:var(--surface-inverse);
  transform:translateX(-50%) translateY(-50%) rotate(45deg);
}
.tooltip:hover > .tip,
.tooltip:focus-within > .tip{opacity:1;transform:translateX(-50%) translateY(0)}
/* positions */
.tooltip--bottom > .tip{inset-block:calc(100% + 8px) auto;transform:translateX(-50%) translateY(-4px)}
.tooltip--bottom > .tip::after{inset-block-start:auto;inset-block-end:100%;transform:translateX(-50%) translateY(50%) rotate(45deg)}
.tooltip--bottom:hover > .tip,.tooltip--bottom:focus-within > .tip{transform:translateX(-50%) translateY(0)}
.tooltip--left > .tip{inset:50% calc(100% + 8px) auto auto;transform:translateY(-50%) translateX(4px)}
.tooltip--left > .tip::after{inset:50% auto auto 100%;transform:translateX(-50%) translateY(-50%) rotate(45deg)}
.tooltip--left:hover > .tip,.tooltip--left:focus-within > .tip{transform:translateY(-50%) translateX(0)}
.tooltip--right > .tip{inset:50% auto auto calc(100% + 8px);transform:translateY(-50%) translateX(-4px)}
.tooltip--right > .tip::after{inset:50% 100% auto auto;transform:translateX(50%) translateY(-50%) rotate(45deg)}
.tooltip--right:hover > .tip,.tooltip--right:focus-within > .tip{transform:translateY(-50%) translateX(0)}

/* ════════════════════════════════════════════════════════════════════════
   9 · SKELETON — shimmer placeholders (transform-driven sweep)
   ════════════════════════════════════════════════════════════════════════ */
.skeleton{
  position:relative;display:inline-block;
  inline-size:100%;block-size:0.9em;vertical-align:middle;
  border-radius:var(--r-2);
  background:var(--surface-sunken);overflow:hidden;
}
.skeleton::after{
  content:"";position:absolute;inset:0;
  background:linear-gradient(90deg,transparent,
    color-mix(in oklab,var(--ink) 8%,transparent),transparent);
  transform:translateX(-100%);
  animation:skeleton-sweep 1.4s var(--ease-out) infinite;
}
.skeleton--text{block-size:0.9em}
.skeleton--num{margin-inline-start:auto;inline-size:4.5rem}
.skeleton--wide{inline-size:70%}
.skeleton--full{inline-size:100%}
.skeleton--title{block-size:1.4em;inline-size:40%;border-radius:var(--r-3)}
.skeleton--block{block-size:var(--s-16);border-radius:var(--r-md)}
.skeleton--circle{inline-size:2.5rem;block-size:2.5rem;border-radius:var(--r-full);flex:none}
/* a ready-made stacked text skeleton */
.skeleton-lines{display:flex;flex-direction:column;gap:var(--s-3)}
@keyframes skeleton-sweep{100%{transform:translateX(100%)}}

/* ════════════════════════════════════════════════════════════════════════
   10 · SPINNER + INDETERMINATE RAIL + INLINE BUSY
   ════════════════════════════════════════════════════════════════════════ */
.spinner{
  display:inline-block;inline-size:1.25rem;block-size:1.25rem;
  border:2px solid var(--hairline-strong);
  border-block-start-color:var(--accent);          /* the lit arc = live signal */
  border-radius:var(--r-full);
  animation:spin 0.7s linear infinite;
  vertical-align:middle;
}
.spinner--sm{inline-size:1rem;block-size:1rem;border-width:2px}
.spinner--lg{inline-size:2rem;block-size:2rem;border-width:3px}
.spinner--ink{border-color:var(--hairline);border-block-start-color:var(--ink-2)}
.spinner--on-accent{border-color:color-mix(in oklab,var(--on-accent-solid) 35%,transparent);
  border-block-start-color:var(--on-accent-solid)}

/* indeterminate progress rail — a mint segment travels the track */
.rail-progress{
  position:relative;block-size:var(--rail-w);inline-size:100%;
  background:var(--hairline);border-radius:var(--r-full);overflow:hidden;
}
.rail-progress::before{
  content:"";position:absolute;inset-block:0;inset-inline-start:0;
  inline-size:38%;border-radius:var(--r-full);background:var(--accent);
  animation:rail-indeterminate 1.3s var(--ease-snap) infinite;
}
/* determinate variant — set --_val (0–1) inline; scaleX from left */
.rail-progress--determinate::before{
  inline-size:100%;animation:none;transform:scaleX(var(--_val,0));transform-origin:left center;
  transition:transform var(--dur-3) var(--ease-out);
}

/* inline busy label — spinner + tracked status text */
.busy{display:inline-flex;align-items:center;gap:var(--s-2);
  font:600 var(--fs-meta)/1 var(--font-text);text-transform:uppercase;
  letter-spacing:var(--tracking-caps);color:var(--ink-3)}

@keyframes spin{to{transform:rotate(360deg)}}
@keyframes rail-indeterminate{
  0%{transform:translateX(-120%)}
  100%{transform:translateX(360%)}
}

/* ════════════════════════════════════════════════════════════════════════
   11 · REDUCED-MOTION + FORCED-COLORS GUARDS
   ----------------------------------------------------------------------------
   Entrances become instant (tokens already zero --dur-*); the live pulse stops
   to a steady mint; the spinner keeps a calm, non-distracting rotation so
   "working" still reads, and the skeleton sweep stops to a steady tint.
   ════════════════════════════════════════════════════════════════════════ */
@media (prefers-reduced-motion: reduce){
  .toast,.scrim,.modal,.drawer,.sheet{animation-duration:1ms}
  .toast .toast-progress{animation:none;transform:scaleX(1);opacity:0.4}
  .pill.is-live::before{animation:none}
  .skeleton::after{animation:none}
  .skeleton{animation:none;opacity:0.7}
  .spinner{animation-duration:1.6s}            /* slow, steady — still legible as busy */
  .rail-progress::before{animation-duration:2.4s}
}

@media (forced-colors: active){
  .alert,.banner,.toast,.modal,.drawer,.sheet,.pill,.badge,.chip{
    border:1px solid CanvasText;
  }
  .toast > .toast-rail,.toast .toast-progress,.alert,.banner{forced-color-adjust:none}
  .tooltip > .tip{border:1px solid CanvasText}
  .spinner{border-block-start-color:Highlight}
}
