/* 31.05.26 02:26 AM / 02:26 — edited by Claude — create base layer: reset, typography defaults, .container/.section primitives, responsive breakpoints */
/* 27.06.26 04:00 AM / 04:00 — edited by Claude — i3: routed the base typography through the FONT ROLE CONTRACT (css/tokens.css). body→--cox-font-body, h1–h6→--cox-font-heading, code/kbd/samp/pre→--cox-font-mono, form controls→--cox-font-ui — each `var(--cox-font-ROLE, <current stack>)` so the global Fonts switcher (js/fonts.js) re-renders content-page text live, with ZERO visual change until a font is picked. */

/* ============================================================================
   base.css — the foundation layer that sits directly on top of tokens.css.
   Owns: a small modern reset, document/typography defaults, accessible focus,
   responsive media, and the two contract layout primitives (.container,
   .section). No component styling lives here — that's components.css.
   Every value references a token; nothing is hardcoded.
   ============================================================================ */

/* ---- Reset -----------------------------------------------------------------
   Border-box everywhere, zero default margins, predictable media + form
   inheritance. Deliberately small — not a full normalize, just the parts that
   actually bite. */
*,
*::before,
*::after {
  box-sizing: border-box;
}

* {
  margin: 0;
}

html {
  -webkit-text-size-adjust: 100%; /* stop iOS bumping font sizes on rotate */
  -moz-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: var(--space-8); /* sticky header doesn't cover anchors */
}

