/* =============================================================
   Novum Alexandria — global styles
   ============================================================= */

:root {
  /* dark (default) — neutralized warmth and stepped down a notch.
     Previously these were warm grays (slight brown cast); now nearly
     neutral with just the faintest hint of warmth to keep the project
     from feeling cold. */
  --ink:           #0a0a09;
  --ink-2:         #131312;
  --ink-3:         #1a1a18;
  --bone:          #d4cdb8;
  --bone-dim:      #948b75;
  --fog:           #6e6759;
  --shadow:        #3d3a33;
  --rule:          #26221c;
  --rule-bright:   #3b362c;
  --gold:          #b89968;
  --gold-dim:      #7c6741;
  --gold-glow:     rgba(184,153,104,0.22);
  --translation:   #c4bea8;   /* slightly cooler, dimmer than --bone */

  /* reader-controllable typography */
  --reader-size: 20px;
  --reader-family: 'EB Garamond', 'Iowan Old Style', Georgia, serif;
}

[data-theme="light"] {
  /* clean near-white — neutral paper, no tan cast. Backgrounds are an
     almost-pure white stepping into very light neutral grays; text is a
     neutral near-black. Gold is kept only as an accent (links, selection,
     CTA hover) so the brand reads through without warming the whole page. */
  --ink:           #fcfcfb;
  --ink-2:         #f4f4f3;
  --ink-3:         #eaeae8;
  --bone:          #1b1b1a;
  --bone-dim:      #54524d;
  --fog:           #7b7872;
  --shadow:        #cfcecb;
  --rule:          #e7e6e3;
  --rule-bright:   #d3d2ce;
  --gold:          #8a6e2e;
  --gold-dim:      #b8a06b;
  --gold-glow:     rgba(138,110,46,0.16);
  --translation:   #3c3b37;   /* slightly lighter and grayer than --bone (ink) */
}

* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
  /* iOS removes the gray tap-highlight rectangle on touch */
  -webkit-tap-highlight-color: transparent;
}
html, body {
  background: var(--ink);
  color: var(--bone);
  /* Prevent horizontal scroll from any rogue wide element. We use `clip`
     (Safari 16+) rather than `hidden` because `hidden` creates a new
     scroll-container ancestor, which breaks `position: sticky` (the
     reader-bar) on iOS — it would stick to that ancestor instead of the
     viewport. `clip` clips without forming a scroll container, so the
     sticky reader-bar continues to track the viewport correctly.
     `overflow-x: hidden` is declared first as a fallback for old browsers
     that don't recognize `clip`; modern browsers use the `clip` line. */
  overflow-x: hidden;
  overflow-x: clip;
  max-width: 100vw;
}
html {
  scroll-behavior: smooth;
  /* prevent iOS Safari from auto-scaling text when device rotates */
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}
body {
  font-family: 'EB Garamond', 'Iowan Old Style', Georgia, serif;
  font-size: 18px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  min-height: 100vh;
  transition: background 0.3s ease, color 0.3s ease;
}

/* Dark mode: no body glow — kept flat and clean. The pseudo-element
   stays in the DOM so the light-mode override below can paint into it
   without re-declaring the geometry. */
body::before {
  content: '';
  position: fixed; inset: 0;
  background: transparent;
  pointer-events: none;
  z-index: 0;
}
[data-theme="light"] body::before {
  /* kept flat/clean — a barely-there neutral haze instead of a warm glow */
  background:
    radial-gradient(ellipse 80% 60% at 50% 0%, rgba(0,0,0,0.015), transparent 70%);
}

a { color: inherit; text-decoration: none; }
::selection { background: var(--gold); color: var(--ink); }
[data-theme="light"] ::selection { background: var(--gold-dim); color: var(--ink); }

.mono { font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, monospace; }

/* ---------- topbar ---------- */
.topbar {
  position: relative; z-index: 10;
  display: flex; align-items: center; justify-content: space-between;
  padding: 28px 48px;
  border-bottom: 1px solid var(--rule);
}
.mark {
  display: flex; align-items: center; gap: 14px;
  font-family: 'EB Garamond', serif;
  font-size: 16px; letter-spacing: 0.04em;
  color: var(--bone);
}
.mark .hex {
  width: 9px; height: 9px;
  background: var(--gold);
  clip-path: polygon(50% 0, 100% 25%, 100% 75%, 50% 100%, 0 75%, 0 25%);
}
.mark .name {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--bone);
}

.topbar-right { display: flex; align-items: center; gap: 32px; }
.topbar nav {
  display: flex; gap: 32px;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 11px; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--fog);
}
.topbar nav a { transition: color 0.2s; }
.topbar nav a:hover, .topbar nav a.active { color: var(--bone); }

.theme-toggle {
  width: 32px; height: 32px;
  background: transparent;
  border: 1px solid var(--rule-bright);
  color: var(--fog);
  cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  font-family: 'JetBrains Mono', monospace;
  font-size: 14px;
  transition: all 0.2s;
}
.theme-toggle:hover { color: var(--gold); border-color: var(--gold); }
.theme-toggle .sun { display: none; }
[data-theme="light"] .theme-toggle .sun { display: inline; }
[data-theme="light"] .theme-toggle .moon { display: none; }

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

.coord {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 11px; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--fog);
}
.divider { height: 1px; background: var(--rule); border: none; margin: 32px 0; }

footer.foot {
  border-top: 1px solid var(--rule);
  padding: 40px 48px;
  display: flex; justify-content: space-between; align-items: flex-start;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--fog);
  margin-top: 80px;
}
footer.foot .foot-left {
  display: inline-flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
}
footer.foot .foot-left .foot-coord {
  color: var(--shadow);
}
footer.foot .foot-right {
  display: inline-flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
  text-align: left;
}
footer.foot .foot-sub {
  /* same JetBrains Mono as the rest of the footer, slightly dimmer */
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-style: normal;
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--shadow);
  text-align: left;
  align-self: flex-start;
  max-width: 56ch;
}

/* =============================================================
   GATE — minimal landing: just an epigraph and a single CTA
   ============================================================= */

.gate-page {
  background: var(--ink);
  color: var(--bone);
  min-height: 100vh;
  margin: 0;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
}

/* Gate page vignette. In dark mode, no gold center glow — just a very
   subtle outer darkening to gently focus the eye toward the cipher.
   Light mode keeps the warm center glow because it reads as warmth on
   parchment rather than as a hot spot. */
.gate-page::before {
  content: '';
  position: fixed; inset: 0;
  background:
    radial-gradient(ellipse 120% 120% at 50% 50%, transparent 60%, rgba(0,0,0,0.35) 100%);
  pointer-events: none;
  z-index: 0;
}
[data-theme="light"] .gate-page::before {
  /* no warm center glow — just a subtle neutral outer darkening to focus
     the eye, matching the clean white treatment */
  background:
    radial-gradient(ellipse 120% 120% at 50% 50%, transparent 55%, rgba(0,0,0,0.04) 100%);
}

.gate {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  width: 100%;
  max-width: 640px;
  padding: 48px 32px;
  animation: gateFadeIn 1.6s cubic-bezier(0.22, 0.7, 0.18, 1);
}

