/* ==========================================================================
   HECATE · visual system
   --------------------------------------------------------------------------
   Direction: signal room. Three accents with a fixed meaning (lime = action,
   cyan = data, violet = adapter, amber = fault). Deep ink ground, three
   elevation levels, editorial rhythm. No webfonts, no bitmaps, no JS needed
   to read the page.

   The contract for this file is site/DESIGN.md.
   ========================================================================== */

/* --- 1. Tokens ----------------------------------------------------------- */

/* One palette, two themes. light-dark() resolves against the used colour
   scheme, so an explicit choice in the theme switcher only has to declare
   the scheme and never duplicates a single token. */
:root {
  color-scheme: dark light;

  --font-sans: system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;

  --ink: light-dark(#f7f8f5, #05070a);
  --ink-2: light-dark(#ffffff, #0a0e13);
  --surface: light-dark(#ffffff, #0f151c);
  --surface-2: light-dark(#f1f4f0, #141c25);
  --surface-3: light-dark(#e7ece6, #1b2530);
  --line: light-dark(rgba(10, 18, 22, 0.12), rgba(255, 255, 255, 0.09));
  --line-hi: light-dark(rgba(10, 18, 22, 0.26), rgba(255, 255, 255, 0.18));
  --text: light-dark(#0a1216, #f2f6f8);
  --text-dim: light-dark(#4a5a64, #9fb0bc);

  --lime: light-dark(#47660a, #c6f24e);
  --cyan: light-dark(#0f766e, #4fd1c5);
  --violet: light-dark(#5b45d6, #8b7bff);
  --amber: light-dark(#8a5a00, #e0a33e);

  --field-lime: light-dark(rgba(71, 102, 10, 0.05), rgba(198, 242, 78, 0.055));
  --field-cyan: light-dark(rgba(15, 118, 110, 0.05), rgba(79, 209, 197, 0.05));
  --field-violet: light-dark(rgba(91, 69, 214, 0.05), rgba(139, 123, 255, 0.05));
  --grain-opacity: 0.1;

  --shadow-color: light-dark(rgba(10, 18, 22, 0.09), rgba(0, 0, 0, 0.28));
  --shadow-1: 0 1px 0 var(--line-hi) inset, 0 1px 2px var(--shadow-color);
  --shadow-2: 0 0 0 1px var(--line), 0 18px 40px -24px var(--shadow-color);
  --shadow-3: 0 0 0 1px var(--line-hi), 0 40px 90px -40px var(--shadow-color);

  --ring-lime: light-dark(rgba(71, 102, 10, 0.45), rgba(198, 242, 78, 0.4));
  --blur-lime: light-dark(rgba(71, 102, 10, 0.3), rgba(198, 242, 78, 0.3));
  --ring-cyan: light-dark(rgba(15, 118, 110, 0.4), rgba(79, 209, 197, 0.34));
  --blur-cyan: light-dark(rgba(15, 118, 110, 0.26), rgba(79, 209, 197, 0.26));
  --ring-violet: light-dark(rgba(91, 69, 214, 0.4), rgba(139, 123, 255, 0.34));
  --blur-violet: light-dark(rgba(91, 69, 214, 0.26), rgba(139, 123, 255, 0.26));
  --glow-lime: 0 0 0 1px var(--ring-lime), 0 0 28px -6px var(--blur-lime);
  --glow-cyan: 0 0 0 1px var(--ring-cyan), 0 0 24px -8px var(--blur-cyan);
  --glow-violet: 0 0 0 1px var(--ring-violet), 0 0 24px -8px var(--blur-violet);

  --s-1: 0.25rem;
  --s-2: 0.5rem;
  --s-3: 0.75rem;
  --s-4: 1rem;
  --s-5: 1.5rem;
  --s-6: 2rem;
  --s-7: 3rem;
  --s-8: 4.5rem;
  --s-9: 7rem;

  --r-1: 4px;
  --r-2: 12px;
  --r-3: 24px;
  --r-full: 999px;

  --e-out: cubic-bezier(0.22, 1, 0.36, 1);
  --e-io: cubic-bezier(0.76, 0, 0.24, 1);
  --e-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
  --d-1: 120ms;
  --d-2: 240ms;
  --d-3: 480ms;
  --d-4: 900ms;

  --z-canvas: 0;
  --z-content: 10;
  --z-header: 20;
  --z-overlay: 30;

  --display: clamp(3.2rem, 1.4rem + 7vw, 8.5rem);
  --step-5: clamp(2rem, 1.2rem + 2.6vw, 3.4rem);
  --step-4: clamp(1.5rem, 1.1rem + 1.3vw, 2.1rem);
  --step-3: clamp(1.25rem, 1.1rem + 0.6vw, 1.5rem);
  --step-2: clamp(1.1rem, 1rem + 0.5vw, 1.35rem);
  --step-0: 1rem;
  --step--1: 0.875rem;
  --step--2: 0.78rem;

  /* Data voice: a figure is evidence, not decoration. */
  --figure-hero: clamp(3rem, 1.6rem + 5.2vw, 5.5rem);
  --figure-lg: clamp(2rem, 1.4rem + 2.2vw, 3.25rem);
  --figure-md: clamp(1.5rem, 1.25rem + 1vw, 2rem);
  --figure-label: clamp(0.72rem, 0.68rem + 0.2vw, 0.8rem);
  /* Tracking for display numerals: large figures need negative tracking to
     avoid looking loose next to the mono label underneath. */
  --figure-tracking: -0.02em;
  /* Ink of a figure. A variable and not a literal so the dark/light switch and
     any future accent change move the figures with the rest of the palette. */
  --figure-color: var(--cyan);

  --measure: 64ch;
  --measure-narrow: 46ch;
  --wrap: 78rem;
}

/* The theme switcher only declares the scheme. */
:root[data-theme="dark"] {
  color-scheme: dark;
}

:root[data-theme="light"] {
  color-scheme: light;
}

@media (prefers-contrast: more) {
  :root {
    --line: light-dark(rgba(10, 18, 22, 0.5), rgba(255, 255, 255, 0.45));
    --line-hi: light-dark(rgba(10, 18, 22, 0.75), rgba(255, 255, 255, 0.7));
    --text-dim: light-dark(#23333c, #d6e2e8);
  }
}

/* --- 2. Base ------------------------------------------------------------- */

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

html {
  background: var(--ink);
  -webkit-text-size-adjust: 100%;
  scroll-padding-top: 6rem;
}

body {
  margin: 0;
  background: transparent;
  color: var(--text);
  font-family: var(--font-sans);
  font-size: var(--step-0);
  line-height: 1.62;
  overflow-x: hidden;
  overflow-wrap: break-word;
}

/* Layered ground: three radial fields with different falloff. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -2;
  pointer-events: none;
  background:
    radial-gradient(1100px 680px at 14% -8%, var(--field-lime), transparent 62%),
    radial-gradient(900px 620px at 86% 2%, var(--field-cyan), transparent 60%),
    radial-gradient(760px 900px at 52% 118%, var(--field-violet), transparent 58%);
}

/* Grain and vignette. */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: var(--grain-opacity);
  /* No mix-blend-mode here: a blended fixed layer has to be recomposed with
     the page on every scroll, and that is what costs frames while reading. */
  background-image:
    radial-gradient(120% 100% at 50% 50%, transparent 42%, rgba(0, 0, 0, 0.55) 100%),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.82' numOctaves='4' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23g)'/%3E%3C/svg%3E");
}

h1,
h2,
h3 {
  margin: 0;
  line-height: 1.16;
  font-weight: 600;
  letter-spacing: -0.015em;
}

p {
  margin: 0;
}

ul,
ol {
  margin: 0;
  padding: 0;
}

a {
  color: var(--lime);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.2em;
}

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

:focus-visible {
  outline: 2px solid var(--lime);
  outline-offset: 3px;
  border-radius: var(--r-1);
}

code,
pre {
  font-family: var(--font-mono);
}

code {
  font-size: 0.9em;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--r-1);
  padding: 0.05em 0.32em;
}

pre {
  margin: 0;
  font-size: var(--step--1);
  line-height: 1.7;
  tab-size: 2;
}

pre code {
  background: none;
  border: 0;
  padding: 0;
  font-size: 1em;
}

.container {
  width: min(100% - 2.5rem, var(--wrap));
  margin-inline: auto;
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  padding: 0.6rem 0.9rem;
  background: var(--ink-2);
  color: var(--text);
  border: 1px solid var(--lime);
  border-radius: var(--r-1);
  font-size: var(--step--1);
  text-decoration: none;
}

.skip-link:focus {
  left: 0.75rem;
  top: 0.75rem;
}

/* --- 3. Header ----------------------------------------------------------- */

.site-header {
  position: sticky;
  top: 0;
  z-index: var(--z-header);
  background: color-mix(in srgb, var(--ink-2) 88%, transparent);
  border-bottom: 1px solid var(--line);
  backdrop-filter: blur(14px) saturate(140%);
}

.site-header--plain {
  position: static;
}

.reading-bar {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  height: 2px;
  background: var(--line);
}

.reading-bar__fill {
  display: block;
  height: 100%;
  width: 100%;
  transform: scaleX(0);
  transform-origin: 0 50%;
  background: linear-gradient(90deg, var(--cyan), var(--lime));
}

.site-header__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem 1.5rem;
  padding-block: 0.85rem;
}

.brand {
  display: inline-flex;
  align-items: baseline;
  gap: 0.4rem;
  font-family: var(--font-mono);
  font-size: var(--step-2);
  font-weight: 700;
  letter-spacing: 0.1em;
  color: var(--text);
  text-decoration: none;
}

.brand__dot {
  width: 6px;
  height: 6px;
  border-radius: var(--r-full);
  background: var(--lime);
  box-shadow: 0 0 12px -2px var(--lime);
}

/* The section menu.
   ------------------------------------------------------------------------
   Above 60rem the seven links are a row inside the header. Below it they were
   wrapped into two rows, which made a sticky header 196px tall on a 390px
   phone: 23% of the screen, permanently, on every scroll position. Now the
   same links live in a panel behind a toggle, so the header keeps one row at
   every width.

   The panel is not a <details> on purpose. A closed <details> hides its
   children with a UA rule that cannot be overridden, and the desktop layout
   needs those children to be visible without any open state. So the collapsed
   layout is enabled by the module, which adds `nav-ready` to <html>: with
   JavaScript off nothing is hidden and nothing is unreachable, the links just
   wrap as they did before. */
.site-nav {
  display: contents;
}

.site-nav__toggle {
  display: none;
  align-items: center;
  gap: 0.45rem;
  min-height: 44px;
  padding: 0 0.7rem;
  border: 1px solid var(--line-hi);
  border-radius: var(--r-1);
  background: var(--surface);
  color: var(--text);
  font: 500 var(--step--1) / 1 var(--font-sans);
  cursor: pointer;
  transition: border-color var(--d-1) var(--e-out), color var(--d-1) var(--e-out);
}

.site-nav__toggle:hover {
  border-color: var(--lime);
  color: var(--lime);
}

/* Three bars from one element and two pseudo elements: no icon font, no SVG
   request, and the open state rotates them into a cross. */
.site-nav__bars,
.site-nav__bars::before,
.site-nav__bars::after {
  display: block;
  width: 16px;
  height: 2px;
  border-radius: 2px;
  background: currentColor;
  transition: transform var(--d-2) var(--e-out), background-color var(--d-1) var(--e-out);
}

.site-nav__bars {
  position: relative;
}

.site-nav__bars::before,
.site-nav__bars::after {
  content: "";
  position: absolute;
  left: 0;
}

.site-nav__bars::before {
  top: -5px;
}

.site-nav__bars::after {
  top: 5px;
}

.site-nav__toggle[aria-expanded="true"] .site-nav__bars {
  background: transparent;
}

.site-nav__toggle[aria-expanded="true"] .site-nav__bars::before {
  transform: translateY(5px) rotate(45deg);
}

.site-nav__toggle[aria-expanded="true"] .site-nav__bars::after {
  transform: translateY(-5px) rotate(-45deg);
}

/* Only once the module is running does the compact header exist. */
.nav-ready .site-nav {
  margin-inline-start: auto;
}

.nav-ready .site-nav__toggle {
  display: inline-flex;
}

/* 68rem and not 60: with the seven labels, the status pill and the theme
   switch, the desktop row needs about 1010px of inner width to stay on one
   line. At 60rem it wrapped into two rows and the header grew to 104px. */
@media (max-width: 67.999rem) {
  .nav-ready .site-header__inner {
    flex-wrap: nowrap;
    padding-block: 0.5rem;
  }

  .nav-ready .site-nav {
    display: block;
    position: static;
    margin-inline-start: auto;
  }

  .nav-ready .site-nav__panel {
    position: absolute;
    left: 0;
    right: 0;
    top: 100%;
    display: none;
    padding: 0.35rem 1.25rem 1.1rem;
    border-bottom: 1px solid var(--line-hi);
    background: var(--ink-2);
    box-shadow: var(--shadow-3);
    max-height: calc(100dvh - 5rem);
    overflow-y: auto;
    overscroll-behavior: contain;
  }

  .nav-ready .site-nav[data-open="true"] .site-nav__panel {
    display: block;
  }

  /* One row per section, 48px tall: the whole point of the panel is that a
     thumb can hit a link without aiming. */
  .nav-ready .primary-nav {
    margin: 0;
  }

  .nav-ready .primary-nav ul {
    flex-direction: column;
    gap: 0;
    font-size: var(--step-0);
  }

  .nav-ready .primary-nav li+li {
    border-top: 1px solid var(--line);
  }

  .nav-ready .primary-nav a {
    display: flex;
    align-items: center;
    min-height: 48px;
    color: var(--text);
  }

  /* The underline grows out of the left edge, which reads as a broken rule in
     a stacked list. The full-width row is the target instead. */
  .nav-ready .primary-nav a::after {
    display: none;
  }

  .nav-ready .site-nav__panel .status-pill {
    margin: 0.9rem 0 0;
    padding: 0.3rem 0.7rem;
    font-size: var(--step--1);
  }

  .nav-ready .theme-switch button {
    padding: 0.35rem 0.5rem;
  }
}

@media (min-width: 68rem) {
  .site-nav__panel {
    display: contents;
  }

  .nav-ready .site-nav {
    margin-inline-start: 0;
  }

  .nav-ready .site-nav__toggle {
    display: none;
  }
}

/* A phone has no room for the word next to the bars, and at 320px there is no
   room for the full width of the theme switch either: the three groups have to
   shrink or the header overflows sideways. */
@media (max-width: 25.999rem) {
  .nav-ready .site-header__inner {
    gap: 0.4rem;
  }

  .nav-ready .site-nav__toggle {
    padding-inline: 0.55rem;
  }

  .nav-ready .site-nav__toggle-text {
    display: none;
  }

  .nav-ready .theme-switch {
    padding: 1px;
    gap: 1px;
  }

  .nav-ready .theme-switch button {
    padding-inline: 0.35rem;
  }

  .nav-ready .brand {
    font-size: 1.05rem;
    letter-spacing: 0.06em;
  }
}

/* Once the page moves, the header separates itself from the content it is
   covering. Without the cue a sticky translucent bar reads as part of the
   page and the blur looks like a rendering artefact. */
.site-header.is-scrolled {
  border-bottom-color: var(--line-hi);
  box-shadow: 0 12px 32px -28px var(--shadow-color);
}

.primary-nav {
  margin-inline-start: auto;
}

.primary-nav ul {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem 1.15rem;
  list-style: none;
  font-size: var(--step--1);
}

.primary-nav a {
  position: relative;
  color: var(--text-dim);
  text-decoration: none;
}

.primary-nav a::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -3px;
  height: 1px;
  background: var(--lime);
  transform: scaleX(0);
  transform-origin: 0 50%;
  transition: transform var(--d-1) var(--e-out);
}

.primary-nav a:hover,
.primary-nav a[aria-current="true"] {
  color: var(--text);
}

.primary-nav a:hover::after,
.primary-nav a[aria-current="true"]::after {
  transform: scaleX(1);
}

.site-header__tools {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 0.75rem;
}

.status-pill {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  margin: 0;
  padding: 0.2rem 0.6rem;
  border: 1px solid var(--line-hi);
  border-radius: var(--r-full);
  background: var(--surface);
  font-family: var(--font-mono);
  font-size: var(--step--2);
  color: var(--text-dim);
  white-space: nowrap;
}

.status-pill__dot {
  width: 6px;
  height: 6px;
  border-radius: var(--r-full);
  background: var(--lime);
  box-shadow: 0 0 10px -1px var(--lime);
}

.theme-switch {
  display: inline-flex;
  padding: 2px;
  gap: 2px;
  border: 1px solid var(--line);
  border-radius: var(--r-full);
  background: var(--surface);
}

.theme-switch button {
  appearance: none;
  border: 0;
  border-radius: var(--r-full);
  padding: 0.2rem 0.6rem;
  background: transparent;
  color: var(--text-dim);
  font: 500 var(--step--2) / 1.4 var(--font-mono);
  cursor: pointer;
  transition: color var(--d-1) var(--e-out), background-color var(--d-1) var(--e-out);
}

.theme-switch button:hover {
  color: var(--text);
}

.theme-switch button[aria-pressed="true"] {
  background: var(--surface-3);
  color: var(--text);
  box-shadow: var(--shadow-1);
}

/* --- 4. Buttons ---------------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.5rem 0.95rem;
  border: 1px solid var(--line-hi);
  border-radius: var(--r-1);
  background: var(--surface);
  color: var(--text);
  font: 500 var(--step--1) / 1.2 var(--font-sans);
  text-decoration: none;
  cursor: pointer;
  transition: transform var(--d-1) var(--e-out), border-color var(--d-1) var(--e-out),
    background-color var(--d-1) var(--e-out), color var(--d-1) var(--e-out);
}

.btn:hover {
  border-color: var(--lime);
  color: var(--lime);
  transform: translateY(-2px);
}

.btn:active {
  transform: translateY(0);
}

.btn[disabled] {
  opacity: 0.45;
  cursor: not-allowed;
  transform: none;
}

.btn--primary {
  background: var(--lime);
  border-color: var(--lime);
  color: var(--ink);
  font-weight: 600;
}

.btn--primary:hover {
  color: var(--ink);
  box-shadow: var(--glow-lime);
}

.btn--secondary {
  background: transparent;
}

.btn--copy {
  padding: 0.25rem 0.6rem;
  font-family: var(--font-mono);
  font-size: var(--step--2);
  color: var(--text-dim);
  background: var(--surface-2);
}

/* A control that cannot act any more keeps its focus: `aria-disabled` leaves
   it focusable, and the browser would drop the focus if it were `disabled`. */
.btn[aria-disabled="true"],
.btn:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}

/* --- 5. Hero ------------------------------------------------------------- */

.hero {
  position: relative;
  isolation: isolate;
  /* Short enough that the metrics band is visible in the first screen: the
     band is the second thing the eye lands on, after the wordmark. */
  min-height: min(72vh, 46rem);
  display: flex;
  align-items: center;
  overflow: hidden;
  border-bottom: 1px solid var(--line);
}

.hero__canvas {
  position: absolute;
  inset: 0;
  z-index: var(--z-canvas);
  width: 100%;
  height: 100%;
  pointer-events: none;
}

.hero__glow {
  position: absolute;
  inset: -20% -10%;
  z-index: 1;
  pointer-events: none;
  mix-blend-mode: screen;
}

.hero__glow-a,
.hero__glow-b {
  position: absolute;
  display: block;
  width: 46rem;
  height: 46rem;
  border-radius: 50%;
  filter: blur(90px);
}

.hero__glow-a {
  top: -14rem;
  left: -8rem;
  background: radial-gradient(circle, rgba(198, 242, 78, 0.16), transparent 66%);
}

.hero__glow-b {
  right: -10rem;
  bottom: -18rem;
  background: radial-gradient(circle, rgba(79, 209, 197, 0.14), transparent 68%);
}

.hero__inner {
  position: relative;
  z-index: var(--z-content);
  padding-block: var(--s-8);
  display: grid;
  gap: var(--s-4);
  justify-items: start;
}

.hero__title {
  font-family: var(--font-mono);
  font-size: var(--display);
  font-weight: 700;
  letter-spacing: -0.045em;
  line-height: 0.88;
  color: var(--text);
  text-shadow: 0 0 60px rgba(79, 209, 197, 0.18);
}

.hero__claim {
  max-width: 22ch;
  font-size: var(--step-5);
  font-weight: 600;
  line-height: 1.12;
  letter-spacing: -0.02em;
  color: var(--text);
}

.hero__sub {
  max-width: 52ch;
  font-size: var(--step-2);
  color: var(--text-dim);
}

.hero__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem 1.25rem;
  list-style: none;
  font-family: var(--font-mono);
  font-size: var(--step--1);
  color: var(--text-dim);
  letter-spacing: 0.04em;
}

.hero__meta li {
  position: relative;
}

.hero__meta li+li::before {
  content: "";
  position: absolute;
  left: -0.7rem;
  top: 0.55em;
  width: 3px;
  height: 3px;
  border-radius: var(--r-full);
  background: var(--line-hi);
}

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: var(--s-2);
}

.hero__vignette {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background: radial-gradient(120% 90% at 50% 40%, transparent 40%, rgba(0, 0, 0, 0.55) 100%);
}

/* --- 6. Marquee ---------------------------------------------------------- */

.marquee {
  overflow: hidden;
  border-bottom: 1px solid var(--line);
  background: var(--ink-2);
  padding-block: 0.6rem;
  mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}

.marquee__track {
  display: flex;
  gap: 2.5rem;
  width: max-content;
  will-change: transform;
}

.marquee__track span {
  font-family: var(--font-mono);
  font-size: var(--step--2);
  letter-spacing: 0.12em;
  color: var(--text-dim);
  white-space: nowrap;
}

/* --- 7. Sections --------------------------------------------------------- */

.section {
  display: grid;
  gap: var(--s-5);
  padding-block: var(--s-7);
  border-top: 1px solid var(--line);
}

.section__head {
  min-width: 0;
}

.section__title {
  font-size: var(--step-4);
  letter-spacing: -0.02em;
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
}

.section__number {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  font-weight: 500;
  letter-spacing: 0.14em;
  color: var(--lime);
}

.section__body {
  min-width: 0;
}

@media (min-width: 62rem) {
  .section {
    grid-template-columns: 15rem minmax(0, 1fr);
    gap: var(--s-6) var(--s-6);
    padding-block: var(--s-8);
  }

  .section--wide>*,
  .section--lab>* {
    grid-column: 1 / -1;
  }

  .section--narrow {
    grid-template-columns: minmax(0, 1fr);
  }

  .section--narrow .section__body {
    max-width: var(--measure);
  }

  .section--sticky .section__head {
    position: sticky;
    top: 6rem;
    align-self: start;
  }

  .section--split .section__body {
    display: grid;
    gap: var(--s-6);
  }
}

.prose {
  max-width: var(--measure);
  display: grid;
  gap: var(--s-4);
}

.prose p {
  color: var(--text-dim);
}

.prose .lead,
.prose__lead {
  color: var(--text);
  font-size: var(--step-2);
  line-height: 1.45;
  letter-spacing: -0.01em;
}

.lead {
  max-width: var(--measure-narrow);
}

/* --- 8. Pillars ---------------------------------------------------------- */

.pillars {
  display: grid;
  gap: var(--s-4);
  grid-template-columns: repeat(auto-fit, minmax(min(17rem, 100%), 1fr));
}

.pillar {
  padding: var(--s-4) var(--s-4) var(--s-4) var(--s-5);
  border: 1px solid var(--line);
  border-left: 2px solid var(--cyan);
  border-radius: var(--r-2);
  background: var(--surface);
  box-shadow: var(--shadow-2);
}

.pillar--violet {
  border-left-color: var(--violet);
}

.pillar__label {
  margin: 0 0 0.4rem;
  font-family: var(--font-mono);
  font-size: var(--step--2);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--cyan);
}

.pillar--violet .pillar__label {
  color: var(--violet);
}

.pillar__title {
  font-size: var(--step-3);
  margin-bottom: 0.5rem;
}

.pillar p {
  color: var(--text-dim);
}

.pillar p+p {
  margin-top: 0.6rem;
}

/* --- 8b. Data voice -------------------------------------------------------- */

.figure {
  color: var(--text) !important;
  display: inline-flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.16em;
  vertical-align: baseline;
}

.figure--inline {
  display: inline;
}

.figure__value {
  display: inline-block;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-weight: 650;
  font-size: var(--figure-md);
  letter-spacing: 0;
  line-height: 1;
  color: var(--figure-color);
}

.figure--lg .figure__value {
  font-size: var(--figure-lg);
  letter-spacing: var(--figure-tracking);
}

/* A figure that stands alone inside a table cell: the label sits directly under
   the number, and the cell is aligned to the top so a tall row doesn't float the
   figure down to the baseline. */
.figure--md {
  gap: 0.1em;
  vertical-align: top;
}

.figure--md .figure__value {
  font-size: var(--figure-md);
  letter-spacing: var(--figure-tracking);
  color: var(--figure-color);
}

.figure__label {
  font-family: var(--font-mono);
  font-size: var(--figure-label);
  font-weight: 600;
  letter-spacing: 0.12em;
  line-height: 1.25;
  text-transform: uppercase;
  color: var(--text-dim);
}

/* The metrics band: the proof of work, right under the wordmark. */
.band {
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  background: var(--surface);
}

.band__inner {
  display: grid;
  gap: var(--s-5);
  padding-block: var(--s-6);
}

.band__eyebrow {
  margin: 0;
  font-family: var(--font-mono);
  font-size: var(--figure-label);
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-dim);
}

.band__metrics {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--s-5) var(--s-4);
  grid-template-columns: repeat(auto-fit, minmax(min(9rem, 100%), 1fr));
}

/* Above these widths the number of columns is stated. Left to auto-fit, the
   browser counts tracks against the minimum and then hands the free space to
   1fr, which can ask for more than the row has, and the band overflows. */
@media (min-width: 48rem) {
  .band__metrics {
    grid-template-columns: repeat(3, minmax(min(9rem, 100%), 1fr));
  }
}

@media (min-width: 72rem) {
  .band__metrics {
    grid-template-columns: repeat(5, minmax(min(9rem, 100%), 1fr));
  }
}

.metric {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  min-width: 0;
}

.metric__value {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-weight: 650;
  font-size: var(--figure-hero);
  letter-spacing: -0.02em;
  line-height: 0.92;
  color: var(--cyan);
  white-space: nowrap;
}

.metric__label {
  font-family: var(--font-mono);
  font-size: var(--figure-label);
  font-weight: 600;
  letter-spacing: 0.12em;
  line-height: 1.3;
  text-transform: uppercase;
  color: var(--text-dim);
}

/* --- 9. Spec table ------------------------------------------------------- */

.module-table {
  border: 1px solid var(--line);
  border-radius: var(--r-2);
  background: var(--surface);
  box-shadow: var(--shadow-2);
  overflow: hidden;
}

.spec-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--step--1);
}

