@import url('/fonts/fonts.css');

*, *::before, *::after { box-sizing: border-box; }

:root {
  /* §7 Web Presence tokens */
  --bg: #000000;
  --surface: #0c0c0e;
  --surface-2: #111114;
  --text: #ffffff;
  --text-muted: #8a8a8f;
  --accent: #ff6d00;
  --accent-strong: #ff6d00;
  --link: #ff8c42;
  --border: #1c1c20;
  --border-warm: #471f00;       /* DECORATIVE hairlines only */
  /* WCAG 1.4.11 requires >=3:1 for the boundary of an interactive control.
     --border (1.15:1) and --border-warm (1.36:1) both fail. This value is the
     rain's existing dusty orange, so it is reuse rather than a new colour:
     3.64:1 on --surface, 3.91:1 on --bg. */
  --border-control: #9c5a28;

  --font-sans: 'Onest', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  --font-mono: 'JetBrains Mono', ui-monospace, 'Fira Code', monospace;

  --radius: 8px;
  --radius-lg: 18px;
  --u: 4px;
  --maxw: 1240px;
}

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-sans);
  font-size: 1.05rem;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

.wrap { max-width: var(--maxw); margin: 0 auto; padding-inline: calc(var(--u) * 7); }

/* ── perspective grid, persistent behind everything ─────────────── */
.grid-bg {
  position: fixed; inset: 0; z-index: -2; pointer-events: none;
  background-image:
    linear-gradient(to right, rgb(255 109 0 / 6%) 1px, transparent 1px),
    linear-gradient(to bottom, rgb(255 109 0 / 6%) 1px, transparent 1px);
  background-size: 72px 72px;
  mask-image: radial-gradient(ellipse 90% 70% at 50% 30%, #000 20%, transparent 78%);
}
.grid-bg::after {
  content: ''; position: absolute; inset: 0;
  background: radial-gradient(ellipse 55% 40% at 78% 18%, rgb(255 109 0 / 9%), transparent 62%);
}

/* ── mono eyebrow: the Zoey signature ───────────────────────────── */
.eyebrow {
  font-family: var(--font-mono);
  font-size: 0.7rem; font-weight: 500;
  letter-spacing: 0.28em; text-transform: uppercase;
  color: var(--accent);
  margin: 0 0 calc(var(--u) * 5);
}
.eyebrow--muted { color: var(--text-muted); }

/* ── nav ────────────────────────────────────────────────────────── */
.site-header {
  position: sticky; top: 0; z-index: 30;
  background: rgb(0 0 0 / 72%);
  backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--border);
}
.site-header .wrap {
  display: flex; align-items: center; justify-content: space-between;
  gap: calc(var(--u) * 6);
  padding-block: calc(var(--u) * 5);
}
.wordmark {
  font-family: var(--font-mono); font-weight: 700;
  font-size: 0.95rem; letter-spacing: 0.16em;
  color: var(--accent); text-decoration: none; white-space: nowrap;
}
.wordmark sup { font-size: 0.6em; opacity: 0.7; }
.nav { display: flex; align-items: center; gap: calc(var(--u) * 8); }
.nav a {
  font-family: var(--font-mono); font-size: 0.7rem; font-weight: 500;
  letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--text-muted); text-decoration: none;
  transition: color 140ms ease;
  /* 2.5.8 target size, all viewports. 0.7rem mono caps are ~18px tall on
     their own; this padding is what carries them past the 24px minimum, so
     it is load-bearing, not spacing. It costs no header height — the row is
     already sized by the taller CTA button beside it. */
  padding-block: calc(var(--u) * 2);
}
.nav a:hover { color: var(--text); }
/* Below 960px the nav drops to its own row. It used to be `display: none`
   with no hamburger and no footer fallback, so phone visitors had no
   navigation at all — on the site whose traffic is mostly phone links.
   Wrapping beats a toggle here: no JS, nothing hidden behind a control,
   and no second state that can break. */
@media (max-width: 960px) {
  /* Five links wrap to two or three rows, making this header 175-215px.
     Sticky, that is a quarter of a phone viewport permanently gone — worse
     than the problem being fixed. Static instead: the whole nav is visible
     on arrival and scrolls away after. Nothing is stranded, because the
     newsletter CTA repeats below the fold. */
  .site-header { position: static; }
  .site-header .wrap { flex-wrap: wrap; row-gap: calc(var(--u) * 2); }
  .nav {
    order: 3; width: 100%; flex-wrap: wrap;
    gap: calc(var(--u) * 1) calc(var(--u) * 6);
  }
}
/* Five nav links plus a CTA; below 420px the wordmark and button stop
   fitting on one line together. */
