/**
 * Ludus Design System — token layer.
 * Original work by Ludus Agency. Licensed MIT (see ../LICENSE).
 *
 * This file is the executable source of truth. Documentation in ../Foundations
 * describes it; where the two disagree, this file wins.
 *
 * Three rules are load-bearing:
 *
 *  1. Components never reference a global token. `--lds-indigo-60` exists only
 *     to build semantics from. Components use `--lds-bg-brand-base-rest`, so a
 *     rebrand is one edit here rather than a search across every screen.
 *  2. Every semantic token is defined in BOTH themes. A token that exists only
 *     in light is a dark-mode bug waiting to ship.
 *  3. Every spatial value is a multiple of 4px.
 *
 * Theming contract (three states, matching how hosts actually behave):
 *   - bare :root                      -> light palette
 *   - @media (prefers-color-scheme: dark) guarded by :root:not([data-theme=light])
 *   - :root[data-theme="dark"]        -> explicit choice wins in both directions
 */

/* =====================================================================
 * 1. GLOBAL PALETTE — raw values, no meaning. Never used by a component.
 *
 * Chromatic hues run 10 (lightest) to 90 (darkest).
 * Neutral runs 10 to 140: dark surfaces need four more steps below the
 * light-mode floor, and inventing a second neutral scale for dark mode is
 * worse than extending this one.
 * ================================================================== */
:root {
  /* Brand — indigo */
  --lds-indigo-10: #eef0ff;
  --lds-indigo-20: #dee0fd;
  --lds-indigo-30: #c4c6fb;
  --lds-indigo-40: #a3a4f7;
  --lds-indigo-50: #8280f2;
  --lds-indigo-60: #4f46e5;
  --lds-indigo-70: #4038c0;
  --lds-indigo-80: #322c99;
  --lds-indigo-90: #232065;

  /* Neutral — zinc */
  --lds-neutral-10: #fafafa;
  --lds-neutral-20: #f4f4f5;
  --lds-neutral-30: #e4e4e7;
  --lds-neutral-40: #d4d4d8;
  --lds-neutral-50: #a1a1aa;
  --lds-neutral-60: #71717a;
  --lds-neutral-70: #52525b;
  --lds-neutral-80: #3f3f46;
  --lds-neutral-90: #33333a;
  --lds-neutral-100: #27272a;
  --lds-neutral-110: #1f1f23;
  --lds-neutral-120: #16161a;
  --lds-neutral-130: #0f0f12;
  --lds-neutral-140: #080809;

  /* Success — emerald */
  --lds-green-10: #ecfdf5;
  --lds-green-20: #d1fae5;
  --lds-green-30: #a7f3d0;
  --lds-green-40: #6ee7b7;
  --lds-green-50: #34d399;
  --lds-green-60: #10b981;
  --lds-green-70: #047857;
  --lds-green-80: #065f46;
  --lds-green-90: #064e3b;

  /* Warning — amber */
  --lds-amber-10: #fffbeb;
  --lds-amber-20: #fef3c7;
  --lds-amber-30: #fde68a;
  --lds-amber-40: #fcd34d;
  --lds-amber-50: #fbbf24;
  --lds-amber-60: #f59e0b;
  --lds-amber-70: #b45309;
  --lds-amber-80: #92400e;
  --lds-amber-90: #78350f;

  /* Error — red */
  --lds-red-10: #fef2f2;
  --lds-red-20: #fee2e2;
  --lds-red-30: #fecaca;
  --lds-red-40: #fca5a5;
  --lds-red-50: #f87171;
  --lds-red-60: #ef4444;
  --lds-red-70: #b91c1c;
  --lds-red-80: #991b1b;
  --lds-red-90: #7f1d1d;

  /* Info — sky. Deliberately not the brand hue: an info banner must not read
     as a brand surface. */
  --lds-sky-10: #f0f9ff;
  --lds-sky-20: #e0f2fe;
  --lds-sky-30: #bae6fd;
  --lds-sky-40: #7dd3fc;
  --lds-sky-50: #38bdf8;
  --lds-sky-60: #0284c7;
  --lds-sky-70: #0369a1;
  --lds-sky-80: #075985;
  --lds-sky-90: #0c4a6e;

  /* Extended accents — data visualisation, tags, category colour. */
  --lds-purple-10: #faf5ff;
  --lds-purple-20: #f3e8ff;
  --lds-purple-30: #e9d5ff;
  --lds-purple-40: #d8b4fe;
  --lds-purple-50: #c084fc;
  --lds-purple-60: #9333ea;
  --lds-purple-70: #7e22ce;
  --lds-purple-80: #6b21a8;
  --lds-purple-90: #581c87;

  --lds-teal-10: #f0fdfa;
  --lds-teal-20: #ccfbf1;
  --lds-teal-30: #99f6e4;
  --lds-teal-40: #5eead4;
  --lds-teal-50: #2dd4bf;
  --lds-teal-60: #0d9488;
  --lds-teal-70: #0f766e;
  --lds-teal-80: #115e59;
  --lds-teal-90: #134e4a;

  --lds-orange-10: #fff7ed;
  --lds-orange-20: #ffedd5;
  --lds-orange-30: #fed7aa;
  --lds-orange-40: #fdba74;
  --lds-orange-50: #fb923c;
  --lds-orange-60: #ea580c;
  --lds-orange-70: #c2410c;
  --lds-orange-80: #9a3412;
  --lds-orange-90: #7c2d12;

  --lds-rose-10: #fff1f2;
  --lds-rose-20: #ffe4e6;
  --lds-rose-30: #fecdd3;
  --lds-rose-40: #fda4af;
  --lds-rose-50: #fb7185;
  --lds-rose-60: #e11d48;
  --lds-rose-70: #be123c;
  --lds-rose-80: #9f1239;
  --lds-rose-90: #881337;

  --lds-white: #ffffff;
  --lds-black: #000000;
}

