/* ============================================================================
   Gass Bilingual Reader — reader.css
   Epic 1: ch05 vertical slice.
   Typography follows Bringhurst-school rules (R2/TC-003/TC-010/TC-011/TC-012).
   ============================================================================ */

/* --- Design tokens (theme-driven) --- */
:root {
  --font-serif: "Literata", "PT Serif", "Cormorant", Georgia, serif;
  --font-mono: ui-monospace, "SF Mono", Menlo, monospace;
  --font-size: 18px;

  /* Day theme (default) */
  --bg: #fbf7ef;
  --fg: #1f1d1a;
  --fg-muted: #6a645b;
  --accent: #6b4f1d;
  --hover-bg: rgba(107, 79, 29, 0.08);
  --hover-fg: #1f1d1a;
  --partner-bg: rgba(107, 79, 29, 0.04);
  --pin-bg: rgba(192, 84, 22, 0.14);
  --pin-bar: #c05416;
  --partner-pin-bg: rgba(192, 84, 22, 0.08);
  --focus-ring: #2563a8;
  --rule: rgba(31, 29, 26, 0.12);
}

/* Sepia theme */
[data-theme="sepia"] {
  --bg: #f0e6d2;
  --fg: #3a2a14;
  --fg-muted: #7a6242;
  --accent: #6e4a1a;
  --hover-bg: rgba(110, 74, 26, 0.12);
  --partner-bg: rgba(110, 74, 26, 0.06);
  --pin-bg: rgba(170, 70, 14, 0.18);
  --pin-bar: #aa460e;
  --partner-pin-bg: rgba(170, 70, 14, 0.10);
  --focus-ring: #6e4a1a;
  --rule: rgba(58, 42, 20, 0.16);
}

/* Night theme */
[data-theme="night"] {
  --bg: #1b1b1f;
  --fg: #e7e3da;
  --fg-muted: #9a948a;
  --accent: #d9c07a;
  --hover-bg: rgba(217, 192, 122, 0.14);
  --partner-bg: rgba(217, 192, 122, 0.06);
  --pin-bg: rgba(217, 122, 80, 0.20);
  --pin-bar: #d97a50;
  --partner-pin-bg: rgba(217, 122, 80, 0.10);
  --focus-ring: #88b5d8;
  --rule: rgba(231, 227, 218, 0.14);
}

/* Respect OS preference on first paint (user override wins once they pick a theme). */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme]) {
    --bg: #1b1b1f;
    --fg: #e7e3da;
    --fg-muted: #9a948a;
    --accent: #d9c07a;
    --hover-bg: rgba(217, 192, 122, 0.14);
    --partner-bg: rgba(217, 192, 122, 0.06);
    --pin-bg: rgba(217, 122, 80, 0.20);
    --pin-bar: #d97a50;
    --partner-pin-bg: rgba(217, 122, 80, 0.10);
    --focus-ring: #88b5d8;
    --rule: rgba(231, 227, 218, 0.14);
  }
}

/* --- Reset / base --- */
* { box-sizing: border-box; }
html, body {
  margin: 0;
  padding: 0;
  height: 100vh;
  overflow: hidden; /* the .reader scrolls internally, not the body */
}

/* --- Access gate (closed-circle consent + one-time PIN) ---
   Book-reading pages only. Reader content hidden until consent given. */
body.gate-locked .reader,
body.gate-locked .chrome-frame,
body.gate-locked .chrome-toggle,
body.gate-locked .reading-progress,
body.gate-locked .reader-crumbs,
body.gate-locked .tap-zone,
body.gate-locked .fab-cluster { display: none !important; }
.access-gate {
  position: fixed;
  inset: 0;
  z-index: 1000;
  background: #fbf7ef;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1rem;
  font-family: var(--font-serif);
  color: #1f1d1a;
}
.access-gate-card {
  max-width: 34rem;
  width: 100%;
  max-height: 92vh;
  overflow-y: auto;
  background: #fff;
  border: 1px solid rgba(31, 29, 26, 0.15);
  border-radius: 12px;
  padding: 1.5rem 1.5rem 1.25rem;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.12);
}
.access-gate-icon { font-size: 1.8rem; margin-bottom: 0.5rem; }
.access-gate-card h2 {
  margin: 0 0 0.75rem;
  font-size: 1.1rem;
  font-weight: 700;
}
.access-gate-legal {
  font-size: 0.85rem;
  line-height: 1.55;
  color: #4a453e;
  margin: 0 0 0.75rem;
}
.access-gate-consent { font-size: 0.85rem; font-weight: 600; margin: 0 0 0.4rem; }
.access-gate-list {
  margin: 0 0 1rem;
  padding-left: 1.2rem;
  font-size: 0.85rem;
  line-height: 1.5;
  color: #4a453e;
}
.access-gate-form { display: flex; gap: 0.5rem; flex-wrap: wrap; }
.access-gate-input {
  flex: 1;
  min-width: 8rem;
  padding: 0.6rem 0.8rem;
  font-size: 1rem;
  border: 1px solid rgba(31, 29, 26, 0.25);
  border-radius: 8px;
  background: #fbf7ef;
  color: #1f1d1a;
}
.access-gate-input:focus { outline: 2px solid #6b4f1d; border-color: transparent; }
.access-gate-btn {
  padding: 0.6rem 1rem;
  background: #6b4f1d;
  color: #fff;
  border: none;
  border-radius: 8px;
  font-size: 0.9rem;
  font-weight: 600;
  cursor: pointer;
}
.access-gate-btn:active { opacity: 0.85; }
.access-gate-error {
  margin: 0.75rem 0 0;
  font-size: 0.8rem;
  color: #a1260e;
  font-weight: 600;
}

/* --- Persistent breadcrumb bar (H3 — always visible escape hatch) --- */
.reader-crumbs {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 15; /* below ≡ toggle (z-index 30) and progress bar (z-index 50) */
  display: flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.25rem 3.2rem 0.25rem 0.6rem; /* right padding reserves space for ≡ */
  font-size: 0.75rem;
  font-family: var(--font-serif);
  color: var(--fg-muted);
  background: color-mix(in srgb, var(--bg) 92%, transparent);
  backdrop-filter: blur(6px);
  max-width: 100vw;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.reader-crumbs a {
  color: var(--accent);
  text-decoration: none;
  font-weight: 500;
  white-space: nowrap;
}
.reader-crumbs a:hover { text-decoration: underline; }
.reader-crumbs .crumb-home { font-size: 0.95rem; }
.reader-crumbs .crumb-sep { color: var(--rule); font-size: 0.7rem; }
.reader-crumbs .crumb-current { color: var(--fg-muted); font-weight: 400; overflow: hidden; text-overflow: ellipsis; }
/* On mobile, keep it compact */
@media (max-width: 50em) {
  .reader-crumbs { font-size: 0.7rem; padding: 0.15rem 0.4rem; }
  .reader-crumbs .crumb-current { max-width: 8rem; }
}
body {
  background: var(--bg);
  color: var(--fg);
  font-family: var(--font-serif);
  font-size: var(--font-size);
  line-height: 1.65;
  font-feature-settings: "kern" 1, "liga" 1, "onum" 1;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  display: flex;
  flex-direction: column;
}

/* --- Reader chrome --- */
.reader-header {
  margin: 0 auto;
  padding: 3rem 1.5rem 1.5rem;
  text-align: center;
}
.reader-kicker {
  margin: 0 0 0.5rem;
  font-size: 0.85rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--fg-muted);
}
.reader-title {
  font-size: 1.9rem;
  font-weight: 500;
  margin: 0 0 0.25rem;
  letter-spacing: -0.01em;
}
.reader-title [lang="ru"] {
  font-style: italic;
  font-weight: 400;
  color: var(--fg-muted);
}
.reader-meta {
  margin: 0;
  font-size: 0.85rem;
  color: var(--fg-muted);
}

/* --- Two-column reader layout ---
   Pure dynamic weighting: grid is `1fr 1fr`, no fixed floor or ceiling.
   The viewport decides the per-column measure; below the collapse breakpoint
   we drop to a single column so neither side becomes unreadable. */
.reader {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0;
  margin: 0 auto;
  padding: 1rem 1.5rem 0;  /* bottom padding is in .column — no wasted space */
  column-gap: 3rem;
  flex: 1;            /* take all remaining vertical space (H8 — maximize text) */
  min-height: 0;      /* critical for flex children that scroll internally */
  overflow: hidden;
}

.column {
  min-width: 0;
  overflow-y: auto;
  padding-bottom: 1rem;  /* breathing room at the bottom of the scroll area */
  /* No CSS scroll-behavior: JS animateScroll() provides iOS-momentum easing. */
  /* Shared baseline grid (TC-011) — both columns share line-height + spacing. */
}

.column-label {
  font-size: 0.8rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--fg-muted);
  font-weight: 500;
  margin: 0 0 1.5rem;
  padding-bottom: 0.5rem;
  border-bottom: 1px solid var(--rule);
}

