/* ═══════════════════════════════════════════════════════════════════════════
   DESIGN SYSTEM — EIGHT THEMES
   Ported from the golfgen dashboard (canonical source:
   golfgen-dashboard/docs/GolfGen_Dashboard_Design_System.html, v5.0).

   Clarity · Cockpit · Broadsheet · Constructivist · GG(house)
   + Terminal · Swiss · Warm (2026-10-02) — eight themes; design/themes.js
   groups them into Light / Dark for the picker (each block's color-scheme).

   Applied as ONE class on <body> by ThemeContext. Each block redefines the
   semantic tokens the ESM components already read — plus every ESM-specific
   alias (--card, --txt*, --border, --card-bg, --rule, --rad-card …) so the whole
   app re-skins with zero component edits.

   Specificity: body.<theme> (0,1,1) beats :root (0,1,0) in App.css, and this
   file is imported AFTER App.css so equal-specificity ties also resolve here.

   INVARIANTS (never change per theme): 8-pt grid · semantic up/dn/warn ·
   tabular right-aligned figures · 3-tier hierarchy. Components must read
   semantic tokens, never raw hex.
   ═══════════════════════════════════════════════════════════════════════════ */

/* Shared alias mapping — every theme block sets the primitives below
   (--acc --acc2 --up --dn --warn --t1 --t2 --t3 --surf --raise --line --bg
   --rad --on-acc --fnum --flab --fbody --shadow-sm), and this rule derives
   the ESM-specific aliases from them exactly once. */
:where(body.clarity, body.cockpit, body.broadsheet, body.constructivist,
       body.gg, body.swiss, body.contrast, body.aurora, body.mono, body.dusk, [data-theme]) {
  /* :where() -> specificity 0. This alias block enumerates every theme, so a
     theme it has not been told about would inherit the previous theme's
     values. Zeroing it lets design/tokens.css derive these from the
     contract; adding [data-theme] means a NEW theme picks them up here. */
  /* surfaces */
  --bg-page: var(--bg);
  --bg2: var(--surf);
  --surface: var(--surf);
  --card: var(--raise);
  --card2: var(--surf);
  --card-bg: var(--raise);
  --chip-bg: var(--surf);
  /* text */
  --ink: var(--t1);
  --txt: var(--t1);
  --txt2: var(--t2);
  --txt3: var(--t3);
  --txt4: var(--t3);
  --muted: var(--t2);
  --text-1: var(--t1);
  --text-2: var(--t2);
  --text-3: var(--t3);
  /* lines */
  --brd: var(--line);
  --border: var(--line);
  --rule: var(--line);
  --card-border: var(--line);
  /* accent */
  /* --acc-wash: the hue used for NEUTRAL UI-state fills (hover/selected/
     unread/"today" backgrounds) — everywhere this file's own components use
     color-mix(in srgb, var(--acc) N%, transparent) as a soft background.
     Defaults to --acc itself (Clarity/GG: accent is a calm blue/teal, safe
     to wash). Overridden to --acc2 inside Cockpit/Broadsheet/Constructivist
     below, where --acc IS --dn (the brand's only accent doubles as the
     negative/alert color) -- washing a generic hover state in that hue both
     misreads as "alert" and, composited over Broadsheet's warm --surf
     (#FBE8D8)/--bg (#FFF1E5), computes to a visible salmon/pink rather than
     the neutral tint every other theme gets at the same opacity (audited
     2026-09-29: 12% #E3120B over #FBE8D8 ≈ rgb(248,206,191)). Reserve plain
     --acc for TRUE brand-accent emphasis (a solid fill/border/text), never
     a translucent wash, in these three themes. */
  --acc-wash: var(--acc);
  --acc-hover: var(--acc2);
  --acc-soft: color-mix(in srgb, var(--acc-wash) 12%, transparent);
  --acc-border: color-mix(in srgb, var(--acc-wash) 30%, transparent);
  --btn-bg: var(--acc);
  --btn-text: var(--on-acc);
  --teal: var(--acc);
  --blue-active: var(--acc);
  --blue-hover: var(--acc2);
  --neg: var(--dn);
  /* radii — derived from the theme's base radius */
  --rad-card: var(--rad);
  --rad-panel: calc(var(--rad) + 4px);
  --rad-input: calc(var(--rad) * 0.5);
  --rad-tight: 4px;
  --rad-pill: 980px;
  --card-shadow: var(--shadow-sm);
  --space-5: 20px;
  --font: var(--fbody);          /* App.css body{} reads --font */
  --kicker: var(--t2);

  background: var(--bg);
  color: var(--t1);
  font-family: var(--fbody);
  font-variant-numeric: tabular-nums;
  transition: background .25s ease, color .25s ease;
}

