:root {
  /* The specimen is behind the whole page rather than inside four boxes, so the page is
     dark-first: the brain sits in the document instead of fighting it.

     Two hues, one rule, and it is the rule that keeps the page honest at a glance:
     WARM is the hypothesised force, COOL is the instrument measuring it. Anything warm is
     the theory; anything cool is a fact about the model. Nothing measured is ever warm,
     and the force is never cool. */
  --void: #05070d;
  --panel: #0b1220;
  --grid: rgba(120, 170, 190, 0.09);
  --bg: var(--void);
  --bg-soft: #080c16;
  --surface: rgba(11, 18, 32, 0.66);
  --text: #e8f1f5;
  --muted: #9db3bf;
  --line: rgba(120, 170, 190, 0.14);
  --line-strong: rgba(120, 170, 190, 0.22);
  /* Boundaries of interactive controls need 3:1 against their background (WCAG 1.4.11). */
  --line-control: #6d8894;

  /* Warm — the force. */
  --accent: #ff7a45;
  --accent-deep: #ffa06e;
  --accent-hot: #ffd9a8;
  --warm-tint: rgba(255, 122, 69, 0.07);

  /* Cool — readouts, axes, angles, indices. Never the force. */
  --bio: #41d4c8;
  --bio-dim: #7fc9c0;

  --radius: 4px;
  --radius-lg: 6px;
  --nav-height: 64px;
  --font: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  /* The HUD register. Real numbers set in mono are what separate an instrument from a
     picture of one. */
  --mono: ui-monospace, SFMono-Regular, "SF Mono", "JetBrains Mono", Menlo, Consolas, monospace;
}

/* Data: coordinates, angles, indices, structure ids. */
.mono,
.section-number,
.callout-angle,
.eyebrow,
.sequence-status {
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
}

/* Corner ticks rather than a frame: an instrument marks where a reading sits without
   boxing it in. Elevation comes from border luminance and blur, never a drop shadow. */
.stage-window::before,
.stage-window::after {
  content: "";
  position: absolute;
  width: 18px;
  height: 18px;
  border: 1px solid var(--line-strong);
  pointer-events: none;
}

.stage-window::before {
  left: 0;
  top: 0;
  border-right: 0;
  border-bottom: 0;
}

.stage-window::after {
  right: 0;
  bottom: 0;
  border-left: 0;
  border-top: 0;
}

/* The one WebGL context, behind everything and inert to the pointer. Opacity belongs to
   the scroll rig: it dims the whole canvas as the active stage window leaves the middle
   of the view, so the model recedes behind copy rather than standing over it. */
.brain-canvas {
  position: fixed;
  left: 0;
  top: 0;
  width: 100%;
  /* Largest viewport height: mobile toolbars collapsing during scroll must not resize
     the canvas (a WebGL resize mid-scroll is a visible hitch). The extra rows sit
     harmlessly below the visible viewport while the toolbar is open. */
  height: 100vh;
  height: 100lvh;
  z-index: 0;
  pointer-events: none;
  transition: opacity 160ms linear;
  will-change: opacity;
}

.brain-canvas canvas {
  width: 100%;
  height: 100%;
}

/* Only the document layers need lifting above the canvas. A blanket `body > *` rule
   outranks `position: fixed` on the utilities that are also body children — it silently
   made the skip link take up space and dropped the orbit hit area into the flow, which
   stopped the model responding to drag at all. */
main,
.site-footer {
  position: relative;
  z-index: 1;
}

/* Tracks the active stage window so the model can be turned there, and only there.
   Anchored at the origin because the rig positions it with a transform. */
.stage-hit {
  position: fixed;
  left: 0;
  top: 0;
  z-index: 2;
  display: none;
  cursor: grab;
  touch-action: pan-y;
}

.stage-hit:active {
  cursor: grabbing;
}

/* Reserves the space the model is framed into. The pixels come from the fixed canvas
   behind it, so this element stays empty and transparent. */
.stage-window {
  position: relative;
  width: 100%;
  height: clamp(360px, 46vw, 590px);
  min-height: 340px;
  border-radius: var(--radius);
}

.stage-window:focus-visible {
  outline: 2px solid var(--bio);
  outline-offset: 6px;
}

* {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
  background: var(--bg);
}

