/* Tusk's Vault — public site.
 *
 * The visual language is shared with the sibling project deliberately: the same
 * ruled-page grid, the same typographic scale, the same panel craft. What is
 * NOT shared is the palette or the imagery. This page is warm all the way
 * through — ember on umber, with crimson where a second colour is needed —
 * and carries no violet at any lightness. If a purple appears here, something
 * has been copied rather than designed.
 *
 * Fonts are self-hosted from site/assets/fonts. The dashboard pulls the same
 * families from Google; this page deliberately does not, because a docs site
 * that talks about not phoning home should not phone home to render its own
 * headings.
 */

/* The @font-face block that makes the sentence above true.
 *
 * Without it the tokens below name "Cinzel" and "Cormorant Garamond" and the
 * browser resolves them against INSTALLED fonts only — so the site rendered
 * correctly on a machine that happens to have them (a designer's) and fell
 * back to Georgia for everyone else, while still shipping 464 KB of woff2
 * nobody ever downloaded. Every family named in a --font-* token below needs a
 * face here; adding a token without one silently re-opens exactly that gap.
 *
 * `swap` on purpose: text is readable in the fallback immediately and reflows
 * when the face arrives. The alternative — invisible text while 26 KB loads —
 * is the worse trade for a docs site people arrive at from search.
 */