/* =====================================================================
 * 2. SEMANTIC — LIGHT THEME (the default)
 *
 * Contrast is stated where it constrains the choice. Every value used for
 * body text clears WCAG 2.1 AA (4.5:1) against its intended surface; every
 * value used for a border or a large label clears 3:1.
 * ================================================================== */
:root {
  color-scheme: light;

  /* --- Surfaces ------------------------------------------------------ */
  --lds-bg-surface-primary: var(--lds-white);
  --lds-bg-surface-secondary: var(--lds-neutral-20);
  --lds-bg-surface-tertiary: var(--lds-neutral-30);
  --lds-bg-surface-sunken: var(--lds-neutral-10);
  --lds-bg-surface-raised: var(--lds-white);
  --lds-bg-surface-inactive: var(--lds-neutral-20);
  --lds-bg-surface-transparent: transparent;
  --lds-bg-surface-overlay: rgb(15 15 18 / 0.55);
  --lds-bg-surface-inverse: var(--lds-neutral-130);

  /* --- Backgrounds: brand -------------------------------------------- */
  --lds-bg-brand-base-rest: var(--lds-indigo-60);
  --lds-bg-brand-base-hover: var(--lds-indigo-70);
  --lds-bg-brand-base-pressed: var(--lds-indigo-80);
  --lds-bg-brand-subtle-rest: var(--lds-indigo-10);
  --lds-bg-brand-subtle-hover: var(--lds-indigo-20);
  --lds-bg-brand-subtle-pressed: var(--lds-indigo-30);

  /* --- Backgrounds: neutral ------------------------------------------ */
  --lds-bg-neutral-base-rest: var(--lds-neutral-100);
  --lds-bg-neutral-base-hover: var(--lds-neutral-90);
  --lds-bg-neutral-base-pressed: var(--lds-neutral-80);
  --lds-bg-neutral-subtle-rest: var(--lds-neutral-20);
  --lds-bg-neutral-subtle-hover: var(--lds-neutral-30);
  --lds-bg-neutral-subtle-pressed: var(--lds-neutral-40);

  /* --- Backgrounds: status ------------------------------------------- */
  --lds-bg-info-base-rest: var(--lds-sky-70);
  --lds-bg-info-base-hover: var(--lds-sky-80);
  --lds-bg-info-base-pressed: var(--lds-sky-90);
  --lds-bg-info-subtle-rest: var(--lds-sky-10);
  --lds-bg-info-subtle-hover: var(--lds-sky-20);
  --lds-bg-info-subtle-pressed: var(--lds-sky-30);

  --lds-bg-success-base-rest: var(--lds-green-70);
  --lds-bg-success-base-hover: var(--lds-green-80);
  --lds-bg-success-base-pressed: var(--lds-green-90);
  --lds-bg-success-subtle-rest: var(--lds-green-10);
  --lds-bg-success-subtle-hover: var(--lds-green-20);
  --lds-bg-success-subtle-pressed: var(--lds-green-30);

  --lds-bg-warning-base-rest: var(--lds-amber-70);
  --lds-bg-warning-base-hover: var(--lds-amber-80);
  --lds-bg-warning-base-pressed: var(--lds-amber-90);
  --lds-bg-warning-subtle-rest: var(--lds-amber-10);
  --lds-bg-warning-subtle-hover: var(--lds-amber-20);
  --lds-bg-warning-subtle-pressed: var(--lds-amber-30);

  --lds-bg-error-base-rest: var(--lds-red-70);
  --lds-bg-error-base-hover: var(--lds-red-80);
  --lds-bg-error-base-pressed: var(--lds-red-90);
  --lds-bg-error-subtle-rest: var(--lds-red-10);
  --lds-bg-error-subtle-hover: var(--lds-red-20);
  --lds-bg-error-subtle-pressed: var(--lds-red-30);

  /* --- Text ----------------------------------------------------------
   * primary   neutral-130  17.5:1 on white
   * secondary neutral-70    7.7:1
   * tertiary  neutral-60    4.8:1  — the lightest value still cleared for
   *                                  body text; nothing below it reads prose.
   * inactive  neutral-50    2.6:1  — fails AA on purpose. Disabled text is
   *                                  exempt under WCAG 1.4.3, but never use
   *                                  it for anything a user must read.
   */
  --lds-text-primary: var(--lds-neutral-130);
  --lds-text-secondary: var(--lds-neutral-70);
  --lds-text-tertiary: var(--lds-neutral-60);
  --lds-text-inactive: var(--lds-neutral-50);
  --lds-text-placeholder: var(--lds-neutral-50);
  --lds-text-on-fill: var(--lds-white);
  --lds-text-on-inverse: var(--lds-neutral-20);
  /* Label colour for each filled surface. Split per status rather than one
     shared `on-fill`, because in dark mode the status fills go light and the
     label has to flip to dark while the brand fill's stays white. */
  --lds-text-on-brand: var(--lds-white);
  --lds-text-on-info: var(--lds-white);
  --lds-text-on-success: var(--lds-white);
  --lds-text-on-warning: var(--lds-white);
  --lds-text-on-error: var(--lds-white);

  --lds-text-brand-rest: var(--lds-indigo-60);
  --lds-text-brand-hover: var(--lds-indigo-70);
  --lds-text-brand-pressed: var(--lds-indigo-80);
  --lds-text-info-rest: var(--lds-sky-70);
  --lds-text-info-hover: var(--lds-sky-80);
  --lds-text-info-pressed: var(--lds-sky-90);
  --lds-text-success-rest: var(--lds-green-70);
  --lds-text-success-hover: var(--lds-green-80);
  --lds-text-success-pressed: var(--lds-green-90);
  --lds-text-warning-rest: var(--lds-amber-70);
  --lds-text-warning-hover: var(--lds-amber-80);
  --lds-text-warning-pressed: var(--lds-amber-90);
  --lds-text-error-rest: var(--lds-red-70);
  --lds-text-error-hover: var(--lds-red-80);
  --lds-text-error-pressed: var(--lds-red-90);

  --lds-text-link-rest: var(--lds-indigo-60);
  --lds-text-link-visited: var(--lds-purple-70);

  /* --- Borders -------------------------------------------------------- */
  --lds-border-brand-base: var(--lds-indigo-60);
  --lds-border-brand-subtle: var(--lds-indigo-30);
  --lds-border-neutral-base: var(--lds-neutral-40);
  --lds-border-neutral-subtle: var(--lds-neutral-30);
  --lds-border-neutral-pale: var(--lds-neutral-20);
  --lds-border-neutral-strong: var(--lds-neutral-60);
  --lds-border-interactive: var(--lds-neutral-60);
  --lds-border-info-base: var(--lds-sky-60);
  --lds-border-info-subtle: var(--lds-sky-30);
  --lds-border-success-base: var(--lds-green-60);
  --lds-border-success-subtle: var(--lds-green-30);
  --lds-border-warning-base: var(--lds-amber-60);
  --lds-border-warning-subtle: var(--lds-amber-30);
  --lds-border-error-base: var(--lds-red-60);
  --lds-border-error-subtle: var(--lds-red-30);
  --lds-border-inactive-base: var(--lds-neutral-30);
  --lds-border-focus: var(--lds-indigo-60);

  /* --- Elevation -----------------------------------------------------
   * Light mode separates planes with shadow. One light source per screen:
   * these are all cast from above. Directional (left/right) variants exist
   * below for the rare case where a panel slides in horizontally.
   */
  --lds-elevation-0: none;
  --lds-elevation-1: 0 1px 2px rgb(15 15 18 / 0.06), 0 1px 3px rgb(15 15 18 / 0.08);
  --lds-elevation-2: 0 2px 4px rgb(15 15 18 / 0.06), 0 4px 8px rgb(15 15 18 / 0.08);
  --lds-elevation-3: 0 4px 8px rgb(15 15 18 / 0.06), 0 8px 20px rgb(15 15 18 / 0.10);
  --lds-elevation-4: 0 8px 16px rgb(15 15 18 / 0.08), 0 16px 40px rgb(15 15 18 / 0.14);
  --lds-elevation-inset: inset 0 1px 2px rgb(15 15 18 / 0.08);
  --lds-elevation-left-2: -4px 2px 8px rgb(15 15 18 / 0.08);
  --lds-elevation-right-2: 4px 2px 8px rgb(15 15 18 / 0.08);

  /* A visible hairline is optional in light mode — shadow already separates. */
  --lds-elevation-ring: 0 0 0 1px rgb(15 15 18 / 0.04);

  /* --- Data visualisation --------------------------------------------
   * A categorical series ramp, ordered so the first five stay
   * distinguishable under the common colour-vision deficiencies. A series
   * must still be told apart by more than hue — a direct label, a dash
   * pattern, or a marker shape.
   */
  --lds-chart-1: var(--lds-indigo-60);
  --lds-chart-2: var(--lds-teal-60);
  --lds-chart-3: var(--lds-amber-60);
  --lds-chart-4: var(--lds-rose-60);
  --lds-chart-5: var(--lds-sky-60);
  --lds-chart-6: var(--lds-purple-60);
  --lds-chart-7: var(--lds-green-60);
  --lds-chart-8: var(--lds-orange-60);
  --lds-chart-grid: var(--lds-border-neutral-subtle);
  --lds-chart-axis: var(--lds-text-tertiary);
}

