/* dmart website — one stylesheet for the generated site.
 *
 * Ported from the Svelte site that served dmart.cc (app.css, App.svelte,
 * Home.svelte, AuroraBackground.svelte and the docs pages), adapted to the
 * fixed HTML the generator emits: layout.html wraps every page, docs pages
 * are plain markdown inside <article class="prose">, and the landing page is
 * built from a small set of section kinds (cards, steps, figures, prose,
 * banner).
 *
 * Theme: the `dark` class on <html> (set by site.js before first paint from
 * localStorage or the OS setting). site.js also sets `light` when the choice
 * is light, so the prefers-color-scheme block below only applies when no
 * script has run at all.
 *
 * Contents
 *   1. Tokens (light, dark)          7. Footer
 *   2. Base                          8. Prose (docs + standalone pages)
 *   3. Aurora background             9. Landing: hero, buttons, stats
 *   4. Header                       10. Landing: bands, cards, figures,
 *   5. Page layouts                      steps, banner
 *   6. Docs sidebar + drawer        11. Responsive
 *                                   12. Colour: hues per card, step, stat
 *                                       and docs section
 *                                   13. Explainer (animated figure)
 */

/* ── 1. Tokens ─────────────────────────────────────────────────────────── */

:root {
  /* One deliberate violet. The iri-* ramp is a tight range of the same hue. */
  --primary-color: #4f46e5;
  --primary-hover: #4338ca;
  --secondary-color: #5d6478;

  /* Neutrals biased toward the brand hue rather than pure grey. */
  --bg-color: #ffffff;
  --bg-secondary: #f6f7fb;
  --text-main: #15161f;
  --text-secondary: #5d6478;
  --border-color: #e3e5ee;

  --code-bg: #f3f4f9;
  --accent-light: #eef0fe;

  /* Signal: reserved for MEASURED values and nothing else. */
  --signal: #8a5200;
  --signal-soft: #fbf1e2;

  --iri-1: #6366f1;
  --iri-2: #7c5cf5;
  --iri-3: #9b6bf0;
  --iri-4: #5b7cf8;
  --iri-5: #c9bdfb;

  --gradient-iri: linear-gradient(120deg, var(--iri-1) 0%, var(--iri-3) 100%);
  --gradient-iri-soft: linear-gradient(120deg, #f2f1fe 0%, #f7f5ff 100%);
  --gradient-iri-v: linear-gradient(180deg, var(--iri-1), var(--iri-3), var(--iri-4));
  --gradient-iri-h: linear-gradient(90deg, var(--iri-1), var(--iri-3), var(--iri-4));
  --gradient-hairline: linear-gradient(90deg, transparent, var(--border-color) 50%, transparent);
  --gradient-hairline-v: linear-gradient(180deg, transparent, var(--border-color) 50%, transparent);

  /* Hues: one per card, step, scene and docs section, cycled in order (see
     12. Colour). Dark enough for text on white; dark mode lifts them. */
  --hue-violet: #7c5cf5;
  --hue-indigo: #4f46e5;
  --hue-purple: #9333ea;
  --hue-sky: #0284c7;
  --hue-teal: #0d9488;
  --hue-emerald: #059669;
  --hue-amber: #d97706;
  --hue-rose: #e11d48;
  --hue-slate: #64748b;
  --gradient-spectrum: linear-gradient(100deg, var(--hue-indigo) 0%, var(--hue-violet) 30%, var(--hue-rose) 68%, var(--hue-amber) 100%);

  /* Explainer stage (13. Explainer). */
  --xp-stage: linear-gradient(135deg, #f4f2ff 0%, #eef5ff 52%, #ecfbf6 100%);
  --xp-surface: #ffffff;
  --xp-line: #d9dcea;
  --xp-ink: #15161f;
  --xp-dim: #6b7186;
  --xp-shadow: rgba(40, 30, 110, 0.10);

  /* Surfaces are opaque; no blur-behind. */
  --glass-bg: #ffffff;
  --glass-border: #e3e5ee;

  --radius-sm: 3px;
  --radius-md: 5px;
  --radius-lg: 10px;
  --radius-card: 14px;

  --nav-h: 64px;

  --shadow-sm: 0 1px 2px rgba(21, 22, 31, 0.05);
  --shadow-md: 0 1px 2px rgba(21, 22, 31, 0.05), 0 4px 14px rgba(21, 22, 31, 0.06);
  --shadow-lg: 0 2px 4px rgba(21, 22, 31, 0.05), 0 12px 32px rgba(21, 22, 31, 0.09);

  --header-bg: rgba(255, 255, 255, 0.72);
  --header-shadow: 0 1px 3px rgba(0, 0, 0, 0.06), 0 1px 2px rgba(0, 0, 0, 0.04);
  --scrim: rgba(0, 0, 0, 0.45);

  /* Aurora wash strength, per blob. */
  --aurora-1: 22%;
  --aurora-2: 16%;
  --aurora-3: 22%;

  /* Which glyph the theme toggle shows: the mode you would switch TO. */
  --theme-moon: inline;
  --theme-sun: none;

  /* Archivo for display, IBM Plex Sans for reading, IBM Plex Mono for
     anything numeric or literal. */
  --font-display: 'Archivo', 'Helvetica Neue', Arial, sans-serif;
  --font-sans: 'IBM Plex Sans', system-ui, -apple-system, sans-serif;
  --font-mono: 'IBM Plex Mono', ui-monospace, 'SF Mono', Menlo, monospace;

  font-family: var(--font-sans);
  font-feature-settings: "ss01", "cv11";
  line-height: 1.6;
  font-weight: 400;

  color-scheme: light;
  color: var(--text-main);
  background-color: var(--bg-color);

  font-synthesis: none;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

:root.dark {
  --primary-color: #9d94ff;
  --primary-hover: #b8b1ff;
  --secondary-color: #9096ad;

  --bg-color: #0d0e15;
  --bg-secondary: #14161f;
  --text-main: #e7e9f2;
  --text-secondary: #9096ad;
  --border-color: #262a39;

  --code-bg: #171a25;
  --accent-light: #1b1a3a;
  --signal: #d59a4a;
  --signal-soft: #2a2114;

  --iri-1: #8b8cf8;
  --iri-2: #9d94ff;
  --iri-3: #b08bf5;
  --iri-4: #7f9bff;
  --iri-5: #cdc4fb;
  --gradient-iri-soft: linear-gradient(120deg, #17172b 0%, #1b1a32 100%);
  --glass-bg: #14161f;
  --glass-border: #262a39;

  --hue-violet: #a594ff;
  --hue-indigo: #818cf8;
  --hue-purple: #c084fc;
  --hue-sky: #38bdf8;
  --hue-teal: #2dd4bf;
  --hue-emerald: #34d399;
  --hue-amber: #fbbf24;
  --hue-rose: #fb7185;
  --hue-slate: #94a3b8;

  --xp-stage: linear-gradient(135deg, #16142b 0%, #101a2b 52%, #0f2124 100%);
  --xp-surface: #1a1c29;
  --xp-line: #2e3246;
  --xp-ink: #e7e9f2;
  --xp-dim: #9096ad;
  --xp-shadow: rgba(0, 0, 0, 0.40);

  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.2), 0 1px 3px rgba(0, 0, 0, 0.3);
  --shadow-md: 0 2px 4px rgba(0, 0, 0, 0.2), 0 4px 12px rgba(0, 0, 0, 0.3);
  --shadow-lg: 0 4px 8px rgba(0, 0, 0, 0.2), 0 8px 24px rgba(0, 0, 0, 0.4);

  --header-bg: rgba(15, 15, 26, 0.85);
  --header-shadow: 0 1px 3px rgba(0, 0, 0, 0.3), 0 1px 2px rgba(0, 0, 0, 0.2);
  --scrim: rgba(0, 0, 0, 0.6);

  --aurora-1: 28%;
  --aurora-2: 22%;
  --aurora-3: 18%;

  --theme-moon: none;
  --theme-sun: inline;

  color-scheme: dark;
}

/* Scripts disabled: follow the OS. Identical to the block above. */
@media (prefers-color-scheme: dark) {
  :root:not(.light):not(.dark) {
    --primary-color: #9d94ff;
    --primary-hover: #b8b1ff;
    --secondary-color: #9096ad;

    --bg-color: #0d0e15;
    --bg-secondary: #14161f;
    --text-main: #e7e9f2;
    --text-secondary: #9096ad;
    --border-color: #262a39;

    --code-bg: #171a25;
    --accent-light: #1b1a3a;
    --signal: #d59a4a;
    --signal-soft: #2a2114;

    --iri-1: #8b8cf8;
    --iri-2: #9d94ff;
    --iri-3: #b08bf5;
    --iri-4: #7f9bff;
    --iri-5: #cdc4fb;
    --gradient-iri-soft: linear-gradient(120deg, #17172b 0%, #1b1a32 100%);
    --glass-bg: #14161f;
    --glass-border: #262a39;

    --hue-violet: #a594ff;
    --hue-indigo: #818cf8;
    --hue-purple: #c084fc;
    --hue-sky: #38bdf8;
    --hue-teal: #2dd4bf;
    --hue-emerald: #34d399;
    --hue-amber: #fbbf24;
    --hue-rose: #fb7185;
    --hue-slate: #94a3b8;

    --xp-stage: linear-gradient(135deg, #16142b 0%, #101a2b 52%, #0f2124 100%);
    --xp-surface: #1a1c29;
    --xp-line: #2e3246;
    --xp-ink: #e7e9f2;
    --xp-dim: #9096ad;
    --xp-shadow: rgba(0, 0, 0, 0.40);

    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.2), 0 1px 3px rgba(0, 0, 0, 0.3);
    --shadow-md: 0 2px 4px rgba(0, 0, 0, 0.2), 0 4px 12px rgba(0, 0, 0, 0.3);
    --shadow-lg: 0 4px 8px rgba(0, 0, 0, 0.2), 0 8px 24px rgba(0, 0, 0, 0.4);

    --header-bg: rgba(15, 15, 26, 0.85);
    --header-shadow: 0 1px 3px rgba(0, 0, 0, 0.3), 0 1px 2px rgba(0, 0, 0, 0.2);
    --scrim: rgba(0, 0, 0, 0.6);

    --aurora-1: 28%;
    --aurora-2: 22%;
    --aurora-3: 18%;

    --theme-moon: none;
    --theme-sun: inline;

    color-scheme: dark;
  }
}

/* ── 2. Base ───────────────────────────────────────────────────────────── */

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

html {
  overflow-x: hidden;
}

@supports (overflow: clip) {
  html {
    overflow-x: clip;
  }
}

body {
  margin: 0;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background-color: var(--bg-color);
  color: var(--text-main);
}

h1, h2, h3, h4, h5, h6 {
  font-family: var(--font-display);
  line-height: 1.15;
  margin-top: 0;
  color: var(--text-main);
  letter-spacing: -0.015em;
  text-wrap: balance;
}

h1 { font-size: 2.6rem; font-weight: 700; margin-bottom: 1.5rem; }
h2 { font-size: 2rem; font-weight: 600; margin-bottom: 1.25rem; }
h3 { font-size: 1.5rem; font-weight: 600; margin-bottom: 1rem; }

p {
  margin-top: 0;
  margin-bottom: 1.5rem;
  color: var(--text-secondary);
}

a {
  color: var(--primary-color);
  text-decoration: none;
  transition: color 0.2s;
}

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

button {
  font: inherit;
  color: inherit;
}

:focus-visible {
  outline: 2px solid var(--primary-color);
  outline-offset: 2px;
}

main:focus {
  outline: none;
}

[hidden] {
  display: none !important;
}

.skip-link {
  position: absolute;
  left: 1rem;
  top: -100px;
  z-index: 1000;
  padding: 0.6rem 1rem;
  border-radius: var(--radius-md);
  background: var(--text-main);
  color: var(--bg-color);
  font-weight: 600;
  font-size: 0.9rem;
}

.skip-link:focus {
  top: 0.75rem;
  color: var(--bg-color);
}

/* Off-screen buffer site.js uses for the execCommand copy fallback. */
.copy-buffer {
  position: fixed;
  top: 0;
  left: -9999px;
  opacity: 0;
}

/* ── 3. Aurora background ──────────────────────────────────────────────────
   Three soft washes behind everything — violet, sky and rose — static (no
   animation), as plain gradients on one fixed layer. Each stop mirrors a
   blurred blob of the old component: same centre, same reach, same per-theme
   strength. */

.aurora {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background-image:
    radial-gradient(circle 32vw at 17.5% calc(27.5vw - 20%),
      color-mix(in srgb, var(--iri-1) var(--aurora-1), transparent) 0%,
      transparent 100%),
    radial-gradient(circle 35vw at 85% calc(30vw + 10%),
      color-mix(in srgb, var(--hue-sky) var(--aurora-2), transparent) 0%,
      transparent 100%),
    radial-gradient(circle 38vw at 42.5% calc(125% - 32.5vw),
      color-mix(in srgb, var(--hue-rose) var(--aurora-3), transparent) 0%,
      transparent 100%);
}

/* ── 4. Header ─────────────────────────────────────────────────────────── */

.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  padding: 0.75rem 0;
  background: var(--header-bg);
  box-shadow: var(--header-shadow);
  border-bottom: 1px solid transparent;
  border-image: var(--gradient-hairline) 1;
}

.header-inner {
  max-width: 1200px;
  margin: 0 auto;
  padding: 0 2rem;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
}

.brand {
  margin-right: auto;
  font-family: var(--font-display);
  font-size: 1.5rem;
  font-weight: 800;
  line-height: 1.6;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--iri-2);
  transition: filter 0.3s ease;
}

.brand:hover {
  color: var(--iri-2);
  filter: brightness(1.12) saturate(1.1);
}

.header-nav {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
}

.header-link {
  display: inline-block;
  padding: 0.5rem 0.75rem;
  font-size: 0.95rem;
  font-weight: 500;
  line-height: normal;
  color: var(--text-secondary);
  border-bottom: 2px solid transparent;
  border-radius: var(--radius-sm);
  white-space: nowrap;
  transition: color 0.2s ease, border-color 0.2s ease;
}

.header-link:hover,
.header-link[aria-current="page"] {
  color: var(--primary-color);
  border-image: var(--gradient-iri-h) 1;
}

.header-link[aria-current="page"] {
  font-weight: 600;
}

.theme-toggle,
.nav-toggle {
  display: none;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  margin: 0;
  border: 1px solid var(--border-color);
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--text-main);
  line-height: normal;
  cursor: pointer;
  transition: border-color 0.2s ease, background-color 0.2s ease, color 0.2s ease;
}

.theme-toggle:hover,
.nav-toggle:hover {
  border-color: var(--primary-color);
  background: var(--accent-light);
}

.nav-toggle:hover {
  color: var(--primary-color);
}

.theme-toggle:active,
.nav-toggle:active {
  transform: translateY(1px);
}

/* The toggle only works with script, so it only appears with script. */
html.js .theme-toggle {
  display: inline-flex;
  margin-left: 0.75rem;
  padding: 0.35rem 0.55rem;
  font-size: 1.15rem;
}

.theme-icon-moon { display: var(--theme-moon); }
.theme-icon-sun { display: var(--theme-sun); }

.nav-toggle {
  padding: 0.4rem 0.7rem;
  font-size: 0.9rem;
  font-weight: 600;
}

.nav-toggle[aria-expanded="true"] {
  border-color: var(--primary-color);
  color: var(--primary-color);
}

/* ── 5. Page layouts ───────────────────────────────────────────────────── */

.layout {
  flex: 1 0 auto;
  width: 100%;
  min-width: 0;
}

.content {
  display: block;
  min-width: 0;
  color: var(--text-main);
}

/* Docs: one opaque panel hanging off the header's hairline, split into a
   sidebar column and the article. */
.page-doc .layout {
  display: grid;
  grid-template-columns: 250px minmax(0, 1fr);
  max-width: 1200px;
  margin: 0 auto;
  min-height: 80vh;
  background: var(--glass-bg);
  border: 1px solid var(--glass-border);
  border-top: none;
  border-radius: 0 0 var(--radius-lg) var(--radius-lg);
}

.page-doc .content {
  padding: 3rem 2.5rem;
}

/* Standalone pages (Features, Why, 404): the same panel, no sidebar. */
.page-standalone .layout {
  max-width: 960px;
  margin: 0 auto;
  min-height: 80vh;
  padding: 3.5rem 2.5rem;
  background: var(--glass-bg);
  border: 1px solid var(--glass-border);
  border-top: none;
  border-radius: 0 0 var(--radius-lg) var(--radius-lg);
}

/* ── 6. Docs sidebar + drawer ──────────────────────────────────────────── */

.sidebar {
  min-width: 0;
  border-right: 1px solid transparent;
  border-image: var(--gradient-hairline-v) 1;
}

.sidebar-nav {
  position: sticky;
  top: var(--nav-h);
  max-height: calc(100vh - var(--nav-h));
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 2rem 1rem 2.5rem;
}

.nav-group + .nav-group {
  margin-top: 1.5rem;
}

.nav-group-title {
  margin: 0 0 0.35rem 0.8rem;
  font-size: 0.72rem;
  font-weight: 700;
  line-height: 1.6;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-secondary);
}

.nav-links {
  list-style: none;
  margin: 0;
  padding: 0;
}

.nav-links a {
  position: relative;
  display: block;
  padding: 0.45rem 0.8rem;
  font-size: 0.9rem;
  line-height: 1.6;
  color: var(--text-secondary);
  border-radius: var(--radius-sm);
}

/* Mirrors the article h1's violet left bar. */
.nav-links a::before {
  content: "";
  position: absolute;
  left: 0;
  top: 6px;
  bottom: 6px;
  width: 3px;
  border-radius: 2px;
  background: var(--gradient-iri-v);
  opacity: 0;
}

.nav-links a:hover,
.nav-links a[aria-current="page"] {
  background: var(--accent-light);
  color: var(--primary-color);
}

.nav-links a[aria-current="page"] {
  font-weight: 600;
}

.nav-links a[aria-current="page"]::before {
  opacity: 1;
}

.nav-scrim {
  position: fixed;
  inset: 0;
  z-index: 250;
  background: var(--scrim);
}

@media (prefers-reduced-motion: no-preference) {
  .nav-links a {
    transition: background-color 0.15s ease, color 0.15s ease;
  }
  .nav-links a::before {
    transition: opacity 0.18s ease;
  }
}

/* ── 7. Footer ─────────────────────────────────────────────────────────── */

.site-footer {
  margin-top: auto;
  padding: 1.5rem 1rem;
  text-align: center;
  font-size: 0.85rem;
  color: var(--text-secondary);
  border-top: 1px solid transparent;
  border-image: var(--gradient-hairline) 1;
}

.site-footer p {
  margin: 0;
  line-height: 1.6;
  color: var(--text-secondary);
}

.site-footer p + p {
  margin-top: 0.4rem;
}

.site-footer a {
  color: var(--text-secondary);
}

.site-footer a:hover {
  color: var(--primary-color);
}

/* ── 8. Prose ──────────────────────────────────────────────────────────────
   Generic markdown output, styled the way the hand-written docs pages
   looked. The old pages boxed each h2 section in its own card; markdown has
   no wrapper to hang that on, so sections are separated by a hairline above
   each h2 instead. */

.prose {
  color: var(--text-main);
  overflow-wrap: break-word;
}

.prose > :first-child {
  margin-top: 0;
}

.prose > :last-child {
  margin-bottom: 0;
}

.prose [id] {
  scroll-margin-top: calc(var(--nav-h) + 1rem);
}

.prose h1 {
  font-size: 2rem;
  margin-bottom: 1.5rem;
  padding-left: 1rem;
  border-left: 4px solid transparent;
  border-image: var(--gradient-iri-v) 1;
}

/* A paragraph straight after the title is the page's lede. */
.prose > h1 + p {
  font-size: 1.05rem;
  line-height: 1.7;
  margin-bottom: 2.5rem;
}

.prose h2 {
  font-size: 1.5rem;
  margin: 3rem 0 1rem;
  padding-top: 2.25rem;
  border-top: 1px solid transparent;
  border-image: var(--gradient-hairline) 1;
}

.prose > h1 + h2,
.prose > h2:first-child {
  margin-top: 0;
  padding-top: 0;
  border-top: none;
}

.prose h3 {
  width: fit-content;
  max-width: 100%;
  font-size: 1.1rem;
  margin: 2rem 0 1rem;
  padding-bottom: 0.2rem;
  letter-spacing: 0.5px;
  border-bottom: 2px solid transparent;
  border-image: var(--gradient-iri-h) 1;
}

.prose h2 + h3 {
  margin-top: 1.25rem;
}

.prose h4 {
  font-size: 0.95rem;
  margin: 1.5rem 0 0.6rem;
  letter-spacing: 0.5px;
}

.prose h5,
.prose h6 {
  font-size: 0.85rem;
  margin: 1.25rem 0 0.5rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.prose h6 {
  color: var(--text-secondary);
}

.prose p {
  margin: 0 0 1rem;
  line-height: 1.6;
}

.prose a {
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.18em;
  text-decoration-color: color-mix(in srgb, currentColor 35%, transparent);
}

.prose a:hover {
  text-decoration-color: currentColor;
}

.prose strong,
.prose b {
  color: var(--text-main);
  font-weight: 700;
}

.prose em,
.prose i {
  font-style: italic;
  font-synthesis: style;
}

.prose ul,
.prose ol {
  margin: 0 0 1rem;
  padding-left: 1.2rem;
}

.prose ul {
  list-style-type: disc;
}

.prose li {
  margin-bottom: 0.5rem;
  color: var(--text-secondary);
  line-height: 1.5;
}

.prose li::marker {
  color: var(--text-secondary);
}

.prose li > p {
  margin: 0 0 0.5rem;
}

.prose li > :last-child {
  margin-bottom: 0;
}

.prose li > ul,
.prose li > ol {
  margin-top: 0.5rem;
  margin-bottom: 0.5rem;
}

/* GitHub-style task lists. */
.prose .contains-task-list,
.prose ul:has(> li > input[type="checkbox"]) {
  list-style: none;
  padding-left: 0.25rem;
}

.prose .task-list-item input[type="checkbox"],
.prose li > input[type="checkbox"] {
  margin: 0 0.55rem 0 0;
  vertical-align: -0.1em;
  accent-color: var(--iri-2);
}

.prose blockquote {
  margin: 1.5rem 0;
  padding: 0.9rem 1.25rem;
  background: var(--gradient-iri-soft);
  border: 1px solid var(--glass-border);
  border-left: 3px solid var(--iri-2);
  border-radius: var(--radius-md);
}

.prose blockquote p,
.prose blockquote li {
  color: var(--text-main);
}

.prose blockquote > :last-child {
  margin-bottom: 0;
}

.prose hr {
  height: 1px;
  margin: 2.5rem 0;
  border: 0;
  background: var(--gradient-hairline);
}

.prose img {
  max-width: 100%;
  height: auto;
  border-radius: var(--radius-md);
}

.prose dl {
  margin: 0 0 1rem;
}

.prose dt {
  font-weight: 600;
  color: var(--text-main);
}

.prose dd {
  margin: 0 0 0.75rem 1.2rem;
  color: var(--text-secondary);
}

.prose kbd {
  font-family: var(--font-mono);
  font-size: 0.8em;
  padding: 0.1rem 0.4rem;
  border: 1px solid var(--border-color);
  border-bottom-width: 2px;
  border-radius: var(--radius-sm);
  background: var(--bg-secondary);
  color: var(--text-main);
}

/* Inline code. */
.prose code {
  font-family: var(--font-mono);
  font-size: 0.85em;
  padding: 0.15rem 0.4rem;
  border: 1px solid var(--border-color);
  border-radius: var(--radius-sm);
  background: var(--code-bg);
  color: var(--text-main);
}

.prose h1 code,
.prose h2 code,
.prose h3 code,
.prose h4 code {
  font-size: 0.8em;
}

/* Code blocks. */
.prose pre {
  margin: 1rem 0 1.5rem;
  padding: 1.25rem;
  overflow-x: auto;
  background: var(--code-bg);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-md);
  -webkit-overflow-scrolling: touch;
}

.prose pre code {
  display: block;
  padding: 0;
  border: none;
  border-radius: 0;
  background: transparent;
  font-size: 0.8rem;
  line-height: 1.6;
  white-space: pre;
  overflow-wrap: normal;
  color: var(--text-main);
  tab-size: 4;
}

/* site.js wraps each block to pin a copy button outside the scroller. */
.code-block {
  position: relative;
  margin: 1rem 0 1.5rem;
}

.code-block > pre {
  margin: 0;
}

.copy-button {
  position: absolute;
  top: 0.5rem;
  right: 0.5rem;
  padding: 0.3rem 0.55rem;
  font-family: var(--font-sans);
  font-size: 0.68rem;
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-secondary);
  background: var(--bg-color);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-sm);
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

