/* ──────────────────────────────────────────────────────────────────────────────
   HomeStream — Dark streaming UI
   Design principles:
     - Dark background so the content (posters) pops
     - Genre-first navigation (not mood/algorithm based)
     - Works on phone, laptop, and TV via browser
   ────────────────────────────────────────────────────────────────────────────── */

/* ── Reset & base ─────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

:root {
  --bg:         #0f0f0f;
  --surface:    #1a1a1a;
  --surface2:   #242424;
  --accent:     #16a34a;
  --accent-dim: #15803d;
  --text:       #e8e8e8;
  --text-muted: #888;
  --card-radius: 6px;
  /* env() is 0 in every normal browser and on desktop — this only does anything
     when the site is running as a home-screen app on a notched iPhone, where
     there is no browser chrome to push the page down. Folding it into
     --nav-height means every existing calc(var(--nav-height) + Npx) offset in
     this file stays correct with no other edits. */
  --safe-top:    env(safe-area-inset-top, 0px);
  --nav-height:  calc(60px + var(--safe-top));
}

html, body {
  background: var(--bg);
  color: var(--text);
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  min-height: 100vh;
  scroll-behavior: smooth;
}

a { color: inherit; text-decoration: none; }
button { cursor: pointer; border: none; background: none; color: inherit; font: inherit; }
img { display: block; max-width: 100%; }
.hidden { display: none !important; }

/* ── Scrollbar ────────────────────────────────────────────────────────────── */
::-webkit-scrollbar { width: 6px; height: 6px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: #333; border-radius: 3px; }

/* ── Navigation ───────────────────────────────────────────────────────────── */
/* Running as a home-screen app on an iPhone there is no browser chrome, so the
   nav sits under the notch / dynamic island unless it is padded down by the
   safe-area inset. env() is 0 everywhere else, so this is a no-op in a normal
   browser and on desktop. */
#navbar {
  position: fixed;
  top: 0; left: 0; right: 0;
  height: var(--nav-height);
  box-sizing: border-box;
  background: linear-gradient(to bottom, rgba(0,0,0,0.95) 0%, rgba(0,0,0,0.6) 100%);
  backdrop-filter: blur(6px);
  display: flex;
  align-items: center;
  gap: 24px;
  /* Top padding, not 0, so the bar's contents clear the notch. --nav-height
     already includes the same inset, so the bar grows rather than squashing. */
  padding: var(--safe-top) 24px 0;
  z-index: 100;
  border-bottom: 1px solid rgba(255,255,255,0.05);
  /* The bar is a fixed 60px. Nothing inside it is allowed to make it taller —
     the category pills scroll sideways instead. See .nav-cats below. */
  min-width: 0;
}

.nav-logo {
  font-size: 1.5rem;
  font-weight: 800;
  color: var(--accent);
  letter-spacing: -0.5px;
  flex-shrink: 0;
}

/* min-width:0 is load-bearing: without it a flex child refuses to shrink below
   its content width, the pills push the bar wide, and nothing ever scrolls. */
.nav-links {
  display: flex;
  align-items: center;
  gap: 16px;
  flex: 1 1 auto;
  min-width: 0;
}

.nav-link {
  font-size: 0.9rem;
  font-weight: 500;
  color: var(--text-muted);
  transition: color 0.2s;
  padding: 4px 0;
}
.nav-link:hover, .nav-link.active { color: var(--text); }
.nav-link.active { border-bottom: 2px solid var(--accent); }

.nav-search { margin-left: auto; position: relative; flex: 0 0 auto; }

/* ── The ☰ menu ───────────────────────────────────────────────────────────────
   Hidden on desktop, where the pill row IS the navigation.

   Below 768px the pills hide and this replaces them. The bar previously tried
   to carry the pills on a second row; a dozen categories on a 390px screen is a
   strip you have to scroll to find anything in, on top of a bar already holding
   a logo, a search box and a gear. The menu is one tap to a list you can read
   at a glance, and it is where Settings lives on a phone. */
.nav-menu-btn {
  display: none;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 38px; height: 38px;
  border-radius: 9px;
  background: var(--surface2);
  color: var(--text);
  font-size: 1.15rem;
  line-height: 1;
}
.nav-menu-btn.is-open { background: var(--accent); color: #fff; }

#nav-menu {
  position: fixed;
  top: calc(var(--nav-height) + 4px);
  left: 8px;
  width: min(300px, calc(100vw - 16px));
  max-height: calc(100vh - var(--nav-height) - 20px);
  overflow-y: auto;
  z-index: 300;
  background: #171717;
  border: 1px solid rgba(255,255,255,0.1);
  border-radius: 12px;
  padding: 6px;
  box-shadow: 0 18px 50px rgba(0,0,0,0.65);
}
/* Tap-anywhere-to-close. A touch screen has no click-outside without something
   to click on, and the menu sits above page content that is itself clickable. */
#nav-menu-scrim { position: fixed; inset: 0; z-index: 299; }

.nav-menu-head {
  color: var(--text-muted);
  font-size: 0.7rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.6px;
  padding: 8px 12px 6px;
}
.nav-menu-item {
  display: block;
  padding: 12px;                 /* ~44px tall: a thumb target, not a mouse one */
  border-radius: 8px;
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--text);
}
.nav-menu-item:hover, .nav-menu-item.active { background: rgba(22,163,74,0.22); }
.nav-menu-sep { height: 1px; background: rgba(255,255,255,0.08); margin: 6px 8px; }

#search-input {
  background: var(--surface2);
  border: 1px solid #333;
  border-radius: 20px;
  color: var(--text);
  font-size: 0.875rem;
  padding: 7px 16px;
  width: 220px;
  outline: none;
  transition: border-color 0.2s, width 0.3s;
}
#search-input:focus { border-color: var(--accent); width: 280px; }
#search-input::placeholder { color: var(--text-muted); }

#search-results {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  width: 320px;
  background: var(--surface);
  border: 1px solid #333;
  border-radius: 8px;
  overflow: hidden;
  display: none;
  z-index: 200;
  box-shadow: 0 8px 32px rgba(0,0,0,0.6);
}
#search-results.visible { display: block; }

.search-result-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 14px;
  cursor: pointer;
  transition: background 0.15s;
}
.search-result-item:hover { background: var(--surface2); }
.search-result-item img {
  width: 40px; height: 56px;
  object-fit: cover;
  border-radius: 3px;
  flex-shrink: 0;
}
.search-result-thumb-placeholder {
  width: 40px; height: 56px;
  background: var(--surface2);
  border-radius: 3px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.2rem;
}
.search-result-info { overflow: hidden; }
.search-result-title {
  font-size: 0.875rem;
  font-weight: 600;
  line-height: 1.3;
  overflow-wrap: anywhere;
}
.search-result-meta { font-size: 0.75rem; color: var(--text-muted); }

/* ── Main content ─────────────────────────────────────────────────────────── */
#app {
  padding-top: var(--nav-height);
  min-height: 100vh;
}