/* =====================================================================
 * 3. SEMANTIC — DARK THEME
 *
 * Not an inversion. Three things change in kind, not degree:
 *
 *  - Elevation stops being shadow. On a dark ground a drop shadow is close
 *    to invisible, so raised planes get LIGHTER (surface tint) and gain a
 *    1px hairline. The shadow tokens stay defined so layout does not shift,
 *    but they carry a hairline ring as their real signal.
 *  - Hover goes lighter, not darker. Darkening a fill on a dark page reads
 *    as disabled.
 *  - Saturated brand and status hues move UP the scale (60 -> 40) for text,
 *    because a mid-tone that clears 4.5:1 on white fails badly on near-black.
 * ================================================================== */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;

    --lds-bg-surface-primary: var(--lds-neutral-120);
    --lds-bg-surface-secondary: var(--lds-neutral-110);
    --lds-bg-surface-tertiary: var(--lds-neutral-100);
    --lds-bg-surface-sunken: var(--lds-neutral-140);
    --lds-bg-surface-raised: var(--lds-neutral-110);
    --lds-bg-surface-inactive: var(--lds-neutral-100);
    --lds-bg-surface-transparent: transparent;
    --lds-bg-surface-overlay: rgb(8 8 9 / 0.72);
    --lds-bg-surface-inverse: var(--lds-neutral-20);

    --lds-bg-brand-base-rest: var(--lds-indigo-60);
    --lds-bg-brand-base-hover: var(--lds-indigo-50);
    --lds-bg-brand-base-pressed: var(--lds-indigo-40);
    --lds-bg-brand-subtle-rest: rgb(79 70 229 / 0.16);
    --lds-bg-brand-subtle-hover: rgb(79 70 229 / 0.24);
    --lds-bg-brand-subtle-pressed: rgb(79 70 229 / 0.32);

    --lds-bg-neutral-base-rest: var(--lds-neutral-30);
    --lds-bg-neutral-base-hover: var(--lds-neutral-20);
    --lds-bg-neutral-base-pressed: var(--lds-neutral-10);
    --lds-bg-neutral-subtle-rest: var(--lds-neutral-100);
    --lds-bg-neutral-subtle-hover: var(--lds-neutral-90);
    --lds-bg-neutral-subtle-pressed: var(--lds-neutral-80);

    --lds-bg-info-base-rest: var(--lds-sky-60);
    --lds-bg-info-base-hover: var(--lds-sky-50);
    --lds-bg-info-base-pressed: var(--lds-sky-40);
    --lds-bg-info-subtle-rest: rgb(2 132 199 / 0.16);
    --lds-bg-info-subtle-hover: rgb(2 132 199 / 0.24);
    --lds-bg-info-subtle-pressed: rgb(2 132 199 / 0.32);

    --lds-bg-success-base-rest: var(--lds-green-60);
    --lds-bg-success-base-hover: var(--lds-green-50);
    --lds-bg-success-base-pressed: var(--lds-green-40);
    --lds-bg-success-subtle-rest: rgb(16 185 129 / 0.16);
    --lds-bg-success-subtle-hover: rgb(16 185 129 / 0.24);
    --lds-bg-success-subtle-pressed: rgb(16 185 129 / 0.32);

    --lds-bg-warning-base-rest: var(--lds-amber-60);
    --lds-bg-warning-base-hover: var(--lds-amber-50);
    --lds-bg-warning-base-pressed: var(--lds-amber-40);
    --lds-bg-warning-subtle-rest: rgb(245 158 11 / 0.16);
    --lds-bg-warning-subtle-hover: rgb(245 158 11 / 0.24);
    --lds-bg-warning-subtle-pressed: rgb(245 158 11 / 0.32);

    --lds-bg-error-base-rest: var(--lds-red-60);
    --lds-bg-error-base-hover: var(--lds-red-50);
    --lds-bg-error-base-pressed: var(--lds-red-40);
    --lds-bg-error-subtle-rest: rgb(239 68 68 / 0.16);
    --lds-bg-error-subtle-hover: rgb(239 68 68 / 0.24);
    --lds-bg-error-subtle-pressed: rgb(239 68 68 / 0.32);

    /* primary neutral-10 on neutral-120 = 16.9:1
     * secondary neutral-40 = 11.6:1
     * tertiary neutral-50 =  7.2:1
     * inactive neutral-60 =  3.8:1 — again disabled-only, never prose. */
    --lds-text-primary: var(--lds-neutral-10);
    --lds-text-secondary: var(--lds-neutral-40);
    --lds-text-tertiary: var(--lds-neutral-50);
    --lds-text-inactive: var(--lds-neutral-60);
    --lds-text-placeholder: var(--lds-neutral-60);
    --lds-text-on-fill: var(--lds-white);
    --lds-text-on-inverse: var(--lds-neutral-130);
    /* Status fills are bright here, so their labels go dark. Brand stays
       indigo-60, which still carries white at 6.3:1. */
    --lds-text-on-brand: var(--lds-white);
    --lds-text-on-info: var(--lds-neutral-140);
    --lds-text-on-success: var(--lds-neutral-140);
    --lds-text-on-warning: var(--lds-neutral-140);
    --lds-text-on-error: var(--lds-neutral-140);

    --lds-text-brand-rest: var(--lds-indigo-40);
    --lds-text-brand-hover: var(--lds-indigo-30);
    --lds-text-brand-pressed: var(--lds-indigo-20);
    --lds-text-info-rest: var(--lds-sky-40);
    --lds-text-info-hover: var(--lds-sky-30);
    --lds-text-info-pressed: var(--lds-sky-20);
    --lds-text-success-rest: var(--lds-green-40);
    --lds-text-success-hover: var(--lds-green-30);
    --lds-text-success-pressed: var(--lds-green-20);
    --lds-text-warning-rest: var(--lds-amber-40);
    --lds-text-warning-hover: var(--lds-amber-30);
    --lds-text-warning-pressed: var(--lds-amber-20);
    --lds-text-error-rest: var(--lds-red-40);
    --lds-text-error-hover: var(--lds-red-30);
    --lds-text-error-pressed: var(--lds-red-20);

    --lds-text-link-rest: var(--lds-indigo-40);
    --lds-text-link-visited: var(--lds-purple-40);

    --lds-border-brand-base: var(--lds-indigo-50);
    --lds-border-brand-subtle: rgb(130 128 242 / 0.32);
    --lds-border-neutral-base: var(--lds-neutral-90);
    --lds-border-neutral-subtle: var(--lds-neutral-100);
    --lds-border-neutral-pale: var(--lds-neutral-110);
    --lds-border-neutral-strong: var(--lds-neutral-70);
    --lds-border-interactive: var(--lds-neutral-60);
    --lds-border-info-base: var(--lds-sky-50);
    --lds-border-info-subtle: rgb(56 189 248 / 0.32);
    --lds-border-success-base: var(--lds-green-50);
    --lds-border-success-subtle: rgb(52 211 153 / 0.32);
    --lds-border-warning-base: var(--lds-amber-50);
    --lds-border-warning-subtle: rgb(251 191 36 / 0.32);
    --lds-border-error-base: var(--lds-red-50);
    --lds-border-error-subtle: rgb(248 113 113 / 0.32);
    --lds-border-inactive-base: var(--lds-neutral-100);
    --lds-border-focus: var(--lds-indigo-40);

    /* Elevation carries a hairline as its primary cue; the shadow is a faint
       secondary that only shows at levels 3 and 4. */
    --lds-elevation-0: none;
    --lds-elevation-1: inset 0 0 0 1px rgb(255 255 255 / 0.06);
    --lds-elevation-2: inset 0 0 0 1px rgb(255 255 255 / 0.08), 0 2px 6px rgb(0 0 0 / 0.32);
    --lds-elevation-3: inset 0 0 0 1px rgb(255 255 255 / 0.10), 0 8px 20px rgb(0 0 0 / 0.44);
    --lds-elevation-4: inset 0 0 0 1px rgb(255 255 255 / 0.12), 0 16px 40px rgb(0 0 0 / 0.56);
    --lds-elevation-inset: inset 0 1px 2px rgb(0 0 0 / 0.4);
    --lds-elevation-left-2: inset 0 0 0 1px rgb(255 255 255 / 0.08), -4px 2px 10px rgb(0 0 0 / 0.4);
    --lds-elevation-right-2: inset 0 0 0 1px rgb(255 255 255 / 0.08), 4px 2px 10px rgb(0 0 0 / 0.4);
    --lds-elevation-ring: inset 0 0 0 1px rgb(255 255 255 / 0.06);

    /* Series hues climb to the 40s so they hold up against a dark ground. */
    --lds-chart-1: var(--lds-indigo-40);
    --lds-chart-2: var(--lds-teal-40);
    --lds-chart-3: var(--lds-amber-40);
    --lds-chart-4: var(--lds-rose-40);
    --lds-chart-5: var(--lds-sky-40);
    --lds-chart-6: var(--lds-purple-40);
    --lds-chart-7: var(--lds-green-40);
    --lds-chart-8: var(--lds-orange-40);
    --lds-chart-grid: var(--lds-border-neutral-subtle);
    --lds-chart-axis: var(--lds-text-tertiary);
  }
}