.code-block:hover .copy-button,
.copy-button:focus-visible,
.copy-button.copied {
  opacity: 1;
}

.copy-button:hover,
.copy-button.copied {
  color: var(--primary-color);
  border-color: var(--primary-color);
}

@media (hover: none) {
  .copy-button {
    opacity: 1;
  }
}

/* Tables scroll inside their own wrapper, never the page. */
.table-wrap {
  margin: 1rem 0 1.5rem;
  overflow-x: auto;
  border: 1px solid var(--border-color);
  border-radius: var(--radius-md);
  -webkit-overflow-scrolling: touch;
}

.prose table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.85rem;
}

.prose thead {
  background: var(--gradient-iri-soft);
}

.prose th {
  padding: 0.75rem 1rem;
  text-align: left;
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  color: var(--text-main);
  border-bottom: 2px solid var(--border-color);
  vertical-align: bottom;
}

.prose td {
  padding: 0.75rem 1rem;
  color: var(--text-secondary);
  border-bottom: 1px solid var(--border-color);
  vertical-align: top;
  line-height: 1.5;
}

.prose tbody tr:last-child td {
  border-bottom: none;
}

.prose td code,
.prose th code {
  font-size: 0.8em;
  white-space: nowrap;
}

/* Mermaid: the bordered diagram panel of the old pages. Until a diagram has
   rendered its source is hidden so the page does not flash a wall of text;
   if it cannot render (no mermaid, syntax error, scripts off) the source is
   shown instead. */