/* ── Hero banner (home page top section) ──────────────────────────────────── */
.hero {
  position: relative;
  height: 420px;
  background: var(--surface);
  display: flex;
  align-items: flex-end;
  padding: 32px 40px;
  overflow: hidden;
}

.hero-bg {
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: center top;
  filter: brightness(0.4);
}

.hero-gradient {
  position: absolute;
  inset: 0;
  background: linear-gradient(
    to right,
    rgba(15,15,15,0.95) 0%,
    rgba(15,15,15,0.6) 50%,
    transparent 100%
  ), linear-gradient(
    to top,
    rgba(15,15,15,1) 0%,
    transparent 40%
  );
}

.hero-content {
  position: relative;
  max-width: 520px;
}

.hero-badge {
  display: inline-block;
  background: var(--accent);
  color: #fff;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 1px;
  text-transform: uppercase;
  padding: 3px 10px;
  border-radius: 3px;
  margin-bottom: 12px;
}

.hero-title {
  font-size: 2.4rem;
  font-weight: 800;
  line-height: 1.1;
  margin-bottom: 12px;
  text-shadow: 0 2px 8px rgba(0,0,0,0.5);
}

.hero-meta {
  display: flex;
  gap: 12px;
  align-items: center;
  margin-bottom: 14px;
  font-size: 0.875rem;
  color: var(--text-muted);
}

.hero-rating { color: #f5c518; font-weight: 700; }

.hero-desc {
  font-size: 0.9rem;
  color: #bbb;
  line-height: 1.5;
  margin-bottom: 20px;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.hero-play {
  background: var(--accent);
  color: #fff;
  padding: 12px 28px;
  border-radius: 6px;
  font-size: 1rem;
  font-weight: 700;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  transition: background 0.2s, transform 0.1s;
}
.hero-play:hover { background: var(--accent-dim); }
.hero-play:active { transform: scale(0.97); }

/* ── Genre navigation grid (home page) ───────────────────────────────────── */
.genre-nav {
  padding: 32px 40px 8px;
}

.genre-nav h2 {
  font-size: 1.1rem;
  font-weight: 700;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 1px;
  margin-bottom: 16px;
}

.genre-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
  gap: 10px;
}

.genre-chip {
  background: var(--surface);
  border: 1px solid #2a2a2a;
  border-radius: 8px;
  padding: 14px 16px;
  font-size: 0.9rem;
  font-weight: 600;
  text-align: center;
  cursor: pointer;
  transition: background 0.2s, border-color 0.2s, transform 0.1s;
}
.genre-chip:hover {
  background: var(--surface2);
  border-color: var(--accent);
  transform: translateY(-2px);
}

/* ── Section rows (home page "All Movies", etc.) ─────────────────────────── */
.section {
  padding: 24px 40px;
}

.section-header {
  display: flex;
  align-items: baseline;
  gap: 12px;
  margin-bottom: 16px;
}

.section-header h2 {
  font-size: 1.3rem;
  font-weight: 700;
}

.section-header a {
  font-size: 0.8rem;
  color: var(--accent);
  font-weight: 600;
}
.section-header a:hover { text-decoration: underline; }

/* ── Card grid ────────────────────────────────────────────────────────────── */
.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
  gap: 14px;
}

/* ── Category cards (home page) ───────────────────────────────────────────────
   Bigger and wider than a title card. Category art on this drive is a mix of
   portrait posters, square logos and wide banners, so the tile has a fixed 16/9
   shape and the art is cropped to fill it — that keeps the grid even whatever
   image is dropped into a folder. */
.cat-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 16px;
  padding: 0 40px 60px;
}

.cat-card {
  position: relative;
  border-radius: 10px;
  overflow: hidden;
  background: var(--surface);
  cursor: pointer;
  aspect-ratio: 16 / 9;
  transition: transform 0.2s, box-shadow 0.2s;
}
.cat-card:hover, .cat-card:focus-visible {
  transform: scale(1.03);
  box-shadow: 0 10px 36px rgba(0,0,0,0.65);
  outline: none;
  z-index: 2;
}
.cat-card:focus-visible { box-shadow: 0 0 0 2px var(--accent), 0 10px 36px rgba(0,0,0,0.65); }

.cat-card-art {
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: center 28%;   /* posters carry their subject high */
  display: block;
}

.cat-card-art-empty {
  display: flex; align-items: center; justify-content: center;
  background: var(--surface2);
  color: var(--text-muted);
  font-size: 0.95rem; font-weight: 600;
  text-align: center; padding: 0 16px;
}

/* Keeps the label readable over a bright poster. */
.cat-card-shade {
  position: absolute; inset: 0;
  background: linear-gradient(to top,
    rgba(0,0,0,0.88) 0%, rgba(0,0,0,0.45) 38%, rgba(0,0,0,0.05) 65%, transparent 100%);
  pointer-events: none;
}

.cat-card-label { position: absolute; left: 16px; right: 16px; bottom: 12px; }
.cat-card-title {
  font-size: 1.15rem; font-weight: 700; line-height: 1.2;
  text-shadow: 0 1px 6px rgba(0,0,0,0.8);
}
.cat-card-sub {
  font-size: 0.8rem; color: #cfcfcf; margin-top: 2px;
  text-shadow: 0 1px 4px rgba(0,0,0,0.8);
}

/* ── Media card ───────────────────────────────────────────────────────────── */
.card {
  border-radius: var(--card-radius);
  overflow: hidden;
  background: var(--surface);
  cursor: pointer;
  transition: transform 0.2s, box-shadow 0.2s;
  position: relative;
}
.card:hover {
  transform: scale(1.04);
  box-shadow: 0 8px 32px rgba(0,0,0,0.6);
  z-index: 2;
}

.card-poster {
  width: 100%;
  aspect-ratio: 2 / 3;
  object-fit: cover;
  background: var(--surface2);
}

.card-poster-placeholder {
  width: 100%;
  aspect-ratio: 2 / 3;
  background: var(--surface2);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  color: var(--text-muted);
  font-size: 2rem;
}

.card-poster-placeholder span {
  font-size: 0.75rem;
  font-weight: 600;
  text-align: center;
  padding: 0 8px;
  color: var(--text-muted);
}

.card-info {
  padding: 10px;
}

/* Titles WRAP — they are never truncated.
   Ellipsis hid the only thing that tells two cards apart: "King of the Ring
   (19…" and "King of the Ring (19…" are different years, and the card was
   giving you no way to know which. A ragged bottom edge is a much smaller
   problem than an unreadable library. `overflow-wrap: anywhere` is what stops
   a single long unbroken filename from pushing past the card. */
.card-title {
  font-size: 0.82rem;
  font-weight: 600;
  line-height: 1.3;
  overflow-wrap: anywhere;
  margin-bottom: 3px;
}

.card-meta {
  font-size: 0.72rem;
  color: var(--text-muted);
}

/* The Apple / VHS mark under a card title.
   Muted rather than bright: it is a note about the copy, not a call to action,
   and 65 of the 340 titles carry the Apple one — at full contrast the grid
   would read as a wall of warnings. `currentColor` in the SVG means the icon
   inherits this, so there is one place to change it. */
