/* Pressmark v2 — design tokens. ROUND 1 REWRITE (THE-101).
 *
 * The art direction changed. The old file was a cold blue slate ground with one lime accent;
 * a fresh design judge scored originality 5/10 and named it the same house as Lotstep v2
 * (evidence/pressmark/v2-qa-r1.md). This file is the replacement world: paper stock, ink,
 * and one stamp. See DESIGN.md §1 and §2 for the reasoning.
 *
 * Contract: design/pressmark-v2/DESIGN.md. Link this file FIRST.
 * No component writes a hex. Verify with `node bin/contrast.mjs design/pressmark-v2/tokens.css`.
 * Self-hosted fonts only — CSP is default-src 'self'.
 */

/* ---------------------------------------------------------------------------
 * Fonts. Three roles, three faces, all OFL 1.1, all variable, all local.
 * Bodoni Moda carries BOTH axes (opsz 6–96, wght 400–900): a Didone is a different
 * drawing at 14px and at 96px, and the display sizes below set the optical size
 * through `font-variation-settings`. Do not swap in the `wght`-only file — it pins
 * opsz at 11 and the headline loses every hairline that makes the face worth shipping.
 * ------------------------------------------------------------------------ */

@font-face {
  font-family: 'Bodoni Moda Variable';
  font-style: normal;
  font-display: swap;
  font-weight: 400 900;
  src: url('../fonts/bodoni-moda-latin-opsz-normal.woff2') format('woff2-variations');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212,
    U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Sora Variable';
  font-style: normal;
  font-display: swap;
  font-weight: 100 800;
  src: url('../fonts/sora-latin-wght-normal.woff2') format('woff2-variations');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212,
    U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Spline Sans Mono Variable';
  font-style: normal;
  font-display: swap;
  font-weight: 300 700;
  src: url('../fonts/spline-sans-mono-latin-wght-normal.woff2') format('woff2-variations');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212,
    U+2215, U+FEFF, U+FFFD;
}

