/* ========================================================================
 * SPECTRUM THEME  ·  Shared dark glassmorphic design system
 * ------------------------------------------------------------------------
 * Colors, typography, base components, utility helpers.
 * Every portal/page imports this as its baseline.
 * ==================================================================== */

*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }

/* ========================================================================
 * v1.4.4 — FLASH-OF-WRONG-BRAND PREVENTION
 * ------------------------------------------------------------------------
 * Before spectrum-tenant-boot.js rewrites [data-brand="*"] elements with the
 * resolved tenant's values, the literal text in the HTML still says
 * "SpectrumField" / "S" / "Innovation Technologies". On non-Spectrum tenants
 * (Digifon, etc.), a brief flash of the wrong brand is visible.
 *
 * Boot toggles <html> from .brand-pending → .brand-ready. We hide the
 * brand-bearing elements while pending, fade them in once ready. Anything
 * without a tenant-boot.js running stays visible by default — the rule only
 * fires when .brand-pending is set (i.e. the boot script kicked in but hasn't
 * finished). Failsafe: a 1.5s safety timer in case boot fails silently.
 * ===================================================================== */
html.brand-pending [data-brand="name"],
html.brand-pending [data-brand="initial"],
html.brand-pending [data-brand="tagline"],
html.brand-pending [data-brand="short"],
html.brand-pending [data-brand="company"],
html.brand-pending [data-brand="logo-img"] {
  visibility: hidden;
}
html.brand-ready [data-brand="name"],
html.brand-ready [data-brand="initial"],
html.brand-ready [data-brand="tagline"],
html.brand-ready [data-brand="short"],
html.brand-ready [data-brand="company"],
html.brand-ready [data-brand="logo-img"] {
  visibility: visible;
  animation: sxBrandIn .18s ease;
}
@keyframes sxBrandIn { from { opacity: 0; } to { opacity: 1; } }

/* ============================================================================
 * v2.0.0 — BRAND MORPH (universal app)
 * ----------------------------------------------------------------------------
 * The universal binary opens neutral and re-skins to the user's organisation
 * the moment it identifies them. Repainting every surface in a single frame
 * reads as a rendering glitch; easing it over ~520ms reads as the app
 * recognising who signed in.
 *
 * Only colour-ish properties transition, and only while .sx-brand-morphing is
 * on <html> — a permanent global transition would fight every hover state and
 * make the whole UI feel laggy. SXBrand.transform() adds the class, applies the
 * brand, and removes it one duration later.
 *
 * `transition: all` is deliberately NOT used: it would animate layout
 * properties too and cause visible reflow jitter on a long list.
 * ==========================================================================*/
html.sx-brand-morphing,
html.sx-brand-morphing body,
html.sx-brand-morphing *:not(svg):not(svg *) {
  transition:
    background-color var(--sx-brand-xfade, 520ms) cubic-bezier(.4, 0, .2, 1),
    background-image  var(--sx-brand-xfade, 520ms) cubic-bezier(.4, 0, .2, 1),
    border-color      var(--sx-brand-xfade, 520ms) cubic-bezier(.4, 0, .2, 1),
    color             var(--sx-brand-xfade, 520ms) cubic-bezier(.4, 0, .2, 1),
    fill              var(--sx-brand-xfade, 520ms) cubic-bezier(.4, 0, .2, 1),
    box-shadow        var(--sx-brand-xfade, 520ms) cubic-bezier(.4, 0, .2, 1) !important;
}

/* SC 2.3.3 Animation from Interactions — an involuntary full-screen colour
   sweep is exactly what this preference exists to suppress. transform() also
   checks the media query in JS and skips straight to apply(); this is the
   belt-and-braces half in case the class is ever added by other means. */
@media (prefers-reduced-motion: reduce) {
  html.sx-brand-morphing,
  html.sx-brand-morphing body,
  html.sx-brand-morphing *:not(svg):not(svg *) { transition: none !important; }
}

