/* styles.css — T-05 component states + craft pass for the V3 shell.
   Every typography, color, spacing, radius, elevation, and motion value comes
   from the D2 design language in shell/tokens.css (carried verbatim by
   index.html's critical <style> for first paint). This sheet defines no colors,
   shadows, or easings; the only local additions are the tokens D2 does not
   carry (font stacks, weights, tracking, rule widths, measures, target sizes),
   documented in the block below. The remaining literals are layout constants
   (column counts, breakpoints, the 1160px measure of <main>, the 3-line
   description clamp, the atlas canvas math). */

/* ---------------------------------------------------------------------------
   Local additions (T-05). D2 (v3/PLAN.md §D2, shell/tokens.css) is the
   authoritative sheet and is not edited here. It carries no font stack,
   weight, tracking, rule width, measure, or target-size token, so those are
   defined once, here, in the one file that needs them. No color, shadow, or
   easing is defined below: those come from D2 only.
   --------------------------------------------------------------------------- */
:root {
  --font-sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-serif: ui-serif, Georgia, "Iowan Old Style", "Times New Roman", serif;
  --chat-col-w: 380px;
  --weight-regular: 400;
  --weight-medium: 500;
  --weight-semibold: 600;
  --tracking-tight: -0.01em;
  --tracking-caps: 0.08em;
  --rule-hairline: 1px;
  --rule-strong: 2px;
  --measure-tight: 52ch;
  --measure-wide: 72ch;
  --target-min: 24px;
  --target-primary: 44px;
  --state-disabled: 0.6;
}

/* --- The six states (D2) ---------------------------------------------------
   Every interactive element in this sheet is listed once below and carries all
   six states: resting, hover (--paper-3 wash), focus-visible (--focus 2px ring
   at 2px offset), active (--accent-2, shifted 1px), disabled (--ink-3 at 60%,
   pointer blocked, aria-disabled), loading (--paper-3 skeleton). Each state is
   distinguishable without color: the wash, the ring, the 1px shift, the
   opacity drop, and the skeleton shape each read on their own. */
:is(
  .card-watch, .card-save, .reader-save, .card-remove,
  .index-search, .index-select,
  .clear-arm, .clear-keep, .clear-confirm-button, .view-note-retry,
  .panel-action, .atlas-node, .atlas-guide-node, .atlas-shelf-trail,
  .atlas-shelf-close, .trail-item-link, .trail-pager-move, .trail-atlas,
  .reader-back, .trail-back, .reader-trail-name, .reader-trail-move,
  .reader-watch, .reader-tab, .reader-source,
  .chat-config-summary, .chat-config-form input, .predicted-q-btn, .chat-cite,
  .chat-input, .cue, button.cue, a.cue, .conn,
  .watch-close, .pip-expand, .pip-close,
  .account-button, .account-menu-item,
  .masthead nav a, .legacy-link, .skip, .wordmark
) {
  transition:
    color var(--dur-fast) var(--ease),
    background-color var(--dur-fast) var(--ease),
    border-color var(--dur-fast) var(--ease),
    transform var(--dur-fast) var(--ease);
}

:is(
  .card-watch, .card-save, .reader-save, .card-remove,
  .index-search, .index-select,
  .clear-arm, .clear-keep, .clear-confirm-button, .view-note-retry,
  .panel-action, .atlas-node, .atlas-guide-node, .atlas-shelf-trail,
  .atlas-shelf-close, .trail-item-link, .trail-pager-move, .trail-atlas,
  .reader-back, .trail-back, .reader-trail-name, .reader-trail-move,
  .reader-watch, .reader-tab, .reader-source,
  .chat-config-summary, .chat-config-form input, .predicted-q-btn, .chat-cite,
  .chat-input, .cue, button.cue, a.cue, .conn,
  .watch-close, .pip-expand, .pip-close,
  .account-button, .account-menu-item,
  .masthead nav a, .legacy-link, .skip, .wordmark
):hover {
  background-color: var(--paper-3);
}

:is(
  .card-watch, .card-save, .reader-save, .card-remove,
  .index-search, .index-select,
  .clear-arm, .clear-keep, .clear-confirm-button, .view-note-retry,
  .panel-action, .atlas-node, .atlas-guide-node, .atlas-shelf-trail,
  .atlas-shelf-close, .trail-item-link, .trail-pager-move, .trail-atlas,
  .reader-back, .trail-back, .reader-trail-name, .reader-trail-move,
  .reader-watch, .reader-tab, .reader-source,
  .chat-config-summary, .chat-config-form input, .predicted-q-btn, .chat-cite,
  .chat-input, .cue, button.cue, a.cue, .conn,
  .watch-close, .pip-expand, .pip-close,
  .account-button, .account-menu-item,
  .masthead nav a, .legacy-link, .skip, .wordmark
):focus-visible {
  outline: var(--rule-strong) solid var(--focus);
  outline-offset: 2px;
}

:is(
  .card-watch, .card-save, .reader-save, .card-remove,
  .index-search, .index-select,
  .clear-arm, .clear-keep, .clear-confirm-button, .view-note-retry,
  .panel-action, .atlas-node, .atlas-guide-node, .atlas-shelf-trail,
  .atlas-shelf-close, .trail-item-link, .trail-pager-move, .trail-atlas,
  .reader-back, .trail-back, .reader-trail-name, .reader-trail-move,
  .reader-watch, .reader-tab, .reader-source,
  .chat-config-summary, .chat-config-form input, .predicted-q-btn, .chat-cite,
  .chat-input, .cue, button.cue, a.cue, .conn,
  .watch-close, .pip-expand, .pip-close,
  .account-button, .account-menu-item,
  .masthead nav a, .legacy-link, .skip, .wordmark
):active {
  color: var(--accent-2);
  transform: translateY(1px);
}

:is(
  .card-watch, .card-save, .reader-save, .card-remove,
  .index-search, .index-select,
  .clear-arm, .clear-keep, .clear-confirm-button, .view-note-retry,
  .panel-action, .atlas-node, .atlas-guide-node, .atlas-shelf-trail,
  .atlas-shelf-close, .trail-item-link, .trail-pager-move, .trail-atlas,
  .reader-back, .trail-back, .reader-trail-name, .reader-trail-move,
  .reader-watch, .reader-tab, .reader-source,
  .chat-config-summary, .chat-config-form input, .predicted-q-btn, .chat-cite,
  .chat-input, .cue, button.cue, a.cue, .conn,
  .watch-close, .pip-expand, .pip-close,
  .account-button, .account-menu-item,
  .masthead nav a, .legacy-link, .skip, .wordmark
):disabled,
:is(
  .card-watch, .card-save, .reader-save, .card-remove,
  .index-search, .index-select,
  .clear-arm, .clear-keep, .clear-confirm-button, .view-note-retry,
  .panel-action, .atlas-node, .atlas-guide-node, .atlas-shelf-trail,
  .atlas-shelf-close, .trail-item-link, .trail-pager-move, .trail-atlas,
  .reader-back, .trail-back, .reader-trail-name, .reader-trail-move,
  .reader-watch, .reader-tab, .reader-source,
  .chat-config-summary, .chat-config-form input, .predicted-q-btn, .chat-cite,
  .chat-input, .cue, button.cue, a.cue, .conn,
  .watch-close, .pip-expand, .pip-close,
  .account-button, .account-menu-item,
  .masthead nav a, .legacy-link, .skip, .wordmark
)[aria-disabled='true'] {
  color: var(--ink-3);
  opacity: var(--state-disabled);
  cursor: not-allowed;
  pointer-events: none;
}

:is(
  .card-watch, .card-save, .reader-save, .card-remove,
  .index-search, .index-select,
  .clear-arm, .clear-keep, .clear-confirm-button, .view-note-retry,
  .panel-action, .atlas-node, .atlas-guide-node, .atlas-shelf-trail,
  .atlas-shelf-close, .trail-item-link, .trail-pager-move, .trail-atlas,
  .reader-back, .trail-back, .reader-trail-name, .reader-trail-move,
  .reader-watch, .reader-tab, .reader-source,
  .chat-config-summary, .chat-config-form input, .predicted-q-btn, .chat-cite,
  .chat-input, .cue, button.cue, a.cue, .conn,
  .watch-close, .pip-expand, .pip-close,
  .account-button, .account-menu-item,
  .masthead nav a, .legacy-link, .skip, .wordmark
)[aria-busy='true'],
:is(
  .card-watch, .card-save, .reader-save, .card-remove,
  .index-search, .index-select,
  .clear-arm, .clear-keep, .clear-confirm-button, .view-note-retry,
  .panel-action, .atlas-node, .atlas-guide-node, .atlas-shelf-trail,
  .atlas-shelf-close, .trail-item-link, .trail-pager-move, .trail-atlas,
  .reader-back, .trail-back, .reader-trail-name, .reader-trail-move,
  .reader-watch, .reader-tab, .reader-source,
  .chat-config-summary, .chat-config-form input, .predicted-q-btn, .chat-cite,
  .chat-input, .cue, button.cue, a.cue, .conn,
  .watch-close, .pip-expand, .pip-close,
  .account-button, .account-menu-item,
  .masthead nav a, .legacy-link, .skip, .wordmark
).is-loading {
  color: transparent;
  background-color: var(--paper-3);
  border-radius: var(--radius-1);
  cursor: progress;
}

/* --- First-paint chrome ----------------------------------------------------
   index.html carries the above-the-fold rules for the masthead, the skeleton
   grid, and the colophon; this sheet restates them in D2 tokens so the chrome
   reads light and warm once the full sheet lands. */
body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font: var(--weight-regular) var(--text-base)/var(--leading-body) var(--font-sans);
  -webkit-font-smoothing: antialiased;
}

a { color: inherit; text-decoration: none; }

a:focus-visible,
button:focus-visible {
  outline: var(--rule-strong) solid var(--focus);
  outline-offset: 2px;
}

.skip {
  position: absolute;
  top: calc(-1 * var(--space-8));
  left: var(--space-5);
  padding: var(--space-3);
  background: var(--paper-2);
  border: var(--rule-hairline) solid var(--line);
  border-radius: var(--radius-1);
  z-index: 50;
}

.skip:focus { top: var(--space-3); }

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
}

.masthead {
  display: flex;
  align-items: center;
  gap: var(--space-6);
  min-height: var(--space-8);
  padding: var(--space-2) var(--space-5);
  border-bottom: 3px solid var(--board);
  background: var(--paper);
}

.wordmark {
  display: inline-flex;
  flex-direction: column;
  justify-content: center;
  min-height: var(--target-primary);
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-1);
  font-family: var(--font-serif);
  font-size: var(--text-lg);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-tight);
  color: var(--ink);
  white-space: nowrap;
}

.wordmark-note {
  display: block;
  font-family: var(--font-sans);
  font-size: var(--text-xs);
  font-weight: var(--weight-regular);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--ink-3);
  margin-top: var(--space-1);
}

