@import url("https://fonts.googleapis.com/css2?family=Instrument+Sans:ital,wght@0,400;0,500;0,600;0,700;1,400&family=IBM+Plex+Mono:wght@400;500;600&display=swap");

/* ============================================================================
   ASPAM Scottish School — Admissions CRM
   tokens.css — the complete design-token layer
   ----------------------------------------------------------------------------
   DESIGN DIRECTION — "Quiet Instrument"
   A calm, cool near-white canvas; one configurable brand hue; hairline borders
   instead of heavy chrome; type and spacing carry the hierarchy. Built to read
   as a current-generation data application, and to stay legible when a school
   swaps the brand colour for their own.

   TYPEFACES
     UI / Display  Instrument Sans  — modern grotesque, excellent at 13–15px.
     Data          IBM Plex Mono    — tabular figures for IDs, money, counts.
   Both ship a full system fallback stack.

   ----------------------------------------------------------------------------
   RUNTIME BRAND  (this is what makes the Branding screen actually work)

   The brand and accent colours are NOT literals. They are composed from
   channel tokens that JavaScript can overwrite on <html>:

     --brand-h        hue        0–360   set by theme.js from the admin's hex
     --brand-s        saturation 0–100%  set by theme.js
     --brand-l-light  lightness used when the LIGHT palette is active
     --brand-l-dark   lightness used when the DARK  palette is active
     --on-brand-light / --on-brand-dark   text colour that sits on the brand

   Each theme block below picks its own lightness:
       :root         { --brand-l: var(--brand-l-light, 46%); }
       dark blocks   { --brand-l: var(--brand-l-dark,  66%); }

   So theme.js writes FOUR values once and both themes stay coherent and
   readable — a school that picks a pale yellow gets a deep yellow on the light
   theme and a soft yellow on the dark one, never white-on-yellow. Every
   derived step (hover, active, soft wash, border, ring) is computed from those
   channels, so nothing has to be recoloured by hand.

   ----------------------------------------------------------------------------
   THEME MECHANICS (hard requirement — do not restructure)
     1. Complete LIGHT palette lives on bare  :root
     2. Dark overrides under  @media (prefers-color-scheme: dark)
        guarded as  :root:not([data-theme="light"])
     3. Dark overrides again under  :root[data-theme="dark"]
     No colour is ever defined ONLY inside a media query.

   ----------------------------------------------------------------------------
   CONTRAST — verified with tools/check_contrast.py (run it after any change).
   Body text is held to 4.5:1, large text and non-text UI to 3:1, against every
   surface the pairing can land on. The default brand clears 4.5:1 on all three
   light surfaces and all three dark surfaces; theme.js re-checks whatever the
   admin picks and warns in the Branding screen before it is saved.
   ========================================================================== */