@media (max-width: 420px) {
  .site-header .wrap { justify-content: flex-start; gap: calc(var(--u) * 3); }
  .site-header .btn { font-size: 0.64rem; padding-inline: calc(var(--u) * 4); }
}

/* ── buttons ────────────────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: calc(var(--u) * 2);
  padding: calc(var(--u) * 4) calc(var(--u) * 7);
  border-radius: var(--radius);
  border: 1px solid transparent;
  font-family: var(--font-mono); font-size: 0.72rem; font-weight: 700;
  letter-spacing: 0.16em; text-transform: uppercase;
  text-decoration: none; cursor: pointer;
  transition: border-color 140ms ease, color 140ms ease, background-color 140ms ease;
}
/* §7 signature: dark fill, orange label, hairline border, NO shadow */
.btn-primary {
  background: var(--surface); color: var(--accent);
  border-color: var(--border-control); box-shadow: none;   /* 1.4.11 */
}
.btn-primary:hover { border-color: var(--accent); }
.btn-ghost { background: transparent; color: var(--text-muted); border-color: transparent; }
/* corAIgen's internal capitals are load-bearing — never uppercase the brand
   name. Use .brand inside any uppercase context. */
.brand { text-transform: none; letter-spacing: 0.02em; }
.btn--brand { text-transform: none; letter-spacing: 0.04em; font-size: 0.82rem; }
.btn-ghost:hover { color: var(--text); }

/* ── hero ───────────────────────────────────────────────────────── */
.hero { position: relative; padding-block: calc(var(--u) * 28) calc(var(--u) * 20); }
.hero .wrap {
  display: grid; align-items: center; gap: calc(var(--u) * 10);
  grid-template-columns: 1.05fr 0.95fr;
}
.hero h1 {
  font-size: clamp(2.6rem, 1.0rem + 5.6vw, 4.6rem);
  line-height: 1.0; letter-spacing: -0.035em; font-weight: 700;
  margin: 0 0 calc(var(--u) * 7); max-width: 16ch;
}
.hero h1 .hl { color: var(--accent); display: block; }
.hero .lede {
  font-size: 1.2rem; color: var(--text-muted);
  margin: 0 0 calc(var(--u) * 10); max-width: 44ch;
}
.hero-actions { display: flex; flex-wrap: wrap; gap: calc(var(--u) * 4); align-items: center; }
.hero-art { position: relative; display: grid; place-items: center; }
.hero-art img { width: 100%; max-width: 560px; height: auto; display: block;
  filter: drop-shadow(0 0 60px rgb(255 109 0 / 28%)) drop-shadow(0 0 120px rgb(214 31 105 / 18%)); }

