/* canonical carbon design system — single source of truth.
   Consumed three ways:
   1. Copied to public/writing/carbon.css by scripts/sync-writing.mjs and
      linked from every Lithograph-rendered post (see carbon-substrate.html)
      and from public/writing/index.html (the /writing list page).
   2. Same copy linked directly by any hand-authored post under external/.
   Edit here; never hand-duplicate these rules into a page-local <style>. */

/* =============================================================
   Carbon · canonical (v1.0)
   One substrate. Research density, with skim-friendly affordances.

   Hierarchy is carried by typography, not by size jumps.
   Single accent. Hairlines. No shadows, no radii.
   Two widths: text body (--col) and image body (--col-wide).
   Page-width view exists only inside the figure-expand modal.
   ============================================================= */

:root {
  /* Perfect-Fourth scale, anchored at 17px body */
  --t-11:  0.6875rem;   /* mono labels, captions, fig-ID */
  --t-14:  0.875rem;    /* secondary mono, table cells */
  --t-17:  1.0625rem;   /* body */
  --t-21:  1.3333rem;   /* lede, TL;DR, h3 inline */
  --t-28:  1.7777rem;   /* h2 / section title */
  --t-37:  2.3703rem;   /* h1 / page title */
  --t-50:  3.1604rem;   /* drop cap glyph */

  /* Extra scale steps used by the /writing list page and the homepage —
     not needed by the post body, but kept on this same superfine scale
     rather than a second hand-rolled one. */
  --t-13:  0.8125rem;
  --t-19:  1.1875rem;
  --t-22:  1.375rem;
  --t-38:  2.369rem;
  --t-72:  4.5rem;
  --t-112: 7rem;

  --ff-sans:  "IBM Plex Sans", system-ui, sans-serif;
  --ff-mono:  "IBM Plex Mono", ui-monospace, "SF Mono", monospace;
  --ff-serif: "Source Serif 4", "Source Serif Pro", Georgia, serif;
  --ff-display: "Instrument Serif", "Source Serif 4", Georgia, serif;

  --bg:      oklch(0.992 0.003 248);
  --ink:     oklch(0.17 0.008 250);
  --ink-2:   oklch(0.36 0.008 250);
  --ink-3:   oklch(0.55 0.008 250);
  --rule:    oklch(0.86 0.006 248);
  --rule-2:  oklch(0.93 0.005 248);
  --accent:  oklch(0.50 0.17 254);
  --accent-bright: oklch(0.44 0.19 254);
  --accent-tint: oklch(0.96 0.04 254 / 0.5);
  --img-surface: #fff;
  --img-shadow: 0 10px 26px oklch(0.17 0.008 250 / 0.08);

  --bg-veil:       rgba(255, 255, 255, 0.82);
  --row-hover:     oklch(0.96 0.005 250 / 0.7);
  --shadow-corner: 0 0 12px rgba(255,255,255,0.75);
  --error:         oklch(0.52 0.20 25);

  --col:       720px;   /* text-body width */
  --col-wide:  960px;   /* image-body width */
  --col-full:  1240px;  /* used only inside fig-expand modal */
  --col-meta:  1080px;  /* masthead, endmatter outer */
}
:root[data-theme="dark"] {
  --bg:      oklch(0.18 0.012 250);
  --ink:     oklch(0.93 0.006 250);
  --ink-2:   oklch(0.74 0.006 250);
  --ink-3:   oklch(0.58 0.006 250);
  --rule:    oklch(0.34 0.008 250);
  --rule-2:  oklch(0.27 0.008 250);
  --accent:  oklch(0.72 0.15 254);
  --accent-bright: oklch(0.86 0.15 254);
  --accent-tint: oklch(0.40 0.07 254 / 0.45);

  --bg-veil:       rgba(0, 0, 0, 0.82);
  --row-hover:     oklch(0.10 0.005 250 / 0.6);
  --shadow-corner: 0 0 12px rgba(0,0,0,0.6);
  --error:         oklch(0.72 0.18 25);
}
/* color-scheme tracks the page's own [data-theme] toggle, not the OS
   preference — this site is manually-toggled, so `light dark` (the
   previous value) let native scrollbar/form-control colors mismatch the
   actual rendered theme whenever they differed from the OS setting. */
:root { color-scheme: light; }
:root[data-theme="dark"] { color-scheme: dark; }
/* Thin, on-brand custom scrollbar so it isn't just the bare OS default
   even once color-scheme is correct. */
* {
  scrollbar-width: thin;
  scrollbar-color: var(--ink-3) transparent;
}
::-webkit-scrollbar { width: 12px; height: 12px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background-color: var(--ink-3);
  border-radius: 8px;
  border: 3px solid var(--bg);
  background-clip: padding-box;
}
::-webkit-scrollbar-thumb:hover { background-color: var(--ink-2); }
/* Accessibility: honor reduced-motion, visible focus, skip link */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; scroll-behavior: auto !important; }
}
:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 2px; }
.skip-link { position: absolute; left: -9999px; top: 8px; z-index: 100; background: var(--accent); color: #fff; padding: 8px 14px; font-family: var(--ff-mono); font-size: var(--t-11); text-transform: uppercase; letter-spacing: 0.12em; text-decoration: none; }
.skip-link:focus { left: 16px; }
.theme-toggle { position: fixed; bottom: 18px; right: 20px; z-index: 70; width: 38px; height: 38px; display: flex; align-items: center; justify-content: center; background: var(--bg); color: var(--ink-2); border: 1px solid var(--rule); border-radius: 50%; cursor: pointer; transition: color 160ms ease, border-color 160ms ease, background 160ms ease; }
.theme-toggle:hover { color: var(--ink); border-color: var(--ink-3); }
.theme-toggle svg { width: 18px; height: 18px; }
.theme-toggle .icon-moon { display: none; }
:root[data-theme="dark"] .theme-toggle .icon-sun { display: none; }
:root[data-theme="dark"] .theme-toggle .icon-moon { display: block; }

*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; }
html, body { background: var(--bg); color: var(--ink); }
/* Headroom so jumped-to anchors don't hug the top */
[id^="ref-"], [id^="fn-"], [id^="fnref-"], section.sect, section.endmatter {
  scroll-margin-top: 48px;
}
body {
  font-family: var(--ff-sans);
  font-size: var(--t-17);
  line-height: 1.55;
  font-feature-settings: "ss01","kern","liga";
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  margin: 0;
  padding: 0 48px 200px;
}