/* 01 · CLARITY — Apple/iOS HIG · white canvas, blue accent, calm.
   ESM's house theme: Clarity Blue is the single accent. */
/* -- TEXT-SAFE VARIANTS -----------------------------------------------
   --warn/--up/--dn/--acc are BRAND/FILL colours. Several fail WCAG AA 4.5:1
   as TEXT on their own card surface, and an audit of 120 files found they are
   used as text far more than as fill:
       --dn 351x   --acc 235x   --up 195x   --warn 98x
   Worst was --warn on constructivist at 1.40:1 -- below even the 3.0
   large-text floor, i.e. effectively invisible, in 98 places.

   Darkening the BASE tokens would gut the design language (clarity's #FF9500
   orange -> brown, constructivist's #F2C014 yellow -> olive). So base tokens
   keep their brand value for fills/borders/badges, and TEXT uses these
   variants. Where a token already passes, the variant aliases it -- no visual
   change at all. Only 6 values across 3 themes actually differ.
   Recompute with the token-contrast audit if a base colour ever changes.  */
/* -- PER-THEME BADGE-TEXT OVERRIDES ------------------------------------
   design/tokens.css:103-105 sets --on-up/--on-dn/--on-warn to a single
   GLOBAL #FFFFFF for text sitting on a --up/--dn/--warn filled background
   (badges, buttons). Measured per theme: 11 of 15 combinations fail WCAG AA
   with a fixed white — worst clarity --on-warn 2.20:1, constructivist
   --on-warn 1.70:1, gg --on-up 2.28:1. These state colours are deliberately
   NOT touched (they are correct as fills/borders); each theme instead picks
   whichever of black/white actually passes against ITS OWN --up/--dn/--warn,
   verified to clear 4.5:1 in every one of the 15 cases.                   */
body.clarity, [data-theme="clarity"] {
  --acc:#0071E3; --acc2:#2E8FFF; --up:#059669; --dn:#DC2626; --warn:#FF9500;
  --t1:#1A2744; --t2:#6E6E73; --t3:#6F6F76;
  --surf:#F5F5F7; --raise:#FFFFFF; --line:#E3E3E6;
  --bg:#FBFBFD; --rad:16px; --on-acc:#FFFFFF;
  --brd-soft:rgba(227,227,230,.6); --brd-str:#D1D1D6; --surface-3:#ECECEE;
  /* system-ui FIRST: -apple-system ignores font-variant-numeric:tabular-nums
     in Chrome (digits render proportional), which breaks design-system rule 3
     (tabular, right-aligned figures). system-ui honours it. */
  --fnum:system-ui,-apple-system,BlinkMacSystemFont,'SF Pro Display','Segoe UI',sans-serif;
  --flab:system-ui,-apple-system,BlinkMacSystemFont,'SF Pro Text','Segoe UI',sans-serif;
  --fbody:system-ui,-apple-system,BlinkMacSystemFont,'SF Pro Text','Segoe UI',sans-serif;
  --shadow-sm:0 2px 12px rgba(0,0,0,.04);
  --shadow:0 1px 3px rgba(0,0,0,.04),0 8px 24px rgba(0,0,0,.06);
  color-scheme: light;
  --brand-rx:1.28px; --brand-tr:-.028em; --brand-tt:none; /* Shelf mark / wordmark */
  --warn-text:#AD6500;        /* 4.53:1 */
  --up-text:#05875E;          /* 4.53:1 */
  --dn-text:var(--dn);        /* alias */
  --acc-text:var(--acc);      /* alias */
  --chart-plan-text:var(--t3); /* alias — chart-plan is already t3 here, 4.99:1 on --raise */
  /* --chart-4 (#AF52DE) is only 4.13:1 on --raise -- fails AA as DOM text
     (Merchant Pages Audit, 2026-08-31; same problem class as chart-plan
     above, LadderPlan.jsx's Fcst Intelligence column being the concrete
     case that surfaced it). Darkened along the same hue to clear 4.5:1,
     same technique as --up-text/--warn-text above -- never touches
     --chart-4 itself, which stays correct as an SVG stroke/fill. */
  --chart-4-text:#A843DB;      /* 4.69:1 */
  --on-up:#000000;    /* per-theme override */
  --on-dn:#FFFFFF;    /* per-theme override */
  --on-warn:#000000;  /* per-theme override */
}

