:root {
  color-scheme: dark;
  --bg: #071019;
  --bg-raised: #111e2b;
  --bar: rgba(9, 20, 31, 0.82);
  --text: #f7fbff;
  --muted: #a9bac7;
  --line: rgba(255, 255, 255, 0.11);
  --cyan: #ff6b61;
  --rose: #8de5d2;
  --heart: #ff9c78;
  --gold: #ffd166;
  --blue: #8de5d2;
  --focus: #ffffff;
  --shadow: 0 24px 70px rgba(0, 0, 0, 0.48);
  --radius-sm: 0.55rem;
  --radius-md: 0.8rem;
  --radius-lg: 1rem;
  --control-h-sm: 2.75rem;
  --control-h-md: 3.25rem;
  --control-h-lg: 4rem;
  --gap-sm: 0.6rem;
  --gap-md: 0.9rem;
  --route-home: #8de5d2;
  --route-library: #78b9ff;
  --route-schedule: #ffd166;
  --route-anipub: #ff806b;
  --route-favorites: #ff9c78;
  --route-sources: #40dfc2;
  --route-settings: #ff8f9f;
}

body[data-theme="light"] {
  color-scheme: light;
  --bg: #eef3f9;
  --bg-raised: #ffffff;
  --bar: rgba(255, 255, 255, 0.76);
  --text: #101524;
  --muted: #667085;
  --line: rgba(16, 21, 36, 0.13);
  --shadow: 0 24px 70px rgba(27, 37, 66, 0.16);
}

* {
  box-sizing: border-box;
}

html {
  min-height: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: 8rem;
  scrollbar-color: rgba(255, 255, 255, 0.16) transparent;
  scrollbar-width: thin;
  /* Chrome's default tap highlight is rgba(51, 181, 229, 0.4) - a 40% blue wash
     over whatever was tapped, which flashed across a whole carousel card. The
     app draws its own press, hover, :focus-visible and .is-tv-focused states, so
     the UA overlay only ever fought them. Inherited, so it covers every control. */
  -webkit-tap-highlight-color: transparent;
}

body {
  min-height: 100vh;
  min-height: 100dvh;
  margin: 0;
  overflow-x: hidden;
  background:
    radial-gradient(circle at 18% 0%, rgba(255, 107, 97, 0.18), transparent 28rem),
    radial-gradient(circle at 100% 20%, rgba(141, 229, 210, 0.12), transparent 30rem),
    linear-gradient(180deg, #142536 0%, var(--bg) 32rem);
  color: var(--text);
  font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
}

html,
body {
  background-color: #050710;
}

/* App-like UX: a stray drag or Ctrl+A shouldn't paint the whole chrome blue.
   Disable text selection globally and re-enable it only on the anime title (the
   one thing worth copying) — plus form fields, which must stay editable. */
body {
  -webkit-user-select: none;
  user-select: none;
}
.watch-title,
.carousel-info h2,
.show-title,
.schedule-title,
input,
textarea,
[contenteditable="true"] {
  -webkit-user-select: text;
  user-select: text;
}

body[data-theme="light"] {
  background:
    radial-gradient(circle at 14% 0%, rgba(0, 210, 255, 0.16), transparent 28rem),
    radial-gradient(circle at 100% 18%, rgba(181, 122, 255, 0.16), transparent 30rem),
    linear-gradient(180deg, #f8fbff 0%, var(--bg) 34rem);
}

body[data-theme="light"]::before {
  background: linear-gradient(90deg, rgba(244, 248, 255, 0.82), transparent 24rem);
}

body[data-theme="light"]::after {
  background:
    linear-gradient(90deg, rgba(244, 248, 255, 0.82) 0%, rgba(244, 248, 255, 0.55) 38%, rgba(244, 248, 255, 0.14) 100%),
    linear-gradient(0deg, rgba(238, 243, 249, 0.92) 0%, rgba(238, 243, 249, 0.42) 46%, transparent 72%),
    radial-gradient(circle at 70% 4%, rgba(0, 210, 255, 0.1), transparent 28rem),
    linear-gradient(135deg, #f8fbff, #e7edf8);
  filter: saturate(1.04) brightness(1);
}

body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background: linear-gradient(90deg, rgba(8, 10, 19, 0.94), transparent 23rem);
  opacity: 0.8;
}

body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -2;
  pointer-events: none;
  background:
    linear-gradient(90deg, rgba(8, 10, 19, 0.98) 0%, rgba(8, 10, 19, 0.78) 36%, rgba(8, 10, 19, 0.36) 100%),
    linear-gradient(0deg, var(--bg) 0%, rgba(8, 10, 19, 0.86) 20%, transparent 62%),
    radial-gradient(circle at 70% 4%, rgba(138, 92, 255, 0.12), transparent 28rem),
    linear-gradient(135deg, #101321, #171b2d);
  background-position: center;
  background-size: cover;
  filter: saturate(1.08) brightness(0.6);
  opacity: 0.9;
  transform: none;
}

::-webkit-scrollbar {
  width: 0.34rem;
  height: 0.34rem;
}

::-webkit-scrollbar-track {
  background: transparent;
}

::-webkit-scrollbar-thumb {
  border-radius: 999rem;
  background: rgba(255, 255, 255, 0.15);
}

::-webkit-scrollbar-thumb:hover {
  background: rgba(255, 255, 255, 0.28);
}

.poster-grid,
.carousel-indicators,
.season-tab-list,
.episode-buttons,
.watch-info,
.main-nav {
  -ms-overflow-style: none;
  scrollbar-width: none;
}

.poster-grid::-webkit-scrollbar,
.carousel-indicators::-webkit-scrollbar,
.season-tab-list::-webkit-scrollbar,
.episode-buttons::-webkit-scrollbar,
.watch-info::-webkit-scrollbar,
.main-nav::-webkit-scrollbar {
  display: none;
}

button,
input {
  font: inherit;
}

button {
  border: 0;
}

.app-loader {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: grid;
  /* True optical centering: content block centered on both axes, and the glow
     centered with it (it used to sit at 42%/58%, reading as high on screen). */
  place-items: center;
  place-content: center;
  justify-items: center;
  text-align: center;
  gap: 0.75rem;
  color: #ffffff;
  background:
    radial-gradient(circle at 50% 46%, rgba(138, 92, 255, 0.20), transparent 20rem),
    radial-gradient(circle at 50% 58%, rgba(0, 210, 255, 0.12), transparent 24rem),
    #070914;
  transition: opacity 180ms ease, visibility 180ms ease;
}

.app-loader::after {
  content: "";
  width: min(16rem, 44vw);
  height: 0.18rem;
  margin-top: 0.45rem;
  border-radius: 999rem;
  background:
    linear-gradient(90deg, rgba(138, 92, 255, 0), rgba(138, 92, 255, 0.95), rgba(0, 210, 255, 0.95), rgba(0, 210, 255, 0));
  background-size: 180% 100%;
  box-shadow: 0 0 1.4rem rgba(138, 92, 255, 0.32);
  animation: loader-fill 1.15s ease-in-out infinite;
}

@media (prefers-reduced-motion: reduce) {
  .loader-mark,
  .loader-mark::before,
  .loader-mark::after,
  .loader-logo,
  .app-loader::after {
    animation: none !important;
  }
  .loader-mark::before { border-top-color: #8a5cff; }
}

.app-loader.is-hidden {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}

/* ── ZenkaiTV app loader ──────────────────────────────────────────────────── */
.loader-mark {
  position: relative;
  display: grid;
  place-items: center;
  width: 5.6rem;
  height: 5.6rem;
  border-radius: 1.6rem;
  background: #0D1B2A;
  box-shadow:
    0 1.3rem 2.8rem rgba(0, 0, 0, 0.42),
    0 0 2.6rem rgba(138, 92, 255, 0.30),
    inset 0 0 0 0.08rem rgba(138, 92, 255, 0.24);
  overflow: hidden;
  animation: loader-breathe 2.4s ease-in-out infinite;
}

/* rotating loading ring */
.loader-mark::before {
  content: "";
  position: absolute;
  inset: -0.42rem;
  border-radius: 2rem;
  border: 0.17rem solid rgba(255, 255, 255, 0.07);
  border-top-color: #8a5cff;
  border-right-color: rgba(0, 210, 255, 0.55);
  animation: loader-spin 1.05s linear infinite;
}

/* light sweep across the logo */
.loader-mark::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
  border-radius: inherit;
  background: linear-gradient(115deg, transparent 40%, rgba(233, 226, 255, 0.34) 50%, transparent 60%);
  transform: translateX(-130%);
  animation: logo-shimmer 3.4s ease-in-out infinite;
  pointer-events: none;
}

.loader-logo {
  position: relative;
  z-index: 1;
  width: 72%;
  height: 72%;
  object-fit: contain;
  filter: drop-shadow(0 0 0.8rem rgba(138, 92, 255, 0.45));
  animation: loader-logo-pulse 2.4s ease-in-out infinite;
}

@keyframes loader-logo-pulse {
  0%, 100% { transform: scale(0.96); }
  50%      { transform: scale(1.05); }
}

.app-loader strong {
  margin-top: 0.1rem;
  font-size: 1.35rem;
  font-weight: 950;
}

.app-loader small {
  color: rgba(255, 255, 255, 0.58);
  font-size: 0.86rem;
  font-weight: 800;
}

.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;
}

.app-shell {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  min-height: 100dvh;
  padding: 0 0 0 5.1rem;
  background:
    linear-gradient(180deg, rgba(8, 10, 19, 0) 0%, rgba(8, 10, 19, 0.5) 66%, #050710 100%);
  transition: padding-left 360ms cubic-bezier(0.22, 1, 0.36, 1);
}

.topbar {
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  z-index: 20;
  display: grid;
  /* Three declared tracks, not four. The search box is the 4th child and is hidden
     in the collapsed rail; with a 4th track declared it still reserved a row-gap
     below the toggle (16px of dead space, so the toggle never sat flush at the
     bottom). Leaving it implicit means the track only exists when the search box
     actually does - which is exactly the expanded sidebar, where the gap is wanted. */
  grid-template-rows: auto 1fr auto;
  grid-template-columns: 1fr;
  align-items: start;
  width: 5.1rem;
  min-height: 100vh;
  padding: 1.2rem 0.55rem;
  background:
    linear-gradient(90deg, rgba(8, 10, 19, 0.48), rgba(8, 10, 19, 0.18) 70%, transparent);
  box-shadow: none;
  backdrop-filter: blur(14px) saturate(1.08);
  animation: topbar-enter 520ms ease both;
  transition: width 360ms cubic-bezier(0.22, 1, 0.36, 1), padding 360ms cubic-bezier(0.22, 1, 0.36, 1), background 260ms ease;
}

.brand {
  display: grid;
  justify-items: center;
  gap: 0.65rem;
  color: var(--text);
  text-decoration: none;
  border-radius: 0.7rem;
}

.brand-mark {
  position: relative;
  display: grid;
  place-items: center;
  width: 4.1rem;
  height: 4.1rem;
  border-radius: 1.35rem;
  background: #0D1B2A;
  box-shadow:
    0 1rem 1.8rem rgba(59, 130, 246, 0.22),
    0 0 1.1rem rgba(59, 130, 246, 0.16),
    inset 0 0 0 0.08rem rgba(92, 155, 255, 0.22);
  overflow: hidden;
  transition: transform 180ms ease, box-shadow 180ms ease,
              width 360ms cubic-bezier(0.22, 1, 0.36, 1), height 360ms cubic-bezier(0.22, 1, 0.36, 1);
  animation: logo-breathe 3.6s ease-in-out infinite;
}

.brand-mark::before {
  content: "";
  position: absolute;
  inset: -24%;
  z-index: 0;
  background: radial-gradient(circle at 50% 50%, rgba(59, 130, 246, 0.55), rgba(37, 99, 235, 0.32) 55%, transparent 72%);
  opacity: 0.5;
  filter: blur(0.5rem);
  animation: logo-breathe-halo 3.6s ease-in-out infinite;
}

/* Faint light sweep that passes over the icon */
.brand-mark::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
  border-radius: inherit;
  background: linear-gradient(115deg, transparent 38%, rgba(180, 210, 255, 0.35) 50%, transparent 62%);
  transform: translateX(-130%);
  animation: logo-shimmer 6s ease-in-out infinite;
  pointer-events: none;
}

.brand-logo {
  position: relative;
  z-index: 1;
  display: block;
  width: 100%;
  height: 100%;
  border-radius: inherit;
  object-fit: cover;
  filter: drop-shadow(0 0 0.7rem rgba(59, 130, 246, 0.3));
}

@keyframes logo-breathe {
  0%, 100% {
    box-shadow:
      0 1rem 1.8rem rgba(59, 130, 246, 0.20),
      0 0 1rem rgba(59, 130, 246, 0.14),
      inset 0 0 0 0.08rem rgba(92, 155, 255, 0.22);
  }
  50% {
    box-shadow:
      0 1.1rem 2.1rem rgba(59, 130, 246, 0.34),
      0 0 1.7rem rgba(59, 130, 246, 0.30),
      inset 0 0 0 0.08rem rgba(92, 155, 255, 0.34);
  }
}

@keyframes logo-breathe-halo {
  0%, 100% { opacity: 0.4; transform: scale(0.97); }
  50%      { opacity: 0.7; transform: scale(1.04); }
}

@keyframes logo-shimmer {
  0%, 72%, 100% { transform: translateX(-130%); }
  84%           { transform: translateX(130%); }
}

/* ── Logo reaction synced with the sidebar collapse/expand ─────────────────── */
/* When collapsing, the mark dips left then springs back (follows the slide-in). */
@keyframes logo-react-collapse {
  0%   { transform: translateX(0) scale(1) rotate(0deg); }
  38%  { transform: translateX(-0.18rem) scale(0.8) rotate(-12deg); }
  72%  { transform: translateX(0) scale(1.08) rotate(5deg); }
  100% { transform: translateX(0) scale(1) rotate(0deg); }
}
/* When expanding, it leans out then settles (follows the slide-out). */
@keyframes logo-react-expand {
  0%   { transform: scale(0.9) rotate(0deg); }
  40%  { transform: scale(1.12) rotate(10deg); }
  72%  { transform: scale(0.97) rotate(-3deg); }
  100% { transform: scale(1) rotate(0deg); }
}
body.is-collapsing .brand-logo {
  animation: logo-react-collapse 600ms cubic-bezier(0.34, 1.4, 0.5, 1);
}
body.is-expanding .brand-logo {
  animation: logo-react-expand 600ms cubic-bezier(0.34, 1.4, 0.5, 1);
}
/* Flare the surrounding glow during the toggle so the motion feels integrated. */
body.is-toggling .brand-mark::before {
  animation: logo-toggle-flare 600ms ease-out;
}
@keyframes logo-toggle-flare {
  0%   { opacity: 0.45; transform: scale(1); }
  40%  { opacity: 0.95; transform: scale(1.18); }
  100% { opacity: 0.45; transform: scale(1); }
}

/* ── Coordinated sidebar open/close: nav items ripple + icons pulse ────────── */
@keyframes nav-item-collapse {
  0%   { opacity: 1; transform: translateX(0); }
  45%  { opacity: 0.55; transform: translateX(-0.32rem) scale(0.95); }
  100% { opacity: 1; transform: translateX(0); }
}
@keyframes nav-item-expand {
  0%   { opacity: 0.35; transform: translateX(-0.55rem); }
  60%  { opacity: 1; transform: translateX(0.12rem); }
  100% { opacity: 1; transform: translateX(0); }
}
@keyframes nav-icon-pulse {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.2); }
}
body.is-collapsing .main-nav .nav-link { animation: nav-item-collapse 440ms cubic-bezier(0.34, 1.2, 0.5, 1) both; }
body.is-expanding  .main-nav .nav-link { animation: nav-item-expand 480ms cubic-bezier(0.34, 1.3, 0.5, 1) both; }
/* Stagger so the items ripple in sequence (top → bottom) */
body.is-toggling .main-nav .nav-link:nth-child(1) { animation-delay: 0ms; }
body.is-toggling .main-nav .nav-link:nth-child(2) { animation-delay: 35ms; }
body.is-toggling .main-nav .nav-link:nth-child(3) { animation-delay: 70ms; }
body.is-toggling .main-nav .nav-link:nth-child(4) { animation-delay: 105ms; }
body.is-toggling .main-nav .nav-link:nth-child(5) { animation-delay: 140ms; }
body.is-toggling .main-nav .nav-link:nth-child(6) { animation-delay: 175ms; }
body.is-toggling .main-nav .nav-link span { animation: nav-icon-pulse 440ms cubic-bezier(0.34, 1.3, 0.5, 1); }

.brand-screen::before {
  content: "";
  position: absolute;
  display: none;
}

.brand-screen::after {
  content: "";
  position: absolute;
  display: none;
}

.brand-spark {
  position: absolute;
  z-index: 2;
  top: 1.48rem;
  width: 0.4rem;
  height: 0.4rem;
  border-radius: 50%;
  background: #83ffdf;
  box-shadow: 0 0 0.65rem rgba(131, 255, 223, 0.72);
}

.brand-spark-one {
  right: 1.23rem;
}

.brand-spark-two {
  left: 1.23rem;
  background: #ff7adf;
  box-shadow: 0 0 0.65rem rgba(255, 122, 223, 0.72);
}

.brand:is(:hover, :focus-visible, .is-tv-focused) .brand-mark {
  transform: translateY(-0.06rem) scale(1.03);
  box-shadow:
    0 1.15rem 2rem rgba(0, 210, 255, 0.23),
    0 0 1.35rem rgba(255, 79, 216, 0.22),
    inset 0 0 0 0.08rem rgba(255, 255, 255, 0.25);
}

.brand-copy {
  display: none;
  line-height: 1;
}

.brand-copy strong {
  font-size: clamp(1.55rem, 2.4vw, 2.25rem);
  letter-spacing: 0;
}

.brand-copy small {
  margin-top: 0.5rem;
  color: rgba(255, 255, 255, 0.64);
  font-size: 0.78rem;
  font-weight: 800;
  letter-spacing: 0.42rem;
}

.main-nav {
  display: grid;
  align-items: center;
  gap: 0.58rem;
  width: 100%;
  margin-top: 2.2rem;
  min-width: 0;
}

.nav-link,
.chip {
  --nav-accent: var(--cyan);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.42rem;
  width: 100%;
  min-height: 3.35rem;
  padding: 0;
  border-radius: var(--radius-lg);
  color: #aeb6cc;
  background: transparent;
  font-weight: 800;
  cursor: pointer;
}

.nav-link.is-active {
  color: #ffffff;
  background: color-mix(in srgb, var(--nav-accent) 20%, transparent);
  box-shadow:
    inset 0 0 0 0.08rem color-mix(in srgb, var(--nav-accent) 36%, rgba(255, 255, 255, 0.08)),
    0 0 1.4rem color-mix(in srgb, var(--nav-accent) 16%, transparent);
}

.nav-link:is(:hover, :focus-visible, .is-tv-focused) {
  color: #ffffff;
  background: color-mix(in srgb, var(--nav-accent) 14%, rgba(255, 255, 255, 0.04));
  box-shadow: inset 0 0 0 0.08rem color-mix(in srgb, var(--nav-accent) 28%, rgba(255, 255, 255, 0.08));
}

.nav-link {
  flex-direction: column;
  font-size: 0.64rem;
  line-height: 1;
  transition:
    min-height 360ms cubic-bezier(0.22, 1, 0.36, 1),
    font-size 320ms cubic-bezier(0.22, 1, 0.36, 1),
    letter-spacing 320ms cubic-bezier(0.22, 1, 0.36, 1),
    background 180ms ease, color 220ms ease, box-shadow 180ms ease;
}

/* Staggered wave: labels collapse/expand in sequence for a fluid feel */
.main-nav .nav-link:nth-child(1) { transition-delay: 0ms; }
.main-nav .nav-link:nth-child(2) { transition-delay: 24ms; }
.main-nav .nav-link:nth-child(3) { transition-delay: 48ms; }
.main-nav .nav-link:nth-child(4) { transition-delay: 72ms; }
.main-nav .nav-link:nth-child(5) { transition-delay: 96ms; }
.main-nav .nav-link:nth-child(6) { transition-delay: 120ms; }

.nav-link span {
  font-size: 1.42rem;
  transition: font-size 360ms cubic-bezier(0.22, 1, 0.36, 1), transform 360ms cubic-bezier(0.34, 1.3, 0.5, 1), color 180ms ease, filter 180ms ease;
}

.nav-link[data-route="home"] {
  --nav-accent: var(--route-home);
}

.nav-link[data-route="library"] {
  --nav-accent: var(--route-library);
}

.nav-link[data-route="schedule"] {
  --nav-accent: var(--route-schedule);
}

.nav-link[data-route="anipub"] {
  --nav-accent: var(--route-anipub);
}

.nav-link[data-route="favorites"] {
  --nav-accent: var(--route-favorites);
}

.nav-link[data-route="sources"] {
  --nav-accent: var(--route-sources);
}

.nav-link[data-route="settings"] {
  --nav-accent: var(--route-settings);
}

.nav-link:is(.is-active, :hover, :focus-visible, .is-tv-focused) span {
  color: var(--nav-accent);
  filter: drop-shadow(0 0 0.65rem color-mix(in srgb, var(--nav-accent) 44%, transparent));
}

.search-box {
  position: relative;
  display: block;
  grid-row: 3;
  width: 100%;
}

.topbar .search-box {
  display: none;
}

/* One button, one look. It is the same circle as the back and fullscreen controls -
   same size, surface, border and hover - so the three read as one family, and it
   does NOT change shape between the shown and hidden states. Only its position
   moves: bottom of the rail when shown, corner of the viewport when hidden. */
.sidebar-toggle {
  display: grid;
  place-items: center;
  /* Pinned to the bottom of the rail: the topbar's nav row is 1fr, so auto top
     margin plus end alignment puts it on the last usable line of the column. */
  align-self: end;
  justify-self: center;
  width: 2.9rem;
  height: 2.9rem;
  min-height: 0;
  margin: auto 0 0;
  border: 0.08rem solid rgba(255, 255, 255, 0.14);
  border-radius: 999rem;
  color: rgba(240, 242, 252, 0.92);
  background: rgba(12, 12, 22, 0.6);
  cursor: pointer;
  -webkit-backdrop-filter: blur(12px) saturate(1.1);
  backdrop-filter: blur(12px) saturate(1.1);
  box-shadow: 0 0.5rem 1.5rem rgba(0, 0, 0, 0.35);
  transition: transform 180ms ease, background 180ms ease, border-color 180ms ease, color 180ms ease, opacity 240ms ease;
}

/* The span stays because body.sidebar-collapsed rotates IT 180deg; it is now just
   a centred box for the icon rather than a text run. */
.sidebar-toggle span {
  display: grid;
  place-items: center;
  line-height: 0;
  transition: transform 240ms cubic-bezier(0.2, 0.8, 0.2, 1);
}

.sidebar-toggle .chev-ico {
  width: 1.25rem;
  height: 1.25rem;
}

/* Same hover as the back and fullscreen buttons. */
.sidebar-toggle:is(:hover, :focus-visible, .is-tv-focused) {
  border-color: rgba(138, 85, 255, 0.55);
  color: #ffffff;
  background: rgba(24, 20, 46, 0.82);
  transform: scale(1.06);
  box-shadow: 0 0.7rem 1.9rem rgba(0, 0, 0, 0.42);
}

/* Compact (collapsed) = narrow icon rail. The content + footer slide WITH the
   rail (push-drawer) on a unified easing, so opening/closing feels integrated.
   Default state is compact; expanding widens the rail and pushes content right. */
/* Collapsed means HIDDEN: the whole rail leaves the side and the page reclaims the
   space. It used to merely shrink 5.9rem -> 4.2rem, which still showed icons and
   gave the content almost nothing back. Shown = the compact icon rail. */
/* Desktop only. Below 960px the topbar becomes a full-width BOTTOM BAR, and these
   hidden-state rules were leaking into it: they zeroed its width, blanked its nav
   and floated the toggle over it, which is why a stray "Home" label sat under a
   floating button and the page gained scroll. The bottom bar has its own layout
   and must not see any of this. */
@media (min-width: 961px) {
  body.sidebar-collapsed .app-shell {
    padding-left: 0;
  }

  body.sidebar-collapsed .topbar {
    width: 0;
    padding-left: 0;
    padding-right: 0;
    background: transparent;
    box-shadow: none;
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
    /* The toggle is fixed-positioned below and has to escape the zero-width column. */
    overflow: visible;
  }

  /* With the rail gone the toggle would go with it, leaving no way back, so it floats
     free in the bottom-left corner - and tucks itself most of the way off the edge so
     it does not sit on top of the content it just made room for. It slides fully out
     on hover, focus or D-pad focus, which is also how it stays reachable on TV. */
  /* Identical button, different anchor. Size, surface, border and hover all inherit
     from .sidebar-toggle above - only the position changes, plus a gentle tuck toward
     the edge so it does not sit on top of the content it just made room for. */
  /* Stuck to the very edge rather than floating with a gap: it sits half off-screen
     against the left border, rounded only on the side that shows, and pops out when
     the pointer gets near it. A gap made it read as a stray control; flush to the
     edge it reads as a handle for the drawer it opens. */
  body.sidebar-collapsed .sidebar-toggle {
    position: fixed;
    left: 0;
    bottom: 1.15rem;
    z-index: 90;
    margin: 0;
    border-left-color: transparent;
    border-radius: 0 999rem 999rem 0;
    transform: translateX(-45%);
    opacity: 0.6;
    transition:
      transform 280ms cubic-bezier(0.22, 1, 0.36, 1),
      opacity 240ms ease,
      background 180ms ease,
      border-color 180ms ease;
  }

  /* "When you get closer": an invisible catch area wider than the button, so it
     starts sliding out before the pointer is actually on top of it. */
  body.sidebar-collapsed .sidebar-toggle::before {
    content: "";
    position: absolute;
    inset: -0.9rem -2.2rem -0.9rem -0.5rem;
  }

  body.sidebar-collapsed .sidebar-toggle:is(:hover, :focus-visible, .is-tv-focused) {
    transform: translateX(0);
    opacity: 1;
  }

  /* Reduced-motion users get the same reachability without the slide. */
  @media (prefers-reduced-motion: reduce) {
    body.sidebar-collapsed .sidebar-toggle {
      transform: none;
      opacity: 0.85;
      transition: none;
    }
  }

  /* Everything except the toggle fades out. visibility (not display) keeps the grid
     tracks intact, so the toggle does not jump when the rail hides. */
  body.sidebar-collapsed .topbar > :is(.brand, .main-nav, .search-box) {
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition: opacity 220ms ease, visibility 0s linear 220ms;
  }

  .topbar > :is(.brand, .main-nav, .search-box) {
    opacity: 1;
    visibility: visible;
    transition: opacity 260ms ease;
  }

  /* The rail is gone entirely in this state, so the footer has no column to clear. */
  body.sidebar-collapsed .bottom-bar {
    margin-left: 0;
    padding-left: clamp(1.4rem, 3.2vw, 3.4rem);
  }

  body.sidebar-collapsed .bottom-bar::before {
    left: 0;
  }
}

/* Compact rail is now the DEFAULT shown state: collapsed means hidden, so the
   icon-only styling below is unconditional. */
.brand-mark.brand-mark {
  /* Bigger mark in a narrower rail: the logo is the only branded element left in
     the compact column, so it carries it. */
  width: 3.5rem;
  height: 3.5rem;
}

/* The mark itself resizes (width/height), so the logo just fills it — no static
   scale here, which keeps the toggle reaction animation settling cleanly. */
body.sidebar-collapsed .brand-logo {
  transform: scale(1);
}

.main-nav.main-nav {
  gap: 0.5rem;
}

.nav-link.nav-link {
  min-height: 3.35rem;
  font-size: 0;
  gap: 0;
}

.nav-link.nav-link span {
  font-size: 1.62rem;
  transform: translateY(0);
}

/* Chevron rotates 180° when collapsed — smooth via the span's transform transition */
body.sidebar-collapsed .sidebar-toggle span {
  transform: rotate(180deg);
}

.search-box input {
  width: 100%;
  min-height: var(--control-h-lg);
  padding: 0 4.7rem 0 1.25rem;     /* room for the clear (×) + magnifier */
  border: 0.12rem solid rgba(255, 255, 255, 0.12);
  border-radius: var(--radius-lg);
  color: var(--text);
  background: #111026;
  outline: 0;
}

/* Hide every browser's native search clear control — we render our own button
   (the webkit-only ::-webkit-search-cancel-button never appears in Firefox). */
.search-box input[type="search"]::-webkit-search-cancel-button {
  -webkit-appearance: none;
  appearance: none;
  display: none;
}

/* Cross-browser clear (×) button. Works in Firefox, Chrome, Safari. */
.search-box .search-clear {
  position: absolute;
  right: 3rem;
  top: 50%;
  transform: translateY(-50%);
  display: grid;
  place-items: center;
  width: 1.55rem;
  height: 1.55rem;
  padding: 0;
  border: 0;
  border-radius: 999rem;
  background: rgba(255, 255, 255, 0.12);
  color: #d7d2ec;
  font-size: 1.05rem;
  line-height: 1;
  cursor: pointer;
  opacity: 0.7;
  transition: transform 150ms ease, background-color 150ms ease, opacity 150ms ease, box-shadow 150ms ease;
}

.search-box .search-clear[hidden] { display: none; }

.search-box .search-clear:hover,
.search-box .search-clear:focus-visible {
  outline: 0;
  opacity: 1;
  color: #fff;
  background-color: rgba(92, 155, 255, 0.42);
  box-shadow: 0 0 0 0.18rem rgba(92, 155, 255, 0.25);
  transform: translateY(-50%) scale(1.16);
}

.search-box .search-clear:active {
  transform: translateY(-50%) scale(0.9);
  background-color: rgba(92, 155, 255, 0.55);
}

/* Crisp SVG magnifying glass (the ⌕ glyph rendered inconsistently). Drawn with
   a CSS mask so it can be tinted and animated. */
.search-box span:last-child {
  position: absolute;
  right: 1.2rem;
  top: 50%;
  width: 1.45rem;
  height: 1.45rem;
  transform: translateY(-50%);
  font-size: 0;                       /* hide the original glyph */
  background-color: #8b84a6;
  -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='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='M21 21l-4.6-4.6'/%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='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='M21 21l-4.6-4.6'/%3E%3C/svg%3E") center / contain no-repeat;
  pointer-events: auto;              /* clickable search button */
  cursor: pointer;
  outline: 0;
  transition: background-color 200ms ease, transform 220ms cubic-bezier(0.34, 1.4, 0.5, 1), filter 200ms ease;
}

.search-box:hover span:last-child {
  background-color: #b7b0d0;
}

/* Direct hover / press feedback when the pointer is on the icon itself. */
.search-box span:last-child:hover,
.search-box span:last-child:focus-visible {
  background-color: #5C9BFF;
  transform: translateY(-50%) scale(1.14);
  filter: drop-shadow(0 0 0.35rem rgba(92, 155, 255, 0.55));
}

.search-box span:last-child:active {
  transform: translateY(-50%) scale(0.9);
}

/* Focus: tint blue, lift, glow, and play a one-shot search "pop". */
.search-box:focus-within span:last-child {
  background-color: #5C9BFF;
  transform: translateY(-50%) scale(1.12);
  filter: drop-shadow(0 0 0.35rem rgba(92, 155, 255, 0.55));
  animation: searchGlassPop 520ms cubic-bezier(0.34, 1.4, 0.5, 1);
}

@keyframes searchGlassPop {
  0%   { transform: translateY(-50%) scale(0.78) rotate(-16deg); }
  55%  { transform: translateY(-50%) scale(1.2) rotate(6deg); }
  100% { transform: translateY(-50%) scale(1.12) rotate(0); }
}

main {
  /* Sticky-footer pattern. .app-shell is a 100dvh flex column, so main must
     GROW to absorb the leftover space - otherwise short routes (Favorites,
     empty Search) leave the footer stranded mid-screen with dead space under
     it. The earlier "flex: 0" was an overcorrection: the real cause of the old
     below-the-fold footer was a 100vh floor on .content-band, which is now
     min-height: 0, so growing main can no longer push the footer off-screen. */
  flex: 1 0 auto;
  /* --page-gutter mirrors the side padding so full-bleed children can cancel it
     exactly. Anything bleeding to the screen edge must use this rather than
     repeating a literal, which is how the hero ended up 3.2px wider than the
     viewport on phones and let the whole page slide sideways. */
  --page-gutter: clamp(1.4rem, 3.2vw, 3.4rem);
  padding: 1.2rem var(--page-gutter) 1.2rem;
  position: relative;
  z-index: 1;
}

.bottom-bar {
  --footer-bleed: 1.55rem;
  --footer-pad-y: clamp(1.45rem, 1.85vw, 1.8rem);
  position: relative;
  isolation: isolate;
  z-index: 1;
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  justify-items: center;
  gap: 0.9rem;
  min-height: clamp(7.3rem, 8.8vh, 8.6rem);
  margin: 0 0 calc(-1 * var(--footer-bleed)) -5.1rem;
  padding: var(--footer-pad-y) clamp(1.4rem, 3.2vw, 3.4rem) calc(var(--footer-pad-y) + env(safe-area-inset-bottom)) calc(5.1rem + clamp(1.4rem, 3.2vw, 3.4rem));
  /* Blend into the page instead of reading as a separate lighter band: the
     app-shell gradient bottoms out at #050710, so the footer continues that
     colour rather than introducing its own blue-tinted slab. */
  border-top: 0.08rem solid rgba(255, 255, 255, 0.06);
  color: rgba(228, 238, 255, 0.72);
  background: linear-gradient(180deg, rgba(8, 10, 19, 0.55), #050710 72%, #050710);
  box-shadow: inset 0 0.08rem 0 rgba(255, 255, 255, 0.035);
  overflow: hidden;
  transition: margin 360ms cubic-bezier(0.22, 1, 0.36, 1), padding 360ms cubic-bezier(0.22, 1, 0.36, 1);
}

.bottom-bar::before {
  content: "";
  position: absolute;
  left: 5.1rem;
  right: 0;
  top: 0;
  height: 0.12rem;
  background: linear-gradient(90deg, transparent, rgba(92, 155, 255, 0.18), rgba(92, 155, 255, 0.12), transparent);
  background-size: 180% 100%;
  animation: footer-line-flow 7s ease-in-out infinite;
  pointer-events: none;
}

.bottom-bar::after {
  content: "";
  position: absolute;
  inset: 0 0 calc(-1 * var(--footer-bleed)) 0;
  z-index: 0;
  background:
    linear-gradient(105deg, transparent 0%, transparent 34%, rgba(255, 255, 255, 0.022) 48%, transparent 62%, transparent 100%),
    linear-gradient(180deg, rgba(255, 255, 255, 0.012), transparent 46%),
    linear-gradient(90deg, rgba(0, 210, 255, 0.02), transparent 34%, transparent 66%, rgba(181, 122, 255, 0.018));
  background-size: 230% 100%, 100% 100%, 100% 100%;
  animation: footer-aurora 11s ease-in-out infinite;
  pointer-events: none;
}

.footer-brand {
  position: relative;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  gap: 0.62rem;
  width: 100%;
  text-align: center;
}

.footer-wordmark {
  display: block;
  width: min(22rem, 56vw);
  max-height: clamp(2.6rem, 4.4vw, 3.6rem);
  object-fit: contain;
  filter:
    drop-shadow(0 0.6rem 1.4rem rgba(0, 0, 0, 0.3))
    drop-shadow(0 0 1.1rem rgba(59, 130, 246, 0.22));
  transition: transform 220ms ease, filter 220ms ease;
}

.footer-wordmark:hover {
  transform: translateY(-0.1rem);
  filter:
    drop-shadow(0 0.8rem 1.7rem rgba(0, 0, 0, 0.34))
    drop-shadow(0 0 1.5rem rgba(59, 130, 246, 0.4));
}

.footer-tagline {
  margin: 0;
  color: rgba(196, 214, 245, 0.66);
  font-size: 0.82rem;
  font-weight: 700;
  letter-spacing: 0.01em;
}

.footer-meta {
  display: inline-flex;
  align-items: center;
  gap: 0.7rem;
  flex-wrap: wrap;
  justify-content: center;
}

.footer-app-actions {
  display: inline-flex;
  align-items: center;
  gap: 0.75rem;
  flex-wrap: wrap;
  justify-content: center;
}

.footer-app-copy {
  color: rgba(196, 214, 245, 0.66);
  font-size: 0.82rem;
  font-weight: 700;
}

.footer-app-download {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  min-height: 2.65rem;
  padding: 0.55rem 0.9rem;
  border: 1px solid rgba(141, 229, 210, 0.36);
  border-radius: 0.7rem;
  background: rgba(141, 229, 210, 0.1);
  color: var(--text);
  font-size: 0.78rem;
  font-weight: 850;
  text-decoration: none;
  transition: background 180ms ease, border-color 180ms ease, transform 180ms ease;
}

.footer-app-download:hover,
.footer-app-download:focus-visible {
  border-color: var(--rose);
  background: rgba(141, 229, 210, 0.2);
  transform: translateY(-1px);
}

.footer-dot {
  width: 0.28rem;
  height: 0.28rem;
  border-radius: 999rem;
  background: rgba(92, 155, 255, 0.55);
}

.footer-credit {
  color: rgba(176, 196, 230, 0.56);
  font-size: 0.74rem;
  font-weight: 700;
  letter-spacing: 0.02em;
}

.footer-status {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 1.95rem;
  padding: 0 0.95rem;
  border: 0.08rem solid rgba(59, 130, 246, 0.28);
  border-radius: 999rem;
  color: rgba(214, 228, 255, 0.82);
  background:
    linear-gradient(135deg, rgba(59, 130, 246, 0.1), rgba(37, 99, 235, 0.05)),
    rgba(13, 22, 38, 0.42);
  font-size: 0.74rem;
  font-weight: 900;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  backdrop-filter: blur(10px);
}

.hero {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  align-items: start;
  gap: clamp(1.4rem, 3vw, 3rem);
  min-height: min(82vh, 56.25vw);
  margin: -1.2rem calc(clamp(1.4rem, 3.2vw, 3.4rem) * -1) -1.5rem;
  padding: 1.2rem clamp(1.4rem, 3.2vw, 3.4rem) 3.2rem;
  padding: 0;
  overflow: hidden;
  isolation: isolate;
}

.hero::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 5;
  height: 8rem;
  pointer-events: none;
  background: linear-gradient(180deg, transparent, rgba(8, 10, 19, 0.74) 58%, var(--bg));
}

/* min-height is kept: measured at 1920x1080, 1366x768, 768, 412 and 375 wide it
   never binds, because .carousel-stage inside is always taller, so it is not a
   layout-shift source and there is no measured reason to delete it.
   margin-bottom: -2.4rem was removed. That one IS loading-specific layout - it
   pulled everything below the hero up by 38.4px for as long as the skeleton was
   on screen, then handed it back the moment the real carousel rendered. */
.hero:has(.carousel-stage.is-loading) {
  min-height: clamp(19rem, 35vh, 25rem);
}

.eyebrow {
  margin: 0 0 0.7rem;
  color: var(--cyan);
  font-size: 0.98rem;
  font-weight: 900;
  text-transform: uppercase;
}

.stremio-search {
  display: block;
  max-width: min(54rem, 100%);
  position: relative;
  z-index: 9;
  margin: 2.7rem 0 1.2rem;
}

.stremio-search input {
  min-height: var(--control-h-lg);
  border-radius: var(--radius-lg);
  background: rgba(7, 9, 19, 0.62);
  backdrop-filter: blur(18px);
  box-shadow: inset 0 0 0 0.08rem rgba(255, 255, 255, 0.07), 0 1rem 2.4rem rgba(0, 0, 0, 0.24);
}

body:not([data-route="home"]) .stremio-search {
  display: none;
}

.library-search {
  width: 100%;
  max-width: min(52rem, 100%);
  margin: 1rem 0;
}

.library-search input {
  min-height: 2.85rem;
  border-radius: 9rem;
  border: 1px solid rgba(255, 255, 255, 0.08);
  background: rgba(255, 255, 255, 0.03);
  box-shadow: none;
  font-size: 0.82rem;
  transition: border-color 0.15s ease, background 0.15s ease, box-shadow 0.15s ease;
}

.library-search input:focus {
  background: rgba(255, 255, 255, 0.06);
  border-color: rgba(138, 85, 255, 0.6);
  box-shadow: 0 0 0.8rem rgba(138, 85, 255, 0.18);
}

.library-filter-toggle {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.35rem 0.95rem;
  border-radius: 9rem;
  border: 1px solid rgba(255, 255, 255, 0.08);
  background: rgba(255, 255, 255, 0.03);
  color: rgba(229, 233, 255, 0.9);
  font-size: 0.78rem;
  font-weight: 900;
  cursor: pointer;
  margin-left: 1.2rem;
  transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}

.library-filter-toggle:is(:hover, :focus-visible, .is-tv-focused) {
  color: #fff;
  background: rgba(255, 255, 255, 0.08);
  border-color: rgba(255, 255, 255, 0.16);
  outline: none;
}

.library-filter-toggle.is-active {
  background: rgba(138, 85, 255, 0.18);
  border-color: rgba(138, 85, 255, 0.5);
  color: #fff;
}

@media (min-width: 761px) {
  #library .library-filter-panel {
    margin-left: 3.7rem !important;
    margin-right: 3.7rem !important;
    width: auto !important;
    max-width: none !important;
  }
  .library-search {
    margin-left: 3.7rem !important;
    margin-right: 3.7rem !important;
    width: auto !important;
    max-width: none !important;
  }
}

.source-status {
  position: absolute;
  top: 1.15rem;
  right: clamp(4.5rem, 7vw, 6.6rem);
  z-index: 6;
  display: inline-flex;
  width: auto;
  margin: 0;
  padding: 0.48rem 0.74rem;
  border: 0.08rem solid rgba(255, 255, 255, 0.12);
  border-radius: 999rem;
  color: rgba(246, 243, 255, 0.82);
  background: rgba(17, 16, 38, 0.46);
  font-size: 0.78rem;
  font-weight: 850;
  backdrop-filter: blur(14px);
}

.primary-action,
.secondary-action,
.play-action {
  min-height: var(--control-h-md);
  padding: 0 1.35rem;
  border-radius: var(--radius-md);
  color: #131127;
  background: var(--cyan);
  font-weight: 900;
  cursor: pointer;
}

.secondary-action {
  color: var(--text);
  background: rgba(255, 255, 255, 0.12);
}

.play-action {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.7rem;
  width: fit-content;
  min-width: 9.2rem;
  min-height: 3.35rem;
  overflow: hidden;
  border: 0.08rem solid rgba(255, 255, 255, 0.22);
  border-radius: 999rem;
  color: #f6f3ff;
  background:
    linear-gradient(135deg, rgba(255, 255, 255, 0.13), rgba(64, 223, 194, 0.11)),
    rgba(17, 16, 38, 0.38);
  box-shadow: inset 0 0 0 0.08rem rgba(255, 255, 255, 0.07), 0 1rem 2rem rgba(0, 0, 0, 0.24);
  backdrop-filter: blur(16px);
}

.play-action::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(90deg, rgba(138, 92, 255, 0.34), rgba(0, 210, 255, 0.32)),
    radial-gradient(circle at 24% 50%, rgba(255, 255, 255, 0.16), transparent 42%);
  opacity: 0;
  transform: scaleX(0.18);
  transform-origin: left;
  transition: opacity 180ms ease, transform 220ms ease;
}

.play-action:is(:hover, :focus-visible, .is-tv-focused) {
  transform: translateY(-0.06rem);
  border-color: rgba(0, 210, 255, 0.42);
  background:
    linear-gradient(135deg, rgba(138, 92, 255, 0.18), rgba(0, 210, 255, 0.13)),
    rgba(17, 16, 38, 0.58);
  box-shadow:
    inset 0 0 0 0.08rem rgba(255, 255, 255, 0.1),
    0 1rem 2rem rgba(0, 0, 0, 0.3),
    0 0 0 0.32rem rgba(0, 210, 255, 0.08);
}

.play-action:is(:hover, :focus-visible, .is-tv-focused)::after {
  opacity: 1;
  transform: scaleX(1);
}

.play-action:is(:hover, :focus-visible, .is-tv-focused) .play-icon {
  background: linear-gradient(135deg, var(--blue), var(--cyan));
  box-shadow: 0 0 1.1rem rgba(0, 210, 255, 0.36), 0 0 0 0.25rem rgba(255, 255, 255, 0.06);
}

.play-icon {
  position: relative;
  z-index: 1;
  display: inline-grid;
  place-items: center;
  width: 2rem;
  height: 2rem;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--cyan), var(--blue));
  box-shadow: 0 0 1rem rgba(64, 223, 194, 0.34);
}

.play-icon::before {
  content: "";
  width: 0;
  height: 0;
  margin-left: 0.16rem;
  border-top: 0.42rem solid transparent;
  border-bottom: 0.42rem solid transparent;
  border-left: 0.68rem solid #ffffff;
}

.play-action span:last-child {
  position: relative;
  z-index: 1;
}

.primary-action,
.secondary-action,
.play-action {
  transition: transform 180ms ease, box-shadow 180ms ease, background 180ms ease;
}

.primary-action:focus,
.secondary-action:focus,
.play-action:focus,
.episode-play-inline:focus {
  outline: 0;
}

.primary-action:is(:hover, :focus-visible, .is-tv-focused),
.secondary-action:is(:hover, :focus-visible, .is-tv-focused) {
  transform: translateY(-0.04rem);
  box-shadow: 0 0.5rem 1.1rem rgba(0, 0, 0, 0.22), inset 0 0 0 0.08rem rgba(255, 255, 255, 0.11);
}

.primary-action:is(:focus-visible, .is-tv-focused),
.secondary-action:is(:focus-visible, .is-tv-focused),
.episode-play-inline:is(:focus-visible, .is-tv-focused) {
  box-shadow:
    inset 0 0 0 0.08rem rgba(255, 255, 255, 0.14),
    0 0 0 0.28rem rgba(0, 210, 255, 0.09),
    0 0.5rem 1.1rem rgba(0, 0, 0, 0.22);
}

.thumb-art::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  background:
    radial-gradient(circle at 29% 31%, rgba(255, 255, 255, 0.82) 0 6%, transparent 6.4%),
    radial-gradient(circle at 37% 31%, rgba(255, 255, 255, 0.82) 0 6%, transparent 6.4%),
    radial-gradient(circle at 32% 45%, rgba(26, 23, 52, 0.9) 0 15%, transparent 15.4%),
    linear-gradient(135deg, var(--thumb-a), var(--thumb-b));
}

.thumb-art::after {
  content: "";
  position: absolute;
  inset: auto 0 0;
  z-index: 2;
  height: 46%;
  background: linear-gradient(0deg, rgba(0, 0, 0, 0.52), transparent);
}

.content-band {
  /* No 100vh floor: it pushed the footer a full screen below short routes. */
  min-height: 0;
  margin-top: 0;
  padding: clamp(1rem, 2vw, 1.75rem) 0 2.4rem;
  scroll-margin-top: 0;
  animation: rise-in 520ms ease both;
}

body[data-route="home"] #continueWatching,
body[data-route="home"] #continueWatchingAdult,
body[data-route="home"] #latest {
  min-height: auto;
  padding-top: 0;
  position: relative;
  z-index: 8;
}

body:not([data-route="home"]) .content-band {
  padding-top: 0;
}

.content-band:nth-of-type(2) {
  animation-delay: 90ms;
}

.content-band:nth-of-type(3) {
  animation-delay: 140ms;
}

.content-band.is-hidden,
[data-section].is-hidden {
  display: none;
}

/* ── Continue-watching height stability (home only) ───────────────────────────
   Reserve a stable min-height ONLY while the section is actually shown (not
   .is-hidden). A hidden/empty section stays display:none so it never leaves a
   blank gap — important because the adult rail is empty for most users and the
   rails render empty until the catalog resolves the resume positions. */
:root[data-has-history] body[data-route="home"] #continueWatching:not(.is-hidden),
:root[data-has-history] body[data-route="home"] #continueWatchingAdult:not(.is-hidden) {
  min-height: 17rem;
}

.section-heading {
  display: flex;
  align-items: center;
  gap: 0.78rem;
  min-height: 3.25rem;
  margin-bottom: 1.05rem;
}

.section-heading h2 {
  margin: 0;
  font-size: clamp(1.55rem, 2vw, 2.2rem);
  letter-spacing: 0;
}

.hot-dot,
.library-dot,
.calendar-dot,
.favorite-dot,
.source-dot {
  --dot-color: var(--cyan);
  position: relative;
  flex: 0 0 auto;
  width: 1.1rem;
  height: 1.1rem;
  border-radius: 50%;
  background: var(--dot-color);
  box-shadow:
    0 0 0 0.42rem color-mix(in srgb, var(--dot-color) 16%, transparent),
    0 0 1.2rem color-mix(in srgb, var(--dot-color) 28%, transparent);
  animation: section-dot-glow 2.6s ease-in-out infinite;
}

.hot-dot::before,
.library-dot::before,
.calendar-dot::before,
.anipub-dot::before,
.favorite-dot::before,
.source-dot::before,
.settings-dot::before {
  content: "";
  position: absolute;
  inset: -0.28rem;
  border-radius: 50%;
  border: 0.08rem solid color-mix(in srgb, var(--dot-color) 36%, transparent);
  opacity: 0.72;
}

body:not([data-route="home"]) .section-heading h2 {
  font-size: clamp(1.48rem, 1.9vw, 2rem);
}

.library-dot {
  --dot-color: var(--route-library);
}

.hot-dot {
  --dot-color: var(--route-home);
}

.calendar-dot {
  --dot-color: var(--route-schedule);
}

.anipub-dot {
  --dot-color: var(--route-anipub);
}

.favorite-dot {
  --dot-color: var(--route-favorites);
}

.source-dot {
  --dot-color: var(--route-sources);
}

.settings-dot {
  --dot-color: var(--route-settings);
}

.addon-sections {
  display: grid;
  gap: clamp(1.6rem, 3vw, 2.8rem);
  margin-top: clamp(1rem, 2vw, 1.8rem);
}

.addon-sections[hidden] {
  display: none;
}

.addon-band {
  min-height: auto;
  padding: 0 0 clamp(1rem, 2vw, 1.8rem);
  /* Below-the-fold rails: let the browser skip layout/paint for the ones still
     off-screen so the initial render only paints what's visible (Speed Index
     win). `auto` remembers each rail's real rendered height, so scrolling to it
     reserves the right space and CLS stays put. */
  content-visibility: auto;
  contain-intrinsic-size: auto 34rem;
}

.addon-more {
  min-height: var(--control-h-sm);
  margin-top: 0.9rem;
  padding: 0 1rem;
  border: 0.08rem solid rgba(255, 255, 255, 0.12);
  border-radius: 999rem;
  color: #ffffff;
  background: rgba(255, 255, 255, 0.08);
  font-weight: 950;
  cursor: pointer;
  transition: transform 180ms ease, border-color 180ms ease, background 180ms ease, box-shadow 180ms ease;
}

.addon-more:is(:hover, :focus-visible, .is-tv-focused) {
  transform: translateY(-0.04rem);
  border-color: rgba(0, 210, 255, 0.36);
  background: rgba(0, 210, 255, 0.12);
  outline: 0;
  box-shadow: 0 0 0 0.16rem rgba(0, 210, 255, 0.08), 0 0.7rem 1.4rem rgba(0, 0, 0, 0.2);
}

.addon-dot {
  --dot-color: var(--blue);
  position: relative;
  flex: 0 0 auto;
  width: 1.1rem;
  height: 1.1rem;
  border-radius: 50%;
  background: var(--dot-color);
  box-shadow:
    0 0 0 0.42rem color-mix(in srgb, var(--dot-color) 16%, transparent),
    0 0 1.2rem color-mix(in srgb, var(--dot-color) 28%, transparent);
  animation: section-dot-glow 2.6s ease-in-out infinite;
}

.addon-dot::before {
  content: "";
  position: absolute;
  inset: -0.28rem;
  border: 0.08rem solid color-mix(in srgb, var(--dot-color) 36%, transparent);
  border-radius: 50%;
  opacity: 0.72;
}

.section-heading small {
  align-self: center;
  padding: 0.35rem 0.58rem;
  border-radius: 999rem;
  color: rgba(246, 243, 255, 0.68);
  background: rgba(255, 255, 255, 0.07);
  font-size: 0.72rem;
  font-weight: 900;
}

.rail-shell {
  position: relative;
  display: grid;
  grid-template-columns: 3rem minmax(0, 1fr) 3rem;
  align-items: center;
  gap: 0.7rem;
  min-width: 0;
  padding: 0;
}

.poster-grid {
  --rail-gap: clamp(0.65rem, 1vw, 0.95rem);
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: calc((100% - (6 * var(--rail-gap))) / 7);
  grid-template-rows: repeat(2, auto);
  grid-template-columns: none;
  gap: var(--rail-gap);
  min-width: 0;
  overflow-x: auto;
  overflow-y: visible;
  padding: 0.25rem 0.35rem 1rem;
  scroll-snap-type: x mandatory;
  scroll-padding-inline: 0;
  scrollbar-width: none;
}

.poster-grid.is-skeleton-loading {
  grid-auto-flow: column;
  grid-template-rows: repeat(2, auto);
  grid-auto-columns: calc((100% - (6 * var(--rail-gap))) / 7);
  overflow: hidden;
  padding-bottom: 1.25rem;
}

.poster-grid.is-skeleton-loading .show-card > span:not(.thumb-art) {
  min-height: 2.5rem;
}

.rail-arrow {
  position: relative;
  align-self: center;
  justify-self: center;
  z-index: 6;
  display: grid;
  place-items: center;
  width: 2.45rem;
  height: 5.2rem;
  margin-top: 0;
  border: 0.08rem solid rgba(255, 255, 255, 0.12);
  border-radius: 999rem;
  color: #ffffff;
  background: rgba(8, 10, 19, 0.46);
  font-size: 2rem;
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
  backdrop-filter: blur(14px);
  transition: transform 180ms ease, background 180ms ease, border-color 180ms ease, opacity 180ms ease;
}

.rail-arrow-left {
  grid-column: 1;
}

.rail-arrow-right {
  grid-column: 3;
}

.rail-arrow:is(:hover, :focus-visible, .is-tv-focused) {
  transform: scale(1.04);
  border-color: rgba(0, 210, 255, 0.42);
  background: rgba(0, 210, 255, 0.18);
}

.rail-shell:has(.poster-grid:empty) .rail-arrow {
  display: none;
}

/* Arrows for a rail whose content already fits. Driven by syncRailOverflow() in
   client.js, which sets .rail-static; the default stays visible so a JS failure
   degrades to the previous behaviour rather than removing the controls.
   visibility (not display) keeps the grid columns stable, so hiding an arrow
   never reflows the rail, and it still drops out of the focus order for D-pad. */
.rail-shell.rail-static .rail-arrow {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}

.poster-grid:empty {
  min-height: 13rem;
}

.poster-grid::-webkit-scrollbar {
  display: none;
}

.content-band {
  position: relative;
}

.show-card {
  position: relative;
  display: grid;
  gap: 0.7rem;
  align-content: start;
  min-width: 0;
  max-width: 100%;
  color: var(--text);
  text-decoration: none;
  background: transparent;
  text-align: left;
  cursor: pointer;
  border-radius: var(--radius-md);
  outline: 0;
  animation: card-rise 480ms ease both;
  animation-delay: calc((var(--card-index, 0) % 12) * 35ms);
  scroll-snap-align: start;
  transition: transform 180ms ease;
}

.skeleton-card {
  pointer-events: none;
}

.skeleton-card .thumb-art,
.carousel-poster-skeleton,
.skeleton-card .show-title,
.skeleton-card .show-meta {
  position: relative;
  overflow: hidden;
  background: rgba(255, 255, 255, 0.07);
}

/* Composited shimmer: sweep a gradient overlay with transform (GPU) instead of
   animating background-position, which forced a full repaint every frame on
   every skeleton card during catalog load. */
.skeleton-card .thumb-art::after,
.carousel-poster-skeleton::after,
.skeleton-card .show-title::after,
.skeleton-card .show-meta::after {
  content: "";
  position: absolute;
  inset: 0;
  height: auto;
  background: linear-gradient(100deg, transparent 25%, rgba(255, 255, 255, 0.14) 50%, transparent 75%);
  transform: translateX(-100%);
  animation: skeleton-sheen 1150ms ease-in-out infinite;
  will-change: transform;
}

.skeleton-card .show-title,
.skeleton-card .show-meta {
  display: block;
  border-radius: 999rem;
}

.skeleton-card .show-title {
  width: 82%;
  height: 1.05rem;
}

.skeleton-card .show-meta {
  width: 58%;
  height: 0.78rem;
  margin-top: 0.5rem;
}

.show-card::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -0.18rem;
  height: 0.12rem;
  border-radius: 999rem;
  background: linear-gradient(90deg, var(--cyan), var(--rose));
  opacity: 0;
  transform: scaleX(0.25);
  transform-origin: left;
  transition: opacity 180ms ease, transform 220ms ease;
}

.show-card > span:not(.thumb-art) {
  display: block;
  width: 100%;
  max-width: 100%;
  min-width: 0;
  overflow: visible;
}

.thumb-art {
  position: relative;
  display: grid;
  place-items: center;
  aspect-ratio: 2 / 3;
  overflow: hidden;
  border: 0.08rem solid rgba(255, 255, 255, 0.1);
  border-radius: var(--radius-md);
  background: linear-gradient(135deg, var(--thumb-a), var(--thumb-b));
  box-shadow: 0 0.75rem 1.35rem rgba(0, 0, 0, 0.22);
  transition: transform 220ms ease, border-color 220ms ease, box-shadow 220ms ease, filter 220ms ease;
}

.thumb-art::before {
  transition: opacity 220ms ease, transform 320ms ease;
}

/* ── Image loading: brand-gradient sheen sweep + fade-in ──────────────────────
   Posters (.thumb-art) and episode thumbnails (.ep-thumb) FADE IN when their
   image loads instead of popping; while loading, a soft purple→cyan sheen sweeps
   the placeholder. The sweep is a GPU transform (same `skeleton-sheen` keyframe
   used during catalog load) so it adds no repaint/TBT cost, and it stops the
   instant the image is ready. `img-ready` is added by a delegated load listener
   in client.js; prefers-reduced-motion users get the static placeholder (the
   global `body.reduce-motion` rule already disables the animation). */
.art-sheen {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: linear-gradient(100deg,
    transparent 28%,
    rgba(138, 92, 255, 0.16) 46%,
    rgba(0, 210, 255, 0.22) 54%,
    transparent 72%);
  transform: translateX(-100%);
  animation: skeleton-sheen 1300ms ease-in-out infinite;
  will-change: transform;
  transition: opacity 0.3s ease;
}
.thumb-art.img-ready .art-sheen,
.ep-thumb.img-ready .art-sheen {
  opacity: 0;
  animation: none;
}
.thumb-poster,
.ep-thumb-img {
  opacity: 0;
  transition: opacity 0.45s ease;
}
.thumb-poster.img-ready,
.ep-thumb-img.img-ready {
  opacity: 1;
}

.thumb-art::after {
  transition: opacity 220ms ease;
}

/* Branded placeholder when poster image fails to load — shows a subtle "Z"
   centered over the card's gradient background (defined on .thumb-art). */
.thumb-fallback-mark {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: grid;
  place-items: center;
  pointer-events: none;
}
.thumb-fallback-mark::before {
  content: "Z";
  font-family: Inter, ui-sans-serif, system-ui, sans-serif;
  font-size: 2.4rem;
  font-weight: 900;
  letter-spacing: -0.04em;
  line-height: 1;
  color: rgba(255, 255, 255, 0.12);
  text-shadow: 0 0.15rem 0.8rem rgba(0, 210, 255, 0.08);
}

.thumb-poster {
  position: relative;
  z-index: 2;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center top;
  box-shadow: inset 0 -4rem 4rem rgba(0, 0, 0, 0.18);
  transition: transform 320ms ease, filter 320ms ease;
}

.thumb-art.has-contained-poster::before {
  content: "";
  position: absolute;
  inset: -1rem;
  z-index: 0;
  background-image: linear-gradient(rgba(7, 9, 19, 0.48), rgba(7, 9, 19, 0.72)), var(--contained-poster);
  background-position: center;
  background-size: cover;
  filter: blur(0.75rem) saturate(0.85);
  transform: scale(1.08);
}

.thumb-poster.is-contained-poster {
  object-fit: contain;
  padding: 0.35rem;
}

.thumb-poster + .episode-pill {
  z-index: 3;
}

.thumb-art .episode-pill {
  position: absolute;
  right: 0.65rem;
  bottom: 0.65rem;
  z-index: 2;
  min-width: 3.1rem;
  padding: 0.26rem 0.52rem;
  border-radius: 0.35rem;
  background: rgba(17, 16, 38, 0.78);
  color: #ffffff;
  font-size: 0.8rem;
  font-weight: 900;
  text-align: center;
}

.show-title {
  /* Long romaji titles used to wrap to 4-5 lines, making one card far taller
     than its neighbours and breaking rail alignment. Clamp to two lines and
     reserve that height so every card in a row lines up. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  width: 100%;
  max-width: 100%;
  min-width: 0;
  min-height: calc(2 * 1.12em);
  margin: 0;
  color: #f9f7ff;
  font-size: clamp(0.95rem, 0.9vw, 1.08rem);
  font-weight: 900;
  line-height: 1.12;
  text-shadow: none;
  overflow-wrap: anywhere;
  word-break: normal;
  hyphens: auto;
  transition: color 180ms ease, transform 180ms ease, text-shadow 180ms ease;
}

.show-meta {
  display: block;
  width: 100%;
  max-width: 100%;
  min-width: 0;
  align-items: center;
  color: var(--muted);
  font-size: 0.78rem;
  font-weight: 850;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.filters {
  display: flex;
  flex-wrap: wrap;
  gap: 0.55rem;
  margin: -0.15rem 0 1.2rem;
}

.library-search,
.anipub-search {
  margin-bottom: clamp(1.05rem, 1.6vw, 1.55rem);
}

#anipub .filters,
#library .filters {
  margin-top: 0;
  margin-bottom: clamp(1.65rem, 2.1vw, 2.25rem);
}

#anipub .rail-shell,
#library .rail-shell {
  margin-top: 0.25rem;
}

.chip {
  width: auto;
  min-width: 5.6rem;
  min-height: 2.35rem;
  padding: 0 0.9rem;
  border-radius: 999rem;
  background: rgba(255, 255, 255, 0.075);
  font-size: 0.86rem;
  box-shadow: inset 0 0 0 0.08rem rgba(255, 255, 255, 0.06);
  transition: transform 180ms ease, background 180ms ease, color 180ms ease, box-shadow 180ms ease;
}

.chip.is-selected {
  color: #131127;
  background: var(--gold);
}

.chip:is(:hover, :focus-visible, .is-tv-focused) {
  transform: translateY(-0.04rem);
  color: #ffffff;
  background: rgba(0, 210, 255, 0.18);
  box-shadow: inset 0 0 0 0.08rem rgba(0, 210, 255, 0.42), 0 0.45rem 1rem rgba(0, 0, 0, 0.18);
}

.schedule-list {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 0.85rem;
  align-items: start;
  overflow: visible;
}

.schedule-day-column {
  min-width: 0;
  border-top: 0.18rem solid rgba(138, 92, 255, 0.52);
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.055), transparent 16rem);
}

.schedule-day-column h3 {
  margin: 0;
  padding: 0.82rem 0.2rem 0.7rem;
  color: #dcd6ef;
  font-size: 0.96rem;
  font-weight: 900;
  text-align: center;
}

/* ── Today highlight ─────────────────────────────────────────────────────── */
.schedule-day-column.is-today {
  border-top-color: #5C9BFF;
  background: linear-gradient(180deg, rgba(92, 155, 255, 0.22), transparent 18rem);
  box-shadow: inset 0 0.18rem 0 0 #5C9BFF;
  animation: scheduleTodayPulse 2.4s ease-in-out infinite;
}

.schedule-day-column.is-today h3 {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  color: #ffffff;
}

.schedule-today-badge {
  padding: 0.1rem 0.5rem;
  border-radius: 999rem;
  background: linear-gradient(135deg, #5C9BFF, #2563EB);
  color: #fff;
  font-size: 0.62rem;
  font-weight: 900;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  box-shadow: 0 0 0 rgba(92, 155, 255, 0.55);
  animation: scheduleTodayBadge 2.4s ease-in-out infinite;
}

@keyframes scheduleTodayPulse {
  0%, 100% { box-shadow: inset 0 0.18rem 0 0 #5C9BFF, 0 0 0.6rem rgba(92, 155, 255, 0.12); }
  50%      { box-shadow: inset 0 0.18rem 0 0 #7DB0FF, 0 0 1.4rem rgba(92, 155, 255, 0.42); }
}

@keyframes scheduleTodayBadge {
  0%, 100% { box-shadow: 0 0 0 rgba(92, 155, 255, 0.0); transform: scale(1); }
  50%      { box-shadow: 0 0 0.7rem rgba(92, 155, 255, 0.6); transform: scale(1.06); }
}

.schedule-day-rail {
  display: grid;
  gap: 0.8rem;
}

.schedule-empty {
  font-size: 0.78rem;
  color: rgba(246, 243, 255, 0.3);
  padding: 0.4rem 0;
  margin: 0;
}

.schedule-item {
  display: grid;
  gap: 0.52rem;
  min-width: 0;
  padding: 0;
  color: var(--text);
  text-decoration: none;
  background: transparent;
  text-align: left;
  cursor: pointer;
  transition: transform 180ms ease;
}

.schedule-item:is(:hover, :focus-visible, .is-tv-focused) {
  transform: translateY(-0.08rem);
}

.schedule-thumb {
  position: relative;
  display: block;
  aspect-ratio: 16 / 7.5;
  overflow: hidden;
  border-radius: var(--radius-sm);
  background: linear-gradient(135deg, rgba(138, 85, 255, 0.28), rgba(0, 210, 255, 0.16)), rgba(255, 255, 255, 0.07);
  box-shadow: 0 0.85rem 1.4rem rgba(0, 0, 0, 0.22);
}

.schedule-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 220ms ease, filter 220ms ease;
}

.schedule-thumb::after {
  content: "";
  position: absolute;
  inset: 42% 0 0;
  background: linear-gradient(0deg, rgba(0, 0, 0, 0.62), transparent);
}

.schedule-thumb span {
  position: absolute;
  right: 0.45rem;
  bottom: 0.38rem;
  z-index: 1;
  padding: 0.18rem 0.42rem;
  border-radius: 999rem;
  background: rgba(0, 0, 0, 0.52);
  color: #ffffff;
  font-size: 0.7rem;
  font-weight: 900;
}

.schedule-copy {
  display: grid;
  gap: 0.2rem;
}

.schedule-item:is(:hover, :focus-visible, .is-tv-focused) .schedule-thumb img {
  transform: scale(1.045);
  filter: saturate(1.08) brightness(1.05);
}

.schedule-title {
  display: -webkit-box;
  min-height: 2.4em;
  overflow: hidden;
  color: #f9f7ff;
  font-weight: 900;
  line-height: 1.2;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  transition: color 180ms ease, text-shadow 180ms ease;
}

.schedule-item:is(:hover, :focus-visible, .is-tv-focused) .schedule-title {
  color: #ffffff;
  text-shadow: 0 0 1rem rgba(0, 210, 255, 0.28);
}

.empty-state {
  margin: 0;
  color: var(--muted);
  font-size: 1.1rem;
}

.source-list {
  display: grid;
  grid-template-columns: repeat(2, minmax(18rem, 1fr));
  gap: 1rem;
  margin-top: 1rem;
}

.source-card {
  position: relative;
  overflow: hidden;
  display: grid;
  gap: 0.75rem;
  padding: 1rem;
  border: 0.08rem solid var(--line);
  border-radius: var(--radius-md);
  background:
    linear-gradient(135deg, rgba(255, 255, 255, 0.075), rgba(255, 255, 255, 0.035));
  transition: transform 200ms ease, border-color 200ms ease, background 200ms ease, box-shadow 200ms ease;
}

.source-card::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(120deg, rgba(138, 92, 255, 0.18), transparent 42%, rgba(0, 210, 255, 0.12));
  opacity: 0;
  transition: opacity 200ms ease;
}

.source-card:is(:hover, :focus-within, .is-enabled) {
  transform: translateY(-0.06rem);
  border-color: rgba(255, 255, 255, 0.22);
  box-shadow: 0 1rem 2rem rgba(0, 0, 0, 0.22);
}

.source-card:is(:hover, :focus-within, .is-enabled)::before {
  opacity: 1;
}

.source-card:active,
.season-card:active,
.episode-button:active,
.schedule-item:active,
.rail-arrow:active,
.primary-action:active,
.secondary-action:active,
.play-action:active {
  transform: scale(0.985);
}

.source-card-feature {
  min-height: 10.4rem;
  border-color: rgba(64, 223, 194, 0.26);
  background:
    radial-gradient(circle at 12% 0%, rgba(138, 92, 255, 0.22), transparent 12rem),
    linear-gradient(135deg, rgba(64, 223, 194, 0.12), rgba(255, 255, 255, 0.045));
}

.source-card > * {
  position: relative;
  z-index: 1;
}

.source-card > div:first-child {
  display: flex;
  align-items: start;
  justify-content: space-between;
  gap: 1rem;
}

.source-card strong,
.source-card span,
.source-card code {
  display: block;
}

.source-card strong {
  font-size: 1.1rem;
}

.source-card div:first-child span {
  flex: 0 0 auto;
  max-width: 52%;
  padding: 0.35rem 0.55rem;
  border: 0.08rem solid rgba(255, 255, 255, 0.12);
  border-radius: 999rem;
  background: rgba(0, 0, 0, 0.22);
  color: #ffffff;
  font-size: 0.72rem;
  font-weight: 900;
  line-height: 1.1;
  text-align: right;
}

.source-card span,
.source-card p,
.source-card code {
  color: var(--muted);
}

.source-card p {
  margin: 0;
  min-height: 3.7rem;
  line-height: 1.35;
}

.source-card code {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  padding: 0.65rem 0.72rem;
  border: 0.08rem solid rgba(255, 255, 255, 0.1);
  border-radius: var(--radius-sm);
  background: rgba(0, 0, 0, 0.22);
  font-size: 0.78rem;
}

.source-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.65rem;
}

.source-key-field {
  display: grid;
  gap: 0.45rem;
  margin-top: 0.25rem;
}

.source-key-field span {
  color: var(--muted);
  font-size: 0.76rem;
  font-weight: 850;
}

.source-key-field input {
  min-height: 2.65rem;
  padding: 0 0.95rem;
  border: 0.08rem solid rgba(0, 210, 255, 0.16);
  border-radius: 0.85rem;
  color: var(--text);
  background: rgba(8, 10, 19, 0.62);
  font: inherit;
  font-size: 0.86rem;
  font-weight: 800;
}

.source-key-field input:is(:hover, :focus-visible, .is-tv-focused) {
  outline: 0;
  border-color: rgba(0, 210, 255, 0.34);
  background: rgba(0, 210, 255, 0.08);
  box-shadow: 0 0 0 0.14rem rgba(0, 210, 255, 0.08);
}

.source-actions .secondary-action {
  min-height: var(--control-h-sm);
  padding: 0 0.9rem;
}

.source-actions .source-remove-action {
  color: #ffd7ee;
  background: rgba(185, 118, 255, 0.12);
}

.source-actions .source-remove-action:is(:hover, :focus-visible, .is-tv-focused) {
  color: #ffffff;
  background: rgba(185, 118, 255, 0.2);
  box-shadow: inset 0 0 0 0.08rem rgba(185, 118, 255, 0.24), 0 0.55rem 1.1rem rgba(0, 0, 0, 0.22);
}

.settings-grid {
  display: grid;
  grid-template-columns: minmax(18rem, 0.92fr) minmax(24rem, 1.4fr);
  gap: 0.9rem;
  max-width: 76rem;
  margin-top: 1.2rem;
  padding: 0.8rem;
  border: 0.08rem solid rgba(255, 255, 255, 0.08);
  border-radius: 1.35rem;
  background:
    radial-gradient(circle at 10% 0%, rgba(0, 210, 255, 0.09), transparent 18rem),
    linear-gradient(135deg, rgba(255, 255, 255, 0.045), rgba(255, 255, 255, 0.02));
  box-shadow: inset 0 0 0 0.08rem rgba(255, 255, 255, 0.035), var(--shadow);
}

.settings-card {
  display: grid;
  align-content: start;
  gap: 0.85rem;
  min-height: auto;
  padding: 1.05rem;
  border: 0.08rem solid rgba(255, 255, 255, 0.09);
  border-radius: 1rem;
  background:
    linear-gradient(135deg, rgba(17, 20, 34, 0.86), rgba(18, 19, 34, 0.58)),
    rgba(8, 10, 19, 0.38);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.05);
}

.settings-card-wide {
  grid-column: 1 / -1;
}

.settings-card-legal {
  background:
    radial-gradient(circle at 90% 0%, rgba(242, 187, 70, 0.12), transparent 12rem),
    linear-gradient(135deg, rgba(17, 20, 34, 0.86), rgba(18, 19, 34, 0.58)),
    rgba(8, 10, 19, 0.38);
}

.settings-link {
  min-height: 2.75rem;
  text-decoration: none;
}

.settings-card-head {
  display: grid;
  grid-template-columns: 2.6rem minmax(0, 1fr);
  align-items: center;
  gap: 0.8rem;
  padding-bottom: 0.2rem;
}

.settings-card strong {
  color: #ffffff;
  font-size: 1.04rem;
}

.settings-card span {
  color: var(--muted);
  font-weight: 800;
}

.settings-icon {
  display: grid;
  place-items: center;
  width: 2.6rem;
  height: 2.6rem;
  border: 0.08rem solid rgba(0, 210, 255, 0.18);
  border-radius: 0.8rem;
  color: #06121d;
  background: linear-gradient(135deg, var(--cyan), var(--blue));
  box-shadow: 0 0.8rem 1.4rem rgba(0, 210, 255, 0.12);
  font-size: 1.05rem;
  font-weight: 950;
}

.settings-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.65rem;
}

.settings-segment {
  display: flex;
  flex-wrap: nowrap;            /* keep options on ONE row — never stack/overlap */
  gap: 0.25rem;
  width: 100%;
  justify-self: end;
  padding: 0.3rem;
  border: 0.08rem solid rgba(255, 255, 255, 0.08);
  border-radius: 999rem;
  background: rgba(2, 4, 12, 0.38);
}

.settings-choice {
  flex: 1 1 0;                  /* equal widths, allow shrink so they fit inline */
  min-width: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 2.5rem;
  padding: 0 0.85rem;
  border: 0.08rem solid transparent;
  border-radius: 999rem;
  color: rgba(246, 243, 255, 0.76);
  background: transparent;
  font-weight: 800;
  font-size: 0.92rem;
  line-height: 1;
  white-space: nowrap;
  text-transform: capitalize;
  cursor: pointer;
  transition: color 160ms ease, background 160ms ease, box-shadow 160ms ease;
}

.settings-choice.is-selected,
.settings-choice:is(:hover, :focus-visible, .is-tv-focused) {
  outline: 0;
  color: #ffffff;
  background: linear-gradient(135deg, #5C9BFF, #2563EB);
  box-shadow: 0 0.3rem 0.8rem rgba(37, 99, 235, 0.28);  /* flat within the track */
}

.settings-field {
  display: grid;
  gap: 0.5rem;
}

.settings-field .language-select {
  width: min(100%, 24rem);
  max-width: none;
  min-height: 3.05rem;
  padding: 0 2.4rem 0 1rem;
  border: 0.08rem solid rgba(59, 130, 246, 0.28);
  border-radius: 0.95rem;
  color: var(--text);
  background:
    linear-gradient(135deg, rgba(59, 130, 246, 0.12), rgba(37, 99, 235, 0.06)),
    rgba(9, 16, 28, 0.7);
  box-shadow: inset 0 0 0 0.08rem rgba(255, 255, 255, 0.04);
  transition: border-color 200ms ease, box-shadow 200ms ease;
}

.settings-field .language-select:focus {
  outline: 0;
  border-color: rgba(59, 130, 246, 0.6);
  box-shadow: 0 0 0 0.16rem rgba(59, 130, 246, 0.16);
}

.language-select option {
  color: #f6f3ff;
  background: #111426;
}

.settings-toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.9rem;
  min-height: 3.2rem;
  padding: 0 0.42rem 0 1rem;
  border: 0.08rem solid rgba(255, 255, 255, 0.1);
  border-radius: 0.95rem;
  color: var(--text);
  background: rgba(255, 255, 255, 0.055);
  font: inherit;
  font-weight: 900;
  cursor: pointer;
}

.settings-toggle b {
  display: inline-grid;
  min-width: 4.4rem;
  min-height: 2.25rem;
  place-items: center;
  padding: 0 0.75rem;
  border-radius: 999rem;
  color: rgba(246, 243, 255, 0.72);
  background: rgba(255, 255, 255, 0.08);
  font-size: 0.78rem;
}

.settings-toggle.is-on b,
.settings-toggle:is(:hover, :focus-visible, .is-tv-focused) b {
  color: #06121d;
  background: linear-gradient(135deg, var(--cyan), var(--blue));
}

.settings-toggle:is(:hover, :focus-visible, .is-tv-focused) {
  outline: 0;
  border-color: rgba(0, 210, 255, 0.24);
  background: rgba(0, 210, 255, 0.09);
  box-shadow: 0 0 0 0.15rem rgba(0, 210, 255, 0.08);
}

.settings-grid:has(.settings-rail) {
  grid-template-columns: minmax(10rem, 14rem) minmax(0, 54rem);
  align-items: start;
  max-width: 86rem;
  min-height: min(42rem, 74vh);
  padding: 0;
  overflow: hidden;
  border-color: rgba(92, 155, 255, 0.1);
  border-radius: 1.2rem;
  background:
    radial-gradient(circle at 88% 0%, rgba(59, 130, 246, 0.18), transparent 24rem),
    linear-gradient(135deg, rgba(11, 18, 30, 0.97), rgba(13, 22, 38, 0.92));
}

.settings-rail {
  position: sticky;
  top: 6rem;
  display: grid;
  align-content: start;
  gap: 0.45rem;
  min-height: min(42rem, 74vh);
  padding: 1rem 0.75rem;
  border-right: 0.08rem solid rgba(255, 255, 255, 0.06);
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.045), transparent),
    rgba(5, 7, 16, 0.36);
}

.settings-rail-item {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  min-height: 3.3rem;
  padding: 0 1rem;
  border: 0.08rem solid transparent;
  border-radius: 999rem;
  color: rgba(246, 243, 255, 0.58);
  background: transparent;
  font: inherit;
  font-weight: 900;
  text-align: left;
  cursor: pointer;
  transition: color 150ms, background 150ms, border-color 150ms, transform 200ms cubic-bezier(0.34, 1.3, 0.5, 1), box-shadow 150ms;
}

.settings-rail-item:is(:hover, :focus-visible, .is-tv-focused) {
  outline: 0;
  color: #ffffff;
  border-color: rgba(92, 155, 255, 0.28);
  background: rgba(59, 130, 246, 0.1);
  box-shadow: inset 0 0 0 0.04rem rgba(255, 255, 255, 0.04);
  transform: translateX(0.18rem);
}

.settings-rail-item.is-selected {
  color: #ffffff;
  border-color: rgba(59, 130, 246, 0.5);
  background:
    linear-gradient(135deg, rgba(59, 130, 246, 0.26), rgba(37, 99, 235, 0.2)),
    rgba(255, 255, 255, 0.05);
  box-shadow: inset 0 0 0 0.04rem rgba(92, 155, 255, 0.22), 0 0.5rem 1.2rem rgba(37, 99, 235, 0.16);
}

.settings-version {
  align-self: end;
  margin-top: auto;
  padding: 1rem;
  color: rgba(246, 243, 255, 0.42);
  font-size: 0.76rem;
  font-weight: 800;
  line-height: 1.35;
}

.settings-console {
  display: grid;
  align-content: start;
  gap: 1rem;
  height: min(74vh, 48rem);
  max-height: none;
  overflow-y: auto;
  overflow-x: hidden;
  overscroll-behavior: contain;
  padding: 1.2rem clamp(1rem, 3vw, 2rem) 2rem;
  scrollbar-width: thin;
}

.settings-panel {
  display: grid;
  gap: 0.65rem;
  min-height: min(64vh, 40rem);
  align-content: start;
  padding: 0.95rem 0 1.35rem;
  scroll-margin-top: 1rem;
}

.settings-panel[hidden] {
  display: none;
}

.settings-panel.is-active {
  animation: settingsPanelIn 180ms ease both;
}

.settings-panel-head {
  display: grid;
  grid-template-columns: 2.3rem minmax(0, 1fr);
  align-items: center;
  gap: 0.8rem;
  margin-bottom: 0.5rem;
  padding-bottom: 0.8rem;
  border-bottom: 0.08rem solid rgba(255, 255, 255, 0.07);
}

.settings-panel-head h3 {
  margin: 0;
  color: #ffffff;
  font-size: clamp(1.35rem, 2vw, 1.8rem);
  line-height: 1.1;
}

.settings-panel-head p {
  margin: 0.18rem 0 0;
  color: rgba(246, 243, 255, 0.52);
  font-size: 0.84rem;
  font-weight: 750;
}

@keyframes settingsPanelIn {
  from {
    opacity: 0;
    transform: translateY(0.35rem);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.settings-line {
  display: grid;
  grid-template-columns: minmax(12rem, 1fr) minmax(10rem, auto);
  align-items: center;
  gap: 0.9rem;
  min-height: 3.4rem;
  padding: 0 0.85rem;
  margin: 0 -0.85rem;
  border-radius: 0.85rem;
  color: rgba(246, 243, 255, 0.86);
  font-weight: 850;
  transition: background 180ms ease;
}

.settings-line:hover {
  background: rgba(92, 155, 255, 0.06);
}

.settings-stat {
  justify-self: end;
  text-align: right;
  color: rgba(246, 243, 255, 0.92);
  font-weight: 800;
  font-size: 0.9rem;
  letter-spacing: 0.01em;
}

.settings-line > span {
  min-width: 0;
  color: rgba(246, 243, 255, 0.78);
}

.settings-select {
  width: min(15rem, 100%);
  max-width: none;
  justify-self: end;
  min-height: 2.55rem;
  border: 0.08rem solid rgba(255, 255, 255, 0.08);
  background: rgba(255, 255, 255, 0.08);
}

.settings-switch {
  justify-self: end;
  position: relative;
  width: 3.25rem;
  height: 1.72rem;
  border: 0;
  border-radius: 999rem;
  background: rgba(255, 255, 255, 0.12);
  box-shadow: inset 0 0 0 0.06rem rgba(255, 255, 255, 0.06);
  cursor: pointer;
  transition: background 240ms ease, box-shadow 240ms ease;
}

.settings-switch:is(:hover, :focus-visible, .is-tv-focused) {
  outline: 0;
  box-shadow: inset 0 0 0 0.06rem rgba(92, 155, 255, 0.3);
}

.settings-switch b {
  position: absolute;
  top: 0.24rem;
  left: 0.25rem;
  width: 1.22rem;
  height: 1.22rem;
  border-radius: 50%;
  background: #ffffff;
  box-shadow: 0 0.2rem 0.5rem rgba(0, 0, 0, 0.35);
  transition: transform 260ms cubic-bezier(0.34, 1.4, 0.5, 1);
}

.settings-switch.is-on {
  background: linear-gradient(135deg, #5C9BFF, #2563EB);
  box-shadow: inset 0 0 0 0.06rem rgba(92, 155, 255, 0.4), 0 0 0.9rem rgba(59, 130, 246, 0.35);
}

.settings-switch.is-on b {
  transform: translateX(1.48rem);
}

.settings-status-pill {
  justify-self: end;
  padding: 0.55rem 0.82rem;
  border-radius: 999rem;
  color: rgba(246, 243, 255, 0.86);
  background: rgba(255, 255, 255, 0.08);
  font-size: 0.82rem;
}

.settings-actions,
.settings-legal-links {
  display: flex;
  flex-wrap: wrap;
  gap: 0.65rem;
  justify-content: flex-start;
  margin-top: 0.3rem;
}

.settings-shortcut-row {
  display: grid;
  grid-template-columns: minmax(10rem, 1fr) auto;
  align-items: center;
  min-height: 3rem;
  color: rgba(246, 243, 255, 0.78);
  font-weight: 850;
}

.settings-shortcut-row kbd {
  padding: 0.55rem 0.78rem;
  border: 0.08rem solid rgba(255, 255, 255, 0.08);
  border-radius: 0.45rem;
  color: #ffffff;
  background: rgba(255, 255, 255, 0.08);
  font: inherit;
  font-size: 0.78rem;
  font-weight: 950;
}

/* ── Settings Rail Icon ──────────────────────────────────────────────── */
.rail-icon {
  display: inline-block;
  width: 1.4em;
  opacity: 0.7;
}

.settings-rail-item.is-selected .rail-icon {
  opacity: 1;
}

/* ── Settings Group Label & Divider ──────────────────────────────────── */
.settings-group-label {
  margin: 0.65rem 0 0.1rem;
  color: rgba(92, 155, 255, 0.85);
  font-size: 0.7rem;
  font-weight: 950;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.settings-divider {
  height: 0.08rem;
  margin: 0.5rem 0 0.2rem;
  border: none;
  background: rgba(255, 255, 255, 0.07);
}

.settings-line > span small {
  display: block;
  margin-top: 0.18rem;
  color: rgba(246, 243, 255, 0.42);
  font-size: 0.76rem;
  font-weight: 750;
}

/* ── Volume Slider ────────────────────────────────────────────────────── */
.settings-volume-line.settings-line {
  display: grid;
  gap: 0.55rem;
  min-height: unset;
  padding: 0.6rem 0;
  grid-template-columns: 1fr;
  align-items: start;
}

.settings-volume-label {
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
}

.settings-volume-label > span {
  color: rgba(246, 243, 255, 0.78);
  font-weight: 850;
}

.settings-volume-value {
  margin-left: auto;
  color: rgba(0, 210, 255, 0.9);
  font-size: 0.82rem;
  font-weight: 900;
  font-variant-numeric: tabular-nums;
  transition: color 120ms;
}

.settings-volume-wrap {
  display: flex;
  align-items: center;
  gap: 0.7rem;
}

.settings-volume-icon {
  font-size: 1rem;
  opacity: 0.65;
  flex-shrink: 0;
}

.settings-volume-slider {
  flex: 1;
  -webkit-appearance: none;
  appearance: none;
  height: 0.38rem;
  border-radius: 999rem;
  outline: none;
  cursor: pointer;
  background: linear-gradient(
    to right,
    var(--cyan) 0%,
    var(--cyan) var(--vol-pct, 10%),
    rgba(255, 255, 255, 0.12) var(--vol-pct, 10%),
    rgba(255, 255, 255, 0.12) 100%
  );
  transition: opacity 160ms;
}

.settings-volume-slider:focus-visible {
  box-shadow: 0 0 0 0.15rem rgba(0, 210, 255, 0.5);
}

.settings-volume-slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 1.15rem;
  height: 1.15rem;
  border-radius: 50%;
  background: #ffffff;
  box-shadow: 0 0.1rem 0.6rem rgba(0, 0, 0, 0.4);
  cursor: pointer;
  transition: transform 160ms, background 160ms;
}

.settings-volume-slider::-moz-range-thumb {
  width: 1.15rem;
  height: 1.15rem;
  border: none;
  border-radius: 50%;
  background: #ffffff;
  box-shadow: 0 0.1rem 0.6rem rgba(0, 0, 0, 0.4);
  cursor: pointer;
}

.settings-volume-slider:hover::-webkit-slider-thumb,
.settings-volume-slider:focus::-webkit-slider-thumb {
  background: var(--cyan);
  transform: scale(1.2);
}

.settings-volume-slider:hover::-moz-range-thumb,
.settings-volume-slider:focus::-moz-range-thumb {
  background: var(--cyan);
  transform: scale(1.2);
}

/* ── Settings Sources Tab ─────────────────────────────────────────────── */
.settings-source-summary {
  margin: 0 0 0.4rem;
  padding: 0.55rem 0.8rem;
  border-radius: 0.65rem;
  background: rgba(255, 255, 255, 0.05);
  color: rgba(246, 243, 255, 0.58);
  font-size: 0.82rem;
  font-weight: 800;
}

.settings-sources-grid {
  display: grid;
  gap: 0.7rem;
}

/* ── Legal Tab ────────────────────────────────────────────────────────── */
.settings-legal-tabs {
  display: flex;
  gap: 0.45rem;
  padding: 0.3rem;
  border: 0.08rem solid rgba(255, 255, 255, 0.08);
  border-radius: 999rem;
  background: rgba(2, 4, 12, 0.38);
  width: fit-content;
  margin-bottom: 0.6rem;
}

.settings-legal-content {
  max-height: 28rem;
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: rgba(255, 255, 255, 0.15) transparent;
  padding-right: 0.5rem;
}

.settings-legal-section {
  display: grid;
  gap: 0.6rem;
}

.settings-legal-section h4 {
  margin: 0.6rem 0 0.1rem;
  color: rgba(0, 210, 255, 0.85);
  font-size: 0.78rem;
  font-weight: 950;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.settings-legal-section h4:first-child {
  margin-top: 0;
}

.settings-legal-section p {
  margin: 0;
  color: rgba(246, 243, 255, 0.64);
  font-size: 0.84rem;
  font-weight: 750;
  line-height: 1.65;
}

.settings-legal-section ul {
  margin: 0;
  padding-left: 1.2rem;
  color: rgba(246, 243, 255, 0.6);
  font-size: 0.84rem;
  font-weight: 750;
  line-height: 1.7;
}

.settings-legal-section a {
  color: rgba(0, 210, 255, 0.9);
  text-decoration: none;
}

.settings-legal-section a:hover {
  text-decoration: underline;
}

body[data-theme="light"] .settings-grid {
  border-color: rgba(16, 21, 36, 0.08);
  background:
    radial-gradient(circle at 10% 0%, rgba(0, 210, 255, 0.12), transparent 18rem),
    linear-gradient(135deg, rgba(255, 255, 255, 0.72), rgba(255, 255, 255, 0.46));
}

body[data-theme="light"] .settings-card {
  border-color: rgba(16, 21, 36, 0.1);
  background: rgba(255, 255, 255, 0.74);
}

body[data-theme="light"] .settings-card strong,
body[data-theme="light"] .settings-choice,
body[data-theme="light"] .settings-toggle {
  color: #101524;
}

body[data-theme="light"] .settings-segment,
body[data-theme="light"] .settings-field .language-select,
body[data-theme="light"] .settings-toggle {
  background: rgba(245, 248, 255, 0.78);
}

body[data-theme="light"] .language-select option {
  color: #101524;
  background: #f8fbff;
}

body.reduce-motion *,
body.reduce-motion *::before,
body.reduce-motion *::after {
  animation-duration: 0.001ms !important;
  animation-iteration-count: 1 !important;
  scroll-behavior: auto !important;
  transition-duration: 0.001ms !important;
}

body.soft-focus .focusable:focus-visible,
body.soft-focus .is-tv-focused {
  box-shadow: none;
}

.focusable:focus-visible,
.is-tv-focused {
  outline: 0.14rem solid rgba(255, 255, 255, 0.82);
  outline-offset: 0.18rem;
  box-shadow: 0 0 0 0.28rem rgba(0, 210, 255, 0.13);
}

/* Text fields report :focus-visible on a plain MOUSE CLICK too (browsers assume
   keyboard interaction is coming), so the big white keyboard ring would flash on
   every click. Drive their ring from .is-tv-focused only — which our focusin
   handler adds for keyboard/D-pad focus and strips for pointer focus — so the
   ring appears just on Tab, while mouse clicks keep the subtle field :focus
   style. */
input.focusable:focus-visible:not(.is-tv-focused),
textarea.focusable:focus-visible:not(.is-tv-focused),
select.focusable:focus-visible:not(.is-tv-focused) {
  outline: none;
  box-shadow: none;
}

.primary-action.focusable:focus-visible,
.secondary-action.focusable:focus-visible,
.play-action.focusable:focus-visible,
.episode-play-inline.focusable:focus-visible,
.episode-button.focusable:focus-visible,
.detail-tab.focusable:focus-visible,
.season-tab.focusable:focus-visible,
.season-card.focusable:focus-visible {
  outline: 0;
}

.primary-action.focusable:focus-visible,
.secondary-action.focusable:focus-visible,
.episode-play-inline.focusable:focus-visible {
  box-shadow:
    inset 0 0 0 0.08rem rgba(255, 255, 255, 0.12),
    0 0 0 0.18rem rgba(0, 210, 255, 0.08),
    0 0.5rem 1.1rem rgba(0, 0, 0, 0.22);
}

.play-action.focusable:focus-visible {
  box-shadow:
    inset 0 0 0 0.08rem rgba(255, 255, 255, 0.1),
    0 0 0 0.2rem rgba(0, 210, 255, 0.08),
    0 1rem 2rem rgba(0, 0, 0, 0.28);
}

.show-card:focus,
.show-card:focus-visible,
.show-card.is-tv-focused {
  outline: 0;
  box-shadow: none;
}

.show-card:is(:hover, :focus-visible, .is-tv-focused) {
  transform: translateY(-0.16rem);
}

.show-card:is(:hover, :focus-visible, .is-tv-focused)::after {
  opacity: 0.9;
  transform: scaleX(1);
}

.show-card.is-tv-focused .thumb-art,
.show-card:focus-visible .thumb-art,
.show-card:hover .thumb-art {
  transform: translateY(-0.08rem);
  border-color: rgba(0, 210, 255, 0.82);
  box-shadow:
    0 1rem 1.65rem rgba(0, 0, 0, 0.34),
    0 0 0 0.16rem rgba(0, 210, 255, 0.15),
    0 0 1.1rem rgba(0, 210, 255, 0.16);
}

.show-card:is(:hover, :focus-visible, .is-tv-focused) .thumb-poster {
  transform: scale(1.03);
  filter: saturate(1.12) brightness(1.06);
}

.show-card:is(:hover, :focus-visible, .is-tv-focused) .show-title {
  color: #f8fbff;
  transform: none;
  text-shadow:
    0 0.35rem 0.9rem rgba(0, 0, 0, 0.58),
    0 0 0.7rem rgba(0, 210, 255, 0.26);
}

.show-card:is(:hover, :focus-visible, .is-tv-focused) .show-meta {
  color: #dcd6ef;
}

.show-card:is(:hover, :focus-visible, .is-tv-focused) .episode-pill {
  background: rgba(0, 210, 255, 0.92);
  color: #08101b;
}

.show-card:active {
  transform: translateY(-0.04rem) scale(0.985);
}

.show-card:active .thumb-art {
  border-color: rgba(255, 255, 255, 0.34);
  box-shadow: 0 0.55rem 1rem rgba(0, 0, 0, 0.3);
}

.show-card:active .thumb-poster {
  transform: scale(1.012);
  filter: brightness(0.96) saturate(1.04);
}

.show-card:active .show-title {
  color: #ffffff;
  text-shadow: none;
}

.thumb-art,
.show-card,
.show-title,
.show-meta {
  transition: transform 220ms ease, border-color 220ms ease, box-shadow 220ms ease, filter 220ms ease, color 220ms ease, text-shadow 220ms ease;
}

.watch-overlay {
  position: fixed;
  inset: 0;
  z-index: 50;
  /* always center the panel both axes */
  display: flex;
  align-items: center;
  justify-content: center;
  padding: clamp(0.75rem, 2vw, 2rem);
  background: rgba(6, 5, 16, 0.82);
  backdrop-filter: blur(12px);
  animation: overlay-fade 200ms ease both;
  overflow-y: auto;
  scrollbar-width: none;
  -ms-overflow-style: none;
}

.watch-overlay::-webkit-scrollbar {
  display: none;
}

.watch-overlay[hidden] {
  display: none;
}

.watch-panel {
  position: relative;
  display: grid;
  grid-template-columns: minmax(24rem, 0.8fr) minmax(26rem, 0.9fr);
  align-items: stretch;
  gap: 1.2rem;
  width: min(102rem, 100%);
  /* Explicit height so grid items can use min-height: 0 and scroll correctly */
  height: min(calc(100dvh - clamp(1.5rem, 4vw, 4rem)), 54rem);
  padding: 1rem;
  border: 0.08rem solid var(--line);
  border-radius: 1.15rem;
  background: #101321;
  box-shadow: var(--shadow);
  overflow: hidden;
  animation: modal-rise 260ms ease both;
  margin: auto;
}

/* Shared chevron. Both of these used the typographic glyph "‹" (U+2039), whose ink
   sits high and left in its em box, so it read as off-centre no matter how the
   button was aligned - no amount of line-height or flex centring fixes a glyph that
   is not centred in its own advance width. An inline SVG is centred by geometry. */
.chev-ico {
  display: block;
  width: 1.15rem;
  height: 1.15rem;
}

.close-button {
  position: absolute;
  top: 1rem;
  right: 1rem;
  z-index: 60;
  flex-shrink: 0;
  display: grid;          /* the glyph is now centred by the grid, not by line-height */
  place-items: center;
  width: 3rem;
  height: 3rem;
  /* Matches the topbar's glass surface instead of the flat grey it used to be, so
     it reads as part of the app rather than pasted onto the artwork. */
  border: 0.08rem solid rgba(178, 186, 255, 0.14);
  border-radius: 999rem;
  color: rgba(246, 243, 255, 0.92);
  background: rgba(12, 15, 29, 0.72);
  cursor: pointer;
  backdrop-filter: blur(14px) saturate(1.08);
  box-shadow: 0 0.5rem 1.4rem rgba(0, 0, 0, 0.38);
  transition: transform 160ms ease, background 160ms ease, border-color 160ms ease, color 160ms ease;
}

.close-button .chev-ico {
  width: 1.3rem;
  height: 1.3rem;
  /* Optical centring: a left chevron's mass sits right of its bounding box centre,
     so a hair of negative offset makes it look centred even though it already is. */
  margin-left: -0.06rem;
}

.close-button:is(:hover, :focus-visible, .is-tv-focused) {
  transform: scale(1.06);
  /* Picks up the app accent on hover, the same way the sidebar controls do. */
  border-color: rgba(138, 85, 255, 0.55);
  background: rgba(24, 20, 46, 0.86);
  color: #ffffff;
  outline: 0;
}

.video-frame {
  position: relative;
  display: grid;
  place-items: center;
  align-content: center;
  min-height: 0;
  padding: 2rem;
  border-radius: 0.5rem;
  overflow: hidden;
  background: linear-gradient(135deg, #58a8ff, #ef5bb8 48%, #f2bb46);
  background-position: center;
  background-size: cover;
  text-align: center;
}

.video-frame::before {
  content: "";
  position: absolute;
  inset: -2rem;
  z-index: 0;
  background:
    linear-gradient(rgba(12, 10, 28, 0.42), rgba(12, 10, 28, 0.9)),
    var(--watch-bg, none),
    linear-gradient(135deg, #58a8ff, #ef5bb8 48%, #f2bb46);
  background-position: center;
  background-size: cover;
  filter: blur(18px) saturate(1.1);
  transform: scale(1.04);
}

.video-frame::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background:
    radial-gradient(circle at 50% 30%, rgba(255, 255, 255, 0.08), transparent 19rem),
    linear-gradient(180deg, rgba(17, 16, 38, 0.1), rgba(17, 16, 38, 0.64));
}

.watch-art,
.watch-ready-state,
.source-picker,
.video-frame p,
.video-frame video {
  position: relative;
  z-index: 2;
}

/* Source picker fills the entire video-frame edge-to-edge */
.video-frame:has(.source-picker) {
  padding: 0;
  align-content: stretch;
  place-items: stretch;
}

.video-frame .source-picker {
  height: 100%;
}

/* ── Rich "ready" state shown before an episode is selected ─────────────── */
.watch-ready-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1rem;
  width: 100%;
  padding: 1.5rem 1rem 0.5rem;
}

.watch-ready-poster-wrap {
  width: min(17.5rem, 50%);
  min-width: 11rem;
  aspect-ratio: 2 / 3;
  filter: drop-shadow(0 1.4rem 2.8rem rgba(0, 0, 0, 0.58));
  animation: watchPosterIn 0.35s ease both;
}

@keyframes watchPosterIn {
  from { opacity: 0; transform: translateY(0.6rem) scale(0.96); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}

.watch-ready-cta {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.32rem;
  text-align: center;
  animation: watchPosterIn 0.42s 0.1s ease both;
}

.watch-ready-source {
  display: inline-block;
  padding: 0.18rem 0.7rem;
  border-radius: 2rem;
  background: rgba(59, 130, 246, 0.22);
  color: rgba(160, 195, 255, 0.95);
  font-size: 0.68rem;
  font-weight: 900;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.watch-ready-hint {
  color: rgba(246, 243, 255, 0.62);
  font-size: 0.84rem;
  font-weight: 700;
  margin: 0;
}

.watch-ready-arrow {
  font-size: 1.3rem;
  color: rgba(138, 92, 255, 0.65);
  animation: watchArrowBounce 1.6s ease-in-out infinite;
  line-height: 1;
}

@keyframes watchArrowBounce {
  0%, 100% { transform: translateY(0); }
  50%       { transform: translateY(5px); }
}
/* ─────────────────────────────────────────────────────────────────────────── */

.watch-art {
  display: grid;
  place-items: center;
  width: min(18rem, 45%);
  min-width: 12rem;
  aspect-ratio: 2 / 3;
  margin-bottom: 1.2rem;
}

.watch-poster,
.watch-poster-placeholder {
  width: 100%;
  height: 100%;
  border: 0.1rem solid rgba(255, 255, 255, 0.22);
  border-radius: 0.5rem;
  object-fit: cover;
  object-position: center top;
  box-shadow: 0 1.8rem 3rem rgba(0, 0, 0, 0.5);
}

.watch-poster-placeholder {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  align-items: flex-start;
  gap: 0.7rem;
  padding: 1.1rem;
  overflow: hidden;
  background:
    radial-gradient(circle at 82% 18%, rgba(48, 205, 232, 0.24), transparent 38%),
    radial-gradient(circle at 20% 84%, rgba(138, 92, 255, 0.32), transparent 46%),
    linear-gradient(150deg, #171827, #080911 76%);
}

.watch-poster-placeholder-mark {
  margin-bottom: auto;
  color: rgba(255, 255, 255, 0.16);
  font-size: 4rem;
  font-weight: 950;
  line-height: 1;
  text-shadow: 0 0 2rem rgba(48, 205, 232, 0.2);
}

.watch-poster-placeholder-copy {
  position: relative;
  z-index: 1;
  display: -webkit-box;
  max-width: 100%;
  color: rgba(255, 255, 255, 0.9);
  font-size: 0.78rem;
  font-weight: 900;
  line-height: 1.08;
  letter-spacing: 0;
  overflow: hidden;
  overflow-wrap: anywhere;
  -webkit-line-clamp: 4;
  -webkit-box-orient: vertical;
}

.video-frame video,
.video-frame iframe {
  width: 100%;
  height: 100%;
  max-height: 34rem;
  border-radius: 0.45rem;
  background: #05050c;
  border: 0;
}

.video-player-shell {
  position: relative;
  z-index: 2;
  display: grid;
  gap: 0.75rem;
  width: 100%;
}

.direct-player-controls {
  position: relative;
  inset: auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: 3.35rem;
  padding: 0.6rem 0.7rem;
  border: 0.08rem solid rgba(0, 210, 255, 0.12);
  border-radius: 0.82rem;
  background:
    linear-gradient(135deg, rgba(18, 22, 39, 0.92), rgba(8, 12, 25, 0.88)),
    rgba(8, 10, 19, 0.86);
  box-shadow: inset 0 0 0 0.08rem rgba(255, 255, 255, 0.03);
  pointer-events: auto;
}

.translated-caption {
  position: absolute;
  left: 50%;
  bottom: 4.5rem;
  z-index: 4;
  width: min(88%, 48rem);
  padding: 0.75rem 1rem;
  border-radius: 0.5rem;
  color: #ffffff;
  background: rgba(5, 5, 12, 0.72);
  box-shadow: 0 1rem 2rem rgba(0, 0, 0, 0.32);
  font-size: clamp(1rem, 1.6vw, 1.35rem);
  font-weight: 900;
  line-height: 1.28;
  text-align: center;
  transform: translateX(-50%);
  backdrop-filter: blur(10px);
}

.subtitle-status {
  position: absolute;
  right: 0.75rem;
  bottom: 0.75rem;
  z-index: 4;
  max-width: min(80%, 24rem);
  padding: 0.42rem 0.65rem;
  border-radius: 999px;
  color: rgba(255, 255, 255, 0.78);
  background: rgba(16, 19, 33, 0.74);
  font-size: 0.75rem;
  font-weight: 800;
}

.play-symbol {
  width: 0;
  height: 0;
  margin-bottom: 1.2rem;
  border-top: 2.2rem solid transparent;
  border-bottom: 2.2rem solid transparent;
  border-left: 3.35rem solid #ffffff;
  filter: drop-shadow(0 0.8rem 1.3rem rgba(0, 0, 0, 0.32));
}

.video-frame p {
  max-width: 25rem;
  margin: 0;
  color: rgba(255, 255, 255, 0.82);
  font-weight: 800;
}

.watch-info {
  /* min-height: 0 lets the grid item shrink to the panel's height */
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
  min-width: 0;
  padding: 1rem 1rem 1.5rem 0;
  scrollbar-width: none;
  -ms-overflow-style: none;
}

.watch-info::-webkit-scrollbar {
  display: none;
}

.watch-panel,
.watch-info,
.episode-buttons,
.source-picker-options,
.detail-tabs {
  scrollbar-width: none;
  -ms-overflow-style: none;
}

.watch-panel::-webkit-scrollbar,
.watch-info::-webkit-scrollbar,
.episode-buttons::-webkit-scrollbar,
.source-picker-options::-webkit-scrollbar,
.detail-tabs::-webkit-scrollbar {
  display: none;
}

.watch-info h2 {
  max-width: 100%;
  margin: 0 0 0.8rem;
  font-size: clamp(1.35rem, 2vw, 2.05rem);
  line-height: 1.08;
  overflow-wrap: anywhere;
  word-break: normal;
  hyphens: auto;
  display: -webkit-box;
  overflow: hidden;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
}

.watch-info p:not(.eyebrow) {
  color: var(--muted);
  line-height: 1.55;
}

.watch-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.8rem;
  margin-top: 1.5rem;
}

.cast-action {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-color: rgba(0, 210, 255, 0.22);
  background:
    linear-gradient(135deg, rgba(0, 210, 255, 0.12), rgba(138, 92, 255, 0.16)),
    rgba(255, 255, 255, 0.08);
}

.cast-action::before {
  content: "";
  width: 0.95rem;
  height: 0.72rem;
  margin-right: 0.42rem;
  border: 0.14rem solid currentColor;
  border-radius: 0.14rem;
  box-shadow: -0.18rem 0.18rem 0 -0.12rem currentColor;
}

.episode-list {
  margin-top: 1.4rem;
  padding-top: 1rem;
  border-top: 0.08rem solid rgba(255, 255, 255, 0.1);
}

.detail-pane {
  display: none;
}

.detail-pane.is-active {
  display: block;
}

.detail-pane > span {
  display: block;
  margin-bottom: 0.75rem;
  color: rgba(255, 255, 255, 0.82);
  font-size: 0.78rem;
  font-weight: 900;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.detail-tabs,
.season-tab-list {
  display: flex;
  gap: var(--gap-sm);
  margin-bottom: 1rem;
  overflow-x: auto;
  padding-bottom: 0.25rem;
}

.detail-tabs {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

.detail-tab,
.season-tab {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: var(--control-h-sm);
  padding: 0 1rem;
  border-radius: var(--radius-md);
  color: rgba(255, 255, 255, 0.78);
  background: rgba(255, 255, 255, 0.075);
  font-weight: 900;
  cursor: pointer;
  white-space: nowrap;
}

.detail-tab:focus,
.season-tab:focus,
.season-card:focus,
.episode-button:focus {
  outline: 0;
}

.season-tab {
  display: grid;
  align-content: center;
  min-width: 8.5rem;
  min-height: var(--control-h-lg);
  padding: 0.55rem 0.85rem;
  border-radius: var(--radius-md);
  text-align: left;
  flex: 0 0 auto;          /* keep full width — never squeeze the label into overlap */
}

/* Title sits on one line and grows the tab to fit; the strip scrolls instead. */
.season-tab strong {
  white-space: nowrap;
}

.season-tab small {
  color: var(--muted);
  font-size: 0.68rem;
  white-space: nowrap;
}

.detail-tab:is(:hover, :focus-visible, .is-tv-focused, .is-selected),
.season-tab:is(:hover, :focus-visible, .is-tv-focused, .is-selected) {
  color: #ffffff;
  background: linear-gradient(135deg, rgba(138, 92, 255, 0.32), rgba(0, 210, 255, 0.16));
  box-shadow: 0 0.55rem 1.25rem rgba(0, 0, 0, 0.2), inset 0 0 0 0.08rem rgba(255, 255, 255, 0.13);
}

.detail-tab:is(:focus-visible, .is-tv-focused),
.season-tab:is(:focus-visible, .is-tv-focused) {
  box-shadow:
    inset 0 0 0 0.1rem rgba(0, 210, 255, 0.34),
    0 0 0 0.28rem rgba(0, 210, 255, 0.08),
    0 0.55rem 1.25rem rgba(0, 0, 0, 0.2);
}

.anime-detail-card {
  display: grid;
  grid-template-columns: 5.4rem minmax(0, 1fr);
  gap: var(--gap-md);
  padding: var(--gap-md);
  border-radius: var(--radius-lg);
  background: rgba(255, 255, 255, 0.045);
}

.anime-detail-poster {
  width: 100%;
  aspect-ratio: 2 / 3;
  border-radius: 0.5rem;
  object-fit: cover;
}

.anime-detail-card h3 {
  margin: 0 0 0.35rem;
}

.anime-detail-card p {
  margin: 0 0 0.5rem;
}

.anime-metadata-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(7.2rem, 1fr));
  gap: 0.45rem;
  margin: 0.55rem 0 0.65rem;
}

.anime-metadata-item {
  display: grid;
  gap: 0.12rem;
  min-height: 3.1rem;
  padding: 0.48rem 0.58rem;
  border: 0.08rem solid rgba(255, 255, 255, 0.08);
  border-radius: 0.45rem;
  background: rgba(255, 255, 255, 0.045);
}

.anime-metadata-label {
  color: rgba(255, 255, 255, 0.56);
  font-size: 0.66rem;
  font-weight: 850;
  text-transform: uppercase;
}

.anime-metadata-value {
  color: #ffffff;
  font-size: 0.84rem;
  font-weight: 850;
  line-height: 1.18;
}

.anime-aliases {
  display: grid;
  gap: 0.18rem;
  margin: 0 0 0.65rem;
  color: rgba(255, 255, 255, 0.7);
  font-size: 0.78rem;
  font-weight: 750;
  line-height: 1.28;
}

.season-card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(10.5rem, 1fr));
  gap: var(--gap-md);
}

.season-card {
  display: grid;
  grid-template-rows: auto auto auto auto;
  gap: 0.45rem;
  min-height: 11.8rem;
  padding: 0.75rem;
  border-radius: var(--radius-lg);
  color: #ffffff;
  background: rgba(255, 255, 255, 0.055);
  text-align: left;
  cursor: pointer;
  transition: transform 180ms ease, background 180ms ease, box-shadow 180ms ease;
}

.season-card img {
  width: 100%;
  aspect-ratio: 16 / 10;
  border-radius: var(--radius-md);
  object-fit: cover;
}

.season-card strong,
.season-card small,
.season-card span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.season-card small,
.season-card span {
  color: var(--muted);
  font-size: 0.72rem;
  font-weight: 800;
}

.season-format-badge {
  display: inline-block;
  margin-left: 0.35rem;
  padding: 0.1rem 0.38rem;
  border-radius: 999rem;
  background: rgba(138, 92, 255, 0.22);
  color: rgba(184, 160, 255, 0.9);
  font-size: 0.62rem;
  font-weight: 900;
  letter-spacing: 0.04em;
  vertical-align: middle;
  text-transform: uppercase;
}

.season-year {
  margin-left: 0.35rem;
  color: rgba(246, 243, 255, 0.38);
  font-size: 0.65rem;
}

.season-card:is(:hover, :focus-visible, .is-tv-focused, .is-selected) {
  transform: translateY(-0.06rem);
  background: rgba(0, 210, 255, 0.13);
  box-shadow: inset 0 0 0 0.1rem rgba(0, 210, 255, 0.28), 0 0.6rem 1.25rem rgba(0, 0, 0, 0.2);
}

.season-card:is(:focus-visible, .is-tv-focused) {
  box-shadow:
    inset 0 0 0 0.1rem rgba(0, 210, 255, 0.34),
    0 0 0 0.28rem rgba(0, 210, 255, 0.08),
    0 0.6rem 1.25rem rgba(0, 0, 0, 0.2);
}

.season-block {
  margin-top: 0.8rem;
  padding: var(--gap-md);
  border-radius: var(--radius-lg);
  background: rgba(255, 255, 255, 0.045);
}

.season-head {
  display: grid;
  grid-template-columns: 3.2rem minmax(0, 1fr) auto;
  align-items: center;
  min-height: 4.8rem;
  gap: var(--gap-md);
  margin-bottom: var(--gap-md);
}

.season-poster-mini {
  width: 3.2rem;
  aspect-ratio: 2 / 3;
  border-radius: var(--radius-sm);
  object-fit: cover;
  box-shadow: 0 0.6rem 1.1rem rgba(0, 0, 0, 0.35);
}

.season-copy {
  min-width: 0;
}

.season-block h3 {
  margin: 0 0 0.55rem;
  color: rgba(255, 255, 255, 0.9);
  font-size: 0.95rem;
  line-height: 1.1;
}

.season-copy h3 {
  margin-bottom: 0.25rem;
}

.season-copy p,
.season-count {
  margin: 0;
  overflow: hidden;
  color: var(--muted);
  font-size: 0.76rem;
  font-weight: 800;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.season-count {
  padding: 0.35rem 0.55rem;
  border-radius: 999rem;
  background: rgba(255, 255, 255, 0.07);
}

.episode-empty {
  margin: 0 0 0.8rem;
  color: var(--muted);
  font-size: 0.9rem;
  line-height: 1.4;
}

.episode-player-card {
  display: grid;
  gap: 0.45rem;
  margin: 0 0 0.85rem;
  min-height: 6.2rem;
  padding: var(--gap-md);
  border: 0.08rem solid rgba(255, 255, 255, 0.11);
  border-radius: var(--radius-lg);
  background: rgba(255, 255, 255, 0.06);
}

.episode-player-card strong {
  color: #ffffff;
}

.episode-player-card span {
  color: var(--muted);
  font-size: 0.86rem;
  font-weight: 800;
}

.via-anipub {
  justify-self: start;
  padding: 0.24rem 0.52rem;
  border-radius: 999rem;
  color: #ffffff;
  background: rgba(185, 118, 255, 0.18);
  border: 0.08rem solid rgba(185, 118, 255, 0.34);
  font-size: 0.72rem;
  font-style: normal;
  font-weight: 950;
}

.episode-player-card.is-ready {
  border-color: rgba(0, 210, 255, 0.36);
  background: rgba(0, 210, 255, 0.1);
}

.episode-player-card.is-missing {
  border-color: rgba(242, 187, 70, 0.28);
  background: rgba(242, 187, 70, 0.08);
}

.episode-player-card.is-external {
  border-color: rgba(185, 118, 255, 0.34);
  background: rgba(185, 118, 255, 0.1);
}

.episode-play-inline {
  justify-self: start;
  min-height: var(--control-h-sm);
  padding: 0 0.9rem;
  border-radius: var(--radius-md);
  color: #ffffff;
  background: rgba(138, 92, 255, 0.42);
  font-weight: 900;
  cursor: pointer;
}

.episode-buttons {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(5.25rem, 1fr));
  gap: var(--gap-sm);
  max-height: 18rem;
  overflow: auto;
  padding-right: 0.2rem;
  mask-image: linear-gradient(180deg, #000 0, #000 calc(100% - 1.8rem), transparent 100%);
}

.episode-button {
  display: grid;
  align-content: center;
  min-height: var(--control-h-lg);
  padding: 0.55rem;
  border: 0.08rem solid rgba(255, 255, 255, 0.1);
  border-radius: var(--radius-md);
  color: #ffffff;
  background: rgba(255, 255, 255, 0.075);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08);
  cursor: pointer;
  transition: transform 180ms ease, border-color 180ms ease, background 180ms ease, box-shadow 180ms ease;
}

.episode-button.is-locked {
  opacity: 0.88;
  border-color: rgba(255, 255, 255, 0.09);
  background: rgba(255, 255, 255, 0.06);
}

.episode-button.is-selected,
.episode-button.is-locked.is-selected {
  opacity: 1;
  border-color: rgba(0, 210, 255, 0.42);
  background: rgba(0, 210, 255, 0.11);
}

.episode-button strong {
  font-size: 1rem;
  line-height: 1;
}

.episode-button small {
  max-width: 100%;
  overflow: hidden;
  color: rgba(255, 255, 255, 0.62);
  font-size: 0.68rem;
  font-weight: 800;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.episode-button:is(:hover, :focus-visible, .is-tv-focused, .is-selected) {
  transform: translateY(-0.03rem);
  border-color: rgba(0, 210, 255, 0.42);
  background: rgba(0, 210, 255, 0.1);
  box-shadow:
    inset 0 0 0 0.08rem rgba(255, 255, 255, 0.06),
    0 0.45rem 0.9rem rgba(0, 0, 0, 0.18);
}

.episode-button:is(:focus, :focus-visible, .is-tv-focused) {
  outline: 0;
  box-shadow:
    inset 0 0 0 0.08rem rgba(0, 210, 255, 0.26),
    0 0 0 0.16rem rgba(0, 210, 255, 0.06),
    0 0.45rem 0.9rem rgba(0, 0, 0, 0.18);
}

.episode-video-empty {
  position: relative;
  z-index: 2;
  display: grid;
  place-items: center;
  gap: 0.75rem;
  max-width: 30rem;
  margin: auto;
  padding: 1.5rem;
  color: #ffffff;
  text-align: center;
}

.episode-video-empty strong {
  font-size: 1.35rem;
}

.episode-video-empty p {
  max-width: 27rem;
}

.episode-video-empty code {
  color: #ffffff;
  font-weight: 900;
}

.episode-video-empty.is-external {
  max-width: 34rem;
}

.embedded-player-container {
  position: relative;
  z-index: 2;
  width: 100%;
  height: 100%;
  min-height: 30rem;
  overflow: hidden;
  border: 0.08rem solid rgba(255, 255, 255, 0.1);
  border-radius: 0.5rem;
  background: #03050c;
  box-shadow: inset 0 0 0 0.08rem rgba(255, 255, 255, 0.04);
}

.anipub-embedded {
  display: grid;
  grid-template-rows: auto minmax(24rem, 1fr) auto auto;
  gap: 0.62rem;
  height: auto;
  min-height: 0;
  padding: 0.62rem;
  overflow: visible;
  border-color: rgba(0, 210, 255, 0.16);
  border-radius: 0.9rem;
  background:
    linear-gradient(180deg, rgba(9, 12, 25, 0.95), rgba(6, 8, 18, 0.98)),
    #03050c;
}

.player-server-options {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.55rem;
  width: 100%;
  padding: 0.15rem 0.05rem;
}

.player-source-heading {
  flex: 1 0 100%;
  display: grid;
  justify-items: center;
  gap: 0.08rem;
  margin-bottom: 0.18rem;
  color: #ffffff;
  text-align: center;
}

.player-source-heading strong {
  font-size: 0.9rem;
  line-height: 1;
}

.player-source-heading span {
  color: rgba(246, 243, 255, 0.58);
  font-size: 0.72rem;
  font-weight: 850;
}

.player-server-option {
  display: grid;
  grid-template-columns: 1fr;
  grid-template-areas:
    "label"
    "number"
    "source";
  align-items: center;
  justify-items: center;
  gap: 0.12rem;
  min-width: 7rem;
  min-height: 4rem;
  padding: 0.58rem 0.72rem;
  border: 0.08rem solid rgba(255, 255, 255, 0.1);
  border-radius: 0.65rem;
  color: rgba(246, 243, 255, 0.82);
  background:
    linear-gradient(135deg, rgba(255, 255, 255, 0.08), rgba(255, 255, 255, 0.035)),
    rgba(40, 35, 72, 0.9);
  box-shadow: inset 0 0 0 0.04rem rgba(255, 255, 255, 0.03);
  cursor: pointer;
  text-align: center;
  transition: transform 180ms ease, background 180ms ease, border-color 180ms ease, box-shadow 180ms ease, color 180ms ease;
}

.player-server-option span {
  grid-area: label;
  color: rgba(246, 243, 255, 0.58);
  font-size: 0.64rem;
  font-weight: 950;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.player-server-option strong {
  grid-area: number;
  max-width: 100%;
  overflow: hidden;
  font-size: 0.94rem;
  line-height: 1.1;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.player-server-option small {
  grid-area: source;
  max-width: 11rem;
  overflow: hidden;
  color: rgba(246, 243, 255, 0.62);
  font-size: 0.62rem;
  font-weight: 900;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.player-server-option:is(:hover, :focus-visible, .is-tv-focused, .is-selected) {
  outline: 0;
  transform: translateY(-0.04rem);
  border-color: rgba(0, 210, 255, 0.34);
  color: #ffffff;
  background:
    linear-gradient(135deg, rgba(34, 215, 255, 0.92), rgba(138, 92, 255, 0.82)),
    rgba(40, 35, 72, 0.92);
  box-shadow: 0 0.7rem 1.45rem rgba(0, 0, 0, 0.24), 0 0 0 0.16rem rgba(0, 210, 255, 0.1);
}

.player-server-option:is(:hover, :focus-visible, .is-tv-focused, .is-selected) small {
  color: rgba(255, 255, 255, 0.78);
}

/* ── Loading hint while addon sources are being fetched ─────────────────── */
.addon-loading-hint {
  padding: 1.2rem 1.5rem;
  color: rgba(246, 243, 255, 0.42);
  font-size: 0.82rem;
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  animation: addonLoadingPulse 1.4s ease-in-out infinite;
}

@keyframes addonLoadingPulse {
  0%, 100% { opacity: 0.35; }
  50%       { opacity: 0.8; }
}

/* Fade-in each addon band as it arrives */
.addon-band {
  animation: addonBandIn 0.38s ease both;
}

@keyframes addonBandIn {
  from { opacity: 0; transform: translateY(0.5rem); }
  to   { opacity: 1; transform: translateY(0); }
}
/* ─────────────────────────────────────────────────────────────────────────── */

/* ── Source picker (shown after ✕ exit button is clicked) ────────────────── */
.source-picker {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  width: 100%;
  height: 100%;
  min-height: 18rem;
  padding: 0;
  gap: 0;
  overflow: hidden;
  cursor: default;
  user-select: none;
}

/* ── Poster hero strip ───────────────────────────────────────────────── */
.source-picker-hero {
  position: relative;
  display: flex;
  align-items: flex-end;
  gap: 1rem;
  flex-shrink: 0;
  min-height: 10rem;
  padding: 1.1rem 1.2rem 0.9rem;
  background: linear-gradient(135deg, rgba(20, 10, 38, 0.85), rgba(10, 14, 28, 0.7));
  overflow: hidden;
}

.source-picker-hero::before {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--watch-bg, none) center / cover no-repeat;
  opacity: 0.22;
  filter: blur(18px) saturate(1.4);
  transform: scale(1.08);
  pointer-events: none;
}

.source-picker-art {
  position: relative;
  flex-shrink: 0;
  width: 4.8rem;
  height: 7rem;
  border-radius: 0.6rem;
  object-fit: cover;
  box-shadow: 0 0.6rem 2rem rgba(0, 0, 0, 0.55);
}

.source-picker-art-placeholder {
  background: linear-gradient(135deg, rgba(0, 210, 255, 0.18), rgba(138, 92, 255, 0.14));
  border: 0.08rem solid rgba(255, 255, 255, 0.1);
}

.source-picker-hero-text {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 0.28rem;
  min-width: 0;
}

.source-picker-show-title {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  color: #ffffff;
  font-size: 0.88rem;
  font-weight: 850;
  line-height: 1.25;
}

.source-picker-ep-label {
  color: rgba(0, 210, 255, 0.85);
  font-size: 0.76rem;
  font-weight: 850;
}

/* ── Heading strip ───────────────────────────────────────────────────── */
.source-picker-heading {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-shrink: 0;
  gap: 0.5rem;
  padding: 0.7rem 1.2rem 0.5rem;
  border-bottom: 0.08rem solid rgba(255, 255, 255, 0.07);
  color: #fff;
}

.source-picker-heading strong {
  font-size: 0.9rem;
  font-weight: 900;
}

.source-picker-heading span {
  font-size: 0.72rem;
  color: rgba(246, 243, 255, 0.46);
  font-weight: 800;
}

/* ── Options list ────────────────────────────────────────────────────── */
.source-picker-options {
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
  padding: 0.75rem 1rem;
  overflow-y: auto;
  flex: 1;
  align-content: flex-start;
}

/* Base option row — shared by all states */
.source-picker-option {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  width: 100%;
  padding: 0.72rem 0.95rem;
  border-radius: 0.72rem;
  border: 0.08rem solid rgba(255, 255, 255, 0.08);
  color: rgba(246, 243, 255, 0.9);
  background: rgba(255, 255, 255, 0.04);
  font: inherit;
  text-align: left;
  transition: background 160ms, border-color 160ms, box-shadow 160ms, transform 120ms;
}

/* ── Found: fully playable server ───────────────────────────────────── */
.source-picker-option-found {
  border-color: rgba(0, 210, 255, 0.28);
  background: linear-gradient(130deg, rgba(0, 210, 255, 0.08), rgba(138, 92, 255, 0.1));
  cursor: pointer;
}

.source-picker-option-found:is(:hover, :focus-visible, .is-tv-focused) {
  outline: 0;
  background: linear-gradient(130deg, rgba(34, 215, 255, 0.88), rgba(138, 92, 255, 0.78));
  border-color: transparent;
  color: #06121d;
  box-shadow: 0 0.4rem 1.2rem rgba(0, 0, 0, 0.3);
  transform: translateY(-0.05rem);
}

.source-picker-option-found:is(:hover, :focus-visible, .is-tv-focused) small,
.source-picker-option-found:is(:hover, :focus-visible, .is-tv-focused) .source-picker-slot-play-icon {
  color: rgba(6, 18, 29, 0.65);
}

.source-picker-option-found:is(:hover, :focus-visible, .is-tv-focused) .source-picker-slot-play-badge {
  background: rgba(6, 18, 29, 0.18);
  color: #06121d;
}

/* ── Checking: lookup still in-flight ───────────────────────────────── */
.source-picker-option-checking {
  opacity: 0.62;
  cursor: default;
  border-color: rgba(255, 255, 255, 0.05);
}

/* ── Unavailable: lookup finished, nothing found ────────────────────── */
.source-picker-option-unavail {
  opacity: 0.32;
  cursor: default;
  border-color: rgba(255, 255, 255, 0.04);
}

/* ── Slot icon (left) ────────────────────────────────────────────────── */
.source-picker-slot-icon {
  flex-shrink: 0;
  width: 1.6rem;
  height: 1.6rem;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  font-size: 0.72rem;
  font-weight: 900;
}

.source-picker-slot-play-icon {
  color: rgba(0, 210, 255, 0.9);
  background: rgba(0, 210, 255, 0.12);
  font-size: 0.6rem;
}

.source-picker-slot-off-icon {
  color: rgba(255, 255, 255, 0.28);
  background: rgba(255, 255, 255, 0.05);
  font-size: 0.85rem;
}

.source-picker-slot-checking-icon {
  background: rgba(0, 210, 255, 0.07);
}

/* ── Slot body (center) ──────────────────────────────────────────────── */
.source-picker-slot-body {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
}

.source-picker-slot-body strong {
  font-size: 0.88rem;
  font-weight: 900;
  line-height: 1.2;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.source-picker-slot-body small {
  color: rgba(246, 243, 255, 0.48);
  font-size: 0.68rem;
  font-weight: 800;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ── Play badge (right, found only) ──────────────────────────────────── */
.source-picker-slot-play-badge {
  flex-shrink: 0;
  padding: 0.22rem 0.6rem;
  border-radius: 999rem;
  background: rgba(0, 210, 255, 0.15);
  color: rgba(0, 210, 255, 0.9);
  font-size: 0.66rem;
  font-weight: 950;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

/* ── Spinner ─────────────────────────────────────────────────────────── */
.source-picker-spinner {
  display: inline-block;
  width: 0.9rem;
  height: 0.9rem;
  border: 0.12rem solid rgba(0, 210, 255, 0.3);
  border-top-color: var(--cyan);
  border-radius: 50%;
  animation: spinnerRotate 700ms linear infinite;
  flex-shrink: 0;
}

@keyframes spinnerRotate {
  to { transform: rotate(360deg); }
}

/* ✕ exit button — always visible, slightly larger than tool buttons */
.vid-exit-button {
  font-size: 1.05rem;
  font-weight: 900;
  min-width: 2.5rem;
  min-height: 2.5rem;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.08);
  pointer-events: auto;
}

.vid-exit-button:is(:hover, :focus-visible, .is-tv-focused) {
  background: rgba(220, 60, 60, 0.55);
  color: #fff;
}

/* Topbar prev/next buttons: hidden in normal mode, shown in cinema mode */
.vid-topbar-nav {
  display: none;
}
/* ─────────────────────────────────────────────────────────────────────────── */

.player-episode-actions {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  align-items: center;
  gap: 0.55rem;
  width: 100%;
  max-width: 44rem;
  /* center the bar horizontally */
  margin-inline: auto;
  min-height: 3.2rem;
  padding: 0.42rem 0.55rem;
  border: 0.08rem solid rgba(255, 255, 255, 0.1);
  border-radius: 999rem;
  background:
    linear-gradient(135deg, rgba(20, 16, 42, 0.94), rgba(10, 12, 24, 0.92));
  box-shadow:
    inset 0 0 0 0.08rem rgba(255, 255, 255, 0.06),
    0 0.5rem 1.6rem rgba(0, 0, 0, 0.35);
  backdrop-filter: blur(10px);
}

.player-episode-actions:has(.player-download-action) {
  grid-template-columns: repeat(4, minmax(0, 1fr));
  max-width: 52rem;
}

.player-language-bar {
  display: grid;
  grid-template-columns: minmax(12rem, 1fr) auto;
  align-items: center;
  gap: 0.75rem;
  width: 100%;
  min-height: 3.7rem;
  padding: 0.72rem 0.84rem;
  border: 0.08rem solid rgba(255, 255, 255, 0.08);
  border-radius: 0.65rem;
  border-color: rgba(0, 210, 255, 0.14);
  background:
    linear-gradient(135deg, rgba(18, 22, 39, 0.92), rgba(8, 12, 25, 0.88)),
    rgba(8, 10, 19, 0.86);
  box-shadow: inset 0 0 0 0.08rem rgba(255, 255, 255, 0.025);
}

.player-nav-action,
.player-download-action,
.player-cast-action {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.42rem;
  width: 100%;
  min-height: 2.45rem;
  padding: 0 0.9rem;
  border: 0.08rem solid transparent;
  border-radius: 999rem;
  color: rgba(246, 243, 255, 0.88);
  background: rgba(255, 255, 255, 0.07);
  font-size: 0.84rem;
  font-weight: 900;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: background 150ms, color 150ms, box-shadow 150ms;
}

.player-nav-action span {
  font-size: 1.3rem;
  line-height: 0;
}

.player-nav-action small {
  display: inline-grid;
  place-items: center;
  min-width: 1.45rem;
  min-height: 1.45rem;
  padding: 0 0.28rem;
  border-radius: 999rem;
  color: #06121d;
  background: linear-gradient(135deg, #22d7ff, #f2bb46);
  font-size: 0.7rem;
}

.player-nav-action:is(:hover, :focus-visible, .is-tv-focused),
.player-download-action:is(:hover, :focus-visible, .is-tv-focused),
.player-cast-action:is(:hover, :focus-visible, .is-tv-focused) {
  outline: 0;
  color: #06121d;
  background: linear-gradient(135deg, #22d7ff, #f2bb46);
  box-shadow: 0 0.55rem 1.25rem rgba(0, 210, 255, 0.16);
}

.player-nav-action:disabled {
  opacity: 0.42;
  cursor: not-allowed;
  pointer-events: none;
  transform: none;
  box-shadow: none;
}

.player-download-action:disabled {
  display: none;
}

.player-nav-action.is-list {
  min-width: 0;
}

.player-download-action {
  color: #06121d;
  background: linear-gradient(135deg, #22d7ff, #58a8ff);
}

.player-cast-action {
  width: auto;
  min-width: 4.8rem;
}

.vidstream-player {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-template-areas:
    "stage"
    "actions";
  gap: 0.9rem;
  align-items: start;
  padding: 0.8rem;
  border: 0.08rem solid rgba(0, 210, 255, 0.16);
  border-radius: 1rem;
  background:
    radial-gradient(circle at 88% 8%, rgba(138, 92, 255, 0.14), transparent 19rem),
    linear-gradient(135deg, rgba(8, 11, 24, 0.96), rgba(12, 14, 29, 0.92));
  box-shadow:
    inset 0 0 0 0.08rem rgba(255, 255, 255, 0.035),
    0 1.1rem 2.4rem rgba(0, 0, 0, 0.24);
}

.vidstream-player .player-episode-actions {
  grid-area: actions;
}

.player-stream-toolbar {
  display: none;
}

.player-stream-toolbar {
  grid-area: prefs;
  grid-template-columns: auto minmax(10rem, 13rem) minmax(10rem, 13rem);
  align-items: center;
  gap: 0.68rem;
  width: 100%;
  padding: 0.62rem;
  border: 0.08rem solid rgba(0, 210, 255, 0.14);
  border-radius: 0.78rem;
  background:
    linear-gradient(135deg, rgba(17, 22, 41, 0.9), rgba(12, 14, 29, 0.86)),
    rgba(13, 16, 31, 0.9);
  box-shadow: inset 0 0 0 0.08rem rgba(255, 255, 255, 0.025);
}

.player-stream-toolbar .source-badge {
  justify-self: start;
  white-space: nowrap;
}

.player-stream-toolbar .language-selector {
  justify-content: end;
  width: 100%;
  max-width: none;
  padding: 0;
  background: transparent;
  border: 0;
}

.player-stream-toolbar .language-select {
  width: min(100%, 13rem);
  max-width: 13rem;
  min-height: 2.55rem;
}

.vid-player-stage {
  grid-area: stage;
  position: relative;
  display: block;
  min-height: clamp(20rem, 44vw, 35rem);
  overflow: hidden;
  border-radius: 0.65rem;
  background: #000000;
  box-shadow: inset 0 0 0 0.08rem rgba(255, 255, 255, 0.05);
}

.vidstream-player .subtitle-status {
  display: none;
}

.video-frame .vid-player-stage video,
.video-frame .vid-player-stage iframe {
  position: absolute;
  inset: 0;
  display: block;
  width: 100% !important;
  height: 100% !important;
  min-height: 0;
  max-height: none;
  border-radius: 0;
  object-fit: contain;
}

.vid-loader {
  position: absolute;
  inset: 0;
  z-index: 3;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1.5rem;
  background: var(--loader-bg, radial-gradient(circle at center, rgba(16, 14, 36, 0.54), rgba(0, 0, 0, 0.84)));
  color: var(--loader-text-color, rgba(246, 243, 255, 0.8));
  font-family: inherit;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  transition: opacity 0.3s ease;

  /* Base Theme Variables for Loader */
  --loader-primary: #8a5cff;
  --loader-secondary: #00d2ff;
  --loader-bg: radial-gradient(circle at center, rgba(8, 10, 19, 0.82), rgba(4, 5, 10, 0.96));
  --loader-text-color: #f6f3ff;
  --loader-glow: rgba(138, 92, 255, 0.4);
}

/* Mature Theme Variables for Loader */
body.adult-mode .vid-loader {
  --loader-primary: #e11d48;
  --loader-secondary: #7a2bd6;
  --loader-bg: radial-gradient(circle at center, rgba(20, 6, 12, 0.88), rgba(6, 2, 4, 0.98));
  --loader-text-color: #f7e9ef;
  --loader-glow: rgba(225, 29, 72, 0.45);
}

.vid-loader[hidden] {
  display: none;
}

/* Container for spinner elements */
.vid-loader-animation {
  position: relative;
  width: 90px;
  height: 90px;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* Outer Spinning Ring */
.vid-loader-ring {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 4px solid transparent;
  border-top-color: var(--loader-primary);
  border-bottom-color: var(--loader-secondary);
  animation: loader-spin 1.2s cubic-bezier(0.5, 0.2, 0.3, 0.8) infinite;
  box-shadow: inset 0 0 10px rgba(255, 255, 255, 0.05);
}

/* Glow Effect Behind the Ring */
.vid-loader-ring-glow {
  position: absolute;
  inset: -2px;
  border-radius: 50%;
  border: 6px solid transparent;
  border-top-color: var(--loader-primary);
  border-bottom-color: var(--loader-secondary);
  filter: blur(8px);
  opacity: 0.65;
  animation: loader-spin 1.2s cubic-bezier(0.5, 0.2, 0.3, 0.8) infinite;
  pointer-events: none;
}

/* Inner Badge or Centerpiece */
.vid-loader-inner {
  position: absolute;
  width: 48px;
  height: 48px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.03);
  box-shadow: inset 0 0 12px rgba(255, 255, 255, 0.05), 0 4px 12px rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  animation: loader-pulse 2s ease-in-out infinite;
  border: 1px solid rgba(255, 255, 255, 0.08);
}

/* Normal Mode: Draw a small play triangle in the center */
body:not(.adult-mode) .vid-loader-inner::after {
  content: "";
  display: block;
  width: 0;
  height: 0;
  margin-left: 4px; /* offset play button to look centered */
  border-top: 8px solid transparent;
  border-bottom: 8px solid transparent;
  border-left: 13px solid var(--loader-secondary);
  filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.3));
}

/* Adult Mode: Display 18+ badge in the center */
body.adult-mode .vid-loader-inner {
  background: rgba(225, 29, 72, 0.08);
  border-color: rgba(225, 29, 72, 0.3);
  box-shadow: inset 0 0 12px rgba(225, 29, 72, 0.15), 0 4px 12px rgba(0, 0, 0, 0.6);
}

body.adult-mode .vid-loader-inner::after {
  content: "18+";
  font-family: inherit;
  font-size: 0.85rem;
  font-weight: 950;
  letter-spacing: -0.02em;
  color: #e11d48;
  text-shadow: 0 0 8px rgba(225, 29, 72, 0.6);
}

/* Text styling */
.vid-loader-text {
  font-size: 0.95rem;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--loader-text-color);
  opacity: 0.85;
  text-shadow: 0 2px 8px rgba(0, 0, 0, 0.5);
  animation: loader-text-pulse 1.8s ease-in-out infinite;
}

body.adult-mode .vid-loader-text {
  text-shadow: 0 0 10px rgba(225, 29, 72, 0.25), 0 2px 4px rgba(0, 0, 0, 0.6);
}

/* Animations */
@keyframes loader-spin {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}

@keyframes loader-pulse {
  0%, 100% {
    transform: scale(1);
    box-shadow: inset 0 0 12px rgba(255, 255, 255, 0.05), 0 4px 12px rgba(0, 0, 0, 0.5);
  }
  50% {
    transform: scale(1.06);
    box-shadow: inset 0 0 12px rgba(255, 255, 255, 0.05), 0 4px 12px var(--loader-glow);
  }
}

@keyframes loader-text-pulse {
  0%, 100% {
    opacity: 0.7;
    transform: scale(0.98);
  }
  50% {
    opacity: 1;
    transform: scale(1);
  }
}

.video-frame .vid-player-stage .apk-video-frame {
  border: 0;
  background: #000000;
}

.vidstream-player.fit-cover .vid-player-stage > video {
  object-fit: cover;
}

.vidstream-player.fit-fill .vid-player-stage > video {
  object-fit: fill;
}

.vidstream-player.fit-cover .vid-player-stage > iframe,
.vidstream-player.fit-fill .vid-player-stage > iframe {
  object-fit: fill;
}

.vid-topbar {
  position: absolute;
  inset: 0 0 auto;
  z-index: 5;
  display: grid;
  grid-template-columns: minmax(0, 1fr) 2.8rem;
  align-items: center;
  gap: 0.55rem;
  min-height: 3.7rem;
  padding: 0.55rem 0.75rem 2.4rem;
  color: #ffffff;
  background: linear-gradient(180deg, rgba(0, 0, 0, 0.72), transparent);
  pointer-events: none;
}

/* iframe mode: solid topbar — title centered, no left-padding compensation */
.vidstream-player.is-iframe .vid-topbar strong {
  padding-left: 0;
  text-align: center;
  font-size: 0.92rem;
  font-weight: 700;
  letter-spacing: 0.01em;
  color: rgba(255, 255, 255, 0.92);
}

.vid-topbar strong {
  min-width: 0;
  overflow: hidden;
  font-size: 0.98rem;
  font-weight: 850;
  padding-left: 2.8rem;
  text-align: center;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.vid-icon-button,
.vid-tool-button {
  display: inline-grid;
  place-items: center;
  min-width: 2.35rem;
  min-height: 2.35rem;
  border: 0;
  border-radius: 999rem;
  color: rgba(255, 255, 255, 0.82);
  background: rgba(255, 255, 255, 0.04);
  font: inherit;
  font-weight: 950;
  cursor: pointer;
  pointer-events: auto;
}

.vid-icon-button:is(:hover, :focus-visible, .is-tv-focused),
.vid-tool-button:is(:hover, :focus-visible, .is-tv-focused) {
  outline: 0;
  color: #ffffff;
  background: rgba(138, 92, 255, 0.38);
  box-shadow: 0 0 0 0.14rem rgba(138, 92, 255, 0.12);
}

.vid-icon-button:disabled,
.vid-tool-button:disabled {
  opacity: 0.28;
  cursor: not-allowed;
  pointer-events: none;
}

.vid-loader {
  position: absolute;
  inset: 0;
  z-index: 3;
  display: grid;
  place-items: center;
  gap: 0.6rem;
  color: rgba(246, 243, 255, 0.8);
  background: radial-gradient(circle at center, rgba(16, 14, 36, 0.54), rgba(0, 0, 0, 0.84));
  font-weight: 900;
}

.vid-loader[hidden] {
  display: none;
}

.vid-loader .play-symbol {
  margin: 0;
  transform: scale(0.42);
}

.player-inline-prefs {
  position: absolute;
  left: 0.8rem;
  right: 0.8rem;
  bottom: 4.8rem;
  z-index: 5;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.46rem;
  pointer-events: none;
}

.player-inline-prefs > * {
  pointer-events: auto;
}

.player-inline-prefs .language-select {
  min-height: 2.35rem;
  max-width: 13rem;
  border: 0.08rem solid rgba(255, 255, 255, 0.12);
  background: rgba(22, 24, 40, 0.88);
  box-shadow: 0 0.6rem 1.4rem rgba(0, 0, 0, 0.18);
}

.vid-controls {
  position: absolute;
  inset: auto 0 0;
  z-index: 6;
  display: grid;
  gap: 0.55rem;
  padding: 0.55rem 0.75rem 0.72rem;
  background: linear-gradient(0deg, rgba(0, 0, 0, 0.82), rgba(0, 0, 0, 0.18), transparent);
}

.vid-seek {
  width: 100%;
  height: 0.35rem;
  accent-color: #8a5cff;
  cursor: pointer;
}

.vid-timeline {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 0.7rem;
  min-width: 0;
}

.vid-timeline .vid-seek {
  min-width: 0;
}

.vid-control-row {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  min-width: 0;
}

.vid-spacer {
  flex: 1 1 auto;
}

.vid-time {
  color: rgba(255, 255, 255, 0.88);
  font-size: 0.86rem;
  font-weight: 800;
  white-space: nowrap;
}

.vid-skip-button {
  position: relative;
  overflow: visible;
  font-size: 1.05rem;
}

.vid-skip-button span {
  position: absolute;
  right: 0.2rem;
  bottom: 0.16rem;
  font-size: 0.54rem;
  line-height: 1;
  font-weight: 900;
}

.vid-panel {
  position: absolute;
  right: 0.75rem;
  bottom: 4.5rem;
  z-index: 7;
  display: grid;
  gap: 0.7rem;
  width: min(20rem, calc(100% - 1.5rem));
  max-height: min(24rem, 70vh);
  overflow: auto;
  padding: 1rem;
  border: 0.08rem solid rgba(255, 255, 255, 0.08);
  border-radius: 0.85rem;
  color: #ffffff;
  background: rgba(16, 14, 36, 0.96);
  box-shadow: 0 1.2rem 2.8rem rgba(0, 0, 0, 0.42);
}

.vid-panel[hidden] {
  display: none;
}

.vid-panel p {
  margin: 0;
  color: rgba(246, 243, 255, 0.62);
  font-size: 0.86rem;
}

.vid-panel-grid {
  display: grid;
  gap: 0.45rem;
}

.vid-panel-choice {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  min-height: 2.8rem;
  padding: 0.45rem 1rem;
  border: 0.08rem solid rgba(255, 255, 255, 0.06);
  border-radius: 0.8rem;
  color: rgba(246, 243, 255, 0.88);
  background: rgba(255, 255, 255, 0.05);
  font: inherit;
  font-weight: 600;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
  transition: all 0.22s cubic-bezier(0.2, 0.8, 0.2, 1);
}

.vid-panel-choice:is(:hover, :focus-visible, .is-tv-focused) {
  outline: 0;
  color: #ffffff;
  background: rgba(138, 92, 255, 0.28);
  border-color: rgba(138, 92, 255, 0.45);
  transform: translateX(0.25rem);
  box-shadow: 0 0.25rem 1rem rgba(138, 92, 255, 0.15);
}

/* Currently-selected server / quality in the in-player Sources panel */
.vid-panel-choice.is-active {
  color: #ffffff;
  background: rgba(138, 92, 255, 0.34);
  border-color: rgba(138, 92, 255, 0.6);
}
.vid-panel-choice.is-active .choice-icon {
  opacity: 1;
  color: #b9a3ff;
}

.vid-panel-choice .choice-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 1.15rem;
  opacity: 0.7;
  transition: opacity 0.22s ease;
}

.vid-panel-choice:is(:hover, :focus-visible, .is-tv-focused) .choice-icon {
  opacity: 1;
}

.vidstream-player.is-iframe {
  grid-template-rows: 1fr auto;
  height: 100%;
  min-height: 0;
  padding: 0.5rem;
}

.vidstream-player.is-iframe .vid-player-stage {
  /* Fill the video-frame area instead of forcing a fixed min-height */
  flex: 1;
  min-height: clamp(14rem, 28vh, 22rem);
  /* Black topbar + iframe stacked vertically */
  display: flex;
  flex-direction: column;
}

/* Opaque black info bar above the iframe */
.vidstream-player.is-iframe .vid-topbar {
  order: -1;
  position: relative;
  inset: auto;
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.95);
  border-bottom: 0.06rem solid rgba(255, 255, 255, 0.13);
  min-height: 2.8rem;
  padding: 0.4rem 3rem;
  pointer-events: auto;
}

/* iframe or video fills remaining space after topbar */
.vidstream-player.is-iframe .vid-player-stage > iframe,
.vidstream-player.is-iframe .vid-player-stage > video {
  flex: 1 1 0;
  min-height: 0;
  height: auto;
  position: relative !important;
}

.vidstream-player.is-iframe .player-inline-prefs {
  bottom: 0.8rem;
}

html.player-cinema-open,
body.player-cinema-open {
  height: 100%;
  overflow: hidden;
  overscroll-behavior: none;
}

/*
 * CRITICAL FIX — containing-block isolation
 * ─────────────────────────────────────────
 * .watch-overlay has backdrop-filter which makes it the containing block
 * for ALL position:fixed descendants.  .watch-panel (inside the overlay)
 * has overflow:hidden, so .vidstream-player.is-cinema { position:fixed }
 * gets clipped to the watch-panel rectangle — never full-viewport.
 *
 * Solution: remove the backdrop-filter when cinema is active so that
 * position:fixed is relative to the true viewport, which overflow:hidden
 * on any ancestor cannot clip.
 */
body.player-cinema-open .watch-overlay {
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
  overflow: hidden;
  /* Kill the entrance animation so it doesn't re-fire on fullscreen toggle */
  animation: none !important;
}

/* Suppress panel re-animation during fullscreen transition */
body.player-cinema-open .watch-panel {
  animation: none !important;
}

/* ── Embedded-player mode (iframe, no full-viewport cinema) ─────────────────
   Kills the backdrop-filter so the iframe's own fullscreen request
   doesn't have to traverse expensive compositor layers. */
body.has-embedded-player .watch-overlay {
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
  animation: none !important;
}
body.has-embedded-player .watch-panel {
  animation: none !important;
}

/* Make the video-frame stretch to fill its grid cell so the iframe uses
   all available vertical space instead of shrinking to min-height. */
body.has-embedded-player .video-frame {
  align-self: stretch;
  align-content: stretch;
  place-items: stretch;
}

/* Hide the overlay's outer × when cinema is active — the in-player vid-exit-button serves as close */
body.player-cinema-open .close-button {
  display: none;
}

/* Native fullscreen: zero-latency backdrop, no transition flash */
/* Instant fullscreen — no fade-in, no compositor overhead */
::backdrop {
  background: #000;
  animation: none !important;
  transition: none !important;
}
:fullscreen,
:-webkit-full-screen {
  animation: none !important;
  transition: none !important;
}
:fullscreen .watch-panel,
:fullscreen .watch-overlay,
:-webkit-full-screen .watch-panel,
:-webkit-full-screen .watch-overlay {
  animation: none !important;
  transition: none !important;
  backdrop-filter: none !important;
}

/* Make player fill the screen in native fullscreen */
:fullscreen.vidstream-player.is-cinema,
:-webkit-full-screen.vidstream-player.is-cinema,
:fullscreen .vidstream-player.is-cinema,
:-webkit-full-screen .vidstream-player.is-cinema {
  top: 0 !important;
  left: 0 !important;
  width: 100vw !important;
  height: 100vh !important;
  max-width: none !important;
  max-height: none !important;
  border: none !important;
  border-radius: 0 !important;
  transform: none !important;
  box-shadow: none !important;
}

/* ══════════════════════════════════════════════════════════════════════════
   Cinema mode — full-screen overlay
   ══════════════════════════════════════════════════════════════════════════
   The cinema container is position:fixed; inset:0 on the true viewport
   (backdrop-filter is disabled on .watch-overlay when cinema is open,
   so there is no re-rooted containing block that could clip this element).

   The stage is position:absolute; inset:0 — relative to the cinema
   container, which is now the true viewport rectangle.  This avoids any
   double-fixed complexity and works correctly in native fullscreen too.
   ══════════════════════════════════════════════════════════════════════════ */

.vidstream-player.is-cinema {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 10050;
  display: block;
  /* True full-screen, edge-to-edge (Netflix-style) — no centered window. */
  width: 100vw;
  height: 100vh;
  height: 100dvh;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: #000;
  overflow: hidden;
  transform: none;
  box-shadow: none;
  transition: none;
}

/* The iframe contains the complete Artplayer experience. Do not layer the
   legacy app chrome or spacing over it. */
.vidstream-player.is-cinema.is-artplayer-frame .vid-player-stage,
.vidstream-player.is-cinema.is-artplayer-frame .apk-video-frame {
  position: absolute !important;
  inset: 0 !important;
  width: 100% !important;
  height: 100% !important;
  min-width: 0 !important;
  min-height: 0 !important;
  max-width: none !important;
  max-height: none !important;
  margin: 0 !important;
  padding: 0 !important;
  border: 0 !important;
  border-radius: 0 !important;
}

/* ── Playback-error overlay — full-screen, with "Try another source" ──────── */
.vidstream-player .vid-error-overlay {
  position: absolute;
  inset: 0;
  z-index: 6;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.85rem;
  padding: 2rem;
  text-align: center;
  background: radial-gradient(circle at 50% 42%, rgba(14, 16, 26, 0.82), rgba(2, 3, 8, 0.96));
}
.vid-error-icon {
  font-size: 3.2rem;
  line-height: 1;
  color: #ff6b6b;
  filter: drop-shadow(0 0.4rem 1.2rem rgba(255, 80, 80, 0.4));
}
.vid-error-title {
  font-size: 1.55rem;
  font-weight: 800;
  color: #fff;
}
.vid-error-message {
  max-width: 34rem;
  margin: 0;
  color: rgba(255, 255, 255, 0.74);
  line-height: 1.55;
}
.vid-error-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  justify-content: center;
  margin-top: 0.4rem;
}
.vid-error-retry {
  padding: 0.62rem 1.4rem;
  border: 0.08rem solid rgba(255, 255, 255, 0.26);
  border-radius: 0.7rem;
  background: rgba(255, 255, 255, 0.08);
  color: #fff;
  font-weight: 700;
  cursor: pointer;
}
.vid-error-retry:hover,
.vid-error-retry:focus-visible {
  background: rgba(255, 255, 255, 0.16);
}

/* ── Skip-intro button (placeholder; shown only inside an intro window) ────── */
.vid-skip-intro {
  position: absolute;
  right: 2.2rem;
  bottom: 5.5rem;
  z-index: 7;
  padding: 0.6rem 1.3rem;
  border: 0.08rem solid rgba(255, 255, 255, 0.3);
  border-radius: 0.7rem;
  background: rgba(10, 12, 20, 0.78);
  color: #fff;
  font: inherit;
  font-weight: 700;
  cursor: pointer;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  transition: background 0.2s ease, border-color 0.2s ease;
}
.vid-skip-intro:is(:hover, :focus-visible, .is-tv-focused) {
  outline: 0;
  background: rgba(138, 92, 255, 0.4);
  border-color: rgba(138, 92, 255, 0.6);
}
.vid-skip-intro[hidden] { display: none; }

/* Stage: fills the cinema container via position:absolute */
.vidstream-player.is-cinema .vid-player-stage {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: block;
  min-height: 0;
  overflow: hidden;
  border-radius: inherit;
  background: #000;
}

/* Media: stretches to fill the entire stage */
.vidstream-player.is-cinema .vid-player-stage > video,
.vidstream-player.is-cinema .vid-player-stage > iframe {
  position: absolute;
  inset: 0;
  display: block;
  width: 100% !important;
  height: 100% !important;
  max-width: none !important;
  max-height: none !important;
  min-width: 0 !important;
  min-height: 0 !important;
  object-fit: contain;
  border-radius: inherit;
  background: #000;
  z-index: 1;
  flex: none;
}

.vidstream-player.is-cinema.is-popup-message .episode-video-empty {
  position: absolute;
  inset: 0;
  display: grid;
  place-content: center;
  width: 100%;
  max-width: none;
  min-height: 0;
  padding: clamp(2rem, 5vw, 4rem);
  background:
    radial-gradient(circle at 50% 42%, rgba(138, 92, 255, 0.2), transparent 19rem),
    linear-gradient(180deg, rgba(7, 8, 18, 0.86), rgba(0, 0, 0, 0.94));
}

.vidstream-player.is-cinema.is-popup-message .episode-video-empty p {
  max-width: min(36rem, 78vw);
  margin: 0;
  color: rgba(246, 243, 255, 0.72);
  font-weight: 800;
  line-height: 1.45;
}

.vidstream-player.is-cinema.is-source-picker .source-picker {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100%;
  padding-top: 4.2rem;
  border-radius: inherit;
}

.vidstream-player.is-cinema.is-source-picker .source-picker-options {
  min-height: 0;
}

.vidstream-player.is-cinema.fit-cover .vid-player-stage > video {
  object-fit: cover;
}

.vidstream-player.is-cinema.fit-fill .vid-player-stage > video {
  object-fit: fill;
}

.vidstream-player.is-cinema.fit-cover .vid-player-stage > iframe,
.vidstream-player.is-cinema.fit-fill .vid-player-stage > iframe {
  object-fit: fill;
}

/* ── Topbar: gradient bar pinned to the top of the stage ── */
.vidstream-player.is-cinema .vid-topbar {
  position: absolute;
  inset: 0 0 auto;         /* top:0  left:0  right:0  bottom:auto */
  z-index: 10;
  display: flex;
  align-items: center;
  gap: 0.6rem;
  min-height: 3.5rem;
  /* right padding leaves room for the ✕ button (~3.4 rem wide) */
  padding: 0.8rem 4rem 3.5rem 1rem;
  background: linear-gradient(180deg, rgba(0, 0, 0, 0.88) 0%, transparent 100%);
  border-bottom: 0;
  pointer-events: none;    /* click-through to video */
}

/* Re-enable pointer events for interactive controls inside the topbar */
.vidstream-player.is-cinema .vid-topbar > * {
  pointer-events: auto;
}

/* Episode title: grows to fill the topbar, clips overflow */
.vidstream-player.is-cinema .vid-topbar strong {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  padding-left: 0;
  text-align: left;
  font-size: 0.92rem;
  font-weight: 700;
  letter-spacing: 0.01em;
  color: rgba(255, 255, 255, 0.95);
}

/* Show Prev / Next nav buttons only in cinema (hidden by default) */
.vidstream-player.is-cinema .vid-topbar-nav {
  display: inline-grid;
  flex-shrink: 0;
}

/* ── ✕ button: pinned to the very top-right of the stage ── */
.vidstream-player.is-cinema .vid-exit-button {
  position: absolute;
  inset: auto;             /* clear any inherited inset */
  top: 0.8rem;
  right: 0.85rem;
  z-index: 12;
  pointer-events: auto;
  width: 3rem;
  height: 3rem;
  min-width: 0;
  min-height: 0;
  border-radius: 999rem;
  background: rgba(56, 58, 72, 0.86);
  border: 0;
  font-size: 1.4rem;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}

.vidstream-player.is-cinema .vid-exit-button:is(:hover, :focus-visible, .is-tv-focused) {
  background: rgba(200, 35, 35, 0.75);
  border-color: rgba(255, 80, 80, 0.4);
  color: #fff;
  box-shadow: 0 0 0 0.18rem rgba(200, 35, 35, 0.25);
}

/* ── Controls bar: gradient bar pinned to the bottom of the stage ── */
.vidstream-player.is-cinema .vid-controls {
  position: absolute;
  inset: auto 0 0;
  z-index: 10;
  padding-bottom: max(0.72rem, env(safe-area-inset-bottom));
  background: linear-gradient(
    0deg,
    rgba(0, 0, 0, 0.9)  0%,
    rgba(0, 0, 0, 0.55) 50%,
    transparent         100%
  );
}

/* ── Episode actions bar: hidden in cinema ──
   Navigation is in the topbar (⏮ ⏭) and vid-controls (⏮ ⏭). */
.vidstream-player.is-cinema .player-episode-actions {
  display: none;
}

/* ── Auto-hide chrome after 2s of inactivity ──
   In cinema playback the topbar (back/✕ + title) and the control bar fade out
   after a short idle, then reappear on any tap / mouse-move / key press. The
   back button is only hidden — never disabled — so a single tap brings it back.
   The source picker and loading/message states keep .is-ui-idle off, so they
   always stay visible. */
.vidstream-player.is-cinema .vid-topbar,
.vidstream-player.is-cinema .vid-controls,
.vidstream-player.is-cinema .vid-exit-button {
  transition: opacity 0.28s ease, visibility 0.28s ease;
}
.vidstream-player.is-cinema.is-ui-idle .vid-topbar,
.vidstream-player.is-cinema.is-ui-idle .vid-controls,
.vidstream-player.is-cinema.is-ui-idle .vid-exit-button {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}
.vidstream-player.is-cinema.is-ui-idle {
  cursor: none;
}

/* Fullscreen button active state — highlight while in native fullscreen */
:fullscreen [data-player-fullscreen],
:-webkit-full-screen [data-player-fullscreen] {
  color: var(--cyan);
  opacity: 1;
}

.player-controls-bar {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  z-index: 4;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.85rem;
  padding: 0.85rem 1rem 2.5rem;
  background: linear-gradient(180deg, rgba(3, 5, 12, 0.92), rgba(3, 5, 12, 0));
  pointer-events: none;
}

.video-player-shell .direct-player-controls {
  position: relative;
  inset: auto;
  padding: 0.6rem 0.7rem;
  background:
    linear-gradient(135deg, rgba(18, 22, 39, 0.92), rgba(8, 12, 25, 0.88)),
    rgba(8, 10, 19, 0.86);
  pointer-events: auto;
}

.anipub-embedded .player-controls-bar {
  position: relative;
  inset: auto;
  display: grid;
  grid-template-columns: minmax(13rem, 1fr) auto auto;
  align-items: center;
  gap: 0.55rem;
  padding: 0.54rem 0.62rem;
  border: 0.08rem solid rgba(0, 210, 255, 0.12);
  border-radius: 0.8rem;
  background:
    linear-gradient(135deg, rgba(18, 22, 39, 0.9), rgba(8, 12, 25, 0.82)),
    rgba(8, 10, 19, 0.82);
  box-shadow:
    inset 0 0 0 0.08rem rgba(255, 255, 255, 0.03),
    0 0.7rem 1.25rem rgba(0, 0, 0, 0.18);
  backdrop-filter: none;
  pointer-events: auto;
}

.episode-info,
.language-selector,
.close-embedded {
  pointer-events: auto;
}

.episode-info {
  display: flex;
  align-items: center;
  min-width: 0;
  gap: 0.5rem;
  color: #ffffff;
  text-align: left;
}

.episode-info strong {
  overflow: hidden;
  max-width: min(31rem, 42vw);
  font-size: 0.78rem;
  font-weight: 850;
  line-height: 1.15;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.source-badge {
  flex: 0 0 auto;
  padding: 0.2rem 0.56rem;
  border: 0.08rem solid rgba(0, 210, 255, 0.24);
  border-radius: 999rem;
  color: #06121d;
  background: linear-gradient(135deg, #22d7ff, #f2bb46);
  font-size: 0.64rem;
  font-weight: 950;
  letter-spacing: 0;
}

.player-default-badge {
  flex: 0 0 auto;
  padding: 0.2rem 0.55rem;
  border: 0.08rem solid rgba(181, 122, 255, 0.22);
  border-radius: 999rem;
  color: rgba(246, 243, 255, 0.76);
  background: rgba(181, 122, 255, 0.12);
  font-size: 0.66rem;
  font-weight: 900;
  letter-spacing: 0;
}

.language-selector {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.5rem;
  padding: 0.38rem;
  border: 0.08rem solid rgba(255, 255, 255, 0.1);
  border-radius: 999rem;
  background: rgba(8, 10, 19, 0.72);
  box-shadow: 0 0.75rem 1.4rem rgba(0, 0, 0, 0.2);
  backdrop-filter: blur(1rem);
}

.anipub-embedded .language-selector {
  flex: 0 0 auto;
  justify-content: flex-end;
  max-width: none;
  gap: 0.4rem;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
  backdrop-filter: none;
}

.language-select {
  min-height: 2rem;
  max-width: 10.5rem;
  padding: 0 0.74rem;
  border: 0;
  border-radius: 999rem;
  color: #ffffff;
  background: rgba(255, 255, 255, 0.08);
  font: inherit;
  font-size: 0.76rem;
  font-weight: 850;
  cursor: pointer;
}

.anipub-embedded .language-select {
  min-height: 2.15rem;
  width: 10.6rem;
  max-width: 10.6rem;
  border: 0.08rem solid rgba(255, 255, 255, 0.1);
  color: rgba(246, 243, 255, 0.94);
  background:
    linear-gradient(135deg, rgba(255, 255, 255, 0.09), rgba(255, 255, 255, 0.04)),
    rgba(28, 31, 48, 0.92);
  box-shadow: inset 0 0 0 0.04rem rgba(255, 255, 255, 0.04);
}

.language-select:is(:hover, :focus-visible, .is-tv-focused) {
  outline: 0;
  border-color: rgba(0, 210, 255, 0.28);
  background:
    linear-gradient(135deg, rgba(0, 210, 255, 0.16), rgba(181, 122, 255, 0.12)),
    rgba(18, 22, 39, 0.95);
  box-shadow: 0 0 0 0.12rem rgba(0, 210, 255, 0.1), inset 0 0 0 0.04rem rgba(255, 255, 255, 0.06);
}

.close-embedded {
  display: grid;
  flex: 0 0 auto;
  place-items: center;
  width: 2.35rem;
  height: 2.35rem;
  border: 0.08rem solid rgba(255, 255, 255, 0.12);
  border-radius: 50%;
  color: #ffffff;
  background: rgba(255, 255, 255, 0.12);
  font-size: 1.35rem;
  line-height: 1;
  cursor: pointer;
  transition: transform 180ms ease, background 180ms ease, box-shadow 180ms ease;
}

.player-dock-actions {
  display: flex;
  flex: 0 0 auto;
  align-items: center;
  gap: 0.36rem;
}

.player-source-strip {
  display: inline-flex;
  flex: 0 1 auto;
  align-items: center;
  gap: 0.32rem;
  min-width: 0;
  padding: 0.14rem;
  border: 0.08rem solid rgba(255, 255, 255, 0.08);
  border-radius: 999rem;
  background: rgba(255, 255, 255, 0.045);
}

.player-source-choice {
  min-height: 2rem;
  max-width: 8.5rem;
  padding: 0 0.72rem;
  overflow: hidden;
  border: 0.08rem solid transparent;
  border-radius: 999rem;
  color: rgba(246, 243, 255, 0.8);
  background: transparent;
  font-size: 0.72rem;
  font-weight: 950;
  text-overflow: ellipsis;
  white-space: nowrap;
  cursor: pointer;
}

.player-source-choice:is(:hover, :focus-visible, .is-tv-focused, .is-selected) {
  outline: 0;
  border-color: rgba(0, 210, 255, 0.22);
  color: #06121d;
  background: linear-gradient(135deg, #22d7ff, #f2bb46);
}

.anipub-embedded .close-embedded {
  width: auto;
  height: auto;
  min-height: 2.15rem;
  padding: 0 0.76rem;
  border-radius: 999rem;
  background: rgba(255, 255, 255, 0.075);
  font-size: 0.76rem;
  font-weight: 950;
}

.close-embedded:is(:hover, :focus-visible, .is-tv-focused) {
  transform: translateY(-0.03rem);
  outline: 0;
  background: rgba(255, 255, 255, 0.2);
  box-shadow: 0 0 0 0.16rem rgba(0, 210, 255, 0.12);
}

.anipub-embedded .close-embedded:is(:hover, :focus-visible, .is-tv-focused) {
  color: #06121d;
  background: linear-gradient(135deg, #22d7ff, #b57aff);
  box-shadow: 0 0 0 0.14rem rgba(0, 210, 255, 0.14), 0 0.7rem 1.4rem rgba(0, 210, 255, 0.16);
}

.iframe-wrapper {
  position: absolute;
  inset: 0;
  z-index: 2;
  background: #000000;
}

.anipub-embedded .iframe-wrapper {
  position: relative;
  inset: auto;
  min-height: 31rem;
  overflow: hidden;
  border: 0.08rem solid rgba(255, 255, 255, 0.08);
  border-radius: 0.74rem;
  background: #000000;
  box-shadow: 0 1rem 2rem rgba(0, 0, 0, 0.24);
}

.embedded-iframe {
  display: block;
  width: 100%;
  height: 100%;
  min-height: 30rem;
  border: 0;
  background: #000000;
}

.anipub-embedded .embedded-iframe {
  min-height: 30rem;
  max-height: none;
  border-radius: 0;
}

.player-tip {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 4;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.65rem;
  padding: 2.4rem 1rem 0.85rem;
  color: rgba(246, 243, 255, 0.76);
  background: linear-gradient(0deg, rgba(3, 5, 12, 0.9), rgba(3, 5, 12, 0));
  font-size: 0.72rem;
  font-weight: 800;
  text-align: center;
  pointer-events: none;
}

.player-tip span {
  pointer-events: auto;
}

.custom-toast {
  /* Center the toast in the viewport so it's always visible regardless of
     what is open underneath (main page, watch overlay, cinema mode, etc.).
     Previously bottom: 5rem landed inside the video player area visually. */
  position: fixed;
  left: 50%;
  top: 50%;
  bottom: auto;
  z-index: 10000;
  max-width: min(32rem, calc(100vw - 2rem));
  padding: 0.8rem 1.15rem;
  transform: translate(-50%, -50%);
  border: 0.08rem solid rgba(0, 210, 255, 0.24);
  border-radius: 999rem;
  color: #ffffff;
  background: rgba(8, 10, 19, 0.92);
  box-shadow: 0 1rem 2.4rem rgba(0, 0, 0, 0.48);
  font-weight: 900;
  text-align: center;
  backdrop-filter: blur(1rem);
  animation: slide-up 220ms ease both;
}

.custom-toast.fade-out {
  opacity: 0;
  transition: opacity 220ms ease;
}

/* Browser-native PWA recommendation. It is deliberately static/client-only:
   the card reuses the already-cached app mark and never calls an API route. */
.install-recommendation {
  position: fixed;
  right: 1.25rem;
  bottom: 1.25rem;
  z-index: 92;
  isolation: isolate;
  display: grid;
  grid-template-columns: 3.25rem minmax(0, 1fr) auto;
  align-items: center;
  gap: 0.8rem;
  width: min(27rem, calc(100vw - 2rem));
  padding: 0.9rem 2.85rem 0.9rem 0.9rem;
  overflow: hidden;
  border: 0.08rem solid rgba(151, 164, 194, 0.24);
  border-radius: 0.5rem;
  color: #f8f9ff;
  background: #111522;
  box-shadow: 0 1.1rem 2.8rem rgba(0, 0, 0, 0.48), 0 0 0 0.08rem rgba(0, 210, 255, 0.05);
  opacity: 0;
  pointer-events: none;
  transform: translateY(0.7rem);
  transition: opacity 180ms ease, transform 180ms ease;
}

.install-recommendation[hidden],
body:not([data-route="home"]) .install-recommendation,
body.watch-detail-open .install-recommendation,
body.player-cinema-open .install-recommendation,
body.has-embedded-player .install-recommendation,
body.is-tv .install-recommendation {
  display: none !important;
}

.install-recommendation.is-visible {
  opacity: 1;
  pointer-events: auto;
  transform: translateY(0);
}

.install-recommendation-accent {
  position: absolute;
  inset: 0 0 auto;
  z-index: -1;
  height: 0.18rem;
  background: linear-gradient(90deg, #00d2ff 0 42%, #8a55ff 42% 78%, #f2bb46 78%);
}

.install-recommendation-logo {
  display: block;
  width: 3.25rem;
  height: 3.25rem;
  border-radius: 0.45rem;
  object-fit: cover;
  box-shadow: 0 0.55rem 1.2rem rgba(0, 0, 0, 0.34);
}

.install-recommendation-copy {
  display: grid;
  min-width: 0;
  gap: 0.16rem;
}

.install-recommendation-kicker {
  color: #55dcf8;
  font-size: 0.61rem;
  font-weight: 950;
  line-height: 1.1;
  text-transform: uppercase;
}

.install-recommendation-copy strong {
  overflow: hidden;
  font-size: 1rem;
  line-height: 1.2;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.install-recommendation-copy small {
  color: rgba(224, 229, 243, 0.72);
  font-size: 0.73rem;
  font-weight: 650;
  line-height: 1.25;
}

.install-recommendation-action {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.38rem;
  min-height: 2.55rem;
  padding: 0 0.82rem;
  border: 0.08rem solid rgba(255, 255, 255, 0.12);
  border-radius: 0.45rem;
  color: #071019;
  background: #43d6f4;
  box-shadow: 0 0.5rem 1.1rem rgba(0, 210, 255, 0.16);
  font: inherit;
  font-size: 0.77rem;
  font-weight: 950;
  cursor: pointer;
}

.install-recommendation-action svg {
  width: 1rem;
  height: 1rem;
  flex: 0 0 auto;
}

.install-recommendation-action:is(:hover, :focus-visible) {
  background: #8beaff;
  transform: translateY(-0.08rem);
}

.install-recommendation-action:disabled {
  cursor: wait;
  opacity: 0.65;
}

.install-recommendation-close {
  position: absolute;
  top: 0.42rem;
  right: 0.42rem;
  display: grid;
  place-items: center;
  width: 2rem;
  height: 2rem;
  padding: 0;
  border: 0;
  border-radius: 50%;
  color: rgba(235, 239, 250, 0.7);
  background: transparent;
  cursor: pointer;
}

.install-recommendation-close svg {
  width: 1rem;
  height: 1rem;
}

.install-recommendation-close:is(:hover, :focus-visible) {
  color: #ffffff;
  background: rgba(255, 255, 255, 0.09);
}

.install-recommendation-hint {
  grid-column: 2 / -1;
  margin: -0.1rem 0 0;
  padding-top: 0.55rem;
  border-top: 0.08rem solid rgba(255, 255, 255, 0.08);
  color: rgba(239, 242, 252, 0.82);
  font-size: 0.74rem;
  font-weight: 700;
  line-height: 1.35;
}

body.adult-mode .install-recommendation-accent {
  background: linear-gradient(90deg, #f05cb9 0 46%, #8a55ff 46% 78%, #f2bb46 78%);
}

body.light-theme .install-recommendation {
  color: #111522;
  border-color: rgba(26, 35, 58, 0.16);
  background: #ffffff;
  box-shadow: 0 1.1rem 2.8rem rgba(28, 35, 55, 0.2);
}

body.light-theme .install-recommendation-copy small,
body.light-theme .install-recommendation-hint {
  color: rgba(28, 35, 55, 0.72);
}

body.light-theme .install-recommendation-close {
  color: rgba(28, 35, 55, 0.68);
}

@media (max-width: 760px) {
  .install-recommendation {
    right: 0.6rem;
    bottom: calc(4.55rem + env(safe-area-inset-bottom, 0px));
    left: 0.6rem;
    width: auto;
    grid-template-columns: 2.8rem minmax(0, 1fr) auto;
    gap: 0.65rem;
    padding: 0.72rem 2.55rem 0.72rem 0.72rem;
  }

  .install-recommendation-logo {
    width: 2.8rem;
    height: 2.8rem;
  }
}

@media (max-width: 360px) {
  .install-recommendation-action {
    width: 2.55rem;
    padding: 0;
  }

  .install-recommendation-action span {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
  }
}

@media (prefers-reduced-motion: reduce) {
  .install-recommendation {
    transition: none;
  }
}

body.reduce-motion .install-recommendation {
  transition: none;
}

.update-banner {
  position: fixed;
  left: 50%;
  bottom: 1.2rem;
  z-index: 10001;
  display: flex;
  align-items: center;
  gap: 0.65rem;
  max-width: min(52rem, calc(100vw - 2rem));
  padding: 0.75rem;
  border: 0.08rem solid rgba(0, 210, 255, 0.2);
  border-radius: 1rem;
  color: var(--text);
  background: linear-gradient(135deg, rgba(18, 22, 39, 0.96), rgba(9, 13, 28, 0.94));
  box-shadow: 0 1rem 2rem rgba(0, 0, 0, 0.32);
  transform: translateX(-50%);
}

.update-banner span {
  font-weight: 900;
}

.update-banner button {
  min-height: 2.25rem;
  padding: 0 0.82rem;
  border: 0.08rem solid rgba(255, 255, 255, 0.11);
  border-radius: 999rem;
  color: #ffffff;
  background: rgba(255, 255, 255, 0.08);
  font-weight: 900;
  cursor: pointer;
}

.update-banner button:is(:hover, :focus-visible, .is-tv-focused),
.update-banner.is-loading button:first-of-type {
  color: #06121d;
  background: linear-gradient(135deg, #22d7ff, #f2bb46);
}

/* Match the lightweight loader inside the current player while a source URL is
   resolving. Provider diagnostics stay out of this transient visual state. */
.ztv-stream-loader {
  display: grid;
  justify-items: center;
  gap: 0.8rem;
  color: rgba(255, 255, 255, 0.82);
}

.ztv-stream-loader > strong {
  margin: 0;
  font-size: 0.82rem;
  font-weight: 900;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.ztv-stream-loader-mark {
  position: relative;
  width: 3.6rem;
  height: 3.6rem;
}

.ztv-stream-loader-mark::after {
  content: "Z";
  position: absolute;
  inset: 0.68rem;
  display: grid;
  place-items: center;
  border-radius: 50%;
  color: #ffffff;
  background: rgba(17, 20, 34, 0.9);
  font-size: 0.9rem;
  font-weight: 950;
  box-shadow: 0 0 1.6rem rgba(139, 92, 246, 0.36);
}

.ztv-stream-loader-mark > span {
  position: absolute;
  inset: 0;
  border: 0.18rem solid transparent;
  border-top-color: #8a5cff;
  border-right-color: #30cde8;
  border-radius: 50%;
  animation: ztv-stream-loader-spin 0.82s linear infinite;
}

.ztv-stream-loader-mark > span + span {
  inset: 0.42rem;
  border-top-color: #f01f60;
  border-right-color: transparent;
  animation-duration: 1.12s;
  animation-direction: reverse;
}

@keyframes ztv-stream-loader-spin {
  to { transform: rotate(360deg); }
}

.episode-video-empty.is-loading .play-symbol {
  animation: player-spin 900ms linear infinite;
}

@keyframes player-spin {
  to {
    transform: rotate(360deg);
  }
}

@keyframes slide-up {
  from {
    opacity: 0;
    /* start slightly below center and rise into position */
    transform: translate(-50%, calc(-50% + 1.2rem));
  }
  to {
    opacity: 1;
    transform: translate(-50%, -50%);
  }
}

@keyframes footer-aurora {
  0%,
  100% {
    background-position: 0% 50%, center, center;
    opacity: 0.78;
  }
  50% {
    background-position: 100% 50%, center, center;
    opacity: 1;
  }
}

@keyframes footer-line-flow {
  0%,
  100% {
    background-position: 0% 50%;
  }
  50% {
    background-position: 100% 50%;
  }
}

@keyframes footer-dot-pulse {
  0%,
  100% {
    transform: scale(0.92);
    box-shadow:
      0 0 0 0.36rem rgba(0, 210, 255, 0.07),
      0 0 1rem rgba(0, 210, 255, 0.24);
  }
  50% {
    transform: scale(1.08);
    box-shadow:
      0 0 0 0.5rem rgba(242, 187, 70, 0.08),
      0 0 1.45rem rgba(0, 210, 255, 0.38);
  }
}

@keyframes logo-halo-spin {
  to {
    transform: rotate(360deg);
  }
}

.cast-message {
  max-width: 34rem;
}

.cast-mini-poster {
  width: 5.2rem;
  aspect-ratio: 2 / 3;
  border-radius: var(--radius-sm);
  object-fit: cover;
  box-shadow: 0 0.9rem 1.6rem rgba(0, 0, 0, 0.36);
}

.cast-toast {
  position: absolute;
  left: 50%;
  bottom: 1.25rem;
  z-index: 4;
  transform: translateX(-50%);
  width: min(28rem, calc(100% - 2rem));
  padding: 0.75rem 1rem;
  border: 0.08rem solid rgba(0, 210, 255, 0.28);
  border-radius: 999rem;
  color: #ffffff;
  text-align: center;
  font-weight: 900;
  background: rgba(12, 13, 28, 0.82);
  box-shadow: 0 1rem 2rem rgba(0, 0, 0, 0.34);
  backdrop-filter: blur(1rem);
}

.iframe-cast-guide {
  position: absolute;
  left: 1rem;
  right: 1rem;
  bottom: 1rem;
  z-index: 5;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto auto;
  align-items: center;
  gap: 0.72rem;
  padding: 0.82rem;
  border: 0.08rem solid rgba(0, 210, 255, 0.22);
  border-radius: 1rem;
  color: #ffffff;
  background:
    linear-gradient(135deg, rgba(17, 20, 38, 0.94), rgba(8, 11, 24, 0.9)),
    rgba(8, 10, 19, 0.92);
  box-shadow: 0 1rem 2.2rem rgba(0, 0, 0, 0.36), inset 0 0 0 0.08rem rgba(255, 255, 255, 0.035);
  backdrop-filter: blur(1rem);
}

.iframe-cast-icon {
  display: grid;
  place-items: center;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 0.8rem;
  color: #06121d;
  background: linear-gradient(135deg, #22d7ff, #f2bb46);
  font-weight: 950;
}

.iframe-cast-guide strong {
  display: block;
  font-size: 0.95rem;
  font-weight: 950;
}

.iframe-cast-guide p {
  margin: 0.12rem 0 0;
  color: rgba(246, 243, 255, 0.72);
  font-size: 0.76rem;
  font-weight: 800;
  line-height: 1.25;
}

.iframe-cast-guide button {
  min-height: 2.3rem;
  padding: 0 0.88rem;
  border: 0.08rem solid rgba(255, 255, 255, 0.12);
  border-radius: 999rem;
  color: rgba(246, 243, 255, 0.94);
  background: rgba(255, 255, 255, 0.08);
  font-weight: 900;
  cursor: pointer;
}

.iframe-cast-guide button:is(:hover, :focus-visible, .is-tv-focused) {
  outline: 0;
  color: #06121d;
  background: linear-gradient(135deg, #22d7ff, #f2bb46);
  box-shadow: 0 0.6rem 1.4rem rgba(0, 210, 255, 0.16);
}

.external-play-button {
  min-height: var(--control-h-md);
  padding: 0 1.15rem;
  border-radius: 999rem;
  color: #ffffff;
  background:
    linear-gradient(135deg, rgba(138, 92, 255, 0.86), rgba(0, 210, 255, 0.62)),
    rgba(255, 255, 255, 0.08);
  box-shadow: 0 0.75rem 1.4rem rgba(0, 0, 0, 0.22), inset 0 1px 0 rgba(255, 255, 255, 0.18);
  font-weight: 950;
  cursor: pointer;
  transition: transform 180ms ease, box-shadow 180ms ease, filter 180ms ease;
}

.external-play-button:is(:hover, :focus-visible, .is-tv-focused) {
  transform: translateY(-0.04rem);
  filter: brightness(1.08);
  outline: 0;
  box-shadow:
    0 0 0 0.16rem rgba(0, 210, 255, 0.18),
    0 0.9rem 1.7rem rgba(0, 0, 0, 0.26),
    inset 0 1px 0 rgba(255, 255, 255, 0.22);
}

.external-confirm,
.external-error {
  display: grid;
  gap: 0.8rem;
  width: min(100%, 32rem);
  padding: 1rem;
  border: 0.08rem solid rgba(255, 255, 255, 0.12);
  border-radius: var(--radius-lg);
  background: rgba(8, 10, 19, 0.72);
}

.external-confirm[hidden],
.external-error[hidden] {
  display: none;
}

.external-confirm p,
.external-error p {
  margin: 0;
  color: rgba(246, 243, 255, 0.82);
  font-weight: 750;
}

.external-confirm-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.65rem;
  justify-content: center;
}

@media (max-width: 1150px) {
  .topbar {
    grid-template-columns: 1fr;
    gap: 1rem;
  }

  .app-shell {
    padding-top: 14.5rem;
  }

  .main-nav {
    overflow-x: auto;
    padding-bottom: 0.2rem;
  }

  .poster-grid {
    grid-template-columns: repeat(4, minmax(9.5rem, 1fr));
  }

  .hero {
    grid-template-columns: 1fr;
  }

  .today-carousel {
    grid-template-columns: 3.2rem minmax(0, 1fr) 3.2rem;
  }

.schedule-list {
    grid-template-columns: 1fr;
  }

  .source-list {
    grid-template-columns: 1fr;
  }

  .settings-grid {
    grid-template-columns: 1fr;
  }

  .settings-grid:has(.settings-rail) {
    grid-template-columns: 1fr;
  }

  .settings-rail {
    position: relative;
    top: auto;
    grid-auto-flow: column;
    grid-auto-columns: minmax(8rem, 1fr);
    min-height: auto;
    overflow-x: auto;
    border-right: 0;
    border-bottom: 0.08rem solid rgba(255, 255, 255, 0.06);
  }

  .settings-version {
    display: none;
  }

  .settings-console {
    max-height: none;
  }
}

@media (max-width: 760px) {
  .topbar {
    padding: 1rem;
  }

  .app-shell {
    padding-top: 14.5rem;
  }

  main {
    --page-gutter: 1rem;
    padding: 1.5rem var(--page-gutter) 3rem;
  }

  .hero {
    grid-template-columns: 1fr;
    min-height: clamp(21rem, 52vh, 26rem);
  }

  .today-carousel {
    grid-template-columns: 1fr;
  }

  .carousel-stage {
    grid-template-columns: minmax(8rem, 12rem) 1fr;
    min-height: 20rem;
    padding: 0.9rem;
  }

  .watch-panel {
    grid-template-columns: 1fr;
    width: 100%;
    height: auto;
    max-height: calc(100dvh - 1.5rem);
    overflow-y: auto;
    overflow-x: hidden;
  }

  /* On mobile the panel stacks vertically (player then episodes/sources).
     Desktop fixed-height + top-margin + overflow:hidden would clip the side panel
     to ~0px on mobile. Force it to size to content and let the watch-panel scroll.
     (.watch-overlay ancestor out-specifies the later base .watch-side rule.) */
  .watch-overlay .watch-side {
    margin: 0;
    height: auto;
    max-height: none;
    border-radius: 0.8rem;
    overflow: visible;
  }

  /* The desktop episode panel fills a fixed-height side column via flex:1 +
     overflow:hidden. On mobile the side is auto-height, so that whole chain
     collapsed every pane to ~0px and the episodes vanished. Size the entire
     chain to its content instead and let the watch-panel be the single scroller.
     (The base .watch-side rules come later in the source, so we out-specify them
     with the .watch-overlay ancestor.) */
  .watch-overlay .watch-side .episode-list {
    flex: 0 0 auto;
    height: auto;
    max-height: none;
    overflow: visible;
  }
  .watch-overlay .watch-side .detail-pane.is-active {
    flex: 0 0 auto;
    min-height: auto;
    overflow: visible;
  }
  .watch-overlay .watch-side .detail-pane.is-active .ep-rows,
  .watch-overlay .watch-side .season-card-grid {
    max-height: none;
    overflow: visible;
  }

  /* Keep long localized episode names inside the phone panel. The desktop
     7rem thumbnail plus intrinsic text width could push the second grid track
     past the viewport before line clamping was applied. */
  .watch-overlay .watch-side .ep-row {
    grid-template-columns: clamp(5.6rem, 29vw, 6.75rem) minmax(0, 1fr);
    gap: 0.65rem;
    padding: 0.4rem 0.15rem;
    overflow: hidden;
  }
  .watch-overlay .watch-side .ep-row-body {
    width: 100%;
    max-width: 100%;
    overflow: hidden;
  }
  .watch-overlay .watch-side .ep-row-title {
    width: 100%;
    max-width: 100%;
    overflow-wrap: anywhere;
  }
  .watch-overlay .watch-side .ep-row-meta {
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .watch-info {
    overflow-y: visible;
    padding: 0.5rem 0.5rem 1rem 0.5rem;
  }

  .player-controls-bar {
    align-items: flex-start;
    flex-direction: column;
    padding: 0.85rem;
    background: rgba(3, 5, 12, 0.9);
  }

  .anipub-embedded .player-controls-bar {
    inset: auto;
    grid-template-columns: 1fr;
    align-items: stretch;
    padding: 0.62rem;
    border-radius: 1rem;
    background:
      linear-gradient(135deg, rgba(18, 20, 35, 0.88), rgba(7, 11, 23, 0.78)),
      rgba(8, 10, 19, 0.74);
  }

  .episode-info strong {
    max-width: calc(100vw - 8rem);
  }

  .anipub-embedded .episode-info {
    flex-wrap: wrap;
  }

  .language-selector {
    justify-content: flex-start;
    border-radius: 1.1rem;
  }

  .anipub-embedded .language-selector {
    justify-content: stretch;
    max-width: none;
  }

  .anipub-embedded .language-select {
    flex: 1 1 9.5rem;
    width: auto;
    max-width: none;
  }

  .player-episode-actions {
    overflow-x: auto;
    padding-bottom: 0.65rem;
  }

  .vidstream-player,
  .vidstream-player.is-iframe {
    grid-template-columns: 1fr;
    grid-template-areas:
      "stage"
      "actions";
    padding: 0.58rem;
  }

  .vid-player-stage,
  .video-frame .vid-player-stage video,
  .video-frame .vid-player-stage iframe,
  .vidstream-player.is-iframe .vid-player-stage {
    min-height: min(62vw, 26rem);
  }

  .player-inline-prefs {
    position: relative;
    left: auto;
    right: auto;
    bottom: auto;
    margin: 0.65rem;
    padding: 0.55rem;
    border-radius: 0.9rem;
    background: rgba(8, 10, 19, 0.66);
  }

  .player-stream-toolbar {
    grid-template-columns: 1fr;
    gap: 0.55rem;
  }

  .player-stream-toolbar .language-selector {
    justify-content: stretch;
    flex-wrap: wrap;
  }

  .player-stream-toolbar .language-select {
    flex: 1 1 10rem;
    width: 100%;
    max-width: none;
  }

  .player-episode-actions,
  .player-episode-actions:has(.player-download-action:not(:disabled)) {
    grid-template-columns: 1fr;
  }

  /* cinema mode is already fully absolute-positioned — no responsive overrides needed */

  .vid-controls {
    padding-bottom: max(0.72rem, env(safe-area-inset-bottom));
  }

  .vid-control-row {
    overflow-x: auto;
    padding-bottom: 0.15rem;
  }

  .vid-timeline {
    gap: 0.5rem;
  }

  .vid-timeline .vid-time {
    font-size: 0.76rem;
  }

  /* Stack label over control with flexbox so the row GROWS to fit its content.
     (As a 1-col grid it stayed pinned at min-height: 3.4rem, so the control
     overflowed and overlapped the next setting on phones.) */
  .settings-line {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 0.5rem;
    min-height: auto;
    padding-top: 0.6rem;
    padding-bottom: 0.6rem;
  }

  .settings-line > span { min-width: 0; }

  .settings-select,
  .settings-switch,
  .settings-status-pill,
  .settings-segment {
    justify-self: start;
    width: 100%;
  }

  .player-nav-action,
  .player-download-action,
  .player-cast-action {
    flex: 0 0 auto;
  }

  .player-language-bar {
    grid-template-columns: 1fr;
    align-items: flex-start;
    overflow: visible;
  }

  .player-tip {
    flex-wrap: wrap;
  }
}
.today-carousel {
  position: relative;
  z-index: 2;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  align-items: center;
  gap: 0;
  min-width: 0;
}

.carousel-stage {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: 1fr;
  align-items: start;
  gap: 0;
  /* Large, immersive "full screen" hero. Taller also means the 16:9 backdrop is
     closer to the hero's aspect on a normal display, so cover crops very little. */
  min-height: min(82vh, 56.25vw);
  height: auto;
  padding: clamp(1rem, 2.4vw, 2.4rem) clamp(1.6rem, 5vw, 5.5rem) 6.2rem;
  border-radius: 0;
  overflow: hidden;
  border: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
  cursor: pointer;
  transition: transform 220ms ease, border-color 220ms ease, box-shadow 220ms ease;
  animation: carousel-enter 520ms ease both;
}

.carousel-stage.is-loading {
  grid-template-columns: minmax(0, 1fr);
  align-items: center;
  /* No min-height here on purpose. The skeleton must reserve exactly the space
     the loaded carousel will occupy, and .carousel-stage resolves to three
     different heights - min(82vh,56.25vw) at base, 30rem under 1150px, 31rem
     under 760px. Any literal value here matches at most one breakpoint; this
     used to be clamp(31rem,66vh,46rem), which moved the content below the hero
     by +173px at 1920x1080 and -196px at 768px wide. Inheriting is the only
     value that is zero-delta at every width, and it stays correct if a
     breakpoint is ever retuned. */
  gap: 0;
  cursor: default;
}

.carousel-stage::before {
  display: none;
  content: none;
}

.carousel-stage:is(:hover, :focus-visible, .is-tv-focused) {
  box-shadow:
    inset 0 0 0 0.08rem rgba(255, 255, 255, 0.04);
  transform: none;
}

.carousel-backdrop,
.carousel-backdrop-image {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  background: linear-gradient(135deg, #58a8ff, #ef5bb8 52%, #f2bb46);
  background-position: center center;
  background-size: cover;
  background-repeat: no-repeat;
  opacity: 1;
  filter: none;
  transform: none;
  transition: opacity 180ms ease;
}

.carousel-backdrop-image {
  display: block;
  color: transparent;
  background: none;
  /* Full-bleed cover so the hero fills the screen edge-to-edge ("full screen").
     The crop is biased upward (center 30%) so characters' faces are kept — anime
     backdrops frame their subjects in the upper-middle, so the bottom (floor/legs)
     is what gets trimmed on screens wider than 16:9. The taller hero below keeps
     the crop small on standard displays. */
  object-fit: cover;
  object-position: center 30%;
}

/* Keep loading cheap and visually quiet. The backdrop div is an app-colored
   surface; only the sharp image layer ever receives artwork. */
.carousel-stage.is-backdrop-loading .carousel-backdrop {
  filter: none;
  transform: none;
}
.carousel-stage.is-backdrop-loading .carousel-backdrop-image { opacity: 0; }

/* Conceal the brief decode handoff behind the same neutral hero surface. A
   single edge-to-edge rail communicates progress without changing the carousel
   layout or introducing a second card/skeleton design. */
.carousel-wait {
  position: absolute;
  inset: 0;
  z-index: 2;
  box-sizing: border-box;
  display: block;
  overflow: hidden;
  visibility: hidden;
  opacity: 0;
  pointer-events: none;
  background: linear-gradient(105deg, #070914 0%, #090d16 54%, #0d1721 100%);
  transition: opacity 160ms ease, visibility 0s linear 160ms;
}

.carousel-stage:is(.is-loading, .is-backdrop-loading) .carousel-wait {
  visibility: visible;
  opacity: 1;
  transition-delay: 0s;
}

.carousel-wait-mark {
  display: none;
}

.carousel-wait-track {
  position: absolute;
  right: 0;
  bottom: 0;
  left: 0;
  width: 100%;
  height: 0.16rem;
  overflow: hidden;
  border-radius: 0;
  background:
    linear-gradient(90deg, transparent, #8a5cff 44%, #30cde8 56%, transparent) 0 0 / 28% 100% no-repeat,
    rgba(255, 255, 255, 0.055);
  animation: calm-loader-track 1.15s cubic-bezier(0.65, 0, 0.35, 1) infinite;
}

.carousel-stage.is-backdrop-loading .carousel-indicators {
  visibility: hidden;
  opacity: 0;
  pointer-events: none;
}

/* A blurred PREVIEW of the slide while its full-resolution backdrop loads - the
   same effect as the anime detail page. It is a small copy of the same artwork,
   never the 4K file itself (see showCarouselBlurPlaceholder), and it exists only
   while loading: once the sharp image is revealed the class goes and the image is
   dropped, so it never becomes a permanent full-screen blurred surface. The
   stage already clips overflow, so the inset bleed hides the soft blur edge. */
.carousel-backdrop-blur {
  position: absolute;
  inset: -6%;
  background-color: transparent;
  background-position: center 30%;
  background-size: cover;
  background-repeat: no-repeat;
  filter: blur(26px) saturate(1.2) brightness(0.82);
  transform: scale(1.06);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 360ms ease, visibility 0s linear 360ms;
}

.carousel-stage.has-blur-placeholder .carousel-backdrop-blur {
  opacity: 1;
  visibility: visible;
  transition-delay: 0s;
}

/* The wait surface is opaque so that a half-decoded image never shows. With a
   finished preview beneath it there is nothing left to hide, so let the preview
   through and keep only the progress rail. */
.carousel-stage.has-blur-placeholder .carousel-wait {
  background: transparent;
}

.carousel-backdrop.has-banner {
  background-position: center center;
  background-size: cover;
}
.carousel-backdrop-image.has-banner {
  background-position: center center;
  image-rendering: auto;
}



.carousel-stage::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background:
    radial-gradient(circle at 78% 34%, rgba(255, 255, 255, 0.06), transparent 22rem),
    linear-gradient(90deg, rgba(8, 10, 19, 0.96) 0%, rgba(8, 10, 19, 0.8) 30%, rgba(8, 10, 19, 0.3) 60%, rgba(8, 10, 19, 0.08) 100%),
    linear-gradient(0deg, var(--bg) 0%, rgba(8, 10, 19, 0.56) 14%, transparent 54%),
    linear-gradient(180deg, rgba(8, 10, 19, 0.1) 0%, transparent 35%);
}

.hero-motion {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  overflow: hidden;
  display: none;
  opacity: 0;
}

.hero-motion span {
  position: absolute;
  width: 18rem;
  height: 0.12rem;
  border-radius: 999rem;
  background: linear-gradient(90deg, transparent, rgba(64, 223, 194, 0.56), transparent);
  filter: blur(0.04rem);
  animation: hero-light-streak 5.8s ease-in-out infinite;
}

.hero-motion span:nth-child(1) {
  top: 26%;
  left: -20rem;
}

.hero-motion span:nth-child(2) {
  top: 48%;
  left: -25rem;
  animation-delay: 1.7s;
  background: linear-gradient(90deg, transparent, rgba(239, 91, 184, 0.5), transparent);
}

.hero-motion span:nth-child(3) {
  top: 68%;
  left: -18rem;
  animation-delay: 3.1s;
  background: linear-gradient(90deg, transparent, rgba(245, 227, 107, 0.42), transparent);
}

.carousel-info {
  position: relative;
  z-index: 3;
  min-height: 14rem;
}

.carousel-poster-wrap {
  display: none !important;
}

.carousel-poster-wrap::before {
  content: "";
  position: absolute;
  inset: -1rem;
  z-index: 0;
  border-radius: 1.25rem;
  background:
    radial-gradient(circle at 50% 50%, rgba(0, 210, 255, 0.28), transparent 64%),
    linear-gradient(135deg, rgba(138, 92, 255, 0.3), rgba(0, 210, 255, 0.24));
  filter: blur(20px);
  opacity: 0.78;
}

.carousel-poster-wrap::after {
  content: "";
  position: absolute;
  inset: -0.32rem;
  z-index: 2;
  padding: 0.12rem;
  border-radius: 1.05rem;
  background: linear-gradient(135deg, rgba(255, 255, 255, 0.54), rgba(0, 210, 255, 0.72) 38%, rgba(138, 92, 255, 0.58));
  opacity: 0.62;
  pointer-events: none;
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude;
}

.carousel-poster {
  position: relative;
  z-index: 3;
  width: 100%;
  height: 100%;
  border: 0.1rem solid rgba(255, 255, 255, 0.32);
  border-radius: 0.9rem;
  object-fit: cover;
  object-position: center top;
  image-rendering: auto;
  box-shadow:
    0 2.4rem 4.4rem rgba(0, 0, 0, 0.62),
    0 0 0 0.08rem rgba(255, 255, 255, 0.12),
    inset 0 0 0 0.08rem rgba(255, 255, 255, 0.12);
  filter: saturate(1.12) contrast(1.08) brightness(1.02);
  transition: transform 320ms ease, filter 320ms ease;
}

.carousel-stage:is(:hover, :focus-visible, .is-tv-focused) .carousel-poster {
  transform: scale(1.035);
  filter: saturate(1.18) contrast(1.1) brightness(1.05);
}

.carousel-stage.is-loading:is(:hover, :focus-visible, .is-tv-focused) .carousel-poster {
  transform: none;
}

.carousel-stage.is-loading .carousel-poster-wrap {
  align-self: center;
  justify-self: end;
  width: min(100%, 23rem);
  opacity: 0.72;
  transform: none;
}

.carousel-stage.is-loading .carousel-poster-wrap::before {
  inset: -0.55rem;
  filter: blur(12px);
  opacity: 0.42;
}

.carousel-stage.is-loading .carousel-poster-wrap::after {
  border-radius: 0.82rem;
  opacity: 0.38;
}

.carousel-stage.is-loading .carousel-poster-skeleton {
  width: 100%;
  height: 100%;
  border-radius: 0.9rem;
  border: 0.1rem solid rgba(255, 255, 255, 0.12);
  box-shadow:
    0 2.4rem 4.4rem rgba(0, 0, 0, 0.52),
    0 0 0 0.08rem rgba(0, 210, 255, 0.08);
}

.carousel-stage.is-loading .carousel-info {
  align-self: center;
  justify-self: start;
  max-width: min(46rem, 62vw);
  padding-left: 0;
  transform: translateY(0);
}

.carousel-stage.is-loading .carousel-info h2 {
  font-size: clamp(1.55rem, 2.6vw, 2.6rem);
}

.carousel-stage.is-loading .carousel-info p:not(.eyebrow) {
  max-width: 40rem;
}

.carousel-stage.is-loading .carousel-meta-line {
  width: fit-content;
}

.carousel-stage.is-loading .play-action {
  display: none;
}

.carousel-stage.is-loading .carousel-indicators {
  display: none;
}

.carousel-stage:is(:hover, :focus-visible, .is-tv-focused) .carousel-poster-wrap::before {
  opacity: 0.95;
  filter: blur(22px);
}

.carousel-info {
  grid-column: 1;
  grid-row: 1;
  display: grid;
  align-self: center;
  grid-template-rows: auto auto auto auto auto;
  gap: 0.85rem;
  padding-top: 0.15rem;
  min-width: 0;
  max-width: min(46rem, 62vw);
  height: auto;
  max-height: none;
  padding: 0;
  transition: transform 300ms ease, opacity 250ms ease;
}

.carousel-info h2 {
  align-self: start;
  min-height: 0;
  margin: 0;
  padding-bottom: 0.18rem;
  font-size: clamp(1.55rem, 3.1vw, 3.1rem);
  line-height: 1;
  letter-spacing: 0;
  display: -webkit-box;
  overflow: hidden;
  overflow-wrap: anywhere;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  text-shadow: 0 1rem 2.2rem rgba(0, 0, 0, 0.46);
  transition: color 220ms ease, text-shadow 220ms ease, transform 220ms ease;
}

.carousel-stage:is(:hover, :focus-visible, .is-tv-focused) .carousel-info h2 {
  color: #ffffff;
  transform: translateY(-0.12rem);
  text-shadow: 0 1rem 2.4rem rgba(0, 0, 0, 0.58), 0 0 1.4rem rgba(64, 223, 194, 0.18);
}

.carousel-info p:not(.eyebrow) {
  position: relative;
  display: -webkit-box;
  max-width: 40rem;
  margin: 0;
  overflow: hidden;
  color: #e2def0;
  font-size: clamp(1.05rem, 1.3vw, 1.24rem);
  line-height: 1.5;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow-wrap: anywhere;
  mask-image: linear-gradient(180deg, #000 72%, transparent 100%);
}

.carousel-meta-line {
  display: block;
  color: rgba(255, 255, 255, 0.78);
  font-size: 0.88rem;
  font-weight: 900;
}

.carousel-stage.is-changing .carousel-info {
  animation: carousel-slide-next 240ms ease-out both;
}

.carousel-stage.is-changing.is-prev .carousel-info {
  animation-name: carousel-slide-prev;
}

.carousel-stage.is-changing .carousel-backdrop {
  animation: none;
}

.carousel-indicators {
  position: absolute;
  left: clamp(2rem, 5vw, 5.2rem);
  right: clamp(2rem, 5vw, 5.2rem);
  bottom: 1.2rem;
  z-index: 4;
  display: flex;
  gap: 0.55rem;
  align-items: center;
  overflow-x: auto;
  padding: 0.35rem 0;
  scrollbar-width: none;
  mask-image: linear-gradient(90deg, transparent 0, #000 1rem, #000 calc(100% - 1rem), transparent 100%);
  transition: opacity 160ms ease, visibility 160ms ease;
}

.carousel-indicators[hidden] {
  display: none !important;
}

.carousel-indicators::-webkit-scrollbar {
  display: none;
}

.carousel-dot {
  flex: 0 0 auto;
  width: 7.2rem;
  height: 4.05rem;
  padding: 0;
  overflow: hidden;
  border: 0.12rem solid rgba(255, 255, 255, 0.14);
  border-radius: 0.55rem;
  background: rgba(255, 255, 255, 0.06);
  cursor: pointer;
  transition: transform 140ms ease, border-color 140ms ease, box-shadow 140ms ease, opacity 140ms ease;
  opacity: 0.7;
}

.carousel-dot img,
.carousel-dot span {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Placeholder shown until the mini thumbnail hydrates: a soft branded gradient
   with a travelling sheen so the strip reads as "loading" instead of as flat
   coloured blocks. */
.carousel-dot span {
  position: relative;
  overflow: hidden;
  background: linear-gradient(135deg, color-mix(in srgb, var(--cyan) 55%, #10142a), color-mix(in srgb, var(--rose) 55%, #10142a));
}

.carousel-dot span::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.28), transparent);
  animation: skeleton-sheen 1.35s ease-in-out infinite;
}

/* Fade the real artwork in so it never pops in hard. */
.carousel-dot img {
  animation: carousel-dot-fade 320ms ease both;
}

@keyframes carousel-dot-fade {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

@media (prefers-reduced-motion: reduce) {
  .carousel-dot span::after {
    animation: none;
  }
  .carousel-dot img {
    animation: none;
  }
}

.carousel-dot:is(:hover, :focus-visible, .is-tv-focused, .is-selected) {
  transform: translateY(-0.1rem) scale(1.04);
  border-color: rgba(255, 255, 255, 0.88);
  box-shadow: 0 0.5rem 1.4rem rgba(0, 0, 0, 0.35), 0 0 0 0.15rem rgba(0, 210, 255, 0.22);
  opacity: 1;
}

@keyframes carousel-slide-next {
  0% {
    opacity: 0.35;
    transform: translateX(0.7rem);
  }
  100% {
    opacity: 1;
    transform: translateX(0);
  }
}

@keyframes carousel-slide-prev {
  0% {
    opacity: 0.35;
    transform: translateX(-0.7rem);
  }
  100% {
    opacity: 1;
    transform: translateX(0);
  }
}

@keyframes backdrop-drift {
  0% {
    opacity: 0.55;
    transform: scale(1.08);
  }
  100% {
    opacity: 0.94;
    transform: scale(1.04);
  }
}

@keyframes hero-backdrop-pan {
  0% {
    background-position: 48% 50%;
    transform: scale(1.005);
  }
  100% {
    background-position: 52% 50%;
    transform: scale(1.035);
  }
}

@keyframes hero-light-streak {
  0%, 18% {
    transform: translateX(0);
    opacity: 0;
  }
  36% {
    opacity: 1;
  }
  72%, 100% {
    transform: translateX(calc(100vw + 30rem));
    opacity: 0;
  }
}

@keyframes ambient-sweep {
  0% {
    transform: translate3d(-2%, -1%, 0) scale(1);
  }
  100% {
    transform: translate3d(2%, 1%, 0) scale(1.04);
  }
}

@keyframes topbar-enter {
  0% {
    opacity: 0;
    transform: translateY(-1rem);
  }
  100% {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes rise-in {
  0% {
    opacity: 0;
    transform: translateY(1rem);
  }
  100% {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes loader-spin {
  to {
    transform: rotate(360deg);
  }
}

@keyframes loader-fill {
  0% {
    background-position: 120% 50%;
    opacity: 0.45;
  }
  50% {
    opacity: 1;
  }
  100% {
    background-position: -60% 50%;
    opacity: 0.45;
  }
}

@keyframes loader-breathe {
  0%,
  100% {
    transform: scale(1);
    filter: brightness(1);
  }
  50% {
    transform: scale(1.035);
    filter: brightness(1.12);
  }
}

@keyframes neko-ear-twitch {
  0%,
  72%,
  100% {
    transform: rotate(0deg) scale(1);
  }
  78% {
    transform: rotate(-2deg) scale(1.015);
  }
  84% {
    transform: rotate(2deg) scale(1.015);
  }
  90% {
    transform: rotate(0deg) scale(1);
  }
}

@keyframes section-dot-glow {
  0%,
  100% {
    transform: scale(1);
    opacity: 0.82;
  }
  50% {
    transform: scale(1.04);
    opacity: 1;
  }
}

@keyframes card-rise {
  0% {
    opacity: 0;
    transform: translateY(0.8rem) scale(0.985);
  }
  100% {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

@keyframes skeleton-sheen {
  0% {
    transform: translateX(-100%);
  }
  100% {
    transform: translateX(100%);
  }
}

@keyframes carousel-enter {
  0% {
    opacity: 0;
    transform: translateY(1.2rem) scale(0.985);
  }
  100% {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

@keyframes overlay-fade {
  0% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}

@keyframes overlay-fade-out {
  0% {
    opacity: 1;
  }
  100% {
    opacity: 0;
  }
}

@keyframes modal-rise {
  0% {
    opacity: 0;
    transform: translateY(1.2rem) scale(0.985);
  }
  100% {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

@keyframes modal-fall {
  0% {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
  100% {
    opacity: 0;
    transform: translateY(1.2rem) scale(0.985);
  }
}

.watch-overlay.is-closing {
  animation: overlay-fade-out 200ms ease both;
}
.watch-overlay.is-closing .watch-panel {
  animation: modal-fall 200ms ease both;
}
body.reduce-motion .watch-overlay.is-closing,
body.reduce-motion .watch-overlay.is-closing .watch-panel {
  animation: none !important;
}

@keyframes play-pulse {
  0% {
    opacity: 0;
    transform: scale(0.4);
  }
  35% {
    opacity: 1;
  }
  100% {
    opacity: 0;
    transform: scale(1.35);
  }
}

@keyframes poster-float {
  0%, 100% {
    transform: translateY(0) rotate(-0.25deg);
  }
  50% {
    transform: translateY(-0.55rem) rotate(0.25deg);
  }
}

@keyframes poster-aura {
  0% {
    opacity: 0.55;
    transform: scale(0.98);
  }
  100% {
    opacity: 0.9;
    transform: scale(1.04);
  }
}

@keyframes poster-border-flow {
  0% {
    filter: hue-rotate(0deg);
  }
  100% {
    filter: hue-rotate(40deg);
  }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    scroll-behavior: auto !important;
    transition-duration: 1ms !important;
  }
}

@media (max-width: 1150px) {
  .hero {
    min-height: auto;
  }

  .hero h1 {
    min-height: 0;
  }

  .carousel-stage {
    height: 31rem;
    min-height: 31rem;
  }
}

@media (max-width: 760px) {
  .carousel-stage {
    grid-template-columns: 1fr;
    /* Fixed height (matches the inline critical CSS exactly) so the
       is-loading -> loaded transition and slide changes never resize the hero
       and shove the rails below it. height == min-height keeps CLS ~0, so this
       value and the one inlined in index.html must always be changed together.
       Was a flat 31rem, which on a phone left no room for the first content row;
       the clamp caps it at the old-ish 26rem on tall screens and shrinks it on
       short ones, with a 21rem floor so the hero content can never be crushed.
       vh (not dvh) on purpose - it does not move when the URL bar hides. */
    height: clamp(21rem, 52vh, 26rem);
    min-height: clamp(21rem, 52vh, 26rem);
  }

  .carousel-info {
    max-width: 100%;
    padding-bottom: 1.8rem;
  }

  .source-status {
    right: 1.4rem;
  }

  .carousel-info h2 {
    font-size: 1.85rem;
    line-height: 1;
  }

  .carousel-poster-wrap {
    display: none;
  }
}

@media (max-width: 1150px) {
  .app-shell {
    padding: 0 0 0 5.35rem;
  }

  .topbar {
    top: 0;
    right: auto;
    bottom: 0;
    left: 0;
    width: 5.35rem;
    min-height: 100vh;
    grid-template-columns: 1fr;
    grid-template-rows: auto 1fr auto;
    padding: 1rem 0.7rem;
  }

  .main-nav {
    display: grid;
    overflow: visible;
    padding-bottom: 0;
  }

  .poster-grid {
    grid-auto-flow: column;
    grid-auto-columns: clamp(10.5rem, 24vw, 14rem);
    grid-template-columns: none;
  }

  .rail-shell .poster-grid {
    grid-auto-columns: calc((100% - (3 * var(--rail-gap))) / 4);
  }

  .today-carousel {
    grid-template-columns: 1fr;
  }

  .carousel-stage {
    height: auto;
    min-height: 30rem;
    padding-bottom: 5.8rem;
  }
}

@media (max-width: 760px) {
  .app-shell {
    padding-left: 5rem;
    padding-top: 0;
  }

  main {
    --page-gutter: 0.8rem;
    padding: 1rem var(--page-gutter) 1.5rem;
  }

  .bottom-bar,
  body.sidebar-collapsed .bottom-bar {
    margin-left: -5rem;
    margin-bottom: calc(-1 * var(--footer-bleed));
    padding-left: calc(5rem + 0.8rem);
    padding-right: 0.8rem;
    padding-top: 1.65rem;
    padding-bottom: calc(1.65rem + env(safe-area-inset-bottom));
  }

  .footer-status {
    max-width: 70vw;
    text-align: center;
  }

  .bottom-bar::before,
  body.sidebar-collapsed .bottom-bar::before {
    left: 5rem;
  }

  .topbar {
    width: 5rem;
  }

  .nav-link {
    min-height: 4rem;
    font-size: 0.62rem;
  }

  .carousel-stage {
    min-height: clamp(21rem, 52vh, 26rem);
    padding: 2rem 1.2rem 5.7rem;
  }
}

/* Final TV layout polish: keep library filters compact and blended. */
#library {
  padding-top: 0;
}

#library .section-heading {
  gap: 0.75rem;
  min-height: 3.25rem;
  margin-bottom: 0;
}

#library .section-heading h2 {
  font-size: clamp(1.35rem, 1.7vw, 1.9rem);
}

#library .library-dot {
  width: 1.1rem;
  height: 1.1rem;
  box-shadow: 0 0 0 0.42rem rgba(64, 223, 194, 0.12);
}

#library .library-filter-panel {
  display: grid;
  gap: 1rem;
  max-width: min(74rem, calc(100vw - 10rem));
  margin: 0.15rem 0 1.2rem;
  padding: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
}

.library-letter-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.42rem;
  padding-bottom: 0.95rem;
  border-bottom: 0.06rem solid rgba(255, 255, 255, 0.07);
}

.library-letter {
  min-width: 2rem;
  height: 2rem;
  border-radius: 50%;
  border: 0;
  color: rgba(229, 233, 255, 0.65);
  background: transparent;
  font-size: 0.82rem;
  font-weight: 700;
  cursor: pointer;
  box-shadow: none;
  transition: background 0.15s ease, color 0.15s ease, transform 0.12s ease;
}

.library-letter:is(:hover, :focus-visible, .is-tv-focused) {
  color: #fff;
  background: rgba(255, 255, 255, 0.08);
  outline: none;
  transform: translateY(-0.05rem);
}

.library-letter.is-selected {
  color: #fff;
  background: linear-gradient(135deg, var(--cyan), #6b8bff);
  box-shadow: 0 0.3rem 0.8rem rgba(0, 210, 255, 0.28);
  outline: none;
}

.library-filter-controls {
  display: grid;
  grid-template-columns: repeat(4, minmax(11rem, 1fr)) auto;
  gap: 0.8rem;
  align-items: center;
}

.library-select-wrap,
.library-sort-wrap {
  position: relative;
  display: flex;
  align-items: center;
  gap: 0.35rem;
  min-height: 2.3rem;
  padding: 0 1rem;
  border-radius: 9rem;
  color: rgba(229, 233, 255, 0.78);
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid rgba(255, 255, 255, 0.08);
  box-shadow: none;
  transition: border-color 0.15s ease, background 0.15s ease, box-shadow 0.15s ease;
}

.library-select-wrap:hover,
.library-sort-wrap:hover {
  background: rgba(255, 255, 255, 0.06);
  border-color: rgba(255, 255, 255, 0.16);
}

.library-select-wrap:focus-within,
.library-sort-wrap:focus-within {
  background: rgba(255, 255, 255, 0.06);
  border-color: rgba(138, 85, 255, 0.6);
  box-shadow: 0 0 0.8rem rgba(138, 85, 255, 0.18);
}

/* Custom chevron — replaces the inconsistent native one across browsers/OS. */
.library-select-wrap::after,
.library-sort-wrap::after {
  content: "";
  position: absolute;
  right: 0.95rem;
  top: 50%;
  width: 0.5rem;
  height: 0.5rem;
  border-right: 0.13rem solid rgba(174, 184, 226, 0.75);
  border-bottom: 0.13rem solid rgba(174, 184, 226, 0.75);
  transform: translateY(-65%) rotate(45deg);
  pointer-events: none;
}

.library-select-wrap span,
.library-sort-wrap span {
  flex: 0 0 auto;
  font-size: 0.76rem;
  font-weight: 850;
}

.library-select-wrap select,
.library-sort-wrap select {
  flex: 1;
  min-width: 0;
  height: 2.2rem;
  padding-right: 1.1rem;
  border: 0;
  color: #f6f3ff;
  background: transparent;
  font: inherit;
  font-size: 0.78rem;
  font-weight: 900;
  outline: none;
  cursor: pointer;
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
}

.library-select-wrap select option,
.library-sort-wrap select option {
  color: #f6f3ff;
  background: #202338;
}

.library-filter-reset {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  min-height: 2.3rem;
  padding: 0 1.25rem;
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 9rem;
  color: rgba(229, 233, 255, 0.92);
  background: rgba(255, 255, 255, 0.03);
  font-size: 0.82rem;
  font-weight: 900;
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease, transform 0.12s ease;
}

.library-filter-reset .reset-icon {
  font-size: 1.02rem;
  line-height: 1;
}

.library-filter-reset:is(:hover, :focus-visible, .is-tv-focused) {
  color: #fff;
  background: rgba(225, 29, 72, 0.16);
  border-color: rgba(225, 29, 72, 0.45);
  transform: translateY(-0.05rem);
  outline: none;
}

.library-filter-meta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding-top: 0.2rem;
  color: rgba(166, 184, 255, 0.96);
  font-size: 0.82rem;
  font-weight: 850;
}

.library-sort-wrap {
  min-width: min(17rem, 100%);
  background: transparent;
  box-shadow: none;
}

.library-sort-wrap:focus-within {
  background: transparent;
  box-shadow: none;
}

#library .poster-grid {
  padding-top: 0.1rem;
}

#library .rail-shell {
  padding-bottom: 0.5rem;
}

.library-scroll-sentinel {
  grid-row: 1 / -1;
  align-self: stretch;
  width: 1px;
  min-height: 1px;
  pointer-events: none;
  scroll-snap-align: none;
}

.library-auto-loader {
  position: absolute;
  right: 3.75rem;
  bottom: 0;
  z-index: 4;
  display: flex;
  align-items: center;
  gap: 0.65rem;
  min-height: 1.25rem;
  max-width: calc(100% - 5rem);
  padding: 0.125rem 0.55rem;
  border: 1px solid rgba(157, 169, 209, 0.2);
  border-radius: 6px;
  background: rgba(10, 12, 20, 0.94);
  color: #e8eaf2;
  font-size: 0.75rem;
  font-weight: 650;
  line-height: 1.25;
  pointer-events: none;
}

.library-auto-loader[hidden] {
  display: none;
}

.library-auto-loader-track {
  position: relative;
  display: block;
  flex: 0 0 2.5rem;
  width: 2.5rem;
  height: 3px;
  overflow: hidden;
  background: rgba(157, 169, 209, 0.16);
}

.library-auto-loader-track > span {
  position: absolute;
  inset: 0 auto 0 0;
  width: 42%;
  background: linear-gradient(90deg, #8b68f2, #31bdd3);
  animation: library-auto-loader-sweep 1.15s ease-in-out infinite;
  will-change: transform;
}

body.adult-mode .library-auto-loader-track > span {
  background: linear-gradient(90deg, #ef3d73, #9f57e8);
}

.library-auto-loader.is-complete .library-auto-loader-track > span,
body.reduce-motion .library-auto-loader-track > span {
  width: 100%;
  animation: none;
  transform: none;
}

@keyframes library-auto-loader-sweep {
  from { transform: translateX(-125%); }
  to { transform: translateX(340%); }
}

@media (prefers-reduced-motion: reduce) {
  .library-auto-loader-track > span {
    width: 100%;
    animation: none;
    transform: none;
  }
}

@media (max-width: 760px) {
  #library .library-filter-panel {
    max-width: calc(100vw - 7rem);
  }
  .library-filter-controls {
    grid-template-columns: 1fr;
    gap: 0.65rem;
  }
  .library-filter-meta {
    align-items: stretch;
    flex-direction: column;
  }
}

/* Poster rails use two rows everywhere, like a TV streaming shelf. */
.rail-shell .poster-grid {
  grid-auto-flow: column;
  grid-auto-columns: calc((100% - (6 * var(--rail-gap))) / 7);
  grid-template-columns: none;
  grid-template-rows: repeat(2, auto);
  grid-column: 2;
  grid-row: 1;
}

/* Responsive column counts — must come AFTER the base rule above */
@media (max-width: 1150px) {
  .rail-shell .poster-grid {
    grid-auto-columns: calc((100% - (6 * var(--rail-gap))) / 7);
  }
}

@media (max-width: 760px) {
  .rail-shell {
    grid-template-columns: 1fr;
    gap: 0.45rem;
  }

  /* Phones: show ~3 reasonably-sized cards per view and scroll the rest with
     smooth scroll-snap, instead of cramming 7 tiny cards across the screen. */
  .rail-shell .poster-grid {
    grid-auto-columns: clamp(7.5rem, 31vw, 9.5rem);
    grid-column: 1;
    scroll-snap-type: x proximity;
    scroll-padding-left: 0.2rem;
    -webkit-overflow-scrolling: touch;
  }

  .rail-shell .poster-grid > .show-card {
    scroll-snap-align: start;
  }

  /* The floating prev/next arrows are pointless on touch — hide them and let the
     rail scroll naturally so cards use the full width. */
  .rail-arrow {
    display: none;
  }
}

/* Use the full right side of the screen; arrows float over the rails. */
.rail-shell {
  margin-left: 0;
  margin-right: 0;
  padding: 0;
}

.rail-shell .poster-grid {
  padding-left: 0;
  padding-right: 0;
}

.rail-arrow-left {
  grid-column: 1;
}

.rail-arrow-right {
  grid-column: 3;
}

#library .rail-shell,
#favorites .rail-shell {
  margin-left: 0;
  margin-right: 0;
}

@media (max-width: 760px) {
  .rail-shell,
  #library .rail-shell,
  #favorites .rail-shell {
    margin-left: 0;
    margin-right: 0;
    padding: 0;
  }

  .rail-arrow-left {
    grid-column: 1;
  }

  .rail-arrow-right {
    grid-column: 3;
  }
}

/* ════════════════════════════════════════════════════════════════════════════
   Modern micro-interactions & reveals (ZenkaiTV)
   A cohesive motion layer — all covered by body.reduce-motion (instant) and
   built on transform/opacity for smooth, GPU-friendly animation.
   ════════════════════════════════════════════════════════════════════════════ */

@keyframes pop-in {
  0%   { opacity: 0; transform: translateY(0.7rem) scale(0.97); }
  100% { opacity: 1; transform: translateY(0) scale(1); }
}
@keyframes fade-slide {
  0%   { opacity: 0; transform: translateY(0.85rem); }
  100% { opacity: 1; transform: translateY(0); }
}

/* ── Detail-tab panes reveal when switched (display:none → block replays) ──── */
.detail-pane.is-active.animate-switch {
  animation: fade-slide 360ms cubic-bezier(0.22, 1, 0.36, 1) both;
}

/* ── Episode buttons: gentle staggered pop-in + springy hover ─────────────── */
.episode-buttons .episode-button {
  animation: pop-in 420ms cubic-bezier(0.22, 1, 0.36, 1) both;
}
.episode-buttons .episode-button:nth-child(1)  { animation-delay: 20ms; }
.episode-buttons .episode-button:nth-child(2)  { animation-delay: 40ms; }
.episode-buttons .episode-button:nth-child(3)  { animation-delay: 60ms; }
.episode-buttons .episode-button:nth-child(4)  { animation-delay: 80ms; }
.episode-buttons .episode-button:nth-child(5)  { animation-delay: 100ms; }
.episode-buttons .episode-button:nth-child(6)  { animation-delay: 120ms; }
.episode-buttons .episode-button:nth-child(7)  { animation-delay: 140ms; }
.episode-buttons .episode-button:nth-child(8)  { animation-delay: 160ms; }
.episode-buttons .episode-button:nth-child(n+9){ animation-delay: 180ms; }
.episode-button {
  transition: transform 200ms cubic-bezier(0.34, 1.3, 0.5, 1), border-color 180ms ease, background 180ms ease, box-shadow 180ms ease;
}
.episode-button:is(:hover, :focus-visible, .is-tv-focused):not(.is-locked) {
  transform: translateY(-0.14rem) scale(1.03);
}
.episode-button:active { transform: scale(0.96); }

/* ── Season cards: staggered reveal ───────────────────────────────────────── */
.season-card-grid .season-card {
  animation: pop-in 460ms cubic-bezier(0.22, 1, 0.36, 1) both;
}
.season-card-grid .season-card:nth-child(2) { animation-delay: 70ms; }
.season-card-grid .season-card:nth-child(3) { animation-delay: 140ms; }
.season-card-grid .season-card:nth-child(4) { animation-delay: 210ms; }
.season-card-grid .season-card:nth-child(n+5) { animation-delay: 280ms; }

/* ── Nav links: lift + icon bounce + press ────────────────────────────────── */
.main-nav .nav-link {
  transition:
    min-height 360ms cubic-bezier(0.22, 1, 0.36, 1),
    font-size 320ms cubic-bezier(0.22, 1, 0.36, 1),
    letter-spacing 320ms cubic-bezier(0.22, 1, 0.36, 1),
    background 180ms ease, color 220ms ease, box-shadow 220ms ease,
    transform 240ms cubic-bezier(0.34, 1.3, 0.5, 1);
}
.main-nav .nav-link:is(:hover, :focus-visible, .is-tv-focused) {
  transform: translateY(-0.1rem);
}
.main-nav .nav-link.nav-link:is(:hover, :focus-visible, .is-tv-focused) {
  transform: scale(1.08);
}
.nav-link:is(:hover, :focus-visible, .is-tv-focused) span {
  transform: translateY(-0.12rem) scale(1.08);
}
.nav-link:active { transform: scale(0.96); }

/* ── Genre chips & filters: lift + press ──────────────────────────────────── */
.chip {
  transition: transform 200ms cubic-bezier(0.34, 1.3, 0.5, 1), background 180ms ease, color 180ms ease, box-shadow 180ms ease;
}
.chip:is(:hover, :focus-visible, .is-tv-focused) { transform: translateY(-0.12rem) scale(1.04); }
.chip:active { transform: scale(0.95); }

/* ── Search boxes: focus glow + subtle lift ───────────────────────────────── */
.search-box input {
  transition: border-color 220ms ease, box-shadow 260ms ease, transform 220ms cubic-bezier(0.22, 1, 0.36, 1), background 220ms ease;
}
.search-box input:focus {
  border-color: rgba(59, 130, 246, 0.55);
  box-shadow: 0 0 0 0.18rem rgba(59, 130, 246, 0.16), 0 0.8rem 1.8rem rgba(0, 0, 0, 0.24);
  transform: translateY(-0.08rem);
}

/* ── Source-picker options: stagger in + hover slide ──────────────────────── */
.source-picker-options .source-picker-option {
  animation: fade-slide 360ms cubic-bezier(0.22, 1, 0.36, 1) both;
}
.source-picker-options .source-picker-option:nth-child(2) { animation-delay: 50ms; }
.source-picker-options .source-picker-option:nth-child(3) { animation-delay: 100ms; }
.source-picker-options .source-picker-option:nth-child(4) { animation-delay: 150ms; }
.source-picker-options .source-picker-option:nth-child(n+5) { animation-delay: 200ms; }
.source-picker-option-found {
  transition: transform 200ms cubic-bezier(0.34, 1.3, 0.5, 1), background 160ms ease, border-color 160ms ease, box-shadow 160ms ease;
}
.source-picker-option-found:is(:hover, :focus-visible, .is-tv-focused) {
  transform: translateX(0.25rem);
}

/* ── Detail tabs & season tabs: press feedback ────────────────────────────── */
.detail-tab, .season-tab {
  transition: transform 200ms cubic-bezier(0.34, 1.3, 0.5, 1), background 180ms ease, color 180ms ease, box-shadow 180ms ease;
}
.detail-tab:is(:hover, :focus-visible, .is-tv-focused),
.season-tab:is(:hover, :focus-visible, .is-tv-focused) {
  transform: translateY(-0.1rem);
}
.detail-tab:active, .season-tab:active { transform: scale(0.97); }

/* ── Genre/section headings: dot pulse already exists; lift the heading in ── */
.section-heading h2 {
  animation: fade-slide 480ms cubic-bezier(0.22, 1, 0.36, 1) both;
}

/* ── Favorite / secondary action buttons: press feedback ──────────────────── */
.secondary-action {
  transition: transform 200ms cubic-bezier(0.34, 1.3, 0.5, 1), background 180ms ease, color 180ms ease, box-shadow 180ms ease;
}
.secondary-action:is(:hover, :focus-visible, .is-tv-focused) { transform: translateY(-0.1rem); }
.secondary-action:active { transform: scale(0.96); }

/* ── Smart Source modal ──────────────────────────────────────────────────── */
.ss-modal-backdrop {
  position: fixed;
  inset: 0;
  /* Explicit viewport sizing so the overlay can never collapse to its content
     if an ancestor (transform/filter/backdrop-filter) establishes a containing
     block — that was leaving the dialog as a tiny box in the corner. */
  width: 100vw;
  height: 100dvh;
  z-index: 10060;            /* above the cinematic watch overlay (10050) */
  display: grid;
  place-items: center;
  padding: 1.25rem;
  /* Solid dim only — NO backdrop-filter. Stacking another blurred backdrop on
     top of the topbar/overlay blurs was producing a washed-out, half-composited
     "glitch" on the first open. A strong opaque dim gives the same focus without
     the GPU compositing issue. */
  background: rgba(4, 6, 14, 0.92);
  animation: ssFade 160ms ease both;
}
@keyframes ssFade { from { opacity: 0; } to { opacity: 1; } }

.ss-modal {
  position: relative;
  /* Viewport-based cap (not 100% of the parent) so the modal keeps a usable
     width even if its backdrop's box is collapsed for any reason. */
  width: min(34rem, calc(100vw - 2.5rem));
  max-height: 90vh;
  overflow: auto;
  padding: 1.6rem 1.5rem 1.4rem;
  border-radius: 1.1rem;
  border: 0.08rem solid rgba(255, 255, 255, 0.1);
  background: linear-gradient(180deg, #141627, #0d0f1d);
  box-shadow: 0 1.5rem 4rem rgba(0, 0, 0, 0.55);
  color: var(--text);
  animation: ssPop 200ms cubic-bezier(0.34, 1.3, 0.5, 1) both;
}
@keyframes ssPop { from { transform: translateY(0.6rem) scale(0.98); opacity: 0; } to { transform: none; opacity: 1; } }

.ss-modal h3 { margin: 0 0 0.35rem; font-size: 1.3rem; font-weight: 900; }
.ss-modal-sub { margin: 0 0 1rem; color: var(--muted); font-size: 0.9rem; line-height: 1.45; }

.ss-modal-close {
  position: absolute;
  top: 0.85rem;
  right: 0.85rem;
  width: 2rem;
  height: 2rem;
  display: grid;
  place-items: center;
  border-radius: 999rem;
  background: rgba(255, 255, 255, 0.08);
  color: #d7d2ec;
  cursor: pointer;
  transition: background 150ms ease, transform 150ms ease;
}
.ss-modal-close:is(:hover, :focus-visible) { outline: 0; background: rgba(92, 155, 255, 0.4); transform: scale(1.08); }

.ss-modal-input {
  width: 100%;
  min-height: 3rem;
  padding: 0 1rem;
  border: 0.1rem solid rgba(255, 255, 255, 0.14);
  border-radius: 0.8rem;
  background: #0a0c18;
  color: var(--text);
  outline: 0;
  transition: border-color 160ms ease, box-shadow 160ms ease;
}
.ss-modal-input:focus { border-color: rgba(92, 155, 255, 0.6); box-shadow: 0 0 0 0.16rem rgba(92, 155, 255, 0.16); }

.ss-modal-detect {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin-top: 0.85rem;
  padding: 0.75rem 0.9rem;
  border-radius: 0.8rem;
  background: rgba(92, 155, 255, 0.1);
  border: 0.08rem solid rgba(92, 155, 255, 0.22);
  animation: ssFade 160ms ease both;
}
/* The detection box / progress box only exist once there's something to show —
   the `display:flex` above would otherwise override the [hidden] attribute and
   leave an empty box on the modal before you type. */
.ss-modal-detect[hidden],
.ss-modal-progress[hidden] { display: none; }
.ss-modal-detect.ss-type-unsupported,
.ss-modal-detect.ss-type-unknown {
  background: rgba(255, 99, 99, 0.1);
  border-color: rgba(255, 99, 99, 0.28);
}
.ss-modal-detect.ss-type-full_website_domain {
  background: rgba(138, 92, 255, 0.12);
  border-color: rgba(138, 92, 255, 0.3);
}
.ss-detect-icon { font-size: 1.5rem; line-height: 1; }
.ss-detect-text { display: grid; gap: 0.1rem; min-width: 0; }
.ss-detect-text strong { font-weight: 900; }
.ss-detect-text small { color: var(--muted); font-size: 0.82rem; line-height: 1.35; }

.ss-modal-progress {
  margin-top: 0.85rem;
  padding: 0.75rem 0.9rem;
  border-radius: 0.8rem;
  background: rgba(0, 0, 0, 0.3);
  border: 0.08rem solid rgba(255, 255, 255, 0.08);
  max-height: 13rem;
  overflow: auto;
  font-size: 0.86rem;
}
.ss-progress-line { padding: 0.18rem 0; color: rgba(246, 243, 255, 0.86); }
.ss-progress-line + .ss-progress-line { border-top: 0.06rem solid rgba(255, 255, 255, 0.05); }

.ss-merge p { margin: 0 0 0.6rem; }
.ss-merge-actions, .ss-modal-actions { display: flex; flex-wrap: wrap; gap: 0.6rem; }
.ss-modal-actions { margin-top: 1.1rem; justify-content: flex-end; }
.ss-offer { margin-top: 0.7rem; }

.ss-btn {
  min-height: 2.55rem;
  padding: 0 1.1rem;
  border-radius: 0.7rem;
  font-weight: 800;
  cursor: pointer;
  transition: transform 150ms ease, background 150ms ease, box-shadow 150ms ease, opacity 150ms ease;
}
.ss-btn:disabled { opacity: 0.45; cursor: not-allowed; }
.ss-btn-primary { color: #07101f; background: linear-gradient(135deg, #5C9BFF, #8A5CFF); }
.ss-btn-primary:is(:hover, :focus-visible):not(:disabled) { outline: 0; transform: translateY(-0.08rem); box-shadow: 0 0.5rem 1.2rem rgba(92, 155, 255, 0.35); }
.ss-btn-ghost { color: var(--text); background: rgba(255, 255, 255, 0.08); }
.ss-btn-ghost:is(:hover, :focus-visible):not(:disabled) { outline: 0; background: rgba(255, 255, 255, 0.14); }
.ss-btn:active:not(:disabled) { transform: scale(0.96); }

body.reduce-motion .ss-modal-backdrop,
body.reduce-motion .ss-modal,
body.reduce-motion .ss-modal-detect { animation: none; }

/* ══════════════════════════════════════════════════════════════════════════
   Cinematic pre-player / details screen
   Left = full-bleed backdrop + metadata + actions. Right = source/episode panel.
   The active player is position:fixed (cinema), so it floats above this layout.
   ══════════════════════════════════════════════════════════════════════════ */

/* Blurred fill layer behind the sharp backdrop: gives low-resolution or
   off-aspect artwork a cinematic, full-bleed look and keeps text readable. */
.watch-backdrop-blur {
  position: absolute;
  inset: -8%;
  z-index: 0;
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  filter: blur(42px) saturate(1.25) brightness(0.62);
  transform: scale(1.12);
  opacity: 0;
  transition: opacity 420ms ease;
  pointer-events: none;
}
.watch-overlay:not([hidden]) .watch-backdrop-blur.is-visible { opacity: 1; }
body.reduce-motion .watch-backdrop-blur { transform: scale(1.08); }

/* Full-bleed backdrop with a slow parallax zoom. */
.watch-backdrop {
  position: absolute;
  inset: 0;
  z-index: 1;
  background-size: cover;
  background-position: center top;
  background-repeat: no-repeat;
  /* Gradient fallback when no artwork is available. */
  background-color: #0a0b16;
  background-image:
    radial-gradient(120% 90% at 80% 0%, rgba(89, 70, 160, 0.55), transparent 60%),
    radial-gradient(120% 90% at 0% 100%, rgba(34, 40, 90, 0.5), transparent 55%);
  opacity: 0;
  transform: scale(1.04);
  transition: opacity 420ms ease, transform 700ms ease;
  pointer-events: none;
}
.watch-overlay:not([hidden]) .watch-backdrop { opacity: 1; }
.watch-backdrop.has-art {
  background-color: transparent;
  animation: watch-backdrop-zoom 26s ease-in-out 600ms both alternate;
}
.watch-backdrop.has-fallback-art {
  background-size: cover;
  background-position: center;
}
.watch-backdrop-title-art {
  position: absolute;
  top: 18%;
  right: clamp(22rem, 27vw, 34rem);
  z-index: 1;
  display: flex;
  width: min(30vw, 28rem);
  min-height: 42%;
  flex-direction: column;
  justify-content: center;
  align-items: flex-start;
  gap: 0.75rem;
  padding: clamp(1.25rem, 3vw, 3rem);
  color: rgba(255, 255, 255, 0.92);
  pointer-events: none;
}
.watch-backdrop-title-art[hidden] { display: none; }
.watch-summary:empty { display: none; }
.watch-backdrop-title-art::before {
  content: "Z";
  position: absolute;
  inset: 50% auto auto 50%;
  color: hsla(var(--artwork-hue, 262), 86%, 68%, 0.1);
  font-size: clamp(13rem, 29vw, 31rem);
  font-weight: 950;
  line-height: 0.72;
  transform: translate(-50%, -50%);
  text-shadow: 0 0 5rem rgba(48, 205, 232, 0.09);
}
.watch-backdrop-title-kicker,
.watch-backdrop-title-art strong,
.watch-backdrop-title-rule { position: relative; z-index: 1; }
.watch-backdrop-title-kicker {
  color: #30cde8;
  font-size: clamp(0.68rem, 1vw, 0.86rem);
  font-weight: 850;
  text-transform: uppercase;
  letter-spacing: 0;
}
.watch-backdrop-title-art strong {
  max-width: 100%;
  display: -webkit-box;
  max-height: 8rem;
  overflow: hidden;
  font-size: clamp(1.45rem, 2.25vw, 2.8rem);
  font-weight: 950;
  line-height: 1.02;
  overflow-wrap: anywhere;
  text-wrap: balance;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  text-shadow: 0 0.3rem 2.2rem rgba(0, 0, 0, 0.72);
}
.watch-backdrop-title-rule {
  width: min(12rem, 45%);
  height: 0.24rem;
  border-radius: 999rem;
  background: linear-gradient(90deg, #8a5cff, #30cde8);
  box-shadow: 0 0 1.4rem rgba(48, 205, 232, 0.28);
}
body.adult-mode .watch-backdrop-title-kicker { color: #fb7185; }
body.adult-mode .watch-backdrop-title-rule {
  background: linear-gradient(90deg, #e11d48, #fb7185);
}
/* Portrait key art, composed like a streaming-service title card rather than
   cropped. background-size: cover on a 460x690 poster fills a 16:9 frame by
   throwing away most of the image, so instead: contain the sharp art at full
   height, seat it right of the metadata column, and let the blurred darkened
   copy behind it (.watch-backdrop-blur) carry the rest of the frame. */
.watch-backdrop.is-poster-fit {
  /* Fill the frame, like every show that has a real backdrop.

     This used to CONTAIN the poster at full height and seat it left of the episode
     panel, on the reasoning that cover "throws away most of the image". Measured
     against the actual result, that reasoning was wrong: these posters are dark, so
     the blurred fill behind them lands near black (brightness .58 on an already
     dark cover), and the sharp poster reads as a small rectangle pasted onto an
     empty page rather than a backdrop - which is what "weird" looked like. Only 114
     of 1000 rows have no wide art, so this path is also the one that looks least
     like the other 886.

     A/B on the same show at 1600x900: contained gave a floating rectangle with wide
     empty margins; cover gave a full-bleed frame consistent with the rest of the
     site. Portrait art cropped to 16:9 does lose composition - but the poster is
     already shown intact as its own card in the panel below, so nothing is lost
     that the page does not still present properly.

     Anchored at 38% rather than centre: portrait key art clusters its characters a
     little above the middle, and the lower third is usually logo or credits.
     Compared on two shows: at 15% the crop landed on a villain's mouth, at 38% it
     lands on the protagonists' faces and leaves the darker lower band under the
     title. */
  background-size: cover;
  background-position: 50% 38%;
  background-repeat: no-repeat;
  animation: none;
}
/* On phones the title and metadata sit ON TOP of the hero, so a sharp portrait
   behind them makes both unreadable - and the same poster already appears as its
   own card immediately below. Keep just the blurred fill there. !important
   because setBackdropArt writes background-image as an inline style. */
/* 860px, matching .watch-overlay.cinematic .watch-panel: below it the episode
   panel stacks underneath, the title sits on top of the hero, and the poster
   already has its own card below - so the sharp layer only fights the text. */
@media (max-width: 860px) {
  .watch-overlay:not([hidden]) .watch-backdrop.is-poster-fit {
    background-image: none !important;
  }
}
/* A deeper fill under composed portrait art: it has to read as a background,
   not as a second copy of the poster. The blur layer precedes .watch-backdrop
   in the DOM, so it is selected with :has(~ ...). */
.watch-overlay:not([hidden]) .watch-backdrop-blur.is-visible:has(~ .watch-backdrop.is-poster-fit) {
  /* brightness was 0.42, below the 0.62 this layer uses elsewhere. Under the
     metadata scrim that read as a black panel rather than a background, which is
     what "the background is not covering" looked like: the fill was there and
     full-bleed, just too dark to see. 0.58 keeps the title legible over it. */
  filter: blur(2.1rem) saturate(1.2) brightness(0.58);
  transform: scale(1.16);
}
/* Holding for the high-res (TMDB) backdrop: keep the sharp layer transparent so
   only the blurred fill behind it shows, until the good art fades in. */
.watch-backdrop.is-blur-hold {
  background-color: transparent;
  background-image: none;
  animation: none;
}
.watch-overlay:not([hidden]) .watch-backdrop.is-blur-hold { opacity: 0; }
@keyframes watch-backdrop-zoom {
  from { transform: scale(1.02); }
  to   { transform: scale(1.12); }
}
body.reduce-motion .watch-backdrop,
body.reduce-motion .watch-backdrop.has-art { animation: none !important; transform: scale(1.02); }

/* Layered scrims: dark left→right behind metadata, bottom→top behind actions,
   plus a soft fade where the backdrop meets the right source panel. */
.watch-backdrop::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
  background:
    linear-gradient(90deg, rgba(7,7,15,0.94) 0%, rgba(7,7,15,0.7) 30%, rgba(7,7,15,0.34) 52%, rgba(7,7,15,0.2) 70%, rgba(7,7,15,0.74) 100%),
    linear-gradient(0deg, rgba(6,6,13,0.96) 1%, rgba(7,7,15,0.05) 46%, rgba(7,7,15,0.36) 100%);
}
body.adult-mode .watch-backdrop::after {
  background: linear-gradient(90deg, rgba(10, 3, 6, 0.85) 0%, rgba(10, 3, 6, 0.45) 25%, transparent 65%) !important;
}
body.adult-mode .watch-backdrop.is-poster-fit {
  background-size: cover !important;
  background-position: center 20% !important;
}

.adult-provider-tabs {
  display: none;
  position: fixed;
  top: clamp(0.75rem, 1.7vh, 1.3rem);
  right: calc(clamp(0.75rem, 1.7vw, 1.3rem) + 6.2rem);
  z-index: 55;
  gap: 0.8rem;
  margin: 0;
  padding: 0.25rem;
  background: rgba(17, 21, 34, 0.45);
  border-radius: 0.5rem;
  border: 1px solid rgba(247, 248, 255, 0.05);
  width: fit-content;
  -webkit-backdrop-filter: blur(14px) saturate(1.08);
  backdrop-filter: blur(14px) saturate(1.08);
}

body.adult-mode .adult-provider-tabs:not([hidden]) {
  display: flex;
}

.adult-provider-tabs[hidden] {
  display: none !important;
}

.adult-provider-tab {
  background: transparent;
  border: none;
  color: var(--muted);
  font-weight: 700;
  font-size: 0.92rem;
  padding: 0.5rem 1.25rem;
  border-radius: 0.4rem;
  cursor: pointer;
  transition: all 180ms ease;
}

.adult-provider-tab:hover {
  color: var(--text);
  background: rgba(247, 248, 255, 0.04);
}

.adult-provider-tab.is-selected {
  color: #fff;
  background: #e11d48;
  box-shadow: 0 2px 8px rgba(225, 29, 72, 0.35);
}

.adult-provider-tab:focus-visible {
  outline: 2px solid #e11d48;
}

/* The overlay lets the backdrop dominate (opaque base so nothing bleeds through). */
.watch-overlay.cinematic {
  background: #06060d;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  padding: 0;
  align-items: stretch;
  overflow: hidden;
  overscroll-behavior: contain;
}

body.watch-detail-open {
  overflow: hidden;
}

/* Full-screen two-column stage. */
.watch-overlay.cinematic .watch-panel {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: none;
  height: 100dvh;
  max-height: 100dvh;
  grid-template-columns: minmax(0, 1fr) clamp(21rem, 27vw, 30rem);
  gap: 0;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
  overflow: hidden;
}

/* Back button — top-left, glassy circle. */
.watch-overlay.cinematic .close-button {
  top: clamp(1rem, 2.4vh, 1.8rem);
  left: clamp(1rem, 2.4vw, 1.8rem);
  right: auto;
  width: 2.9rem;
  height: 2.9rem;
  background: rgba(12, 12, 22, 0.6);
  border: 0.08rem solid rgba(255, 255, 255, 0.14);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
}

/* This variant out-specifies the base .close-button hover, so the hover state has
   to be restated here or it simply never shows on the detail page. Same accent the
   sidebar controls use, so the two chevrons behave identically. */
.watch-overlay.cinematic .close-button:is(:hover, :focus-visible, .is-tv-focused) {
  border-color: rgba(138, 85, 255, 0.55);
  background: rgba(24, 20, 46, 0.82);
  color: #ffffff;
}

/* ── LEFT: cinematic content ─────────────────────────────────────────────── */
.watch-stage {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  align-self: stretch;
  min-width: 0;
  min-height: 0;
  height: 100dvh;
  padding: clamp(2rem, 5vh, 4.5rem) clamp(1.6rem, 4vw, 4.5rem) clamp(1.6rem, 5vh, 3.4rem);
  overflow: hidden;
}
.watch-stage-body {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 0.85rem;
  width: 100%;
  max-width: 42rem;
  animation: watch-stage-in 360ms ease both;
}
@keyframes watch-stage-in {
  from { opacity: 0; transform: translateY(1.2rem); }
  to   { opacity: 1; transform: none; }
}
body.reduce-motion .watch-stage-body { animation: none; }

/* Detail hydration stays out of the layout: a thin rail at the viewport edge
   shows that richer metadata is still arriving, while empty metadata fields use
   the same calm sheen as poster placeholders. Fast, already-complete opens hide
   this before its short reveal delay, so cached titles never flash a loader. */
.watch-detail-progress {
  position: fixed;
  inset: 0 0 auto;
  z-index: 140;
  height: 0.18rem;
  overflow: hidden;
  pointer-events: none;
  background: rgba(255, 255, 255, 0.06);
  opacity: 0;
  animation: watch-detail-progress-reveal 120ms ease 140ms forwards;
}

.watch-detail-progress > span:first-child {
  display: block;
  width: 34%;
  height: 100%;
  border-radius: 999rem;
  background: linear-gradient(90deg, transparent, #8a5cff 44%, #30cde8 58%, transparent);
  box-shadow: 0 0 0.8rem rgba(48, 205, 232, 0.45);
  animation: watch-detail-progress-slide 1.05s cubic-bezier(0.65, 0, 0.35, 1) infinite;
}

.watch-overlay.is-hydrating-details .watch-meta-row:empty,
.watch-overlay.is-hydrating-details .watch-summary:empty {
  display: block;
  position: relative;
  overflow: hidden;
  border-radius: 999rem;
  background: rgba(255, 255, 255, 0.1);
}

.watch-overlay.is-hydrating-details .watch-meta-row:empty {
  width: min(18rem, 72vw);
  height: 0.78rem;
}

.watch-overlay.is-hydrating-details .watch-summary:empty {
  width: min(34rem, 86vw);
  height: 2.4rem;
  border-radius: 0.35rem;
}

.watch-overlay.is-hydrating-details .watch-meta-row:empty::after,
.watch-overlay.is-hydrating-details .watch-summary:empty::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(100deg, transparent 18%, rgba(255, 255, 255, 0.14) 48%, transparent 78%);
  transform: translateX(-100%);
  animation: watch-detail-sheen 1.25s ease-in-out infinite;
}

@keyframes watch-detail-progress-reveal {
  to { opacity: 1; }
}

@keyframes watch-detail-progress-slide {
  from { transform: translateX(-110%); }
  to { transform: translateX(300%); }
}

@keyframes watch-detail-sheen {
  to { transform: translateX(100%); }
}

body.reduce-motion .watch-detail-progress,
body.reduce-motion .watch-detail-progress > span:first-child,
body.reduce-motion .watch-overlay.is-hydrating-details .watch-meta-row:empty::after,
body.reduce-motion .watch-overlay.is-hydrating-details .watch-summary:empty::after {
  animation: none;
}

body.reduce-motion .watch-detail-progress { opacity: 1; }

.watch-logo {
  max-width: min(28rem, 70%);
  max-height: 9rem;
  width: auto;
  object-fit: contain;
  filter: drop-shadow(0 0.6rem 1.6rem rgba(0,0,0,0.6));
}
.watch-overlay.cinematic .watch-title {
  margin: 0;
  font-size: clamp(2rem, 4.6vw, 4.2rem);
  line-height: 1.05;
  letter-spacing: 0;
  font-weight: 900;
  color: #fff;
  text-shadow: 0 0.5rem 2rem rgba(0,0,0,0.6);
  text-wrap: balance;
  /* A 120-character romaji title at the full hero size wrapped to ~10 lines and
     swallowed the artwork. Cap the block and step the size down by length
     (classes set in syncWatchHeading); the full title stays in the tooltip. */
  display: -webkit-box;
  -webkit-line-clamp: 3;
  line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
  max-width: 20ch;
}

/* 46-80 chars: still prominent, but no longer full-bleed. */
.watch-overlay.cinematic .watch-title.is-long-title {
  font-size: clamp(1.7rem, 3.2vw, 2.9rem);
  max-width: 26ch;
}

/* 80+ chars: smaller, four lines, wider measure so it reads as a paragraph. */
.watch-overlay.cinematic .watch-title.is-xlong-title {
  font-size: clamp(1.35rem, 2.3vw, 2.15rem);
  -webkit-line-clamp: 4;
  line-clamp: 4;
  max-width: 34ch;
  line-height: 1.15;
}

.watch-meta-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.55rem 0.9rem;
  margin: 0.2rem 0 0;
  color: rgba(236, 238, 250, 0.92);
  font-size: 0.95rem;
  font-weight: 700;
}
.watch-meta-chip { display: inline-flex; align-items: center; }
.watch-meta-chip + .watch-meta-chip::before {
  content: "•";
  margin-right: 0.9rem;
  color: rgba(255,255,255,0.4);
  font-weight: 900;
}
.watch-meta-score { color: #ffd66b; }

.watch-taglist {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin: 0.15rem 0;
}
.watch-pill {
  padding: 0.32rem 0.8rem;
  border-radius: 999rem;
  border: 0.08rem solid rgba(255,255,255,0.18);
  background: rgba(255,255,255,0.07);
  color: rgba(240, 241, 250, 0.95);
  font-size: 0.82rem;
  font-weight: 700;
  letter-spacing: 0.01em;
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
}
.watch-pill-cast {
  border-style: dashed;
  border-color: rgba(255,255,255,0.14);
  background: transparent;
}

.watch-summary {
  margin: 0.2rem 0 0.3rem;
  max-width: 38rem;
  color: rgba(223, 226, 240, 0.86);
  font-size: clamp(0.92rem, 1.1vw, 1.04rem);
  line-height: 1.5;
  display: block;
  max-height: 6em;
  overflow: hidden;
  scrollbar-width: thin;
  overscroll-behavior: contain;
  text-shadow: 0 0.2rem 0.8rem rgba(0,0,0,0.45);
}
.watch-summary.is-expanded {
  max-height: min(28dvh, 18rem);
  overflow-y: auto;
}
.watch-summary-toggle {
  align-self: flex-start;
  margin: -0.4rem 0 0;
  padding: 0.2rem 0.1rem;
  border: 0;
  background: transparent;
  color: #bb9cff;
  font: inherit;
  font-size: 0.86rem;
  font-weight: 700;
  cursor: pointer;
}
.watch-summary-toggle[hidden] { display: none; }
.watch-summary-toggle:is(:hover, :focus-visible, .is-tv-focused) {
  color: #e0d0ff;
  text-decoration: underline;
  outline-offset: 0.2rem;
}
.watch-summary:focus-visible {
  outline: 0.12rem solid var(--accent, #8955ff);
  outline-offset: 0.2rem;
}

/* ── Bottom action bar ───────────────────────────────────────────────────── */
.watch-overlay.cinematic .watch-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.7rem;
  margin-top: 0.5rem;
}
.watch-overlay.cinematic .primary-action {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.85rem 1.9rem;
  border: 0;
  border-radius: 0.7rem;
  background: var(--accent, #8a5cff);
  color: #fff;
  font-size: 1.05rem;
  font-weight: 850;
  letter-spacing: 0.01em;
  cursor: pointer;
  box-shadow: 0 0.7rem 1.8rem rgba(138, 92, 255, 0.42);
  transition: transform 160ms ease, box-shadow 160ms ease, filter 160ms ease;
}
.watch-overlay.cinematic .primary-action::before {
  content: "▶";
  font-size: 0.92em;
  line-height: 1;
}
.watch-overlay.cinematic .primary-action:is(:hover, :focus-visible) {
  transform: translateY(-1px);
  filter: brightness(1.06);
  box-shadow: 0 0.9rem 2.2rem rgba(138, 92, 255, 0.55);
  outline: 0;
}

.icon-action {
  position: relative;
  display: inline-grid;
  place-items: center;
  width: 3rem;
  height: 3rem;
  flex: none;
  border: 0.08rem solid rgba(255,255,255,0.18);
  border-radius: 999rem;
  background: rgba(18, 18, 30, 0.55);
  color: #fff;
  font-size: 1.2rem;
  cursor: pointer;
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  transition: transform 160ms ease, background 160ms ease, border-color 160ms ease;
}
.icon-action:is(:hover, :focus-visible) {
  transform: translateY(-1px);
  background: rgba(40, 40, 60, 0.7);
  border-color: rgba(255,255,255,0.32);
  outline: 0;
}
.icon-action.is-active {
  color: #ff6b8b;
  border-color: rgba(255, 107, 139, 0.6);
  background: rgba(255, 107, 139, 0.16);
}

#favoriteButton {
  isolation: isolate;
  overflow: visible;
  touch-action: manipulation;
}

#favoriteButton > span {
  position: relative;
  z-index: 1;
  display: inline-block;
  transform-origin: center;
}

#favoriteButton.favorite-feedback > span {
  animation: favorite-heart-feedback 500ms cubic-bezier(0.2, 0.9, 0.25, 1.25) both;
}

#favoriteButton.favorite-feedback::before {
  content: "";
  position: absolute;
  inset: -0.24rem;
  z-index: 0;
  border: 0.12rem solid rgba(255, 107, 139, 0.78);
  border-radius: inherit;
  pointer-events: none;
  animation: favorite-ring-feedback 500ms ease-out both;
}

#favoriteButton.favorite-feedback.is-favorite-removed::before {
  border-color: rgba(190, 198, 219, 0.58);
}

@keyframes favorite-heart-feedback {
  0% { transform: scale(1); }
  32% { transform: scale(0.72); }
  62% { transform: scale(1.34); }
  82% { transform: scale(0.94); }
  100% { transform: scale(1); }
}

@keyframes favorite-ring-feedback {
  0% { opacity: 0; transform: scale(0.76); }
  30% { opacity: 1; }
  100% { opacity: 0; transform: scale(1.18); }
}

@media (prefers-reduced-motion: reduce) {
  #favoriteButton.favorite-feedback > span {
    animation: none;
  }

  #favoriteButton.favorite-feedback::before {
    animation: favorite-ring-reduced 160ms ease-out both;
  }
}

@keyframes favorite-ring-reduced {
  0% { opacity: 0; }
  50% { opacity: 1; }
  100% { opacity: 0; }
}
/* Tooltip on pointer devices. */
@media (hover: hover) {
  .icon-action[data-tip]::after {
    content: attr(data-tip);
    position: absolute;
    bottom: calc(100% + 0.5rem);
    left: 50%;
    transform: translateX(-50%) translateY(0.3rem);
    padding: 0.3rem 0.6rem;
    border-radius: 0.45rem;
    background: rgba(10, 10, 18, 0.95);
    color: #fff;
    font-size: 0.72rem;
    font-weight: 700;
    white-space: nowrap;
    opacity: 0;
    pointer-events: none;
    transition: opacity 140ms ease, transform 140ms ease;
  }
  .icon-action[data-tip]:hover::after {
    opacity: 1;
    transform: translateX(-50%) translateY(0);
  }
}

/* ── RIGHT: elevated source / episode panel ──────────────────────────────── */
.watch-side {
  position: relative;
  z-index: 2;
  display: flex;
  flex-direction: column;
  min-height: 0;
  /* Inset from the top so the floating fullscreen button sits clearly ABOVE
     the panel (over the backdrop), not inside the episode list. */
  margin: clamp(3.6rem, 7vh, 4.8rem) 0 0;
  height: calc(100dvh - clamp(3.6rem, 7vh, 4.8rem));
  max-height: calc(100dvh - clamp(3.6rem, 7vh, 4.8rem));
  /* No top padding — the sticky tab bar owns the top edge so nothing can bleed
     into a gap above it. */
  padding: 0 0.7rem 0.9rem 0.9rem;
  /* Translucent glassmorphism panel — lets the beautiful backdrop show through
     while keeping text and actions perfectly legible with backdrop-filter blur. */
  background: rgba(14, 15, 26, 0.72);
  border: 0;
  border-radius: 1.1rem 0 0 1.1rem;
  -webkit-backdrop-filter: blur(20px);
  backdrop-filter: blur(20px);
  box-shadow: -1.6rem 0 3rem rgba(0,0,0,0.5);
  overflow: hidden;
  overscroll-behavior: contain;
  scrollbar-width: none;
}
.watch-side::-webkit-scrollbar { display: none; }
.watch-side .episode-list {
  flex: 1 1 auto;
  height: 100%;
  min-height: 0;
  overflow: hidden;
}

/* Two-tab selector (Seasons / Episodes) — two simple pills on a sticky bar that
   is the SAME colour as the panel, so there is no track box / seam, and it stays
   opaque so episodes never bleed through while scrolling. */

/* The panel does not repeat the show's name. The watch content already carries
   it directly above on every layout this panel appears in. */
@media (max-width: 1024px) {
  /* The rule that draws the panel separator sets border-top AND padding-top:1rem
     together, but a later (max-width: 860px) rule zeroes .episode-list padding
     outright - so the compact panel kept the line and lost the air under it.
     Measured at 820 and at 375: border-top 0.8px with padding-top 0, the hairline
     sitting directly on the tabs while desktop had a full 1rem of space. Restore
     the gap, and soften the line itself so it reads as a seam between sections
     rather than a rule drawn across the panel. */
  /* .watch-overlay scopes this above the later (max-width: 860px) rule that
     sets .watch-side .episode-list { padding: 0 } - same specificity, and it
     comes after, so it was winning the padding back to zero and leaving the
     line flush against the tabs. */
  .watch-overlay .watch-side .episode-list {
    margin-top: 1.1rem;
    padding-top: 0.9rem;
    border-top: 0.08rem solid rgba(255, 255, 255, 0.07);
  }

  /* The poster carries a 0.1rem / 0.22-alpha border all the way round. In a
     desktop column that reads as a frame. In the compact panel the poster
     spans the full width, so only its top and bottom edges are ever visible -
     measured 1.6px at 0.22 alpha, twice the width and three times the opacity
     of every other line here - and they land either side of the season row as
     two bright rules bracketing it. Soften them to the same weight as the rest
     of the seams; the frame is kept, it just stops shouting. */
  .watch-overlay .watch-poster,
  .watch-overlay .watch-poster-placeholder {
    border-width: 0.06rem;
    border-color: rgba(255, 255, 255, 0.08);
  }

  /* The Seasons tab is redundant on compact widths: the Episodes pane already
     carries the whole season navigator - Prev / Next and a dropdown listing
     every season - so the tab only ever led to a second way of doing what is
     already one tap away, at the cost of a full-width bar above the list.

     Adult titles are the exception and keep their bar. There the first tab is
     Gallery, not Seasons, and .adult-detail-gallery has no other route to it -
     hiding that would remove the only way in. The marker is set per SHOW, so a
     normal title browsed while adult mode is on still drops its tab bar. */
  #episodeList:not(.is-adult-detail) .detail-tabs.detail-tabs-2 {
    display: none;
  }

  /* With no tab bar there is no way back, so the panes cannot be left to the
     remembered tab: a /anime/x?tab=seasons deep link would otherwise open the
     seasons pane with nothing to switch away from it. Pin them. */
  #episodeList:not(.is-adult-detail) .detail-pane[data-detail-pane="seasons"] {
    display: none;
  }

  .watch-side #episodeList:not(.is-adult-detail) .detail-pane[data-detail-pane="episodes"] {
    display: flex;
    flex: 1 1 auto;
    flex-direction: column;
    min-height: 0;
  }

  /* Adult details keep Gallery/Episodes, but at compact widths the selector is
     part of the panel surface instead of a detached dark rectangle. */
  .watch-side #episodeList.is-adult-detail .detail-tabs.detail-tabs-2 {
    gap: 0.25rem;
    margin-bottom: 0.7rem;
    padding: 0.28rem;
    border: 0.06rem solid rgba(255, 255, 255, 0.09);
    border-radius: 0.78rem;
    background: rgba(11, 13, 25, 0.48);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.045);
    -webkit-backdrop-filter: blur(14px) saturate(1.08);
    backdrop-filter: blur(14px) saturate(1.08);
  }

  .watch-side #episodeList.is-adult-detail .detail-tab {
    min-height: 2.7rem;
    border-radius: 0.58rem;
  }
}

.watch-side .detail-tabs.detail-tabs-2 {
  grid-template-columns: repeat(2, minmax(0, 1fr));
  position: relative;
  z-index: 7;
  flex: 0 0 auto;
  gap: 0.5rem;
  margin: 0;
  padding: 0.85rem 0 0.7rem;
  border: 0;
  border-radius: 0;
  background: transparent;
}
.watch-side .detail-tab {
  min-height: 2.55rem;
  padding: 0 0.7rem;
  border: 0;
  border-radius: 0.7rem;
  background: rgba(255, 255, 255, 0.06);
  color: rgba(240, 241, 250, 0.72);
  box-shadow: none;
  font-size: 0.92rem;
  font-weight: 800;
  transition: background 150ms ease, color 150ms ease;
}
.watch-side .detail-tab:is(:hover, :focus-visible, .is-tv-focused) {
  color: #fff;
  background: rgba(255, 255, 255, 0.12);
  box-shadow: none;
}
.watch-side .detail-tab.is-selected,
.watch-side .detail-tab.is-selected:is(:hover, :focus-visible, .is-tv-focused) {
  color: #ffffff;
  background: #8a5cff;
  box-shadow: 0 0.4rem 0.9rem rgba(138, 92, 255, 0.3);
}
.watch-side .detail-pane { display: none; }
.watch-side .detail-pane.is-active {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  min-height: 0;
  overflow: hidden;
}
/* Only the Seasons/Episodes tabs stay pinned (solid, so nothing bleeds through).
   The season-nav scrolls with the list — having two stacked sticky bands was what
   left a gap that let episodes overlap the header. */
.watch-side .detail-pane .ep-panel-head {
  position: static;
  z-index: auto;
  flex: 0 0 auto;
  margin: 0 0 0.45rem;
  padding: 0.1rem 0.15rem 0.55rem;
  background: transparent;
}
/* Season cards fit the narrow panel. */
.watch-side .season-card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(8.5rem, 1fr));
  gap: 0.6rem;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: none;
}
.watch-side .season-card-grid::-webkit-scrollbar { display: none; }

.watch-side .adult-detail-gallery {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: 0.78rem;
  padding: 0.1rem 0.08rem 0.85rem;
  overflow-y: auto;
  overflow-x: hidden;
  overscroll-behavior: contain;
  scrollbar-width: none;
}
.watch-side .adult-detail-gallery::-webkit-scrollbar { display: none; }

.adult-detail-gallery-group {
  flex: 0 0 auto;          /* never shrink — keeps the grid from being clipped
                              so the whole gallery scrolls past 2 episodes */
  overflow: hidden;
  border-radius: 0.95rem;
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.052), rgba(255, 255, 255, 0.024)),
    rgba(12, 13, 24, 0.64);
  border: 0.06rem solid rgba(255, 255, 255, 0.075);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04);
}

.adult-detail-gallery-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.6rem;
  padding: 0.62rem 0.72rem 0.52rem;
  background: rgba(255, 255, 255, 0.035);
  border-bottom: 0.06rem solid rgba(255, 255, 255, 0.06);
  box-shadow: inset 0 -1px 0 rgba(225, 29, 72, 0.16);
}

.adult-detail-gallery-head strong,
.adult-detail-gallery-head small {
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.adult-detail-gallery-head strong {
  color: rgba(255, 255, 255, 0.94);
  font-size: 0.78rem;
  font-weight: 900;
}

.adult-detail-gallery-head small {
  max-width: 46%;
  color: rgba(207, 210, 229, 0.62);
  font-size: 0.66rem;
  font-weight: 800;
}

.adult-detail-gallery-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.42rem;
  padding: 0.5rem;
}

.adult-detail-gallery-thumb {
  position: relative;
  min-width: 0;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  border: 0.06rem solid rgba(255, 255, 255, 0.075);
  border-radius: 0.72rem;
  background: rgba(255, 255, 255, 0.035);
  cursor: pointer;
  transition: border-color 150ms ease, box-shadow 150ms ease, transform 150ms ease;
}

.adult-detail-gallery-thumb img {
  width: 100%;
  height: 100%;
  display: block;
  object-fit: cover;
  object-position: center;
  filter: brightness(0.84) saturate(0.98);
  transition: transform 180ms ease, filter 180ms ease;
  pointer-events: none;
}

.adult-detail-gallery-thumb::after {
  content: "";
  position: absolute;
  inset: auto 0 0;
  height: 48%;
  background: linear-gradient(0deg, rgba(0, 0, 0, 0.62), transparent);
  pointer-events: none;
}

.adult-detail-gallery-thumb span {
  position: absolute;
  right: 0.34rem;
  bottom: 0.28rem;
  z-index: 1;
  display: inline-grid;
  min-width: 1.15rem;
  height: 1.15rem;
  place-items: center;
  border-radius: 0.38rem;
  background: rgba(8, 10, 18, 0.78);
  border: 0.06rem solid rgba(255, 255, 255, 0.14);
  color: #fff;
  font-size: 0.64rem;
  font-weight: 900;
  pointer-events: none;
}

.adult-detail-gallery-thumb:is(:hover, :focus-visible, .is-tv-focused),
.adult-detail-gallery-thumb.is-active {
  outline: 0;
  border-color: rgba(138, 92, 255, 0.78);
  box-shadow: inset 0 0 0 0.1rem rgba(138, 92, 255, 0.52), 0 0.7rem 1.4rem rgba(0, 0, 0, 0.38);
}

.adult-detail-gallery-thumb:is(:hover, :focus-visible, .is-tv-focused) img,
.adult-detail-gallery-thumb.is-active img {
  transform: scale(1.035);
  filter: brightness(1) saturate(1.04);
}

.adult-detail-gallery-thumb:focus:not(:focus-visible):not(.is-tv-focused):not(.is-active) {
  border-color: rgba(255, 255, 255, 0.075);
  box-shadow: none;
}

/* The video-frame is only a mount point for the fixed cinema player; in the
   detail view it occupies no space and its placeholder content stays hidden. */
.watch-side .video-frame {
  position: absolute;
  width: 0;
  height: 0;
  min-height: 0;
  margin: 0;
  padding: 0;
  border: 0;
  overflow: hidden;
  background: none !important;
}
.watch-side .video-frame::before { display: none !important; }

/* During playback the fixed cinema player must escape to the viewport, so strip
   any property on its ancestors that would create a fixed-positioning context. */
body.player-cinema-open .watch-side,
body.has-embedded-player .watch-side {
  -webkit-backdrop-filter: none !important;
  backdrop-filter: none !important;
  filter: none !important;
  transform: none !important;
  overflow: visible !important;
}

/* ── Mobile: stack backdrop + content, source panel becomes a bottom sheet ── */
@media (max-width: 860px) {
  /* .watch-panel is the sole vertical scroller on compact layouts. `hidden`
     still permits programmatic scrolling, so scrollIntoView could also move
     this fixed outer shell and reveal the blurred backdrop below the panel. */
  .watch-overlay.cinematic { overflow: clip; }

  .watch-overlay.cinematic .watch-panel {
    grid-template-columns: 1fr;
    grid-template-rows: 1fr auto;
    height: 100%;
    max-height: 100%;
    margin: 0;
  }
  .watch-backdrop { background-position: center 8%; }
  .watch-backdrop::after {
    background:
      linear-gradient(0deg, rgba(6,6,13,0.97) 8%, rgba(7,7,15,0.05) 60%, rgba(7,7,15,0.3) 100%),
      linear-gradient(90deg, rgba(7,7,15,0.55) 0%, transparent 40%);
  }
  .watch-stage {
    justify-content: flex-end;
    padding: 3rem 1.2rem 1rem;
  }
  .watch-stage-body { max-width: none; }
  .watch-side {
    height: auto;
    max-height: 46dvh;
    margin: 0;
    padding: 0.8rem 0.9rem calc(0.8rem + env(safe-area-inset-bottom));
    border: 0;
    border-top: 0.08rem solid rgba(255,255,255,0.08);
    border-radius: 1.1rem 1.1rem 0 0;
    box-shadow: 0 -1.4rem 3rem rgba(0,0,0,0.5);
  }
  .watch-overlay.cinematic .watch-title { font-size: clamp(1.7rem, 7vw, 2.6rem); }
  .watch-summary.is-expanded { max-height: 20dvh; }
}

/* Small tablets keep the cinematic hero and episode browser in one viewport.
   The generic <=860px stack used a `1fr auto` grid while .watch-stage still
   owned 100dvh, which squeezed the second row to roughly 26px at 820px wide.
   Phones use the flattened scrolling layout below; this split is specifically
   for the tablet band between those two designs. */
@media (min-width: 761px) and (max-width: 860px) {
  .watch-overlay.cinematic .watch-panel {
    grid-template-rows: minmax(0, 54%) minmax(0, 46%);
    overflow: hidden;
  }
  .watch-overlay.cinematic .watch-stage {
    height: 100%;
    min-height: 0;
    padding: 3.2rem 1.4rem 1.2rem;
  }
  .watch-overlay.cinematic .watch-side {
    height: 100%;
    min-height: 0;
    max-height: 100%;
    margin: 0;
    overflow: hidden;
  }
  .watch-overlay.cinematic .watch-side .episode-list {
    height: 100%;
    min-height: 0;
  }
}

/* ── TV remote focus: clear ring + lift on the cinematic controls ─────────── */
.watch-overlay.cinematic .primary-action.is-tv-focused,
.icon-action.is-tv-focused,
.watch-overlay.cinematic .close-button.is-tv-focused {
  outline: 0;
  box-shadow: 0 0 0 0.22rem var(--accent, #8a5cff), 0 0.8rem 2rem rgba(0,0,0,0.5);
  transform: translateY(-2px) scale(1.04);
}

/* ══════════════════════════════════════════════════════════════════════════
   Episode browser (Stremio-style): season nav + video search + thumbnail rows
   ══════════════════════════════════════════════════════════════════════════ */
.watch-side .episode-list {
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
  padding: 0;
}

/* Sticky season-nav + search header. */
.ep-panel-head {
  position: sticky;
  top: 0;
  z-index: 3;
  display: grid;
  /* rail | centred season button | rail - the outer tracks size to their
     buttons, so the middle one is always the true centre of the bar. */
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 0.4rem;
  padding: 0.36rem 0.2rem 0.62rem;
  margin: 0 -0.1rem;
  background: #0c0d16;
}
/* The rails keep their own size; only the middle track is free to absorb the
   remaining width, which is what keeps the button centred as the panel grows. */
.ep-panel-head > .ep-nav-btn:first-child { justify-self: start; }
.ep-panel-head > .ep-nav-btn:last-child { justify-self: end; }
.ep-panel-head > .ep-season-select { justify-self: center; max-width: 100%; }
.ep-nav-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  min-height: 2.25rem;
  padding: 0.32rem 0.55rem;
  border: 0;
  border-radius: 999rem;
  background: rgba(255, 255, 255, 0.045);
  color: rgba(226, 228, 242, 0.74);
  font-size: 0.82rem;
  font-weight: 700;
  cursor: pointer;
  transition: background 150ms ease, color 150ms ease, transform 150ms ease;
}
.ep-nav-btn span[aria-hidden] { font-size: 1.08rem; line-height: 1; }
.ep-nav-btn:is(:hover, :focus-visible) { background: rgba(255,255,255,0.09); color: #fff; outline: 0; }
.ep-nav-btn[disabled] { opacity: 0.32; pointer-events: none; }
.ep-nav-label { font-size: 0.82rem; }

.ep-season-select { position: relative; }
.ep-season-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  min-height: 2.38rem;
  padding: 0.38rem 0.82rem;
  border: 0.08rem solid rgba(255, 255, 255, 0.12);
  border-radius: 999rem;
  background:
    linear-gradient(135deg, rgba(255, 255, 255, 0.08), rgba(255, 255, 255, 0.03));
  color: #fff;
  font-size: 0.9rem;
  font-weight: 800;
  cursor: pointer;
  box-shadow: inset 0 0 0 0.08rem rgba(255, 255, 255, 0.025);
  transition: background 150ms ease, border-color 150ms ease, box-shadow 150ms ease;
}
.ep-season-btn:is(:hover, :focus-visible) {
  border-color: rgba(0, 210, 255, 0.34);
  background: linear-gradient(135deg, rgba(138, 92, 255, 0.22), rgba(0, 210, 255, 0.12));
  box-shadow: 0 0 0 0.16rem rgba(0, 210, 255, 0.08);
  outline: 0;
}
.ep-season-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}
.ep-season-btn { max-width: 100%; }
.ep-season-caret { flex: 0 0 auto; font-size: 0.8rem; color: rgba(255,255,255,0.6); }
.ep-season-menu {
  position: absolute;
  top: calc(100% + 0.35rem);
  left: 50%;
  transform: translateX(-50%);
  z-index: 20;
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  min-width: 12rem;
  max-height: 18rem;
  overflow-y: auto;
  padding: 0.4rem;
  border: 0.08rem solid rgba(255,255,255,0.12);
  border-radius: 0.8rem;
  background: rgba(18, 19, 32, 0.98);
  box-shadow: 0 1.2rem 3rem rgba(0,0,0,0.55);
  scrollbar-width: none;
}
.ep-season-menu[hidden] {
  display: none;
}
.ep-season-menu::-webkit-scrollbar { display: none; }
.ep-season-option {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.8rem;
  padding: 0.55rem 0.7rem;
  border: 0;
  border-radius: 0.5rem;
  background: transparent;
  color: rgba(232, 234, 246, 0.9);
  font-size: 0.92rem;
  font-weight: 700;
  text-align: left;
  cursor: pointer;
  white-space: nowrap;
}
.ep-season-option small { color: rgba(255,255,255,0.45); font-weight: 600; }
.ep-season-option:is(:hover, :focus-visible) { background: rgba(255,255,255,0.1); color: #fff; outline: 0; }
.ep-season-option.is-selected { background: var(--accent, #8a5cff); color: #fff; }
.ep-season-option.is-selected small { color: rgba(255,255,255,0.8); }

/* Video search. */
.ep-search {
  position: relative;
  display: flex;
  align-items: center;
  margin: 0 0.1rem 0.5rem;
}
.ep-search-input {
  width: 100%;
  padding: 0.7rem 2.4rem 0.7rem 1rem;
  border: 0.08rem solid rgba(255,255,255,0.12);
  border-radius: 999rem;
  background: rgba(255,255,255,0.06);
  color: #fff;
  font-size: 0.95rem;
  transition: border-color 150ms ease, background 150ms ease;
}
.ep-search-input::placeholder { color: rgba(226,228,242,0.5); }
.ep-search-input:focus { outline: 0; border-color: var(--accent, #8a5cff); background: rgba(255,255,255,0.09); }
.ep-search-icon { position: absolute; right: 1rem; color: rgba(255,255,255,0.55); font-size: 1.05rem; pointer-events: none; }

/* Episode rows. */
.ep-rows {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  gap: 0.35rem;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding-bottom: 0.75rem;
  scrollbar-width: none;
  -ms-overflow-style: none;
}
.ep-rows::-webkit-scrollbar { display: none; }
.ep-row {
  display: grid;
  grid-template-columns: 7rem 1fr;
  align-items: center;
  gap: 0.85rem;
  width: 100%;
  padding: 0.45rem;
  border: 0.08rem solid transparent;
  border-radius: 0.7rem;
  background: transparent;
  color: inherit;
  text-align: left;
  cursor: pointer;
  transition: background 150ms ease, border-color 150ms ease, transform 150ms ease;
  content-visibility: auto;
  contain-intrinsic-size: 5.4rem;
}
.ep-row:is(:hover, :focus-visible) { background: rgba(255,255,255,0.07); outline: 0; }
.ep-row.is-selected { background: rgba(138, 92, 255, 0.16); border-color: rgba(138, 92, 255, 0.5); }
.ep-row.is-locked { opacity: 0.5; }

.ep-thumb {
  position: relative;
  aspect-ratio: 16 / 9;
  width: 100%;
  border-radius: 0.5rem;
  overflow: hidden;
  background: linear-gradient(135deg, #1b1d2e, #11121d);
  display: grid;
  place-items: center;
}
.ep-thumb.is-placeholder {
  isolation: isolate;
  box-shadow:
    inset 0 0 0 0.06rem rgba(255, 255, 255, 0.08),
    inset 0 -2rem 3.5rem rgba(0, 0, 0, 0.34),
    0 0.9rem 2rem rgba(0, 0, 0, 0.22);
  background:
    radial-gradient(circle at 82% 18%, hsla(var(--episode-hue), 94%, 64%, 0.42), transparent 30%),
    radial-gradient(circle at 18% 88%, hsla(calc(var(--episode-hue) + 82), 92%, 56%, 0.28), transparent 42%),
    linear-gradient(145deg, hsl(var(--episode-hue), 48%, 18%), #070912 72%);
}
.ep-thumb.is-fallback {
  isolation: isolate;
  background:
    radial-gradient(circle at 75% 20%, hsla(var(--episode-hue), 85%, 60%, 0.38), transparent 38%),
    radial-gradient(circle at 25% 80%, hsla(calc(var(--episode-hue) + 60), 80%, 50%, 0.28), transparent 44%),
    linear-gradient(135deg, hsl(var(--episode-hue), 40%, 16%), #080912 75%);
}
.ep-thumb.is-fallback .ep-thumb-img {
  filter: brightness(0.65) saturate(1.05);
  transform: scale(1.02);
  opacity: 0.85;
}
/* Keep unloaded episode art calm and stable while the real season still is
   prefetched. Movement here made a season change read as a flashing reload. */
.ep-thumb.is-placeholder::before {
  content: "";
  position: absolute;
  inset: -22%;
  z-index: 0;
  background:
    radial-gradient(40% 48% at 30% 32%, hsla(var(--episode-hue), 92%, 64%, 0.55), transparent 72%),
    radial-gradient(46% 54% at 74% 70%, hsla(calc(var(--episode-hue) + 58), 88%, 58%, 0.45), transparent 76%),
    radial-gradient(36% 42% at 58% 48%, hsla(calc(var(--episode-hue) + 184), 72%, 54%, 0.30), transparent 80%);
  filter: blur(7px) saturate(1.18);
  transform: scale(1.12);
  opacity: 0.72;
}
.ep-thumb-empty {
  position: absolute;
  inset: 0.45rem;
  z-index: 1;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  align-items: flex-start;
  gap: 0.18rem;
  padding: 0.55rem 0.6rem 1.2rem;
  border-radius: 0.38rem;
  border: 0.05rem solid rgba(255, 255, 255, 0.08);
  background: linear-gradient(145deg, rgba(255, 255, 255, 0.055), rgba(8, 9, 18, 0.18));
  overflow: hidden;
}
.ep-thumb-empty::before {
  content: "";
  position: absolute;
  inset: auto -12% -45% 35%;
  height: 86%;
  border-radius: 999rem 999rem 0 0;
  background: radial-gradient(circle at 50% 24%, hsla(var(--episode-hue), 90%, 62%, 0.16), transparent 62%);
  opacity: 0.7;
}
.ep-thumb-empty-copy {
  position: relative;
  z-index: 2;
  display: -webkit-box;
  max-width: 100%;
  color: rgba(255, 255, 255, 0.88);
  font-size: clamp(0.5rem, 1.1vw, 0.64rem);
  font-weight: 850;
  line-height: 1.05;
  letter-spacing: 0;
  overflow: hidden;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}
.ep-thumb-empty-kicker {
  position: relative;
  z-index: 2;
  color: hsla(var(--episode-hue), 96%, 74%, 0.95);
  font-size: 0.48rem;
  font-weight: 900;
  line-height: 1;
  text-transform: uppercase;
  letter-spacing: 0;
}
.ep-thumb.is-placeholder .ep-thumb-play {
  opacity: 0;
  background: linear-gradient(135deg, rgba(138, 92, 255, 0.88), rgba(0, 210, 255, 0.68));
  box-shadow: 0 0 1.1rem rgba(0, 210, 255, 0.22);
}
.ep-thumb-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.ep-thumb-num {
  position: absolute;
  left: 0.3rem;
  bottom: 0.3rem;
  z-index: 1;
  padding: 0.05rem 0.4rem;
  border-radius: 0.35rem;
  background: rgba(6, 6, 13, 0.78);
  color: #fff;
  font-size: 0.74rem;
  font-weight: 800;
}

.poster-placeholder {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  align-items: center;
  padding: 1.5rem;
  border-radius: 0.5rem;
  box-shadow:
    inset 0 0 0 0.06rem rgba(255, 255, 255, 0.08),
    inset 0 -4rem 6rem rgba(0, 0, 0, 0.45);
  background:
    radial-gradient(circle at 82% 18%, hsla(280, 94%, 64%, 0.35), transparent 40%),
    radial-gradient(circle at 18% 88%, hsla(190, 92%, 56%, 0.22), transparent 50%),
    linear-gradient(145deg, hsl(280, 48%, 14%), #070912 85%);
  overflow: hidden;
}

/* Same "blurred fill" loading language as the episode thumb + watch backdrop:
   one soft, out-of-focus colour wash that gently drifts (was a white sheen sweep
   PLUS a spinning orbit circle — two competing animations). */
.poster-placeholder::before {
  content: "";
  position: absolute;
  inset: -18%;
  z-index: 0;
  background:
    radial-gradient(38% 40% at 30% 30%, hsla(280, 92%, 64%, 0.5), transparent 72%),
    radial-gradient(44% 46% at 74% 72%, hsla(196, 90%, 56%, 0.4), transparent 76%),
    radial-gradient(34% 38% at 58% 50%, hsla(330, 80%, 60%, 0.28), transparent 80%);
  filter: blur(10px) saturate(1.18);
  transform: scale(1.1);
  animation: blur-fill-drift 9s ease-in-out infinite;
  will-change: transform;
}

.poster-placeholder-mark {
  color: rgba(255, 255, 255, 0.92);
  font-family: Inter, ui-sans-serif, system-ui, sans-serif;
  font-size: 3.5rem;
  font-weight: 950;
  line-height: 1;
  text-shadow: 0 0 1.5rem hsla(280, 90%, 62%, 0.6);
  margin-bottom: auto;
  margin-top: 4rem;
  z-index: 2;
}

.poster-placeholder-copy {
  color: rgba(255, 255, 255, 0.6);
  font-family: Inter, ui-sans-serif, system-ui, sans-serif;
  font-size: 0.75rem;
  font-weight: 850;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  z-index: 2;
  text-align: center;
  text-shadow: 0 0.1rem 0.5rem rgba(0, 0, 0, 0.5);
}
.ep-thumb-play {
  position: relative;
  z-index: 1;
  display: grid;
  place-items: center;
  width: 1.9rem;
  height: 1.9rem;
  border-radius: 999rem;
  background: rgba(8, 8, 16, 0.55);
  color: #fff;
  font-size: 0.85rem;
  opacity: 0;
  transition: opacity 150ms ease;
}
.ep-row:is(:hover, :focus-visible, .is-tv-focused) .ep-thumb-play { opacity: 1; }

@keyframes ep-thumb-sheen {
  0%, 46% { transform: translateX(-48%); opacity: 0.48; }
  62% { transform: translateX(24%); opacity: 0.86; }
  100% { transform: translateX(48%); opacity: 0.48; }
}

@keyframes ep-thumb-orbit {
  0%, 100% { transform: scale(0.94); opacity: 0.72; }
  50% { transform: scale(1.05); opacity: 1; }
}

/* Gentle out-of-focus drift for the "blurred fill" loading placeholders. Pure
   GPU transform (translate/scale) so it never costs layout/paint. Start and end
   match for a seamless loop. */
@keyframes blur-fill-drift {
  0%   { transform: scale(1.12) translate3d(-3%, -2%, 0); }
  33%  { transform: scale(1.2) translate3d(2%, -3%, 0); }
  66%  { transform: scale(1.16) translate3d(3%, 2%, 0); }
  100% { transform: scale(1.12) translate3d(-3%, -2%, 0); }
}

@media (prefers-reduced-motion: reduce) {
  .ep-thumb.is-placeholder::before,
  .ep-thumb.is-placeholder::after,
  .poster-placeholder::before {
    animation: none;
  }
}

.ep-row-body { min-width: 0; display: flex; flex-direction: column; gap: 0.2rem; }
.ep-row-title {
  color: #fff;
  font-size: 0.98rem;
  font-weight: 700;
  line-height: 1.25;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.ep-row-meta { color: rgba(220, 222, 238, 0.6); font-size: 0.82rem; font-weight: 600; }
.ep-empty { padding: 1.4rem 0.6rem; color: rgba(220, 222, 238, 0.6); font-size: 0.9rem; line-height: 1.5; }

/* TV remote focus for the episode browser. */
.ep-row.is-tv-focused,
.ep-nav-btn.is-tv-focused,
.ep-season-btn.is-tv-focused,
.ep-season-option.is-tv-focused,
.ep-search-input.is-tv-focused {
  outline: 0;
  box-shadow: 0 0 0 0.18rem var(--accent, #8a5cff);
  background: rgba(138, 92, 255, 0.18);
}
.ep-row.is-tv-focused { transform: scale(1.015); }

/* ── Global fullscreen and adult random controls ─────────────────────────── */
.fs-toggle,
.adult-random-toggle {
  position: fixed;
  /* Sits higher than it used to: in the detail overlay the Seasons/Episodes panel
     starts just under the top-right corner and the two were crowding each other. */
  top: clamp(0.5rem, 1.05vh, 0.85rem);
  right: clamp(0.75rem, 1.7vw, 1.3rem);
  z-index: 60;
  display: grid;
  place-items: center;
  width: 2.9rem;
  height: 2.9rem;
  /* Same surface and border as the back button in the opposite corner, so the two
     read as a matched pair rather than two different controls. */
  border: 0.08rem solid rgba(255, 255, 255, 0.14);
  border-radius: 999rem;
  background: rgba(12, 12, 22, 0.6);
  color: rgba(240, 242, 252, 0.92);
  cursor: pointer;
  -webkit-backdrop-filter: blur(12px) saturate(1.1);
  backdrop-filter: blur(12px) saturate(1.1);
  box-shadow: 0 0.5rem 1.5rem rgba(0,0,0,0.35), inset 0 0 0 0.08rem rgba(255,255,255,0.04);
  transition: background 180ms ease, transform 180ms ease, border-color 180ms ease, box-shadow 180ms ease;
}
.adult-random-toggle {
  right: calc(clamp(0.75rem, 1.7vw, 1.3rem) + 3.55rem);
  display: none;
}
body.adult-mode .adult-random-toggle:not([hidden]) { display: grid; }
.adult-random-toggle:disabled { cursor: wait; opacity: 0.65; }
/* Identical hover to the back button: same accent, same scale, same easing. */
.fs-toggle:is(:hover, :focus-visible),
.adult-random-toggle:is(:hover, :focus-visible) {
  background: rgba(24, 20, 46, 0.82);
  border-color: rgba(138, 85, 255, 0.55);
  color: #ffffff;
  transform: scale(1.06);
  box-shadow: 0 0.7rem 1.9rem rgba(0, 0, 0, 0.42);
  outline: 0;
}
.fs-toggle:active,
.adult-random-toggle:active { transform: scale(0.94); }
.fs-toggle.is-tv-focused,
.adult-random-toggle.is-tv-focused {
  outline: 0;
  border-color: transparent;
  box-shadow: 0 0 0 0.2rem var(--accent, #8a5cff), 0 0.7rem 1.9rem rgba(0,0,0,0.42);
  transform: scale(1.08);
}

/* Stacked icons that cross-fade + rotate between expand and compress. */
.fs-toggle .fs-ico,
.adult-random-toggle .adult-random-ico {
  grid-area: 1 / 1;
  width: 1.35rem;
  height: 1.35rem;
  transition: opacity 260ms ease, transform 360ms cubic-bezier(0.34, 1.4, 0.5, 1);
}
.adult-random-toggle.is-shuffling .adult-random-ico {
  animation: adult-random-cycle 420ms cubic-bezier(0.34, 1.35, 0.5, 1);
}
@keyframes adult-random-cycle {
  0% { transform: rotate(0deg) scale(1); }
  48% { transform: rotate(16deg) scale(0.82); }
  100% { transform: rotate(0deg) scale(1); }
}
.fs-ico-expand   { opacity: 1; transform: rotate(0deg) scale(1); }
.fs-ico-compress { opacity: 0; transform: rotate(-90deg) scale(0.55); }
body.is-fullscreen .fs-ico-expand   { opacity: 0; transform: rotate(90deg) scale(0.55); }
body.is-fullscreen .fs-ico-compress { opacity: 1; transform: rotate(0deg) scale(1); }

/* Pulse the button each time fullscreen toggles (class added briefly in JS). */
.fs-toggle.fs-pulse { animation: fs-pulse 460ms cubic-bezier(0.34, 1.5, 0.5, 1); }
@keyframes fs-pulse {
  0%   { transform: scale(1); }
  35%  { transform: scale(1.22); box-shadow: 0 0 0 0.45rem rgba(138,92,255,0.28); }
  100% { transform: scale(1); box-shadow: 0 0.5rem 1.5rem rgba(0,0,0,0.35); }
}
body.reduce-motion .fs-toggle.fs-pulse { animation: none; }
body.reduce-motion .adult-random-toggle.is-shuffling .adult-random-ico { animation: none; }

/* Stay clear of the active video player chrome (cinema z-index is far higher). */
body.player-cinema-open .fs-toggle,
body.has-embedded-player .fs-toggle,
body.adult-mode.player-cinema-open .adult-random-toggle:not([hidden]),
body.adult-mode.has-embedded-player .adult-random-toggle:not([hidden]) { display: none; }

/* ══════════════════════════════════════════════════════════════════════════
   Low-power TV WebView safety: drop GPU-heavy effects (backdrop-filter blurs
   and the continuous backdrop zoom). On a 4K TV GPU these can OOM/crash the
   renderer. Panels get opaque backgrounds so the dropped blur still reads well.
   ══════════════════════════════════════════════════════════════════════════ */
body.is-tv *,
body.is-tv *::before,
body.is-tv *::after {
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
}
body.is-tv .watch-backdrop {
  animation: none !important;
  transform: scale(1.02) !important;
}
body.is-tv .watch-stage-body { animation: none !important; }
body.is-tv .watch-overlay.cinematic { background: #06060d; }
body.is-tv .watch-side {
  background: linear-gradient(180deg, rgba(13, 14, 24, 0.97), rgba(8, 9, 17, 0.99));
}
/* The native TV app is already fullscreen — hide the (non-working there) button. */
body.is-tv .fs-toggle { display: none !important; }
body.is-tv.adult-mode .adult-random-toggle:not([hidden]) {
  right: clamp(0.75rem, 1.7vw, 1.3rem);
}
body.is-tv .icon-action { background: rgba(24, 25, 40, 0.92); }
body.is-tv .ep-season-menu { background: rgba(18, 19, 32, 1); }

/* ══════════════════════════════════════════════════════════════════════════
   Watch tracking — WATCHED/CONTINUE badges, progress bars, season stats,
   Continue Watching rail. (Local-only; layered onto the existing UI.)
   ══════════════════════════════════════════════════════════════════════════ */
.ep-row { position: relative; }
.ep-row.is-watched { opacity: 0.72; }
.ep-row.is-watched .ep-row-title { color: rgba(236, 238, 250, 0.7); }

.ep-badge {
  position: absolute;
  top: 0.5rem;
  right: 0.55rem;
  padding: 0.12rem 0.42rem;
  border-radius: 0.35rem;
  font-size: 0.62rem;
  font-weight: 900;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  line-height: 1.5;
  pointer-events: none;
}
.ep-badge-watched { background: rgba(46, 204, 130, 0.92); color: #04130c; }
.ep-badge-continue { background: var(--accent, #8a5cff); color: #fff; }

/* The badge is absolutely positioned over the row's top-right corner, so a long
   episode title ran straight underneath it - "Like a Villainess, Like a
   Villainess" overlapped the CONTINUE chip by 73px. Reserve the chip's width on
   the title so the 2-line clamp wraps before reaching it.
   Measured: chip 4.47rem wide + 0.55rem right offset, less the row's 0.45rem
   padding, so 5.1rem clears it with a small gap. Scoped with :has() so rows
   without a badge keep the full title width. */
.ep-row:has(.ep-badge) .ep-row-title {
  padding-right: 5.1rem;
}

/* Thin progress bar pinned to the bottom of the episode thumbnail. */
.ep-progress {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 0.28rem;
  background: rgba(0, 0, 0, 0.55);
  z-index: 2;
}
.ep-progress > span { display: block; height: 100%; background: var(--accent, #8a5cff); }
.ep-row.is-watched .ep-progress > span { background: #2ecc82; }

/* Season completion line. */
.ep-stats {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: 0.4rem 0.6rem;
  margin: 0 0.1rem 0.7rem;
  padding: 0.55rem 0.7rem;
  border-radius: 0.6rem;
  background: rgba(255, 255, 255, 0.05);
  color: rgba(226, 228, 242, 0.85);
  font-size: 0.82rem;
  font-weight: 700;
}
.ep-stats-text b { color: #fff; }
.ep-stats-pct { color: var(--accent, #8a5cff); font-weight: 900; }
.ep-stats-bar { grid-column: 1 / -1; height: 0.3rem; border-radius: 999rem; background: rgba(255,255,255,0.1); overflow: hidden; }
.ep-stats-bar > span { display: block; height: 100%; background: var(--accent, #8a5cff); border-radius: inherit; }

/* Continue Watching rail (landscape cards with a resume bar). */
.section-heading .continue-dot { background: var(--accent, #8a5cff); }
.section-heading .continue-dot.adult-dot { background: #e11d48; }
.continue-card {
  width: clamp(13rem, 22vw, 16rem);
  text-align: left;
}
.continue-thumb {
  position: relative;
  display: block;
  aspect-ratio: 16 / 9;
  width: 100%;
  border-radius: 0.7rem;
  overflow: hidden;
  background: linear-gradient(135deg, #1b1d2e, #11121d);
}
.continue-thumb img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.continue-play {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  font-size: 1.5rem;
  color: #fff;
  background: rgba(6, 6, 14, 0.28);
  opacity: 0;
  transition: opacity 160ms ease;
}
.continue-card:is(:hover, :focus-visible, .is-tv-focused) .continue-play { opacity: 1; }
.continue-bar { position: absolute; left: 0; right: 0; bottom: 0; height: 0.32rem; background: rgba(0,0,0,0.55); }
.continue-bar > span { display: block; height: 100%; background: var(--accent, #8a5cff); }
.continue-bar-outside { position: absolute; left: 0; right: 0; bottom: 0; height: 0.22rem; background: rgba(255, 255, 255, 0.18); overflow: hidden; z-index: 5; }
.continue-bar-outside > span { display: block; height: 100%; background: #ffffff; }
.continue-card-title {
  display: block;
  margin: 0.5rem 0 0.1rem;
  color: #fff;
  font-size: 0.92rem;
  font-weight: 800;
  line-height: 1.2;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.continue-card-sub { color: rgba(220, 222, 238, 0.62); font-size: 0.78rem; font-weight: 600; }

/* ══════════════════════════════════════════════════════════════════════════
   Stremio-style web player polish (visual only — control structure unchanged)
   ══════════════════════════════════════════════════════════════════════════ */
/* Title reads left-aligned like Stremio (episode nav stays in the control row). */
.vidstream-player:not(.is-iframe) .vid-topbar {
  background: linear-gradient(180deg, rgba(0,0,0,0.78), rgba(0,0,0,0.12) 70%, transparent);
}
.vidstream-player:not(.is-iframe) .vid-topbar strong {
  text-align: left;
  padding-left: 0.4rem;
  font-size: clamp(0.98rem, 1.4vw, 1.18rem);
  font-weight: 800;
  letter-spacing: 0.01em;
}
/* Bottom controls: cleaner gradient + a little more breathing room. */
.vid-controls {
  gap: 0.65rem;
  padding: 1rem 1rem 0.9rem;
  background: linear-gradient(0deg, rgba(0,0,0,0.9), rgba(0,0,0,0.32) 55%, transparent);
}
/* Bigger, draggable accent seek bar that grows on hover/focus (Stremio feel). */
.vid-controls .vid-seek {
  height: 0.4rem;
  border-radius: 999rem;
  accent-color: var(--accent, #8a5cff);
  transition: height 120ms ease;
}
.vid-controls .vid-seek:is(:hover, :focus-visible) { height: 0.6rem; outline: 0; }
.vid-controls .vid-seek::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 1.05rem;
  height: 1.05rem;
  border-radius: 999rem;
  background: #fff;
  box-shadow: 0 0 0 0.3rem rgba(138, 92, 255, 0.4);
  cursor: pointer;
}
.vid-controls .vid-seek::-moz-range-thumb {
  width: 1.05rem; height: 1.05rem; border: 0; border-radius: 999rem;
  background: #fff; box-shadow: 0 0 0 0.3rem rgba(138, 92, 255, 0.4); cursor: pointer;
}
/* Slightly larger, cleaner control icons. */
.vid-control-row .vid-icon-button,
.vid-control-row .vid-tool-button { min-width: 2.5rem; min-height: 2.5rem; background: transparent; }
.vid-control-row .vid-icon-button:is(:hover, :focus-visible, .is-tv-focused),
.vid-control-row .vid-tool-button:is(:hover, :focus-visible, .is-tv-focused) {
  background: rgba(255,255,255,0.14);
  box-shadow: none;
}
.vid-time { font-variant-numeric: tabular-nums; }
.vid-volume-control { display: flex; align-items: center; gap: 0.35rem; }
.vid-volume-slider { width: 5.5rem; height: 0.3rem; accent-color: var(--accent, #8a5cff); border-radius: 999rem; cursor: pointer; opacity: 0.8; transition: width 0.2s ease, opacity 0.2s ease; }
.vid-volume-slider:is(:hover, :focus-visible) { opacity: 1; }
@media (max-width: 480px) { .vid-volume-slider { width: 3.5rem; } }

/* ══════════════════════════════════════════════════════════════════════════
   18+ / Hentai Mode — mature theme, header badge, age-gate dialog
   The toggle adds `.adult-mode` to <body>; removing it fully reverts the theme.
   ══════════════════════════════════════════════════════════════════════════ */
.nav-link[data-route="releases"] { --nav-accent: var(--route-schedule); }
.main-nav [data-route="releases"][hidden],
body:not(.adult-mode) .main-nav [data-route="releases"],
body:not(.adult-mode) #releases { display: none !important; }

.release-icon {
  display: inline-block;
  flex: 0 0 auto;
  width: 1.2rem;
  height: 1.2rem;
  background: currentColor;
  mask: var(--release-icon) center / contain no-repeat;
  -webkit-mask: var(--release-icon) center / contain no-repeat;
}
.release-icon-calendar-days { --release-icon: url("js/icons/calendar-days.svg"); }
.release-icon-chevron-left { --release-icon: url("js/icons/chevron-left.svg"); }
.release-icon-chevron-right { --release-icon: url("js/icons/chevron-right.svg"); }
.release-icon-arrow-up-right { --release-icon: url("js/icons/arrow-up-right.svg"); }
.release-icon-search { --release-icon: url("js/icons/search.svg"); }
.main-nav .nav-link > .release-icon { width: 1.3rem; height: 1.3rem; background: currentColor; border-radius: 0; }
#releases { min-width: 0; letter-spacing: 0; }
.releases-heading { display: flex; align-items: center; justify-content: space-between; gap: 1rem; padding: 0.6rem 0 1.7rem; }
.releases-heading-copy { min-width: 0; }
.releases-kicker { display: block; color: var(--muted); font-size: 0.75rem; margin-bottom: 0.35rem; }
.releases-heading h1 { margin: 0; font-size: 2rem; line-height: 1.15; font-weight: 800; letter-spacing: 0; overflow-wrap: anywhere; }
.releases-year-nav { display: flex; align-items: center; flex: 0 0 auto; gap: 0.4rem; margin-right: 3rem; }
.release-icon-button { display: grid; place-items: center; width: 2.5rem; height: 2.5rem; padding: 0; color: var(--text); background: transparent; border: 1px solid var(--line); border-radius: 6px; cursor: pointer; }
.release-icon-button:disabled { opacity: 0.3; cursor: default; }
.releases-year-nav select { width: 6.2rem; height: 2.5rem; border: 0; background: var(--bg-raised); color: var(--text); padding: 0 0.7rem; border-radius: 6px; font: inherit; font-size: 1.1rem; font-weight: 700; }
.releases-toolbar { display: flex; justify-content: space-between; align-items: center; gap: 1rem; padding-bottom: 1.2rem; }
.releases-status-tabs { display: flex; align-items: center; gap: 0.2rem; min-width: 0; padding: 0.2rem; background: rgba(255,255,255,0.035); border-radius: 6px; }
.releases-status-tabs button { border: 0; border-radius: 4px; padding: 0.65rem 0.95rem; background: transparent; color: var(--muted); font: inherit; font-size: 0.82rem; font-weight: 650; cursor: pointer; }
.releases-status-tabs button[aria-pressed="true"] { background: #ad1941; color: #fff; }
.releases-search { display: flex; align-items: center; gap: 0.6rem; width: min(18rem, 38%); min-width: 0; border-bottom: 1px solid rgba(255,255,255,0.18); color: var(--muted); padding: 0.6rem 0; }
.releases-search input { width: 100%; min-width: 0; border: 0; background: transparent; color: var(--text); font: inherit; font-size: 0.85rem; outline-offset: 4px; }
.releases-search input::placeholder { color: var(--muted); opacity: 0.8; }
.releases-months { display: flex; gap: 0.15rem; overflow-x: auto; overscroll-behavior-inline: contain; scrollbar-width: none; border-block: 1px solid var(--line); padding: 0.45rem 0; }
.releases-months::-webkit-scrollbar { display: none; }
.releases-months button { display: flex; align-items: center; justify-content: center; gap: 0.35rem; flex: 1 0 auto; min-height: 2.8rem; padding: 0.55rem; border: 0; border-radius: 4px; background: transparent; color: var(--muted); font: inherit; font-size: 0.78rem; cursor: pointer; white-space: nowrap; }
.releases-months button span { font-size: 0.62rem; opacity: 0.65; font-variant-numeric: tabular-nums; }
.releases-months button[aria-pressed="true"] { color: #fff; background: rgba(225,29,72,0.17); box-shadow: inset 0 -2px #f05d81; }
.releases-summary { display: flex; align-items: center; justify-content: space-between; gap: 1rem; min-height: 3.7rem; color: var(--muted); font-size: 0.75rem; }
.releases-summary p { margin: 0; color: var(--text); }
.releases-summary > span { text-align: right; }
.release-month-group { margin-bottom: 2rem; }
.release-month-heading { display: flex; align-items: baseline; gap: 0.8rem; margin: 0 0 1rem; }
.release-month-heading h2 { margin: 0; font-size: 1.15rem; font-weight: 700; letter-spacing: 0; }
.release-month-heading > span { color: var(--muted); font-size: 0.7rem; }
.release-grid { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 1.6rem 1.1rem; }
.release-card { display: block; min-width: 0; color: var(--text); text-decoration: none; border-radius: 8px; }
.release-poster { position: relative; width: 100%; aspect-ratio: 259 / 370; overflow: hidden; isolation: isolate; background: var(--bg-raised) url("logo-mark-128.webp") center / 3rem no-repeat; border-radius: 8px; box-shadow: inset 0 0 0 1px rgba(255,255,255,0.06); }
.release-poster img { display: block; width: 100%; height: 100%; object-fit: cover; opacity: 0; transition: opacity 140ms ease, transform 220ms ease; }
.release-poster img.img-ready { opacity: 1; }
.release-poster img[hidden] { display: none; }
.release-episode { position: absolute; left: 0.55rem; bottom: 0.55rem; padding: 0.28rem 0.45rem; border-radius: 4px; background: rgba(8,8,12,0.91); color: #fff; font-size: 0.66rem; font-weight: 700; line-height: 1.4; }
.release-open { position: absolute; top: 0.55rem; right: 0.55rem; display: grid; place-items: center; width: 1.8rem; height: 1.8rem; border-radius: 50%; color: #fff; background: rgba(8,8,12,0.82); opacity: 0; transition: opacity 180ms ease; }
.release-card:is(:hover, :focus-visible, .is-tv-focused) .release-open { opacity: 1; }
a.release-card:is(:hover, :focus-visible, .is-tv-focused) .release-poster img { transform: scale(1.035); }
.release-card-copy { padding-top: 0.65rem; }
.release-card-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 0.3rem 0.5rem; font-size: 0.68rem; line-height: 1.5; }
.release-card-meta time { color: var(--muted); }
.release-status { display: inline-flex; align-items: center; gap: 0.3rem; }
.release-status::before { content: ""; width: 4px; height: 4px; border-radius: 50%; background: currentColor; }
.release-status.is-available { color: #7edab3; }
.release-status.is-upcoming { color: #eec46b; }
.release-status.is-released { color: #bcb5c2; }
.release-card h3 { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; overflow: hidden; min-height: 2.8em; margin: 0.35rem 0 0; font-size: 0.87rem; line-height: 1.4; font-weight: 650; letter-spacing: 0; overflow-wrap: anywhere; }
.release-card:focus-visible, #releases button:focus-visible, #releases select:focus-visible { outline: 2px solid #fb7185; outline-offset: 3px; }
#releases button:not(:disabled):hover { color: #fff; }
.releases-empty { display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 17rem; padding: 2rem 1rem; text-align: center; color: var(--muted); }
.releases-empty > .release-icon { width: 2rem; height: 2rem; color: #f05d81; }
.releases-empty button { border: 1px solid var(--line); background: var(--bg-raised); color: var(--text); border-radius: 6px; padding: 0.6rem 1rem; font: inherit; font-size: 0.85rem; cursor: pointer; }
.release-skeleton > div { aspect-ratio: 259 / 370; background: rgba(255,255,255,0.055); border-radius: 8px; animation: release-pulse 1.4s ease-in-out infinite alternate; }
.release-skeleton > span { display: block; height: 0.7rem; margin-top: 0.7rem; width: 85%; background: rgba(255,255,255,0.05); border-radius: 3px; }
.release-skeleton > span:last-child { width: 55%; }
@keyframes release-pulse { to { opacity: 0.45; } }
@media (max-width: 1250px) { .release-grid { grid-template-columns: repeat(5, minmax(0, 1fr)); } }
@media (max-width: 1050px) { .release-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
@media (max-width: 800px) { .release-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 600px) {
  .releases-heading { align-items: center; padding-top: 2.8rem; padding-bottom: 1.2rem; gap: 0.5rem; }
  .releases-heading h1 { font-size: 1.65rem; }
  .releases-kicker { font-size: 0.65rem; }
  .releases-year-nav { gap: 0.1rem; margin-right: 0; }
  .release-icon-button { width: 2rem; height: 2.5rem; border: 0; }
  .releases-year-nav select { width: 5.2rem; font-size: 0.95rem; padding: 0 0.3rem; }
  .releases-toolbar { flex-direction: column; align-items: stretch; gap: 0.7rem; }
  .releases-status-tabs button { flex: 1; padding: 0.65rem 0.4rem; font-size: 0.78rem; }
  .releases-search { width: 100%; }
  .releases-months button { padding-inline: 0.7rem; }
  .releases-summary { gap: 0.5rem; font-size: 0.68rem; }
  .release-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.25rem 0.8rem; }
  .release-card h3 { font-size: 0.8rem; }
  .release-card-meta { font-size: 0.65rem; gap: 0.2rem 0.4rem; }
  .release-month-heading h2 { font-size: 1.05rem; }
}

/* The regular weekly schedule uses the same compact calendar language as the
   adult release view: one horizontal period selector and a responsive poster
   grid. Its data and routes remain the regular airing catalogue. */
#schedule { min-width: 0; letter-spacing: 0; }
#schedule .schedule-page-heading { padding: 0.6rem 0 1.45rem; }
#schedule .schedule-page-heading h1 {
  margin: 0;
  font-size: 2rem;
  line-height: 1.15;
  font-weight: 800;
  letter-spacing: 0;
  overflow-wrap: anywhere;
}
#schedule .schedule-list { display: block; overflow: visible; }
#schedule .schedule-days button[aria-pressed="true"] {
  color: #fff;
  background: color-mix(in srgb, var(--route-schedule) 16%, transparent);
  box-shadow: inset 0 -2px var(--route-schedule);
}
#schedule .schedule-days button.is-today::before {
  content: "";
  flex: 0 0 auto;
  width: 0.34rem;
  height: 0.34rem;
  border-radius: 50%;
  background: var(--route-schedule);
  box-shadow: 0 0 0.55rem color-mix(in srgb, var(--route-schedule) 62%, transparent);
}
#schedule .schedule-days button.is-today:not([aria-pressed="true"]) { color: var(--text); }
#schedule .schedule-summary { margin-bottom: 0.1rem; }
#schedule .schedule-day-group { margin-bottom: 2.2rem; }
#schedule .schedule-day-group[aria-current="date"] .release-month-heading h2 { color: var(--route-schedule); }
#schedule .schedule-poster {
  background-color: var(--bg-raised);
  background-image:
    url("logo-mark-128.webp"),
    linear-gradient(145deg, color-mix(in srgb, var(--route-schedule) 11%, var(--bg-raised)), var(--bg-raised));
  background-position: center, center;
  background-repeat: no-repeat;
  background-size: 3rem, cover;
}
#schedule .schedule-poster .poster-placeholder { border-radius: 8px; }
#schedule .schedule-card:focus-visible,
#schedule .schedule-days button:focus-visible {
  outline: 2px solid var(--route-schedule);
  outline-offset: 3px;
}
#schedule .schedule-empty-state { min-height: 15rem; }
#schedule .schedule-empty-state > .release-icon { color: var(--route-schedule); }

@media (max-width: 600px) {
  #schedule .schedule-page-heading {
    align-items: center;
    padding-top: 0.7rem;
    padding-bottom: 1.1rem;
  }
  #schedule .schedule-page-heading h1 { font-size: 1.65rem; }
  #schedule .schedule-days button { padding-inline: 0.75rem; }
  #schedule .schedule-summary { gap: 0.5rem; font-size: 0.68rem; }
  #schedule .schedule-day-group { margin-bottom: 1.6rem; }
}

@media (prefers-reduced-motion: reduce) {
  .release-poster img, .release-open { transition: none; }
  .release-skeleton > div { animation: none; }
}

body.adult-mode {
  color-scheme: dark;
  --bg: #0a0306;
  --bg-raised: #1a0a12;
  --bar: rgba(26, 6, 14, 0.82);
  --text: #f7e9ef;
  --muted: #c690a4;
  --line: rgba(225, 29, 72, 0.16);
  --cyan: #e11d48;          /* primary accent → deep red */
  --rose: #7a2bd6;          /* dark violet */
  --heart: #c026d3;
  --blue: #7a2bd6;
  --gold: #f2bb46;
  --accent: #e11d48;
  --route-home: #e11d48;
  --route-library: #c026d3;
  --route-schedule: #f2bb46;
  --route-favorites: #c026d3;
  --route-settings: #e11d48;
}
body.adult-mode .app-shell {
  background:
    radial-gradient(120% 80% at 82% 0%, rgba(122, 43, 214, 0.20), transparent 60%),
    radial-gradient(110% 70% at 0% 100%, rgba(225, 29, 72, 0.16), transparent 58%),
    var(--bg);
}

/* "18+ — Hentai Mode" badge — fixed to the top-center so it never crowds the
   narrow icon sidebar (where it used to overflow into the carousel). */
.adult-mode-badge {
  position: absolute;
  bottom: 0.28rem;
  right: 0.25rem;
  z-index: 3;
  display: inline-block;
  padding: 0.1rem 0.3rem;
  border-radius: 0.22rem;
  background: #e11d48;
  color: #fff;
  font-size: 0.6rem;
  font-weight: 900;
  letter-spacing: 0.07em;
  line-height: 1.3;
  pointer-events: none;
  box-shadow: 0 0.08rem 0.4rem rgba(225, 29, 72, 0.8), inset 0 0 0 0.04rem rgba(255,255,255,0.18);
}
.adult-mode-badge::before { display: none; }
.adult-mode-badge[hidden] { display: none; }

/* Make the ZenkaiTV logo read red in 18+ mode: recolor the PNG glyph via filter
   AND retint the circular mark's glow/halo (which use hard-coded blues). */
body.adult-mode .brand-logo,
body.adult-mode .loader-logo {
  filter: grayscale(1) brightness(0.55) sepia(1) saturate(7) hue-rotate(-18deg) brightness(1.05);
}
body.adult-mode .brand-mark {
  background: #1a0a12;
  box-shadow:
    0 1rem 1.8rem rgba(225, 29, 72, 0.3),
    0 0 1.1rem rgba(225, 29, 72, 0.22),
    inset 0 0 0 0.08rem rgba(225, 29, 72, 0.34);
}
body.adult-mode .brand-mark::before {
  background: radial-gradient(circle at 50% 50%, rgba(225, 29, 72, 0.62), rgba(122, 43, 214, 0.34) 55%, transparent 72%);
}

/* Footer matches the mature theme in 18+ mode (blue glows/line → red/violet). */
body.adult-mode .bottom-bar {
  border-top-color: rgba(225, 29, 72, 0.22);
  background:
    radial-gradient(circle at 42% 0%, rgba(225, 29, 72, 0.2), transparent 24rem),
    radial-gradient(circle at 62% 110%, rgba(122, 43, 214, 0.16), transparent 23rem),
    linear-gradient(90deg, rgba(20, 6, 12, 0.96) 0 5.1rem, rgba(20, 6, 12, 0.9) 5.1rem, rgba(20, 6, 12, 0.82) 100%),
    linear-gradient(180deg, rgba(26, 10, 18, 0.94), #0a0306 92%, #0a0306);
}
body.adult-mode .bottom-bar::before {
  background: linear-gradient(90deg, transparent, rgba(225, 29, 72, 0.5), rgba(122, 43, 214, 0.34), transparent);
  background-size: 180% 100%;
}
body.adult-mode .bottom-bar::after {
  background:
    linear-gradient(105deg, transparent 0%, transparent 34%, rgba(255, 255, 255, 0.05) 48%, transparent 62%, transparent 100%),
    linear-gradient(180deg, rgba(255, 255, 255, 0.024), transparent 46%),
    linear-gradient(90deg, rgba(225, 29, 72, 0.06), transparent 34%, transparent 66%, rgba(122, 43, 214, 0.05));
  background-size: 230% 100%, 100% 100%, 100% 100%;
}
body.adult-mode .footer-wordmark {
  filter: grayscale(1) brightness(0.55) sepia(1) saturate(7) hue-rotate(-18deg) brightness(1.05);
}

/* Settings screen matches the mature theme in 18+ mode (its selected category,
   segmented choices, and toggle switches use hard-coded blues). */
body.adult-mode .settings-rail-item:is(:hover, :focus-visible, .is-tv-focused) {
  border-color: rgba(225, 29, 72, 0.32);
  background: rgba(225, 29, 72, 0.12);
}
body.adult-mode .settings-rail-item.is-selected {
  border-color: rgba(225, 29, 72, 0.5);
  background:
    linear-gradient(135deg, rgba(225, 29, 72, 0.28), rgba(122, 43, 214, 0.22)),
    rgba(255, 255, 255, 0.05);
  box-shadow: inset 0 0 0 0.04rem rgba(225, 29, 72, 0.24), 0 0.5rem 1.2rem rgba(225, 29, 72, 0.18);
}
body.adult-mode .settings-choice.is-selected,
body.adult-mode .settings-choice:is(:hover, :focus-visible, .is-tv-focused) {
  background: linear-gradient(135deg, #e11d48, #7a2bd6);
  box-shadow: 0 0.3rem 0.8rem rgba(225, 29, 72, 0.3);
}
body.adult-mode .settings-switch:is(:hover, :focus-visible, .is-tv-focused) {
  box-shadow: inset 0 0 0 0.06rem rgba(225, 29, 72, 0.4);
}
body.adult-mode .settings-switch.is-on {
  background: linear-gradient(135deg, #e11d48, #7a2bd6);
  box-shadow: inset 0 0 0 0.06rem rgba(225, 29, 72, 0.45), 0 0 0.9rem rgba(225, 29, 72, 0.4);
}
body.adult-mode .settings-field .language-select {
  border-color: rgba(225, 29, 72, 0.32);
}

/* Weekly Schedule isn't meaningful in 18+ mode — hide its nav entry + section. */
body.adult-mode [data-route="schedule"],
body.adult-mode #schedule {
  display: none !important;
}

/* Smooth the swap between the regular and mature palettes. */
.app-shell,
.topbar,
.nav-link,
.carousel-info,
.show-card,
.adult-mode-badge {
  transition: background-color 420ms ease, color 320ms ease, box-shadow 320ms ease, filter 420ms ease;
}

/* One-shot full-screen wash played when the theme is toggled. */
.theme-flash {
  position: fixed;
  inset: 0;
  z-index: 9999;
  pointer-events: none;
  opacity: 0;
  animation: theme-flash 620ms ease forwards;
}
@keyframes theme-flash {
  0%   { opacity: 0; }
  35%  { opacity: 0.85; }
  100% { opacity: 0; }
}
body.reduce-motion .theme-flash { animation-duration: 1ms; }

/* 18+ confirmation dialog (reuses the .ss-modal shell). */
.adult-confirm { text-align: center; border-color: rgba(225, 29, 72, 0.4); }
.adult-confirm-mark {
  display: inline-grid;
  place-items: center;
  width: 3.4rem;
  height: 3.4rem;
  margin: 0 auto 0.5rem;
  border-radius: 999rem;
  background: linear-gradient(135deg, #e11d48, #7a2bd6);
  color: #fff;
  font-weight: 900;
  font-size: 1.02rem;
  box-shadow: 0 0.4rem 1.2rem rgba(225, 29, 72, 0.4);
}
.adult-confirm .ss-modal-actions { justify-content: center; }
.adult-confirm-yes {
  color: #fff !important;
  background: linear-gradient(135deg, #e11d48, #b21e5a) !important;
}

/* Special Red Highlight and pulse animation for 18+ Mode Toggle in Settings */
.settings-line.adult-mode-highlight {
  border: 1px solid rgba(225, 29, 72, 0.4);
  box-shadow: 0 0 10px rgba(225, 29, 72, 0.2);
  animation: adultHighlightPulse 2s infinite ease-in-out;
  transition: all 0.3s ease;
}

.settings-line.adult-mode-highlight > span {
  color: #f43f5e !important; /* soft red / rose */
}

.settings-line.adult-mode-highlight .settings-switch {
  border-color: rgba(225, 29, 72, 0.8) !important;
}

@keyframes adultHighlightPulse {
  0%, 100% {
    border-color: rgba(225, 29, 72, 0.4);
    box-shadow: 0 0 8px rgba(225, 29, 72, 0.2);
    background: rgba(225, 29, 72, 0.04);
  }
  50% {
    border-color: rgba(225, 29, 72, 0.95);
    box-shadow: 0 0 16px rgba(225, 29, 72, 0.5);
    background: rgba(225, 29, 72, 0.12);
  }
}

/* ──────────────────────────────────────────────────────────────────────────
   Supabase Authentication UI & Profiles
   ────────────────────────────────────────────────────────────────────────── */
.topbar-auth {
  position: fixed;
  top: clamp(0.75rem, 1.7vh, 1.3rem);
  right: calc(clamp(0.75rem, 1.7vw, 1.3rem) + 3.4rem);
  z-index: 60;
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

body.player-cinema-open .topbar-auth,
body.has-embedded-player .topbar-auth,
body.is-tv .topbar-auth {
  display: none !important;
}

.topbar-auth-btn {
  display: grid;
  place-items: center;
  width: 2.9rem;
  height: 2.9rem;
  border: 0.08rem solid rgba(255, 255, 255, 0.18);
  border-radius: 999rem;
  background: rgba(13, 14, 24, 0.6);
  color: rgba(240, 242, 252, 0.92);
  cursor: pointer;
  -webkit-backdrop-filter: blur(12px) saturate(1.1);
  backdrop-filter: blur(12px) saturate(1.1);
  box-shadow: 0 0.5rem 1.5rem rgba(0, 0, 0, 0.35), inset 0 0 0 0.08rem rgba(255, 255, 255, 0.04);
  transition: background 180ms ease, transform 180ms ease, border-color 180ms ease, box-shadow 180ms ease;
  padding: 0;
  outline: none;
  overflow: hidden;
}
.topbar-auth-btn:is(:hover, :focus-visible) {
  background: rgba(36, 38, 58, 0.78);
  border-color: rgba(255, 255, 255, 0.34);
  transform: scale(1.07);
  box-shadow: 0 0.7rem 1.9rem rgba(0, 0, 0, 0.42);
  outline: 0;
}
.topbar-auth-btn:active {
  transform: scale(0.94);
}
.topbar-auth-btn.is-tv-focused {
  outline: 0;
  border-color: transparent;
  box-shadow: 0 0 0 0.2rem var(--accent, #8a5cff), 0 0.7rem 1.9rem rgba(0, 0, 0, 0.42);
  transform: scale(1.08);
}

.topbar-avatar-img {
  width: 100%;
  height: 100%;
  border-radius: 50%;
  object-fit: cover;
  display: block;
}

.user-profile-menu-container {
  position: relative;
  display: inline-block;
}
.user-profile-menu-container[hidden] {
  display: none !important;
}

.user-dropdown-menu {
  position: absolute;
  top: 2.8rem;
  right: 0;
  width: 9rem;
  background: rgba(13, 27, 42, 0.92);
  backdrop-filter: blur(1.2rem);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 0.6rem;
  padding: 0.4rem;
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  box-shadow: 0 0.6rem 2rem rgba(0, 0, 0, 0.45);
  z-index: 100;
}
.user-dropdown-menu .dropdown-item {
  background: transparent;
  color: rgba(226, 228, 242, 0.9);
  border: none;
  text-align: left;
  padding: 0.5rem 0.8rem;
  font-size: 0.85rem;
  font-weight: 600;
  border-radius: 0.4rem;
  cursor: pointer;
  transition: background 0.2s ease, color 0.2s ease;
}
.user-dropdown-menu .dropdown-item:is(:hover, :focus-visible, .is-tv-focused) {
  background: rgba(255, 255, 255, 0.08);
  color: #fff;
}

/* Auth Modal Overlay */
.auth-overlay {
  position: fixed;
  inset: 0;
  background: rgba(5, 7, 12, 0.82);
  backdrop-filter: blur(0.5rem);
  display: flex;
  align-items: center;
  justify-content: center;
  /* Above every other overlay (toasts 10000, cinema 10050, modal backdrop
     10060) so the login modal is never covered / click-blocked. */
  z-index: 10080;
  animation: fadeIn 0.25s ease forwards;
}
.auth-overlay[hidden] {
  display: none !important;
}
.auth-card {
  width: 24rem;
  max-width: 90vw;
  background: rgba(20, 25, 38, 0.85);
  backdrop-filter: blur(1.5rem);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 1.2rem;
  padding: 2.2rem;
  position: relative;
  box-shadow: 0 1.2rem 3rem rgba(0, 0, 0, 0.6);
  animation: scaleIn 0.25s ease forwards;
}
.auth-close-btn {
  position: absolute;
  top: 1rem;
  right: 1.2rem;
  background: transparent;
  border: none;
  color: rgba(255, 255, 255, 0.45);
  font-size: 1.8rem;
  cursor: pointer;
  line-height: 1;
  padding: 0.2rem;
  transition: color 0.2s ease;
}
.auth-close-btn:is(:hover, :focus-visible, .is-tv-focused) {
  color: #fff;
}

.auth-view h2 {
  font-size: 1.5rem;
  font-weight: 800;
  margin-bottom: 0.3rem;
  color: #fff;
}
.auth-view p {
  font-size: 0.85rem;
  color: rgba(226, 228, 242, 0.62);
  margin-bottom: 1.5rem;
}

.auth-form {
  display: flex;
  flex-direction: column;
  gap: 1.1rem;
}
.form-group {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  text-align: left;
}
.form-group label {
  font-size: 0.82rem;
  font-weight: 700;
  color: rgba(226, 228, 242, 0.8);
}
.form-group input {
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 0.5rem;
  padding: 0.65rem 0.9rem;
  color: #fff;
  font-size: 0.9rem;
  outline: none;
  transition: border-color 0.2s ease, background-color 0.2s ease;
}
.form-group input:focus,
.form-group input.is-tv-focused {
  border-color: var(--cyan, #00d2ff);
  background: rgba(255, 255, 255, 0.07);
}

.auth-error-msg {
  background: rgba(239, 68, 68, 0.12);
  border: 1px solid rgba(239, 68, 68, 0.24);
  color: #f87171;
  padding: 0.6rem 0.8rem;
  border-radius: 0.4rem;
  font-size: 0.8rem;
  font-weight: 600;
  text-align: left;
}
.auth-success-msg {
  background: rgba(16, 185, 129, 0.12);
  border: 1px solid rgba(16, 185, 129, 0.24);
  color: #34d399;
  padding: 0.6rem 0.8rem;
  border-radius: 0.4rem;
  font-size: 0.8rem;
  font-weight: 600;
  text-align: left;
}

.auth-submit-btn {
  background: linear-gradient(135deg, var(--cyan, #00d2ff), var(--rose, #7a2bd6));
  color: #fff;
  border: none;
  border-radius: 0.5rem;
  padding: 0.72rem;
  font-weight: 700;
  font-size: 0.92rem;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 0.3rem 1rem rgba(0, 210, 255, 0.25);
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.auth-submit-btn:is(:hover, :focus-visible, .is-tv-focused) {
  transform: scale(1.02);
  box-shadow: 0 0.4rem 1.4rem rgba(0, 210, 255, 0.45);
}

.auth-divider {
  display: flex;
  align-items: center;
  text-align: center;
  color: rgba(226, 228, 242, 0.34);
  font-size: 0.78rem;
  font-weight: 600;
  margin: 1.2rem 0;
}
.auth-divider::before,
.auth-divider::after {
  content: '';
  flex: 1;
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}
.auth-divider span {
  padding: 0 0.8rem;
}

.social-login-buttons {
  display: flex;
  gap: 0.8rem;
  margin-bottom: 1.4rem;
}
.social-btn {
  flex: 1;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.08);
  color: rgba(226, 228, 242, 0.9);
  padding: 0.6rem;
  border-radius: 0.5rem;
  font-weight: 700;
  font-size: 0.85rem;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.45rem;
  transition: background 0.2s ease, border-color 0.2s ease;
}
.social-btn:is(:hover, :focus-visible, .is-tv-focused) {
  background: rgba(255, 255, 255, 0.08);
  border-color: rgba(255, 255, 255, 0.16);
  color: #fff;
}
.social-icon {
  width: 1.05rem;
  height: 1.05rem;
}

.auth-switch {
  font-size: 0.82rem;
  color: rgba(226, 228, 242, 0.55);
}
.switch-link {
  background: transparent;
  border: none;
  color: var(--cyan, #00d2ff);
  font-weight: 700;
  cursor: pointer;
  padding: 0;
  font-size: inherit;
}
.switch-link:is(:hover, :focus-visible, .is-tv-focused) {
  text-decoration: underline;
}

/* User Profile card styling */
.profile-card {
  max-width: 32rem;
  margin: 1.5rem auto 0;
  background: rgba(255, 255, 255, 0.02);
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 0.8rem;
  padding: 1.8rem;
  box-shadow: 0 0.5rem 1.5rem rgba(0, 0, 0, 0.2);
}
.profile-info-row {
  display: flex;
  align-items: center;
  gap: 1.2rem;
  text-align: left;
  margin-bottom: 1.8rem;
}
.profile-avatar-large {
  width: 4.5rem;
  height: 4.5rem;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--cyan, #00d2ff), var(--rose, #7a2bd6));
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 2rem;
  font-weight: 800;
  color: #fff;
  border: 3px solid rgba(255, 255, 255, 0.1);
  box-shadow: 0 0 1.5rem rgba(0, 210, 255, 0.35);
}
.profile-card h3 {
  font-size: 1.25rem;
  font-weight: 800;
  color: #fff;
  margin: 0;
}
.profile-joined {
  font-size: 0.82rem;
  color: rgba(226, 228, 242, 0.55);
  margin-top: 0.2rem;
}
.profile-actions-grid {
  display: flex;
  justify-content: flex-end;
}
.profile-action-btn {
  background: rgba(239, 68, 68, 0.15);
  border: 1px solid rgba(239, 68, 68, 0.3);
  color: #f87171;
  padding: 0.55rem 1.3rem;
  border-radius: 0.4rem;
  font-weight: 700;
  font-size: 0.85rem;
  cursor: pointer;
  transition: background 0.2s ease, border-color 0.2s ease;
}
.profile-action-btn:is(:hover, :focus-visible, .is-tv-focused) {
  background: rgba(239, 68, 68, 0.25);
  border-color: #ef4444;
  color: #fff;
}

@keyframes fadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}
@keyframes scaleIn {
  from { transform: scale(0.95); opacity: 0; }
  to { transform: scale(1); opacity: 1; }
}

/* Custom layouts to force Continue Watching rail as a single horizontal scrolling row */
.rail-shell #continueGrid,
.rail-shell #continueGridAdult {
  grid-template-rows: auto;
  grid-auto-columns: clamp(13rem, 22vw, 16rem);
}

/* Episode range chunk selector for large episode lists */
.watch-side .ep-chunks-container {
  flex: 0 0 auto;
  margin: 0 0 0.55rem;
  padding: 0 0.15rem;
  overflow-x: auto;
  scrollbar-width: none; /* Firefox */
}
.watch-side .ep-chunks-container::-webkit-scrollbar {
  display: none; /* Chrome/Safari */
}
.watch-side .ep-chunks {
  display: flex;
  gap: 0.4rem;
  padding-bottom: 0.2rem;
}
.watch-side .ep-chunk-btn {
  flex: 0 0 auto;
  min-width: 4.5rem;
  height: 2.2rem;
  padding: 0 0.6rem;
  border: 0;
  border-radius: 0.5rem;
  background: rgba(255, 255, 255, 0.05);
  color: rgba(240, 241, 250, 0.7);
  font-size: 0.85rem;
  font-weight: 700;
  cursor: pointer;
  transition: background 150ms ease, color 150ms ease, transform 100ms ease;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.watch-side .ep-chunk-btn:is(:hover, :focus-visible, .is-tv-focused) {
  color: #fff;
  background: rgba(255, 255, 255, 0.12);
  outline: none;
}
.watch-side .ep-chunk-btn.is-selected {
  color: #fff;
  background: #8a5cff;
  box-shadow: 0 0.3rem 0.6rem rgba(138, 92, 255, 0.25);
}
.watch-side .ep-chunk-btn:active {
  transform: scale(0.96);
}

/* Continue watching history action */
.clear-continue-btn {
  margin-left: auto;
  min-height: 2rem;
  padding: 0.32rem 0.7rem;
  border: 0.08rem solid rgba(255, 255, 255, 0.1);
  border-radius: 0.4rem;
  background: rgba(8, 11, 22, 0.46);
  color: rgba(226, 230, 244, 0.72);
  font-size: 0.78rem;
  font-weight: 700;
  cursor: pointer;
  transition: background 150ms ease, color 150ms ease, border-color 150ms ease, transform 100ms ease;
}
.clear-continue-btn:is(:hover, :focus-visible, .is-tv-focused) {
  color: #fff;
  border-color: color-mix(in srgb, var(--cyan) 48%, transparent);
  background: color-mix(in srgb, var(--cyan) 12%, rgba(8, 11, 22, 0.72));
  outline: none;
}
.clear-continue-btn:active {
  transform: scale(0.96);
}

/* Playback Source Filter Dropdown */
.source-filter-select.language-select {
  min-height: 2.3rem;
  max-width: 12rem;
  width: auto;
  font-size: 0.82rem;
  font-weight: 700;
  padding: 0 2rem 0 1rem;
  border-radius: 0.5rem;
  background: rgba(255, 255, 255, 0.08);
  border: 0.08rem solid rgba(255, 255, 255, 0.12);
  box-shadow: 0 0.2rem 0.6rem rgba(0, 0, 0, 0.15);
  margin-right: 0.5rem;
  /* Chevron arrow styling */
  appearance: none;
  -webkit-appearance: none;
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23ffffff'%3E%3Cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.75rem center;
  background-size: 0.75rem;
  transition: all 0.2s ease;
}

.source-filter-select.language-select:is(:hover, :focus-visible, .is-tv-focused) {
  background-color: rgba(255, 255, 255, 0.16);
  border-color: #5c9bff;
  box-shadow: 0 0 0 0.15rem rgba(92, 155, 255, 0.25), 0 0.3rem 0.8rem rgba(0, 0, 0, 0.25);
  outline: none;
}

.source-filter-select.language-select option {
  background-color: #121424;
  color: #ffffff;
  font-size: 0.85rem;
  font-weight: 600;
}

/* Redesigned Source Picker List-based Layout */
.source-picker-topbar {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  display: flex;
  align-items: center;
  gap: 0.8rem;
  padding: 1rem 1.5rem;
  background: linear-gradient(180deg, rgba(0, 0, 0, 0.75), rgba(0, 0, 0, 0.05) 75%, transparent) !important;
  z-index: 10;
}

.source-picker-topbar .source-picker-back {
  background: transparent;
  border: 0;
  color: rgba(255, 255, 255, 0.85);
  cursor: pointer;
  width: 2.2rem;
  height: 2.2rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  transition: background 150ms ease, color 150ms ease;
  padding: 0;
  margin-right: 0.2rem;
}

.source-picker-topbar .source-picker-back:is(:hover, :focus-visible, .is-tv-focused) {
  background: rgba(255, 255, 255, 0.12);
  color: #ffffff;
  outline: none;
}

.source-picker-topbar .source-picker-title {
  flex: 1;
  font-size: 1.05rem;
  font-weight: 700;
  color: #ffffff;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.vidstream-player.is-cinema.is-source-picker .source-picker {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100%;
  padding-top: 4.2rem;
  border-radius: inherit;
  background: rgba(18, 20, 32, 0.88) !important;
  backdrop-filter: blur(25px);
  -webkit-backdrop-filter: blur(25px);
}

.vidstream-player.is-cinema.is-source-picker .source-picker-options {
  display: flex;
  flex-direction: column;
  gap: 0 !important;
  padding: 0 !important;
  overflow-y: auto;
  flex: 1;
}

.source-picker-option {
  display: grid !important;
  grid-template-columns: 8.5rem 1fr !important;
  align-items: center !important;
  gap: 1.2rem !important;
  width: 100% !important;
  padding: 0.9rem 1.6rem !important;
  border-radius: 0 !important;
  border: 0 !important;
  border-bottom: 0.06rem solid rgba(255, 255, 255, 0.08) !important;
  background: transparent !important;
  color: rgba(255, 255, 255, 0.9) !important;
  text-align: left !important;
  transition: background 150ms ease, border-left-color 150ms ease !important;
  border-left: 0.25rem solid transparent !important;
  box-shadow: none !important;
  transform: none !important;
}

.source-picker-option.is-source-filter-hidden {
  display: none !important;
}

.source-picker-option-found {
  cursor: pointer;
}

.source-picker-option-found:is(:hover, :focus-visible, .is-tv-focused) {
  background: rgba(255, 255, 255, 0.06) !important;
  border-left-color: #5c9bff !important;
  color: #ffffff !important;
  outline: none !important;
  transform: none !important;
  box-shadow: none !important;
}

.source-picker-left {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}

.source-provider-title {
  font-size: 0.88rem;
  font-weight: 750;
  color: #ffffff;
  letter-spacing: 0.01em;
}

.source-type-subtitle {
  font-size: 0.66rem;
  font-weight: 700;
  color: rgba(255, 255, 255, 0.38);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.source-picker-right {
  display: flex;
  flex-direction: column;
  gap: 0.28rem;
  min-width: 0;
}

.source-filename {
  font-size: 0.86rem;
  font-weight: 600;
  color: rgba(255, 255, 255, 0.85);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  line-height: 1.25;
}

.source-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.9rem;
}

.source-meta-item {
  font-size: 0.72rem;
  font-weight: 600;
  color: rgba(255, 255, 255, 0.45);
  display: inline-flex;
  align-items: center;
  gap: 0.22rem;
}

.source-meta-item .meta-icon {
  font-size: 0.74rem;
  opacity: 0.8;
}

.source-picker-option-checking {
  opacity: 0.75;
}

.source-picker-option-unavail {
  opacity: 0.38;
}

.source-picker-empty {
  margin: 0.45rem 0;
  padding: 1rem;
  border: 0.08rem dashed rgba(255, 255, 255, 0.14);
  border-radius: 0.9rem;
  color: rgba(246, 243, 255, 0.66);
  background: rgba(255, 255, 255, 0.04);
  font-size: 0.86rem;
  font-weight: 850;
  text-align: center;
}

/* ─── Side-panel inline source picker ───────────────────────────────────────
   Replaces the episode list in .episode-list when an episode is clicked.
   Uses the same .source-picker-option row styles as the cinema picker but
   lives in the narrow right column without entering cinema / fullscreen mode.
*/
.side-source-picker {
  display: flex;
  flex-direction: column;
  height: 100%;
  min-height: 0;
  overflow: visible;
  border-radius: 1.35rem 0 0 0;
  animation: fade-slide 280ms cubic-bezier(0.22, 1, 0.36, 1) both;
}

.side-source-picker-topbar {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 0.7rem;
  margin: 0 -0.7rem 0 -0.3rem;
  padding: 0.62rem 0.7rem 0.62rem 1rem;
  background: transparent;
  border-bottom: 0.06rem solid rgba(225, 29, 72, 0.22);
  border-radius: 1.35rem 0 0 0;
  min-height: 0;
}

.side-source-picker-back {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.2rem;
  height: 2.2rem;
  border-radius: 50%;
  border: 0.08rem solid rgba(255, 255, 255, 0.18);
  background: rgba(255, 255, 255, 0.14);
  color: #ffffff;
  cursor: pointer;
  transition: background 150ms ease, color 150ms ease;
}
.side-source-picker-back svg {
  width: 1.1rem;
  height: 1.1rem;
}
.side-source-picker-back:is(:hover, :focus-visible, .is-tv-focused) {
  background: rgba(255, 255, 255, 0.15);
  color: #ffffff;
  outline: none;
}

.side-source-picker-title {
  flex: 1;
  font-size: 0.9rem;
  font-weight: 700;
  color: #ffffff;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.side-source-gallery-toggle {
  flex: 0 0 auto;
  min-height: 2rem;
  padding: 0 0.68rem;
  border-radius: 999rem;
  border: 0.08rem solid rgba(255, 255, 255, 0.14);
  background: rgba(255, 255, 255, 0.065);
  color: rgba(240, 241, 250, 0.72);
  font-size: 0.7rem;
  font-weight: 850;
  white-space: nowrap;
  cursor: pointer;
  transition: background 150ms ease, border-color 150ms ease, color 150ms ease, transform 150ms ease;
}
.side-source-gallery-toggle:is(:hover, :focus-visible, .is-tv-focused) {
  outline: 0;
  color: #fff;
  border-color: rgba(138, 92, 255, 0.48);
  background: rgba(138, 92, 255, 0.16);
}
.side-source-gallery-toggle.is-on {
  color: #fff;
  border-color: rgba(138, 92, 255, 0.55);
  background: linear-gradient(135deg, rgba(138, 92, 255, 0.35), rgba(11, 183, 226, 0.18));
}

/* Compact "filter sources" dropdown inside the narrow side-panel topbar. */
.side-source-filter.language-select {
  flex: 0 0 auto;
  max-width: 11.5rem;
  min-height: 2rem;
  margin-right: 0;
  font-size: 0.75rem;
  padding: 0 1.7rem 0 0.7rem;
}


.side-source-picker.is-adult-source-picker .side-source-gallery-toggle {
  min-height: 2.45rem;
  padding: 0 0.78rem;
  border-radius: 0.55rem;
  font-size: 0.74rem;
  background: rgba(255, 255, 255, 0.075);
}

.side-source-picker.is-adult-source-picker .side-source-filter.language-select {
  max-width: 9rem;
  min-height: 2.45rem;
  padding: 0 2rem 0 0.9rem;
  border-radius: 0.55rem;
  border-color: rgba(255, 255, 255, 0.16);
  color: rgba(255, 255, 255, 0.94);
  background-color: rgba(255, 255, 255, 0.11);
  font-size: 0.84rem;
  font-weight: 900;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08);
}

.side-source-picker-list {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 0 !important;
  padding: 0 !important;
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: none;
  min-height: 0;
}
.side-source-picker-list::-webkit-scrollbar { display: none; }

/* Compact grid in the narrow panel: narrow provider column, rest to details */
.side-source-picker-list .source-picker-option {
  grid-template-columns: 4.5rem 1fr !important;
  padding: 0.65rem 0.6rem !important;
  gap: 0.55rem !important;
}
.side-source-picker-list .source-filename {
  font-size: 0.8rem;
}
.side-source-picker-list .source-meta {
  gap: 0.5rem;
}

/* Side-source-picker content body: full-width, gallery now lives externally */
.side-source-picker-body {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  min-height: 0;
  overflow: hidden;
}

/* ── Adult Episode Gallery Panel ──────────────────────────────────────────────
   Sits inside .watch-panel, between .watch-stage and .watch-side.
   Visually "attached" to the left edge of watch-side — shares the same top
   margin, matching glassmorphism, and a seamless border so they look like
   one continuous panel. Designed for exactly 6 images in a 2×3 grid.
   ───────────────────────────────────────────────────────────────────────────── */

.watch-panel {
  position: relative !important;
}

.adult-gallery-panel {
  position: absolute;
  /* +1rem accounts for .watch-panel's top padding so the gallery's top lines up
     exactly with the source picker (a grid item inside the padded content box). */
  top: calc(1rem + clamp(3.6rem, 7vh, 4.8rem));
  bottom: 1rem;
  display: flex;
  flex-direction: column;
  background:
    linear-gradient(180deg, rgba(17, 18, 30, 0.62), rgba(8, 9, 17, 0.5)),
    rgba(14, 15, 26, 0.52);
  -webkit-backdrop-filter: blur(22px) saturate(1.12);
  backdrop-filter: blur(22px) saturate(1.12);
  border: 0.08rem solid rgba(255, 255, 255, 0.08);
  border-right: 0;
  border-radius: 1.35rem 0 0 1.35rem;
  box-shadow:
    -1.1rem 0 2.4rem rgba(0, 0, 0, 0.38),
    inset 0 1px 0 rgba(255, 255, 255, 0.05);
  /* Below .watch-side (z-index 2) so the source picker — and its back button —
     always render on top; any flush-edge overlap tucks neatly underneath. */
  z-index: 1;
  overflow: hidden;
  overscroll-behavior: contain;
  animation: agp-slide-in 280ms cubic-bezier(0.22, 1, 0.36, 1) both;
}

@keyframes agp-slide-in {
  from { opacity: 0; transform: translateX(1.5rem); }
  to   { opacity: 1; transform: translateX(0); }
}

.adult-gallery-panel[hidden] { display: none; }

.watch-panel:not(:has(.side-source-picker)) .adult-gallery-panel {
  display: none !important;
}

.watch-panel:has(.adult-gallery-panel:not([hidden])) .side-source-picker,
.watch-panel:has(.adult-gallery-panel:not([hidden])) .side-source-picker-topbar {
  border-top-left-radius: 0;
}

.watch-panel:has(.adult-gallery-panel:not([hidden])) .watch-side {
  box-shadow: -1.6rem 0 3rem rgba(0, 0, 0, 0.5);
}

/* ── Header — clean dark glass with a subtle rose accent (no muddy gradient) ── */
.agp-header {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem;
  min-height: 3.2rem;
  padding: 0 0.95rem;
  background: transparent;
  border-bottom: 1px solid rgba(225, 29, 72, 0.22);
  border-radius: 1.35rem 0 0 0;
}

.agp-label {
  flex: 1 1 auto;
  min-width: 0;
  font-size: 0.84rem;
  font-weight: 800;
  color: rgba(255, 255, 255, 0.95);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.agp-count {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  padding: 0.2rem 0.6rem;
  font-size: 0.64rem;
  font-weight: 800;
  letter-spacing: 0.02em;
  color: rgba(255, 255, 255, 0.86);
  background: rgba(225, 29, 72, 0.16);
  border: 0.08rem solid rgba(225, 29, 72, 0.3);
  border-radius: 9rem;
  white-space: nowrap;
}

/* ── 2-column grid (3 rows for 6 images) — gapped & padded ── */
.agp-grid {
  flex: 1 1 auto;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  grid-template-rows: repeat(3, minmax(0, 1fr));
  gap: 0.55rem;
  padding: 0.6rem;
  overflow-y: hidden;
  overflow-x: hidden;
  overscroll-behavior: contain;
  scrollbar-width: none;
  align-content: stretch;
  min-height: 0;
}
.agp-grid::-webkit-scrollbar { display: none; }

/* ── Thumbnail cards — rounded & lifted ── */
.agp-thumb {
  position: relative;
  display: block;
  width: 100%;
  height: 100%;
  min-height: 0;
  margin: 0;
  padding: 0;          /* kill the <button> UA padding so the image fills edge-to-edge */
  border-radius: 0.85rem;
  overflow: hidden;
  cursor: pointer;
  border: 0.08rem solid rgba(255, 255, 255, 0.09);
  background: rgba(6, 7, 14, 0.62);
  box-shadow: 0 0.35rem 0.9rem rgba(0, 0, 0, 0.32);
  transition:
    border-color 160ms ease,
    box-shadow   160ms ease,
    transform    160ms cubic-bezier(0.22, 1, 0.36, 1);
}

.agp-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  display: block;
  pointer-events: none;
  transition: transform 220ms cubic-bezier(0.22, 1, 0.36, 1);
  filter: brightness(0.92) saturate(1.0);
  opacity: 1;
}

.agp-thumb::after {
  content: "";
  position: absolute;
  inset: auto 0 0;
  height: 40%;
  background: linear-gradient(0deg, rgba(0, 0, 0, 0.5), transparent);
  pointer-events: none;
}

/* Image number badge */
.agp-thumb-num {
  position: absolute;
  bottom: 0.34rem;
  right: 0.36rem;
  font-size: 0.64rem;
  font-weight: 850;
  color: #fff;
  background: rgba(8, 10, 18, 0.74);
  border: 0.06rem solid rgba(255, 255, 255, 0.16);
  padding: 0.1rem 0.36rem;
  border-radius: 0.42rem;
  line-height: 1.3;
  pointer-events: none;
  z-index: 1;
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
}

/* ── Hover / focus ── */
.agp-thumb:is(:hover, :focus-visible) {
  border-color: rgba(138, 92, 255, 0.85);
  box-shadow:
    0 0 0 0.12rem rgba(138, 92, 255, 0.5),
    0 0.8rem 1.8rem rgba(0, 0, 0, 0.45);
  transform: translateY(-0.12rem);
  outline: none;
  z-index: 2;
}
.agp-thumb:is(:hover, :focus-visible) img {
  transform: scale(1.05);
  filter: brightness(1.0) saturate(1.06);
  opacity: 1;
}

/* Active (lightbox open) */
.agp-thumb.is-active {
  border-color: rgba(138, 92, 255, 0.95);
  box-shadow: 0 0 0 0.15rem rgba(138, 92, 255, 0.62), 0 0.9rem 2rem rgba(0, 0, 0, 0.5);
}

.agp-thumb:focus:not(:focus-visible):not(.is-tv-focused):not(.is-active) {
  box-shadow: 0 0.35rem 0.9rem rgba(0, 0, 0, 0.32);
  border-color: rgba(255, 255, 255, 0.09);
}

/* ── Narrow screens ── */
@media (max-width: 960px) {
  .adult-gallery-panel {
    position: fixed;
    left: 0;
    top: 0;
    bottom: 0;
    right: auto;
    margin: 0;
    border-radius: 0 0.9rem 0.9rem 0;
    border-right: 1px solid rgba(255, 255, 255, 0.08);
    width: min(20rem, 75vw);
    z-index: 60;
  }
}



/* ── Trailer modal (in-app trailer player popup) ── */
.trailer-modal {
  position: fixed;
  inset: 0;
  z-index: 10000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: clamp(1rem, 4vw, 3rem);
  background:
    radial-gradient(circle at 50% 40%, rgba(138, 92, 255, 0.14), transparent 42rem),
    rgba(4, 4, 10, 0.9);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  animation: fade-in 180ms ease both;
}
.trailer-modal-inner {
  position: relative;
  width: min(72rem, 100%);
  max-height: 100%;
  animation: modal-rise 260ms cubic-bezier(0.22, 1, 0.36, 1) both;
}
.trailer-modal-frame {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  border-radius: 1rem;
  overflow: hidden;
  background: #000;
  box-shadow: 0 2rem 5rem rgba(0, 0, 0, 0.7), 0 0 0 1px rgba(255, 255, 255, 0.08);
}
.trailer-modal-frame iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}
.trailer-modal-close {
  position: absolute;
  top: -3.2rem;
  right: 0;
  width: 2.6rem;
  height: 2.6rem;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 0.08rem solid rgba(255, 255, 255, 0.22);
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.12);
  color: #fff;
  font-size: 1.2rem;
  cursor: pointer;
  transition: background 150ms ease, transform 150ms ease;
}
.trailer-modal-close:is(:hover, :focus-visible, .is-tv-focused) {
  background: rgba(225, 29, 72, 0.5);
  transform: scale(1.06);
  outline: none;
}
@media (max-width: 600px) {
  .trailer-modal-close { top: -3rem; right: 0.2rem; }
}

/* Lightbox overlay for full-size view */
.ep-gallery-lightbox {
  position: fixed;
  inset: 0;
  z-index: 9999;
  background:
    radial-gradient(circle at 50% 50%, rgba(138, 92, 255, 0.12), transparent 38rem),
    rgba(0,0,0,0.92);
  display: flex;
  align-items: center;
  justify-content: center;
  animation: fade-in 160ms ease both;
  cursor: zoom-out;
  overscroll-behavior: contain;
}
.ep-gallery-lightbox img {
  max-width: min(94vw, 82rem);
  max-height: 88vh;
  object-fit: contain;
  border-radius: 0.9rem;
  border: 0.08rem solid rgba(255,255,255,0.16);
  box-shadow: 0 2rem 6rem rgba(0,0,0,0.8);
  pointer-events: none;
}
.ep-gallery-lightbox-nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  background: rgba(24, 25, 38, 0.72);
  border: 0.08rem solid rgba(255,255,255,0.22);
  color: #fff;
  border-radius: 50%;
  width: 3.2rem;
  height: 3.2rem;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  font-size: 1.3rem;
  transition: background 150ms;
}
.ep-gallery-lightbox-nav:hover { background: rgba(255,255,255,0.25); }
.ep-gallery-lightbox-nav.prev { left: 1.2rem; }
.ep-gallery-lightbox-nav.next { right: 1.2rem; }
.ep-gallery-lightbox-close {
  position: absolute;
  top: 1rem;
  right: 1rem;
  background: rgba(24, 25, 38, 0.78);
  border: 0.08rem solid rgba(255,255,255,0.22);
  color: #fff;
  border-radius: 50%;
  width: 3rem;
  height: 3rem;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  font-size: 1.1rem;
  transition: background 150ms;
}
.ep-gallery-lightbox-close:hover { background: rgba(225,29,72,0.4); }
.ep-gallery-counter {
  position: absolute;
  bottom: 1.2rem;
  left: 50%;
  transform: translateX(-50%);
  background: rgba(0,0,0,0.6);
  color: rgba(255,255,255,0.75);
  font-size: 0.78rem;
  padding: 0.2rem 0.7rem;
  border-radius: 9rem;
  pointer-events: none;
}


/* ============================================================================
   PHONE BOTTOM NAVIGATION  (<= 760px)
   The left sidebar (.topbar) is repositioned into a fixed bottom navigation bar
   so phones get the full screen width. The HTML is unchanged — these are the
   same .nav-link route buttons, just laid out horizontally. Selectors also list
   the body.sidebar-collapsed variants (matched specificity, later in source
   order) so the bottom bar wins regardless of the persisted sidebar state.
   ========================================================================== */
@media (max-width: 760px) {
  .app-shell,
  body.sidebar-collapsed .app-shell {
    padding: 0 0 calc(4.9rem + env(safe-area-inset-bottom, 0px)) 0;
  }

  .topbar,
  body.sidebar-collapsed .topbar {
    top: auto;
    bottom: 0;
    left: 0;
    right: 0;
    width: 100%;
    min-height: 0;
    height: auto;
    display: block;
    padding: 0.3rem 0.35rem calc(0.3rem + env(safe-area-inset-bottom, 0px));
    background: linear-gradient(0deg, rgba(7, 9, 18, 0.99), rgba(9, 12, 23, 0.95));
    border-top: 0.08rem solid rgba(255, 255, 255, 0.08);
    box-shadow: 0 -0.5rem 1.6rem rgba(0, 0, 0, 0.45);
    backdrop-filter: blur(18px) saturate(1.1);
  }

  /* Only the route links belong in the bottom bar. */
  .topbar .brand,
  .topbar .sidebar-toggle,
  .topbar .search-box {
    display: none;
  }

  .main-nav,
  body.sidebar-collapsed .main-nav {
    display: flex;
    flex-direction: row;
    align-items: stretch;
    justify-content: space-around;
    width: 100%;
    margin: 0;
    gap: 0.15rem;
    overflow: visible;
  }

  .nav-link,
  body.sidebar-collapsed .nav-link {
    flex: 1 1 0;
    min-width: 0;
    min-height: 3.4rem;          /* >= 44px touch target */
    gap: 0.16rem;
    padding: 0.3rem 0.1rem;
    font-size: 0.6rem;
    border-radius: 0.85rem;
  }

  .nav-link span,
  body.sidebar-collapsed .nav-link span {
    font-size: 1.34rem;
  }

  /* Footer no longer needs the old sidebar offset once the nav is at the bottom —
     apply unconditionally (not just when sidebar-collapsed) so it's never shoved
     left / overflowing on phones. */
  .bottom-bar,
  body.sidebar-collapsed .bottom-bar {
    margin-left: 0;
    /* No negative footer-bleed on phones — it left a gap between the footer and
       the fixed bottom nav. Sit flush against the nav instead. */
    margin-bottom: 0;
    padding-left: clamp(1rem, 4vw, 1.5rem);
    padding-right: clamp(1rem, 4vw, 1.5rem);
    text-align: center;
  }
  .bottom-bar::before,
  body.sidebar-collapsed .bottom-bar::before {
    left: 0;
  }
  .bottom-bar::after {
    inset: 0;          /* the aurora layer also used the footer-bleed offset */
  }
}

/* Hero full-bleed on phones: cancel exactly main's side padding (edge to edge of
   the content column). Using negative margins instead of 100vw avoids a
   scrollbar-width horizontal overflow on viewports that render a classic
   scrollbar (100vw includes the scrollbar gutter; the content box does not).
   The literal used to be -1rem while main's phone padding is 0.8rem, so the hero
   stuck out 3.2px each side and the whole page could slide sideways. Reading the
   gutter back from main keeps the two in step at every breakpoint. */
@media (max-width: 760px) {
  .hero {
    width: auto;
    max-width: none;
    margin-inline: calc(var(--page-gutter, 0.8rem) * -1);
  }

  /* Portrait phones: measured at 375x812, the hero's content filled 474 of its
     496px, so the height above could not simply be trimmed - the synopsis had to
     go with it. It is two lines of "The third season of ..." that the detail
     page repeats in full, which makes it the cheapest 60px on the page. Title,
     meta, Play and the thumbnail strip all stay. */
  .carousel-info p:not(.eyebrow):not(.carousel-meta-line) {
    display: none;
  }
}

/* Tablets (761–1024px): roomier rails — ~5 cards per view instead of the
   desktop 7, so posters stay legible without feeling cramped. */
@media (min-width: 761px) and (max-width: 1024px) {
  .rail-shell .poster-grid {
    grid-auto-columns: calc((100% - (4 * var(--rail-gap))) / 5);
  }
}

/* Phones: the Weekly Schedule shows only TODAY — scrolling all 7 day columns is
   too much on a phone. The single day spans full width. */
@media (max-width: 760px) {
  .schedule-day-column:not(.is-today) { display: none; }
  .schedule-day-column.is-today {
    animation: none;            /* no pulse — it's the only column */
    border-radius: 0.8rem;
  }
  .schedule-day-column.is-today h3 { font-size: 1.05rem; }
}

/* ── Mobile watch/detail overlay — flatten to one scrolling column ───────────
   The desktop overlay is a fixed-height 2-column grid whose episode panel fills
   the column via flex:1 + overflow:hidden. On a phone the column is auto-height,
   so that whole chain collapses the episode list to ~0px and the watch-panel
   clips it. Appended last so it reliably wins the cascade over the base rules. */
@media (max-width: 760px) {
  /* .cinematic is always added to the overlay and its rules are 0,3,0 — match it
     so these win. */
  .watch-overlay.cinematic .watch-panel,
  .watch-overlay .watch-panel {
    display: block;
    width: 100%;
    height: 100%;
    max-height: 100%;
    margin: 0;
    overflow-y: auto;
    overflow-x: hidden;
    -webkit-overflow-scrolling: touch;
    /* The modal-rise animation leaves an identity transform that would make the
       position:fixed Back button a child of the (scrolling) panel. Drop it so
       fixed is relative to the viewport. */
    animation: none;
    transform: none;
  }
  .watch-overlay.cinematic .watch-stage,
  .watch-overlay.cinematic .watch-side,
  .watch-overlay .watch-stage,
  .watch-overlay .watch-side {
    display: block;
    width: 100%;
    height: auto;
    min-height: 0;
    max-height: none;
    margin: 0;
    overflow: visible;
  }
  .watch-overlay .watch-side {
    padding: 0 0.7rem 1.2rem;
    overscroll-behavior: auto;
  }
  /* The player/poster frame must keep its own height (don't let it collapse). */
  .watch-overlay .watch-side .video-frame {
    height: auto;
    min-height: 0;
  }
  .watch-overlay .watch-side .episode-list,
  .watch-overlay .watch-side .detail-pane.is-active {
    display: block;
    flex: none;
    height: auto;
    min-height: 0;
    max-height: none;
    overflow: visible;
  }
  .watch-overlay .watch-side .detail-pane.is-active .ep-rows,
  .watch-overlay .watch-side .season-card-grid {
    max-height: none;
    overflow: visible;
  }
  .watch-overlay .watch-side .episode-list,
  .watch-overlay .watch-side .detail-pane.is-active,
  .watch-overlay .watch-side .ep-rows,
  .watch-overlay .watch-side .ep-row {
    width: 100%;
    max-width: 100%;
    min-width: 0;
  }
  .watch-overlay .watch-side .ep-row {
    grid-template-columns: minmax(0, clamp(5.6rem, 29vw, 6.75rem)) minmax(0, 1fr);
  }
  .watch-overlay .watch-side .ep-thumb,
  .watch-overlay .watch-side .ep-row-body,
  .watch-overlay .watch-side .ep-row-title {
    min-width: 0;
  }
  .watch-overlay .watch-side .ep-row-title {
    white-space: normal;
    overflow-wrap: anywhere;
    word-break: break-word;
  }
  /* Phones skip the pre-playback placeholder entirely. #videoFrame renders a
     .watch-ready-state before an episode is chosen: a SECOND copy of the poster
     that is already at the top of the page, a source badge, the line "N episodes
     - select one below to watch", and a down arrow pointing at the list directly
     beneath it. On a phone that is a full screen of restating what the next
     screenful shows. Hiding it collapses #videoFrame to 0 and lifts the episode
     list from y=627 to y=429 - measured on a 375x812 phone - so opening a show
     lands on its episodes. The frame still holds the real player once an episode
     is selected; only this placeholder is skipped, and only on phones. */
  .watch-overlay .watch-ready-state {
    display: none;
  }

  /* Pinned just below the fixed Back / fullscreen controls rather than
     scrolling under them. Those two occupy the viewport to y=57 and y=55; 4rem
     clears both. This replaces an earlier static treatment - the tabs scrolled
     with the list, which is exactly how they ended up beneath the controls. */
  .watch-overlay .watch-side .detail-tabs.detail-tabs-2 {
    position: sticky;
    top: 4rem;
    z-index: 8;
    margin: 0 0 0.6rem;
    padding: 0.35rem 0 0.4rem;
    border-radius: 0;
    /* Opaque, or episode rows show through as they scroll behind the tabs. */
    background: #0f1224;
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }

  /* Keep the adult selector inside the same gutter and surface language as the
     episode browser. A solid compact track is cheaper to paint than another
     blurred full-width layer and stays legible while rows pass underneath. */
  .watch-overlay .watch-side #episodeList.is-adult-detail .detail-tabs.detail-tabs-2 {
    margin: 0.35rem 0.25rem 0.7rem;
    padding: 0.22rem;
    border: 0.06rem solid rgba(255, 255, 255, 0.1);
    border-radius: 0.5rem;
    background: #171a2b;
    box-shadow: 0 0.35rem 0.9rem rgba(0, 0, 0, 0.24), inset 0 1px 0 rgba(255, 255, 255, 0.035);
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }

  .watch-overlay .watch-side #episodeList.is-adult-detail .detail-tab {
    min-height: 2.5rem;
    border-radius: 0.38rem;
  }

  /* The watch panel is the only vertical scroller on phones. The desktop
     gallery's auto overflow plus overscroll containment consumed touch/wheel
     gestures even when the gallery had no overflow of its own, so the parent
     panel never moved. Let gestures bubble directly to that parent scroller. */
  .watch-overlay .watch-side #episodeList.is-adult-detail .detail-pane[data-detail-pane="gallery"].is-active,
  .watch-overlay .watch-side #episodeList.is-adult-detail .adult-detail-gallery {
    flex: 0 0 auto;
    height: auto;
    max-height: none;
    overflow: visible;
    overscroll-behavior: auto;
    touch-action: pan-y;
  }

  .watch-overlay .watch-side #episodeList.is-adult-detail .adult-detail-gallery-group,
  .watch-overlay .watch-side #episodeList.is-adult-detail .adult-detail-gallery-thumb {
    overflow: clip;
  }

  /* Pin Back to the viewport so it stays reachable while the panel scrolls
     (it's inside the scrolling panel, so absolute scrolled it off-screen). */
  .watch-overlay .close-button,
  .watch-overlay .watch-panel .close-button {
    position: fixed;
    top: 0.65rem;
    left: 0.65rem;
    right: auto;
    z-index: 90;
    display: grid;
    place-items: center;
    width: 2.9rem;
    height: 2.9rem;
    padding: 0;
    font-size: 1.85rem;
    line-height: 1;
    color: #fff;
    background: rgba(8, 9, 16, 0.85);
    box-shadow: 0 0.4rem 1.1rem rgba(0, 0, 0, 0.5), inset 0 0 0 0.06rem rgba(255, 255, 255, 0.1);
    -webkit-backdrop-filter: blur(10px);
    backdrop-filter: blur(10px);
  }
}

/* Mini footer for mobile web — just the ZenkaiTV wordmark, compact and flush with
   the bottom nav. The full tagline + credits footer read as a big empty gap on a
   phone. Appended last so it wins over the earlier mobile footer rules. */
@media (max-width: 760px) {
  .bottom-bar,
  body.sidebar-collapsed .bottom-bar {
    min-height: 0;
    gap: 0;
    /* Cancel the app-shell nav-reservation padding (negative margin) and refill it
       as the footer bottom padding, so the footer bg reaches behind the fixed
       bottom nav with NO gap; the wordmark stays above the nav via padding-top. */
    margin-bottom: calc(-4.9rem - env(safe-area-inset-bottom, 0px));
    padding-top: 0.5rem;
    /* Sit the wordmark right above the bottom nav (~0.2rem gap). The +4.1rem
       clears the nav height; the bg still fills down behind it (negative margin). */
    padding-bottom: calc(0.1rem + 2.9rem + env(safe-area-inset-bottom, 0px));
  }
  .footer-brand { gap: 0; }
  .footer-tagline,
  .footer-meta { display: none; }
  .footer-wordmark { width: min(7.5rem, 30vw); max-height: 1.7rem; }
}

/* ── Scroll polish ─────────────────────────────────────────────────────────
   Most of what a "premium streaming" scroll feel needs already existed here:
   html has scroll-behavior:smooth and scroll-padding-top:8rem, the rails carry
   scroll-snap-type:x mandatory with scroll-snap-align:start on every card,
   scrollbars are hidden, and card-rise / rise-in give staggered entrance
   animation behind prefers-reduced-motion. Only this was missing:

   Keep a sideways swipe INSIDE the rail instead of letting it chain out to the
   browser back-gesture on touch devices - the usual way horizontal carousels
   misbehave on phones. CSS-only, no listeners, no libraries.

   Deliberately NOT added: vertical section snapping (scroll-snap-type:y).
   The hero and content bands are ~590px tall, close to a full viewport, so even
   `proximity` pulls hard and risks the reader being unable to stop where they
   want - the opposite of the requirement that it never force the user into a
   section. It also could not be validated in the local preview, which does not
   respond to programmatic scrolling. Do not add it without shrinking sections
   well below viewport height AND verifying on a real device.

   Also NOT added: `body { overscroll-behavior-y: none }` - overscroll-behavior
   on body propagates to the viewport and interacts badly with this layout. */
.poster-grid,
.schedule-day-rail,
.source-picker-options {
  overscroll-behavior-x: contain;
}

/* Calm loading states -------------------------------------------------------
   Keep loaded content opaque. Loading is shown with one small branded rail,
   never by flashing or fading an entire section. */
.topbar,
.content-band,
.show-card,
.carousel-stage {
  animation: none;
}

.app-loader {
  gap: 0.72rem;
  background:
    radial-gradient(circle at 50% 48%, rgba(138, 92, 255, 0.13), transparent 19rem),
    #070914;
  transition: opacity 240ms ease, visibility 240ms ease;
}

.app-loader::after {
  width: min(11rem, 42vw);
  height: 0.16rem;
  margin-top: 0.38rem;
  border-radius: 999rem;
  background:
    linear-gradient(90deg, transparent, #8a5cff 46%, #30cde8 54%, transparent) 0 0 / 38% 100% no-repeat,
    rgba(255, 255, 255, 0.08);
  box-shadow: inset 0 0 0 0.04rem rgba(255, 255, 255, 0.06);
  animation: calm-loader-track 1.55s cubic-bezier(0.65, 0, 0.35, 1) infinite;
}

.loader-mark {
  width: 5.35rem;
  height: 5.35rem;
  border-radius: 1.45rem;
  overflow: visible;
  background: linear-gradient(155deg, #17182a, #0b0d17 72%);
  box-shadow:
    0 1.2rem 2.8rem rgba(0, 0, 0, 0.45),
    0 0 2.4rem rgba(138, 92, 255, 0.18),
    inset 0 0 0 0.06rem rgba(255, 255, 255, 0.1);
  animation: none;
}

.loader-mark::before {
  inset: -0.38rem;
  border-radius: 1.82rem;
  border-width: 0.12rem;
  border-color: rgba(255, 255, 255, 0.07);
  border-top-color: #8a5cff;
  border-right-color: rgba(48, 205, 232, 0.42);
  animation: loader-spin 1.8s linear infinite;
}

.loader-mark::after {
  inset: 15%;
  z-index: 0;
  background: radial-gradient(circle, rgba(138, 92, 255, 0.2), transparent 70%);
  transform: none;
  animation: none;
}

.loader-logo {
  z-index: 1;
  width: 74%;
  height: 74%;
  filter: drop-shadow(0 0 0.65rem rgba(138, 92, 255, 0.34));
  animation: none;
}

.app-loader small {
  color: rgba(255, 255, 255, 0.56);
}

.thumb-art {
  background: #0d0f19;
}

.thumb-art::before {
  content: "Z";
  display: grid;
  place-items: center;
  color: rgba(235, 232, 255, 0.14);
  font-family: Inter, ui-sans-serif, system-ui, sans-serif;
  font-size: clamp(2rem, 3vw, 3.4rem);
  font-weight: 950;
  line-height: 1;
  text-shadow: 0 0 1.6rem rgba(138, 92, 255, 0.24);
  background:
    radial-gradient(circle at 50% 43%, color-mix(in srgb, var(--thumb-a) 16%, transparent), transparent 34%),
    linear-gradient(155deg, #171827, #0a0b13 72%);
}

.art-sheen,
.skeleton-card .thumb-art::after,
.carousel-poster-skeleton::after {
  position: absolute;
  inset: auto 16% 13%;
  z-index: 1;
  height: 0.15rem;
  border-radius: 999rem;
  pointer-events: none;
  background:
    linear-gradient(90deg, transparent, #8a5cff 46%, #30cde8 54%, transparent) 0 0 / 38% 100% no-repeat,
    rgba(255, 255, 255, 0.07);
  transform: none;
  will-change: background-position;
  animation: calm-loader-track 1.7s cubic-bezier(0.65, 0, 0.35, 1) infinite;
  transition: opacity 160ms ease;
}

.thumb-art.img-ready .art-sheen,
.ep-thumb.img-ready .art-sheen {
  opacity: 0;
  animation: none;
}

.thumb-poster,
.ep-thumb-img {
  opacity: 1;
}

.skeleton-card .thumb-art,
.carousel-poster-skeleton {
  background: #0d0f19;
}

.skeleton-card .show-title,
.skeleton-card .show-meta {
  background: rgba(255, 255, 255, 0.055);
}

.skeleton-card .show-title::after,
.skeleton-card .show-meta::after {
  content: none;
  animation: none;
}

.poster-placeholder {
  justify-content: flex-end;
  align-items: flex-start;
  gap: 0.55rem;
  padding: 0.85rem;
  background:
    radial-gradient(circle at 50% 43%, rgba(138, 92, 255, 0.13), transparent 34%),
    linear-gradient(155deg, #171827, #0a0b13 72%);
}

.poster-placeholder::before {
  inset: 0;
  background: radial-gradient(circle at 50% 43%, rgba(48, 205, 232, 0.07), transparent 44%);
  filter: none;
  transform: none;
  animation: none;
}

.poster-placeholder-mark {
  margin: 0 0 auto;
  color: rgba(235, 232, 255, 0.16);
  font-size: 2.6rem;
  text-shadow: 0 0 1.5rem rgba(138, 92, 255, 0.24);
}

.poster-placeholder-copy {
  position: relative;
  z-index: 2;
  display: -webkit-box;
  max-width: 100%;
  color: rgba(255, 255, 255, 0.88);
  font-size: clamp(0.62rem, 0.85vw, 0.76rem);
  font-weight: 900;
  line-height: 1.08;
  letter-spacing: 0;
  text-align: left;
  text-transform: none;
  overflow: hidden;
  overflow-wrap: anywhere;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
}

.ep-thumb-empty-copy {
  display: -webkit-box;
}

.carousel-dot span {
  background: linear-gradient(145deg, #171827, #0a0b13 74%);
}

.carousel-dot span::after {
  inset: auto 12% 16%;
  height: 0.12rem;
  border-radius: 999rem;
  background:
    linear-gradient(90deg, transparent, #8a5cff 46%, #30cde8 54%, transparent) 0 0 / 38% 100% no-repeat,
    rgba(255, 255, 255, 0.07);
  transform: none;
  animation: calm-loader-track 1.7s cubic-bezier(0.65, 0, 0.35, 1) infinite;
}

.carousel-dot img {
  opacity: 1;
  animation: none;
}

.theme-flash {
  display: none !important;
}

body.adult-mode .app-loader {
  background:
    radial-gradient(circle at 50% 48%, rgba(225, 29, 72, 0.13), transparent 19rem),
    #0a0306;
}

body.adult-mode .app-loader::after,
body.adult-mode .carousel-wait-track,
body.adult-mode .art-sheen,
body.adult-mode .skeleton-card .thumb-art::after,
body.adult-mode .carousel-poster-skeleton::after,
body.adult-mode .carousel-dot span::after {
  background:
    linear-gradient(90deg, transparent, #e11d48 46%, #7a2bd6 54%, transparent) 0 0 / 38% 100% no-repeat,
    rgba(255, 255, 255, 0.08);
}

body.adult-mode .loader-mark {
  background: linear-gradient(155deg, #211019, #0b0609 72%);
  box-shadow:
    0 1.2rem 2.8rem rgba(0, 0, 0, 0.48),
    0 0 2.4rem rgba(225, 29, 72, 0.18),
    inset 0 0 0 0.06rem rgba(255, 255, 255, 0.1);
}

body.adult-mode .loader-mark::before {
  border-top-color: #e11d48;
  border-right-color: rgba(122, 43, 214, 0.52);
}

body.adult-mode .thumb-art::before,
body.adult-mode .poster-placeholder {
  color: rgba(255, 226, 234, 0.14);
  text-shadow: 0 0 1.6rem rgba(225, 29, 72, 0.24);
  background:
    radial-gradient(circle at 50% 43%, rgba(225, 29, 72, 0.14), transparent 34%),
    linear-gradient(155deg, #211019, #0b0609 72%);
}

body.adult-mode .thumb-art.has-contained-poster::before {
  background-image:
    linear-gradient(rgba(12, 5, 9, 0.42), rgba(12, 5, 9, 0.7)),
    var(--contained-poster);
  background-position: center;
  background-size: cover;
  filter: blur(0.85rem) saturate(0.9);
  transform: scale(1.12);
}

body.adult-mode .thumb-poster.is-contained-poster {
  object-position: center;
}

body.adult-mode .poster-placeholder-mark {
  color: rgba(255, 226, 234, 0.16);
  text-shadow: 0 0 1.5rem rgba(225, 29, 72, 0.24);
}

@keyframes calm-loader-track {
  from { background-position: -60% 0, 0 0; }
  to { background-position: 160% 0, 0 0; }
}

@media (prefers-reduced-motion: reduce) {
  .app-loader::after,
  .loader-mark::before,
  .carousel-wait-track,
  .art-sheen,
  .skeleton-card .thumb-art::after,
  .carousel-poster-skeleton::after,
  .carousel-dot span::after {
    animation: none !important;
  }

  .carousel-wait,
  .carousel-indicators {
    transition: none !important;
  }
}

body.reduce-motion .carousel-wait-track {
  animation: none !important;
}

body.reduce-motion .carousel-wait,
body.reduce-motion .carousel-indicators {
  transition: none !important;
}

body.reduce-motion .carousel-backdrop-blur {
  transition: none !important;
}

@media (prefers-reduced-motion: reduce) {
  .carousel-backdrop-blur {
    transition: none !important;
  }
}


/* Home keeps native vertical wheel and touch momentum. Horizontal content rails
   retain their own x-axis snapping, but sections never pull the page vertically. */
html:has(> body[data-route="home"]) {
  scroll-snap-type: none;
}

body[data-route="home"] #latest,
body[data-route="home"] #continueWatching,
body[data-route="home"] #continueWatchingAdult {
  scroll-snap-align: none;
}

/* Settings lives in the app canvas instead of inside a second, scrollable app. */
#settings {
  width: min(100%, 92rem);
  margin-inline: auto;
  padding-bottom: 1rem;
}

.settings-page-heading {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  max-width: 78rem;
  padding: 0.4rem 0 1.15rem;
  border-bottom: 0.08rem solid rgba(255, 255, 255, 0.08);
}

.settings-page-heading .section-heading {
  min-height: 0;
  margin: 0;
}

.settings-page-heading .empty-state {
  margin: 0.25rem 0 0;
  padding: 0;
  color: rgba(224, 230, 246, 0.58);
  background: none;
}

.settings-page-icon {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: 2.75rem;
  height: 2.75rem;
  color: #ffffff;
  font-size: 1.25rem;
  background: linear-gradient(145deg, var(--cyan), var(--blue));
  border-radius: 0.5rem;
  box-shadow: 0 0.7rem 1.6rem color-mix(in srgb, var(--cyan) 20%, transparent);
}

.settings-grid,
.settings-grid:has(.settings-rail) {
  display: block;
  width: 100%;
  max-width: 78rem;
  min-height: 0;
  margin-top: 1rem;
  padding: 0;
  overflow: visible;
  border: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
}

.settings-rail {
  position: sticky;
  top: 0.75rem;
  z-index: 12;
  display: flex;
  align-items: center;
  gap: 0.2rem;
  min-height: 3.25rem;
  padding: 0.3rem;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scrollbar-width: none;
  border: 0.08rem solid rgba(255, 255, 255, 0.09);
  border-radius: 0.5rem;
  background: rgba(8, 11, 21, 0.93);
  box-shadow: 0 0.8rem 2rem rgba(0, 0, 0, 0.22);
  -webkit-backdrop-filter: blur(18px);
  backdrop-filter: blur(18px);
}

.settings-rail::-webkit-scrollbar {
  display: none;
}

.settings-rail-item {
  position: relative;
  flex: 1 0 auto;
  justify-content: center;
  min-width: 7rem;
  min-height: 2.6rem;
  padding: 0 0.85rem;
  border: 0;
  border-radius: 0.35rem;
  color: rgba(229, 234, 248, 0.62);
  background: transparent;
  transform: none;
  box-shadow: none;
}

.settings-rail-item::after {
  content: "";
  position: absolute;
  left: 0.8rem;
  right: 0.8rem;
  bottom: 0.18rem;
  height: 0.12rem;
  border-radius: 999rem;
  background: transparent;
}

.settings-rail-item:is(:hover, :focus-visible, .is-tv-focused) {
  color: #ffffff;
  border-color: transparent;
  background: rgba(255, 255, 255, 0.055);
  box-shadow: none;
  transform: none;
}

.settings-rail-item.is-selected {
  color: #ffffff;
  border-color: transparent;
  background: color-mix(in srgb, var(--cyan) 12%, rgba(255, 255, 255, 0.035));
  box-shadow: none;
}

.settings-rail-item.is-selected::after {
  background: linear-gradient(90deg, var(--cyan), var(--blue));
  box-shadow: 0 0 0.7rem color-mix(in srgb, var(--cyan) 45%, transparent);
}

.settings-version {
  flex: 0 0 auto;
  align-self: center;
  margin: 0 0.75rem 0 auto;
  padding: 0;
  color: rgba(229, 234, 248, 0.38);
  font-size: 0.68rem;
  line-height: 1;
  white-space: nowrap;
}

.settings-console {
  display: block;
  width: 100%;
  height: auto;
  max-height: none;
  padding: 1.5rem 0 0;
  overflow: visible;
}

.settings-panel {
  gap: 0;
  min-height: 0;
  max-width: 64rem;
  padding: 0;
  margin: 0 auto;
}

.settings-panel.is-active {
  animation: settingsPanelIn 180ms ease both;
}

.settings-panel-head {
  grid-template-columns: 2.5rem minmax(0, 1fr);
  gap: 0.75rem;
  margin: 0 0 0.6rem;
  padding: 0 0 1.1rem;
  border-bottom: 0.08rem solid rgba(255, 255, 255, 0.1);
}

.settings-panel-head .settings-icon {
  width: 2.5rem;
  height: 2.5rem;
  border: 0;
  border-radius: 0;
  color: var(--cyan);
  background: transparent;
  box-shadow: none;
  font-size: 1.35rem;
}

.settings-panel-head h3 {
  font-size: clamp(1.35rem, 2vw, 1.7rem);
}

.settings-group-label {
  margin: 1.3rem 0 0.25rem;
  color: color-mix(in srgb, var(--cyan) 78%, white);
  letter-spacing: 0.08em;
}

.settings-divider {
  display: none;
}

.settings-line {
  grid-template-columns: minmax(13rem, 1fr) minmax(10rem, auto);
  min-height: 4.35rem;
  gap: 1.25rem;
  margin: 0;
  padding: 0.72rem 0;
  border-bottom: 0.08rem solid rgba(255, 255, 255, 0.065);
  border-radius: 0;
}

.settings-line:hover {
  background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--cyan) 6%, transparent), transparent);
}

.settings-line.adult-mode-highlight {
  margin: 0;
  padding-inline: 0;
  border: 0;
  border-bottom: 0.08rem solid rgba(255, 255, 255, 0.065);
  border-radius: 0;
  background: transparent;
  box-shadow: none;
}

.settings-line.adult-mode-highlight:hover {
  background: linear-gradient(90deg, transparent, rgba(225, 29, 72, 0.07), transparent);
}

.settings-segment,
.settings-legal-tabs {
  width: auto;
  padding: 0.22rem;
  border-radius: 0.45rem;
}

.settings-choice {
  min-height: 2.25rem;
  border-radius: 0.3rem;
}

.settings-choice.is-selected,
.settings-choice:is(:hover, :focus-visible, .is-tv-focused) {
  background: linear-gradient(135deg, var(--cyan), var(--blue));
}

.settings-select {
  border-radius: 0.4rem;
}

.settings-source-summary {
  padding: 0.7rem 0;
  border-bottom: 0.08rem solid rgba(255, 255, 255, 0.065);
  border-radius: 0;
  background: transparent;
}

.settings-shortcut-row {
  min-height: 3.4rem;
  border-bottom: 0.08rem solid rgba(255, 255, 255, 0.065);
}

.settings-legal-content {
  max-height: none;
  overflow: visible;
  padding-right: 0;
}

/* The footer is part of Settings on desktop, not persistent app chrome. */
.bottom-bar,
body.sidebar-collapsed .bottom-bar {
  display: none;
}

@media (min-width: 761px) {
  body[data-route="settings"] .bottom-bar,
  body.sidebar-collapsed[data-route="settings"] .bottom-bar {
    display: flex;
    min-height: 5.2rem;
    margin-top: 1rem;
    padding-top: 1rem;
    padding-bottom: calc(1rem + env(safe-area-inset-bottom));
  }

  body[data-route="settings"] .footer-brand {
    flex-direction: row;
    justify-content: flex-start;
    gap: 1rem;
    width: min(100%, 78rem);
    text-align: left;
  }

  body[data-route="settings"] .footer-wordmark {
    width: 9.5rem;
    max-height: 2.2rem;
  }

  body[data-route="settings"] .footer-meta {
    margin-left: auto;
    flex-wrap: nowrap;
  }
}

/* Once the embedded player owns the screen, its own back button is the only one. */
body.has-embedded-player .watch-overlay .close-button,
body.player-cinema-open .watch-overlay .close-button {
  display: none !important;
}

@media (max-width: 900px) {
  .settings-version {
    display: none;
  }
}

@media (max-width: 760px) {
  #settings {
    padding-bottom: 0.5rem;
  }

  .settings-page-heading {
    gap: 0.7rem;
    padding: 0 0 0.9rem;
  }

  .settings-page-icon {
    width: 2.4rem;
    height: 2.4rem;
    font-size: 1.05rem;
  }

  .settings-page-heading .section-heading h2 {
    font-size: 1.55rem;
  }

  .settings-page-heading .empty-state {
    font-size: 0.8rem;
    line-height: 1.35;
  }

  .settings-grid,
  .settings-grid:has(.settings-rail) {
    margin-top: 0.75rem;
  }

  .settings-rail {
    top: 0.4rem;
    margin-inline: -0.25rem;
  }

  .settings-rail-item {
    flex: 0 0 auto;
    min-width: auto;
    min-height: 2.55rem;
    padding-inline: 0.7rem;
    font-size: 0.78rem;
  }

  .settings-rail-item .rail-icon {
    width: auto;
    font-size: 0.9rem;
  }

  .settings-console {
    padding-top: 1.15rem;
  }

  .settings-panel-head {
    grid-template-columns: 2rem minmax(0, 1fr);
    padding-bottom: 0.9rem;
  }

  .settings-panel-head .settings-icon {
    width: 2rem;
    height: 2rem;
    font-size: 1.1rem;
  }

  .settings-panel-head h3 {
    font-size: 1.25rem;
  }

  .settings-line,
  .settings-line.adult-mode-highlight {
    gap: 0.65rem;
    padding: 0.8rem 0;
  }

  .settings-segment,
  .settings-select,
  .settings-status-pill {
    width: 100%;
  }

  .settings-switch {
    width: 3.25rem;
  }

  .settings-stat {
    justify-self: start;
    text-align: left;
  }

  .settings-actions {
    display: grid;
    grid-template-columns: 1fr 1fr;
  }

  .bottom-bar,
  body.sidebar-collapsed .bottom-bar,
  body[data-route="settings"] .bottom-bar {
    display: none !important;
  }
}


/* ── Phone: the player is a 16:9 banner, not a full-screen portrait box ──────
   Cinema mode is `position: fixed; width: 100vw; height: 100dvh`. On a desktop
   that is the Netflix-style edge-to-edge player it was written for; on a phone
   it is a 375x812 PORTRAIT box, so a 16:9 picture sat in the middle with ~300px
   of black above and below and the episode list was pushed off-screen entirely.

   So on phones the shell goes back in flow at its natural shape. The stage and
   the iframe already pin themselves to `inset: 0` with !important, so they fill
   whatever box they are given - the aspect-ratio here is the only thing that
   decides it, and the video inside keeps its own ratio (object-fit is unchanged),
   so nothing is cropped or stretched.

   Rotate the phone to landscape (or use the explicit fullscreen control) for the
   fixed viewport player. Portrait keeps this compact banner and the episode list
   in the same scrolling panel. */
@media (max-width: 760px) and (orientation: portrait) {
  /* `.watch-side .video-frame` is collapsed to 0x0 on purpose - the player it
     holds is normally position:fixed, so its container is told to take no space.
     An in-flow player needs a real box back, or it inherits that zero width. */
  .watch-overlay .watch-side .video-frame {
    position: relative;
    /* Edge to edge: cancel .watch-side's 11.2px gutter so the picture uses the
       whole phone width, the way a streaming app's player does. auto width +
       negative margins rather than 100vw, which would include the scrollbar
       gutter and reintroduce a sideways scroll. */
    width: auto;
    margin-inline: -11.2px;
    height: auto;
    padding: 0;
  }

  .vidstream-player.is-cinema {
    position: relative;
    top: auto;
    left: auto;
    z-index: 1;
    width: 100%;
    height: auto;
    /* Wider than tall, full phone width, no horizontal overflow. */
    aspect-ratio: 16 / 9;
  }

}

/* ── Phone: give the watch header some restraint ─────────────────────────────
   Measured on a 390px phone, the block above the video came to ~470px: a 27px
   two-line title, the genre row, then a studio list that wrapped to FOUR rows
   (142px on its own - the single biggest thing on the screen), the synopsis and
   the action row. The video and the episodes were pushed most of a screen down,
   which is what made everything feel oversized.

   Nothing is removed, only bounded: the studio list keeps its first row (the
   studios are repeated in the metadata below), the title steps down a size, and
   the stack tightens slightly. Desktop and tablet are untouched. */
@media (max-width: 760px) {
  .watch-stage-body {
    gap: 0.62rem;
    /* Back is position:fixed at top .65rem and 2.9rem tall, so it covers the
       viewport down to ~57px. Without this the title's first line rendered at
       y=48 and ran underneath it. 1.75rem puts the title at y=76 - a 19px gap -
       and holds for 2-line and 4-line titles alike. */
    padding-top: 1.75rem;
  }

  /* Specificity has to match `.watch-overlay.cinematic .watch-title`, whose
     phone floor is 1.7rem; a plain `.watch-stage-body .watch-title` loses to it
     however late it appears in the file. */
  .watch-overlay.cinematic .watch-stage-body .watch-title {
    font-size: clamp(1.2rem, 5.4vw, 1.55rem);
    line-height: 1.18;
  }

  .watch-stage-body .watch-castlist {
    /* One row. overflow:hidden rather than a display:none on later children, so
       a show with a single studio is unaffected. */
    max-height: 1.95rem;
    overflow: hidden;
  }

  .watch-stage-body .watch-summary {
    font-size: 0.84rem;
  }

  .watch-stage-body .watch-summary.is-expanded {
    max-height: none;
    overflow: visible;
  }

  .watch-backdrop-title-art {
    top: 5rem;
    right: 1rem;
    width: min(46%, 11rem);
    min-height: 8rem;
    align-items: flex-end;
    justify-content: flex-start;
    gap: 0.38rem;
    padding: 0.65rem;
    text-align: right;
    opacity: 0.26;
  }

  .watch-backdrop-title-art::before {
    font-size: 9rem;
  }

  .watch-backdrop-title-art strong {
    display: -webkit-box;
    max-width: 100%;
    max-height: 3.5rem;
    font-size: 1.12rem;
    line-height: 1.02;
    overflow: hidden;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
  }

  .watch-backdrop-title-kicker {
    display: none;
  }

  .watch-backdrop-title-rule {
    width: 3.5rem;
    height: 0.16rem;
  }
}

/* Prev / episode-list / Next (and Save when the source is a direct file) sit
   under the picture in Artplayer mode. The row already carries its own pill
   styling; inside the shell it is a grid area, out here it just needs its own
   breathing room. Same markup and the same wirePlayerChrome handlers as the
   legacy player - nothing new, only rendered where it was previously skipped. */
.video-frame > .player-episode-actions {
  margin-block: 0.7rem 0;
}

/* One line under the 16:9 player, not a stack. The phone rule further up turns
   this row into a single column, which was right when it sat beneath a
   full-height legacy stage and had a whole screen to itself; under a 220px
   player it turned three buttons into 154px of chrome. Scoped to the row that
   sits outside the shell so the legacy layout keeps its stacked version. */
/* One control, not three slabs adrift between the video and the list.

   The row was three separate rounded rects laid straight across the full
   width. Measured at 375px the three columns came to 119.7px each and summed
   to exactly the 375px viewport with no inset at all, so Prev and Next were
   clipped by the screen edges - while the season bar and every episode row
   below them sit 14px in. Three floating slabs, bleeding off both sides,
   aligned to nothing above or beneath: chrome that belonged to neither.

   It is now one bordered container on the app's own tokens, inset to the same
   14px column as the content under it, with the three actions as segments
   inside it. The container owns the border and the fill; the segments own
   neither, which is what makes them read as one control rather than three.
   Servers keeps the accent, since it is the action of the three.

   Through 1024 rather than 760: the inline bar is the same three buttons at
   tablet widths, and above 1024 the wide pill still suits a full desktop row. */
@media (max-width: 1024px) {
  /* Built to the SAME spec as .ep-panel-head, the season row directly beneath
     it, so the two read as one family rather than two unrelated bars: the same
     auto | 1fr | auto tracks, the same 0.4rem gap, the same pill buttons, and
     no container box of its own. Prev and Next sit on the rails and the middle
     action is centred on the bar - which lines each control up with its
     counterpart in the row below. Values are copied from .ep-nav-btn and
     .ep-season-btn deliberately; if those change, change these with them. */
  .video-frame > .player-episode-actions {
    grid-template-columns: auto minmax(0, 1fr) auto;
    align-items: center;
    gap: 0.4rem;
    min-height: 0;
    /* .video-frame is a grid with justify-items:center, which sized this row to
       its own content - measured 238px of a 375px frame, floating centred under
       a full-bleed video. Stretching it back across its track and insetting by
       margin puts it in the same column as the season row and episode list. */
    justify-self: stretch;
    width: auto;
    margin: 0.55rem 0.7rem 0;
    padding: 0.36rem 0.2rem 0.2rem;
    border: 0;
    border-radius: 0;
    background: none;
    box-shadow: none;
  }

  /* A download turns the middle into two actions; they share the centre track
     rather than adding a fourth column, so the rails stay put. */
  .video-frame > .player-episode-actions:has(.player-download-action) {
    grid-template-columns: auto minmax(0, 1fr) auto auto;
  }

  /* .ep-nav-btn, matched. */
  .video-frame > .player-episode-actions .player-nav-action,
  .video-frame > .player-episode-actions .player-download-action {
    width: auto;
    gap: 0.3rem;
    min-height: 2.25rem;
    padding: 0.32rem 0.55rem;
    border: 0;
    border-radius: 999rem;
    background: rgba(255, 255, 255, 0.045);
    color: rgba(226, 228, 242, 0.74);
    font-size: 0.82rem;
    font-weight: 700;
  }

  /* The glyphs are set at 1.3rem for the wide desktop pill, which overpowers a
     0.82rem label at this size. .ep-nav-btn uses 1.08rem for the same reason. */
  .video-frame > .player-episode-actions .player-nav-action span[aria-hidden] {
    font-size: 1.08rem;
    line-height: 1;
  }

  /* The centre action, sized and centred like .ep-season-btn - it is the same
     slot in the same grid as the season button directly below. It keeps the
     accent because it is the action of the three, where the season button only
     opens a list. */
  .video-frame > .player-episode-actions .player-nav-action.is-list {
    justify-self: center;
    max-width: 100%;
    min-height: 2.38rem;
    padding: 0.38rem 0.82rem;
    border: 0.08rem solid rgba(138, 92, 255, 0.52);
    background: linear-gradient(135deg, rgba(138, 92, 255, 0.95), rgba(138, 92, 255, 0.7));
    color: #fff;
    font-weight: 800;
  }

  /* .ep-nav-btn[disabled] fades rather than repainting; matched. */
  .video-frame > .player-episode-actions .player-nav-action:disabled {
    background: rgba(255, 255, 255, 0.045);
    opacity: 0.32;
  }
}

/* ── Close the page instead of trailing off ──────────────────────────────────
   Measured on a 1280x800 desktop: 95px sat between the bottom of the last row
   of cards and the end of the document - the rail's 16px, the band's 38px gap
   to the next band (which there isn't one of) and main's 19px, stacked.
   The band padding is spacing BETWEEN sections, so it is only removed from the
   last one; every gap higher up the page is untouched. client.js tags that band
   because the DOM-last one is normally a hidden route. */
.content-band.is-last-band {
  padding-bottom: 0.35rem;
}

/* At the end of Home, Latest Episodes becomes the final screen instead of a
   short shelf with part of the previous band still hanging above it. Its
   content may grow beyond one viewport, so this is a floor rather than a fixed
   height and normal vertical scrolling remains intact. */
body[data-route="home"] #latest.is-last-band {
  display: flex;
  min-height: calc(100dvh - 0.5rem);
  flex-direction: column;
  justify-content: center;
  padding-top: clamp(1.25rem, 3.5vh, 3rem);
  padding-bottom: clamp(1rem, 2.5vh, 2.25rem);
}

/* The full-screen final band is useful on desktop, where two complete rows fill
   it. On a phone the rail is much shorter and vertical centering manufactured
   large empty areas above and below the heading. Keep the final band compact
   there and let the fixed bottom navigation follow it immediately. */
@media (max-width: 760px) {
  body[data-route="home"] #latest.is-last-band {
    min-height: 0;
    justify-content: flex-start;
    padding-top: 0.85rem;
    padding-bottom: 0.5rem;
  }
}

main {
  padding-bottom: 0.5rem;
}

/* ── The player must be clickable ────────────────────────────────────────────
   .video-frame::before / ::after are decorative gradients laid over the whole
   frame. ::after sits at z-index 1 with inset 0, which was harmless while the
   playing shell was position:fixed at z-index 10050 - far above it. Making the
   phone player an in-flow 16:9 box dropped the shell to z-index 1, tying with
   ::after, and a tie is broken by paint order: the pseudo-element won and ate
   every tap. elementFromPoint over the picture, the control bar and the corner
   buttons all returned #videoFrame instead of the iframe, so nothing in the
   player could be pressed at all on a phone.

   Two fixes, because either alone would leave this fragile: decoration should
   never take pointer events, and the shell should not be tied with it. */
.video-frame::before,
.video-frame::after {
  pointer-events: none;
}

@media (max-width: 760px) and (orientation: portrait) {
  .vidstream-player.is-cinema {
    z-index: 2;
  }
}

/* Once playback starts on a phone or portrait tablet, the video becomes the
   page header and the episode browser follows it. The large metadata hero is
   still shown before an episode is selected, but it no longer sits between the
   viewer and the playing episode. */
@media (max-width: 860px) and (orientation: portrait) {
  body.player-cinema-open .watch-overlay.cinematic .watch-panel {
    display: block;
    width: 100%;
    height: 100%;
    max-height: 100%;
    margin: 0;
    overflow-y: auto;
    overflow-x: hidden;
    transform: none;
  }

  body.player-cinema-open .watch-overlay.cinematic .watch-stage {
    display: none;
  }

  body.player-cinema-open .watch-overlay.cinematic .watch-side {
    display: block;
    width: 100%;
    height: auto;
    min-height: 100dvh;
    max-height: none;
    margin: 0;
    padding: 0 0.7rem 1rem;
    border: 0;
    border-radius: 0;
    background: rgba(8, 9, 18, 0.76);
    box-shadow: none;
    overflow: visible;
  }

  body.player-cinema-open .watch-overlay .watch-side .video-frame {
    position: sticky;
    top: 0;
    z-index: 12;
    width: auto;
    height: auto;
    margin-inline: -0.7rem;
    padding: 0;
    background: #000 !important;
  }

  body.player-cinema-open .vidstream-player.is-cinema {
    position: relative;
    inset: auto;
    z-index: 2;
    width: 100%;
    height: auto;
    aspect-ratio: 16 / 9;
  }

  body.player-cinema-open .watch-overlay .watch-side .episode-list {
    display: block;
    margin-top: 0.45rem;
    padding-top: 0.45rem;
    border-top: 0;
  }

  body.player-cinema-open .close-button,
  body.player-cinema-open .watch-overlay .close-button {
    position: fixed;
    top: 0.65rem;
    left: 0.65rem;
    z-index: 90;
    display: grid !important;
  }
}

/* A touch more separation keeps the next rail's rounded poster corners from
   peeking into the initial Home viewport as a clipped sliver. */
#continueWatching .section-heading,
#continueWatchingAdult .section-heading {
  margin-bottom: 1.55rem;
}

/* ── A way out of the show, on a phone ───────────────────────────────────────
   Two rules hide the overlay's Back button while player-cinema-open is set,
   because cinema used to mean a full-viewport player that owned the screen and
   had its own back inside the iframe.
   On a phone the player is now a 16:9 banner in an ordinary scrolling page, but
   the class is still applied - so from the moment an episode started there was
   no way to leave the show at all. Measured: display:none, rect 0x0, and
   elementFromPoint over it returned .watch-stage.
   The second of those rules is !important, so this has to be too. */
@media (max-width: 760px) and (orientation: portrait) {
  body.player-cinema-open .close-button,
  body.player-cinema-open .watch-overlay .close-button {
    display: grid !important;
  }
}

/* ── Phone: pin the player, do not chase it ──────────────────────────────────
   Two requests wanted the same thing: opening a show should land on the episode
   list, and picking an episode should put you where it is playing. Both were
   attempted as scrolls, and both kept losing a race - sources resolve for ~20s
   after an episode starts and every pass re-renders the episode list, moving the
   player each time. Any scroll, one-shot or retried, either fired before the
   layout settled or was undone by the next re-render.

   Sticky removes the race instead of trying to win it: the player holds the top
   of the scrolling panel while the episodes scroll underneath, so it is in view
   the whole time by construction and there is nothing to chase. This is also
   how the streaming apps this page is modelled on behave.

   .watch-panel is the scroller; nothing between it and here may clip, which is
   why the cinema rules already force overflow:visible on .watch-side. */
@media (max-width: 760px) and (orientation: portrait) {
  /* Only once a player is actually mounted. Before an episode is picked this same
     container is the tall poster "ready" panel - roughly a full screen of it - and
     pinning that buried the episode list you are meant to be choosing from.
     body.player-cinema-open is set by setPlayerCinema when the player mounts. */
  body.player-cinema-open .watch-overlay .watch-side .video-frame {
    position: sticky;
    top: 0;
    z-index: 3;
    /* Opaque, or the episode rows show through as they slide under it. */
    background: #000 !important;
  }
}

/* --- Phone: Library and Favorites are browse surfaces, not shelves ---------
   As rails they inherited grid-auto-flow: column plus 2 rows, which on a 350px
   viewport made the Library a 5597px filmstrip: 16 screens of sideways swiping
   with 6% of the grid on screen, and the auto-loader kept appending to it. The
   home rails above are deliberately left alone - a shelf you flick through is
   the right pattern for Latest Episodes. The #id here is 1,2,0, which beats the
   0,2,0 .rail-shell .poster-grid rules earlier in the sheet.
   Paired with libraryRailIsNearEnd/observeLibraryScrollSentinel in client.js,
   which must measure the page instead of scrollLeft once this wraps. */
@media (max-width: 760px) {
  #library .rail-shell .poster-grid,
  #favorites .rail-shell .poster-grid {
    grid-auto-flow: row;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    grid-template-rows: none;
    grid-auto-columns: auto;
    overflow-x: hidden;
    overflow-y: visible;
    scroll-snap-type: none;
    row-gap: 1.1rem;
  }

  /* The sentinel is grid-row: 1 / -1 so it spans both rows of the rail. In a
     wrapped grid that would stretch it down the entire column and sit in view
     from the start, firing the loader immediately and forever. */
  #library .rail-shell .poster-grid > .library-scroll-sentinel,
  #favorites .rail-shell .poster-grid > .library-scroll-sentinel {
    grid-row: auto;
    grid-column: 1 / -1;
    align-self: auto;
    width: auto;
    height: 1px;
  }
}

/* Codec note on a source-picker row. Informational only: the source stays
   selectable and the Cast ladder sends AV1 CMAF to receivers that support it. */
.source-codec-note {
  display: block;
  margin-top: 0.15rem;
  font-size: 0.72rem;
  letter-spacing: 0.01em;
  opacity: 0.72;
}

.source-codec-note[data-codec="AV1"] {
  color: #f7a13a;
  opacity: 0.95;
}

/* Final compact phone/tablet rhythm. The bottom-nav reservation now matches its
   rendered height, cards are large enough to scan, and route bands do not stack
   desktop spacing on a narrow viewport. */
@media (max-width: 760px) {
  .app-shell,
  body.sidebar-collapsed .app-shell {
    padding-bottom: calc(4.05rem + env(safe-area-inset-bottom, 0px));
  }

  main {
    --page-gutter: 0.6rem;
    padding: 0.55rem var(--page-gutter) 0.7rem;
  }

  .hero,
  .carousel-stage {
    height: clamp(19.5rem, 46vh, 23.5rem);
    min-height: clamp(19.5rem, 46vh, 23.5rem);
  }

  .carousel-stage {
    padding: 1rem 0.95rem 4.7rem;
  }

  .carousel-info {
    gap: 0.55rem;
    padding-bottom: 0.7rem;
  }

  .carousel-info h2 {
    font-size: 1.65rem;
  }

  .carousel-indicators {
    right: 0.9rem;
    bottom: 0.55rem;
    left: 0.9rem;
    gap: 0.45rem;
  }

  .carousel-dot {
    width: 5.5rem;
    height: 3.1rem;
  }

  .content-band {
    padding: 0.7rem 0 1rem;
  }

  .section-heading {
    margin-bottom: 0.6rem;
  }

  #continueWatching .section-heading,
  #continueWatchingAdult .section-heading {
    margin-bottom: 0.65rem;
  }

  .poster-grid {
    --rail-gap: 0.55rem;
  }

  .rail-shell .poster-grid {
    grid-auto-columns: clamp(8.4rem, 36vw, 10.25rem);
    gap: 0.55rem;
    padding-bottom: 0.55rem;
  }

  .show-card {
    gap: 0.48rem;
  }

  .bottom-bar,
  body.sidebar-collapsed .bottom-bar {
    margin-bottom: calc(-4.05rem - env(safe-area-inset-bottom, 0px));
  }
}

@media (min-width: 761px) and (max-width: 1024px) {
  main {
    padding: 0.8rem 1.1rem 1rem;
  }

  .carousel-stage {
    min-height: clamp(25rem, 50vh, 29rem);
    padding-bottom: 5rem;
  }

  .content-band {
    padding-top: 0.9rem;
    padding-bottom: 1.5rem;
  }

  .rail-shell .poster-grid {
    grid-auto-columns: calc((100% - (3 * var(--rail-gap))) / 4);
  }
}