.prose pre.mermaid,
pre.mermaid {
  margin: 1.5rem 0;
  padding: 1rem;
  overflow-x: auto;
  text-align: center;
  font-family: var(--font-mono);
  font-size: 0.8rem;
  line-height: 1.6;
  white-space: pre;
  color: var(--text-main);
  background: var(--bg-color);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-lg);
}

pre.mermaid.mermaid-source {
  text-align: left;
}

html.js pre.mermaid:not([data-processed]):not(.mermaid-source),
pre.mermaid.mermaid-pending {
  color: transparent;
}

pre.mermaid svg {
  max-width: 100%;
  height: auto;
}

/* 404 */
.prose.not-found {
  padding: 3rem 0;
  text-align: center;
}

.prose.not-found h1 {
  padding-left: 0;
  border-left: none;
  font-size: 3rem;
}

/* ── 9. Landing: hero, buttons, stats ──────────────────────────────────── */

.hero {
  max-width: 1200px;
  margin: 0 auto;
  padding: 6rem 2rem 3rem;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 4rem;
}

.hero-inner {
  flex: 1;
  min-width: 0;
  max-width: 540px;
}

.hero-badge {
  display: inline-block;
  margin: 0 0 1.5rem;
  padding: 0.3rem 1rem;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 3px;
  text-transform: uppercase;
  color: var(--primary-color);
  background: var(--gradient-iri-soft);
  border: 1px solid var(--glass-border);
  border-radius: 100px;
  box-shadow: 0 1px 2px rgba(139, 92, 246, 0.08);
}

