/* Episode landing pages (/episode/<item-guid>), rendered by
 * functions/episode/[guid].js.
 *
 * THE DELTAS ONLY. The page links show-page.css and reuses its `.show-*`
 * classes verbatim — the hero, the stat tiles, the Nostr Community wall and the
 * boost list are the same components, emitted by the same functions in
 * functions/_shared/detail-page.js, and a parallel set of `.episode-*` names for
 * identical boxes would be a rename with no meaning behind it. The site already
 * keeps `lb-*` and `.sup-*` for exactly this reason; see the naming note in
 * CLAUDE.md.
 *
 * It also links feed-cards.css, because the community-episodes section paints
 * the homepage's episode card. That file needs --accent / --accent-d / --tint,
 * which show-page.css supplies on .show-main.
 *
 * Load order matters and is fixed in the Function's <head>: show-page.css, then
 * feed-cards.css, then this.
 */

/* ── Hero ─────────────────────────────────────────────────────────────── */

/* The eyebrow is the show's name and a link to its page, where /show's is the
   bare word "Show". Inherits the eyebrow's uppercase brand treatment and only
   adds the affordance — it is the one thing on the page that says which feed
   this episode belongs to, so it has to read as a way out. */
.show-eyebrow a {
  color: inherit;
  text-decoration: none;
  border-bottom: 1px solid transparent;
}
.show-eyebrow a:hover {
  border-bottom-color: currentColor;
}

/* An episode title is longer than a show's and is the page's subject, so it
   wraps to more lines before it is worth shrinking. .show-ident h1's clamp is
   otherwise unchanged. */
.show-main--episode .show-ident h1 {
  font-size: clamp(1.35rem, 3.4vw, 2rem);
}

/* The player sits under the hero's identity block rather than inside it: a long
   title already competes with the artwork for that row, and the control is
   full-width by nature. Above the stat tiles, because playing the episode is
   what a reader came for and reading its numbers is what they stayed for. */
.ep-player-row {
  margin: 1.1rem 0;
}
.ep-player-row .pcast-player {
  width: 100%;
  display: block;
}

/* ── The player card, and the two drawers inside it ───────────────────── */

/* ONE CARD holds the artwork, the title, the actions, the player, the chapters
   and the show notes — everything about the recording. The stat tiles sit
   outside it on the page background, because they are about its BOOSTS and they
   are the same tiles /show has, in the same place. localbitcoiners' episode
   pages are the reference: .ep-card there is a white bordered panel with the
   player and both disclosures inside it.

   Scoped to .show-main--episode rather than styling .show-hero, which the show
   page shares and where there is nothing to enclose. */
.show-main--episode .ep-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 1.4rem 1.4rem 0;
  box-shadow: 0 4px 16px rgba(11, 58, 82, 0.06);
  overflow: hidden;
}

/* The drawers reuse .ep-drawer from show-page.css — the sunken band, the
   SHOW/HIDE word, the rotating chevron — so this file adds only where they sit
   and what is inside them. A reader who has opened the episode drawer on
   /show/<guid> has already learned the control.

   ⚠️ THEY BLEED TO THE CARD'S EDGES rather than sitting inside its padding as
   nested boxes, which is what makes the card read as one object with bands
   rather than as a panel with two panels in it. Same move LB makes with its
   shownotes disclosure. The negative margins therefore have to match the card's
   padding above, and the card clips them with overflow:hidden so its rounded
   corners survive.

   Both ship collapsed. See the note in functions/episode/[guid].js for why the
   chapter list is not open by default the way localbitcoiners' is. */
.show-main--episode .ep-chapters,
.show-main--episode .ep-notes {
  margin: 0 -1.4rem;
  border: 0;
  border-top: 1px solid var(--border);
  border-radius: 0;
}
/* The air above the first band belongs to .ep-player-row's own bottom margin
   rather than to the drawers: which drawer comes first depends on whether this
   episode has chapters, so a margin on the drawers would vanish with the hidden
   one. That margin is also what closes the card when neither drawer renders —
   .ep-card has no bottom padding, and its overflow:hidden makes it a block
   formatting context, so the margin cannot escape it. */
/* <details> carries a UA `display: block`, and the attribute selector outranks
   it, but this page hides a drawer as a normal state rather than an edge case —
   worth stating rather than inheriting. */
.ep-drawer[hidden] { display: none; }

/* Capped and scrolled for the same reason .ep-list is on the show page: a long
   list inside a drawer should not make the page endless. 22rem is about eleven
   rows, which is the length at which a chapter list stops being a glance. */