/* ── Top reading progress hairline ──────────────────────────── */
.read-progress {
  position: fixed; inset: 0 0 auto 0; height: 2px;
  z-index: 60; pointer-events: none;
}
.read-progress__bar {
  height: 100%; background: var(--accent); width: 0%;
}

/* ── Corner page markers ────────────────────────────────────── */
.corner {
  position: fixed; z-index: 10;
  font-family: var(--ff-mono); font-size: var(--t-11);
  text-transform: uppercase; letter-spacing: 0.14em;
  color: var(--ink-3); pointer-events: none; line-height: 1.4;
}
.corner b { color: var(--ink); font-weight: 500; }
.corner a {
  pointer-events: auto;
  color: var(--ink-2);
  text-decoration: none;
  border-bottom: 1px solid transparent;
}
.corner b a { color: var(--ink); }
.corner a:hover { color: var(--ink); border-bottom-color: var(--ink); }
.corner__nav {
  margin-top: 4px;
  letter-spacing: 0.10em;
}
.corner--tl { top: 20px; left: 24px; }
.corner--tr { top: 20px; right: 24px; text-align: right; }
.corner--br { bottom: 20px; right: 70px; text-align: right; }
@media (max-width: 900px) { .corner { display: none; } }

/* ── Side TOC ───────────────────────────────────────────────── */
.toc {
  position: fixed; left: 24px; top: 50%;
  transform: translateY(-50%);
  z-index: 40;
  padding: 18px 22px 18px 18px;
  display: flex; flex-direction: column; gap: 14px;
  background: transparent;
  transition: background-color 220ms ease, box-shadow 220ms ease;
}
.toc:hover, .toc:focus-within {
  /* Theme-relative (was a hardcoded near-white literal — broke in dark
     mode) and flat rather than blurred glass, matching the rest of the
     site's hairline/flat-surface vocabulary instead of a glassmorphism
     panel that reads as a different design system. */
  background: color-mix(in oklch, var(--bg) 94%, transparent);
  box-shadow: 0 0 0 1px var(--rule-2);
}
.toc::before {
  content: ""; position: absolute; inset: -30px -40px -30px -24px;
}
.toc__item {
  position: relative;
  display: grid; grid-template-columns: 32px max-content;
  align-items: center; gap: 14px;
  text-decoration: none; border: none; color: var(--ink-3);
}
.toc__tick {
  height: 1px; width: 12px; background: var(--ink-3);
  justify-self: start;
  transition: width 220ms ease, background-color 220ms ease;
}
.toc__label {
  font-family: var(--ff-mono); font-size: var(--t-11);
  text-transform: uppercase; letter-spacing: 0.12em;
  color: var(--ink-3); white-space: nowrap;
  opacity: 0; transform: translateX(-6px);
  transition: opacity 220ms ease, transform 220ms ease, color 220ms ease;
  pointer-events: none;
}
.toc:hover .toc__label, .toc:focus-within .toc__label {
  opacity: 1; transform: translateX(0);
}
.toc:hover .toc__tick { width: 20px; }
.toc__item:hover .toc__label, .toc__item:focus .toc__label { color: var(--ink); }
.toc__item[data-current="true"] .toc__tick {
  background: var(--accent); width: 28px;
}
.toc__item[data-current="true"] .toc__label { color: var(--ink); }
@media (max-width: 1100px) { .toc { display: none; } }

/* ── Masthead ───────────────────────────────────────────────── */
.masthead {
  max-width: var(--col-meta);
  margin: 120px auto 0;
}
.masthead__top {
  display: grid;
  grid-template-columns: max-content 1fr max-content;
  align-items: baseline; gap: 32px;
  padding-bottom: 18px;
  border-bottom: 1px solid var(--ink);
}
.masthead__series {
  font-family: var(--ff-mono); font-size: var(--t-11);
  text-transform: uppercase; letter-spacing: 0.14em;
  color: var(--ink); font-weight: 500;
}
.masthead__series a {
  color: inherit;
  text-decoration: none;
  border-bottom: 1px solid transparent;
}
.masthead__series a:hover { border-bottom-color: var(--ink); }
.masthead__rule { border-top: 1px solid var(--rule); height: 1px; align-self: center; }
.masthead__nav {
  display: flex; gap: 18px;
  font-family: var(--ff-mono); font-size: var(--t-11);
  text-transform: uppercase; letter-spacing: 0.14em;
}
.masthead__nav a {
  color: var(--ink-3); text-decoration: none;
  border-bottom: 1px solid transparent; padding-bottom: 2px;
}
.masthead__nav a:hover { color: var(--ink); border-bottom-color: var(--ink); }
.masthead__ext {
  display: flex; flex-direction: row;
  align-items: center; justify-content: flex-end;
  gap: 18px;
  padding-top: 12px;
  font-family: var(--ff-mono); font-size: var(--t-13);
  text-transform: uppercase; letter-spacing: 0.14em;
}
.masthead__ext a {
  display: inline-flex; align-items: center; gap: 6px;
  color: var(--ink-3); text-decoration: none;
  border-bottom: 1px solid transparent;
  padding-bottom: 2px;
  transition: color 200ms ease, border-color 200ms ease;
}
.masthead__ext a:hover { color: var(--ink); border-bottom-color: var(--ink); }
.masthead__ext svg { width: 15px; height: 15px; }

/* ── Title block ────────────────────────────────────────────── */
.title-block {
  max-width: var(--col-meta);
  margin: 28px auto 56px;
}
.title-block__inner { max-width: 1000px; }

h1.title {
  font-family: var(--ff-serif); font-weight: 500;
  font-size: var(--t-37); line-height: 1.05;
  letter-spacing: -0.012em;
  margin: 14px 0 16px;
  text-wrap: balance;
}
.subtitle {
  font-family: var(--ff-serif); font-style: italic; font-weight: 400;
  font-size: var(--t-21); line-height: 1.3;
  color: var(--ink-2);
  margin: 0 0 40px;
  text-wrap: balance;
  max-width: 68ch;
}
.byline {
  max-width: var(--col-meta);
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 16px 32px;
  padding: 18px 0;
  border-top: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
  font-family: var(--ff-mono); font-size: var(--t-11);
  text-transform: uppercase; letter-spacing: 0.10em;
  color: var(--ink-3);
}
.byline > div { display: flex; flex-direction: column; gap: 6px; }
.byline > div:last-child { text-align: right; align-items: flex-end; }
.byline .value { color: var(--ink); font-weight: 500; letter-spacing: 0.06em; }