.spec-table__caption {
  padding: var(--s-4) var(--s-4) 0;
  text-align: left;
  font-family: var(--font-mono);
  font-size: var(--step--2);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-dim);
}

.spec-table th,
.spec-table td {
  text-align: left;
  vertical-align: top;
  padding: 0.65rem var(--s-4);
  border-top: 1px solid var(--line);
}

.spec-table thead th {
  position: sticky;
  top: 0;
  background: var(--surface-2);
  font-family: var(--font-mono);
  font-size: var(--step--2);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-dim);
  font-weight: 500;
}

.spec-table tbody th {
  font-weight: 500;
  color: var(--text);
  white-space: nowrap;
}

.spec-table td {
  color: var(--text-dim);
}

.spec-table__group th {
  background: var(--surface-2);
  font-family: var(--font-mono);
  font-size: var(--step--2);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--cyan);
  font-weight: 500;
}

.spec-table__group+tr th,
.spec-table__group+tr td {
  border-top: 0;
}

@media (max-width: 47.99rem) {
  .spec-table thead {
    display: none;
  }

  .spec-table tbody th,
  .spec-table tbody td,
  .spec-table__group th {
    display: block;
    border-top: 0;
    padding-block: 0.2rem;
  }

  .spec-table tbody tr {
    display: block;
    padding: var(--s-3) var(--s-4);
    border-top: 1px solid var(--line);
  }

  .spec-table tbody td {
    padding-top: 0.2rem;
  }

  .spec-table__group {
    display: block;
    padding-top: var(--s-3);
  }
}