/* 02 · COCKPIT — Tesla · near-black, red flare, Montserrat, dense */
body.cockpit, [data-theme="cockpit"] {
  --acc:#E82127; --acc2:#5C636E; --up:#2FD25F; --dn:#E82127; --warn:#E8A33A;
  --t1:#FFFFFF; --t2:#A0A4AB; --t3:#9096A0;   /* lifted from #6B6F76 (3.3:1) → 5.6:1 on --raise */
  --surf:#15161A; --raise:#1D1E22; --line:#2A2B30;
  --bg:#0A0A0B; --rad:8px; --on-acc:#FFFFFF;
  --acc-wash: var(--acc2);   /* --acc IS --dn here; wash neutral states in the gray secondary instead */
  --brd-soft:#202126; --brd-str:#353740; --surface-3:#22252C;
  --fnum:"Montserrat",sans-serif; --flab:"Montserrat",sans-serif; --fbody:"Montserrat",sans-serif;
  --shadow-sm:0 1px 0 rgba(255,255,255,.03) inset;
  --shadow:0 0 0 1px rgba(255,255,255,.02) inset,0 12px 36px rgba(0,0,0,.6);
  color-scheme: dark;
  --brand-rx:0.64px; --brand-tr:.04em; --brand-tt:uppercase; /* Shelf mark / wordmark */
  --warn-text:var(--warn);    /* alias */
  --up-text:var(--up);        /* alias */
  --dn-text:#FF2D33;          /* 4.50:1 */
  --acc-text:#FF2D33;         /* 4.50:1 */
  --chart-plan-text:var(--t3); /* alias — chart-plan is already t3 here, 5.60:1 on --raise */
  --chart-4-text:var(--chart-4); /* alias — chart-4 (#E8726F) already 5.60:1 on --raise */
  --on-up:#000000;    /* per-theme override */
  --on-dn:#000000;    /* per-theme override */
  --on-warn:#000000;  /* per-theme override */
}