/* --- Newspaper headline (Ep07 Aeolus unique formatting) ---
   ALL-CAPS section headers that precede short paragraphs, mimicking
   the newspaper layout Joyce used in the original edition. */
.headline {
  font-size: 0.85em;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  text-align: center;
  text-indent: 0;
  margin: 2.2em 0 1.2em;
  color: var(--fg);
  line-height: 1.4;
}
.headline:first-of-type { margin-top: 0; }
.headline-empty { min-height: 1em; }

.paragraph {
  margin: 0 0 1.4em; /* paragraph spacing — clearly visible break between paragraphs */
  text-indent: 1.5em;
  /* Left gutter so the pin accent-bar (inset 3px on .is-pinned) never sits on
     top of the text. Bar lives in this gutter; text never reflows on pin. */
  padding-left: 1.5rem;
}
.paragraph:first-of-type { text-indent: 0; }

/* The first paragraph after a column label starts flush. */
.column > .paragraph:first-of-type { margin-top: 0; }

/* --- Epigraph (paragraph-level type='epigraph') ---
   Operator: "this is a quote at the front of the chapter, separate from the flow"
   Visual: large centred opening quote, indented italic verse, separated from body. */
.epigraph {
  margin: 0 0 2rem;
  padding: 0;
  text-indent: 0;
  position: relative;
  border-bottom: 1px solid var(--rule);
  padding-bottom: 1.5rem;
}
.epigraph-mark {
  display: block;
  font-family: var(--font-serif);
  font-size: 3rem;
  line-height: 1;
  font-style: italic;
  font-weight: 500;
  color: var(--fg-muted);
  text-align: center;
  margin: 0 0 0.5rem;
  user-select: none;
}
.epigraph .sentence {
  display: block;
  font-style: italic;
  font-size: 0.95em;
  color: var(--fg);
  padding-left: 2rem;
  padding-right: 2rem;
  text-align: left;
}
/* In poetry lines, keep line-height tighter than prose */
.epigraph .poem-line,
.poem .poem-line {
  display: block;
}

/* --- Generic poem block (for in-body verse like Margaret, Borges, etc.) --- */
.poem {
  margin: 1.5rem 0;
  padding: 0.5rem 1.5rem 0.5rem 1.5rem; /* symmetric horizontal padding so the right edge breathes like the left */
  border-left: 3px solid var(--rule);
  font-style: italic;
  font-size: 0.95em;
  color: var(--fg);
}
.poem .sentence,
.poem .poem-line {
  display: block;
}

/* --- Enumeration block (labelled a./b./c./d. lists, like Gass's
   "organizing principles of lists" in ch05). Indented block, each
   lettered item on its own visual line, lead-in and coda flow inline. --- */
.enumeration {
  margin: 1.4em 0;
  padding-left: 2em;     /* gutter for the a./b./c./d. labels */
}
/* Each item gets its own line. Items indent by 2em so wrapped lines
   align under the text (NOT under the letter label). The letter label
   is at the start of the line, in the gutter.
   No hanging indent — avoids column-overflow clipping. */
.enumeration .sentence {
  display: block;
  margin-left: 2em;
  text-indent: 0;
}
/* Lead-in: first sentence — flush with the block's left edge, no indent */
.enumeration > .sentence:first-of-type {
  margin-left: 0;
  margin-bottom: 0.4em;
}
/* Coda: last sentence — flush with the block's left edge */
.enumeration > .sentence:last-of-type {
  margin-left: 0;
  margin-top: 0.4em;
}
/* Letter labels (a./b./c./d.) — bold so they read as list markers,
   not as part of the prose flow. */
.enumeration .enum-label {
  font-weight: 700;
  margin-right: 0.3em;
}