.gate-epigraph {
  /* Wider than truth needs (54-char truth line ~ 40ch in Garamond) so the
     SCRAMBLED state — cipher pool chars (caps, digits, wide punct like W,
     M, @, %) average ~1.5× lowercase width — fits line 1 without soft-
     wrapping. If parent is too narrow, em max-width below is irrelevant
     because the parent's content area binds first.
     width:100% (not just max-width) is essential: .gate-epigraph is a flex
     item of the centered column .gate, so without an explicit width it
     shrink-wraps to its current content. During the decode the random
     glyphs change width every tick, so a shrink-wrapped box would resize
     and re-center on every frame — the dominant source of decode jitter.
     Pinning width:100% gives a stable box the text flows within. */
  width: 100%;
  max-width: 100ch;
  margin: 0 auto 80px;
  font-family: 'EB Garamond', 'Iowan Old Style', Georgia, serif;
  font-style: normal;
  font-size: clamp(16px, 1.8vw, 21px);
  line-height: 1.55;
  color: var(--bone-dim);
}
/* Lock the quote to exactly two lines, with stable word-to-line
   membership. The truth string carries an explicit \n after
   "causes,"; white-space: pre-wrap honors it as a hard break.
   cipher.js preserves \n (it's in PRESERVE), so the break never
   gets replaced by a random character. This means the same words
   always live on the same line regardless of how wide the random
   cipher characters happen to render — no word ever jumps line.
   max-width must be wide enough that the SCRAMBLED line 1 fits
   without soft-wrapping. Truth chars (mostly lowercase) are narrow,
   but cipher pool chars (caps, digits, wide punct like W, M, @, %)
   average ~1.5× the width of lowercase. With truth line 1 at ~54
   chars, the scrambled state needs ~80ch — 100ch gives generous
   headroom. The block is centered in the page via negative auto
   margins so the wider em remains visually centered even though
   its .gate-epigraph parent is narrower. The height + overflow
   clip is a final safety net for any unexpected escape. */
.gate-epigraph em {
  display: block;
  font-style: normal;
  max-width: 100ch;
  margin: 0 auto;
  white-space: pre-wrap;
  height: calc(1.55em * 2);
  overflow: hidden;
}

/* Cell mode (data-cipher-cells): each character is rendered in its own
   fixed-width inline-block sized to its truth glyph, so a changing glyph
   never reflows its neighbors. nowrap keeps each line intact (line breaks
   come from explicit <br>s the script inserts for newline positions). */
/* Two classes so this beats `.gate-epigraph em` (which sets pre-wrap). */
.cipher.cipher-cells { white-space: nowrap; }
.cipher-cell {
  display: inline-block;
  text-align: center;
  /* A scramble glyph wider than its slot may overhang slightly; let it
     spill rather than shift the line, and don't let it catch pointer
     events between cells. */
  overflow: visible;
}

/* Prevent the brief "truth flash" on page load: any cipher element
   that should be scrambled at rest stays invisible until cipher.js
   has run its first paint (at which point data-cipher-state is set
   and this rule stops matching). Default-revealed ciphers show
   immediately because their rest state IS the truth — no flash. */
.cipher:not([data-cipher-default="revealed"]):not([data-cipher-state]) {
  visibility: hidden;
}

.gate-epigraph .epigraph-attr {
  display: block;
  margin-top: 24px;
  font-family: 'EB Garamond', 'Iowan Old Style', Georgia, serif;
  font-style: normal;
  font-size: 14px;
  letter-spacing: 0;
  text-transform: none;
  color: var(--fog);
}


/* CTA is hidden until the cipher group ('gate') has been fully revealed
   for the first time. The reveal is sticky: once discovered, the CTA
   persists even if the cipher scrambles again. */
.gate-cta {
  display: inline-flex;
  align-items: center;
  gap: 18px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--bone);
  text-decoration: none;
  padding: 18px 36px;
  border: 1px solid var(--rule-bright);
  background: transparent;
  cursor: pointer;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.9s ease 0.3s,
              color 0.3s ease,
              background 0.3s ease,
              border-color 0.3s ease,
              transform 0.3s ease,
              box-shadow 0.3s ease;
}
.gate.cipher-all-revealed .gate-cta {
  opacity: 1;
  pointer-events: auto;
}
.gate-cta:hover {
  color: var(--ink);
  background: var(--gold);
  border-color: var(--gold);
  transform: translateY(-2px);
  box-shadow: 0 14px 36px -10px var(--gold-glow);
}
.gate-cta .cta-arrow { transition: transform 0.3s ease; color: inherit; }
.gate-cta:hover .cta-arrow { transform: translateX(6px); }

@keyframes gateFadeIn {
  0%   { opacity: 0; transform: translateY(18px); }
  100% { opacity: 1; transform: translateY(0); }
}

@media (max-width: 700px) {
  .gate { padding: 32px 20px; }
  .gate-epigraph { margin-bottom: 64px; }
}

/* =============================================================
   ABOUT (home / minimalist · two-column)
   — Prose on the left, interactive demo on the right, sitting at
     the same vertical level. Generous spacing throughout, no
     hero heading. Click the passage itself to translate.
   ============================================================= */

.about {
  max-width: 1200px;
  margin: 0 auto;
  padding: 120px 64px 96px;
}
.about-coord {
  margin: 0 auto 56px;
  text-align: center;
}

/* Small column mark beneath the coord — Greek/Roman pillar drawn in line
   art, sized to feel like a typographic ornament rather than an icon.
   Equal vertical spacing above (via the coord's margin-bottom) and below
   (via this margin-bottom) so the pillar sits visually centered between
   the coord and the prose. */
.about-mark {
  display: block;
  width: 26px;
  height: auto;
  margin: 0 auto 56px;
  color: var(--gold-dim);
  opacity: 0.85;
}

/* ─── PROSE ─────────────────────────────────────────────────── */
/* Two prose paragraphs at the top, both at the same Garamond size.
   Block is centered on the page; text within stays left-aligned for
   readability across multi-line paragraphs. */
.about-prose {
  max-width: 72ch;
  margin: 0 auto 160px;
}
.about-prose p {
  font-family: 'EB Garamond', serif;
  font-size: clamp(18px, 1.5vw, 22px);
  line-height: 1.5;
  color: var(--bone);
  margin: 0 0 36px;
}
.about-prose p:last-child { margin-bottom: 0; }
/* Small coda after the last lead paragraph — italic, slightly smaller,
   dimmer, and indented so it reads as a subordinate stat. The negative
   top margin pulls it close to the previous paragraph (overriding the
   36px gap used between the two lead paragraphs). */
.about-stat {
  font-family: 'EB Garamond', serif;
  font-style: normal;
  font-size: clamp(16px, 1.2vw, 18px);
  line-height: 1.5;
  color: var(--bone-dim);
  margin: -20px 0 0 3em;
}

/* ─── STATIC DEMO (side-by-side, no interaction) ────────────── */
.about-demo { margin-bottom: 80px; }
.demo-pair {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 64px;
  align-items: start;
}
.demo-col { min-width: 0; }
.demo-col-eyebrow {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 10px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--fog);
  margin: 0 0 18px;
}

/* ─── CTA ───────────────────────────────────────────────────── */
.about-cta { margin-top: 0; }