/* Explicit dark choice — same block, unconditional, so a toggle beats the OS
   in both directions. Kept as a duplicate rather than a shared class because a
   :root token block cannot be @extended and a wrapper class would leak into
   every consumer's markup. */
:root[data-theme="dark"] {
  color-scheme: dark;

  --lds-bg-surface-primary: var(--lds-neutral-120);
  --lds-bg-surface-secondary: var(--lds-neutral-110);
  --lds-bg-surface-tertiary: var(--lds-neutral-100);
  --lds-bg-surface-sunken: var(--lds-neutral-140);
  --lds-bg-surface-raised: var(--lds-neutral-110);
  --lds-bg-surface-inactive: var(--lds-neutral-100);
  --lds-bg-surface-transparent: transparent;
  --lds-bg-surface-overlay: rgb(8 8 9 / 0.72);
  --lds-bg-surface-inverse: var(--lds-neutral-20);

  --lds-bg-brand-base-rest: var(--lds-indigo-60);
  --lds-bg-brand-base-hover: var(--lds-indigo-50);
  --lds-bg-brand-base-pressed: var(--lds-indigo-40);
  --lds-bg-brand-subtle-rest: rgb(79 70 229 / 0.16);
  --lds-bg-brand-subtle-hover: rgb(79 70 229 / 0.24);
  --lds-bg-brand-subtle-pressed: rgb(79 70 229 / 0.32);

  --lds-bg-neutral-base-rest: var(--lds-neutral-30);
  --lds-bg-neutral-base-hover: var(--lds-neutral-20);
  --lds-bg-neutral-base-pressed: var(--lds-neutral-10);
  --lds-bg-neutral-subtle-rest: var(--lds-neutral-100);
  --lds-bg-neutral-subtle-hover: var(--lds-neutral-90);
  --lds-bg-neutral-subtle-pressed: var(--lds-neutral-80);

  --lds-bg-info-base-rest: var(--lds-sky-60);
  --lds-bg-info-base-hover: var(--lds-sky-50);
  --lds-bg-info-base-pressed: var(--lds-sky-40);
  --lds-bg-info-subtle-rest: rgb(2 132 199 / 0.16);
  --lds-bg-info-subtle-hover: rgb(2 132 199 / 0.24);
  --lds-bg-info-subtle-pressed: rgb(2 132 199 / 0.32);

  --lds-bg-success-base-rest: var(--lds-green-60);
  --lds-bg-success-base-hover: var(--lds-green-50);
  --lds-bg-success-base-pressed: var(--lds-green-40);
  --lds-bg-success-subtle-rest: rgb(16 185 129 / 0.16);
  --lds-bg-success-subtle-hover: rgb(16 185 129 / 0.24);
  --lds-bg-success-subtle-pressed: rgb(16 185 129 / 0.32);

  --lds-bg-warning-base-rest: var(--lds-amber-60);
  --lds-bg-warning-base-hover: var(--lds-amber-50);
  --lds-bg-warning-base-pressed: var(--lds-amber-40);
  --lds-bg-warning-subtle-rest: rgb(245 158 11 / 0.16);
  --lds-bg-warning-subtle-hover: rgb(245 158 11 / 0.24);
  --lds-bg-warning-subtle-pressed: rgb(245 158 11 / 0.32);

  --lds-bg-error-base-rest: var(--lds-red-60);
  --lds-bg-error-base-hover: var(--lds-red-50);
  --lds-bg-error-base-pressed: var(--lds-red-40);
  --lds-bg-error-subtle-rest: rgb(239 68 68 / 0.16);
  --lds-bg-error-subtle-hover: rgb(239 68 68 / 0.24);
  --lds-bg-error-subtle-pressed: rgb(239 68 68 / 0.32);

  --lds-text-primary: var(--lds-neutral-10);
  --lds-text-secondary: var(--lds-neutral-40);
  --lds-text-tertiary: var(--lds-neutral-50);
  --lds-text-inactive: var(--lds-neutral-60);
  --lds-text-placeholder: var(--lds-neutral-60);
  --lds-text-on-fill: var(--lds-white);
  --lds-text-on-inverse: var(--lds-neutral-130);
  --lds-text-on-brand: var(--lds-white);
  --lds-text-on-info: var(--lds-neutral-140);
  --lds-text-on-success: var(--lds-neutral-140);
  --lds-text-on-warning: var(--lds-neutral-140);
  --lds-text-on-error: var(--lds-neutral-140);

  --lds-text-brand-rest: var(--lds-indigo-40);
  --lds-text-brand-hover: var(--lds-indigo-30);
  --lds-text-brand-pressed: var(--lds-indigo-20);
  --lds-text-info-rest: var(--lds-sky-40);
  --lds-text-info-hover: var(--lds-sky-30);
  --lds-text-info-pressed: var(--lds-sky-20);
  --lds-text-success-rest: var(--lds-green-40);
  --lds-text-success-hover: var(--lds-green-30);
  --lds-text-success-pressed: var(--lds-green-20);
  --lds-text-warning-rest: var(--lds-amber-40);
  --lds-text-warning-hover: var(--lds-amber-30);
  --lds-text-warning-pressed: var(--lds-amber-20);
  --lds-text-error-rest: var(--lds-red-40);
  --lds-text-error-hover: var(--lds-red-30);
  --lds-text-error-pressed: var(--lds-red-20);

  --lds-text-link-rest: var(--lds-indigo-40);
  --lds-text-link-visited: var(--lds-purple-40);

  --lds-border-brand-base: var(--lds-indigo-50);
  --lds-border-brand-subtle: rgb(130 128 242 / 0.32);
  --lds-border-neutral-base: var(--lds-neutral-90);
  --lds-border-neutral-subtle: var(--lds-neutral-100);
  --lds-border-neutral-pale: var(--lds-neutral-110);
  --lds-border-neutral-strong: var(--lds-neutral-70);
  --lds-border-interactive: var(--lds-neutral-60);
  --lds-border-info-base: var(--lds-sky-50);
  --lds-border-info-subtle: rgb(56 189 248 / 0.32);
  --lds-border-success-base: var(--lds-green-50);
  --lds-border-success-subtle: rgb(52 211 153 / 0.32);
  --lds-border-warning-base: var(--lds-amber-50);
  --lds-border-warning-subtle: rgb(251 191 36 / 0.32);
  --lds-border-error-base: var(--lds-red-50);
  --lds-border-error-subtle: rgb(248 113 113 / 0.32);
  --lds-border-inactive-base: var(--lds-neutral-100);
  --lds-border-focus: var(--lds-indigo-40);

  --lds-elevation-0: none;
  --lds-elevation-1: inset 0 0 0 1px rgb(255 255 255 / 0.06);
  --lds-elevation-2: inset 0 0 0 1px rgb(255 255 255 / 0.08), 0 2px 6px rgb(0 0 0 / 0.32);
  --lds-elevation-3: inset 0 0 0 1px rgb(255 255 255 / 0.10), 0 8px 20px rgb(0 0 0 / 0.44);
  --lds-elevation-4: inset 0 0 0 1px rgb(255 255 255 / 0.12), 0 16px 40px rgb(0 0 0 / 0.56);
  --lds-elevation-inset: inset 0 1px 2px rgb(0 0 0 / 0.4);
  --lds-elevation-left-2: inset 0 0 0 1px rgb(255 255 255 / 0.08), -4px 2px 10px rgb(0 0 0 / 0.4);
  --lds-elevation-right-2: inset 0 0 0 1px rgb(255 255 255 / 0.08), 4px 2px 10px rgb(0 0 0 / 0.4);
  --lds-elevation-ring: inset 0 0 0 1px rgb(255 255 255 / 0.06);

  /* Series hues climb to the 40s so they hold up against a dark ground. */
  --lds-chart-1: var(--lds-indigo-40);
  --lds-chart-2: var(--lds-teal-40);
  --lds-chart-3: var(--lds-amber-40);
  --lds-chart-4: var(--lds-rose-40);
  --lds-chart-5: var(--lds-sky-40);
  --lds-chart-6: var(--lds-purple-40);
  --lds-chart-7: var(--lds-green-40);
  --lds-chart-8: var(--lds-orange-40);
  --lds-chart-grid: var(--lds-border-neutral-subtle);
  --lds-chart-axis: var(--lds-text-tertiary);
}