/* 03 · BROADSHEET — FT/newspaper · warm paper, serif, narrate */
body.broadsheet, [data-theme="broadsheet"] {
  --acc:#E3120B; --acc2:#0F5499; --up:#0F5499; --dn:#E3120B; --warn:#B5731A;
  --t1:#2B2724; --t2:#6B635C; --t3:#6E655D;   /* darkened from #8A8078 (3.67:1) → 5.4:1 on --raise */
  --surf:#FBE8D8; --raise:#FFF8F0; --line:#E6D8C9;
  --bg:#FFF1E5; --rad:6px; --on-acc:#FFFFFF;
  --acc-wash: var(--acc2);   /* --acc IS --dn here; a translucent --acc wash over this warm --surf reads as pink (audited 2026-09-29) */
  --brd-soft:#EFE3D6; --brd-str:#D8C7B5; --surface-3:#F3E0CF;
  --fnum:"Newsreader",Georgia,serif; --flab:"Space Grotesk",sans-serif; --fbody:"Newsreader",Georgia,serif;
  --shadow-sm:0 1px 2px rgba(43,39,36,.1);
  --shadow:0 1px 3px rgba(43,39,36,.08),0 10px 26px -12px rgba(43,39,36,.18);
  color-scheme: light;
  --brand-rx:0.48px; --brand-tr:-.015em; --brand-tt:none; /* Shelf mark / wordmark */
  --warn-text:#A16617;        /* 4.50:1 */
  --up-text:var(--up);        /* alias */
  --dn-text:var(--dn);        /* alias */
  --acc-text:var(--acc);      /* alias */
  --chart-plan-text:var(--acc); /* alias — matches --acc-text; chart-plan is --acc here, 4.58:1 on --raise */
  --chart-4-text:var(--warn-text); /* alias — chart-4 (#B5731A) IS --warn here; reuse its already-verified 4.50:1 -text */
  --on-up:#FFFFFF;    /* per-theme override */
  --on-dn:#FFFFFF;    /* per-theme override */
  --on-warn:#000000;  /* per-theme override */
}

/* 04 · CONSTRUCTIVIST — bold blocks, hard edges, Jost, express */
body.constructivist, [data-theme="constructivist"] {
  --acc:#E1251B; --acc2:#114BB5; --up:#114BB5; --dn:#E1251B; --warn:#F2C014;
  --t1:#1A1A1A; --t2:#5A564E; --t3:#6A6459;   /* 4.64 → 5.9:1 */
  --surf:#FFFFFF; --raise:#FFFFFF; --line:#1A1A1A;
  --bg:#EFE8D7; --rad:0px; --on-acc:#FFFFFF;
  --acc-wash: var(--acc2);   /* --acc IS --dn here; wash neutral states in the blue secondary instead */
  --brd-soft:#C9C2B2; --brd-str:#1A1A1A; --surface-3:#F2EDE0;
  --fnum:"Jost",sans-serif; --flab:"Jost",sans-serif; --fbody:"Jost",sans-serif;
  --shadow-sm:0 1px 0 #1A1A1A;
  --shadow:0 2px 0 #1A1A1A;
  color-scheme: light;
  --brand-rx:0px; --brand-tr:.035em; --brand-tt:uppercase; /* Shelf mark / wordmark */
  --warn-text:#91730C;        /* 4.50:1 */
  --up-text:var(--up);        /* alias */
  --dn-text:var(--dn);        /* alias */
  --acc-text:var(--acc);      /* alias */
  --chart-plan-text:var(--t1); /* alias — chart-plan is already t1 here, 17.4:1 on --raise */
  /* --chart-4 (#8A8478) is only 3.72:1 on --raise -- fails AA. Darkened
     along the same hue, same technique as --warn-text above. */
  --chart-4-text:#7A7469;      /* 4.63:1 */
  --on-up:#FFFFFF;    /* per-theme override */
  --on-dn:#FFFFFF;    /* per-theme override */
  --on-warn:#000000;  /* per-theme override */
}

