/* ui/shared/tokens.css — the single source of visual truth.
   Every color, size, radius, depth and duration in the UI resolves to a token
   here. Games never define their own; game character lives in ui/games/<slug>/
   content, never in style.

   SYSTEM v3 — "Economics Games · Playful" (2026-08-20,
   decisions/shared/20260820-0900-design-adoption.md). The palette, type and
   shape below are the user's adopted Claude Design mockup, verbatim
   (journal/_design/playful.dc.html): a warm cream app surface, white cards
   with soft warm shadows, one orange accent doing all the pointing, Nunito
   with tabular numerals, pills for chips and CTAs.

   What did NOT change: every truth rule (no figure ever animates its
   magnitude, reveals present inputs before conclusions), the motion duration
   tokens the beats run on, and the sign convention that a loss is visibly a
   loss. The subject still supplies the palette's meaning — money you made
   (accent-deep), money you lost (ink, always signed, on a loss-tinted field
   where it is a field), the rival's figures neutral. */

/* Nunito, vendored (OFL — see ui/shared/fonts/OFL.txt). One variable-weight
   file covers 400-800 upright; italic is a 400 instance. Served from this
   origin; the app never fetches a font (or anything else) from another host. */
@font-face {
  font-family: 'Nunito';
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url('/ui/shared/fonts/nunito-latin-400-800.woff2') format('woff2');
}
@font-face {
  font-family: 'Nunito';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url('/ui/shared/fonts/nunito-latin-italic-400.woff2') format('woff2');
}