/* =====================================================================
 * 4. THEME-INDEPENDENT TOKENS
 * Space, radius, type, motion, z-index, layout. These do not change with
 * theme, so they are defined once.
 * ================================================================== */
:root {
  /* --- Space: the 4px grid ------------------------------------------
   * Named by multiplier, so space-6 is unambiguously 24px. There is no
   * t-shirt aliasing on top: two names for one value is how a system drifts.
   */
  --lds-space-0: 0px;
  --lds-space-px: 1px;
  --lds-space-1: 4px;
  --lds-space-2: 8px;
  --lds-space-3: 12px;
  --lds-space-4: 16px;
  --lds-space-5: 20px;
  --lds-space-6: 24px;
  --lds-space-7: 28px;
  --lds-space-8: 32px;
  --lds-space-10: 40px;
  --lds-space-12: 48px;
  --lds-space-14: 56px;
  --lds-space-16: 64px;
  --lds-space-20: 80px;
  --lds-space-24: 96px;
  --lds-space-32: 128px;
  --lds-space-40: 160px;

  /* --- Radius -------------------------------------------------------- */
  --lds-radius-none: 0px;
  --lds-radius-xs: 2px;
  --lds-radius-sm: 4px;
  --lds-radius-md: 8px;
  --lds-radius-lg: 12px;
  --lds-radius-xl: 16px;
  --lds-radius-2xl: 24px;
  --lds-radius-full: 9999px;

  /* --- Border width -------------------------------------------------- */
  --lds-border-width-none: 0px;
  --lds-border-width-hairline: 1px;
  --lds-border-width-thick: 2px;
  --lds-border-width-heavy: 4px;

  /* --- Type families -------------------------------------------------
   * Inter and JetBrains Mono are both SIL OFL. Every fallback is a system
   * face, so the system degrades correctly with no webfont at all.
   * Never hard-code a family in a component; localisation swaps these.
   */
  --lds-font-sans: "Inter", ui-sans-serif, system-ui, -apple-system,
    "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif,
    "Apple Color Emoji", "Segoe UI Emoji";
  --lds-font-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo,
    Consolas, "Liberation Mono", monospace;
  --lds-font-display: var(--lds-font-sans);

  /* --- Weights ------------------------------------------------------- */
  --lds-weight-regular: 400;
  --lds-weight-medium: 500;
  --lds-weight-semibold: 600;
  --lds-weight-bold: 700;

  /* --- Tracking ------------------------------------------------------
   * Large type needs negative tracking to stop looking loose; small type
   * needs positive tracking to stay legible. */
  --lds-tracking-tight: -0.02em;
  --lds-tracking-snug: -0.01em;
  --lds-tracking-normal: 0em;
  --lds-tracking-wide: 0.01em;
  --lds-tracking-caps: 0.06em;

  /* --- Type ramp: default (>= 1024px) --------------------------------
   * Sizes and line heights are all multiples of 4px so text sits on the
   * baseline grid. The compact ramp below 1024px overrides only what has
   * to shrink; body sizes deliberately do not change, because shrinking
   * body text on a phone is the wrong direction.
   */
  --lds-display-1-size: 72px;  --lds-display-1-line: 80px;
  --lds-display-2-size: 60px;  --lds-display-2-line: 68px;
  --lds-display-3-size: 48px;  --lds-display-3-line: 56px;
  --lds-heading-1-size: 40px;  --lds-heading-1-line: 48px;
  --lds-heading-2-size: 32px;  --lds-heading-2-line: 40px;
  --lds-heading-3-size: 24px;  --lds-heading-3-line: 32px;
  --lds-heading-4-size: 20px;  --lds-heading-4-line: 28px;
  --lds-heading-5-size: 16px;  --lds-heading-5-line: 24px;
  --lds-heading-6-size: 14px;  --lds-heading-6-line: 20px;
  --lds-subtitle-1-size: 20px; --lds-subtitle-1-line: 32px;
  --lds-subtitle-2-size: 16px; --lds-subtitle-2-line: 24px;
  --lds-body-1-size: 18px;     --lds-body-1-line: 28px;
  --lds-body-2-size: 16px;     --lds-body-2-line: 24px;
  --lds-body-3-size: 14px;     --lds-body-3-line: 20px;
  --lds-label-1-size: 14px;    --lds-label-1-line: 20px;
  --lds-label-2-size: 12px;    --lds-label-2-line: 16px;
  --lds-caption-size: 12px;    --lds-caption-line: 16px;
  --lds-overline-size: 12px;   --lds-overline-line: 16px;
  --lds-code-size: 13px;       --lds-code-line: 20px;

  /* --- Motion --------------------------------------------------------
   * Duration scales with distance travelled, not with importance. A 200ms
   * fade and a 200ms full-screen slide do not feel the same.
   */
  --lds-duration-instant: 0ms;
  --lds-duration-fast: 100ms;
  --lds-duration-quick: 150ms;
  --lds-duration-normal: 200ms;
  --lds-duration-slow: 300ms;
  --lds-duration-slower: 500ms;

  --lds-ease-standard: cubic-bezier(0.2, 0, 0, 1);
  --lds-ease-enter: cubic-bezier(0, 0, 0, 1);
  --lds-ease-exit: cubic-bezier(0.3, 0, 1, 1);
  --lds-ease-emphasised: cubic-bezier(0.2, 0, 0, 1.2);
  --lds-ease-linear: linear;

  --lds-transition-colors:
    color var(--lds-duration-quick) var(--lds-ease-standard),
    background-color var(--lds-duration-quick) var(--lds-ease-standard),
    border-color var(--lds-duration-quick) var(--lds-ease-standard),
    box-shadow var(--lds-duration-quick) var(--lds-ease-standard);

  /* --- Z-index -------------------------------------------------------
   * A fixed ladder. Anything that needs a z-index picks a rung; nobody
   * writes z-index: 9999 because there is nowhere left to go.
   */
  --lds-z-base: 0;
  --lds-z-raised: 10;
  --lds-z-sticky: 100;
  --lds-z-header: 200;
  --lds-z-drawer: 300;
  --lds-z-overlay: 400;
  --lds-z-modal: 500;
  --lds-z-popover: 600;
  --lds-z-toast: 700;
  --lds-z-tooltip: 800;

  /* --- Layout: grid + density ---------------------------------------
   * Density shifts gutters and margins only; column count is a function of
   * viewport alone. Set --lds-density on a container to change it locally,
   * or on :root for the whole app.
   */
  --lds-grid-columns: 12;
  --lds-grid-gutter: 16px;
  --lds-grid-margin: 40px;
  --lds-container-max: 1440px;

  /* --- Sizing --------------------------------------------------------- */
  --lds-control-height-sm: 32px;
  --lds-control-height-md: 40px;
  --lds-control-height-lg: 48px;
  --lds-target-min: 44px;   /* WCAG 2.5.8 target size */
  --lds-icon-sm: 16px;
  --lds-icon-md: 20px;
  --lds-icon-lg: 24px;
  --lds-icon-xl: 32px;

  --lds-focus-ring-width: 2px;
  --lds-focus-ring-offset: 2px;
}

