/* ═══════════════════════════════════════════════════════════════════
   theme.css — maps brand tokens onto site tokens.

   Layer 2 of 3:  brand.css  →  theme.css  →  style.css
   Rebranding happens here and only here. style.css never contains a
   literal hex value; it only ever reads the tokens defined below.
   ═══════════════════════════════════════════════════════════════════ */

/* ─── Fonts ─────────────────────────────────────────────────────────
   Self-hosted from the first commit. Never a Google Fonts request,
   not even in a preview build: a runtime request transmits every
   visitor's IP to a third country, and it is the single largest
   privacy exposure a static site can have.

   Both faces are OFL 1.1; the licence text ships beside them in
   assets/fonts/. Subsets are Latin + Latin Extended-A and were
   verified to retain  →  —  –  ·  ©  , which the copy depends on.

   Hanken Grotesk is one variable file covering 100–900: it is
   smaller than the three static weights it replaces (34.1 KB against
   35.3 KB) and costs one request instead of three.
   ─────────────────────────────────────────────────────────────────── */
@font-face {
  font-family: 'Hanken Grotesk';
  src: url('/assets/fonts/hanken-grotesk-var.woff2') format('woff2');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'IBM Plex Mono';
  src: url('/assets/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('/assets/fonts/ibm-plex-mono-500.woff2') format('woff2');
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}

:root {
  /* ─── Surfaces ───────────────────────────────────────────────────
     ⚠ These deliberately do NOT come from brand.css.

     brand.css still defines --pp-paper #f6f6f4 and --pp-canvas
     #e6e7e4. Those are the warm greys that made the earlier draft
     feel muted, and replacing them was the single biggest colour
     decision taken. brand.css stays untouched as the brand's own
     record — it is still correct for print.

     Wiring --bg to --pp-canvas would look like tidying up and would
     quietly reintroduce the beige. Do not do it.
     ───────────────────────────────────────────────────────────── */
  --bg:      #f1f7f6;   /* page canvas — faintly teal, not grey  */
  --surface: #ffffff;   /* cards, content surfaces               */
  --border:  #d8e5e2;   /* hairlines — teal-tinted               */
  --tint-1:  #eff7f5;   /* alternating sections, icon plates     */
  --tint-2:  #dcece8;   /* diagram fills, photo plates           */
  --tint-3:  #c3ded8;   /* card hover edge, diagram connectors   */

  /* ─── Ink ────────────────────────────────────────────────────────
     Straight from brand.css. The neutral departure above is limited
     to surfaces; the spec's palette table leaves the inks alone. */
  --text:       var(--pp-ink);
  --text-soft:  var(--pp-ink-soft);
  /* Not var(--pp-ink-faint). The brand's #74787a measures 4.46:1 on
     white and 3.94:1 on this canvas, and it is used for captions, mono
     labels and table headers — all small text, all needing 4.5:1. This
     value is the same hue a step darker: 5.15:1 on white, 4.75:1 on the
     canvas, 4.71:1 on the tint. brand.css keeps its own value for
     print, where the contrast question does not arise. */
  --text-faint: #6a6e70;

  /* ─── Teal — the system, and every action ────────────────────── */
  --accent:        var(--pp-teal);
  --accent-hover:  var(--pp-teal-deep);
  --accent-bright: var(--pp-teal-bright);

  /* ─── Terracotta — identity and outcomes, never an action ─────
     Never on buttons or links. Warm reds read as "error" in an
     interface; teal keeps every interactive job on the site. */
  --warm:        var(--pp-terracotta);        /* mark, highlight rule   */
  --warm-ink:    var(--pp-terracotta-deep);   /* eyebrows, small text   */
  --warm-bright: var(--pp-terracotta-bright); /* on ink surfaces only   */
  --warm-tint:   var(--pp-terracotta-tint);   /* CTA band, "after" cell */

  /* ─── Ink surfaces (statement band, footer) ──────────────────── */
  --band:       var(--pp-ink);
  --band-text:  #f3f7f6;
  --band-soft:  #c2ccce;
  --band-faint: #8fa0a1;
  --band-rule:  var(--pp-teal-bright);
  --band-line:  #333e40;
  --band-link:  #c6d3d2;

  --shadow: rgba(35, 39, 42, .08);

  /* ─── Type ───────────────────────────────────────────────────── */
  --sans: 'Hanken Grotesk', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --mono: 'IBM Plex Mono', ui-monospace, 'SF Mono', Menlo, monospace;

  /* Tight scale, ratio ≈ 1.25. Desktop values; the mobile step is
     in style.css at the 900px breakpoint. */
  --fs-h1:      44px;
  --fs-h2:      30px;
  --fs-h3:      21px;
  --fs-lede:    21px;
  --fs-body:    17px;
  --fs-small:   15px;
  --fs-mono:    13px;
  --fs-band-h2: 38px;

  --lh-h1: 1.1;
  --lh-h2: 1.2;
  --lh-h3: 1.3;
  --lh-lede: 1.5;
  --lh-body: 1.55;

  --ls-head: -.01em;
  --ls-mono: .08em;

  /* ─── Rhythm — everything is a multiple of 8 ─────────────────── */
  --sp-section:  64px;  /* section to section          */
  --sp-block:    24px;  /* block to block within one   */
  --sp-head:     12px;  /* heading to its body         */
  --sp-card:     20px;  /* card padding                */
  --pad:         48px;  /* page gutter, above 768px    */

  --w-content: 1200px;  /* card grids, diagrams        */
  --w-prose:    720px;  /* prose sections              */
  --measure:     68ch;  /* prose never runs wider      */

  --r-card: 12px;
  --r-btn:   8px;

  /* Motion is deliberately dull. Nothing over 300ms, nothing that
     delays reading, nothing on a timer. */
  --t: .18s ease-out;
}

@media (max-width: 768px) {
  :root { --pad: 24px; }
}
@media (max-width: 480px) {
  :root { --pad: 20px; }
}