.hero-title {
  margin: 0 0 1.5rem;
  font-size: 5rem;
  font-weight: 900;
  line-height: 0.95;
  letter-spacing: -3px;
}

.hero-title-line {
  display: block;
}

.hero-title-line.accent,
.band-banner .accent {
  background: var(--gradient-iri);
  background-size: 220% 220%;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.hero-subtitle {
  max-width: 420px;
  margin: 0 0 2rem;
  font-size: 1.1rem;
  line-height: 1.8;
  color: var(--text-secondary);
}

.hero-figure {
  flex-shrink: 0;
  width: 380px;
  max-width: 100%;
}

.hero-figure svg {
  display: block;
  width: 100%;
  height: auto;
}

/* Architecture figure (figures/architecture.svg). One stroke weight, one type
   size, three roles distinguished by fill: clients and store are outlines,
   the engine is the filled object, the index sits between them. */
.hf rect {
  fill: var(--bg-color);
  stroke: var(--border-color);
  stroke-width: 1;
}

.hf .hf-engine > rect {
  fill: var(--accent-light);
  stroke: var(--iri-2);
}

.hf .hf-chip rect {
  fill: var(--bg-color);
  stroke: var(--border-color);
}

.hf .hf-index rect {
  fill: var(--bg-secondary);
}

.hf text {
  font-family: var(--font-mono);
  font-size: 8.5px;
  fill: var(--text-secondary);
  text-anchor: middle;
}

.hf .hf-clients text,
.hf .hf-chip text {
  fill: var(--text-main);
}

.hf .hf-title {
  text-anchor: start;
  font-family: var(--font-display);
  font-size: 10px;
  font-weight: 600;
  fill: var(--text-main);
}

.hf .hf-store text:not(.hf-title),
.hf .hf-index text:not(.hf-title) {
  text-anchor: start;
}

.hf .hf-wire path {
  fill: none;
  stroke: var(--border-color);
  stroke-width: 1;
}

.hf .hf-edge {
  font-size: 7.5px;
  fill: var(--text-secondary);
}

/* Action rows (hero, sections, banner). */
.actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1rem;
}

.btn {
  display: inline-block;
  padding: 0.7rem 1.8rem;
  font-family: var(--font-sans);
  font-size: 0.9rem;
  font-weight: 600;
  line-height: normal;
  letter-spacing: 1px;
  text-align: center;
  border-radius: 6px;
  cursor: pointer;
}

.btn:active {
  transform: translateY(1px);
}

.btn-primary {
  color: #fff;
  font-weight: 700;
  border-radius: 8px;
  background: var(--gradient-iri);
  background-size: 160% 160%;
  background-position: 0% 50%;
  box-shadow: 0 4px 14px -4px rgba(139, 92, 246, 0.55);
  transition: background-position 0.4s ease, box-shadow 0.2s ease, transform 0.15s ease;
}

.btn-primary:hover {
  color: #fff;
  background-position: 100% 50%;
  box-shadow: 0 6px 20px -4px rgba(217, 70, 239, 0.55);
  transform: translateY(-1px);
}

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

.btn-secondary {
  color: var(--primary-color);
  background: transparent;
  border: 1px solid var(--primary-color);
  transition: background-color 0.2s, color 0.2s;
}

.btn-secondary:hover {
  color: #fff;
  background-color: var(--primary-color);
}

.btn-link {
  padding: 0;
  font-size: 0.85rem;
  line-height: 1.6;
  font-weight: 700;
  text-transform: uppercase;
  color: var(--text-secondary);
  border-radius: 0;
  transition: color 0.2s;
}

.btn-link:hover {
  color: var(--primary-color);
}

.btn-link:active {
  transform: none;
}

/* Stats strip. */
.stats {
  background: var(--gradient-iri-soft);
  border-top: 1px solid transparent;
  border-bottom: 1px solid transparent;
  border-image: var(--gradient-hairline) 1;
}

.stats-inner {
  max-width: 1200px;
  margin: 0 auto;
  padding: 0;
  list-style: none;
  display: flex;
  align-items: center;
  justify-content: center;
}

.stat {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.25rem;
  padding: 2.5rem 3rem;
  text-align: center;
}

.stat + .stat::before {
  content: "";
  position: absolute;
  left: 0;
  top: 50%;
  width: 1px;
  height: 3rem;
  margin-top: -1.5rem;
  background: var(--gradient-hairline-v);
}

.stat-value {
  font-size: 1.8rem;
  font-weight: 900;
  letter-spacing: -1px;
  white-space: nowrap;
  background: var(--gradient-iri);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.stat-label {
  font-size: 0.7rem;
  letter-spacing: 2px;
  text-transform: uppercase;
  color: var(--text-secondary);
}

/* ── 10. Landing: bands ────────────────────────────────────────────────── */

.band {
  max-width: 1200px;
  margin: 0 auto;
  padding: 4rem 2rem;
}

.section-title {
  margin: 0 0 3rem;
  font-size: 1.5rem;
  font-weight: 700;
  text-align: center;
  text-transform: uppercase;
  letter-spacing: 3px;
  color: var(--text-main);
}

.section-body {
  max-width: 720px;
  margin: -1.5rem auto 2.5rem;
  text-align: center;
}

.section-body > :last-child {
  margin-bottom: 0;
}

.band > .actions {
  justify-content: center;
  margin-top: 2.5rem;
}

/* Prose band: free text under a section title. */
.band-prose .section-body {
  margin-top: 0;
  text-align: left;
}

/* After the steps, bands are divided by a hairline, as on the old page. */
.band-steps,
.band-steps + .band:not(.band-banner) {
  border-top: 1px solid transparent;
  border-image: var(--gradient-hairline) 1;
}

/* ── Cards ── */

.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
  gap: 1.5rem;
}

/* Column counts by item count, so four tiles sit in one row, not 3 + 1. */
.cards:has(> :nth-child(2):last-child) { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.cards:has(> :nth-child(3):last-child) { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.cards:has(> :nth-child(4):last-child) { grid-template-columns: repeat(4, minmax(0, 1fr)); }

/* Linked card: the pillar tile. */
a.card {
  position: relative;
  isolation: isolate;
  display: flex;
  flex-direction: column;
  padding: 2rem;
  color: inherit;
  background: var(--glass-bg);
  border: 1px solid var(--glass-border);
  border-radius: var(--radius-card);
  transition: box-shadow 0.25s ease, transform 0.25s ease, border-color 0.25s ease;
}

/* Violet ring that fades in on hover. */
a.card::before {
  content: "";
  position: absolute;
  inset: -1px;
  padding: 1px;
  border-radius: inherit;
  background: conic-gradient(from 0deg, var(--iri-1), var(--iri-3), var(--iri-4), var(--iri-1));
  -webkit-mask: linear-gradient(#000, #000) content-box, linear-gradient(#000, #000);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000, #000) content-box, linear-gradient(#000, #000);
  mask-composite: exclude;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s ease;
}

a.card:hover {
  color: inherit;
  box-shadow: 0 12px 30px -12px rgba(139, 92, 246, 0.4), var(--shadow-md);
  transform: translateY(-3px);
}

a.card:hover::before {
  opacity: 1;
}

a.card:focus-visible {
  outline: 2px solid var(--iri-2);
  outline-offset: 3px;
}

.card-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 34px;
  height: 34px;
  margin-bottom: 1.1rem;
  color: var(--iri-2);
  background: var(--bg-color);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-md);
  transition: border-color 0.2s ease;
}

.card-icon svg {
  display: block;
  width: 18px;
  height: 18px;
}

a.card:hover .card-icon {
  border-color: var(--iri-2);
}

.card-title {
  margin: 0 0 0.5rem;
  font-size: 1rem;
  letter-spacing: 1px;
  text-transform: uppercase;
}

.card-body {
  flex: 1;
  margin: 0 0 1rem;
  font-size: 0.85rem;
  line-height: 1.5;
  color: var(--text-secondary);
}

.card-body p {
  margin: 0;
  color: inherit;
}

.card-body p + p {
  margin-top: 0.5rem;
}

.card-arrow {
  font-size: 1.2rem;
  line-height: 1.6;
  color: var(--text-secondary);
  transition: transform 0.2s, color 0.2s;
}

a.card:hover .card-arrow {
  transform: translateX(4px);
  color: var(--primary-color);
}

/* Unlinked cards: one panel split by hairlines, with a mono eyebrow for a
   title (the "Your Data Stays Yours" look). */
.band-cards:has(> .cards > div.card) {
  max-width: 1100px;
  padding: 4.5rem 1.5rem 0;
}

.cards:has(> div.card) {
  gap: 1px;
  background: var(--border-color);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-lg);
  overflow: hidden;
}