:root {
  /* ---- Stock: the paper. Unbroken from nav to the colophon. ----------------
   * A warm-neutral bone at hue ~90 and chroma under 0.025 — paper, not cream.
   * The chroma ceiling is the guard against the cream-and-terracotta default
   * that `frontend-design` names: this stock is barely a colour, and the one
   * accent on it is cool-dark, not warm-mid. */
  --stock-050: #FAF8F2; /* a fresh catalog card, face up — the brightest thing on the page */
  --stock-100: #F2EEE4; /* PAGE GROUND. The sheet. */
  --stock-200: #E7E2D5; /* the sheet underneath; inactive questionnaire rows; drawer interior */
  --stock-300: #D9D3C3; /* card edges seen end-on in the drawer; the cards behind in a stack */

  /* ---- Rule: the ledger lining ---- */
  --rule: #DED8C9;      /* decorative: the ruled lines, sheet edges, table rules (1.2:1) */
  --rule-live: #8C836E; /* meaningful: a leader, the keyline of the row being traced (3.2:1) */

  /* ---- Ink ----
   * Warm near-black at hue 67. Not a blue-black: the blue-black page is the thing
   * being removed, and a warm ink is what sits on paper. #000000 appears nowhere. */
  --ink-900: #1C1814; /* display and body (15.2:1 on --stock-100) */
  --ink-500: #5B5346; /* card values, secondary headings (6.5:1) */
  --ink-400: #696151; /* captions, field labels, illustrative notes (5.3:1) */

  /* ---- The stamp. The only colour on the site. ---------------------------
   * Oxblood: the colour of a struck date-stamp and of a ledger binding.
   * IMPRESSION = reviewed data. PLANE = action. Never both at once — §2. */
  --stamp: #6E2639;       /* 9.1:1 on --stock-100 · --stock-100 on it = 9.1:1 */
  --stamp-ink: #581D2D;   /* primary button hover only: the press struck harder */
  --stamp-mid: #9C4A5C;   /* dataviz ramp step 2 (5.1:1) */
  --stamp-pale: #B2737F;  /* dataviz ramp step 3 (3.2:1) */

  /* ---- The colophon block: the one inverted surface, at the foot of the page ---- */
  --colophon: #1C1814;      /* == --ink-900 as a field */
  --colophon-text: #F2EEE4; /* == --stock-100 as text on it (15.2:1) */
  --colophon-muted: #B8B1A3; /* 7.6:1 on --colophon */
  --colophon-rule: #3A342C;

  /* ---- The ratios above, as assertions `bin/contrast.mjs` checks ----
   * Every threshold is the one DESIGN.md §2 states for that pair.
   *
   * @contrast ink-900 on stock-100 >= 4.5    display and body on the sheet
   * @contrast ink-900 on stock-050 >= 4.5    text on a card face
   * @contrast ink-900 on stock-200 >= 4.5    text on the sheet underneath
   * @contrast ink-500 on stock-100 >= 4.5    card values, secondary headings
   * @contrast ink-500 on stock-050 >= 4.5    the same, on a card face
   * @contrast ink-400 on stock-100 >= 4.5    captions, labels, illustrative notes
   * @contrast ink-400 on stock-050 >= 4.5    field labels on a card face
   * @contrast ink-400 on stock-200 >= 4.5    labels on an inactive row — the tightest text pair
   * @contrast stamp on stock-100 >= 4.5      the stamp as impression or as text
   * @contrast stamp on stock-050 >= 4.5      the stamp struck on a card face
   * @contrast stamp on stock-200 >= 4.5      the stamp struck on the sheet underneath
   * @contrast stock-100 on stamp >= 4.5      the CTA label on the stamp plane
   * @contrast stock-100 on stamp-ink >= 4.5  the same label on hover
   * @contrast colophon-text on colophon >= 4.5   the inverted block at the foot
   * @contrast colophon-muted on colophon >= 4.5  secondary text in the colophon
   * @contrast rule-live on stock-100 >= 3    non-text: leaders, traced-row keyline
   * @contrast stamp-mid on stock-100 >= 3    non-text: dataviz ramp step 2
   * @contrast stamp-pale on stock-100 >= 3   non-text: dataviz ramp step 3
   * @contrast stamp-pale on colophon >= 3    non-text: the mark inside the colophon block
   * @contrast rule on stock-100 < 3          decorative on purpose (DESIGN.md §2 "Rule"): the
   *                                          ledger lining must stay under --rule-live, which is
   *                                          the only hairline that carries meaning
   * @contrast stock-300 on stock-100 < 3     decorative on purpose: a card edge is a surface,
   *                                          not a line, and must not read as one
   * @contrast stamp on colophon < 3          FORBIDDEN inside the colophon block: the oxblood
   *                                          disappears on ink. Use --stamp-pale there.
   */

  /* ---- Type ----
   * Three roles, and the boundaries between them are enforced in DESIGN.md §3:
   *   display  Bodoni Moda      — h1, h2, section numerals. Nothing under 24px, ever.
   *   text     Sora             — body, labels, buttons, nav. Nothing over 20px, ever.
   *   code     Spline Sans Mono — shelf-mark codes and dates. Nothing else, ever.
   * The third rule is a fix, not a preference: the QA judge listed "the same mono
   * micro-labels" among the things that made this site read as Lotstep's. */
  --font-display: 'Bodoni Moda Variable', Georgia, 'Times New Roman', serif;
  --font-text: 'Sora Variable', system-ui, sans-serif;
  --font-code: 'Spline Sans Mono Variable', ui-monospace, monospace;

  /* Optical size, set per role. A Didone needs this or it is not a Didone. */
  --opsz-h1: 'opsz' 72;
  --opsz-h2: 'opsz' 40;
  --opsz-h3: 'opsz' 18;

  --size-h1: clamp(2.75rem, 1.55rem + 4.6vw, 5rem);
  --size-h2: clamp(1.875rem, 1.25rem + 2.2vw, 2.875rem);
  --size-h3: 1.25rem;
  --size-lead: clamp(1rem, 0.96rem + 0.22vw, 1.125rem);
  --size-body: 1rem;
  --size-caption: 0.8125rem;
  --size-data: 0.8125rem;

  /* Display weights are low on purpose: a Didone gets its authority from the contrast
   * between stem and hairline, not from mass. 700+ fills the counters and kills it. */
  --weight-h1: 500;
  --weight-h2: 500;
  --weight-h3: 600; /* Sora */
  --weight-action: 550;
  --weight-data: 450;
  --weight-body: 400; /* 400, not 350: ink on paper does not need the dark-ground correction */

  --lh-h1: 0.98;
  --lh-h2: 1.06;
  --lh-h3: 1.3;
  --lh-lead: 1.5;
  --lh-body: 1.6;
  --lh-caption: 1.45;
  --lh-data: 1.35;

  /* A Didone sets tight by nature; a little negative tracking closes the word spaces. */
  --track-h1: -0.015em;
  --track-h2: -0.01em;
  --track-h3: -0.005em;
  --track-data: 0.02em;

  --measure-body: 62ch;
  --measure-lead: 50ch;
  --measure-caption: 46ch;

  /* ---- Spacing (4px base) ---- */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 24px;
  --space-6: 32px;
  --space-7: 48px;
  --space-8: 64px;
  --space-9: 96px;
  --space-10: 144px;

  /* Was 8.5rem (136px). Cut to 6rem because QA measured five of six bands under 45%
   * content fill (v2-qa-r1.md). The band rhythm was the biggest single contributor.
   * DESIGN.md §9 carries the matching fill floor. */
  --space-section: 6rem;

  /* ---- The ruled sheet ----
   * The page's skeleton. A 32px baseline ruling runs the full content width through
   * every band, so no band is ever one small object floating in a void. */
  --ruling: 32px;        /* distance between ruled lines */
  --margin-rule: 64px;   /* the ledger margin: the vertical rule, this far from the sheet's left */

  /* ---- Shape. Paper is cut, not rounded. ---- */
  --radius-card: 2px;   /* a catalog card's corner is barely rounded */
  --radius-chip: 2px;
  --radius-button: 0px; /* the stamp plane is a struck rectangle, not a pill */
  --hairline: 1px;
  --stamp-weight: 2px;  /* the impression's keyline */

  /* ---- Grid ---- */
  --content-width: 1120px;
  --page-pad: 24px;
  --gutter: 24px;

  /* ---- Motion. One orchestrated moment; everything else answers an action. ---- */
  --ease: cubic-bezier(.2, 0, 0, 1);
  --dur-hover: 120ms;
  --dur-reveal: 560ms;
  --dur-wipe: 520ms;
  --dur-strike: 180ms; /* the stamp coming down: short, hard, no bounce */

  /* ---- Stack offsets. Fixed values, never random. ---- */
  --stack-2-x: 8px;
  --stack-2-y: 10px;
  --stack-2-rot: 1.2deg;
  --stack-3-x: 16px;
  --stack-3-y: 20px;
  --stack-3-rot: -0.8deg;
  --stamp-rot: -2.5deg; /* a stamp is never struck square */
}