@font-face {
  font-family: "Cinzel";
  src: url("assets/fonts/cinzel-600.woff2") format("woff2");
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Cinzel";
  src: url("assets/fonts/cinzel-700.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Cinzel Decorative";
  src: url("assets/fonts/cinzel-decorative-700.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Cinzel Decorative";
  src: url("assets/fonts/cinzel-decorative-900.woff2") format("woff2");
  font-weight: 900;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Cormorant Garamond";
  src: url("assets/fonts/cormorant-400.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Cormorant Garamond";
  src: url("assets/fonts/cormorant-400-italic.woff2") format("woff2");
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}
@font-face {
  font-family: "Cormorant Garamond";
  src: url("assets/fonts/cormorant-600.woff2") format("woff2");
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Fondamento";
  src: url("assets/fonts/fondamento-400.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Fondamento";
  src: url("assets/fonts/fondamento-400-italic.woff2") format("woff2");
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}
@font-face {
  font-family: "Inter";
  src: url("assets/fonts/inter-400.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Inter";
  src: url("assets/fonts/inter-500.woff2") format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Inter";
  src: url("assets/fonts/inter-600.woff2") format("woff2");
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}

:root {
  /* Palette taken from the app's own theme (src/index.css), so the site and
     the dashboard read as one product rather than two designs sharing a name.

     Warm the whole way through. Ember carries the primary role, crimson is the
     second colour, and the ground is umber. There is no violet at any
     lightness — not as an accent, not in a border, not in a gradient. */

  /* Surfaces — umber, the colour of a room lit by one candle. */
  --bg: oklch(0.11 0.025 50);
  --bg-deep: oklch(0.08 0.02 50);
  --card: oklch(0.16 0.04 50);
  --card2: oklch(0.20 0.05 50);
  --fg: oklch(0.94 0.025 90);          /* parchment */
  --muted: oklch(0.72 0.035 65);       /* warm muted, never cool grey */

  /* Primary — ember. */
  --flame: oklch(0.72 0.19 55);
  --flame-bright: oklch(0.85 0.16 62);

  /* Second colour — crimson. Used where something needs to read as attention
     rather than as invitation: a refusal, a warning, the wrong half of a
     comparison. Warm enough to sit on this ground without fighting it. */
  --accent: oklch(0.62 0.21 25);
  --accent-bright: oklch(0.74 0.19 28);

  --gold: #c2a14d;
  --border: oklch(0.32 0.07 55);       /* warm border to match the field */

  --font-display: "Cinzel", "Trajan Pro", Georgia, serif;
  --font-deco: "Cinzel Decorative", "Cinzel", Georgia, serif;
  --font-script: "Fondamento", "Cormorant Garamond", Georgia, serif;
  --font-serif: "Cormorant Garamond", Georgia, serif;
  --font-sans: "Inter", ui-sans-serif, system-ui, "Segoe UI", Roboto, sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  --radius: 12px;
  --maxw: 68rem;

  /* Structural tokens, borrowed wholesale from the reference the site was
   * re-cut against. Three ideas do most of the work there:
   *
   *   1. Cards are much rounder than a typical app UI — 26px, not 12px — which
   *      reads as printed matter rather than as chrome.
   *   2. Buttons are full pills. At this radius a rectangle looks unfinished
   *      next to the cards.
   *   3. Prose sits in a genuinely narrow column (~38rem, near enough 62
   *      characters) no matter how wide the card around it is. That is the
   *      single biggest readability difference and the easiest to lose.
 */
  --radius-card: 26px;
  --radius-pill: 999px;
  /* ---- Landing structural system -------------------------------------
     One panel primitive, so a container never has to be invented again.

     The page had four corner radii (12 / 14 / 18 / 26px) doing the same
     job, which is what made adjacent sections read as different designs.
     One radius, two paddings — roomy for a card the reader chooses
     between, tight for a row in a sequence — and a single rail width for
     the semantic left-edge accents.

     Pills keep --radius-pill; they are a different object, not a panel. */
  --panel-r: 16px;
  --panel-pad: 1.6rem 1.7rem;
  --panel-pad-tight: 1.15rem 1.35rem;
  --panel-rail: 3px;

  /* Vertical rhythm. Sections were spacing themselves individually. */
  --section-gap: 5.5rem;
  --lede-measure: 58ch;
  --measure: 38rem;
}

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

html {
  scroll-behavior: smooth;
  scroll-padding-top: 5rem;
}

body {
  margin: 0;
  background-color: var(--bg);
  color: var(--fg);
  font-family: var(--font-sans);
  font-size: 1.02rem;
  line-height: 1.65;
  -webkit-text-size-adjust: 100%;
  background-image:
    radial-gradient(ellipse 120% 80% at 50% -20%, oklch(0.35 0.14 55 / 0.3), transparent 60%),
    radial-gradient(ellipse 80% 60% at 50% 120%, oklch(0.2 0.1 50 / 0.45), transparent 65%),
    radial-gradient(ellipse 60% 50% at 12% 28%, oklch(0.4 0.12 55 / 0.1), transparent 70%),
    radial-gradient(ellipse 50% 40% at 88% 72%, oklch(0.55 0.16 50 / 0.07), transparent 75%);
  background-attachment: fixed;
}

h1,
h2,
h3,
h4 {
  font-family: var(--font-display);
  line-height: 1.2;
  letter-spacing: 0.01em;
  margin: 0 0 0.5em;
  text-wrap: balance;
}

a {
  color: var(--flame-bright);
  text-underline-offset: 0.15em;
}
a:hover {
  color: var(--flame);
}

code {
  font-family: var(--font-mono);
  font-size: 0.9em;
  background: var(--bg-deep);
  border: 1px solid var(--border);
  border-radius: 5px;
  padding: 0.1em 0.35em;
  color: var(--flame-bright);
  /* Inline code has no spaces to break at, so a long one — a curl command, a
     file path, an env var with a URL in it — is a single unbreakable box that
     pushes the whole document sideways on a phone. `anywhere` lets it wrap
     mid-token rather than widening the page. Measured: one
     `curl -X POST http://localhost:3000/api/...` in a docs paragraph took a
     375px viewport to 481px. */
  overflow-wrap: anywhere;
}

/* Code BLOCKS keep their line breaks and scroll instead — wrapping a shell
   snippet mid-flag makes it uncopyable, which is the opposite of the point. */
pre code {
  overflow-wrap: normal;
}

img {
  max-width: 100%;
  height: auto;
}

::selection {
  background-color: var(--flame);
  color: oklch(0.99 0.005 52);
}

::-webkit-scrollbar {
  width: 10px;
  height: 10px;
}
::-webkit-scrollbar-track {
  background: oklch(0.13 0.04 50);
}
::-webkit-scrollbar-thumb {
  background: oklch(0.3 0.08 52);
  border-radius: 6px;
  border: 2px solid oklch(0.13 0.04 50);
}
::-webkit-scrollbar-thumb:hover {
  background: oklch(0.45 0.12 55);
}

/* Inline SVG symbol sheet. A class rather than style="display:none" so the
 * page carries no inline styles at all and the CSP can forbid them. */
.svg-defs {
  display: none;
}

.skip {
  position: absolute;
  left: -9999px;
}
.skip:focus {
  left: 1rem;
  top: 1rem;
  z-index: 100;
  background: var(--card);
  border: 2px solid var(--flame);
  border-radius: var(--radius);
  padding: 0.5rem 1rem;
}

:focus-visible {
  outline: 2px solid var(--flame-bright);
  outline-offset: 2px;
}

/* Read aloud, never shown. Used where a glyph carries the meaning — a tick in
 * a comparison grid says "yes" to anyone who can see it and nothing at all to
 * anyone who cannot. */
.vh {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ---------- keyframes ---------- */

@keyframes brand-pulse {
  0%, 100% { filter: drop-shadow(0 0 18px oklch(0.65 0.22 55 / 0.35)); }
  50% { filter: drop-shadow(0 0 30px oklch(0.72 0.24 55 / 0.6)); }
}
@keyframes spell-charge {
  0%, 100% { box-shadow: 0 0 0 1px oklch(0.65 0.22 55 / 0.4), 0 8px 24px -8px oklch(0.65 0.22 55 / 0.45); }
  50% { box-shadow: 0 0 0 1px oklch(0.72 0.24 55 / 0.6), 0 10px 28px -6px oklch(0.7 0.24 55 / 0.55), 0 0 0 4px oklch(0.7 0.24 55 / 0.08); }
}
@keyframes slow-spin {
  to { transform: rotate(360deg); }
}
@keyframes ember-drift {
  0% { opacity: 0; transform: translate3d(0, 0, 0) scale(0.6); }
  10% { opacity: 0.6; }
  80% { opacity: 0.4; }
  100% { opacity: 0; transform: translate3d(var(--dx, 12px), -100vh, 0) scale(1); }
}

/* Drifting embers — fixed background layer behind everything.
 *
 * The field has to work harder here than in the sibling project. There, embers
 * were the warm accent against a cool violet page and read instantly. Here the
 * page is ALREADY warm umber, so ember-on-ember would disappear. Three changes
 * earn it back:
 *
 *   1. A hearth glow anchored to the bottom of the viewport — the "candle-light
 *      at dusk" the app's theme is named for. It gives the embers a source to
 *      have risen from, instead of leaving them floating in nothing.
 *   2. Ten particles rather than six, at mixed sizes, so the drift reads as a
 *      field rather than as six tracked dots.
 *   3. Every third ember is . That is the accent doing the same job it
 *      does in the app: one cool note against the warm field, which is also the
 *      only thing keeping warm particles legible on a warm ground.
 */
.ember-field {
  position: fixed;
  inset: 0;
  pointer-events: none;
  overflow: hidden;
  z-index: 0;
}
/* The hearth. Sits under the particles, never moves, costs nothing to paint. */
.ember-field::after {
  content: "";
  position: absolute;
  inset: auto 0 0 0;
  height: 45vh;
  background:
    radial-gradient(60% 100% at 50% 100%, oklch(0.72 0.19 55 / 0.10), transparent 70%),
    radial-gradient(35% 100% at 18% 100%, oklch(0.65 0.22 50 / 0.06), transparent 70%);
}
.ember-field span {
  position: absolute;
  bottom: -20px;
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: radial-gradient(circle, oklch(0.88 0.16 60 / 0.95), oklch(0.66 0.19 55 / 0.4) 60%, transparent 75%);
  box-shadow: 0 0 8px oklch(0.80 0.18 58 / 0.55);
  animation: ember-drift 15s linear infinite;
}
/* The  counter-notes. */
.ember-field span:nth-child(3n) {
  background: radial-gradient(circle, oklch(0.80 0.20 50 / 0.9), oklch(0.60 0.20 50 / 0.35) 60%, transparent 75%);
  box-shadow: 0 0 9px oklch(0.68 0.20 50 / 0.5);
}
.ember-field span:nth-child(1)  { left: 8%;  --dx: 18px;  width: 5px; height: 5px; animation-duration: 13s; animation-delay: -1s; }
.ember-field span:nth-child(2)  { left: 21%; --dx: 8px;   animation-duration: 16s; animation-delay: -3s; }
.ember-field span:nth-child(3)  { left: 33%; --dx: -14px; width: 3px; height: 3px; animation-duration: 19s; animation-delay: -8s; }
.ember-field span:nth-child(4)  { left: 44%; --dx: 20px;  animation-duration: 15s; animation-delay: -11s; }
.ember-field span:nth-child(5)  { left: 55%; --dx: -22px; width: 5px; height: 5px; animation-duration: 17s; animation-delay: -5s; }
.ember-field span:nth-child(6)  { left: 63%; --dx: -10px; width: 3px; height: 3px; animation-duration: 18s; animation-delay: -6s; }
.ember-field span:nth-child(7)  { left: 72%; --dx: 14px;  animation-duration: 21s; animation-delay: -14s; }
.ember-field span:nth-child(8)  { left: 81%; --dx: -6px;  width: 5px; height: 5px; animation-duration: 14s; animation-delay: -2s; }
.ember-field span:nth-child(9)  { left: 89%; --dx: 22px;  width: 3px; height: 3px; animation-duration: 20s; animation-delay: -9s; }
.ember-field span:nth-child(10) { left: 96%; --dx: -16px; animation-duration: 16s; animation-delay: -12s; }

/* ---------- header / footer ---------- */

.site-head {
  position: sticky;
  top: 0;
  z-index: 50;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.5rem;
  align-items: center;
  justify-content: space-between;
  padding: 0.7rem clamp(1rem, 4vw, 2.5rem);
  background: linear-gradient(180deg, oklch(0.11 0.04 50 / 0.92), oklch(0.11 0.04 50 / 0.62));
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--border);
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  font-family: var(--font-deco);
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  font-size: 0.86rem;
  color: var(--fg);
  text-decoration: none;
}
.brand svg {
  width: 24px;
  height: 24px;
  color: var(--gold);
}

.site-head nav {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1.15rem;
  font-size: 0.86rem;
}
.site-head nav a {
  text-decoration: none;
  color: var(--muted);
  letter-spacing: 0.03em;
}
.site-head nav a:hover {
  color: var(--flame-bright);
}
.site-head nav a.gh {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.5rem 0.95rem;
  border-radius: var(--radius-pill);
  font-family: var(--font-display);
  font-weight: 600;
  color: oklch(0.99 0.005 52);
  border: 1px solid oklch(0.65 0.22 55 / 0.5);
  background: linear-gradient(180deg, oklch(0.5 0.2 55), oklch(0.38 0.18 55));
  transition: 0.2s;
}
.site-head nav a.gh:hover {
  transform: translateY(-1px);
  box-shadow: 0 0 0 1px oklch(0.8 0.22 55 / 0.6), 0 6px 20px -6px oklch(0.7 0.24 55 / 0.5);
}
.site-head nav a.gh svg {
  width: 15px;
  height: 15px;
}

.site-foot {
  position: relative;
  z-index: 1;
  border-top: 1px solid var(--border);
  margin-top: 4rem;
  padding: 2.5rem clamp(1rem, 4vw, 2.5rem);
  color: var(--muted);
  font-size: 0.9rem;
  text-align: center;
}
.site-foot p {
  margin: 0.4rem 0;
}

/* ---------- landing ---------- */

main {
  position: relative;
  z-index: 1;
  display: block;
}

.hero {
  max-width: var(--maxw);
  margin: 0 auto;
  padding: clamp(2.5rem, 7vw, 4.5rem) clamp(1rem, 4vw, 2.5rem) 2rem;
  text-align: center;
}
.sigil-ring.inner {
  inset: 8%;
  color: var(--accent);
  opacity: 0.4;
  animation: slow-spin 90s linear infinite reverse;
}

.hero h1 {
  font-family: var(--font-deco);
  font-weight: 900;
  letter-spacing: 0.02em;
  font-size: clamp(1.9rem, 4.6vw, 3.1rem);
  line-height: 1.15;
  margin: 0.15em 0 0.35em;
  background: linear-gradient(180deg, oklch(0.98 0.02 55), oklch(0.86 0.14 55) 55%, oklch(0.7 0.2 55));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  animation: brand-pulse 4s ease-in-out infinite;
}

.eyebrow {
  margin: 0 0 0.75rem;
  font-family: var(--font-display);
  font-size: 0.76rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--accent);
}

.lede {
  max-width: 44rem;
  margin: 0 auto 2rem;
  font-family: var(--font-serif);
  font-size: clamp(1.15rem, 2.2vw, 1.4rem);
  line-height: 1.6;
  color: oklch(0.88 0.03 50);
}

/* The second lede line is the turn, not more of the same sentence: the first
   paragraph explains the machinery, this one says what the machinery buys you.
   Set apart with a rule and the accent colour so it reads as a beat rather
   than as a fourth clause nobody finishes. */
.lede-2 {
  margin-top: -1rem;
  padding-left: 1rem;
  border-left: 2px solid var(--gold);
  color: var(--flame-bright, oklch(0.8 0.12 45));
  font-style: italic;
}


.cta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.85rem;
  justify-content: center;
  margin: 0 0 1.25rem;
}

.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-family: var(--font-display);
  font-weight: 600;
  letter-spacing: 0.05em;
  font-size: 0.9rem;
  padding: 0.8rem 1.6rem;
  border-radius: var(--radius-pill);
  text-decoration: none;
  transition: 0.25s;
  color: var(--fg);
  border: 1px solid var(--border);
  background: oklch(0.18 0.05 50 / 0.6);
}
.btn:hover {
  border-color: var(--flame);
  color: var(--flame-bright);
}
.btn.primary {
  color: oklch(0.99 0.005 52);
  border-color: oklch(0.65 0.22 55 / 0.6);
  background: linear-gradient(180deg, oklch(0.5 0.2 55), oklch(0.38 0.18 55));
  animation: spell-charge 3.6s ease-in-out infinite;
}
.btn.primary:hover {
  animation-play-state: paused;
  transform: translateY(-1px);
  color: oklch(0.99 0.005 52);
  box-shadow: 0 0 0 1px oklch(0.85 0.22 55 / 0.7), 0 12px 32px -4px oklch(0.7 0.24 55 / 0.6);
}

.runestones {
  display: flex;
  gap: 0.6rem;
  justify-content: center;
  flex-wrap: wrap;
  margin: 0;
  padding: 0;
  list-style: none;
}
.runestones li {
  font-size: 0.71rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
  padding: 0.35rem 0.85rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  background: oklch(0.16 0.05 50 / 0.6);
}
.runestones b {
  color: var(--gold);
  font-weight: 700;
}


/* ---- Which accent, and when ------------------------------------------
   Three accents on one page only works if each means something. The split
   is borrowed from the object the site is about — a manuscript, where the
   body text is one colour and the scribe’s marginal notes are rubricated
   in another.

     --flame / --flame-bright   the product speaking. Anything
                                  interactive, and any structure the
                                  software itself imposes: buttons, links,
                                  the pipeline’s own steps, panel edges.

     --accent                      a person speaking. The maintainer’s
                                  voice, annotations on a sample, an
                                  attribution, and warnings — which are the
                                  strongest form of someone telling you
                                  something.

     --gold                       the mark itself. The brand glyph and the
                                  runestone facts beneath the hero, and
                                  nothing else. Gold is not a third accent
                                  to reach for.

   A colour that means two things means neither, so before using one of
   these, decide which of the three is doing the talking. */

/* Rune divider between sections. */
.rune {
  display: flex;
  align-items: center;
  gap: 1rem;
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 0 clamp(1rem, 4vw, 2.5rem);
  color: var(--flame);
  opacity: 0.8;
}
.rune::before,
.rune::after {
  content: "";
  flex: 1;
  height: 1px;
  background: linear-gradient(90deg, transparent, oklch(0.65 0.22 55 / 0.55), transparent);
}
.rune svg {
  width: 20px;
  height: 20px;
  filter: drop-shadow(0 0 6px oklch(0.7 0.22 55 / 0.55));
}

.section {
  max-width: var(--maxw);
  margin: 0 auto;
  padding: clamp(2.25rem, 5vw, 3.25rem) clamp(1rem, 4vw, 2.5rem);
}

/* Section headings are a light-weight serif at a large size with leading near
 * 1.0, rather than a heavy display face letterspaced into a title. The effect
 * is that a long sentence-case heading reads as a *sentence* — which is what
 * lets the copy say "Two ways in, one chronicle out" instead of "Workflows".
 * Cinzel is kept for the wordmark and the eyebrows, where the carved look is
 * the point; at paragraph-heading size it fights the text underneath it. */
.section > h2 {
  text-align: center;
  font-family: var(--font-serif);
  font-weight: 400;
  letter-spacing: -0.005em;
  font-size: clamp(1.85rem, 4vw, 2.7rem);
  line-height: 1.06;
  max-width: 30ch;
  margin-inline: auto;
  margin-bottom: 0.6rem;
  text-wrap: balance;
}

.section-lede {
  max-width: var(--measure);
  margin: 0 auto 2.5rem;
  text-align: center;
  line-height: 1.55;
  color: var(--muted);
  text-wrap: pretty;
}

.tag {
  display: inline-block;
  vertical-align: middle;
  margin-left: 0.5rem;
  padding: 0.12rem 0.55rem;
  border-radius: var(--radius-pill);
  background: oklch(0.3 0.1 55 / 0.35);
  border: 1px solid oklch(0.5 0.14 55 / 0.6);
  color: var(--flame-bright);
  font-family: var(--font-sans);
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.tier.critical {
  --tier-colour: oklch(0.68 0.19 25);
}
.tier.advised {
  --tier-colour: var(--accent);
}
.tier.nice {
  --tier-colour: oklch(0.72 0.15 155);
}

/* Expectation-setting callouts. `.warn` is the ember variant, used where a
 * reader could otherwise waste an evening finding out the hard way. */
.notice {
  margin-top: 1.5rem;
  padding: var(--panel-pad-tight);
  border-radius: var(--panel-r);
  border: 1px solid var(--border);
  border-left: 3px solid var(--flame);
  background: oklch(0.16 0.05 50 / 0.7);
}
.notice.warn {
  border-left-color: var(--accent);
  background: oklch(0.18 0.06 50 / 0.16);
}
.notice h3 {
  margin: 0 0 0.5rem;
  font-size: 1.02rem;
  letter-spacing: 0.02em;
  color: var(--fg);
}
.notice.warn h3 {
  color: var(--accent);
}
.notice p {
  margin: 0 0 0.7rem;
  color: var(--muted);
  font-size: 0.95rem;
}
.notice p:last-child {
  margin-bottom: 0;
}
.notice strong {
  color: var(--fg);
}

.caveats {
  margin: 0.5rem 0 0;
  padding-left: 1.1rem;
  color: var(--muted);
  font-size: 0.95rem;
}
.caveats li {
  margin-bottom: 0.5rem;
}
.caveats strong {
  color: var(--fg);
}

.table-wrap {
  overflow-x: auto;
  /* Same reason as .matrix-wrap: any absolutely-positioned descendant of a
     too-wide table — a visually-hidden label, a tooltip — resolves against
     the nearest positioned ancestor, and if that is not this box it escapes
     the scroller and widens the document instead. */
  position: relative;
  margin-top: 1.5rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--card);
}

table {
  border-collapse: collapse;
  width: 100%;
  min-width: 34rem;
  font-size: 0.93rem;
}
caption {
  caption-side: top;
  text-align: left;
  padding: 0.85rem 1rem;
  color: var(--muted);
  font-size: 0.85rem;
}
th,
td {
  text-align: left;
  padding: 0.7rem 1rem;
  border-top: 1px solid var(--border);
  vertical-align: top;
}
thead th {
  background: var(--card2);
  color: var(--fg);
  font-family: var(--font-display);
  letter-spacing: 0.04em;
}
tbody th {
  color: var(--fg);
  font-weight: 600;
}
tbody td {
  color: var(--muted);
}
tbody tr:nth-child(even) td {
  background: oklch(0.16 0.05 50 / 0.5);
}

.faq {
  max-width: 48rem;
  margin: 1.5rem auto 0;
}


.doc-index {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: 1.5rem;
  margin-top: 1.5rem;
}
.doc-group h3 {
  font-size: 0.78rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 0.6rem;
}
.doc-group ul {
  list-style: none;
  margin: 0;
  padding: 0;
  font-size: 0.93rem;
}
.doc-group li {
  margin-bottom: 0.35rem;
}

/* ---------- V · the walkthrough (video facade + pending state) ---------- */

.video {
  position: relative;
  margin-top: 1.5rem;
  border: 1px solid var(--border);
  border-radius: var(--panel-r);
  overflow: hidden;
  background: #000;
  aspect-ratio: 16 / 9;
}
.video iframe {
  width: 100%;
  height: 100%;
  border: 0;
  display: block;
}
.video-play {
  display: block;
  width: 100%;
  height: 100%;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  position: relative;
}
.video-play img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0.6;
  display: block;
}
.video-btn {
  position: absolute;
  inset: 0;
  margin: auto;
  width: 5rem;
  height: 3.5rem;
  border-radius: 12px;
  background: linear-gradient(180deg, oklch(0.6 0.22 55), oklch(0.42 0.18 55));
  box-shadow: 0 0 24px oklch(0.65 0.22 55 / 0.55), 0 0 0 1px oklch(0.75 0.22 55 / 0.6);
}
.video-btn::after {
  content: "";
  position: absolute;
  inset: 0;
  margin: auto;
  width: 0;
  height: 0;
  border-style: solid;
  border-width: 0.65rem 0 0.65rem 1.1rem;
  border-color: transparent transparent transparent oklch(0.99 0.005 52);
}
.video-play:hover .video-btn {
  background: linear-gradient(180deg, oklch(0.72 0.22 55), oklch(0.5 0.2 55));
}
.video-note {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0.6rem;
  color: oklch(0.9 0.02 50);
  font-size: 0.78rem;
  text-shadow: 0 1px 4px #000;
}
.video-compact .video-btn {
  width: 3.5rem;
  height: 2.5rem;
}
.video-compact .video-btn::after {
  border-width: 0.5rem 0 0.5rem 0.8rem;
}

/* A guide video embedded in a documentation page, under the heading it
   illustrates. The player itself reuses .video; this only supplies the
   surrounding spacing and the caption, so the two surfaces cannot drift
   apart visually. Margins are larger than a paragraph's because the video
   is a step in the procedure, not an illustration beside one. */
.doc-video {
  margin: 1.75rem 0 2rem;
}
.doc-video .video {
  margin-top: 0;
}
.doc-video-cap {
  margin: 0.6rem 0 0;
  color: var(--muted);
  font-size: 0.86rem;
  line-height: 1.5;
}

/* Chapter index under the demo player. Timestamps are monospaced and
 * fixed-width so the labels line up into a readable column. */
.chapters {
  margin-top: 1.25rem;
  padding: var(--panel-pad-tight);
  border: 1px solid var(--border);
  border-radius: var(--panel-r);
  background: oklch(0.16 0.05 50 / 0.6);
}
.chapters h3 {
  margin: 0 0 0.6rem;
  font-family: var(--font-display);
  font-size: 0.76rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--accent);
}
.chapter-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: 0.15rem 1.5rem;
}
.chapter {
  display: flex;
  align-items: baseline;
  gap: 0.75rem;
  width: 100%;
  padding: 0.4rem 0.55rem;
  border: 0;
  border-radius: 7px;
  background: none;
  color: var(--muted);
  font: inherit;
  font-size: 0.93rem;
  text-align: left;
  cursor: pointer;
  transition: 0.15s;
}
.chapter:hover {
  background: oklch(0.22 0.06 52 / 0.6);
  color: var(--fg);
}
.chapter[aria-current='true'] {
  background: oklch(0.22 0.06 52 / 0.8);
  color: var(--flame-bright);
}
.chapter-time {
  flex: none;
  min-width: 3.2rem;
  font-family: var(--font-mono);
  font-size: 0.85rem;
  color: var(--flame-bright);
  font-variant-numeric: tabular-nums;
}
.chapter[aria-current='true'] .chapter-time {
  color: var(--accent);
}