/* ── Featured (hero) image ──────────────────────────────────── */
.hero {
  max-width: var(--col-meta);
  margin: 56px auto 0;
}
.hero__slot {
  width: 100%; height: auto; aspect-ratio: 21 / 9;
  display: block;
  background: repeating-linear-gradient(135deg, transparent 0 13px, var(--rule-2) 13px 14px);
  --is-bg: transparent;
  --is-radius: 0;
  --is-border: none;
  border-top: 1px solid var(--ink);
}
.hero--image img {
  display: block;
  width: 100%;
  max-width: 100%;
  height: auto;
  background: var(--img-surface);
  box-shadow: var(--img-shadow);
}
.hero__caption {
  padding-top: 12px;
  font-size: var(--t-14);
  color: var(--ink-2);
  line-height: 1.5;
  text-wrap: pretty;
  position: relative;
  display: flex;
  justify-content: space-between;
  gap: 24px;
}
.hero__caption .fig-id {
  font-family: var(--ff-mono);
  font-size: var(--t-11);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--ink);
  font-weight: 500;
  flex-shrink: 0;
}
.hero__caption .credit {
  font-family: var(--ff-mono);
  font-size: var(--t-11);
  text-transform: uppercase;
  letter-spacing: 0.10em;
  color: var(--ink-3);
  flex-shrink: 0;
  align-self: flex-end;
}
.hero__caption .body {
  flex: 1;
  max-width: 56ch;
}

/* ── Article column ─────────────────────────────────────────── */
.doc { max-width: var(--col); margin: 0 auto; }

/* ── Lede ───────────────────────────────────────────────────── */
.lede {
  max-width: var(--col);
  font-size: var(--t-21); line-height: 1.42;
  color: var(--ink);
  margin: 56px auto 36px;
  text-wrap: pretty;
}
/* Lede opener: the whole first WORD set as a serif display lead-in
   (the renderer wraps the first word, not just the first letter). */
.lede__cap {
  font-family: var(--ff-serif); font-weight: 600;
  font-size: 1.55em; line-height: 1;
  letter-spacing: -0.01em;
  color: var(--accent);
  white-space: nowrap;
}

/* ── Abstract (academic/paper posts only) ───────────────────── */
/* Use for posts that are explicitly papers, not essays or blog posts.
   Placement: between the byline and the lede.
   HTML:
     <div class="abstract">
       <span class="abstract__label">Abstract</span>
       <p>One paragraph. Thesis, method, main finding.</p>
     </div> */
.abstract {
  max-width: var(--col); margin: 48px auto 0;
  padding: 16px 0 16px 18px; border-left: 2px solid var(--rule);
  display: grid; grid-template-columns: 64px 1fr; gap: 0 16px; align-items: start;
}
.abstract__label {
  font-family: var(--ff-mono); font-size: var(--t-11);
  text-transform: uppercase; letter-spacing: 0.14em;
  color: var(--ink-3); font-weight: 500; padding-top: 3px; white-space: nowrap;
}
.abstract p { font-size: var(--t-14); line-height: 1.6; color: var(--ink-2); margin: 0; text-wrap: pretty; }

/* ── Sections ───────────────────────────────────────────────── */
section.sect {
  max-width: var(--col);
  margin: 96px auto 0;
  position: relative;
}
.sect__head {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: 16px;
  margin-bottom: 18px;
  font-family: var(--ff-mono);
  font-size: var(--t-11);
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--ink-3);
}
.sect__num {
  color: var(--ink);
  font-weight: 500;
}
.sect__num .accent { color: var(--accent); }
.sect__num-kicker { display: block; margin-top: 2px; }
.sect__counter {
  color: var(--ink-3);
  white-space: nowrap;
}
@media (min-width: 1240px) {
  .sect__head { display: contents; }
  .sect__num {
    position: absolute;
    left: -156px;
    top: 0.5em;
    width: 128px;
    text-align: right;
  }
  .sect__counter {
    position: absolute;
    right: -156px;
    top: 0.5em;
    width: 128px;
    text-align: left;
  }
}
.sect__title {
  font-family: var(--ff-serif); font-weight: 500;
  font-size: var(--t-28); line-height: 1.12;
  letter-spacing: -0.008em;
  margin: 0 0 16px;
  text-wrap: balance;
  color: var(--ink);
}
.sect__tldr {
  font-family: var(--ff-sans); font-weight: 500;
  font-size: var(--t-17); line-height: 1.45;
  color: var(--ink);
  padding-left: 14px;
  border-left: 2px solid var(--accent);
  margin: 0 0 32px;
  max-width: 56ch;
  text-wrap: pretty;
}
.sect__tldr .lbl {
  font-family: var(--ff-mono); font-size: var(--t-11);
  text-transform: uppercase; letter-spacing: 0.14em;
  color: var(--ink-3);
  font-weight: 500;
  display: block;
  margin-bottom: 4px;
}

/* h3 subsection */
.sect h3 {
  font-family: var(--ff-mono); font-weight: 500;
  font-size: var(--t-11); line-height: 1.3;
  text-transform: uppercase; letter-spacing: 0.16em;
  color: var(--ink);
  margin: 48px 0 14px;
  padding-bottom: 6px;
  border-bottom: 1px solid var(--rule);
}

/* ── Click-to-copy heading anchors (renderer wraps titles in a.sect__anchor) ── */
/* The anchor must read identically to plain heading text until hovered: inherit
   color, no underline. The "Copied" flash is the only heading-side mark; the
   copy affordance itself is a small icon living in .sect__num / .sect__h3-num
   (the floating section-number kicker), not next to the title. Hovering the
   number OR the title reveals it, via the :has() rules below. Explicit
   border:none on hover is required — `.sect a:hover` sets a generic
   border-bottom that would otherwise underline "§ 01"/the kicker/the title. */
.sect__title .sect__anchor,
.sect__num .sect__anchor,
.sect h3 .sect__anchor {
  color: inherit;
  text-decoration: none;
  border: none;
  position: relative;
  cursor: pointer;
}
.sect__title .sect__anchor:hover,
.sect__num .sect__anchor:hover,
.sect h3 .sect__anchor:hover { border: none; color: inherit; }

/* Copy-link icon: immediately left of the § glyph, sized and colored to
   match it (not the smaller/dimmer treatment used for the h3 sub-marker). */