/* --- 9b. Plane map ------------------------------------------------------- */

.plane-map {
  margin-top: var(--s-4);
  padding: var(--s-4);
  border: 1px solid var(--line);
  border-radius: var(--r-2);
  background: var(--surface-2);
  display: grid;
  gap: var(--s-3);
}

.plane-map__title {
  font-family: var(--font-mono);
  font-size: var(--step--2);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-dim);
}

.plane-map__lane {
  display: grid;
  gap: 0.4rem;
}

@media (min-width: 48rem) {
  .plane-map__lane {
    grid-template-columns: 9rem minmax(0, 1fr);
    align-items: center;
    gap: var(--s-4);
  }
}

.plane-map__label {
  font-family: var(--font-mono);
  font-size: var(--step--2);
  color: var(--cyan);
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.plane-map__blocks {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
}

.plane-map__block {
  padding: 0.25rem 0.5rem;
  border: 1px solid var(--line);
  border-radius: var(--r-1);
  background: var(--surface-3);
  font-family: var(--font-mono);
  font-size: var(--step--2);
  color: var(--text-dim);
  white-space: nowrap;
  transition: color var(--d-1) var(--e-out), border-color var(--d-1) var(--e-out),
    background-color var(--d-1) var(--e-out), box-shadow var(--d-1) var(--e-out);
}

.plane-map__block.is-active {
  color: var(--ink);
  background: var(--cyan);
  border-color: var(--cyan);
  box-shadow: var(--glow-cyan);
}

/* --- 10. Swarm lab ------------------------------------------------------- */

.lab {
  display: grid;
  gap: var(--s-5);
  grid-template-columns: minmax(0, 1fr);
}

@media (min-width: 58rem) {
  .lab {
    grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
    gap: var(--s-6);
  }
}

.lab__figure {
  position: relative;
  border: 1px solid var(--line);
  border-radius: var(--r-3);
  background: var(--surface);
  box-shadow: var(--shadow-3);
  overflow: hidden;
  aspect-ratio: 16 / 10;
}

.lab__canvas {
  display: block;
  width: 100%;
  height: 100%;
}

.lab__fallback {
  padding: var(--s-5);
  color: var(--text-dim);
  font-size: var(--step--1);
}

.lab__fallback strong {
  color: var(--text);
  font-weight: 600;
}

.lab__panel {
  display: grid;
  gap: var(--s-4);
  align-content: start;
}

.lab__controls {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
}

.lab__status {
  margin: 0;
  padding: var(--s-3) var(--s-4);
  border: 1px solid var(--line);
  border-left: 2px solid var(--text-dim);
  border-radius: var(--r-1);
  background: var(--surface-2);
  font-family: var(--font-mono);
  font-size: var(--step--1);
  color: var(--text);
}

.lab__status[data-state="healthy"] {
  border-left-color: var(--lime);
}

.lab__status[data-state="degraded"] {
  border-left-color: var(--amber);
}

.lab__status[data-state="idle"] {
  border-left-color: var(--text-dim);
}

.lab__note {
  margin: 0;
  font-size: var(--step--2);
  color: var(--text-dim);
  line-height: 1.55;
}

.lab__figure-data {
  margin: var(--s-4) 0;
}

/* --- 11. Growth narrative (M7) ------------------------------------------ */

.growth {
  margin-top: var(--s-6);
  border: 1px solid var(--line);
  border-radius: var(--r-3);
  background: var(--surface);
  box-shadow: var(--shadow-3);
  /* clip, not hidden: hidden would create a scroll container and break the
     sticky stage inside. */
  overflow: clip;
  position: relative;
}

.growth__stage {
  display: grid;
  gap: var(--s-5);
  padding: var(--s-5);
}

@media (min-width: 62rem) {

  /* The narrative is scrubbed along a tall track. The stage sticks to the
     viewport, and the track reserves its height from the first paint, so
     locking the stage never moves anything on the page. */
  .growth {
    min-height: 220vh;
  }

  .growth__stage {
    position: sticky;
    top: 0;
    height: 100vh;
    align-content: center;
    grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr);
    gap: var(--s-6);
    padding: var(--s-6);
    align-items: center;
  }
}