/* The same chapters before the video exists: an outline, not a control strip.
 * Ordinals rather than timestamps, and the blurbs shown — with nothing to play,
 * what the walkthrough covers is the useful part, and it doubles as a summary
 * of the workflow. Nothing here is clickable, so nothing here looks clickable. */
.chapters.is-outline {
  margin-top: 1.25rem;
}
.chapters.is-outline .chapter-list {
  gap: 0.9rem 1.75rem;
}
.chapter-step {
  display: grid;
  grid-template-columns: 1.6rem minmax(0, 1fr);
  align-items: baseline;
  gap: 0.1rem 0.7rem;
}
.chapter-ord {
  grid-row: 1 / span 2;
  font-family: var(--font-display);
  font-size: 0.85rem;
  color: var(--flame-bright);
  font-variant-numeric: tabular-nums;
}
.chapter-step .chapter-label {
  color: var(--fg);
  font-size: 0.95rem;
}
.chapter-blurb {
  color: var(--muted);
  font-family: var(--font-serif);
  font-size: 0.95rem;
  line-height: 1.35;
}

.clip {
  margin: 1.25rem 0 0;
}
.clip-time {
  display: inline-block;
  margin-right: 0.5rem;
  padding: 0.08rem 0.45rem;
  border-radius: 5px;
  background: oklch(0.3 0.1 55 / 0.35);
  border: 1px solid oklch(0.5 0.14 55 / 0.5);
  color: var(--flame-bright);
  font-family: var(--font-mono);
  font-size: 0.78rem;
  font-variant-numeric: tabular-nums;
}
.clip figcaption {
  margin-top: 0.6rem;
  font-size: 0.85rem;
  color: var(--muted);
  font-family: var(--font-display);
  letter-spacing: 0.02em;
}

/* The section before there is a video in it.
 *
 * Deliberately the same 16:9 footprint the player will occupy, so the space is
 * visibly held rather than missing — and deliberately WITHOUT a play triangle,
 * which would invite a click that does nothing. Corner marks instead: a frame
 * waiting for a plate reads as intent; a dashed box reads as an unfinished
 * page. */
.video-pending {
  margin-top: 1.5rem;
}
.video-pending-frame {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  aspect-ratio: 16 / 9;
  padding: 2rem 1.5rem;
  border: 1px solid var(--border);
  border-radius: var(--panel-r);
  text-align: center;
  background:
    radial-gradient(120% 90% at 50% 100%, oklch(0.3 0.11 55 / 0.35), transparent 65%),
    var(--card);
}
/* Registration marks, one pseudo-element per diagonal pair. */
.video-pending-frame::before,
.video-pending-frame::after {
  content: "";
  position: absolute;
  width: 1.6rem;
  height: 1.6rem;
  border: 2px solid oklch(0.55 0.16 55 / 0.7);
}
.video-pending-frame::before {
  top: 0.9rem;
  left: 0.9rem;
  border-right: 0;
  border-bottom: 0;
  border-top-left-radius: 6px;
}
.video-pending-frame::after {
  right: 0.9rem;
  bottom: 0.9rem;
  border-left: 0;
  border-top: 0;
  border-bottom-right-radius: 6px;
}
.video-pending-tag {
  margin: 0;
  font-family: var(--font-display);
  font-size: 0.72rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--accent);
}
.video-pending-title {
  margin: 0;
  font-family: var(--font-deco);
  font-size: clamp(1.15rem, 2.6vw, 1.6rem);
  color: var(--fg);
  text-wrap: balance;
}
.video-pending-sub {
  margin: 0;
  max-width: 34rem;
  color: var(--muted);
  font-family: var(--font-serif);
  font-size: 1.02rem;
}
.video-pending-alt {
  margin: 0.85rem 0 0;
  color: var(--muted);
  font-size: 0.92rem;
}

/* ---------- docs pages ---------- */

.docs-layout {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: 16rem minmax(0, 1fr);
  gap: clamp(1.5rem, 4vw, 3rem);
  max-width: 80rem;
  margin: 0 auto;
  padding: 2rem clamp(1rem, 4vw, 2.5rem);
  align-items: start;
}

@media (max-width: 60rem) {
  .docs-layout {
    grid-template-columns: minmax(0, 1fr);
  }
  .docs-nav {
    position: static !important;
    max-height: none !important;
    border-right: 0 !important;
  }
}

.docs-nav {
  position: sticky;
  top: 4.5rem;
  max-height: calc(100vh - 6.5rem);
  overflow-y: auto;
  font-size: 0.9rem;
  border-right: 1px solid var(--border);
  padding-right: 1rem;
}
.docs-nav h2 {
  font-family: var(--font-display);
  font-size: 0.72rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--accent);
  margin: 1.5rem 0 0.5rem;
}
.docs-nav h2:first-child {
  margin-top: 0;
}
.docs-nav ul {
  list-style: none;
  margin: 0;
  padding: 0;
}
.docs-nav a {
  display: block;
  padding: 0.28rem 0.55rem;
  border-radius: 6px;
  color: var(--muted);
  text-decoration: none;
}
.docs-nav a:hover {
  background: oklch(0.22 0.06 52 / 0.55);
  color: var(--flame-bright);
}
.docs-nav a[aria-current="page"] {
  background: oklch(0.22 0.06 52 / 0.7);
  color: var(--flame-bright);
  font-weight: 600;
}

.crumbs {
  font-size: 0.83rem;
  color: var(--muted);
  margin-bottom: 1.25rem;
}
.crumbs a {
  text-decoration: none;
}

.toc {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1rem 1.25rem;
  margin-bottom: 2rem;
}
.toc h2 {
  font-family: var(--font-display);
  font-size: 0.72rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--accent);
  margin: 0 0 0.5rem;
}
.toc ul {
  margin: 0;
  padding-left: 1.1rem;
  font-size: 0.9rem;
  columns: 2;
  column-gap: 2rem;
}
@media (max-width: 45rem) {
  .toc ul {
    columns: 1;
  }
}
.toc li {
  margin: 0.2rem 0;
  break-inside: avoid;
}

