/* tokens.css — design tokens for the PUBLIC (pre-login) marketing site.
 *
 * Separate from app/static/tokens.css on purpose. That file is the product's
 * token contract (warm paper, ink-blue, sidebar shell); this one is the
 * marketing site's, and the two are allowed to diverge — a sales page and a
 * working tool have different jobs. Sharing one palette would force every
 * marketing decision through the app's UI constraints and vice versa.
 *
 * SOURCE OF TRUTH: docs/design-reference/tokens.md, extracted from the approved
 * Claude Design render (docs/design-reference/pressmatch-homepage.html, frozen
 * 2026-07-27). Every value below is traceable to that render. Change a value
 * here only with the reference updated in the same commit, or the "why this
 * blue?" answer rots.
 *
 * COLOUR-BLINDNESS (owner is red/green CVD): there is no saturated red or green
 * in this palette, deliberately. Meaning is carried by LIGHTNESS plus one blue;
 * gold marks a single top value. Any state colour added later must clear the
 * same bar — never a red/green pair as the only difference between two states.
 */

/* --- Typefaces: self-hosted, OFL. See fonts/README.md. ------------------
 * Never a Google Fonts hotlink: it leaks the visitor's IP to a third party
 * before they have done anything, and it punches a hole in the CSP.
 * These blocks are the vendor's own (weights, stretch, unicode-range) with
 * only the src rewritten — the subsetting is theirs, not a guess of ours.
 */
@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 400 600;
  font-stretch: 100%;
  font-display: swap;
  src: url(fonts/archivo-400-600-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 400 600;
  font-stretch: 100%;
  font-display: swap;
  src: url(fonts/archivo-400-600-latin.woff2) format('woff2');
  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: 'Public Sans';
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url(fonts/public-sans-400-600-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Public Sans';
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url(fonts/public-sans-400-600-latin.woff2) format('woff2');
  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: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(fonts/ibm-plex-mono-400-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(fonts/ibm-plex-mono-400-latin.woff2) format('woff2');
  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: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(fonts/ibm-plex-mono-500-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(fonts/ibm-plex-mono-500-latin.woff2) format('woff2');
  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;
}

:root {
  /* --- Paper: the surface ladder ------------------------------------- */
  --pm-paper-page:   #F1EFE9;  /* the page itself */
  --pm-paper-sheet:  #FCFAF5;  /* raised panels — paste box, match readout */
  --pm-paper-card:   #F7F2E6;  /* warm card fill — the coach tip */
  --pm-paper-deep:   #EDE8DC;  /* recessed / inset fill */
  --pm-rule:         #E3E1DA;  /* hairline dividers */

  /* --- Ink ------------------------------------------------------------ */
  --pm-ink:          #14171A;  /* display + primary text */
  --pm-graphite:     #454B52;  /* body text */
  /* Captions, secondary lines, eyebrows. DARKENED from the render's #7C7565,
   * which measures 3.98:1 on --pm-paper-page — below the 4.5:1 WCAG AA floor
   * for normal-size text, and this token's whole job is small text (eyebrows
   * are 11px). #6F695B is the same hue and saturation two steps darker, at
   * 4.75:1. The difference is invisible next to the original; failing it is
   * not. The app's own tokens.css made the identical call for --c-faint. */
  --pm-muted:        #6F695B;

  /* --- Signal: the one accent ----------------------------------------- */
  --pm-signal:       #1E5FCC;
  --pm-signal-hover: #164A9F;

  /* --- County ramp: the geography lattice ------------------------------
   * Four steps, lightness-primary. RELATIVE shading of journalist density
   * per county — not a scale with units, and the figures are still
   * placeholders (LAUNCH-PLAN-public-site §10 q2). Never label it as counts.
   */
  --pm-county-1:     #C9D8F1;
  --pm-county-2:     #A8C3EC;
  --pm-county-3:     #7BA3E3;
  --pm-county-4:     #4C82D9;

  /* --- Gold: spend it ONCE --------------------------------------------
   * One bar in the county lattice. A second use turns a signature into
   * decoration.
   *
   * NEVER TEXT. It measures 2.82:1 on paper — below AA for text at any size,
   * and below the 3:1 non-text floor as well. It works where it is used because
   * a bar is read by LENGTH first and the colour only says "this one"; it would
   * not work as a label, a link or a state. The approved render spends it a
   * second time on a link, which is the mistake this comment exists to prevent
   * being copied.
   */
  --pm-gold:         #B8862B;

  /* --- Type families --------------------------------------------------- */
  --pm-display: 'Archivo', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --pm-body:    'Public Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --pm-mono:    'IBM Plex Mono', ui-monospace, 'Cascadia Mono', Consolas, monospace;

  /* --- Type scale ------------------------------------------------------
   * The render is one fixed 1440px artboard, so its display sizes are the
   * TOP of the scale, not the whole of it. They are fluid here because an
   * 84px headline on a phone is not a decision anyone made — the artboard
   * simply had no mobile state to copy. The 1440px value is the clamp max,
   * so a wide screen renders exactly what was approved.
   */
  --pm-d1: clamp(2.75rem, 1.30rem + 5.80vw, 5.25rem);   /* 44 → 84 */
  --pm-d2: clamp(2.05rem, 1.30rem + 3.00vw, 3.25rem);   /* 33 → 52 */
  --pm-d3: clamp(1.75rem, 1.25rem + 2.00vw, 2.625rem);  /* 28 → 42 */
  --pm-d4: clamp(1.40rem, 1.10rem + 1.20vw, 1.875rem);  /* 22 → 30 */
  --pm-d5: clamp(1.20rem, 1.06rem + 0.55vw, 1.3125rem); /* 19 → 21 */
  --pm-body-l: clamp(1.05rem, 0.97rem + 0.35vw, 1.25rem);   /* 17 → 20 */
  --pm-body-m: clamp(1.0rem, 0.97rem + 0.13vw, 1.0625rem);  /* 16 → 17 */
  --pm-body-s: 0.9375rem;                                    /* 15 */
  --pm-label:  0.75rem;                                      /* 12 */
  --pm-label-s: 0.6875rem;                                   /* 11 */

  /* Leading + tracking, from the render's `font:` shorthands. */
  --pm-lh-display: 0.98;
  --pm-lh-head:    1.16;
  --pm-lh-body:    1.68;
  --pm-lh-tight:   1.22;
  --pm-tr-d1:     -0.036em;
  --pm-tr-d4:     -0.024em;
  --pm-tr-label:   0.13em;

  /* --- Layout ----------------------------------------------------------
   * The artboard is 1440px with 68px gutters. --pm-maxw is the CONTENT
   * width inside those gutters (1440 - 2*68), so a wide screen reproduces
   * the approved measure instead of stretching it.
   */
  --pm-maxw:   1304px;
  --pm-gutter: clamp(1.25rem, 0.60rem + 2.90vw, 4.25rem);   /* 20 → 68 */
  --pm-section-y: clamp(3.5rem, 2.0rem + 6.0vw, 6.5rem);

  /* --- Motion ----------------------------------------------------------
   * Three cues on the whole page, and that is the budget. The brief bans
   * fake liveness: nothing may tick, re-sort or otherwise imply the page is
   * doing work it is not doing.
   */
  --pm-ease: cubic-bezier(0.2, 0, 0.2, 1);
  --pm-dur:  200ms;
}

@keyframes pm-rise {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: none; }
}

/* Honour the OS setting — a quality floor, not a feature. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