.masthead nav {
  position: relative;
  display: flex;
  gap: var(--space-5);
  flex-wrap: wrap;
}

.nav-ink {
  position: absolute;
  left: 0;
  bottom: 6px;
  height: 2px;
  width: 24px;
  background: var(--accent);
  opacity: 0;
  pointer-events: none;
  transform: translateX(0);
  transition:
    transform var(--dur-base) var(--ease),
    width var(--dur-base) var(--ease),
    opacity var(--dur-fast) var(--ease);
}

.masthead nav a {
  display: inline-flex;
  align-items: center;
  min-height: var(--target-primary);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-1);
  font-size: var(--text-sm);
  color: var(--ink-2);
}

.masthead nav a[aria-current='page'] {
  color: var(--accent);
  font-weight: var(--weight-medium);
}

.legacy-link {
  display: inline-flex;
  align-items: center;
  min-height: var(--target-min);
  margin-left: auto;
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-1);
  font-size: var(--text-xs);
  color: var(--ink-3);
}

main {
  max-width: 1160px;
  margin: 0 auto;
  padding: var(--space-7) var(--space-6) var(--space-8);
}

.colophon {
  display: flex;
  justify-content: space-between;
  gap: var(--space-5);
  flex-wrap: wrap;
  border-top: var(--rule-hairline) solid var(--line);
  padding: var(--space-5) var(--space-6);
  font-size: var(--text-xs);
  color: var(--ink-3);
}

/* --- Page titles ----------------------------------------------------------- */
.page-title {
  font-family: var(--font-serif);
  font-size: var(--text-display);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-tight);
  margin: 0 0 var(--space-7);
}

.page-title:focus { outline: none; }

/* --- The home grid: an editorial card grid ---------------------------------
   Cards are paper surfaces that breathe: --space-5 gaps, --radius-2 corners,
   a hairline --line, and one soft --shadow on hover. Hierarchy is type. */
.card-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-5);
}

.card {
  background: none;
  border: 0;
  border-radius: 0;
  padding: 0;
  min-width: 0;
  transition:
    background-color var(--dur-fast) var(--ease),
    border-color var(--dur-fast) var(--ease),
    box-shadow var(--dur-base) var(--ease);
}

.card:hover .card-eyebrow,
.card:focus-within .card-eyebrow {
  box-shadow: 0 1px 0 0 var(--board);
}

.card--skeleton:hover,
.card--skeleton:focus-within {
  background: var(--paper-2);
  border-color: var(--line);
  box-shadow: none;
}

.card-eyebrow {
  display: flex;
  justify-content: space-between;
  gap: var(--space-3);
  align-items: baseline;
  margin: 0 0 var(--space-3);
  padding-bottom: var(--space-2);
  border-bottom: var(--rule-hairline) solid var(--line);
  font-family: var(--font-sans);
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-caps);
  color: var(--ink-3);
}

/* The rule row shrinks with its card: the caps text ellipsizes rather than
   pushing the duration stamp over the neighbouring card. */
.card-eyebrow { min-width: 0; }

.card-eyebrow-text { overflow-wrap: anywhere; min-width: 0; overflow: hidden; text-overflow: ellipsis; }

.card-eyebrow .card-duration {
  flex: none;
  color: var(--ink);
  letter-spacing: 0;
  font-variant-numeric: tabular-nums;
}

.card-stamp {
  flex: none;
  border: 1px solid var(--accent);
  border-radius: 2px;
  color: var(--accent);
  padding: 1px 6px;
  letter-spacing: var(--tracking-caps);
}

.card-title {
  margin: 0 0 var(--space-3);
  font-family: var(--font-serif);
  font-size: var(--text-lg);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-tight);
  overflow-wrap: anywhere;
}

/* The title link is the card's single keyboard entry point, in DOM order.
   T-320: it carries the card's whole face — the thumbnail above the title —
   so one target opens the reader from either. */
.card-link {
  display: block;
  border-radius: var(--radius-1);
  transition: color var(--dur-fast) var(--ease);
}

.card-link:hover {
  color: var(--accent-2);
  text-decoration: underline;
  text-decoration-thickness: var(--rule-hairline);
  text-underline-offset: var(--space-1);
}

.card-link:focus-visible {
  outline: var(--rule-strong) solid var(--focus);
  outline-offset: 2px;
}

.card-link:active {
  color: var(--accent-2);
  transform: translateY(1px);
}

.card-link[aria-disabled='true'] {
  color: var(--ink-3);
  opacity: var(--state-disabled);
  pointer-events: none;
}

.card-link[aria-busy='true'],
.card-link.is-loading {
  color: transparent;
  background-color: var(--paper-3);
  border-radius: var(--radius-1);
  cursor: progress;
}

.card-byline {
  margin: 0 0 var(--space-3);
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  color: var(--ink-3);
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  overflow-wrap: anywhere;
}

/* Duration reads as plain tabular meta inside the byline — no boxed chip. */
.card-duration {
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  font-variant-numeric: tabular-nums;
  color: var(--ink-2);
  white-space: nowrap;
}

.card-dot { color: var(--ink-3); }

/* Descriptions are the one long-form moment on the grid: serif, relaxed. */
.card-desc {
  margin: 0;
  font-family: var(--font-serif);
  font-size: var(--text-base);
  line-height: var(--leading-body);
  color: var(--ink-2);
  max-width: var(--measure-tight);
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
  overflow-wrap: anywhere;
}

/* The card's action row: the watch affordance (T-011) and the save
   affordance (T-322) share one baseline — quiet text controls, the accent
   arriving on hover/focus, per the one-accent rule. */
.card-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3) var(--space-4);
  margin: 0 0 var(--space-3);
}

/* Watch is the card's primary action: a one-click play, so it holds the
   44px target. */
.card-watch {
  display: inline-flex;
  align-items: center;
  min-height: var(--target-primary);
  min-width: var(--target-primary);
  margin: 0;
  padding: var(--space-1) var(--space-2);
  border: 0;
  border-radius: var(--radius-1);
  background: none;
  cursor: pointer;
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  color: var(--ink-2);
}

.card-watch:hover,
.card-watch:focus-visible { color: var(--accent-2); }

/* The save affordance (T-322): a star toggle on every card. Filled (★) and
   accent when the piece is saved — the accent marks state, never decoration;
   open (☆) and muted while it is not. */
.card-save,
.reader-save {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  min-height: var(--target-min);
  min-width: var(--target-min);
  padding: var(--space-1) var(--space-2);
  border: 0;
  border-radius: var(--radius-1);
  background: none;
  cursor: pointer;
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  color: var(--ink-2);
}

.save-star {
  font-size: var(--text-base);
  line-height: var(--leading-tight);
}

.card-save:hover,
.card-save:focus-visible,
.reader-save:hover,
.reader-save:focus-visible { color: var(--accent-2); }

.card-save[aria-pressed='true'],
.reader-save[aria-pressed='true'] { color: var(--accent); }

.card-save[aria-pressed='true']:hover,
.card-save[aria-pressed='true']:focus-visible,
.reader-save[aria-pressed='true']:hover,
.reader-save[aria-pressed='true']:focus-visible { color: var(--accent-2); }

/* --- Image previews (T-320): the thumbnail grammar --------------------------
   A sized 16:9 box on every card-carrying surface, in the tokens' language:
   the inset-paper ground is the skeleton while the lazy image loads and
   stays as the designed fallback tile (the title's initial) for items with
   no video_id and no thumbnail, or whose frame fails to load — never a
   broken frame. Lazy loading plus the fixed aspect reserve the space, so
   nothing shifts when bytes arrive (B2/B3); the image fills the box, cropped
   to cover (hqdefault is 4:3 with letterbox bars). The 96px trail row and
   the reader header's clamp are layout constants, like the watch stage's. */
.card-thumb,
.trail-thumb,
.reader-thumb {
  display: block;
  aspect-ratio: 16 / 9;
  background: var(--paper-3);
  border-radius: var(--radius-1);
  overflow: hidden;
}

.thumb-img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.thumb-fallback {
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  aspect-ratio: 16 / 9;
  border: 1px solid var(--line);
  background: var(--paper);
}

.thumb-cover-title {
  flex: 1;
  display: flex;
  align-items: center;
  padding: var(--space-4) var(--space-3);
  font-family: var(--font-serif);
  font-size: var(--text-lg);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-tight);
  overflow-wrap: anywhere;
}

.thumb-cover-src {
  padding: var(--space-2) var(--space-3);
  border-top: var(--rule-hairline) solid var(--line);
  font-size: var(--text-xs);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--ink-3);
}

.card-thumb { margin-bottom: var(--space-4); }

/* The skeleton's matching box: the first-paint grid holds the same shape the
   loaded cards will, so the swap shifts nothing (B3 + CLS). */
.card--skeleton .sk-thumb {
  width: 100%;
  aspect-ratio: 16 / 9;
  margin-bottom: var(--space-4);
}

/* Trail rows: the small preview sits left of the row's text, spanning its
   heading and meta; the ordered list's own markers are untouched. */
.trail-item-body {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  column-gap: var(--space-4);
  align-items: start;
}

.trail-thumb {
  grid-row: 1 / span 2;
  width: 96px; /* layout constant: the trail row's small preview */
}

/* The reader header: the text column in column one, the small preview
   riding beside it in its own column, top-aligned with the eyebrow. */
.reader-head {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  column-gap: var(--space-6);
  align-items: start;
}

.reader-thumb {
  width: clamp(140px, 22vw, 240px); /* layout constant: the header preview */
}

/* The loading header has no preview to pair with: its skeleton lines stack. */
.reader-head--skeleton { grid-template-columns: 1fr; }

/* --- The home tools (T-321): search, subject, sort --------------------------
   One hairline-ruled row of native controls above the grid — paper fields with
   a hairline --line and --radius-1 corners, tracked caps labels — with the
   result count riding the row's right edge. The 260px search basis is a layout
   constant, like the grid's own column rhythm. */
.index-tools {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--space-4) var(--space-6);
  margin: 0 0 var(--space-6);
  padding: var(--space-4) 0;
  border-top: var(--rule-hairline) solid var(--line);
  border-bottom: var(--rule-hairline) solid var(--line);
}

.index-field {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  min-width: 0;
}

.index-field--search { flex: 1 1 260px; }

.index-field-label {
  font-family: var(--font-sans);
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--ink-3);
}

.index-search,
.index-select {
  width: 100%;
  min-height: var(--target-primary);
  padding: var(--space-2) var(--space-3);
  border: var(--rule-hairline) solid var(--line);
  border-radius: var(--radius-1);
  background: var(--paper-2);
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: var(--text-base);
  color-scheme: light; /* the native pickers and the search's clear control read on the paper */
}

.index-search::placeholder { color: var(--ink-3); }

.index-search:focus-visible,
.index-select:focus-visible { border-color: var(--focus); }

.index-count {
  margin: 0 0 var(--space-1);
  margin-left: auto;
  align-self: flex-end;
  font-family: var(--font-sans);
  font-size: var(--text-xs);
  font-variant-numeric: tabular-nums;
  color: var(--ink-3);
  white-space: nowrap;
}

