@layer base {

/* ============================================================
   TY MABEE - FIELD JOURNAL · typefaces & foundations
   ============================================================ */

/* ------------------------------------------------------------
   SELF-HOSTED TYPE
   ------------------------------------------------------------
   Was a render-blocking third-party request pulling both italic
   and roman Fraunces across every axis. Now: latin-subset woff2
   on our own origin, regenerated by tools/fetch-fonts.mjs.

   Every face is paired with a METRIC-MATCHED FALLBACK below.
   The size-adjust / ascent-override / descent-override values
   were measured from the real fonts (subset woff2 vs the actual
   Windows system font), so the swap from fallback to web font
   moves nothing at all - this is what takes CLS to a true 0
   rather than merely "under 0.1".

   If you change a face, recompute the overrides:

     k                = renderedWidth(webFace) / renderedWidth(fallback)
     size-adjust      = k
     ascent-override  = (webAscent/upm)  / k
     descent-override = (webDescent/upm) / k

   MEASURE k IN A BROWSER, not from the font's hmtx table. Reading
   hmtx gives a VARIABLE font's default instance, and for Fraunces
   that default sits at a different optical size than body text
   actually renders at - it put size-adjust 14% out, which is a
   visible reflow on every font swap. Rendering a sample string in
   the real face and in the real fallback and dividing the widths
   is both simpler and correct.
   ------------------------------------------------------------ */

@font-face {
  font-family: "Fraunces";
  font-style: normal;
  font-weight: 300 900;
  font-display: swap;
  src: url("../fonts/fraunces-normal-300-900.woff2") format("woff2-variations");
}
@font-face {
  font-family: "Fraunces";
  font-style: italic;
  font-weight: 600;
  font-display: swap;
  src: url("../fonts/fraunces-i-italic-600.woff2") format("woff2");
}
@font-face {
  font-family: "Caveat";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/caveat-normal-400.woff2") format("woff2");
}
@font-face {
  font-family: "Space Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/spacemono-normal-400.woff2") format("woff2");
}
@font-face {
  font-family: "Space Mono";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("../fonts/spacemono-normal-700.woff2") format("woff2");
}

/* measured in-browser at 16px: Fraunces 581.03px vs Georgia 552.78px */
@font-face {
  font-family: "Fraunces Fallback";
  font-style: normal;
  src: local("Georgia"), local("Times New Roman");
  size-adjust: 105.11%;
  ascent-override: 93.04%;
  descent-override: 24.26%;
  line-gap-override: 0%;
}
/* the cover tagline's one <em>: Fraunces italic 572.11px vs Georgia Italic 651.81px */
@font-face {
  font-family: "Fraunces Fallback";
  font-style: italic;
  src: local("Georgia Italic"), local("Georgia");
  size-adjust: 87.77%;
  ascent-override: 111.42%;
  descent-override: 29.05%;
  line-gap-override: 0%;
}
/* measured in-browser at 16px: Caveat 419.70px vs Segoe Script 696.97px */
@font-face {
  font-family: "Caveat Fallback";
  src: local("Segoe Script"), local("Bradley Hand"), local("Comic Sans MS");
  size-adjust: 60.22%;
  ascent-override: 159.42%;
  descent-override: 49.82%;
  line-gap-override: 0%;
}
/* measured in-browser at 16px: Space Mono 714.83px vs Courier New 700.92px */
@font-face {
  font-family: "Space Mono Fallback";
  src: local("Courier New"), local("Menlo");
  size-adjust: 101.98%;
  ascent-override: 109.82%;
  descent-override: 35.40%;
  line-gap-override: 0%;
}

/* ------------------------------------------------------------
   RESET
   ------------------------------------------------------------ */
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-display);
  font-optical-sizing: auto;
  font-size: 1.06rem;
  line-height: 1.65;
  /* `clip`, NOT `hidden`. overflow-x: hidden forces overflow-y to
     compute to `auto`, which makes <body> a scroll container - that
     changes what `animation-timeline: scroll()` resolves against and
     breaks position: sticky descendants. `clip` does neither. */
  overflow-x: clip;
}

::selection { background: var(--green); color: var(--paper); }

img, svg { max-width: 100%; }

a { color: inherit; }

/* ------------------------------------------------------------
   UTILITY TYPE
   ------------------------------------------------------------ */
.mono { font-family: var(--font-mono); font-size: 0.72rem; letter-spacing: 0.08em; }
.hand { font-family: var(--font-hand); }
.ink-green { color: var(--green); }
.ink-brown { color: var(--brown); }

.ink-link {
  display: inline-flex; align-items: center; gap: 0.45rem;
  color: var(--green); font-weight: 600; text-decoration: none;
  border-bottom: 2px solid var(--amber);
  transition: border-color 0.2s ease, color 0.2s ease;
  padding-bottom: 1px;
}
.ink-link:hover { color: var(--rust); border-color: var(--rust); }
.hand-arrow svg { width: 34px; height: 14px; display: block; }
.ink-link:hover .hand-arrow svg { animation: arrow-nudge 0.5s var(--ease-spring); }

/* ------------------------------------------------------------
   ACCESSIBILITY PRIMITIVES
   ------------------------------------------------------------ */
.skip-link {
  position: absolute; left: -999px; top: 0; z-index: var(--z-skip);
  background: var(--ink); color: var(--paper); padding: 0.6rem 1rem;
  font-family: var(--font-mono); font-size: 0.8rem;
}
.skip-link:focus { left: 0.5rem; top: 0.5rem; }

:focus-visible { outline: 2px dashed var(--green); outline-offset: 3px; }

/* Visually hidden but present for assistive tech. */
.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap; border: 0;
}

}
