/* Tusk's Tomes — public site stylesheet.
 *
 * The visual language (void-violet base, amethyst primary, ember accent,
 * gold-leaf detailing, Cinzel/Cormorant/Inter) is ported from the app's own
 * theme in src/index.css, so the site and the product look like the same
 * thing. Committed dark, matching the app — not a light/dark pair.
 *
 * Self-hosted fonts and no external stylesheet: the page makes ZERO
 * third-party requests at load. That keeps the no-telemetry promise honest
 * (a Google Fonts link would hand every visitor's IP to a third party) and
 * protects the Core Web Vitals that feed search ranking.
 *
 * Fonts are OFL-1.1 — see assets/fonts/LICENSES.txt for attribution.
 */

/* ---------- self-hosted fonts (paths relative to this file) ---------- */
@font-face { font-family: "Cinzel"; font-weight: 600; font-style: normal; font-display: swap; src: url("assets/fonts/cinzel-600.woff2") format("woff2"); }
@font-face { font-family: "Cinzel"; font-weight: 700; font-style: normal; font-display: swap; src: url("assets/fonts/cinzel-700.woff2") format("woff2"); }
@font-face { font-family: "Cinzel Decorative"; font-weight: 700; font-style: normal; font-display: swap; src: url("assets/fonts/cinzel-decorative-700.woff2") format("woff2"); }
@font-face { font-family: "Cinzel Decorative"; font-weight: 900; font-style: normal; font-display: swap; src: url("assets/fonts/cinzel-decorative-900.woff2") format("woff2"); }
@font-face { font-family: "Fondamento"; font-weight: 400; font-style: normal; font-display: swap; src: url("assets/fonts/fondamento-400.woff2") format("woff2"); }
@font-face { font-family: "Fondamento"; font-weight: 400; font-style: italic; font-display: swap; src: url("assets/fonts/fondamento-400-italic.woff2") format("woff2"); }
@font-face { font-family: "Cormorant Garamond"; font-weight: 400; font-style: normal; font-display: swap; src: url("assets/fonts/cormorant-400.woff2") format("woff2"); }
@font-face { font-family: "Cormorant Garamond"; font-weight: 600; font-style: normal; font-display: swap; src: url("assets/fonts/cormorant-600.woff2") format("woff2"); }
@font-face { font-family: "Cormorant Garamond"; font-weight: 400; font-style: italic; font-display: swap; src: url("assets/fonts/cormorant-400-italic.woff2") format("woff2"); }
@font-face { font-family: "Inter"; font-weight: 400; font-style: normal; font-display: swap; src: url("assets/fonts/inter-400.woff2") format("woff2"); }
@font-face { font-family: "Inter"; font-weight: 500; font-style: normal; font-display: swap; src: url("assets/fonts/inter-500.woff2") format("woff2"); }
@font-face { font-family: "Inter"; font-weight: 600; font-style: normal; font-display: swap; src: url("assets/fonts/inter-600.woff2") format("woff2"); }

:root {
  --bg: oklch(0.11 0.04 285);
  --bg-deep: oklch(0.09 0.03 285);
  --card: oklch(0.16 0.05 285);
  --card2: oklch(0.19 0.06 290);
  --fg: oklch(0.94 0.025 90);
  --muted: oklch(0.72 0.04 285);
  --arcane: oklch(0.65 0.22 295);
  --arcane-bright: oklch(0.8 0.2 295);
  --ember: oklch(0.72 0.19 50);
  --gold: #c2a14d;
  --border: oklch(0.32 0.07 290);

  --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 295 / 0.3), transparent 60%),
    radial-gradient(ellipse 80% 60% at 50% 120%, oklch(0.2 0.1 285 / 0.45), transparent 65%),
    radial-gradient(ellipse 60% 50% at 12% 28%, oklch(0.4 0.12 295 / 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(--arcane-bright);
  text-underline-offset: 0.15em;
}
a:hover {
  color: var(--arcane);
}

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(--arcane-bright);
}

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

::selection {
  background-color: var(--arcane);
  color: oklch(0.99 0.005 290);
}

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