.prose {
  max-width: 46rem;
}
.prose h1 {
  font-family: var(--font-deco);
  font-size: clamp(1.8rem, 3.8vw, 2.4rem);
  letter-spacing: 0.02em;
  margin-bottom: 0.6em;
  color: var(--fg);
}
.prose h2 {
  font-size: 1.5rem;
  margin-top: 2.2em;
  padding-bottom: 0.25rem;
  border-bottom: 1px solid oklch(0.32 0.07 52 / 0.6);
}
.prose h3 {
  font-size: 1.18rem;
  margin-top: 1.8em;
}
.prose h4 {
  font-size: 1.02rem;
  margin-top: 1.5em;
}
.prose blockquote {
  margin: 1.5rem 0;
  padding: 0.6rem 1.2rem;
  border-left: 3px solid var(--flame);
  background: oklch(0.14 0.045 50 / 0.6);
  color: var(--muted);
  font-family: var(--font-serif);
  font-size: 1.08em;
}
.prose pre {
  background: var(--bg-deep);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1rem 1.2rem;
  overflow-x: auto;
}
.prose pre code {
  background: none;
  border: 0;
  padding: 0;
  font-size: 0.86rem;
  color: oklch(0.88 0.03 50);
}
.prose img {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  display: block;
  margin: 1.5rem 0;
}
.prose table {
  min-width: 0;
  display: block;
  overflow-x: auto;
}
.prose hr {
  border: 0;
  border-top: 1px solid var(--border);
  margin: 2.5rem 0;
}

.prose details {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--card);
  padding: 0.6rem 1.1rem;
  margin: 1.25rem 0;
}
.prose details summary {
  cursor: pointer;
  font-weight: 600;
  font-family: var(--font-display);
}
.prose details summary h2,
.prose details summary h3 {
  display: inline;
  border: 0;
  font-size: 1.1rem;
  margin: 0;
  padding: 0;
}

.edit-link {
  margin-top: 3rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--border);
  font-size: 0.88rem;
}

/* Bespoke motion is decoration — drop all of it when asked. */
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
  .hero h1,
  .btn.primary,
  .sigil-ring,
  .ember-field span,
  .card:hover,
  .site-head nav a.gh:hover {
    animation: none !important;
    transform: none !important;
  }
}
.tile:hover,

@media (prefers-reduced-motion: reduce) {
  .tile,
}

/* ---------------------------------------------------------------------------
   Documentation filter + index entries
   --------------------------------------------------------------------------- */
.doc-filter {
  margin: 0 0 1.75rem;
}
.doc-filter-label {
  display: block;
  font-size: 0.85rem;
  color: var(--muted);
  margin-bottom: 0.4rem;
}
.doc-filter input {
  width: 100%;
  max-width: 32rem;
  padding: 0.7rem 0.9rem;
  border-radius: 10px;
  border: 1px solid var(--border);
  background: var(--card);
  color: var(--fg);
  font: inherit;
  font-size: 0.95rem;
}
.doc-filter input::placeholder {
  color: var(--muted);
  opacity: 0.75;
}
.doc-filter input:focus-visible {
  outline: 2px solid var(--flame-bright);
  outline-offset: 1px;
  border-color: transparent;
}
.doc-filter-count {
  margin: 0.5rem 0 0;
  font-size: 0.85rem;
  color: var(--muted);
  /* Reserve the line so results appearing don't shove the list downward. */
  min-height: 1.2em;
}

.doc-item-note {
  display: block;
  font-size: 0.85rem;
  color: var(--muted);
  margin-top: 0.1rem;
  /* Summaries are one line of context, not a paragraph — keep them from
     wrapping into a wall that buries the links they describe. */
  line-height: 1.45;
}
.doc-index .doc-item + .doc-item,
.doc-group .doc-item + .doc-item {
  margin-top: 0.6rem;
}

/* One button per card, so the pair reads as a choice rather than a menu. */
.route .cta {
  justify-content: flex-start;
  margin: 1.2rem 0 0;
}

/* ===========================================================================
   Sample output
   ===========================================================================
   The one place on the site where the reader looks at the product's actual
   output rather than a description of it, so the styling gets out of the way:
   generated prose is set in the reading serif at the prose measure, and every
   piece of surrounding chrome — labels, counts, commentary — is set in the UI
   sans. A reader should never have to wonder which words the tool wrote. */

.samples {
  display: grid;
  gap: 1.25rem;
  margin-top: 1.75rem;
}

.sample {
  padding: var(--panel-pad);
  border-radius: var(--panel-r);
  background: linear-gradient(180deg, var(--card2), var(--card));
  border: 1px solid oklch(0.34 0.08 52);
  box-shadow:
    0 1px 0 oklch(0.55 0.16 55 / 0.18) inset,
    0 28px 56px -28px oklch(0.04 0.02 50 / 0.85);
}

.sample-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.4rem 0.85rem;
  padding-bottom: 1rem;
  margin-bottom: 1.4rem;
  border-bottom: 1px solid var(--border);
}

/* The sample cards are <details>, collapsed by default — see the site
   generator's sample() helper for why. Interaction styling mirrors
   the output tiles above so the two disclosure patterns on this page behave
   identically. */
.sample > summary {
  cursor: pointer;
  /* Default triangle can't be styled cross-browser and sits badly in a flex
     row; ::after below replaces it, exactly as the tiles do. */
  list-style: none;
}
.sample > summary::-webkit-details-marker {
  display: none;
}
.sample > summary:focus-visible {
  outline: 2px solid var(--flame-bright);
  outline-offset: -2px;
}

/* Closed, the header IS the whole card, so the rule beneath it would be a
   line to nowhere. It only earns its keep once there is body text under it. */
.sample:not([open]) > .sample-head {
  padding-bottom: 0;
  margin-bottom: 0;
  border-bottom: none;
}

/* .sample-meta keeps its auto left margin, so it still sits at the far end of
   the header and this chevron lands just outside it. */
.sample > summary::after {
  content: "";
  margin-left: 0.85rem;
  width: 0.5rem;
  height: 0.5rem;
  border-right: 2px solid var(--flame-bright);
  border-bottom: 2px solid var(--flame-bright);
  transform: rotate(45deg) translate(-2px, -2px);
  transition: transform 0.28s;
  flex: none;
  align-self: center;
}
.sample[open] > summary::after {
  transform: rotate(-135deg);
}

.sample-head h3 {
  margin: 0;
  font-family: var(--font-serif);
  font-weight: 400;
  font-size: 1.5rem;
  line-height: 1.1;
  color: var(--fg);
}

.sample-note {
  margin: 0;
  font-family: var(--font-mono);
  font-size: 0.7rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--flame-bright);
}

/* "4 of the 17 this session produced" — the honesty line. Pushed to the far
   end of the header so it reads as a footnote to the title rather than as a
   claim being made. */
.sample-meta {
  margin: 0 0 0 auto;
  font-size: 0.82rem;
  color: var(--muted);
}

.sample-body {
  max-width: var(--measure);
  font-family: var(--font-serif);
  font-size: 1.1rem;
  line-height: 1.66;
  color: oklch(0.9 0.025 50);
}

.sample-body p {
  margin: 0 0 1.1rem;
  text-wrap: pretty;
}

.sample-subhead {
  margin-top: 1.75rem;
  font-family: var(--font-mono);
  font-size: 0.7rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--flame-bright);
}

.sample-list,
.sample-bullets {
  margin: 0;
  padding-left: 1.25rem;
}

.sample-list li,
.sample-bullets li {
  margin-bottom: 0.9rem;
}

.sample-list li::marker,
.sample-bullets li::marker {
  color: var(--flame);
}

/* Commentary on the sample, not part of it. Sans-serif and rail-marked so it
   is unmistakably the site talking rather than more generated text — the one
   ambiguity that would undermine the whole section. */
.sample-callout {
  max-width: var(--measure);
  margin: 1.6rem 0 0;
  padding-left: 1rem;
  border-left: 2px solid var(--accent);
  font-family: var(--font-sans);
  font-size: 0.94rem;
  line-height: 1.6;
  color: var(--muted);
}

.provenance {
  max-width: 46rem;
  margin: 0 auto;
  padding: 1.6rem 1.7rem 1.2rem;
  border-radius: var(--panel-r);
  border: 1px dashed var(--border);
  background: oklch(0.14 0.04 50 / 0.6);
}

.provenance h3 {
  margin: 0 0 1rem;
  font-family: var(--font-mono);
  font-weight: 400;
  font-size: 0.72rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent);
}

.provenance p {
  font-size: 0.92rem;
  line-height: 1.6;
  color: var(--muted);
}

.provenance-note {
  padding-top: 0.9rem;
  border-top: 1px solid var(--border);
}

.provenance-note strong {
  color: var(--fg);
}

.quotes {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr));
  gap: 1rem;
}

.quote {
  display: flex;
  flex-direction: column;
  margin: 0;
  padding: 1.2rem 1.3rem 1rem;
  border-radius: var(--panel-r);
  background: oklch(0.13 0.035 50 / 0.75);
  border: 1px solid var(--border);
}

.quote blockquote {
  margin: 0;
  font-size: 1.02rem;
  line-height: 1.5;
  color: var(--fg);
}

.quote blockquote p {
  margin: 0;
}

/* funny · stupid · dark. A pill rather than a coloured border, because the
   three categories are equals and a colour scale would imply a ranking. */
.quote-kind {
  align-self: flex-start;
  margin-bottom: 0.7rem;
  padding: 0.15rem 0.6rem;
  border-radius: var(--radius-pill);
  font-family: var(--font-mono);
  font-size: 0.62rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--flame-bright);
  background: oklch(0.65 0.22 55 / 0.14);
  border: 1px solid oklch(0.65 0.22 55 / 0.3);
}

.quote-context {
  margin: 0 0 0.6rem;
  font-family: var(--font-sans);
  font-size: 0.8rem;
  line-height: 1.45;
  color: var(--muted);
}

/* An exchange keeps one line per turn, with the speaker in a fixed gutter, so
   the back-and-forth stays legible as a back-and-forth. Collapsing it into a
   run-on paragraph would destroy the only thing that makes it land. */
.quote-turns {
  display: grid;
  gap: 0.45rem;
}

.quote-turns p {
  display: grid;
  grid-template-columns: minmax(4.5rem, auto) 1fr;
  gap: 0.75rem;
  align-items: baseline;
}

.quote-turns b {
  font-family: var(--font-mono);
  font-weight: 400;
  font-size: 0.72rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--muted);
}

.quote-by {
  margin-top: 0.85rem;
  font-family: var(--font-sans);
  font-size: 0.82rem;
  color: var(--accent);
}

/* Local-review banner. Loud on purpose — it exists to be impossible to miss in
   a preview build, and the publish step refuses to push any page carrying it. */
.notice.unapproved {
  max-width: 46rem;
  margin: 0 auto 1.5rem;
  border-style: dashed;
}

@media (max-width: 45rem) {
  .sample-meta {
    margin-left: 0;
  }
  .quote-turns p {
    grid-template-columns: 1fr;
    gap: 0.15rem;
  }
}

/* The site's own voice, inside a sample card — 'a quiet scene first: …'.
   Sans-serif and quieter than the extract it introduces, so the boundary
   between our words and generated prose is never ambiguous. */
.sample-intro {
  max-width: var(--measure);
  margin: 0 0 1.4rem !important;
  font-family: var(--font-sans) !important;
  font-size: 0.92rem !important;
  line-height: 1.6;
  color: var(--muted);
}