:root {
  /* v1.4.0 — TENANT BRAND VARIABLES. JS overrides these at SX.tenant.applyBranding()
   * time, falling back to Spectrum defaults below if no tenant is configured.
   *
   * v2.0.0 — this used to read `--brand-primary: var(--brand-primary)`, a
   * self-reference. Per CSS Variables spec that is invalid at computed-value
   * time, so the token resolved to nothing and every consumer (--cy, --cy3,
   * --fill-brand, --gd-brand) fell back to unset. It went unnoticed because
   * spectrum-tenant-boot.js sets the value inline on <html> before first paint
   * — but with JS disabled, blocked, or erroring, the whole app lost its brand
   * colour. The UNIVERSAL app makes that worse: it boots NEUTRAL and only
   * learns the real brand at sign-in, so the pre-login screens depend on this
   * literal default being real. Spectrum cyan is the correct fallback. */
  --brand-primary:      #00B5E2;
  --brand-primary-dark: #0A4A8A;
  --brand-accent:       #8DC63F;
  --brand-text:         #e8f4fc;

  /* v1.20 — brand DERIVATIVES. applyBranding() rewrites all four per tenant so
   * every tint, border, glow and brand-coloured label repaints with the tenant
   * identity instead of being frozen Spectrum cyan.
   *   --brand-rgb  : "r,g,b" triplet so any alpha tint can be composed
   *   --brand-ink  : the brand hue lightened until it clears 4.5:1 as TEXT
   *   --brand-on   : black or white — whichever is readable ON a brand fill
   *   --brand-accent-rgb : same trick for the secondary accent */
  --brand-rgb:        0,181,226;
  --brand-accent-rgb: 141,198,63;
  --brand-ink:        #3FD0F5;
  /* v1.23 — --accent-ink MUST have a :root default. applyBranding() sets it at
     runtime, but a bare var(--accent-ink) on an undeclared property is invalid
     at computed-value time, so `color` silently falls back to `inherit` before
     init or if JS fails. Consumers should still prefer the guarded
     var(--accent-ink, var(--brand-ink)) form. */
  --accent-ink:       #A8D65C;
  --brand-on:         #0B0E14;
  --accent-on:        #0B0E14;

  /* v1.21 — INK ON A SATURATED FILL.
   * Avatar chips, status badges and count dots fill with a vivid colour and
   * used to hardcode `color:#fff`. White on these fills measures 2.0–3.5:1 —
   * the single largest contrast defect on the platform (46% of all failures).
   * Black clears 5.6–9.6:1 on every fixed fill below, so these are static.
   * Brand-derived fills must NOT use this: Dangote red (#CD0001) and Tolaram
   * red (#E4002B) are dark enough that WHITE is the readable ink there, so
   * those surfaces use --brand-on / --accent-on, which applyBranding()
   * recomputes per tenant against the worst stop of the actual gradient. */
  --on-fill:          #0B0E14;   /* ink for fixed vivid fills (amber/green/violet/coral/gold) */
  --on-fill-danger:   #0B0E14;   /* #FF453A -> 5.67:1 */

  /* v1.21 — SOLID fills for anything that carries TEXT.
   * --gd-brand spans --brand-primary -> --brand-primary-dark. On Spectrum that
   * is cyan -> navy, a luminance range so wide that NO ink clears AA across it
   * (white 2.41:1 at the cyan end, dark 2.17:1 at the navy end). Gradients stay
   * for decorative surfaces; every chip, avatar, badge and button that renders
   * text uses these solid fills instead, so --brand-on / --accent-on — each
   * computed against that one colour — is guaranteed readable. */
  --fill-brand:       var(--brand-primary);
  --fill-accent:      var(--brand-accent);
  --brand-font:         -apple-system,BlinkMacSystemFont,'SF Pro Display',system-ui,Segoe UI,Roboto,sans-serif;

  /* Brand — legacy aliases (every spectrum-* CSS still uses these). At runtime
   * the JS layer keeps them in sync with --brand-primary so existing styles
   * automatically pick up the tenant palette. */
  --cy:  var(--brand-primary);
  --cy2: #33C6E8;
  --cy3: rgba(var(--brand-rgb),.12);
  --cy4: rgba(var(--brand-rgb),.28);
  --cy5: rgba(var(--brand-rgb),.06);
  --gr:  var(--brand-accent);
  --gr2: #A5D85F;
  --or:  #E8622A;
  --or2: #F0976A;

  /* ===================================================================
   * v1.20 DESIGN SYSTEM v2 — "warm graphite + 8 vibrant hues"
   * -------------------------------------------------------------------
   * Goals: colourful/lovable/vibrant, WCAG-AA everywhere, and fully
   * tenant-repaintable (every brand tint derives from --brand-rgb, which
   * applyBranding() rewrites per tenant — so Dangote red / Glo green /
   * Tolaram red / Korevra orange no longer sit on Spectrum-cyan chrome).
   * Contrast ratios in comments are measured against the surface named.
   * =================================================================== */

  /* SURFACES — warmed ~12° off pure blue-black toward graphite so the UI
   * feels warm and premium rather than cold and clinical. */
  --bg:  #0C1017;
  --s1:  #12171F;
  --s2:  #171D27;
  --s3:  #1D2530;
  --s4:  #252E3B;
  --s5:  #2F3949;
  --s0:  var(--bg);            /* was consumed but never defined */

  /* BORDERS — derive from the tenant brand so chrome repaints per tenant */
  --bd:  rgba(var(--brand-rgb), .14);
  --bd2: rgba(var(--brand-rgb), .30);
  --bd3: rgba(var(--brand-rgb), .45);
  --bd-soft: rgba(255,255,255,.07);   /* neutral hairline, brand-agnostic */

  /* TEXT — ratios on bg / s2 / s3
   *   --tx  17.4 / 15.5 / 14.1
   *   --tx2 12.5 / 11.1 / 10.1
   *   --mt   7.3 /  6.5 /  5.9   (was #5a7a8e = 4.2:1 -> FAILED AA on 474 sites)
   *   --mt2  6.5 /  5.7 /  5.2
   * v1.22 — --mt2 was #6E7E92 = 4.59 / 4.08 / 3.72. It reads as TEXT on ~60
   * sites (10px timestamps, sidebar section labels, unit hints), so it failed
   * AA everywhere below --bg. Lifted to #8A98AC, which clears 4.5:1 on every
   * surface up to --s4 (4.68) while staying a step dimmer than --mt. Its only
   * two non-text uses — the read-notification dot here and a 2px hairline in
   * training.html — merely get brighter, which cannot regress contrast. */
  --tx:  #F2F5F9;
  --tx2: #C9D2DE;
  --mt:  #93A2B4;
  --mt2: #8A98AC;

  /* STATES — brightened for AA on the warm ramp, and given soft tint +
   * border companions so status surfaces can be colour-blocked. */
  --ok:  #3DDC84;   --ok-bg:  rgba(61,220,132,.13);  --ok-bd:  rgba(61,220,132,.34);
  --er:  #FF6B6B;   --er-bg:  rgba(255,107,107,.13); --er-bd:  rgba(255,107,107,.34);
  --wa:  #FFB020;   --wa-bg:  rgba(255,176,32,.13);  --wa-bd:  rgba(255,176,32,.34);
  --in:  #4CC9F0;   --in-bg:  rgba(76,201,240,.13);  --in-bd:  rgba(76,201,240,.34);
  --bad: var(--er);           /* was consumed but never defined */

  /* ===== 8-HUE SEMANTIC ACCENT SCALE =====================================
   * Every hue ships {ink = AA-safe text/icon, bg = soft tint surface,
   * bd = border}. Use the -ink for text, the -bg for the card wash.
   * Inks measured >= 4.5:1 on --s2/--s3; large-text/UI uses clear 3:1. */
  --sky-ink:    #4CC9F0;  --sky-bg:    rgba(76,201,240,.12);  --sky-bd:    rgba(76,201,240,.30);
  --mint-ink:   #3DDC84;  --mint-bg:   rgba(61,220,132,.12);  --mint-bd:   rgba(61,220,132,.30);
  --amber-ink:  #FFC24B;  --amber-bg:  rgba(255,194,75,.12);  --amber-bd:  rgba(255,194,75,.30);
  --rose-ink:   #FF7A93;  --rose-bg:   rgba(255,122,147,.12); --rose-bd:   rgba(255,122,147,.30);
  --violet-ink: #B39CFF;  --violet-bg: rgba(179,156,255,.12); --violet-bd: rgba(179,156,255,.30);
  --teal-ink:   #35D9C4;  --teal-bg:   rgba(53,217,196,.12);  --teal-bd:   rgba(53,217,196,.30);
  --coral-ink:  #FF9A5B;  --coral-bg:  rgba(255,154,91,.12);  --coral-bd:  rgba(255,154,91,.30);
  --gold-ink:   #FFD766;  --gold-bg:   rgba(255,215,102,.12); --gold-bd:   rgba(255,215,102,.30);

  /* CHART / CATEGORICAL — one ordered scale, max adjacent-hue separation.
   * Replaces four mutually-inconsistent ad-hoc scales. */
  --chart-1: var(--brand-ink);
  --chart-2: var(--teal-ink);
  --chart-3: var(--violet-ink);
  --chart-4: var(--coral-ink);
  --chart-5: var(--mint-ink);
  --chart-6: var(--gold-ink);
  --chart-7: var(--sky-ink);
  --chart-8: var(--rose-ink);
  --chart-grid:  rgba(255,255,255,.06);
  --chart-axis:  #93A2B4;
  --chart-track: rgba(255,255,255,.05);
  --chart-label: var(--tx2);

  /* PER-METRIC KPI TINT — a KPI card sets data-metric and inherits its hue,
   * so "money" is always mint, "risk" always rose, across every portal. */
  --kpi-people-ink:  var(--sky-ink);    --kpi-people-bg:  var(--sky-bg);    --kpi-people-bd:  var(--sky-bd);
  --kpi-money-ink:   var(--mint-ink);   --kpi-money-bg:   var(--mint-bg);   --kpi-money-bd:   var(--mint-bd);
  --kpi-time-ink:    var(--amber-ink);  --kpi-time-bg:    var(--amber-bg);  --kpi-time-bd:    var(--amber-bd);
  --kpi-risk-ink:    var(--rose-ink);   --kpi-risk-bg:    var(--rose-bg);   --kpi-risk-bd:    var(--rose-bd);
  --kpi-insight-ink: var(--violet-ink); --kpi-insight-bg: var(--violet-bg); --kpi-insight-bd: var(--violet-bd);
  --kpi-ops-ink:     var(--teal-ink);   --kpi-ops-bg:     var(--teal-bg);   --kpi-ops-bd:     var(--teal-bd);
  --kpi-sales-ink:   var(--coral-ink);  --kpi-sales-bg:   var(--coral-bg);  --kpi-sales-bd:   var(--coral-bd);
  --kpi-reward-ink:  var(--gold-ink);   --kpi-reward-bg:  var(--gold-bg);   --kpi-reward-bd:  var(--gold-bd);

  /* COLOR-BLOCKED SIDEBAR — each nav section owns a hue so the eye can
   * navigate by colour, not just by reading every label. */
  --sec-overview-ink: var(--brand-ink);
  --sec-people-ink:   var(--sky-ink);
  --sec-ops-ink:      var(--teal-ink);
  --sec-money-ink:    var(--mint-ink);
  --sec-intel-ink:    var(--violet-ink);
  --sec-growth-ink:   var(--coral-ink);
  --sec-system-ink:   var(--mt);

  /* MOTION SCALE — one vocabulary for every transition + choreography.
   * Honoured by the prefers-reduced-motion block at the end of this file. */
  --motion-xfast: 90ms;
  --motion-fast:  150ms;
  --motion-mid:   240ms;
  --motion-slow:  380ms;
  --motion-slower:600ms;
  --ease-out:     cubic-bezier(.22,.9,.28,1);
  --ease-in-out:  cubic-bezier(.6,.05,.28,.98);
  --ease-spring:  cubic-bezier(.34,1.56,.64,1);   /* gentle overshoot */
  --stagger:      55ms;                            /* per-item entrance delay */

  /* Gradients — v1.4.2 base off brand vars so the same gradient repaints
   * with the active tenant's palette. --gd-brand is the primary CTA gradient;
   * legacy aliases keep working for code still using --gd-cy. */
  --gd-brand: linear-gradient(135deg, var(--brand-primary), var(--brand-primary-dark));
  --gd-cy:    var(--gd-brand);
  --gd-cy2:   linear-gradient(135deg, #33C6E8, #0090b8);
  --gd-gr:    linear-gradient(135deg, var(--brand-accent), #5a8a1a);
  --gd-or:    linear-gradient(135deg, #E8622A, #b03a10);
  --gd-pu:    linear-gradient(135deg, #7b68ee, #4a3abf);

  /* Shadows */
  --sh1: 0 4px 16px rgba(0,0,0,.3);
  --sh2: 0 12px 36px rgba(0,0,0,.45);
  --sh3: 0 24px 60px rgba(0,0,0,.6);
  --sh-cy: 0 4px 18px rgba(var(--brand-rgb),.35);
  --sh-cy2:0 12px 36px rgba(var(--brand-rgb),.25);

  /* Radii */
  --r-sm: 8px;
  --r-md: 12px;
  --r-lg: 18px;
  --r-xl: 24px;

  /* Timing */
  --t-fast: .15s;
  --t-mid:  .25s;
  --t-slow: .4s;
}

html, body {
  font-family: -apple-system, 'SF Pro Display', 'Segoe UI', system-ui, Inter, sans-serif;
  background: var(--bg);
  color: var(--tx);
  min-height: 100vh;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

a { color: inherit; text-decoration: none; }
button { font-family: inherit; cursor: pointer; border: 0; background: none; color: inherit; }
input, textarea, select { font-family: inherit; color: var(--tx); }
ul, ol { list-style: none; }
img { max-width: 100%; display: block; }

/* ==========================================================================
   FORM FIELDS — sx-input, sx-textarea, sx-select, sx-label
   All fields use a dark-theme-safe background. Text and placeholders have
   guaranteed contrast. Numeric spinners are suppressed for a clean look.
   ========================================================================== */
.sx-label {
  display: block;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .5px;
  color: var(--mt);
  margin-bottom: 6px;
}
.sx-input,
.sx-textarea,
.sx-select {
  width: 100%;
  padding: 11px 14px;
  background: rgba(255, 255, 255, .05);
  border: 1px solid rgba(255, 255, 255, .12);
  border-radius: 10px;
  color: var(--tx);
  font-size: 14px;
  font-family: inherit;
  outline: none;
  transition: border-color .15s, background .15s, box-shadow .15s;
  box-sizing: border-box;
  -webkit-appearance: none;
  appearance: none;
}
.sx-textarea { min-height: 92px; resize: vertical; line-height: 1.5; }
.sx-input:focus,
.sx-textarea:focus,
.sx-select:focus {
  border-color: var(--cy);
  background: rgba(var(--brand-rgb), .05);
  box-shadow: 0 0 0 3px rgba(var(--brand-rgb), .12);
}
.sx-input::placeholder,
.sx-textarea::placeholder {
  /* v1.22 — rgba(255,255,255,.34) composited to rgb(107,110,114) on the field
     wash = 3.32:1. --mt gives 6.07:1 and still reads as a hint, not a value. */
  color: var(--mt);
  opacity: 1;
}
.sx-input:disabled,
.sx-textarea:disabled,
.sx-select:disabled {
  opacity: .5;
  cursor: not-allowed;
}
.sx-input[readonly] {
  background: rgba(255, 255, 255, .02);
  color: var(--mt);
}
.sx-select {
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'><path fill='%23888' d='M6 9L1 4h10z'/></svg>");
  background-repeat: no-repeat;
  background-position: right 14px center;
  padding-right: 36px;
}
.sx-select option {
  background: #1a1f2e;
  color: #fff;
}
.sx-input[type="number"]::-webkit-outer-spin-button,
.sx-input[type="number"]::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.sx-input[type="number"] { -moz-appearance: textfield; }

/* Light theme variant for any portal that opts into a light form background */
.sx-input.light,
.sx-textarea.light,
.sx-select.light {
  background: #fff;
  border-color: rgba(0, 0, 0, .15);
  color: #0f172a;
}
/* v1.22 — .4 alpha composited to rgb(159,162,168) on #fff = 2.55:1; .62 gives
   rgb(106,111,123) = 5.03:1. */
.sx-input.light::placeholder,
.sx-textarea.light::placeholder { color: rgba(15, 23, 42, .62); }

/* Datalist/autofill guard against browser-default white text on white bg */
input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus,
textarea:-webkit-autofill,
select:-webkit-autofill {
  -webkit-box-shadow: 0 0 0 1000px rgba(14, 20, 33, .95) inset !important;
  -webkit-text-fill-color: var(--tx) !important;
  caret-color: var(--tx);
}

::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: var(--s1); }
::-webkit-scrollbar-thumb { background: var(--s4); border-radius: 5px; border: 2px solid var(--s1); }
::-webkit-scrollbar-thumb:hover { background: var(--s5); }

::selection { background: var(--cy4); color: #fff; }

/* ---- animated background orbs ---- */
.sx-bg-orbs { position: fixed; inset: 0; pointer-events: none; overflow: hidden; z-index: 0; }
.sx-orb { position: absolute; border-radius: 50%; filter: blur(80px); opacity: .22; animation: sxOrbFloat 14s ease-in-out infinite; }
.sx-orb-1 { width: 500px; height: 500px; background: radial-gradient(circle, var(--cy), transparent); top: -100px; left: -100px; animation-duration: 16s; }
.sx-orb-2 { width: 400px; height: 400px; background: radial-gradient(circle, var(--gr), transparent); bottom: -80px; right: -80px; animation-duration: 20s; animation-delay: -6s; }
.sx-orb-3 { width: 300px; height: 300px; background: radial-gradient(circle, #0a4a8a, transparent); top: 40%; left: 50%; animation-duration: 24s; animation-delay: -3s; }
@keyframes sxOrbFloat {
  0%, 100% { transform: translateY(0) scale(1); }
  50%      { transform: translateY(-40px) scale(1.08); }
}

.sx-grid-bg {
  position: fixed; inset: 0; pointer-events: none; z-index: 0;
  background-image: linear-gradient(rgba(var(--brand-rgb),.03) 1px, transparent 1px),
                    linear-gradient(90deg, rgba(var(--brand-rgb),.03) 1px, transparent 1px);
  background-size: 60px 60px;
}

/* ---- NAV ---- */
.sx-nav {
  position: fixed; top: 0; left: 0; right: 0; height: 64px;
  background: rgba(3,8,15,.88); backdrop-filter: blur(20px);
  border-bottom: 1px solid var(--bd);
  display: flex; align-items: center; justify-content: space-between;
  padding: 0 32px; z-index: 100;
}
.sx-nav-brand { display: flex; align-items: center; gap: 12px; }
/* v1.22 — the brand initial is TEXT, so the wide --gd-cy gradient is not
   usable: white measured 2.41:1 at the cyan stop. Solid fill + paired ink. */
.sx-logo-sq {
  width: 38px; height: 38px; border-radius: 11px;
  background: var(--fill-brand);
  display: flex; align-items: center; justify-content: center;
  font-size: 19px; font-weight: 900; color: var(--brand-on); letter-spacing: -1px;
  box-shadow: 0 4px 16px rgba(var(--brand-rgb),.4);
}
.sx-nav-brand-tx { font-size: 16px; font-weight: 800; color: var(--tx); }
/* raw brand hue as text = 3.49:1 on Tolaram red, 1.37:1 on Tolaram navy */
.sx-nav-brand-tx span { color: var(--brand-ink); }
.sx-nav-sub { font-size: 10px; color: var(--mt); margin-top: 2px; letter-spacing: .3px; }
.sx-nav-right { display: flex; align-items: center; gap: 14px; }
.sx-nav-live {
  display: flex; align-items: center; gap: 7px;
  background: rgba(48,209,88,.08); border: 1px solid rgba(48,209,88,.22);
  border-radius: 20px; padding: 5px 12px;
  font-size: 11px; font-weight: 700; color: var(--ok);
}
.sx-nav-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--ok); animation: sxBlink 2s ease-in-out infinite; }
@keyframes sxBlink { 0%,100% {opacity:1} 50% {opacity:.3} }

/* ---- Sync status pill ---- */
.sx-sync-pill {
  display: flex; align-items: center; gap: 7px;
  border-radius: 20px; padding: 5px 12px;
  font-size: 11px; font-weight: 700; letter-spacing: .3px;
  cursor: pointer; transition: all var(--t-fast);
  background: rgba(128,144,170,.08); border: 1px solid rgba(128,144,170,.22); color: var(--mt);
}
.sx-sync-pill:hover { filter: brightness(1.18); }
.sx-sync-pill .sx-sync-dot {
  width: 6px; height: 6px; border-radius: 50%; background: currentColor;
}
.sx-sync-pill.sx-sync-connected {
  background: rgba(48,209,88,.08); border-color: rgba(48,209,88,.22); color: var(--ok);
}
.sx-sync-pill.sx-sync-connected .sx-sync-dot { animation: sxBlink 2s ease-in-out infinite; }
.sx-sync-pill.sx-sync-connecting {
  background: rgba(255,193,7,.10); border-color: rgba(255,193,7,.25); color: #ffc107;
}
.sx-sync-pill.sx-sync-connecting .sx-sync-dot { animation: sxBlink 1s ease-in-out infinite; }
.sx-sync-pill.sx-sync-error {
  background: rgba(255,69,58,.10); border-color: rgba(255,69,58,.28); color: var(--bad);
}
.sx-sync-pill.sx-sync-disconnected {
  background: rgba(128,144,170,.08); border-color: rgba(128,144,170,.22); color: var(--mt);
}
.sx-sync-menu {
  position: fixed; z-index: 1200;
  background: var(--s1); border: 1px solid var(--bd); border-radius: 14px;
  padding: 16px; min-width: 320px;
  box-shadow: 0 24px 64px rgba(0,0,0,.6);
  color: var(--tx);
}
.sx-sync-menu h4 { font-size: 13px; font-weight: 800; margin: 0 0 10px; color: var(--brand-ink); }
.sx-sync-menu .sx-sync-info { font-size: 11px; color: var(--mt); margin-bottom: 12px; line-height: 1.6; }
.sx-sync-menu .sx-sync-info b { color: var(--tx); }
.sx-sync-menu input[type=text] {
  width: 100%; padding: 8px 10px; font-size: 12px;
  background: var(--s0); border: 1px solid var(--bd); border-radius: 8px;
  color: var(--tx); margin-bottom: 8px;
}
.sx-sync-menu .sx-sync-actions { display: flex; gap: 8px; }
.sx-sync-menu button {
  flex: 1; padding: 7px 12px; border-radius: 8px;
  font-size: 11px; font-weight: 700; cursor: pointer;
  border: 1px solid var(--bd); background: var(--s0); color: var(--tx);
  transition: all var(--t-fast);
}
.sx-sync-menu button.primary { background: var(--fill-brand); border-color: transparent; color: var(--brand-on); }
.sx-sync-menu button:hover { filter: brightness(1.2); }
.sx-nav-btn {
  padding: 9px 20px; border-radius: 10px;
  font-size: 13px; font-weight: 700;
  /* v1.22 — was --gd-cy + #fff: 2.41:1 at the cyan stop, 2.17:1 for dark ink
     at the navy stop, so NO ink cleared AA across the gradient. */
  background: var(--fill-brand); color: var(--brand-on);
  transition: all var(--t-fast);
}
.sx-nav-btn:hover { box-shadow: var(--sh-cy); transform: translateY(-1px); }
.sx-nav-ghost {
  padding: 8px 16px; border-radius: 10px;
  font-size: 12px; font-weight: 700;
  background: transparent; color: var(--mt);
  border: 1px solid var(--bd);
  transition: all var(--t-fast);
}
.sx-nav-ghost:hover { color: var(--brand-ink); border-color: var(--bd2); }

/* ---- User chip ---- */
.sx-user-chip {
  display: flex; align-items: center; gap: 10px;
  background: var(--s1); border: 1px solid var(--bd);
  border-radius: 20px; padding: 4px 14px 4px 4px;
  cursor: pointer; transition: all var(--t-fast);
}
.sx-user-chip:hover { border-color: var(--bd2); }
.sx-user-av {
  width: 30px; height: 30px; border-radius: 50%;
  /* v1.22 — initials are text: gradient + #fff measured 2.41:1 at the light stop */
  background: var(--fill-brand);
  display: flex; align-items: center; justify-content: center;
  font-size: 12px; font-weight: 800; color: var(--brand-on);
}
.sx-user-name { font-size: 12px; font-weight: 700; color: var(--tx); }
.sx-user-role { font-size: 10px; color: var(--mt); }
.sx-user-menu {
  position: absolute; top: 64px; right: 32px;
  background: var(--s1); border: 1px solid var(--bd2);
  border-radius: 14px; padding: 8px;
  box-shadow: var(--sh3);
  min-width: 220px; z-index: 200;
  display: none;
}
.sx-user-menu.open { display: block; animation: sxFadeIn .2s ease; }
.sx-user-menu a, .sx-user-menu button {
  display: block; width: 100%; text-align: left;
  padding: 10px 14px; border-radius: 10px;
  font-size: 13px; color: var(--tx2); font-weight: 600;
  transition: all var(--t-fast);
}
.sx-user-menu a:hover, .sx-user-menu button:hover { background: var(--s3); color: var(--brand-ink); }
.sx-user-menu .sx-menu-danger:hover { background: rgba(255,69,58,.1); color: var(--er); }
.sx-user-menu hr { border: 0; border-top: 1px solid var(--bd); margin: 6px 0; }

/* ---- Cards ---- */
.sx-card {
  background: var(--s1); border: 1px solid var(--bd);
  border-radius: var(--r-lg); padding: 22px;
  transition: all var(--t-mid);
}
.sx-card-hover:hover { border-color: var(--bd2); transform: translateY(-2px); box-shadow: var(--sh2); }
.sx-card-title { font-size: 13px; font-weight: 700; color: var(--tx); display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; }
.sx-card-sub { font-size: 11px; color: var(--mt); }

/* ---- Buttons ---- */
.sx-btn {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 11px 20px; border-radius: 11px;
  font-size: 13px; font-weight: 700;
  /* v1.22 — label text: --gd-cy spanned cyan->navy, where white read 2.41:1
     and dark ink 2.17:1. Solid brand fill + its paired ink instead. */
  background: var(--fill-brand); color: var(--brand-on);
  transition: all var(--t-fast);
  white-space: nowrap;
}
.sx-btn:hover { box-shadow: var(--sh-cy); transform: translateY(-1px); }
.sx-btn:disabled { opacity: .5; cursor: not-allowed; }
.sx-btn-ghost {
  background: transparent; color: var(--mt);
  border: 1.5px solid var(--bd);
}
.sx-btn-ghost:hover { color: var(--brand-ink); border-color: var(--bd2); box-shadow: none; transform: none; }
/* v1.22 — status buttons are FIXED vivid fills, so they take the dark ink
   (white was 2.02 / 3.41 / 2.06 on their light stops). Each dark stop was
   lifted until the dark ink also clears 4.6:1 there:
     #1e8e3e 4.59 -> #219A42 5.30 · #b71818 2.90 -> #DE5744 5.11
     #b06b00 4.55 -> #C27A08 5.59 */
.sx-btn-ok { background: linear-gradient(135deg, #30d158, #219A42); color: var(--on-fill); }
.sx-btn-er { background: linear-gradient(135deg, #ff453a, #DE5744); color: var(--on-fill); }
.sx-btn-wa { background: linear-gradient(135deg, #ff9f0a, #C27A08); color: var(--on-fill); }
.sx-btn-sm { padding: 7px 14px; font-size: 11px; }

/* ---- Forms ---- */
.sx-field { margin-bottom: 14px; }
.sx-field label {
  display: block; font-size: 10px; font-weight: 700;
  color: var(--mt); text-transform: uppercase;
  letter-spacing: .5px; margin-bottom: 6px;
}
.sx-field input, .sx-field select, .sx-field textarea {
  width: 100%; background: var(--s2);
  border: 1.5px solid var(--bd); border-radius: 10px;
  padding: 12px 14px;
  /* v1.3.9.6 — 16px font-size prevents iOS Safari from auto-zooming on focus. */
  font-size: 16px; color: var(--tx);
  outline: none; transition: border-color var(--t-fast);
}
/* v1.3.9.6 — minimum tap-target sizes per HIG / Material guidelines */
.sx-btn { min-height: 44px; }
.sx-btn-sm { min-height: 36px; }
.sx-field input:focus, .sx-field select:focus, .sx-field textarea:focus { border-color: var(--cy); }
.sx-field textarea { resize: vertical; min-height: 88px; }

/* ---- Badges / pills ---- */
.sx-badge {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 9px; border-radius: 8px;
  font-size: 10px; font-weight: 700;
  background: var(--s3); color: var(--mt);
  border: 1px solid var(--bd);
}
.sx-badge-ok { background: rgba(48,209,88,.12); color: var(--ok); border-color: rgba(48,209,88,.25); }
.sx-badge-wa { background: rgba(255,159,10,.12); color: var(--wa); border-color: rgba(255,159,10,.25); }
.sx-badge-er { background: rgba(255,69,58,.12); color: var(--er); border-color: rgba(255,69,58,.25); }
.sx-badge-in { background: var(--cy3); color: var(--brand-ink); border-color: var(--bd2); }
.sx-badge-pu { background: rgba(123,104,238,.12); color: #b8a7ff; border-color: rgba(123,104,238,.3); }

/* ---- Stat cell ---- */
.sx-stat { text-align: center; padding: 12px; }
/* v1.22 — brand hues as TEXT: raw --cy is 3.49:1 on Tolaram red, raw --gr is
   1.37:1 on Tolaram's navy accent. The pre-lightened inks clear 4.6:1. */
.sx-stat-val { font-size: 32px; font-weight: 900; color: var(--brand-ink); line-height: 1; }
.sx-stat-val.gr { color: var(--accent-ink, var(--brand-ink)); }
.sx-stat-val.or { color: var(--or); }
.sx-stat-lbl { font-size: 11px; color: var(--mt); margin-top: 6px; font-weight: 600; text-transform: uppercase; letter-spacing: .4px; }

/* ---- Table ---- */
.sx-table { width: 100%; border-collapse: collapse; }
.sx-table th {
  text-align: left; padding: 12px 14px;
  font-size: 10px; font-weight: 700; color: var(--mt);
  text-transform: uppercase; letter-spacing: .5px;
  border-bottom: 1px solid var(--bd);
}
.sx-table td {
  padding: 14px 14px; font-size: 13px; color: var(--tx2);
  border-bottom: 1px solid var(--bd);
}
.sx-table tr:hover td { background: var(--s2); }
.sx-table tr:last-child td { border-bottom: 0; }

/* ---- Empty states ---- */
.sx-empty {
  padding: 60px 24px; text-align: center;
}
.sx-empty-icon { font-size: 48px; opacity: .4; margin-bottom: 12px; }
.sx-empty-title { font-size: 15px; font-weight: 700; color: var(--tx2); margin-bottom: 4px; }
.sx-empty-sub { font-size: 12px; color: var(--mt); }

/* ---- Modal / overlay ---- */
.sx-modal-backdrop {
  position: fixed; inset: 0; background: rgba(3,8,15,.85);
  backdrop-filter: blur(12px); z-index: 9999;
  display: flex; align-items: center; justify-content: center;
  padding: 24px; animation: sxFadeIn .2s ease;
}
.sx-modal {
  background: var(--s1); border: 1px solid var(--bd2);
  border-radius: 22px; padding: 32px;
  max-width: 520px; width: 100%; max-height: 92vh; overflow-y: auto;
  box-shadow: var(--sh3); animation: sxModalIn .3s cubic-bezier(.4,0,.2,1);
}
.sx-modal-title {
  font-size: 20px; font-weight: 800; color: var(--tx);
  margin-bottom: 6px;
}
.sx-modal-sub {
  font-size: 13px; color: var(--mt); margin-bottom: 20px;
}
@keyframes sxModalIn {
  from { opacity: 0; transform: translateY(20px) scale(.96); }
  to   { opacity: 1; transform: none; }
}
@keyframes sxFadeIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* ---- Tabs ---- */
.sx-tabs { display: flex; gap: 4px; border-bottom: 1px solid var(--bd); margin-bottom: 20px; }
.sx-tab {
  padding: 12px 18px; font-size: 12px; font-weight: 700;
  color: var(--mt); border-bottom: 2px solid transparent;
  transition: all var(--t-fast); cursor: pointer;
}
.sx-tab:hover { color: var(--tx2); }
.sx-tab.active { color: var(--brand-ink); border-bottom-color: var(--cy); }

/* ---- Grids ---- */
.sx-grid { display: grid; gap: 18px; }
.sx-grid-2 { grid-template-columns: repeat(2, 1fr); }
.sx-grid-3 { grid-template-columns: repeat(3, 1fr); }
.sx-grid-4 { grid-template-columns: repeat(4, 1fr); }
@media (max-width: 900px) {
  .sx-grid-3, .sx-grid-4 { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 600px) {
  .sx-grid-2, .sx-grid-3, .sx-grid-4 { grid-template-columns: 1fr; }
}

/* ---- Progress bar ---- */
.sx-bar {
  height: 6px; background: var(--s3); border-radius: 3px; overflow: hidden;
}
.sx-bar-fill {
  height: 100%; background: var(--gd-cy); border-radius: 3px;
  transition: width .6s cubic-bezier(.4,0,.2,1);
}

/* ---- Toast (shared) ---- */
#sx-toast { font-family: inherit; }

/* ---- Auth overlay (shared) ---- */
#sx-auth {
  position: fixed; inset: 0;
  background: rgba(3,8,15,.97); backdrop-filter: blur(32px);
  z-index: 9999; display: flex; align-items: center; justify-content: center;
  padding: 24px; transition: opacity .3s;
}
#sx-auth.hidden { opacity: 0; pointer-events: none; }
.sx-auth-box {
  background: var(--s1); border: 1px solid var(--bd2);
  border-radius: 24px; padding: 36px 38px;
  width: 100%; max-width: 430px;
  box-shadow: 0 40px 120px rgba(0,0,0,.6), 0 0 60px rgba(var(--brand-rgb),.08);
  animation: sxModalIn .4s cubic-bezier(.4,0,.2,1);
}
/* v1.5.4 — On phones / touch devices / the native app, the login fills the
   whole screen instead of floating as a narrow centred card (which read as
   "slim / not fitting"). Edge-to-edge, content vertically centred, safe-area
   aware, scrollable if the keyboard shrinks the viewport. */
@media (max-width: 540px), (pointer: coarse) {
  #sx-auth { padding: 0; align-items: stretch; }
  .sx-auth-box {
    max-width: none; width: 100%;
    min-height: 100vh; min-height: 100dvh;
    border-radius: 0; border: 0; box-shadow: none;
    display: flex; flex-direction: column; justify-content: center;
    padding: calc(34px + env(safe-area-inset-top, 0px)) 22px calc(34px + env(safe-area-inset-bottom, 0px));
    overflow-y: auto;
  }
}
html.sx-native #sx-auth { padding: 0; align-items: stretch; }
html.sx-native .sx-auth-box {
  max-width: none; width: 100%;
  min-height: 100vh; min-height: 100dvh;
  border-radius: 0; border: 0; box-shadow: none;
  display: flex; flex-direction: column; justify-content: center;
  padding: calc(34px + env(safe-area-inset-top, 0px)) 22px calc(34px + env(safe-area-inset-bottom, 0px));
  overflow-y: auto;
}
/* v1.5.7 — PIN show/hide toggle */
.sx-pin-wrap { position: relative; display: block; }
.sx-pin-wrap input { width: 100%; padding-right: 46px; }
.sx-pin-eye {
  position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
  background: none; border: 0; cursor: pointer; padding: 8px;
  font-size: 18px; line-height: 1; opacity: .75; border-radius: 8px;
  transition: opacity .15s, background .15s; -webkit-tap-highlight-color: transparent;
}
.sx-pin-eye:hover { opacity: 1; background: rgba(255,255,255,.06); }
.sx-pin-eye:active { transform: translateY(-50%) scale(.92); }
/* v1.5.8 — Naira money-bag icon (replaces the 💰 emoji whose glyph bakes in a "$").
   Sized in em so it scales to whatever container font-size it sits in. */
.sx-bag-ic { display: inline-block; width: 1.12em; height: 1.12em; vertical-align: -0.2em; object-fit: contain; }
.sx-mod-ic .sx-bag-ic { width: 1em; height: 1em; vertical-align: middle; }
.sx-auth-logo {
  display: flex; align-items: center; gap: 12px;
  margin-bottom: 22px;
}
.sx-auth-s {
  width: 46px; height: 46px; border-radius: 13px;
  /* v1.22 — carries the brand initial; gradient + #fff was 2.41:1 */
  background: var(--fill-brand);
  display: flex; align-items: center; justify-content: center;
  font-size: 22px; font-weight: 900; color: var(--brand-on);
  box-shadow: 0 4px 20px rgba(var(--brand-rgb),.4);
}
.sx-auth-brand-name { font-size: 17px; font-weight: 800; color: var(--tx); }
.sx-auth-brand-sub  { font-size: 11px; color: var(--or2); margin-top: 2px; }
.sx-auth-hd { font-size: 22px; font-weight: 800; color: var(--tx); margin-bottom: 5px; }
.sx-auth-p  { font-size: 13px; color: var(--mt); margin-bottom: 18px; }
.sx-auth-demo {
  margin-top: 20px; padding-top: 18px; border-top: 1px solid var(--bd);
}
.sx-auth-demo-title {
  font-size: 10px; font-weight: 700; color: var(--mt);
  text-transform: uppercase; letter-spacing: .6px; margin-bottom: 10px;
}
.sx-auth-demo-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.sx-auth-demo-card {
  padding: 10px 12px; background: var(--s2);
  border: 1px solid var(--bd); border-radius: 10px;
  cursor: pointer; transition: all var(--t-fast);
  text-align: left;
}
.sx-auth-demo-card:hover { border-color: var(--cy); background: var(--s3); }
.sx-auth-demo-n { font-size: 12px; font-weight: 700; color: var(--tx); }
.sx-auth-demo-r { font-size: 10px; color: var(--mt); margin-top: 2px; }
.sx-auth-err {
  min-height: 20px; font-size: 12px; color: var(--er);
  margin-bottom: 10px; font-weight: 600; text-align: center;
}

/* ---- Utility ---- */
.sx-flex { display: flex; }
.sx-flex-center { display: flex; align-items: center; justify-content: center; }
.sx-flex-between { display: flex; align-items: center; justify-content: space-between; }
.sx-gap-4 { gap: 4px; } .sx-gap-8 { gap: 8px; } .sx-gap-12 { gap: 12px; } .sx-gap-16 { gap: 16px; } .sx-gap-24 { gap: 24px; }
.sx-mb-4 { margin-bottom: 4px; } .sx-mb-8 { margin-bottom: 8px; } .sx-mb-12 { margin-bottom: 12px; } .sx-mb-16 { margin-bottom: 16px; } .sx-mb-24 { margin-bottom: 24px; }
.sx-mt-4 { margin-top: 4px; } .sx-mt-8 { margin-top: 8px; } .sx-mt-16 { margin-top: 16px; } .sx-mt-24 { margin-top: 24px; }
.sx-hidden { display: none !important; }
.sx-muted { color: var(--mt); }
.sx-muted2 { color: var(--mt2); }
.sx-bold { font-weight: 700; }
/* v1.22 — brand/accent hues used as text take the AA-safe ink variants */
.sx-tx-cy { color: var(--brand-ink); } .sx-tx-gr { color: var(--accent-ink, var(--brand-ink)); } .sx-tx-or { color: var(--or2); }
.sx-tx-ok { color: var(--ok); } .sx-tx-er { color: var(--er); } .sx-tx-wa { color: var(--wa); }
.sx-sm { font-size: 11px; } .sx-xs { font-size: 10px; }

/* ---- Korevra powered-by badge ---- */
.sx-kor-badge {
  display: inline-flex; align-items: center; gap: 9px;
  background: rgba(232,98,42,.08);
  border: 1px solid rgba(232,98,42,.22);
  border-radius: 10px; padding: 7px 14px;
}
.sx-kor-sq { display: flex; flex-direction: column; gap: 2px; }
.sx-kor-r { display: flex; gap: 2px; }
.sx-kor-s { width: 5px; height: 5px; border-radius: 1.5px; background: var(--or); }
.sx-kor-tx { font-size: 11px; font-weight: 700; color: var(--or2); }

/* ---- Loading spinner ---- */
.sx-spin {
  display: inline-block; width: 14px; height: 14px;
  border: 2px solid var(--bd); border-top-color: var(--cy);
  border-radius: 50%; animation: sxSpin .8s linear infinite;
}
@keyframes sxSpin { to { transform: rotate(360deg); } }

/* ---- Page loader / Splash ---- */
.sx-page-loader {
  position: fixed; inset: 0; background: radial-gradient(ellipse at center, #0a1828 0%, #03080f 70%);
  display: flex; align-items: center; justify-content: center;
  flex-direction: column; gap: 8px; z-index: 10000;
  transition: opacity .4s;
}
.sx-page-loader.done { opacity: 0; pointer-events: none; }
.sx-page-loader .sx-spin { width: 32px; height: 32px; border-width: 3px; }
.sx-page-loader-tx { font-size: 12px; color: var(--mt); font-weight: 600; margin-top: 6px; }
.sx-splash-logo {
  width: 90px; height: 90px; border-radius: 26px;
  /* v1.22 — holds the 44px brand initial (.sx-splash-s), so it must be a
     solid fill: white on the cyan stop of --gd-cy measured 2.41:1. */
  background: var(--fill-brand);
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 12px 60px rgba(var(--brand-rgb),.6), 0 4px 20px rgba(var(--brand-rgb),.3);
  animation: splashPulse 2s ease-in-out infinite;
  margin-bottom: 14px;
}
.sx-splash-s {
  font-size: 44px; font-weight: 900; color: var(--brand-on); letter-spacing: -2px;
  text-shadow: 0 2px 12px rgba(0,0,0,.4);
}
.sx-splash-name { font-size: 22px; font-weight: 800; color: var(--tx); letter-spacing: -.5px; }
.sx-splash-sub  { font-size: 11px; color: var(--or2); font-weight: 600; margin-bottom: 4px; }
@keyframes splashPulse {
  0%,100% { transform: scale(1); box-shadow: 0 12px 60px rgba(var(--brand-rgb),.6); }
  50%     { transform: scale(1.04); box-shadow: 0 12px 80px rgba(var(--brand-rgb),.9); }
}

/* ---- Pills ---- */
.sx-pill {
  display: inline-block; padding: 3px 10px;
  background: var(--s3); border: 1px solid var(--bd);
  border-radius: 10px; font-size: 10px;
  color: var(--mt); font-weight: 700;
  text-transform: uppercase; letter-spacing: .4px;
}
.sx-pill-cy { background: var(--cy3); color: var(--brand-ink); border-color: var(--bd2); }
.sx-pill-gr { background: rgba(141,198,63,.12); color: var(--gr2); border-color: rgba(141,198,63,.3); }
.sx-pill-or { background: rgba(232,98,42,.1); color: var(--or2); border-color: rgba(232,98,42,.28); }
.sx-pill-ok { background: rgba(48,209,88,.12); color: var(--ok); border-color: rgba(48,209,88,.3); }
.sx-pill-wa { background: rgba(255,159,10,.12); color: var(--wa); border-color: rgba(255,159,10,.3); }
.sx-pill-er { background: rgba(255,69,58,.12); color: var(--er); border-color: rgba(255,69,58,.3); }

/* ---- Button variants ---- */
.sx-btn-full { width: 100%; justify-content: center; padding: 13px; font-size: 14px; }

/* ---- Auth multi-view ---- */
.sx-auth-views { min-height: 340px; position: relative; }
.sx-auth-view { display: none; }
.sx-auth-view.active { display: block; animation: sxFadeIn .2s ease; }
.sx-auth-link {
  font-size: 12px; color: var(--brand-ink); font-weight: 700;
  display: inline-block; cursor: pointer;
}
.sx-auth-link:hover { text-decoration: underline; }
.sx-auth-or {
  position: relative; text-align: center; margin: 18px 0 12px;
  font-size: 11px; color: var(--mt);
}
.sx-auth-or::before, .sx-auth-or::after {
  content: ''; position: absolute; top: 50%; width: 40%;
  height: 1px; background: var(--bd);
}
.sx-auth-or::before { left: 0; }
.sx-auth-or::after  { right: 0; }
.sx-auth-or span { background: var(--s1); padding: 0 12px; position: relative; }

/* ============================================================================
 * v2.0.0 — ORG STEP (universal app, sign-in step 1 of 2)
 * ----------------------------------------------------------------------------
 * Every colour here is a TOKEN, never a literal. The universal app repaints
 * --brand-* at runtime from an organisation it may never have seen before, so
 * anything hardcoded would be correct for exactly one customer. Text colours
 * are --tx / --mt (fixed, audited against --s1) and brand colour appears only
 * as a fill or a border, never as small text — --brand-ink is the token for
 * that, and it is the one the engine pre-lightens to clear 5.2:1.
 * ==========================================================================*/

/* Live match preview — appears under the field as soon as the typed domain
   resolves, so the user sees their own company before committing. */
.sx-org-preview {
  display: flex; align-items: center; gap: 9px;
  margin: -6px 0 14px;
  padding: 9px 12px;
  border: 1px solid var(--bd);
  border-radius: 11px;
  background: rgba(var(--brand-rgb), .07);
  animation: sxBrandIn .18s ease;
}
.sx-org-preview[hidden] { display: none; }

/* The brand swatch. --fill-brand (not --brand-primary) because the engine
   nudges that one clear of the mid-tone dead zone; a 10px dot beside text
   is decorative, but keeping the two in step avoids a visible mismatch
   against the chips the same colour fills elsewhere. */
.sx-org-dot {
  width: 10px; height: 10px; border-radius: 50%;
  background: var(--fill-brand);
  flex: 0 0 auto;
  box-shadow: 0 0 0 3px rgba(var(--brand-rgb), .18);
}
.sx-org-nm   { font-size: 13px; font-weight: 700; color: var(--tx); flex: 1 1 auto; }
.sx-org-tick { font-size: 11px; font-weight: 700; color: var(--brand-ink); }

/* Previously-used organisations — one tap instead of retyping an email. */
.sx-org-known { display: flex; flex-wrap: wrap; gap: 8px; }
.sx-org-chip {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 9px 13px;
  border: 1px solid var(--bd);
  border-radius: 999px;
  background: var(--s2);
  color: var(--tx);
  font-size: 12px; font-weight: 700;
  font-family: inherit;
  cursor: pointer;
  /* 44px is the WCAG 2.5.5 / iOS HIG minimum touch target. These sit close
     together on a phone and are the fastest path for a returning user, so
     they must not be the thing that is hard to hit. */
  min-height: 44px;
}
.sx-org-chip:hover  { border-color: rgba(var(--brand-rgb), .45); background: var(--s3); }
.sx-org-chip:focus-visible {
  outline: 2px solid var(--brand-ink);
  outline-offset: 2px;
}

.sx-org-foot {
  margin-top: 18px;
  font-size: 11px; line-height: 1.55;
  color: var(--mt);
  text-align: center;
}


/* ---- Sheet (mobile bottom sheet) ---- */
.sx-sheet-backdrop {
  position: fixed; inset: 0;
  background: rgba(3,8,15,.75); backdrop-filter: blur(8px);
  z-index: 9998; opacity: 0; transition: opacity .25s;
  display: flex; align-items: flex-end; justify-content: center;
}
.sx-sheet-backdrop.open { opacity: 1; }
.sx-sheet {
  background: var(--s1); border: 1px solid var(--bd2);
  border-radius: 24px 24px 0 0;
  width: 100%; max-width: 720px;
  padding: 10px 24px 32px;
  max-height: 88vh; overflow-y: auto;
  transform: translateY(100%); transition: transform .3s cubic-bezier(.4,0,.2,1);
  box-shadow: 0 -24px 80px rgba(0,0,0,.5);
}
.sx-sheet-backdrop.open .sx-sheet { transform: translateY(0); }
.sx-sheet-grab {
  width: 40px; height: 4px; border-radius: 2px;
  background: var(--bd2); margin: 0 auto 12px;
}
.sx-sheet-head {
  display: flex; justify-content: space-between; align-items: start;
  padding-bottom: 16px; margin-bottom: 16px;
  border-bottom: 1px solid var(--bd);
}
.sx-sheet-title { font-size: 18px; font-weight: 800; color: var(--tx); }
.sx-sheet-sub { font-size: 12px; color: var(--mt); margin-top: 4px; }
.sx-sheet-x {
  width: 32px; height: 32px; border-radius: 50%;
  background: var(--s3); border: 1px solid var(--bd);
  color: var(--mt); font-size: 13px; font-weight: 700;
  display: flex; align-items: center; justify-content: center;
}

/* ---- Notification bell + panel ---- */
.sx-nav-bell {
  position: relative; width: 38px; height: 38px; border-radius: 11px;
  background: var(--s2); border: 1px solid var(--bd);
  display: flex; align-items: center; justify-content: center;
  font-size: 15px; transition: all var(--t-fast);
}
.sx-nav-bell:hover { background: var(--s3); border-color: var(--bd2); }
.sx-nav-bell-dot {
  position: absolute; top: -4px; right: -4px;
  /* v1.21 — white on --er (#FF6B6B) measured 2.78:1. Dark ink clears 6.96:1
     and keeps the alert red just as loud. */
  background: var(--er); color: var(--on-fill, #0B0E14);
  min-width: 18px; height: 18px; padding: 0 5px;
  border-radius: 9px; display: none;
  font-size: 10px; font-weight: 800;
  align-items: center; justify-content: center;
  border: 2px solid var(--s1);
}
.sx-nav-bell-dot[style*="block"] { display: flex !important; }
.sx-nt-panel {
  position: fixed; top: 72px; right: 24px;
  background: var(--s1); border: 1px solid var(--bd2);
  border-radius: 16px; padding: 0;
  min-width: 340px; max-width: 400px; max-height: 560px;
  box-shadow: var(--sh3); z-index: 200;
  overflow: hidden; display: flex; flex-direction: column;
  animation: sxModalIn .2s ease;
}
.sx-nt-head {
  padding: 14px 16px; border-bottom: 1px solid var(--bd);
  display: flex; justify-content: space-between; align-items: center;
}
.sx-nt-title { font-size: 14px; font-weight: 800; color: var(--tx); }
.sx-nt-list { overflow-y: auto; flex: 1; }
.sx-nt-item {
  display: flex; gap: 10px; padding: 12px 16px;
  border-bottom: 1px solid var(--bd);
  transition: background var(--t-fast);
}
.sx-nt-item:hover { background: var(--s2); }
.sx-nt-item.unread { background: rgba(var(--brand-rgb),.04); }
.sx-nt-dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--cy); margin-top: 6px; flex-shrink: 0;
  box-shadow: 0 0 8px rgba(var(--brand-rgb),.5);
}
.sx-nt-item:not(.unread) .sx-nt-dot { background: var(--mt2); box-shadow: none; }
.sx-nt-t { font-size: 13px; font-weight: 700; color: var(--tx); }
.sx-nt-b { font-size: 11px; color: var(--mt); margin-top: 3px; line-height: 1.5; }
.sx-nt-at { font-size: 10px; color: var(--mt2); margin-top: 4px; }

/* ---- Toast stack ---- */
.sx-toast-stack {
  position: fixed; top: 80px; right: 24px;
  display: flex; flex-direction: column; gap: 8px;
  z-index: 10001; pointer-events: none;
}
.sx-toast {
  display: flex; align-items: center; gap: 12px;
  background: var(--s1); border: 1px solid var(--bd2);
  border-radius: 12px; padding: 12px 16px;
  min-width: 280px; max-width: 380px;
  box-shadow: var(--sh2);
  transform: translateX(120%); transition: transform .3s cubic-bezier(.4,0,.2,1);
  pointer-events: auto;
}
.sx-toast.show { transform: translateX(0); }
.sx-toast-icon {
  width: 28px; height: 28px; border-radius: 50%;
  background: var(--cy3); color: var(--brand-ink);
  display: flex; align-items: center; justify-content: center;
  font-size: 14px; font-weight: 800;
  flex-shrink: 0;
}
.sx-toast-success .sx-toast-icon { background: rgba(48,209,88,.15); color: var(--ok); }
.sx-toast-error .sx-toast-icon   { background: rgba(255,69,58,.15); color: var(--er); }
.sx-toast-warn .sx-toast-icon    { background: rgba(255,159,10,.15); color: var(--wa); }
.sx-toast-title { font-size: 12px; font-weight: 800; color: var(--tx); margin-bottom: 2px; }
.sx-toast-msg { font-size: 12px; color: var(--tx2); }

/* ---- Avatar circle ---- */
.sx-av {
  width: 38px; height: 38px; border-radius: 50%;
  /* v1.22 — avatar initials are text; gradient + #fff measured 2.41:1 */
  background: var(--fill-brand); color: var(--brand-on);
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 13px; font-weight: 800;
  flex-shrink: 0;
}
.sx-av-sm { width: 28px; height: 28px; font-size: 11px; }
.sx-av-lg { width: 56px; height: 56px; font-size: 18px; }

/* ---- Chip ---- */
.sx-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 12px; background: var(--s2);
  border: 1px solid var(--bd); border-radius: 20px;
  font-size: 11px; color: var(--tx2); font-weight: 600;
  cursor: pointer; transition: all var(--t-fast);
}
.sx-chip:hover { border-color: var(--bd2); background: var(--s3); }
.sx-chip.active { background: var(--cy3); color: var(--brand-ink); border-color: var(--bd2); }

/* ---- Segmented control ---- */
.sx-seg {
  display: flex; background: var(--s2);
  border: 1px solid var(--bd); border-radius: 10px;
  padding: 3px; gap: 3px;
}
.sx-seg button {
  padding: 8px 14px; font-size: 11px; font-weight: 700;
  color: var(--mt); border-radius: 7px; transition: all var(--t-fast);
}
/* v1.22 — solid brand fill carrying a label: #fff was 2.41:1 on Spectrum cyan */
.sx-seg button.active { background: var(--fill-brand); color: var(--brand-on); }
.sx-seg button:hover:not(.active) { color: var(--tx2); }

/* ---- Stepper ---- */
.sx-stepper {
  display: flex; gap: 4px; margin-bottom: 18px;
}
.sx-stepper-s {
  flex: 1; height: 4px; border-radius: 2px;
  background: var(--bd); transition: background .3s;
}
.sx-stepper-s.done { background: var(--cy); }

/* ---- Module tile (mobile grid) ---- */
.sx-module {
  background: var(--s2); border: 1px solid var(--bd);
  border-radius: 18px; padding: 20px 12px;
  display: flex; flex-direction: column; align-items: center;
  gap: 10px; cursor: pointer;
  transition: all var(--t-fast);
  position: relative;
}
.sx-module:hover { border-color: var(--bd2); background: var(--s3); transform: translateY(-2px); }
.sx-module-icon { font-size: 32px; }
.sx-module-name { font-size: 13px; font-weight: 700; color: var(--tx); text-align: center; }
.sx-module-badge {
  position: absolute; top: 8px; right: 8px;
  /* v1.22 — white on --er (#FF6B6B) measured 2.78:1; dark ink clears 6.96:1 */
  background: var(--er); color: var(--on-fill);
  min-width: 20px; height: 20px; padding: 0 6px;
  border-radius: 10px;
  font-size: 10px; font-weight: 800;
  display: flex; align-items: center; justify-content: center;
  border: 2px solid var(--s2);
}

/* ---- Activity item ---- */
.sx-act {
  display: flex; gap: 12px; padding: 14px 0;
  border-bottom: 1px solid var(--bd);
}
.sx-act:last-child { border-bottom: 0; }
.sx-act-ic {
  width: 38px; height: 38px; border-radius: 11px;
  background: var(--cy3); color: var(--brand-ink);
  display: flex; align-items: center; justify-content: center;
  font-size: 16px; flex-shrink: 0;
}
.sx-act-t { font-size: 13px; font-weight: 700; color: var(--tx); }
.sx-act-s { font-size: 11px; color: var(--mt); margin-top: 2px; }
.sx-act-at { font-size: 10px; color: var(--mt2); margin-top: 4px; }

/* ---- Progress ring ---- */
.sx-ring {
  position: relative; width: 72px; height: 72px;
}
.sx-ring svg { transform: rotate(-90deg); }
.sx-ring circle { fill: none; stroke-width: 6; }
.sx-ring-bg { stroke: var(--s3); }
.sx-ring-fg { stroke: var(--cy); transition: stroke-dashoffset 1s cubic-bezier(.4,0,.2,1); }
.sx-ring-val {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  font-size: 18px; font-weight: 900; color: var(--brand-ink);
}

/* ---- KPI progress bar (horizontal) ---- */
.sx-kpi-row { display: flex; align-items: center; gap: 12px; margin-bottom: 14px; }
.sx-kpi-row:last-child { margin-bottom: 0; }
.sx-kpi-label { font-size: 12px; color: var(--tx2); min-width: 140px; font-weight: 600; }
.sx-kpi-bar-wrap { flex: 1; height: 8px; background: var(--s3); border-radius: 4px; overflow: hidden; }
.sx-kpi-bar-fill { height: 100%; background: var(--gd-cy); border-radius: 4px; transition: width .8s ease; }
.sx-kpi-score { font-size: 13px; font-weight: 800; color: var(--brand-ink); min-width: 42px; text-align: right; }

/* ---- Module icon tint variants ---- */
.sx-module.cy .sx-module-icon { filter: drop-shadow(0 2px 12px rgba(var(--brand-rgb),.5)); }
.sx-module.gr .sx-module-icon { filter: drop-shadow(0 2px 12px rgba(141,198,63,.5)); }
.sx-module.or .sx-module-icon { filter: drop-shadow(0 2px 12px rgba(232,98,42,.5)); }

/* ---- Responsive overrides ---- */
@media (max-width: 700px) {
  .sx-nav { padding: 0 16px; }
  .sx-nav-sub { display: none; }
  .sx-nt-panel { right: 8px; left: 8px; min-width: auto; max-width: none; }
  .sx-toast-stack { right: 8px; left: 8px; }
  .sx-toast { min-width: auto; max-width: none; }
}

/* ===========================================================================
 * v1.20 DESIGN SYSTEM v2 — COMPONENT LAYER
 * Vibrant, colour-blocked, accessible, motion-aware. Additive: it upgrades
 * existing markup via data-attributes + utility classes, so 28 portals gain
 * the new look without being rewritten.
 * ======================================================================== */

/* ---- 1. TONE UTILITIES ---------------------------------------------------
 * One class turns any chip/badge/card into a semantic hue with a soft tint,
 * an AA-safe ink and a matching border. Replaces dozens of ad-hoc variants. */
.sx-tone-sky    { --tone-ink: var(--sky-ink);    --tone-bg: var(--sky-bg);    --tone-bd: var(--sky-bd); }
.sx-tone-mint   { --tone-ink: var(--mint-ink);   --tone-bg: var(--mint-bg);   --tone-bd: var(--mint-bd); }
.sx-tone-amber  { --tone-ink: var(--amber-ink);  --tone-bg: var(--amber-bg);  --tone-bd: var(--amber-bd); }
.sx-tone-rose   { --tone-ink: var(--rose-ink);   --tone-bg: var(--rose-bg);   --tone-bd: var(--rose-bd); }
.sx-tone-violet { --tone-ink: var(--violet-ink); --tone-bg: var(--violet-bg); --tone-bd: var(--violet-bd); }
.sx-tone-teal   { --tone-ink: var(--teal-ink);   --tone-bg: var(--teal-bg);   --tone-bd: var(--teal-bd); }
.sx-tone-coral  { --tone-ink: var(--coral-ink);  --tone-bg: var(--coral-bg);  --tone-bd: var(--coral-bd); }
.sx-tone-gold   { --tone-ink: var(--gold-ink);   --tone-bg: var(--gold-bg);   --tone-bd: var(--gold-bd); }
.sx-tone-brand  { --tone-ink: var(--brand-ink);  --tone-bg: rgba(var(--brand-rgb),.12); --tone-bd: rgba(var(--brand-rgb),.30); }
[class*="sx-tone-"] { color: var(--tone-ink); }
.sx-chip-tone {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 10px; border-radius: 999px;
  background: var(--tone-bg); border: 1px solid var(--tone-bd);
  color: var(--tone-ink); font-size: 11px; font-weight: 700;
  letter-spacing: .2px; white-space: nowrap;
}

/* ---- 2. PER-METRIC TINTED KPI CARDS --------------------------------------
 * <div class="sx-kpi" data-metric="money"> gets a mint wash, mint border,
 * mint number and a soft corner bloom — a dashboard reads as a colour-coded
 * set instead of eight identical grey boxes. */
.sx-kpi {
  --kpi-ink: var(--brand-ink);
  --kpi-bg:  rgba(var(--brand-rgb), .10);
  --kpi-bd:  rgba(var(--brand-rgb), .26);
  position: relative; overflow: hidden;
  background:
    radial-gradient(120% 130% at 100% 0%, var(--kpi-bg), transparent 62%),
    var(--s2);
  border: 1px solid var(--kpi-bd);
  border-radius: var(--r-lg);
  padding: 16px 18px;
  transition: transform var(--motion-fast) var(--ease-out),
              box-shadow var(--motion-fast) var(--ease-out),
              border-color var(--motion-fast) var(--ease-out);
}
.sx-kpi::after {
  content: ""; position: absolute; right: -30px; top: -30px;
  width: 120px; height: 120px; border-radius: 50%;
  background: radial-gradient(circle, var(--kpi-bg), transparent 70%);
  pointer-events: none;
}
.sx-kpi:hover { transform: translateY(-2px); box-shadow: var(--sh2); border-color: var(--kpi-ink); }
.sx-kpi-v  { color: var(--kpi-ink); font-size: 26px; font-weight: 800; line-height: 1.05; }
.sx-kpi-l  { color: var(--mt); font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .4px; margin-top: 6px; }
.sx-kpi-ic { color: var(--kpi-ink); }
.sx-kpi[data-metric="people"]  { --kpi-ink: var(--kpi-people-ink);  --kpi-bg: var(--kpi-people-bg);  --kpi-bd: var(--kpi-people-bd); }
.sx-kpi[data-metric="money"]   { --kpi-ink: var(--kpi-money-ink);   --kpi-bg: var(--kpi-money-bg);   --kpi-bd: var(--kpi-money-bd); }
.sx-kpi[data-metric="time"]    { --kpi-ink: var(--kpi-time-ink);    --kpi-bg: var(--kpi-time-bg);    --kpi-bd: var(--kpi-time-bd); }
.sx-kpi[data-metric="risk"]    { --kpi-ink: var(--kpi-risk-ink);    --kpi-bg: var(--kpi-risk-bg);    --kpi-bd: var(--kpi-risk-bd); }
.sx-kpi[data-metric="insight"] { --kpi-ink: var(--kpi-insight-ink); --kpi-bg: var(--kpi-insight-bg); --kpi-bd: var(--kpi-insight-bd); }
.sx-kpi[data-metric="ops"]     { --kpi-ink: var(--kpi-ops-ink);     --kpi-bg: var(--kpi-ops-bg);     --kpi-bd: var(--kpi-ops-bd); }
.sx-kpi[data-metric="sales"]   { --kpi-ink: var(--kpi-sales-ink);   --kpi-bg: var(--kpi-sales-bg);   --kpi-bd: var(--kpi-sales-bd); }
.sx-kpi[data-metric="reward"]  { --kpi-ink: var(--kpi-reward-ink);  --kpi-bg: var(--kpi-reward-bg);  --kpi-bd: var(--kpi-reward-bd); }

/* Trend arrow expresses DIRECTION, not always-green success. */
.stc-tr, .sx-trend { color: var(--mt); font-weight: 700; }
.stc-tr.up,   .sx-trend.up   { color: var(--mint-ink); }
.stc-tr.down, .sx-trend.down { color: var(--rose-ink); }
.stc-tr.flat, .sx-trend.flat { color: var(--mt); }

/* ---- 3. COLOR-BLOCKED SIDEBAR -------------------------------------------
 * Each nav section owns a hue: heading, active rail and icon share it, so
 * users navigate by colour memory instead of re-reading every label. */
.sb-sec, .sx-nav-sec {
  color: var(--sec-ink, var(--mt));
  font-size: 10px; font-weight: 800; letter-spacing: .7px;
  text-transform: uppercase; padding: 16px 18px 6px;
  display: flex; align-items: center; gap: 8px;
}
.sb-sec::before, .sx-nav-sec::before {
  content: ""; width: 14px; height: 2px; border-radius: 2px;
  background: var(--sec-ink, var(--mt)); opacity: .9;
}
[data-sec="overview"] { --sec-ink: var(--sec-overview-ink); }
[data-sec="people"]   { --sec-ink: var(--sec-people-ink); }
[data-sec="ops"]      { --sec-ink: var(--sec-ops-ink); }
[data-sec="money"]    { --sec-ink: var(--sec-money-ink); }
[data-sec="intel"]    { --sec-ink: var(--sec-intel-ink); }
[data-sec="growth"]   { --sec-ink: var(--sec-growth-ink); }
[data-sec="system"]   { --sec-ink: var(--sec-system-ink); }
[data-sec] .sb-i.active, [data-sec] .sx-nav-i.active {
  background: color-mix(in srgb, var(--sec-ink) 12%, transparent);
  border-left-color: var(--sec-ink) !important;
  color: var(--sec-ink);
}
[data-sec] .sb-i.active .sb-i-ic { color: var(--sec-ink); }

/* ---- 4. FOCUS VISIBILITY (previously 0 rules platform-wide) -------------- */
:focus-visible {
  outline: 2px solid var(--brand-ink);
  outline-offset: 2px;
  border-radius: inherit;
}
.sx-btn:focus-visible, button:focus-visible, a:focus-visible,
input:focus-visible, select:focus-visible, textarea:focus-visible {
  outline: 2px solid var(--brand-ink);
  outline-offset: 2px;
  box-shadow: 0 0 0 4px rgba(var(--brand-rgb), .22);
}
.sx-skip-link {
  position: absolute; left: -9999px; top: 8px; z-index: 10000;
  background: var(--s3); color: var(--tx); padding: 10px 16px;
  border-radius: var(--r-md); border: 1px solid var(--bd2); font-weight: 700;
}
.sx-skip-link:focus { left: 8px; }

/* ---- 5. MOTION SCALE + ONBOARDING CHOREOGRAPHY --------------------------- */
@keyframes sxFadeUp    { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
@keyframes sxPopIn     { from { opacity: 0; transform: scale(.94); }        to { opacity: 1; transform: none; } }
@keyframes sxSlideIn   { from { opacity: 0; transform: translateX(-12px); } to { opacity: 1; transform: none; } }
@keyframes sxCountPop  { 0% { transform: scale(.9); } 55% { transform: scale(1.06); } 100% { transform: scale(1); } }
@keyframes sxPulseRing { 0% { box-shadow: 0 0 0 0 rgba(var(--brand-rgb),.45); } 100% { box-shadow: 0 0 0 18px rgba(var(--brand-rgb),0); } }
@keyframes sxShimmer   { 0% { background-position: -420px 0; } 100% { background-position: 420px 0; } }

.sx-anim-in    { animation: sxFadeUp var(--motion-mid) var(--ease-out) both; }
.sx-anim-pop   { animation: sxPopIn  var(--motion-mid) var(--ease-spring) both; }
.sx-anim-slide { animation: sxSlideIn var(--motion-mid) var(--ease-out) both; }
.sx-celebrate  { animation: sxCountPop var(--motion-slow) var(--ease-spring); }
.sx-attention  { animation: sxPulseRing 1.6s var(--ease-out) infinite; }

/* Staggered entrance — the "choreography": children arrive in sequence
 * rather than snapping in as one block. */
.sx-stagger > * { animation: sxFadeUp var(--motion-mid) var(--ease-out) both; }
.sx-stagger > *:nth-child(1) { animation-delay: calc(var(--stagger) * 0); }
.sx-stagger > *:nth-child(2) { animation-delay: calc(var(--stagger) * 1); }
.sx-stagger > *:nth-child(3) { animation-delay: calc(var(--stagger) * 2); }
.sx-stagger > *:nth-child(4) { animation-delay: calc(var(--stagger) * 3); }
.sx-stagger > *:nth-child(5) { animation-delay: calc(var(--stagger) * 4); }
.sx-stagger > *:nth-child(6) { animation-delay: calc(var(--stagger) * 5); }
.sx-stagger > *:nth-child(7) { animation-delay: calc(var(--stagger) * 6); }
.sx-stagger > *:nth-child(8) { animation-delay: calc(var(--stagger) * 7); }
.sx-stagger > *:nth-child(n+9) { animation-delay: calc(var(--stagger) * 8); }

/* Skeleton loading — replaces blank screens while data resolves. */
.sx-skeleton {
  background: linear-gradient(90deg, var(--s2) 25%, var(--s3) 37%, var(--s2) 63%);
  background-size: 840px 100%;
  animation: sxShimmer 1.4s linear infinite;
  border-radius: var(--r-md); color: transparent !important;
}

/* ---- 6. REDUCED MOTION (previously absent) ------------------------------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}
