/* gw-fonts.css — the self-hosted brand faces, for pages that reach neither
   sentinel.css nor gw-editorial.css.

   WS-FONTS 2026-08-11. The vault card/rank/leaderboard surfaces are served as
   standalone static HTML (routes/vault_ranks.py -> send_from_directory), so
   they link none of the design-system sheets and used to pull their type from
   fonts.googleapis.com. On a product that sells getting your details off the
   internet, that handed a third party the IP address of every visitor, and the
   two preconnects opened the TLS handshakes before the page had painted.

   The @font-face bodies below are byte-identical to the ones in
   gw-editorial.css and sentinel.css. Identical family+src is deduped by the
   browser, so a page that ends up with both pays nothing extra.

   Do not add an @import to a font CDN back. Add a woff2 to static/fonts/ and
   an @font-face here. Pinned by
   tests/test_no_page_leaks_the_reader_to_a_font_cdn.py. */

/* WS-TYPE 2026-08-11 — Newsreader (display) + Public Sans (body), both SIL
   Open Font License 1.1, latin variable subsets from Google Fonts
   (Newsreader v1.003 opsz pinned 36 / wght 300–700; Public Sans v2.001 /
   wght 100–900), subset with pyftsubset to the unicode-range below.
   Provenance, licence obligations and the fallback derivation live in
   gw-editorial.css; the full notice is static/fonts/LICENSES.md. */
/* ── WS-TYPE 2026-08-11 (part 2) — THE RETIRED PAIR IS GONE FROM THIS FILE.
   The 'Inter' and 'Space Grotesk' @font-face blocks, and their metric-matched
   Fallback companions, used to sit here. Part 1 shipped Newsreader + Public
   Sans and left them in place, so the site shipped BOTH pairs: 145.2 KB of
   webfont against the 45.0 KB PRODUCT.md §Typography was approved on.

   What kept the two files on the wire was two `<link rel="preload" as="font">`
   lines in templates/shared.py. A preload is UNCONDITIONAL, so both faces were
   fetched on 26/26 public routes at both viewports while /pricing and
   /features resolved zero elements and zero pseudo-elements to either.

   Retired only after the census came back empty: measured 2026-08-11 across
   41 public routes at 1440 and 390, counting ::before and ::after as well as
   elements — Public Sans and Newsreader on every route, the retired pair on
   none, and neither .woff2 in any request log. The files are deliberately
   still on disk so reverting this is a one-file revert.

   The NEW faces' per-weight fallbacks below must NOT follow them out. They are
   why the measured CLS 0.371 regression cannot return. ─────────────────── */
