/* ============================================================
   rxdx Design System — "Ink & Paper"
   tokens.css — SINGLE SOURCE OF TRUTH for all styling.
   LOCKED tokens. Do not alter color values.
   ============================================================ */

/* --- Metric-matched font fallbacks (kills the load-time "jerk") ----------------
   The web fonts (Fraunces, DM Sans) load NON-BLOCKING (media=print onload, so Brave
   never blocks first paint). The page therefore paints in a fallback first, then the
   web font swaps in — and because a plain Georgia/Arial fallback has different letter
   metrics, that swap REFLOWS the whole layout ("goes big/small ever so slightly").
   These two @font-faces re-shape the local fallback (Georgia / Arial) with
   size-adjust + ascent/descent overrides so it occupies the EXACT same space as the
   web font — the swap then causes zero reflow. Overrides computed from the served
   woff2's real metrics via @capsizecss (do not hand-tune; regenerate if the font
   version changes). Slotted between the web font and the generic fallback in the
   stacks below. */
/* SELF-HOSTED web fonts (same-origin woff2, preloaded in each page <head>) — so the real face is ready at
   first paint and there is NO fallback→web-font SWAP ("the ghost"), and privacy browsers can't block them.
   Fraunces + DM Sans are single variable files. Paired with the metric-matched fallbacks below (zero reflow). */
@font-face { font-family: 'Fraunces'; src: url('fonts/fraunces-var.woff2') format('woff2'); font-weight: 400 700; font-style: normal; font-display: swap; }
@font-face { font-family: 'DM Sans'; src: url('fonts/dmsans-var.woff2') format('woff2'); font-weight: 100 1000; font-style: normal; font-display: swap; }
/* Inter — the body/UI face (owner 2026-08-12: DM Sans read "bulky"). Single variable file, latin subset,
   self-hosted + preloaded like the others. Cleaner, more neutral strokes than DM Sans at the same weights. */
@font-face { font-family: 'Inter'; src: url('fonts/inter-var.woff2') format('woff2'); font-weight: 100 900; font-style: normal; font-display: swap; }
@font-face { font-family: 'IBM Plex Mono'; src: url('fonts/plexmono-400.woff2') format('woff2'); font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: 'IBM Plex Mono'; src: url('fonts/plexmono-500.woff2') format('woff2'); font-weight: 500; font-style: normal; font-display: swap; }
@font-face { font-family: 'IBM Plex Mono'; src: url('fonts/plexmono-600.woff2') format('woff2'); font-weight: 600; font-style: normal; font-display: swap; }
@font-face {
  font-family: 'Fraunces Fallback';
  src: local('Georgia');
  font-display: swap;
  ascent-override: 89.5263%;
  descent-override: 23.3428%;
  line-gap-override: 0%;
  size-adjust: 109.2416%;
}
@font-face {
  font-family: 'DM Sans Fallback';
  src: local('Arial'), local('ArialMT');
  font-display: swap;
  ascent-override: 94.9001%;
  descent-override: 29.6563%;
  line-gap-override: 0%;
  size-adjust: 104.531%;
}
/* Metric-matched Arial fallback for Inter — same zero-reflow trick as above (Inter's published capsize
   overrides), so the fallback→Inter swap doesn't jerk the layout. */
@font-face {
  font-family: 'Inter Fallback';
  src: local('Arial'), local('ArialMT');
  font-display: swap;
  ascent-override: 90.44%;
  descent-override: 22.52%;
  line-gap-override: 0%;
  size-adjust: 107.12%;
}

