/* Deliberately its own external stylesheet, not part of global.css. Astro
   inlines every page's CSS into a per-page <style> block (astro.config.mjs's
   inlineStylesheets: 'always'), and on every client-side navigation its
   ClientRouter only *persists* a <style> tag across the swap if its text is
   byte-identical between the old and new page — otherwise it's torn down and
   a fresh one inserted. Since each page bundles a different mix of
   component CSS alongside these @font-face rules, that inlined block is
   never actually identical page-to-page, so on every navigation the
   font-face declarations were being destroyed and recreated too, even
   though nothing about the fonts themselves had changed. Recreating an
   @font-face rule makes the browser re-verify the resource (a real network
   round-trip, visible as a fresh request in the Network tab even when the
   font's already cached and comes back 304) before it'll commit to
   rendering with it — on a slow connection that's a long enough window for
   the fallback font to flash and the metric-matched-but-not-pixel-identical
   glyphs to visibly reflow when the real font takes over, on *every* page
   view, not just the first.

   A real external stylesheet, referenced by a stable <link rel="stylesheet"
   href="/fonts.css"> (see BaseLayout.astro), sidesteps this: the router
   matches persisted <link rel="stylesheet"> elements by href alone, not
   content, so this exact tag is reused indefinitely across navigations and
   the font-face declarations are never recreated after the first load. */

@font-face {
	font-family: 'Geist';
	src: url('/fonts/Geist-Variable.woff2') format('woff2');
	font-weight: 100 900;
	font-style: normal;
	font-display: swap;
}

@font-face {
	font-family: 'Geist Mono';
	src: url('/fonts/GeistMono-Variable.woff2') format('woff2');
	font-weight: 100 900;
	font-style: normal;
	font-display: swap;
}

/* Preloading (see BaseLayout.astro's <head>) shrinks the gap between first
   paint and Geist finishing loading, but doesn't eliminate it — there's
   always some window where text renders in the browser's generic fallback
   (ui-sans-serif/ui-monospace) before swapping, and since that fallback's
   character widths differ from Geist's, text visibly reflows when the swap
   happens (e.g. a word jumping from the end of one line to the start of the
   next). These two @font-face rules define a *local* fallback — Arial /
   Courier New, near-universally installed — with its line metrics and
   average character width mathematically adjusted (via size-adjust +
   the *-override descriptors) to match Geist's own metrics almost exactly.
   The glyph shapes still differ for that brief window, but the text takes
   up the identical amount of space either way, so nothing reflows when the
   real font swaps in. Values computed directly from the actual font files
   with fontTools (average advance width of a-z, plus hhea ascent/descent/
   lineGap, each expressed as a fraction of unitsPerEm) rather than guessed —
   see the ascent-override formula note below for why they're divided by
   size-adjust rather than used as-is. */
@font-face {
	font-family: 'Geist Fallback';
	src: local('Arial');
	ascent-override: 92.16%;
	descent-override: 27.05%;
	line-gap-override: 0%;
	size-adjust: 109.05%;
}

@font-face {
	font-family: 'Geist Mono Fallback';
	src: local('Courier New');
	ascent-override: 100.52%;
	descent-override: 29.5%;
	line-gap-override: 0%;
	size-adjust: 99.98%;
}