div.card {
  display: flex;
  flex-direction: column;
  padding: 1.6rem 1.5rem;
  background: var(--bg-color);
}

div.card .card-title {
  margin: 0 0 0.6rem;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  font-weight: 400;
  line-height: 1.6;
  letter-spacing: 0.1em;
  color: var(--iri-2);
}

div.card .card-body {
  margin: 0;
  font-size: 0.93rem;
  line-height: 1.6;
}

div.card .card-icon {
  margin-bottom: 0.9rem;
}

/* The Explore section: two wide cards per row, icon and arrow on one line,
   a violet edge that draws in on hover. Keyed on the section id so other
   card sections keep the tile look. */
#explore .cards {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

#explore a.card {
  display: grid;
  grid-template-columns: auto 1fr;
  grid-template-rows: auto auto 1fr;
  grid-template-areas:
    "icon arrow"
    "title title"
    "body body";
  align-items: center;
  overflow: hidden;
}

#explore a.card::before {
  display: none;
}

#explore a.card::after {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 3px;
  background: var(--gradient-iri);
  transform: scaleY(0);
  transform-origin: top;
  transition: transform 0.3s ease;
}

#explore a.card:hover {
  border-color: transparent;
  box-shadow: 0 10px 28px -12px rgba(139, 92, 246, 0.35), var(--shadow-md);
}

#explore a.card:hover::after {
  transform: scaleY(1);
}

#explore .card-icon {
  grid-area: icon;
  margin-bottom: 1rem;
}

#explore .card-arrow {
  grid-area: arrow;
  justify-self: end;
  margin-bottom: 1rem;
}

#explore .card-title {
  grid-area: title;
  font-size: 1.2rem;
  letter-spacing: -0.015em;
  text-transform: none;
}

#explore .card-body {
  grid-area: body;
  align-self: start;
  margin: 0;
  font-size: 0.9rem;
}

/* ── Figures: a lede, a paragraph, and a column of measured values. ── */

.band-figures {
  max-width: 1100px;
  padding: 4.5rem 1.5rem 0;
}

.figures-grid {
  display: grid;
  grid-template-columns: 1.35fr 1fr;
  gap: 3rem;
  align-items: start;
}

.figures-main p {
  max-width: 58ch;
  margin: 0 0 1rem;
  color: var(--text-secondary);
}

.figures-main p:last-child {
  margin-bottom: 0;
}

.figures-main > p:first-child {
  max-width: none;
  font-size: 1.15rem;
  line-height: 1.55;
  color: var(--text-main);
}

.figures-main strong {
  color: inherit;
}

.figures {
  display: flex;
  flex-direction: column;
  margin: 0;
  border-top: 1px solid var(--border-color);
}

.figure {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.85rem 0;
  border-bottom: 1px solid var(--border-color);
}

/* Signal colour, used here and nowhere else: these values came off an
   instrument, not a marketing deck. */
.figure dt {
  font-family: var(--font-mono);
  font-size: 1.35rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  color: var(--signal);
}

.figure dd {
  max-width: 22ch;
  margin: 0;
  font-size: 0.85rem;
  text-align: right;
  color: var(--text-secondary);
}

.figure dd p {
  margin: 0;
  color: inherit;
}

/* ── Steps ── */

.band-steps {
  max-width: 800px;
}

.steps {
  display: flex;
  flex-direction: column;
  margin: 0;
  padding: 0;
  list-style: none;
}

.step {
  display: flex;
  align-items: flex-start;
  gap: 2rem;
  padding: 1.5rem 0;
  border-bottom: 1px solid transparent;
  border-image: var(--gradient-hairline) 1;
}

.step:last-child {
  border-bottom: none;
}

.step-num {
  min-width: 3rem;
  font-size: 2.2rem;
  font-weight: 900;
  line-height: 1;
  letter-spacing: -1px;
  background: var(--gradient-iri);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  opacity: 0.55;
}

.step-content {
  min-width: 0;
}

.step-title {
  margin: 0 0 0.3rem;
  font-size: 1rem;
}

.step-body {
  font-size: 0.9rem;
  line-height: 1.5;
  color: var(--text-secondary);
}

.step-body p {
  margin: 0;
  color: inherit;
}

.step-body p + p {
  margin-top: 0.5rem;
}

/* ── Banner ── */

.band-banner {
  max-width: none;
  padding: 5rem 2rem;
  text-align: center;
  background: var(--gradient-iri-soft);
  border-top: 1px solid transparent;
  border-image: var(--gradient-hairline) 1;
}

.band-banner > * {
  max-width: 600px;
  margin-left: auto;
  margin-right: auto;
}

.band-banner .section-title {
  margin-bottom: 2rem;
  font-weight: 600;
  line-height: 1.4;
  letter-spacing: -0.015em;
  text-transform: none;
}

.band-banner .section-body {
  margin-top: -1rem;
}

.band-banner > .actions {
  justify-content: center;
  margin-top: 0;
}

/* ── 11. Responsive ────────────────────────────────────────────────────── */

@media (max-width: 1100px) {
  .stat {
    padding: 2.5rem 2rem;
  }
}

@media (max-width: 900px) {
  /* Landing */
  .hero {
    flex-direction: column;
    gap: 2rem;
    padding: 3rem 1.5rem 2rem;
    text-align: center;
  }

  .hero-inner {
    max-width: 100%;
  }

  .hero-title {
    font-size: 3.5rem;
  }

  .hero-subtitle {
    margin-left: auto;
    margin-right: auto;
  }

  .hero .actions {
    justify-content: center;
  }

  .stats-inner {
    flex-wrap: wrap;
  }

  .stat {
    padding: 2rem 1.5rem;
  }

  .band {
    padding: 3.5rem 1.5rem;
  }

  .band-figures,
  .band-cards:has(> .cards > div.card) {
    padding: 3.5rem 1.5rem 0;
  }

  .band-banner {
    padding: 4rem 1.5rem;
  }

  .cards:has(> :nth-child(4):last-child) {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 1rem;
  }

  .cards:has(> :nth-child(3):last-child),
  #explore .cards {
    grid-template-columns: minmax(0, 1fr);
  }

  .cards:has(> div.card) {
    gap: 1px;
  }

  .figures-grid {
    grid-template-columns: minmax(0, 1fr);
    gap: 2rem;
  }

  .figure dd {
    max-width: none;
  }

  /* Docs: the sidebar leaves the grid. With script it becomes an off-canvas
     drawer behind the Menu button; without script it sits above the
     article as a plain list, so the docs stay navigable. */
  .page-doc .layout {
    display: block;
  }

  .page-doc .content {
    padding: 2rem 1.25rem;
  }

  .page-doc .sidebar {
    border-right: none;
    border-image: none;
    border-bottom: 1px solid var(--border-color);
  }

  .page-doc .sidebar-nav {
    position: static;
    max-height: none;
    padding: 1.5rem 1.25rem;
  }

  html.js .page-doc .nav-toggle {
    display: inline-flex;
  }

  html.js .page-doc .sidebar {
    position: fixed;
    top: 0;
    bottom: 0;
    left: 0;
    z-index: 300;
    width: min(300px, 82vw);
    overflow-y: auto;
    overscroll-behavior: contain;
    background: var(--bg-secondary);
    border-right: 1px solid var(--glass-border);
    border-bottom: none;
    box-shadow: var(--shadow-lg);
    transform: translateX(-100%);
    visibility: hidden;
  }

  html.js .page-doc .sidebar.open {
    transform: none;
    visibility: visible;
  }

  html.js .page-doc .sidebar-nav {
    padding: 2rem 1rem 2.5rem;
  }

  body.nav-open {
    overflow: hidden;
  }

  .page-standalone .layout {
    padding: 2rem 1.25rem;
  }
}