:root {

  /* --- Color: surfaces & ink ------------------------------- */
  --bg:        #f4efe4;  /* app background (paper)            */
  --surface:   #fbf7ef;  /* card / raised surface            */
  --surface-2: #efe8da;  /* inset / secondary surface        */
  --ink:       #241c15;  /* primary text                     */
  --ink-2:     #6a5c48;  /* secondary text                   */
  --ink-3:     #a2937d;  /* tertiary / muted text            */

  /* --- Color: lines ---------------------------------------- */
  --line:   #e3d9c7;     /* hairline / divider (1px)         */
  --line-2: #d5c8b1;     /* stronger border                  */


  /* --- Color: accent (rust) -------------------------------- */
  --accent:       #c2410c; /* primary accent                 */
  --accent-press: #9a330a; /* accent pressed / active        */
  --accent-bg:    #f8e7dc; /* accent tint background         */
  --on-accent:    #fff;    /* text/icon on accent fill       */
  --hl:           #f6dd77; /* hint highlighter (marker yellow) */
  /* Recall app signature — a calm deep teal, distinct from the rust accent so the drill app reads as its
     own thing (owner: "every app should have its own vibe"); still sits on the warm ground. */
  /* 👤 2026-10-15: "remove the teal color change" — Recall wears the site accent like every app (aliases kept so no rule breaks) */
  --recall:       var(--accent);
  --recall-press: var(--accent-press);
  --recall-tint:  var(--accent-bg);

  /* --- Color: semantic status ------------------------------ */
  --good:    #1f7a4d;    /* correct / success text           */
  --good-bg: #e3f2e9;    /* correct / success background     */
  --bad:     #b81d3b;    /* wrong / error text (crimson — distinct from --accent rust) */
  --bad-bg:  #f9e4e9;    /* wrong / error background (cooled to pair with the crimson) */
  --danger:  #c0392b;    /* absolute-contraindication red    */
  --page:    #0e6b66;    /* a chip that opens a page of its own: teal, so it never reads as --good (correct) */
  --page-bg: #dff0ee;    /* page chip tint on hover and focus */
  --dx:      #2f5e8f;    /* diagnosis blue (decision-tree role: a diagnosis box, distinct from treatment green) */
  /* A lab value outside its reference range on the reveal: high reads red, low reads blue. */
  --lab-high: var(--bad);
  --lab-low:  var(--dx);

  /* --- Color: warn / amber (the "!" clarification call-out) - */
  --warn:        #d99a1c; /* amber icon fill                  */
  --warn-bg:     #fdf4e3; /* amber note background            */
  --warn-border: #e8c974; /* amber note border                */
  --warn-ink:    #a5710f; /* amber emphasis text              */

  /* CONTENT CALLOUTS — the two the long-form study guides use, by ROLE, not by taste:
     TERMS (a definition set, opening a section) in blue · a common MISTAKE in the amber above.
     ⛔ 2026-09-07: the renal guide carried this blue as private hex, so I replaced it with a neutral gray
     when I pulled the page onto the design system. 👤: "all the colors that were on that site are not
     there anymore." He was right — the answer was to DECLARE the color here, not delete it. */
  --terms:    #3f6b90; /* terms-callout edge + label       */
  --terms-bg: #edf3f8; /* terms-callout background         */

  /* --- Color: misc surfaces -------------------------------- */
  --rail-bg: var(--bg);  /* rail matches the page so the top-left isn't 3 mismatched color bands (rail/bar/page) */

  /* --- Color: WALK (interactive tree) — LIGHT + pastel (owner 2026-08-09: "thin and light · white/lighter
     cards · pastel accents · NO quiz colors here"). The walk is a knowledge space, not a test: near-WHITE
     cards on the page, a soft petrol/teal accent, a pastel teal tint for the selected path + teaching notes.
     NO green/red (those belong to the quiz). Scoped to `.walk` only. */
  --walk-surface:    #fdfefe; /* near-white card (brighter than --surface) — the options + notes  */
  --walk-line:       #e6efec; /* light cool hairline                                             */
  --walk-line-2:     #d3e3de; /* light card border                                               */
  --walk-accent:     #0e6b62; /* soft petrol/teal — the walk's one accent (step · CTA · selected) */
  --walk-accent-press:#0a4f48;/* pressed/active teal                                             */
  --walk-tint:       #eaf4f1; /* pastel teal — selected option + the teaching-note callout        */

  /* The flowchart's five node kinds, shared by the drawn charts and their legend. */
  --flow-patient: #ece8fd;  --flow-patient-line: #9b8fe0;
  --flow-tool: #fde9da;     --flow-tool-line: #e2a47c;
  --flow-question: #86b4e3;
  --flow-action: #e3f6ec;   --flow-action-line: #82c7a0;
  --flow-step: #f0f2f7;     --flow-step-line: #aab4c6;
  /* --- Elevation (shadows) + scrim ------------------------- */
  --shadow-1: 0 1px 3px rgba(60,46,24,.10);  /* sticky bars, cards        */
  --shadow-2: 0 8px 28px rgba(60,46,24,.16); /* popover / dropdown        */
  --shadow-3: 0 24px 60px rgba(38,26,20,.32);/* modal / lightbox          */
  --shadow-edge: 0 0 24px rgba(60,46,24,.20);/* a panel over the page: the menu's peek, the phone panel */
  --scrim:    rgba(40,28,12,.34);            /* drawer / sheet backdrop   */
  --scrim-strong: rgba(38,26,20,.62);        /* lightbox backdrop         */
  --scrim-light:  rgba(244,239,228,.72);     /* dialog backdrop: the paper color (--bg), so it softens the page without cooling it */

  /* --- Typeface families ----------------------------------- */
  --display: 'Fraunces', 'Fraunces Fallback', Georgia, serif;         /* headings / wordmark only */
  --body:    'Inter', 'Inter Fallback', system-ui, sans-serif;        /* body + questions/answers */
  --sans:    'Inter', 'Inter Fallback', system-ui, sans-serif;        /* eyebrow / uppercase section labels */
  /* ⛔ ONE TYPEFACE (👤 10-10: "different font sizes … everywhere"): the monospace face is retired — ids, counts and the glossary's
     abbreviations now set in the site's sans, with tabular digits (body below) so numbers still line up. One token, every use. */
  --mono:    var(--sans);

  /* --- Type scale (THE ONLY sizes allowed — never a raw px font-size) --- */
  --t-hero: 48px;
  --t-brand: 22px;       /* top-bar brand-mark (display)                 */
  --t-h1:   22px;
  --t-h2:   17px;
  --t-h3:   15px;        /* question stem — the anchor */
  --t-body: 14px;        /* answers · prose (dropped on desktop, owner 2026-08-12) */
  --t-meta: 13px;
  --t-eye:  11px;        /* eyebrow / overline · numeric counts          */

  /* The five text roles (Label, Stem, Body, Meta, Button) each read one line height, so no text falls back to the font's own `normal`. */
  --lh-label: 16px;
  --lh-stem: 1.5;
  --lh-title: 1.2;
  --lh-body: 1.6;
  --lh-meta: 20px;
  /* The three weights: text, the question stem, and emphasis (the Result, option keys, buttons). */
  --fw-text: 400;
  --fw-stem: 500;
  --fw-strong: 600;

  /* ⛳ ONE TRACKING FOR EVERY UPPERCASE LABEL ON THE SITE. 👤, 2026-09-17: *"are the properties from app
     to app the same or are you just doing it blind?"* — 🔬 I MEASURED INSTEAD OF ANSWERING, and the answer
     was NO. Across all 18 pages the same element — a small caps label — rendered **16 DISTINCT WAYS**, and
     the source carried **81 uppercase rules using TWELVE different letter-spacings**: .12 · .06 · .08 ·
     .14 · .1 · .04 · .03 · .02em, plus 1px, .5px, .4px and .3px.
     ⚖️ Nothing CHOSE those twelve. They accumulated one rule at a time, each defensible alone — which is
     the "you don't have a style guide" complaint in its measurable form.
     ⛳ `.12em` wins BY USAGE (27 of the 81, and the value the drug card and the decision tree already use),
     ⛔ not by my taste. Rung C15 enforces it, so the thirteenth cannot arrive quietly.
     ⚠️ COLOR stays per-role on purpose — an accent eyebrow, a muted label and a danger header are
     different meanings, not drift. ⚠️ WEIGHT is STILL MIXED (400/500/600/700) and is NOT governed yet;
     written down here rather than letting this comment imply more than it delivers. */
  --track-caps: .12em;

  /* caps labels: quiet, or emphatic. Was four weights across the site; 500 and 700 folded in. */
  --w-cap: 400;
  --w-cap-strong: 600;
  --t-micro: 10px;       /* tiny flags (lab hi/lo)                       */

  /* --- Spacing scale (px) ---------------------------------- */
  --s-1:  4px;
  --s-2:  8px;
  --s-3:  12px;
  --s-4:  16px;
  --s-5:  24px;
  --s-6:  32px;
  /* ⛳ --s-7 IS REAL NOW, AND IT WAS BEING USED BEFORE IT EXISTED. 🔬 2026-09-13: three shipped rules read
     `var(--s-7)` — `.acct` bottom padding, `.acct-sec` section separation and `.gd` bottom padding — and the
     scale stopped at --s-6. An UNDEFINED custom property with no fallback makes the WHOLE declaration
     invalid at computed-value time, so all three resolved to ZERO. That is why 👤 said the account page is
     "such an ugly page… why is this order so backwards and confusing": its three sections had no separation
     at all, so each section head read as a continuation of the section above it. ⛔ The silent part is the
     defect — CSS does not warn, nothing went red, and I had just *raised* .acct-sec from --s-5 to this.
     ⛳ Guarded by `tools/check_tokens.js` (A24), which fails on any var(--x) that nothing defines. The same
     class of bug as the `--r-3` phantom recorded in PAGE_FORMAT_STANDARD's corrections block — twice is a
     pattern, and §8 says a fix is not a fix until it ships the guard. */
  /* SPACING ROLES (Style Guide §2.2). A component names the role a space plays and never picks a step of the scale itself; these are
     the only declarations that turn a role into a size. A single-line label sets its line to --lh-title, never a paragraph's --lh-body. */
  --sp-inside:  var(--s-1);  /* between the parts of one item: a name and its subline, an icon and its label */
  --sp-item:    var(--s-2);  /* above and below an item's content; between two items of a list or a grid */
  --sp-control: var(--s-3);  /* the side padding inside a control or a chip */
  --sp-block:   var(--s-4);  /* between two blocks inside a card or a sheet; the phone's page gutter */
  --sp-group: var(--s-5);   /* between two groups (a heading and its items, the next heading); --s-6 on a phone, below */
  --sp-page:    var(--s-5);  /* a card's padding and the start line under the top bar */
  --kv-k:       9rem;       /* the label column of every label and value list */
  --kv-gap:     var(--sp-control);
  --kv-pad:     var(--s-2);
  --sp-section: var(--s-7);  /* between two sections of a page */
  --s-7:  48px;          /* section separation — the step above --s-6 */
  /* Layout geometry: named sizes that are not a space between pieces but a part of the frame. A padding, margin or gap may name one of
     these or a --sp-* role, and nothing else (check_spacing.js). */
  --hair: 1px;       /* the width of a border or divider, for a control that overlaps its neighbor's line */
  --bar-side: 120px; /* the room the top bar keeps on each side of its centered title for the back button and the tools */
  --ft-mark: 22px;   /* the width of a flowchart step's marker, which the step's text clears */

  /* Optical-center lift: seat a full-screen hero block THIS far above the mathematical middle so a
     top-heavy wordmark doesn't read low. Used by the home hero, About, and the sign-in/boot surfaces. */
  --optical-lift: 6vh;
  /* ⛳ THE OPTICAL CENTER, ONE NUMBER (👤 2026-11-01: "these pages are not optically centered… optically is different than actual center,
     right?"): a centered block's MIDDLE sits at 44% of the free space, top bar to bottom bar (or the window's edges where there is no bar),
     not at 50%: a block hung at the exact middle reads low. Home's 6vh lift is this same 44% on a page with no bars. The setup steps
     (anchorStep) read it. Guard: flows `optical-center`. */
  --optical-center: .44;

  /* --- Radius (minimal set — ONE control radius, one card radius, one pill) --- */
  --r-0: 0;              /* a segment INSIDE a segmented bar — the bar carries the --r-1 corner, its segments are square */
  --r-1: 8px;            /* ALL small controls: buttons · chips · tabs · pills · inputs · badges */
  --r-2: 12px;           /* cards / panels / modals (containers only) */
  --r-mark: 2px;         /* a select-all answer marker: a BOX; a one-pick answer has NO marker, the plain letter — 2026-10-25 */
  --r-pill: 999px;       /* fully-round: toggles, progress bars, oval status pills */

  /* --- Motion (SINGLE SOURCE, same as type and space) ------------------------------
     Motion had no tokens until now, so every transition was hand-picked where it was
     written — 20 different durations and 9 easing curves across the site, which is why
     the same kind of thing moved at a different speed depending on the screen. Three
     tiers, one job each. Anything longer than these is a deliberate, decorative
     animation (an ECG sweep, the build sequence) and states its own duration. */
  --dur-1: .12s;         /* STATE: hover, focus, border/color change — near-instant   */
  --dur-2: .2s;          /* REVEAL: toasts, small panels, chips, in-place disclosure   */
  --dur-3: .3s;          /* SURFACE: drawers, modals, sheets — things that cover       */
  --slide: var(--dur-3);        /* every panel's slide in and out: the left menu, the right panel, the phone pull-up, and the page beside them */
  --slide-ease: var(--ease-1);  /* one curve both ways, so a close starts as gently as an open ends */
  --ease-1: cubic-bezier(.4, 0, .2, 1);    /* standard: both ends, most things         */
  --ease-out: cubic-bezier(.16, 1, .3, 1); /* entrances: fast in, soft landing         */

  /* --- Control & tap sizing -------------------------------- */
  --seg-min: 5rem;       /* the narrowest a segmented-bar choice may get before the bar wraps to a second row */
  --ctl:    36px;        /* standard control height          */
  /* ⛳ THE CHIP HEIGHT — ONE number per GRID (a grid where no label wraps is marked `.one-line` and drops to --ctl, site.css; Style Guide §5.3) (👤, 2026-09-07: "shouldn't these
     boxes all be the same size and follow your style guide?"). 🔬 They were not: --ctl 36 for a
     one-line label and 49 for a two-line one, THREE distinct heights in one step, because
     `.chips .chip` carried `height:auto` — which contradicted `CHIP_SIZING_MAP.md`, the doc that
     calls itself the authority on chip heights. ⛔ Two rules, and the CSS won silently.
     Sized to hold TWO lines of --t-meta at 1.2 plus --s-2 padding, so a long disease name never
     clips and a short one never sits in a shorter box. Scales with --ctl on touch. */
  --ctl-2l: 48px;       /* chip height — two-line capable, uniform everywhere */
  --ctl-row: 48px;      /* phone drawer menu row — the ONE height for every drawer navlink (was 52 + auto/48) */
  --ctl-sm: 34px;        /* compact control (top-bar pills / subtabs inside the 44px bar) */
  --ic-1: 14px;         /* an icon inside a line of text */
  --ic-2: 16px;         /* an icon in a menu row, a list row or a question's corner */
  --ic-3: 18px;         /* a tool's icon on a phone */
  --ic-4: 20px;         /* a lone glyph and the phone menu's icons */
  --mark-1: 8px;        /* a small marker dot on a control or beside a name */
  --mark-2: 12px;       /* a legend swatch */
  --badge: 20px;        /* a small inline badge: a step number, a keycap, a row tag */
  --tap:    44px;        /* min interactive tap target        */
  --row:    var(--tap);  /* ⑦ a list row, one line (Style Guide §5.3 "The ten kinds"; 👤 2026-11-01): 44 at every width */
  --row-2:  56px;        /* ⑦ a list row, two lines (name + meta) */

  /* --- Layout ---------------------------------------------- */
  /* THE FOUR WIDTHS (STYLE_GUIDE §11 rule 5) — every max-width names one of these */
  --w-text:  640px;       /* a reading column (prose, a short form, the Recall subject list) */
  --w-col:   820px;       /* the main column: setup + quiz */
  --w-wide:  1040px;      /* a wide page (lists, cards) */
  --w-panel: 380px;       /* the docked Helpers panel */
  --w-dialog: 600px;      /* a dialog box, such as Report an issue */
  --rail:   60px;        /* collapsed left icon-rail width   */
  --drawer: 248px;       /* expanded sidebar drawer width    */

  /* --- Safe-area insets (notch / home-indicator) ----------
     The device's safe-area, tokenized so the shell reads it from ONE place. Resolves to 0 on any
     device without a notch/rounded corner (desktop, most iPads), so referencing these is free —
     it only takes effect where the hardware actually intrudes. REQUIRES viewport-fit=cover in the
     page <meta viewport> (set on every .html); without it the browser keeps these at 0. */
  --sa-top:    env(safe-area-inset-top,    0px);
  --sa-bottom: env(safe-area-inset-bottom, 0px);
  --sa-left:   env(safe-area-inset-left,   0px);
  --sa-right:  env(safe-area-inset-right,  0px);

  /* --- Header (top bar) height ----------------------------- */
  --bar-h:    calc(var(--ctl) + var(--s-4));   /* ONE height for the top bar, the bottom bar and the rail's two end cells: a control plus 8 above and 8 below — 52 desktop · 56 tablet · 60 phone (👤 2026-10-18: "your top and bottom menu bars do their own thing with size") */
  --topbar-h: var(--bar-h);
  --bottombar-h: calc(var(--bar-h) + var(--sa-bottom));   /* the bottom bar as drawn: the bar plus the home-indicator inset below it */
  --stick-top: calc(var(--topbar-h) + var(--s-3));
  --below-bar: calc(100dvh - var(--topbar-h) - var(--sa-top));   /* the screen under the top bar; dvh, because 100vh runs behind a phone browser's bars */
  --between-bars: calc(var(--below-bar) - var(--bottombar-h));   /* the screen between the top bar and the bottom bar */   /* where a sticky column in the page stops: below the sticky top bar, which the page scrolls under */
  --nav-w:    calc(var(--s-7) * 2 + var(--s-5));   /* ONE width for every navigation button in the top bar (‹ Back · ‹ Exit · Start over · Confirm) — 120 (👤 2026-10-18) */
}

