/* Timora — cinematic, restrained. One accent, no gradients, posters first. */

:root {
  --bg: #0e0e10;
  --surface: #17171a;
  --surface-2: #1e1e22;
  --text: #f0efec;
  --muted: #94938c;
  --faint: #55544f;
  --accent: #d4a44c;
  --danger: #c96a5a;
  --line: rgba(255, 255, 255, 0.07);
  --radius: 10px;
  --radius-lg: 16px;
  --ease: cubic-bezier(0.2, 0.7, 0.3, 1);
  /* motion: exponential ease-outs only, short durations; motion reports
     state (arrived, opened, progressed), it never decorates */
  --ease-out-quint: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-out-quart: cubic-bezier(0.25, 1, 0.5, 1);
  --dur-1: 150ms;
  --dur-2: 220ms;
  --dur-3: 320ms;
  /* State changes move transform, opacity or grid rows. The deliberate
     paint-only exceptions: hover/focus colour feedback (color, background,
     border, underline colour) on small controls, the composer's focus
     border and shadow, and the tab highlight's clip-path window (a scaled
     pill squashes its rounded ends). None of them triggers layout. */
  /* chat type scale: secondary text, body, the empty-state heading, and
     tool output. Half-pixel steps between them read as inconsistency, not
     hierarchy; the composer's input is body size, 16px on touch screens
     only, so iOS does not zoom it. */
  --fs-sm: 13px;
  --fs-md: 15px;
  --fs-lg: 22px;
  --fs-mono: 12px;
  --safe-b: env(safe-area-inset-bottom, 0px);
  --safe-t: env(safe-area-inset-top, 0px);
  /* page gutter — one var so full-bleed sections (hero) can escape it;
     --edge is the dead space main's centered max-width leaves on each side,
     so full-bleed children can re-align their text with the content column */
  --pad-x: 20px;
  --edge: max(0px, calc((100vw - 1100px) / 2));
}

/* The chat composer's live height (app.js, ResizeObserver). Registered as
   non-inherited and set only on what reads it: body (its ::after band and
   the toast inherit it explicitly) and the chat log. While the composer's
   status line unfolds it changes every frame for 220ms; on :root, each write
   restyled the whole document, which grows with the thread. Browsers without
   @property inherit it from body, as before. */
@property --composer-h { syntax: "<length>"; inherits: false; initial-value: 120px; }

* { box-sizing: border-box; margin: 0; padding: 0; }

html { background: var(--bg); }

body {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  background: var(--bg);
  color: var(--text);
  -webkit-font-smoothing: antialiased;
  -webkit-tap-highlight-color: transparent;
  min-height: 100vh;
  min-height: 100dvh;
  padding-bottom: calc(76px + var(--safe-b));
  /* the hero's 50vw full-bleed can overhang by a scrollbar's width */
  overflow-x: clip;
}

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* Transitions are 0s, not 0.01ms: transition-property defaults to "all",
   so a non-zero duration here gave every element a one-frame transition on
   every property, including ones nothing animates. Padding and heights then
   landed a frame late, and code that measured right after a change (keeping
   a reader at the end of the chat, placing the header under the dock) read
   the old layout. No script waits for transitionend. Animations keep a tiny
   duration so `forwards`/`both` fills still land on their end state. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0s !important;
  }
}

/* ---------- chrome ---------- */

.top {
  max-width: 1100px;
  margin: 0 auto;
  padding: calc(14px + var(--safe-t)) 10px 4px 20px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  min-height: calc(56px + var(--safe-t));
}

.wordmark {
  display: inline-block;
  font-size: 15px;
  font-weight: 600;
  letter-spacing: 0.34em;
  text-transform: uppercase;
  color: var(--accent);
}

main {
  padding: 12px var(--pad-x) 24px;
  max-width: 1100px;
  margin: 0 auto;
}

/* The dock is always one line: Discover · Chat · Library. With left: 50%
   its shrink-to-fit width is only half the viewport, which once wrapped a
   long tab label onto a second line; size it to its tabs instead. "safe
   center" falls back to start alignment, so a dock that ever overflows
   scrolls rather than clipping its first or last tab. */
.tabs {
  position: fixed;
  bottom: calc(10px + var(--safe-b));
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  justify-content: safe center;
  gap: 2px;
  padding: 5px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: rgba(23, 23, 26, 0.88);
  -webkit-backdrop-filter: saturate(140%) blur(18px);
  backdrop-filter: saturate(140%) blur(18px);
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.5);
  z-index: 30;
  width: max-content;
  max-width: calc(100vw - 24px);
  overflow-x: auto;
  scrollbar-width: none;
}
.tabs::-webkit-scrollbar { display: none; }
/* One neutral highlight slides between tabs: a clip-path window on a layer
   behind the labels (app.js sets --tab-window), so the pill keeps its exact
   shape in motion. Gold stays for actions. */
.tabs::before {
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(255, 255, 255, 0.09);
  clip-path: var(--tab-window, inset(50% 50% 50% 50% round 999px));
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--dur-1) var(--ease-out-quint);
}
.tabs.has-active::before { opacity: 1; }
.tabs.tabs-animate::before { transition: clip-path var(--dur-2) var(--ease-out-quint), opacity var(--dur-1) var(--ease-out-quint); }

/* Desktop: the dock moves to the top of the page, streaming-site style,
   centred between the wordmark and the account button. */
@media (min-width: 720px) {
  .tabs {
    bottom: auto;
    top: calc(12px + var(--safe-t));
  }
  body { padding-top: 64px; padding-bottom: 40px; }
  /* The header spans the width so the account button sits at the right; it
     lets clicks through to the dock between its children. */
  .top {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 31;
    max-width: none;
    min-height: 0;
    height: calc(64px + var(--safe-t));
    padding: calc(8px + var(--safe-t)) 12px 0 20px;
    pointer-events: none;
  }
  .top > * { pointer-events: auto; }
}

/* Wide desktop: let every page breathe across the screen. */
@media (min-width: 1200px) {
  :root {
    --pad-x: max(40px, calc((100vw - 1720px) / 2));
    --edge: 0px; /* main is full-width here; the gutter is the whole story */
  }
  main {
    max-width: none;
    padding-left: var(--pad-x);
    padding-right: var(--pad-x);
  }
}

.tab {
  position: relative;
  appearance: none;
  border: 0;
  background: none;
  color: var(--muted);
  font: inherit;
  font-size: 14px;
  font-weight: 500;
  padding: 10px 20px;
  border-radius: 999px;
  cursor: pointer;
  flex: none;
  white-space: nowrap;
  transition: color var(--dur-2) var(--ease-out-quint);
}
.tab[hidden] { display: none !important; }
.tab.active { color: var(--text); }

@media (hover: hover) {
  .tab:not(.active):hover,
  .chip:not(.active):hover,
  .season-chip:not(.on):hover { color: var(--text); }
  .cta:not(:disabled):hover { opacity: 0.9; }
  .linklike:hover { text-decoration: underline; }
}

/* ---------- account ---------- */
/* One quiet button at the top right; its menu holds Messages, Admin,
   Sessions & credentials and Sign out. */
.account { position: relative; flex: none; }
.account-button {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 36px;
  max-width: 44vw;
  padding: 6px 10px 6px 12px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--muted);
  font: inherit;
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  transition: color var(--dur-1) var(--ease-out-quint), background-color var(--dur-1) var(--ease-out-quint);
}
.account-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.account-button svg { flex: none; transition: transform var(--dur-2) var(--ease-out-quint); }
.account-button.is-open svg { transform: rotate(180deg); }
.account-button.is-open, .account-button.is-current { color: var(--text); background: var(--surface); }
@media (hover: hover) { .account-button:hover { color: var(--text); background: var(--surface); } }
@media (pointer: coarse) { .account-button { min-height: 44px; } }
.account-menu {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  z-index: 40;
  min-width: 220px;
  max-width: calc(100vw - 24px);
  padding: 5px;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: var(--surface);
  box-shadow: 0 18px 48px rgba(0, 0, 0, 0.55);
  transform-origin: top right;
  animation: account-menu-in 160ms var(--ease-out-quint) both;
}
.account-menu.is-leaving { animation: account-menu-out 120ms var(--ease-out-quart) forwards; pointer-events: none; }
@keyframes account-menu-in { from { opacity: 0; transform: translateY(-4px) scale(0.98); } }
@keyframes account-menu-out { to { opacity: 0; transform: translateY(-2px); } }
.account-item {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  width: 100%;
  min-height: 38px;
  padding: 9px 11px;
  border: 0;
  border-radius: 9px;
  background: transparent;
  color: var(--text);
  font: inherit;
  font-size: 14px;
  text-align: left;
  cursor: pointer;
  transition: background-color var(--dur-1) var(--ease-out-quint), color var(--dur-1) var(--ease-out-quint);
}
.account-item-label { display: inline-flex; align-items: center; gap: 6px; }
.account-item-label svg { color: var(--muted); }
.account-item-note { max-width: 240px; color: var(--muted); font-size: 12px; line-height: 1.4; }
/* Keyboard focus needs more than the 1.08:1 surface step hover uses: the
   gold ring every other control has, drawn inside the item. Hover moves
   focus (app.js), so one item is highlighted at a time. */
.account-item:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; background: var(--surface-2); }
.account-item[aria-disabled="true"] { cursor: default; color: var(--muted); }
.account-item[aria-current="page"] .account-item-label::after {
  content: "";
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--muted);
}
.account-separator { height: 1px; margin: 5px 6px; background: var(--line); }
.account-sign-out { color: var(--muted); }
.account-sign-out.is-armed { color: var(--danger); }
@media (hover: hover) { .account-item:not([aria-disabled="true"]):hover { background: var(--surface-2); } }
@media (pointer: coarse) { .account-item { min-height: 44px; } }
@media (prefers-reduced-motion: reduce) {
  .account-menu, .account-menu.is-leaving { animation: none; }
  .account-button svg, .tabs.tabs-animate::before { transition: none; }
}

/* ---------- discover ---------- */

.searchbar {
  display: block;
  width: 100%;
  appearance: none;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--surface);
  color: var(--text);
  font: inherit;
  font-size: 17px;
  padding: 13px 20px;
  margin: 4px 0 20px;
  outline: none;
  transition: background-color 180ms var(--ease), border-color 180ms var(--ease);
}

.searchbar::placeholder { color: var(--muted); }
.searchbar:focus { background: var(--surface-2); border-color: rgba(212, 164, 76, 0.55); }

.chips {
  display: flex;
  gap: 8px;
  margin: 0 0 18px;
  overflow-x: auto;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}

.chips::-webkit-scrollbar { display: none; }
.chips .chip { flex: 0 0 auto; }

@media (max-width: 520px) {
  /* Let the overflowing Discover filters scroll all the way to the viewport
     edges while preserving the page gutter in their resting position. */
  .searchbar + .chips {
    margin-inline: calc(50% - 50vw);
    padding-inline: calc(var(--edge, 0px) + var(--pad-x));
  }
}

.chip {
  appearance: none;
  border: 0;
  background: var(--surface);
  color: var(--muted);
  font: inherit;
  font-size: 13px;
  font-weight: 500;
  padding: 8px 14px;
  border-radius: 999px;
  cursor: pointer;
  transition: color 160ms var(--ease), background-color 160ms var(--ease);
}

.chip.active { background: var(--surface-2); color: var(--text); }

/* ---------- library page ---------- */

.library-switcher { margin: 4px 0 0; }

.library-page {
  display: flow-root;
}

.library-page-section {
  margin-top: 30px;
}

.library-section-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 14px;
}

.library-section-head .section-title,
.library-section-head .linklike {
  margin: 0;
}

.library-section-action {
  flex: none;
  font-size: 13px;
  text-decoration: none;
}

.library-page-section .empty {
  padding-top: 42px;
  padding-bottom: 42px;
}

.library-page > .banner { margin-top: 30px; }
.library-page .cta.continue-watching { margin-top: 0; }

.library-filter-row {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  margin: 0 0 18px;
  padding-bottom: 2px;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}

.library-filter-row::-webkit-scrollbar { display: none; }

.library-filter-row .genre-chip {
  flex: 0 0 auto;
  min-width: 0;
  border-radius: 999px;
  padding: 8px 14px;
  font-size: 13px;
  font-weight: 500;
}

/* ---------- native music ---------- */

.music-shelf {
  align-items: flex-start;
}

.music-card {
  appearance: none;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  text-align: left;
  display: block;
  min-width: 0;
  cursor: pointer;
  padding: 0;
  -webkit-user-select: none;
  user-select: none;
}

.music-art {
  display: flex;
  position: relative;
  aspect-ratio: 1;
  align-items: flex-end;
  overflow: hidden;
  border-radius: var(--radius);
  background: var(--surface);
  box-shadow: inset 0 0 0 1px var(--line);
  transition: transform 180ms var(--ease), box-shadow 180ms var(--ease);
}

.music-card:active .music-art { transform: scale(.965); }
@media (hover: hover) {
  .music-card:hover .music-art {
    transform: translateY(-4px) scale(1.02);
    box-shadow: 0 14px 32px rgba(0, 0, 0, .5);
  }
}