/* ── marquee word strip ─────────────────────────────────────────── */
.strip {
  border-block: 1px solid var(--border);
  padding-block: calc(var(--u) * 7);
  overflow: hidden;
  mask-image: linear-gradient(to right, transparent, #000 12%, #000 88%, transparent);
}
.strip-track {
  display: flex; gap: calc(var(--u) * 14); white-space: nowrap;
  font-family: var(--font-mono); font-size: clamp(1.1rem, 2.4vw, 1.9rem);
  font-weight: 700; letter-spacing: 0.22em; text-transform: uppercase;
  color: transparent; -webkit-text-stroke: 1px #2a2a30;
  animation: drift 38s linear infinite;
}
@keyframes drift { to { transform: translateX(-50%); } }
@media (prefers-reduced-motion: reduce) { .strip-track { animation: none; } }

/* ── generic section ────────────────────────────────────────────── */
.section { position: relative; padding-block: calc(var(--u) * 26); }
.section h2 {
  font-size: clamp(2rem, 0.9rem + 3.6vw, 3.4rem);
  line-height: 1.06; letter-spacing: -0.025em; font-weight: 700;
  margin: 0 0 calc(var(--u) * 6); max-width: 18ch;
}
.section h2 .hl { color: var(--accent); }
.section .lede { color: var(--text-muted); max-width: 46ch; margin: 0; font-size: 1.1rem; }

.split { display: grid; gap: calc(var(--u) * 14); align-items: center; grid-template-columns: 1fr 1fr; }
.split--flip .split-art { order: -1; }
.split-art { position: relative; display: grid; place-items: center; }
.split-art img { width: 100%; max-width: 470px; height: auto; display: block; opacity: 0.95;
  filter: drop-shadow(0 0 48px rgb(255 109 0 / 20%)); }

/* ── numbered step cards ────────────────────────────────────────── */
.steps { display: grid; gap: calc(var(--u) * 4); }
.step {
  display: grid; grid-template-columns: auto 1fr; gap: calc(var(--u) * 6);
  align-items: start;
  padding: calc(var(--u) * 6) calc(var(--u) * 7);
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  transition: border-color 140ms ease;
}
.step:hover { border-color: var(--border-warm); }
.step-n {
  font-family: var(--font-mono); font-size: 1.5rem; font-weight: 700;
  color: #33333a; line-height: 1.2;
}
.step h3 { margin: 0 0 calc(var(--u) * 2); font-size: 1.05rem; font-weight: 600; }
.step p { margin: 0; color: var(--text-muted); font-size: 0.96rem; }

/* ── journey tiles ──────────────────────────────────────────────── */
.tiles { display: grid; grid-template-columns: repeat(4, 1fr); gap: calc(var(--u) * 4); margin-top: calc(var(--u) * 12); }
.tile {
  display: flex; flex-direction: column;
  padding: calc(var(--u) * 7);
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  transition: border-color 140ms ease;
}
.tile:hover { border-color: var(--border-warm); }
.tile-n {
  font-family: var(--font-mono); font-size: 0.72rem; font-weight: 700;
  letter-spacing: 0.2em; color: #33333a; margin-bottom: calc(var(--u) * 5);
}
.tile h3 { margin: 0 0 calc(var(--u) * 3); font-size: 1.08rem; font-weight: 600; }
.tile-quote { color: var(--text-muted); font-size: 0.95rem; margin: 0 0 calc(var(--u) * 5); min-height: calc(1.6em * 2); }
.tile-needs { list-style: none; margin: 0 0 calc(var(--u) * 5); padding: 0; font-size: 0.9rem; }
.tile-needs li { padding: calc(var(--u) * 0.5) 0; color: var(--text-muted); }
.tile-needs li::before { content: '—'; color: var(--accent); margin-right: calc(var(--u) * 2); }
.tile-route {
  margin-top: auto; padding-top: calc(var(--u) * 4);
  border-top: 1px solid var(--border);
  font-family: var(--font-mono); font-size: 0.62rem; font-weight: 500;
  letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--text-muted); text-decoration: none;
  display: inline-flex; align-items: center; gap: calc(var(--u) * 2);
  transition: color 140ms ease;
}
.tile-route:hover { color: var(--accent); }
.tile--exec { border-color: var(--border-warm); }
.tile--exec .tile-route { color: var(--accent); }

/* ── corner-bracket HUD card (the Coraigen handoff) ─────────────── */
.hud { position: relative; padding: calc(var(--u) * 12); background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg); }
.hud::before, .hud::after {
  content: ''; position: absolute; width: 22px; height: 22px; border: 2px solid var(--accent);
}
.hud::before { top: 14px; left: 14px; border-right: 0; border-bottom: 0; }
.hud::after { right: 14px; bottom: 14px; border-left: 0; border-top: 0; }

/* ── pipeline ───────────────────────────────────────────────────── */
.pipeline { display: grid; grid-template-columns: repeat(4, 1fr); gap: calc(var(--u) * 3); margin-top: calc(var(--u) * 10); }
.pipe {
  padding: calc(var(--u) * 5); border: 1px solid var(--border); border-radius: var(--radius);
  background: var(--surface-2);
}
.pipe .k { font-family: var(--font-mono); font-size: 0.62rem; letter-spacing: 0.2em; text-transform: uppercase; color: var(--text-muted); }
.pipe .v { margin-top: calc(var(--u) * 2); font-weight: 600; font-size: 0.98rem; }
.pipe--end { border-color: var(--border-warm); background: var(--surface); }
.pipe--end .v { color: var(--accent); }

/* ── newsletter ─────────────────────────────────────────────────── */
.signup { display: flex; flex-wrap: wrap; gap: calc(var(--u) * 3); max-width: 540px; margin-top: calc(var(--u) * 9); }
.field {
  flex: 1 1 260px;
  padding: calc(var(--u) * 4) calc(var(--u) * 5);
  border-radius: var(--radius);
  background: var(--surface); color: var(--text);
  border: 1px solid var(--border-control);   /* 1.4.11 */
  font: inherit; font-size: 0.98rem;
}
.field::placeholder { color: var(--text-muted); }
.field:focus-visible, .btn:focus-visible, .nav a:focus-visible, .tile-route:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 3px;
}