/* --- The personal surfaces (T-322 collection, T-323 history) ----------------
   #/collection and #/history ride the classic localStorage contracts in the
   shell's grammar: a hairline-ruled header row carrying the count and the
   confirm-then-clear control, cards in the home grid's own anatomy, one
   quiet tracked-caps "Watched X ago" line on history cards, and a designed
   note — never a hidden view — when the enrichment fetch fails. */

.view-row {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3) var(--space-5);
  margin: 0 0 var(--space-6);
  padding: var(--space-4) 0;
  border-top: var(--rule-hairline) solid var(--line);
  border-bottom: var(--rule-hairline) solid var(--line);
}

.view-count {
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--text-xs);
  font-variant-numeric: tabular-nums;
  color: var(--ink-3);
  white-space: nowrap;
}

/* Destructive clears confirm in place: the armed question, the confirm
   control carrying the accent, and the keep control standing down. */
.clear-control,
.clear-confirm {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
}

.clear-control { gap: var(--space-3) var(--space-4); }
.clear-confirm { gap: var(--space-2) var(--space-3); }

/* The flex display would override the hidden attribute's display:none —
   stand-down must actually hide the bar. */
.clear-confirm[hidden] { display: none; }

.clear-question {
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  color: var(--ink-2);
}

.clear-arm,
.clear-confirm-button,
.clear-keep {
  min-height: var(--target-min);
  padding: var(--space-1) var(--space-2);
  border: 0;
  border-bottom: var(--rule-hairline) solid transparent;
  border-radius: var(--radius-1);
  background: none;
  cursor: pointer;
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  color: var(--ink-3);
}

.clear-arm:hover,
.clear-keep:hover,
.clear-arm:focus-visible,
.clear-keep:focus-visible { color: var(--ink); border-bottom-color: var(--ink-3); }

.clear-confirm-button { color: var(--accent); }

.clear-confirm-button:hover,
.clear-confirm-button:focus-visible { color: var(--accent-2); border-bottom-color: var(--accent); }

/* One quiet line naming when the piece was watched. */
.card-watched {
  margin: 0 0 var(--space-3);
  font-family: var(--font-sans);
  font-size: var(--text-xs);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--ink-3);
}

/* The history card's own remove affordance, in the action row's grammar. */
.card-remove {
  display: inline-flex;
  align-items: center;
  min-height: var(--target-min);
  min-width: var(--target-min);
  padding: var(--space-1) var(--space-2);
  border: 0;
  border-radius: var(--radius-1);
  background: none;
  cursor: pointer;
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  color: var(--ink-3);
}

.card-remove:hover,
.card-remove:focus-visible { color: var(--accent-2); }

/* The inventory note: enrichment failing never hides the user's own data —
   a designed line and an inline retry carry the view. */
.view-note {
  margin: 0 0 var(--space-6);
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  color: var(--ink-2);
}

.view-note-retry {
  min-height: var(--target-min);
  padding: var(--space-1) var(--space-2);
  border: 0;
  border-bottom: var(--rule-hairline) solid transparent;
  border-radius: var(--radius-1);
  background: none;
  cursor: pointer;
  font: inherit;
  color: var(--ink);
}

.view-note-retry:hover,
.view-note-retry:focus-visible { color: var(--accent-2); border-bottom-color: var(--ink-3); }

/* --- Designed panels: arriving placeholders and the feed failure state ---- */
.panel {
  background: var(--paper-2);
  border: var(--rule-hairline) solid var(--line);
  border-left: var(--rule-strong) solid var(--accent);
  border-radius: var(--radius-2);
  padding: var(--space-7) var(--space-6) var(--space-6);
  max-width: var(--measure-wide);
  margin: var(--space-7) 0;
}

.panel-kicker {
  margin: 0 0 var(--space-4);
  font-family: var(--font-sans);
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--ink-3);
}

.panel-title {
  margin: 0 0 var(--space-3);
  font-family: var(--font-serif);
  font-size: var(--text-xl);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-tight);
}

.panel-title:focus { outline: none; }

.panel-copy {
  margin: 0 0 var(--space-5);
  font-family: var(--font-serif);
  font-size: var(--text-base);
  line-height: var(--leading-body);
  color: var(--ink-2);
  max-width: var(--measure);
}

.panel-note {
  margin: var(--space-4) 0 0;
  font-family: var(--font-sans);
  font-size: var(--text-xs);
  line-height: var(--leading-body);
  color: var(--ink-3);
}

/* The panel's primary action: a 44px target, paper at rest, the accent on
   press. */
.panel-action {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: var(--target-primary);
  min-width: var(--target-primary);
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  padding: var(--space-3) var(--space-5);
  border: var(--rule-hairline) solid var(--ink-3);
  border-radius: var(--radius-1);
  cursor: pointer;
  background: none;
  color: var(--ink);
}

.panel-action:hover {
  background: var(--paper-3);
  border-color: var(--ink-2);
  color: var(--ink);
}

.panel-action:active {
  background: var(--accent-2);
  border-color: var(--accent-2);
  color: var(--paper);
}

.panel--failure { border-left-color: var(--error); }
.panel--arriving { border-left-color: var(--accent); }

/* --- The atlas (T-004): subjects charted from collection.json -------------
   Spatial chart + field guide + shelf. Structure stays hairlines and type;
   the one accent is spent on interaction and selection state only.
   Shape literals here (the 1160/840 canvas aspect, the 50% round node, the
   0.1724cqw canvas-unit scale, the 900px swap) are layout constants that
   pair with the layout math in app.mjs; everything else is tokens. */
.atlas-standfirst {
  margin: calc(-1 * var(--space-4)) 0 var(--space-2);
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  color: var(--ink-2);
}

.atlas-hint {
  margin: 0 0 var(--space-7);
  font-family: var(--font-sans);
  font-size: var(--text-xs);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--ink-3);
}

/* SVG hairline edges sit beneath the sector flow; both address the same
   1160×840 unit canvas (edges in viewBox units, sectors in percentages). */
.atlas-chart {
  position: relative;
  aspect-ratio: 1160 / 840;
  container-type: inline-size;
}

.atlas-edges {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

.atlas-edge { stroke: var(--line); stroke-width: 1.1; }
.atlas-edge--primary { stroke: var(--ink-3); }

.atlas-node {
  cursor: pointer;
  background: none;
  border: 0;
  border-radius: var(--radius-1);
  padding: var(--space-1) var(--space-2);
  font: inherit;
  color: var(--ink);
}

/* Sector boxes come from the treemap (percent boxes set by app.mjs); their
   content is normal flow — the hub, then the field's satellites filed into
   columns — so labels at real px size cannot overlap. */
.atlas-sector {
  position: absolute;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  min-width: 0;
  padding-top: var(--space-2);
}

.atlas-orbits {
  columns: var(--cols, 1);
  column-gap: var(--space-6);
  margin: 0;
  padding: 0;
  list-style: none;
}

.atlas-orbits li {
  break-inside: avoid;
  padding: var(--space-1) 0;
}

/* Nodes read dot-first; the label takes the room left in its column and
   wraps within it; the count rides to the column's right edge. */
.atlas-node--sat,
.atlas-node--hub {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  width: 100%;
  text-align: left;
}

/* Node dots scale with the canvas (1 canvas unit = 0.0862cqw; --dot carries
   the unit radius set per node in app.mjs). */
.atlas-dot {
  flex: none;
  width: calc(var(--dot, 4) * 0.1724cqw);
  height: calc(var(--dot, 4) * 0.1724cqw);
  border-radius: 50%;
  background: var(--ink-2);
  transition: background-color var(--dur-fast) var(--ease);
}

.atlas-dot--hub { background: var(--ink); }

.atlas-label {
  flex: 1;
  min-width: 0;
  overflow-wrap: anywhere;
  font-family: var(--font-sans);
  font-size: var(--text-xs);
  line-height: var(--leading-tight);
  color: var(--ink-2);
  transition: color var(--dur-fast) var(--ease);
}

/* Density handling: large topics promote one type step and full ink. */
.atlas-node--major .atlas-label {
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--ink);
}

.atlas-count {
  flex: none;
  font-family: var(--font-sans);
  font-size: var(--text-xs);
  font-variant-numeric: tabular-nums;
  color: var(--ink-3);
  transition: color var(--dur-fast) var(--ease);
}

.atlas-node--hub .atlas-hub-name {
  font-family: var(--font-serif);
  font-size: var(--text-base);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-tight);
  line-height: var(--leading-tight);
  color: var(--ink);
  transition: color var(--dur-fast) var(--ease);
}

.atlas-node:hover .atlas-label,
.atlas-node:hover .atlas-hub-name { color: var(--accent-2); }

.atlas-node[aria-pressed='true'] .atlas-label,
.atlas-node[aria-pressed='true'] .atlas-hub-name,
.atlas-node[aria-pressed='true'] .atlas-count { color: var(--accent); }

.atlas-node[aria-pressed='true'] .atlas-dot { background: var(--accent); }

/* Selection focus (T-005): the selected subject holds the accent; its related
   subjects keep full ink and its own edges take the accent hairline, while
   the rest of the chart recedes to muted ink. Class-driven state riding the
   same fast motion token as every other state change (instant under
   prefers-reduced-motion). The guide — a document, not a chart — carries the
   positive half only: related subjects keep full ink, nothing hides. */
.atlas-node.is-related .atlas-label,
.atlas-node.is-related .atlas-hub-name { color: var(--ink); }

.atlas-node.is-related .atlas-dot { background: var(--ink); }

.atlas-edge {
  transition:
    stroke var(--dur-fast) var(--ease),
    stroke-width var(--dur-fast) var(--ease);
}

.atlas-edge--active { stroke: var(--accent); stroke-width: 1.4; }

.atlas-chart[data-selected] .atlas-node:not(.is-selected):not(.is-related) .atlas-label,
.atlas-chart[data-selected] .atlas-node:not(.is-selected):not(.is-related) .atlas-hub-name,
.atlas-chart[data-selected] .atlas-node:not(.is-selected):not(.is-related) .atlas-count { color: var(--ink-3); }

.atlas-chart[data-selected] .atlas-node:not(.is-selected):not(.is-related) .atlas-dot { background: var(--ink-3); }

.atlas-chart[data-selected] .atlas-edge:not(.atlas-edge--active) { stroke: var(--line); }

.atlas-guide-node.is-related { color: var(--ink); }

/* Field guide — the documented small-viewport treatment: below the shell's
   900px breakpoint a spatial chart cannot hold ~75 legible labels, so the
   same subject model renders as a document. Every subject stays a labeled,
   focusable, operable node; nothing scrolls sideways. */
.atlas-guide { display: none; }

@media (max-width: 900px) {
  .atlas-chart { display: none; }
  .atlas-guide { display: block; }
}