:root {
  color-scheme: light;

  /* ------------------------------------------------------------------
     1. BRAND CHANNELS  (overwritten at runtime by theme.js)
     ------------------------------------------------------------------ */
  --brand-h: 224;
  --brand-s: 72%;
  --brand-l-light: 46%;
  --brand-l-dark:  66%;
  --on-brand-light: #FFFFFF;
  --on-brand-dark:  #08111F;

  --accent-h: 38;
  --accent-s: 92%;
  --accent-l-light: 40%;
  --accent-l-dark:  64%;
  --on-accent-light: #1F1500;
  --on-accent-dark:  #1F1500;

  /* Resolved for THIS theme */
  --brand-l:  var(--brand-l-light);
  --accent-l: var(--accent-l-light);
  --on-brand:  var(--on-brand-light);
  --on-accent: var(--on-accent-light);

  /* ------------------------------------------------------------------
     2. PRIMITIVE RAMPS  (reference these from the semantic aliases only)
     ------------------------------------------------------------------ */

  /* Cool neutrals — the canvas and the structure */
  --n-0:   #FFFFFF;
  --n-25:  #FBFCFD;
  --n-50:  #F7F8FA;
  --n-100: #F1F3F7;
  --n-150: #E8ECF2;
  --n-200: #E2E6ED;
  --n-300: #CBD3E0;
  --n-400: #9BA7BA;
  --n-500: #5D6B82;
  --n-600: #475569;
  --n-700: #334155;
  --n-800: #1E293B;
  --n-900: #0F172A;
  --n-950: #080D18;

  /* Semantic hues */
  --green-600: #047857;  --green-500: #059669;  --green-300: #4ADE9A;
  --amber-600: #B45309;  --amber-500: #D97706;  --amber-300: #FBBF4C;
  --red-600:   #C42020;  --red-500:   #E23B32;  --red-300:   #FB8983;
  --blue-600:  #0369A1;  --blue-500:  #0284C7;  --blue-300:  #6BB8F0;

  /* ------------------------------------------------------------------
     3. SURFACES
     ------------------------------------------------------------------ */
  --surface-sunken:   var(--n-100);   /* page gutter, wells, table zebra   */
  --surface:          var(--n-50);    /* app canvas                        */
  --surface-elevated: var(--n-0);     /* cards, menus, modals, drawers     */
  --surface-raised:   var(--n-25);    /* subtle lift inside a card         */
  --surface-overlay:  rgba(15, 23, 42, 0.42);
  --surface-inset:    rgba(15, 23, 42, 0.035);
  --surface-hover:    hsl(var(--brand-h) var(--brand-s) var(--brand-l) / 0.055);
  --surface-active:   hsl(var(--brand-h) var(--brand-s) var(--brand-l) / 0.11);
  --surface-selected: hsl(var(--brand-h) var(--brand-s) var(--brand-l) / 0.08);

  /* ------------------------------------------------------------------
     4. TEXT
     ------------------------------------------------------------------ */
  --text-primary:   var(--n-900);
  --text-secondary: var(--n-600);
  --text-muted:     var(--n-500);
  --text-faint:     var(--n-400);
  --text-inverse:   var(--n-0);
  --text-link:      var(--brand);
  --text-link-hover:var(--brand-hover);

  /* ------------------------------------------------------------------
     5. BORDERS & DIVIDERS
     ------------------------------------------------------------------ */
  --border-subtle: var(--n-200);
  --border-strong: var(--n-300);
  --border-brand:  var(--brand);
  --border-focus:  var(--brand);
  --divider:       var(--n-150);
  --hairline:      rgba(15, 23, 42, 0.07);

  /* ------------------------------------------------------------------
     6. BRAND & ACCENT  (all derived — never hand-edit a step)
     ------------------------------------------------------------------ */
  --brand:            hsl(var(--brand-h) var(--brand-s) var(--brand-l));
  --brand-hover:      hsl(var(--brand-h) var(--brand-s) calc(var(--brand-l) - 7%));
  --brand-active:     hsl(var(--brand-h) var(--brand-s) calc(var(--brand-l) - 13%));
  --brand-soft:       hsl(var(--brand-h) calc(var(--brand-s) * 0.62) 96%);
  --brand-soft-hover: hsl(var(--brand-h) calc(var(--brand-s) * 0.62) 92%);
  --brand-border:     hsl(var(--brand-h) calc(var(--brand-s) * 0.55) 84%);
  --brand-ink:        hsl(var(--brand-h) var(--brand-s) calc(var(--brand-l) - 6%));
  --brand-ring:       hsl(var(--brand-h) var(--brand-s) var(--brand-l) / 0.32);
  --brand-gradient:   linear-gradient(160deg,
                        hsl(var(--brand-h) calc(var(--brand-s) * 0.72) 22%) 0%,
                        hsl(var(--brand-h) calc(var(--brand-s) * 0.78) 14%) 60%,
                        hsl(var(--brand-h) calc(var(--brand-s) * 0.7) 9%) 100%);

  --accent:        hsl(var(--accent-h) var(--accent-s) var(--accent-l));
  --accent-hover:  hsl(var(--accent-h) var(--accent-s) calc(var(--accent-l) - 6%));
  --accent-soft:   hsl(var(--accent-h) calc(var(--accent-s) * 0.75) 94%);
  --accent-border: hsl(var(--accent-h) calc(var(--accent-s) * 0.6) 80%);
  --accent-ink:    hsl(var(--accent-h) var(--accent-s) calc(var(--accent-l) - 12%));
  --accent-rule:   linear-gradient(90deg, var(--accent), transparent);

  /* ------------------------------------------------------------------
     7. SEMANTIC STATES  (ink + soft wash + solid fill + border)
     ------------------------------------------------------------------ */
  --success-ink:  var(--green-600);
  --success-soft: #E7F6EF;
  --success-fill: var(--green-500);
  --success-border: #A7DCC5;

  --warning-ink:  var(--amber-600);
  --warning-soft: #FDF2E0;
  --warning-fill: var(--amber-500);
  --warning-border: #F1CE93;

  --danger-ink:   var(--red-600);
  --danger-soft:  #FCEAE8;
  --danger-fill:  var(--red-500);
  --danger-border: #F3B6B1;

  --info-ink:     var(--blue-600);
  --info-soft:    #E4F1FB;
  --info-fill:    var(--blue-500);
  --info-border:  #ADD4EE;

  --neutral-ink:   var(--n-600);
  --neutral-soft:  var(--n-100);
  --neutral-fill:  var(--n-500);
  --neutral-border:var(--n-300);

  /* Lead temperature — Hot / Warm / Cold */
  --hot-ink:  #C2410C;  --hot-soft:  #FDECE2;  --hot-border:  #F5C0A2;
  --warm-ink: var(--amber-600); --warm-soft: #FDF2E0; --warm-border: #F1CE93;
  --cold-ink: var(--blue-600);  --cold-soft: #E4F1FB; --cold-border: #ADD4EE;

  /* ------------------------------------------------------------------
     8. DATA VIZ
     Fixed hues on purpose: series colours must stay stable and
     distinguishable no matter what brand colour the school picks.
     ------------------------------------------------------------------ */
  --viz-1: #2563EB;   /* blue     */
  --viz-2: #C2410C;   /* orange   */
  --viz-3: #0D9488;   /* teal     */
  --viz-4: #A16207;   /* gold     */
  --viz-5: #BE3B7B;   /* magenta  */
  --viz-6: #047857;   /* green    */

  /* Single-series visuals — the funnel, a trend line, a sparkline, a capacity
     meter — carry no categorical meaning, so they follow the school's brand.
     The --viz-1..6 series above deliberately do NOT: those encode different
     things at once and have to stay distinguishable from each other whatever
     colour the school picks. */
  --viz-primary: var(--brand);
  --viz-primary-soft: var(--brand-soft);

  --viz-grid:    rgba(15, 23, 42, 0.08);
  --viz-axis:    rgba(15, 23, 42, 0.20);
  --viz-track:   var(--n-150);
  --viz-surface: var(--surface-elevated);

  /* Ordinal ramp (magnitude, light -> dark), follows the brand hue */
  --ramp-1: hsl(var(--brand-h) calc(var(--brand-s) * 0.5) 88%);
  --ramp-2: hsl(var(--brand-h) calc(var(--brand-s) * 0.7) 74%);
  --ramp-3: hsl(var(--brand-h) var(--brand-s) 58%);
  --ramp-4: hsl(var(--brand-h) var(--brand-s) 44%);
  --ramp-5: hsl(var(--brand-h) var(--brand-s) 30%);

  /* Pipeline stage rail — brand -> accent. Always labelled in text too. */
  --stage-1: hsl(var(--brand-h) var(--brand-s) 38%);
  --stage-2: hsl(var(--brand-h) var(--brand-s) 45%);
  --stage-3: hsl(var(--brand-h) var(--brand-s) 52%);
  --stage-4: hsl(var(--brand-h) calc(var(--brand-s) * 0.8) 56%);
  --stage-5: hsl(calc(var(--brand-h) - 30) 30% 55%);
  --stage-6: hsl(90 18% 52%);
  --stage-7: hsl(60 40% 46%);
  --stage-8: hsl(var(--accent-h) calc(var(--accent-s) * 0.8) 48%);
  --stage-9: hsl(var(--accent-h) var(--accent-s) var(--accent-l));

  /* ------------------------------------------------------------------
     9. SPACING  (4px base)
     ------------------------------------------------------------------ */
  --space-0:  0;
  --space-1:  0.25rem;   /*  4 */
  --space-2:  0.5rem;    /*  8 */
  --space-3:  0.75rem;   /* 12 */
  --space-4:  1rem;      /* 16 */
  --space-5:  1.25rem;   /* 20 */
  --space-6:  1.5rem;    /* 24 */
  --space-7:  1.75rem;   /* 28 */
  --space-8:  2rem;      /* 32 */
  --space-10: 2.5rem;    /* 40 */
  --space-12: 3rem;      /* 48 */
  --space-16: 4rem;      /* 64 */
  --space-20: 5rem;      /* 80 */
  --space-24: 6rem;      /* 96 */

  /* ------------------------------------------------------------------
     10. RADII
     ------------------------------------------------------------------ */
  --radius-xs:   4px;
  --radius-sm:   6px;
  --radius-md:   8px;
  --radius-lg:   12px;
  --radius-xl:   16px;
  --radius-2xl:  24px;
  --radius-full: 999px;

  /* ------------------------------------------------------------------
     11. ELEVATION — layered, low-opacity, cool-tinted
     ------------------------------------------------------------------ */
  --shadow-xs: 0 1px 1px rgba(15, 23, 42, 0.04);
  --shadow-sm: 0 1px 2px rgba(15, 23, 42, 0.05), 0 1px 3px rgba(15, 23, 42, 0.04);
  --shadow-md: 0 1px 3px rgba(15, 23, 42, 0.05), 0 6px 16px rgba(15, 23, 42, 0.07);
  --shadow-lg: 0 2px 6px rgba(15, 23, 42, 0.06), 0 16px 36px rgba(15, 23, 42, 0.10);
  --shadow-xl: 0 6px 14px rgba(15, 23, 42, 0.07), 0 32px 64px rgba(15, 23, 42, 0.14);
  --shadow-inset: inset 0 1px 2px rgba(15, 23, 42, 0.05);
  --shadow-focus: 0 0 0 3px var(--brand-ring);
  --shadow-focus-danger: 0 0 0 3px rgba(226, 59, 50, 0.30);

  /* ------------------------------------------------------------------
     12. Z-INDEX
     ------------------------------------------------------------------ */
  --z-base:      0;
  --z-raised:    10;
  --z-sticky:    100;
  --z-header:    200;
  --z-sidebar:   300;
  --z-dropdown:  600;
  --z-scrim:     800;
  --z-drawer:    850;
  --z-modal:     900;
  /* Menus and typeaheads are appended to <body>, so when one is opened
     from inside a drawer or modal it has to outrank it or it renders
     behind the panel that spawned it. */
  --z-popover:   950;
  --z-toast:     1000;
  --z-tooltip:   1100;

  /* ------------------------------------------------------------------
     13. TYPOGRAPHY
     ------------------------------------------------------------------ */
  --font-ui: "Instrument Sans", ui-sans-serif, -apple-system, BlinkMacSystemFont,
             "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-display: var(--font-ui);
  --font-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, "SF Mono",
               Menlo, Consolas, "Liberation Mono", monospace;

  /* Type scale — tuned for a dense data application */
  --text-2xs:  0.6875rem;  /* 11 — micro labels, table meta          */
  --text-xs:   0.75rem;    /* 12 — badges, captions, column headers  */
  --text-sm:   0.8125rem;  /* 13 — dense table cells, secondary UI   */
  --text-base: 0.875rem;   /* 14 — body / controls                   */
  --text-md:   0.9375rem;  /* 15 — prominent body, card titles       */
  --text-lg:   1.0625rem;  /* 17 — section headings                  */
  --text-xl:   1.3125rem;  /* 21 — page headings                     */
  --text-2xl:  1.625rem;   /* 26 — stat figures                      */
  --text-3xl:  2.125rem;   /* 34 — hero figures                      */
  --text-4xl:  2.75rem;    /* 44 — display                           */
  --text-5xl:  3.5rem;     /* 56 — login brand panel                 */

  --leading-none:    1;
  --leading-tight:   1.16;
  --leading-snug:    1.34;
  --leading-normal:  1.5;
  --leading-relaxed: 1.68;

  --tracking-tighter: -0.022em;
  --tracking-tight:   -0.012em;
  --tracking-normal:  0;
  --tracking-wide:    0.02em;
  --tracking-wider:   0.05em;
  --tracking-widest:  0.11em;

  --weight-regular:  400;
  --weight-medium:   500;
  --weight-semibold: 600;
  --weight-bold:     700;

  /* ------------------------------------------------------------------
     14. MOTION
     ------------------------------------------------------------------ */
  --dur-instant: 0ms;
  --dur-1: 90ms;
  --dur-2: 150ms;
  --dur-3: 220ms;
  --dur-4: 360ms;
  --dur-5: 560ms;

  --ease-out:    cubic-bezier(0.16, 1, 0.30, 1);
  --ease-in:     cubic-bezier(0.55, 0, 1, 0.45);
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
  --ease-spring: cubic-bezier(0.34, 1.42, 0.64, 1);
  --ease-linear: linear;

  /* ------------------------------------------------------------------
     15. LAYOUT METRICS
     ------------------------------------------------------------------ */
  --sidebar-w:      252px;
  --sidebar-rail-w: 68px;
  --topbar-h:       56px;
  --bottomnav-h:    62px;
  --content-max:    1640px;
  --drawer-w:       min(760px, 100vw);
  --sheet-w:        min(560px, 100vw);
  --control-h-sm:   30px;
  --control-h:      36px;
  --control-h-lg:   42px;
  --touch-min:      44px;
  --row-h:          44px;
  --row-h-compact:  36px;

  /* Ambient page texture — off by default; the clean canvas is the look. */
  --texture-grid: none;
  --texture-size: 56px 56px;
}