@media (max-width: 900px) and (prefers-reduced-motion: no-preference) {
  html.js .page-doc .sidebar {
    transition: transform 0.25s ease, visibility 0s linear 0.25s;
  }

  html.js .page-doc .sidebar.open {
    transition: transform 0.25s ease, visibility 0s linear 0s;
  }
}

@media (max-width: 768px) {
  /* Two header rows cover more of the page; keep text from showing through. */
  .site-header {
    padding: 0.6rem 0;
    background: var(--bg-color);
  }

  .header-inner {
    padding: 0 1rem;
    row-gap: 0.35rem;
  }

  /* Brand and toggles on the first row, the links on their own row. */
  .header-nav {
    order: 3;
    flex-basis: 100%;
    justify-content: center;
    gap: 0.25rem;
  }

  .header-link {
    padding: 0.4rem 0.6rem;
    font-size: 0.9rem;
  }

  html.js .theme-toggle {
    margin-left: 0;
  }

  .page-doc .layout,
  .page-standalone .layout {
    border-left: none;
    border-right: none;
    border-radius: 0;
  }

  .prose h1 {
    font-size: 1.75rem;
  }

  .prose.not-found h1 {
    font-size: 2.4rem;
  }

  .prose h2 {
    font-size: 1.3rem;
  }
}

@media (max-width: 600px) {
  .hero-title {
    font-size: 2.5rem;
    letter-spacing: -2px;
  }

  .hero-figure {
    width: 100%;
  }

  .stats-inner {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .stat {
    padding: 1.5rem 1rem;
  }

  .stat + .stat::before {
    display: none;
  }

  .stat-value {
    font-size: 1.3rem;
  }

  .section-title {
    margin-bottom: 2rem;
    font-size: 1.25rem;
    letter-spacing: 2px;
  }

  .cards:has(> :nth-child(2):last-child),
  .cards:has(> :nth-child(4):last-child) {
    grid-template-columns: minmax(0, 1fr);
  }

  a.card {
    padding: 1.5rem;
  }

  .step {
    gap: 1.25rem;
  }

  .step-num {
    min-width: 2.5rem;
    font-size: 1.8rem;
  }

  .figure {
    flex-direction: column;
    gap: 0.15rem;
  }

  .figure dd {
    text-align: left;
  }
}

/* ── 12. Colour ────────────────────────────────────────────────────────────
   One hue per card, step, stat, scene and docs section, cycled in source
   order, so a section reads as a set of distinct things rather than one
   violet block. Components read the hue as --h; the h-* classes set it
   explicitly (the explainer art uses them). The measured figures keep the
   signal colour: that colour is reserved for values off an instrument. */

.h-violet  { --h: var(--hue-violet); }
.h-indigo  { --h: var(--hue-indigo); }
.h-purple  { --h: var(--hue-purple); }
.h-sky     { --h: var(--hue-sky); }
.h-teal    { --h: var(--hue-teal); }
.h-emerald { --h: var(--hue-emerald); }
.h-amber   { --h: var(--hue-amber); }
.h-rose    { --h: var(--hue-rose); }
.h-slate   { --h: var(--hue-slate); }

.cards > :nth-child(6n + 1),
.steps > :nth-child(6n + 1),
.stat:nth-child(6n + 1) { --h: var(--hue-violet); --h2: var(--hue-indigo); }
.cards > :nth-child(6n + 2),
.steps > :nth-child(6n + 2),
.stat:nth-child(6n + 2) { --h: var(--hue-sky); --h2: var(--hue-teal); }
.cards > :nth-child(6n + 3),
.steps > :nth-child(6n + 3),
.stat:nth-child(6n + 3) { --h: var(--hue-emerald); --h2: var(--hue-teal); }
.cards > :nth-child(6n + 4),
.steps > :nth-child(6n + 4),
.stat:nth-child(6n + 4) { --h: var(--hue-amber); --h2: var(--hue-rose); }
.cards > :nth-child(6n + 5),
.steps > :nth-child(6n + 5),
.stat:nth-child(6n + 5) { --h: var(--hue-rose); --h2: var(--hue-purple); }
.cards > :nth-child(6n + 6),
.steps > :nth-child(6n + 6),
.stat:nth-child(6n + 6) { --h: var(--hue-teal); --h2: var(--hue-sky); }

/* Hero: the accent line runs the whole spectrum, slowly. */
.hero-title-line.accent,
.band-banner .accent {
  background-image: var(--gradient-spectrum);
}

@media (prefers-reduced-motion: no-preference) {
  .hero-title-line.accent {
    animation: spectrum-drift 9s ease-in-out infinite alternate;
  }
}

@keyframes spectrum-drift {
  from { background-position: 0% 50%; }
  to { background-position: 100% 50%; }
}

/* Section titles: a short spectrum rule underneath. */
.band:not(.band-banner) > .section-title::after {
  content: "";
  display: block;
  width: 56px;
  height: 4px;
  margin: 0.9rem auto 0;
  border-radius: 2px;
  background: var(--gradient-spectrum);
}

/* Stats: each value in its own pair of hues. */
.stat-value {
  background-image: linear-gradient(120deg, var(--h, var(--iri-1)), var(--h2, var(--iri-3)));
}

/* Pillar tiles: a tinted top, a filled icon tile, and a ring in the card's
   own hue on hover. */
a.card {
  background:
    linear-gradient(180deg, color-mix(in srgb, var(--h, var(--iri-2)) 7%, var(--glass-bg)) 0%, var(--glass-bg) 55%);
  border-top: 3px solid var(--h, var(--iri-2));
}

a.card::before {
  background: conic-gradient(from 0deg, var(--h), var(--h2, var(--h)), var(--h));
}

a.card:hover {
  box-shadow: 0 14px 32px -14px color-mix(in srgb, var(--h, var(--iri-2)) 70%, transparent), var(--shadow-md);
}

.card-icon {
  width: 44px;
  height: 44px;
  color: var(--h, var(--iri-2));
  background: color-mix(in srgb, var(--h, var(--iri-2)) 14%, var(--bg-color));
  border: none;
  border-radius: 12px;
}

.card-icon svg {
  width: 22px;
  height: 22px;
}

a.card:hover .card-arrow {
  color: var(--h, var(--primary-color));
}

div.card .card-title {
  color: var(--h, var(--iri-2));
}

div.card {
  box-shadow: inset 0 3px 0 var(--h, transparent);
}

#explore a.card {
  border-top-width: 1px;
  border-top-color: var(--glass-border);
}

#explore a.card::after {
  background: var(--h, var(--iri-2));
}

#explore a.card:hover {
  box-shadow: 0 12px 30px -14px color-mix(in srgb, var(--h, var(--iri-2)) 65%, transparent), var(--shadow-md);
}

/* How it works: numbered stops on one coloured line. */
.steps {
  position: relative;
}

.steps::before {
  content: "";
  position: absolute;
  left: 1.5rem;
  top: 2.75rem;
  bottom: 2.75rem;
  width: 2px;
  margin-left: -1px;
  background: linear-gradient(180deg, var(--hue-violet), var(--hue-sky), var(--hue-emerald), var(--hue-amber));
  opacity: 0.45;
}

.step {
  border-image: none;
  border-bottom: none;
}

.step-num {
  position: relative;
  z-index: 1;
  display: grid;
  place-items: center;
  flex-shrink: 0;
  width: 3rem;
  min-width: 3rem;
  height: 3rem;
  font-family: var(--font-mono);
  font-size: 0.95rem;
  font-weight: 600;
  letter-spacing: 0;
  color: #fff;
  background: linear-gradient(135deg, var(--h, var(--iri-1)), var(--h2, var(--iri-3)));
  -webkit-background-clip: border-box;
  background-clip: border-box;
  border-radius: 50%;
  box-shadow: 0 0 0 6px var(--bg-color), 0 10px 22px -10px var(--h, var(--iri-2));
  opacity: 1;
}

.step-content {
  padding-top: 0.55rem;
}

.step-title {
  font-size: 1.1rem;
}

/* Closing banner: a wash in three hues instead of one. */
.band-banner {
  background:
    radial-gradient(60% 120% at 0% 0%, color-mix(in srgb, var(--hue-violet) 14%, transparent), transparent 70%),
    radial-gradient(50% 120% at 100% 100%, color-mix(in srgb, var(--hue-sky) 14%, transparent), transparent 70%),
    radial-gradient(40% 90% at 70% 0%, color-mix(in srgb, var(--hue-rose) 10%, transparent), transparent 70%),
    var(--bg-secondary);
}

/* Docs: each h2 carries a hue chip, cycled through the page; inline code,
   tables and the sidebar pick up the same palette. */