/* ─── shared button classes (kept for legacy use elsewhere) ─── */
.btn {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px; letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--bone);
  border: 1px solid var(--rule-bright);
  background: transparent;
  padding: 14px 22px;
  cursor: pointer;
  transition: all 0.2s;
}
.btn:hover { color: var(--ink); background: var(--gold); border-color: var(--gold); }
.btn-text {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px; letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--fog);
  background: none; border: none;
  cursor: pointer; padding: 14px 0;
  border-bottom: 1px solid var(--rule);
  transition: color 0.2s, border-color 0.2s;
}
.btn-text:hover { color: var(--gold); border-color: var(--gold); }

/* ─── demo internals (clickable original, modern reveal, etc.) ─ */
.demo-original, .demo-modern {
  font-family: 'EB Garamond', serif;
  font-size: 20px;
  line-height: 1.55;
  color: var(--bone);
  max-width: 56ch;
  margin: 0 0 0 24px;
  padding-left: 16px;
  border-left: 1px solid var(--rule);
}
.demo-original { font-style: italic; color: var(--bone-dim); }
.demo-modern { font-style: normal; color: var(--bone); }
/* =============================================================
   LIBRARY
   ============================================================= */

.library-wrap { max-width: 1480px; margin: 0 auto; padding: 64px 48px 96px; }
.library-head {
  display: flex; justify-content: space-between; align-items: end;
  padding-bottom: 24px; border-bottom: 1px solid var(--rule);
  margin-bottom: 48px;
}
.library-head h2 {
  font-family: 'EB Garamond', serif;
  font-weight: 400; font-size: 48px;
  font-variant: small-caps; letter-spacing: 0.04em;
}
/* =================================================
   CATALOG — wall-of-cards layout (CARD GRID MODE)
   To revert to the previous vertical list, swap this block back
   to the row-grid rules in git history. Markup is identical.
   ================================================= */
.catalog {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 18px;
}
.catalog li {
  display: flex;
  flex-direction: column;
  padding: 22px 22px 18px;
  border: 1px solid var(--rule);
  background: transparent;
  font-family: 'EB Garamond', serif;
  font-size: 17px;
  color: var(--bone-dim);
  cursor: pointer;
  position: relative;
  transition: background 0.2s ease, border-color 0.2s ease, transform 0.18s ease;
}
.catalog li:hover {
  background: var(--ink-2);
  border-color: var(--rule-bright);
  color: var(--bone);
  transform: translateY(-1px);
}
.catalog li.unavailable { cursor: default; opacity: 0.42; }
.catalog li.unavailable:hover { background: transparent; transform: none; }

.catalog .year {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.22em;
  color: var(--fog);
  margin-bottom: 16px;
}
.catalog .title {
  font-family: 'EB Garamond', serif;
  font-style: italic;
  font-size: 22px;
  line-height: 1.2;
  color: var(--bone);
  margin-bottom: 6px;
}
.catalog li.unavailable .title { color: var(--bone-dim); }
.catalog .author {
  font-family: 'EB Garamond', serif;
  font-size: 14px;
  color: var(--bone-dim);
  margin-bottom: 14px;
}
.catalog .blurb {
  font-family: 'EB Garamond', serif;
  font-size: 13px;
  line-height: 1.55;
  color: var(--shadow);
  font-style: italic;
  flex: 1 1 auto;
  transition: color 0.2s;
}
.catalog li:hover .blurb { color: var(--fog); }

.catalog .enter {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.15em;
  color: var(--shadow);
  margin-top: 16px;
  padding-top: 12px;
  border-top: 1px solid var(--rule);
  display: flex;
  align-items: baseline;
  justify-content: flex-end;
  gap: 8px;
  transition: color 0.2s, border-color 0.2s;
}
.catalog li:hover .enter { border-top-color: var(--rule-bright); }
.catalog .enter .pct {
  color: var(--gold);
  font-weight: 500;
  text-align: right;
  flex: 0 0 auto;
}
.catalog .enter .dot { color: var(--shadow); flex: 0 0 auto; }
.catalog .enter .count {
  text-align: right;
  flex: 0 0 auto;
}
.catalog li:hover .enter .count { color: var(--bone-dim); }
.catalog li.unavailable .enter::before { content: 'forthcoming'; font-size: 10px; flex: 1 1 auto; }
.catalog li.unavailable .enter span { display: none; }

/* ── Favorite (pin) button ─────────────────────────────────────── */
.catalog .fav-btn {
  position: absolute;
  top: 12px;
  right: 12px;
  background: none;
  border: none;
  padding: 4px;
  cursor: pointer;
  color: var(--rule-bright);
  line-height: 0;
  z-index: 2;
  transition: color 0.18s ease, transform 0.18s ease;
}
.catalog .fav-btn svg {
  width: 13px;
  height: 15px;
  fill: none;
  display: block;
}
.catalog .fav-btn:hover { color: var(--gold-dim); transform: translateY(-1px); }
.catalog li.is-fav .fav-btn { color: var(--gold); }
.catalog li.is-fav .fav-btn svg { fill: var(--gold); }
.catalog li.is-fav .fav-btn:hover { color: var(--gold); }

/* Pinned cards get a faint gold left rule so the favorites section
   reads as visually distinct from the rest of the wall. */
.catalog li.pinned {
  border-left: 2px solid var(--gold-dim);
}
.catalog li.pinned:hover { border-left-color: var(--gold); }

.library-note {
  margin-top: 60px;
  font-family: 'EB Garamond', serif;
  font-style: italic; font-size: 16px;
  color: var(--fog);
  max-width: 60ch;
}

/* ── library controls: search + filter chips ─────────────────── */
.library-controls {
  display: flex; flex-direction: row; flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 24px 36px;
  margin-bottom: 32px;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--rule);
}

/* ── Search input — bottom-border underline only, no chrome ──────── */
.lib-search {
  flex: 0 1 360px;
  width: 360px;
  max-width: 100%;
  background: transparent;
  border: none;
  border-bottom: 1px solid var(--rule);
  padding: 10px 2px;
  font-family: 'EB Garamond', serif;
  font-size: 17px;
  font-style: italic;
  color: var(--bone);
  outline: none;
  transition: border-color 0.2s, color 0.2s;
}
.lib-search::placeholder { color: var(--shadow); font-style: italic; }
.lib-search:hover { border-bottom-color: var(--rule-bright); }
.lib-search:focus { border-bottom-color: var(--bone-dim); }
.lib-search::-webkit-search-cancel-button {
  -webkit-appearance: none; appearance: none;
}

/* ── Sort strip (author · year · tradition · form · shuffle) ───── */
.lib-sort {
  display: inline-flex;
  align-items: baseline;
  gap: 10px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
}
.lib-sort .sort-btn {
  background: none;
  border: none;
  padding: 0;
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  color: var(--fog);
  cursor: pointer;
  transition: color 0.15s;
}
.lib-sort .sort-btn:hover { color: var(--bone); }
.lib-sort .sort-btn.on { color: var(--gold); }
.lib-sort .sort-btn .dir {
  color: inherit;
  margin-left: 1px;
  font-size: 0.95em;
}
.lib-sort .sep { color: var(--shadow); }

/* ── Generic group header (used by all sort modes) ─────────────── */
.catalog .group-header {
  display: block;
  padding: 32px 4px 10px;
  border-bottom: 1px solid var(--rule);
  cursor: default;
  background: transparent;
  font-family: 'EB Garamond', serif;
  font-style: italic;
  font-size: 15px;
  color: var(--gold-dim);
  letter-spacing: 0.04em;
}
.catalog .group-header:hover { background: transparent; color: var(--gold-dim); }
.catalog .group-header:first-child { padding-top: 8px; }