.growth__figure {
  min-width: 0;
  border: 1px solid var(--line);
  border-radius: var(--r-2);
  background: var(--ink-2);
  padding: var(--s-3);
}

.growth__svg {
  display: block;
  width: 100%;
  height: auto;
}

.growth__lane-label {
  fill: var(--text-dim);
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.growth__seg {
  fill: var(--surface-2);
  stroke: var(--line-hi);
  stroke-width: 1;
}

.growth__seg--new {
  fill: rgba(198, 242, 78, 0.14);
  stroke: var(--lime);
}

.growth__seg--expert {
  fill: rgba(139, 123, 255, 0.16);
  stroke: var(--violet);
}

.growth__link {
  fill: none;
  stroke: var(--cyan);
  stroke-width: 1.4;
  stroke-linecap: round;
}

.growth__link--replica {
  stroke-dasharray: 5 5;
  opacity: 0.85;
}

.growth__link--depth {
  stroke: var(--lime);
}

.growth__link--expert {
  stroke: var(--violet);
}

.growth__node circle {
  fill: var(--surface-3);
  stroke: var(--cyan);
  stroke-width: 1.4;
}

.growth__node text {
  fill: var(--text-dim);
  font-family: var(--font-mono);
  font-size: 10px;
  text-anchor: middle;
}

.growth__node--new circle {
  stroke: var(--lime);
}

.growth__node--violet circle {
  stroke: var(--violet);
}

.growth__badge {
  fill: var(--cyan);
  font-family: var(--font-mono);
  font-size: 12px;
  text-anchor: middle;
}

.growth__steps {
  list-style: none;
  display: grid;
  gap: var(--s-3);
  counter-reset: growth;
}

.growth__step {
  position: relative;
  padding: var(--s-3) var(--s-4);
  border: 1px solid var(--line);
  border-radius: var(--r-1);
  background: var(--surface-2);
  overflow: hidden;
}

/* The active step is marked with a rule that grows, never with a lower
   opacity: the text of an inactive step stays readable and AA. */
.growth__step::before {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  width: 2px;
  background: var(--lime);
  transform: scaleY(0);
  transform-origin: top center;
  transition: transform 0.35s var(--e-out);
}

.growth__step[aria-current="step"]::before {
  transform: scaleY(1);
}

.growth__step-index {
  font-family: var(--font-mono);
  font-size: var(--step--2);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-dim);
}

