/* =========================================================================
   Delta — styles.css
   All look-and-feel lives in the :root variables (see specs/design-tokens.md).
   Values carried forward from the naked/media prototype (Richard: keep the look).
   Stage 2: title bar + reader viewport with a translating two-card track for
   the slide-up advance; progress bar; arm-rule scroll-then-swipe.
   ========================================================================= */

:root {
  /* --- palette --- */
  --bg:            #faf8f4;   /* main reading surface — warm off-white "paper" */
  --ink:           #222;      /* main reading text */
  --ink-soft:      #567;      /* secondary text */
  --ink-faint:     #999;      /* faint meta (segment id) */

  --segment-bg:    #ffffff;   /* segment card background */
  --segment-line:  #e3ddd1;   /* hairline dividers / card edges */
  --here-ink:      #8a7a4a;   /* "you are here" label ink (warm brown) */

  --node-bg:       #f3eee3;   /* node-card background (Stage 3) */
  --pivot-bg:      #fffdf5;   /* pivot-card background (Stage 3) */
  --pivot-line:    #b8860b;   /* THE accent — warm goldenrod (also the progress fill) */
  --pivot-ink:     #2a2a2a;
  --pivot-chip:    #8a7a4a;

  /* --- type --- */
  --font-read:  Georgia, "Times New Roman", serif;
  --font-ui:    system-ui, -apple-system, "Segoe UI", sans-serif;
  --read-size:  1.06rem;
  --read-line:  1.62;

  /* --- spacing / geometry --- */
  --gutter:        18px;
  --card-radius:   12px;
  --max-w:         520px;
  --pivot-thumb-h: 150px;   /* pivot-card height — fits a 2-line bold + 3-line teaser cleanly */

  /* --- motion --- */
  --snap-ease:    cubic-bezier(.22,.61,.36,1);
  --snap-dur:     280ms;
  --nudge-dur:    180ms;
  --slide-in-dur: 300ms;
  --cover-dur:    432ms;    /* first-segment reveal — deliberately gentle (slowed twice on playtest) */

  --progress-h: 4px;

  /* --- wayfinding / index page --- */
  --nav-fill:        var(--pivot-line);   /* progress / completion fill (goldenrod) */
  --nav-unexplored:  #c9c4bb;   /* thread-bar track: reachable but unexplored */
  --nav-locked:      #f1f0ee;   /* undiscovered / not-yet-revealed (locked bars, skeleton, unseen sprout) */
  --idx-border:      #e7e1d6;   /* pill / page hairline */
  --idx-divider:     #f0ebe1;   /* between delta rows */
  --idx-dur:         420ms;     /* index open/close roll */
  --idx-clear:       62px;      /* prose top padding so text clears the floating pill */

  /* --- Story icons (assets-stories.md §8): one source image, masked to a circle, three sizes --- */
  --story-icon-door:  56px;             /* pivot-card circle */
  --story-icon-rail:  30px;             /* segment-page rail circle */
  --story-icon-index: 40px;             /* index STORIES / BRANCHES circle */
  --story-icon-ring:  var(--idx-border);/* thin ring around a circle */
  --story-icon-bg:    var(--node-bg);   /* placeholder fill: discovered but image missing */
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-ui);
  -webkit-text-size-adjust: 100%;
  overscroll-behavior: none;        /* no rubber-band page bounce on iOS */
  overflow-x: hidden;               /* the index parks off-screen right (translateX 100%) — no stray h-scroll */
}

#app {
  position: fixed;                  /* lock the app to the viewport; the reader owns scroll */
  inset: 0;
  display: flex;
  flex-direction: column;
}

/* ---- persistent top-of-page progress bar (visited / total) ---------------- */
.progress {
  flex: 0 0 auto;
  height: var(--progress-h);
  width: 100%;
  background: var(--segment-line);
}
.progress__fill {
  height: 100%;
  background: var(--pivot-line);
  transition: width var(--snap-dur) var(--snap-ease);
}

/* ---- title bar ------------------------------------------------------------ */
.titlebar {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 10px var(--gutter);
  font-family: var(--font-ui);
  font-size: .85rem;
  background: var(--bg);
  border-bottom: 1px solid var(--segment-line);
}
.titlebar__title { font-weight: 600; color: var(--ink); }
.titlebar__thread { display: flex; align-items: center; gap: 6px; color: var(--here-ink); }
.titlebar__thread .dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--pivot-line); display: inline-block;
}