.sample-body p + .sample-intro {
  margin-top: 2rem !important;
  padding-top: 1.6rem;
  border-top: 1px solid var(--border);
}

.sample-body em {
  font-style: italic;
  color: var(--fg);
}

.sample-bullets strong,
.sample-body strong {
  color: var(--fg);
  font-weight: 600;
}
/* ---------- collapsible FAQ ---------- */

.faq-item {
  border-bottom: 1px solid var(--border);
}
.faq-item:first-of-type {
  border-top: 1px solid var(--border);
}

.faq-item > summary {
  cursor: pointer;
  list-style: none;
  display: flex;
  align-items: baseline;
  gap: 0.9rem;
  padding: 1.05rem 0.2rem;
  font-family: var(--font-display);
  font-size: 1.02rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--fg);
}
.faq-item > summary::-webkit-details-marker {
  display: none;
}
.faq-item > summary:focus-visible {
  outline: 2px solid var(--flame-bright);
  outline-offset: -2px;
}
.faq-item > summary::after {
  content: "";
  flex: 0 0 auto;
  margin-left: auto;
  width: 0.45rem;
  height: 0.45rem;
  border-right: 2px solid var(--flame-bright);
  border-bottom: 2px solid var(--flame-bright);
  transform: rotate(-45deg);
  transition: transform 0.2s ease;
}
.faq-item[open] > summary::after {
  transform: rotate(45deg);
}
.faq-item[open] > summary {
  color: var(--flame-bright);
}

.faq-answer {
  padding: 0 0.2rem 1.25rem;
  max-width: var(--measure);
  color: var(--muted);
  line-height: 1.65;
}
.faq-answer p:first-child {
  margin-top: 0;
}

/* Deep-linked entry — browsers open a targeted <details> automatically, so
   this only needs to mark which one the link landed on. */
.faq-item:target > summary {
  color: var(--flame-bright);
}

/* ---------- collapsible documentation index ---------- */

.doc-group {
  border-bottom: 1px solid var(--border);
}
.doc-group > summary {
  cursor: pointer;
  list-style: none;
  display: flex;
  align-items: center;
  padding: 0.85rem 0.2rem;
}
.doc-group > summary::-webkit-details-marker {
  display: none;
}
.doc-group > summary:focus-visible {
  outline: 2px solid var(--flame-bright);
  outline-offset: -2px;
}
.doc-group > summary h3 {
  margin: 0;
  display: flex;
  align-items: center;
  gap: 0.6rem;
}
.doc-group > summary::after {
  content: "";
  flex: 0 0 auto;
  margin-left: auto;
  width: 0.45rem;
  height: 0.45rem;
  border-right: 2px solid var(--flame-bright);
  border-bottom: 2px solid var(--flame-bright);
  transform: rotate(-45deg);
  transition: transform 0.2s ease;
}
.doc-group[open] > summary::after {
  transform: rotate(45deg);
}

/* How many pages are behind the heading — otherwise a closed group gives no
   sense of whether it is worth opening. */
.doc-count {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0;
  padding: 0.05rem 0.45rem;
  border-radius: var(--radius-pill);
  color: var(--muted);
  background: oklch(0.65 0.22 55 / 0.12);
  border: 1px solid var(--border);
}

.doc-group > ul {
  padding-bottom: 1rem;
}

@media (prefers-reduced-motion: reduce) {
  .faq-item > summary::after,
  .doc-group > summary::after {
    transition: none;
  }
}

/* ---------------------------------------------------------------------------
   Docs callouts
   ---------------------------------------------------------------------------
   The documentation carries no emoji. Colour is the only thing separating
   "this can break something" from "this got easier", so these need to read at
   a glance without relying on an icon.

   Markup is produced by the site generator's renderAlerts(), which
   rewrites GitHub's `> [!CAUTION]` alert syntax. github.com renders that same
   syntax natively in the same colours, and the in-app Help tab applies an
   equivalent rewrite — so one .md source is correct in all three places.

   These rules sit after .prose blockquote deliberately: an alert is no longer
   a blockquote by the time it reaches the page, but keeping the declaration
   order stable makes the relationship obvious to the next person editing. */
.docs-alert {
  --docs-alert-hue: var(--border);
  margin: 1.5rem 0;
  padding: 0.9rem 1.2rem;
  border-left: 3px solid var(--docs-alert-hue);
  border-radius: var(--radius);
  background: color-mix(in oklab, var(--docs-alert-hue) 10%, transparent);
}
.docs-alert > .docs-alert-label {
  font-family: var(--font-display);
  font-size: 0.74rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--docs-alert-hue);
  margin-bottom: 0.35rem;
}
/* Prose inside the callout keeps normal reading contrast — tinting a whole
   paragraph to match the label makes long callouts harder to read. */
.docs-alert > p:first-of-type {
  margin-top: 0;
}
.docs-alert > :last-child {
  margin-bottom: 0;
}

/* Body prose picks up the callout's hue. Mixing toward the foreground rather
   than using the hue neat keeps a long callout readable — fully saturated
   paragraph text is the reason coloured callouts usually fail. Emphasis and
   inline code go the other way and take the hue at close to full strength, so
   the important half of a sentence still lands. */
.docs-alert {
  color: color-mix(in oklab, var(--docs-alert-hue) 34%, var(--fg));
}
.docs-alert strong,
.docs-alert b {
  color: color-mix(in oklab, var(--docs-alert-hue) 72%, var(--fg));
  font-weight: 650;
}
.docs-alert em,
.docs-alert i {
  color: color-mix(in oklab, var(--docs-alert-hue) 60%, var(--fg));
}
.docs-alert code {
  color: color-mix(in oklab, var(--docs-alert-hue) 78%, var(--fg));
  background: color-mix(in oklab, var(--docs-alert-hue) 14%, transparent);
}
.docs-alert a {
  color: color-mix(in oklab, var(--docs-alert-hue) 82%, var(--fg));
  text-decoration-color: color-mix(in oklab, var(--docs-alert-hue) 50%, transparent);
}
.docs-alert li::marker {
  color: var(--docs-alert-hue);
}

/* Red — a warning. Something can break, cost money, or lose data. */
.docs-alert-caution { --docs-alert-hue: oklch(0.68 0.20 25); }
/* Orange — a notice. A caveat worth reading before you act. */
.docs-alert-warning { --docs-alert-hue: var(--accent); }
/* Green — streamlined. Something that got simpler, faster, or automatic. */
.docs-alert-tip { --docs-alert-hue: oklch(0.72 0.17 150); }
/* Blue — a neutral aside. */
.docs-alert-note { --docs-alert-hue: oklch(0.70 0.14 240); }
/* Amethyst — load-bearing detail that is easy to miss. */
.docs-alert-important { --docs-alert-hue: var(--flame-bright); }

/* A heading that divides a section without starting a new one — used where two
   former sections were merged and the seam still needs marking. */
.subhead {
  font-family: var(--font-display);
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--flame-bright);
  margin: 2.6rem 0 0.6rem;
}

/* Documentation hand-off, folded into the closing call to action so the last
   thing on the page offers somewhere to go rather than ending flat. */
.closing-docs {
  margin-top: 2.4rem;
  padding-top: 1.6rem;
  border-top: 1px solid var(--border);
}

/* ===========================================================================
   THE RULED PAGE — landing layout system
   ===========================================================================
   One grid for the whole page, and everything hangs off it.

   A manuscript is organised by a ruled margin and a text block. That is the
   through-line this page was missing: previously each section arrived with its
   own centred heading, its own centred lede and its own grid, so nine sections
   read as nine designs that happened to share a palette.

   Here, every section is a `.leaf` — a two-column grid of a narrow ruled
   margin and a body at a fixed measure. The margin carries the section
   numeral, its label, and occasionally a note in the maintainer's own voice.
   The rule down the margin is continuous in the eye from section to section,
   which is what makes them read as one document.

   Alignment is LEFT, deliberately. Centred text is the single strongest
   contributor to the "generic landing page" feeling, and a manuscript does not
   centre its body copy.

   Panels appear in exactly one place — section IV, where the reader is
   genuinely choosing between two options. Everywhere else, structure is space
   and rules. That is the discipline that stops a tenth container idiom being
   invented next time.
   =========================================================================== */

.landing main {
  --leaf-rail: 8.5rem;
  --leaf-gap: 2.75rem;
  --leaf-measure: 62ch;
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 0 1.5rem;
}

/* ---------- the leaf ---------- */

.leaf {
  display: grid;
  grid-template-columns: var(--leaf-rail) minmax(0, 1fr);
  gap: 0 var(--leaf-gap);
  padding: 4.25rem 0;
  border-top: 1px solid var(--border);
}

.leaf:first-of-type { border-top: 0; }

/* The ruled margin. Sticky so the numeral stays with you while you read the
   section it belongs to — the page's one piece of motion, and it is doing a
   navigational job rather than decorating. */
.rail {
  position: sticky;
  top: 5.5rem;
  align-self: start;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding-right: var(--leaf-gap);
  border-right: 1px solid var(--border);
  text-align: right;
}

.numeral {
  font-family: var(--font-display);
  font-size: 1.5rem;
  font-weight: 600;
  line-height: 1;
  color: var(--gold);
  font-variant-numeric: tabular-nums;
}

.rail-label {
  margin: 0;
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  line-height: 1.35;
  color: var(--muted);
}

.leaf-body > * + * { margin-top: 1.15rem; }

/* h1 shares this exactly. The examples page is a standalone page rather than a
   section of the landing page, so its top heading is an <h1> — a page whose
   highest heading is an <h2> has no document title for a screen reader or a
   search engine to anchor on. The two selectors are one rule so promoting the
   tag changed the semantics and nothing about the appearance. */
.leaf-body h1,
.leaf-body h2 {
  font-family: var(--font-serif);
  font-weight: 400;
  font-size: clamp(1.9rem, 3.4vw, 2.6rem);
  line-height: 1.14;
  letter-spacing: -0.01em;
  margin: 0 0 1.35rem;
  max-width: 22ch;
  text-wrap: balance;
  color: var(--fg);
}

/* A sub-heading inside a leaf. Sized well below the section h2 so it reads
   as a turn within the argument rather than the start of a new one, and set
   in the display face the rail labels use so it does not compete with the
   serif h2 above it. */
.trust-sub {
  font-family: var(--font-display, var(--font-serif));
  font-weight: 600;
  font-size: 1.12rem;
  letter-spacing: 0.01em;
  line-height: 1.3;
  margin: 2.25rem 0 0.9rem;
  color: var(--fg);
  max-width: var(--leaf-measure);
}

.leaf-body .measure {
  max-width: var(--leaf-measure);
  margin-left: 0;
  margin-right: 0;
  color: var(--muted);
  font-size: 1.03rem;
  line-height: 1.68;
}

.leaf-body .measure strong { color: var(--fg); font-weight: 600; }

.outro { margin-top: 2rem; }
.outro a { white-space: nowrap; }

/* A note in the maintainer's voice, set as marginalia would be: rubricated,
   in the book's own serif, and never the same weight as the body. */
.marginalia {
  max-width: var(--leaf-measure);
  margin-top: 2rem;
  padding-left: 1.1rem;
  border-left: 2px solid oklch(0.72 0.19 50 / 0.5);
  font-family: var(--font-serif);
  font-size: 1.16rem;
  line-height: 1.55;
  color: var(--accent);
}

.marginalia a { color: inherit; }