/* ── (legacy) era group headers — preserved for fallback ────────── */
.catalog .era-header {
  display: flex; align-items: baseline; gap: 16px;
  padding: 36px 4px 10px;
  border-bottom: 1px solid var(--rule);
  cursor: default;
  background: transparent;
}
.catalog .era-header:hover { background: transparent; color: inherit; }
.catalog .era-header:first-child { padding-top: 14px; }
.catalog .era-label {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px; letter-spacing: 0.28em;
  color: var(--gold);
}
.catalog .era-range {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px; letter-spacing: 0.18em;
  color: var(--shadow);
}

/* ── match count + clear link in the head ────────────────────── */
.library-head .match-count { color: var(--gold); }
.library-head .clear-link {
  margin-left: 10px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px; letter-spacing: 0.22em; text-transform: uppercase;
  color: var(--gold-dim);
  text-decoration: none;
  border-bottom: 1px dotted var(--gold-dim);
  transition: color 0.15s, border-color 0.15s;
}
.library-head .clear-link:hover { color: var(--gold); border-bottom-color: var(--gold); }

/* ── empty result line ───────────────────────────────────────── */
.catalog-empty {
  margin: 64px auto;
  text-align: center;
  font-family: 'EB Garamond', serif;
  font-style: italic;
  font-size: 17px;
  color: var(--gold-dim);
}

@media (max-width: 720px) {
  .catalog .era-header { padding: 24px 4px 8px; }
}

/* =============================================================
   READER
   ============================================================= */

.reader-bar {
  position: sticky; top: 0; z-index: 20;
  background: color-mix(in srgb, var(--ink) 92%, transparent);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--rule);
  padding: 18px 48px;
  display: flex; justify-content: space-between; align-items: center;
}
.reader-bar .crumb {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--fog);
  display: flex; align-items: center; gap: 14px;
}
.reader-bar .crumb a { color: var(--bone-dim); transition: color 0.2s; }
.reader-bar .crumb a:hover { color: var(--gold); }
.reader-bar .crumb .sep { color: var(--shadow); }
.reader-bar .crumb .title {
  font-family: 'EB Garamond', serif; font-style: italic;
  font-size: 17px; letter-spacing: 0; text-transform: none;
  color: var(--bone);
}
.reader-tools {
  display: flex; gap: 6px; align-items: center;
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px; letter-spacing: 0.18em; text-transform: uppercase;
}
.reader-tools button {
  background: none; border: 1px solid var(--rule);
  color: var(--fog); padding: 6px 10px; cursor: pointer;
  font: inherit; letter-spacing: 0.18em; text-transform: uppercase;
  transition: all 0.15s;
}
.reader-tools button:hover { color: var(--bone); border-color: var(--rule-bright); }
.reader-tools button.active { color: var(--gold); border-color: var(--gold); }

.type-wrap { position: relative; }
.type-panel {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  width: 260px;
  background: var(--ink-2);
  border: 1px solid var(--rule-bright);
  padding: 18px;
  z-index: 50;
  display: none;
  box-shadow: 0 12px 32px -8px rgba(0,0,0,0.4);
}
.type-panel.open { display: block; }
.type-panel .row { margin-bottom: 16px; }
.type-panel .row:last-child { margin-bottom: 0; }
.type-panel .row-label {
  font-family: 'JetBrains Mono', monospace;
  font-size: 9px; letter-spacing: 0.25em; text-transform: uppercase;
  color: var(--shadow);
  margin-bottom: 8px;
}
.type-panel .row-options { display: flex; gap: 4px; }
.type-panel .row-options button {
  flex: 1;
  background: transparent;
  border: 1px solid var(--rule);
  color: var(--bone-dim);
  padding: 8px;
  cursor: pointer;
  font-family: 'EB Garamond', serif;
  font-size: 15px;
  transition: all 0.15s;
  text-transform: none; letter-spacing: 0;
}
.type-panel .row-options button:hover { color: var(--bone); border-color: var(--rule-bright); }
.type-panel .row-options button.on {
  color: var(--gold);
  border-color: var(--gold);
  background: color-mix(in srgb, var(--gold) 8%, transparent);
}
.type-panel .row-options.size button:nth-child(1) { font-size: 13px; }
.type-panel .row-options.size button:nth-child(2) { font-size: 17px; }
.type-panel .row-options.size button:nth-child(3) { font-size: 22px; }
.type-panel .row-options.family button[data-font="serif"] { font-family: 'EB Garamond', serif; font-style: italic; }
.type-panel .row-options.family button[data-font="sans"] { font-family: 'Inter', system-ui, sans-serif; }
.type-panel .row-options.mode button {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  padding: 9px 4px;
}

/* ────── Bookmark button + panel ────── */
.bookmark-wrap { position: relative; }
/* match the AA / CLEAR button sizing exactly */
#bookmark-btn {
  padding: 6px 10px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
}
#bookmark-btn svg {
  width: 14px;
  height: 16px;
  display: block;
}
#bookmark-btn.flash {
  color: var(--gold);
  border-color: var(--gold);
  background: color-mix(in srgb, var(--gold) 12%, transparent);
}
.bookmark-panel {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  width: 360px;
  max-width: calc(100vw - 32px);
  background: var(--ink-2);
  border: 1px solid var(--rule-bright);
  padding: 12px;
  z-index: 50;
  display: none;
  box-shadow: 0 12px 32px -8px rgba(0,0,0,0.4);
}
.bookmark-panel.open { display: block; }
.bm-add {
  width: 100%;
  background: transparent;
  border: 1px solid var(--rule-bright);
  color: var(--bone);
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 10px; letter-spacing: 0.2em; text-transform: uppercase;
  padding: 10px 12px;
  cursor: pointer;
  margin-bottom: 10px;
  transition: all 0.15s;
}
.bm-add:hover {
  border-color: var(--gold);
  color: var(--gold);
}
.bm-list { max-height: 60vh; overflow-y: auto; }
.bm-empty {
  font-family: 'EB Garamond', serif;
  font-style: italic;
  font-size: 13px;
  color: var(--fog);
  text-align: center;
  padding: 14px 8px 6px;
}
.bm-item {
  display: flex;
  align-items: stretch;
  border-top: 1px solid var(--rule);
  position: relative;
}
.bm-item:first-child { border-top: none; }
.bm-link {
  flex: 1;
  display: block;
  padding: 10px 4px 10px 6px;
  text-decoration: none;
  color: var(--bone);
  transition: background 0.15s;
}
.bm-link:hover {
  background: color-mix(in srgb, var(--bone) 4%, transparent);
}
.bm-meta {
  display: flex; justify-content: space-between; align-items: baseline;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 9px; letter-spacing: 0.22em; text-transform: uppercase;
  margin-bottom: 4px;
}
.bm-book  { color: var(--gold-dim); }
.bm-coord { color: var(--gold); }
.bm-preview {
  font-family: 'EB Garamond', serif;
  font-style: italic;
  font-size: 13px;
  line-height: 1.4;
  color: var(--bone-dim);
}
.bm-remove {
  flex: 0 0 28px;
  background: none; border: none;
  color: var(--shadow);
  font-family: 'JetBrains Mono', monospace;
  font-size: 14px;
  cursor: pointer;
  align-self: stretch;
  transition: color 0.15s;
}
.bm-remove:hover { color: var(--gold); }