.atlas-guide-field {
  padding: var(--space-5) 0;
  border-bottom: var(--rule-hairline) solid var(--line);
}

.atlas-guide-field:first-child { padding-top: 0; }

.atlas-guide-head { margin: 0 0 var(--space-3); }

.atlas-guide-list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-5);
  margin: 0;
  padding: 0;
  list-style: none;
}

.atlas-guide-node {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  min-height: var(--target-min);
  padding: var(--space-1) var(--space-2);
  cursor: pointer;
  background: none;
  border: 0;
  border-bottom: var(--rule-hairline) solid transparent;
  border-radius: var(--radius-1);
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  color: var(--ink-2);
}

.atlas-guide-node--field .atlas-guide-name {
  font-family: var(--font-serif);
  font-size: var(--text-lg);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-tight);
  color: var(--ink);
}

.atlas-guide-node:hover { color: var(--accent-2); border-bottom-color: var(--accent); }

.atlas-guide-node[aria-pressed='true'] { color: var(--accent); border-bottom-color: var(--accent); }

.atlas-guide-node[aria-pressed='true'] .atlas-guide-name { color: var(--accent); }

.atlas-guide-empty {
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--text-xs);
  color: var(--ink-3);
}

/* The shelf — the selected subject's entries below the chart/guide. */
.atlas-shelf {
  margin-top: var(--space-7);
  padding-top: var(--space-5);
  border-top: var(--rule-strong) solid var(--ink-3);
  scroll-margin-top: var(--space-5);
}

.atlas-shelf-title {
  margin: 0 0 var(--space-2);
  font-family: var(--font-serif);
  font-size: var(--text-xl);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-tight);
  line-height: var(--leading-tight);
}

.atlas-shelf-title:focus { outline: none; }

.atlas-shelf-meta {
  margin: 0 0 var(--space-5);
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  color: var(--ink-3);
}

.atlas-shelf-trail {
  display: inline-flex;
  align-items: center;
  min-height: var(--target-min);
  margin: calc(-1 * var(--space-4)) 0 var(--space-4);
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-1);
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  color: var(--accent);
}

.atlas-shelf-trail:hover { color: var(--accent-2); }

.atlas-shelf-note {
  margin: calc(-1 * var(--space-4)) 0 var(--space-5);
  font-family: var(--font-sans);
  font-size: var(--text-xs);
  color: var(--ink-3);
}

.atlas-shelf-grid { margin-bottom: var(--space-3); }

.atlas-shelf-more {
  margin: 0 0 var(--space-4);
  font-family: var(--font-sans);
  font-size: var(--text-xs);
  color: var(--ink-3);
}

.atlas-shelf-close {
  min-height: var(--target-min);
  padding: var(--space-1) var(--space-2);
  cursor: pointer;
  background: none;
  border: 0;
  border-bottom: var(--rule-hairline) solid transparent;
  border-radius: var(--radius-1);
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  color: var(--ink-3);
}

.atlas-shelf-close:hover { color: var(--ink); border-bottom-color: var(--ink-3); }

/* Chart skeleton: static inset-paper blocks in the composition's own shape
   (B3 — skeleton, never a spinner). */
.atlas-skeleton-wrap .atlas-standfirst .sk {
  display: inline-block;
  width: 42%;
  height: var(--space-3);
  background: var(--paper-3);
  border-radius: var(--radius-1);
}

.atlas-skeleton {
  position: relative;
  aspect-ratio: 1160 / 840;
  margin-top: var(--space-5);
}

.atlas-skeleton .sk {
  position: absolute;
  background: var(--paper-3);
  border-radius: var(--radius-1);
}

/* --- The learning paths (T-006): curated subject reading paths --------------
   One section per subject; hairline-separated rows, serif titles, tabular
   meta. Long paths page — each path mounts at most one page of rows
   (TRAIL_PAGE in app.mjs) — and the pager is text-only, like the atlas
   shelf controls. Structure stays hairlines and type; the accent is spent on
   interaction only. */
.trail-standfirst {
  margin: calc(-1 * var(--space-4)) 0 var(--space-2);
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  color: var(--ink-2);
}

.trail-hint {
  margin: 0 0 var(--space-7);
  font-family: var(--font-sans);
  font-size: var(--text-xs);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--ink-3);
}

.trail-section {
  padding: var(--space-6) 0;
  border-top: var(--rule-hairline) solid var(--line);
  scroll-margin-top: var(--space-5); /* a fragment landing on a section clears the page edge */
}

.trail-section:first-child { padding-top: 0; border-top: 0; }

.trail-title {
  margin: 0 0 var(--space-2);
  font-family: var(--font-serif);
  font-size: var(--text-xl);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-tight);
  overflow-wrap: anywhere;
}

.trail-meta {
  margin: 0 0 var(--space-4);
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  color: var(--ink-3);
}

/* The ordered list keeps the sequence's own numbering; markers are sans meta. */
.trail-items {
  margin: 0;
  padding: 0 0 0 var(--space-6);
  list-style: decimal;
}

.trail-item {
  padding: var(--space-3) 0;
  border-top: var(--rule-hairline) solid var(--line);
}

.trail-item:first-child { padding-top: 0; border-top: 0; }

.trail-item::marker {
  font-family: var(--font-sans);
  font-size: var(--text-xs);
  font-variant-numeric: tabular-nums;
  color: var(--ink-3);
}

.trail-item-title {
  margin: 0 0 var(--space-1);
  font-family: var(--font-serif);
  font-size: var(--text-base);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-tight);
  overflow-wrap: anywhere;
}

.trail-item-link {
  display: inline-block;
  min-height: var(--target-min);
  border-radius: var(--radius-1);
  transition: color var(--dur-fast) var(--ease);
}

.trail-item-link:hover {
  color: var(--accent-2);
  text-decoration: underline;
  text-decoration-thickness: var(--rule-hairline);
  text-underline-offset: var(--space-1);
}

.trail-item:focus-within { border-top-color: var(--accent); }

.trail-item-meta {
  margin: 0;
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  color: var(--ink-3);
  overflow-wrap: anywhere;
}

.trail-item-duration {
  font-variant-numeric: tabular-nums;
  color: var(--ink-2);
  white-space: nowrap;
}

/* The deep path route's per-row place in the whole sequence ("3 of 47"). */
.trail-item-pos {
  font-variant-numeric: tabular-nums;
  color: var(--ink-2);
  white-space: nowrap;
}

/* The entry a reader left the path from — the visible "you are here" of the
   resumed place (T-007): the sequence's own marker takes the accent. */
.trail-item--current { border-top-color: var(--accent); }
.trail-item--current:first-child { border-top: 0; }
.trail-item--current::marker { color: var(--accent); }

/* Pager — text controls; the position line is tabular meta, never a chip. */
.trail-pager {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  margin-top: var(--space-3);
}

.trail-pager-move {
  min-height: var(--target-min);
  padding: var(--space-1) var(--space-2);
  cursor: pointer;
  background: none;
  border: 0;
  border-bottom: var(--rule-hairline) solid transparent;
  border-radius: var(--radius-1);
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  color: var(--ink-3);
}

.trail-pager-move:hover { color: var(--ink); border-bottom-color: var(--ink-3); }

.trail-pager-move:disabled,
.trail-pager-move:disabled:hover {
  color: var(--ink-3);
  opacity: var(--state-disabled);
  border-bottom-color: transparent;
  cursor: not-allowed;
}

.trail-pager-part {
  font-family: var(--font-sans);
  font-size: var(--text-xs);
  font-variant-numeric: tabular-nums;
  color: var(--ink-3);
}

/* The deep path route's return cross-link to its atlas subject (T-007) —
   the same quiet machinery as the pager controls. */
.trail-atlas {
  display: inline-flex;
  align-items: center;
  min-height: var(--target-min);
  margin: 0 0 var(--space-6);
  padding: var(--space-1) var(--space-2);
  border-bottom: var(--rule-hairline) solid transparent;
  border-radius: var(--radius-1);
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  color: var(--ink-3);
}

.trail-atlas:hover { color: var(--ink); border-bottom-color: var(--ink-3); }

/* Path skeleton: inset-paper blocks in the path composition's own shape
   (B3 — skeleton, never a spinner). */
.trail-skeleton .sk {
  display: block;
  height: var(--space-3);
  margin: 0 0 var(--space-2);
  background: var(--paper-3);
  border-radius: var(--radius-1);
}

.trail-skeleton-block {
  padding: var(--space-6) 0;
  border-top: var(--rule-hairline) solid var(--line);
}

.trail-skeleton-block:first-child { padding-top: 0; border-top: 0; }

.trail-skeleton .trail-sk-title { height: var(--text-xl); width: 34%; margin-bottom: var(--space-3); }
.trail-skeleton .trail-sk-meta { width: 24%; margin-bottom: var(--space-4); }
.trail-skeleton .trail-sk-row:nth-child(odd) { width: 84%; }
.trail-skeleton .trail-sk-row:nth-child(even) { width: 68%; }

/* --- The reader (T-008): the five-tab reading surface -----------------------
   Briefing, chat, chapters, transcript, connections in fixed editorial
   order. Header and tab bar hold still while the active tab renders into
   one stable panel area (the 50vh floor keeps short panels from collapsing
   the composition), so switching tabs never shifts layout. Structure stays
   hairlines and type; the accent marks the selected tab and interaction only. */
.reader-back,
.trail-back {
  display: inline-flex;
  align-items: center;
  min-height: var(--target-min);
  margin: 0 0 var(--space-6);
  padding: var(--space-1) var(--space-2);
  border-bottom: var(--rule-hairline) solid transparent;
  border-radius: var(--radius-1);
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  color: var(--ink-3);
}

.reader-back:hover,
.trail-back:hover { color: var(--ink); border-bottom-color: var(--ink-3); }

.reader-eyebrow {
  margin: 0 0 var(--space-3);
  font-family: var(--font-sans);
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--ink-3);
  overflow-wrap: anywhere;
}

.reader-title {
  margin: 0 0 var(--space-3);
  max-width: var(--measure-wide);
  font-family: var(--font-serif);
  font-size: var(--text-display);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-tight);
  overflow-wrap: anywhere;
}

.reader-title:focus { outline: none; }

.reader-byline {
  margin: 0 0 var(--space-7);
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-2);
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  color: var(--ink-3);
  overflow-wrap: anywhere;
}

/* The path position line (T-007) sits in the stable header, so the place in
   the curated sequence is visible on every tab: the path's name reads as a
   quiet link back to its deep route, the position line is tabular meta, and
   the moves are the same text-only controls as the path pager. */
.reader-trail {
  margin: calc(-1 * var(--space-5)) 0 var(--space-6);
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-2) var(--space-3);
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  color: var(--ink-3);
  overflow-wrap: anywhere;
}

.reader-trail-name {
  min-height: var(--target-min);
  padding: var(--space-1) var(--space-2);
  color: var(--ink-2);
  border-bottom: var(--rule-hairline) solid transparent;
  border-radius: var(--radius-1);
}

