/*
 * product-tokens.css
 *
 * THE single token sheet for the Atlas product console (UI reconciliation,
 * founder-ruled 2026-08-12). This file replaces, by migration, the token
 * blocks previously duplicated across: portfolio-dash-d5.css,
 * marina-judgment-d5.css, exam-opening-frame-d5.css, room-d5.css, and the
 * inline TIME_MACHINE_CSS in exhibit_time_machine.py. Page CSS files keep
 * only page-layout rules; they must not redefine any token declared here.
 *
 * Founder rulings this file implements (recorded in the strategy folder's
 * action items; D-6 REVERSED 2026-08-14, light-first reskin 2026-08-15,
 * D-1 SUPERSEDED 2026-08-16):
 *   D-1  SUPERSEDED (founder, 2026-08-16). The product skin WAS IBM Plex
 *        Sans / IBM Plex Mono. The light-first reskin transcribed the
 *        ratified prototype's colour but deliberately held its FONTS back
 *        as a founder decision; the founder has now ruled the prototype's
 *        stacks apply. Body and heading take the prototype's system stack
 *        (system-ui, -apple-system, "Segoe UI", sans-serif) and mono takes
 *        its ui-monospace stack, on all four arms. Inter / DM Sans remains
 *        the marketing skin (geoliquefy-design/tokens.css).
 *        "One skeleton, two skins": the structural scale below is copied
 *        unchanged from the design harness; only the skin block differs.
 *        Type SIZES are untouched by this ruling (eyebrow 12px, body 15px
 *        stand); only the family stacks changed.
 *        NO SEPARATE HEADING FACE. The prototype declares exactly three
 *        font-family rules: body, .mono, and .display. Its headings carry
 *        size and weight only and INHERIT the body face, so --font-heading
 *        resolves to the same system stack rather than staying on a face
 *        the ruling retired. The prototype's Avenir stack belongs to its
 *        .display class alone and is NEVER a body face; no --font-display
 *        token is declared here, matching the prototype, which scopes it
 *        with a page rule rather than a token. Avenir appears nowhere in
 *        this sheet.
 *        The @font-face blocks below still self-host IBM Plex. They are
 *        left in place deliberately: an unreferenced face is never
 *        downloaded, so they cost nothing, and removing them (plus the
 *        .woff2 assets) is a separate change with its own asset tests.
 *   D-2  Outcomes get dedicated --outcome-* tokens; --warn-800 returns to
 *        warning semantics only and is never an outcome color again. That
 *        half of D-2 STANDS. Its ice-steel-cyan accent (#7FAFC6) is
 *        SUPERSEDED: the accent language is now brass and ember.
 *   D-6  REVERSED (founder, 2026-08-14: "the black really isn't helping").
 *        The product was dark-only; it is now LIGHT-FIRST, with dark as a
 *        prefers-color-scheme fallback. The shipped dark build was not at
 *        fault: it executed D-6 faithfully. This is a change of
 *        destination, not a defect.
 *
 * THE THREE ARMS, and why the light values appear TWICE. A light default
 * needs a bare :root block. But console.css (always loaded BEFORE this
 * file) carries its own :root[data-theme='light'] block at specificity
 * (0,2,0), which would beat a bare :root at (0,1,0) and repaint an
 * explicitly-light page in the retired marketing blue. So the light values
 * are declared under BOTH `:root` and `:root[data-theme='light']`: equal
 * specificity to console.css's, later load order, so this file wins. That
 * is the same load-order mechanism the D-6 note above described for dark,
 * and it is NOT a duplicate palette to be "de-duplicated" away. The source
 * artifact does the same thing for its dark arm, declaring it once in the
 * media block and once under [data-theme="dark"].
 *
 *   :root                                  light (the default everyone sees)
 *   :root[data-theme='light']              light, to beat console.css
 *   @media (prefers-color-scheme: dark)
 *     :root:not([data-theme='light'])      dark fallback, unless pinned light
 *   :root[data-theme='dark']               dark, explicit toggle wins
 *
 * Value provenance. The DARK arm and the light arm's surfaces, text and
 * instrument hues are transcribed from the ratified prototype
 * (SOURCE-OF-TRUTH-artifact-5bab5d0c.html). Its token names (--ground,
 * --panel, --ink, --brass) are the PROTOTYPE's vocabulary; this file keeps
 * the PRODUCT vocabulary and maps onto it, because 30 consumers already
 * read the product names. The mapping is anchored by identity, not guessed:
 * --dissent-600 #D9707F, --leg-susceptibility-600 #4FB0A8 and
 * --leg-opportunity-600 #7E93DD were already drawn from this same
 * prototype's dark arm (claret / teal / indigo), value for value.
 *
 *   ground -> --surface-0     ink   -> --on-surface-0   brass -> --accent-600
 *   panel  -> --surface-1     muted -> --on-surface-1   claret-> --dissent-600
 *   panel2 -> --surface-1-map                          teal  -> --leg-susceptibility-600
 *   chip-bg-> --surface-2                              indigo-> --leg-opportunity-600
 *   line   -> --border-divider                         shadow-> --shadow-sm
 *
 * TWO tokens are RETAINED rather than mapped, because taking the artifact's
 * value would have broken the contrast gate on the light arm:
 *   --on-surface-2  the artifact's faint #8FA0A6 measures 2.27:1 here and
 *                   this token fills real text, so the shipped console light
 *                   grey #4A4A4F (7.36:1) is kept instead.
 *   --success-700   console.css's light #1E7A43 measures 4.48:1 on
 *                   --surface-2, just under the bar, so the ruled green is
 *                   used rather than inventing a fifth hex.
 *
 * DL-A3, THE ONE DELIBERATE DEPARTURE FROM THE ARTIFACT. The artifact's
 * four text-carrying instrument hues fail 4.5:1 on light (brass 2.60,
 * green 3.05, teal 3.45, ember 3.54, each on chip-bg). Founder ruled
 * readability paramount, so the LIGHT arm darkens exactly those four, hue
 * preserved; the DARK arm keeps the artifact's hexes untouched. Same
 * light-derived-from-dark operation atlas/figures/base.py already ships
 * for print. Measured against ALL FOUR light surfaces (a three-surface
 * measurement that drops chip-bg reports a flattering 4.77/5.09/5.17/5.41
 * and has not earned the pass):
 *
 *   brass #B98A2E -> #856410   4.59:1    green #3E9663 -> #2E7049  4.97:1
 *   ember #C75B2E -> #A8471F   4.89:1    teal  #2E8A84 -> #246B66  5.21:1
 *
 * The accepted-failure set for LIGHT TEXT is EMPTY. Tokens that clear 3:1
 * but not 4.5:1 on light are marked MARKS ONLY below and must never carry
 * text there.
 *
 * Load order on a migrated page:
 *   design-tokens.css (legacy, until fully retired) -> console.css ->
 *   product-tokens.css -> page layout css
 */

