/* Shared design tokens. Colour, type scale, spacing. Nothing else.
   Both sites copy this into their own output directory at build time, so
   neither ever loads a stylesheet from the other's origin.

   Light and dark are VARIABLE SWAPS, not two stylesheets. Every rule below the
   token block reads a name; only the value behind the name moves. That is what
   makes the second theme a fast follow rather than a rewrite, and it is the
   same structure the app uses. */

:root {
  color-scheme: light dark;

  /* ── Surface and text ───────────────────────────────────────────────
     Light is the default. The dark block at the bottom swaps the same
     eight names, and nothing else in any stylesheet changes. */
  --bg: #fbfbfc;
  --bg-raised: #ffffff;
  --bg-sunken: #f1f1f4;
  --fg: #17171b;
  --fg-muted: #55555f;
  --line: #d8d8de;
  --line-strong: #b4b4be;
  /* A control's border is MEANINGFUL non-text: it is what tells you where the
     input is, so it owes 3:1 and --line does not pay it (1.37:1). This is the
     name every form field and button outline uses. 3.31:1 against --bg,
     3.03:1 against --bg-sunken, so it holds on any surface here. */
  --line-control: #8a8a94;

  /* ── Attribution ────────────────────────────────────────────────────
     The identity, carried across verbatim from the design system's
     attribution pair: user is slate, agent is fuchsia. One colour for what
     the person authored, one for what an agent proposed.

     TEXT and MARK are separate names on purpose. WCAG asks 4.5:1 of text
     and 3:1 of meaningful non-text, and the fuchsia solid sits between
     those two bars on a light surface:

       #c026d3 on #fbfbfc  =  4.55:1   clears the text bar by 0.05
       #a21caf on #fbfbfc  =  6.11:1   clears it by 1.61

     4.55 is a pass, and a pass that close is one off-white away from a fail.
     So agent-coloured text steps one down the ramp and the solid is kept for
     rules, dots and underlines, where the bar is 3:1 and it is nowhere near
     it. Same identity, no borderline reading.

     Slate needs no such correction. #475569 on #fbfbfc is 7.33:1.

     Colour is never the only carrier. Anything attributed also takes a
     label or a shape, which is why --attr-*-mark exists as its own name. */

  /* Slate, user */
  --user-50: #f8fafc;
  --user-100: #f1f5f9;
  --user-200: #e2e8f0;
  --user-300: #cbd5e1;
  --user-400: #94a3b8;
  --user-500: #64748b;
  --user-600: #475569;
  --user-700: #334155;
  --user-800: #1e293b;
  --user-900: #0f172a;

  /* Fuchsia, agent */
  --agent-50: #fdf4ff;
  --agent-100: #fae8ff;
  --agent-200: #f5d0fe;
  --agent-300: #f0abfc;
  --agent-400: #e879f9;
  --agent-500: #d946ef;
  --agent-600: #c026d3;
  --agent-700: #a21caf;
  --agent-800: #86198f;
  --agent-900: #701a75;

  /* The four names a treatment actually uses. */
  --attr-user-text: var(--user-600);
  --attr-user-mark: var(--user-600);
  --attr-user-wash: color-mix(in oklab, var(--user-600) 12%, transparent);

  --attr-agent-text: var(--agent-700);
  --attr-agent-mark: var(--agent-600);
  --attr-agent-wash: color-mix(in oklab, var(--agent-600) 12%, transparent);

  /* Focus. Its own name because it must clear 3:1 against BOTH the page and
     the control it rings, in either theme. */
  --focus-ring: var(--agent-700);

  /* Kept for sites/lab, which is not in this brief. Not a brand colour and
     not carried onto the curator page. */
  --accent: #6f7ae8;

  /* ── Type ───────────────────────────────────────────────────────────
     Fluid, so there is no fixed pixel layout and no breakpoint where the
     page stops adapting. Every step is a clamp between a phone value and a
     desktop value, interpolated on viewport width.

     The rem half of each clamp is what carries 200% text zoom: the vw half
     alone would ignore the user's font-size setting entirely, which is the
     usual way a fluid scale fails an accessibility check. */
  --font-sans: ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI",
    Roboto, Helvetica, Arial, sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  --step--1: clamp(0.83rem, 0.80rem + 0.15vw, 0.92rem);
  --step-0: clamp(1rem, 0.96rem + 0.20vw, 1.13rem);
  --step-1: clamp(1.25rem, 1.16rem + 0.45vw, 1.55rem);
  --step-2: clamp(1.56rem, 1.38rem + 0.90vw, 2.15rem);
  --step-3: clamp(1.95rem, 1.62rem + 1.65vw, 3.00rem);
  --step-4: clamp(2.44rem, 1.87rem + 2.85vw, 4.20rem);

  --line-tight: 1.15;
  --line-body: 1.6;
  --measure: 62ch;

  /* ── Space ──────────────────────────────────────────────────────────
     Also fluid at the large end, so vertical rhythm on a phone is not the
     desktop rhythm crushed. */
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 1rem;
  --space-4: clamp(1.5rem, 1.2rem + 1.5vw, 2.5rem);
  --space-5: clamp(2.5rem, 1.8rem + 3.5vw, 5rem);
  --space-6: clamp(4rem, 2.5rem + 7vw, 9rem);

  --radius: 0.5rem;
  --gutter: clamp(1.25rem, 0.9rem + 1.8vw, 2.5rem);
}