.marginalia .sign {
  display: block;
  margin-top: 0.35rem;
  font-family: var(--font-script);
  font-size: 1.3rem;
  color: oklch(0.8 0.14 55);
}

/* ---------- hero ---------- */

.landing .hero {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
  gap: 3.5rem;
  align-items: center;
  padding: 4.5rem 0 5rem;
  text-align: left;
}

.hero-text .eyebrow {
  margin: 0 0 1.1rem;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--accent);
}

.landing .hero h1 {
  font-family: var(--font-deco);
  font-weight: 700;
  font-size: clamp(2.5rem, 5.4vw, 4rem);
  line-height: 1.04;
  letter-spacing: -0.015em;
  margin: 0 0 1.4rem;
  max-width: 15ch;
  text-wrap: balance;
  color: var(--fg);
}

.landing .hero .lede {
  max-width: 46ch;
  margin: 0 0 2rem;
  font-size: 1.1rem;
  line-height: 1.62;
  color: var(--muted);
}

.landing .hero .cta { justify-content: flex-start; margin: 0; }

.landing .runestones {
  justify-content: flex-start;
  margin-top: 2.25rem;
}

/* ---------- the grounding figure (hero) ---------- */
/* Two states of one line. The whole product, in the space of a caption. */

.grounding {
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 0;
}

.grounding-row {
  padding: 1.35rem 1.5rem;
  border: 1px solid var(--border);
  background: oklch(0.13 0.04 50 / 0.7);
}

.grounding-row.is-before {
  border-radius: var(--panel-r) var(--panel-r) 0 0;
  border-bottom: 0;
}

.grounding-row.is-after {
  border-radius: 0 0 var(--panel-r) var(--panel-r);
  border-top: 0;
  background: oklch(0.15 0.05 50 / 0.85);
  box-shadow: inset 0 0 0 1px oklch(0.55 0.16 55 / 0.22);
}

.grounding-label {
  margin: 0 0 0.55rem;
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
}

.grounding-line {
  margin: 0;
  font-family: var(--font-serif);
  font-size: 1.18rem;
  line-height: 1.5;
  color: var(--fg);
}

/* Wrong, but not shouted about — a strikethrough would make the reader parse
   an edit. A dotted underline reads as "this is the bit that was off". */
.mis {
  color: var(--muted);
  text-decoration: underline dotted oklch(0.72 0.19 50 / 0.75);
  text-underline-offset: 0.25em;
}

.fix {
  color: var(--flame-bright);
  font-weight: 500;
}

/* The seam between the two states, carrying the label for what happens there. */
.grounding-arrow {
  position: relative;
  display: flex;
  justify-content: center;
  border-inline: 1px solid var(--border);
  background: oklch(0.13 0.04 50 / 0.7);
}

.grounding-arrow::before {
  content: '';
  position: absolute;
  inset-inline: 1.5rem;
  top: 50%;
  border-top: 1px dashed oklch(0.45 0.1 50);
}

.grounding-arrow span {
  position: relative;
  padding: 0.3rem 0.9rem;
  border: 1px solid oklch(0.42 0.12 50);
  border-radius: var(--radius-pill);
  background: var(--bg-deep);
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--flame-bright);
}

.grounding figcaption {
  margin-top: 1rem;
  font-size: 0.88rem;
  line-height: 1.55;
  color: var(--muted);
}

/* ---------- III · the matrix -----------------------------------------------

   A comparison grid, drawn to be believed rather than to win.

   Two decisions carry that. The crosses are muted rather than red: a table
   where every competitor row glows with failure reads as marketing, and the
   reader discounts the whole thing including the parts that are true. And the
   only emphasis anywhere is positional — our column gets a tinted ground, so
   its ticks stand out by where they are, not by being a different colour from
   everyone else's.

   Ticks are --flame because the accent means "the product speaking", and a
   capability claim is exactly that. Nothing here is --accent: no one is
   speaking, and this is not a warning. */

/* A labelled band inside the comparison grid. The grid used to be sixteen
   undifferentiated rows, and a reader had to get through all of them to find
   the four that were about their own concern. Grouping them puts the question
   a GM actually asks first (can my table use it, is it any fun) and the price
   last, and makes the block of rows this project loses a visible section
   rather than something to be discovered. */

/* The two-column ledger in section III.
   It replaced four paragraphs that narrated the comparison table sitting
   directly beneath them. Side by side is the point: what the other tool is
   not attempting, and what this one charges for being built differently,
   read as one trade rather than as a claim followed much later by a caveat.
   Stacks below 46rem, like every other pair on this page. */
.ledger {
  margin: 2rem 0 0;
}
.ledger-pair {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1rem;
}
.ledger-card {
  padding: 1.1rem 1.25rem 1.25rem;
  border: 1px solid var(--border);
  border-radius: var(--panel-r);
  background: var(--card);
}
/* The costs column is marked, not hidden. A reader skimming two boxes should
   be able to tell at a glance which one is the bill. */
.ledger-card.is-cost {
  border-color: oklch(0.42 0.11 40);
  background: oklch(0.14 0.035 40);
}
.ledger-head {
  margin: 0 0 0.7rem;
  font-family: var(--font-sans);
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--gold);
}
.ledger-card.is-cost .ledger-head {
  color: var(--accent-bright);
}
.ledger-card ul {
  margin: 0;
  padding-left: 1.05rem;
  list-style: none;
}
.ledger-card li {
  position: relative;
  margin: 0 0 0.5rem;
  font-size: 0.95rem;
  line-height: 1.45;
  color: oklch(0.85 0.025 60);
}
.ledger-card li:last-child {
  margin-bottom: 0;
}
.ledger-card li::before {
  content: "";
  position: absolute;
  left: -1.05rem;
  top: 0.6em;
  width: 0.34rem;
  height: 0.34rem;
  border-radius: 50%;
  background: var(--gold);
  opacity: 0.7;
}
.ledger-card.is-cost li::before {
  background: var(--accent);
  opacity: 0.9;
}
.ledger figcaption {
  max-width: 44rem;
  margin: 1rem 0 0;
  font-size: 0.9rem;
  line-height: 1.55;
  color: oklch(0.72 0.025 60);
}

@media (max-width: 46rem) {
  .ledger-pair { grid-template-columns: minmax(0, 1fr); }
}

.matrix-band th {
  padding-top: 1.5rem;
  font-family: var(--font-sans);
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--gold);
  background: oklch(0.15 0.035 50);
  border-top: 1px solid var(--border);
}

.matrix-wrap {
  /* The grid is wider than a phone and must stay a grid — reflowing a
     comparison into stacked cards loses the comparison. So it scrolls
     sideways inside its own box, and the page never does. */
  margin-top: 1.75rem;
  overflow-x: auto;
  /* Load-bearing, and not for stacking: `overflow-x: auto` alone did NOT keep
     the page from scrolling. The cells carry visually-hidden <span class="vh">
     labels ("Yes", "Partly") which are position:absolute, so their containing
     block was the nearest POSITIONED ancestor — which was not this box. They
     were laid out at the table's own coordinates, up to ~950px, escaped the
     clip entirely, and dragged the whole document sideways on a phone.
     Positioning this element makes it their containing block, so the overflow
     rule above finally applies to them too. */
  position: relative;
  border: 1px solid var(--border);
  border-radius: var(--panel-r);
  background: var(--card);
}
.matrix {
  /* Five comparison columns plus the row header. Below this the mark columns
     hit their 9.5rem floor and the row headings crush; the wrap scrolls. */
  min-width: 62rem;
  font-size: 0.92rem;
}
.matrix caption {
  font-family: var(--font-display);
  font-size: 0.74rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--accent);
  padding: 1rem 1.1rem 0.65rem;
}
.matrix thead th {
  background: transparent;
  vertical-align: bottom;
  font-size: 0.9rem;
  line-height: 1.25;
  border-bottom: 1px solid var(--border);
}
/* The mark columns size to their glyph, which would crush these headings to
   one word per line. Floor them instead and let the row-header column take
   whatever is left. */
.matrix thead th:not(:first-child) {
  min-width: 9.5rem;
}
.matrix thead th small {
  display: block;
  margin-top: 0.2rem;
  font-family: var(--font-sans);
  font-size: 0.74rem;
  letter-spacing: 0;
  font-weight: 400;
  color: var(--muted);
}
.matrix tbody th {
  font-weight: 400;
  color: var(--fg);
  max-width: 22rem;
}
.matrix td.m {
  text-align: center;
  width: 1%;
  white-space: nowrap;
}
/* The tinted column. Applied per-cell rather than with a column selector so
   the header, the marks and the cost line all share one edge. */
.matrix .is-us {
  background: oklch(0.24 0.075 50 / 0.55);
}
.matrix thead th.is-us {
  color: var(--flame-bright);
  border-bottom-color: oklch(0.55 0.18 55 / 0.7);
}
.mark {
  font-style: normal;
  font-size: 1.05rem;
  line-height: 1;
}
.mark.yes {
  color: var(--flame-bright);
}
.mark.no,
.mark.part,
.mark.na {
  color: oklch(0.55 0.03 50);
}
.matrix-cost td,
.matrix-cost th {
  border-top: 1px solid oklch(0.45 0.1 50 / 0.6);
  font-family: var(--font-serif);
  font-size: 1rem;
  color: var(--muted);
}
.matrix-cost td.is-us {
  color: var(--fg);
}

/* ---------- IV · the pipeline ---------- */
/* Drawn as a numbered descent with a rule running through it, so the
   hand-off from pass to pass is visible rather than asserted. */

.pipeline {
  list-style: none;
  margin: 2rem 0 0;
  padding: 0;
  position: relative;
  max-width: var(--leaf-measure);
}

/* The thread the stages hang from. */
.pipeline::before {
  content: '';
  position: absolute;
  left: 0.95rem;
  top: 0.6rem;
  bottom: 0.6rem;
  width: 1px;
  background: linear-gradient(
    180deg,
    oklch(0.55 0.16 55 / 0.65),
    oklch(0.4 0.1 50 / 0.35)
  );
}

.stage {
  position: relative;
  padding: 0 0 1.9rem 3.1rem;
}

.stage:last-child { padding-bottom: 0; }

.stage-n {
  position: absolute;
  left: 0;
  top: 0;
  display: grid;
  place-items: center;
  width: 1.95rem;
  height: 1.95rem;
  border-radius: 50%;
  border: 1px solid oklch(0.42 0.12 50);
  background: var(--bg-deep);
  font-family: var(--font-display);
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

.stage h3 {
  font-family: var(--font-serif);
  font-weight: 400;
  font-size: 1.32rem;
  line-height: 1.2;
  margin: 0.1rem 0 0.35rem;
  color: var(--fg);
}

.stage p {
  margin: 0;
  font-size: 0.97rem;
  line-height: 1.6;
  color: var(--muted);
}

/* The grounding pass is the differentiator, so it is the one stage that
   lifts off the thread. */
.stage.is-key .stage-n {
  border-color: var(--flame);
  color: var(--flame-bright);
  box-shadow: 0 0 0 4px oklch(0.55 0.16 55 / 0.14);
}

.stage.is-key h3 { color: var(--flame-bright); }

.stage-note {
  margin-top: 0.5rem !important;
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent);
}

/* ---------- VI · the one place cards belong ---------- */

.choice {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(19rem, 1fr));
  gap: 1.25rem;
  margin-top: 2rem;
}

.option {
  display: flex;
  flex-direction: column;
  padding: var(--panel-pad);
  border: 1px solid var(--border);
  border-radius: var(--panel-r);
  background: linear-gradient(180deg, var(--card2), var(--card));
}