/* Flash highlight when scrolling to a bookmarked passage */
.para.flash {
  animation: paraFlash 1.6s ease-out;
}
@keyframes paraFlash {
  0%   { background: color-mix(in srgb, var(--gold) 18%, transparent); }
  100% { background: transparent; }
}

/* =================================================
   Reader frame — per-paragraph row layout
   Each paragraph is wrapped in a .para-row. Splits happen
   per row, not page-wide, so other paragraphs never
   move when you translate one of them.

   View modes (set as a class on .reader-frame):
     .mode-centered  → split only the rows that have translations open
     .mode-skewed    → every row split (always-on parallel edition)
   ================================================= */
.reader-frame {
  max-width: 1320px;
  margin: 0 auto;
  padding: 80px 48px 120px;
}
.reader-title-block,
.para-row,
.end-fragment-row,
.section-header {
  display: grid;
  grid-template-columns: 1fr 560px 0fr 1fr;
  column-gap: 0;
  transition:
    grid-template-columns 0.45s cubic-bezier(0.22, 0.7, 0.18, 1),
    column-gap 0.45s cubic-bezier(0.22, 0.7, 0.18, 1);
}
/* a row that has at least one translation open in local / parallel modes */
.para-row.split,
.mode-skewed .para-row,
.mode-skewed .section-header {
  grid-template-columns: 1fr 560px 560px 1fr;
  column-gap: 64px;
}

/* Section header — Roman numeral prefix + title, lives in the original
   column so it aligns with the source text. */
.section-header {
  margin: 80px 0 36px;
}
.section-header > * { grid-column: 2 / 3; }
.section-header .section-num {
  display: block;
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--gold-dim);
  margin-bottom: 6px;
}
.section-header .section-text {
  font-family: 'EB Garamond', serif;
  font-weight: 400;
  font-style: italic;
  font-size: 30px;
  line-height: 1.2;
  color: var(--bone);
  padding-bottom: 14px;
  border-bottom: 1px solid var(--rule);
}
/* the very first section-header on the page shouldn't have a giant gap */
.reader-text > .section-header:first-child {
  margin-top: 0;
}

/* Verse paragraphs (Paradise Lost) — slightly tighter line-height for
   line-broken text; the address tag aligns with the first line. */
.para.verse {
  line-height: 1.5;
}
.para.verse br { line-height: inherit; }

/* Intro paragraphs — front-matter rendered in the same italic key as
   New Atlantis's preface: dimmer, italic, no translation affordance. */
.para.intro {
  font-style: italic;
  color: var(--bone-dim);
  cursor: default;
  font-size: calc(var(--reader-size) * 0.95);
}
.para.intro:hover { color: var(--bone-dim); }   /* no hover lift */

/* =================================================
   Table-of-contents view
   ================================================= */
.toc-list {
  max-width: 720px;
  margin: 40px auto 0;
  padding: 0 24px;
  display: flex;
  flex-direction: column;
}
.toc-item {
  display: grid;
  grid-template-columns: 56px 1fr auto;
  align-items: baseline;
  gap: 28px;
  padding: 20px 4px;
  border-top: 1px solid var(--rule);
  text-decoration: none;
  color: var(--bone);
  cursor: pointer;
  transition: background 0.2s, color 0.2s;
}
.toc-item:last-child { border-bottom: 1px solid var(--rule); }
.toc-item:hover {
  background: color-mix(in srgb, var(--bone) 4%, transparent);
  color: var(--gold);
}
.toc-item .toc-num {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px; letter-spacing: 0.22em;
  color: var(--gold-dim);
  text-transform: uppercase;
  text-align: right;
}
.toc-item .toc-label {
  font-family: 'EB Garamond', serif;
  font-style: italic;
  font-size: 21px;
  line-height: 1.3;
}
.toc-item .toc-count {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px; letter-spacing: 0.18em;
  color: var(--fog);
  white-space: nowrap;
}

/* book-group header (only emitted when sections share a "Book X, Ch. Y." pattern) */
.toc-list .toc-book {
  margin: 56px 0 0;
  padding: 0 4px 10px;
  font-family: 'EB Garamond', serif;
  font-variant: small-caps;
  letter-spacing: 0.14em;
  font-size: 22px;
  color: var(--gold);
}
.toc-list .toc-book:first-child { margin-top: 24px; }
/* Reset the border on the first chapter immediately following a Book header */
.toc-list .toc-book + .toc-item.toc-sub {
  border-top: 1px solid var(--rule-bright);
}
/* indent the sub-items so the hierarchy reads at a glance */
.toc-item.toc-sub {
  padding-left: 32px;
}
.toc-item.toc-sub .toc-label {
  font-size: 19px;
}

/* =================================================
   Section navigation (prev / TOC / next at the foot of each section)
   ================================================= */
.section-nav {
  display: grid;
  grid-template-columns: 1fr 560px 0fr 1fr;
  margin: 100px 0 60px;
}
.mode-skewed .section-nav {
  grid-template-columns: 1fr 560px 560px 1fr;
  column-gap: 64px;
}
.section-nav > .section-nav-inner {
  grid-column: 2 / 3;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  gap: 24px;
  padding: 28px 0;
  border-top: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px; letter-spacing: 0.18em;
  text-transform: uppercase;
}
.section-nav .nav-cell { display: flex; align-items: center; gap: 10px; min-height: 24px; }
.section-nav .nav-cell.prev { justify-self: start; }
.section-nav .nav-cell.toc { justify-self: center; }
.section-nav .nav-cell.next { justify-self: end; }
.section-nav .nav-cell a {
  color: var(--bone-dim);
  text-decoration: none;
  display: flex;
  align-items: center;
  gap: 10px;
  transition: color 0.2s;
}
.section-nav .nav-cell a:hover { color: var(--gold); }
.section-nav .nav-cell .arrow { color: var(--gold-dim); font-family: 'EB Garamond', serif; font-size: 14px; }
.section-nav .nav-cell .nav-label {
  font-family: 'EB Garamond', serif;
  font-style: italic;
  font-size: 14px;
  text-transform: none;
  letter-spacing: 0;
  max-width: 28ch;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.section-nav .nav-cell .empty { color: var(--shadow); }
.section-nav .nav-cell.toc a { color: var(--gold); }
.section-nav .nav-cell.toc a:hover { color: var(--gold-dim); }

.reader-title-block {
  margin-bottom: 80px;
  padding-bottom: 40px;
  border-bottom: 1px solid var(--rule);
}
.reader-title-block > * { grid-column: 2 / 3; }
.reader-title-block .coord { margin-bottom: 24px; }
.reader-title-block h1 {
  font-family: 'EB Garamond', serif;
  font-weight: 400;
  font-size: 64px;
  line-height: 1;
  letter-spacing: -0.01em;
  color: var(--bone);
  margin-bottom: 16px;
}
.reader-title-block h1 em { font-style: italic; color: var(--gold); }
.reader-title-block .byline {
  font-family: 'EB Garamond', serif; font-style: italic;
  font-size: 21px; color: var(--bone-dim);
}
.reader-title-block .byline .author {
  color: var(--bone); font-style: normal;
  font-variant: small-caps; letter-spacing: 0.06em;
}
.reader-title-block .preface {
  margin-top: 32px;
  font-family: 'EB Garamond', serif;
  font-size: 18px; line-height: 1.65;
  color: var(--bone-dim); font-style: italic;
  max-width: 70ch;
}

.para-row > .para { grid-column: 2 / 3; }
.para-row > .row-gutter {
  grid-column: 3 / 4;
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding-top: 0;          /* card has its own padding-top, this would double */
  overflow: hidden;        /* clip the card while the column has zero width */
}

/* "Plain English" sign — only on rows that actually have a translation card,
   and only at the start of each non-continuous translation group.
   In Skewed mode, all rows have .split applied for layout purposes, so we
   gate the label specifically on the presence of a .translation.gutter card. */
/* The label sits absolutely above the column so it doesn't push the
   translation body down out of alignment with the original's first line.
   Override the default overflow:hidden on .row-gutter (which was there to
   clip the card while the column has zero width) so the label is visible
   when expanded; the inner card still has its own clean transitions. */
.para-row.split:has(.translation.gutter) > .row-gutter {
  position: relative;
  overflow: visible;
}
.para-row.split:has(.translation.gutter) > .row-gutter::before {
  content: 'Plain English';
  position: absolute;
  top: -22px;
  left: 0;
  right: 0;
  font-family: 'JetBrains Mono', monospace;
  font-size: 9px;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--gold-dim);
  padding: 0 0 6px 40px;
  border-bottom: 1px solid var(--rule);
  pointer-events: none;
}
.para-row.split:has(.translation.gutter) + .para-row.split:has(.translation.gutter) > .row-gutter::before {
  display: none;
}