.ep-chapters-list {
  list-style: none;
  margin: 0;
  padding: 0.25rem 0;
  max-height: 22rem;
  overflow-y: auto;
  overscroll-behavior: contain;
  border-top: 1px solid var(--border);
}
.ep-chapter { margin: 0; }

/* A row is a button, not a link: it seeks the player on this page rather than
   navigating. The left border is the rail the active marker slides down, and it
   is reserved on every row so the list does not shift by 3px when playback
   crosses a boundary. */
.ep-chapter-btn {
  display: flex;
  align-items: baseline;
  gap: 0.75rem;
  width: 100%;
  padding: 0.5rem 1rem;
  text-align: left;
  background: transparent;
  border: 0;
  border-left: 3px solid transparent;
  font: inherit;
  color: var(--ink);
  cursor: pointer;
  transition: background 0.12s, border-color 0.12s, color 0.12s;
}
.ep-chapter-btn:hover { background: var(--cream); color: var(--brand-dd); }
.ep-chapter-btn:focus-visible { outline: 2px solid var(--brand); outline-offset: -2px; }

.ep-chapter-time {
  flex: none;
  min-width: 3.2rem;
  /* Tabular figures so the timestamps form a column rather than a ragged edge
     as the minute digits change width. */
  font-variant-numeric: tabular-nums;
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--muted);
}
.ep-chapter-btn:hover .ep-chapter-time { color: var(--brand-d); }

.ep-chapter-title {
  font-size: 0.95rem;
  line-height: 1.4;
  overflow-wrap: anywhere;
}

/* The row covering the playhead, set by episode-page.js as the audio advances.
   Brand on the rail rather than a background wash strong enough to compete with
   hover — the two states have to be distinguishable while the pointer is inside
   the list. */
.ep-chapter-btn.is-active {
  background: var(--cream);
  border-left-color: var(--brand);
  color: var(--ink);
}
.ep-chapter-btn.is-active .ep-chapter-time { color: var(--brand-dd); }
.ep-chapter-btn.is-active .ep-chapter-title { font-weight: 600; }

/* Show notes.
 *
 * TWO SHAPES IN ONE BOX, and they arrive in that order. The server renders D1's
 * copy as a single <p> — the collector's clean_html has flattened every
 * paragraph break out of it — and episode-page.js replaces that with the
 * publisher's real paragraphs once /api/episode-meta answers. So the rhythm
 * between paragraphs has to be right even though the first paint has only one,
 * and it is also capped: a full note runs to several thousand characters where
 * the truncated one is ~590. */
.ep-notes-body {
  padding: 0.95rem 1rem 1.15rem;
  border-top: 1px solid var(--border);
  max-height: 34rem;
  overflow-y: auto;
  overscroll-behavior: contain;
  font-size: 0.95rem;
  line-height: 1.7;
  color: var(--text);
  overflow-wrap: anywhere;
}
.ep-notes-body p { margin: 0; max-width: 46rem; }
.ep-notes-body p + p { margin-top: 0.85rem; }
.ep-notes-body a { color: var(--brand-d); font-weight: 600; }
.ep-notes-body a:hover { color: var(--brand-dd); }

/* ── The community drawer's stacked summary ───────────────────────────── */

/* "Other Episodes/Songs This Community Boosts" carries a line saying what the
   list actually is, and it belongs against the NAME of the list rather than in
   the toolbar below it, where it would crowd the range buttons off a phone.
   .ep-drawer > summary is a centered flex row, so the pair is one column inside
   it and .drawer-hint's margin-left:auto still pins the SHOW/HIDE word right. */
.cs-head {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  min-width: 0;
}
/* The title inherits the summary's Playfair; the sub-line deliberately does not
   — it is a caption, and setting it in the display face at a small size reads as
   a subtitle competing with the heading rather than as a note under it. */
.cs-head-sub {
  font: 400 0.78rem/1.45 -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  color: var(--muted);
}

/* ── Other Episodes/Songs This Community Boosts ───────────────────────── */

/* The one client-rendered section on either detail page, and the same OBJECT as
   the show page's community drawer: an .ep-drawer whose <summary> is the
   heading, with the sort band inside the lid. Only the rows differ, because
   these are full episode cards where those are 44px links.

   The SECTION ships empty and its DRAWER ships hidden, which is not
   interchangeable: episode-page.js watches the section with an
   IntersectionObserver to decide when to pull the card renderer, and an observer
   never fires on a display:none target. An empty section is a zero-height block
   that still has a position. Everything else here describes a state the server
   never emits. */