.reader-trail-name:hover { color: var(--accent-2); border-bottom-color: var(--ink-3); }

.reader-trail-at {
  font-variant-numeric: tabular-nums;
  color: var(--ink-2);
  white-space: nowrap;
}

.reader-trail-moves {
  display: inline-flex;
  gap: var(--space-3);
}

.reader-trail-move {
  display: inline-flex;
  align-items: center;
  min-height: var(--target-min);
  padding: var(--space-1) var(--space-2);
  border-bottom: var(--rule-hairline) solid transparent;
  border-radius: var(--radius-1);
  color: var(--ink-3);
}

.reader-trail-move:hover { color: var(--ink); border-bottom-color: var(--ink-3); }

.reader-time {
  font-variant-numeric: tabular-nums;
  color: var(--ink-2);
  white-space: nowrap;
}

/* The header's action row (T-011 watch, T-322 save) sits in the stable
   reader header, so every tab offers it; the row pulls the byline's closing
   rhythm back in. */
.reader-watch-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3) var(--space-5);
  margin: calc(-1 * var(--space-5)) 0 var(--space-6);
}

/* Watch is the reader's primary action: a 44px target. */
.reader-watch {
  display: inline-flex;
  align-items: center;
  min-height: var(--target-primary);
  min-width: var(--target-primary);
  padding: var(--space-1) var(--space-2);
  border: 0;
  border-radius: var(--radius-1);
  background: none;
  cursor: pointer;
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  color: var(--ink-2);
}

.reader-watch:hover,
.reader-watch:focus-visible { color: var(--accent-2); }

/* Tab bar: one hairline rule; the selected tab carries the accent underline. */
.reader-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-6);
  border-bottom: var(--rule-hairline) solid var(--line);
}

.reader-tab {
  min-height: var(--target-primary);
  padding: var(--space-3) var(--space-2);
  border: 0;
  border-bottom: var(--rule-strong) solid transparent;
  margin-bottom: calc(-1 * var(--rule-hairline));
  border-radius: var(--radius-1) var(--radius-1) 0 0;
  background: none;
  cursor: pointer;
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  color: var(--ink-3);
}

.reader-tab:hover { color: var(--ink); }

.reader-tab[aria-selected='true'] { color: var(--accent); border-bottom-color: var(--accent); }

/* Panels: one stable container; each tab renders into its own panel. */
.reader-panels {
  min-height: 50vh; /* layout constant: keeps the composition still between tabs */
  padding-top: var(--space-6);
}

.reader-panel { max-width: var(--measure); }

.reader-panels .panel { margin: 0; }

.reader-section-title {
  margin: 0 0 var(--space-5);
  font-family: var(--font-serif);
  font-size: var(--text-xl);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-tight);
}

/* Briefing: the orientation view — serif lead, hairline-separated blocks. */
.reader-lead { max-width: var(--measure); margin: 0 0 var(--space-6); }

.reader-lead p {
  margin: 0 0 var(--space-4);
  font-family: var(--font-serif);
  font-size: var(--text-base);
  line-height: var(--leading-body);
  color: var(--ink-2);
  overflow-wrap: anywhere;
}

.reader-lead p:last-child { margin-bottom: 0; }

.reader-block {
  margin: 0 0 var(--space-6);
  padding-top: var(--space-5);
  border-top: var(--rule-hairline) solid var(--line);
}

.reader-block-title {
  margin: 0 0 var(--space-3);
  font-family: var(--font-sans);
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--ink-3);
}

.reader-reasons {
  margin: 0;
  padding-left: var(--space-5);
  font-family: var(--font-serif);
  font-size: var(--text-base);
  line-height: var(--leading-body);
  color: var(--ink-2);
}

.reader-reasons li { margin-bottom: var(--space-2); }
.reader-reasons li::marker { color: var(--ink-3); }

.reader-facts {
  margin: 0;
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: var(--space-2) var(--space-5);
  font-family: var(--font-sans);
  font-size: var(--text-sm);
}

.reader-facts dt { color: var(--ink-3); }
.reader-facts dd { margin: 0; color: var(--ink-2); overflow-wrap: anywhere; }

.reader-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3) var(--space-5);
  margin: 0 0 var(--space-6);
}

.reader-source {
  display: inline-flex;
  align-items: center;
  min-height: var(--target-min);
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-1);
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  color: var(--ink);
}

.reader-source:hover {
  color: var(--accent-2);
  text-decoration: underline;
  text-decoration-thickness: var(--rule-hairline);
  text-underline-offset: var(--space-1);
}

/* Chat: the live companion (T-325) — the classic panel's anatomy (config,
   predicted questions, the persisted log, the input) in the shell's grammar:
   hairline rules, type for hierarchy, the accent only where it interacts. */
.chat-config-details { margin: 0 0 var(--space-5); }

.chat-config-summary {
  display: inline-flex;
  align-items: center;
  width: max-content;
  min-height: var(--target-min);
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-1);
  cursor: pointer;
  font-family: var(--font-sans);
  font-size: var(--text-xs);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--ink-3);
}

.chat-config-summary:hover { color: var(--ink); }

.chat-config-form {
  display: grid;
  gap: var(--space-3);
  margin-top: var(--space-3);
  padding-top: var(--space-3);
  border-top: var(--rule-hairline) solid var(--line);
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  color: var(--ink-2);
}

.chat-config-form label { display: grid; gap: var(--space-1); }

.chat-config-form input {
  min-height: var(--target-min);
  background: var(--paper-2);
  border: var(--rule-hairline) solid var(--line);
  border-radius: var(--radius-1);
  color: var(--ink);
  font: inherit;
  padding: var(--space-1) var(--space-2);
}

.chat-config-form input:focus-visible { border-color: var(--focus); }

.chat-config-note {
  margin: 0;
  font-size: var(--text-xs);
  color: var(--ink-3);
  overflow-wrap: anywhere;
}

.predicted-questions { margin: 0 0 var(--space-5); }

.predicted-label {
  margin: 0 0 var(--space-3);
  font-family: var(--font-sans);
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--ink-3);
}

.predicted-list { border-top: var(--rule-hairline) solid var(--line); }

.predicted-q-btn {
  display: flex;
  align-items: center;
  width: 100%;
  min-height: var(--target-primary);
  text-align: left;
  border: 0;
  border-bottom: var(--rule-hairline) solid var(--line);
  border-radius: var(--radius-1);
  background: none;
  cursor: pointer;
  padding: var(--space-3) var(--space-2);
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  color: var(--ink-2);
}

.predicted-q-btn:hover { color: var(--accent-2); }

.loading-q {
  display: block;
  padding: var(--space-3) var(--space-2);
  border-bottom: var(--rule-hairline) solid var(--line);
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  color: var(--ink-3);
}

.chat-messages {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  max-height: min(56vh, 560px); /* layout constant: the log scrolls in its own measure */
  overflow-y: auto;
  border-top: var(--rule-hairline) solid var(--line);
  padding: var(--space-4) 0;
}

.chat-empty {
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  color: var(--ink-3);
}

/* The two voices: the reader's question in the machinery's sans, held to the
   right by its rule; the companion's answer in the reading voice, full and
   calm. */
.chat-bubble { max-width: 52ch; min-width: 0; }

.chat-bubble--user {
  align-self: flex-end;
  padding-right: var(--space-4);
  border-right: var(--rule-strong) solid var(--ink-3);
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  line-height: var(--leading-body);
  color: var(--ink);
  overflow-wrap: anywhere;
}

.chat-bubble--assistant {
  font-family: var(--font-serif);
  font-size: var(--text-base);
  line-height: var(--leading-body);
  color: var(--ink-2);
  overflow-wrap: anywhere;
}

.chat-bubble--pending { font-family: var(--font-sans); }

.chat-dots { display: inline-flex; gap: var(--space-1); }

.chat-dot {
  width: var(--space-2);
  height: var(--space-2);
  border-radius: 50%;
  background: var(--ink-3);
  opacity: 0.6;
  animation: chat-think 1.2s var(--ease) infinite;
}

.chat-dot:nth-child(2) { animation-delay: 160ms; }
.chat-dot:nth-child(3) { animation-delay: 320ms; }

/* The thinking pulse is the one looping animation on the shell; the token
   block's reduced-motion rule collapses it to still dots. */
@keyframes chat-think {
  0%, 100% { opacity: 0.25; }
  50% { opacity: 1; }
}

.chat-cite {
  min-height: var(--target-min);
  border: 0;
  background: none;
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-1);
  cursor: pointer;
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  font-variant-numeric: tabular-nums;
  color: var(--accent);
  text-decoration: underline;
  text-decoration-thickness: var(--rule-hairline);
  text-underline-offset: var(--space-1);
}

.chat-cite:hover { color: var(--accent-2); }

/* X2: the honest failure carries the failure panels' accent edge and offers
   the retry in the panels' action grammar. */
.chat-bubble--error {
  max-width: var(--measure-tight);
  padding-left: var(--space-4);
  border-left: var(--rule-strong) solid var(--error);
}

.chat-error-copy {
  margin: 0 0 var(--space-3);
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  line-height: var(--leading-body);
  color: var(--ink-2);
  overflow-wrap: anywhere;
}

.chat-input-form {
  display: flex;
  gap: var(--space-3);
  margin-top: var(--space-2);
  padding-top: var(--space-4);
  border-top: var(--rule-hairline) solid var(--line);
}

.chat-input {
  flex: 1;
  min-width: 0;
  min-height: var(--target-primary);
  background: var(--paper-2);
  border: var(--rule-hairline) solid var(--line);
  border-radius: var(--radius-1);
  color: var(--ink);
  font-family: var(--font-serif);
  font-size: var(--text-base);
  padding: var(--space-2) var(--space-3);
}

.chat-input:focus-visible { border-color: var(--focus); }

.chat-input::placeholder { color: var(--ink-3); }

.chat-send { flex-shrink: 0; }

/* Chapters and transcript share the cue row: tabular time, serif text. */
.cue-list {
  margin: 0;
  padding: 0;
  list-style: none;
}

.cue {
  display: flex;
  align-items: baseline;
  gap: var(--space-4);
  min-height: var(--target-min);
  padding: var(--space-3) var(--space-2);
  border-bottom: var(--rule-hairline) solid var(--line);
  border-radius: var(--radius-1);
}

.cue time {
  flex: none;
  min-width: 7ch; /* layout constant: aligns the text edge across cue rows */
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  font-variant-numeric: tabular-nums;
  color: var(--ink-3);
}

.cue-title,
.cue-text {
  margin: 0;
  font-family: var(--font-serif);
  font-size: var(--text-base);
  line-height: var(--leading-body);
  color: var(--ink);
  overflow-wrap: anywhere;
}

a.cue { color: inherit; text-decoration: none; }
a.cue .cue-title, button.cue .cue-title { transition: color var(--dur-fast) var(--ease); }
a.cue:hover .cue-title, button.cue:hover .cue-title {
  color: var(--accent-2);
  text-decoration: underline;
  text-decoration-thickness: var(--rule-hairline);
  text-underline-offset: var(--space-1);
}
a.cue:hover time, button.cue:hover time { color: var(--ink-2); }