.para {
  position: relative;
  margin-bottom: 32px;
  font-family: var(--reader-family);
  font-size: var(--reader-size);
  line-height: 1.75;
  color: var(--bone);
  padding: 6px 0 6px 24px;
  cursor: pointer;
  transition: color 0.2s;
}
/* No active-state background or border — the translation appearing alongside
   is the indicator. Only the small coordinate tag changes color. */
.para .addr {
  position: absolute;
  left: -76px;
  top: 12px;
  width: 60px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px; letter-spacing: 0.15em;
  color: var(--shadow);
  text-align: right;
  user-select: none;
  transition: color 0.2s;
}
.para:hover .addr { color: var(--gold-dim); }
.para.active .addr { color: var(--gold); }

/* =================================================
   Translation card — flow-positioned inside its row.
   Stripped of all chrome so it reads like a sibling paragraph
   of the source. Top-aligns with the original.
   Placement (set by JS):
     .translation.gutter  → in the row's right column
     .translation.inline  → in the row's left column, below the paragraph
   ================================================= */
.translation {
  position: relative;
  width: 560px;
  padding: 6px 12px 6px 70px;   /* left padding holds the section·N address */
  background: transparent;
  cursor: pointer;
  opacity: 0;
  transform: translateX(-4px);
  transition: opacity 0.3s ease 0.1s,
              transform 0.3s ease 0.1s;
  pointer-events: none;
  align-self: start;
}
/* (No hover background on translation cards — cursor:pointer is enough.) */
.translation.inline {
  grid-column: 2 / 3;        /* same column as paragraph, below it */
  margin-top: -8px;
  margin-bottom: 24px;
}
.translation.visible {
  opacity: 1;
  transform: translateX(0);
  pointer-events: auto;
}

.translation .t-body {
  font-family: var(--reader-family);
  font-size: var(--reader-size);
  line-height: 1.55;          /* tighter than original (1.75) so the column matches height */
  color: var(--translation);  /* subtle tint to distinguish from the original voice */
}
.translation .t-body em {
  color: var(--bone-dim);
  font-style: italic;
}

/* small I·N address inside the translation — pairs visually with the
   address on the source paragraph at the same vertical position */
.translation > .addr {
  position: absolute;
  top: 12px;
  left: 0;
  width: 60px;
  padding-right: 6px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px; letter-spacing: 0.1em;
  color: var(--gold-dim);
  text-align: right;
  user-select: none;
  pointer-events: none;
}

/* (× button has been removed entirely — clicking anywhere on the
   translation closes it. Cursor is pointer over the whole card so
   the affordance is obvious; the hover tint reinforces it.) */

/* loading state — body holds a small pulse */
.translation.loading .t-body { color: var(--shadow); }
.translation .dots { display: inline-flex; gap: 5px; vertical-align: middle; }
.translation .dots .d {
  width: 5px; height: 5px;
  background: var(--gold);
  clip-path: polygon(50% 0, 100% 25%, 100% 75%, 50% 100%, 0 75%, 0 25%);
  animation: pulse 1.4s ease-in-out infinite;
}
.translation .dots .d:nth-child(2) { animation-delay: 0.18s; }
.translation .dots .d:nth-child(3) { animation-delay: 0.36s; }
@keyframes pulse {
  0%, 80%, 100% { opacity: 0.2; }
  40% { opacity: 1; }
}

/* =================================================
   Inline footnote markers — small italic Garamond superscripts in
   gold, set like an editor's scholia rather than a citation number.
   Each marker links to the corresponding entry in the book's dedicated
   "Editor's Notes" chapter.
   ================================================= */
.fnref {
  font-family: 'EB Garamond', 'Iowan Old Style', Georgia, serif;
  font-style: italic;
  font-weight: 400;
  font-size: 0.62em;
  line-height: 0;
  vertical-align: super;
  margin: 0 0.04em 0 0.12em;
  letter-spacing: 0;
  color: var(--gold);
  opacity: 0.68;
  scroll-margin-top: 100px;
  transition: opacity 0.18s, color 0.18s;
}
.fnref a {
  color: inherit;
  text-decoration: none;
  border-bottom: none;
  padding: 0 1px;
}
.fnref:hover,
.fnref:focus-within { opacity: 1; color: var(--gold); }
.para.flash .fnref { opacity: 1; }

/* =================================================
   Editor's Notes — dedicated end-of-book "chapter"
   ================================================= */
.view-notes .reader-frame .reader-title-block { display: none; }

.notes-frontispiece {
  text-align: center;
  margin: 24px 0 64px;
  padding: 48px 0 40px;
  border-bottom: 1px solid var(--rule);
}
.notes-eyebrow {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.42em;
  text-transform: uppercase;
  color: var(--gold-dim);
  margin-bottom: 18px;
}
.notes-title {
  font-family: 'EB Garamond', serif;
  font-style: italic;
  font-weight: 400;
  font-size: 38px;
  line-height: 1.1;
  color: var(--bone);
  margin: 0 0 18px;
}
.notes-sub {
  font-family: 'EB Garamond', serif;
  font-style: italic;
  font-size: 15px;
  color: var(--fog);
  max-width: 440px;
  margin: 0 auto;
  line-height: 1.55;
}

/* Per-section blocks within the Notes chapter — each gathered under a
   small Roman-numeral eyebrow + the section's own label, mirroring the
   in-book section header but in a quieter key. */
.notes-block > .notes-block-body { grid-column: 2 / 3; }
.notes-block { margin: 0 0 56px; }
.notes-section-head {
  display: flex;
  align-items: baseline;
  gap: 16px;
  border-top: 1px solid var(--rule);
  padding-top: 18px;
  margin-bottom: 22px;
}
.notes-section-head .ns-num {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--gold-dim);
  flex-shrink: 0;
}
.notes-section-head .ns-label {
  font-family: 'EB Garamond', serif;
  font-style: italic;
  font-size: 22px;
  color: var(--bone);
  line-height: 1.25;
}