.growth__action {
  font-family: var(--font-mono);
  font-size: var(--step-2);
  color: var(--lime);
  margin: 0.1rem 0 0.2rem;
}

.growth__node-line {
  font-family: var(--font-mono);
  font-size: var(--step--2);
  color: var(--cyan);
  font-variant-numeric: tabular-nums;
}

/* The two figures of a growth step share one grid, so the three steps stay
   vertically comparable while the reader scrubs them. */
.growth__figures {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--s-4);
  margin: var(--s-3) 0 var(--s-2);
  align-items: start;
}

.growth__note {
  margin-top: 0.35rem;
  font-size: var(--step--1);
  color: var(--text-dim);
  line-height: 1.5;
}

/* --- 12. Terminal blocks ------------------------------------------------- */

.terminal {
  margin-top: var(--s-4);
  border: 1px solid var(--line);
  border-radius: var(--r-2);
  background: var(--surface-2);
  box-shadow: var(--shadow-2);
  overflow: hidden;
}

.terminal__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-4);
  padding: 0.55rem 0.6rem 0.55rem var(--s-4);
  border-bottom: 1px solid var(--line);
  background: var(--surface-3);
}

.terminal__title {
  font-family: var(--font-mono);
  font-size: var(--step--2);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-dim);
}

.terminal__body {
  padding: var(--s-4);
  overflow-x: auto;
  color: var(--text);
  white-space: pre;
}