.option h3 {
  font-family: var(--font-serif);
  font-weight: 400;
  font-size: 1.45rem;
  line-height: 1.18;
  margin: 0 0 0.6rem;
  color: var(--fg);
}

.option p {
  margin: 0 0 0.9rem;
  font-size: 0.97rem;
  line-height: 1.6;
  color: var(--muted);
}

.option-flow {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.3rem 0.45rem;
  margin: 0 0 0.9rem !important;
  font-size: 0.62rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
}

.option-flow span:last-child { color: var(--flame-bright); }

.option-flow span:not(:last-child)::after {
  content: '';
  display: inline-block;
  width: 0.32rem;
  height: 0.32rem;
  margin-left: 0.5rem;
  border-top: 1px solid currentColor;
  border-right: 1px solid currentColor;
  transform: rotate(45deg) translateY(-0.06rem);
  opacity: 0.65;
}

.option-needs {
  margin-top: auto !important;
  padding-top: 0.9rem;
  border-top: 1px solid var(--border);
  font-size: 0.9rem !important;
}

.option-needs strong { color: var(--fg); }

.option .cta { margin: 1rem 0 0; justify-content: flex-start; }

/* ---------- VII · the ledger ---------- */
/* A price list, set as one. Dotted leaders and lining figures, because the
   comparison is the argument and it should be readable in one pass. */

.ledger {
  margin-top: 2rem;
  max-width: var(--leaf-measure);
  border-top: 1px solid var(--border);
}

.ledger-row {
  display: flex;
  align-items: baseline;
  gap: 1rem;
  padding: 0.85rem 0;
  border-bottom: 1px solid var(--border);
}

.ledger-what {
  margin: 0;
  flex: 1;
  font-size: 0.98rem;
  line-height: 1.45;
  color: var(--muted);
}

.ledger-cost {
  margin: 0;
  font-family: var(--font-display);
  font-size: 1.15rem;
  font-weight: 600;
  color: var(--fg);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.ledger-row.is-zero .ledger-cost { color: oklch(0.76 0.15 155); }

/* The row that is not us. Set back, so the page is not sneering. */
.ledger-row.is-them {
  border-bottom: 0;
  opacity: 0.72;
}

.ledger-row.is-them .ledger-cost { color: var(--accent); }

/* ---------- VIII · the boundary ---------- */
/* The privacy question, drawn. Two enclosures and exactly one thing crossing
   between them, which is the whole answer. */

.boundary {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  align-items: center;
  gap: 1.25rem;
  margin: 2rem 0 0;
  max-width: var(--leaf-measure);
}

.boundary-box {
  padding: 1.3rem 1.4rem;
  border: 1px solid oklch(0.42 0.12 50);
  border-radius: var(--panel-r);
  background: oklch(0.15 0.05 50 / 0.75);
}

/* Not yours, so it is drawn as a dashed outline with no ground of its own. */
.boundary-box.is-remote {
  border-style: dashed;
  border-color: var(--border);
  background: none;
}

.boundary-title {
  margin: 0 0 0.7rem;
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--flame-bright);
}

.boundary-box.is-remote .boundary-title { color: var(--muted); }

.boundary-items {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  font-size: 0.92rem;
  color: var(--muted);
}

.boundary-items li { position: relative; padding-left: 0.85rem; }

.boundary-items li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.6em;
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: oklch(0.5 0.12 50);
}

.boundary-link {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.5rem;
  width: 9.5rem;
}

.boundary-arrow {
  width: 100%;
  height: 1px;
  background: linear-gradient(90deg, oklch(0.55 0.16 55 / 0.8), oklch(0.42 0.12 50 / 0.4));
  position: relative;
}

.boundary-arrow::after {
  content: '';
  position: absolute;
  right: 0;
  top: -3px;
  width: 6px;
  height: 6px;
  border-top: 1px solid oklch(0.5 0.14 50);
  border-right: 1px solid oklch(0.5 0.14 50);
  transform: rotate(45deg);
}

.boundary-what {
  font-size: 0.68rem;
  line-height: 1.4;
  text-align: center;
  color: var(--muted);
}

.boundary figcaption {
  grid-column: 1 / -1;
  margin-top: 0.5rem;
  font-size: 0.88rem;
  line-height: 1.55;
  color: var(--muted);
}

.nevers {
  list-style: none;
  margin: 1.75rem 0 0;
  padding: 0;
  max-width: var(--leaf-measure);
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.nevers li {
  position: relative;
  padding-left: 1.4rem;
  font-size: 0.98rem;
  line-height: 1.55;
  color: var(--muted);
}

/* A struck-through circle: the shape of "does not". */
.nevers li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.48em;
  width: 0.62rem;
  height: 0.62rem;
  border: 1px solid oklch(0.6 0.13 155 / 0.85);
  border-radius: 50%;
}

/* ---------- X · the close ---------- */

.leaf.is-final { padding-bottom: 5.5rem; }

.leaf.is-final .cta { justify-content: flex-start; margin: 2rem 0 0; }

.leaf.is-final .doc-index {
  margin-top: 3rem;
  padding-top: 2rem;
  border-top: 1px solid var(--border);
}

/* ---------- responsive ---------- */
/* The rail folds up above the body rather than disappearing: the numeral is
   how you know where you are in the document, and that matters more on a
   small screen, not less. */

@media (max-width: 60rem) {
  .landing .hero {
    grid-template-columns: minmax(0, 1fr);
    gap: 2.5rem;
    padding-bottom: 3.5rem;
  }
  .landing .hero h1 { max-width: 18ch; }
  .boundary { grid-template-columns: minmax(0, 1fr); }
  .boundary-link {
    width: 100%;
    flex-direction: row;
    justify-content: center;
    gap: 0.75rem;
  }
  .boundary-arrow { width: 3rem; transform: rotate(90deg); }
}

@media (max-width: 48rem) {
  .landing main { --leaf-gap: 0rem; }
  .leaf {
    grid-template-columns: minmax(0, 1fr);
    padding: 3rem 0;
  }
  .rail {
    position: static;
    flex-direction: row;
    align-items: baseline;
    gap: 0.75rem;
    margin-bottom: 1.25rem;
    padding-right: 0;
    padding-bottom: 0.6rem;
    border-right: 0;
    border-bottom: 1px solid var(--border);
    text-align: left;
  }
  .numeral { font-size: 1.1rem; }
  .stage { padding-left: 2.7rem; }
}

@media (prefers-reduced-motion: reduce) {
  .rail { position: static; }
}

/* Two components arrive on the landing page from the docs system, inside the
   injected sample and documentation blocks. They keep the docs radius on docs
   pages, where that system is internally consistent, and take the landing
   radius here, so this page draws one shape and only one. */
.landing .table-wrap,
.landing .doc-filter input {
  border-radius: var(--panel-r);
}

/* The "fan" section is gone. It was the sibling project's five-artefacts-
   from-one-recording diagram (.fan, .artefact, .lead-in, .excerpt) — about
   3.8 KB of rules matching nothing this generator emits. excerptBlock was
   removed from the generator and its styles were not. Verified against a
   real build: zero occurrences of any of those classes in the output. */

/* ---------- the hero answer ----------
 * A single annotated object rather than a comparison. It is built to read in
 * the order the eye takes it: the question, the answer, the limit of the
 * answer, then the files. The limit line is the differentiator, so it gets the
 * only rule on the card and sits on its own.
 */
.answer {
  margin: 0;
  padding: 1.6rem 1.7rem 1.35rem;
  border: 1px solid oklch(0.34 0.06 50);
  border-radius: var(--radius-card);
  background:
    linear-gradient(180deg, oklch(0.18 0.045 50 / 0.92), oklch(0.14 0.035 50 / 0.92));
  box-shadow: 0 24px 60px -30px oklch(0.05 0.02 50 / 0.9);
  position: relative;
}
/* A hairline of ember down the left edge — the same rail the page uses. */
.answer::before {
  content: "";
  position: absolute;
  inset: 1.1rem auto 1.1rem 0;
  width: 2px;
  border-radius: 2px;
  background: linear-gradient(180deg, var(--flame), oklch(0.45 0.14 50 / 0.15));
}

.answer-ask {
  margin: 0 0 1.15rem;
  font-family: var(--font-sans);
  font-size: 0.94rem;
  line-height: 1.5;
  color: var(--muted);
}
.answer-at {
  font-weight: 600;
  color: var(--flame);
}

.answer-said {
  font-family: var(--font-serif);
  font-size: 1.16rem;
  line-height: 1.62;
  color: var(--fg);
}
.answer-said p { margin: 0 0 0.7rem; }

/* Citation markers. Superscript-ish without <sup>, so the line height of the
 * paragraph does not jump around them. */
.cite {
  display: inline-block;
  margin-left: 0.18em;
  padding: 0 0.34em;
  border-radius: 5px;
  border: 1px solid oklch(0.5 0.14 55 / 0.55);
  background: oklch(0.32 0.09 50 / 0.7);
  color: var(--flame-bright);
  font-family: var(--font-mono);
  font-size: 0.62em;
  line-height: 1.7;
  vertical-align: 0.42em;
  text-decoration: none;
}
.cite:hover,
.cite:focus-visible {
  background: oklch(0.42 0.13 52 / 0.85);
  color: oklch(0.97 0.03 80);
}

/* The limit of the answer. The whole argument of the project sits here. */
.answer-limit {
  margin: 0.9rem 0 0;
  padding-top: 0.85rem;
  border-top: 1px dashed oklch(0.4 0.09 50);
  font-family: var(--font-serif);
  font-style: italic;
  color: var(--parchment-dim, oklch(0.86 0.05 72));
}

.answer-sources {
  margin: 1.15rem 0 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 0.42rem;
}
.answer-sources li {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  font-family: var(--font-mono);
  font-size: 0.76rem;
  color: var(--muted);
}
.answer-sources code {
  background: none;
  border: 0;
  padding: 0;
  color: oklch(0.86 0.05 72);
}
.src-n {
  flex: none;
  width: 1.35rem;
  height: 1.35rem;
  display: grid;
  place-items: center;
  border-radius: 50%;
  border: 1px solid oklch(0.5 0.14 55 / 0.5);
  color: var(--flame);
  font-size: 0.68rem;
}

.answer figcaption {
  margin-top: 1.2rem;
  padding-top: 0.9rem;
  border-top: 1px solid oklch(0.3 0.05 50);
  font-family: var(--font-sans);
  font-size: 0.82rem;
  line-height: 1.55;
  color: var(--muted);
}

/* ---------- the gap loop ----------
 * A cycle, not a row. Four steps left to right, then a return line that runs
 * back underneath them — because the claim being made is that step four feeds
 * step one forever, and four cards in a row cannot say that.
 *
 * The refusal step is crimson: it is the moment the thing declines, and this
 * is the one place on the page where "stop" is the correct reading. The step
 * where the human does the work is ember, because that is the payoff.
 */
.gaploop { margin: 2rem 0 0; }