/* 05 · GG — house style · refined midnight, teal, Sora */
body.gg, [data-theme="gg"] {
  --acc:#2ECFAA; --acc2:#E87830; --up:#22C55E; --dn:#FF5A5F; --warn:#E87830;
  --t1:#FFFFFF; --t2:#8B94A3; --t3:#8892A1;   /* lifted from #5A6473 (2.7:1) → 5.1:1 on --raise */
  --surf:#151B24; --raise:#1A212C; --line:#222A35;
  --bg:#090C11; --rad:14px; --on-acc:#06241C;
  --brd-soft:#1A212C; --brd-str:#2C3744; --surface-3:#222A35;
  --fnum:"Sora",sans-serif; --flab:"Space Grotesk",sans-serif; --fbody:"Sora",sans-serif;
  --shadow-sm:0 1px 3px rgba(0,0,0,.5);
  --shadow:0 1px 0 rgba(255,255,255,.03) inset,0 12px 36px rgba(0,0,0,.55);
  color-scheme: dark;
  --brand-rx:1.12px; --brand-tr:-.015em; --brand-tt:none; /* Shelf mark / wordmark */
  --warn-text:var(--warn);    /* alias */
  --up-text:var(--up);        /* alias */
  --dn-text:var(--dn);        /* alias */
  --acc-text:var(--acc);      /* alias */
  --chart-plan-text:var(--acc2); /* chart-plan is --acc2 (#E87830) here, no prior -text alias covered it; verified 5.52:1 on --raise */
  --chart-4-text:var(--chart-4); /* alias — chart-4 (#A78BFA, inherited from :root) already 5.95:1 on --raise */
  --on-up:#000000;    /* per-theme override */
  --on-dn:#000000;    /* per-theme override */
  --on-warn:#000000;  /* per-theme override */
}

/* 07 · SWISS — International Typographic · white, black, one vermilion accent */
body.swiss, [data-theme="swiss"] {
  --acc:#FF4F00; --acc2:#111111; --up:#0B7A3B; --dn:#B3141C; --warn:#B45F00;
  --t1:#0A0A0A; --t2:#5A5A5A; --t3:#6B6B6B;
  --surf:#F3F3F1; --raise:#FFFFFF; --line:#DEDEDA;
  --bg:#FFFFFF; --rad:0px; --on-acc:#0A0A0A;
  --acc-wash: var(--acc2);   /* wash neutral states in black -> a plain grey, never an orange tint */
  --brd-soft:#EAEAE6; --brd-str:#0A0A0A; --surface-3:#EBEBE7;
  --fnum:"Inter Tight",Helvetica,Arial,sans-serif;
  --flab:"Inter Tight",Helvetica,Arial,sans-serif;
  --fbody:"Inter Tight",Helvetica,Arial,sans-serif;
  --shadow-sm:none;
  --shadow:none;
  color-scheme: light;
  --brand-rx:0px; --brand-tr:-.03em; --brand-tt:none; /* Shelf mark / wordmark */
  --warn-text:#9C5200;        /* 5.80:1 on --raise, 5.22:1 on --surf */
  --up-text:var(--up);        /* alias — 5.44:1 */
  --dn-text:var(--dn);        /* alias — 6.92:1 */
  --acc-text:#CC3B00;         /* 5.01:1 on --raise, 4.51:1 on --surf */
  --chart-plan-text:var(--acc-text); /* chart-plan is --acc here */
  --chart-4-text:var(--chart-4); /* alias — #2F5BEA, 5.52:1 on --raise */
  --on-up:#FFFFFF;    /* per-theme override */
  --on-dn:#FFFFFF;    /* per-theme override */
  --on-warn:#FFFFFF;  /* per-theme override — 4.59:1 */
}