/* No margin of its own until it has content. .show-section carries a 2.75rem top
   margin, and an unhydrated section is empty, so with JavaScript off that margin
   lands between the hero and the community wall and doubles one gap. Degrades to
   exactly that where :has() is unsupported, which is why it is worth having and
   not worth working around. */
#community-episodes:has([data-ce-body][hidden]) { margin-top: 0; }

/* The control band is .cs-controls unmodified — the same tinted lid-and-toolbar
   stack both drawers on /show have. It carried a set of overrides that flattened
   it into a plain row, from when this section was a bare <h2> with controls
   under it rather than a drawer; those are gone, and the only delta left is the
   one below. */

/* .cs-controls pins its sort to the far end with margin-left:auto, because the
   show page's episode drawer puts a "See All Episodes" link at the other end of
   the same band. There is no second control here — the range group is the sort's
   partner, not its opposite — so the pair sits together at the right the way it
   does in the homepage's feed bar. */
.ce-controls .pcast-sort { margin-left: 0; }

/* The scroll container.
 *
 * Same intent as .ep-list on the show page — cap the section and scroll inside
 * it rather than making the page endless — but deliberately NOT the same 32rem.
 * That number was chosen for 44px rows, where it shows eleven of them; a card
 * here is ~180px, so 32rem would be two and a half cards and read as a bug. The
 * cap is a share of the VIEWPORT instead, which is the honest expression of what
 * it is for: leave the reader a screenful of list and keep the rest of the page
 * reachable. 46rem is the ceiling on a tall desktop, where 75vh would otherwise
 * be most of the document again.
 *
 * ⚠️ overflow CLIPS the card's ⋮ subscribe menu and the per-boost ⋮ menu, both of
 * which are position:absolute. They still contribute to the container's scroll
 * height, so an opened menu near the bottom edge is reachable rather than lost,
 * and episodeCard scrolls it into view on open. The alternative is a portal or a
 * popover, which is a rewrite of a component the homepage shares. That trade is
 * the price of the container and it is worth stating rather than discovering.
 */
.ce-scroll {
  max-height: min(75vh, 46rem);
  overflow-y: auto;
  /* Stop a flick at the bottom of the list from carrying on into the page —
     the box is the thing being scrolled, so it should absorb the gesture. */
  overscroll-behavior: contain;
  /* A hairline lid, the way .ep-list has one on the show page. No floor: the
     drawer's own bottom border is the floor now, and a second line one pixel
     above it read as a doubled edge. */
  border-top: 1px solid var(--border);
  /* Room for .pcast-card's hover shadow and its focus ring, which would
     otherwise be shaved off against the container's edges. */
  padding: 0.45rem 0.35rem;
}
.ce-scroll:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }

/* The load-more sits INSIDE the container, so it needs less air above it than
   the feed's does at the foot of a page. */
.ce-scroll .pcast-more-wrap { margin-top: 0.8rem; margin-bottom: 0.2rem; }

.ce-loading {
  padding: 1.75rem 0;
  text-align: center;
  color: var(--muted);
  font-size: 0.88rem;
}

/* The truncation note, printed under the last page of cards when the endpoint
   capped the corpus. Quiet and at the foot deliberately: it is an answer for a
   reader who reached the end of a long list, not a warning over the top of one.
   See the cap note in functions/api/v1/episodes/[guid].js. */
.ce-note {
  margin: 1.1rem auto 0;
  max-width: 34rem;
  text-align: center;
  color: var(--muted);
  font-size: 0.78rem;
  line-height: 1.5;
}

/* The cards are a grid of their own inside a .show-section, which has no
   list-reset of its own to inherit from. */
.show-main--episode .pcast-list {
  margin-top: 0.4rem;
}

@media (max-width: 640px) {
  /* The card's padding comes in, and the drawers' negative margins have to
     follow it exactly or the bands stop meeting the card's edges. */
  .show-main--episode .ep-card { padding: 1rem 1rem 0; border-radius: 12px; }
  .show-main--episode .ep-chapters,
  .show-main--episode .ep-notes { margin-left: -1rem; margin-right: -1rem; }
  .ep-chapter-btn { padding: 0.5rem 0.8rem; }
  .ep-notes-body { padding: 0.85rem 0.8rem 1rem; }
  /* The stacked summary is two lines before the SHOW/HIDE word gets a column of
     its own; keep the caption legible rather than letting it shrink with the
     heading. */
  .cs-head-sub { font-size: 0.74rem; }
}