.sect__num .sect__anchor-icon {
  display: inline-flex; align-items: center; justify-content: center;
  margin-right: 4px;
  font-size: var(--t-28);
  color: var(--accent);
  text-decoration: none; border: none;
  opacity: 0;
  transition: opacity 160ms ease;
}
.sect__num .sect__anchor-icon svg { width: 0.62em; height: 0.62em; }
.sect__h3-num .sect__anchor-icon {
  display: inline-flex; align-items: center; justify-content: center;
  margin-right: 7px;
  vertical-align: -1px;
  color: var(--accent);
  text-decoration: none; border: none;
  opacity: 0;
  transition: opacity 160ms ease;
}
.sect__num .sect__anchor-icon:hover,
.sect__num .sect__anchor-icon:focus-visible,
.sect__h3-num .sect__anchor-icon:hover,
.sect__h3-num .sect__anchor-icon:focus-visible { opacity: 1; }
section.sect:has(.sect__title > .sect__anchor:hover) .sect__num .sect__anchor-icon,
section.sect:has(.sect__title > .sect__anchor:focus-visible) .sect__num .sect__anchor-icon,
section.sect:has(.sect__num > .sect__anchor:hover) .sect__num .sect__anchor-icon,
section.sect:has(.sect__num > .sect__anchor:focus-visible) .sect__num .sect__anchor-icon { opacity: 1; }
.sect h3:has(.sect__anchor:hover) .sect__h3-num .sect__anchor-icon,
.sect h3:has(.sect__anchor:focus-visible) .sect__h3-num .sect__anchor-icon { opacity: 1; }

.sect__copied {
  position: absolute;
  left: -0.2em; top: -1.7em;
  font-family: var(--ff-mono); font-size: var(--t-11);
  text-transform: uppercase; letter-spacing: 0.12em;
  color: var(--accent); background: var(--bg);
  padding: 2px 7px; border: 1px solid var(--rule);
  opacity: 0; transform: translateY(4px);
  transition: opacity 160ms ease, transform 160ms ease;
  pointer-events: none; white-space: nowrap;
}
.sect__copied.is-visible { opacity: 1; transform: translateY(0); }

/* ── Body prose ─────────────────────────────────────────────── */
.sect p, .lede p {
  margin: 0 0 18px;
  text-wrap: pretty;
  hyphens: auto;
}
.sect a, .lede a {
  color: var(--ink);
  text-decoration: none;
  border-bottom: 1px solid var(--rule);
  transition: border-color 120ms;
}
.sect a:hover, .lede a:hover { border-bottom-color: var(--ink); }
em { font-style: italic; }
strong { font-weight: 600; color: var(--ink); }
/* Inline math inside bold. KaTeX styles its own root with the `font`
   shorthand (`font: normal 1.21em KaTeX_Main…`), and the shorthand resets
   font-weight to `normal`. So a `$…$` sitting inside `**bold**` silently
   drops back to regular weight and snaps the bold run in half mid-sentence —
   "this machinery is $N$-means clustering" renders with a thin N. Re-assert
   the weight on the KaTeX root: `strong .katex` (0,1,1) outranks KaTeX's own
   `.katex` (0,1,0) in either load order, and the weight then inherits down to
   `.mathnormal` / `.mord`, which set family and style but not weight. KaTeX
   ships true 700 faces (KaTeX_Main 700, KaTeX_Math 700 italic), so this
   selects a real bold face rather than a synthesized smear. Scoped to
   strong/b only — display math and ordinary inline math are untouched. */
strong .katex, b .katex { font-weight: 700; }
code, .mono {
  font-family: var(--ff-mono);
  font-size: 0.92em;
  color: var(--ink);
}
/* Inline code only. :not(pre) > code structurally excludes code blocks
   (parent is always <pre> there) rather than fighting `pre code` on
   specificity — a plain `pre code { background: none }` override loses to
   this rule's specificity and paints one background per wrapped line
   inside the block instead of leaving it to <pre>'s own background. */
.doc :not(pre) > code {
  background: color-mix(in oklch, var(--ink) 6%, var(--bg));
  padding: 0.15em 0.4em;
  border-radius: 3px;
}

/* ── Citations & footnotes ──────────────────────────────────── */
/* Click still jumps to the definition (real hrefs, unchanged); cursor:help
   signals the added hover/focus preview (see #hover-tip below) alongside
   that, not instead of it. */
/* No brackets on either — bare superscript numerals. Footnotes and
   citations need their own signal now that "[N]" isn't doing that job for
   both identically: footnotes stay plain (an aside, in the single accent
   color); citations get the dotted underline already used for glosses
   elsewhere in this file (the same "there's a popup here" grammar, since
   a citation and a gloss are both "hover for more, click if you want the
   full thing" — a footnote is closer to a parenthetical). */
/* a.___ (tag+class, matching .sect a/.lede a's own specificity) rather
   than the bare .fn-ref/.cite class — these markers render inside .sect
   and .lede prose (and .fn-ref also inside .endmatter, for a footnote
   that cross-references another), where the generic link rule above
   otherwise wins on specificity and overrides the color/border entirely,
   regardless of which one is defined later in the file. Being defined
   after that rule here breaks the specificity tie in this selector's
   favor. */
a.cite, a.fn-ref {
  font-family: var(--ff-mono); font-size: 0.78em;
  vertical-align: super; line-height: 0;
  text-decoration: none; border: none; font-weight: 500;
  padding: 0 1px;
  cursor: help;
}
a.fn-ref { color: var(--accent); }
a.fn-ref:hover { color: var(--ink); }
a.cite {
  color: var(--ink-2);
  border-bottom: 1px dotted var(--ink-3);
}
a.cite:hover { color: var(--accent); border-bottom-color: var(--accent); }

/* ── Glosses (foreign / unfamiliar terms, hover-defined) ─────── */
.gloss {
  border-bottom: 1px dotted var(--ink-3);
  cursor: help;
  color: inherit;
}
.gloss:hover, .gloss:focus-visible {
  border-bottom-color: var(--accent);
  color: var(--accent);
  outline: none;
}

/* ── Shared hover preview (citations, footnotes, glosses) ─────
   One floating box, positioned in JS via getBoundingClientRect() rather
   than three separate CSS-only :hover popovers — avoids per-trigger
   clipping/z-index bookkeeping and lets all three share one
   show/hide/position implementation. No box-shadow: hairline border only,
   matching the "no shadows" rule the rest of this file follows. */