/* A chapter mark without a published source moment is still a real control
   (T-009), so the row grammar holds for buttons as well as anchors. */
button.cue {
  width: 100%;
  margin: 0;
  padding: var(--space-3) var(--space-2);
  border: 0;
  border-bottom: var(--rule-hairline) solid var(--line);
  border-radius: var(--radius-1);
  background: none;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
}

/* Chapter length reads as trailing tabular meta — type, not a chip. */
.cue-duration {
  margin-left: auto;
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  font-variant-numeric: tabular-nums;
  color: var(--ink-3);
  white-space: nowrap;
}

/* The subscribed playback position (T-009): the active chapter carries
   aria-current and reads in the accent — state, never decoration. */
.cue[aria-current='true'] time,
.cue[aria-current='true'] .cue-title,
.cue[aria-current='true'] .cue-duration { color: var(--accent); }

/* The transcript (T-009): the full text as calm long-form reading — serif at
   the reading size and measure, cues gathered into prose paragraphs — inside
   its own scroll, so the reading position belongs to this tab alone. */
.transcript-scroll {
  max-height: 72vh; /* layout constant: the transcript's own reading viewport */
  overflow-y: auto;
  overscroll-behavior: contain;
  scroll-padding-block: var(--space-5);
}

.transcript-text {
  max-width: var(--measure);
  font-family: var(--font-serif);
  font-size: var(--text-base);
  line-height: var(--leading-body);
  color: var(--ink-2);
}

.transcript-p {
  margin: 0 0 var(--space-5);
  overflow-wrap: anywhere;
}

.transcript-p:last-child { margin-bottom: 0; }

.transcript-passage { transition: color var(--dur-fast) var(--ease); }

/* The current passage carries aria-current from the playback position; the
   accent marks where the reading is, nothing else moves. */
.transcript-passage[aria-current='true'] { color: var(--accent); }

/* Connections (T-010): the graph around the piece — related content grouped
   by relation type (same path, same subject, same source), hairline rows
   like the paths. Each row says why it connects: its shared relations plus
   an adjacent-depth note read as one sans meta line above the byline. */
.reader-intro {
  margin: calc(-1 * var(--space-4)) 0 var(--space-5);
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  color: var(--ink-3);
}

.reader-group-title {
  margin: 0 0 var(--space-3);
  font-family: var(--font-serif);
  font-size: var(--text-lg);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-tight);
}

/* The group's count reads as trailing tabular meta, like the atlas counts. */
.reader-group-count {
  margin-left: var(--space-2);
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  font-weight: var(--weight-regular);
  font-variant-numeric: tabular-nums;
  color: var(--ink-3);
}

.conn-list {
  margin: 0 0 var(--space-2);
  padding: 0;
  list-style: none;
}

.conn {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-height: var(--target-min);
  padding: var(--space-3) var(--space-2);
  border-bottom: var(--rule-hairline) solid var(--line);
  border-radius: var(--radius-1);
  color: inherit;
  text-decoration: none;
}

.conn-title {
  font-family: var(--font-serif);
  font-size: var(--text-base);
  line-height: var(--leading-tight);
  color: var(--ink);
  overflow-wrap: anywhere;
  transition: color var(--dur-fast) var(--ease);
}

.conn:hover .conn-title { color: var(--accent-2); }

/* Why it connects: the relations this piece shares, in words — secondary ink
   so the reason reads above the plain byline meta. */
.conn-why {
  font-family: var(--font-sans);
  font-size: var(--text-xs);
  color: var(--ink-2);
  overflow-wrap: anywhere;
}

.conn-meta {
  font-family: var(--font-sans);
  font-size: var(--text-xs);
  color: var(--ink-3);
  overflow-wrap: anywhere;
}

.reader-more {
  margin: 0 0 var(--space-5);
  font-family: var(--font-sans);
  font-size: var(--text-xs);
  color: var(--ink-3);
}

/* Loading and empty states: skeletons and calm notices, never spinners (B3). */
.reader-status {
  margin: 0 0 var(--space-5);
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  color: var(--ink-3);
}

.reader-skeleton .sk,
.reader-head--skeleton .sk,
.reader-tabs--skeleton .sk {
  display: block;
  height: var(--space-3);
  margin-bottom: var(--space-3);
  background: var(--paper-3);
  border-radius: var(--radius-1);
}

.reader-head--skeleton .sk--title { height: var(--text-xl); margin-bottom: var(--space-4); }

.reader-tabs--skeleton { gap: var(--space-5); }

.reader-tabs--skeleton .sk { flex: none; margin-bottom: var(--space-4); }

.reader-empty { padding-top: var(--space-2); }

.reader-empty-title {
  margin: 0 0 var(--space-2);
  font-family: var(--font-serif);
  font-size: var(--text-xl);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-tight);
}

.reader-empty-copy {
  margin: 0 0 var(--space-5);
  max-width: var(--measure);
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  line-height: var(--leading-body);
  color: var(--ink-3);
}

/* --- The watch modal (T-011): C6's player over the shell --------------------
   A native dialog in the top layer: the shell and any open reader stay
   mounted beneath it, so closing restores the reader's tab and scroll
   exactly (continuity across navigation is T-012's picture-in-picture). The
   frame is paper with hairline rules; the stage is the one surface that
   yields to video. Layout constants: the 1080px frame measure, the dvh
   height cap, the 16:9 stage, and the 84% backdrop dim. */
.watch {
  width: min(calc(100vw - var(--space-8)), 1080px);
  max-height: calc(100dvh - var(--space-8));
  margin: auto;
  padding: var(--space-6);
  overflow: auto;
  border: var(--rule-hairline) solid var(--line);
  border-top: var(--rule-strong) solid var(--ink-3);
  border-radius: var(--radius-3);
  background: var(--paper);
  color: var(--ink);
  box-shadow: var(--shadow);
}

.watch::backdrop {
  background: var(--paper); /* fallback where color-mix is unsupported */
  background: color-mix(in srgb, var(--paper) 84%, transparent);
}

.watch-top {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-5);
  margin: 0 0 var(--space-4);
}

.watch-eyebrow {
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--ink-3);
  overflow-wrap: anywhere;
}

.watch-close {
  flex: none;
  min-height: var(--target-min);
  padding: var(--space-1) var(--space-2);
  cursor: pointer;
  background: none;
  border: 0;
  border-bottom: var(--rule-hairline) solid transparent;
  border-radius: var(--radius-1);
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  color: var(--ink-3);
}

.watch-close:hover { color: var(--ink); border-bottom-color: var(--ink-3); }

.watch-title {
  margin: 0 0 var(--space-2);
  font-family: var(--font-serif);
  font-size: var(--text-xl);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-tight);
  overflow-wrap: anywhere;
}

.watch-byline {
  margin: 0 0 var(--space-5);
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-2);
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  color: var(--ink-3);
  overflow-wrap: anywhere;
}

.watch-byline time {
  font-variant-numeric: tabular-nums;
  color: var(--ink-2);
  white-space: nowrap;
}

.watch-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(220px, 280px);
  gap: var(--space-5);
  align-items: start;
  margin: 0 0 var(--space-5);
}
.watch-layout .watch-stage { margin: 0; }
.watch-rail { min-width: 0; max-height: min(56vw, 520px); overflow: auto; }
.watch-rail .up-next { border-left: 1px solid var(--line); padding-left: var(--space-4); }
.watch-stage { margin: 0 0 var(--space-5); }

.watch-player {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  border: 0;
  border-radius: var(--radius-1);
  background: var(--paper-3);
}

/* The modal's chapter rail: the reader's own marks as seek controls under
   the player, in the same cue grammar. */
.watch-chapters-title {
  margin: 0 0 var(--space-3);
  font-family: var(--font-sans);
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--ink-3);
}

.watch-chapters .cue-list { max-width: var(--measure-wide); }

/* --- The picture-in-picture dock (T-012): C6's continuity promise -----------
   Closing the watch modal never stops playback: the same dialog drops out
   of the top layer and re-styles into this corner dock, its player
   untouched in the DOM — never re-parented, never reloaded — so watching
   survives every route change. Only the dock's own Close control ends the
   session. Layout constants: the 360px dock measure and the space-5
   viewport inset; the stage keeps the modal's 16:9. */
.watch--pip {
  position: fixed;
  /* Non-modal dialogs join normal stacking, so page cards would paint over
     the dock; lift it above content but below modal dialogs. */
  z-index: 55;
  /* Clear the floating companion dock: its measured height rides in
     --chat-dock-h, so the mini player always sits above the chat bar. */
  inset: auto var(--space-5) calc(var(--chat-dock-h, 56px) + var(--space-4)) auto;
  margin: 0;
  width: min(360px, calc(100vw - var(--space-6)));
  max-height: none;
  padding: var(--space-2);
  overflow: visible;
  background: var(--paper-2);
  border-radius: var(--radius-3);
  box-shadow: var(--shadow);
}

/* The modal's chrome reads at full size only; the dock carries its own. */
.watch--pip .watch-top,
.watch--pip .watch-title,
.watch--pip .watch-byline,
.watch--pip .watch-chapters { display: none; }

.watch--pip .watch-layout { display: block; margin: 0; }
.watch--pip .watch-rail { display: none; }
.watch--pip .watch-stage { margin: 0; }

.pip-bar { display: none; }

.watch--pip .pip-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  margin: var(--space-2) 0 0;
}

.pip-title {
  margin: 0;
  min-width: 0;
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  color: var(--ink-2);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.pip-actions {
  display: flex;
  flex: none;
  gap: var(--space-4);
}

/* The dock's controls speak the modal Close control's grammar: quiet text,
   the accent arriving on hover/focus — the one accent. */
.pip-expand,
.pip-close {
  flex: none;
  min-height: var(--target-min);
  padding: var(--space-1) var(--space-2);
  cursor: pointer;
  background: none;
  border: 0;
  border-bottom: var(--rule-hairline) solid transparent;
  border-radius: var(--radius-1);
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  color: var(--ink-3);
}

.pip-expand:hover,
.pip-expand:focus-visible,
.pip-close:hover,
.pip-close:focus-visible { color: var(--accent-2); border-bottom-color: var(--ink-3); }

/* --- Account presence (T-324) ----------------------------------------------
   One quiet control at the masthead's right edge: Sign in when there is no
   session, the person's name and initials when there is. The menu it opens
   is hairline paper, never chrome; the slot itself stays hidden until Clerk
   reports a state, so a failed load leaves no trace. */
.masthead-account {
  display: flex;
  align-items: center;
  margin-left: var(--space-5);
}

.masthead-account[hidden] { display: none; }

.account { position: relative; display: flex; }

.account-button {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: var(--target-primary);
  border: 0;
  background: none;
  cursor: pointer;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-1);
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  color: var(--ink-2);
}