/* 08 · CONTRAST — WCAG-AAA light · pure black on white, thick rules, Atkinson Hyperlegible */
body.contrast, [data-theme="contrast"] {
  --acc:#0033CC; --acc2:#000000; --up:#006B2D; --dn:#B00020; --warn:#8A4B00;
  --t1:#000000; --t2:#1A1A1A; --t3:#3D3D3D;
  --surf:#F2F2F2; --raise:#FFFFFF; --line:#000000;
  --bg:#FFFFFF; --rad:4px; --on-acc:#FFFFFF;
  --acc-wash: var(--acc2);
  --brd-soft:#595959; --brd-str:#000000; --surface-3:#E6E6E6;
  --fnum:"Atkinson Hyperlegible",system-ui,Arial,sans-serif;
  --flab:"Atkinson Hyperlegible",system-ui,Arial,sans-serif;
  --fbody:"Atkinson Hyperlegible",system-ui,Arial,sans-serif;
  --shadow-sm:none; --shadow:none;
  color-scheme: light;
  --brand-rx:0.32px; --brand-tr:0; --brand-tt:none;
  --warn-text:var(--warn);    /* alias — 6.80:1 on --raise */
  --up-text:var(--up);        /* alias — 6.69:1 */
  --dn-text:var(--dn);        /* alias — 7.33:1 */
  --acc-text:var(--acc);      /* alias — 8.95:1 */
  --chart-plan-text:var(--t3);
  --chart-4-text:var(--chart-4);
  --on-up:#FFFFFF; --on-dn:#FFFFFF; --on-warn:#FFFFFF;
}

/* 09 · AURORA — frosted glass over a violet-to-blue glow · Plus Jakarta Sans */
body.aurora, [data-theme="aurora"] {
  --acc:#9B8CFF; --acc2:#4CC9F0; --up:#34D399; --dn:#FB7185; --warn:#FBBF24;
  --t1:#F4F3FF; --t2:#B8B5DC; --t3:#9F9BCB;
  --surf:#15132B; --raise:#1B1838; --line:#2C2850;
  --bg:#0B0A1A; --rad:18px; --on-acc:#0B0A1A;
  --brd-soft:#221F44; --brd-str:#3C3770; --surface-3:#262250;
  --fnum:"Plus Jakarta Sans",system-ui,sans-serif;
  --flab:"Plus Jakarta Sans",system-ui,sans-serif;
  --fbody:"Plus Jakarta Sans",system-ui,sans-serif;
  --shadow-sm:0 4px 24px rgba(10,6,40,.35);
  --shadow:0 0 0 1px rgba(255,255,255,.06) inset,0 18px 48px rgba(6,3,30,.55);
  color-scheme: dark;
  --brand-rx:1.12px; --brand-tr:-.01em; --brand-tt:none;
  --warn-text:var(--warn); --up-text:var(--up); --dn-text:var(--dn); --acc-text:var(--acc);
  --chart-plan-text:var(--t3);
  --chart-4-text:var(--chart-4);
  --on-up:#000000; --on-dn:#000000; --on-warn:#000000;
}

/* 10 · MONO — true-black OLED · greys only, colour reserved for up/down · Geist */
body.mono, [data-theme="mono"] {
  --acc:#FFFFFF; --acc2:#A3A3A3; --up:#4ADE80; --dn:#F87171; --warn:#FBBF24;
  --t1:#FAFAFA; --t2:#A3A3A3; --t3:#8F8F8F;
  --surf:#0A0A0A; --raise:#0F0F0F; --line:#262626;
  --bg:#000000; --rad:10px; --on-acc:#000000;
  --acc-wash: var(--acc2);
  --brd-soft:#1A1A1A; --brd-str:#3A3A3A; --surface-3:#171717;
  --fnum:"Geist",system-ui,sans-serif;
  --flab:"Geist",system-ui,sans-serif;
  --fbody:"Geist",system-ui,sans-serif;
  --shadow-sm:none; --shadow:none;
  color-scheme: dark;
  --brand-rx:0.64px; --brand-tr:-.02em; --brand-tt:none;
  --warn-text:var(--warn); --up-text:var(--up); --dn-text:var(--dn); --acc-text:var(--acc);
  --chart-plan-text:var(--t3);
  --chart-4-text:var(--chart-4);
  --on-up:#000000; --on-dn:#000000; --on-warn:#000000;
}