#hover-tip {
  position: fixed;
  z-index: 90;
  max-width: 340px;
  background: var(--bg);
  border: 1px solid var(--rule);
  padding: 12px 16px;
  font-family: var(--ff-sans);
  font-size: var(--t-14);
  line-height: 1.5;
  color: var(--ink);
  opacity: 0;
  visibility: hidden;
  transform: translateY(4px);
  transition: opacity 140ms ease, transform 140ms ease;
  pointer-events: none;
}
#hover-tip.is-visible { opacity: 1; visibility: visible; transform: translateY(0); }
#hover-tip .hover-tip__label {
  display: block;
  font-family: var(--ff-mono); font-size: var(--t-11);
  text-transform: uppercase; letter-spacing: 0.1em;
  color: var(--accent);
  margin-bottom: 5px;
}
#hover-tip .hover-tip__label[hidden] { display: none; }
#hover-tip .hover-tip__body :first-child { margin-top: 0; }
#hover-tip .hover-tip__body :last-child { margin-bottom: 0; }
#hover-tip .hover-tip__body .back { display: none; } /* strip the ↩ from the preview copy */
@media (max-width: 900px) {
  #hover-tip { display: none; } /* no hover on touch; tap still jumps via the real href */
}

/* ── Math ───────────────────────────────────────────────────── */
.math, .math-block { font-family: var(--ff-serif); font-style: italic; }
.math sub, .math sup, .math-block sub, .math-block sup {
  font-style: normal; font-family: var(--ff-serif);
}

/* ── Equation numbering (auto, KaTeX display math) ─────────────
   Targets KaTeX's own `.katex-display` wrapper rather than a page-local
   convention like `.math-display` — KaTeX applies that class to every
   display-mode render ($$…$$ / \[…\]) regardless of whether the author
   added an outer wrapper div, and inline math ($…$ / \(…\)) renders as a
   bare `.katex` span with no `-display` suffix, so this selector numbers
   block equations only, automatically, with no per-post markup.
   Reset lives on body, not a content wrapper — a rendered Carbon page is
   always exactly one document (sections are siblings directly under
   <body>, no shared <article>), so there's no risk of the counter bleeding
   between posts sharing a page (the /writing index page carries no
   equations at all). `.katex-display` is block-level and full-width per
   KaTeX's own CSS (its inner `.katex` is the centered inline-block), so
   the number pins to the column's right margin regardless of how wide the
   rendered formula itself is — the conventional placement for numbered
   equations, not flush against the glyphs.
   `html body`, not `body`: KaTeX's own stylesheet ships `body {
   counter-reset: katexEqnNo mmlEqnNo; }` (its internal support for
   \tag{}), loaded after carbon.css since inject_katex() splices the KaTeX
   <link> right before the closing head tag. Same-specificity `body` rules resolve by
   source order, so KaTeX's would silently win and wipe out ours — no
   ancestor would establish the `equation` counter's scope, and every
   .katex-display would instantiate its own local counter starting at 1,
   the exact bug this comment is here to keep someone from reintroducing.
   `html body` (two type selectors) always outranks `body` alone
   regardless of link order. The reset also carries KaTeX's own counter
   names forward so a future \tag{} equation still numbers correctly.
   Excludes `.katex-display` nested in `.math-block`: the annotated /
   interactive equation figure type (Lithograph skill,
   figure-types/annotated-equations.md) calls
   `katex.render(..., {displayMode:true})` into a `.math-block` target and
   hand-authors its own `<span class="eq-num">` beside it — that also
   produces a `.katex-display`, so without the exclusion an annotated
   equation would show two numbers. Plain display equations (the common
   case, via auto-render on $$…$$) are unaffected. */
html body { counter-reset: equation katexEqnNo mmlEqnNo; }
.katex-display:not(.math-block *) {
  counter-increment: equation;
  position: relative;
}
.katex-display:not(.math-block *)::after {
  content: "(" counter(equation) ")";
  position: absolute;
  top: 50%;
  right: 0;
  transform: translateY(-50%);
  font-family: var(--ff-mono);
  font-size: var(--t-11);
  color: var(--ink-3);
  letter-spacing: 0.10em;
  font-variant-numeric: tabular-nums;
}

/* ── Interactive equations ──────────────────────────────────── */
.eq-block {
  max-width: var(--col); margin: 36px auto;
  padding: 8px 0;
}
.math-block {
  text-align: center;
  font-size: var(--t-28);
  margin: 0;
  color: var(--ink);
}
.math-block .eq-num {
  float: right;
  font-family: var(--ff-mono); font-style: normal;
  font-size: var(--t-11);
  color: var(--ink-3);
  margin-top: 10px;
  letter-spacing: 0.10em;
}
.eq-term {
  cursor: pointer; padding: 1px 3px;
  border-bottom: 1px dotted var(--rule);
  transition: background-color 220ms ease, border-color 220ms ease, color 220ms ease;
}
.eq-term:hover { border-bottom-color: var(--ink); }
.eq-term[data-active="true"] {
  background: var(--accent-tint);
  border-bottom: 1px solid var(--accent);
}
.eq-gloss {
  margin-top: 22px;
  padding-top: 14px;
  border-top: 1px solid var(--rule);
  display: grid; grid-template-columns: max-content 1fr;
  gap: 20px; align-items: baseline;
  font-size: var(--t-14); line-height: 1.55;
  color: var(--ink-2);
  overflow: hidden;
  animation: glossIn 240ms cubic-bezier(0.2, 0.7, 0.2, 1) both;
}
@keyframes glossIn {
  from { opacity: 0; transform: translateY(-4px); max-height: 0; padding-top: 0; margin-top: 0; }
  to   { opacity: 1; transform: translateY(0);    max-height: 400px; padding-top: 14px; margin-top: 22px; }
}
.eq-gloss[hidden] { display: none; }
.eq-gloss__id {
  font-family: var(--ff-mono); font-size: var(--t-11);
  text-transform: uppercase; letter-spacing: 0.14em;
  color: var(--ink); font-weight: 500; white-space: nowrap;
}
.eq-gloss__body b { color: var(--ink); font-weight: 600; }
.eq-hint {
  display: block; text-align: right; margin-top: 10px;
  font-family: var(--ff-mono); font-size: var(--t-11);
  text-transform: uppercase; letter-spacing: 0.12em;
  color: var(--ink-3);
  transition: opacity 200ms;
}

/* ── Figures ────────────────────────────────────────────────── */
figure {
  margin: 56px auto;
  max-width: var(--col-wide);
  position: relative;
}
figure.figure--full { max-width: var(--col-meta); }