/* --- Breakpoint ladder ------------------------------------------------
 * XS   320-479    2 columns
 * S    480-767    6 columns
 * M    768-1023   6 columns
 * L    1024-1365  12 columns
 * XL   1366-1583  12 columns
 * 2XL  1584-1919  12 columns
 * 3XL  1920+      12 columns
 * Designed mobile-up: each block only states what changes.
 * ------------------------------------------------------------------- */
@media (max-width: 479px) {
  :root { --lds-grid-columns: 2; --lds-grid-gutter: 16px; --lds-grid-margin: 16px; }
}
@media (min-width: 480px) and (max-width: 767px) {
  :root { --lds-grid-columns: 6; --lds-grid-gutter: 16px; --lds-grid-margin: 16px; }
}
@media (min-width: 768px) and (max-width: 1023px) {
  :root { --lds-grid-columns: 6; --lds-grid-gutter: 16px; --lds-grid-margin: 32px; }
}
@media (min-width: 1024px) and (max-width: 1365px) {
  :root { --lds-grid-columns: 12; --lds-grid-gutter: 16px; --lds-grid-margin: 40px; }
}
@media (min-width: 1366px) and (max-width: 1583px) {
  :root { --lds-grid-columns: 12; --lds-grid-gutter: 16px; --lds-grid-margin: 48px; }
}
@media (min-width: 1584px) and (max-width: 1919px) {
  :root { --lds-grid-columns: 12; --lds-grid-gutter: 24px; --lds-grid-margin: 64px; }
}
@media (min-width: 1920px) {
  :root { --lds-grid-columns: 12; --lds-grid-gutter: 32px; --lds-grid-margin: 72px; }
}