/* ============================================================================
   DARK THEME — OS preference (loses to an explicit data-theme="light")
   ========================================================================== */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;

    /* Brand channels stay as set by theme.js; only the lightness swaps. */
    --brand-l:  var(--brand-l-dark);
    --accent-l: var(--accent-l-dark);
    --on-brand:  var(--on-brand-dark);
    --on-accent: var(--on-accent-dark);

    --surface-sunken:   #080C14;
    --surface:          #0E131C;
    --surface-elevated: #161C28;
    --surface-raised:   #1B2230;
    --surface-overlay:  rgba(3, 6, 12, 0.64);
    --surface-inset:    rgba(255, 255, 255, 0.035);
    --surface-hover:    hsl(var(--brand-h) var(--brand-s) var(--brand-l) / 0.10);
    --surface-active:   hsl(var(--brand-h) var(--brand-s) var(--brand-l) / 0.18);
    --surface-selected: hsl(var(--brand-h) var(--brand-s) var(--brand-l) / 0.14);

    --text-primary:   #E8EDF5;
    --text-secondary: #A9B4C6;
    --text-muted:     #7E8CA3;
    --text-faint:     #5D6A7F;
    --text-inverse:   #0E131C;

    --border-subtle: #232B3A;
    --border-strong: #354054;
    --divider:       #1E2532;
    --hairline:      rgba(255, 255, 255, 0.07);

    --brand-soft:       hsl(var(--brand-h) calc(var(--brand-s) * 0.5) 16%);
    --brand-soft-hover: hsl(var(--brand-h) calc(var(--brand-s) * 0.5) 21%);
    --brand-border:     hsl(var(--brand-h) calc(var(--brand-s) * 0.45) 32%);
    --brand-ink:        hsl(var(--brand-h) var(--brand-s) calc(var(--brand-l) + 6%));
    --brand-ring:       hsl(var(--brand-h) var(--brand-s) var(--brand-l) / 0.40);
    --brand-gradient:   linear-gradient(160deg,
                          hsl(var(--brand-h) calc(var(--brand-s) * 0.6) 18%) 0%,
                          hsl(var(--brand-h) calc(var(--brand-s) * 0.6) 11%) 60%,
                          hsl(var(--brand-h) calc(var(--brand-s) * 0.5) 7%) 100%);

    --accent-soft:   hsl(var(--accent-h) calc(var(--accent-s) * 0.45) 14%);
    --accent-border: hsl(var(--accent-h) calc(var(--accent-s) * 0.4) 30%);
    --accent-ink:    hsl(var(--accent-h) var(--accent-s) calc(var(--accent-l) + 6%));

    --success-ink: #4ADE9A;  --success-soft: #0C2A1E;  --success-fill: #10A366;  --success-border: #245C44;
    --warning-ink: #FBBF4C;  --warning-soft: #2C2210;  --warning-fill: #C2790C;  --warning-border: #5B4620;
    --danger-ink:  #FB8983;  --danger-soft:  #33191A;  --danger-fill:  #D2453C;  --danger-border:  #683230;
    --info-ink:    #6BB8F0;  --info-soft:    #10253A;  --info-fill:    #1B7FC4;  --info-border:    #2A4664;
    --neutral-ink: #A9B4C6;  --neutral-soft: #1B2330;  --neutral-fill: #54637C;  --neutral-border: #313C4F;

    --hot-ink:  #FB8983;  --hot-soft:  #33191A;  --hot-border:  #683230;
    --warm-ink: #FBBF4C;  --warm-soft: #2C2210;  --warm-border: #5B4620;
    --cold-ink: #6BB8F0;  --cold-soft: #10253A;  --cold-border: #2A4664;

    --viz-1: #5E9BF5;
    --viz-2: #E8814A;
    --viz-3: #2DBFAE;
    --viz-4: #D3A32B;
    --viz-5: #E0709F;
    --viz-6: #34B57C;

    --viz-grid:    rgba(255, 255, 255, 0.07);
    --viz-axis:    rgba(255, 255, 255, 0.18);
    --viz-track:   #1E2735;
    --viz-surface: var(--surface-elevated);

    --ramp-1: hsl(var(--brand-h) calc(var(--brand-s) * 0.45) 84%);
    --ramp-2: hsl(var(--brand-h) calc(var(--brand-s) * 0.6) 72%);
    --ramp-3: hsl(var(--brand-h) var(--brand-s) 60%);
    --ramp-4: hsl(var(--brand-h) var(--brand-s) 48%);
    --ramp-5: hsl(var(--brand-h) var(--brand-s) 36%);

    --stage-1: hsl(var(--brand-h) var(--brand-s) 68%);
    --stage-2: hsl(var(--brand-h) var(--brand-s) 63%);
    --stage-3: hsl(var(--brand-h) calc(var(--brand-s) * 0.85) 60%);
    --stage-4: hsl(var(--brand-h) calc(var(--brand-s) * 0.65) 60%);
    --stage-5: hsl(calc(var(--brand-h) - 30) 25% 60%);
    --stage-6: hsl(90 16% 58%);
    --stage-7: hsl(60 32% 58%);
    --stage-8: hsl(var(--accent-h) calc(var(--accent-s) * 0.7) 62%);
    --stage-9: hsl(var(--accent-h) var(--accent-s) var(--accent-l));

    --shadow-xs: 0 1px 1px rgba(0, 0, 0, 0.34);
    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.40), 0 1px 3px rgba(0, 0, 0, 0.30);
    --shadow-md: 0 1px 3px rgba(0, 0, 0, 0.40), 0 6px 16px rgba(0, 0, 0, 0.42);
    --shadow-lg: 0 2px 6px rgba(0, 0, 0, 0.42), 0 16px 36px rgba(0, 0, 0, 0.50);
    --shadow-xl: 0 6px 14px rgba(0, 0, 0, 0.44), 0 32px 64px rgba(0, 0, 0, 0.58);
    --shadow-inset: inset 0 1px 2px rgba(0, 0, 0, 0.40);
    --shadow-focus: 0 0 0 3px var(--brand-ring);
    --shadow-focus-danger: 0 0 0 3px rgba(251, 137, 131, 0.34);

    --texture-grid: none;
  }
}