.prose h2:nth-of-type(6n + 1) { --h: var(--hue-violet); }
.prose h2:nth-of-type(6n + 2) { --h: var(--hue-sky); }
.prose h2:nth-of-type(6n + 3) { --h: var(--hue-emerald); }
.prose h2:nth-of-type(6n + 4) { --h: var(--hue-amber); }
.prose h2:nth-of-type(6n + 5) { --h: var(--hue-rose); }
.prose h2:nth-of-type(6n + 6) { --h: var(--hue-teal); }

.prose h2::before {
  content: "";
  display: inline-block;
  width: 0.5em;
  height: 0.5em;
  margin-right: 0.55em;
  vertical-align: 0.12em;
  border-radius: 3px;
  background: var(--h, var(--iri-2));
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--h, var(--iri-2)) 16%, transparent);
}

.prose :not(pre) > code {
  color: color-mix(in srgb, var(--hue-violet) 78%, var(--text-main));
  background: color-mix(in srgb, var(--hue-violet) 7%, var(--code-bg));
  border-color: color-mix(in srgb, var(--hue-violet) 20%, var(--border-color));
}

.prose thead {
  background:
    linear-gradient(90deg, color-mix(in srgb, var(--hue-violet) 12%, transparent), color-mix(in srgb, var(--hue-sky) 10%, transparent));
}

.prose tbody tr:nth-child(even) td {
  background: color-mix(in srgb, var(--bg-secondary) 75%, transparent);
}

.prose tbody tr:hover td {
  background: color-mix(in srgb, var(--hue-violet) 6%, transparent);
}

.prose blockquote {
  background: color-mix(in srgb, var(--hue-sky) 7%, var(--bg-color));
  border-color: color-mix(in srgb, var(--hue-sky) 22%, var(--border-color));
  border-left-color: var(--hue-sky);
}

.nav-group:nth-child(4n + 1) { --h: var(--hue-violet); }
.nav-group:nth-child(4n + 2) { --h: var(--hue-sky); }
.nav-group:nth-child(4n + 3) { --h: var(--hue-emerald); }
.nav-group:nth-child(4n + 4) { --h: var(--hue-amber); }

.nav-group-title::before {
  content: "";
  display: inline-block;
  width: 7px;
  height: 7px;
  margin-right: 0.5rem;
  vertical-align: 0.1em;
  border-radius: 2px;
  background: var(--h, var(--iri-2));
}

.nav-links a::before {
  background: var(--h, var(--iri-2));
}

.nav-links a:hover,
.nav-links a[aria-current="page"] {
  color: color-mix(in srgb, var(--h, var(--primary-color)) 85%, var(--text-main));
  background: color-mix(in srgb, var(--h, var(--primary-color)) 10%, transparent);
}

@media (max-width: 900px) {
  .steps::before {
    left: 1.25rem;
  }

  .step-num {
    width: 2.5rem;
    min-width: 2.5rem;
    height: 2.5rem;
    font-size: 0.85rem;
  }

  .step {
    gap: 1.25rem;
  }

  .step-content {
    padding-top: 0.3rem;
  }
}

/* ── 13. Explainer ─────────────────────────────────────────────────────────
   An animated figure (figures/explainer.svg: one <g class="sc"> per scene)
   over a row of captions. site.js shows one scene at a time (`.on`) and
   advances every SCENE_MS, which must match the 6s caption bar below.
   Every animation runs FROM an offset state TO the element's resting pose,
   so with motion reduced (animations off) each scene shows its end state,
   and without script the last scene stands as a still frame. */

.band-explainer {
  max-width: 1120px;
}

.explainer {
  display: grid;
  gap: 1.25rem;
}

.explainer-stage {
  position: relative;
  overflow: hidden;
  background: var(--xp-stage);
  border: 1px solid var(--border-color);
  border-radius: 22px;
  box-shadow: var(--shadow-lg);
}

/* A faint dot grid, like a canvas. */
.explainer-stage::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background-image: radial-gradient(color-mix(in srgb, var(--xp-dim) 30%, transparent) 1px, transparent 1.4px);
  background-size: 22px 22px;
  opacity: 0.55;
}

.xp {
  position: relative;
  display: block;
  width: 100%;
  height: auto;
}

.explainer-toggle {
  position: absolute;
  right: 14px;
  bottom: 14px;
  padding: 0.35rem 0.95rem;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-main);
  background: color-mix(in srgb, var(--xp-surface) 88%, transparent);
  border: 1px solid var(--border-color);
  border-radius: 999px;
  cursor: pointer;
}

.explainer-toggle:hover {
  border-color: var(--primary-color);
}

/* Scenes: one at a time. */
.xp .sc {
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.45s ease, visibility 0s linear 0.45s;
}

.xp .sc.on,
.explainer:not(.is-live) .xp .sc:last-of-type {
  opacity: 1;
  visibility: visible;
  transition: opacity 0.45s ease;
}

/* Art. */
.xp text {
  font-family: var(--font-sans);
  font-size: 15px;
  fill: var(--xp-ink);
}

.xp .xp-label { font-weight: 500; }
.xp .xp-strong { font-family: var(--font-display); font-weight: 700; }
.xp .xp-small { font-size: 12.5px; }
.xp .xp-mono { font-family: var(--font-mono); font-size: 14px; }
.xp .xp-mono.xp-small { font-size: 12px; }
.xp .xp-dim { fill: var(--xp-dim); }

.xp .xp-card {
  fill: var(--xp-surface);
  stroke: var(--xp-line);
  stroke-width: 1.2;
  filter: drop-shadow(0 8px 16px var(--xp-shadow));
}

.xp .xp-head { fill: color-mix(in srgb, var(--h) 12%, var(--xp-surface)); }
.xp .xp-row { fill: color-mix(in srgb, var(--h) 5%, var(--xp-surface)); stroke: var(--xp-line); }
.xp .xp-folder { fill: color-mix(in srgb, var(--h) 75%, transparent); }
.xp .xp-line { fill: var(--xp-line); }

.xp .xp-wire {
  fill: none;
  stroke: var(--xp-line);
  stroke-width: 2;
  stroke-linecap: round;
}

.xp .xp-wire-hue { stroke: color-mix(in srgb, var(--h) 55%, var(--xp-line)); }