body {
  margin: 0;
  color: var(--text);
  background: var(--bg);
  font-family: var(--font);
  font-size: 16px;
  line-height: 1.6;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* The copy scrims bleed past their columns by design; clip keeps that from ever becoming
   sideways scroll on a phone without making main a scroll container (sticky still works). */
main {
  overflow-x: clip;
}

/* One focus treatment for every control. Cool, because warm means the force. */
:where(a, button, input, [tabindex]):focus-visible {
  outline: 2px solid var(--bio);
  outline-offset: 3px;
}

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

button,
a {
  font: inherit;
}

a {
  color: inherit;
}

/* Opaque, because it appears over the brand: on a translucent ground the two words read
   through each other. */
.skip-link {
  position: fixed;
  left: 12px;
  top: 10px;
  z-index: 100;
  transform: translateY(-200%);
  border: 1px solid var(--line-control);
  border-radius: var(--radius-lg);
  background: var(--panel);
  color: var(--text);
  font-size: 0.875rem;
  font-weight: 600;
  padding: 0.65rem 0.95rem;
  text-decoration: none;
}

.skip-link:focus {
  transform: translateY(0);
  outline: 2px solid var(--bio);
  outline-offset: 2px;
}

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

/* No backdrop-filter anywhere on this page: the canvas behind it repaints every frame,
   so each blurred surface re-blurs on every frame whether or not anything else moved —
   it was the single largest scroll cost. The header is simply opaque: at 92% every
   heading that scrolled under it ghosted through. The hairline is a box-shadow so the
   header's height is exactly --nav-height, which is what scroll-margin-top matches. */
.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background-color: var(--void);
  box-shadow: 0 1px 0 var(--line);
}

.site-nav {
  display: flex;
  height: var(--nav-height);
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  width: min(1180px, calc(100% - 32px));
  margin: 0 auto;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 0.7rem;
  color: var(--text);
  font-size: 0.95rem;
  font-weight: 650;
  letter-spacing: -0.005em;
  text-decoration: none;
}

.brand-mark {
  width: 22px;
  height: 22px;
  border: 1.5px solid var(--bio-dim);
  border-radius: 50%;
  background:
    linear-gradient(90deg, transparent 46%, rgba(95, 143, 153, 0.32) 47%, rgba(95, 143, 153, 0.32) 53%, transparent 54%),
    radial-gradient(circle at 57% 42%, var(--accent) 0 12%, transparent 13%),
    rgba(8, 12, 22, 0.9);
}

.nav-links {
  display: flex;
  align-items: center;
  gap: 0.1rem;
}

.nav-links a {
  position: relative;
  border-radius: var(--radius);
  color: var(--muted);
  font-size: 0.875rem;
  font-weight: 600;
  padding: 0.5rem 0.8rem;
  text-decoration: none;
  transition: color 160ms ease;
}

/* The indicator sits on the header's bottom edge whatever the link's own height: 100% in
   an absolute box's `bottom` is the link's height, so this is half the difference. */
.nav-links a::after {
  content: "";
  position: absolute;
  left: 0.8rem;
  right: 0.8rem;
  bottom: calc((100% - var(--nav-height)) / 2);
  height: 2px;
  border-radius: 2px 2px 0 0;
  background: var(--bio);
  transform: scaleX(0);
  transition: transform 220ms ease;
}

.nav-links a:hover,
.nav-links a.is-active {
  color: var(--text);
}

.nav-links a.is-active::after {
  transform: scaleX(1);
}

.nav-toggle {
  display: none;
  width: 44px;
  height: 44px;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  gap: 4px;
  margin-right: -6px;
  border: 0;
  border-radius: var(--radius-lg);
  background: transparent;
  color: var(--text);
  cursor: pointer;
}

.nav-toggle span {
  width: 18px;
  height: 2px;
  border-radius: 1px;
  background: currentColor;
  transition:
    transform 220ms ease,
    opacity 160ms ease;
}

/* Bars 2px tall with a 4px gap: 6px between centres folds them into a cross. */
.nav-toggle[aria-expanded="true"] span:nth-child(1) {
  transform: translateY(6px) rotate(45deg);
}

.nav-toggle[aria-expanded="true"] span:nth-child(2) {
  opacity: 0;
}

.nav-toggle[aria-expanded="true"] span:nth-child(3) {
  transform: translateY(-6px) rotate(-45deg);
}

.section {
  border-bottom: 1px solid var(--line);
}

/* Flush under the header: a larger margin left a strip of the previous section, its
   border included, showing under the header after every nav jump. */
main > section {
  scroll-margin-top: var(--nav-height);
}

.section-inner {
  width: min(1180px, calc(100% - 32px));
  margin: 0 auto;
}

.hero {
  min-height: calc(100svh - var(--nav-height));
  display: flex;
  align-items: center;
  padding: clamp(4.5rem, 8vw, 8rem) 0 clamp(2.5rem, 6vw, 5rem);
  /* A cool pool of light behind the figure. The warm corner glow this replaced was tied
     to nothing on the page, and warm is the force's colour. */
  background: radial-gradient(55% 65% at 72% 52%, rgba(47, 125, 138, 0.1), transparent 70%);
}

