/* Fonts, self-hosted from Google Fonts (all three are OFL).
   They used to arrive as a render-blocking third-party stylesheet in every
   <head>, which cost two DNS lookups and TLS handshakes before a single
   glyph could be requested. Same files, same unicode-range splits — a
   browser still downloads only the subsets a page actually needs — served
   from our own origin. Regenerate with the CSS2 URL in tools/README.md if a
   family or weight changes. */
@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 100 900;
  font-stretch: 100% 125%;
  font-display: swap;
  src: url('/assets/fonts/archivo-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: 'Archivo';
  font-style: normal;
  font-weight: 100 900;
  font-stretch: 100% 125%;
  font-display: swap;
  src: url('/assets/fonts/archivo-var-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: 'Space Grotesk';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('/assets/fonts/space-grotesk-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: 'Space Grotesk';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('/assets/fonts/space-grotesk-var-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: 'Space Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/assets/fonts/space-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: 'Space Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/assets/fonts/space-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: 'Space Mono';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('/assets/fonts/space-mono-700-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: 'Space Mono';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('/assets/fonts/space-mono-700-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;
}

/* Design tokens — inlined from css/tokens/*.css so the browser doesn't have
   to chase a chain of @import round trips (each @import only starts
   downloading after its parent finishes parsing) before it has colors,
   type, or spacing. */
:root{
  /* colors — base: acid */
  --acid-100:#f7fa9a; --acid-200:#f0f65c; --acid-300:#e9ee1b; --acid-400:#c9ce00; --acid-500:#8f9300; --acid-600:#5d5807; --acid-700:#3a3705; --acid-800:#201e09;
  /* colors — base: ink (site is dark-first) */
  --ink-000:#000000; --ink-050:#090909; --ink-100:#111113; --ink-150:#161618; --ink-200:#1c1c1e; --ink-300:#242427; --ink-400:#33333a; --ink-500:#55555d; --ink-600:#7d7d84; --ink-700:#a8a8ad; --ink-800:#d4d4d2; --ink-900:#eaeae8;
  /* colors — base: utility */
  --olive-mid:#807836; --rust-300:#e06b2b; --steel-300:#5f9ea8; --danger-300:#e2453a; --success-300:#7ac943;

  /* colors — semantic: surfaces */
  --surface-page:var(--ink-100);
  --surface-frame:var(--acid-600);
  --surface-card:var(--ink-150);
  --surface-raised:var(--ink-200);
  --surface-inset:var(--ink-050);
  --surface-accent:var(--acid-300);
  --surface-accent-muted:var(--acid-800);
  --surface-overlay:rgba(9,9,9,.82);

  /* colors — semantic: text */
  --text-strong:var(--ink-900);
  --text-body:var(--ink-800);
  --text-muted:var(--ink-600);
  --text-faint:var(--ink-500);
  --text-accent:var(--acid-300);
  --text-on-accent:var(--ink-050);

  /* colors — semantic: lines */
  --line-hairline:rgba(234,234,232,.10);
  --line-strong:rgba(234,234,232,.22);
  --line-accent:var(--acid-600);
  --line-guide:rgba(234,234,232,.06);

  /* colors — semantic: state */
  --state-hover-accent:var(--acid-200);
  --state-press-accent:var(--acid-400);
  --state-focus-ring:var(--acid-300);
  --state-disabled-fg:var(--ink-500);
  --state-disabled-bg:var(--ink-300);
  --state-danger:var(--danger-300);
  --state-success:var(--success-300);

  /* typography */
  --font-display:"Archivo","Arial Black",system-ui,sans-serif;
  --font-text:"Space Grotesk",system-ui,sans-serif;
  --font-label:"Space Mono",ui-monospace,monospace;

  --display-stretch:118%;
  --weight-black:800;
  --weight-bold:700;
  --weight-medium:500;
  --weight-regular:400;

  --size-hero:112px;   --lh-hero:.86;
  --size-d1:72px;      --lh-d1:.88;
  --size-d2:48px;      --lh-d2:.92;
  --size-d3:32px;      --lh-d3:1.0;
  --size-body-lg:18px; --lh-body-lg:1.5;
  --size-body:15px;    --lh-body:1.55;
  --size-body-sm:13px; --lh-body-sm:1.5;
  --size-label:11px;   --lh-label:1.1;
  --track-label:.14em;
  --size-label-sm:9px; --lh-label-sm:1.1;
  --track-label-sm:.18em;

  --track-display:-.02em;
  --track-body:0em;

  /* spacing */
  --space-1:4px; --space-2:8px; --space-3:12px; --space-4:16px; --space-5:24px;
  --space-6:32px; --space-7:48px; --space-8:64px; --space-9:96px; --space-10:128px;
  --gutter-page:30px;
  --gutter-section:72px;
  --grid-columns:12;
  --grid-gap:24px;
  --content-max:1180px;
  --control-h-sm:28px;
  --control-h-md:36px;
  --control-h-lg:48px;

  /* borders */
  --radius-none:0px; --radius-xs:2px; --radius-sm:4px; --radius-md:6px; --radius-pill:999px;
  --border-hairline:1px;
  --border-strong:2px;
  --border-dashed:1px dashed var(--line-guide);

  /* elevation */
  --shadow-none:none;
  --shadow-card:0 1px 0 rgba(234,234,232,.05) inset;
  --shadow-raised:0 12px 32px rgba(0,0,0,.55);
  --shadow-accent:0 0 0 1px var(--acid-600), 0 8px 24px rgba(233,238,27,.10);
  --glow-accent:0 0 24px rgba(233,238,27,.28);
  --scrim-bottom:linear-gradient(to top, rgba(9,9,9,.92) 0%, rgba(9,9,9,.55) 45%, rgba(9,9,9,0) 100%);
  --scrim-left:linear-gradient(to right, rgba(9,9,9,.88) 0%, rgba(9,9,9,0) 60%);
  --blur-panel:blur(14px);

  /* motion */
  --ease-standard:cubic-bezier(.22,.61,.36,1);
  --ease-out-fast:cubic-bezier(.16,1,.3,1);
  --ease-in-out:cubic-bezier(.65,.05,.36,1);
  --dur-instant:80ms;
  --dur-fast:140ms;
  --dur-base:240ms;
  --dur-slow:420ms;
  --dur-marquee:28s;
  --hover-lift:translateY(-2px);
  --press-scale:.985;
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
  margin: 0;
  background: var(--surface-page);
  color: var(--text-body);
  font-family: var(--font-text);
  font-size: var(--size-body);
  line-height: var(--lh-body);
  -webkit-font-smoothing: antialiased;
}
a { color: var(--text-accent); }
a:hover { color: var(--acid-200); }
img, svg { display: block; max-width: 100%; }
h1, h2, h3, h4, h5, dl, dd, p { margin: 0; }

/* Keyboard focus. Only the visualizer's own controls used to draw a ring, so
   everything else — every nav link, every button, every form field — was
   focusable with nothing to show for it. Later files can still override this
   where a component draws its own indicator. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
textarea:focus-visible,
select:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--state-focus-ring);
  outline-offset: 2px;
}

/* First tab stop on every page: jumps past the eight header links straight to
   <main id="main">. Off-screen until focused, never display: none, which
   would take it out of the tab order and defeat the point. */
.skip-link {
  position: fixed;
  top: min(30px, 3vw);
  left: min(30px, 3vw);
  z-index: 500;
  transform: translateY(calc(-100% - min(30px, 3vw)));
  padding: 12px 20px;
  background: var(--surface-accent);
  color: var(--text-on-accent);
  font-family: var(--font-label);
  font-size: var(--size-label-sm);
  letter-spacing: var(--track-label-sm);
  text-transform: uppercase;
  text-decoration: none;
}
.skip-link:focus { transform: translateY(0); }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

/* Fixed olive frame around every page, matching the design system's "boxed" layout */
.page-frame {
  background: var(--surface-page);
  color: var(--text-body);
  font-family: var(--font-text);
  padding: min(30px, 3vw);
  overflow-x: clip;
}
.frame-edge {
  position: fixed;
  background: var(--surface-frame);
  z-index: 400;
  pointer-events: none;
}
.frame-edge--top { top: 0; left: 0; right: 0; height: min(30px, 3vw); }
.frame-edge--bottom { bottom: 0; left: 0; right: 0; height: min(30px, 3vw); }
.frame-edge--left { top: 0; bottom: 0; left: 0; width: min(30px, 3vw); }
.frame-edge--right { top: 0; bottom: 0; right: 0; width: min(30px, 3vw); }