.terminal__foot {
  padding: 0 var(--s-4) var(--s-4);
  font-size: var(--step--2);
  color: var(--text-dim);
  line-height: 1.55;
}

.terminal__cursor {
  display: inline-block;
  width: 0.5em;
  height: 1em;
  margin-left: 0.1em;
  vertical-align: -0.15em;
  background: var(--lime);
  animation: terminal-blink 1s steps(2, end) infinite;
}

/* A terminal that carries a whole verification run and needs the width: it is
   the only block on the page that may break out of the prose measure, because
   wrapping the output of `verify.sh` would destroy the columns that make it
   readable. */
.terminal--wide {
  max-width: none;
  width: 100%;
}

@keyframes terminal-blink {

  0%,
  100% {
    opacity: 1;
  }

  50% {
    opacity: 0;
  }
}

/* --- 13. Steps ----------------------------------------------------------- */

.steps {
  margin-top: var(--s-4);
  padding-left: 1.5rem;
  display: grid;
  gap: 0.5rem;
  max-width: var(--measure);
  font-size: var(--step--1);
  color: var(--text-dim);
}

.steps li::marker {
  font-family: var(--font-mono);
  font-size: var(--step--2);
  color: var(--lime);
}

/* --- 14. Documentation links --------------------------------------------- */