/* --- Sentences --- */
.sentence {
  cursor: pointer;
  border-radius: 2px;
  padding: 0 1px;       /* tiny breath so highlight rect isn't cramped */
  margin: 0 -1px;
  transition: background-color 120ms ease, color 120ms ease;
  /* contain-intrinsic-size keeps scrollbar stable under content-visibility (TC-029) */
  content-visibility: auto;
  contain-intrinsic-size: auto 1.65em;
}

/* Space between adjacent sentences inside a paragraph. */
.sentence + .sentence::before { content: " "; }

/* --- Glossary annotated proper names (H6 Recognition) ---
   Subtle dotted underline — doesn't disrupt prose flow.
   Hover gives a light tint. Click opens modal with research. */
.glossary-term {
  border-bottom: 1px dotted var(--accent);
  cursor: help;
  color: inherit;
  font-style: inherit;
  border-radius: 2px;
  padding: 0 1px;
  transition: background-color 120ms ease;
}
.glossary-term:hover {
  background: var(--hover-bg);
}
.glossary-term:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}

/* --- Glossary modal (H6 — context in-place, not alt-tab to Wikipedia) --- */
.glossary-overlay {
  position: fixed;
  inset: 0;
  z-index: 100;
  background: rgba(0, 0, 0, 0.4);
  backdrop-filter: blur(2px);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 2rem;
}
.glossary-overlay[hidden] { display: none; }

.glossary-modal {
  position: relative;
  max-width: min(32rem, 90vw);
  max-height: 80vh;
  overflow-y: auto;
  background: var(--bg);
  color: var(--fg);
  border: 1px solid var(--rule);
  border-radius: 8px;
  box-shadow: 0 8px 40px rgba(0, 0, 0, 0.2);
  padding: 2rem 2.5rem;
  font-family: var(--font-serif);
  line-height: 1.7;
}
.glossary-modal-close {
  position: absolute;
  top: 0.75rem;
  right: 1rem;
  background: none;
  border: none;
  color: var(--fg-muted);
  font-size: 1.5rem;
  cursor: pointer;
  line-height: 1;
  padding: 0.25rem 0.5rem;
}
.glossary-modal-close:hover { color: var(--fg); }

/* Tessera image (optional, e.g. 1987 Count Chocula box). */
.glossary-modal-figure {
  margin: 0 0 1rem 0;
  padding: 0;
  text-align: center;
}
.glossary-modal-img {
  max-width: 100%;
  max-height: 40vh;
  border-radius: 6px;
  border: 1px solid var(--rule);
  object-fit: contain;
}
.glossary-modal-caption {
  margin-top: 0.4rem;
  font-size: 0.8rem;
  color: var(--fg-muted);
  font-family: var(--font-sans, system-ui, sans-serif);
  line-height: 1.4;
}

/* Tessera audio player (optional, e.g. "So Lonesome I Could Cry"). */
.glossary-modal-audio {
  display: block;
  width: 100%;
  max-width: 28rem;
  margin: 0 auto 1rem;
  height: 2.4rem;
}

.glossary-modal-title {
  font-size: 1.3rem;
  font-weight: 500;
  margin: 0 0 1rem;
  color: var(--accent);
  font-style: italic;
  padding-right: 2rem;  /* don't overlap close button */
}

.glossary-modal-body {
  font-size: 0.95rem;
  text-align: justify;
  hyphens: auto;
}
.glossary-modal-body p {
  margin: 0 0 0.85rem;
}
.glossary-modal-body p:last-child {
  margin-bottom: 0;
}

/* Hover (transient) — source + partner both lit.
   Applies to BOTH .paragraph (new books, paragraph-level) and
   .sentence (legacy books, sentence-level). */
.paragraph.is-hover, .sentence.is-hover {
  background: var(--hover-bg);
  color: var(--hover-fg);
}
.paragraph.is-partner-hover, .sentence.is-partner-hover {
  background: var(--partner-bg);
}

/* Pin (persistent) — stronger, with left bar accent. */
.paragraph.is-pinned, .sentence.is-pinned,
.paragraph.is-partner-pinned, .sentence.is-partner-pinned {
  background: var(--pin-bg);
  box-shadow: inset 3px 0 0 var(--pin-bar);
}
.paragraph.is-partner-pinned, .sentence.is-partner-pinned {
  background: var(--partner-pin-bg);
}

/* Both pinned + hovered at once. */
.paragraph.is-pinned.is-hover, .sentence.is-pinned.is-hover {
  background: var(--pin-bg);
}

/* Paragraphs are interactive — cursor pointer + focus ring. */
.paragraph[data-pid] {
  cursor: pointer;
  border-radius: 2px;
}
.paragraph[data-pid]:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}

/* Off-screen partner indicator — REMOVED in Epic 2 v2 (Nielsen H8: didn't earn
   its place in the independent-column-scroll architecture). */

/* --- Reading progress bar (H1 Visibility) --- */
.reading-progress {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 50;
  width: 100vw;
  height: 4px;
  border: none;
  background: var(--rule); /* faint track so the filled portion reads clearly */
  color: var(--pin-bar);   /* strong accent (the same orange used for pin bars) */
  pointer-events: none; /* never block clicks */
}
.reading-progress::-webkit-progress-bar {
  background: var(--rule);
}
.reading-progress::-webkit-progress-value {
  background: var(--pin-bar);
  transition: width 80ms linear;
}
.reading-progress::-moz-progress-bar {
  background: var(--pin-bar);
}

/* --- Floating action cluster (H7: copy link / back to top) --- */
.fab-cluster {
  position: fixed;
  bottom: 1.5rem;
  right: 1.5rem;
  z-index: 20;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  align-items: flex-end;
}
.fab {
  width: 2.4rem;
  height: 2.4rem;
  border-radius: 50%;
  border: 1px solid var(--rule);
  background: var(--bg);
  color: var(--fg);
  font-size: 1rem;
  line-height: 1;
  cursor: pointer;
  box-shadow: 0 1px 4px rgba(0,0,0,0.08);
  transition: background-color 120ms ease, transform 120ms ease, opacity 120ms ease;
  display: flex;
  align-items: center;
  justify-content: center;
}
.fab:hover { background: var(--hover-bg); transform: scale(1.05); }
.fab[hidden] { display: none; }
.fab.copied-flash {
  background: var(--accent);
  color: var(--bg);
}