.card-format {
  display: flex;
  align-items: center;
  gap: 4px;
  color: rgba(255, 255, 255, 0.62);
  margin: 2px 0 4px;
  line-height: 0;
}
.card-format .fmark { display: block; }

/* Visible to screen readers, not to the eye. The mark is an icon on purpose
   (the grid is dense), so the words have to live somewhere. */
.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.card-genres {
  font-size: 0.7rem;
  color: var(--text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ── Detail page ──────────────────────────────────────────────────────────── */
.detail {
  padding-top: 0;
}

.detail-backdrop {
  position: relative;
  height: 460px;
  background: var(--surface);
  overflow: hidden;
}

.detail-backdrop-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center top;
  filter: brightness(0.35);
}

.detail-backdrop-gradient {
  position: absolute;
  inset: 0;
  background: linear-gradient(
    to right,
    rgba(15,15,15,0.98) 0%,
    rgba(15,15,15,0.6) 60%,
    transparent 100%
  ), linear-gradient(
    to top,
    rgba(15,15,15,1) 0%,
    transparent 50%
  );
}

.detail-content {
  position: relative;
  display: flex;
  gap: 32px;
  align-items: flex-end;
  padding: 32px 40px;
  height: 100%;
}

.detail-poster {
  width: 160px;
  flex-shrink: 0;
  border-radius: 6px;
  overflow: hidden;
  box-shadow: 0 8px 32px rgba(0,0,0,0.7);
}

.detail-poster img {
  width: 100%;
  aspect-ratio: 2 / 3;
  object-fit: cover;
}

.detail-poster-placeholder {
  width: 160px;
  aspect-ratio: 2 / 3;
  background: var(--surface2);
  border-radius: 6px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 3rem;
}

.detail-info { flex: 1; }

.detail-title {
  font-size: 2.2rem;
  font-weight: 800;
  margin-bottom: 10px;
  text-shadow: 0 2px 8px rgba(0,0,0,0.5);
}

.detail-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: center;
  margin-bottom: 14px;
  font-size: 0.875rem;
  color: var(--text-muted);
}

.detail-rating { color: #f5c518; font-weight: 700; }

.detail-genres {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 16px;
}

.genre-tag {
  background: rgba(255,255,255,0.08);
  border: 1px solid rgba(255,255,255,0.12);
  border-radius: 20px;
  padding: 4px 14px;
  font-size: 0.78rem;
  font-weight: 500;
  cursor: pointer;
  transition: background 0.2s;
}
.genre-tag:hover { background: rgba(255,255,255,0.15); }

.detail-desc {
  font-size: 0.92rem;
  color: #bbb;
  line-height: 1.6;
  max-width: 560px;
  margin-bottom: 22px;
}

.play-btn {
  background: var(--accent);
  color: #fff;
  padding: 13px 32px;
  border-radius: 6px;
  font-size: 1.05rem;
  font-weight: 700;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  transition: background 0.2s, transform 0.1s;
}
.play-btn:hover { background: var(--accent-dim); }
.play-btn:active { transform: scale(0.97); }

/* ── Episode list (TV show detail) ───────────────────────────────────────── */
.episodes-section {
  padding: 32px 40px;
}

.season-tabs {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin-bottom: 20px;
}

.season-tab {
  background: var(--surface);
  border: 1px solid #333;
  border-radius: 6px;
  padding: 8px 18px;
  font-size: 0.875rem;
  font-weight: 600;
  transition: background 0.2s, border-color 0.2s;
}
.season-tab:hover { background: var(--surface2); }
.season-tab.active { background: var(--accent); border-color: var(--accent); color: #fff; }

.episode-list { display: flex; flex-direction: column; gap: 4px; }

.episode-item {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 12px 16px;
  border-radius: 6px;
  cursor: pointer;
  transition: background 0.15s;
}
.episode-item:hover { background: var(--surface); }

.ep-num {
  width: 36px;
  text-align: center;
  font-size: 0.875rem;
  font-weight: 700;
  color: var(--text-muted);
  flex-shrink: 0;
}

.ep-info { flex: 1; overflow: hidden; }

.ep-title {
  font-size: 0.9rem;
  font-weight: 600;
  line-height: 1.3;
  overflow-wrap: anywhere;
}

.ep-season { font-size: 0.75rem; color: var(--text-muted); }

.ep-play {
  width: 36px; height: 36px;
  border-radius: 50%;
  background: var(--accent);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  opacity: 0;
  transition: opacity 0.15s;
  font-size: 0.8rem;
}
.episode-item:hover .ep-play { opacity: 1; }

/* ── Seasons list (show detail page) ─────────────────────────────────────── */
.seasons-heading {
  font-size: 1.1rem;
  font-weight: 700;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 1px;
  margin-bottom: 14px;
}

.seasons-list { display: flex; flex-direction: column; gap: 6px; }

.season-card {
  display: flex;
  align-items: center;
  justify-content: space-between;
  background: var(--surface);
  border: 1px solid #2a2a2a;
  border-radius: 8px;
  padding: 16px 20px;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s;
  max-width: 480px;
}
.season-card:hover { background: var(--surface2); border-color: var(--accent); }

.season-card-inner { display: flex; align-items: baseline; gap: 10px; }

.season-card-label { font-size: 1rem; font-weight: 700; }

.season-card-count { font-size: 0.85rem; color: var(--text-muted); }

.season-card-arrow { font-size: 1.4rem; color: var(--text-muted); }

/* ── Genre page ───────────────────────────────────────────────────────────── */
.genre-page {
  padding: 32px 40px;
}

.page-title {
  font-size: 1.8rem;
  font-weight: 800;
  margin-bottom: 8px;
}

.page-subtitle {
  font-size: 0.9rem;
  color: var(--text-muted);
  margin-bottom: 28px;
}

/* ── Empty / loading states ───────────────────────────────────────────────── */
.loading {
  text-align: center;
  padding: calc(var(--nav-height) + 20px) 40px;
  color: var(--text-muted);
  font-size: 0.9rem;
}

.empty {
  text-align: center;
  padding: 60px 40px;
  color: var(--text-muted);
}
.empty p { margin-top: 8px; font-size: 0.875rem; }

/* ── Video player ─────────────────────────────────────────────────────────── */
#player-overlay { position: fixed; inset: 0; z-index: 1000; }
#player-scrim   { position: absolute; inset: 0; background: rgba(0,0,0,0.85); }

#player-stage {
  position: absolute;
  background: #000;
  display: flex; flex-direction: column;
  overflow: hidden;
  box-shadow: 0 20px 80px rgba(0,0,0,0.7);
}

/* The video and anything drawn ON the video (the Skip button) share a wrapper,
   so the button positions against the picture rather than against the whole
   stage — otherwise it floats over the bottom bar. */
#player-video-wrap { position: relative; flex: 1 1 auto; min-height: 0; display: flex; }
#video-player { width: 100%; height: 100%; object-fit: contain; background: #000; }

/* ── Skip intro / skip credits ────────────────────────────────────────────────
   Sits clear of the native video control bar (~44px tall in Safari and Chrome),
   which is why the offset is 64px and not 12px. */
#skip-btn {
  position: absolute;
  right: 16px;
  bottom: 64px;
  z-index: 4;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: rgba(15,15,15,0.86);
  border: 1px solid rgba(255,255,255,0.35);
  color: #fff;
  font-size: 0.85rem;
  font-weight: 700;
  padding: 9px 16px;
  border-radius: 8px;
  backdrop-filter: blur(4px);
}
#skip-btn:hover  { background: var(--accent); border-color: var(--accent); }
#skip-btn:active { transform: scale(0.97); }