.account-button:hover { color: var(--ink); }

.account-avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: calc(var(--space-6) - var(--space-2)); /* layout constant: 24px seat */
  height: calc(var(--space-6) - var(--space-2));
  border: var(--rule-hairline) solid var(--ink-3);
  border-radius: 50%;
  font-family: var(--font-sans);
  font-size: var(--text-xs);
  color: var(--accent);
}

.account-name { white-space: nowrap; }

.account-menu {
  position: absolute;
  top: 100%;
  right: 0;
  z-index: 40;
  display: grid;
  min-width: 12rem; /* layout constant: the menu's measure */
  background: var(--paper-2);
  border: var(--rule-hairline) solid var(--line);
  border-radius: var(--radius-2);
  box-shadow: var(--shadow);
  padding: var(--space-2) 0;
}

.account-menu-item {
  min-height: var(--target-min);
  border: 0;
  background: none;
  cursor: pointer;
  text-align: left;
  padding: var(--space-2) var(--space-4);
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  color: var(--ink-2);
}

.account-menu-item:hover,
.account-menu-item:focus-visible { color: var(--ink); }

/* --- Footer --------------------------------------------------------------- */
.colophon code,
.panel-note code {
  font: inherit;
  color: var(--ink);
}

/* --- Responsive ------------------------------------------------------------ */
@media (max-width: 900px) {
  .card-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-5); }
  .masthead { flex-wrap: wrap; gap: var(--space-3); padding-bottom: var(--space-3); }
  .legacy-link { margin-left: 0; }
  .masthead-account { margin-left: auto; } /* the wrapped masthead keeps the account at its right edge */
}

@media (max-width: 600px) {
  main { padding: var(--space-6) var(--space-5) var(--space-7); }
  .masthead { flex-wrap: wrap; padding: var(--space-3) var(--space-5); }
  .masthead nav {
    order: 3;
    flex-basis: 100%;
    flex-wrap: nowrap;
    gap: var(--space-4);
    overflow-x: auto;
    scrollbar-width: none;
    -webkit-mask-image: linear-gradient(90deg, #000 85%, transparent);
    mask-image: linear-gradient(90deg, #000 85%, transparent);
  }
  .masthead nav::-webkit-scrollbar { display: none; }
  .masthead nav a { padding: var(--space-2) var(--space-3); font-size: var(--text-sm); white-space: nowrap; }
  .masthead-account { margin-left: auto; }
  .drawer-grid { grid-template-columns: 1fr; gap: var(--space-5); padding-left: var(--space-5); padding-right: var(--space-5); }
  .plate { left: var(--space-5); }
  .drawer-all { right: var(--space-5); }
  .card-grid { grid-template-columns: 1fr; gap: var(--space-5); }
  .panel { padding: var(--space-5) var(--space-4); margin: var(--space-6) 0; }
  .colophon { padding: var(--space-4) var(--space-5); }
  .trail-section { padding: var(--space-5) 0; }
  .trail-title { font-size: var(--text-lg); }
  .trail-items { padding-left: var(--space-5); }
  .reader-tabs { gap: var(--space-5); }
  .watch--pip { inset: auto var(--space-4) calc(var(--chat-dock-h, 56px) + var(--space-4)) auto; z-index: 55; }
  .cue { flex-direction: column; gap: var(--space-1); }
  .cue time { min-width: 0; }
  .watch { padding: var(--space-5) var(--space-4); }
  .watch-title { font-size: var(--text-xl); }
  .trail-thumb { width: 64px; } /* layout constant: the row preview at phone width */
  .reader-head { grid-template-columns: 1fr; }
  .reader-thumb { width: min(280px, 60%); }
  .chat-bubble { max-width: 100%; }
  .chat-bubble--user { align-self: flex-start; padding-right: 0; border-right: 0; padding-left: var(--space-4); border-left: var(--rule-strong) solid var(--ink-3); }
  .chat-input-form { flex-direction: column; align-items: flex-start; }
  .index-count { margin-left: 0; flex-basis: 100%; }
}

/* Motion: only tokenized color/rule transitions; everything collapses under
   prefers-reduced-motion via the token block (see shell/tokens.css). */


/* T-06 / D3 — home greeting, resume row, explore teaser */
.home-greeting { margin: var(--space-4) 0 var(--space-5); }
.home-greeting-line { font-size: var(--text-lg); line-height: var(--leading-body); color: var(--ink); max-width: var(--measure); margin: 0 0 var(--space-2); }
.home-greeting-count { font-size: var(--text-sm); color: var(--ink-3); margin: 0; }
.resume-row { margin: 0 0 var(--space-6); padding: var(--space-4) 0; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.resume-title { font-size: var(--text-sm); font-weight: 600; letter-spacing: 0.02em; text-transform: uppercase; color: var(--ink-3); margin: 0 0 var(--space-3); }
.resume-list { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: var(--space-3); }
.resume-item { min-width: 0; }
.resume-link { display: inline-block; padding: var(--space-2) var(--space-3); border: 1px solid var(--line); border-radius: var(--radius-2); background: var(--paper-2); color: var(--ink); text-decoration: none; font-size: var(--text-sm); transition: background var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease); }
.resume-link:hover { background: var(--paper-3); border-color: var(--ink-3); }
.resume-link:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.explore-teaser { margin: var(--space-6) 0 var(--space-4); font-size: var(--text-sm); }
.explore-teaser-link { color: var(--link); text-decoration: none; border-bottom: 1px solid var(--line); }
.explore-teaser-link:hover { border-bottom-color: var(--link); }
.explore-teaser-link:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }


/* Up next rail (YouTube-style) + reader two-column layout */
.reader-layout { display: grid; grid-template-columns: minmax(0, 1fr) minmax(280px, 340px); gap: var(--space-6); align-items: start; }
.reader-main { min-width: 0; }
.up-next { border-left: 1px solid var(--line); padding-left: var(--space-5); }
.up-next-title { font-size: var(--text-sm); font-weight: 600; letter-spacing: 0.02em; text-transform: uppercase; color: var(--ink-3); margin: 0 0 var(--space-4); }
.up-next-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-4); }
.up-next-item { min-width: 0; }
.up-next-link { display: grid; grid-template-columns: 112px minmax(0, 1fr); gap: var(--space-3); align-items: start; text-decoration: none; color: var(--ink); border-radius: var(--radius-2); padding: var(--space-1); transition: background var(--dur-fast) var(--ease); }
.up-next-link:hover { background: var(--paper-3); }
.up-next-link:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.up-next-thumb { width: 112px; }
.up-next-body { display: flex; flex-direction: column; gap: var(--space-1); min-width: 0; }
.up-next-name { font-size: var(--text-sm); line-height: var(--leading-tight); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.up-next-meta { font-size: var(--text-xs); color: var(--ink-3); }
@media (max-width: 900px) {
  .reader-layout { grid-template-columns: minmax(0, 1fr); }
  .up-next { border-left: 0; border-top: 1px solid var(--line); padding-left: 0; padding-top: var(--space-5); }
}


/* Learning paths: search + compact subject index (easier navigation) */
.paths-tools { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-4); margin: var(--space-4) 0 var(--space-3); }
.paths-search { flex: 1 1 260px; max-width: 420px; padding: var(--space-3) var(--space-4); font-size: var(--text-base); color: var(--ink); background: var(--paper-2); border: 1px solid var(--line); border-radius: var(--radius-2); }
.paths-search:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.paths-count { margin: 0; font-size: var(--text-sm); color: var(--ink-3); }
.paths-index { margin: 0 0 var(--space-6); padding: var(--space-4) 0; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.paths-index-list { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-3); }
.paths-index-link { display: inline-flex; align-items: baseline; gap: var(--space-2); padding: var(--space-2) var(--space-3); border: 1px solid var(--line); border-radius: var(--radius-2); background: var(--paper-2); color: var(--ink); text-decoration: none; font-size: var(--text-sm); transition: background var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease); }
.paths-index-link:hover { background: var(--paper-3); border-color: var(--ink-3); }
.paths-index-link:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.paths-index-count { font-size: var(--text-xs); color: var(--ink-3); }


/* Floating companion dock — fixed at the bottom of every surface */
.chat-dock { position: fixed; left: 0; right: 0; bottom: 0; z-index: 60; background: var(--paper-2); border-top: 1px solid var(--line); box-shadow: var(--shadow); }
.chat-dock-bar { display: flex; align-items: center; justify-content: space-between; gap: var(--space-4); padding: var(--space-2) var(--space-5); }
.chat-dock-context { margin: 0; font-size: var(--text-xs); color: var(--ink-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chat-dock-toggle { padding: var(--space-2) var(--space-4); font-size: var(--text-sm); color: var(--paper); background: var(--accent); border: 0; border-radius: var(--radius-2); cursor: pointer; }
.chat-dock-toggle:hover { background: var(--accent-2); }
.chat-dock-toggle:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.chat-dock-panel { max-height: min(60vh, 520px); display: flex; flex-direction: column; gap: var(--space-3); padding: var(--space-4) var(--space-5) var(--space-5); border-top: 1px solid var(--line); }
.chat-dock-panel[hidden] { display: none; }
.chat-dock-log { overflow-y: auto; display: flex; flex-direction: column; gap: var(--space-3); }
.chat-dock-empty { margin: 0; font-size: var(--text-sm); color: var(--ink-3); }
html.js .chat-dock-message { animation: card-settle var(--dur-base) var(--ease) both; }
.chat-dock-message { margin: 0; font-size: var(--text-sm); line-height: var(--leading-body); padding: var(--space-3) var(--space-4); border-radius: var(--radius-2); max-width: var(--measure); }
.chat-dock-message--user { align-self: flex-end; background: var(--paper-3); color: var(--ink); }
.chat-dock-message--assistant { align-self: flex-start; background: var(--paper); border: 1px solid var(--line); color: var(--ink); }
.chat-dock-form { display: flex; gap: var(--space-3); }
.chat-dock-input { flex: 1; padding: var(--space-3) var(--space-4); font-size: var(--text-base); color: var(--ink); background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius-2); }
.chat-dock-input:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.chat-dock-send { padding: var(--space-3) var(--space-5); font-size: var(--text-sm); color: var(--paper); background: var(--accent); border: 0; border-radius: var(--radius-2); cursor: pointer; }
.chat-dock-send:hover { background: var(--accent-2); }
.chat-dock-send:disabled { opacity: 0.6; cursor: progress; }
.chat-dock-resume { align-self: flex-start; padding: var(--space-2) var(--space-4); font-size: var(--text-sm); color: var(--paper); background: var(--success); border: 0; border-radius: var(--radius-2); cursor: pointer; }
.chat-dock-resume:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
body { padding-bottom: var(--chat-dock-h, 56px); }
@media (max-width: 700px) { .chat-dock-bar { padding: var(--space-2) var(--space-4); } .chat-dock-panel { padding: var(--space-3) var(--space-4) var(--space-4); } }


/* Compact atlas strip: the map's shape, pinned while the shelf scrolls */
.atlas-mini { position: sticky; top: 0; z-index: 5; display: flex; flex-wrap: wrap; gap: var(--space-3) var(--space-5); align-items: center; padding: var(--space-3) 0; margin-bottom: var(--space-4); background: var(--paper); border-bottom: 1px solid var(--line); }
.atlas-mini-field { display: flex; align-items: center; gap: var(--space-2); }
.atlas-mini-hub { padding: var(--space-1) var(--space-2); font-size: var(--text-xs); font-weight: 600; color: var(--ink-2); background: var(--paper-2); border: 1px solid var(--line); border-radius: var(--radius-1); cursor: pointer; }
.atlas-mini-hub:hover { background: var(--paper-3); }
.atlas-mini-hub.is-selected { color: var(--paper); background: var(--accent); border-color: var(--accent); }
.atlas-mini-hub:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.atlas-mini-dots { display: inline-flex; align-items: center; gap: 4px; }
.atlas-mini-dot { width: 10px; height: 10px; padding: 0; background: var(--paper-3); border: 1px solid var(--line); border-radius: 50%; cursor: pointer; }
.atlas-mini-dot:hover { background: var(--ink-3); }
.atlas-mini-dot.is-selected { background: var(--accent); border-color: var(--accent); transform: scale(1.35); }
.atlas-mini-dot:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
@media (max-width: 700px) { .atlas-mini { gap: var(--space-2) var(--space-3); } .atlas-mini-dot { width: 8px; height: 8px; } }


/* Autoplay-next toggle in the watch modal */
.watch-autoplay { padding: var(--space-1) var(--space-3); font-size: var(--text-xs); color: var(--ink-2); background: var(--paper-2); border: 1px solid var(--line); border-radius: var(--radius-1); cursor: pointer; }
.watch-autoplay[aria-pressed="true"] { color: var(--paper); background: var(--accent); border-color: var(--accent); }
.watch-autoplay:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }


