/**
 * BASE — reset, self-hosted faces, typographic defaults, accessibility.
 *
 * Contains no colour values and no spacing numbers. Every one arrives as a custom
 * property from tokens.css. A literal appearing in this file means the token system
 * has been bypassed and that property has silently left the design system.
 */

/* ── Self-hosted faces. No third-party font CDN: one less origin, one less request on
   the critical path, and no visitor data leaving the site. ──
 *
 * TYPEFACE CHANGE 2026-08 (second pass) — founder's decision: distinctive, not generic.
 *
 * The Inter/Inter Tight pairing did its job — a clean Helvetica register — and that was
 * exactly the complaint: "Inter Bold, done" is the default costume of every AI startup
 * this decade. The replacement keeps the same architecture (display cut / body cut /
 * mono for values) but swaps the voices:
 *
 * SPACE GROTESK (display) — Florian Karsten's geometric grotesk derived from Space
 * Mono. It keeps the monospace ancestor's quirks — the lowercase g's flat ear, the
 * angular counters, the slightly machined curves — which gives headlines a technical
 * signature no neo-grotesque has. OFL licensed, so self-hosting is unambiguous. The
 * hosted file is the official variable cut: its wght axis runs 300–700, and the
 * `font-weight: 300 700` range below must match it exactly — declare wider and the
 * browser synthesises the missing 800/900 and the stroke contrast breaks at hero size
 * (the weight tokens in tokens.css cap display weight at 700 for the same reason).
 *
 * SATOSHI (body) — Indian Type Foundry's grotesk, released through Fontshare under the
 * ITF Free Font License (free for commercial use; redistribution outside the product is
 * what the license prohibits, self-hosting within the site is the licensed use). Warmer
 * and rounder than Inter at text sizes without drifting humanist, and its neutrality is
 * earned rather than default — it reads as chosen. Ships with a true italic variable
 * cut, which Inter's single hosted file never had; both roman and italic cover
 * wght 300–900.
 *
 * All three faces are VARIABLE, subset to latin + latin-ext: three files, ~96 KB total
 * (display 22 KB + body roman 36 KB + body italic 37 KB), against 93 KB for the two
 * Inter files — the true italic is the only net addition. The previous inter-*.woff2
 * files remain on disk until deployment cleanup but nothing references them. */
@font-face {
  font-family: 'Space Grotesk';
  src: url('../fonts/space-grotesk-var.woff2') format('woff2-variations');
  font-weight: 300 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Satoshi';
  src: url('../fonts/satoshi-var.woff2') format('woff2-variations');
  font-weight: 300 900;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Satoshi';
  src: url('../fonts/satoshi-var-italic.woff2') format('woff2-variations');
  font-weight: 300 900;
  font-style: italic;
  font-display: swap;
}
@font-face { font-family: 'JetBrains Mono';  src: url('../fonts/jetbrains-mono-400.woff2')  format('woff2'); font-weight: 400; font-style: normal; font-display: swap; }

/* ── Reset ─────────────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }

html {
  -webkit-text-size-adjust: 100%;
  /* Native smooth scroll. No momentum-hijacking scroll library: it costs anchor
     precision and adds jank risk on low-end devices for no benefit here. */
  scroll-behavior: smooth;
  /* Anchored headings must clear the fixed header. */
  scroll-padding-top: calc(var(--header-h) + var(--space-5));
}

body {
  background: var(--surface-base);
  color: var(--text-primary);
  font-family: var(--font-body);
  font-size: var(--text-base);
  line-height: var(--leading-body);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  overflow-x: clip;
  /*
    NO TRANSITION ON background/color, and this is not a style preference.
    Both values arrive through a custom property redefined by [data-theme] on the root.
    Chromium does not reliably restart a running colour transition when the value
    behind it comes from a custom property redeclared on an ancestor — body kept the
    Cosmos ground while every block surface flipped, producing ivory panels on a
    near-black page. The switch snaps instead: a theme that changes instantly beats a
    theme that changes halfway.
  */
}