/* 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(--arcane);
  border-radius: var(--radius);
  padding: 0.5rem 1rem;
}

:focus-visible {
  outline: 2px solid var(--arcane-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 295 / 0.35)); }
  50% { filter: drop-shadow(0 0 30px oklch(0.72 0.24 295 / 0.6)); }
}
@keyframes spell-charge {
  0%, 100% { box-shadow: 0 0 0 1px oklch(0.65 0.22 295 / 0.4), 0 8px 24px -8px oklch(0.65 0.22 295 / 0.45); }
  50% { box-shadow: 0 0 0 1px oklch(0.72 0.24 295 / 0.6), 0 10px 28px -6px oklch(0.7 0.24 295 / 0.55), 0 0 0 4px oklch(0.7 0.24 295 / 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. */
.ember-field {
  position: fixed;
  inset: 0;
  pointer-events: none;
  overflow: hidden;
  z-index: 0;
}
.ember-field span {
  position: absolute;
  bottom: -20px;
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: radial-gradient(circle, oklch(0.85 0.18 50 / 0.95), oklch(0.6 0.18 50 / 0.4) 60%, transparent 75%);
  box-shadow: 0 0 8px oklch(0.78 0.18 50 / 0.6);
  animation: ember-drift 15s linear infinite;
}
.ember-field span:nth-child(1) { left: 12%; --dx: 18px; animation-duration: 13s; animation-delay: -1s; }
.ember-field span:nth-child(2) { left: 30%; --dx: 8px; animation-duration: 16s; animation-delay: -3s; }
.ember-field span:nth-child(3) { left: 47%; --dx: -14px; animation-duration: 19s; animation-delay: -8s; }
.ember-field span:nth-child(4) { left: 64%; --dx: 20px; animation-duration: 15s; animation-delay: -11s; }
.ember-field span:nth-child(5) { left: 80%; --dx: -22px; animation-duration: 17s; animation-delay: -5s; }
.ember-field span:nth-child(6) { left: 91%; --dx: -10px; animation-duration: 18s; animation-delay: -6s; }

/* ---------- 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 285 / 0.92), oklch(0.11 0.04 285 / 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(--arcane-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 290);
  border: 1px solid oklch(0.65 0.22 295 / 0.5);
  background: linear-gradient(180deg, oklch(0.5 0.2 295), oklch(0.38 0.18 295));
  transition: 0.2s;
}
.site-head nav a.gh:hover {
  transform: translateY(-1px);
  box-shadow: 0 0 0 1px oklch(0.8 0.22 295 / 0.6), 0 6px 20px -6px oklch(0.7 0.24 295 / 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(--ember);
  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 295), oklch(0.86 0.14 295) 55%, oklch(0.7 0.2 295));
  -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(--ember);
}

.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 285);
}


.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 285 / 0.6);
}
.btn:hover {
  border-color: var(--arcane);
  color: var(--arcane-bright);
}
.btn.primary {
  color: oklch(0.99 0.005 290);
  border-color: oklch(0.65 0.22 295 / 0.6);
  background: linear-gradient(180deg, oklch(0.5 0.2 295), oklch(0.38 0.18 295));
  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 290);
  box-shadow: 0 0 0 1px oklch(0.85 0.22 295 / 0.7), 0 12px 32px -4px oklch(0.7 0.24 295 / 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 285 / 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.

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

     --ember                      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(--arcane);
  opacity: 0.8;
}
.rune::before,
.rune::after {
  content: "";
  flex: 1;
  height: 1px;
  background: linear-gradient(90deg, transparent, oklch(0.65 0.22 295 / 0.55), transparent);
}
.rune svg {
  width: 20px;
  height: 20px;
  filter: drop-shadow(0 0 6px oklch(0.7 0.22 295 / 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 295 / 0.35);
  border: 1px solid oklch(0.5 0.14 295 / 0.6);
  color: var(--arcane-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(--ember);
}
.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(--arcane);
  background: oklch(0.16 0.05 285 / 0.7);
}
.notice.warn {
  border-left-color: var(--ember);
  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(--ember);
}
.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;
  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 285 / 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(--ember);
  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 295), oklch(0.42 0.18 295));
  box-shadow: 0 0 24px oklch(0.65 0.22 295 / 0.55), 0 0 0 1px oklch(0.75 0.22 295 / 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 290);
}
.video-play:hover .video-btn {
  background: linear-gradient(180deg, oklch(0.72 0.22 295), oklch(0.5 0.2 295));
}
.video-note {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0.6rem;
  color: oklch(0.9 0.02 285);
  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 285 / 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(--ember);
}
.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 290 / 0.6);
  color: var(--fg);
}
.chapter[aria-current='true'] {
  background: oklch(0.22 0.06 290 / 0.8);
  color: var(--arcane-bright);
}
.chapter-time {
  flex: none;
  min-width: 3.2rem;
  font-family: var(--font-mono);
  font-size: 0.85rem;
  color: var(--arcane-bright);
  font-variant-numeric: tabular-nums;
}
.chapter[aria-current='true'] .chapter-time {
  color: var(--ember);
}

/* 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(--arcane-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 295 / 0.35);
  border: 1px solid oklch(0.5 0.14 295 / 0.5);
  color: var(--arcane-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 295 / 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 295 / 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(--ember);
}
.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(--ember);
  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 290 / 0.55);
  color: var(--arcane-bright);
}
.docs-nav a[aria-current="page"] {
  background: oklch(0.22 0.06 290 / 0.7);
  color: var(--arcane-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(--ember);
  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 290 / 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(--arcane);
  background: oklch(0.14 0.045 285 / 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 285);
}
.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(--arcane-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 290);
  box-shadow:
    0 1px 0 oklch(0.55 0.16 295 / 0.18) inset,
    0 28px 56px -28px oklch(0.04 0.02 285 / 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 sample()
   helper in scripts/site/build-site.mjs 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(--arcane-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(--arcane-bright);
  border-bottom: 2px solid var(--arcane-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(--arcane-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 285);
}

.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(--arcane-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(--arcane);
}

/* 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(--ember);
  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 285 / 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(--ember);
}

.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 285 / 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(--arcane-bright);
  background: oklch(0.65 0.22 295 / 0.14);
  border: 1px solid oklch(0.65 0.22 295 / 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(--ember);
}

/* Local-review banner. Loud on purpose — it exists to be impossible to miss in
   a preview build, and publish-site.mjs refuses to push any page carrying it.
   See UNAPPROVED_PREVIEW_MARKER in scripts/site/build-site.mjs. */