:root {
  /* ---- ground + surfaces (mockup-exact) ------------------------------- */
  --ground: #eee4d6;            /* desktop/page ground outside the app surface */
  --surface-app: #fdf6ee;       /* the app's own field (cream) */
  --surface: #ffffff;           /* cards, chips, pills */
  --sunken: #f3e6d7;            /* neutral tint: wells, tracks, quiet chips */
  --track: #e9dbc9;             /* slider/gauge track */
  --hairline: #f7ede0;          /* row separators inside white cards */
  --ink: #33241c;               /* primary text */
  --on-brand: #ffffff;          /* text/marks on an accent field */

  /* ---- THE INK GROUND (added 2026-08-28, see decisions/shared/
     20260828-c8-kit-widening.md) ---------------------------------------------
     A DARK PANEL, which this system had no way to draw. `--ink` is a TEXT
     colour; a surface painted with it needs its own on-colour, or every child
     inherits ink-on-ink and the panel renders blank. The user's own
     `cournot-setup.dc.html` briefing uses one (`background:#3a2e26`,
     `color:#f6f1e7`) for the payoff block, and `game-catalog.dc.html` uses one
     for the featured hero — the two places the design goes dark. Values are the
     frozen palette's own ink and app cream, not new hues: this adds a ROLE,
     it does not add a colour. Nothing existing resolves to these, so no
     consumer's rendering moves. */
  --ground-ink: var(--ink);     /* a dark panel: code blocks, featured hero */
  --on-ink: var(--surface-app); /* text/marks on the ink ground */
  --on-ink-soft: rgba(253, 246, 238, 0.66);
  --on-ink-line: rgba(253, 246, 238, 0.16);

  /* ---- the accent ------------------------------------------------------ */
  --accent: #e85d3d;            /* CTAs, marks, the active dot */
  --accent-deep: #c4472b;       /* text-on-tint, links, YOUR money made */
  --accent-faded: #f0b7a5;      /* a past step's dot */
  --accent-tint: #fbe5dd;       /* chips' wash, your scoreboard row */
  --accent-tint-strong: #f6d2c5;/* the same wash one step deeper (pulses) */
  --accent-glow: rgba(232, 93, 61, 0.35);

  /* legacy identity names, kept so every component resolves to one palette */
  --primary: var(--accent);
  --primary-deep: var(--accent-deep);
  --primary-bright: #ff7a58;    /* the white-hot end of a celebration bloom */
  --primary-tint: var(--accent-tint);
  --primary-tint-strong: var(--accent-tint-strong);
  --primary-soft: rgba(232, 93, 61, 0.45);
  --primary-glow: rgba(232, 93, 61, 0.28);

  /* YOUR MONEY, LOST: the sign convention survives the palette. A negative
     figure is INK at full strength (the mockup's own convention) — always
     with the typographic minus — and where a loss owns a surface, the surface
     goes quiet (neutral tint) rather than celebratory. Another player's GAIN
     is muted ink, so in any column a loss is visibly distinct from a gain. */
  --loss: #33241c;
  --loss-deep: #1f1510;
  --loss-tint: #f3e6d7;
  --loss-tint-strong: #eadbc6;
  --loss-line: rgba(51, 36, 28, 0.30);
  --loss-glow: rgba(51, 36, 28, 0.26);

  /* THE RIVAL: their figures stay neutral (never your money's color); their
     character is drawn in the cast's own inks below. */
  --rival: rgba(51, 36, 28, 0.62);
  --rival-tint: #f3e6d7;
  /* the cast's inks (avatar drawing, mockup-exact): ink body, accent roof,
     cream lit window */
  --cast-body: #33241c;
  --cast-roof: var(--accent);
  --cast-window: #fdf6ee;

  /* derived ink shades (alpha over --ink, still one palette) */
  --ink-soft: rgba(51, 36, 28, 0.62);
  --ink-mid: rgba(51, 36, 28, 0.52);
  --ink-faint: rgba(51, 36, 28, 0.45);
  --line: rgba(51, 36, 28, 0.13);
  --line-strong: rgba(51, 36, 28, 0.24);
  --scrim: rgba(31, 21, 16, 0.5);
  --focus-ring: 0 0 0 4px rgba(232, 93, 61, 0.35);

  /* ---- type ------------------------------------------------------------ */
  --font: 'Nunito', ui-rounded, "SF Pro Rounded", "Segoe UI", system-ui, -apple-system, sans-serif;
  --fs-xs: 12px;   /* micro-labels, chip meta */
  --fs-sm: 13.5px; /* secondary lines */
  --fs-md: 15px;   /* body */
  --fs-lg: 22px;   /* the screen's question */
  --fs-xl: 27px;   /* section figures */
  --fs-2xl: 40px;  /* the live readout, the typed quantity */
  --fs-3xl: 54px;  /* the round's answer */
  --fs-hero: 48px; /* the hero money figure (outcome/terminal) */
  --w-semi: 600;
  --w-bold: 700;
  --w-heavy: 800;
  --track-tight: -0.02em;
  --track-caps: 0.09em;    /* micro-label caps: .08-.13em in the mockup */
  --track-caps-wide: 0.12em;

  /* ---- radii (mockup: cards 14-20, pills everywhere) ------------------- */
  --r-xl: 20px;
  --r-lg: 16px;
  --r-md: 14px;
  --r-sm: 11px;
  --r-pill: 999px;

  /* ---- space (4px base) ------------------------------------------------ */
  --sp-1: 4px;
  --sp-2: 8px;
  --sp-3: 12px;
  --sp-4: 16px;
  --sp-5: 20px;
  --sp-6: 24px;
  --sp-8: 32px;
  --sp-14: 56px;

  /* ---- touch targets --------------------------------------------------- */
  --tap: 46px;        /* the floor for anything tappable */
  --tap-lg: 48px;     /* stepper tiles */
  --tap-xl: 48px;     /* the number row */
  --tap-action: 54px; /* the anchored primary action (mockup CTA height) */

  /* ---- depth (mockup: soft warm shadows, no lips) ----------------------
     Cards float on 1px 4-5px washes of the ink's own hue; the CTA carries an
     accent glow. --lip survives as the press-travel distance the commit beat
     animates through (a token the motion spec reads), not as a drawn slab. */
  --lip: 3px;
  --lip-sm: 2px;
  --shadow-card: 0 1px 5px rgba(51, 36, 28, 0.09);
  --shadow-card-soft: 0 1px 4px rgba(51, 36, 28, 0.07);
  --shadow-ctl: 0 1px 5px rgba(51, 36, 28, 0.12);
  --shadow-cta: 0 4px 12px rgba(232, 93, 61, 0.35);
  --shadow-pop: 0 16px 40px rgba(31, 21, 16, 0.22); /* sheets only */

  /* ---- the board's dimensions (r20) ------------------------------------
     The wide (>=900px) composition is ONE cream board; these are its shared
     measures. Every screen reads them — no screen invents its own. */
  --rail-w: 240px;      /* the history/benchmark rail's column */
  --dcol-w: 260px;      /* a board card's packed side column (decision column) */
  --board-max: 1280px;  /* the board never stretches past this */

  /* ---- the stage's dimensions (r21) ------------------------------------
     THE STAGE PARADIGM (decisions/shared/20260821-1000-stage-paradigm): at
     wide-and-tall-enough viewports an in-game screen composes to the viewport
     like a game — slim app bar, the game's figure filling all remaining
     height, one control strip along the bottom, a context panel on the right
     (open by default). These are the shared measures; the engagement decision
     itself (>=900 wide AND >=720 tall AND the screen has a declared stage
     figure) is made by the play container, because a media query cannot read
     a game's config. Below either threshold the r20 Ledger board renders
     exactly as committed. */
  --appbar-h: 58px;     /* the wide app bar's height (Stage AND Ledger tiers) */
  --panel-w: 340px;     /* the context panel's column */

  /* THE LEDGER SKIN (r21 correction, same ruling): the wide fallback tier is
     the user's beautified Ledger mockup (journal/_design/ledger.dc.html) —
     flat cream surface, tiles delimited by 2px hairline borders, no card
     shadows at the wide tier, bubbles on the hairline tint. The phone keeps
     its committed white-card language untouched. */
  --tile-line: #f0e3d2; /* the Ledger tile border (mockup-exact) */
  --ledger-col: 390px;  /* the Ledger decision/outcome column */
  --ledger-max: 1160px; /* the Ledger composition's width */

  /* ---- the chart slot (r20) --------------------------------------------
     AT WIDTH, A CHART IS A LANDSCAPE FIGURE. The phone keeps its own
     width-derived ratios (curve.js provisional heights — untouched); at
     >=900px every shared chart slot (svg.curve in a .curve-wrap) takes this
     aspect, with a hard ceiling so a very wide slot cannot become a wall.
     base.css applies it to the slot; curve.js re-maps its data onto whatever
     box the slot renders (ui/shared/curve.js syncToSlot) — so no screen ever
     sizes a chart, and the proportion rule is one token for every game. */
  --chart-aspect-wide: 1.6;   /* w:h — the tall end of the landscape band */
  --chart-h-max: 380px;       /* plot ceiling at width */

  /* THE INK GROUND lives up beside the surfaces (`--ground-ink` / `--on-ink`),
     added by the same widening. It was briefly declared twice, here and there,
     under two names — caught and collapsed onto the one above on the day it
     landed. Do not re-add it here: a token with two names is a token with two
     values waiting to happen. */

  /* ---- measures for the NON-GAME screens (added 2026-08-28) -------------
     --board-max / --ledger-max are in-game measures: a figure plus a
     decision column. Setup, catalog, join and monitor are a reading column
     plus an aside that carries context, so they get their own pair rather
     than borrowing a number that means something else (TOKENS.md's tier-scope
     amendment: these screens are Playful cards at every width, never Ledger). */
  --page-max: 1120px;   /* the setup / catalog content column */
  --aside-w: 340px;     /* the context aside beside a form */
  --tap-step: 44px;     /* a stepper tile in a FORM (a dozen per screen, read
                           at a desk) — distinct from --tap-lg, which is the
                           play screen's single across-the-room stepper */

  --ease: cubic-bezier(0.2, 0.7, 0.3, 1);
  --t-fast: 140ms;
  --t-med: 220ms;

  /* ---- motion tokens (binding motion spec; freeze candidates) ----------
     UNCHANGED in v3: every beat lives in 150-450ms; staged sequences stay
     <= ~1.2s total; prefers-reduced-motion collapses ALL of these to instant
     state changes. The restyle repaints the beats, it does not retime them. */
  --t-press: 90ms;
  --t-quick: 180ms;
  --t-beat: 260ms;
  --t-track: 120ms;
  --t-figure: 320ms;
  --t-figure-lg: 450ms;
  --t-seal: 340ms;
  --t-land: 620ms;
  --t-crest: 700ms;
  --t-breathe: 1800ms;
  --ease-pop: cubic-bezier(0.34, 1.56, 0.64, 1);
}

/* ---- THE DESKTOP SCALE STEP (r20) ---------------------------------------
   At the wide tier the type and control scale takes ONE deliberate step up,
   through tokens only: a laptop is read at arm's length, so the question, the
   primary figures and the controls are ADJUSTED for that distance rather than
   merely spread out. Any screen that composes from tokens inherits the step;
   nothing below 900px changes by definition. */
@media (min-width: 900px) {
  :root {
    --fs-lg: 24px;      /* the screen's question */
    --fs-xl: 30px;      /* section figures / titles */
    --fs-2xl: 44px;     /* the typed quantity */
    --fs-3xl: 58px;
    --fs-hero: 54px;    /* the hero money figure */
    --tap-lg: 52px;     /* stepper tiles */
    --tap-xl: 52px;     /* the number row */
    --tap-action: 56px; /* the primary action pill */
  }
}
/* the board relaxes once there is room for the full rail + column measures */
@media (min-width: 1280px) {
  :root {
    --rail-w: 280px;
    --dcol-w: 280px;
  }
}
/* ...and the context panel takes the mockup's full width where there is room */
@media (min-width: 1440px) {
  :root {
    --panel-w: 380px;
  }
}