/* 11 · DUSK — muted slate, low glare · desaturated Nord-style palette · IBM Plex Sans */
body.dusk, [data-theme="dusk"] {
  --acc:#88C0D0; --acc2:#B48EAD; --up:#A3BE8C; --dn:#E8949C; --warn:#EBCB8B;
  --t1:#E5E9F0; --t2:#BAC3D1; --t3:#A3AEC0;
  --surf:#2A3240; --raise:#303A4A; --line:#3E4A5E;
  --bg:#232A36; --rad:10px; --on-acc:#1E2430;
  --brd-soft:#374154; --brd-str:#4C5970; --surface-3:#394456;
  --fnum:"IBM Plex Sans",system-ui,sans-serif;
  --flab:"IBM Plex Sans",system-ui,sans-serif;
  --fbody:"IBM Plex Sans",system-ui,sans-serif;
  --shadow-sm:0 1px 2px rgba(10,14,22,.25);
  --shadow:0 6px 20px rgba(10,14,22,.28);
  color-scheme: dark;
  --brand-rx:0.64px; --brand-tr:0; --brand-tt:none;
  --warn-text:var(--warn); --up-text:var(--up); --dn-text:var(--dn); --acc-text:var(--acc);
  --chart-plan-text:var(--t3);
  --chart-4-text:var(--chart-4);
  --on-up:#000000; --on-dn:#000000; --on-warn:#000000;
}

/* Sidebar is a themed surface for every theme now (App.css .app-sidebar
   reads --surf/--line/--t1-3/--acc directly) — no per-theme override needed. */

/* ── Per-theme "feel": Constructivist is hard-edged; Broadsheet is hairline ── */
/* ── Derived aliases — added 2026-08-23 ────────────────────────────────────────
   These seven were REFERENCED but never DEFINED: --text-muted alone appears 85
   times and --line-soft 32, overwhelmingly with no fallback. An undefined custom
   property makes the declaration invalid at computed-value time, so the property
   silently INHERITS instead of erroring — and because border-color inherits from
   color, a "soft line" could paint as a strong text-coloured border. Nothing
   crashes, nothing logs, and it looks merely slightly wrong, which is why it
   survived.

   Defined as aliases of existing per-theme tokens rather than literal hex, so all
   five themes stay correct automatically and nobody has to remember to update
   five blocks. Declared after the theme blocks with equal specificity so the
   var() references resolve against whichever theme is active. ★ */
body.clarity, [data-theme="clarity"],
body.cockpit, [data-theme="cockpit"],
body.broadsheet, [data-theme="broadsheet"],
body.constructivist, [data-theme="constructivist"],
body.gg, [data-theme="gg"],
body.swiss, [data-theme="swiss"],
body.contrast, [data-theme="contrast"],
body.aurora, [data-theme="aurora"],
body.mono, [data-theme="mono"],
body.dusk, [data-theme="dusk"] {
  --text-muted: var(--t2);                 /* secondary text, per-theme */
  --line-soft: var(--brd-soft);            /* the soft border that already exists */
  --danger: var(--dn);                     /* semantic down/negative */
  --success: var(--up);                    /* semantic up/positive */
  --space-7: 28px;                         /* 4px scale, matching --space-5:20px */
  --radius-sm: calc(var(--rad) * .5);      /* half the card radius */
  --accent-soft: color-mix(in srgb, var(--acc-wash) 12%, transparent);
}