/* --- Skip link (H4 standard a11y pattern) --- */
.skip-link {
  position: absolute;
  top: -100px;
  left: 1rem;
  z-index: 100;
  background: var(--accent);
  color: var(--bg);
  padding: 0.6rem 1rem;
  border-radius: 4px;
  text-decoration: none;
  font-size: 0.9rem;
  /* No transition — the link must appear instantly on focus for keyboard users. */
}
.skip-link:focus {
  top: 1rem;
}

}

/* --- Collapsible chrome (H8 Minimalist) --- */
.chrome-toggle {
  position: fixed;
  top: 0.5rem;
  right: 0.5rem;
  z-index: 30;
  width: 2.2rem;
  height: 2.2rem;
  border: 1px solid var(--rule);
  background: var(--bg);
  color: var(--fg);
  font-size: 1rem;
  line-height: 1;
  cursor: pointer;
  border-radius: 4px;
  box-shadow: 0 1px 4px rgba(0,0,0,0.08);
  transition: background-color 120ms ease;
}
.chrome-toggle:hover { background: var(--hover-bg); }

/* Tiny persistent context label, visible only when chrome is collapsed. */
.chrome-context-label {
  position: fixed;
  top: 0.5rem;
  left: 1rem;
  z-index: 25;
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  background: color-mix(in srgb, var(--bg) 75%, transparent);
  backdrop-filter: blur(6px);
  padding: 0.3rem 0.6rem;
  border-radius: 3px;
  pointer-events: none;
  max-width: calc(100vw - 5rem); /* don't overlap the toggle button */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.chrome-context-label[hidden] { display: none; }
.chrome-context-pos {
  font-size: 0.7rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--fg-muted);
}
.chrome-context-title {
  font-size: 0.85rem;
  font-weight: 500;
  color: var(--fg);
  font-style: italic;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Collapsed state: animated via max-height + opacity transition.
   The transition rules live in the "Chrome frame auto-hide" section below
   (cubic-bezier natural physics). We do NOT use display:none here because
   it kills CSS transitions — the element must stay in the render tree. */
/* Context label REMOVED from collapsed view (2026-08-09, operator request):
   when collapsed, ONLY the breadcrumb strip + ≡ are visible. The label
   (chapter name + sentence counter) overlapped the breadcrumbs and covered
   the first sentences. Position info lives in the expanded header instead. */
body.chrome-collapsed .chrome-context-label {
  display: none;
}
.chrome-context-label { display: none !important; }

/* Reserve space for the fixed breadcrumb strip so the first sentences are
   never hidden under it (mobile). Expanded: frame padding clears the strip.
   NOTE: crumbs are now shown ONLY when expanded (2026-08-09). When collapsed
   the top is clean — full-screen reading, just the ≡ corner button. */
@media (max-width: 50em) {
  .chrome-frame { padding-top: 2rem; }
  /* Collapsed: no top strip at all — crumbs hidden, reader flush from top. */
  body.chrome-collapsed .reader-crumbs { display: none; }
  /* Narrower pin-bar gutter on mobile — preserve reading width. */
  .paragraph { padding-left: 0.75rem; }
}

/* --- Reader toolbar (theme switch, layout toggle) --- */
.reader-toolbar {
  position: sticky;
  top: 0;
  z-index: 10;
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  justify-content: center;
  padding: 0.5rem 1rem 0.5rem 1rem;
  /* Reserve space for fixed .chrome-toggle (≡) on the right */
  margin-right: 2.7rem;
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--rule);
}
.reader-toolbar button {
  font: inherit;
  font-size: 0.85rem;
  padding: 0.35rem 0.75rem;
  background: transparent;
  color: var(--fg);
  border: 1px solid var(--rule);
  border-radius: 4px;
  cursor: pointer;
}
.reader-toolbar button:hover { background: var(--hover-bg); }
.reader-toolbar button[aria-pressed="true"] {
  background: var(--accent);
  color: var(--bg);
  border-color: var(--accent);
}
/* Theme cycle button — single icon (☀◐☾) replaces Day/Sepia/Night trio */
.reader-toolbar .theme-cycle-btn {
  font-size: 1.1rem;
  line-height: 1;
  min-width: 2rem;
}
/* Home breadcrumb — escape hatch back to the book index (H3 User Control). */
.reader-toolbar .toolbar-home-btn {
  font-size: 0.95rem;
  line-height: 1;
  padding: 0.3rem 0.5rem;
  text-decoration: none;
  color: var(--fg-muted);
  border: 1px solid transparent;
  border-radius: 4px;
  transition: color 120ms ease, border-color 120ms ease;
}
.reader-toolbar .toolbar-home-btn:hover {
  color: var(--accent);
  border-color: var(--rule);
}

/* --- Vertical layout (portrait / vertical-monitor reading, R1) --- */
[data-layout="vertical"] .reader {
  grid-template-columns: 1fr;
  max-width: 38em;
}
[data-layout="vertical"] .column {
  min-width: 0;
  max-width: none;
}
[data-layout="vertical"] .column + .column {
  margin-top: 3rem;
  padding-top: 2rem;
  border-top: 1px solid var(--rule);
}

/* --- Chapter summary (collapsible) --- */
.chapter-summary {
  max-width: 72rem;
  margin: 0 auto 1.5rem;
  padding: 0 1.5rem;
}
.chapter-summary-toggle {
  font: inherit;
  font-size: 0.9rem;
  font-weight: 500;
  letter-spacing: 0.04em;
  color: var(--fg-muted);
  background: transparent;
  border: 1px solid var(--rule);
  border-radius: 4px;
  padding: 0.5rem 1rem;
  cursor: pointer;
  transition: background-color 120ms ease;
  list-style: none;
}
.chapter-summary-toggle::-webkit-details-marker { display: none; }
.chapter-summary-toggle::before {
  content: "▸ ";
  font-family: var(--font-mono);
  font-size: 0.8em;
}
.chapter-summary[open] .chapter-summary-toggle::before {
  content: "▾ ";
}
.chapter-summary-toggle:hover {
  background: var(--hover-bg);
}
.chapter-summary-content {
  margin-top: 1rem;
  padding: 1.25rem 1.5rem;
  background: var(--hover-bg);
  border-radius: 6px;
  font-size: 0.95rem;
  line-height: 1.6;
}
.chapter-summary-content p {
  margin: 0 0 0.75rem;
}
.chapter-summary-content p:last-child {
  margin-bottom: 0;
  font-style: italic;
  color: var(--fg-muted);
}