.figure-frame {
  padding: 0;
  background: var(--img-surface);
}
.figure-frame img {
  display: block;
  width: 100%;
  max-width: 100%;
  height: auto;
  box-shadow: var(--img-shadow);
}
/* Markdown inline images (bare <img> in body copy, not in <figure>) */
.doc img,
.lede img {
  display: block;
  width: 100%;
  max-width: 100%;
  height: auto;
  background: var(--img-surface);
  margin: 28px 0;
  box-shadow: var(--img-shadow);
}
/* Vertical figure variant — image is taller than wide; constrain width */
figure.figure--vert {
  max-width: 520px;
}
figure.figure--vert .figure-frame img {
  max-height: 80vh;
  object-fit: contain;
  margin: 0 auto;
}
figcaption {
  margin-top: 14px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--rule);
  font-size: var(--t-14);
  color: var(--ink-2);
  line-height: 1.5;
  text-wrap: pretty;
}
figcaption b { color: var(--ink); font-weight: 600; }

/* Fig-ID inline at start of caption with weight contrast. */
.fig-id {
  font-family: var(--ff-mono);
  font-size: var(--t-11);
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--ink);
  font-weight: 600;
  margin-right: 10px;
  white-space: nowrap;
}

/* In-prose figure cross-reference, e.g. "[fig:w7]" -> "Fig. 8". Accent +
   dotted underline distinguishes it from a plain body link (ink + solid
   rule) as a structural jump-to-figure, not an external reference.
   Selectors repeat `.sect`/`.lede` to out-specificity the ".sect a" /
   ".lede a" body-link rule above, which otherwise wins the cascade. */
.sect a.fig-ref, .lede a.fig-ref {
  color: var(--accent);
  text-decoration: none;
  border-bottom: 1px dotted var(--accent);
  font-weight: 500;
  white-space: nowrap;
  transition: color 120ms, border-color 120ms;
}
.sect a.fig-ref:hover, .lede a.fig-ref:hover {
  color: var(--ink); border-bottom-color: var(--ink); border-bottom-style: solid;
}

/* Expand icon — floats right inside the caption, text wraps around */
/* Expand affordance — naked icon, no box, no hover label. */
.fig-expand {
  float: right;
  margin: 2px 0 6px 16px;
  display: inline-flex;
  align-items: center;
  background: transparent;
  border: none;
  color: var(--ink-3);
  cursor: pointer;
  padding: 4px;
  line-height: 0;
  transition: color 200ms ease;
}
.fig-expand:hover { color: var(--ink); }
.fig-expand .label { display: none; }
.fig-expand .sr-only { display: none; }

/* ── Pull-quote — quiet single line ─────────────────────────── */
.pq {
  max-width: var(--col); margin: 48px auto;
  padding: 20px 0;
  border-top: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
}
.pq__body {
  font-family: var(--ff-serif); font-style: italic; font-weight: 400;
  font-size: var(--t-21); line-height: 1.35;
  color: var(--ink);
  text-wrap: pretty;
  margin: 0;
}
.pq__cite {
  display: block;
  margin-top: 8px;
  font-family: var(--ff-mono); font-size: var(--t-11);
  text-transform: uppercase; letter-spacing: 0.12em;
  color: var(--ink-3);
}
.pq__cite b { color: var(--ink); font-weight: 500; }

/* ── Stats row (optional, body-width) ───────────────────────── */
.stats {
  max-width: var(--col); margin: 48px auto;
  display: grid; grid-template-columns: repeat(3, 1fr);
  border-top: 1px solid var(--ink);
  border-bottom: 1px solid var(--rule);
}
.stat {
  padding: 20px 16px;
  border-right: 1px solid var(--rule);
}
.stat:last-child { border-right: none; }
.stat__n {
  font-family: var(--ff-serif); font-weight: 500;
  font-size: var(--t-37); line-height: 1;
  letter-spacing: -0.015em;
  color: var(--ink);
  font-variant-numeric: tabular-nums lining-nums;
}
.stat__n--accent { color: var(--accent); }
.stat__n .unit {
  font-family: var(--ff-mono); font-size: var(--t-14);
  font-weight: 400; color: var(--ink-3);
  margin-left: 4px;
}
.stat__label {
  font-family: var(--ff-mono); font-size: var(--t-11);
  text-transform: uppercase; letter-spacing: 0.12em;
  color: var(--ink-3); font-weight: 500;
  margin-top: 10px;
}
.stat__body {
  font-size: var(--t-14);
  color: var(--ink-2); line-height: 1.45;
  margin-top: 6px;
}
@media (max-width: 720px) {
  .stats { grid-template-columns: 1fr; }
  .stat { border-right: none; border-bottom: 1px solid var(--rule); }
  .stat:last-child { border-bottom: none; }
}

/* ── Tables ─────────────────────────────────────────────────── */
.tbl-wrap { max-width: var(--col); margin: 36px auto; }
table {
  width: 100%; border-collapse: collapse;
  font-size: var(--t-14);
  font-variant-numeric: tabular-nums lining-nums;
}
thead th {
  text-align: left;
  font-family: var(--ff-mono); font-weight: 500;
  font-size: var(--t-11);
  text-transform: uppercase; letter-spacing: 0.12em;
  color: var(--ink-3);
  padding: 10px 12px 8px;
  border-top: 1px solid var(--ink);
  border-bottom: 1px solid var(--ink);
}
tbody td {
  padding: 10px 12px;
  border-bottom: 1px solid var(--rule-2);
  color: var(--ink);
  vertical-align: top;
}
tbody tr:last-child td { border-bottom: 1px solid var(--rule); }
tbody td:first-child { font-family: var(--ff-mono); }
td.num, th.num { text-align: right; font-variant-numeric: tabular-nums; }

/* ── Code block ─────────────────────────────────────────────── */
pre {
  /* Shared height for the language pill and the copy button — both sit in
     the same sticky top-right row and need to line up exactly, not just
     approximately (t-11 line-height + the pill's own padding + border).
     Define once here so neither can drift from the other again. */
  --code-pill-h: calc(var(--t-11) * 1.55 + 12px);
  max-width: var(--col); margin: 28px auto;
  font-family: var(--ff-mono);
  font-size: var(--t-14); line-height: 1.55;
  color: var(--ink);
  /* Theme-relative, not a fixed color, so it stays a quiet surface in both
     light and dark without a separate override. No border-radius — that
     was in an earlier pass and made this read as a UI "card" rather than
     a block of text with a tint, which is the actual "no shadows, no
     radii" rule this file follows everywhere else. */
  background: color-mix(in oklch, var(--ink) 4%, var(--bg));
  padding: 16px 20px;
  border-top: 1px solid var(--ink);
  border-bottom: 1px solid var(--rule);
  overflow-x: auto;
  white-space: pre-wrap;
  overflow-wrap: break-word;
  position: relative;
}
/* Language tag rides in the same sticky top-right row as .pre__copy
   (float order puts this — pre's first generated content — rightmost,
   the copy button just to its left) rather than floating disconnected
   above the block, so the two read as one grouped affordance.
   Scoped to [data-lang] (renderer omits the attribute when there's no
   language) so an unlabeled block doesn't get an empty floating pill. */