/* Theater: big centered box, page dimmed behind.
   The old caps were width:min(1100px,94vw) height:min(80vh,720px) — on a 2600px
   display that pinned the video to 1100x720 in the middle of the screen, which
   is what made "theater mode" look like a small window. The vw/vh figures are
   the real limits now; the pixel caps only stop it going comically wide on an
   ultrawide, and 2200px is well past any 4K panel's usable width. */
.mode-theater #player-stage {
  top: 50%; left: 50%; transform: translate(-50%, -50%);
  width: min(2200px, 96vw); height: min(94vh, 1400px);
  border-radius: 10px;
}
/* Fullscreen: the Fullscreen API takes over #player-stage */
.mode-full #player-stage { inset: 0; width: 100%; height: 100%; border-radius: 0; transform: none; }
/* Small: mini player bottom-right, page usable */
.mode-small #player-scrim { display: none; }
.mode-small #player-stage {
  right: 20px; bottom: 20px; width: 480px; height: 300px; border-radius: 10px;
  border: 1px solid rgba(255,255,255,0.15);
  /* Drag it by the title bar; grab the corner to resize. */
  resize: both; min-width: 260px; min-height: 170px;
}
.mode-small #player-bottombar { display: none; }
/* The title bar doubles as the drag handle in mini mode. `touch-action: none`
   is required — without it the browser claims the pointer for panning and the
   drag dies after a few pixels on a trackpad or phone. */
.mode-small #player-topbar { cursor: grab; touch-action: none; user-select: none; }
.mode-small #player-topbar.is-dragging { cursor: grabbing; }