/* --- Font size label --- */
.font-size-label {
  font-size: 0.85rem;
  min-width: 3em;
  text-align: center;
  color: var(--fg-muted);
  font-variant-numeric: tabular-nums;
}

/* --- Index page --- */
.reader-index ul {
  list-style: none;
  padding: 0;
}
.reader-index a {
  color: var(--accent);
  text-decoration: none;
  font-size: 1.1rem;
}
.reader-index a:hover { text-decoration: underline; }

/* --- Reduced motion (TC-024) --- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    transition: none !important;
    animation: none !important;
    scroll-behavior: auto !important;
  }
}

/* --- Print --- */
@media print {
  .reader-toolbar { display: none; }
  .reader { grid-template-columns: 1fr 1fr; }
  .sentence { background: none !important; box-shadow: none !important; }
}

/* --- Responsive (≤50em): MOBILE SINGLE-LANGUAGE MODE (Nielsen H8 Minimalism).
     Instead of stacking both language columns (two separate scroll areas = bad
     mobile UX), show ONE language full-screen. Tap a sentence → its translation
     appears inline (accordion). ⇄ FAB swaps which language is primary.
     Toolbar HIDDEN on mobile — 8 buttons wrapping to 6 rows wastes 40% of
     viewport. Theme/font/layout controls are desktop-only; mobile is reading. --- */