/* ---- load / error status --------------------------------------------------- */
.status {
  margin: auto;
  color: var(--ink-soft);
  font-size: .9rem;
  text-align: center;
  max-width: var(--max-w);
  line-height: 1.5;
  padding: var(--gutter);
}
.status--error { color: #a3402a; }
.status small { color: var(--ink-faint); }

/* ---- the reader viewport + translating track ------------------------------ */
.reader {
  flex: 1 1 auto;
  position: relative;
  overflow: hidden;                 /* the track translates; cards scroll internally */
}
.track {
  position: absolute;
  inset: 0;
  will-change: transform;
}
.track.animate { transition: transform var(--snap-dur) var(--snap-ease); }

/* ---- segment card: fills the reader; exactly one on screen ----------------- */
.segment-card {
  position: absolute;
  left: 0; right: 0; top: 0;
  height: 100%;
  display: flex;
  flex-direction: column;
  background: var(--segment-bg);
}
.segment-card.is-next { top: 100%; }   /* sits one screen below, ready to rise (advance) */
.segment-card.is-prev { top: -100%; }  /* sits one screen above, ready to drop (rewind) */

/* media-mode transition face: an <img> painted (src + Size/motion) to the target's start frame
   via Rich.stillFor — same element + transform the overlay uses, so the pull-in hands off seamlessly */
.segment-card.media-still { padding: 0; background: #fff; overflow: hidden; }   /* clip the scaled img to the card (don't bleed over the node card) */
.media-still__img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
  object-position: 50% 50%; background: #fff; }
.media-still__img.cat { inset: auto; left: 50%; top: 50%; width: 75%; height: auto; max-height: 78%;
  object-fit: contain; transform: translate(-50%, -50%); }
/* reader-side media title cover: a segment being transitioned to in media presents its TITLE (opaque),
   identical to the overlay's per-page .rich-ptitle, so the reader→overlay handoff is title→title. */
.media-title-cover { position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center; padding: 0 calc(var(--gutter) + 8px);
  background: var(--segment-bg);
  font-family: var(--font-read); font-weight: 600; font-size: 1.9rem; line-height: 1.24;
  color: var(--ink); text-align: center; }

/* "you are here" line, pinned at the card top; carries the visited checkbox */
.segment-card__here {
  flex: 0 0 auto;
  display: flex;
  align-items: baseline;
  gap: 8px;
  width: 100%;
  max-width: var(--max-w);
  margin: 0 auto;
  font-family: var(--font-ui);
  font-size: .8rem;
  color: var(--here-ink);
  background: var(--segment-bg);
  border-bottom: 1px solid var(--segment-line);
  padding: 12px var(--gutter) 10px;
}
.segment-card__check { font-size: .95rem; line-height: 1; color: var(--ink-faint); }
.segment-card__check.is-on { color: var(--pivot-line); }
.segment-card__here-label { opacity: .65; }
.segment-card__here-where { font-weight: 600; }
.segment-card__id {
  display: none;                  /* dev/debug label — hidden; flip to inline-block to restore */
  margin-left: auto;
  font-family: ui-monospace, Menlo, monospace;
  font-size: .72rem;
  color: var(--ink-faint);
  background: #f0ece3;
  border: 1px solid var(--segment-line);
  border-radius: 5px;
  padding: 1px 6px;
}

/* the prose — the scrollable region of the card */
.segment-card__prose {
  flex: 1 1 auto;
  overflow-y: auto;
  overflow-x: hidden;             /* clip pivot-card bounce/swipe, no stray scrollbar */
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
  width: 100%;
  max-width: var(--max-w);
  margin: 0 auto;
  padding: var(--gutter) var(--gutter) 8px;
  font-family: var(--font-read);
  font-size: var(--read-size);
  line-height: var(--read-line);
  color: var(--ink);
}
.segment-card__prose p { margin: 0 0 1em; }
/* verse (poems: S012 tail, S027 lullaby, S043 song) keeps its authored line breaks AND
   leading whitespace — pre-wrap (not pre-line) preserves the indentation that shapes
   S012's tail poem; the other four verse paragraphs have no indentation so render the same. */
.segment-card__prose p.verse { white-space: pre-wrap; }

/* advance / end-of-thread affordances at the bottom of the prose */
.advance-hint, .end-hint {
  text-align: center;
  font-family: var(--font-ui);
  font-size: .8rem;
  color: var(--ink-faint);
  padding: 16px 0 28px;
}
.advance-hint { cursor: pointer; user-select: none; }
.end-hint { color: var(--here-ink); opacity: .8; }

/* ---- segment image (frameless: blends into the white card) ---------------- */
.seg-figure { margin: 0 0 16px; }
.seg-figure img { display: block; width: 100%; height: auto; }

/* ---- end-of-Story copy on a terminal segment (#12 — replaces the v1 ✦ glyph) -- */
.story-end {
  margin: 30px 0 12px;
  padding-top: 22px;
  border-top: 1px solid var(--segment-line);
  font-family: var(--font-read);
  font-size: 1rem;
  line-height: 1.55;
  color: var(--ink-soft);
}

/* ---- node card: its own card, holding the pivot-card stack ----------------- */
.node-card .segment-card__prose,
.segment-card.node-card .segment-card__prose { padding-top: 16px; }
/* node cards carry no orientation bar — the pivot cards stand on their own */
.node-card .segment-card__here { display: none; }
.node-card .segment-card__prose { padding-top: var(--gutter); }
/* Branch header (design: "Delta UI edits.pdf"): the delta mark shows LARGE and CENTERED at the top of
   the Branch page — it displays the completed state of the Branch — with the "New Branch" / "Branch"
   title centered directly beneath it. (Shared by the node card and the delta-jump incoming card.) */
.branch-head {
  display: flex; flex-direction: column; align-items: center; gap: 14px;
  padding: 34px var(--gutter) 12px; text-align: center;
}
.branch-mark { width: 116px; height: 116px; flex: 0 0 auto; }
.branch-title { font-family: var(--font-ui); font-weight: 600; font-size: 1.55rem; color: var(--ink); }

.node-stack {
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding-bottom: 24px;
}

/* ---- pivot card: image-led, two-column, left-swipe to commit -------------- */
.pivot-card {
  position: relative;
  display: flex;
  align-items: center;                         /* circle Story icon centred beside the body */
  gap: 14px;
  padding-left: 12px;
  height: var(--pivot-thumb-h);                /* FIXED — image loading must not reflow the card */
  background: var(--pivot-bg);
  border: 1px solid var(--segment-line);
  border-left: 4px solid var(--pivot-line);
  border-radius: 10px;
  overflow: hidden;
  touch-action: pan-y;                         /* we own horizontal; vertical scroll passes through */
  transition: transform var(--nudge-dur) var(--snap-ease);
  box-shadow: 0 2px 6px rgba(0,0,0,.08);
}
.pivot-card.swiping { transition: none; }       /* 1:1 with the finger while dragging */

/* entrance: each pivot card flies in from the right and bounces to rest, staggered.
   fill-mode backwards holds the off-screen start during the stagger delay; we do
   NOT keep `forwards` so the inline drag transform works once it settles. */
.pivot-card.flyin { animation: pivot-flyin 560ms ease-out backwards; }
.pivot-card.flyin:nth-child(1) { animation-delay: 40ms; }
.pivot-card.flyin:nth-child(2) { animation-delay: 150ms; }
.pivot-card.flyin:nth-child(3) { animation-delay: 260ms; }
@keyframes pivot-flyin {
  0%   { transform: translateX(115%); opacity: 0; }
  55%  { opacity: 1; }
  68%  { transform: translateX(-12px); }   /* arrive and overshoot past rest */
  84%  { transform: translateX(4px); }
  100% { transform: translateX(0); }
}

.pivot-card__icon { --sz: var(--story-icon-door); }   /* destination Story's circle, door size */
.pivot-card__body {
  flex: 1 1 auto;
  min-width: 0;                  /* let text truncate instead of forcing width */
  padding: 14px 14px 14px 0;
  display: flex;
  flex-direction: column;
  gap: 5px;
  overflow: hidden;
  height: 100%;
}
.pivot-card__top { display: flex; align-items: center; gap: 6px; }
.pivot-card__check { width: 18px; height: 18px; flex: 0 0 auto; }
.pivot-card__prog { display: flex; align-items: center; gap: 8px; margin-top: auto; }
.pivot-card__bar { flex: 1 1 auto; height: 6px; border-radius: 3px; background: var(--nav-unexplored); overflow: hidden; }
.pivot-card__bar > i { display: block; height: 100%; background: var(--nav-fill); }
.pivot-card__ratio { flex: 0 0 auto; font-family: var(--font-ui); font-size: .7rem; color: var(--pivot-chip); }
/* the character · location chip now lives in the bold slot (title removed) */
.pivot-card__title {
  font-family: var(--font-ui);
  font-weight: 600;
  font-size: .9rem;
  line-height: 1.25;
  color: var(--pivot-ink);
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;         /* clamp the bold line so it can't push the teaser out */
  overflow: hidden;
}
.pivot-card__teaser {
  margin: 0;
  font-family: var(--font-read);
  font-size: .9rem;
  line-height: 1.42;
  color: var(--ink);
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;         /* bound the text so card height stays fixed (progress row below) */
  overflow: hidden;
}

/* ---- title cover (branding; slides up to begin) --------------------------- */
.cover {
  position: fixed; inset: 0; z-index: 250;   /* above the media overlay + nav pill at the very start */
  background: var(--segment-bg);   /* white, so the engraving's white ground blends in */
  display: flex; align-items: center; justify-content: center;
  padding: var(--gutter);
  will-change: transform;
  transition: transform var(--cover-dur) var(--snap-ease);
}
.cover.is-leaving { transform: translateY(-100%); }
.cover__inner { width: 100%; max-width: var(--max-w); text-align: center; }
.cover__img {
  display: block; width: 100%; max-width: 240px; height: auto; margin: 0 auto 26px;  /* 20% smaller */
}
.cover__title {
  font-family: var(--font-read); font-weight: 600; font-size: 2.4rem;
  color: var(--ink); margin: 0 0 8px; letter-spacing: .01em;
}
.cover__subtitle { font-family: var(--font-ui); font-size: .9rem; color: var(--ink-soft); margin: 0 0 32px; }
.cover__begin {
  font-family: var(--font-ui); font-size: 1rem; font-weight: 600;
  color: #fff; background: var(--pivot-line);
  border: none; border-radius: 999px; padding: 12px 40px;
}
.cover__begin:active { transform: translateY(1px); }
/* returning-reader secondary action + reset/intro copy */
.cover__startover {
  display: block; margin: 14px auto 0;
  font-family: var(--font-ui); font-size: .9rem; font-weight: 600;
  color: var(--ink-soft); background: none; border: none; padding: 8px 16px;
}
.cover__startover:active { transform: translateY(1px); }
.cover__intro {
  font-family: var(--font-ui); font-size: .92rem; line-height: 1.55;
  color: var(--ink); max-width: 30em; margin: 0 auto 30px; text-align: left;
}
.cover__note { font-family: var(--font-ui); font-size: .84rem; color: var(--here-ink); margin: 0 0 22px; }

/* ---- session setup screen (Stage 5) --------------------------------------- */
.setup {
  position: fixed; inset: 0; z-index: 50;
  background: var(--bg);
  display: flex; align-items: center; justify-content: center;
  padding: var(--gutter);
}
.setup__box { width: 100%; max-width: 360px; }
.setup__title { font-family: var(--font-ui); font-weight: 600; font-size: 1.1rem; color: var(--ink); margin-bottom: 22px; }
.setup__label { display: block; font-family: var(--font-ui); font-size: .82rem; color: var(--ink-soft); margin: 14px 0 6px; }
.setup__input {
  width: 100%; padding: 11px 12px; font-size: 1rem; font-family: var(--font-ui);
  border: 1px solid var(--segment-line); border-radius: 8px; background: var(--segment-bg); color: var(--ink);
}
.setup__choices { display: flex; gap: 8px; }
.setup__choices button {
  flex: 1; padding: 10px 6px; font-family: var(--font-ui); font-size: .82rem;
  border: 1px solid var(--segment-line); border-radius: 8px; background: var(--segment-bg); color: var(--ink-soft);
}
.setup__choices button.on { border-color: var(--pivot-line); color: var(--pivot-ink); background: var(--pivot-bg); font-weight: 600; }
.setup__begin {
  width: 100%; margin-top: 24px; padding: 13px; font-family: var(--font-ui); font-size: 1rem; font-weight: 600;
  border: none; border-radius: 8px; background: var(--pivot-line); color: #fff;
}
.setup__begin:disabled { opacity: .4; }
.setup__id { margin-top: 14px; font-family: ui-monospace, Menlo, monospace; font-size: .7rem; color: var(--ink-faint); text-align: center; }

/* ---- hidden researcher trigger + retrieval panel -------------------------- */
.corner-tap { position: fixed; bottom: 0; left: 0; width: 46px; height: 46px; z-index: 41; }
.panel { position: fixed; inset: 0; z-index: 260; background: rgba(0,0,0,.55); display: flex; align-items: center; justify-content: center; padding: var(--gutter); }
.panel__box { width: 100%; max-width: 420px; background: var(--segment-bg); border-radius: 12px; padding: 16px; }
.panel__row { font-family: var(--font-ui); font-size: .85rem; color: var(--ink); margin-bottom: 10px; }
.panel__log {
  width: 100%; height: 46vh; resize: none; font-family: ui-monospace, Menlo, monospace; font-size: .72rem;
  border: 1px solid var(--segment-line); border-radius: 8px; padding: 8px; color: var(--ink); background: #fbf9f5;
}
.panel__actions { display: flex; gap: 8px; margin-top: 12px; }
.panel__actions button {
  flex: 1; padding: 10px 6px; font-family: var(--font-ui); font-size: .8rem;
  border: 1px solid var(--segment-line); border-radius: 8px; background: var(--bg); color: var(--ink);
}

/* ---- incoming pivot target: dragged in from the right --------------------- */
.incoming {
  position: absolute;
  inset: 0;
  z-index: 5;
  background: var(--segment-bg);
  will-change: transform;
}
.incoming.animate { transition: transform var(--slide-in-dur) var(--snap-ease); }
.incoming .segment-card { position: absolute; inset: 0; height: 100%; }

/* delta-jump (#11): the target Branch card slides in from the right, OVER the index (z-210).
   Above the index, below the cover — the same right-in lateral grammar as a pivot destination. */
.jump-in { position: fixed; inset: 0; z-index: 220; background: var(--segment-bg); overflow: hidden; will-change: transform; }
.jump-in.animate { transition: transform var(--snap-dur) var(--snap-ease); }
.jump-in .segment-card { position: absolute; inset: 0; height: 100%; }

/* =========================================================================
   INDEX PAGE (wayfinding) — the location pill expands into the full page.
   See specs/design-tokens.md "Navigation & wayfinding motif".
   ========================================================================= */

/* the pill now carries "you are here"; the per-card byline header is retired,
   and prose starts below the floating pill */
.segment-card__here { display: none; }
/* segment title at the top of the card (v2 §5 — replaces the retired pill byline) */
.segment-card__head { padding: 20px var(--gutter) 6px; }
.segment-card__title { margin: 0; font-family: var(--font-read); font-weight: 600;
  font-size: 1.35rem; line-height: 1.22; color: var(--ink); }
.segment-card__prose { padding-top: 4px; }
.segment-card.node-card .segment-card__prose {
  padding-top: 0;
  display: flex; flex-direction: column;
  justify-content: center;          /* center the pivot stack — reachable by thumb without moving the hand */
  justify-content: safe center;     /* …but fall back to top-scroll if the stack ever overflows */
}

.idx-backdrop {
  position: fixed; inset: 0; z-index: 205;   /* above the media overlay (200), below the pill */
  background: rgba(40,36,30,0); pointer-events: none;
  transition: background .32s ease;
}
.idx-backdrop.show { background: rgba(40,36,30,.20); pointer-events: auto; }

/* v2 §5: the index is a full-screen page that slides in from the right (and out to the right),
   the same lateral grammar as a pivot swipe. It sits above the media overlay (z-200) and, when
   opened over media, pauses it — like swiping to a different page. */
.idx {
  position: fixed; inset: 0; z-index: 210;
  background: var(--segment-bg); overflow: hidden;
  display: flex; flex-direction: column;
  transform: translateX(100%); will-change: transform;
  transition: transform var(--snap-dur) var(--snap-ease);
  pointer-events: none;
}
.idx.open { transform: translateX(0); pointer-events: auto; }
/* jump-arrival closes the index with no slide/fade (the Branch card already covers it) */
.idx--instant { transition: none !important; }
.idx-close {
  position: absolute; top: calc(12px + env(safe-area-inset-top)); right: 14px; z-index: 2;
  width: 40px; height: 40px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--segment-bg); border: 1px solid var(--idx-border);
  font-size: 1.25rem; line-height: 1; color: var(--ink-soft); cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.idx-close:active { background: var(--nav-locked); }
.idx-head { position: relative; flex: 0 0 auto; height: calc(58px + env(safe-area-inset-top)); }

.idx-body {
  flex: 1 1 auto; overflow-y: auto; -webkit-overflow-scrolling: touch;
  padding: 0 var(--gutter) calc(16px + env(safe-area-inset-bottom));
  font-family: var(--font-ui);
}

.idx-sec { font-size: .66rem; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-faint); margin: 22px 0 11px; }
.idx-sec--gap { margin-top: 26px; }

/* World bar — name + overall progress + read/total */
.idx-world { margin: 2px 0 4px; }
.idx-world__row { display: flex; align-items: baseline; justify-content: space-between; margin-bottom: 9px; }
.idx-world__name { font-family: var(--font-read); font-weight: 600; font-size: 1.2rem; color: var(--ink); }
.idx-world__ratio { font-size: .82rem; color: var(--ink-soft); flex: 0 0 auto; margin-left: 10px; }
.idx-world__bar { display: block; height: 8px; border-radius: 5px; background: var(--nav-unexplored); overflow: hidden; }
.idx-world__bar > i { display: block; height: 100%; background: var(--nav-fill); transition: width var(--snap-dur) var(--snap-ease); }

/* STORIES — one row per Story: circle · name · furthest-fill-with-gaps bar · x/y */
.idx-story { display: flex; align-items: center; gap: 12px; padding: 9px 0; border-top: 1px solid var(--idx-divider); }
.idx-story__icon { --sz: var(--story-icon-index); }
/* a revealed Story icon jumps to that Story's first segment (read from the start) */
.idx-story__icon--jump { cursor: pointer; -webkit-tap-highlight-color: transparent; }
.idx-story__icon--jump:active { transform: scale(0.94); }
.idx-story__icon--jump:focus-visible { outline: 2px solid var(--nav-fill); outline-offset: 2px; border-radius: 50%; }
.idx-story__body { flex: 1 1 auto; min-width: 0; }
.idx-story__top { display: flex; align-items: baseline; justify-content: space-between; margin-bottom: 7px; }
.idx-story__name { font-size: .9rem; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.idx-story__ratio { font-size: .78rem; color: var(--ink-soft); flex: 0 0 auto; margin-left: 10px; }
/* v1 look: cells touch edge-to-edge, so consecutive seen segments read as one continuous fill and a
   break only shows where a segment is unseen (the "go explore" gap). No per-segment gap. */
.idx-track { height: 11px; border-radius: 6px; background: var(--nav-unexplored); overflow: hidden; display: flex; }
.idx-cell { flex: 1 1 0; }
.idx-cell.on { background: var(--nav-fill); }

/* BRANCHES — a list in story order (one row per Branch, easier to parse than a grid). Each row:
   mark · member Story icons sitting next to each other and next to the mark. Rows share the same
   top-divider look as the Stories list above. */
.idx-branches { display: flex; flex-direction: column; }
.idx-branch { display: flex; align-items: center; gap: 12px; padding: 10px 0; width: 100%;
  border: none; border-top: 1px solid var(--idx-divider); background: none;
  text-align: left; cursor: default; -webkit-tap-highlight-color: transparent; }
.idx-branch.seen { cursor: pointer; }
.idx-branch.seen:active { background: var(--nav-locked); }
.idx-branch__mark { width: 28px; height: 28px; flex: 0 0 auto; }
.idx-branch__mark.faded { opacity: .28; }
.idx-branch__members { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.idx-branch__member { --sz: 26px; }
/* a followed member (its destination has been visited) wears a gold ring to read as "already followed" */
.idx-branch__member--followed { box-shadow: 0 0 0 2px var(--nav-fill); }

/* =========================================================================
   Rich-media overlay (rich.js) — full-bleed VO + subtitles + panning images.
   A sibling of #app at a high z-index; the reader sits underneath untouched.
   ========================================================================= */
.rich { position: fixed; inset: 0; z-index: 200; background: #fff; overflow: hidden;
        touch-action: none;   /* pager uses pointer events — stop Safari stealing the vertical swipe as a scroll/bounce */
        -webkit-touch-callout: none; -webkit-user-select: none; user-select: none; }
.rich[hidden], .rich-end[hidden] { display: none !important; }
/* on-device debug readout — only shown with ?debug in the URL */
.rich-dbg { position: absolute; top: calc(58px + env(safe-area-inset-top)); left: 6px; z-index: 300;
  max-width: 62vw; font: 10px/1.35 ui-monospace, Menlo, monospace; white-space: pre; color: #0f0;
  background: rgba(0,0,0,.72); padding: 5px 7px; border-radius: 5px; pointer-events: none; }

/* TikTok-style vertical pager: prev/current/next stacked, joined edge-to-edge */
.rich-track { position: absolute; inset: 0; will-change: transform; }
.rich-page { position: absolute; left: 0; right: 0; height: 100%; }
.rich-page--prev { top: -100%; }
.rich-page--cur  { top: 0; }
.rich-page--next { top: 100%; }

/* AIRTIGHT no-stray-frame: the image layer can't paint until the segment clock reveals it (rich.js sets
   visibility:visible only once the title has begun to lift). So no image EXISTS on screen during the
   title beat, independent of z-order / opacity / any render-race. */
.rich-imgs { position: absolute; inset: 0; visibility: hidden; }
.rich-imgs img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
  object-position: 50% 50%; opacity: 0; transition: opacity .35s ease; background: #fff;
  will-change: transform, object-position;
  pointer-events: none; -webkit-touch-callout: none; -webkit-user-drag: none; }
.rich-imgs img.on { opacity: 1; }
/* Cheshire fallback: small, centered — ~75% width, no full-bleed cover, no pan */
.rich-imgs img.cat { inset: auto; left: 50%; top: 50%; width: 75%; height: auto; max-height: 78%;
  object-fit: contain; transform: translate(-50%, -50%); }

/* Narrowed on both sides to clear the right rail (right:14, 44px wide), and dropped into the white
   letterbox beneath a centered landscape image. Sits above the scrub bar + Read toggle (~62px).
   May overlay taller/portrait images — acceptable. */
.rich-capwrap { position: absolute; left: 64px; right: 64px; bottom: calc(120px + env(safe-area-inset-bottom));
  display: flex; justify-content: center; pointer-events: none; }
.rich-cap { display: inline-block; max-width: 560px; text-align: center; font-family: Georgia, serif;
  font-size: 1.25rem; line-height: 1.45; font-weight: 600; color: #fff;
  background: rgba(0,0,0,.6); padding: 6px 13px; border-radius: 6px; }

/* Per-page title: the OPENING of each segment's own timeline, INSIDE its pager page, so it moves with
   the segment in the roll (TikTok) and presents as one baked clip. Opacity is driven imperatively by
   the segment clock in rich.js (the current page dissolves along the title beat; neighbours sit opaque
   on their own title until they become current). */
.rich-ptitle { position: absolute; inset: 0; z-index: 2;
  display: flex; align-items: center; justify-content: center; padding: 0 calc(var(--gutter) + 8px);
  background: var(--segment-bg);
  font-family: var(--font-read); font-weight: 600; font-size: 1.9rem; line-height: 1.24;
  color: var(--ink); text-align: center;
  opacity: 0; pointer-events: none; }

/* #13.2: scrub bar — bottom-anchored, larger hit area, more prominent (seek behaviour unchanged).
   Full-width so the fill maps 1:1 to seekTo's scrubEl rect; a bottom scrim keeps it legible on any image. */
.rich-scrub { position: absolute; left: 0; right: 0; bottom: 0; z-index: 6;
  height: calc(44px + env(safe-area-inset-bottom));
  padding-bottom: calc(8px + env(safe-area-inset-bottom));
  display: flex; align-items: flex-end; touch-action: none; cursor: pointer;
  background: linear-gradient(to top, rgba(0,0,0,.4), rgba(0,0,0,0)); }
.rich-vprog { position: relative; width: 100%; height: 7px; background: rgba(255,255,255,.32); overflow: hidden; }
.rich-vprog > i { display: block; height: 100%; width: 0; background: var(--pivot-line); }

.rich-tap { position: absolute; inset: 0; z-index: 4; display: flex; align-items: center;
  justify-content: center; pointer-events: none; opacity: 0; transition: opacity .2s ease; }
.rich-tap.show { opacity: 1; }
.rich-tap i { width: 80px; height: 80px; border-radius: 50%; background: rgba(0,0,0,.4);
  display: flex; align-items: center; justify-content: center; }
.rich-tap svg { width: 34px; height: 34px; margin-left: 4px; }

.rich-ff { position: absolute; top: calc(64px + env(safe-area-inset-top)); left: 0; right: 0; z-index: 5;
  text-align: center; pointer-events: none; opacity: 0; transition: opacity .15s ease; }
.rich-ff.show { opacity: 1; }
.rich-ff span { font-family: var(--font-ui); font-weight: 700; font-size: .78rem; color: #fff;
  background: rgba(0,0,0,.5); padding: 4px 12px; border-radius: 999px; }

/* The Read toggle occupies the SAME slot as the rail's media button (which is visibility:hidden in
   media mode), so it must match that circle exactly: 44px, right:14, bottom:18 — see .rail / .rail-media. */
.rich-toggle { position: fixed; bottom: calc(18px + env(safe-area-inset-bottom)); right: 14px; z-index: 8;
  width: 44px; height: 44px; padding: 0;
  border: 1px solid var(--segment-line); border-radius: 50%; background: var(--segment-bg);
  box-shadow: 0 2px 8px rgba(0,0,0,.12); display: flex; align-items: center; justify-content: center; }
.rich-toggle svg { width: 22px; height: 22px; }

/* end-of-Story beat in media: the last image dims and the end copy fades in over it (#12 in media) */
.rich-end { position: absolute; inset: 0; z-index: 7;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 26px;
  padding: 0 var(--gutter); text-align: center;
  background: rgba(20,17,13,.72); animation: rich-end-in .8s ease both; }
@keyframes rich-end-in { from { opacity: 0; } to { opacity: 1; } }
.rich-end__text { max-width: 32ch; font-family: var(--font-read); font-size: 1.2rem; line-height: 1.5; color: #fff; }
.rich-end__text:empty { display: none; }
.rich-end button { background: #fff; color: var(--ink); border: none; border-radius: 999px;
  padding: 12px 30px; font-weight: 600; font-family: var(--font-ui); }

/* Right-hand rail (feature-read-motion §4): World-progress pie · Story icons · media button.
   The media button lives here now — the old floating listen FAB is gone, not duplicated.
   Placement is provisional (a Workstream-E user-testing question). */
/* z:205 keeps the rail above the media overlay (200) — it stays visible in media mode — while the
   index (210) and cover (250) still cover it. Original bottom-right position; identical in read and
   media so the layout never jumps between them. */
.rail { position: fixed; z-index: 205;
  right: 14px; bottom: calc(18px + env(safe-area-inset-bottom));
  display: flex; flex-direction: column; align-items: center; gap: 13px;
  pointer-events: none; }   /* container passes taps through; only the buttons catch them, so the
                               media overlay's Read toggle stays tappable beneath the reserved slot */
.rail button { -webkit-tap-highlight-color: transparent; pointer-events: auto; }
/* In media mode the media button is redundant; hide it but KEEP its slot so the rail doesn't reflow.
   visibility:hidden also drops it as a pointer target, so the Read toggle beneath shows through and works. */
.rail-media--reserved { visibility: hidden; }

/* Every rail circle is the same 44px diameter, centred on one vertical axis (align-items:center). */
.rail-pie { width: 44px; height: 44px; padding: 0; border: none; background: none; cursor: pointer; display: block; }
.rail-pie__svg { width: 100%; height: 100%; display: block; }
.rail-pie__bg    { fill: var(--nav-unexplored); }        /* the empty pie */
.rail-pie__wedge { fill: none; stroke: var(--nav-fill); stroke-width: 17;   /* fills centre→rim = a solid sector */
  transition: stroke-dasharray var(--snap-dur) var(--snap-ease); }
.rail-pie__ring  { fill: none; stroke: var(--idx-border); stroke-width: 1; }

.rail-story.story-icon { --sz: 44px; padding: 0; cursor: pointer; }   /* compound beats .story-icon's own --sz */

.rail-media { width: 44px; height: 44px; padding: 0; cursor: pointer;
  border: 1px solid var(--segment-line); border-radius: 50%; background: var(--segment-bg); color: var(--pivot-line);
  display: flex; align-items: center; justify-content: center; box-shadow: 0 2px 8px rgba(0,0,0,.12); }
.rail-media svg { width: 22px; height: 22px; }
.rail-media:active { transform: translateY(1px); }

/* ---- Story icon (assets-stories.md §8) -------------------------------------
   One source image masked into a circle at --sz (set per use: door / rail /
   index). Monogram placeholder shows through when the image is missing; the
   "--unknown" variant is the "?" for an undiscovered Story / Branch member.
   Reused on the pivot card, the segment-page rail, and the index. */
.story-icon {
  --sz: var(--story-icon-index);
  position: relative; flex: 0 0 auto;
  width: var(--sz); height: var(--sz);
  border-radius: 50%; overflow: hidden;
  background: var(--story-icon-bg);
  border: 1px solid var(--story-icon-ring);
  display: inline-flex; align-items: center; justify-content: center;
  vertical-align: middle;
}
.story-icon__mono {
  font-family: var(--font-ui); font-weight: 600; line-height: 1;
  color: var(--here-ink); font-size: calc(var(--sz) * 0.42);
  user-select: none;
}
.story-icon__img {                 /* covers the circle; object-position = focal */
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; background: var(--story-icon-bg);
}
.story-icon--unknown { background: var(--nav-locked); border-color: transparent; }
.story-icon--unknown .story-icon__mono { color: var(--ink-faint); font-weight: 400; }

/* one-time storage-unavailable notice — non-blocking bar, tap to dismiss */
.storage-note {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 60;
  padding: calc(10px + env(safe-area-inset-bottom)) 16px 10px;
  background: var(--node-bg); color: var(--ink-soft); border-top: 1px solid var(--segment-line);
  font-family: var(--font-ui); font-size: .82rem; text-align: center;
}