pre[data-lang]::before {
  content: attr(data-lang);
  display: inline-flex;
  align-items: center;
  height: var(--code-pill-h);
  box-sizing: border-box;
  position: sticky;
  float: right;
  top: 8px;
  margin-left: 8px;
  padding: 0 8px;
  font-family: var(--ff-mono);
  font-size: var(--t-11);
  text-transform: uppercase; letter-spacing: 0.10em;
  color: var(--ink-3);
  background: var(--bg);
  border: 1px solid var(--rule);
  border-radius: 3px;
  opacity: 0.85;
}
pre .kw { color: var(--ink); font-weight: 600; }
pre .cm { color: var(--ink-3); font-style: italic; }
pre .ac { color: var(--accent); }

/* ── Copy-to-clipboard on code blocks ──────────────────────────
   Renderer wraps a <button class="pre__copy"> as the first child of
   every <pre>; JS wires the click handler. Sticky (not absolute) so
   it stays pinned to the right edge while a long line scrolls under
   it — `pre` is the only scroll container, horizontal-only. */
.pre__copy {
  position: sticky;
  float: right;
  top: 8px; right: 8px;
  margin-left: 8px;
  display: inline-flex; align-items: center; justify-content: center;
  /* Same --code-pill-h as the language pill beside it (see `pre`) — was
     previously its own separate calc() that happened to land close but
     not exact, which is exactly the kind of thing that should share one
     source instead of two formulas aimed at the same number. */
  width: var(--code-pill-h); height: var(--code-pill-h);
  box-sizing: border-box;
  padding: 0;
  border: 1px solid var(--rule);
  border-radius: 3px;
  background: var(--bg);
  color: var(--ink-2);
  cursor: pointer;
  opacity: 0.55;
  transition: opacity 160ms ease, color 120ms ease, border-color 120ms ease;
}
pre:hover .pre__copy,
pre:focus-within .pre__copy { opacity: 1; }
.pre__copy:hover { color: var(--accent-bright); border-color: var(--accent-bright); }
.pre__copy-label {
  position: absolute;
  top: -1.9em; right: 0;
  font-family: var(--ff-mono); font-size: var(--t-11);
  text-transform: uppercase; letter-spacing: 0.12em;
  color: var(--accent); background: var(--bg);
  padding: 2px 7px; border: 1px solid var(--rule);
  opacity: 0; transform: translateY(4px);
  transition: opacity 160ms ease, transform 160ms ease;
  pointer-events: none; white-space: nowrap;
}
.pre__copy-label.is-visible { opacity: 1; transform: translateY(0); }

/* ── Endmatter ──────────────────────────────────────────────── */
.endmatter {
  max-width: var(--col-meta);
  margin: 120px auto 0;
  padding-top: 24px;
  border-top: 1px solid var(--ink);
  display: grid; grid-template-columns: 220px 1fr; gap: 48px;
}
.endmatter h2 {
  font-family: var(--ff-mono);
  font-size: var(--t-11);
  text-transform: uppercase; letter-spacing: 0.14em;
  color: var(--ink); font-weight: 500;
  margin: 0;
}
.endmatter__meta {
  font-family: var(--ff-mono); font-size: var(--t-11);
  text-transform: uppercase; letter-spacing: 0.10em;
  color: var(--ink-3); line-height: 1.6;
  margin-top: 12px; max-width: 200px;
}
.endmatter ol {
  list-style: none; padding: 0; margin: 0;
  columns: 1;
}
.endmatter#refs ol {
  columns: 2; column-gap: 48px;
  column-rule: 1px solid var(--rule);
}
.endmatter li {
  display: grid; grid-template-columns: 36px 1fr; gap: 12px;
  padding: 12px 0;
  border-bottom: 1px solid var(--rule-2);
  break-inside: avoid;
  font-size: var(--t-14); line-height: 1.55;
  color: var(--ink-2);
}
.endmatter li:first-child { padding-top: 0; }
.endmatter li:last-child { border-bottom: none; }
.endmatter li[data-clickable="true"] { cursor: pointer; transition: background-color 200ms ease; }
.endmatter li[data-clickable="true"]:hover { background: var(--accent-tint); }
.endmatter .back {
  font-family: var(--ff-mono);
  font-size: var(--t-11);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--ink-3);
  text-decoration: none;
  border: none;
  white-space: nowrap;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-left: 8px;
  opacity: 0;
  transition: opacity 200ms ease, color 200ms ease;
}
.endmatter li:hover .back { opacity: 1; }
.endmatter .back:hover { color: var(--ink); }
.endmatter .back .arr { font-family: var(--ff-mono); }
.endmatter .marker {
  font-family: var(--ff-mono);
  font-size: var(--t-11);
  text-transform: uppercase; letter-spacing: 0.10em;
  color: var(--ink-3);
  padding-top: 3px;
}
.endmatter cite { font-style: normal; color: var(--ink); }
.endmatter .ref-title { color: var(--ink); }
.endmatter .ref-venue { font-style: italic; color: var(--ink-2); }
@media (max-width: 900px) {
  .endmatter { grid-template-columns: 1fr; gap: 24px; }
  .endmatter#refs ol { columns: 1; }
}

/* ── Colophon ───────────────────────────────────────────────── */
.colophon {
  max-width: var(--col-meta);
  margin: 96px auto 0;
  padding: 24px 0;
  border-top: 1px solid var(--rule);
  display: grid; grid-template-columns: 220px 1fr 1fr;
  gap: 48px;
  font-family: var(--ff-mono); font-size: var(--t-11);
  text-transform: uppercase; letter-spacing: 0.10em;
  color: var(--ink-3);
}
.colophon b { color: var(--ink); font-weight: 500; }
.colophon__label { color: var(--ink); letter-spacing: 0.14em; }
@media (max-width: 900px) {
  .colophon { grid-template-columns: 1fr; gap: 16px; }
}