.note-list {
  list-style: none;
  margin: 0;
  padding: 0;
  counter-reset: na-note;
  font-family: var(--reader-family);
  font-size: calc(var(--reader-size) * 0.88);
  line-height: 1.65;
  color: var(--bone-dim);
}
.note {
  position: relative;
  padding: 0 0 0 40px;
  margin: 0 0 16px;
  scroll-margin-top: 100px;
}
.note::before {
  content: attr(value);
  position: absolute;
  left: 0;
  top: 0.18em;
  width: 28px;
  text-align: right;
  font-family: 'EB Garamond', serif;
  font-style: italic;
  font-size: 0.82em;
  letter-spacing: 0;
  color: var(--gold);
  opacity: 0.7;
}
.note em { color: var(--bone); font-style: italic; }
.note-back {
  display: inline-block;
  margin-left: 6px;
  color: var(--gold-dim);
  text-decoration: none;
  font-family: 'EB Garamond', serif;
  font-style: italic;
  font-size: 1.05em;
  transition: color 0.18s, transform 0.18s;
}
.note-back:hover {
  color: var(--gold);
  transform: translate(-1px, -1px);
}
.note.flash::before { color: var(--gold); opacity: 1; }
.note.flash {
  animation: paraFlash 1.6s ease-out;
}

/* Apparatus entry in the TOC */
.toc-divider {
  height: 1px;
  background: var(--rule);
  margin: 22px 0;
  opacity: 0.6;
}
.toc-item.toc-apparatus .toc-num,
.toc-item.toc-apparatus .toc-count {
  color: var(--gold);
  opacity: 0.8;
  font-family: 'EB Garamond', serif;
  font-style: italic;
}
.toc-item.toc-apparatus .toc-label {
  font-style: italic;
}

/* =================================================
   Pure reading mode — toggled by the "pure" toolbar button.
   Renders the source like a plain Project-Gutenberg page:
   continuous prose, no per-paragraph coordinate tags, no translation
   gutter, modest paragraph spacing.
   ================================================= */
.reader-frame.reading-mode .para-row,
.reader-frame.reading-mode .para-row.split,
.mode-skewed .reader-frame.reading-mode .para-row {
  grid-template-columns: 1fr 560px 0fr 1fr;
  column-gap: 0;
}
.reader-frame.reading-mode .translation,
.reader-frame.reading-mode .span-popover {
  display: none !important;
}
/* Remove the coordinate addr (I·N) and click affordances */
.reader-frame.reading-mode .para .addr { display: none; }
.reader-frame.reading-mode .para {
  cursor: default;
  margin: 0;            /* no row-level margin */
  padding: 0;           /* no chrome — pure body text */
}
.reader-frame.reading-mode .para + .para,
.reader-frame.reading-mode .para-row + .para-row .para {
  margin-top: 0.6em;    /* a normal paragraph break, not a card gap */
}
.reader-frame.reading-mode .para:hover { color: var(--bone); }
.reader-frame.reading-mode .para.active { /* no active-state effect */ }
.reader-frame.reading-mode .row-gutter { display: none; }
.reader-frame.reading-mode .para-row.split:has(.translation.gutter) > .row-gutter::before {
  display: none;
}
/* Tighten section headers a touch in reading mode so they don't tower */
.reader-frame.reading-mode .section-header {
  margin: 48px 0 20px;
}

/* end fragment row */
.end-fragment-row > .end-fragment {
  grid-column: 2 / 3;
}
.end-fragment {
  margin-top: 48px;
  font-family: 'EB Garamond', serif;
  font-style: italic;
  font-size: 16px;
  color: var(--fog);
  text-align: center;
  letter-spacing: 0.04em;
}

/* =================================================
   Progress strip — more visible, with a coordinate readout
   ================================================= */
.progress-bar {
  position: fixed; bottom: 0; left: 0; right: 0;
  height: 5px;
  background: color-mix(in srgb, var(--gold) 18%, transparent);
  border-top: 1px solid var(--rule);
  z-index: 30;
  display: flex; align-items: stretch;
}
.progress-bar .fill {
  height: 100%; background: var(--gold);
  width: 0%;
  transition: width 0.12s;
  box-shadow: 0 0 8px var(--gold-glow);
}
.progress-readout {
  position: fixed; bottom: 12px; right: 24px;
  z-index: 31;
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px; letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--bone-dim);
  background: color-mix(in srgb, var(--ink) 92%, transparent);
  border: 1px solid var(--rule);
  padding: 4px 10px;
  pointer-events: none;
  opacity: 0.85;
}
.progress-readout .pct { color: var(--gold); margin-left: 8px; }

/* =================================================
   Ephemeral span popover — appears for highlight-to-translate.
   Floating tooltip near the selection; auto-dismisses on click outside,
   Escape, scroll, or a new selection. Not persistent like paragraph cards.
   ================================================= */
.span-popover {
  position: absolute;
  z-index: 60;
  width: 560px;
  max-width: calc(100vw - 32px);    /* clamp on narrow viewports */
  min-width: 280px;
  padding: 16px 20px 18px;
  background: var(--ink-2);
  border: 1px solid var(--rule-bright);
  box-shadow:
    0 16px 40px -10px rgba(0,0,0,0.5),
    0 2px 8px -2px rgba(0,0,0,0.3);
  font-family: var(--reader-family);
  font-size: var(--reader-size);
  line-height: 1.55;
  color: var(--translation);
  opacity: 0;
  transform: translateY(4px);
  transition: opacity 0.2s, transform 0.2s;
  pointer-events: none;
}
.span-popover.show {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}
.span-popover .sp-body { color: var(--translation); }
.span-popover .dots { display: inline-flex; gap: 5px; vertical-align: middle; }
.span-popover .dots .d {
  width: 5px; height: 5px;
  background: var(--gold);
  clip-path: polygon(50% 0, 100% 25%, 100% 75%, 50% 100%, 0 75%, 0 25%);
  animation: pulse 1.4s ease-in-out infinite;
}
.span-popover .dots .d:nth-child(2) { animation-delay: 0.18s; }
.span-popover .dots .d:nth-child(3) { animation-delay: 0.36s; }

/* selection bubble — appears above a drag-select */
.sel-bubble {
  position: absolute;
  z-index: 40;
  display: inline-flex; align-items: center; gap: 8px;
  padding: 8px 12px;
  background: var(--gold);
  color: var(--ink);
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px; letter-spacing: 0.2em; text-transform: uppercase;
  cursor: pointer;
  box-shadow: 0 8px 24px -6px var(--gold-glow), 0 2px 6px rgba(0,0,0,0.25);
  opacity: 0; transform: translateY(4px);
  transition: opacity 0.15s, transform 0.15s;
  pointer-events: none;
  white-space: nowrap;
}
.sel-bubble.show { opacity: 1; transform: translateY(0); pointer-events: auto; }
.sel-bubble::after {
  content: '';
  position: absolute;
  bottom: -5px; left: 16px;
  width: 0; height: 0;
  border: 5px solid transparent;
  border-top-color: var(--gold);
  border-bottom: 0;
}
.sel-bubble .icon {
  display: inline-block;
  width: 9px; height: 9px;
  background: var(--ink);
  clip-path: polygon(50% 0, 100% 25%, 100% 75%, 50% 100%, 0 75%, 0 25%);
}