.music-art img { width: 100%; height: 100%; object-fit: cover; display: block; }
.music-fallback { padding: 13px; color: var(--muted); font-size: 13px; line-height: 1.35; }
.music-meta, .music-title, .music-sub { display: block; }
.music-meta { margin-top: 8px; font-size: 13px; line-height: 1.3; }
.music-title {
  display: -webkit-box;
  overflow: hidden;
  font-size: 13px;
  font-weight: 500;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
}
.music-sub { margin-top: 2px; color: var(--muted); font-size: 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.music-grid .music-card { width: 100%; }
.skel .music-art { animation: pulse 1.4s ease-in-out infinite; }

.music-list { border-top: 1px solid var(--line); }
.music-list-row { display: flex; justify-content: space-between; gap: 18px; padding: 13px 2px; border-bottom: 1px solid var(--line); color: var(--muted); font-size: 13px; }
.music-list-row strong, .music-list-row small { display: block; color: var(--text); }
.music-list-row small { margin-top: 3px; color: var(--muted); font-size: 11px; text-transform: capitalize; }
.music-sheet-head { display: flex; align-items: center; gap: 18px; margin: 10px 0 24px; }
.music-sheet-head .music-art.large { flex: 0 0 128px; }
.music-sheet-head h2 { margin: 0; }

.music-download-option {
  display: flex;
  flex-direction: column;
  gap: 3px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  padding: 14px 16px;
  margin: 4px 0 12px;
  font-size: 14px;
}

.music-download-option span { color: var(--muted); font-size: 12px; }

/* ---------- books, audiobooks, and papers ---------- */

.library-card .poster { background: #1a1a1e; }

.paper-cover,
.library-card .paper-cover {
  background:
    linear-gradient(155deg, hsl(var(--paper-hue) 42% 23%), hsl(var(--paper-hue) 32% 10%));
  color: #f5f2e9;
}

.paper-cover.is-document { background: #f4f1e9; }
.paper-cover.is-document img {
  position: relative;
  z-index: 1;
  object-fit: cover;
  object-position: top center;
}

.paper-editorial {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  padding: 13px;
  overflow: hidden;
  isolation: isolate;
}

.paper-editorial::before {
  content: "";
  position: absolute;
  z-index: -1;
  inset: 24% -32% -18% 18%;
  opacity: .34;
  background:
    radial-gradient(circle at 18% 28%, hsl(var(--paper-hue) 85% 70% / .75) 0 2px, transparent 3px),
    repeating-linear-gradient(118deg, transparent 0 17px, hsl(var(--paper-hue) 72% 68% / .22) 18px 19px),
    repeating-radial-gradient(circle at 70% 48%, transparent 0 14px, hsl(var(--paper-hue) 80% 76% / .16) 15px 16px);
  transform: rotate(-8deg);
}

.paper-cover-kicker {
  min-height: 2.4em;
  color: hsl(var(--paper-hue) 60% 79%);
  font-size: 9px;
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: .08em;
  text-transform: uppercase;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
}

.paper-cover-mark {
  margin: auto 0 11px;
  color: hsl(var(--paper-hue) 78% 75%);
  font-size: clamp(30px, 5vw, 48px);
  font-weight: 780;
  letter-spacing: -.06em;
  line-height: .85;
}

.paper-cover-title {
  font-size: 11px;
  font-weight: 650;
  line-height: 1.25;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 4;
  overflow: hidden;
}

.paper-cover-byline {
  margin-top: 7px;
  color: hsl(var(--paper-hue) 24% 78%);
  font-size: 8px;
  line-height: 1.2;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.paper-access-badge {
  position: absolute;
  left: 8px;
  bottom: 8px;
  z-index: 3;
  border: 1px solid rgba(255, 255, 255, .2);
  border-radius: 999px;
  background: rgba(10, 10, 12, .82);
  color: #f5f2e9;
  padding: 4px 7px;
  font-size: 8px;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  backdrop-filter: blur(8px);
}

.paper-venue { color: var(--faint); }

/* Paper covers already share a 2:3 frame. Keep the text block equally
   predictable too: long author or journal names should not make individual
   cards taller than their neighbours. */
.paper-card { min-width: 0; }

.paper-card .meta {
  height: 87px;
  overflow: hidden;
}

.paper-card .meta .sub {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.paper-hero-ambient {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(circle at 82% 38%, hsl(var(--paper-hue) 48% 24% / .9), transparent 31%),
    linear-gradient(115deg, hsl(var(--paper-hue) 28% 13%), var(--bg) 72%);
}

.paper-hero .library-hero-cover .paper-cover {
  width: 100%;
  height: 100%;
  aspect-ratio: auto;
  border-radius: 0;
}

.library-hero-carousel .hero-thumb > .paper-cover {
  width: 100%;
  height: 100%;
  aspect-ratio: auto;
  border-radius: 0;
}

.hero-thumb .paper-editorial { padding: 4px; }
.hero-thumb .paper-cover-kicker,
.hero-thumb .paper-cover-title,
.hero-thumb .paper-cover-byline { display: none; }
.hero-thumb .paper-cover-mark { margin: auto; font-size: 15px; }

/* Rank numerals are anchored to the poster, not the variable-height paper
   metadata beneath it. Otherwise long journal/citation lines drag the number
   down behind the card text. */
.library-shelf.ranked .rank-num {
  top: 60px;
  bottom: auto;
}

@media (min-width: 640px) {
  .library-shelf.ranked .rank-num { top: 80px; }
}

.library-favourite {
  position: absolute;
  right: 9px;
  top: 7px;
  color: var(--accent);
  font-size: 18px;
  line-height: 1;
  text-shadow: 0 2px 8px rgba(0, 0, 0, .75);
}

.library-subject-panel { margin-bottom: 20px; }
.library-browse { min-height: 220px; }
.library-shelf { align-items: flex-start; }
.library-request-controls .empty { padding-top: 36px; padding-bottom: 24px; }
.library-sheet-head .poster { box-shadow: 0 12px 30px rgba(0, 0, 0, .35); }

.library-format-option {
  border-top: 1px solid var(--line);
  padding-top: 20px;
  margin-top: 20px;
}

.library-format-option:first-of-type { margin-top: 6px; }

.library-format-heading {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 14px;
}

.library-format-heading h3 { margin: 0; font-size: 16px; }
.library-format-heading span { color: var(--muted); font-size: 12px; }

/* ---------- native audiobook player ---------- */

.audiobook-player {
  position: fixed;
  inset: max(16px, env(safe-area-inset-top)) max(16px, env(safe-area-inset-right))
    max(16px, env(safe-area-inset-bottom)) max(16px, env(safe-area-inset-left));
  z-index: 90;
  max-width: 920px;
  margin: auto;
  padding: 22px;
  overflow: auto;
  border: 1px solid var(--line);
  border-radius: 22px;
  background: color-mix(in srgb, var(--bg) 94%, black);
  box-shadow: 0 30px 90px rgba(0, 0, 0, .55);
}

.audiobook-player[hidden] { display: none; }
.audiobook-player-head {
  display: grid;
  grid-template-columns: 72px minmax(0, 1fr) auto;
  gap: 14px;
  align-items: center;
}
.audiobook-player-art {
  width: 72px;
  height: 72px;
  border-radius: 10px;
  object-fit: cover;
  background: var(--panel);
}
.audiobook-player-identity { display: grid; min-width: 0; gap: 5px; }
.audiobook-player-title,
.audiobook-player-author {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.audiobook-player-author,
.audiobook-player-time { color: var(--muted); }
.audiobook-player-chapter { margin-top: 22px; font-weight: 600; }
.audiobook-player-seek { width: 100%; margin-top: 14px; }
.audiobook-player-time { display: block; margin-top: 6px; font-variant-numeric: tabular-nums; }
.audiobook-player-transport,
.audiobook-player-options {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
  justify-content: center;
  margin-top: 18px;
}
.audiobook-player-transport button,
.audiobook-player-options button,
.audiobook-player-options select,
.audiobook-player-close {
  min-height: 42px;
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 8px 14px;
  background: var(--panel);
  color: var(--text);
}
.audiobook-player-transport .primary { background: var(--accent); color: #fff; }
.audiobook-player-panels {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 12px;
  margin-top: 20px;
}
.audiobook-player-panels > section {
  display: grid;
  align-content: start;
  gap: 6px;
  max-height: 240px;
  overflow: auto;
  padding: 10px;
  border-radius: 12px;
  background: var(--panel);
}
.audiobook-player-panels button,
.audiobook-bookmark-row {
  min-height: 38px;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: var(--text);
  text-align: left;
}
.audiobook-bookmark-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; }
.audiobook-player-queue .active { background: var(--accent); color: #fff; }
.audiobook-player-error { color: var(--danger); }

@media (max-width: 680px) {
  .audiobook-player {
    inset: env(safe-area-inset-top) 0 0;
    border-radius: 22px 22px 0 0;
    padding-bottom: calc(22px + env(safe-area-inset-bottom));
  }
  .audiobook-player-panels { grid-template-columns: 1fr; }
  .audiobook-player-head { grid-template-columns: 58px minmax(0, 1fr) auto; }
  .audiobook-player-art { width: 58px; height: 58px; }
}

.library-hero-carousel .hero-thumb {
  width: 30px;
  height: 42px;
}

@media (min-width: 720px) {
  .library-hero-carousel .hero-thumb { width: 42px; height: 60px; }
  .library-hero-cover {
    width: clamp(170px, 19vw, 300px);
    aspect-ratio: 2 / 3;
  }
}

.music-detail-head {
  display: flex;
  align-items: flex-start;
  gap: 22px;
  margin-top: 8px;
}

.music-detail-head .music-art.large {
  flex: 0 0 min(34vw, 210px);
  width: min(34vw, 210px);
}

.music-detail-info { flex: 1; min-width: 0; }
.music-detail-info h1 {
  margin: 4px 0 8px;
  font-size: clamp(23px, 4vw, 34px);
  line-height: 1.12;
}
.music-detail-info .facts { color: var(--muted); font-size: 14px; line-height: 1.5; }

.music-track-list { padding-bottom: 58px; }
.music-track-row {
  appearance: none;
  width: 100%;
  padding: 0;
  background: none;
  border-right: 0;
  border-bottom: 0;
  border-left: 0;
  text-align: left;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 58px;
  border-top: 1px solid var(--surface-2);
  color: inherit;
  font-size: 14px;
}
.music-track-row:disabled { cursor: default; opacity: 0.6; }
@media (hover: hover) { .music-track-row:not(:disabled):hover { background: var(--surface); } }
.music-track-list .music-track-row:first-child { border-top: 0; }
.music-track-row input {
  flex: none;
  width: 18px;
  height: 18px;
  accent-color: var(--accent);
}
.music-track-number {
  flex: 0 0 28px;
  color: var(--faint);
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  text-align: right;
}
.music-track-facts {
  color: var(--muted);
  font-size: 12px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.music-track-duration {
  flex: none;
  color: var(--muted);
  font-size: 12px;
  font-variant-numeric: tabular-nums;
}

/* ---------- native playback ---------- */

.mini-player {
  position: fixed;
  left: 50%;
  bottom: calc(82px + var(--safe-b));
  z-index: 45;
  transform: translateX(-50%);
  width: min(980px, calc(100vw - 24px));
  min-height: 68px;
  display: grid;
  grid-template-columns: 48px minmax(120px, 1fr) auto minmax(160px, 1.25fr) auto;
  align-items: center;
  gap: 12px;
  padding: 9px 12px;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: rgba(23, 23, 26, 0.96);
  box-shadow: 0 18px 48px rgba(0, 0, 0, 0.55);
  -webkit-backdrop-filter: blur(20px) saturate(140%);
  backdrop-filter: blur(20px) saturate(140%);
}
.mini-player[hidden], .now-playing-panel[hidden] { display: none; }
.mini-player audio { display: none; }
.mini-player-art {
  appearance: none;
  width: 48px;
  height: 48px;
  overflow: hidden;
  border: 0;
  border-radius: 7px;
  background: var(--surface-2);
  cursor: pointer;
}
.mini-player-art img { width: 100%; height: 100%; object-fit: cover; display: block; }
.mini-player-meta {
  appearance: none;
  min-width: 0;
  border: 0;
  background: none;
  color: inherit;
  text-align: left;
  cursor: pointer;
}
.mini-player-title, .mini-player-artist { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mini-player-title { font-size: 13px; font-weight: 650; }
.mini-player-artist { margin-top: 3px; color: var(--muted); font-size: 11px; }
.player-transport, .player-options, .player-timeline { display: flex; align-items: center; gap: 6px; }
.player-control, .player-mode {
  appearance: none;
  border: 0;
  background: none;
  color: var(--muted);
  font: inherit;
  cursor: pointer;
}
.player-control { width: 32px; height: 32px; border-radius: 50%; font-size: 20px; }
.player-control.primary { color: var(--bg); background: var(--text); font-size: 14px; }
.player-mode { padding: 6px; font-size: 11px; }
.player-mode.on { color: var(--accent); }
.player-seek, .player-volume { accent-color: var(--accent); cursor: pointer; }
.player-seek { width: 100%; min-width: 80px; }
.player-volume { width: 70px; }
.player-time { flex: none; color: var(--muted); font-size: 10px; font-variant-numeric: tabular-nums; }
.now-playing-panel {
  position: fixed;
  left: 50%;
  bottom: calc(158px + var(--safe-b));
  z-index: 44;
  transform: translateX(-50%);
  width: min(540px, calc(100vw - 24px));
  max-height: min(60vh, 520px);
  overflow: auto;
  padding: 14px;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: rgba(23, 23, 26, 0.98);
  box-shadow: 0 18px 48px rgba(0, 0, 0, 0.6);
}
.now-playing-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; }
.now-playing-queue { display: flex; flex-direction: column; }
.now-playing-row {
  appearance: none;
  display: grid;
  grid-template-columns: 24px minmax(0, 1fr) minmax(0, .7fr);
  gap: 9px;
  align-items: center;
  min-height: 44px;
  border: 0;
  border-top: 1px solid var(--line);
  background: none;
  color: inherit;
  text-align: left;
  cursor: pointer;
}
.now-playing-row.active { color: var(--accent); }
.now-playing-number, .now-playing-artist { color: var(--muted); font-size: 11px; }
.now-playing-name, .now-playing-artist { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.now-playing-connected {
  margin: 12px 0;
  color: var(--muted);
  font-size: 12px;
  line-height: 1.45;
}
.now-playing-lyrics { border-top: 1px solid var(--line); padding-top: 12px; }
.lyrics-plain {
  margin: 10px 0 0;
  white-space: pre-wrap;
  color: var(--muted);
  font: inherit;
  line-height: 1.55;
}
.lyrics-timed { display: grid; gap: 8px; margin-top: 10px; }
.lyrics-line { color: var(--muted); transition: color 120ms var(--ease); }
.lyrics-line.active { color: var(--text); font-weight: 650; }

/* ---------- immersive video player ---------- */

body.cinema-open { overflow: hidden; }

.cinema-player {
  --cinema-safe-top: max(22px, env(safe-area-inset-top));
  --cinema-safe-right: max(28px, env(safe-area-inset-right));
  --cinema-safe-bottom: max(22px, env(safe-area-inset-bottom));
  --cinema-safe-left: max(28px, env(safe-area-inset-left));
  position: fixed;
  inset: 0;
  z-index: 1000;
  overflow: hidden;
  color: #fff;
  background: #000;
  font-family: Inter, ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  isolation: isolate;
  user-select: none;
  touch-action: manipulation;
}
.cinema-player[hidden] { display: none; }
.cinema-player [hidden] { display: none !important; }
.cinema-video { position: absolute; inset: 0; display: block; width: 100%; height: 100%; border: 0; background: #000; object-fit: contain; }

.cinema-shade { position: absolute; z-index: 1; right: 0; left: 0; height: 34%; pointer-events: none; opacity: 1; transition: opacity 240ms ease; }
.cinema-shade-top { top: 0; background: linear-gradient(to bottom, rgba(0, 0, 0, .8), rgba(0, 0, 0, .34) 48%, transparent); }
.cinema-shade-bottom { bottom: 0; height: 42%; background: linear-gradient(to top, rgba(0, 0, 0, .92), rgba(0, 0, 0, .45) 52%, transparent); }
.cinema-controls-layer { position: absolute; z-index: 4; opacity: 1; transition: opacity 180ms ease, transform 220ms ease; }
.cinema-player.controls-hidden { cursor: none; }
.cinema-player.controls-hidden .cinema-controls-layer,
.cinema-player.controls-hidden .cinema-shade { opacity: 0; pointer-events: none; }
.cinema-player.controls-hidden .cinema-top { transform: translateY(-12px); }
.cinema-player.controls-hidden .cinema-bottom { transform: translateY(16px); }

.cinema-top { top: 0; right: 0; left: 0; display: grid; grid-template-columns: 52px minmax(0, 1fr) 52px; gap: 14px; align-items: center; padding: var(--cinema-safe-top) var(--cinema-safe-right) 30px var(--cinema-safe-left); }
.cinema-title-wrap { min-width: 0; }
.cinema-eyebrow { display: block; min-height: 16px; margin-bottom: 3px; color: rgba(255, 255, 255, .68); font-size: 12px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; }
.cinema-title { display: block; overflow: hidden; font-size: clamp(17px, 2vw, 25px); font-weight: 650; line-height: 1.2; text-overflow: ellipsis; text-shadow: 0 2px 12px rgba(0, 0, 0, .65); white-space: nowrap; }

.cinema-button { appearance: none; display: inline-grid; place-items: center; width: 44px; height: 44px; flex: 0 0 auto; margin: 0; border: 0; border-radius: 50%; padding: 8px; color: #fff; background: transparent; cursor: pointer; transition: color 140ms ease, background 140ms ease, transform 120ms ease; }
.cinema-button svg { width: 100%; height: 100%; overflow: visible; fill: none; stroke: currentColor; stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round; }
.cinema-button:hover { background: rgba(255, 255, 255, .16); }
.cinema-button:active { transform: scale(.9); }
.cinema-button:disabled { opacity: .38; cursor: default; }

.cinema-center { top: 50%; left: 50%; display: flex; gap: clamp(22px, 5vw, 64px); align-items: center; transform: translate(-50%, -50%); }
.cinema-player.controls-hidden .cinema-center { transform: translate(-50%, -50%) scale(.96); }
.cinema-play-large { width: clamp(72px, 9vw, 104px); height: clamp(72px, 9vw, 104px); padding: 18px; background: rgba(0, 0, 0, .38); }
.cinema-play-large:hover { background: rgba(255, 255, 255, .2); }
.cinema-jump { width: clamp(54px, 7vw, 76px); height: clamp(54px, 7vw, 76px); padding: 11px; }

.cinema-spinner { position: absolute; z-index: 7; top: 50%; left: 50%; width: 68px; height: 68px; margin: -34px 0 0 -34px; border: 4px solid rgba(255, 255, 255, .25); border-top-color: #fff; border-radius: 50%; animation: cinema-spin .8s linear infinite; pointer-events: none; }
@keyframes cinema-spin { to { transform: rotate(360deg); } }
.cinema-seek-feedback { position: absolute; z-index: 7; top: 50%; left: 50%; padding: 10px 16px; border-radius: 999px; color: #fff; background: rgba(0, 0, 0, .72); font-size: 14px; font-weight: 700; transform: translate(-50%, -50%); pointer-events: none; }

.cinema-bottom { right: 0; bottom: 0; left: 0; padding: 36px var(--cinema-safe-right) var(--cinema-safe-bottom) var(--cinema-safe-left); }
.cinema-timeline { position: relative; height: 34px; display: flex; align-items: center; margin: 0 2px 3px; }
.cinema-timeline-track { position: absolute; right: 0; left: 0; height: 4px; overflow: hidden; border-radius: 999px; background: rgba(255, 255, 255, .28); transition: height 120ms ease; }
.cinema-timeline:hover .cinema-timeline-track,
.cinema-timeline:focus-within .cinema-timeline-track { height: 7px; }
.cinema-timeline-buffer,
.cinema-timeline-played,
.cinema-timeline-markers { position: absolute; inset: 0 auto 0 0; width: 0; pointer-events: none; }
.cinema-timeline-buffer { background: rgba(255, 255, 255, .5); }
.cinema-timeline-played { z-index: 2; background: #e50914; }
.cinema-timeline-markers { z-index: 3; width: 100%; }
.cinema-segment-marker { position: absolute; top: 0; bottom: 0; min-width: 2px; border-right: 1px solid rgba(0, 0, 0, .42); border-left: 1px solid rgba(0, 0, 0, .42); background: rgba(255, 255, 255, .24); }
.cinema-segment-marker.outro,
.cinema-segment-marker.credits { background: rgba(229, 9, 20, .34); }
.cinema-seek { position: absolute; z-index: 5; inset: 0; width: 100%; height: 34px; margin: 0; opacity: 0; cursor: pointer; }
.cinema-timeline-preview { position: absolute; bottom: 27px; min-width: 56px; padding: 7px 9px; border-radius: 5px; color: #fff; background: rgba(12, 12, 12, .94); font-size: 12px; font-variant-numeric: tabular-nums; text-align: center; transform: translateX(-50%); pointer-events: none; }

.cinema-control-row,
.cinema-control-group { display: flex; align-items: center; }
.cinema-control-row { justify-content: space-between; gap: 18px; }
.cinema-control-group { min-width: 0; gap: 4px; }
.cinema-control-right { justify-content: flex-end; }
.cinema-volume { width: 92px; margin: 0 8px 0 0; accent-color: #fff; cursor: pointer; }
.cinema-time { margin: 0 11px 0 4px; color: rgba(255, 255, 255, .78); font-size: 12px; font-variant-numeric: tabular-nums; white-space: nowrap; }
.cinema-now-title { overflow: hidden; max-width: min(38vw, 540px); font-size: 14px; font-weight: 650; text-overflow: ellipsis; white-space: nowrap; }

.cinema-skip,
.cinema-undo { position: absolute; z-index: 8; right: var(--cinema-safe-right); bottom: 132px; min-height: 45px; border: 2px solid rgba(255, 255, 255, .82); border-radius: 4px; padding: 8px 20px; color: #fff; background: rgba(17, 17, 17, .82); box-shadow: 0 4px 24px rgba(0, 0, 0, .38); font: inherit; font-size: 15px; font-weight: 750; cursor: pointer; transition: background 140ms ease, transform 120ms ease; }
.cinema-skip:hover,
.cinema-undo:hover { background: #fff; color: #111; }
.cinema-skip:active,
.cinema-undo:active { transform: scale(.96); }
.cinema-undo { right: auto; left: var(--cinema-safe-left); }

.cinema-panel,
.cinema-postplay,
.cinema-error { position: absolute; z-index: 12; border: 1px solid rgba(255, 255, 255, .13); color: #fff; background: rgba(20, 20, 20, .98); box-shadow: 0 24px 80px rgba(0, 0, 0, .62); user-select: text; }
.cinema-settings { right: var(--cinema-safe-right); bottom: 102px; width: min(420px, calc(100vw - 40px)); max-height: min(72vh, 720px); overflow: hidden; border-radius: 8px; }
.cinema-panel-head { position: sticky; z-index: 2; top: 0; display: flex; min-height: 58px; align-items: center; justify-content: space-between; padding: 7px 10px 7px 20px; border-bottom: 1px solid rgba(255, 255, 255, .12); background: #161616; }
.cinema-panel-head strong { font-size: 17px; }
.cinema-panel-close { width: 40px; height: 40px; }
.cinema-settings-body { max-height: calc(min(72vh, 720px) - 58px); overflow: auto; overscroll-behavior: contain; }
.cinema-settings-section { padding: 18px 20px; }
.cinema-settings-section + .cinema-settings-section { border-top: 1px solid rgba(255, 255, 255, .1); }
.cinema-settings-section h3 { margin: 0 0 12px; color: rgba(255, 255, 255, .64); font-size: 12px; letter-spacing: .1em; text-transform: uppercase; }
.cinema-option,
.cinema-toggle { display: flex; min-height: 48px; gap: 12px; align-items: center; margin: 0; cursor: pointer; }
.cinema-option input { width: 18px; height: 18px; margin: 0; accent-color: #fff; }
.cinema-toggle { justify-content: space-between; }
.cinema-toggle input { appearance: none; position: relative; width: 44px; height: 25px; flex: 0 0 auto; border-radius: 99px; background: #555; cursor: pointer; transition: background 140ms ease; }
.cinema-toggle input::after { content: ""; position: absolute; top: 3px; left: 3px; width: 19px; height: 19px; border-radius: 50%; background: #fff; transition: transform 140ms ease; }
.cinema-toggle input:checked { background: #e50914; }
.cinema-toggle input:checked::after { transform: translateX(19px); }
.cinema-option-copy { display: grid; min-width: 0; gap: 3px; }
.cinema-option-copy strong { overflow: hidden; font-size: 14px; font-weight: 600; text-overflow: ellipsis; white-space: nowrap; }
.cinema-option-copy small,
.cinema-settings-note { color: rgba(255, 255, 255, .58); font-size: 12px; line-height: 1.45; }
.cinema-settings-note { margin: 9px 0 0; }
.cinema-speed-grid { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 6px; }
.cinema-speed { appearance: none; min-height: 38px; border: 1px solid rgba(255, 255, 255, .2); border-radius: 4px; color: #fff; background: transparent; font: inherit; font-size: 12px; cursor: pointer; }
.cinema-speed.active,
.cinema-speed:hover { border-color: #fff; background: #fff; color: #111; }
.cinema-provider-link { display: inline-flex; margin-top: 10px; color: #fff; font-size: 13px; font-weight: 650; }
.cinema-episodes-body { padding: 0 12px 16px; }
.cinema-season-heading { position: sticky; z-index: 1; top: 0; margin: 0 -12px 4px; padding: 14px 18px 8px; color: rgba(255, 255, 255, .62); background: rgba(20, 20, 20, .98); font-size: 11px; letter-spacing: .1em; text-transform: uppercase; }
.cinema-episode-row { appearance: none; display: grid; width: 100%; grid-template-columns: 104px minmax(0, 1fr); gap: 13px; align-items: center; min-height: 74px; border: 0; border-radius: 5px; padding: 8px; color: #fff; background: transparent; font: inherit; text-align: left; cursor: pointer; }
.cinema-episode-row:hover,
.cinema-episode-row.current { background: rgba(255, 255, 255, .1); }
.cinema-episode-art { display: block; width: 104px; height: 59px; border-radius: 3px; background: #080808; object-fit: cover; }
.cinema-episode-copy { display: grid; min-width: 0; gap: 4px; }
.cinema-episode-copy strong { overflow: hidden; font-size: 13px; font-weight: 650; text-overflow: ellipsis; white-space: nowrap; }
.cinema-episode-copy small { color: rgba(255, 255, 255, .56); font-size: 11px; }
.cinema-episode-progress { display: block; height: 3px; overflow: hidden; border-radius: 99px; background: rgba(255, 255, 255, .2); }
.cinema-episode-progress span { display: block; height: 100%; background: #e50914; }

.cinema-postplay,
.cinema-error { top: 50%; right: max(5vw, var(--cinema-safe-right)); width: min(420px, calc(100vw - 40px)); border-radius: 8px; padding: clamp(24px, 4vw, 42px); background-color: rgba(15, 15, 15, .96); background-position: center; background-size: cover; transform: translateY(-50%); }
.cinema-postplay::before { content: ""; position: absolute; inset: 0; z-index: -1; border-radius: inherit; background: linear-gradient(90deg, rgba(10, 10, 10, .98), rgba(10, 10, 10, .72)); }
.cinema-post-eyebrow { color: #e50914; font-size: 12px; font-weight: 800; letter-spacing: .12em; text-transform: uppercase; }
.cinema-post-title,
.cinema-error h2 { margin: 9px 0 8px; font-size: clamp(25px, 4vw, 38px); line-height: 1.05; }
.cinema-post-meta,
.cinema-error-message { margin: 0 0 24px; color: rgba(255, 255, 255, .72); font-size: 14px; line-height: 1.5; }
.cinema-post-actions { display: flex; flex-wrap: wrap; gap: 10px; }
.cinema-primary-action,
.cinema-secondary-action { appearance: none; display: inline-flex; min-height: 44px; align-items: center; justify-content: center; border: 1px solid rgba(255, 255, 255, .25); border-radius: 4px; padding: 9px 18px; color: #fff; background: rgba(255, 255, 255, .14); font: inherit; font-size: 14px; font-weight: 750; text-decoration: none; cursor: pointer; }
.cinema-primary-action { border-color: #fff; color: #111; background: #fff; }
.cinema-primary-action:hover { background: rgba(255, 255, 255, .82); }
.cinema-secondary-action:hover { background: rgba(255, 255, 255, .25); }
.cinema-error { left: 50%; right: auto; text-align: center; transform: translate(-50%, -50%); }
.cinema-error .cinema-post-actions { justify-content: center; }

.cinema-player button:focus-visible,
.cinema-player a:focus-visible,
.cinema-player input:focus-visible { outline: 3px solid #fff; outline-offset: 3px; }

@media (max-width: 760px) {
  .cinema-player { --cinema-safe-top: max(12px, env(safe-area-inset-top)); --cinema-safe-right: max(12px, env(safe-area-inset-right)); --cinema-safe-bottom: max(12px, env(safe-area-inset-bottom)); --cinema-safe-left: max(12px, env(safe-area-inset-left)); }
  .cinema-top { grid-template-columns: 44px minmax(0, 1fr) 44px; gap: 5px; padding-bottom: 18px; }
  .cinema-button { width: 42px; height: 42px; padding: 9px; }
  .cinema-title { font-size: 16px; }
  .cinema-eyebrow { min-height: 13px; font-size: 10px; }
  .cinema-center { gap: 18px; }
  .cinema-play-large { width: 66px; height: 66px; padding: 17px; }
  .cinema-jump { width: 52px; height: 52px; }
  .cinema-bottom { padding-top: 24px; }
  .cinema-control-row { gap: 4px; }
  .cinema-control-group { gap: 0; }
  .cinema-volume,
  .cinema-now-title { display: none; }
  .cinema-time { margin-right: 2px; font-size: 10px; }
  .cinema-control-right .cinema-button:nth-last-child(2) { display: none; }
  .cinema-skip,
  .cinema-undo { bottom: 104px; min-height: 40px; padding: 7px 14px; font-size: 13px; }
  .cinema-settings { right: 0; bottom: 0; left: 0; width: 100%; max-height: min(78vh, 720px); border-width: 1px 0 0; border-radius: 14px 14px 0 0; }
  .cinema-settings-body { max-height: calc(min(78vh, 720px) - 58px); padding-bottom: env(safe-area-inset-bottom); }
  .cinema-postplay,
  .cinema-error { top: auto; right: 12px; bottom: max(18px, env(safe-area-inset-bottom)); left: 12px; width: auto; padding: 24px; transform: none; }
  .cinema-error { text-align: left; }
  .cinema-error .cinema-post-actions { justify-content: flex-start; }
}

@media (max-height: 480px) and (orientation: landscape) {
  .cinema-top { padding-top: max(8px, env(safe-area-inset-top)); }
  .cinema-bottom { padding-bottom: max(8px, env(safe-area-inset-bottom)); }
  .cinema-center { gap: 24px; }
  .cinema-play-large { width: 62px; height: 62px; }
  .cinema-jump { width: 48px; height: 48px; }
  .cinema-skip,
  .cinema-undo { bottom: 96px; }
}

@media (pointer: coarse) {
  .cinema-timeline { height: 42px; }
  .cinema-seek { height: 42px; }
  .cinema-timeline-track { height: 6px; }
}

@media (prefers-reduced-motion: reduce) {
  .cinema-player *,
  .cinema-player *::before,
  .cinema-player *::after { scroll-behavior: auto !important; transition-duration: .01ms !important; animation-duration: .01ms !important; }
}


@media (min-width: 720px) {
  .mini-player { bottom: calc(14px + var(--safe-b)); }
  .now-playing-panel { bottom: calc(90px + var(--safe-b)); }
}

@media (max-width: 760px) {
  .mini-player {
    grid-template-columns: 42px minmax(0, 1fr) auto;
    min-height: 62px;
    gap: 9px;
    padding: 8px 10px;
  }
  .mini-player-art { width: 42px; height: 42px; }
  .player-timeline { grid-column: 1 / -1; }
  .player-options { grid-column: 1 / -1; justify-content: flex-end; }
  .player-options > :nth-child(-n + 4) { display: none; }
  .player-time { min-width: 68px; text-align: right; }
  .now-playing-panel { bottom: calc(154px + var(--safe-b)); }
}

@media (max-width: 520px) {
  .music-sheet-head .music-art.large { flex-basis: 104px; }
  .music-detail-head { gap: 16px; }
  .music-detail-head .music-art.large { flex-basis: 112px; width: 112px; }
  .music-detail-info .cta.inline { display: block; margin: 12px 0 0; }
  .music-detail-info .cta.inline + .cta.inline { margin-left: 0; }
  .music-track-row { gap: 9px; }
  .music-track-number { flex-basis: 22px; }
}

/* ---------- poster grid ---------- */

.grid,
.music-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(108px, 1fr));
  gap: 22px 14px;
}

@media (min-width: 640px) {
  .grid,
  .music-grid { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 28px 18px; }
}

.card {
  /* real <button> so posters are keyboard-reachable; undo button chrome */
  appearance: none;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  text-align: left;
  display: block;
  width: 100%;
  cursor: pointer;
  padding: 0;
  -webkit-user-select: none;
  user-select: none;
}

.card.skel { cursor: default; }

.poster {
  display: block;
  position: relative;
  aspect-ratio: 2 / 3;
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--surface);
  transition: transform 200ms var(--ease), box-shadow 200ms var(--ease);
}

/* hairline ring so posters read as objects on the dark canvas */
.poster::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  box-shadow: inset 0 0 0 1px var(--line);
  pointer-events: none;
}

.card:active .poster { transform: scale(0.965); }

@media (hover: hover) {
  .card:hover .poster {
    transform: translateY(-4px) scale(1.02);
    box-shadow: 0 14px 32px rgba(0, 0, 0, 0.5);
  }
}

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

/* Visible by default; the fade only runs on fresh (non-cached) loads so a
   paused transition in a background tab can never leave posters invisible. */
.poster img.fade { animation: poster-in 220ms var(--ease); }

@keyframes poster-in {
  from { opacity: 0; }
}

.card .meta, .card .meta .sub { display: block; }

.poster .fallback {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: flex-end;
  padding: 12px;
  font-size: 13px;
  font-weight: 500;
  color: var(--muted);
  line-height: 1.35;
}

.badge {
  position: absolute;
  top: 8px;
  left: 8px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding: 4px 7px;
  border-radius: 4px;
  background: rgba(14, 14, 16, 0.85);
  color: var(--accent);
}

.badge.available { color: var(--muted); }

.card .meta {
  margin-top: 8px;
  font-size: 13px;
  line-height: 1.3;
}

.card .meta .title {
  font-weight: 500;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.card .meta .sub { color: var(--muted); font-size: 12px; margin-top: 2px; }

/* skeletons */

.skel .poster { background: var(--surface); animation: pulse 1.4s ease-in-out infinite; }
.skel .line {
  display: block;
  height: 12px;
  width: 80%;
  border-radius: 3px;
  background: var(--surface);
  margin-top: 8px;
  animation: pulse 1.4s ease-in-out infinite;
}

.skeleton-meta { display: block; margin-top: 8px; }
.skeleton-meta .line { width: 78%; margin-top: 0; }
.skeleton-meta .subline { width: 48%; height: 9px; margin-top: 5px; }

/* page-shaped skeletons: hero billboard and the item screen */

.hero-skel {
  background: var(--surface);
  min-height: clamp(360px, 62vh, 540px);
  margin: calc(-12px - var(--hero-lift, 0px)) calc(50% - 50vw) 26px;
  animation: pulse 1.4s ease-in-out infinite;
}

@media (min-width: 720px) {
  .hero-skel { --hero-lift: 26px; min-height: clamp(440px, 72vh, 720px); }
}

.skel-lines { flex: 1; align-self: center; }
.skel .line.lg { height: 22px; width: 55%; }
.skel .line.sm { width: 40%; }
.skel .vthumb { animation: pulse 1.4s ease-in-out infinite; }
.vfile-row.skel { cursor: default; }

@keyframes pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.55; }
}

/* ---------- sections / empty states ---------- */

.section-title {
  font-size: 17px;
  font-weight: 650;
  letter-spacing: -0.01em;
  color: var(--text);
  margin: 30px 0 14px;
}

.section-title:first-child { margin-top: 4px; }

.scroll-sentinel { height: 1px; }

.feed-end {
  text-align: center;
  color: var(--faint);
  font-size: 13px;
  padding: 36px 0 12px;
}

.empty {
  padding: 72px 24px;
  text-align: center;
  color: var(--muted);
  font-size: 15px;
  line-height: 1.6;
}

.empty .hint { color: var(--faint); font-size: 13px; margin-top: 6px; }

/* recently-added shelf */

.shelf {
  display: flex;
  gap: 14px;
  overflow-x: auto;
  scrollbar-width: none;
  /* full viewport bleed like the hero: cards scroll to the screen edge,
     while the padding keeps the resting position on the content column */
  margin: 0 calc(50% - 50vw);
  padding: 0 calc(var(--edge, 0px) + var(--pad-x)) 8px;
  -webkit-overflow-scrolling: touch;
}

.shelf::-webkit-scrollbar { display: none; }

.shelf .card { flex: 0 0 108px; }
.shelf .music-card { flex: 0 0 108px; }

.rail-sentinel { flex: 0 0 1px; align-self: stretch; }

.rail-loading {
  flex: 0 0 auto;
  color: var(--faint);
  font-size: 13px;
  padding: 54px 8px;
}

@media (min-width: 640px) {
  .shelf .card,
  .shelf .music-card { flex-basis: 140px; }
}

/* Trending as a ranked top-10 rail: a big outlined numeral sits half
   behind each poster, streaming-chart style. */
.shelf.ranked { gap: 24px; padding-top: 6px; }

.rank-slot {
  position: relative;
  flex: 0 0 auto;
  padding-left: 30px;
}

.rank-slot .card { position: relative; z-index: 1; width: 108px; }
.rank-slot .music-card { position: relative; z-index: 1; width: 108px; }

.rank-num {
  position: absolute;
  left: -4px;
  bottom: 44px;
  z-index: 0;
  font-size: 96px;
  font-weight: 800;
  line-height: 0.8;
  letter-spacing: -0.04em;
  /* solid bg fill + stroke painted underneath: a transparent fill lets the
     stroke's inner self-intersections show through (the mangled "2") */
  color: var(--bg);
  -webkit-text-stroke: 2px var(--muted);
  paint-order: stroke fill;
  pointer-events: none;
  -webkit-user-select: none;
  user-select: none;
}

/* Double digits need more runway before the poster covers them. */
.rank-slot:nth-child(n + 10) { padding-left: 62px; }

@media (min-width: 640px) {
  .shelf.ranked { gap: 30px; }
  .rank-slot { padding-left: 40px; }
  .rank-slot:nth-child(n + 10) { padding-left: 88px; }
  .rank-slot .card { width: 140px; }
  .rank-slot .music-card { width: 140px; }
  .rank-num { font-size: 128px; bottom: 48px; }
}

/* ---------- hero billboard + carousel (discover) ---------- */

/* Full viewport bleed: 50%-50vw escapes both the gutter and main's
   max-width, so the artwork runs edge to edge like a streaming front page.
   --edge re-aligns the text block with the content column underneath. */
.hero-carousel {
  position: relative;
  margin: calc(-12px - var(--hero-lift, 0px)) calc(50% - 50vw) 26px;
}

/* Slides stack in one grid cell so the panel sizes to the tallest slide
   and crossfades happen in place with no height jump. */
.hero-track { display: grid; }

.hero-slide {
  grid-area: 1 / 1;
  opacity: 0;
  visibility: hidden;
  transition: opacity 420ms var(--ease), visibility 0s linear 420ms;
}

.hero-slide.on {
  opacity: 1;
  visibility: visible;
  transition: opacity 420ms var(--ease);
}

.hero-thumbs {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  bottom: 12px;
  display: flex;
  gap: 8px;
  z-index: 2;
}

.hero-thumb {
  appearance: none;
  border: 1px solid rgba(240, 239, 236, 0.25);
  padding: 0;
  width: 52px;
  height: 30px;
  border-radius: 6px;
  overflow: hidden;
  background: var(--surface-2);
  cursor: pointer;
  opacity: 0.55;
  transition: opacity 200ms var(--ease), border-color 200ms var(--ease),
    transform 200ms var(--ease);
}

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

.hero-thumb.on {
  opacity: 1;
  border-color: var(--accent);
  transform: scale(1.08);
}

@media (hover: hover) {
  .hero-thumb:not(.on):hover { opacity: 0.85; }
}

@media (min-width: 720px) {
  /* Desktop: the strip docks bottom-right, clear of the text block. */
  .hero-thumbs { left: auto; transform: none; right: calc(var(--edge, 0px) + var(--pad-x)); bottom: 22px; }
  .hero-thumb { width: 78px; height: 44px; border-radius: 8px; }
}

.hero-arrow {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 2;
  appearance: none;
  border: 1px solid var(--line);
  width: 38px;
  height: 38px;
  border-radius: 50%;
  background: rgba(14, 14, 16, 0.7);
  color: var(--text);
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
  display: none;
  place-items: center;
  padding-bottom: 3px;
  transition: background-color 160ms var(--ease), color 160ms var(--ease), opacity 200ms var(--ease);
  opacity: 0;
}

.hero-arrow.prev { left: 14px; }
.hero-arrow.next { right: 14px; }

@media (hover: hover) {
  .hero-arrow { display: grid; }
  .hero-carousel:hover .hero-arrow,
  .hero-arrow:focus-visible { opacity: 1; }
  .hero-arrow:hover { background: var(--surface-2); color: var(--accent); }
}

.hero {
  appearance: none;
  border: 0;
  font: inherit;
  color: inherit;
  text-align: left;
  display: block;
  width: 100%;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  background: var(--surface);
  padding: 0;
  height: clamp(360px, 62vh, 540px);
}

/* Sharp backdrop art fills the slide; a slow drift keeps it alive. */
.hero-bg {
  display: block;
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: center 22%;
  transform: scale(1);
}

.hero-slide.on .hero-bg { animation: hero-drift 14s var(--ease) forwards; }

@keyframes hero-drift {
  from { transform: scale(1.05); }
  to { transform: scale(1); }
}

/* Poster-only fallback: blurred-ambient like the old billboard, so a 2:3
   poster never gets stretched into a 16:9 frame. */
.hero-bg.is-poster {
  inset: -64px;
  filter: blur(52px) saturate(140%);
  opacity: 0.55;
}

/* Legibility scrims: fade to the page at the bottom (the feed continues
   seamlessly below), darken the left where the text sits, and a whisper at
   the top for the wordmark/status bar. */
.hero-scrim {
  display: block;
  position: absolute;
  inset: 0;
  background:
    linear-gradient(to top, var(--bg) 0%, rgba(14, 14, 16, 0.72) 22%, rgba(14, 14, 16, 0) 55%),
    linear-gradient(90deg, rgba(14, 14, 16, 0.78), rgba(14, 14, 16, 0.28) 52%, rgba(14, 14, 16, 0) 78%),
    linear-gradient(to bottom, rgba(14, 14, 16, 0.55), rgba(14, 14, 16, 0) 18%);
}

.hero-info {
  position: absolute;
  left: 0;
  right: 0;
  /* clears the thumbnail strip (30px + 12px inset) on mobile, where both
     are bottom-anchored; desktop docks the thumbs right and resets this */
  bottom: 60px;
  display: block;
  min-width: 0;
  padding: 0 calc(var(--edge, 0px) + var(--pad-x));
  max-width: calc(var(--edge, 0px) + var(--pad-x) + 640px);
}

.hero-tag, .hero-title, .hero .facts, .hero .overview { display: block; }

.hero-tag {
  color: var(--accent);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.hero-title {
  font-size: clamp(26px, 6vw, 44px);
  font-weight: 750;
  letter-spacing: -0.02em;
  line-height: 1.08;
  margin-top: 8px;
  text-wrap: balance;
  text-shadow: 0 2px 24px rgba(0, 0, 0, 0.45);
}

.hero .facts { color: var(--text); opacity: 0.85; font-size: 14px; margin-top: 10px; }

.hero .overview {
  margin-top: 10px;
  font-size: 14px;
  line-height: 1.55;
  color: var(--text);
  max-width: 58ch;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  text-shadow: 0 1px 12px rgba(0, 0, 0, 0.5);
}

.hero-cta {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: 16px;
  background: var(--accent);
  color: var(--bg);
  font-size: 14px;
  font-weight: 650;
  border-radius: 999px;
  padding: 10px 20px;
  transition: opacity 160ms var(--ease), transform 160ms var(--ease);
}

@media (hover: hover) {
  .hero:hover .hero-cta { opacity: 0.9; transform: translateY(-1px); }
}

.hero:active .hero-cta { opacity: 0.8; }

@media (min-width: 720px) {
  /* Desktop: the artwork's top edge sits at the nav dock's midline (~38px
     from the viewport top; body reserves 64px + main 12px, so a 26px lift
     lands it there), and the top fade blends it in from the black above. */
  .hero-carousel { --hero-lift: 26px; }
  .hero { height: clamp(440px, 72vh, 720px); }
  .hero-info { bottom: 48px; }
  .hero .overview { -webkit-line-clamp: 3; font-size: 15px; }
  .hero-scrim {
    background:
      linear-gradient(to top, var(--bg) 0%, rgba(14, 14, 16, 0.72) 22%, rgba(14, 14, 16, 0) 55%),
      linear-gradient(90deg, rgba(14, 14, 16, 0.78), rgba(14, 14, 16, 0.28) 52%, rgba(14, 14, 16, 0) 78%),
      linear-gradient(to bottom, var(--bg) 0, rgba(14, 14, 16, 0) 150px);
  }
}

/* Album art has no wide backdrop. Keep the same cinematic hero shell, but
   let the real cover carry the composition instead of floating as a small
   card in a mostly empty ambient field. */
.music-hero .hero-info { z-index: 2; }
.music-hero-bg { opacity: 0.7; }
.music-hero-cover { display: none; }
.music-hero-carousel .hero-thumb { width: 30px; height: 30px; }

/* Music, books, and papers only have square/portrait artwork. On phones the
   blurred ambient layer cannot communicate that artwork on its own, so keep
   the real cover in the open upper half of the billboard. */
@media (max-width: 719px) {
  .music-hero { min-height: 400px; }

  .music-hero-cover {
    display: block;
    position: absolute;
    top: 18px;
    left: 50%;
    z-index: 1;
    width: clamp(210px, 62vw, 320px);
    aspect-ratio: 1;
    transform: translateX(-50%);
    overflow: hidden;
    border-radius: var(--radius-lg);
    box-shadow: 0 18px 48px rgba(0, 0, 0, 0.46), inset 0 0 0 1px var(--line);
  }

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

  .library-hero-cover {
    top: 14px;
    width: clamp(150px, 42vw, 210px);
    aspect-ratio: 2 / 3;
  }

  .music-hero .hero-title {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    overflow: hidden;
  }

  .music-hero .facts {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    overflow: hidden;
  }

  .music-hero .overview { display: none; }
}

@media (min-width: 720px) {
  .music-hero .hero-info {
    right: auto;
    width: 58%;
    max-width: none;
  }

  .music-hero-cover {
    display: block;
    position: absolute;
    top: 45%;
    right: calc(var(--edge, 0px) + var(--pad-x));
    z-index: 1;
    width: clamp(300px, min(36vw, 58vh), 520px);
    aspect-ratio: 1;
    transform: translateY(-50%);
    overflow: hidden;
    border-radius: var(--radius-lg);
    box-shadow: 0 24px 64px rgba(0, 0, 0, 0.48), inset 0 0 0 1px var(--line);
  }

  .music-hero-cover img { display: block; width: 100%; height: 100%; object-fit: cover; }
  .music-hero-carousel .hero-thumb { width: 44px; height: 44px; }

  .library-hero-cover {
    width: clamp(230px, min(28vw, 40vh), 400px);
    aspect-ratio: 2 / 3;
  }
}

/* ---------- browse by genre ---------- */

.genre-panel {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(130px, 1fr));
  gap: 10px;
  margin: 0 0 30px;
}

.genre-chip {
  appearance: none;
  border: 1px solid var(--line);
  background: var(--surface);
  color: var(--text);
  font: inherit;
  font-size: 14px;
  font-weight: 550;
  padding: 13px 10px;
  border-radius: var(--radius);
  text-align: center;
  cursor: pointer;
  transition: background-color 160ms var(--ease), color 160ms var(--ease),
    border-color 160ms var(--ease);
}

.genre-chip.on {
  background: var(--accent);
  border-color: transparent;
  color: var(--bg);
  font-weight: 650;
}

@media (hover: hover) {
  .genre-chip:not(.on):hover { background: var(--surface-2); }
}

/* ---------- detail sheet ---------- */

.sheet-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0);
  z-index: 40;
  transition: background-color 220ms var(--ease);
}

.sheet-backdrop.open { background: rgba(0, 0, 0, 0.6); }

.sheet {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  max-height: 92vh;
  overflow-y: auto;
  background: var(--surface);
  border-radius: 14px 14px 0 0;
  padding: 20px 20px calc(28px + var(--safe-b));
  z-index: 41;
  transform: translateY(100%);
  transition: transform 240ms var(--ease);
  -webkit-overflow-scrolling: touch;
}

.sheet.open { transform: translateY(0); }

/* The dialog panel takes programmatic focus on open; a ring around the whole
   sheet is noise — keyboard focus indication continues on its inner controls. */
.sheet:focus-visible { outline: none; }

@media (min-width: 720px) {
  .sheet {
    left: 50%; right: auto; bottom: 50%;
    transform: translate(-50%, calc(50% + 40px));
    opacity: 0;
    width: 640px;
    max-height: 80vh;
    border-radius: var(--radius-lg);
    transition: transform 240ms var(--ease), opacity 240ms var(--ease);
  }
  .sheet.open { transform: translate(-50%, 50%); opacity: 1; }
}

.sheet .grabber {
  width: 36px; height: 4px;
  border-radius: 2px;
  background: var(--faint);
  margin: 0 auto 18px;
}

@media (min-width: 720px) { .sheet .grabber { display: none; } }

.sheet .head { display: flex; gap: 18px; }

.sheet .head .poster {
  flex: 0 0 34%;
  max-width: 180px;
}

.sheet h2 { font-size: 22px; font-weight: 650; line-height: 1.2; margin-top: 6px; }

.sheet .facts { color: var(--muted); font-size: 14px; margin-top: 8px; }

.sheet .facts .dotsep { margin: 0 6px; color: var(--faint); }

.sheet .overview {
  margin-top: 18px;
  font-size: 15px;
  line-height: 1.6;
  color: var(--text);
}

.sheet .note {
  margin-top: 18px;
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--muted);
}

.media-state {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-top: 20px;
  padding: 13px 15px;
  border: 1px solid var(--surface-2);
  border-radius: var(--radius);
  background: rgba(255, 255, 255, 0.025);
}

.media-state strong { font-size: 14px; }
.media-state span { color: var(--muted); font-size: 13px; line-height: 1.45; }
.media-controls > .cta + .cta { margin-top: 10px; }

.confirm-panel {
  margin-top: 12px;
  padding: 14px;
  border: 1px solid color-mix(in srgb, var(--danger) 42%, var(--surface-2));
  border-radius: var(--radius);
  background: var(--surface);
}

.confirm-panel p { margin: 0; font-size: 14px; line-height: 1.5; }
.confirm-actions { display: flex; gap: 10px; margin-top: 12px; }
.confirm-actions .cta { margin: 0; padding: 11px 13px; font-size: 14px; }
.shelf > .confirm-panel { flex: 0 0 min(280px, 80vw); align-self: stretch; }

.sheet label.field {
  display: block;
  margin-top: 22px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
}

.sheet select {
  display: block;
  width: 100%;
  margin-top: 8px;
  appearance: none;
  border: 0;
  border-radius: var(--radius);
  background: var(--surface-2);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5 11 1.5' fill='none' stroke='%2394938c' stroke-width='1.8' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 14px center;
  color: var(--text);
  font: inherit;
  font-size: 15px;
  padding: 12px 40px 12px 14px;
}

.disclosure {
  display: flex;
  width: 100%;
  align-items: center;
  justify-content: space-between;
  appearance: none;
  border: 0;
  border-radius: var(--radius);
  background: var(--surface-2);
  color: var(--text);
  font: inherit;
  font-size: 15px;
  padding: 12px 14px;
  margin-top: 14px;
  cursor: pointer;
}

.disclosure .lab {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
}

.disclosure .right { display: flex; align-items: center; gap: 10px; }
.disclosure .chev {
  color: var(--muted);
  transition: transform 200ms var(--ease);
}
.disclosure.open .chev { transform: rotate(180deg); }

.season-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 10px;
}

.season-chip {
  appearance: none;
  border: 0;
  background: var(--surface-2);
  color: var(--muted);
  font: inherit;
  font-size: 14px;
  padding: 8px 14px;
  border-radius: 999px;
  cursor: pointer;
  transition: color 160ms var(--ease), background-color 160ms var(--ease);
}

.season-chip.on { background: var(--accent); color: var(--bg); font-weight: 600; }

.linklike {
  appearance: none;
  border: 0;
  background: none;
  color: var(--accent);
  font: inherit;
  font-size: 14px;
  cursor: pointer;
  margin-top: 16px;
  padding: 4px 0;
}

.more-info-btn { margin-top: 8px; }

.more-info {
  margin-top: 6px;
  padding: 10px 12px;
  border-radius: var(--radius);
  background: var(--surface);
  font-size: 14px;
}

.more-info-row { display: flex; gap: 10px; padding: 3px 0; }

.more-info-label { color: var(--muted); flex: 0 0 82px; }

.more-info-vals { color: var(--text); }

.ep-list { margin-top: 10px; }

.ep-season-label { font-size: 13px; font-weight: 600; color: var(--muted); margin: 14px 0 6px; }

.ep-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 0;
  cursor: pointer;
  font-size: 15px;
}

.ep-row .num { color: var(--muted); font-variant-numeric: tabular-nums; width: 2.4em; }

.ep-row .have { margin-left: auto; font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); }

.ep-row input { accent-color: var(--accent); width: 18px; height: 18px; }

.cta {
  display: block;
  width: 100%;
  appearance: none;
  border: 0;
  border-radius: var(--radius);
  background: var(--accent);
  color: var(--bg);
  font: inherit;
  font-size: 16px;
  font-weight: 650;
  padding: 15px;
  margin-top: 26px;
  cursor: pointer;
  transition: opacity 160ms var(--ease), transform 160ms var(--ease);
}

.cta:active { transform: scale(0.985); }
.cta:disabled { background: var(--surface-2); color: var(--muted); cursor: default; }

.cta.secondary { background: var(--surface-2); color: var(--text); }
.cta.compact { display: inline-flex; width: auto; min-width: max-content; text-decoration: none; }

/* ---------- downloading cards (library) ---------- */

.bar {
  display: block;
  height: 3px;
  border-radius: 2px;
  background: var(--surface-2);
  margin-top: 8px;
  overflow: hidden;
}

.bar .fill {
  display: block;
  height: 100%;
  width: 100%;
  background: var(--accent);
  border-radius: 2px;
  transform-origin: left;
  transform: scaleX(0);
  transition: transform 400ms var(--ease);
}

.dl-card .meta { margin-top: 6px; }
/* one line: a wrapped status made its tile taller and knocked the row of
   posters out of line */
.dl-card .sub { font-variant-numeric: tabular-nums; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.badge.attention { color: var(--danger); }

/* download detail sheet */

.sheet .dl-status {
  color: var(--muted);
  font-size: 14px;
  margin-top: 8px;
  font-variant-numeric: tabular-nums;
}

.sheet > .bar { margin-top: 20px; }

.file-list { margin-top: 4px; }

.file-heading {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 18px 0 4px;
}

.file-row {
  display: flex;
  align-items: baseline;
  gap: 12px;
  padding: 10px 0;
  font-size: 14px;
}

.file-row + .file-row { border-top: 1px solid var(--surface-2); }

.file-row .num {
  flex: none;
  width: 2.4em;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

.file-row .fname {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.file-row .fpct {
  flex: none;
  color: var(--muted);
  font-size: 13px;
  font-variant-numeric: tabular-nums;
}

.file-row.done .fname { color: var(--muted); }

.file-hint { color: var(--muted); font-size: 14px; padding: 14px 0; }

/* ---------- item screen ---------- */

.backlink {
  appearance: none;
  border: 0;
  background: none;
  color: var(--muted);
  font: inherit;
  font-size: 14px;
  padding: 8px 0;
  margin-bottom: 6px;
  cursor: pointer;
  display: block;
}

@media (hover: hover) {
  .backlink:hover { color: var(--text); }
}

/* item screen header row: back link left, ⋯ menu right */

.item-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.menu-wrap { position: relative; }

.kebab {
  appearance: none;
  border: 0;
  background: none;
  color: var(--muted);
  font: inherit;
  font-size: 20px;
  line-height: 1;
  padding: 6px 10px;
  border-radius: 8px;
  cursor: pointer;
  transition: color 160ms var(--ease), background 160ms var(--ease);
}

@media (hover: hover) {
  .kebab:hover { color: var(--text); background: var(--surface); }
}

.menu-pop {
  position: absolute;
  right: 0;
  top: calc(100% + 4px);
  min-width: 210px;
  background: var(--surface);
  border: 1px solid var(--surface-2);
  border-radius: 12px;
  padding: 6px;
  z-index: 25;
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.5);
}

.menu-item {
  appearance: none;
  display: block;
  width: 100%;
  text-align: left;
  border: 0;
  background: none;
  color: var(--text);
  font: inherit;
  font-size: 14px;
  padding: 10px 12px;
  border-radius: 8px;
  cursor: pointer;
}

.menu-item:disabled { color: var(--muted); cursor: default; }

.menu-item.danger { color: var(--danger); }

@media (hover: hover) {
  .menu-item:not(:disabled):hover { background: var(--surface-2); }
}

.item-head { display: flex; gap: 18px; }

.item-head .poster { flex: 0 0 30%; max-width: 170px; }

.item-head h2 { font-size: 22px; font-weight: 650; line-height: 1.2; margin-top: 6px; }

.item-head .facts { color: var(--muted); font-size: 14px; margin-top: 8px; }

.cta.inline {
  display: inline-block;
  width: auto;
  padding: 10px 18px;
  font-size: 14px;
  margin-top: 18px;
}

.cta.inline + .cta.inline { margin-left: 10px; }

.files-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin: 30px 0 4px;
}

.files-head .section-title { margin: 0; }
.files-head .linklike { margin: 0; }

.files-head + .season-row { margin: 2px 0 14px; }
.files-head + .shelf { margin-top: 10px; }

.vfile-list { padding-bottom: 56px; }

.vfile-row {
  /* button (tap to play) or label (edit mode) — same skin for both */
  appearance: none;
  background: none;
  color: inherit;
  font: inherit;
  text-align: left;
  width: 100%;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 9px 0;
  font-size: 14px;
  border: 0;
  border-top: 1px solid var(--surface-2);
  cursor: pointer;
}

.vfile-list .vfile-row:first-child,
.ep-season-label + .vfile-row { border-top: 0; }

.vfile-row input {
  flex: none;
  width: 18px;
  height: 18px;
  accent-color: var(--accent);
}

/* rows that play give the same press/hover feedback as poster cards */
.vfile-row.playable:active .vthumb { transform: scale(0.965); }

@media (hover: hover) {
  .vfile-row.playable:hover .vthumb {
    transform: translateY(-2px) scale(1.02);
    box-shadow: 0 8px 20px rgba(0, 0, 0, 0.45);
  }
  .vfile-row.playable:hover .vname { color: var(--accent); }
}

.vthumb {
  flex: none;
  width: 98px;
  aspect-ratio: 16 / 9;
  border-radius: 4px;
  overflow: hidden;
  background: var(--surface);
  display: block;
  transition: transform 200ms var(--ease), box-shadow 200ms var(--ease);
}

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

.vmeta {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 5px;
}

.vmeta .vname {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-weight: 500;
  transition: color 160ms var(--ease);
}

.vsub {
  display: flex;
  align-items: center;
  gap: 8px;
}

.vtranslation {
  color: var(--accent);
  font-size: 11px;
}

.vtranslation.failed { color: var(--danger); }
.vtranslation.completed { color: var(--muted); }

.vtranslate {
  flex: none;
  appearance: none;
  border: 1px solid var(--surface-2);
  background: var(--surface);
  color: var(--accent);
  font: inherit;
  font-size: 11px;
  font-weight: 700;
  padding: 5px 9px;
  border-radius: 999px;
  cursor: pointer;
}

.translate-controls { display: grid; gap: 16px; }

.vsub .vsize {
  color: var(--muted);
  font-size: 12px;
  font-variant-numeric: tabular-nums;
}

.vplay {
  flex: none;
  color: var(--faint);
  font-size: 11px;
  padding-right: 4px;
  transition: color 160ms var(--ease);
}

@media (hover: hover) {
  .vfile-row.playable:hover .vplay { color: var(--accent); }
}

/* Missing-episode gap rows: quiet, with a Get button to the download sheet */

.vfile-row.gap .vname { color: var(--muted); }

.vfile-row.gap .vthumb { opacity: 0.35; }

.vmiss {
  color: var(--faint);
  font-size: 12px;
}

.vget {
  flex: none;
  appearance: none;
  border: 1px solid var(--surface-2);
  background: var(--surface);
  color: var(--accent);
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  padding: 5px 14px;
  border-radius: 999px;
  cursor: pointer;
  transition: background 160ms var(--ease), transform 160ms var(--ease);
}

.vget:active { transform: scale(0.95); }

@media (hover: hover) {
  .vget:hover { background: var(--surface-2); }
}

/* quality tier chips: 4K gold, 1080p bright, 720p/SD muted */

.q {
  flex: none;
  min-width: 44px;
  text-align: center;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.08em;
  padding: 3px 7px;
  border-radius: 4px;
  background: var(--surface-2);
  color: var(--muted);
}

.q.q4k { color: var(--accent); }
.q.qhd { color: var(--text); }
.q.qhdr { min-width: auto; }

/* floating selection bar in edit mode */

.edit-actions {
  position: fixed;
  left: 50%;
  transform: translateX(-50%);
  bottom: calc(84px + var(--safe-b));
  display: flex;
  align-items: center;
  gap: 14px;
  background: var(--surface-2);
  border-radius: 999px;
  padding: 8px 8px 8px 20px;
  z-index: 35;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.55);
  max-width: 92vw;
}

.edit-actions[hidden] { display: none; }

.edit-actions .count {
  font-size: 13px;
  color: var(--text);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.edit-actions .cta {
  width: auto;
  margin: 0;
  padding: 10px 18px;
  font-size: 14px;
  border-radius: 999px;
}

.cta.danger { background: var(--danger); color: var(--bg); }
.edit-actions .cta.danger:disabled { background: var(--surface); color: var(--muted); }

/* ---------- activity ---------- */

/* whole-disk usage card above the quick links */

.storage-card {
  background: var(--surface);
  border-radius: var(--radius);
  padding: 14px 16px;
  margin: 4px 0 12px;
}

.storage-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 10px;
}

.storage-title { font-weight: 600; font-size: 15px; }
.storage-figures { color: var(--muted); font-size: 12px; white-space: nowrap; }

.storage-bar {
  height: 6px;
  border-radius: 3px;
  background: var(--surface-2);
  overflow: hidden;
}

.storage-fill {
  height: 100%;
  width: 100%;
  border-radius: 3px;
  background: var(--accent);
  transform-origin: left;
  transition: transform 400ms var(--ease);
}

.storage-fill.low { background: var(--danger); }

/* quick doorways to sibling services (Jellyfin, mirror) */

.quick-links {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  margin: 4px 0 8px;
}

.quick-link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  background: var(--surface);
  border-radius: var(--radius);
  padding: 14px 16px;
  text-decoration: none;
  color: var(--text);
  transition: background-color 160ms var(--ease), transform 160ms var(--ease);
}

.quick-link:active { transform: scale(0.985); }

@media (hover: hover) {
  .quick-link:hover { background: var(--surface-2); }
  .quick-link:hover .ql-arrow { color: var(--accent); }
}

.ql-meta { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.ql-label { font-weight: 600; font-size: 15px; }
.ql-sub {
  color: var(--muted);
  font-size: 12px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ql-arrow { flex: none; color: var(--faint); font-size: 15px; transition: color 160ms var(--ease); }

.banner {
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--danger);
  font-size: 14px;
  padding: 14px 16px;
  margin-bottom: 20px;
}

.ev-row {
  display: flex;
  gap: 14px;
  padding: 12px 0;
  font-size: 14px;
  line-height: 1.45;
}

.ev-row + .ev-row { border-top: 1px solid var(--surface-2); }

.ev-time {
  flex: 0 0 auto;
  color: var(--muted);
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  padding-top: 2px;
}

.ev-body { overflow-wrap: anywhere; }
.ev-body .detail { color: var(--muted); font-size: 13px; margin-top: 2px; }
.ev-body.error { color: var(--danger); }

/* ---------- chat ---------- */
/* Content first. The composer is the only container; everything else is
   spacing, weight and muted colour. At rest at most one gold element is on
   screen, and it is the action that matters now. Motion only reports state:
   something arrived, opened, progressed or finished. */

.chat-navigation,
.chat-outcome,
.attention-root,
.chat-log { max-width: 720px; margin-left: auto; margin-right: auto; }

/* Shared chevron for disclosures, drawn with a mask so it takes the text
   colour of its summary. */
.chat-work > summary::before,
.chat-followup-more > summary::before,
.chat-outcome-details > summary::before,
.chat-snippet > summary::before,
.attention-heading::after,
.chat-outcome-chevron {
  content: "";
  flex: none;
  width: 10px;
  height: 10px;
  background-color: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9 5l7 7-7 7'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9 5l7 7-7 7'/%3E%3C/svg%3E") center / contain no-repeat;
  transition: transform 200ms var(--ease-out-quint);
}
.chat-work[open]:not(.is-closing) > summary::before,
.chat-followup-more[open]:not(.is-closing) > summary::before,
.chat-outcome-details[open]:not(.is-closing) > summary::before,
.chat-snippet[open]:not(.is-closing) > summary::before { transform: rotate(90deg); }
/* A trailing chevron (the attention line, like the request strip's) points
   down at rest and up when open; a leading one turns from right to down. */
.attention-heading::after { transform: rotate(90deg); }
.chat-attention[open]:not(.is-closing) > .attention-heading::after { transform: rotate(-90deg); }

/* A disclosure body is one grid row that opens 0fr → 1fr (animated from
   app.js); its content clips only while it moves, so focus rings inside an
   open disclosure are never cut off. */
.chat-disclosure { display: grid; grid-template-rows: 1fr; }
.chat-disclosure > * { min-height: 0; }
details.is-animating > .chat-disclosure > * { overflow: hidden; }
.chat-log summary, .chat-outcome summary, .attention-root summary { list-style: none; cursor: pointer; }
.chat-log summary::-webkit-details-marker,
.chat-outcome summary::-webkit-details-marker,
.attention-root summary::-webkit-details-marker { display: none; }

/* header: the conversation title is a quiet text control */
.chat-navigation { position: relative; margin-top: 2px; }
.chat-nav-row { min-width: 0; min-height: 44px; display: flex; align-items: center; gap: 10px; }
.chat-title {
  position: relative;
  flex: 0 1 auto;
  min-width: 0;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-left: -8px;
  padding: 7px 8px;
  border-radius: 10px;
  color: var(--text);
  transition: background-color var(--dur-1) var(--ease-out-quint);
}
.chat-title-text {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: var(--fs-md);
  font-weight: 400;
  /* a navigation control, not the page headline: regular weight and muted
     (6.25:1), so the request's title below is the one emphasised line above
     the conversation. Hover brings it to the text colour. */
  color: var(--muted);
  transition: color var(--dur-1) var(--ease-out-quint);
}
.chat-title-chevron { flex: none; color: var(--muted); transition: color var(--dur-1) var(--ease-out-quint); }
/* The native select lies over the title: its picker, keyboard behaviour and
   accessible name stay native while the title reads as plain text. */
.chat-thread-select {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  appearance: none;
  -webkit-appearance: none;
  border: 0;
  font: inherit;
  font-size: 16px;
  cursor: pointer;
}
.chat-thread-select option { background: var(--surface); color: var(--text); font-size: var(--fs-md); font-weight: 400; }
.chat-thread-select:disabled { cursor: default; }
.chat-title:has(.chat-thread-select:disabled) { opacity: 0.6; }
.chat-title:has(.chat-thread-select:focus-visible) { outline: 2px solid var(--accent); outline-offset: 2px; }
@media (hover: hover) {
  .chat-title:has(.chat-thread-select:not(:disabled):hover) { background: var(--surface); }
  .chat-title:has(.chat-thread-select:not(:disabled):hover) .chat-title-chevron,
  .chat-title:has(.chat-thread-select:not(:disabled):hover) .chat-title-text { color: var(--text); }
}
/* what the title cannot say: an owner thread, a failure or a cleanup lock */
.chat-thread-meta { flex: none; display: inline-flex; align-items: center; gap: 8px; color: var(--muted); font-size: var(--fs-sm); white-space: nowrap; }
.chat-thread-meta > * + *::before { content: "·"; margin-right: 8px; color: var(--muted); }
.chat-thread-status.chat-tone-failed { color: var(--danger); }
.chat-thread-status.chat-tone-waiting { color: var(--accent); }
.chat-new {
  flex: none;
  margin-left: auto;
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  padding: 0;
  border: 0;
  border-radius: 10px;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  transition: color var(--dur-1) var(--ease-out-quint), background-color var(--dur-1) var(--ease-out-quint), transform var(--dur-1) var(--ease-out-quint);
}
.chat-new:active:not(:disabled) { transform: scale(0.94); }
.chat-new:disabled { opacity: 0.4; cursor: default; }
@media (hover: hover) { .chat-new:not(:disabled):hover { color: var(--text); background: var(--surface); } }
/* The 18px glyph, not the button's box, sits on the column's right edge,
   like the title's -8px optical inset on the left. */
.chat-new { margin-right: -10px; }
@media (pointer: coarse) { .chat-new { width: 44px; height: 44px; margin-right: -13px; } }

/* Desktop: the floating tab dock sits over the top of the page. Pin the
   header below it on a solid band (full width, behind the column) that
   fades into the transcript, so the dock never covers the header and text
   scrolls away softly instead of against a hard edge.
   76px = body (64) + main (12) padding. */
@media (min-width: 720px) {
  .chat-navigation {
    position: sticky;
    top: 0;
    z-index: 20;
    margin-top: -76px;
    padding-top: calc(76px + var(--safe-t));
    padding-bottom: 4px;
  }
  .chat-navigation::before,
  .chat-navigation::after {
    content: "";
    position: absolute;
    left: 50%;
    width: 100vw;
    transform: translateX(-50%);
    pointer-events: none;
    z-index: -1;
  }
  .chat-navigation::before { top: 0; bottom: 0; background: var(--bg); }
  .chat-navigation::after { top: 100%; height: 20px; background: linear-gradient(var(--bg), rgba(14, 14, 16, 0)); }
}

/* small shared chat button (outcome actions, attention controls): plain
   text that underlines on hover, so an expanded strip adds words, not
   boxes. The composer stays the only container; the one filled shape is
   the accent action, .primary. The hit area keeps its height. */
.chat-button {
  min-height: 34px;
  padding: 7px 0;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: var(--text);
  font: inherit;
  font-size: var(--fs-sm);
  font-weight: 500;
  text-decoration: underline;
  text-decoration-color: transparent;
  text-underline-offset: 3px;
  cursor: pointer;
  transition: background-color var(--dur-1) var(--ease-out-quint), text-decoration-color var(--dur-1) var(--ease-out-quint), transform var(--dur-1) var(--ease-out-quint), opacity var(--dur-1) var(--ease-out-quint);
}
.chat-button.is-quiet { color: var(--muted); }
.chat-button:active:not(:disabled) { transform: scale(0.97); }
.chat-button.primary { padding: 7px 12px; border-radius: 999px; background: var(--accent); color: var(--bg); font-weight: 600; text-decoration: none; }
.chat-button:disabled { opacity: 0.5; cursor: default; }
@media (hover: hover) {
  .chat-button:not(.primary):not(:disabled):hover { text-decoration-color: color-mix(in srgb, currentColor 45%, transparent); }
  .chat-button.primary:not(:disabled):hover { background: color-mix(in srgb, var(--accent) 88%, var(--text)); }
}
@media (pointer: coarse) { .chat-button { min-height: 40px; padding-block: 9px; } .chat-button.primary { padding-inline: 14px; } }

/* saved request: one line and a hairline track; expands on tap */
.chat-outcome:empty { display: none; }
.chat-outcome { margin-top: 6px; }
.chat-outcome-card { font-size: var(--fs-sm); line-height: 1.5; overflow-wrap: anywhere; }
.chat-outcome-summary {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  align-items: center;
  column-gap: 10px;
  padding-top: 8px;
}
.chat-outcome-identity { min-width: 0; display: flex; align-items: baseline; white-space: nowrap; }
/* the title gives way first; the episode or season scope stays readable */
.chat-outcome-title { min-width: 0; overflow: hidden; text-overflow: ellipsis; color: var(--text); font-size: var(--fs-md); font-weight: 600; }
.chat-outcome-sep { flex: none; white-space: pre; color: var(--muted); }
.chat-outcome-scope { flex: none; color: var(--muted); }
.chat-outcome-status {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  color: var(--muted);
  font-size: var(--fs-sm);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.chat-outcome-status.chat-tone-waiting { color: var(--accent); }
.chat-outcome-status.chat-tone-success { color: var(--text); }
/* Amber means only "needs you" or "act": landing is reported in the text
   colour, so a finished request adds no accent to the screen. */
.chat-outcome-check { color: var(--text); }
.chat-outcome-check path { stroke-dasharray: 20; stroke-dashoffset: 0; }
.chat-outcome-status.is-arriving .chat-outcome-check path { animation: chat-check-draw 300ms var(--ease-out-quint) 380ms both; }
.chat-outcome-status.is-arriving .chat-outcome-status-text { animation: chat-fade-in var(--dur-2) var(--ease-out-quint) 200ms both; }
.chat-outcome-chevron { color: var(--muted); transform: rotate(90deg); transition: transform 200ms var(--ease-out-quint), color var(--dur-1) var(--ease-out-quint); }
.chat-outcome-card[open]:not(.is-closing) .chat-outcome-chevron { transform: rotate(-90deg); }
@media (hover: hover) { .chat-outcome-summary:hover .chat-outcome-chevron { color: var(--text); } }
/* Phones: a long title would be cut to a few characters beside the status;
   give it the line and set the scope under it. */
@media (max-width: 420px) {
  .chat-outcome-identity { flex-direction: column; align-items: stretch; }
  .chat-outcome-title { display: block; }
  .chat-outcome-sep { display: none; }
  .chat-outcome-scope { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
}

/* The track: 2px, the column's width. Its space is always kept so the
   strip never changes height as states come and go. */
.chat-outcome-track {
  grid-column: 1 / -1;
  position: relative;
  height: 2px;
  margin-top: 10px;
  border-radius: 2px;
  overflow: hidden;
  background: rgba(255, 255, 255, 0.07);
  transition: opacity 300ms var(--ease-out-quart);
}
.chat-outcome-fill {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: rgba(240, 239, 236, 0.7);
  transform: scaleX(var(--fill, 0));
  transform-origin: left center;
  transition: transform 400ms var(--ease-out-quint);
}
/* Needs you: the status text is the strip's one amber signal; the fill is
   simply still, which already contrasts with the breathing pending line. */
.chat-outcome-track.is-waiting .chat-outcome-fill { background: color-mix(in srgb, var(--text) 45%, transparent); }
.chat-outcome-track.is-paused .chat-outcome-fill { background: var(--muted); }
.chat-outcome-track.is-pending { animation: chat-breathe-track 2.4s ease-in-out infinite; }
.chat-outcome-track.is-pending .chat-outcome-fill { background: rgba(240, 239, 236, 0.45); }
.chat-outcome-track.is-arriving { animation: chat-fade-out 320ms var(--ease-out-quart) 480ms forwards; }
.chat-outcome-track.is-gone { opacity: 0; }
.chat-outcome-card:not(:has(.chat-outcome-track)) .chat-outcome-summary::after { content: ""; grid-column: 1 / -1; height: 12px; }

.chat-outcome-body { display: grid; gap: 8px; padding: 12px 0 4px; }
.chat-outcome-sentence { color: var(--text); max-width: 68ch; }
.chat-outcome-when { color: var(--muted); }
.chat-outcome-when:empty { display: none; }
.chat-outcome-blocker { color: var(--muted); max-width: 68ch; }
.chat-outcome-blocker.chat-tone-waiting { color: var(--text); }
.chat-outcome-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 0 20px; }
.chat-outcome-details { color: var(--muted); }
.chat-outcome-details > summary { display: inline-flex; align-items: center; gap: 6px; padding: 4px 0; transition: color var(--dur-1) var(--ease-out-quint); }
.chat-outcome-facts { display: grid; gap: 4px; padding: 4px 0 2px 16px; }
@media (hover: hover) { .chat-outcome-details > summary:hover { color: var(--text); } }

/* attention: one quiet line with an amber dot, details on tap */
.attention-root:empty { display: none; }
.attention-root { margin-top: 4px; }
.chat-attention { font-size: var(--fs-sm); }
.attention-heading {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 36px;
  padding: 6px 0;
  color: var(--muted);
  transition: color var(--dur-1) var(--ease-out-quint);
}
.attention-dot { flex: none; width: 6px; height: 6px; border-radius: 50%; background: var(--accent); }
@media (hover: hover) { .attention-heading:hover { color: var(--text); } }
.chat-attention[open] > .attention-heading { color: var(--text); }
.attention-list { display: grid; gap: 18px; padding: 6px 0 14px 14px; }
.attention-item { display: grid; gap: 3px; color: var(--text); text-align: left; }
.attention-title { font-weight: 600; overflow-wrap: anywhere; }
.attention-summary { color: var(--muted); overflow-wrap: anywhere; }
.attention-controls { display: flex; flex-wrap: wrap; align-items: center; gap: 0 16px; margin-top: 4px; }
.attention-input {
  min-width: 0;
  flex: 1 1 180px;
  min-height: 34px;
  padding: 6px 12px;
  border: 1px solid var(--line);
  border-radius: 999px;
  color: var(--text);
  background: var(--bg);
  font: inherit;
  font-size: var(--fs-sm);
}
.attention-result { color: var(--muted); }
.attention-result:empty { display: none; }

/* log: 28px between turns, 10px within one */
.chat-log {
  display: flex;
  flex-direction: column;
  margin-top: 22px;
  /* Room for the fixed composer (its live height) plus a 24px gap. The
     composer sits 70px up, above the tab dock; main (24px) and body (76px)
     already pad the page bottom, so the log adds the rest:
     composer + 70 + 24 - 24 - 76. More than this left every thread ending in
     ~126px of blank space on phones. */
  padding-bottom: max(0px, calc(var(--composer-h, 120px) - 6px));
}
.chat-log > * + * { margin-top: 28px; }
.chat-log > .msg.user + .msg.user { margin-top: 10px; }
.chat-log > .chat-notice { margin-top: 16px; }
/* Only the empty state fills the screen (to centre its hero). A short thread
   must not scroll on open: scrolling to its end hid the request strip, and
   its Review download recovery button, under the sticky header. */
.chat-log:has(.chat-hero) { min-height: calc(100dvh - 290px); margin-top: 0; }

/* what arrives while the conversation is open rises into place */
.chat-log > .is-entering { animation: chat-enter var(--dur-2) var(--ease-out-quint) both; }

/* empty state: a calm, left-aligned block, centred in the free space. The
   heading carries the moment; no decorative mark sits above it. */
.chat-hero { width: 100%; max-width: 520px; margin: auto 0; padding: 28px 0 20px; }
@media (max-height: 700px) { .chat-hero { padding-top: 8px; } }
.chat-hero h2 { font-size: var(--fs-lg); font-weight: 600; letter-spacing: -0.015em; line-height: 1.25; text-wrap: balance; }
.chat-hero-lede { max-width: 44ch; margin-top: 6px; color: var(--muted); font-size: var(--fs-md); line-height: 1.55; text-wrap: pretty; }
.chat-hero-note { margin-top: 14px; color: var(--muted); font-size: var(--fs-sm); }
/* Its own class, not .is-entering: the per-message rise on the hero itself
   compounded with its children's (a 12px, 0.4-opacity start) and, having no
   offset, restarted from invisible on every rebuild in the first 600ms. */
.chat-hero.is-staggering > :not(.chat-suggestions),
.chat-hero.is-staggering .chat-suggestion {
  animation: chat-rise var(--dur-3) var(--ease-out-quint) both;
  animation-delay: calc(var(--i, 0) * 40ms - var(--enter-offset, 0ms));
}

/* assistant choice: two text options over a hairline; the underline slides.
   The lede above already changes with the choice, so no hint repeats it. */
.chat-mode { margin-top: 20px; display: grid; justify-items: start; }
.chat-mode-options {
  position: relative;
  display: inline-flex;
  gap: 24px;
  box-shadow: inset 0 -1px 0 var(--line);
}
.chat-mode-option {
  appearance: none;
  min-height: 40px;
  padding: 8px 2px 10px;
  border: 0;
  background: none;
  color: var(--muted);
  font: inherit;
  font-size: var(--fs-sm);
  font-weight: 500;
  cursor: pointer;
  transition: color var(--dur-2) var(--ease-out-quint);
}
.chat-mode-option[aria-checked="true"] { color: var(--text); }
.chat-mode-option:disabled { cursor: default; opacity: 0.6; }
@media (hover: hover) { .chat-mode-option:not(:disabled):hover { color: var(--text); } }
/* A 1px-wide line scaled to the chosen label's width (app.js measures it),
   so the underline moves and resizes with transform alone. */
.chat-mode-indicator {
  position: absolute;
  left: 0;
  bottom: 0;
  width: 1px;
  height: 2px;
  background: var(--text);
  transform: translateX(var(--indicator-x, 0px)) scaleX(var(--indicator-w, 0));
  transform-origin: left center;
  pointer-events: none;
}
.chat-mode-options.is-sliding > .chat-mode-indicator { transition: transform var(--dur-2) var(--ease-out-quint); }

/* suggestions: plain rows; the arrow arrives on hover */
.chat-suggestions { display: grid; gap: 2px; margin: 20px -12px 0; }
.chat-suggestion {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  width: 100%;
  min-height: 44px;
  padding: 10px 12px;
  border: 0;
  border-radius: 12px;
  background: transparent;
  color: var(--muted);
  font: inherit;
  font-size: var(--fs-md);
  text-align: left;
  cursor: pointer;
  transition: color var(--dur-1) var(--ease-out-quint), background-color var(--dur-1) var(--ease-out-quint), opacity var(--dur-2) var(--ease-out-quint);
}
.chat-suggestion-text { min-width: 0; }
.chat-suggestion-arrow { flex: none; opacity: 0; transform: translateX(-4px); transition: opacity var(--dur-2) var(--ease-out-quint), transform var(--dur-2) var(--ease-out-quint); }
.chat-suggestion:disabled { cursor: default; opacity: 0.55; }
@media (hover: hover) {
  .chat-suggestion:not(:disabled):hover { color: var(--text); background: var(--surface); }
  .chat-suggestion:not(:disabled):hover .chat-suggestion-arrow { opacity: 1; transform: none; }
}
@media (hover: none) { .chat-suggestion-arrow { opacity: 0.5; transform: none; } }
.chat-suggestion:focus-visible .chat-suggestion-arrow { opacity: 1; transform: none; }

/* messages */
.msg.user {
  align-self: flex-end;
  max-width: min(80%, 560px);
  padding: 10px 15px;
  border-radius: 18px;
  background: var(--surface-2);
  color: var(--text);
  font-size: var(--fs-md);
  line-height: 1.5;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.msg.bot { align-self: stretch; min-width: 0; color: var(--text); font-size: var(--fs-md); line-height: 1.65; }
.msg.bot > * + * { margin-top: 10px; }
.msg.bot .md > * + * { margin-top: 12px; }
/* prose measure: shelves may run wide, text must not */
.msg.bot p, .msg.bot ul, .msg.bot ol, .msg.bot h3, .msg.bot h4, .msg.bot pre { max-width: 68ch; }
.msg.bot p, .msg.bot li, .msg.bot a, .msg.bot code, .msg.user code { overflow-wrap: anywhere; }
.msg.bot p { text-wrap: pretty; }
.msg.bot h3, .msg.bot h4 { font-size: var(--fs-md); font-weight: 600; margin-top: 18px; }
.msg.bot ul, .msg.bot ol { padding-left: 22px; }
.msg.bot li { margin: 4px 0; }
.msg.bot li::marker { color: var(--muted); }
/* Links are underlined text, not gold: colour alone is too weak a cue
   (gold on this text is about 2:1), and gold stays for actions. */
.msg.bot a {
  color: var(--text);
  text-decoration: underline;
  text-decoration-color: color-mix(in srgb, var(--text) 35%, transparent);
  text-underline-offset: 3px;
  transition: text-decoration-color var(--dur-1) var(--ease-out-quint);
}
.msg.bot a:hover { text-decoration-color: currentColor; }
.msg.bot code {
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: var(--fs-sm);
  background: var(--surface);
  border-radius: 4px;
  padding: 2px 6px;
}
/* code blocks scroll inside their own box, never the page */
.msg.bot pre {
  max-width: 100%;
  background: var(--surface);
  border-radius: var(--radius);
  padding: 12px 14px;
  overflow-x: auto;
}
.msg.bot pre code { background: none; padding: 0; overflow-wrap: normal; white-space: pre; }
.chat-pending { display: block; margin-top: 4px; color: var(--muted); font-size: var(--fs-sm); }
.chat-unsent { display: flex; align-items: center; gap: 10px; margin-top: 6px; font-size: var(--fs-sm); color: var(--danger); white-space: normal; }
.chat-unsent .linklike { margin: 0; font-size: var(--fs-sm); padding: 0; }
.chat-snippet { margin-top: 8px; font-size: var(--fs-sm); white-space: normal; }
.chat-snippet > summary { display: inline-flex; align-items: center; gap: 6px; color: var(--muted); transition: color var(--dur-1) var(--ease-out-quint); }
@media (hover: hover) { .chat-snippet > summary:hover { color: var(--text); } }
.chat-snippet pre { white-space: pre-wrap; overflow-wrap: anywhere; max-height: 240px; overflow: auto; margin-top: 6px; }
.chat-handoff { display: grid; grid-template-columns: auto 1fr; gap: 2px 10px; margin-top: 6px; }
.chat-handoff dt { color: var(--muted); text-transform: capitalize; }
.chat-handoff dd { overflow-wrap: anywhere; }
.chat-image { display: block; max-width: 100%; max-height: 360px; object-fit: contain; border-radius: 10px; margin-top: 8px; }

/* poster shelves inside a reply */
.chat-shelf { margin: 14px -20px 6px; padding: 0 20px 4px; }
.chat-shelf .card { flex: 0 0 118px; }
@media (min-width: 640px) { .chat-shelf .card { flex-basis: 132px; } }

/* work: steps and commentary behind one quiet disclosure */
.chat-work { font-size: var(--fs-sm); }
.chat-work > summary, .chat-followup-more > summary {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 0;
  color: var(--muted);
  transition: color var(--dur-1) var(--ease-out-quint);
}
@media (hover: hover) { .chat-work > summary:hover, .chat-followup-more > summary:hover { color: var(--text); } }
.chat-work-list {
  display: grid;
  gap: 6px;
  margin-left: 4px;
  padding: 8px 0 4px 12px;
  border-left: 1px solid var(--line);
}
.msg.bot .chat-commentary { color: var(--muted); font-size: var(--fs-sm); line-height: 1.55; }
.msg.bot .chat-commentary > * + * { margin-top: 6px; }
.chat-step > summary { padding: 3px 0; color: var(--muted); font-size: var(--fs-sm); overflow-wrap: anywhere; transition: color var(--dur-1) var(--ease-out-quint); }
.chat-step[open] > summary { color: var(--text); }
@media (hover: hover) { .chat-step > summary:hover { color: var(--text); } }
.chat-step-failed { color: var(--danger) !important; }
.chat-step-body { display: grid; gap: 6px; padding: 4px 0 8px; font-size: var(--fs-sm); min-width: 0; }
.chat-step-body strong { color: var(--muted); font-weight: 600; }
.msg.bot .chat-step-body pre, .chat-step-body pre {
  max-width: 100%;
  max-height: 280px;
  overflow: auto;
  padding: 8px 10px;
  border-radius: 8px;
  background: var(--surface);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: var(--fs-mono);
}
.chat-step-note { color: var(--muted); }

/* automatic progress checks: one muted row, then the latest answer in the
   assistant's normal voice (it is usually the newest state on the page);
   earlier checks stay small and muted inside the disclosure */
.chat-followup-head, .chat-followup-more > summary { font-size: var(--fs-sm); color: var(--muted); }
/* A head with nothing to open has no chevron; its text still starts on the
   summaries' text column (10px chevron + 6px gap). */
.chat-followup-head, .chat-auto-head { padding: 3px 0 3px 16px; }
.chat-followup-list { display: grid; }
.chat-followup-entry { display: grid; gap: 4px; margin: 8px 0 4px 4px; padding-left: 12px; border-left: 1px solid var(--line); color: var(--muted); font-size: var(--fs-sm); line-height: 1.55; }
.chat-followup-time { color: var(--muted); }
/* an automatic turn with no steps to show: one muted line marks it unrequested
   (with steps, that label leads its Show work summary instead) */
.chat-auto-head { font-size: var(--fs-sm); color: var(--muted); }

/* a provider retry notice: one quiet line per turn */
.chat-provider-note {
  max-width: 100%;
  overflow: hidden;
  color: var(--muted);
  font-size: var(--fs-sm);
  white-space: nowrap;
  text-overflow: ellipsis;
}

.chat-error { max-width: 68ch; color: var(--danger); font-size: var(--fs-md); }
.chat-resolved { max-width: 68ch; color: var(--muted); font-size: var(--fs-sm); }

/* copy: faint on touch, fades in on hover or focus elsewhere; confirms in place */
.chat-copy {
  position: relative;
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  margin: 2px 0 -6px -6px;
  padding: 0;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  opacity: 0.65;
  transition: opacity var(--dur-1) var(--ease-out-quint), color var(--dur-1) var(--ease-out-quint), background-color var(--dur-1) var(--ease-out-quint);
}
.chat-copy svg { grid-area: 1 / 1; }
.chat-copy .icon-check { opacity: 0; color: var(--text); }
.chat-copy .icon-check path { stroke-dasharray: 20; stroke-dashoffset: 0; }
.chat-copy.is-copied { opacity: 1; }
.chat-copy.is-copied svg:first-child { opacity: 0; }
.chat-copy.is-copied .icon-check { opacity: 1; }
/* The path is drawn at rest; the animation draws it in from 20 (fill both),
   so a page without animation still shows the check. */
.chat-copy.is-copied .icon-check path { animation: chat-check-draw 300ms var(--ease-out-quint) both; }
/* With a pointer the icon is hidden until hover, so it must not hold open a
   gap of its own: it hangs in the space below the answer instead. */
@media (hover: hover) {
  .msg.bot:has(> .chat-copy) { position: relative; }
  .chat-log > .msg.bot:has(> .chat-copy) + * { margin-top: 38px; }
  .chat-copy { position: absolute; top: calc(100% + 1px); left: -6px; width: 26px; height: 26px; margin: 0; opacity: 0; }
  .msg.bot:hover .chat-copy, .msg.bot:focus-within .chat-copy, .chat-copy.is-copied { opacity: 1; }
  .chat-copy:hover { color: var(--text); background: var(--surface); }
}

/* worker notices: small, muted, left-aligned, no box */
.chat-notice { align-self: flex-start; max-width: 68ch; color: var(--muted); font-size: var(--fs-sm); line-height: 1.5; overflow-wrap: anywhere; }
.chat-notice-success { color: var(--text); }
/* Two classes: the plain .chat-notice rule above must not turn the needs-you
   sentence back to small grey. It reads at body size in the text colour,
   never as a filled callout or amber text: when it carries the page's one
   accent action, the button under it is the only gold where the chat ends. */
.chat-notice.chat-notice-waiting { color: var(--text); font-size: var(--fs-md); }
.chat-notice-waiting.has-action { display: flex; flex-direction: column; align-items: flex-start; gap: 10px; }
.chat-notice-text { min-width: 0; }
/* announced, not shown (e.g. "Copied") */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* composer: the one container, pinned above the tab dock */
.composer {
  position: fixed;
  left: 50%;
  transform: translateX(-50%);
  bottom: calc(70px + var(--safe-b));
  /* on the column's edges: the page gutter on each side, 720px at most */
  width: calc(100% - 2 * var(--pad-x));
  max-width: 720px;
  display: block;
  padding: 5px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 24px;
  z-index: 31;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.35);
  transition: border-color var(--dur-2) var(--ease-out-quint), box-shadow var(--dur-2) var(--ease-out-quint);
}
.composer:focus-within {
  border-color: rgba(255, 255, 255, 0.16);
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.35), 0 0 0 4px rgba(255, 255, 255, 0.025);
}
/* Arriving by keyboard (Tab from the "+" or the page), the quiet change is
   too weak to find the focus (1.35:1 against the idle border). A textarea
   matches :focus-visible on every focus, so app.js marks keyboard
   navigation on the root and only then does the border step up to about
   3:1. Clicking or tapping into the composer, or the page focusing it on
   load, keeps the quiet look; gold stays for actions. */
.is-keyboard-nav .composer:focus-within { border-color: rgba(255, 255, 255, 0.4); }
.composer .chat-input:focus, .composer .chat-input:focus-visible { outline: none; }

/* the status line grows and folds with a grid row; its children carry the
   vertical padding so a folded line is truly zero high */
.chat-status {
  display: grid;
  grid-template-rows: 0fr;
  opacity: 0;
  transition: grid-template-rows var(--dur-2) var(--ease-out-quint), opacity var(--dur-1) var(--ease-out-quint);
}
.chat-status.is-shown { grid-template-rows: 1fr; opacity: 1; }
.chat-connection {
  /* The line sits on the composer's own columns: its text starts where the
     textarea's text does (44px attach + 2px gap + 4px input padding), and a
     status dot centres under the "+" (22px in, so 19px for a 6px dot). */
  --status-text: 50px;
  --status-dot: 19px;
  min-height: 0;
  overflow: hidden;
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  padding: 0 12px 0 var(--status-text);
  color: var(--muted);
  font-size: var(--fs-sm);
  line-height: 1.4;
}
.chat-connection > * { padding-top: 7px; padding-bottom: 3px; }
.chat-connection[hidden] { display: none; }
.chat-connection.is-error { color: var(--danger); }
.chat-connection .linklike { margin: 0; font-size: var(--fs-sm); flex: none; padding-left: 0; padding-right: 0; }
.chat-connection strong { color: var(--text); font-weight: 600; flex: none; }
.chat-connection-text, .chat-connection-note { min-width: 0; overflow-wrap: anywhere; }
.chat-working { flex: 1; min-width: 0; display: inline-flex; align-items: center; gap: 8px; }
.chat-working-label { flex: none; }
.chat-working-label[hidden], .chat-working-detail[hidden] { display: none; }
.chat-working-detail { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chat-working-label:not([hidden]) + .chat-working-detail::before { content: "·"; margin-right: 8px; }
.chat-reply { display: inline-flex; align-items: center; gap: 8px; color: var(--muted); }
/* The dot hangs left of the text column, under the "+": 50 - 19 = 31px
   back, then 25 - 8 (the gap) = 17px to the text. Working breathes in the
   text colour; "Reply to continue" needs you, so its dot is amber, and only
   the dot: the words repeat the "Reply to Timora…" placeholder. */
.chat-pulse, .chat-reply-dot {
  flex: none;
  width: 6px;
  height: 6px;
  margin-left: calc(var(--status-dot) - var(--status-text));
  margin-right: calc(var(--status-text) - var(--status-dot) - 6px - 8px);
  border-radius: 50%;
  background: currentColor;
}
.chat-reply-dot { background: var(--accent); }
.chat-pulse { animation: chat-breathe 1.8s ease-in-out infinite; }

.chat-attachments { display: flex; flex-wrap: wrap; gap: 6px; }
.chat-attachments:not(:empty) { padding: 6px 6px 2px; }
.chat-attachment {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  max-width: 100%;
  min-height: 30px;
  padding: 4px 9px 4px 11px;
  border: 0;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.06);
  color: var(--text);
  font: inherit;
  font-size: var(--fs-sm);
  text-align: left;
  overflow-wrap: anywhere;
  cursor: pointer;
  transition: background-color var(--dur-1) var(--ease-out-quint);
}
.chat-attachment svg { flex: none; color: var(--muted); }
@media (hover: hover) { .chat-attachment:hover { background: rgba(255, 255, 255, 0.1); } }

.composer-row { display: flex; align-items: flex-end; gap: 2px; }
.chat-input {
  flex: 1;
  min-width: 0;
  min-height: 44px;
  max-height: 160px;
  appearance: none;
  border: 0;
  background: none;
  color: var(--text);
  font: inherit;
  font-size: var(--fs-md);
  line-height: 1.4;
  padding: 11px 4px;
  resize: none;
}
@media (pointer: coarse) { .chat-input { font-size: 16px; } }
.chat-input::placeholder { color: var(--muted); }
.chat-attach {
  flex: none;
  appearance: none;
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  transition: color var(--dur-1) var(--ease-out-quint), background-color var(--dur-1) var(--ease-out-quint), opacity var(--dur-1) var(--ease-out-quint);
}
.chat-attach:disabled { opacity: 0.35; cursor: default; }
@media (hover: hover) { .chat-attach:not(:disabled):hover { color: var(--text); background: rgba(255, 255, 255, 0.05); } }

/* Send and Stop share one slot: a 44px target with a 34px circle drawn
   behind the icon. The idle one fades and settles to 92% before it hides.
   Send's gold is its own layer (::after) that fades and scales in over the
   neutral disc, so the crossfade moves opacity and transform only. */
.composer-slot { flex: none; display: grid; width: 44px; height: 44px; }
.composer-slot > button {
  grid-area: 1 / 1;
  position: relative;
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  cursor: pointer;
  transition: opacity var(--dur-1) var(--ease-out-quint), transform var(--dur-1) var(--ease-out-quint), color var(--dur-1) var(--ease-out-quint), visibility 0s linear 0s;
}
.composer-slot > button::before,
.composer .send::after {
  content: "";
  position: absolute;
  inset: 5px;
  border-radius: 50%;
  transition: transform var(--dur-1) var(--ease-out-quint), opacity var(--dur-1) var(--ease-out-quint);
}
.composer-slot > button svg { position: relative; z-index: 1; }
.composer-slot[data-mode="send"] > .chat-stop,
.composer-slot[data-mode="stop"] > .send {
  opacity: 0;
  transform: scale(0.92);
  visibility: hidden;
  pointer-events: none;
  transition: opacity var(--dur-1) var(--ease-out-quint), transform var(--dur-1) var(--ease-out-quint), visibility 0s linear var(--dur-1);
}
.composer .send { color: var(--muted); }
.composer .send::before { background: rgba(255, 255, 255, 0.06); transform: scale(0.92); }
.composer .send::after { background: var(--accent); opacity: 0; transform: scale(0.92); }
.composer .send.is-ready { color: var(--bg); }
.composer .send.is-ready::before, .composer .send.is-ready::after { opacity: 1; transform: scale(1); }
.composer .send:disabled, .composer .send[aria-disabled="true"] { cursor: default; }
.chat-stop { color: var(--text); }
.chat-stop::before { background: rgba(255, 255, 255, 0.14); }
.chat-stop:disabled { opacity: 0.5; cursor: default; }
.composer .send.is-ready:active::after, .chat-stop:not(:disabled):active::before { transform: scale(0.9); }
@media (hover: hover) {
  .composer .send.is-ready:hover::after { background: color-mix(in srgb, var(--accent) 88%, var(--text)); }
  .chat-stop:not(:disabled):hover::before { background: rgba(255, 255, 255, 0.2); }
}
.chat-navigation button:focus-visible, .chat-log button:focus-visible, .chat-outcome button:focus-visible,
.attention-root button:focus-visible, .composer button:focus-visible,
.chat-log summary:focus-visible, .chat-outcome summary:focus-visible, .attention-root summary:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.chat-outcome summary:focus-visible { outline-offset: 4px; border-radius: 4px; }

@keyframes chat-enter { from { opacity: 0; transform: translateY(6px); } }
@keyframes chat-rise { from { opacity: 0; transform: translateY(6px); } }
@keyframes chat-fade-in { from { opacity: 0; } }
@keyframes chat-fade-out { to { opacity: 0; } }
@keyframes chat-breathe { 0%, 100% { opacity: 0.35; transform: scale(0.8); } 50% { opacity: 1; transform: scale(1); } }
@keyframes chat-breathe-track { 0%, 100% { opacity: 0.45; } 50% { opacity: 1; } }
@keyframes chat-check-draw { from { stroke-dashoffset: 20; } to { stroke-dashoffset: 0; } }

/* Reduced motion: no travel, no breathing. Changes land at once (the global
   rule above shortens anything left to an instant), and the states stay
   legible without movement. */
@media (prefers-reduced-motion: reduce) {
  .chat-log > .is-entering,
  .chat-hero.is-staggering > :not(.chat-suggestions),
  .chat-hero.is-staggering .chat-suggestion,
  .chat-outcome-status.is-arriving .chat-outcome-check path,
  .chat-outcome-status.is-arriving .chat-outcome-status-text,
  .chat-copy.is-copied .icon-check path { animation: none; }
  .chat-pulse { animation: none; opacity: 1; transform: none; }
  .chat-outcome-track.is-pending { animation: none; opacity: 0.7; }
  .chat-outcome-track.is-arriving { animation: none; opacity: 0; }
  .chat-outcome-fill, .chat-mode-indicator, .chat-status, .chat-suggestion-arrow,
  .composer-slot > button, .composer-slot > button::before, .composer .send::after,
  .composer-slot[data-mode="send"] > .chat-stop,
  .composer-slot[data-mode="stop"] > .send { transition: none; }
}

/* ---------- toast ---------- */

#toast {
  position: fixed;
  left: 50%;
  bottom: calc(92px + var(--safe-b));
  transform: translate(-50%, 12px);
  background: var(--surface-2);
  color: var(--text);
  font-size: 14px;
  padding: 12px 20px;
  border-radius: 999px;
  opacity: 0;
  pointer-events: none;
  transition: opacity 200ms var(--ease), transform 200ms var(--ease);
  z-index: 60;
  max-width: 86vw;
  text-align: center;
}

#toast.show { opacity: 1; transform: translate(-50%, 0); }

/* A band from just above the composer down to the screen edge, under the
   tab dock (z 30) and the composer (z 31). Its top 20px fades in, so the
   transcript dissolves into the composer instead of being cut by it, and no
   text shows through the gap between composer and dock. */
body:has(.composer)::after {
  --composer-h: inherit;
  content: "";
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  height: calc(70px + var(--safe-b) + var(--composer-h, 60px) + 20px);
  background: linear-gradient(rgba(14, 14, 16, 0), var(--bg) 20px);
  z-index: 29;
  pointer-events: none;
}
@media (min-width: 720px) {
  body:has(.composer)::after { height: calc(24px + var(--composer-h, 60px) + 20px); }
}

/* Phones: the dock sits 11px under the composer. Two bordered, shadowed
   capsules read as two stacked bars, so under the composer the dock keeps
   only its fill and the composer is the one container on screen. */
@media (max-width: 719px) {
  body:has(.composer) .tabs { border-color: transparent; box-shadow: none; }
}

/* the chat composer occupies the toast's band; float toasts above it */
body:has(.composer) #toast { --composer-h: inherit; bottom: calc(var(--composer-h, 120px) + 84px + var(--safe-b)); }

/* Desktop: the tab dock lives at the top, so bottom-anchored chrome drops down. */
@media (min-width: 720px) {
  .composer { bottom: 24px; }
  .edit-actions { bottom: 28px; }
  #toast { bottom: 96px; }
  body:has(.composer) #toast { bottom: calc(var(--composer-h, 120px) + 40px); }
  /* composer 24px up, 24px gap, body pads 40px and main 24px: no dock at the
     bottom here, so no dock allowance */
  .chat-log { padding-bottom: max(0px, calc(var(--composer-h, 120px) - 16px)); }
}

/* ---------------------------------------------------- availability list
   Real, grabbable releases shown on the detail sheet: quality, source,
   size and health — so a tap downloads a copy that actually exists. */
.avail { margin-top: 16px; display: flex; flex-direction: column; gap: 8px; }
.avail-loading, .avail-empty { color: var(--muted); font-size: 14px; padding: 12px 0; }
.avail-heading { color: var(--faint); font-size: 12px; text-transform: uppercase; letter-spacing: 0.04em; margin-bottom: 2px; }
.avail-row {
  display: flex; align-items: center; gap: 12px;
  width: 100%; text-align: left; cursor: pointer;
  background: var(--surface); border: 1px solid transparent;
  border-radius: var(--radius); padding: 12px 14px;
  color: var(--text);
  transition: background-color 160ms var(--ease), border-color 160ms var(--ease),
    transform 160ms var(--ease);
}
.avail-row:active { transform: scale(0.985); }
.avail-row.busy { opacity: 0.6; cursor: default; }

@media (hover: hover) {
  .avail-row:not(.busy):hover { background: var(--surface-2); border-color: var(--faint); }
}
.avail-main { flex: 1; min-width: 0; }
.avail-q { display: flex; align-items: center; gap: 8px; }
.avail-res { font-weight: 600; }
.avail-proto { font-size: 11px; padding: 1px 7px; border-radius: 999px; letter-spacing: 0.02em; }
.avail-proto.usenet { background: rgba(212, 164, 76, 0.18); color: var(--accent); }
.avail-proto.torrent { background: rgba(255, 255, 255, 0.08); color: var(--muted); }
.avail-best { font-size: 11px; color: var(--accent); border: 1px solid var(--accent); border-radius: 999px; padding: 0 7px; }
.avail-sub { color: var(--muted); font-size: 12px; margin-top: 3px; }
.avail-flags { flex-shrink: 0; font-size: 16px; }
.avail-ok { color: #6fae7a; }
.avail-warn { color: var(--danger); }

/* Optional Phase-4 discovery guidance and release selection. These controls
   never imply that a selected release has been acquired. */
.source-guidance {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  margin: 18px 0 4px;
  padding: 14px 16px;
  border: 1px solid rgba(212, 164, 76, 0.32);
  border-radius: var(--radius);
  background: rgba(212, 164, 76, 0.08);
}
.plex-discovery {
  margin: 12px 0;
  padding: 14px;
  border: 1px solid var(--surface-2);
  border-radius: var(--radius);
  background: var(--surface);
}
.plex-discovery-items {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(130px, 1fr));
  gap: 10px;
  margin: 10px 0;
}
.plex-discovery-item { color: inherit; text-decoration: none; }
.plex-discovery-item img {
  width: 100%;
  aspect-ratio: 2 / 3;
  object-fit: cover;
  border-radius: 8px;
  background: var(--surface-2);
}
.plex-discovery-item span { display: block; margin-top: 5px; font-size: 12px; }
.source-guidance-copy { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.source-guidance-copy strong { font-size: 14px; }
.source-guidance-copy span { color: var(--muted); font-size: 13px; line-height: 1.45; }
.source-guidance-actions { display: flex; gap: 8px; flex-shrink: 0; }
.source-guidance-actions .linklike { margin: 0; }
.source-catalog { display: flex; flex-direction: column; gap: 8px; margin-top: 18px; }
.source-catalog-row {
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 12px 14px;
  border: 1px solid var(--surface-2);
  border-radius: var(--radius);
  color: var(--text);
  text-decoration: none;
}
.source-catalog-row span { color: var(--muted); font-size: 12px; text-transform: capitalize; }
.custom-provider-form { margin-top: 4px; }
.custom-provider-form input {
  display: block;
  width: 100%;
  margin-top: 8px;
  border: 0;
  border-radius: var(--radius);
  background: var(--surface-2);
  color: var(--text);
  font: inherit;
  padding: 12px 14px;
}
.custom-provider-form .cta { margin-top: 16px; }

.release-choice { display: flex; flex-direction: column; gap: 9px; margin-top: 18px; }
.release-boundary {
  margin: 0 0 6px;
  padding: 11px 13px;
  border-radius: var(--radius);
  background: var(--surface-2);
  color: var(--muted);
  font-size: 13px;
  line-height: 1.45;
}
.release-option {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 13px 14px;
  border: 1px solid var(--surface-2);
  border-radius: var(--radius);
  background: var(--surface);
}
.release-option.selected { border-color: rgba(212, 164, 76, 0.6); }
.release-option.rejected { opacity: 0.72; }
.release-option-main { display: flex; flex: 1; min-width: 0; flex-direction: column; gap: 5px; }
.release-option-main strong {
  overflow: hidden;
  font-size: 13px;
  line-height: 1.35;
  text-overflow: ellipsis;
}
.release-chips { display: flex; flex-wrap: wrap; gap: 5px; }
.release-chip {
  appearance: none;
  border: 0;
  min-height: 44px;
  padding: 8px 11px;
  border-radius: 999px;
  background: var(--surface-2);
  color: var(--muted);
  cursor: help;
  font: inherit;
  font-size: 11px;
}
.release-chip:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.release-chip.warning { color: var(--danger); }
.release-chip-definition {
  flex-basis: 100%;
  color: var(--muted);
  font-size: 12px;
  line-height: 1.4;
  padding: 2px 4px 5px;
}
.release-chip-definition[hidden] { display: none; }
.release-explanation { color: var(--muted); font-size: 12px; line-height: 1.4; }
.release-pick {
  flex-shrink: 0;
  appearance: none;
  border: 0;
  border-radius: 999px;
  background: var(--accent);
  color: var(--bg);
  cursor: pointer;
  font: inherit;
  font-size: 12px;
  font-weight: 650;
  padding: 8px 11px;
  min-height: 44px;
}
.release-pick:disabled { cursor: default; opacity: 0.65; }
.release-rejected { flex-shrink: 0; color: var(--faint); font-size: 11px; }
.release-alternatives { display: flex; flex-direction: column; gap: 8px; }

@media (max-width: 560px) {
  .source-guidance { align-items: flex-start; flex-direction: column; }
  .release-option { align-items: flex-start; flex-direction: column; }
  .release-pick { align-self: flex-end; }
}

/* ---------- library: continue watching / remove request ---------- */

.cta.continue-watching { margin-top: 22px; }
.cta.remove-request { margin-top: 12px; }

/* premium-format badges on availability rows (4K / HDR / DV / Atmos) */
.avail-fmt { font-size: 10px; font-weight: 600; letter-spacing: 0.03em; padding: 1px 6px; border-radius: 999px; border: 1px solid transparent; }
.fmt-uhd { background: rgba(212, 164, 76, 0.15); color: var(--accent); border-color: rgba(212, 164, 76, 0.4); }
.fmt-hdr { background: rgba(255, 255, 255, 0.06); color: #cbb98f; }
.fmt-dv { background: rgba(120, 90, 200, 0.18); color: #b9a6e8; }
.fmt-atmos { background: rgba(255, 255, 255, 0.06); color: var(--muted); }

/* ------------------------------------------------------------- profiles */

.login-screen {
  position: fixed;
  inset: 0;
  z-index: 60;
  background: var(--bg);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
}

.login-box {
  width: 100%;
  max-width: 320px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.login-title {
  font-size: 18px;
  font-weight: 600;
  letter-spacing: 0.34em;
  text-transform: uppercase;
  color: var(--accent);
  text-align: center;
  margin: 0;
}

.login-sub { color: var(--muted); font-size: 13px; text-align: center; margin: 0 0 8px; }

.login-input {
  font: inherit;
  color: var(--text);
  background: var(--surface);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 10px;
  padding: 12px 14px;
}
.login-input:focus { outline: none; border-color: rgba(212, 164, 76, 0.55); background: var(--surface-2); }

.login-error { color: #e0765f; font-size: 13px; min-height: 16px; text-align: center; }
.setup-screen {
  position: fixed;
  inset: 0;
  z-index: 60;
  overflow: auto;
  background: var(--bg);
  padding: 40px 20px;
}
.setup-box {
  width: min(620px, 100%);
  margin: 0 auto;
  display: grid;
  gap: 16px;
}
.setup-subtitle { margin: 8px 0 0; text-align: center; font-size: 16px; }
.setup-modes { display: grid; gap: 10px; border: 0; padding: 0; }
.setup-modes legend { margin-bottom: 8px; font-weight: 650; }
.setup-choice, .setup-category {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--surface);
  padding: 14px;
}
.setup-choice small, .setup-category small {
  display: block;
  margin-top: 5px;
  color: var(--muted);
  line-height: 1.45;
}
.setup-personal, .setup-advanced { display: grid; gap: 10px; }
.setup-personal[hidden] { display: none; }
.setup-advanced summary { cursor: pointer; color: var(--muted); }
.setup-advanced[open] summary { margin-bottom: 10px; }
.setup-categories { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
.feature-settings { display: grid; gap: 12px; margin-top: 26px; }
@media (max-width: 520px) {
  .setup-categories { grid-template-columns: 1fr; }
}

.card .req-by { color: var(--accent); opacity: 0.85; }

.users-admin { margin-top: 28px; }
.admin-users-heading { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.users-list { display: flex; flex-direction: column; gap: 2px; margin-bottom: 14px; }

.user-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  background: var(--surface);
  border-radius: 10px;
  padding: 10px 14px;
}

.user-meta { display: flex; flex-direction: column; gap: 2px; }
.user-name { font-weight: 600; font-size: 14px; }
.user-sub { color: var(--muted); font-size: 12px; }
.user-actions { display: flex; gap: 14px; }
.linklike.danger { color: #e0765f; }
.user-row[role="button"] { cursor: pointer; }
.user-row[role="button"]:hover { background: var(--surface-2); }
.user-row[role="button"]:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.user-open { color: var(--muted); font-size: 22px; }

.admin-title { margin: 2px 0 16px; font-size: 22px; }
.admin-user-detail { display: flex; flex-direction: column; gap: 14px; }
.admin-user-identity { padding: 2px 0 4px; }
.admin-stat-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; }
.admin-stat { display: flex; flex-direction: column; gap: 3px; padding: 12px; border-radius: 10px; background: var(--surface); }
.admin-stat strong { font-size: 20px; }
.admin-stat span { color: var(--muted); font-size: 11px; }
.admin-service-row, .admin-activity-filters { display: flex; flex-wrap: wrap; gap: 7px; }
.admin-service { padding: 4px 8px; border-radius: 999px; font-size: 11px; background: var(--surface); color: var(--muted); }
.admin-service.ok { color: var(--accent); }
.admin-service.missing { color: #e0765f; }
.admin-account-actions { display: flex; flex-direction: column; gap: 8px; }
.admin-account-actions .cta { margin: 0; }

@media (max-width: 520px) {
  .admin-stat-grid { grid-template-columns: 1fr 1fr; }
}

.user-add { display: flex; gap: 8px; flex-wrap: wrap; }
.user-add .login-input { flex: 1 1 120px; }
.user-add .cta.inline { flex: 0 0 auto; margin: 0; }

.native-reader-overlay {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: grid;
  grid-template-rows: auto 1fr;
  background: var(--bg);
}
.native-reader-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: max(10px, env(safe-area-inset-top)) 14px 10px;
  border-bottom: 1px solid var(--line);
  background: var(--surface);
}
.native-reader-bar strong {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.native-reader-frame {
  width: 100%;
  height: 100%;
  border: 0;
  background: Canvas;
}

/* Current broadcast activity is distinct from files held in the library. */
.freshness-chip {
  display: inline-flex;
  align-items: center;
  width: fit-content;
  max-width: 100%;
  padding: 5px 8px;
  border-radius: 6px;
  background: var(--accent);
  color: var(--bg);
  font-size: 11px;
  font-weight: 700;
  line-height: 1.2;
}
.poster > .freshness-chip { position: absolute; top: 8px; left: 7px; right: 7px; }
.poster.has-freshness > .badge { top: auto; bottom: 8px; left: 7px; right: 7px; width: fit-content; letter-spacing: .04em; }
.card .meta .tv-card-context { color: var(--accent); margin: 5px 0; font-size: 11px; }
.hero-info > .freshness-chip { margin-top: 12px; }
.hero-activity, .hero-next { display: block; font-size: 14px; line-height: 1.45; margin-top: 10px; }
.hero-next { font-size: 12px; color: var(--muted); margin-top: 5px; }
.section-caption { display: block; margin-top: 4px; font-size: 11px; font-weight: 400; letter-spacing: 0; text-transform: none; color: var(--muted); }
.tv-activity { display: grid; gap: 9px; margin: 18px 0; }
.tv-activity:empty { display: none; }
.tv-activity-line { display: grid; grid-template-columns: 52px 1fr; gap: 12px; font-size: 13px; line-height: 1.5; }
.tv-activity-line > strong { color: var(--muted); font-weight: 500; }
.tv-activity-line > span { min-width: 0; overflow-wrap: anywhere; }

.tv-continuation { margin: 20px 0; padding: 16px; border: 1px solid var(--surface-2); border-radius: 12px; background: var(--surface); min-width: 0; }
.tv-continuation-label { display: flex; align-items: center; justify-content: space-between; gap: 16px; cursor: pointer; min-height: 44px; font-size: 14px; line-height: 1.5; }
.tv-continuation-label > strong { min-width: 0; font-weight: 600; }
.tv-continuation input.tv-continuation-toggle[type="checkbox"] { appearance: none; -webkit-appearance: none; width: 44px; height: 26px; margin: 0; padding: 0; flex: 0 0 44px; border: 1px solid var(--muted); border-radius: 16px; background: var(--surface-2); cursor: pointer; position: relative; transition: background 120ms; }
.tv-continuation-toggle::before { content: ""; display: block; width: 18px; height: 18px; position: absolute; top: 3px; left: 3px; border-radius: 50%; background: var(--muted); transition: transform 120ms; }
.tv-continuation input.tv-continuation-toggle:checked { border-color: var(--accent); background: var(--accent); }
.tv-continuation-toggle:checked::before { background: var(--bg); transform: translateX(18px); }
.tv-continuation-toggle:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; }
.tv-continuation-toggle:disabled { cursor: wait; opacity: .55; }
.tv-continuation-description, .tv-continuation-status, .tv-continuation-error { margin: 8px 0 0; font-size: 13px; line-height: 1.6; overflow-wrap: anywhere; }
.tv-continuation-description, .tv-continuation-status { color: var(--muted); }
.tv-continuation-status { font-size: 12px; }
.tv-continuation-error { color: var(--danger); }
.tv-continuation-status:empty, .tv-continuation-error:empty, .tv-continuation [hidden] { display: none; }
.tv-continuation .linklike { margin-top: 10px; }

/* Selection first; source rows never dispatch a transfer on their own. */
.tv-source-picker { margin-top: 22px; }
.tv-source-picker fieldset { min-width: 0; padding: 0; border: 0; margin: 0; }
.tv-source-picker .field-title { padding: 0; margin-bottom: 12px; font-size: 13px; font-weight: 600; }
.tv-scope-tabs { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 16px; }
.tv-scope-tabs .season-chip { padding: 10px 15px; font-size: 13px; }
.tv-season-choices { margin-bottom: 14px; }
.tv-source-picker [hidden] { display: none !important; }
.tv-source-picker .tv-scope-summary { font-size: 13px; color: var(--accent); margin: 14px 0; }
.tv-source-picker .field { margin-top: 12px; }
.tv-pack-choice, .tv-pack-acknowledgement { display: flex; align-items: flex-start; gap: 10px; font-size: 13px; line-height: 1.5; margin: 14px 0; }
.tv-source-picker input[type="checkbox"], .tv-source-picker input[type="radio"] { accent-color: var(--accent); flex: 0 0 auto; width: 18px; height: 18px; margin: 2px 0 0; }
.tv-episode-choices { max-height: 310px; overflow-y: auto; overscroll-behavior: contain; padding: 0 4px; }
.tv-episode-choices .ep-row { align-items: flex-start; }
.tv-episode-choices .ep-row > span:not(.num):not(.have) { flex: 1; min-width: 0; }
.tv-episode-choices .have { text-align: right; font-size: 10px; flex: 0 0 auto; max-width: 95px; }
.tv-source-picker .tv-source-results { margin-top: 24px; }
.tv-source-group { margin: 10px 0; border: 1px solid var(--surface-2); border-radius: 10px; overflow: hidden; }
.tv-source-group-title { padding: 14px; cursor: pointer; font-size: 13px; font-weight: 600; line-height: 1.4; background: var(--surface); overflow-wrap: anywhere; }
.tv-source-option { padding: 13px; border-top: 1px solid var(--surface-2); transition: background 120ms; }
.tv-source-option.selected { background: rgba(212, 164, 76, .08); box-shadow: inset 3px 0 var(--accent); }
.tv-source-option-label { display: flex; align-items: flex-start; gap: 12px; cursor: pointer; }
.tv-source-copy { min-width: 0; display: grid; gap: 4px; font-size: 13px; line-height: 1.5; }
.tv-source-copy > strong { font-weight: 600; overflow-wrap: anywhere; }
.tv-coverage { display: block; font-size: 12px; color: var(--muted); }
.tv-pack-warning { display: block; font-size: 12px; color: var(--accent); }
.tv-release-details { margin: 9px 0 0 30px; font-size: 12px; }
.tv-release-details summary { cursor: pointer; color: var(--muted); }
.tv-release-title { overflow-wrap: anywhere; line-height: 1.5; color: var(--text); }
.tv-source-group .note { padding: 0 14px; }
.tv-source-option .note { padding: 0; overflow-wrap: anywhere; }
.tv-source-review { margin: 22px 0 10px; padding: 14px; border-radius: 10px; background: var(--surface); font-size: 13px; }
.tv-source-review > strong { font-size: 13px; font-weight: 600; }
.tv-review-list { margin: 10px 0; padding-left: 18px; color: var(--muted); line-height: 1.65; }
.tv-source-review .note { margin-bottom: 0; }
.tv-source-error { font-size: 13px; color: var(--danger); line-height: 1.5; }
.tv-source-error:empty { display: none; }
.tv-download-cta { margin-top: 14px; }
.tv-source-picker fieldset:disabled { opacity: .65; }
@media (max-width: 420px) {
  .tv-scope-tabs { gap: 6px; }
  .tv-scope-tabs .season-chip { padding: 10px 12px; font-size: 12px; }
  .tv-source-option { padding: 11px; }
  .tv-activity-line { grid-template-columns: 45px 1fr; gap: 7px; }
}
.tv-existing-plans:empty { display: none; }
.tv-existing-plan { border: 1px solid var(--surface-2); padding: 14px; border-radius: 10px; margin-bottom: 16px; font-size: 13px; }
.tv-existing-plan summary { cursor: pointer; color: var(--accent); font-weight: 600; }
.tv-existing-plan li { overflow-wrap: anywhere; }
.tv-previous-handoff { padding: 12px; border: 1px solid var(--accent); border-radius: 10px; }

/* Keep focused controls visible and make diagnostics readable on small screens. */
.cinema-diagnostics { margin-top: 12px; }
.cinema-diagnostics summary { cursor: pointer; }
.cinema-diagnostics pre { max-height: 220px; overflow: auto; font-size: 11px; white-space: pre-wrap; overflow-wrap: anywhere; user-select: text; }
.cinema-player:focus { outline: none; }
@media (prefers-reduced-motion: reduce) {
  .cinema-controls-layer, .cinema-shade, .cinema-button { transition: none; }
}

/* Bound the administrator queue review on small screens and long queues. */
dialog.attention-dialog[open] { display: grid; gap: 8px; }
dialog.attention-dialog {
  padding: 16px;
  border-radius: var(--radius-lg);
  background: var(--surface);
  margin: auto;
  border: 1px solid var(--line);
  color: var(--text);
  width: min(640px, calc(100vw - 32px));
  max-height: calc(100dvh - 48px);
  overflow-y: auto;
}
dialog.attention-dialog::backdrop { background: rgb(0 0 0 / 55%); }
dialog.attention-dialog ul { padding-left: 20px; }