.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(--arcane-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(--arcane-bright);
  border-bottom: 2px solid var(--arcane-bright);
  transform: rotate(-45deg);
  transition: transform 0.2s ease;
}
.faq-item[open] > summary::after {
  transform: rotate(45deg);
}
.faq-item[open] > summary {
  color: var(--arcane-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(--arcane-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(--arcane-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(--arcane-bright);
  border-bottom: 2px solid var(--arcane-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 295 / 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 renderAlerts() in scripts/site/build-site.mjs, 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(--ember); }
/* 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(--arcane-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(--arcane-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; }

.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);
}

.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(--ember);
}

.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(--ember);
}

.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 285 / 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 288 / 0.85);
  box-shadow: inset 0 0 0 1px oklch(0.55 0.16 295 / 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(--arcane-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 285 / 0.7);
}

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

.grounding-arrow span {
  position: relative;
  padding: 0.3rem 0.9rem;
  border: 1px solid oklch(0.42 0.12 293);
  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(--arcane-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 --arcane because the accent means "the product speaking", and a
   capability claim is exactly that. Nothing here is --ember: no one is
   speaking, and this is not a warning.                                       */

.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;
  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(--ember);
  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 292 / 0.55);
}
.matrix thead th.is-us {
  color: var(--arcane-bright);
  border-bottom-color: oklch(0.55 0.18 295 / 0.7);
}
.mark {
  font-style: normal;
  font-size: 1.05rem;
  line-height: 1;
}
.mark.yes {
  color: var(--arcane-bright);
}
.mark.no,
.mark.part,
.mark.na {
  color: oklch(0.55 0.03 285);
}
.matrix-cost td,
.matrix-cost th {
  border-top: 1px solid oklch(0.45 0.1 292 / 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 295 / 0.65),
    oklch(0.4 0.1 292 / 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 293);
  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(--arcane);
  color: var(--arcane-bright);
  box-shadow: 0 0 0 4px oklch(0.55 0.16 295 / 0.14);
}

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

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

/* ---------- 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(--arcane-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(--ember); }

/* ---------- 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 293);
  border-radius: var(--panel-r);
  background: oklch(0.15 0.05 288 / 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(--arcane-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 293);
}

.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 295 / 0.8), oklch(0.42 0.12 293 / 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 293);
  border-right: 1px solid oklch(0.5 0.14 293);
  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);
}

/* ---------- II · the fan ---------------------------------------------------
   One session, five artefacts. Drawn rather than listed, because "you also
   get a recap and a quotes list" is a sentence people skim and a shape people
   take in.

   Deliberately not cards. The previous version of this section was five
   stacked collapsibles, which read as a wall to get past rather than as
   evidence — so the artefacts are columns separated by rules, with a bracket
   above showing they all come from the same run. */

.fan {
  margin: 2.25rem 0 0;
  padding: 0;
}

.fan-source {
  margin: 0 0 0.85rem;
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--arcane-bright);
}

/* The bracket: one line across, with a tick descending at each artefact. The
   ticks are a repeating gradient so the count follows the grid automatically
   rather than needing a hand-placed element per column. */
.fan-spread {
  height: 1.4rem;
  border-top: 1px solid oklch(0.5 0.14 293);
  background-image: repeating-linear-gradient(
    90deg,
    oklch(0.45 0.12 293) 0 1px,
    transparent 1px 20%
  );
  background-position: 10% 0;
  background-size: 100% 100%;
  mask-image: linear-gradient(180deg, #000 0 60%, transparent 100%);
}

.fan-out {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 0 1.35rem;
}

.artefact {
  padding-top: 0.15rem;
  border-top: 1px solid transparent;
}

.artefact h3 {
  font-family: var(--font-serif);
  font-weight: 400;
  font-size: 1.12rem;
  line-height: 1.2;
  margin: 0 0 0.4rem;
  color: var(--fg);
}

.artefact p {
  margin: 0;
  font-size: 0.86rem;
  line-height: 1.55;
  color: var(--muted);
}

/* The chronicle is the one nobody turns off, so it is the one that reads
   first. */
.artefact.is-primary h3 { color: var(--arcane-bright); }

.fan figcaption {
  margin-top: 1.4rem;
  padding-top: 0.9rem;
  border-top: 1px solid var(--border);
  font-size: 0.88rem;
  color: var(--muted);
}

.fan figcaption code {
  padding: 0.08rem 0.35rem;
  border-radius: 5px;
  background: oklch(0.2 0.05 288);
  font-family: var(--font-mono);
  font-size: 0.9em;
}

/* ---------- II · the excerpt ----------------------------------------------
   A paragraph of the actual prose, set as prose. No box, no collapsible, no
   chrome — the argument is the writing, so the writing is what is on screen.
   An oversized opening quote does the framing a border would otherwise do. */

.lead-in {
  margin: 3rem 0 0 !important;
  font-family: var(--font-display);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
}

.excerpt {
  position: relative;
  margin: 1.1rem 0 0;
  padding-left: 2.6rem;
  max-width: var(--leaf-measure);
}

.excerpt::before {
  content: '\201C';
  position: absolute;
  left: -0.2rem;
  top: -0.9rem;
  font-family: var(--font-serif);
  font-size: 5rem;
  line-height: 1;
  color: oklch(0.5 0.14 293 / 0.55);
}

.excerpt blockquote {
  margin: 0;
  font-family: var(--font-serif);
  font-size: 1.24rem;
  line-height: 1.62;
  color: var(--fg);
}

.excerpt blockquote em { color: var(--arcane-bright); font-style: italic; }

.excerpt figcaption {
  margin-top: 0.9rem;
  font-size: 0.85rem;
  color: var(--muted);
}

@media (max-width: 60rem) {
  .fan-out { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.5rem 1.35rem; }
  .fan-spread { display: none; }
  .artefact { border-top-color: var(--border); padding-top: 0.9rem; }
}

@media (max-width: 34rem) {
  .fan-out { grid-template-columns: minmax(0, 1fr); }
  .excerpt { padding-left: 1.6rem; }
  .excerpt::before { font-size: 3.4rem; left: -0.3rem; top: -0.5rem; }
}