/* --- Lamp field + settle (mega-design loop 3) ------------------------------
   WebGL paper grain and a lamp pool live behind the room. Cards and the
   outlet settle onto the shelf; reduced-motion tokens collapse the durations. */
#lamp-gl {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
  pointer-events: none;
  opacity: 0.5;
  mix-blend-mode: multiply;
}
body > .masthead,
body > main,
body > footer { position: relative; z-index: 1; }
#outlet.outlet-enter { animation: outlet-enter var(--dur-slow) var(--ease); }
@keyframes outlet-enter { from { transform: translateY(8px); } to { transform: none; } }
html.js .print .drawer-grid > .card {
  animation: card-settle var(--dur-base) var(--ease) both;
}
@keyframes card-settle { from { transform: translateY(6px); } to { transform: none; } }

/* --- Catalog drawers (mega-design loop 2) ----------------------------------
   The index files into field drawers: a warmer interior strip closed by a
   full-width wooden board, named by a plate; the day's card stands open. */
.drawer-shelf { display: flex; flex-direction: column; gap: var(--space-7); }
.drawer {
  background: var(--paper-drawer);
  border-top: var(--rule-hairline) solid var(--line);
  margin-inline: calc(50% - 50vw);
}
.drawer-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-6);
  max-width: 1160px;
  margin: 0 auto;
  padding: var(--space-5) var(--space-6) var(--space-6);
}
/* Cards are li elements; inside a drawer they are not a list, so they stack as
   blocks (no marker) — the lead card keeps its own grid. */
.drawer-grid { list-style: none; }
.drawer-grid > .card:not(.card--lead) { display: flex; flex-direction: column; }
@media (min-width: 601px) { .card-eyebrow-text { white-space: nowrap; } }
.drawer-tail .card-grid { max-width: 1160px; margin: 0 auto; padding: 0 var(--space-6); }
.drawer-foot { position: relative; height: 3px; }
.board { position: absolute; inset: 0; background: var(--board); }
.plate,
.drawer-all {
  position: absolute;
  top: 0;
  transform: translateY(-50%);
  background: var(--paper);
  border: 1px solid var(--board);
  padding: 2px 10px;
  font-size: var(--text-xs);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
}
.plate { left: max(var(--space-6), calc(50vw - 580px + var(--space-6))); color: var(--board); }
.drawer-all { right: max(var(--space-6), calc(50vw - 580px + var(--space-6))); color: var(--board); text-decoration: none; }
.drawer-all:hover { color: var(--accent-2); border-color: var(--accent-2); }
.drawer-all:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }

/* The open drawer: the day's card, with the lamp pool behind its paper. */
.drawer--open { position: relative; }
.drawer--open::after {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(70% 60% at 62% 60%, var(--lamp), transparent 72%);
  opacity: 0;
  transition: opacity var(--dur-slow) var(--ease);
  pointer-events: none;
}
body.is-playing .drawer--open::after { opacity: 1; }
.drawer--open .drawer-grid { position: relative; z-index: 1; grid-template-columns: 1.6fr 1fr; align-items: start; }
.card--lead { display: flex; flex-direction: column; gap: var(--space-4); }
.card--lead .card-thumb { margin-bottom: 0; }
.card--lead .card-title { font-size: var(--text-xl); }
@media (min-width: 901px) {
  .card--lead { display: grid; grid-template-columns: 1.6fr 1fr; gap: var(--space-4) var(--space-5); }
  .card--lead .card-thumb { grid-area: 1 / 1 / 6 / 2; }
  .card--lead .card-thumb .thumb-img,
  .card--lead .card-thumb .thumb-fallback { height: 100%; }
  .card--lead > .card-eyebrow,
  .card--lead > .card-title,
  .card--lead > .card-byline,
  .card--lead > .card-actions { grid-column: 2; }
}

/* Accent scale: the filled watch belongs to the day's card; shelf watches are
   outline terracotta, so accent stays at event scale. */
.card .card-watch { background: none; border: 1px solid var(--accent); color: var(--accent); }
.card .card-watch:hover { background: var(--accent); color: var(--paper); }
.card--lead .card-watch { background: var(--accent); border-color: var(--accent); color: var(--paper); }
.card--lead .card-watch:hover { background: var(--accent-2); border-color: var(--accent-2); }

/* Print motion: the first two drawers settle once, JS-gated; every other
   drawer renders settled, and reduced motion collapses the durations. */
html.js .print .plate,
html.js .print .drawer-all { clip-path: inset(0 100% 0 0); animation: plate-print var(--dur-base) var(--ease) 0.1s both; }
html.js .print .board { transform: scaleX(0); transform-origin: left; animation: board-draw 220ms var(--ease) 0.25s both; }
@keyframes plate-print { to { clip-path: inset(0 0 0 0); } }
@keyframes board-draw { to { transform: scaleX(1); } }

/* The lamp event: the room answers the film and returns when it ends. */
body.is-playing .chat-dock { border-top-color: var(--lamp-edge); }

@media (max-width: 900px) {
  .drawer-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .drawer--open .drawer-grid { grid-template-columns: 1fr; }
  .card--lead .card-thumb { aspect-ratio: 16 / 9; }
}

.drawer-tail .tail-more {
  display: block;
  margin: var(--space-5) auto 0;
  padding: var(--space-2) var(--space-5);
  font-size: var(--text-sm);
  color: var(--paper);
  background: var(--accent);
  border: 0;
  border-radius: var(--radius-2);
  cursor: pointer;
}
.drawer-tail .tail-more:hover { background: var(--accent-2); }
.drawer-tail .tail-more:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }

/* The companion column (desktop): the chat stands always open as a right-hand
   column, so the masthead, the index, and the reader share the width beside
   it; drawer boards bleed only to the main column's edges. The phone keeps
   the one-tap dock, and the chat riding the watch dialog is untouched. */
@media (min-width: 901px) {
  body { padding-right: var(--chat-col-w); padding-bottom: 0; }
  body > .chat-dock,
  .watch > .chat-dock {
    top: 0; right: 0; bottom: 0; left: auto;
    width: var(--chat-col-w);
    display: flex; flex-direction: column;
    border-top: 0; border-left: 1px solid var(--line);
    box-shadow: none;
  }
  body > .chat-dock .chat-dock-bar,
  .watch > .chat-dock .chat-dock-bar {
    border-bottom: var(--rule-hairline) solid var(--line);
    padding: var(--space-5) var(--space-5) var(--space-3);
  }
  body > .chat-dock .chat-dock-context,
  .watch > .chat-dock .chat-dock-context {
    font-size: var(--text-xs);
    font-weight: var(--weight-medium);
    letter-spacing: var(--tracking-caps);
    text-transform: uppercase;
    color: var(--ink-3);
    white-space: normal;
  }
  body > .chat-dock .chat-dock-toggle,
  .watch > .chat-dock .chat-dock-toggle { display: none; }
  body > .chat-dock .chat-dock-panel,
  .watch > .chat-dock .chat-dock-panel {
    flex: 1;
    min-height: 0;
    max-height: none;
    border-top: 0;
    padding: var(--space-4) var(--space-5) var(--space-5);
    display: flex;
    flex-direction: column;
  }
  body > .chat-dock .chat-dock-log,
  .watch > .chat-dock .chat-dock-log { flex: 1; min-height: 0; }
  body > .chat-dock .chat-dock-empty,
  .watch > .chat-dock .chat-dock-empty {
    font-family: var(--font-serif);
    font-size: var(--text-lg);
    line-height: var(--leading-body);
    color: var(--ink-2);
    max-width: 22ch;
  }
  body > .chat-dock .chat-dock-form,
  .watch > .chat-dock .chat-dock-form {
    margin-top: auto;
    padding-top: var(--space-4);
    border-top: var(--rule-hairline) solid var(--line);
  }
  body > .chat-dock .chat-dock-input,
  .watch > .chat-dock .chat-dock-input {
    background: var(--paper-2);
    border-color: var(--line);
  }
  body.is-playing > .chat-dock,
  .watch > .chat-dock { border-left-color: var(--lamp-edge); }
  .watch--pip { right: calc(var(--chat-col-w) + var(--space-5)); }
  .drawer { margin-inline: calc(50% - 50vw + var(--chat-col-w) / 2); }
  /* :not(.watch--pip) keeps the modal measure off the corner dock, whose
     fixed inset and 360px width in .watch--pip would otherwise be beaten
     by this later same-specificity rule. */
  .watch:not(.watch--pip) {
    width: min(calc(100vw - var(--chat-col-w) - var(--space-8)), 1080px);
    margin: auto calc(var(--chat-col-w) + var(--space-4)) auto auto;
  }
  body.is-playing .reader-layout > .up-next { visibility: hidden; }
}
@media (max-width: 900px) {
  .watch-layout { grid-template-columns: minmax(0, 1fr); }
  .watch-rail .up-next { border-left: 0; border-top: 1px solid var(--line); padding-left: 0; padding-top: var(--space-4); }
  .watch-rail { max-height: 240px; }
}