@font-face{
  font-family:'Newsreader';font-style:normal;font-weight:300 700;font-display:swap;
  src:url('/static/fonts/newsreader-var-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:100 900;font-display:swap;
  src:url('/static/fonts/public-sans-var-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;
}
/* metric-matched pre-swap fallbacks — mirror of gw-editorial.css (CLS fix
   2026-07-16). Arial sized to occupy the same box as the real face, so
   font-display:swap causes no reflow. See gw-editorial.css for the derivation. */
/* WS-TYPE 2026-08-11 — PER-WEIGHT, and that is the whole point.
   A single fallback value is correct for a GROTESK, whose advances barely move
   with weight: measured over the weights this site paints, Space Grotesk's one
   override is +1.78% at 300 and +1.25% at 700. A SERIF is not like that.
   Newsreader's override derived at 700 (the research note's 100.37%) measures
   +11.64% at 300 — and 300 is the weight the hero H1 is painted at. It
   re-wrapped the headline on first paint and re-wrapped it back on swap:
   measured CLS 0.0248 on / at 1440 and 0.0523 at 390, against 0.0000 for the
   faces it replaces. Copying the one-value idiom here would have shipped the
   /pricing 0.371 regression back in a new costume.
   Derived two-pass in headless Chrome against the exact woff2 files above, at
   every weight a rendered route actually paints (display 300-700, body
   300-900, measured — not read off the CSS): converged to |advance error|
   < 0.01% and line-box delta +0.00px at every weight.
   The `font-weight` descriptor is load-bearing twice: it selects the right
   stand-in, AND it stops the browser synthetically emboldening Arial, which
   changes its advances. Re-derive with the descriptors in place, never from
   the binary alone. Harness: scratchpad/ws-type/tune_per_weight.py. */
@font-face{font-family:'Newsreader Fallback';font-weight:300;src:local('Arial');size-adjust:89.90%;ascent-override:81.75%;descent-override:29.47%;line-gap-override:0%}
@font-face{font-family:'Newsreader Fallback';font-weight:350;src:local('Arial');size-adjust:91.20%;ascent-override:80.59%;descent-override:29.05%;line-gap-override:0%}
@font-face{font-family:'Newsreader Fallback';font-weight:400;src:local('Arial');size-adjust:92.47%;ascent-override:79.49%;descent-override:28.66%;line-gap-override:0%}
@font-face{font-family:'Newsreader Fallback';font-weight:500;src:local('Arial');size-adjust:94.75%;ascent-override:77.57%;descent-override:27.96%;line-gap-override:0%}
@font-face{font-family:'Newsreader Fallback';font-weight:600;src:local('Arial');size-adjust:97.30%;ascent-override:75.54%;descent-override:27.23%;line-gap-override:0%}
@font-face{font-family:'Newsreader Fallback';font-weight:700;src:local('Arial');size-adjust:99.85%;ascent-override:73.61%;descent-override:26.54%;line-gap-override:0%}
@font-face{font-family:'Public Sans Fallback';font-weight:300;src:local('Arial');size-adjust:103.09%;ascent-override:92.15%;descent-override:21.83%;line-gap-override:0%}
@font-face{font-family:'Public Sans Fallback';font-weight:350;src:local('Arial');size-adjust:103.49%;ascent-override:91.79%;descent-override:21.74%;line-gap-override:0%}
@font-face{font-family:'Public Sans Fallback';font-weight:400;src:local('Arial');size-adjust:103.89%;ascent-override:91.44%;descent-override:21.66%;line-gap-override:0%}
@font-face{font-family:'Public Sans Fallback';font-weight:500;src:local('Arial');size-adjust:104.70%;ascent-override:90.74%;descent-override:21.49%;line-gap-override:0%}
@font-face{font-family:'Public Sans Fallback';font-weight:600;src:local('Arial');size-adjust:105.49%;ascent-override:90.05%;descent-override:21.33%;line-gap-override:0%}
@font-face{font-family:'Public Sans Fallback';font-weight:700;src:local('Arial');size-adjust:106.82%;ascent-override:88.93%;descent-override:21.06%;line-gap-override:0%}
@font-face{font-family:'Public Sans Fallback';font-weight:800;src:local('Arial');size-adjust:108.15%;ascent-override:87.84%;descent-override:20.81%;line-gap-override:0%}
@font-face{font-family:'Public Sans Fallback';font-weight:900;src:local('Arial');size-adjust:109.48%;ascent-override:86.77%;descent-override:20.55%;line-gap-override:0%}

/* ── the two aliases, so the surfaces this file serves can reach the type the
   same way every other surface does. ─────────────────────────────────────
   WS-TYPE 2026-08-11. The vault rank/leaderboard/card pages are the only
   pages on the property that link this sheet and nothing else — no
   gw-tokens.css, no sentinel.css, no gw-editorial.css — and gw-tokens.css is
   where --gw-sans/--gw-display are declared for everybody else. Without this
   block, retargeting those pages' 40-odd inline display declarations onto
   var(--gw-display) would resolve to the var() fallback on every one of them:
   correct faces, but by luck of the fallback list rather than through the
   token, and any future token change would reach the whole site EXCEPT the
   vault. Same values as gw-tokens.css §5; the Fallback family stays second
   because it is the metric-matched Arial that holds the box for the pre-swap
   moment. */
:root{
  --gw-sans:'Public Sans','Public Sans Fallback',system-ui,-apple-system,'Segoe UI',Roboto,sans-serif;
  --gw-display:'Newsreader','Newsreader Fallback',Georgia,'Times New Roman',serif;
}

/* WS-TYPE 2026-08-11 — and the rule that USES them. This sheet declared four
   faces and consumed none, so the root element on the vault surfaces fell to
   the browser default: measured 1 element in Times on /vault-ranks,
   /vault-leaderboard and /vault-card/*, which is the <html> box the page's own
   `body{...}` rule never covers. DESIGN.md §1.2 is the same finding on the
   other shell. */
html,body{font-family:var(--gw-sans);}