/* ── footer ─────────────────────────────────────────────────────── */
.site-footer {
  border-top: 1px solid var(--border);
  padding-block: calc(var(--u) * 10);
  color: var(--text-muted); font-size: 0.85rem;
}
.site-footer .wrap { display: flex; flex-wrap: wrap; gap: calc(var(--u) * 5); justify-content: space-between; }
.site-footer a { color: var(--link); text-decoration: none; }

/* Netlify honeypot. MUST be display:none — .visually-hidden uses the clip-rect
   pattern, which deliberately KEEPS content in the accessibility tree and tab
   order. A screen-reader or autofill user filling it makes Netlify silently
   discard the submission while the visitor is shown a success page — the exact
   failure that cost this site 17 days of signups. */
.hp { display: none; }

.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 ─────────────────────────────────────────────────── */
@media (max-width: 1040px) {
  .tiles { grid-template-columns: repeat(2, 1fr); }
  .pipeline { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 860px) {
  .hero .wrap { grid-template-columns: 1fr; }
  /* `.hero-art { order: -1 }` used to sit here, putting the panel above the
     headline on mobile. That works for a hero *image*; this "art" is a 700px
     terminal panel, so it pushed "Stop Learning AI. Start Using It." — the
     whole pitch — clean off the first screen. Headline first now. */
  .hero-art img { max-width: 380px; }
  .split { grid-template-columns: 1fr; }
  .split--flip .split-art { order: 0; }
}
@media (max-width: 620px) {
  .tiles { grid-template-columns: 1fr; }
  .pipeline { grid-template-columns: 1fr; }
  .tile-quote { min-height: 0; }
  .hero { padding-block: calc(var(--u) * 14) calc(var(--u) * 12); }
  .section { padding-block: calc(var(--u) * 16); }
  .wrap { padding-inline: calc(var(--u) * 5); }
}

/* ══ MATRIX GLYPH RAIN ═══════════════════════════════════════════
   Full-page layer sits above the grid but below all content. Kept
   deliberately faint and masked away from the centre column so §7's
   AA text contrast survives — verified by pixel sampling, see
   tools/contrast-check.mjs. */
.rain-bg {
  position: fixed; inset: 0; width: 100%; height: 100%;
  z-index: -1; pointer-events: none;
  opacity: 0.30;
  mask-image:
    radial-gradient(ellipse 62% 58% at 50% 42%, transparent 38%, #000 88%),
    linear-gradient(to bottom, #000 0%, #000 88%, transparent 100%);
  mask-composite: intersect;
  -webkit-mask-composite: source-in;
}
@media (prefers-reduced-motion: reduce) { .rain-bg { opacity: 0.2; } }

/* Text protection: a soft dark halo so a bright glyph passing behind a
   glyph of type never eats it. Cheaper and more robust than a scrim. */
.hero h1, .hero .lede, .section h2, .section .lede,
.eyebrow, .step h3, .step p, .tile h3, .tile-quote { text-shadow: 0 0 14px #000, 0 0 4px #000; }

/* ── framed terminal panel (replaces the static spheres) ────────── */
.panel {
  position: relative; width: 100%; max-width: 560px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-lg); overflow: hidden;
  box-shadow: 0 0 0 1px rgb(255 109 0 / 6%), 0 24px 70px rgb(0 0 0 / 70%);
}
.panel::before, .panel::after {
  content: ''; position: absolute; width: 16px; height: 16px;
  border: 2px solid var(--accent); opacity: 0.55; z-index: 2;
}
.panel::before { top: 54px; left: 10px; border-right: 0; border-bottom: 0; }
/* Sits above the note bar, not across it — overlapping it both looked untidy
   and dropped the note's local contrast below AA. */
.panel::after { right: 10px; bottom: 52px; border-left: 0; border-top: 0; }
.panel-bar {
  display: flex; align-items: center; gap: calc(var(--u) * 2);
  padding: calc(var(--u) * 3) calc(var(--u) * 4);
  border-bottom: 1px solid var(--border);
  background: #08080a;
}
.panel-bar .dot { width: 8px; height: 8px; border-radius: 50%; background: #26262c; }
.panel-bar .dot:first-child { background: var(--border-warm); }
.panel-bar p {
  margin: 0 0 0 auto;
  font-family: var(--font-mono); font-size: 0.6rem; font-weight: 500;
  letter-spacing: 0.18em; text-transform: uppercase; color: var(--text-muted);
}
.panel-rain { position: absolute; inset: 44px 0 0; width: 100%; height: auto; background: #000; opacity: 0.5; }

.panel-caption {
  position: absolute; left: 0; right: 0; bottom: 0; margin: 0;
  padding: calc(var(--u) * 4);
  background: linear-gradient(to top, #000 20%, transparent);
  font-family: var(--font-mono); font-size: 0.66rem; font-weight: 500;
  letter-spacing: 0.16em; text-transform: uppercase; color: var(--accent);
}


/* Sticky header is ~72px; without this, an anchor jump buries the section
   eyebrow and first headline line underneath it. */
.section, .hero, .strip { scroll-margin-top: 88px; }

/* ══ TERMINAL PANEL CONTENT ═══════════════════════════════════════
   Rain is a backdrop inside the panel; this sits over it on a scrim so
   the prompt stays legible. Verified by tools/contrast-check.mjs. */
.panel-body {
  position: relative; z-index: 2;
  min-height: 320px;
  padding: calc(var(--u) * 6) calc(var(--u) * 6) calc(var(--u) * 5);
  background: linear-gradient(180deg, rgb(0 0 0 / 82%) 0%, rgb(0 0 0 / 92%) 45%, rgb(0 0 0 / 82%) 100%);
}
.panel--hero .panel-body { min-height: 380px; }

.wf { display: flex; flex-direction: column; gap: calc(var(--u) * 4); }
/* An author `display` declaration beats the UA stylesheet's [hidden]{display:none},
   so without this the rotating slides all render stacked. */
.wf[hidden] { display: none; }
.wf-in {
  margin: 0; font-family: var(--font-mono); font-size: 0.68rem;
  letter-spacing: 0.1em; text-transform: uppercase; color: var(--text-muted);
}
.wf-prompt {
  margin: 0; font-family: var(--font-mono); font-size: 0.82rem; line-height: 1.75;
  color: #ffd9b8;
  padding-left: calc(var(--u) * 4);
  border-left: 2px solid var(--accent);
  min-height: 5.2em;                 /* reserve space so typing doesn't reflow */
}
.wf-prompt.typing::after {
  content: '▌'; color: var(--accent);
  animation: blink 1s steps(2, start) infinite;
}
@keyframes blink { 50% { opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .wf-prompt.typing::after { animation: none; } }

.wf-out { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: calc(var(--u) * 2); }
.wf-out li {
  font-family: var(--font-mono); font-size: 0.66rem; letter-spacing: 0.08em;
  padding: calc(var(--u) * 1.5) calc(var(--u) * 3);
  border: 1px solid var(--border); border-radius: 4px; color: var(--text-muted);
}
.wf-out .ok::before { content: '✓ '; color: #6ee7a8; }
.wf-out .warn::before { content: '⚠ '; color: var(--accent); }

.wf-copy {
  align-self: flex-start; margin-top: calc(var(--u) * 1);
  padding: calc(var(--u) * 2.5) calc(var(--u) * 5);
  background: transparent; color: var(--accent);
  border: 1px solid var(--border-control); border-radius: var(--radius);   /* 1.4.11 */
  font-family: var(--font-mono); font-size: 0.64rem; font-weight: 700;
  letter-spacing: 0.16em; text-transform: uppercase; cursor: pointer;
  transition: border-color 140ms ease, color 140ms ease;
}
.wf-copy:hover { border-color: var(--accent); }
.wf-copy:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.wf-copy.is-copied { color: #6ee7a8; border-color: #2f6b4b; }

/* readiness gauges */
.gauges { list-style: none; margin: 0; padding: 0; display: grid; gap: calc(var(--u) * 3); }
.gauges li { display: grid; grid-template-columns: 1fr auto; align-items: center; gap: calc(var(--u) * 4); }
.gauges span {
  font-family: var(--font-mono); font-size: 0.7rem; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--text-muted);
}
.gauges .g {
  display: block; width: 116px; height: 6px; border-radius: 3px;
  background: #1e1e23; position: relative; overflow: hidden;
}
.gauges .g::after {
  content: ''; position: absolute; inset: 0 auto 0 0; width: var(--v);
  background: var(--accent); border-radius: 3px;
}
.wf-result {
  margin: calc(var(--u) * 2) 0 0; font-family: var(--font-mono);
  font-size: 0.76rem; line-height: 2; color: var(--text-muted);
}
.wf-result .hand { color: var(--accent); }

.live {
  display: inline-block; width: 6px; height: 6px; border-radius: 50%;
  background: var(--accent); margin-right: calc(var(--u) * 2);
  animation: pulse 2.2s ease-in-out infinite;
}
@keyframes pulse { 50% { opacity: 0.25; } }
@media (prefers-reduced-motion: reduce) { .live { animation: none; } }

.panel-note {
  position: relative; z-index: 2; margin: 0;
  padding: calc(var(--u) * 3) calc(var(--u) * 6);
  border-top: 1px solid var(--border); background: #08080a;
  font-family: var(--font-mono); font-size: 0.58rem;
  letter-spacing: 0.12em; text-transform: uppercase; color: var(--text-muted);
}

@media (max-width: 620px) {
  .panel-body, .panel--hero .panel-body { min-height: 300px; padding: calc(var(--u) * 5); }
  .wf-prompt { font-size: 0.78rem; }
  .gauges .g { width: 84px; }
}

/* ══ EDUCATION PAGES ══════════════════════════════════════════════
   Article and catalogue layouts. Interactive boundaries use
   --border-control (3.64:1); --border and --border-warm are decorative
   only and fail WCAG 1.4.11 at 1.15:1 and 1.36:1. */
.prose .wrap { max-width: 68ch; }
.prose h1 {
  font-size: clamp(2rem, 1rem + 3.4vw, 3rem); line-height: 1.1;
  letter-spacing: -0.03em; font-weight: 700; margin: 0 0 calc(var(--u) * 9);
}
.prose h2 {
  font-size: 1.6rem; font-weight: 600; letter-spacing: -0.015em;
  margin: calc(var(--u) * 12) 0 calc(var(--u) * 4);
}
.prose h3 { font-size: 1.2rem; font-weight: 600; margin: calc(var(--u) * 9) 0 calc(var(--u) * 3); }
.prose p, .prose li { color: var(--text-muted); font-size: 1.08rem; line-height: 1.75; }
.prose p { margin: 0 0 calc(var(--u) * 5); }
.prose ul, .prose ol { margin: 0 0 calc(var(--u) * 6); padding-left: calc(var(--u) * 6); }
.prose li { margin-bottom: calc(var(--u) * 2); }
.prose a { color: var(--link); }
.prose strong { color: var(--text); font-weight: 600; }
.prose pre {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); padding: calc(var(--u) * 5);
  overflow-x: auto; margin: 0 0 calc(var(--u) * 6);
}
.prose pre code {
  font-family: var(--font-mono); font-size: 0.9rem; line-height: 1.7;
  color: #ffd9b8;
  /* pre-wrap, not pre: these are prompts to be read and copied. Clipping them
     off the right edge makes the payload of the page unreadable. */
  white-space: pre-wrap; word-break: break-word;
}
.prose :not(pre) > code {
  font-family: var(--font-mono); font-size: 0.9em;
  background: var(--surface); padding: 0.15em 0.4em;
  border-radius: 4px; color: var(--link);
}
.prose blockquote {
  margin: 0 0 calc(var(--u) * 6); padding-left: calc(var(--u) * 5);
  border-left: 2px solid var(--accent); color: var(--text-muted);
}
.prose-back {
  margin-top: calc(var(--u) * 14); padding-top: calc(var(--u) * 6);
  border-top: 1px solid var(--border);
  font-family: var(--font-mono); font-size: 0.7rem;
  letter-spacing: 0.16em; text-transform: uppercase;
}
.prose-back a { color: var(--text-muted); text-decoration: none; }
.prose-back a:hover { color: var(--accent); }

.cat-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: calc(var(--u) * 5); margin-top: calc(var(--u) * 12);
}
.cat-card {
  display: block; padding: calc(var(--u) * 7);
  background: var(--surface); border: 1px solid var(--border-control);
  border-radius: var(--radius-lg); text-decoration: none;
  transition: border-color 140ms ease;
}
a.cat-card:hover { border-color: var(--accent); }   /* only real links advertise clickability */
.cat-card:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.cat-card h2 {
  margin: 0 0 calc(var(--u) * 3); font-size: 1.1rem; font-weight: 600;
  color: var(--text); letter-spacing: -0.01em;
}
.cat-card p { margin: 0; color: var(--text-muted); font-size: 0.95rem; line-height: 1.6; }
.cat-meta {
  margin-top: calc(var(--u) * 4) !important;
  font-family: var(--font-mono); font-size: 0.64rem;
  letter-spacing: 0.14em; text-transform: uppercase;
}
/* Prompt bodies on /prompts/ — the payload of that page, so they get real
   space rather than being truncated into a blurb. */
.cat-body {
  margin: calc(var(--u) * 4) 0 0; padding: calc(var(--u) * 4);
  background: #08080a; border: 1px solid var(--border);
  border-radius: var(--radius);
  font-family: var(--font-mono); font-size: 0.78rem; line-height: 1.65;
  color: #ffd9b8; white-space: pre-wrap; overflow-x: auto;
}

@media (max-width: 620px) {
  .cat-grid { grid-template-columns: 1fr; }
  .prose h2 { font-size: 1.35rem; }
}

/* Grouped catalogues — track headings between card grids. */
.cat-section {
  margin: calc(var(--u) * 16) 0 calc(var(--u) * 3);
  font-size: 1.5rem; font-weight: 600; letter-spacing: -0.02em; color: var(--text);
}
.cat-section-lede {
  margin: 0 0 calc(var(--u) * 2); color: var(--text-muted);
  font-size: 1rem; max-width: 60ch;
}
.cat-grid:empty { display: none; }

/* ── reduced motion, global backstop ─────────────────────────────────
   The rain canvas and the keyframe animations were each guarded
   individually, but `scroll-behavior: smooth` on <html> was not — and that
   is the one every in-page nav link fires, so it was the most-triggered
   unguarded motion on the site. Individual guards keep working; this is the
   net beneath them, so a new transition cannot ship unguarded by omission. */
@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;
  }
}

/* ── skip link ───────────────────────────────────────────────────────
   Deliberately NOT display:none, visibility:hidden, or the clip-rect
   .visually-hidden pattern. The first two drop it out of the tab order, so
   the keyboard user it exists for could never reach it; the third keeps it
   focusable but is the exact pattern that made the Netlify honeypot
   reachable on this site. transform is the one that hides it visually while
   leaving it focusable, and :focus brings it back on screen. */
.skip {
  position: fixed; left: calc(var(--u) * 4); top: calc(var(--u) * 4); z-index: 100;
  transform: translateY(calc(-100% - var(--u) * 8));
  padding: calc(var(--u) * 3) calc(var(--u) * 5);
  background: var(--surface); color: var(--accent);
  border: 1px solid var(--border-control); border-radius: var(--radius);
  font-family: var(--font-mono); font-size: 0.72rem; font-weight: 700;
  letter-spacing: 0.16em; text-transform: uppercase; text-decoration: none;
}
.skip:focus { transform: translateY(0); outline: 2px solid var(--accent); outline-offset: 2px; }

/* The sticky header would otherwise cover the top of whatever we jumped to. */
#main { scroll-margin-top: 96px; }

/* ── phone: tighten the header ────────────────────────────────────────
   The wrapped nav plus a full-size CTA made this header a fifth of a phone
   screen, which is what "crowded" meant. Everything below is smaller only
   below 620px; tablets keep the roomier setting.
   The one thing NOT reduced past its floor is the nav link height — 2.5.8
   still wants 24px, and these land at ~29px. */
@media (max-width: 620px) {
  .site-header .wrap {
    padding-block: calc(var(--u) * 3);
    row-gap: calc(var(--u) * 1.5);
    gap: calc(var(--u) * 3);
  }
  .nav { gap: 0 calc(var(--u) * 5); }
  .nav a {
    font-size: 0.62rem; letter-spacing: 0.12em;
    padding-block: calc(var(--u) * 2);
  }
  .site-header .btn {
    padding: calc(var(--u) * 2.5) calc(var(--u) * 4);
    font-size: 0.62rem; letter-spacing: 0.1em;
  }
}

/* The desktop hero opens with ~112px of air above the eyebrow. On a phone
   that is a third of the remaining screen after the header, for no gain —
   there is no wide layout to breathe into. */
@media (max-width: 620px) {
  .hero { padding-block: calc(var(--u) * 14) calc(var(--u) * 12); }
}