.doclist__group {
  margin: var(--s-5) 0 var(--s-3);
  font-family: var(--font-mono);
  font-size: var(--figure-label);
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-dim);
}

.doclist__group:first-of-type {
  margin-top: 0;
}

.doclist {
  list-style: none;
  display: grid;
  gap: 0;
  border-top: 1px solid var(--line);
}

.doclist li {
  display: grid;
  gap: 0.15rem var(--s-4);
  padding: var(--s-3) 0;
  border-bottom: 1px solid var(--line);
}

@media (min-width: 48rem) {
  .doclist li {
    grid-template-columns: 16rem minmax(0, 1fr);
    align-items: baseline;
  }
}

.doclist a {
  position: relative;
  justify-self: start;
  color: var(--lime);
  text-decoration: none;
}

.doclist a:hover {
  color: var(--lime);
}

.doclist span {
  color: var(--text-dim);
  font-size: var(--step--1);
}

/* --- 15. Limitations ----------------------------------------------------- */

.limits {
  list-style: none;
  display: grid;
  gap: var(--s-3);
}

.limit-card {
  padding: var(--s-4);
  border: 1px solid var(--line);
  border-left: 2px solid var(--violet);
  border-radius: var(--r-2);
  background: var(--surface);
  box-shadow: var(--shadow-1);
}

.limit-card h3 {
  font-size: var(--step-2);
  margin-bottom: 0.35rem;
}