body.constructivist [class*="card"],
body.constructivist table { border-radius: 0 !important; }
body.constructivist [class*="card"] { border: 2px solid #1A1A1A !important; }
body.broadsheet [class*="card"] { box-shadow: none !important; }
/* ── Structural "feel" — layout character, not just colour ───────────────────── */
/* Swiss: rules, not boxes — no card fill or frame, one heavy rule above each
   section, oversized flush-left titles, tight uppercase labels. */
body.swiss [class*="card"] { box-shadow: none !important; border-radius: 0 !important; background: transparent !important;
  border: 0 !important; border-top: 3px solid #0A0A0A !important; padding-top: 14px; }
body.swiss h1, body.swiss .page-title { font-size: 40px; letter-spacing: -.035em; font-weight: 700; line-height: 1.02; }
body.swiss th { text-transform: uppercase; letter-spacing: .08em; font-size: 10px; font-weight: 600; }
body.swiss table { border-collapse: collapse; }
body.swiss td, body.swiss th { border-left: 0 !important; border-right: 0 !important; }
body.swiss button, body.swiss .btn { border-radius: 0 !important; }

/* Contrast: every control is unmistakable — 2px frames, 3px focus ring, no tint-only states. */
body.contrast [class*="card"] { border: 2px solid #000 !important; box-shadow: none !important; }
body.contrast table td, body.contrast table th { border-bottom: 1px solid #000; }
body.contrast a { text-decoration: underline; text-underline-offset: 2px; }
body.contrast :focus-visible { outline: 3px solid #0033CC !important; outline-offset: 2px !important; }
body.contrast button, body.contrast input, body.contrast select { border: 2px solid #000 !important; }

/* Aurora: glass. A fixed violet/blue glow sits behind translucent, blurred panels. */
body.aurora { background:
    radial-gradient(900px 600px at 10% 4%, rgba(124,92,255,.55), transparent 60%),
    radial-gradient(800px 560px at 94% 10%, rgba(56,189,248,.38), transparent 60%),
    radial-gradient(900px 700px at 55% 105%, rgba(168,85,247,.34), transparent 60%),
    #0B0A1A fixed; }
body.aurora [class*="card"] { background: rgba(27,24,56,.55) !important; backdrop-filter: blur(18px) saturate(1.4);
  -webkit-backdrop-filter: blur(18px) saturate(1.4); border: 1px solid rgba(255,255,255,.09) !important; }
body.aurora button.primary, body.aurora .btn-primary { background: linear-gradient(135deg,#9B8CFF,#4CC9F0) !important; color:#0B0A1A !important; }

/* Mono: hairlines only, no fills, no shadow — numbers do the talking. */
body.mono [class*="card"] { background: transparent !important; box-shadow: none !important; border: 1px solid #262626 !important; }
body.mono table td { border-bottom: 1px solid #1A1A1A; }
body.mono :focus-visible { outline: 1px solid #FFFFFF; outline-offset: 2px; }

/* Dusk: soft and low-glare — gentle shadows, slower transitions, no pure white anywhere. */
body.dusk * { transition-duration: .22s; }
body.dusk [class*="card"] { box-shadow: 0 6px 20px rgba(10,14,22,.28) !important; border: 1px solid #3E4A5E !important; }

/* Theme picker (sidebar) — a Light / Dark switch, then that mode's themes.
   Click a mode to open its swatches; click a swatch to apply the theme. */
.theme-picker { display: flex; flex-direction: column; gap: 6px; padding: 0; }
.theme-modes { display: flex; gap: 4px; }
.theme-mode {
  flex: 1; display: flex; align-items: center; justify-content: center; gap: 5px;
  padding: 4px 6px; font: 600 11px var(--flab); color: var(--t2);
  background: transparent; border: 1px solid var(--line); border-radius: 6px;
  cursor: pointer; transition: background .12s ease, color .12s ease, border-color .12s ease;
}
.theme-mode:hover { color: var(--t1); border-color: var(--brd-str, var(--line)); }
.theme-mode.open { color: var(--t1); border-color: var(--acc-text, var(--acc)); background: var(--acc-soft); }
.theme-mode .tp-count { color: var(--t3); font-weight: 500; }
.theme-chips { display: flex; gap: 5px; flex-wrap: wrap; }
.theme-chip {
  width: 22px; height: 22px; border-radius: 6px; cursor: pointer;
  border: 2px solid transparent; padding: 0; flex-shrink: 0;
  transition: transform .12s ease, border-color .12s ease;
}
.theme-chip:hover { transform: scale(1.12); }
.theme-chip.active { border-color: var(--t1); box-shadow: 0 0 0 1px var(--bg); }
.theme-current { font: 500 10px var(--flab); color: var(--t3); }