.xp .xp-chip { fill: color-mix(in srgb, var(--h) 15%, var(--xp-surface)); }
.xp .xp-chip-text { fill: var(--h); font-weight: 600; }
.xp .xp-type { fill: color-mix(in srgb, var(--h) 9%, var(--xp-surface)); stroke: color-mix(in srgb, var(--h) 35%, transparent); }
.xp .xp-type-text { fill: var(--h); }
.xp .xp-badge { fill: var(--h); filter: drop-shadow(0 8px 14px color-mix(in srgb, var(--h) 40%, transparent)); }
.xp .xp-badge-text { fill: #fff; font-weight: 700; }
.xp .xp-tile { fill: var(--h); }
.xp .xp-tile-text { fill: #fff; font-family: var(--font-mono); font-weight: 600; }
.xp .xp-tile-glyph { fill: #fff; }

/* Fixed, not themed: white type on the core must read in both themes. */
.xp .xp-stop-a { stop-color: #4f46e5; }
.xp .xp-stop-b { stop-color: #9333ea; }

.xp .xp-core {
  fill: url(#xp-g-core);
  filter: drop-shadow(0 12px 26px color-mix(in srgb, var(--hue-violet) 50%, transparent));
}

.xp .xp-core-text {
  font-family: var(--font-display);
  font-size: 28px;
  font-weight: 800;
  letter-spacing: -0.5px;
  fill: #fff;
}

.xp .xp-core-sub {
  font-family: var(--font-mono);
  font-size: 12px;
  fill: rgba(255, 255, 255, 0.82);
}

.xp .xp-db { fill: color-mix(in srgb, var(--h) 10%, var(--xp-surface)); stroke: var(--h); stroke-width: 1.5; }
.xp .xp-db-top { fill: color-mix(in srgb, var(--h) 24%, var(--xp-surface)); stroke: var(--h); stroke-width: 1.5; }

.xp .xp-avatar { fill: color-mix(in srgb, var(--h) 16%, var(--xp-surface)); stroke: var(--h); stroke-width: 2; }
.xp .xp-avatar-text { font-family: var(--font-display); font-size: 24px; font-weight: 800; fill: var(--h); }
.xp .xp-gate { fill: color-mix(in srgb, var(--h) 14%, var(--xp-surface)); stroke: var(--h); stroke-width: 2.5; }
.xp .xp-lock { fill: var(--h); }
.xp .xp-lock-loop { fill: none; stroke: var(--h); stroke-width: 4; }
.xp .xp-pill { fill: color-mix(in srgb, var(--h) 14%, var(--xp-surface)); stroke: var(--h); stroke-width: 1.5; }
.xp .xp-pill-text { fill: var(--h); font-weight: 600; }

.xp .xp-search { stroke: color-mix(in srgb, var(--h) 55%, var(--xp-line)); stroke-width: 2; }
.xp .xp-lens { fill: none; stroke: var(--h); stroke-width: 2.5; stroke-linecap: round; }
.xp .xp-query { font-size: 15px; }

.xp .xp-node { fill: var(--xp-surface); stroke: var(--h); stroke-width: 2; filter: drop-shadow(0 6px 12px var(--xp-shadow)); }
.xp .xp-node-text { fill: var(--h); font-weight: 700; }

/* Dark mode lifts the hues, so type set on a filled hue turns dark. */
:root.dark .xp .xp-badge-text,
:root.dark .xp .xp-tile-text,
:root.dark .xp .xp-tile-glyph {
  fill: #0d0e15;
}

:root.dark .scene-num,
:root.dark .step-num {
  color: #0d0e15;
}

@media (prefers-color-scheme: dark) {
  :root:not(.light):not(.dark) .xp .xp-badge-text,
  :root:not(.light):not(.dark) .xp .xp-tile-text,
  :root:not(.light):not(.dark) .xp .xp-tile-glyph {
    fill: #0d0e15;
  }

  :root:not(.light):not(.dark) .scene-num,
  :root:not(.light):not(.dark) .step-num {
    color: #0d0e15;
  }
}

/* Resting poses of things that only exist in motion. */
.xp .xp-dot { fill: var(--h); opacity: 0; }
.xp .xp-cover { fill: var(--xp-surface); transform: scaleX(0); }

.xp .a-pop,
.xp .a-wipe {
  transform-box: fill-box;
}

.xp .a-pop { transform-origin: center; }
.xp .a-wipe { transform-origin: right center; }
.xp .a-draw { stroke-dasharray: 1; }

/* Motion, only while the scene is showing. */
.xp .sc.on .a-in { animation: xp-in 0.6s cubic-bezier(0.2, 0.8, 0.2, 1) var(--t, 0s) both; }
.xp .sc.on .a-left { animation: xp-left 0.65s cubic-bezier(0.2, 0.8, 0.2, 1) var(--t, 0s) both; }
.xp .sc.on .a-right { animation: xp-right 0.65s cubic-bezier(0.2, 0.8, 0.2, 1) var(--t, 0s) both; }
.xp .sc.on .a-pop { animation: xp-pop 0.55s cubic-bezier(0.3, 1.45, 0.5, 1) var(--t, 0s) both; }
.xp .sc.on .a-draw { animation: xp-draw 0.7s ease-out var(--t, 0s) both; }
.xp .sc.on .a-wipe { animation: xp-wipe 1.3s steps(34, end) var(--t, 0s) both; }
.xp .sc.on .a-flash { animation: xp-flash 1.1s ease var(--t, 0s) both; }
.xp .sc.on .a-pass { animation: xp-pass 2s cubic-bezier(0.45, 0, 0.2, 1) var(--t, 0s) both; }
.xp .sc.on .a-stop { animation: xp-stop 1.7s ease var(--t, 0s) both; }
.xp .sc.on .xp-dot { animation: xp-travel 1.1s ease-in-out var(--t, 0s) 2 both; }
.xp .sc.on .xp-dot.xp-loop { animation-duration: 1.6s; animation-iteration-count: infinite; }

@keyframes xp-in { from { opacity: 0; transform: translateY(10px); } }
@keyframes xp-left { from { opacity: 0; transform: translateX(-40px); } }
@keyframes xp-right { from { opacity: 0; transform: translateX(40px); } }
@keyframes xp-pop { from { opacity: 0; transform: scale(0.6); } }
@keyframes xp-draw { from { stroke-dashoffset: 1; } to { stroke-dashoffset: 0; } }
@keyframes xp-wipe { from { transform: scaleX(1); } to { transform: scaleX(0); } }

@keyframes xp-travel {
  0% { opacity: 0; transform: translate(0, 0); }
  15%, 85% { opacity: 1; }
  100% { opacity: 0; transform: translate(var(--dx), var(--dy)); }
}

/* The gate flashes red as the anonymous request is refused. */
@keyframes xp-flash {
  0%, 100% { stroke: var(--h); }
  25%, 60% { stroke: var(--hue-rose); stroke-width: 5; }
}

/* Alice's request: from her avatar to the gate, a beat at the check, then
   through to the entry. Resting pose is past the gate. */
@keyframes xp-pass {
  0% { opacity: 0; transform: translateX(-330px); }
  10% { opacity: 1; }
  45%, 62% { transform: translateX(-140px); }
  100% { opacity: 1; transform: translateX(0); }
}

/* The anonymous request reaches the gate and is shaken off. */
@keyframes xp-stop {
  0% { opacity: 0; transform: translateX(-70px); }
  15% { opacity: 1; }
  55% { transform: translateX(0); }
  63% { transform: translateX(-9px); }
  71% { transform: translateX(6px); }
  79% { transform: translateX(-3px); }
  86%, 100% { transform: translateX(0); }
}

/* Paused, or scrolled away: freeze in place. */
.explainer.is-paused .xp *,
.explainer.is-paused .scene-bar::after,
.explainer.is-offscreen .xp *,
.explainer.is-offscreen .scene-bar::after {
  animation-play-state: paused !important;
}

/* Captions. */
.explainer-scenes {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 11rem), 1fr));
  gap: 0.85rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.scene:nth-child(5n + 1) { --h: var(--hue-violet); }
.scene:nth-child(5n + 2) { --h: var(--hue-sky); }
.scene:nth-child(5n + 3) { --h: var(--hue-amber); }
.scene:nth-child(5n + 4) { --h: var(--hue-teal); }
.scene:nth-child(5n + 5) { --h: var(--hue-rose); }

.scene {
  position: relative;
  padding: 0.85rem 1rem 1rem;
  background: var(--glass-bg);
  border: 1px solid var(--border-color);
  border-radius: 14px;
  transition: opacity 0.3s ease, border-color 0.3s ease, box-shadow 0.3s ease, transform 0.3s ease;
}

.scene-title {
  margin: 0;
  font-size: 0.95rem;
  letter-spacing: 0;
}

.scene-jump {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  width: 100%;
  padding: 0;
  font: inherit;
  font-weight: 700;
  text-align: left;
  color: var(--text-main);
  background: none;
  border: 0;
  cursor: pointer;
}

.scene-jump:disabled {
  cursor: default;
}

.scene-jump:focus-visible {
  outline-offset: 4px;
}

.scene-num {
  display: inline-grid;
  place-items: center;
  flex-shrink: 0;
  width: 1.6rem;
  height: 1.6rem;
  font-family: var(--font-mono);
  font-size: 0.75rem;
  font-weight: 600;
  color: #fff;
  background: var(--h);
  border-radius: 50%;
}

.scene-bar {
  display: block;
  height: 3px;
  margin: 0.65rem 0 0.6rem;
  overflow: hidden;
  background: color-mix(in srgb, var(--h) 18%, transparent);
  border-radius: 2px;
}

.scene-bar::after {
  content: "";
  display: block;
  width: 100%;
  height: 100%;
  background: var(--h);
  transform: scaleX(0);
  transform-origin: left;
}

.scene-body {
  font-size: 0.84rem;
  line-height: 1.5;
  color: var(--text-secondary);
}

.scene-body p {
  margin: 0;
  color: inherit;
}

.explainer:not(.is-live) .scene-bar {
  display: none;
}

.explainer:not(.is-live) .scene-title {
  margin-bottom: 0.5rem;
}

.explainer.is-live .scene {
  opacity: 0.62;
}

.explainer.is-live .scene:hover {
  opacity: 0.9;
}

.explainer.is-live .scene.is-on {
  opacity: 1;
  border-color: color-mix(in srgb, var(--h) 55%, var(--border-color));
  box-shadow: 0 12px 28px -16px color-mix(in srgb, var(--h) 70%, transparent);
  transform: translateY(-2px);
}

.scene.is-on .scene-bar::after {
  animation: xp-bar 6s linear both;
}

.explainer.is-reduced .scene.is-on .scene-bar::after {
  transform: scaleX(1);
}

@keyframes xp-bar { from { transform: scaleX(0); } to { transform: scaleX(1); } }

@media (prefers-reduced-motion: reduce) {
  .xp *,
  .xp .sc,
  .scene,
  .scene-bar::after {
    animation: none !important;
    transition: none !important;
  }
}

/* Narrow: the captions stack, and only the playing scene shows its text. */
@media (max-width: 900px) {
  .explainer-stage {
    border-radius: 16px;
  }

  .explainer-scenes {
    grid-template-columns: minmax(0, 1fr);
    gap: 0.5rem;
  }

  .explainer.is-live .scene:not(.is-on) .scene-bar,
  .explainer.is-live .scene:not(.is-on) .scene-body {
    display: none;
  }

  .explainer.is-live .scene {
    padding: 0.65rem 0.9rem;
  }

  .explainer.is-live .scene.is-on {
    padding-bottom: 0.9rem;
  }

  .explainer-toggle {
    right: 8px;
    bottom: 8px;
    padding: 0.25rem 0.7rem;
  }
}