/* Equal halves: the headline's size is derived from this column's width (see h1). */
.hero-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(2rem, 4.5vw, 4rem);
  align-items: center;
}

.hero-copy {
  max-width: 580px;
}

h1,
h2,
h3,
p {
  margin-top: 0;
}

h1,
h2,
h3,
.section-hook {
  text-wrap: balance;
}

p,
li {
  text-wrap: pretty;
}

/* The headline's longest unbreakable run, "Neural Neighborhood", is 9.73em wide in the
   system face. Sized so it fits the hero column with room for wider platform fonts, the
   headline sets in three balanced lines instead of stranding "Neural" on its own. */
h1 {
  margin-bottom: 1.35rem;
  font-size: clamp(2.25rem, 3.75vw, 3.375rem);
  line-height: 1.04;
  font-weight: 700;
  letter-spacing: -0.02em;
}

h2 {
  margin-bottom: 1rem;
  font-size: clamp(1.9rem, 2.9vw, 2.75rem);
  line-height: 1.06;
  font-weight: 700;
  letter-spacing: -0.015em;
}

h3 {
  margin-bottom: 0.6rem;
  font-size: clamp(1.2rem, 1.6vw, 1.45rem);
  line-height: 1.2;
  font-weight: 650;
  letter-spacing: -0.005em;
}

.hero-thesis,
.copy-column p,
.detail-panel p {
  color: var(--muted);
}

.copy-column p,
.detail-panel p {
  max-width: 64ch;
}

/* The specimen is behind the copy now, not beside it. A soft well of the page base keeps
   text legible wherever the model drifts, without boxing the copy in. Only prose that sits
   directly on the model needs it: the panels carry their own blurred surface, and a scrim
   on the full-width .section-heading showed as a hard seam across the specimen. */
.copy-column,
.hero-copy,
.narrow-layout,
.footer-grid {
  position: relative;
  isolation: isolate;
}

/* The footer has an opaque ground of its own, and its scrim bled 48px past the end of the
   document, so it is not in this list. */
.copy-column::before,
.hero-copy::before,
.narrow-layout::before {
  content: "";
  position: absolute;
  /* Generous bleed so the gradient reaches zero inside its own box and leaves no edge. */
  inset: -7rem -11rem;
  z-index: -1;
  pointer-events: none;
  background: radial-gradient(
    ellipse 62% 58% at 34% 50%,
    rgba(5, 7, 13, 0.96) 0%,
    rgba(5, 7, 13, 0.9) 46%,
    rgba(5, 7, 13, 0.66) 70%,
    rgba(5, 7, 13, 0) 90%
  );
}

.hero-thesis {
  max-width: 54ch;
  font-size: clamp(1.05rem, 1.35vw, 1.2rem);
  line-height: 1.65;
}

.model-section {
  padding: clamp(4.5rem, 8vw, 7.5rem) 0;
}

/* No section washes: the sections sit above the canvas, so a tint over a section tinted
   the specimen with it, and the alternating warm one read as a muddy brown band. One
   ground, with hairlines for rhythm. */

.split-layout {
  display: grid;
  grid-template-columns: minmax(300px, 0.85fr) minmax(420px, 1.15fr);
  gap: clamp(2rem, 5vw, 5rem);
  align-items: center;
}

.split-layout--reverse {
  grid-template-columns: minmax(360px, 0.86fr) minmax(420px, 1.14fr);
}

/* The number owns its own row so it stays above the heading, and the heading stays on
   the page's left rail, matching the sections that lay their copy out in a column. */
.section-heading {
  display: grid;
  grid-template-columns: minmax(0, 1.12fr) minmax(0, 0.88fr);
  grid-template-areas:
    "num num"
    "title hook";
  align-items: end;
  column-gap: clamp(1.5rem, 4vw, 3.5rem);
  margin-bottom: clamp(1.7rem, 4vw, 3rem);
}

.section-heading .section-number {
  grid-area: num;
}

.section-heading h2 {
  grid-area: title;
  margin-bottom: 0;
}

.section-heading .section-hook {
  grid-area: hook;
  margin-bottom: 0;
}

/* Specific enough to beat `.copy-column p`, which was colouring two of the five numbers
   as body text while the rest read as data. */