/* ================================================================
   FONT LOADING (self-hosted, /static/fonts/, OFL-1.1: FONTS-LICENSE.txt)
   Declared ONCE here. Migrated pages must not carry their own copies.

   DORMANT since D-1 was superseded (2026-08-16): no token below names
   IBM Plex any more, so no @font-face here matches and none of these
   .woff2 files is fetched. Kept rather than deleted so retiring the
   self-hosted assets stays one deliberate change; see the D-1 note above.
   ================================================================ */

@font-face {
  font-family: 'IBM Plex Sans';
  src: url('/static/fonts/ibm-plex-sans-400.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'IBM Plex Sans';
  src: url('/static/fonts/ibm-plex-sans-500.woff2') format('woff2');
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'IBM Plex Sans';
  src: url('/static/fonts/ibm-plex-sans-600.woff2') format('woff2');
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'IBM Plex Sans';
  src: url('/static/fonts/ibm-plex-sans-700.woff2') format('woff2');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'IBM Plex Mono';
  src: url('/static/fonts/ibm-plex-mono-400.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'IBM Plex Mono';
  src: url('/static/fonts/ibm-plex-mono-500.woff2') format('woff2');
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'IBM Plex Mono';
  src: url('/static/fonts/ibm-plex-mono-600.woff2') format('woff2');
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}

/* ================================================================
   STRUCTURAL SKELETON (theme-independent)
   Copied unchanged from the design harness (design-tokens.css, W5d pass),
   plus the container tier collapse ruled in the reconciliation plan:
   eight ad-hoc page widths become three named shells plus the reading
   measure. Strays map to the nearest tier during page migration:
   900px (time machine) and 920px (opening frame) -> --shell-narrow;
   1240px (curated room) -> --shell; 1400px (portfolio below-fold)
   -> --shell-wide. The 480px error card is a component dimension, not a
   shell, and stays in error_pages.py.
   ================================================================ */

:root {
  /* ---- Layout: shells (container tier collapse) ---- */
  --shell-narrow: 1100px;  /* prose-led pages: coverage, methodology */
  --shell: 1200px;         /* console default, was --container-wide */
  --shell-wide: 1400px;    /* data-dense: portfolio below-fold */

  /* ---- Typography: weights ---- */
  --font-light: 300;
  --font-regular: 400;
  --font-medium: 500;
  --font-semibold: 600;
  --font-bold: 700;

  /* ---- Typography: fluid type scale ---- */
  --text-display: clamp(3.5rem, 2.6rem + 4.2vw, 5rem);
  --text-h1: clamp(2.5rem, 2.1rem + 1.8vw, 3rem);
  --text-h2: clamp(1.75rem, 1.55rem + 0.9vw, 2rem);
  --text-h3: clamp(1.25rem, 1.15rem + 0.45vw, 1.5rem);
  --text-h4: clamp(1.125rem, 1.075rem + 0.22vw, 1.25rem);
  --text-body-xl: 1.5rem;
  --text-body-l: 1.3125rem;
  --text-body-m: 1.0625rem;
  --text-body-s: 0.9375rem;
  --text-caption: 0.875rem;
  --text-micro: 0.75rem;   /* 12px: the floor. Nothing renders smaller. */

  /* ---- Typography: line heights ---- */
  --leading-tight: 1.1;
  --leading-marketing: 1.47059;
  --leading-dossier: 1.6;

  /* ---- Typography: measure ---- */
  --measure-body: 65ch;
  --measure-dossier: 75ch;

  /* ---- Typography: letter-spacing ---- */
  --tracking-display: -0.03em;
  --tracking-h1: -0.03em;
  --tracking-h2: -0.025em;
  --tracking-h3: -0.02em;
  --tracking-h4: -0.015em;
  --tracking-body: -0.011em;
  --tracking-body-s: -0.008em;
  --tracking-micro: 0.05em;
  --tracking-eyebrow: 0.12em;

  /* ---- Spacing (8pt grid) ---- */
  --space-1: 8px;
  --space-1-5: 12px;
  --space-2: 16px;
  --space-3: 24px;
  --space-4: 32px;
  --space-6: 48px;
  --space-8: 64px;
  --space-10: 80px;
  --space-12: 96px;
  --space-15: 120px;

  /* ---- Radius (console scale, ruled default for the product; the
     marketing 8/16/24px scale lives in the harness file, not here) ---- */
  --radius-sm: 4px;
  --radius-md: 6px;
  --radius-lg: 8px;
  --radius-full: 980px;

  /* ---- Motion ---- */
  --ease-default: ease;
  --ease-btn: cubic-bezier(0.25, 0.1, 0.25, 1);
  --ease-entrance: cubic-bezier(0.16, 1, 0.3, 1);
  --duration-instant: 0.1s;
  --duration-fast: 0.2s;
  --duration-base: 0.3s;
  --duration-slow: 0.5s;
  --duration-entrance: 0.8s;
  --duration-shimmer: 2.2s;

  /* ---- Icons ---- */
  --icon-stroke: 1.5px;
  --icon-size-default: 24px;
  --icon-size-compact: 20px;
}

/* ================================================================
   PRODUCT SKIN, ARM 1 of 3: LIGHT, THE DEFAULT (D-6 reversed)
   A bare :root, so a page that sets no data-theme at all renders light.
   ================================================================ */

:root {
  /* ---- Families (D-1 SUPERSEDED: the artifact's system stack) ---- */
  --font-body: system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-heading: system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, monospace;

  /* ---- Surfaces (artifact: ground / panel / chip-bg) ---- */
  --surface-0: #F3F6F5;
  --surface-1: #FFFFFF;
  --surface-2: #E6ECEA;
  --surface-1-map: #EBF0EF;

  /* ---- Glass panels (portfolio dash floating chrome). Light glass over
     the light ground: strong carries bars, rails and popups; soft carries
     banners and attribution. The zebra stripe is the table's even-row
     wash, an alpha over --surface-0. ---- */
  --glass-panel-strong: rgba(255, 255, 255, 0.90);
  --glass-panel-soft: rgba(255, 255, 255, 0.72);
  --zebra-stripe: rgba(0, 0, 0, 0.03);

  /* ---- On-accent: text sitting ON an --accent-600 fill (toggle thumb,
     checkbox check), 5.48:1 on light brass #856410 ---- */
  --on-accent: #FFFFFF;

  /* ---- On-surface / text (artifact: ink / muted / faint) ---- */
  --on-surface-0: #1B262B;   /* 12.92:1 worst surface */
  --on-surface-1: #5B6C72;   /*  4.58:1 worst surface */
  --on-surface-2: #4A4A4F;   /* 7.36:1 worst surface. RETAINED, not mapped.
    The artifact's --faint (#8FA0A6) measures 2.27:1 here and clears NEITHER
    the 4.5:1 text bar nor the 3:1 mark bar, and this token fills real <text>
    (figure axis labels, section headers, console metadata). The light arm
    therefore keeps the shipped, contrast-measured console light grey rather
    than adopting the artifact's value or inventing a fifth hex: the same
    "retain what is measured" move the status and outcome families take
    below. No carve-out is needed on this arm, and none is claimed.
    Note it sits DARKER than --on-surface-1; that tier inversion is the
    shipped light convention (console.css), not a mistake to correct. */

  /* ---- Accent (D-2's cyan SUPERSEDED: brass, per DL-A3) ---- */
  --accent-600: #856410;   /* 4.59:1 worst surface */
  --accent-700: #6B4F0D;   /* 6.38:1 worst surface */
  --accent-soft: rgba(133, 100, 16, 0.10);
  --accent-ring: rgba(133, 100, 16, 0.30);

  /* ---- Focus (DL-A2: a DEDICATED value, not var(--accent-600), so a
     future accent change cannot silently degrade the focus ring) ---- */
  --focus-ring: #856410;

  /* ---- Outcome colors (D-2). Print-side light palette, re-measured on
     these four surfaces: all four clear the 4.5:1 TEXT bar, which matters
     because --outcome-mixed is used as a text colour (console.css .chip
     outcome rules, portfolio, gallery). ---- */
  --outcome-indicated: #9E3B28;        /* 5.64:1 */
  --outcome-indicated-soft: rgba(158, 59, 40, 0.10);
  --outcome-mixed: #5E5A8C;            /* 5.29:1 */
  --outcome-mixed-soft: rgba(94, 90, 140, 0.10);
  --outcome-insufficient: #4A525C;     /* 6.62:1 */
  --outcome-insufficient-soft: rgba(74, 82, 92, 0.12);
  --outcome-not-indicated: #4A6355;    /* 5.47:1 */
  --outcome-not-indicated-soft: rgba(74, 99, 85, 0.10);

  /* ---- Status (system feedback, NOT outcomes) ---- */
  --danger-600: #C4291F;   /* 4.76:1 */
  --danger-fill: #C4291F;
  --danger-soft: rgba(196, 41, 31, 0.08);
  --success-700: #2E7049;  /* 4.97:1. The DL-A3 ruled green. console.css's
    light #1E7A43 measures 4.48:1 on --surface-2 and would be the only light
    text token below the bar; the ruled green is used instead of inventing a
    fifth hex, per DL-C1's "do not grow another accent". */
  --success-soft: rgba(46, 112, 73, 0.10);
  --warn-800: #8A5A00;     /* 4.95:1. Warnings only, never an outcome. */
  --warn-soft: rgba(138, 90, 0, 0.08);

  /* ---- Analytic families (R2). On LIGHT these clear the 3:1 graphical-mark
     bar but NOT the 4.5:1 text bar, so on this arm they are MARKS ONLY:
     strokes, borders, dots and fills, never a text colour. (On the dark arm
     they clear both, which is what the dark block's note records.) ---- */
  --dissent-600: #B44E60;              /* MARKS ONLY, 4.18:1 (artifact claret) */
  --dissent-soft: rgba(180, 78, 96, 0.12);
  --leg-susceptibility-600: #246B66;   /* 5.21:1 (DL-A3 teal), text-safe */
  --leg-opportunity-600: #5A6FB0;      /* MARKS ONLY, 4.05:1 (artifact indigo) */

  /* ---- Legacy outcome aliases, migration only ---- */
  --mixed-600: var(--outcome-mixed);
  --mixed-soft: var(--outcome-mixed-soft);
  --insufficient-600: var(--outcome-insufficient);
  --insufficient-soft: var(--outcome-insufficient-soft);

  /* ---- Borders (artifact --line) ---- */
  --border-subtle: rgba(20, 40, 40, 0.10);
  --border-strong: rgba(20, 40, 40, 0.18);
  --border-divider: #D5DDDB;

  /* ---- Scrim / shadows (artifact --shadow) ---- */
  --scrim: rgba(27, 38, 43, 0.45);
  --shadow-sm: 0 1px 3px rgba(20, 40, 40, 0.08);
  --shadow-md: 0 12px 30px rgba(20, 40, 40, 0.10);
  --shadow-lg: 0 24px 60px rgba(20, 40, 40, 0.14);
  --shadow-accent: 0 4px 12px rgba(133, 100, 16, 0.30);

  color-scheme: light;
}

/* ================================================================
   ARM 1b: the SAME light values under [data-theme='light'].
   Not a second palette. console.css ships its own
   :root[data-theme='light'] block at (0,2,0) and loads FIRST; a bare
   :root at (0,1,0) would lose to it and an explicitly-light page would
   repaint in the retired marketing blue. Equal specificity plus later
   load order is what makes "explicit light wins" actually true.
   ================================================================ */

:root[data-theme='light'] {
  /* ---- Families (D-1 SUPERSEDED: the artifact's system stack) ---- */
  --font-body: system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-heading: system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, monospace;

  /* ---- Surfaces (artifact: ground / panel / chip-bg) ---- */
  --surface-0: #F3F6F5;
  --surface-1: #FFFFFF;
  --surface-2: #E6ECEA;
  --surface-1-map: #EBF0EF;

  /* ---- Glass panels (portfolio dash floating chrome). Light glass over
     the light ground: strong carries bars, rails and popups; soft carries
     banners and attribution. The zebra stripe is the table's even-row
     wash, an alpha over --surface-0. ---- */
  --glass-panel-strong: rgba(255, 255, 255, 0.90);
  --glass-panel-soft: rgba(255, 255, 255, 0.72);
  --zebra-stripe: rgba(0, 0, 0, 0.03);

  /* ---- On-accent: text sitting ON an --accent-600 fill (toggle thumb,
     checkbox check), 5.48:1 on light brass #856410 ---- */
  --on-accent: #FFFFFF;

  /* ---- On-surface / text (artifact: ink / muted / faint) ---- */
  --on-surface-0: #1B262B;   /* 12.92:1 worst surface */
  --on-surface-1: #5B6C72;   /*  4.58:1 worst surface */
  --on-surface-2: #4A4A4F;   /* 7.36:1 worst surface. RETAINED, not mapped.
    The artifact's --faint (#8FA0A6) measures 2.27:1 here and clears NEITHER
    the 4.5:1 text bar nor the 3:1 mark bar, and this token fills real <text>
    (figure axis labels, section headers, console metadata). The light arm
    therefore keeps the shipped, contrast-measured console light grey rather
    than adopting the artifact's value or inventing a fifth hex: the same
    "retain what is measured" move the status and outcome families take
    below. No carve-out is needed on this arm, and none is claimed.
    Note it sits DARKER than --on-surface-1; that tier inversion is the
    shipped light convention (console.css), not a mistake to correct. */

  /* ---- Accent (D-2's cyan SUPERSEDED: brass, per DL-A3) ---- */
  --accent-600: #856410;   /* 4.59:1 worst surface */
  --accent-700: #6B4F0D;   /* 6.38:1 worst surface */
  --accent-soft: rgba(133, 100, 16, 0.10);
  --accent-ring: rgba(133, 100, 16, 0.30);

  /* ---- Focus (DL-A2: a DEDICATED value, not var(--accent-600), so a
     future accent change cannot silently degrade the focus ring) ---- */
  --focus-ring: #856410;

  /* ---- Outcome colors (D-2). Print-side light palette, re-measured on
     these four surfaces: all four clear the 4.5:1 TEXT bar, which matters
     because --outcome-mixed is used as a text colour (console.css .chip
     outcome rules, portfolio, gallery). ---- */
  --outcome-indicated: #9E3B28;        /* 5.64:1 */
  --outcome-indicated-soft: rgba(158, 59, 40, 0.10);
  --outcome-mixed: #5E5A8C;            /* 5.29:1 */
  --outcome-mixed-soft: rgba(94, 90, 140, 0.10);
  --outcome-insufficient: #4A525C;     /* 6.62:1 */
  --outcome-insufficient-soft: rgba(74, 82, 92, 0.12);
  --outcome-not-indicated: #4A6355;    /* 5.47:1 */
  --outcome-not-indicated-soft: rgba(74, 99, 85, 0.10);

  /* ---- Status (system feedback, NOT outcomes) ---- */
  --danger-600: #C4291F;   /* 4.76:1 */
  --danger-fill: #C4291F;
  --danger-soft: rgba(196, 41, 31, 0.08);
  --success-700: #2E7049;  /* 4.97:1. The DL-A3 ruled green. console.css's
    light #1E7A43 measures 4.48:1 on --surface-2 and would be the only light
    text token below the bar; the ruled green is used instead of inventing a
    fifth hex, per DL-C1's "do not grow another accent". */
  --success-soft: rgba(46, 112, 73, 0.10);
  --warn-800: #8A5A00;     /* 4.95:1. Warnings only, never an outcome. */
  --warn-soft: rgba(138, 90, 0, 0.08);

  /* ---- Analytic families (R2). On LIGHT these clear the 3:1 graphical-mark
     bar but NOT the 4.5:1 text bar, so on this arm they are MARKS ONLY:
     strokes, borders, dots and fills, never a text colour. (On the dark arm
     they clear both, which is what the dark block's note records.) ---- */
  --dissent-600: #B44E60;              /* MARKS ONLY, 4.18:1 (artifact claret) */
  --dissent-soft: rgba(180, 78, 96, 0.12);
  --leg-susceptibility-600: #246B66;   /* 5.21:1 (DL-A3 teal), text-safe */
  --leg-opportunity-600: #5A6FB0;      /* MARKS ONLY, 4.05:1 (artifact indigo) */

  /* ---- Legacy outcome aliases, migration only ---- */
  --mixed-600: var(--outcome-mixed);
  --mixed-soft: var(--outcome-mixed-soft);
  --insufficient-600: var(--outcome-insufficient);
  --insufficient-soft: var(--outcome-insufficient-soft);

  /* ---- Borders (artifact --line) ---- */
  --border-subtle: rgba(20, 40, 40, 0.10);
  --border-strong: rgba(20, 40, 40, 0.18);
  --border-divider: #D5DDDB;

  /* ---- Scrim / shadows (artifact --shadow) ---- */
  --scrim: rgba(27, 38, 43, 0.45);
  --shadow-sm: 0 1px 3px rgba(20, 40, 40, 0.08);
  --shadow-md: 0 12px 30px rgba(20, 40, 40, 0.10);
  --shadow-lg: 0 24px 60px rgba(20, 40, 40, 0.14);
  --shadow-accent: 0 4px 12px rgba(133, 100, 16, 0.30);

  color-scheme: light;
}

/* ================================================================
   ARM 2 of 3: DARK, the prefers-color-scheme FALLBACK.
   Guarded :root:not([data-theme='light']) so a page pinned explicitly
   light is never dragged dark by the OS preference.
   ================================================================ */

@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) {
  /* ---- Families (D-1 SUPERSEDED: the artifact's system stack) ---- */
  --font-body: system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-heading: system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, monospace;

  /* ---- Surfaces ---- */
  --surface-0: #0C1114;
  --surface-1: #131A1E;
  --surface-2: #1B2429;
  --surface-1-map: #0F1619;

  /* ---- Glass panels (portfolio dash floating chrome): the shipped dark
     glass, now token-driven so the light arm can differ ---- */
  --glass-panel-strong: rgba(17, 21, 26, 0.90);
  --glass-panel-soft: rgba(17, 21, 26, 0.72);
  --zebra-stripe: rgba(255, 255, 255, 0.02);

  /* ---- On-accent: text sitting ON an --accent-600 fill (toggle thumb,
     checkbox check); dark brass #D9A441 is bright, so near-black ---- */
  --on-accent: #0A0D10;

  /* ---- On-surface / text ---- */
  --on-surface-0: #DCE7EA;
  --on-surface-1: #93A5AC;
  --on-surface-2: #5E7178; /* labels/metadata only, never body copy: fails
    AA-normal by design, always pair with position or icon */

  /* ---- Accent (brass, the artifact's dark hex) ---- */
  --accent-600: #D9A441;
  --accent-700: #A87F30;
  --accent-soft: rgba(217, 164, 65, 0.14);
  --accent-ring: rgba(217, 164, 65, 0.35);

  /* ---- Focus (DL-A2: dedicated, not an alias of the accent) ---- */
  --focus-ring: #D9A441;

  /* ---- Outcome colors (D-2) ---- */
  --outcome-indicated: #E0713C;        /* artifact ember */
  --outcome-indicated-soft: rgba(224, 113, 60, 0.12);
  --outcome-mixed: #A78BE0;            /* artifact violet */
  --outcome-mixed-soft: rgba(167, 139, 224, 0.12);
  --outcome-insufficient: #5A6470;
  --outcome-insufficient-soft: rgba(90, 100, 112, 0.16);
  --outcome-not-indicated: #57B87E;    /* artifact green */
  --outcome-not-indicated-soft: rgba(87, 184, 126, 0.12);

  /* ---- Status (system feedback, NOT outcomes) ---- */
  --danger-600: #C97066;
  --danger-fill: #C97066;
  --danger-soft: rgba(201, 112, 102, 0.12);
  --success-700: #57B87E;
  --success-soft: rgba(87, 184, 126, 0.12);
  --warn-800: #E0A340;
  --warn-soft: rgba(224, 163, 64, 0.12);

  /* ---- Analytic families (R2). On dark these clear both the 3:1 mark bar
     and the 4.5:1 text bar, so none is restricted to marks here. ---- */
  --dissent-600: #D9707F;
  --dissent-soft: rgba(217, 112, 127, 0.12);
  --leg-susceptibility-600: #4FB0A8;
  --leg-opportunity-600: #7E93DD;

  /* ---- Legacy outcome aliases, migration only ---- */
  --mixed-600: var(--outcome-mixed);
  --mixed-soft: var(--outcome-mixed-soft);
  --insufficient-600: var(--outcome-insufficient);
  --insufficient-soft: var(--outcome-insufficient-soft);

  /* ---- Borders ---- */
  --border-subtle: rgba(255, 255, 255, 0.08);
  --border-strong: rgba(255, 255, 255, 0.14);
  --border-divider: rgba(255, 255, 255, 0.08);

  /* ---- Scrim / shadows ---- */
  --scrim: rgba(12, 17, 20, 0.72);
  --shadow-sm: none;
  --shadow-md: 0 12px 30px rgba(0, 0, 0, 0.36);
  --shadow-lg: 0 24px 60px rgba(0, 0, 0, 0.48);
  --shadow-accent: 0 4px 12px rgba(217, 164, 65, 0.30);

  color-scheme: dark;
  }
}