/* ============================================================
   MOBILE type + header (<=720px). The desktop scale is tuned for a
   wide viewport; on a phone it reads too small, so bump the whole
   scale ~1 step. Redefining the tokens here keeps them the single
   source of truth and scales the WHOLE site at once.
   ============================================================ */
@media (max-width:720px){
  :root{
    --t-brand:  25px;    /* top-bar context title (was 22) */
    --t-h1:     24px;    /* was 28 → 24, 2026-10-03 (👤 "title too big"; STYLE_GUIDE R3: ONE title size) */
    --t-h2:     21px;    /* was 19 */
    --t-h3:     18px;    /* was 16 */
    --t-body:   16px;    /* was 15 — closer to native ~17 */
    --t-meta:   14px;    /* was 13 */
    --t-eye:    12px;    /* was 11 — the MODE/EXAM/LENS eyebrows */
    --ctl-2l:   60px;    /* two-line chip, touch scale (44 + the same 16px the desktop pair uses) */
    --sp-group: var(--s-6);   /* group to group on a phone (Style Guide §2.2) */
    --ctl:      44px;    /* was 36 — chips/buttons hit the real 44px tap target on a PHONE too (the tablet
                            block already did this; phones were missed, so chips read a touch small + cramped
                            to tap). One lever: --ctl steps 36 desktop · 40 tablet · 44 phone (by width, here). */
  }
}

/* ============================================================
   TABLET / small-laptop (721–1180px). This band catches iPads AND
   any laptop/browser window whose LOGICAL width lands here (very
   common on retina laptops ~1000–1180). The old rule scaled TYPE up
   ~1 step for iPads-held-close, but on a laptop that read as
   oversized ("grandma's computer"). So type now INHERITS the desktop
   scale (identical sizes, one consistent reading experience across
   desktop/laptop/tablet); only the CHROME gets a light, non-inflating
   bump — a slightly taller bar, wider rail, and 40px (not 44px)
   controls so touch still has a target without towering on a laptop.
   ============================================================ */
@media (min-width:721px) and (max-width:1180px){
  :root{
    --rail:     66px;    /* was 76 */
    --ctl:      40px;    /* was 44 — touch-reachable but not oversized on a laptop pointer */
    --ctl-2l:   56px;    /* two-line chip at the same scale */
  }
}