body {
  min-height: 100vh;
  background-color: var(--color-bg);
  color: var(--color-text);
  font-family: var(--cox-font-body, "Atkinson Hyperlegible", ui-sans-serif, sans-serif);
  font-size: var(--text-base);
  line-height: var(--leading-normal);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

/* Media should never overflow its box and should reserve its own line. */
img,
picture,
video,
canvas,
svg {
  display: block;
  max-width: 100%;
}

/* Forms inherit type instead of falling back to tiny browser defaults. */
input,
button,
textarea,
select {
  font: inherit;
  /* UI role: form controls / buttons follow the Fonts switcher (default = body face). */
  font-family: var(--cox-font-ui, "Atkinson Hyperlegible", ui-sans-serif, sans-serif);
  color: inherit;
}

/* Long words / code shouldn't blow out a narrow column. */
p,
li,
h1,
h2,
h3,
h4 {
  overflow-wrap: break-word;
}

/* ---- Typography ------------------------------------------------------------
   Headings step down through the type scale with a tight leading; weight and
   letter-spacing give clear hierarchy without extra fonts. */
h1,
h2,
h3,
h4,
h5,
h6 {
  /* 31.05.26 05:05 AM / 05:05 — edited by Claude — headings now use the Space Grotesk display family (was inheriting --font-sans); weight 600 matches a loaded cut */
  /* 06.06.26 06:07 PM / 18:07 — edited by Claude — retro-terminal: display face is now VT323 (single-weight pixel). Weight 600→400 (no faux-bold on a one-cut font), tracking -0.02em→0 (a pixel face wants no negative tracking), + soft CRT phosphor glow. */
  /* 10.06.26 03:01 AM / 03:01 — edited by Claude — display face is now Space Mono (real 700 cut): weight 400→700, slight -0.015em tightening (a crisp mono can take it at display sizes; the pixel face couldn't). Glow token itself was retuned in tokens.css. */
  font-family: var(--cox-font-heading, "Space Mono", "Courier New", ui-monospace, monospace);
  line-height: var(--leading-tight);
  font-weight: 700;
  letter-spacing: -0.015em;
  color: var(--color-text);
  text-shadow: var(--glow-text); /* CRT phosphor halo on the pixel display type */
  text-wrap: balance; /* nicer multi-line heading breaks where supported */
}

h1 { font-size: var(--text-4xl); }
h2 { font-size: var(--text-3xl); }
h3 { font-size: var(--text-2xl); }
h4 { font-size: var(--text-xl); }
h5 { font-size: var(--text-lg); }
h6 { font-size: var(--text-base); }

/* Constrain prose so reading lines don't run the full screen. Opt-in via the
   .prose helper so layout/markup blocks aren't forced narrow. */
.prose {
  max-width: 68ch;
}

.prose p + p,
.prose ul,
.prose ol {
  margin-top: var(--space-4);
}

a {
  color: var(--color-accent);
  text-decoration: none;
  transition: color var(--dur-fast) var(--ease-standard);
}

a:hover {
  color: var(--color-accent-hover);
}

/* Inline code / monospace flavor for the terminal-themed brand. */
code,
kbd,
samp,
pre {
  font-family: var(--cox-font-mono, "Space Mono", ui-monospace, monospace);
  font-size: 0.9em;
}

strong,
b {
  font-weight: 650;
}

::selection {
  background: var(--color-accent-soft);
  color: var(--color-text);
}

/* ---- Accessible focus ------------------------------------------------------
   Keyboard focus must always be clearly visible. Mouse clicks don't show the
   ring (:focus-visible), keyboard navigation does. */
:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

/* ---- Layout primitives (CONTRACT) ------------------------------------------
   .container — centers content and clamps it to the max line width, with
   responsive gutters so there is no horizontal overflow at any size.
   .section  — the standard vertical rhythm between page bands. */
.container {
  width: 100%;
  max-width: var(--container-max);
  margin-inline: auto;
  padding-inline: var(--space-5);
}

.section {
  padding-block: var(--space-8);
}

/* Elevated banding — alternate sections get a raised surface + hairline rules
   so long pages read as distinct bands without per-section inline styles. */
.section--alt {
  background-color: var(--color-bg-elevated);
  border-block: 1px solid var(--color-border);
}

/* 31.05.26 02:50 AM / 02:50 — edited by Claude — add generic layout utilities (grids, flow rhythm, measure) so pages compose without inline styles */

/* Responsive card grids. Mobile-first single column; widen at breakpoints.
   .grid-3 → 1/2/3, .grid-4 → 1/2/4, .grid-2 → 1/2. */
.grid-2,
.grid-3,
.grid-4 {
  display: grid;
  gap: var(--space-5);
  grid-template-columns: 1fr;
}

/* 31.05.26 03:13 AM / 03:13 — edited by Claude — grid items default to min-width:auto and won't shrink below a child's intrinsic width; a white-space:pre .code-block then forces horizontal page overflow on narrow screens. min-width:0 lets the track shrink so the code block scrolls internally instead. */
.grid-2 > *,
.grid-3 > *,
.grid-4 > * {
  min-width: 0;
}

@media (min-width: 40rem) { /* ~640px */
  .grid-2 { grid-template-columns: repeat(2, 1fr); }
  .grid-3 { grid-template-columns: repeat(2, 1fr); }
  .grid-4 { grid-template-columns: repeat(2, 1fr); }
}

@media (min-width: 64rem) { /* ~1024px */
  .grid-3 { grid-template-columns: repeat(3, 1fr); }
  .grid-4 { grid-template-columns: repeat(4, 1fr); }
}

/* Vertical rhythm helper (the "owl" pattern): every child after the first gets
   a top margin, so stacked content auto-spaces with no per-element margins. */
.flow > * + * {
  margin-block-start: var(--space-4);
}
.flow--lg > * + * {
  margin-block-start: var(--space-6);
}

/* Small helper utilities reused across pages. */
.text-muted { color: var(--color-text-muted); }
.text-center { text-align: center; }
.mx-auto    { margin-inline: auto; }
.measure    { max-width: 26ch; }      /* constrain heading width */

/* 10.06.26 03:01 AM / 03:01 — edited by Claude — .type-cursor: opt-in blinking
   terminal block-cursor appended to a heading (the site-wide "we live in a
   terminal" wink). steps(2,jump-none) = hard on/off, no fade — like a real TTY.
   Inline-block + no-select so it never reflows text or pollutes copied prose.
   The global reduced-motion reset below freezes it to a solid block (fine). */
.type-cursor::after {
  content: "▌";
  display: inline-block;
  margin-left: 0.12em;
  color: var(--color-accent);
  text-shadow: var(--glow-text);
  user-select: none;
  animation: type-cursor-blink var(--blink) steps(2, jump-none) infinite;
}

@keyframes type-cursor-blink {
  0%   { opacity: 1; }
  100% { opacity: 0; }
}

/* Screen-reader-only content (skip links, labels) without visual footprint. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ---- Responsive ------------------------------------------------------------
   Mobile-first. We only widen gutters and rhythm as the viewport grows; the
   layout itself is fluid (flex/grid in components), so nothing overflows. */
@media (min-width: 48rem) { /* ~768px tablet+ */
  .container { padding-inline: var(--space-6); }
  .section   { padding-block: calc(var(--space-8) + var(--space-5)); }
  h1 { font-size: var(--text-5xl); }
}

@media (min-width: 64rem) { /* ~1024px desktop+ */
  body { font-size: var(--text-lg); }
}

/* ---- Reduced motion --------------------------------------------------------
   Global safety net: anyone who asked the OS to reduce motion gets near-instant
   transitions and no smooth-scroll. The hero ships its own static fallback. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}