/* ============================================================================
   DARK THEME — explicit toggle. Wins over an OS light preference.
   ========================================================================== */
:root[data-theme="dark"] {
  color-scheme: dark;

  --brand-l:  var(--brand-l-dark);
  --accent-l: var(--accent-l-dark);
  --on-brand:  var(--on-brand-dark);
  --on-accent: var(--on-accent-dark);

  --surface-sunken:   #080C14;
  --surface:          #0E131C;
  --surface-elevated: #161C28;
  --surface-raised:   #1B2230;
  --surface-overlay:  rgba(3, 6, 12, 0.64);
  --surface-inset:    rgba(255, 255, 255, 0.035);
  --surface-hover:    hsl(var(--brand-h) var(--brand-s) var(--brand-l) / 0.10);
  --surface-active:   hsl(var(--brand-h) var(--brand-s) var(--brand-l) / 0.18);
  --surface-selected: hsl(var(--brand-h) var(--brand-s) var(--brand-l) / 0.14);

  --text-primary:   #E8EDF5;
  --text-secondary: #A9B4C6;
  --text-muted:     #7E8CA3;
  --text-faint:     #5D6A7F;
  --text-inverse:   #0E131C;

  --border-subtle: #232B3A;
  --border-strong: #354054;
  --divider:       #1E2532;
  --hairline:      rgba(255, 255, 255, 0.07);

  --brand-soft:       hsl(var(--brand-h) calc(var(--brand-s) * 0.5) 16%);
  --brand-soft-hover: hsl(var(--brand-h) calc(var(--brand-s) * 0.5) 21%);
  --brand-border:     hsl(var(--brand-h) calc(var(--brand-s) * 0.45) 32%);
  --brand-ink:        hsl(var(--brand-h) var(--brand-s) calc(var(--brand-l) + 6%));
  --brand-ring:       hsl(var(--brand-h) var(--brand-s) var(--brand-l) / 0.40);
  --brand-gradient:   linear-gradient(160deg,
                        hsl(var(--brand-h) calc(var(--brand-s) * 0.6) 18%) 0%,
                        hsl(var(--brand-h) calc(var(--brand-s) * 0.6) 11%) 60%,
                        hsl(var(--brand-h) calc(var(--brand-s) * 0.5) 7%) 100%);

  --accent-soft:   hsl(var(--accent-h) calc(var(--accent-s) * 0.45) 14%);
  --accent-border: hsl(var(--accent-h) calc(var(--accent-s) * 0.4) 30%);
  --accent-ink:    hsl(var(--accent-h) var(--accent-s) calc(var(--accent-l) + 6%));

  --success-ink: #4ADE9A;  --success-soft: #0C2A1E;  --success-fill: #10A366;  --success-border: #245C44;
  --warning-ink: #FBBF4C;  --warning-soft: #2C2210;  --warning-fill: #C2790C;  --warning-border: #5B4620;
  --danger-ink:  #FB8983;  --danger-soft:  #33191A;  --danger-fill:  #D2453C;  --danger-border:  #683230;
  --info-ink:    #6BB8F0;  --info-soft:    #10253A;  --info-fill:    #1B7FC4;  --info-border:    #2A4664;
  --neutral-ink: #A9B4C6;  --neutral-soft: #1B2330;  --neutral-fill: #54637C;  --neutral-border: #313C4F;

  --hot-ink:  #FB8983;  --hot-soft:  #33191A;  --hot-border:  #683230;
  --warm-ink: #FBBF4C;  --warm-soft: #2C2210;  --warm-border: #5B4620;
  --cold-ink: #6BB8F0;  --cold-soft: #10253A;  --cold-border: #2A4664;

  --viz-1: #5E9BF5;
  --viz-2: #E8814A;
  --viz-3: #2DBFAE;
  --viz-4: #D3A32B;
  --viz-5: #E0709F;
  --viz-6: #34B57C;

  --viz-grid:    rgba(255, 255, 255, 0.07);
  --viz-axis:    rgba(255, 255, 255, 0.18);
  --viz-track:   #1E2735;
  --viz-surface: var(--surface-elevated);

  --ramp-1: hsl(var(--brand-h) calc(var(--brand-s) * 0.45) 84%);
  --ramp-2: hsl(var(--brand-h) calc(var(--brand-s) * 0.6) 72%);
  --ramp-3: hsl(var(--brand-h) var(--brand-s) 60%);
  --ramp-4: hsl(var(--brand-h) var(--brand-s) 48%);
  --ramp-5: hsl(var(--brand-h) var(--brand-s) 36%);

  --stage-1: hsl(var(--brand-h) var(--brand-s) 68%);
  --stage-2: hsl(var(--brand-h) var(--brand-s) 63%);
  --stage-3: hsl(var(--brand-h) calc(var(--brand-s) * 0.85) 60%);
  --stage-4: hsl(var(--brand-h) calc(var(--brand-s) * 0.65) 60%);
  --stage-5: hsl(calc(var(--brand-h) - 30) 25% 60%);
  --stage-6: hsl(90 16% 58%);
  --stage-7: hsl(60 32% 58%);
  --stage-8: hsl(var(--accent-h) calc(var(--accent-s) * 0.7) 62%);
  --stage-9: hsl(var(--accent-h) var(--accent-s) var(--accent-l));

  --shadow-xs: 0 1px 1px rgba(0, 0, 0, 0.34);
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.40), 0 1px 3px rgba(0, 0, 0, 0.30);
  --shadow-md: 0 1px 3px rgba(0, 0, 0, 0.40), 0 6px 16px rgba(0, 0, 0, 0.42);
  --shadow-lg: 0 2px 6px rgba(0, 0, 0, 0.42), 0 16px 36px rgba(0, 0, 0, 0.50);
  --shadow-xl: 0 6px 14px rgba(0, 0, 0, 0.44), 0 32px 64px rgba(0, 0, 0, 0.58);
  --shadow-inset: inset 0 1px 2px rgba(0, 0, 0, 0.40);
  --shadow-focus: 0 0 0 3px var(--brand-ring);
  --shadow-focus-danger: 0 0 0 3px rgba(251, 137, 131, 0.34);

  --texture-grid: none;
}

/* Explicit light stamp — restores the light scheme hint when the OS is dark. */
:root[data-theme="light"] { color-scheme: light; }

/* ============================================================================
   DENSITY — the admin/user can trade whitespace for rows on screen.
   ========================================================================== */
:root[data-density="compact"] {
  --row-h: 34px;
  --row-h-compact: 30px;
  --control-h: 32px;
  --control-h-sm: 26px;
  --space-4: 0.8125rem;
  --space-5: 1rem;
  --space-6: 1.1875rem;
}

/* ============================================================================
   REDUCED MOTION — collapse every duration token at the source
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  :root {
    --dur-1: 0ms; --dur-2: 0ms; --dur-3: 0ms; --dur-4: 0ms; --dur-5: 0ms;
  }
}