.limit-card p {
  color: var(--text-dim);
  font-size: var(--step--1);
  line-height: 1.55;
}

/* --- 16. Error page ------------------------------------------------------ */

.error__title {
  font-size: var(--step-5);
  letter-spacing: -0.02em;
  margin-bottom: var(--s-3);
}

/* --- 17. Footer ---------------------------------------------------------- */

.site-footer {
  border-top: 1px solid var(--line);
  background: var(--ink-2);
  padding-block: var(--s-6) var(--s-7);
  margin-top: var(--s-7);
}

.site-footer__inner {
  display: grid;
  gap: var(--s-3);
}

.site-footer__license {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  color: var(--text);
}

.site-footer__artifacts {
  max-width: 62ch;
  font-size: var(--step--1);
  color: var(--text-dim);
}

.site-footer__links ul {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem 1.25rem;
  list-style: none;
  font-size: var(--step--1);
}

.site-footer__note {
  font-size: var(--step--2);
  color: var(--text-dim);
}

/* --- 18. Copy confirmation ----------------------------------------------- */

.copy-toast {
  position: fixed;
  left: 50%;
  bottom: 1.5rem;
  z-index: var(--z-overlay);
  transform: translate(-50%, 1rem);
  padding: 0.45rem 0.9rem;
  border: 1px solid var(--lime);
  border-radius: var(--r-full);
  background: var(--ink-2);
  color: var(--text);
  font-family: var(--font-mono);
  font-size: var(--step--2);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--d-2) var(--e-out), transform var(--d-2) var(--e-out);
}

.copy-toast[data-visible="true"] {
  opacity: 1;
  transform: translate(-50%, 0);
}

/* --- 19. Motion ---------------------------------------------------------- */

/* M9 · hover micro-interactions.
   Pure CSS on purpose: a pointer that cannot hover never triggers them, and
   the reduced motion query removes every transition at once. */
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .pillar {
    position: relative;
    transition: transform var(--d-1) var(--e-out);
  }

  .pillar:hover {
    transform: translateY(-2px);
  }

  .pillar::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    height: 2px;
    background: var(--lime);
    transform: scaleX(0);
    transform-origin: 0 50%;
    transition: transform var(--d-1) var(--e-out);
  }

  .pillar:hover::after {
    transform: scaleX(1);
  }

  .doclist a::before {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: -4px;
    height: 1px;
    background: var(--lime);
    transform: scaleX(0);
    transform-origin: 0 50%;
    transition: transform var(--d-1) var(--e-out);
  }

  .doclist a:hover::before {
    transform: scaleX(1);
  }

  .doclist a::after {
    content: "→";
    display: inline-block;
    margin-left: 0.4em;
    transition: transform var(--d-1) var(--e-out);
  }

  .doclist a:hover::after {
    transform: translateX(3px);
  }
}

@media (prefers-reduced-motion: no-preference) {
  .js .hero__title {
    clip-path: inset(0 0 110% 0);
  }

  .js .hero__claim,
  .js .hero__sub,
  .js .hero__meta,
  .js .hero__actions {
    opacity: 0;
    transform: translateY(14px);
  }

  .js .pillar,
  .js .module-table,
  .js .lab,
  .js .terminal,
  .js .steps,
  .js .doclist li,
  .js .limit-card {
    opacity: 0;
    transform: translateY(20px);
  }

  /* The metrics band is deliberately not revealed: it is the second thing the
     reader lands on, and hiding it delays the largest paint of the page. */

  .js .growth__seg--new,
  .js .growth__link--replica,
  .js .growth__link--depth,
  .js .growth__link--expert,
  .js .growth__node--new,
  .js #growth-expert-lane,
  .js #growth-replica-badge {
    opacity: 0;
  }
}

@media (prefers-reduced-motion: reduce) {

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

@media (prefers-reduced-transparency: reduce) {
  .site-header {
    background: var(--ink-2);
    backdrop-filter: none;
  }
}

@media (forced-colors: active) {

  .pillar,
  .limit-card,
  .terminal,
  .module-table,
  .lab__figure,
  .growth,
  .growth__step {
    border: 1px solid CanvasText;
  }

  .growth__seg,
  .growth__node circle {
    fill: Canvas;
    stroke: CanvasText;
  }

  .growth__link {
    stroke: CanvasText;
  }

  .btn--primary {
    border: 1px solid CanvasText;
  }
}

/* --- 20. Input devices --------------------------------------------------- */

/* A finger needs 44px; the hero buttons were 34px tall and the theme buttons
   24px, which is below the minimum a thumb can hit reliably. A mouse does not
   need the extra height, so the rule is scoped to coarse pointers and the
   desktop density is left alone. */
@media (pointer: coarse) {
  .btn {
    min-height: 44px;
  }

  .theme-switch button {
    min-height: 40px;
    padding-inline: 0.6rem;
  }

  .primary-nav a {
    display: flex;
    align-items: center;
    min-height: 44px;
  }
}

/* A touch screen fires :hover on tap and keeps it until the next tap, so the
   lifted button and the growing underline stay stuck on a control the reader
   has already used. Where there is no hover, the interactive feedback is the
   :active state alone. */
@media (hover: none) {
  .btn:hover {
    transform: none;
    border-color: var(--line-hi);
    color: var(--text);
  }

  .btn--primary:hover {
    border-color: var(--lime);
    color: var(--ink);
    box-shadow: none;
  }

  .btn:active {
    border-color: var(--lime);
    color: var(--lime);
  }

  .btn--primary:active {
    color: var(--ink);
  }

  .primary-nav a:hover::after {
    transform: scaleX(0);
  }

  .primary-nav a:hover {
    color: var(--text-dim);
  }

  .primary-nav a[aria-current="true"] {
    color: var(--text);
  }
}