/* ================================================================
   ARM 3 of 3: DARK, the EXPLICIT toggle. Beats the media query, so
   data-theme wins in BOTH directions.
   ================================================================ */

:root[data-theme='dark'] {
  /* ---- Families (D-1 SUPERSEDED: the artifact's system stack) ---- */
  --font-body: system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-heading: system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, monospace;

  /* ---- Surfaces ---- */
  --surface-0: #0C1114;
  --surface-1: #131A1E;
  --surface-2: #1B2429;
  --surface-1-map: #0F1619;

  /* ---- Glass panels (portfolio dash floating chrome): the shipped dark
     glass, now token-driven so the light arm can differ ---- */
  --glass-panel-strong: rgba(17, 21, 26, 0.90);
  --glass-panel-soft: rgba(17, 21, 26, 0.72);
  --zebra-stripe: rgba(255, 255, 255, 0.02);

  /* ---- On-accent: text sitting ON an --accent-600 fill (toggle thumb,
     checkbox check); dark brass #D9A441 is bright, so near-black ---- */
  --on-accent: #0A0D10;

  /* ---- On-surface / text ---- */
  --on-surface-0: #DCE7EA;
  --on-surface-1: #93A5AC;
  --on-surface-2: #5E7178; /* labels/metadata only, never body copy: fails
    AA-normal by design, always pair with position or icon */

  /* ---- Accent (brass, the artifact's dark hex) ---- */
  --accent-600: #D9A441;
  --accent-700: #A87F30;
  --accent-soft: rgba(217, 164, 65, 0.14);
  --accent-ring: rgba(217, 164, 65, 0.35);

  /* ---- Focus (DL-A2: dedicated, not an alias of the accent) ---- */
  --focus-ring: #D9A441;

  /* ---- Outcome colors (D-2) ---- */
  --outcome-indicated: #E0713C;        /* artifact ember */
  --outcome-indicated-soft: rgba(224, 113, 60, 0.12);
  --outcome-mixed: #A78BE0;            /* artifact violet */
  --outcome-mixed-soft: rgba(167, 139, 224, 0.12);
  --outcome-insufficient: #5A6470;
  --outcome-insufficient-soft: rgba(90, 100, 112, 0.16);
  --outcome-not-indicated: #57B87E;    /* artifact green */
  --outcome-not-indicated-soft: rgba(87, 184, 126, 0.12);

  /* ---- Status (system feedback, NOT outcomes) ---- */
  --danger-600: #C97066;
  --danger-fill: #C97066;
  --danger-soft: rgba(201, 112, 102, 0.12);
  --success-700: #57B87E;
  --success-soft: rgba(87, 184, 126, 0.12);
  --warn-800: #E0A340;
  --warn-soft: rgba(224, 163, 64, 0.12);

  /* ---- Analytic families (R2). On dark these clear both the 3:1 mark bar
     and the 4.5:1 text bar, so none is restricted to marks here. ---- */
  --dissent-600: #D9707F;
  --dissent-soft: rgba(217, 112, 127, 0.12);
  --leg-susceptibility-600: #4FB0A8;
  --leg-opportunity-600: #7E93DD;

  /* ---- Legacy outcome aliases, migration only ---- */
  --mixed-600: var(--outcome-mixed);
  --mixed-soft: var(--outcome-mixed-soft);
  --insufficient-600: var(--outcome-insufficient);
  --insufficient-soft: var(--outcome-insufficient-soft);

  /* ---- Borders ---- */
  --border-subtle: rgba(255, 255, 255, 0.08);
  --border-strong: rgba(255, 255, 255, 0.14);
  --border-divider: rgba(255, 255, 255, 0.08);

  /* ---- Scrim / shadows ---- */
  --scrim: rgba(12, 17, 20, 0.72);
  --shadow-sm: none;
  --shadow-md: 0 12px 30px rgba(0, 0, 0, 0.36);
  --shadow-lg: 0 24px 60px rgba(0, 0, 0, 0.48);
  --shadow-accent: 0 4px 12px rgba(217, 164, 65, 0.30);

  color-scheme: dark;
}

/* ================================================================
   ACCESSIBILITY FLOORS (global)
   ================================================================ */

:focus-visible {
  outline: 2px solid var(--focus-ring, var(--accent-600));
  outline-offset: 2px;
}

.btn:focus-visible,
.nav-btn:focus-visible,
button:focus-visible {
  outline-offset: 3px;
}

::selection {
  background: var(--accent-ring);
  color: var(--on-surface-0);
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