@media (max-width: 1199px) {
  :root { --space-section: 5rem; --margin-rule: 40px; }
}

@media (max-width: 767px) {
  :root {
    --space-section: 4rem;
    --page-pad: 16px;
    --margin-rule: 24px;
    --ruling: 28px;
  }
}

/* ---------------------------------------------------------------------------
 * Semantic layer. Components reference THESE, not the scale names above.
 * ------------------------------------------------------------------------ */
:root,
[data-theme='stock'] {
  --ground: var(--stock-100);
  --surface: var(--stock-050);
  --surface-sunk: var(--stock-200);
  --text: var(--ink-900);
  --text-muted: var(--ink-400);
  --rule-quiet: var(--rule);
  --mark-line: var(--stamp);
}

/* The colophon block at the foot of the page, and nothing else on the site. */
[data-theme='colophon'] {
  --ground: var(--colophon);
  --surface: var(--colophon);
  --surface-sunk: var(--colophon);
  --text: var(--colophon-text);
  --text-muted: var(--colophon-muted);
  --rule-quiet: var(--colophon-rule);
  --mark-line: var(--stamp-pale); /* --stamp is 1.9:1 on the ink block: unusable there */
}

/* One focus ring, everywhere, never removed. Clears the sheet AND the stamp plane. */
:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px var(--stock-100), 0 0 0 4px var(--ink-900);
}

[data-theme='colophon'] :focus-visible {
  box-shadow: 0 0 0 2px var(--colophon), 0 0 0 4px var(--colophon-text);
}

/* The hero renders its final frame; nothing transitions. Not a degraded page — an equivalent one. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}
