/* ============================================================
   Termdeck — Typography tokens
   ============================================================ */

:root {
  /* Families — V3: Geist is the UI + display face, DM Mono the code face.
     DM Mono replaced Geist Mono in this stack; Geist Mono keeps its
     @font-face and is still reachable by name, but it is NOT listed behind
     DM Mono — that would be a webfont behind a webfont, which is exactly
     what the measurement below says never to do. DM Mono ships only
     300/400/500, so mono set at 600+ is synthetic bold, by design.
     The Meridian faces (DM Sans, Space Grotesk, JetBrains Mono, IBM Plex) are
     no longer in these stacks. They are WEBFONTS, and a webfont behind another
     webfont can only ever be shown in the swap window before the first one
     arrives — which is a second download, at full price, for a few hundred
     milliseconds of type nobody asked for. Measured: making the board paint
     sooner was enough to open that window, and the browser fetched DM Sans
     (36 KB) the instant Geist landed, which cost a chat deep link ~900 ms of
     bandwidth the transcript was waiting on. The system faces after them cover
     the same gap for free, which is what a fallback is for.
     The @font-face declarations stay: anything naming a face directly still
     gets it. */
  --font-sans: 'Geist', 'Helvetica Neue', Arial, ui-sans-serif, system-ui, sans-serif;
  --font-display: 'Geist', 'Helvetica Neue', Arial, ui-sans-serif, system-ui, sans-serif;
  --font-mono: 'DM Mono', ui-monospace, 'SF Mono', 'Menlo', 'Consolas', monospace;

  /* Type scale (rem, 16px base) */
  --text-xs:   0.75rem;   /* 12 */
  --text-sm:   0.8125rem; /* 13 */
  --text-base: 0.9375rem; /* 15 — default UI body */
  --text-md:   1rem;      /* 16 */
  --text-lg:   1.125rem;  /* 18 */
  --text-xl:   1.375rem;  /* 22 */
  --text-2xl:  1.75rem;   /* 28 */
  --text-3xl:  2.25rem;   /* 36 */
  --text-4xl:  3rem;      /* 48 */
  --text-5xl:  3.75rem;   /* 60 */
  --text-6xl:  4.75rem;   /* 76 */

  /* --- Workspace UI scale -------------------------------------
     The ramp above is authored for marketing: it starts at 12 and
     the gaps are wide, because a landing page has one thing to say
     per screen. Dense Operate chrome needs rungs it does not have,
     and the app had been inventing them one declaration at a time —
     the settings surface alone carried 11, 11.5, 12, 12.5, 13, 13.5
     and 14. Seven steps inside three pixels: not one of them a
     difference a reader can see, every one of them a difference a
     maintainer has to keep alive.

     Five rungs, each with a job. If a new size is needed, the
     question to answer first is which of these it is not.

     THE LADDER MOVED UP ONE STEP (11-15 → 12-16). The brief was a
     roomier, less dense console, taken from a marketing system whose
     body copy sits at 16px. Setting --ui-control to 16 outright would
     have been the copy-paste: 16px is a reading size for a centred
     820px column, and a sidebar row, a select and a composer chip are
     none of those — the tabstrip and the permission dialog would have
     had to shed labels to fit. Moving every rung up a single pixel
     keeps the five jobs and their relationships intact, lands body and
     control inside the 14-16 band the reference actually reads at, and
     leaves the geometry solvable. Same shape, one notch roomier. */
  --ui-label: 0.75rem;      /* 12 — uppercase micro-labels, group headings */
  --ui-meta: 0.8125rem;     /* 13 — tags, counts, status, timestamps */
  --ui-control: 0.875rem;   /* 14 — nav items, inputs, selects, buttons */
  --ui-body: 0.9375rem;     /* 15 — descriptions and running prose */
  --ui-emphasis: 1rem;      /* 16 — the title of a group or a row */

  /* The sixth rung, and the one the Five-Rungs Rule asks you to justify: it is
     the only size in the app set for READING rather than for chrome. A turn in
     the transcript is prose you sit with, not a label you scan, and it shipped
     at 16 from the beginning — `.md pre` even calls itself "deliberately
     tighter than the 16px prose". Two things follow from it, which is why it
     earns a name: the composer types at the size the transcript reads at, and
     16 is also the size below which iOS Safari zooms the page on focus, so the
     message box cannot go smaller without the viewport jumping on every tap. */
  --ui-read: 1rem;          /* 16 — transcript prose and the composer */

  /* Display, for surfaces that name themselves. */
  --ui-title: 1.125rem;     /* 18 — a modal's own name */
  --ui-display-sm: 1.5rem;  /* 24 — a pane title, narrow */
  --ui-display: 1.875rem;   /* 30 — a pane title */

  /* Weights
     600 is the ceiling for sans. The reference system never goes heavier
     than semibold and never lighter than regular, and that restraint is
     most of why it reads as engineered rather than shouty — emphasis
     comes from size, colour and space instead of from fat type. 700 and
     800 stay declared because rules still reference them, but they are
     legacy rungs: nothing new should reach for them, and the eyebrow /
     display roles below top out at 600.
     Mono has its own, lower ceiling of 500 — see the Monospace Spine
     Rule and tests/mono-weight-ceiling.mjs. */
  --weight-light: 300;
  --weight-regular: 400;
  --weight-medium: 500;
  --weight-semibold: 600;   /* the sans ceiling */
  --weight-bold: 700;       /* legacy — being retired */
  --weight-extrabold: 800;  /* legacy — being retired */

  /* Line heights */
  --leading-none: 1;
  --leading-tight: 1.15;
  --leading-snug: 1.3;
  --leading-normal: 1.5;
  --leading-relaxed: 1.65;

  /* Letter spacing */
  --tracking-tighter: -0.03em;
  --tracking-tight: -0.018em;
  --tracking-normal: 0;
  --tracking-wide: 0.02em;
  --tracking-caps: 0.08em;

  /* Keep display weights restrained for the Claude-like editorial serif. */
  --display-hero: var(--weight-bold) var(--text-6xl)/var(--leading-none) var(--font-display);
  --display-title: var(--weight-bold) var(--text-3xl)/var(--leading-tight) var(--font-display);
}