/* ── Dark ─────────────────────────────────────────────────────────────
   Eight surface names and the attribution ramps, inverted. The app inverts
   the ramps rather than reaching for different hues, so --attr-user-text
   stays the name and only the step behind it moves. Nothing else in any
   stylesheet is aware this block exists. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #0e0e10;
    --bg-raised: #17171b;
    --bg-sunken: #08080a;
    --fg: #ededf0;
    --fg-muted: #a4a4ae;
    --line: #2c2c33;
    --line-strong: #43434c;
    --line-control: #6a6a75;

    --user-50: #0f172a;
    --user-100: #1e293b;
    --user-200: #334155;
    --user-300: #475569;
    --user-400: #64748b;
    --user-500: #94a3b8;
    --user-600: #cbd5e1;
    --user-700: #e2e8f0;
    --user-800: #f1f5f9;
    --user-900: #f8fafc;

    --agent-50: #4a044e;
    --agent-100: #701a75;
    --agent-200: #86198f;
    --agent-300: #a21caf;
    --agent-400: #c026d3;
    --agent-500: #d946ef;
    --agent-600: #e879f9;
    --agent-700: #f0abfc;
    --agent-800: #f5d0fe;
    --agent-900: #fae8ff;

    /* On a dark surface the fuchsia solid clears the text bar comfortably,
       so text and mark converge rather than stepping apart. */
    --attr-user-text: var(--user-500);
    --attr-user-mark: var(--user-500);
    --attr-user-wash: color-mix(in oklab, var(--user-500) 18%, transparent);

    --attr-agent-text: var(--agent-600);
    --attr-agent-mark: var(--agent-600);
    --attr-agent-wash: color-mix(in oklab, var(--agent-600) 16%, transparent);

    --focus-ring: var(--agent-600);
  }
}

/* The same block, for a reader who chose dark on a light system. The two
   must match, and tools/theme.test.mjs fails the build when they drift. */
:root[data-theme="dark"] {
  --bg: #0e0e10;
  --bg-raised: #17171b;
  --bg-sunken: #08080a;
  --fg: #ededf0;
  --fg-muted: #a4a4ae;
  --line: #2c2c33;
  --line-strong: #43434c;
  --line-control: #6a6a75;

  --user-50: #0f172a;
  --user-100: #1e293b;
  --user-200: #334155;
  --user-300: #475569;
  --user-400: #64748b;
  --user-500: #94a3b8;
  --user-600: #cbd5e1;
  --user-700: #e2e8f0;
  --user-800: #f1f5f9;
  --user-900: #f8fafc;

  --agent-50: #4a044e;
  --agent-100: #701a75;
  --agent-200: #86198f;
  --agent-300: #a21caf;
  --agent-400: #c026d3;
  --agent-500: #d946ef;
  --agent-600: #e879f9;
  --agent-700: #f0abfc;
  --agent-800: #f5d0fe;
  --agent-900: #fae8ff;

  /* On a dark surface the fuchsia solid clears the text bar comfortably,
     so text and mark converge rather than stepping apart. */
  --attr-user-text: var(--user-500);
  --attr-user-mark: var(--user-500);
  --attr-user-wash: color-mix(in oklab, var(--user-500) 18%, transparent);

  --attr-agent-text: var(--agent-600);
  --attr-agent-mark: var(--agent-600);
  --attr-agent-wash: color-mix(in oklab, var(--agent-600) 16%, transparent);

  --focus-ring: var(--agent-600);
}

/* A choice also sets the scheme the browser draws its own controls and
   scrollbars in. */
:root[data-theme="light"] {
  color-scheme: light;
}

:root[data-theme="dark"] {
  color-scheme: dark;
}

/* The page follows the system preference until a reader chooses. A's
   masthead toggle (theme.js) records the choice as `data-theme` on the root,
   and the two selectors above are the whole of what it hooks into. No rule
   anywhere reads a hex value directly, so nothing else moves. A page with no
   toggle never sets the attribute and behaves exactly as before. */