img, picture, video, canvas, svg { display: block; max-width: 100%; }
img, video { height: auto; }
input, button, textarea, select { font: inherit; color: inherit; }
p, h1, h2, h3, h4, h5, h6 { overflow-wrap: break-word; }
ul, ol { padding: 0; list-style: none; }

/**
 * Display type. Separated from body on four axes at once — family, weight, tracking
 * and leading — so heading and body read as two voices rather than one face at two
 * sizes. Space Grotesk against Satoshi pushes that separation further than the Inter
 * superfamily ever could: the display face carries visible drawing decisions (flat
 * terminals, angular counters) while the body face stays quiet, so the contrast is one
 * of character, not merely of tightness.
 */
h1, h2, h3, h4, h5 {
  font-family: var(--font-display);
  font-weight: var(--weight-display);
  line-height: var(--leading-display);
  letter-spacing: var(--track-2xl);
  text-wrap: balance;
}

h1 {
  font-size: var(--text-4xl);
  font-weight: var(--weight-displayHeavy);
  line-height: var(--leading-displayTight);
  letter-spacing: var(--track-4xl);
}
h2 {
  font-size: var(--text-3xl);
  font-weight: var(--weight-displayHeavy);
  letter-spacing: var(--track-3xl);
}
h3 { font-size: var(--text-2xl); letter-spacing: var(--track-2xl); }
h4 { font-size: var(--text-xl);  letter-spacing: var(--track-xl); }
/* -0.004em continues the token ramp below --track-xl (-0.008em); h5 is smaller than
   h4, so it must always sit shallower — retuned with the ramp for Space Grotesk. */
h5 { font-size: var(--text-lg);  letter-spacing: -0.004em; }

/* Body stays at zero tracking and near-double the leading of display. */
p, li, dd {
  letter-spacing: var(--track-body);
  line-height: var(--leading-body);
}

/**
 * Structural labels — eyebrows, section markers, nav. Body face, uppercase, widely
 * tracked. Explicitly NOT monospace: mono is reserved for values that are genuinely
 * technical, and using it decoratively is what makes engineering sites interchangeable.
 */
.label, .eyebrow {
  font-family: var(--font-body);
  font-weight: var(--weight-bodyMedium);
  font-size: var(--text-xs);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--text-muted);
}

code, kbd, pre, samp { font-family: var(--font-mono); font-size: 0.92em; }

a { color: var(--accent-interactive); text-decoration: none; }

/* ── Focus ─────────────────────────────────────────────────────────────────── */
:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}
:focus:not(:focus-visible) { outline: none; }

.visually-hidden:not(:focus):not(:active) {
  position: absolute;
  width: 1px; height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* Keyboard users land here first. Visible only when focused. */
.skip-link {
  position: absolute;
  top: var(--space-3);
  left: var(--space-3);
  z-index: 200;
  padding: var(--space-3) var(--space-5);
  background: var(--surface-overlay);
  color: var(--text-primary);
  border: 1px solid var(--border-accent);
  border-radius: var(--radius-md);
  font-size: var(--text-sm);
  transform: translateY(-200%);
}
.skip-link:focus { transform: none; }

/* Honour forced-colors mode instead of fighting it. */
@media (forced-colors: active) {
  * { forced-color-adjust: auto; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ── WordPress layout primitives ───────────────────────────────────────────── */
.wp-site-blocks { display: block; }

/* WordPress emits alignfull with negative margins against root padding. The theme's
   sections manage their own gutters, so full-bleed means genuinely edge to edge. */
.wp-site-blocks > .alignfull,
.alignfull { margin-left: 0; margin-right: 0; max-width: none; }

.wp-block-image img { border-radius: var(--radius-lg); }

/* Selection uses the decorative gold — it is a wash behind text, not text itself. */
::selection { background: var(--accent-decorative); color: var(--text-on-accent); }

/* ── Scrollbar ─────────────────────────────────────────────────────────────── */
@supports (scrollbar-color: auto) {
  html { scrollbar-color: var(--border-strong) transparent; scrollbar-width: thin; }
}