/* ── Post navigation (back to notes index) ───────────────────── */
.post-nav {
  max-width: var(--col-meta);
  margin: clamp(72px, 10vw, 96px) auto 0;
  padding-top: 24px;
  border-top: 1px solid var(--rule);
}
.post-nav__back {
  font-family: var(--ff-mono);
  font-size: var(--t-11);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--ink-2);
  text-decoration: none;
  border-bottom: 1px solid var(--rule);
  transition: color 200ms ease, border-color 200ms ease;
}
.post-nav__back:hover {
  color: var(--accent);
  border-bottom-color: var(--accent);
}
.post-nav__arrow { margin-right: 0.35em; }

/* ── Figure expand modal ────────────────────────────────────── */
.fig-modal {
  position: fixed; inset: 0; z-index: 200;
  background: oklch(0.985 0.003 248);
  display: grid;
  grid-template-rows: auto 1fr auto;
  padding: 0;
  animation: modalIn 280ms cubic-bezier(0.2, 0.7, 0.2, 1) both;
}
.fig-modal[hidden] { display: none; }
.fig-modal__body > * {
  animation: modalFigIn 360ms 80ms cubic-bezier(0.2, 0.7, 0.2, 1) both;
}
@keyframes modalIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}
@keyframes modalFigIn {
  from { opacity: 0; transform: translateY(8px) scale(0.985); }
  to   { opacity: 1; transform: translateY(0)   scale(1); }
}
@media (prefers-reduced-motion: reduce) {
  .fig-modal, .fig-modal__body > *, .eq-gloss { animation: none; }
}
.fig-modal__head {
  padding: 18px 32px;
  border-bottom: 1px solid var(--rule);
  display: flex; justify-content: space-between; align-items: baseline;
  font-family: var(--ff-mono);
  font-size: var(--t-11);
  text-transform: uppercase; letter-spacing: 0.14em;
  color: var(--ink-3);
}
.fig-modal__title b { color: var(--ink); font-weight: 500; }
.fig-modal__close {
  font-family: var(--ff-mono); font-size: var(--t-11);
  text-transform: uppercase; letter-spacing: 0.14em;
  color: var(--ink);
  background: transparent;
  border: none;
  cursor: pointer;
  padding: 0;
}
.fig-modal__close:hover { color: var(--accent); }
.fig-modal__body {
  display: flex; align-items: center; justify-content: center;
  padding: clamp(32px, 6vh, 80px) clamp(32px, 8vw, 160px);
  overflow: auto;
  min-height: 0;
}
.fig-modal__body > * {
  width: 100%;
  max-width: 1400px;
  max-height: 76vh;
}
.fig-modal__body svg {
  width: 100%; height: auto;
  max-height: 76vh;
}
.fig-modal__body img {
  display: block;
  width: 100%; height: auto;
  max-height: 76vh;
  object-fit: contain;
  background: var(--img-surface);
  box-shadow: var(--img-shadow);
}
.fig-modal__body .figure-frame {
  border: none;
}
.fig-modal__caption {
  padding: 18px 32px 28px;
  font-size: var(--t-14);
  color: var(--ink-2);
  line-height: 1.55;
  max-width: 80ch;
  margin: 0 auto;
}
.fig-modal__caption b { color: var(--ink); font-weight: 600; }

/* ── Figure tip ─────────────────────────────────────────────── */
.fig-tip {
  position: fixed; pointer-events: none;
  background: var(--ink); color: var(--bg);
  font-family: var(--ff-mono); font-size: var(--t-11);
  letter-spacing: 0.08em; text-transform: uppercase;
  padding: 6px 10px; z-index: 150;
  white-space: nowrap;
  opacity: 0; transition: opacity 120ms;
  transform: translate(-50%, -130%);
}
.fig-tip[data-show="true"] { opacity: 1; }

/* ── Fig 1.1 internals ──────────────────────────────────────── */
.fig1-svg { display: block; width: 100%; height: auto; }
.fig1-svg .axis     { stroke: var(--ink); stroke-width: 1; }
.fig1-svg .gridline { stroke: var(--rule); stroke-width: 1; }
.fig1-svg .trace    { fill: none; stroke: var(--ink); stroke-width: 1.25; }
.fig1-svg .trace-2  { fill: none; stroke: var(--ink-3); stroke-width: 1; stroke-dasharray: 3 3; }
.fig1-svg .point    { fill: var(--bg); stroke: var(--ink); stroke-width: 1; cursor: crosshair; }
.fig1-svg .point:hover { stroke-width: 2; }
.fig1-svg .point-accent { fill: var(--accent); stroke: var(--accent); }
.fig1-svg text { font-family: var(--ff-mono); font-size: 13px; fill: var(--ink-3); letter-spacing: 0.04em; }
.fig1-svg .label-strong { fill: var(--ink); }

/* ── Responsive ─────────────────────────────────────────────── */
@media (max-width: 760px) {
  :root {
    --t-37: 1.7rem;
    --t-28: 1.4rem;
    --t-21: 1.15rem;
  }
  body { padding: 0 20px 96px; }
  .masthead { margin-top: 56px; }
  .masthead__top { grid-template-columns: 1fr; gap: 12px; }
  .masthead__rule { display: none; }
  .masthead__ext { align-items: flex-start; padding-top: 16px; }
  .byline { display: grid; grid-template-columns: 1fr 1fr; }
  .byline > div:last-child { text-align: left; align-items: flex-start; }
  .hero__caption { flex-direction: column; gap: 6px; }
}

  /* === Lithograph defaults (v1.0, 2026-05-14) ===
     - sect__tldr and sect__counter are NOT emitted by default
       (set display:none in case they sneak in from a template author who copies the sample)
     - section-num kicker bumped from --t-11 to --t-17 for read-at-a-glance scan */
  .sect__tldr   { display: none; }
  .sect__counter { display: none; }
  /* Section header hierarchy v5 (Rome 2026-05-15 — title dominates, kicker label recedes) */
  .sect__num            { font-size: var(--t-21); color: var(--ink-3); font-weight: 400; line-height: 1.2; }
  /* display:block moved to .sect__num-kicker (the line break belongs after
     the icon+§-number line, not on .accent itself — see the rule near the
     top of this file). */
  .sect__num .accent    { font-size: var(--t-28); line-height: 1.12; font-weight: 500; }
  .sect__num-kicker     { margin-bottom: 8px; }
  .sect__title          { font-size: var(--t-37); font-weight: 600; line-height: 1.08; margin-bottom: 24px; }
  @media (min-width: 1240px) {
    .sect__num { top: 0.32em; width: 220px; left: -256px; }
    .sect__title { margin-top: 0; }
  }