.copy-column .section-number,
.section-number {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin-bottom: 1.1rem;
  color: var(--bio);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

/* A short index rule after the number: the instrument's tick, not a divider. */
.section-number::after {
  content: "";
  width: 2rem;
  height: 1px;
  background: currentColor;
  opacity: 0.45;
}

.section-hook {
  color: var(--text) !important;
  font-size: clamp(1.1rem, 1.45vw, 1.3rem);
  line-height: 1.4;
  font-weight: 550;
  letter-spacing: -0.005em;
}

.caption {
  margin-top: 1.4rem;
  padding-top: 1rem;
  border-top: 1px solid var(--line);
  color: var(--muted);
  font-size: 0.875rem;
  line-height: 1.55;
}

/* What a stage says while the model is on its way, or if it cannot start. */
.stage-status {
  position: absolute;
  inset: 0;
  display: grid;
  place-content: center;
  justify-items: center;
  gap: 0.9rem;
  margin: 0;
  padding: 1.5rem;
  color: var(--muted);
  font-family: var(--mono);
  font-size: 0.75rem;
  letter-spacing: 0.04em;
  text-align: center;
  pointer-events: none;
}

.scene-loading .stage-status::before {
  content: "";
  width: 28px;
  height: 28px;
  border: 1.5px solid var(--line-strong);
  border-top-color: var(--bio);
  border-radius: 50%;
  animation: stage-spin 900ms linear infinite;
}

@keyframes stage-spin {
  to {
    transform: rotate(360deg);
  }
}

.scene-ready .stage-status {
  display: none;
}

/* Without WebGL there is nothing for the fixed layer to show. */
.no-webgl .brain-canvas,
.no-webgl .stage-hit {
  display: none;
}

/* The model arrives rather than appears. */
.brain-canvas canvas {
  animation: canvas-in 700ms ease both;
}

@keyframes canvas-in {
  from {
    opacity: 0;
  }
}

.primary-action:disabled,
.secondary-action:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

.brain-label-layer {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.brain-label {
  position: absolute;
  left: 0;
  top: 0;
  transform: translate(-50%, -50%);
  border: 1px solid rgba(65, 212, 200, 0.36);
  border-radius: var(--radius);
  background: var(--void);
  color: var(--bio);
  font-family: var(--mono);
  font-size: 0.68rem;
  line-height: 1;
  letter-spacing: 0.1em;
  padding: 0.4rem 0.55rem;
  text-align: center;
  text-transform: uppercase;
  white-space: nowrap;
  transition: opacity 200ms ease;
}

.brain-label-leaders,
.brain-loupe-leader {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
  pointer-events: none;
}

.brain-label-leaders line,
.brain-loupe-leader line {
  stroke: rgba(65, 212, 200, 0.55);
  stroke-width: 1;
}

.brain-label-leaders circle,
.brain-loupe-leader circle {
  fill: var(--bio);
}

/* Controls and their readout on the left, the model on the right — the same side as every
   other section. The model is sticky, so whichever part of the controls the reader is
   using, the force plays beside it; it used to play a screen below the fold. */
.interactive-layout {
  display: grid;
  grid-template-columns: minmax(0, 0.92fr) minmax(0, 1.08fr);
  gap: clamp(1.5rem, 4vw, 3.5rem);
  align-items: start;
}

.control-column {
  display: grid;
  gap: 1.25rem;
  min-width: 0;
}

.module-column {
  min-width: 0;
}

.interactive-layout .module-column {
  position: sticky;
  top: calc(var(--nav-height) + 24px);
}

.interactive-layout .stage-window {
  height: min(620px, calc(100svh - var(--nav-height) - 48px));
  min-height: 360px;
}

.chip-list {
  display: flex;
  flex-wrap: wrap;
  gap: 0.55rem;
  margin-bottom: 1rem;
}

.chip {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  min-height: 44px;
  border: 1px solid var(--line-control);
  border-radius: var(--radius-lg);
  background: rgba(11, 18, 32, 0.82);
  color: var(--text);
  cursor: pointer;
  font-size: 0.875rem;
  font-weight: 600;
  padding: 0.55rem 1rem 0.55rem 0.85rem;
  transition:
    border-color 180ms ease,
    background-color 180ms ease,
    box-shadow 180ms ease,
    color 180ms ease;
}

/* Selection was signalled by colour alone. The indicator fills as well as recolours, so
   the state survives a monochrome or colour-blind reading. */
.chip::before {
  content: "";
  flex: none;
  width: 0.8em;
  height: 0.8em;
  border: 1.5px solid var(--line-control);
  border-radius: 50%;
  transition:
    border-color 180ms ease,
    background-color 180ms ease,
    box-shadow 180ms ease;
}

.chip:hover {
  border-color: var(--bio-dim);
  background-color: rgba(16, 26, 44, 0.9);
}

/* Selected: the warm ring says the force is aimed here; the filled dot says it without
   colour. No glow — the selection is a state, not an event. */
.chip[aria-pressed="true"],
.chip[aria-checked="true"] {
  border-color: rgba(255, 122, 69, 0.85);
  background-color: rgba(255, 122, 69, 0.08);
  color: var(--accent-hot);
}

.chip[aria-pressed="true"]::before,
.chip[aria-checked="true"]::before {
  border-color: var(--accent);
  background: var(--accent);
  box-shadow: inset 0 0 0 2px var(--void);
}

.detail-panel {
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background:
    radial-gradient(circle, var(--grid) 0.8px, transparent 0.9px) 0 0 / 8px 8px,
    rgba(11, 18, 32, 0.88);
  padding: clamp(1.25rem, 3vw, 1.75rem);
}

.panel-hook {
  margin-bottom: 0.55rem;
  color: var(--bio-dim) !important;
  font-size: 0.88rem;
  font-weight: 700;
}

.zoom-callout {
  display: grid;
  grid-template-columns: 112px minmax(0, 1fr);
  gap: 1rem;
  align-items: center;
  margin-top: 1.5rem;
}

.nucleus-zoom {
  --beam-angle: -28deg;
  position: relative;
  width: 112px;
  aspect-ratio: 1;
  border: 1px solid var(--line-strong);
  border-radius: 50%;
  background:
    radial-gradient(circle, var(--grid) 1px, transparent 1.6px) 0 0 / 10px 10px,
    radial-gradient(circle at 50% 50%, rgba(65, 212, 200, 0.07) 0 42%, rgba(5, 7, 13, 0.9) 100%);
  overflow: hidden;
}

.nucleus-dot {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 18px rgba(255, 122, 69, 0.68);
  transform: translate(-50%, -50%);
}

.nucleus-beam {
  position: absolute;
  left: -18%;
  top: 50%;
  width: 136%;
  height: 3px;
  background: var(--accent);
  box-shadow: 0 0 16px rgba(255, 122, 69, 0.72);
  transform: rotate(var(--beam-angle));
  transform-origin: center;
}

.callout-label {
  margin-bottom: 0.25rem;
  color: var(--text) !important;
  font-size: 0.84rem;
  font-weight: 700;
}

/* Derived from the beam vector, not authored — it must read as a measurement. */
.callout-angle {
  margin-top: 0.35rem;
  color: var(--bio-dim) !important;
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
  font-size: 0.8rem;
  letter-spacing: 0.02em;
}

.action-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: 1.8rem;
}

.primary-action,
.secondary-action {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  min-height: 46px;
  border-radius: var(--radius-lg);
  cursor: pointer;
  font-size: 0.9rem;
  font-weight: 600;
  padding: 0.7rem 1.15rem;
  transition:
    border-color 180ms ease,
    background-color 180ms ease,
    color 180ms ease;
}

/* Play fires the force, so it is the one warm button on the page. */
.primary-action {
  border: 1px solid var(--accent);
  background: rgba(255, 122, 69, 0.14);
  color: var(--accent-hot);
}

.primary-action:hover {
  background: rgba(255, 122, 69, 0.22);
}

/* The glyph is drawn, not typed, so the button's label stays exactly the words it has: a
   play triangle, or a stop square while the sequence runs. */
.primary-action::before {
  content: "";
  flex: none;
  width: 0.62rem;
  height: 0.72rem;
  background: currentColor;
  clip-path: polygon(0 0, 100% 50%, 0 100%);
}

.primary-action[data-playing="true"]::before {
  width: 0.62rem;
  height: 0.62rem;
  clip-path: inset(0 round 1px);
}

.secondary-action {
  border: 1px solid var(--line-control);
  background: rgba(11, 18, 32, 0.55);
  color: var(--text);
}

.secondary-action:hover {
  border-color: var(--bio-dim);
  background: rgba(16, 26, 44, 0.8);
}

.sequence-status {
  min-height: 1.5rem;
  margin-top: 1rem;
  color: var(--muted);
  font-size: 0.8125rem;
  line-height: 1.55;
}

.site-footer {
  padding: clamp(3rem, 6vw, 4.5rem) 0 clamp(3rem, 6vw, 5rem);
  background: var(--bg-soft);
  color: var(--muted);
  font-size: 0.9rem;
}

.footer-grid {
  display: grid;
  gap: 1.1rem;
  max-width: 68ch;
}

.site-footer p {
  margin: 0;
}

.footer-note {
  color: var(--text);
  font-size: 1rem;
  line-height: 1.6;
}

.footer-disclaimer {
  padding-left: 0.95rem;
  border-left: 2px solid var(--accent);
  color: var(--text);
  font-style: italic;
  font-weight: 600;
  font-size: 0.95rem;
}

.footer-citation cite {
  font-style: italic;
  font-weight: 600;
  color: var(--text);
}

@media (max-width: 900px) {
  .hero {
    min-height: auto;
  }

  .hero-grid,
  .split-layout,
  .split-layout--reverse,
  .interactive-layout {
    grid-template-columns: 1fr;
  }

  .section-heading {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas:
      "num"
      "title"
      "hook";
  }

  .section-heading h2 {
    margin-bottom: 0.75rem;
  }

  .stage-window {
    height: clamp(330px, 68vw, 500px);
  }

  /* One column: the model comes first, so a choice made in the controls below it plays
     just above them, not a screen away. Visual order only — the DOM keeps controls first
     for keyboard and screen-reader order. Not sticky here: the controls would scroll over
     the model, which is drawn beneath the document. */
  .interactive-layout .module-column {
    order: -1;
    position: static;
  }

  .interactive-layout .stage-window {
    height: clamp(300px, 72vw, 460px);
    min-height: 300px;
  }
}

@media (max-width: 720px) {
  :root {
    --nav-height: 60px;
  }

  .site-nav {
    width: min(100% - 24px, 1180px);
  }

  .nav-toggle {
    display: inline-flex;
  }

  /* A full-width sheet hung from the header (the header is sticky, so it is the containing
     block), opaque for the same reason the header is. */
  .nav-links {
    position: absolute;
    left: 0;
    right: 0;
    top: 100%;
    display: none;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    border-top: 1px solid var(--line);
    border-bottom: 1px solid var(--line);
    background-color: var(--void);
    padding: 0.4rem 0 0.8rem;
  }

  .site-nav.is-open .nav-links {
    display: flex;
  }

  .nav-links a {
    display: flex;
    align-items: center;
    min-height: 52px;
    padding: 0 12px 0 calc(12px + 0.9rem);
    border-radius: 0;
    font-size: 1rem;
  }

  /* In the sheet the indicator is a bar on the leading edge. */
  .nav-links a::after {
    left: 12px;
    right: auto;
    top: 14px;
    bottom: 14px;
    width: 2px;
    height: auto;
    border-radius: 2px;
    transform: scaleY(0);
  }

  .nav-links a.is-active::after {
    transform: scaleY(1);
  }

  .section-inner {
    width: min(100% - 24px, 1180px);
  }

  .hero,
  .model-section {
    padding: 3.5rem 0;
  }

  /* 9vw keeps "Neural Neighborhood" inside a 320–414px column with a margin for wider
     platform faces, so the headline still sets in three lines. */
  h1 {
    font-size: clamp(1.8rem, 9vw, 2.25rem);
  }

  .zoom-callout {
    grid-template-columns: 92px minmax(0, 1fr);
  }

  .nucleus-zoom {
    width: 92px;
  }

  .brain-label {
  font-size: 0.66rem;
  padding: 0.34rem 0.44rem;
  }
}

@media (max-width: 420px) {
  /* Two columns of symptoms still fit a 320px phone once the chips give up some padding. */
  .symptom-block .chip,
  .check-chip {
    gap: 0.5rem;
    padding: 0.5rem 0.65rem;
    font-size: 0.8125rem;
  }

  .check-chip input {
    width: 16px;
    height: 16px;
    background-size: 11px 11px;
  }

  .accordion-panel {
    padding-left: 0.875rem;
    padding-right: 0.875rem;
  }
}

@media (max-width: 470px) {
  .stage-window {
    min-height: 300px;
    height: 330px;
  }

  .action-row {
  display: grid;
    grid-template-columns: 1fr;
  }

  .primary-action,
  .secondary-action {
    width: 100%;
  }
}

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

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

/* ---------- Hero: eyebrow, disclaimer, bullseye ---------- */

.eyebrow {
  margin-bottom: 0.45rem;
  color: var(--bio);
  font-size: 0.82rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

/* The author's byline: finer than the over-title above it, in an old-style italic —
   Palatino's is the calligraphic one, its forms close to a written hand. System faces only,
   so it costs nothing to load: Palatino on Apple, Palatino Linotype on Windows, the
   platform serif's italic elsewhere. */
.byline {
  margin: 0 0 1.35rem;
  color: #c9d6dc;
  font-family: "Palatino Linotype", Palatino, "Book Antiqua", "URW Palladio L", "TeX Gyre Pagella", Georgia, serif;
  font-size: 1.125rem;
  font-style: italic;
  font-weight: 400;
  letter-spacing: 0.01em;
}

.medical-note {
  margin-top: 1.5rem;
  padding-left: 0.95rem;
  border-left: 3px solid var(--accent);
  color: var(--text) !important;
  font-style: italic;
  font-weight: 600;
  font-size: 0.98rem;
  max-width: 52ch;
}

/* The hero's stage. It was a dark box laid across the specimen; now the specimen is framed
   into it and the reticle sits on top, transparent, so the two read as one figure. The
   aspect ratio is fixed because the rings are drawn to the zone's projected size, which
   scales with the frame. */
.hero-figure {
  position: relative;
  margin: 0;
  aspect-ratio: 5 / 4;
}

.hero-figure img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

/* ---------- Simulator: accordion ---------- */

.accordion {
  display: grid;
  gap: 0.75rem;
}

.accordion-item {
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-lg);
  background: rgba(11, 18, 32, 0.82);
  overflow: hidden;
  transition: border-color 180ms ease;
}

.accordion-item:has(.accordion-trigger[aria-expanded="true"]) {
  border-color: var(--line-control);
}

.accordion-heading {
  margin: 0;
  font-size: 1rem;
}

.accordion-trigger {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  width: 100%;
  min-height: 60px;
  padding: 0.9rem clamp(1rem, 2.2vw, 1.4rem);
  border: 0;
  background: transparent;
  color: var(--text);
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: background-color 160ms ease;
}

.accordion-trigger:hover {
  background-color: rgba(65, 212, 200, 0.05);
}

.accordion-trigger:focus-visible {
  outline: 2px solid var(--bio);
  outline-offset: -2px;
  border-radius: var(--radius-lg);
}

.accordion-label {
  flex: 1;
  font-size: clamp(1.02rem, 1.4vw, 1.15rem);
  font-weight: 650;
  letter-spacing: -0.005em;
}

/* A chevron that turns rather than a plus that loses a stroke: it points at what opening
   does. */
.accordion-icon {
  flex: none;
  width: 9px;
  height: 9px;
  margin: 0 4px 4px 0;
  border-right: 2px solid var(--bio);
  border-bottom: 2px solid var(--bio);
  transform: rotate(45deg);
  transition: transform 220ms ease, margin 220ms ease;
}

.accordion-trigger[aria-expanded="true"] .accordion-icon {
  margin: 4px 4px 0 0;
  transform: rotate(-135deg);
}

.accordion-panel {
  padding: 0 clamp(1rem, 2.2vw, 1.4rem) 1.4rem;
  border-top: 1px solid var(--line);
}

.aura-note {
  margin: 1.1rem 0 0;
  color: var(--accent-deep);
  font-size: 0.875rem;
  font-weight: 500;
}

/* ---------- Simulator: symptom controls ---------- */

.symptom-block {
  margin-top: 1.1rem;
}

.block-label {
  margin-bottom: 0.7rem;
  color: var(--text);
  font-family: var(--mono);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.block-hint {
  margin-top: -0.4rem;
  margin-bottom: 0.8rem;
  color: var(--muted);
  font-size: 0.875rem;
}

.combination-block {
  margin-top: 1.5rem;
  padding-top: 1.3rem;
  border-top: 1px solid var(--line);
}

/* Four symptoms, two by two: a free wrap left one of them alone on a second row. */
.symptom-block .chip-list,
.check-row {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.5rem;
  margin-bottom: 0;
}

.symptom-block .chip,
.check-chip {
  width: 100%;
  text-align: left;
  line-height: 1.25;
}

.check-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  min-height: 44px;
  padding: 0.5rem 1rem 0.5rem 0.8rem;
  border: 1px solid var(--line-control);
  border-radius: var(--radius-lg);
  background: rgba(11, 18, 32, 0.55);
  color: var(--text);
  font-size: 0.875rem;
  font-weight: 500;
  cursor: pointer;
  transition:
    border-color 160ms ease,
    background-color 160ms ease,
    color 160ms ease;
}

.check-chip:hover {
  border-color: var(--bio-dim);
  background-color: rgba(16, 26, 44, 0.8);
}

/* Drawn by the page: the OS box was a white square in a dark instrument. The tick is an
   SVG in the background so it renders the same in every engine. */
.check-chip input {
  appearance: none;
  flex: none;
  width: 18px;
  height: 18px;
  margin: 0;
  border: 1.5px solid var(--line-control);
  border-radius: 4px;
  background: transparent center / 12px 12px no-repeat;
  cursor: pointer;
  transition:
    background-color 160ms ease,
    border-color 160ms ease;
}

.check-chip input:checked {
  border-color: var(--accent);
  background-color: var(--accent);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M2.5 6.2 5 8.6 9.6 3.6' fill='none' stroke='%2305070d' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}

.check-chip input:focus-visible {
  outline: none;
}

.check-chip:has(input:checked) {
  border-color: rgba(255, 122, 69, 0.85);
  background-color: rgba(255, 122, 69, 0.08);
  color: var(--accent-hot);
}

.check-chip:has(input:focus-visible) {
  outline: 2px solid var(--bio);
  outline-offset: 3px;
}

/* ---------- Simulator: readout ---------- */

.readout-list {
  display: grid;
  gap: 0.5rem;
}

/* The grid's gap spaces the lines, and spacing belongs to whatever follows the readout, so
   an empty panel carries no slack under its last line. */
.readout-list > p {
  margin: 0;
}

.readout-list + .panel-detail:not(:empty) {
  margin-top: 1rem;
}

.readout-empty {
  color: var(--muted) !important;
  font-size: 0.95rem;
}

.readout-line {
  padding: 0.55rem 0.75rem;
  border-left: 2px solid var(--accent);
  background: var(--warm-tint);
  color: var(--text) !important;
  font-size: 1rem;
  font-weight: 700;
  animation: readout-in 260ms ease both;
}

.readout-line--aura {
  border-left-color: var(--bio);
  background: rgba(65, 212, 200, 0.07);
}

@keyframes readout-in {
  from {
    opacity: 0;
    transform: translateY(6px);
  }
}

.panel-detail {
  display: grid;
  gap: 0.5rem;
  font-size: 0.95rem;
}

/* Only rendered when a selection reaches more than one structure, to keep the
   descriptions apart. */
.detail-structure {
  color: var(--text) !important;
  font-size: 0.84rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}

.detail-structure:not(:first-child) {
  margin-top: 0.6rem;
}

/* ---------- Structures reference ---------- */

/* A list rather than a wrap of long pills: each choice reads symptom first, with the
   structure it strikes beneath, and the five line up to be scanned. */
.option-list {
  display: grid;
  gap: 0.5rem;
  margin: 0;
}

.option-list .chip {
  width: 100%;
  min-height: 58px;
  padding: 0.65rem 1rem 0.65rem 0.95rem;
  gap: 0.8rem;
  text-align: left;
}

.chip-text {
  display: grid;
  gap: 0.1rem;
}

.chip-label {
  font-size: 0.9375rem;
  font-weight: 600;
  line-height: 1.3;
}

.chip-sub {
  color: var(--muted);
  font-size: 0.8125rem;
  font-weight: 500;
  line-height: 1.3;
}

.chip[aria-checked="true"] .chip-sub {
  color: var(--accent-deep);
}

.reference-panel h3 {
  margin-bottom: 0.8rem;
  font-size: clamp(1.1rem, 1.9vw, 1.35rem);
  font-weight: 700;
}

.reference-panel p {
  color: var(--muted);
}

/* ---------- Pineal body ---------- */

.narrow-layout {
  max-width: 72ch;
}

.narrow-layout p {
  color: var(--muted);
}

.narrow-layout cite {
  font-style: italic;
  font-weight: 600;
  color: var(--text);
}

.key-points {
  margin: 0 0 1.4rem;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 0.5rem;
}

.key-points li {
  position: relative;
  padding-left: 1.5rem;
  color: var(--text);
  font-weight: 700;
}

.key-points li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.55em;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--accent);
}