@media (max-width: 50em) {
  .reader-toolbar { display: none !important; }

  .reader {
    grid-template-columns: 1fr;
    max-width: 38em;
  }
  .column { min-width: 0; max-width: none; }

  /* Compact header on mobile — shrink title + reduce padding (H8 Minimalism) */
  .reader-header { padding: 1rem 1rem 0.5rem; }
  .reader-title { font-size: 1.4rem; margin-bottom: 0.1rem; }
  .reader-kicker { margin-bottom: 0.25rem; font-size: 0.75rem; }
  .reader-meta { font-size: 0.75rem; }

  /* Hide translation column by default (source is primary).
     Gass fallback: [data-column="ru"] for pages without data-role. */
  .column[data-role="translation"],
  .column[data-column="ru"] {
    display: none;
  }

  /* When swapped to translation-primary, flip visibility */
  body[data-mobile-primary="translation"] .column[data-role="source"],
  body[data-mobile-primary="translation"] .column[data-column="en"] {
    display: none;
  }
  body[data-mobile-primary="translation"] .column[data-role="translation"],
  body[data-mobile-primary="translation"] .column[data-column="ru"] {
    display: block;
  }

  /* Bottom sheet: translation floats UP from bottom like surfacing from water.
     High-contrast background, sits over reading content (no shift).
     Nielsen H1 Visibility + H8 Minimalism + H6 Recognition (familiar iOS pattern). */
  .mobile-sheet-overlay {
    position: fixed;
    inset: 0;
    z-index: 200;
    background: rgba(0,0,0,0.3);
    backdrop-filter: blur(1px);
    display: flex;
    align-items: flex-end;
    justify-content: center;
    opacity: 0;
    transition: opacity 300ms ease;
  }
  .mobile-sheet-overlay.open { opacity: 1; }
  .mobile-sheet {
    width: 100%;
    max-width: 38em;
    max-height: 85vh;
    overflow-y: auto;
    background: var(--bg, #fff);
    border-top: 3px solid var(--pin-bar, #c05416);
    border-radius: 16px 16px 0 0;
    padding: 1.5rem 1.2rem calc(1.5rem + env(safe-area-inset-bottom, 0));
    box-shadow: 0 -4px 24px rgba(0,0,0,0.12);
    transform: translateY(100%);
    transition: transform 350ms cubic-bezier(0.32, 0.72, 0, 1);
    position: relative;
  }
  .mobile-sheet-overlay.open .mobile-sheet {
    transform: translateY(0);
  }
  .mobile-sheet-close {
    position: absolute;
    top: 0.6rem;
    right: 0.8rem;
    width: 2rem;
    height: 2rem;
    border: none;
    background: var(--hover-bg, #f0ede5);
    color: var(--fg-muted, #999);
    font-size: 1.3rem;
    line-height: 1;
    border-radius: 50%;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 1;
  }
  .mobile-sheet-close:hover { background: var(--accent, #6b4f1d); color: #fff; }
  .mobile-sheet-role {
    display: inline-block;
    font-size: 0.7rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    padding: 0.2em 0.55em;
    border-radius: 4px;
    margin-bottom: 0.6rem;
    line-height: 1;
  }
  .role-translation { background: var(--accent, #6b4f1d); color: #fff; }
  .role-original  { background: var(--hover-bg, #f0ede5); color: var(--fg-muted, #777); }
  .mobile-sheet-text {
    margin: 0;
    padding-right: 2.5rem;
    font-size: 1rem;
    color: var(--fg, #333);
    line-height: 1.65;
    font-weight: 500;
  }
  /* "Continue reading in this language" — contextual language switch inside
     the sheet. The modal is high-priority (above tap zones), so this never
     conflicts with page-flip navigation. */
  .mobile-sheet-continue {
    display: block;
    width: 100%;
    margin-top: 1rem;
    padding: 0.65rem 1rem;
    background: var(--accent, #6b4f1d);
    color: #fff;
    border: none;
    border-radius: 8px;
    font-size: 0.95rem;
    font-weight: 600;
    cursor: pointer;
    transition: opacity 0.15s;
  }
  .mobile-sheet-continue:active { opacity: 0.85; }

  /* Tapped sentence highlight in mobile mode */
  .sentence.mobile-active {
    background: var(--pin-bg);
    box-shadow: inset 3px 0 0 var(--pin-bar);
    border-radius: 2px;
  }

  /* Mobile reading settings sheet (⚙): font size / alignment / hyphenation */
  .settings-sheet { padding: 1.25rem 1.25rem 1.5rem; }
  .settings-title {
    margin: 0 0 1rem;
    font-size: 1.05rem;
    font-weight: 600;
    color: var(--fg, #333);
    padding-right: 2.5rem;
  }
  .settings-row {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    padding: 0.75rem 0;
    border-top: 1px solid var(--border, rgba(0,0,0,0.08));
  }
  .settings-label {
    font-size: 0.85rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--fg-dim, #777);
  }
  .settings-controls {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
  }
  .settings-btn {
    border: 1px solid var(--border, rgba(0,0,0,0.15));
    background: var(--bg, #fff);
    color: var(--fg, #333);
    border-radius: 8px;
    padding: 0.5rem 0.9rem;
    font-size: 1rem;
    min-width: 2.75rem;
    cursor: pointer;
    transition: background 0.15s, border-color 0.15s;
  }
  .settings-btn:active { background: var(--hover-bg, rgba(0,0,0,0.05)); }
  .settings-toggle.active {
    background: var(--accent, #6b4f1d);
    border-color: var(--accent, #6b4f1d);
    color: #fff;
  }
  .settings-value {
    font-size: 0.95rem;
    font-weight: 600;
    color: var(--fg, #333);
    min-width: 3rem;
    text-align: center;
  }
  /* Page navigation inside settings sheet (◀ Страница ▶).
     Lets the user turn pages while adjusting settings — no modal trap. */
  .settings-page-nav {
    flex-direction: row;
    align-items: center;
    justify-content: center;
    gap: 0.75rem;
    padding: 0.5rem 0;
  }
  .settings-page-btn {
    font-size: 1.2rem;
    min-width: 2.5rem;
    padding: 0.35rem 0.7rem;
  }
  .settings-page-label {
    font-size: 0.85rem;
    color: var(--fg-muted, #777);
    font-weight: 500;
  }

  /* Kindle-style: ZERO floating FABs on mobile. Swap moved to ≡ chrome panel.
     Tap zones handle page-flip navigation (left=up, right=down). */
  .fab, .fab-cluster, .swap-lang-fab { display: none !important; }

  /* Invisible tap zones for page-flip (left/right 30% of viewport).
     Center 40% is uncovered — sentence taps pass through directly.
     When the chrome menu is expanded, the frame stacks above the zones
     (Mode B) — menu is tappable, zones keep working below it. */
  .tap-zone {
    position: fixed;
    top: 4rem;
    bottom: 0;
    width: 30%;
    z-index: 1;
    background: transparent;
    -webkit-tap-highlight-color: transparent;
  }
  .tap-zone-left { left: 0; }
  .tap-zone-right { right: 0; }
}

/* Mode B (sandbox-validated 2026-08-09): when the chrome menu is expanded it
   stacks ABOVE the tap zones (position:relative + higher z-index). Menu buttons
   stay tappable; zones below the menu keep flipping pages (Kindle behavior).
   Taps inside the menu box never reach the zones. When collapsed, frame height
   is 0 so it covers nothing. */
.chrome-frame {
  position: relative;
  z-index: 6; /* above .tap-zone (1), below ≡ toggle (30) */
}
@media (min-width: 50.01em) {
  .tap-zone { display: none !important; }
}

/* --- Reading typography prefs (set via ⚙ settings sheet, persisted) ---
   Justify + language-correct hyphenation. Sentences carry lang="ru|de|en",
   so hyphens:auto applies each language's own hyphen rules. */
body[data-align="justify"] .sentence {
  text-align: justify;
}
body[data-hyphens="auto"] .sentence {
  -webkit-hyphens: auto;
  hyphens: auto;
  hyphenate-limit-chars: 5 3 3;
}
body[data-align="justify"][data-hyphens="off"] .sentence {
  /* Justify without hyphenation creates rivers of whitespace —
     soften with slightly looser word spacing */
  word-spacing: 0.05em;
}
/* --- Translation attribution (slim one-liner under RU column header) --- */
/* Nielsen #8 minimalism + #6 recognition: short visible tag, full
   provenance one click away via progressive disclosure (<details>). */
.column-attribution {
  margin: 0 0 1rem;
  font-size: 0.78rem;
  line-height: 1.4;
  color: var(--fg-muted);
  font-weight: 400;
}
.column-attribution em {
  font-style: italic;
  color: var(--fg-muted);
}
.column-attribution-details {
  display: inline;
}
.column-attribution-details > summary {
  display: inline;
  list-style: none;
  cursor: help;
  color: var(--fg-muted);
  opacity: 0.7;
  padding: 0 0.2em;
  font-size: 1em;
  line-height: 1;
  vertical-align: baseline;
}
.column-attribution-details > summary::-webkit-details-marker { display: none; }
.column-attribution-details > summary:hover {
  opacity: 1;
  text-decoration: underline dotted;
}
.column-attribution-details[open] > summary {
  display: none;
}
.column-attribution-full {
  display: block;
  margin-top: 0.4rem;
  padding: 0.5rem 0.75rem;
  background: var(--hover-bg);
  border-left: 2px solid var(--rule);
  border-radius: 0 3px 3px 0;
  font-size: 0.75rem;
  line-height: 1.5;
  color: var(--fg-muted);
}

/* ============================================================================
   Resume toast (TC-003) — "Resumed at sentence N — jump to top"
   Non-blocking pill shown after progress restore. Auto-hides 4s.
   ============================================================================ */
.resume-toast {
  position: fixed;
  bottom: 24px;
  left: 50%;
  transform: translateX(-50%) translateY(8px);
  padding: 8px 14px;
  background: color-mix(in srgb, var(--bg) 92%, transparent);
  color: var(--fg-muted, #555);
  font-size: 13px;
  line-height: 1.4;
  border-radius: 999px;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.18);
  opacity: 0;
  transition: opacity 200ms ease, transform 200ms ease;
  z-index: 1000;
  pointer-events: none;
  max-width: calc(100vw - 32px);
  border: 1px solid rgba(0, 0, 0, 0.06);
}
.resume-toast.visible {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
  pointer-events: auto;
}
.resume-toast-jump {
  background: none;
  border: none;
  padding: 0 0 0 2px;
  margin: 0;
  font: inherit;
  color: var(--accent, #0066cc);
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 2px;
}
.resume-toast-jump:hover {
  text-decoration: none;
  opacity: 0.8;
}
@media (prefers-reduced-motion: reduce) {
  .resume-toast,
  .resume-toast.visible {
    transition: none;
    transform: translateX(-50%);
  }
}

/* sentence-counter chip REMOVED — blocked the chrome-toggle button (≡).
   Position info is already shown by .chrome-context-label when collapsed. */

/* ============================================================================
   Multi-chapter: TOC modal + auto-hide (added for unified reader)
   ============================================================================ */

/* TOC modal */
.toc-overlay{position:fixed;inset:0;z-index:100;background:rgba(0,0,0,.4);
 backdrop-filter:blur(2px);display:none;align-items:center;justify-content:center;}
.toc-overlay.open{display:flex;}
.toc-modal{background:var(--bg,var(--paper,#fff));border:1px solid var(--rule,#ccc);
 border-radius:8px;padding:1.5rem 2rem;max-width:400px;max-height:70vh;overflow-y:auto;
 box-shadow:0 4px 20px rgba(0,0,0,.15);}
.toc-modal h3{margin:0 0 1rem;font-size:1rem;color:var(--accent,#6b4f1d);}
.toc-ch-link{display:block;padding:.5rem .8rem;margin:.2rem 0;border-radius:4px;
 cursor:pointer;font-size:.9rem;color:var(--fg,#333);text-decoration:none;}
.toc-ch-link:hover{background:var(--accent,#6b4f1d);color:#fff;}
.toc-ch-link.current{background:rgba(107,79,29,.12);font-weight:600;}
.toc-close{float:right;cursor:pointer;color:var(--fg-muted,#999);font-size:1.2rem;
 border:none;background:none;padding:0 .3rem;}
.toc-close:hover{color:var(--fg,#333);}

/* Chapter overview modal (golden rule: every chapter gets a summary_ru).
   «Обзор» button on each .ch-heading opens a modal — no inline expansion
   that pushes content down. Reuses .toc-overlay backdrop pattern. */
.chapter-overview-btn{
  float:right;font-size:.65rem;font-weight:400;letter-spacing:.04em;
  color:var(--fg-muted,#999);background:transparent;border:1px solid var(--rule,#ccc);
  border-radius:3px;padding:.1rem .4rem;cursor:pointer;margin-top:.1rem;
  transition:background-color 120ms ease,color 120ms ease;}
.chapter-overview-btn:hover{background:var(--accent,#6b4f1d);color:#fff;border-color:var(--accent,#6b4f1d);}
.chapter-overview-modal{position:fixed;inset:0;z-index:100;background:rgba(0,0,0,.4);
  backdrop-filter:blur(2px);display:none;align-items:center;justify-content:center;}
.chapter-overview-modal.open{display:flex;}
.chapter-overview-card{background:var(--bg,var(--paper,#fff));border:1px solid var(--rule,#ccc);
  border-radius:8px;padding:1.5rem 2rem;max-width:480px;max-width:min(480px,90vw);max-height:75vh;overflow-y:auto;
  box-shadow:0 4px 20px rgba(0,0,0,.15);}
.chapter-overview-card h3{margin:0 0 1rem;font-size:1rem;color:var(--accent,#6b4f1d);}
.chapter-overview-card p{margin:0 0 .8rem;font-size:.92rem;line-height:1.6;color:var(--fg,#333);}
.chapter-overview-card p:last-child{margin-bottom:0;}
.chapter-overview-card p[lang]{font-style:normal;}
.chapter-overview-card p.summary-ru{font-weight:500;}
.chapter-overview-card p.summary-src{color:var(--fg-muted,#777);font-style:italic;font-size:.85rem;border-top:1px solid var(--rule,#e3d9c6);padding-top:.8rem;margin-top:.8rem;}
.chapter-overview-close{float:right;cursor:pointer;color:var(--fg-muted,#999);font-size:1.2rem;
  border:none;background:none;padding:0 .3rem;line-height:1;}
.chapter-overview-close:hover{color:var(--fg,#333);}

/* Chrome frame auto-hide — natural physics (Material Design standard ease).
   cubic-bezier(0.4, 0, 0.2, 1) gives a smooth decelerate-then-settle feel
   like a physical drawer sliding shut. max-height tuned to fit all chrome
   content (toolbar + header + nav) without clipping. */
.chrome-frame{
  transition: max-height .35s cubic-bezier(0.4, 0, 0.2, 1), opacity .25s ease;
  max-height: 320px;
  opacity: 1;
  overflow: hidden;
}
body.chrome-collapsed .chrome-frame {
  max-height: 0;
  opacity: 0;
}

/* Nav bar inside chrome-frame.
   Right padding reserves space for the fixed .chrome-toggle (≡) button
   (2.2rem wide + 0.5rem right offset ≈ 2.7rem) so nav buttons never
   slide under it on narrow screens. */
.nav-bar{display:flex;gap:.5rem;justify-content:center;padding:.4rem 1rem .4rem 3.2rem;
 border-bottom:1px solid var(--rule,#e3d9c6);}
.nav-btn{background:none;border:1px solid var(--rule,#ccc);color:var(--accent,#6b4f1d);
 border-radius:4px;padding:.3rem .7rem;cursor:pointer;font-size:.8rem;
 text-decoration:none;font-weight:600;}
.nav-btn:hover{background:var(--accent,#6b4f1d);color:#fff;}
.nav-home{margin-right:.5rem;}

/* Quick-action row: language + font + theme — at the TOP of expanded chrome.
   These are the most-used controls, placed first for instant access (Nielsen H6). */
.quick-actions{
 display:flex;gap:.4rem;justify-content:center;align-items:center;
 padding:.5rem 1rem;flex-wrap:wrap;
 border-bottom:1px solid var(--rule,#e3d9c6);}
.quick-btn{
 background:var(--bg,#fff);border:1px solid var(--rule,#ccc);
 border-radius:6px;padding:.4rem .8rem;font-size:.9rem;font-weight:600;
 cursor:pointer;color:var(--fg,#333);min-width:2.5rem;text-align:center;
 transition:background .15s,border-color .15s;}
.quick-btn:active{background:var(--hover-bg,rgba(0,0,0,.06));}
.quick-lang-btn{background:var(--accent,#6b4f1d);color:#fff;border-color:var(--accent,#6b4f1d);min-width:5rem;font-size:1rem;}

/* Multi-chapter sticky headings */
.ch-heading{font-size:.95rem;color:var(--accent,#6b4f1d);
 border-bottom:1px solid var(--rule,#e3d9c6);
 padding:.4rem 0 .25rem;margin:0 0 .6em;font-weight:600;
 position:sticky;top:0;background:var(--bg,var(--paper,#fff));z-index:5;}
.ch-heading .strand{font-size:.6rem;color:var(--fg-muted,#999);
 vertical-align:super;letter-spacing:.1em;font-weight:400;}

/* Mobile: hide sticky ch-heading — it permanently eats ~36px at the top
   ("1cm dead area") showing chapter name with little value in the reading
   flow. Removing it balances the top/bottom padding. Desktop keeps it
   (useful for multi-chapter navigation). */
@media (max-width: 50em) {
  .ch-heading { display: none; }
  /* Also hide the column-label (H2 "DE"/"RU") on mobile — the breadcrumb
     shows the book title; language is obvious from content. */
  .column-label { display: none; }
  /* Balance padding: small top margin + matching bottom breathing room */
  .column { padding-top: 0.5rem; padding-bottom: 0.5rem; }
}


/* ============================================================================
   TTS audio pill + cache markers (TC-005)
   Bottom-fixed pill appears on pin (reader:pinned); all colors via design
   tokens so day/sepia/night themes render correctly. z-index 250: above
   fab-cluster (100) and mobile sheet (200), below header/modals (1000).
   ============================================================================ */
.audio-pill {
  position: fixed;
  left: 50%;
  transform: translateX(-50%);
  bottom: calc(14px + env(safe-area-inset-bottom, 0px));
  z-index: 250;
  min-width: 0;
  max-width: min(340px, 92vw);
  background: var(--bg);
  color: var(--fg);
  border: 1px solid var(--rule);
  border-radius: 10px;
  box-shadow: 0 3px 12px rgba(0, 0, 0, 0.16);
  padding: 0.26rem 0.5rem;
  font-size: 0.75rem;
}
.audio-pill-row { display: flex; align-items: center; gap: 0.4rem; }
.audio-pill-icon { font-size: 0.9rem; line-height: 1; }
.audio-pill-id {
  color: var(--fg-muted);
  font-family: var(--font-mono);
  font-size: 0.68rem;
  white-space: nowrap;
}
/* Selection-change pulse: visible proof the pill follows the clicked paragraph */
.audio-pill-pop { animation: audio-pop 0.5s ease-out; }
@keyframes audio-pop {
  0% { box-shadow: 0 0 0 3px var(--pin-bar), 0 3px 12px rgba(0, 0, 0, 0.16); }
  100% { box-shadow: 0 0 0 0 rgba(0, 0, 0, 0), 0 3px 12px rgba(0, 0, 0, 0.16); }
}
.audio-pill.is-generating .audio-pill-iconbtn {
  display: inline-block;
  animation: audio-spin 1.2s linear infinite;
}
@keyframes audio-spin { to { transform: rotate(360deg); } }
.audio-pill-iconbtn {
  background: transparent;
  border: 0;
  font-size: 1rem;
  line-height: 1;
  cursor: pointer;
  padding: 0.1rem 0.25rem;
  border-radius: 6px;
}
.audio-pill-iconbtn:hover:not(:disabled) { background: var(--hover-bg); }
.audio-pill-iconbtn:disabled { opacity: 0.45; cursor: default; }
.audio-pill-iconbtn.is-unavailable { opacity: 0.5; }
.audio-pill-progress {
  margin-top: 0.25rem;
  height: 3px;
  background: var(--rule);
  border-radius: 2px;
  overflow: hidden;
}
.audio-pill-progress i {
  display: block;
  height: 100%;
  width: 0;
  background: var(--pin-bar);
  transition: width 0.25s linear;
}
/* Generating: indeterminate sliding segment (no chunk progress from proxy) */
.audio-pill.is-generating .audio-pill-progress i {
  width: 35%;
  transition: none;
  animation: audio-slide 1.1s ease-in-out infinite alternate;
}
@keyframes audio-slide {
  from { transform: translateX(-10%); }
  to { transform: translateX(200%); }
}
.audio-pill-time {
  color: var(--fg-muted);
  font-size: 0.68rem;
  white-space: nowrap;
  max-width: 45%;
  overflow: hidden;
  text-overflow: ellipsis;
}
.audio-pill-more {
  background: transparent;
  border: 0;
  color: var(--fg-muted);
  font-size: 0.95rem;
  line-height: 1;
  cursor: pointer;
  padding: 0.05rem 0.3rem;
  border-radius: 6px;
}
.audio-pill-more:hover { background: var(--hover-bg); color: var(--fg); }
/* [hidden] loses to author display rules — restore it inside the pill */
.audio-pill [hidden] { display: none !important; }
.audio-pill-extra {
  margin-top: 0.5rem;
  padding-top: 0.5rem;
  border-top: 1px solid var(--rule);
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}
.audio-regen {
  background: transparent;
  border: 1px solid var(--rule);
  border-radius: 8px;
  color: var(--fg);
  font: inherit;
  font-size: 0.8rem;
  padding: 0.3rem 0.5rem;
  cursor: pointer;
  text-align: left;
}
.audio-regen:hover { border-color: var(--accent); background: var(--hover-bg); }
.audio-voice { color: var(--fg-muted); font-size: 0.78rem; opacity: 0.7; }
.audio-meta { color: var(--fg-muted); font-size: 0.72rem; }

/* Gutter cache marker — one speaker glyph in the left margin of voiced paras */
[data-pid] { position: relative; }
[data-pid].audio-cached::before {
  content: "🔊";
  position: absolute;
  left: -1.4em;
  top: 0.18em;
  font-size: 0.62em;
  opacity: 0.35;
  pointer-events: none;
}
[data-pid].audio-cached.audio-stale::before { content: "🔊⚠"; opacity: 0.55; }

@media (prefers-reduced-motion: reduce) {
  .audio-pill.is-generating .audio-pill-icon { animation: none; }
  .audio-pill-progress i { transition: none; }
}
.audio-pill-close {
  background: transparent;
  border: 0;
  color: var(--fg-muted);
  font-size: 0.9rem;
  line-height: 1;
  cursor: pointer;
  padding: 0.05rem 0.3rem;
  border-radius: 6px;
}
.audio-pill-close:hover { background: var(--hover-bg); color: var(--fg); }
/* Loud failure state — errors are never silent */
.audio-pill-error { border-color: var(--pin-bar); }
.audio-pill-error .audio-pill-time { color: var(--pin-bar); font-weight: 600; }
.audio-pill-handoff {
  display: block;
  margin-top: 0.3rem;
  font-size: 0.7rem;
  color: var(--accent);
  text-decoration: none;
  white-space: nowrap;
}
.audio-pill-handoff:hover { text-decoration: underline; }