/* =============================================================
   RESPONSIVE
   ============================================================= */

/* intermediate widths — shrink the row columns so two of them still fit */
@media (max-width: 1180px) and (min-width: 901px) {
  .reader-title-block,
  .para-row,
  .end-fragment-row,
  .section-header,
  .section-nav {
    grid-template-columns: 1fr 480px 0fr 1fr;
  }
  .para-row.split,
  .mode-skewed .para-row,
  .mode-skewed .section-header,
  .mode-skewed .section-nav {
    grid-template-columns: 1fr 460px 460px 1fr;
    column-gap: 40px;
  }
  .translation { width: 460px; }
}

/* mobile — single column flow; force solo mode regardless of preference */
@media (max-width: 900px) {
  /* ─── topbar: keep nav visible, tighten everything ─────── */
  .topbar {
    padding: 14px 20px;
    flex-wrap: wrap;
    row-gap: 12px;
    column-gap: 16px;
  }
  .topbar nav {
    display: flex;
    gap: 18px;
    font-size: 10px;
    letter-spacing: 0.14em;
  }
  .topbar nav a {
    /* generous tap target without changing visual layout */
    display: inline-block;
    padding: 8px 0;
  }
  .topbar-right { gap: 14px; }
  .mark { gap: 10px; }
  .mark .name { font-size: 10px; letter-spacing: 0.16em; }
  .theme-toggle { width: 36px; height: 36px; }

  /* ─── footer: stack vertically, breathing room, safe-area ──── */
  footer.foot {
    flex-direction: column;
    align-items: flex-start;
    gap: 24px;
    padding: 32px 20px calc(32px + env(safe-area-inset-bottom));
    margin-top: 56px;
  }
  footer.foot .foot-right { width: 100%; }
  footer.foot .foot-sub {
    line-height: 1.6;
    max-width: none;
  }

  .about, .library-wrap { padding: 56px 20px; }
  .about-prose { margin-bottom: 64px; }
  .about-stat { margin-left: 1.5em; }
  .demo-pair {
    grid-template-columns: 1fr;
    gap: 40px;
  }
  .about-coord { margin-bottom: 48px; }
  .about-mark { margin-bottom: 48px; }
  .demo-original, .demo-modern { margin-left: 0; }

  /* ─── library: stack the head + controls, shrink heading ──── */
  .library-head {
    flex-direction: column;
    align-items: flex-start;
    gap: 10px;
    padding-bottom: 18px;
    margin-bottom: 28px;
  }
  .library-head h2 {
    font-size: clamp(28px, 8vw, 38px);
    letter-spacing: 0.03em;
  }
  .library-head .coord { font-size: 10px; line-height: 1.5; }
  .library-controls {
    flex-direction: column;
    align-items: stretch;
    gap: 16px;
    padding-bottom: 12px;
  }
  .lib-search {
    width: 100%;
    flex: 1 1 auto;
    font-size: 16px;     /* 16px prevents iOS Safari auto-zoom on focus */
  }
  .lib-sort {
    gap: 8px;
    font-size: 9px;
    letter-spacing: 0.16em;
    flex-wrap: wrap;
  }
  .catalog { gap: 14px; }
  .catalog li { padding: 18px 18px 14px; }
  .catalog .title { font-size: 19px; }

  /* ─── reader bar: tighter, smaller buttons, sticky-safe ─── */
  .reader-bar {
    padding: 12px 16px;
    flex-wrap: wrap;
    row-gap: 8px;
    column-gap: 12px;
  }
  .reader-bar .crumb {
    font-size: 10px;
    gap: 8px;
    flex: 1 1 auto;
    min-width: 0;
  }
  .reader-bar .crumb .title {
    font-size: 14px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
  }
  .reader-tools { gap: 4px; }
  .reader-tools button { padding: 6px 8px; font-size: 9px; letter-spacing: 0.14em; }

  /* ─── reader frame: collapse ALL row layouts to one column,
     including reading-mode (which has higher specificity than
     the plain .para-row rule and was sneaking through) ──────── */
  .reader-frame { padding: 32px 20px 64px; }
  .reader-title-block,
  .para-row,
  .para-row.split,
  .end-fragment-row,
  .section-header,
  .section-nav,
  .mode-skewed .para-row,
  .mode-skewed .section-header,
  .mode-skewed .section-nav,
  .reader-frame.reading-mode .para-row,
  .reader-frame.reading-mode .para-row.split,
  .mode-skewed .reader-frame.reading-mode .para-row {
    grid-template-columns: 1fr;
    column-gap: 0;
    transition: none;
  }
  .reader-title-block > *,
  .para-row > .para,
  .para-row > .row-gutter,
  .section-header > *,
  .section-nav > .section-nav-inner,
  .end-fragment-row > .end-fragment {
    grid-column: 1;
  }
  .section-header { margin: 56px 0 24px; }
  .section-header .section-text { font-size: 24px; }
  .section-nav > .section-nav-inner {
    grid-template-columns: 1fr;
    gap: 16px;
    text-align: center;
  }
  .section-nav .nav-cell { justify-self: center; }
  .toc-list { padding: 0 8px; }
  .translation {
    width: 100%;
    grid-column: 1;
  }
  .para-row > .row-gutter { padding-top: 0; }
  .para { padding-left: 0; }
  .para .addr {
    position: static; display: block; text-align: left;
    margin-bottom: 6px;
  }
  /* inline translation card on mobile (inserted directly after its paragraph).
     `grid-column: 1` is critical — the desktop `.translation.inline` rule
     sets it to `2 / 3` which on a 1-column mobile grid would create an
     implicit second column to the RIGHT of the paragraph. That's the bug
     where translations appeared on the side instead of beneath. */
  .translation.inline {
    position: relative;
    left: 0; top: auto;
    width: auto;
    grid-column: 1 !important;
    margin: 0 0 32px 0;
    padding: 12px 0 12px 16px;
    border-left: 1px solid var(--gold-dim);
  }
  /* On desktop the "Plain English" label sits above the right-hand
     translation column once per page. On mobile each translation is
     stacked under its own paragraph, so the label needs to repeat above
     every inline card to identify what it is. */
  .translation.inline::before {
    content: 'Plain English';
    display: block;
    font-family: 'JetBrains Mono', monospace;
    font-size: 9px;
    letter-spacing: 0.28em;
    text-transform: uppercase;
    color: var(--gold-dim);
    margin-bottom: 10px;
  }
  /* Hide the absolute-positioned address coord inside the translation —
     it was overlapping the "Plain English" label. The source paragraph
     above this card already shows the same coord, so nothing is lost. */
  .translation.inline > .addr {
    display: none;
  }
  /* card grid is already responsive — auto-fill drops to a single column
     when the viewport is too narrow for two 280px cards side by side */
  .type-panel { right: -8px; }
  /* Keep the progress strip + coord readout visible on mobile so the
     reader can see where they are and bookmark from the right spot. */
  .progress-readout {
    display: inline-flex;
    bottom: calc(10px + env(safe-area-inset-bottom));
    right: 12px;
    font-size: 9px;
    letter-spacing: 0.18em;
    padding: 3px 8px;
  }
  .progress-bar {
    bottom: env(safe-area-inset-bottom);
  }
}