/* Density modifiers. Apply to :root or to any container. */
[data-density="compact"] {
  --lds-grid-gutter: 16px;
  --lds-control-height-sm: 28px;
  --lds-control-height-md: 32px;
  --lds-control-height-lg: 40px;
}
[data-density="comfortable"] {
  --lds-grid-gutter: 32px;
  --lds-control-height-sm: 36px;
  --lds-control-height-md: 48px;
  --lds-control-height-lg: 56px;
}

/* Compact type ramp below 1024px. Display and heading sizes step down one
   rung; body, label and caption do not move. */
@media (max-width: 1023px) {
  :root {
    --lds-display-1-size: 48px;  --lds-display-1-line: 56px;
    --lds-display-2-size: 40px;  --lds-display-2-line: 48px;
    --lds-display-3-size: 32px;  --lds-display-3-line: 40px;
    --lds-heading-1-size: 32px;  --lds-heading-1-line: 40px;
    --lds-heading-2-size: 24px;  --lds-heading-2-line: 32px;
    --lds-heading-3-size: 20px;  --lds-heading-3-line: 28px;
    --lds-heading-4-size: 18px;  --lds-heading-4-line: 24px;
    --lds-subtitle-1-size: 18px; --lds-subtitle-1-line: 28px;
    --lds-body-1-size: 16px;     --lds-body-1-line: 24px;
  }
}

/* Reduced motion: collapse every duration rather than disabling transitions
   one by one. Components stay declarative; the token layer honours the
   preference. */
@media (prefers-reduced-motion: reduce) {
  :root {
    --lds-duration-fast: 0ms;
    --lds-duration-quick: 0ms;
    --lds-duration-normal: 0ms;
    --lds-duration-slow: 0ms;
    --lds-duration-slower: 0ms;
  }
}

/* Forced-colors / high-contrast: let the OS palette through and keep the
   focus ring visible, which is the one thing forced-colors commonly loses. */
@media (forced-colors: active) {
  :root { --lds-border-focus: Highlight; }
  * { forced-color-adjust: auto; }
}