/* ---------- Measurements ---------- */

/* Cool, mono, and derived: every figure here comes from js/data.js or falls out of the
   geometry, so it is a fact about the model rather than a claim about migraine. */
.hud {
  display: grid;
  gap: 0.4rem;
  margin-top: 1.4rem;
  padding-top: 1.1rem;
  border-top: 1px solid var(--line);
  font-family: var(--mono);
  font-size: 0.76rem;
  font-variant-numeric: tabular-nums;
  line-height: 1.5;
}

.hud:empty {
  display: none;
}

.hud-row {
  display: grid;
  grid-template-columns: 5.5rem minmax(0, 1fr);
  gap: 0.6rem;
}

.hud-key {
  color: var(--bio);
  letter-spacing: 0.08em;
}

.hud-value {
  color: var(--muted);
  overflow-wrap: anywhere;
}

/* The author's one non-negotiable, stated as a measurement the reader can watch hold. */
.hud-row--clear .hud-value {
  color: var(--bio-dim);
}

.hud-row--struck .hud-value {
  color: var(--accent-deep);
}

@media (max-width: 520px) {
  .hud-row {
    grid-template-columns: minmax(0, 1fr);
    gap: 0;
  }
}

/* ---------- Motion ---------- */

.reveal {
  opacity: 0;
  transform: translateY(10px);
  transition:
    opacity 420ms cubic-bezier(0.2, 0.8, 0.2, 1) var(--reveal-delay, 0ms),
    transform 420ms cubic-bezier(0.2, 0.8, 0.2, 1) var(--reveal-delay, 0ms);
}

.reveal.is-revealed {
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  /* A complete path, not a degraded one: everything arrives, nothing travels. */
  .reveal {
    opacity: 1;
    transform: none;
    transition: none;
  }
}