.gaploop-steps {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0.9rem;
  counter-reset: gstep;
}
@media (max-width: 60rem) {
  .gaploop-steps { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 34rem) {
  .gaploop-steps { grid-template-columns: 1fr; }
}

.gstep {
  position: relative;
  padding: 1.05rem 1.05rem 1.1rem;
  border: 1px solid oklch(0.3 0.05 50);
  border-radius: 14px;
  background: oklch(0.155 0.035 50 / 0.75);
}
/* The connective tissue: a hairline from each card to the next. */
.gstep::after {
  content: "";
  position: absolute;
  top: 50%;
  right: -0.9rem;
  width: 0.9rem;
  height: 1px;
  background: oklch(0.42 0.08 50);
}
.gstep:last-child::after { display: none; }
@media (max-width: 60rem) {
  .gstep::after { display: none; }
}

.gstep-when {
  margin: 0 0 0.55rem;
  font-family: var(--font-mono);
  font-size: 0.66rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: oklch(0.6 0.05 60);
}
.gstep h3 {
  margin: 0 0 0.45rem;
  font-family: var(--font-display);
  font-size: 1rem;
  line-height: 1.25;
  color: var(--fg);
}
.gstep p:last-child {
  margin: 0;
  font-size: 0.87rem;
  line-height: 1.5;
  color: var(--muted);
}

/* The two steps that carry meaning get a left rail rather than a full tint,
 * so the row still reads as one row. */
.gstep.is-refusal { border-color: oklch(0.42 0.14 25 / 0.6); }
.gstep.is-refusal .gstep-when { color: var(--accent-bright); }
.gstep.is-key { border-color: oklch(0.5 0.14 55 / 0.65); }
.gstep.is-key .gstep-when { color: var(--flame); }

/* The return path. A rule that runs back under the row and arrives with the
 * point of the whole figure. */
.gaploop-return {
  margin: 0;
  padding: 1.15rem 1.2rem 0 1.2rem;
  position: relative;
  border-left: 1px solid oklch(0.42 0.08 50);
  border-right: 1px solid oklch(0.42 0.08 50);
  border-bottom: 1px solid oklch(0.42 0.08 50);
  border-radius: 0 0 14px 14px;
  min-height: 2.6rem;
}
.gaploop-return span {
  display: inline-block;
  transform: translateY(0.85rem);
  padding: 0.34rem 0.8rem;
  border-radius: var(--radius-pill);
  border: 1px solid oklch(0.5 0.14 55 / 0.5);
  background: oklch(0.2 0.05 50);
  font-family: var(--font-sans);
  font-size: 0.8rem;
  color: oklch(0.88 0.05 72);
}

.gaploop figcaption {
  margin-top: 1.6rem;
  font-family: var(--font-sans);
  font-size: 0.86rem;
  line-height: 1.6;
  color: var(--muted);
  max-width: 46ch;
}

/* ── The tell (section I) ───────────────────────────────────────────────
   Two answers to one question. The cards are deliberately identical in
   weight and colour: the argument is that you cannot tell them apart from
   the prose, so styling one as "wrong" would undo the point being made.
   The whole difference lives in the footer rule and its mark. */
.tell {
  margin: 2.4rem 0 0;
  padding: 0;
}

.tell-q {
  font-family: var(--font-mono);
  font-size: 0.83rem;
  color: var(--muted);
  margin: 0 0 0.9rem;
  padding-left: 0.9rem;
  border-left: 2px solid var(--border);
}

.tell-at { color: var(--flame); }

.tell-pair {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: 1rem;
}

.tell-card {
  border: 1px solid var(--border);
  border-radius: var(--panel-r);
  padding: var(--panel-pad-tight);
  background: color-mix(in oklab, var(--bg) 88%, #000);
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}

.tell-who {
  font-family: var(--font-display);
  font-size: 0.7rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0;
}

.tell-said {
  margin: 0;
  color: var(--fg);
  font-size: 0.97rem;
  line-height: 1.6;
  flex: 1;
}

/* The invented detail. Underlined in the accent as the eye arrives, so the
   reveal is a beat after the sentence has already been read as plausible. */
.tell-said em {
  font-style: normal;
  background-image: linear-gradient(var(--accent-bright), var(--accent-bright));
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 0 2px;
  animation: tell-underline 900ms ease-out 1.1s forwards;
}

@keyframes tell-underline { to { background-size: 100% 2px; } }

.tell-foot {
  margin: 0;
  padding-top: 0.6rem;
  border-top: 1px solid var(--border);
  font-size: 0.78rem;
  line-height: 1.45;
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
}

.tell-mark {
  width: 0.5rem;
  height: 0.5rem;
  flex: 0 0 auto;
  border-radius: 50%;
  transform: translateY(-1px);
}

.tell-foot.is-none { color: var(--accent-bright); }
.tell-foot.is-none .tell-mark { background: var(--accent); }

.tell-foot.is-cite { color: var(--flame-bright); }
.tell-foot.is-cite .tell-mark { background: var(--flame); }

.tell-card.is-vault { border-color: color-mix(in oklab, var(--flame) 40%, var(--border)); }

.tell figcaption {
  margin-top: 1rem;
  max-width: var(--leaf-measure);
  color: var(--muted);
  font-size: 0.9rem;
  line-height: 1.6;
}

@media (prefers-reduced-motion: reduce) {
  .tell-said em { animation: none; background-size: 100% 2px; }
}

/* ── Three surfaces, one engine (section VI) ────────────────────────────
   Boxes, not SVG: a fixed viewBox cannot reflow, so on a phone every label
   rendered at half size. This lays out as a row on desktop and a column on
   a narrow screen, and the labels stay real text at real sizes throughout. */
.converge { margin: 0 0 1.9rem; }

.cv {
  display: grid;
  grid-template-columns: auto auto minmax(0, 1fr) auto auto;
  align-items: center;
  gap: 0.7rem;
}

.cv-ins {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.4rem;
}

.cv-ins li,
.cv-out {
  border: 1px solid var(--border);
  border-radius: 10px;
  background: color-mix(in oklab, var(--bg) 82%, #000);
  padding: 0.5rem 0.8rem;
  font-size: 0.86rem;
  color: var(--fg);
  text-align: center;
  white-space: nowrap;
}

/* The convergence itself: a bracket the three inputs feed into. */
.cv-arrow {
  width: 1.5rem;
  height: 1px;
  background: var(--border);
  position: relative;
  justify-self: center;
}

.cv-arrow::after {
  content: "";
  position: absolute;
  right: -1px;
  top: 50%;
  width: 0.42rem;
  height: 0.42rem;
  border-top: 1.5px solid var(--flame);
  border-right: 1.5px solid var(--flame);
  transform: translateY(-50%) rotate(45deg);
}

.cv-core {
  border: 1.25px solid color-mix(in oklab, var(--flame) 45%, var(--border));
  background: color-mix(in oklab, var(--flame) 8%, transparent);
  border-radius: 14px;
  padding: 0.85rem 1rem;
  display: grid;
  gap: 0.15rem;
  text-align: center;
  font-family: var(--font-display);
  font-size: 0.85rem;
  letter-spacing: 0.05em;
  color: var(--flame-bright);
}

.cv-out {
  border-color: color-mix(in oklab, var(--flame) 45%, var(--border));
  display: grid;
  gap: 0.1rem;
  white-space: normal;
}

.cv-out-t { color: var(--flame-bright); font-size: 0.86rem; }
.cv-out-s { color: var(--muted); font-size: 0.75rem; }

.converge figcaption {
  margin-top: 0.9rem;
  max-width: var(--leaf-measure);
  color: var(--muted);
  font-size: 0.9rem;
  line-height: 1.6;
}

/* Narrow: stack, and turn the connectors a quarter turn to match. */
@media (max-width: 40rem) {
  .cv {
    grid-template-columns: minmax(0, 1fr);
    justify-items: stretch;
    gap: 0.5rem;
  }
  .cv-ins li, .cv-out, .cv-core { white-space: normal; }
  .cv-arrow {
    width: 1px;
    height: 1.3rem;
    justify-self: center;
  }
  .cv-arrow::after {
    right: 50%;
    top: auto;
    bottom: -1px;
    transform: translateX(50%) rotate(135deg);
  }
}

/* ── If the project stops (section VIII) ────────────────────────────────
   Deliberately the same two-column shape as .boundary above it: that one
   splits what stays on your machine from what leaves, this one splits what
   survives the project from what doesn't. Same question asked twice, so the
   reader should recognise the form the second time. */
.fate {
  margin: 1.3rem 0 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
  gap: 1rem;
}

.fate figcaption {
  grid-column: 1 / -1;
  margin-top: 0.4rem;
  max-width: var(--leaf-measure);
  color: var(--muted);
  font-size: 0.9rem;
  line-height: 1.6;
}

.fate-col {
  border: 1px solid var(--border);
  border-radius: var(--panel-r);
  padding: var(--panel-pad-tight);
  background: color-mix(in oklab, var(--bg) 88%, #000);
  border-top-width: var(--panel-rail);
}

.fate-col.is-keep { border-top-color: var(--flame); }
.fate-col.is-lose { border-top-color: color-mix(in oklab, var(--muted) 55%, transparent); }

.fate-head {
  font-family: var(--font-display);
  font-size: 0.7rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  margin: 0 0 0.75rem;
}

.fate-col.is-keep .fate-head { color: var(--flame-bright); }
.fate-col.is-lose .fate-head { color: var(--muted); }

.fate-col ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.5rem;
}

.fate-col li {
  position: relative;
  padding-left: 0.95rem;
  color: var(--muted);
  font-size: 0.9rem;
  line-height: 1.55;
}

.fate-col li strong { color: var(--fg); font-weight: 600; }

.fate-col li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.55em;
  width: 0.35rem;
  height: 0.35rem;
  border-radius: 50%;
}

.fate-col.is-keep li::before { background: var(--flame); }
.fate-col.is-lose li::before { background: color-mix(in oklab, var(--muted) 60%, transparent); }

.fate-note {
  margin: 0.9rem 0 0;
  padding-top: 0.7rem;
  border-top: 1px solid var(--border);
  font-family: var(--font-serif);
  font-size: 0.92rem;
  line-height: 1.5;
  color: var(--muted);
}

.fate-col.is-keep .fate-note { color: var(--flame-bright); }

/* ── A year of charges (section VII) ────────────────────────────────────
   Twelve cells per row, one per month. The ledger above compares amounts;
   this compares how OFTEN, which is the part a per-question price cannot be
   put next to a monthly one to show. Empty cells are the argument, so they
   keep their outline rather than disappearing. */
.year {
  margin: 1.4rem 0 0;
  display: grid;
  gap: 0.85rem;
}

.year-row {
  display: grid;
  grid-template-columns: minmax(7.5rem, auto) minmax(0, 1fr) minmax(7rem, auto);
  align-items: center;
  gap: 0.9rem;
}

.year-who {
  margin: 0;
  font-family: var(--font-display);
  font-size: 0.72rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--flame-bright);
}

.year-row.is-them .year-who { color: var(--muted); }

.year-months {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: 0.28rem;
}

.year-months li {
  height: 1.5rem;
  border-radius: 4px;
  border: 1px solid var(--border);
  background: transparent;
}

.year-months li.on { background: color-mix(in oklab, var(--flame) 62%, transparent); border-color: transparent; }
.year-row.is-them .year-months li.on { background: color-mix(in oklab, var(--accent) 55%, transparent); }

.year-sum {
  margin: 0;
  font-size: 0.8rem;
  color: var(--muted);
  text-align: right;
}

.year figcaption {
  margin-top: 0.35rem;
  max-width: var(--leaf-measure);
  color: var(--muted);
  font-size: 0.9rem;
  line-height: 1.6;
}

@media (max-width: 40rem) {
  .year-row {
    grid-template-columns: minmax(0, 1fr);
    gap: 0.35rem;
  }
  .year-sum { text-align: left; }
  .year-months li { height: 1.15rem; }
}