#player-topbar, #player-bottombar {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 14px; background: rgba(0,0,0,0.6); color: #fff;
}
#player-title { font-weight: 600; font-size: 0.95rem; flex: 1; min-width: 0; line-height: 1.3; overflow-wrap: anywhere; }
/* Back is the phone's exit. Desktop has ✕ and Esc and doesn't need it. */
#player-back {
  display: none;
  flex: 0 0 auto;
  width: 34px; height: 32px;
  border-radius: 8px;
  background: rgba(255,255,255,0.12);
  color: #fff;
  font-size: 1.5rem;
  line-height: 1;
  padding: 0 0 3px;
}
.player-tools { display: flex; gap: 6px; flex: 0 0 auto; }
.player-tools button {
  width: 34px; height: 30px; border-radius: 6px; color: #ddd;
  background: rgba(255,255,255,0.08); font-size: 0.95rem;
}
.player-tools button:hover { background: var(--accent); color: #fff; }
#player-bottombar { justify-content: space-between; }
#player-context { color: var(--text-muted); font-size: 0.82rem; flex: 1; text-align: center; }
.pbtn { background: rgba(255,255,255,0.1); color: #fff; padding: 8px 14px; border-radius: 6px; font-size: 0.85rem; }
.pbtn:hover { background: var(--accent); }

/* Up-next auto-advance card */
#upnext { position: absolute; right: 18px; bottom: 66px; z-index: 5; }
.mode-small #upnext { right: 6px; bottom: 6px; }
.upnext-card { background: rgba(15,15,15,0.95); border: 1px solid rgba(255,255,255,0.12); border-radius: 10px; padding: 14px 16px; width: 260px; }
.upnext-label { color: var(--text-muted); font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.5px; }
.upnext-title { font-weight: 700; margin: 4px 0 10px; font-size: 0.95rem; }
.upnext-actions { display: flex; gap: 8px; }
#upnext-play { background: var(--accent); color: #fff; padding: 8px 12px; border-radius: 6px; font-size: 0.82rem; flex: 1; }
#upnext-cancel { background: rgba(255,255,255,0.1); color: #ddd; padding: 8px 12px; border-radius: 6px; font-size: 0.82rem; }

/* ── Category pills in the top nav (between Home and Settings) ─────────────── */
/* ── Category pills: one row, scrolls sideways ────────────────────────────────
   Previously flex-wrap:wrap, which pushed a second row out of the 60px bar and
   clipped Settings. Categories are generated from folders, so they only ever
   grow — a single scrolling row is the only layout that can't break. */
.nav-cats {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: nowrap;
  flex: 1 1 auto;
  min-width: 0;                      /* see .nav-links */
  overflow-x: auto;
  overflow-y: hidden;
  scroll-behavior: smooth;
  overscroll-behavior-x: contain;    /* don't trigger back-swipe at the ends */
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;             /* Firefox */
  -ms-overflow-style: none;
  padding: 4px 0;                    /* room for the focus ring */
  cursor: grab;
}
.nav-cats::-webkit-scrollbar { display: none; }
.nav-cats.is-dragging { cursor: grabbing; scroll-behavior: auto; }
.nav-cats.is-dragging .nav-cat { pointer-events: none; }  /* no accidental nav on drag */

/* Soft fade telling you there's more in that direction. JS toggles the classes
   in app.js (setupNavScroll) based on actual scroll position. */
.nav-cats.can-left  { mask-image: linear-gradient(to right, transparent 0, #000 28px); }
.nav-cats.can-right { mask-image: linear-gradient(to left,  transparent 0, #000 28px); }
.nav-cats.can-left.can-right {
  mask-image: linear-gradient(to right, transparent 0, #000 28px,
                              #000 calc(100% - 28px), transparent 100%);
}

.nav-cat {
  padding: 6px 14px; border-radius: 999px; background: var(--surface2);
  color: var(--text); font-size: 0.82rem; font-weight: 600; white-space: nowrap;
  border: 1px solid rgba(255,255,255,0.06); cursor: pointer; transition: background 0.15s;
  flex: 0 0 auto;                    /* never squash a pill */
  user-select: none;
}
.nav-cat:hover { background: #333; }
.nav-cat.active { background: var(--accent); border-color: var(--accent); color: #fff; }

/* Home and Settings sit outside the scroller and stay put. */
.nav-links > .nav-link { flex: 0 0 auto; }

/* ── Category bar (home organize buttons) ─────────────────────────────────── */
.home-head { padding: calc(var(--nav-height) + 30px) 40px 0; }
.cat-bar { display: flex; flex-wrap: wrap; gap: 10px; margin: 18px 0 6px; }
.cat-btn {
  padding: 9px 18px; border-radius: 999px; background: var(--surface2);
  color: var(--text); font-size: 0.9rem; font-weight: 600; border: 1px solid rgba(255,255,255,0.06);
}
.cat-btn:hover { background: #333; }
.cat-btn.active { background: var(--accent); border-color: var(--accent); color: #fff; }
#az-grid { padding: 8px 40px 60px; }

/* ── Breadcrumbs + browse header ──────────────────────────────────────────── */
.browse { padding: calc(var(--nav-height) + 22px) 40px 60px; }
.crumbs { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; color: var(--text-muted); font-size: 0.85rem; margin-bottom: 16px; }
.crumbs a { color: var(--accent); }
.crumbs a:hover { text-decoration: underline; }
.crumb-here { color: var(--text); font-weight: 600; }
.crumb-sep { opacity: 0.5; }
.browse-head { display: flex; align-items: center; gap: 18px; margin-bottom: 10px; }
.browse-thumb { width: 92px; height: 138px; object-fit: cover; border-radius: 8px; }

/* ── Detail (a playable title) ────────────────────────────────────────────── */
.detail-head { position: relative; border-radius: 14px; overflow: hidden; margin-bottom: 10px; }
.detail-bg { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; filter: blur(28px) brightness(0.4); transform: scale(1.15); }
.detail-bg-fade { position: absolute; inset: 0; background: linear-gradient(to top, var(--bg), rgba(15,15,15,0.4)); }
.detail-head-inner { position: relative; display: flex; gap: 24px; padding: 30px; }
.detail-poster img { width: 200px; border-radius: 10px; box-shadow: 0 10px 40px rgba(0,0,0,0.6); }
.detail-poster-placeholder { width: 200px; height: 300px; background: var(--surface2); border-radius: 10px; display: flex; align-items: center; justify-content: center; font-size: 3rem; }
.detail-info { display: flex; flex-direction: column; justify-content: flex-end; }
.detail-title { font-size: 2.2rem; font-weight: 800; margin-bottom: 16px; }
.play-btn { align-self: flex-start; background: var(--accent); color: #fff; padding: 12px 26px; border-radius: 8px; font-size: 1rem; font-weight: 700; }
.play-btn:hover { background: var(--accent-dim); }

/* DRM'd Apple titles — white button, black text, opens in the Apple TV app */
.appletv-btn { align-self: flex-start; background: #fff; color: #000; padding: 12px 26px; border-radius: 8px; font-size: 1rem; font-weight: 700; }
.appletv-btn:hover { background: #e2e2e2; }
.apple-row { cursor: pointer; }
.apple-tag { background: #fff; color: #000; font-weight: 700; font-size: 0.78rem; padding: 6px 12px; border-radius: 999px; white-space: nowrap; }

/* Toast */
#toast {
  position: fixed; left: 50%; bottom: 28px; transform: translate(-50%, 20px);
  background: #fff; color: #000; font-weight: 600; font-size: 0.9rem;
  padding: 12px 20px; border-radius: 10px; box-shadow: 0 10px 40px rgba(0,0,0,0.5);
  opacity: 0; pointer-events: none; transition: opacity 0.2s, transform 0.2s; z-index: 2000;
}
#toast.show { opacity: 1; transform: translate(-50%, 0); }

/* ── Video list (episodes / parts) ────────────────────────────────────────── */
.section-title { font-size: 1.2rem; font-weight: 700; margin: 22px 0 12px; }
.video-list { display: flex; flex-direction: column; gap: 8px; }
.video-row { display: flex; align-items: center; gap: 14px; background: var(--surface); padding: 12px 16px; border-radius: 8px; cursor: pointer; transition: background 0.15s; }
.video-row:hover { background: var(--surface2); }
.vr-num { color: var(--text-muted); font-weight: 700; min-width: 22px; }
.vr-info { flex: 1; min-width: 0; }
/* Episode / part rows wrap too — the distinguishing part of a long episode
   name is usually at the END, which is exactly what an ellipsis eats. */
.vr-title { font-weight: 600; line-height: 1.3; overflow-wrap: anywhere; }
.vr-play { color: var(--accent); font-size: 1.1rem; padding: 0 6px; }
/* Season label under an episode title in the All Episodes list. Only rendered
   on multi-season shows — see episodesSection in app.js. */
.vr-sub { color: var(--text-muted); font-size: 0.8rem; margin-top: 2px; }

/* All Episodes: the count beside the heading, and the Play All / Shuffle row
   that sits between the heading and the list. */
.section-count { color: var(--text-muted); font-size: 0.85rem; font-weight: 600; margin-left: 8px; }
.ep-actions { display: flex; flex-direction: row; flex-wrap: wrap; align-items: center; gap: 10px; margin-bottom: 14px; }
/* .play-btn sets align-self: flex-start for the hero column; in this row it has
   to sit on the same line as the shuffle button. */
.ep-actions .play-btn { align-self: center; font-size: 0.95rem; padding: 10px 22px; }
.ep-actions .shuffle-btn-page { margin-top: 0; font-size: 0.9rem; padding: 9px 16px; }

/* Watch-progress bar (how far the last watch got) — sits left of the restart + play controls */
.vr-progress { width: 120px; height: 6px; background: rgba(255,255,255,0.12); border-radius: 3px; overflow: hidden; flex-shrink: 0; }
.vr-progress-fill { height: 100%; background: var(--accent); border-radius: 3px; }
.vr-restart { display: inline-flex; align-items: center; justify-content: center; width: 34px; height: 30px; border-radius: 6px; background: rgba(255,255,255,0.06); flex-shrink: 0; }
.vr-restart:hover { background: rgba(43,156,229,0.18); }
.ricon { display: block; }

/* Hero actions: main button + Restart Now underneath */
.hero-actions { display: flex; flex-direction: column; align-items: flex-start; gap: 10px; }
/* Watch buttons sit in a ROW — a title with a DVD and a Blu-ray shows both side
   by side. Wraps rather than overflowing when a title has several versions on a
   narrow window. Restart / Shuffle stay stacked beneath. */
.watch-row { display: flex; flex-direction: row; flex-wrap: wrap; align-items: center; gap: 10px; }
.restart-now { display: inline-flex; align-items: center; gap: 8px; background: rgba(255,255,255,0.08); color: var(--text); padding: 9px 16px; border-radius: 8px; font-size: 0.9rem; font-weight: 600; }
.restart-now:hover { background: rgba(43,156,229,0.18); }

/* ── Settings ─────────────────────────────────────────────────────────────── */
.settings-page { padding: calc(var(--nav-height) + 30px) 40px 60px; max-width: 720px; }
.settings-card { background: var(--surface); border-radius: 12px; padding: 6px 20px; margin-top: 16px; }
.setting-row { display: flex; align-items: center; justify-content: space-between; gap: 20px; padding: 18px 0; border-bottom: 1px solid rgba(255,255,255,0.06); }
.setting-row:last-child { border-bottom: none; }
.setting-label { font-weight: 600; }
.setting-desc { color: var(--text-muted); font-size: 0.85rem; margin-top: 3px; max-width: 460px; }
.settings-note { color: var(--text-muted); font-size: 0.8rem; margin-top: 14px; }
.settings-heading { font-size: 1rem; font-weight: 700; margin-top: 28px; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.6px; }
.danger-btn { background: rgba(255,255,255,0.08); color: #e06666; border: 1px solid rgba(224,102,102,0.35); padding: 8px 14px; border-radius: 8px; font-size: 0.85rem; font-weight: 600; flex-shrink: 0; }
.danger-btn:hover { background: rgba(224,102,102,0.18); }
.num-input { width: 70px; background: var(--surface2); color: var(--text); border: 1px solid rgba(255,255,255,0.1); border-radius: 6px; padding: 8px; font-size: 0.95rem; text-align: center; }
.switch { position: relative; display: inline-block; width: 48px; height: 26px; flex-shrink: 0; }
.switch input { opacity: 0; width: 0; height: 0; }
.slider { position: absolute; inset: 0; background: #444; border-radius: 26px; transition: 0.2s; }
.slider::before { content: ''; position: absolute; height: 20px; width: 20px; left: 3px; top: 3px; background: #fff; border-radius: 50%; transition: 0.2s; }
.switch input:checked + .slider { background: var(--accent); }
.switch input:checked + .slider::before { transform: translateX(22px); }

.ph-icon { font-size: 2rem; }

/* ── Responsive ───────────────────────────────────────────────────────────── */
@media (max-width: 768px) {
  /* The bar is TWO rows on a phone: logo + search + gear, then the category
     pills. It used to be one row with `.nav-links { display: none }`, which hid
     the pills AND the Settings link — there was no way to reach Settings from a
     phone at all, and no way to change category without going Home first.
     Overriding --nav-height is all it takes to move every calc() offset in this
     file down with it. The bar is back to a single 60px row now that the
     categories live in the ☰ menu rather than on a second row of pills. */

  #navbar { padding: var(--safe-top) 12px 0; gap: 10px; }
  .nav-menu-btn { display: inline-flex; }
  .nav-logo   { font-size: 1.1rem; flex: 0 0 auto; }
  /* flex-basis 0, not auto: the search box carries an explicit width, so an
     auto basis makes it claim that width before it will shrink. */
  .nav-search { margin-left: auto; flex: 1 1 0; min-width: 0; }
  /* Everything in here is in the ☰ menu instead. */
  .nav-links  { display: none; }

  #search-input, #search-input:focus { width: 100%; }
  #search-results { width: min(320px, calc(100vw - 24px)); }

  .hero { height: 300px; padding: 20px; }
  .hero-title { font-size: 1.6rem; }

  .genre-nav, .section, .genre-page, .episodes-section { padding: 20px 16px; }

  .genre-grid { grid-template-columns: repeat(auto-fill, minmax(130px, 1fr)); }
  .card-grid  { grid-template-columns: repeat(auto-fill, minmax(130px, 1fr)); gap: 10px; }

  .detail-content { padding: 20px 16px; gap: 16px; flex-direction: column; }
  .detail-poster { width: 120px; }
  .detail-title { font-size: 1.5rem; }

  .hero-play, .play-btn { padding: 10px 20px; font-size: 0.9rem; }

  .home-head, #az-grid, .cat-grid, .browse, .settings-page { padding-left: 16px; padding-right: 16px; }
  /* #app already pads the whole page down by --nav-height; these three then add
     nav-height AGAIN on top of it. That double offset was a tolerable 150px
     under a 60px desktop bar — under the taller two-row phone bar it became 214
     and pushed the first real content most of the way down the screen. */
  .home-head, .browse, .settings-page { padding-top: 18px; }
  .cat-grid { grid-template-columns: 1fr; gap: 12px; }
  .detail-head-inner { flex-direction: column; padding: 20px; }
  .detail-poster img, .detail-poster-placeholder { width: 140px; }
  .detail-poster-placeholder { height: 210px; }
}


/* ── Player on a handheld ─────────────────────────────────────────────────────
   NOT width-based, and that is the point. A phone in landscape is 844px wide —
   wider than the 768px breakpoint — so a pure max-width rule left the player in
   its desktop layout exactly when the phone was turned sideways to watch
   something. The second condition catches that: a short viewport with a coarse
   pointer is a handheld held sideways, never a laptop.
   ────────────────────────────────────────────────────────────────────────────*/
@media (max-width: 768px), (pointer: coarse) and (max-height: 560px) {
  /* THE PORTRAIT BUG.
     This used to be `width: 100vw; height: 100vh` while leaving the theater
     rule's `top/left: 50%` and `translate(-50%, -50%)` in place. On iOS, 100vh
     is the viewport WITHOUT the browser's own chrome — taller than what you can
     actually see — so centring a 100vh box on the visible area pushed the top
     bar (Back, ✕, fullscreen) off the top of the screen and the Prev/Next bar
     off the bottom. In landscape the chrome is much shorter, the overflow was
     small enough not to matter, and the controls appeared: hence "options only
     show up horizontally".
     #player-overlay is already position:fixed inset:0, so pinning the stage to
     it with inset:0 gives the real visible box in both orientations, with no
     viewport units and no transform involved. */
  .mode-theater #player-stage,
  .mode-small   #player-stage,
  .mode-full    #player-stage {
    inset: 0;
    top: 0; left: 0; right: 0; bottom: 0;
    transform: none;
    width: auto; height: auto;
    border: none; border-radius: 0;
    resize: none;
  }
  /* The mini player is a desktop idea — a draggable, resizable window. On a
     phone there is nowhere to drag it to, so mode-small renders full bleed like
     everything else and the three buttons that switch to it are hidden. */
  .desk-only { display: none !important; }
  .mode-small #player-scrim { display: block; }
  .mode-small #player-bottombar { display: flex; }
  .mode-small #upnext, .mode-small #endcard { right: 12px; bottom: 76px; }
  #player-back { display: inline-flex; }

  /* Bigger tap targets in the player bar, and room for the home indicator. */
  .player-tools button { width: 40px; height: 36px; font-size: 1.05rem; }

  /* SAFE AREAS. index.html sets viewport-fit=cover and the home-screen app uses
     a black-translucent status bar, so the page really does extend under the
     notch, the status bar and the rounded corners. #navbar was given
     var(--safe-top) for exactly this; the player's own bars were not, and the
     player replaces the navbar while it is open.

     Portrait: the top bar (Back, title, fullscreen, close) is ~52px tall and
     the status-bar inset is 47-59px on a notched phone, so the whole row sat
     underneath it — the controls were there, just not reachable.
     Landscape: the top/bottom insets go to 0 but left/right become ~47px, which
     is where the notch and the corner radius live. The two buttons at the right
     end of the row — fullscreen and close — are the ones that land under it.

     Pad both bars on every side that has an inset. All four are 0px on a
     desktop and on a phone without a notch, so this changes nothing there. */
  #player-topbar {
    padding: calc(8px + env(safe-area-inset-top, 0px))
             calc(10px + env(safe-area-inset-right, 0px))
             8px
             calc(10px + env(safe-area-inset-left, 0px));
  }
  #player-bottombar {
    padding: 10px
             calc(14px + env(safe-area-inset-right, 0px))
             calc(10px + env(safe-area-inset-bottom, 0px))
             calc(14px + env(safe-area-inset-left, 0px));
  }
  #player-title { font-size: 0.85rem; }

  /* The cards are pinned to the right edge on a 390px screen otherwise. */
  #upnext, #endcard { right: 12px; left: 12px; bottom: 76px; }
  .upnext-card, #endcard .upnext-card { width: auto; }

  #skip-btn { right: calc(12px + env(safe-area-inset-right, 0px)); bottom: 72px; padding: 11px 18px; font-size: 0.9rem; }

  /* The chip was a full-size pill in the bottom-left corner — directly on top
     of the video's own scrubber once the player went full bleed. It is smaller
     here, sits above the home indicator, and hides itself while the player is
     up (see paintChip in shuffle.js). */
  #shuffle-chip {
    left: 12px;
    right: auto;
    bottom: calc(12px + env(safe-area-inset-bottom, 0px));
    font-size: 0.72rem;
    padding: 5px 5px 5px 10px;
    gap: 5px;
    max-width: calc(100vw - 24px);
  }
  #shuffle-chip .chip-text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  #shuffle-chip .chip-toggle { font-size: 0.68rem; padding: 3px 8px; }
}

/* ── TV sizing (large screen, used from Apple TV via AirPlay) ─────────────── */
@media (min-width: 1400px) {
  .card-grid  { grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); }
  .genre-grid { grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); }
  .hero-title { font-size: 3rem; }
  .detail-title { font-size: 2.8rem; }
  .section, .genre-page, .genre-nav, .episodes-section { padding: 32px 60px; }
}

/* ── Shuffle ──────────────────────────────────────────────────────────────────
   The home-page strip sits above the category grid and is deliberately smaller
   than a category card: it's a shortcut, not a destination. Buttons are
   generated from the real folder list, so this row has to survive an unknown
   number of items — hence wrap rather than a fixed column count. */
.shuffle-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  padding: 18px 40px 4px;
}

.shuffle-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: var(--surface2);
  color: var(--text);
  border: 1px solid rgba(255,255,255,0.08);
  padding: 7px 14px;
  border-radius: 999px;
  font-size: 0.82rem;
  font-weight: 600;
  white-space: nowrap;
  transition: background 0.15s, border-color 0.15s, transform 0.1s;
}
.shuffle-btn:hover  { background: rgba(22,163,74,0.18); border-color: var(--accent); }
.shuffle-btn:active { transform: scale(0.97); }

/* Shuffle All is the headline action of the row. */
.shuffle-btn-all { background: var(--accent); border-color: var(--accent); color: #fff; }
.shuffle-btn-all:hover { background: var(--accent-dim); }

/* ── Shuffle: one split button, not a row of them ─────────────────────────────
   This row used to hold a button per category, generated from the folder list.
   That means it grows every time a folder is added to the drive, and at a dozen
   categories it stopped reading as a choice and started reading as a wall — on
   a phone it was most of the first screen before you saw a single poster.

   Split, not a plain dropdown: Shuffle All is the common case and stays ONE
   tap as the left half. The caret opens the rest. */
.shuffle-split { position: relative; display: inline-flex; align-items: stretch; }
.shuffle-split .shuffle-btn-all {
  border-top-right-radius: 0;
  border-bottom-right-radius: 0;
  border-right: 1px solid rgba(0,0,0,0.28);
}
.shuffle-caret {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 40px; padding: 0 10px;
  background: var(--accent-dim);
  color: #fff;
  border: 1px solid var(--accent-dim);
  border-left: none;
  border-radius: 0 999px 999px 0;
  font-size: 0.75rem;
}
.shuffle-caret:hover { background: #0f6b32; }
.shuffle-caret[aria-expanded="true"] { background: #0f6b32; }

.shuffle-menu {
  position: absolute;
  top: calc(100% + 8px);
  left: 0;
  min-width: 240px;
  max-width: calc(100vw - 32px);
  max-height: 60vh;
  overflow-y: auto;
  z-index: 250;
  background: #171717;
  border: 1px solid rgba(255,255,255,0.1);
  border-radius: 12px;
  padding: 6px;
  box-shadow: 0 18px 50px rgba(0,0,0,0.65);
}
.shuffle-menu-head {
  color: var(--text-muted);
  font-size: 0.7rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.6px;
  padding: 8px 12px 6px;
}
.shuffle-menu-item {
  display: block; width: 100%;
  text-align: left;
  padding: 12px;
  border-radius: 8px;
  font-size: 0.92rem;
  font-weight: 600;
  color: var(--text);
  white-space: nowrap;
}
.shuffle-menu-item:hover { background: rgba(22,163,74,0.22); }
/* The pool that's actually running is lit here too, same as the buttons were. */
.shuffle-menu-item.is-shuffling { background: var(--accent); color: #fff; }

/* The pool that's actually running, so you can tell at a glance. */
.shuffle-btn.is-shuffling {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}

/* The button always sits UNDER the item count, left-aligned with the title —
   never floated to the far right, where it reads as unrelated to the page.
   On a title page it stacks under Play inside .hero-actions for the same
   reason. */
.browse-head-text { display: flex; flex-direction: column; align-items: flex-start; }
.browse-head .shuffle-btn-page { margin-top: 10px; }
.hero-actions .shuffle-btn-page { align-self: flex-start; font-size: 0.9rem; padding: 9px 16px; }

/* ── Shuffle status chip ──────────────────────────────────────────────────────
   Shuffle keeps running after the player is closed, so the indicator lives on
   the page, not in the overlay. Without it you can be in shuffle mode with no
   visible sign of it. */
#shuffle-chip {
  position: fixed;
  left: 20px;
  bottom: 20px;
  z-index: 1500;
  display: flex;
  align-items: center;
  gap: 8px;
  background: rgba(22,163,74,0.95);
  color: #fff;
  font-size: 0.82rem;
  font-weight: 600;
  padding: 8px 10px 8px 14px;
  border-radius: 999px;
  box-shadow: 0 8px 30px rgba(0,0,0,0.5);
}
/* Off state: same pill, dimmed, still on screen — because the way back ON has
   to be where the way OFF was. Switching shuffle off used to delete the chip. */
#shuffle-chip.is-off {
  background: rgba(36,36,36,0.95);
  border: 1px solid rgba(255,255,255,0.15);
  color: var(--text-muted);
}
#shuffle-chip.is-off .chip-icon { opacity: 0.5; }

/* The On/Off switch itself. Reads as a state, and pressing it flips that state
   — it is not a close button. Closing is the separate ✕, and only in the off
   state, so a press can never leave shuffle running with nothing saying so. */
#shuffle-chip .chip-toggle {
  background: rgba(0,0,0,0.3);
  color: #fff;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.3px;
  line-height: 1;
  padding: 4px 10px;
  border-radius: 999px;
}
#shuffle-chip.is-off .chip-toggle { background: rgba(255,255,255,0.12); color: var(--text-muted); }
#shuffle-chip .chip-toggle:hover { background: rgba(0,0,0,0.5); color: #fff; }
#shuffle-chip .chip-x {
  color: inherit;
  opacity: 0.7;
  font-size: 0.85rem;
  line-height: 1;
  padding: 2px 4px;
}
#shuffle-chip .chip-x:hover { opacity: 1; }

/* ── Shuffle end-of-item card ─────────────────────────────────────────────────
   Same geometry as #upnext so the two never look like different products; it
   just carries more buttons (continue / next episode / stop). */
#endcard { position: absolute; right: 18px; bottom: 66px; z-index: 6; }
.mode-small #endcard { right: 6px; bottom: 6px; }
#endcard .upnext-card { width: 280px; }
#endcard-primary {
  background: var(--accent); color: #fff; padding: 9px 12px;
  border-radius: 6px; font-size: 0.85rem; font-weight: 700; flex: 1;
}
#endcard-primary:hover { background: var(--accent-dim); }
#endcard-secondary {
  display: block; width: 100%; margin-top: 8px;
  background: rgba(255,255,255,0.1); color: #ddd;
  padding: 8px 12px; border-radius: 6px; font-size: 0.8rem;
  text-align: left; line-height: 1.35; overflow-wrap: anywhere;
}
#endcard-secondary:hover { background: rgba(255,255,255,0.18); }
#endcard-dismiss {
  display: block; width: 100%; margin-top: 6px;
  color: var(--text-muted); font-size: 0.75rem; padding: 4px;
}
#endcard-dismiss:hover { color: var(--text); }

@media (max-width: 768px) {
  .shuffle-row { padding-left: 16px; padding-right: 16px; }
  /* LEFT-anchored, deliberately. Right-anchoring looks like the safe choice —
     it is what keeps a menu on screen when its button sits on the right — but
     this button sits at the left margin, so pinning a 280px panel to its right
     edge (x≈170) put the panel at x=-110 and half of it off the screen.
     Measured at 390px, which is an iPhone. */
  .shuffle-menu {
    left: 0; right: auto;
    min-width: min(280px, calc(100vw - 40px));
  }
}

/* Same handheld condition as the player block above. It has to be repeated down
   here, after `#endcard .upnext-card { width: 280px }`, because that rule is
   equally specific and later in the file — putting the override only in the
   earlier query left the card a fixed 280px on a 390px screen. */
@media (max-width: 768px), (pointer: coarse) and (max-height: 560px) {
  #endcard .upnext-card, #upnext .upnext-card { width: auto; }
  #endcard-secondary { text-align: center; }
}

/* ── Match card (wrestling) ──────────────────────────────────────────────────
   A collapsed button that opens the event's card. Sits between the header and
   the Watch button, so on a phone the thing you came for is still above the
   fold with the card closed. */
.match-section { padding-top: 8px; padding-bottom: 8px; }

.matches-btn {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  background: var(--surface2);
  border: 1px solid #333;
  color: var(--text);
  padding: 11px 20px;
  border-radius: 6px;
  font-size: 0.95rem;
  font-weight: 600;
  transition: background 0.2s, border-color 0.2s;
}
.matches-btn:hover { background: #2e2e2e; border-color: #444; }
.matches-btn[aria-expanded="true"] { border-color: var(--accent); }
.matches-btn .mc-icon { font-size: 1rem; }
.matches-btn .mc-caret { color: var(--text-muted); font-size: 0.8rem; }

.match-panel { margin-top: 14px; }
.match-panel[hidden] { display: none; }

.mc-card {
  background: var(--surface);
  border: 1px solid #2a2a2a;
  border-radius: 8px;
  padding: 20px 22px;
  max-width: 760px;
}
.mc-event  { font-size: 1.1rem; font-weight: 700; }
.mc-meta   { color: var(--text-muted); font-size: 0.85rem; margin-top: 4px; }
.mc-partial {
  margin-top: 12px;
  font-size: 0.82rem;
  color: #d4a017;
}
.mc-loading { color: var(--text-muted); font-size: 0.9rem; padding: 6px 2px; }

.mc-list { list-style: none; margin-top: 16px; }
/* Grid, not flex: a long bout ("Shelton Benjamin vs. Carlito vs. Johnny Nitro")
   has to wrap INSIDE its own column. Flex-wrap put the row number on a line of
   its own above the bout as soon as anything got long, which on a phone was
   most rows. */
.mc-row {
  display: grid;
  grid-template-columns: 22px 1fr auto;
  align-items: baseline;
  gap: 4px 12px;
  padding: 10px 0;
  border-top: 1px solid #262626;
}
.mc-row:first-child { border-top: none; padding-top: 0; }

.mc-num {
  grid-column: 1;
  color: var(--text-muted);
  font-size: 0.8rem;
  font-variant-numeric: tabular-nums;
}
/* The bout is the line you scan; the stipulation or title on the line sits
   under it in muted type rather than beside it, because "— WWE Championship"
   on the end of every third row wraps badly on a phone. */
.mc-bout { grid-column: 2; min-width: 0; line-height: 1.4; }
.mc-note { display: block; color: var(--text-muted); font-size: 0.82rem; margin-top: 2px; }
.mc-tag {
  grid-column: 3;
  align-self: center;
  background: var(--surface2);
  color: var(--text-muted);
  border-radius: 4px;
  padding: 3px 8px;
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  white-space: nowrap;
}
.mc-source {
  margin-top: 16px;
  padding-top: 12px;
  border-top: 1px solid #262626;
  color: var(--text-muted);
  font-size: 0.75rem;
}

@media (max-width: 768px) {
  .match-section { padding-left: 20px; padding-right: 20px; }
  .mc-card { padding: 16px; }
  /* "Pre-show" is real information, so it drops under the bout rather than
     being hidden — a narrow screen shouldn't quietly change what the card says. */
  .mc-row { grid-template-columns: 22px 1fr; }
  .mc-tag { grid-column: 2; justify-self: start; }
}

/* ── The off-network link in Settings ─────────────────────────────────────── */
/* `user-select: all` so one tap selects the whole URL on a phone, where the
   Copy button is the happy path but a long-press is the fallback people reach
   for first. Monospace because a ts.net hostname is a string you may have to
   read out loud. */
.access-link {
  margin-top: 8px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.82rem;
  color: #2b9ce5;
  word-break: break-all;
  user-select: all;
}

.ghost-btn {
  background: transparent;
  color: var(--text, #f5f5f5);
  border: 1px solid #3a3a3a;
  border-radius: 8px;
  padding: 8px 14px;
  font-size: 0.85rem;
  cursor: pointer;
  white-space: nowrap;
}
.ghost-btn:active { opacity: 0.75; }
