/* ==========================================================================
   Self-hosted Roboto — two files.
   Google Fonts now ships Roboto's upright styles as a single variable font
   (one file spans weights 100-900); we download it once at build time into
   src/fonts/ and serve it from our own origin. No requests to
   fonts.googleapis.com or fonts.gstatic.com happen at runtime — this is the
   whole point of self-hosting (see spec §1.5): no third-party origin, no
   CDN round-trip, no consent/tracking surface, and we control
   font-display ourselves.

   The "normal" (upright) file IS variable: font-weight: 300 700 on that
   @font-face rule is a *range*, not a single number — it tells the browser
   "this one file can render any weight in this range," and the browser
   picks the exact instance (300/400/500/700) our CSS asks for per element,
   same as if these were 4 separate static files.

   The "italic" file is different: Google serves italic Roboto as a plain
   static weight-400 file (used only for the case-study throughline, which
   is always Roboto 400 italic — see spec §1.5), so its @font-face declares
   a single font-weight: 400, not a range, and skips the
   "woff2-variations" format hint that only applies to true variable fonts.
   ========================================================================== */

@font-face {
  font-family: "Roboto";
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url("/fonts/roboto-variable-normal.woff2") format("woff2-variations"),
       url("/fonts/roboto-variable-normal.woff2") format("woff2");
}

@font-face {
  font-family: "Roboto";
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url("/fonts/roboto-variable-italic.woff2") format("woff2");
}

/* ------------------------------------------------------------------------
   Metric-matched fallback face (zero-CLS strategy, spec §1.5 / AC#4).
   "Roboto-fallback" is not a real font file — it's `local()`-only, pointing
   at a system font already installed on the visitor's machine (Arial on
   nearly every platform), with size-adjust/metric overrides tuned so its
   line boxes match Roboto closely. Because --font-sans lists
   "Roboto-fallback" right after "Roboto", the browser paints text in this
   fallback the instant CSS loads, then swaps to real Roboto when the woff2
   arrives (font-display: swap) — and because the two faces occupy almost
   the same vertical space, that swap causes no visible reflow.
   ------------------------------------------------------------------------ */
@font-face {
  font-family: "Roboto-fallback";
  src: local("Arial");
  ascent-override: 92.5%;
  descent-override: 24.3%;
  line-gap-override: 0%;
  size-adjust: 100.06%;
}

/* ==========================================================================
   Self-hosted Noto Serif — Direction 2.0 (v2.1), the display face.

   Same self-hosting rationale as Roboto above (no fonts.googleapis.com /
   fonts.gstatic.com request at runtime). Two files, matching the existing
   normal+italic pattern:
     - noto-serif-variable-normal.woff2 — the upright variable file, wght
       instanced down to 300-700 (we never use lighter than 300 or bolder
       than 700 on this face, so the axis was narrowed at subset time to
       save bytes — see the developer's report for the exact numbers).
     - noto-serif-variable-italic.woff2 — Noto Serif's real, separately-
       drawn italic (not a synthetic CSS slant), same 300-700 wght range,
       used only for pull-quotes.

   Subset to Latin (U+0000-00FF + common punctuation/symbols) — this single
   range already covers every Spanish/Chilean glyph needed (á é í ó ú ñ ü ¿
   ¡ and their capitals all live in the Latin-1 Supplement block, U+00E1
   etc.), so the much larger "Latin Extended" block Google ships alongside
   it (Vietnamese, Croatian caron letters, etc.) was dropped entirely — it
   is not needed for English or Spanish and would have roughly quadrupled
   the payload for glyphs this site will never render.

   No `wdth` (width) axis: Noto Serif's variable file only exposes `wght`,
   confirmed by inspecting the downloaded font — so there is nothing to
   drop or vary there (the proposal's "drop wdth if the tool allows" note
   is moot for this specific typeface).

   No `font-optical-sizing` declared: that CSS property only does something
   on faces with an `opsz` axis, which Noto Serif does not have — declaring
   it would be a no-op, so it's omitted per the proposal.
   ========================================================================== */

@font-face {
  font-family: "Noto Serif";
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url("/fonts/noto-serif-variable-normal.woff2") format("woff2-variations"),
       url("/fonts/noto-serif-variable-normal.woff2") format("woff2");
}

@font-face {
  font-family: "Noto Serif";
  font-style: italic;
  font-weight: 300 700;
  font-display: swap;
  src: url("/fonts/noto-serif-variable-italic.woff2") format("woff2-variations"),
       url("/fonts/noto-serif-variable-italic.woff2") format("woff2");
}

/* ------------------------------------------------------------------------
   Metric-matched fallback face for Noto Serif (zero-CLS strategy, same
   technique as Roboto-fallback above, this time computed against Georgia —
   the serif fallback named in --font-serif — rather than assumed:

     size-adjust:      121.38%  (ratio of avgCharWidth/unitsPerEm between
                                  Noto Serif and Georgia — scales Georgia's
                                  glyphs to occupy the same visual width)
     ascent-override:   88.07%  (Noto Serif's usWinAscent, expressed as a
                                  percentage of GEORGIA's em box after the
                                  size-adjust scale is applied)
     descent-override:  32.05%  (same method, Noto Serif's usWinDescent)

   These numbers were computed from the two fonts' real OS/2 and hhea
   tables (Noto Serif: unitsPerEm 1000, ascent 1069, descent 389; Georgia:
   unitsPerEm 2048, ascent 1878, descent 449, avgCharWidth 901 vs. Noto
   Serif's 534) — not guessed — so the swap from fallback to the real
   Noto Serif causes as close to zero layout shift as a metric override
   can achieve. `local()` intentionally omitted: unlike Arial (present on
   effectively every OS), Georgia is not guaranteed on Android/Linux, so
   this face is deliberately metrics-only (no font file, no local() match)
   — its only job is to hold the correct box size until the real Noto
   Serif swaps in; the visible glyphs during that (usually sub-100ms)
   window come from the next name in the --font-serif stack.
   ------------------------------------------------------------------------ */
@font-face {
  font-family: "Noto Serif-fallback";
  src: local("Georgia"), local("Times New Roman");
  ascent-override: 88.07%;
  descent-override: 32.05%;
  line-gap-override: 0%;
  size-adjust: 121.38%;
}
