/* Web player - Overcast look. Dark by default, light on request.
 *
 * Tokens on :root; components below are shared by every view:
 *   layout   .shell .topbar .tabbar .outlet .view .page-head
 *   surfaces .card .card-head .hint-card .note
 *   rails    .rail-section .section-head .rail-wrap .rail .rail-btn
 *   cards    .card-item.shape-poster|wide|square .card-media .card-title
 *            .card-sub(.cm .cm-rate) .card-badge(.live) .card-progress .card-remove
 *   grids    .grid  lists .list .row .row-main .row-logo .row-text
 *   controls .btn(.btn-primary|-secondary|-ghost|-danger|-sm|-lg|-block)
 *            .icon-btn .chip(.active|.chip-warn) .seg .input .field .check
 *   feedback .modal .toast .empty .skeleton(.sk) .spinner
 *   player   .player .player-bar .player-stage .player-info (.pv-head .pv-eps)
 */

@font-face { font-family: "Poppins"; font-style: normal; font-weight: 400; font-display: swap; src: url(../fonts/poppins-400-latin.woff2) format("woff2"); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "Poppins"; font-style: normal; font-weight: 400; font-display: swap; src: url(../fonts/poppins-400-latin-ext.woff2) format("woff2"); unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; }
@font-face { font-family: "Poppins"; font-style: normal; font-weight: 500; font-display: swap; src: url(../fonts/poppins-500-latin.woff2) format("woff2"); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "Poppins"; font-style: normal; font-weight: 500; font-display: swap; src: url(../fonts/poppins-500-latin-ext.woff2) format("woff2"); unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; }
@font-face { font-family: "Poppins"; font-style: normal; font-weight: 600; font-display: swap; src: url(../fonts/poppins-600-latin.woff2) format("woff2"); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "Poppins"; font-style: normal; font-weight: 600; font-display: swap; src: url(../fonts/poppins-600-latin-ext.woff2) format("woff2"); unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; }
@font-face { font-family: "Poppins"; font-style: normal; font-weight: 700; font-display: swap; src: url(../fonts/poppins-700-latin.woff2) format("woff2"); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "Poppins"; font-style: normal; font-weight: 700; font-display: swap; src: url(../fonts/poppins-700-latin-ext.woff2) format("woff2"); unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; }

/* Colours. Dark is the default; Account > Appearance (js/core/theme.js) sets
   data-theme="light" on <html> for the light set below. The player overlay,
   Fullscreen TV stay dark in either theme (they sit on
   video and artwork), so they take the dark set again. Components use these
   tokens; a literal colour left in a rule is one that sits on a picture. */
:root,
:root[data-theme="light"] :is(.player, .fs-view, .fs-boot) {
  --bg: #0f172a;
  --bg-rgb: 15, 23, 42;
  --surface: #172033;
  --field: #172033;     /* inputs and dropdowns */
  --card: #1c2739;
  --card-2: #212e44;
  --card-grad: linear-gradient(180deg, #1c2739, #19233a);
  --line: #243149;
  --line-2: #2b3a55;
  --text: #e8eef7;
  --text-2: #c9d4e5;   /* secondary text: meta lines, list rows */
  --text-3: #b3c0d6;   /* descriptions */
  --text-4: #d3dcea;   /* long reading text (plots, facts) */
  --muted: #8b9ab3;
  --faint: #4b5d7d;    /* empty-state icons, artwork fallbacks */
  --dot: #5b6b86;      /* separator dots */
  --placeholder: #66758f;
  --initials: #9fb0cc;
  --chip-hover: #3a4d70;
  --teal: #2ec4a6;
  --teal-rgb: 46, 196, 166;
  --teal-soft: rgba(46, 196, 166, .14);
  --teal-text: #bff3e8; /* text on --teal-soft */
  --teal-count: #8fe3d1;
  --sel-sub: #a9c9c2;   /* the now line of a selected channel */
  --day: #1c2739;       /* a day's head in the events week */
  --hero-tint: #1c2a44; /* a title page's hero before its artwork */
  --hf-veil: rgba(15, 23, 42, .62); /* Home's featured row, over its blurred artwork */
  --hf-text: #fff;
  --hf-shadow: 0 1px 3px rgba(0, 0, 0, .6);
  --hf-edge: var(--block-shadow);
  --on-teal: #062c5c;   /* text and icons on solid --teal */
  --rate: #ffd58a;
  --danger: #e5534b;
  --danger-text: #ff8f88;
  --warning: #f0a92e;
  --warn-text: #ffd58a;
  --ok: #2ec4a6;
  --hover: rgba(255, 255, 255, .05);
  --hover-2: rgba(255, 255, 255, .1);
  --hover-solid: #1b2740;
  --btn-2: #1e293b;
  --btn-2-hover: #253349;
  --btn-2-in: #2b3a55;        /* secondary buttons on a card or dialog */
  --btn-2-in-hover: #34466a;
  --thumb-grad: linear-gradient(160deg, #22304a, #18223a);
  --sk-1: #1c2739;
  --sk-2: #24324b;
  --toast: #24324b;
  --popover: #172033;
  --rail-btn: rgba(23, 32, 51, .92);
  --tag-bg: rgba(255, 255, 255, .06);
  --tag-line: rgba(255, 255, 255, .1);
  --age-line: rgba(255, 255, 255, .35);
  --track: rgba(255, 255, 255, .14);
  --backdrop: rgba(5, 10, 20, .66);
  --scroll-track: #1e293b;
  --scroll-thumb: #172033;
  --hero-shadow: 0 2px 20px rgba(0, 0, 0, .45);
  --head-bg: linear-gradient(315deg, rgba(0, 51, 115, .5), rgba(52, 142, 159, .5));
  --tab-bg: linear-gradient(315deg, rgba(18, 26, 42, .5), rgba(16, 23, 37, .5));
  --tab-bg-2: linear-gradient(315deg, rgba(22, 35, 61, .5), rgba(17, 28, 48, .5));
  --grad: linear-gradient(90deg, #276579, #062c5c);
  --grad-hover: linear-gradient(90deg, #2e7890, #0a3a75);
  --header: linear-gradient(90deg, #276579, #062c5c);
  --shadow: 0 10px 30px rgba(0, 0, 0, .35);
  --shadow-pop: 0 10px 30px rgba(0, 0, 0, .45);
  --shadow-card: 0 4px 14px rgba(0, 0, 0, .25);
  --shadow-lift: 0 10px 24px rgba(0, 0, 0, .4);
  /* Overcast block shadow: the hard 3px bottom edge the panel puts on its
     table rows and inputs. On the page (#0f172a) it needs the darker #050912;
     inside a card or pane the panel's own #0f172a. */
  --block-shadow: 0 3px 0 0 #050912;
  --block-shadow-in: 0 3px 0 0 #0f172a;
  --nav-shadow-in: var(--block-shadow-in); /* the selected header / tab bar button */
  --bar-shadow: 0 3px 0 0 rgba(5, 9, 18, .5); /* the header and tab bar: the block shadow at 50% */
  --ring: 0 0 0 2px var(--bg), 0 0 0 4px var(--teal);
  color-scheme: dark;
  /* text colour is inherited as computed: the dark islands set their own */
  color: var(--text);
}
/* Light: a pale blue page, lighter blue cards, ink text. The brand blues
   (header, primary buttons) are the same, the header opaque so its white
   text holds; teal is deepened so it still reads as text on white. */
:root[data-theme="light"] {
  --bg: #e2eaf4;
  --bg-rgb: 226, 234, 244;
  --surface: #f0f5fb;
  --field: #c3d3e7;     /* the secondary buttons' blue */
  --card: #f0f5fb;
  --card-2: #e8eff8;
  --card-grad: linear-gradient(180deg, #f2f6fb, #edf3fa);
  --line: #d2ddea;
  --line-2: #c2d0e1;
  --text: #101b2e;
  --text-2: #34445c;
  --text-3: #46566e;
  --text-4: #26344a;
  --muted: #5f6f87;
  --faint: #a3b0c2;
  --dot: #a3b0c2;
  --placeholder: #5a6b84;
  --initials: #5f6f87;
  --chip-hover: #a3b0c2;
  --teal: #0e8f78;
  --teal-rgb: 14, 143, 120;
  --teal-soft: rgba(14, 143, 120, .12);
  --teal-text: #0a6655;
  --teal-count: #0e8f78;
  --sel-sub: #2f6b60;
  --day: #dde7f2;
  --hero-tint: #d6e1ee;
  --hf-veil: rgba(240, 245, 251, .74);
  --hf-text: var(--text);
  --hf-shadow: none;
  --hf-edge: 0 3px 0 0 #0a2440; /* the featured row's cards: the selected nav button's navy edge */
  --on-teal: #ffffff;
  --rate: #a86a00;
  --danger: #d64036;
  --danger-text: #b4302a;
  --warning: #d98b0b;
  --warn-text: #8a5a00;
  --ok: #0e8f78;
  --hover: rgba(16, 27, 46, .05);
  --hover-2: rgba(16, 27, 46, .08);
  --hover-solid: #e3ebf5;
  --btn-2: #c3d3e7;
  --btn-2-hover: #b3c6de;
  --btn-2-in: #c3d3e7;
  --btn-2-in-hover: #b3c6de;
  --thumb-grad: linear-gradient(160deg, #e4eaf2, #d7dfea);
  --sk-1: #d9e3ef;
  --sk-2: #e9f0f8;
  --toast: #f2f6fb;
  --popover: #f2f6fb;
  --rail-btn: rgba(240, 245, 251, .95);
  --tag-bg: rgba(16, 27, 46, .04);
  --tag-line: rgba(16, 27, 46, .12);
  --age-line: rgba(16, 27, 46, .35);
  --track: rgba(16, 27, 46, .1);
  --backdrop: rgba(16, 27, 46, .42);
  --scroll-track: #d9e3ef;
  --scroll-thumb: #c3cddb;
  --hero-shadow: none;
  --head-bg: linear-gradient(315deg, rgba(0, 51, 115, .94), rgba(52, 142, 159, .94));
  --tab-bg: linear-gradient(315deg, rgba(0, 51, 115, .94), rgba(52, 142, 159, .94));
  --tab-bg-2: linear-gradient(315deg, rgba(10, 64, 130, .94), rgba(39, 120, 140, .94));
  --shadow: 0 10px 30px rgba(16, 27, 46, .12);
  --shadow-pop: 0 10px 30px rgba(16, 27, 46, .16);
  --shadow-card: 0 4px 14px rgba(16, 27, 46, .1);
  --shadow-lift: 0 10px 24px rgba(16, 27, 46, .16);
  --block-shadow: 0 3px 0 0 #c6d3e3;
  --block-shadow-in: 0 3px 0 0 #d5dfeb;
  /* the selected header / tab bar button: a navy edge under its navy fill */
  --nav-shadow-in: 0 3px 0 0 #0a2440;
  --bar-shadow: 0 3px 0 0 rgba(198, 211, 227, .5);
  color-scheme: light;
}
:root {
  --radius: .6rem;
  --radius-sm: .6rem;
  --top-h: 64px;
  /* the floating header's full height: the bar plus the gutter above it */
  --head-h: calc(var(--top-h) + var(--gutter));
  --tab-h: 0px;
  /* the room the floating tab bar takes at the bottom: the bar plus the gutter under it */
  --tab-room: 0px;
  --gutter: 24px;
  --sat: env(safe-area-inset-top, 0px);
  /* the screen's height: the dynamic one (100dvh, the space left by a phone's
     browser bars) where the engine has it. Use calc(var(--dvh) ...), never a
     100vh line followed by a 100dvh one: with a var() in the calc an engine
     without dvh keeps the second line anyway (it cannot check it until the
     values are known), finds it invalid then, and the height is lost (WebView
     before 108: Live TV and the guide ran past the screen) */
  --dvh: 100vh;
  --sab: env(safe-area-inset-bottom, 0px);
  --sal: env(safe-area-inset-left, 0px);
  --sar: env(safe-area-inset-right, 0px);
}
@supports (height: 100dvh) { :root { --dvh: 100dvh; } }

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; background: var(--bg); }
html.player-open, body.modal-open { overflow: hidden; }
body {
  margin: 0; min-height: 100vh; min-height: 100dvh;
  background: var(--bg); color: var(--text);
  font: 400 15px/1.5 "Poppins", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  -webkit-font-smoothing: antialiased; -webkit-tap-highlight-color: transparent;
  overflow-x: hidden;
}
img { max-width: 100%; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; }
h1, h2, h3 { margin: 0; font-weight: 600; line-height: 1.25; }
p { margin: 0; }
[hidden] { display: none !important; }
.muted { color: var(--muted); }
.ellipsis { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
/* a channel's catch-up: how far back it keeps recordings (core/ui.js cuChip) */
.cu-chip { display: inline-flex; align-items: center; gap: 4px; flex: none; color: var(--teal); font-size: 11.5px; font-weight: 600; line-height: 1; white-space: nowrap; }
.cu-chip .ico { width: 13px; height: 13px; stroke-width: 2; }
.grow { flex: 1; }

.ico { width: 20px; height: 20px; flex: none; display: block; }

/* Focus: visible ring for keyboard / remote users everywhere. */
:focus { outline: none; }
:focus-visible { outline: 2px solid var(--teal); outline-offset: 2px; }
body.kbd :focus { outline: 2px solid var(--teal); outline-offset: 2px; }
.skip-link { position: absolute; left: -999px; top: 8px; z-index: 100; padding: 8px 14px; background: var(--card); border-radius: var(--radius-sm); }
.skip-link:focus { left: 12px; }

/* ------------------------------------------------------------------ boot */
.boot, .boot-error { min-height: 100vh; min-height: 100dvh; display: grid; place-content: center; justify-items: center; gap: 28px; padding: 24px; }
/* The operator's logo is drawn for the dark header: on a light page the boot
   screen takes the login wall's blue. */
:root[data-theme="light"] :is(.boot, .boot-error) { background: linear-gradient(315deg, #003373, #348e9f); color: #fff; }
.boot-logo { width: 220px; max-width: 70vw; opacity: .9; }

/* ------------------------------------------------------------------ shell */
.shell { min-height: 100vh; min-height: 100dvh; }
/* Floating header, like the admin panel's: a rounded bar inset by the page
   gutter, so its edges line up with the content, with the same gap above it.
   It sticks at the top; the page color fades in behind it so content
   scrolling away under it does not show through the gap. */
.topbar {
  position: sticky; top: 0; z-index: 30;
  padding: calc(var(--gutter) + var(--sat)) calc(var(--gutter) + var(--sar)) 0 calc(var(--gutter) + var(--sal));
}
/* The admin's blur strips, for the header here and the phone tab bar below.
   Each bar blurs what is behind it itself, rounded with it. A strip covers
   the gap between the bar and the screen edge plus the bar's height: solid
   across the bar's width, stopping a corner radius short of the bar's far
   edge so no blur shows outside the bar's far corners; in the margins
   beside the bar the blur ends along a line from where the far corner's curve
   meets the bar's side out to the screen edge at --bar-blur-angle, rising
   towards the top of the screen for the header and falling towards the
   bottom for the tab bar. The fade (--bar-blur-soft) lies entirely on the
   blurred side, so it reaches nothing at the line. In a margin box the line
   sits (strip height - radius) x cos(angle) along the gradient. --bar-edge is
   the screen edge to the bar's end (the gutter, or more once the header hits
   its max width). Browsers without CSS trig get the plain strip. */
.topbar::before, .tabbar::before {
  --bar-blur-angle: 30deg;
  --bar-blur-soft: 2rem;
  --bar-radius: .6rem;
  --bar-gutter: var(--bar-edge);
  /* The margin pieces reach 1px in under the bar: where two mask pieces met
     edge to edge, both anti-aliased the shared column and at scaled displays
     it came out half unblurred, a 1px line beside the bar. The overlap sits
     under the bar (never outside it: below the corner curve the margin piece
     is clear already). */
  --bar-cut: calc((var(--bar-strip) - var(--bar-radius)) * cos(var(--bar-blur-angle)));
  --bar-fade: #000 calc(var(--bar-cut) - var(--bar-blur-soft)), transparent var(--bar-cut);
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  backdrop-filter: blur(2.5rem); -webkit-backdrop-filter: blur(2.5rem);
}
.topbar::before {
  --bar-edge: max(calc(var(--gutter) + var(--sal)), calc((100% - 1680px) / 2 + var(--gutter)));
  --bar-strip: calc(var(--head-h) + var(--sat));
  --bar-solid: linear-gradient(#000, #000) center top / calc(100% - 2 * var(--bar-edge)) calc(100% - var(--bar-radius)) no-repeat;
  -webkit-mask:
    linear-gradient(calc(180deg + var(--bar-blur-angle)), var(--bar-fade)) left top / calc(var(--bar-gutter) + 1px) 100% no-repeat,
    linear-gradient(calc(180deg - var(--bar-blur-angle)), var(--bar-fade)) right top / calc(var(--bar-gutter) + 1px) 100% no-repeat,
    var(--bar-solid);
  mask:
    linear-gradient(calc(180deg + var(--bar-blur-angle)), var(--bar-fade)) left top / calc(var(--bar-gutter) + 1px) 100% no-repeat,
    linear-gradient(calc(180deg - var(--bar-blur-angle)), var(--bar-fade)) right top / calc(var(--bar-gutter) + 1px) 100% no-repeat,
    var(--bar-solid);
}
/* Desktop: the margins' blur edge falls towards the screen edge instead (the
   rising angle above is the phones'), so the blur covers the margins beside
   the bar and page text never shows there. The edge still meets the bar's
   side where its corner curve begins; out at the screen edge it is lower by
   the margin's width x tan(angle), so the cut moves on by edge x sin(angle). */
@media (min-width: 992px) {
  .topbar::before {
    --bar-cut: calc((var(--bar-strip) - var(--bar-radius)) * cos(var(--bar-blur-angle)) + var(--bar-edge) * sin(var(--bar-blur-angle)));
    -webkit-mask:
      linear-gradient(calc(180deg - var(--bar-blur-angle)), var(--bar-fade)) left top / calc(var(--bar-gutter) + 1px) 100% no-repeat,
      linear-gradient(calc(180deg + var(--bar-blur-angle)), var(--bar-fade)) right top / calc(var(--bar-gutter) + 1px) 100% no-repeat,
      var(--bar-solid);
    mask:
      linear-gradient(calc(180deg - var(--bar-blur-angle)), var(--bar-fade)) left top / calc(var(--bar-gutter) + 1px) 100% no-repeat,
      linear-gradient(calc(180deg + var(--bar-blur-angle)), var(--bar-fade)) right top / calc(var(--bar-gutter) + 1px) 100% no-repeat,
      var(--bar-solid);
  }
}
@supports not (height: calc(1px * cos(0deg))) {
  .topbar::before { -webkit-mask: none; mask: none; }
}
.topbar-in {
  position: relative; isolation: isolate;
  height: var(--top-h); max-width: calc(1680px - 2 * var(--gutter)); margin: 0 auto;
  display: flex; align-items: center; gap: 12px; padding: 0 16px 0 18px; color: #fff;
  border-radius: .6rem; box-shadow: var(--bar-shadow);
  backdrop-filter: blur(2.5rem); -webkit-backdrop-filter: blur(2.5rem);
  /* the admin header's bg-animate-info: the default blue gradient at 50%
     alpha (the blur behind shows through), the far end crossfading in and
     out over 10 s */
  background-image: var(--head-bg); background-size: 400% 400%; background-position: 0% 50%;
}
.topbar-in::after {
  content: ""; position: absolute; inset: 0; z-index: -1; border-radius: inherit;
  background: inherit; background-position: 100% 50%; pointer-events: none;
  animation: btn-login-fade 10s ease infinite;
}
@media (prefers-reduced-motion: reduce) { .topbar-in::after { animation: none; opacity: 0; } }
/* the gradient's slow crossfade: decoration, only with motion on */
body:not(.motion) .topbar-in::after { animation: none; opacity: 0; }
.tb-logo { display: flex; align-items: center; flex: none; padding: 6px 4px; border-radius: var(--radius-sm); }
.tb-logo img { height: 24px; width: auto; display: block; }
.tb-title { display: none; font-weight: 600; font-size: 17px; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 1; }
.tb-nav { display: flex; gap: 4px; margin-left: 20px; flex: 1; }
.tb-link {
  display: flex; align-items: center; gap: 8px; padding: 8px 14px; border-radius: .6rem;
  color: rgba(232, 238, 247, .78); font-weight: 500; font-size: 14px; position: relative;
  transition: background .15s, color .15s;
}
.tb-link .ico { width: 18px; height: 18px; opacity: .85; }
/* Header items: plain, 0.6rem corners; the active one is a block (dark
   fill, the 3px dark shadow). */
.tb-link:hover { color: #fff; background: rgba(15, 23, 42, .25); }
.tb-link.active { color: #fff; background: rgba(15, 23, 42, .5); box-shadow: var(--nav-shadow-in); }
.tb-account {
  display: flex; align-items: center; gap: 10px; padding: 4px 12px 4px 4px; border-radius: .6rem;
  color: #fff; font-size: 14px; font-weight: 500; flex: none;
}
.tb-account:hover { background: rgba(15, 23, 42, .25); }
.tb-account.active { background: rgba(15, 23, 42, .5); box-shadow: var(--nav-shadow-in); }
.topbar .tb-back { border-radius: .6rem; }
/* Avatar and clock: the account button (it opens Account). */
.tb-clock { padding: 4px 14px 4px 4px; }
.tb-time { display: inline-flex; align-items: baseline; font-size: 18px; font-weight: 600; font-variant-numeric: tabular-nums; letter-spacing: .01em; }
.tb-colon { padding: 0 1px; }
/* Header text never wraps; when the bar is too narrow Shell._fitHeader steps
   down: tb-fit-1 drops the time (the avatar alone), tb-fit-2 also tightens
   the bar's gaps and the section links, tb-fit-3 also drops the links'
   icons. Steps add up. */
.tb-link, .tb-time, .tb-title { white-space: nowrap; }
.topbar-in:is(.tb-fit-1, .tb-fit-2, .tb-fit-3) .tb-time { display: none; }
.topbar-in:is(.tb-fit-1, .tb-fit-2, .tb-fit-3) .tb-clock { padding-right: 4px; }
.topbar-in:is(.tb-fit-2, .tb-fit-3) { gap: 8px; }
.topbar-in:is(.tb-fit-2, .tb-fit-3) .tb-nav { margin-left: 8px; gap: 2px; }
.topbar-in:is(.tb-fit-2, .tb-fit-3) .tb-link { padding: 8px 10px; gap: 6px; }
.topbar-in.tb-fit-3 .tb-link .ico { display: none; }
@media (prefers-reduced-motion: reduce) { .tb-colon { animation: none; } }
/* the account button's avatar: a user icon on teal, as the MAG app's */
.tb-avatar { width: 32px; height: 32px; border-radius: 50%; display: grid; place-items: center; background: var(--teal); color: var(--on-teal); }
.tb-avatar .ico { width: 18px; height: 18px; }
.tb-back { margin-left: -2px; }
.tb-back.off { visibility: hidden; pointer-events: none; }

/* scrollIntoView (keyboard focus) keeps the floating header and tab bar clear */
html { scroll-padding: calc(var(--head-h) + var(--sat)) 0 calc(var(--tab-room) + var(--sab)); }
.outlet { display: block; max-width: 1680px; margin: 0 auto; padding: 24px calc(var(--gutter) + var(--sar)) calc(48px + var(--tab-room) + var(--sab)) calc(var(--gutter) + var(--sal)); outline: none; }
.view { animation: fade-in .18s ease-out; }
@keyframes fade-in { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }

.tabbar { display: none; }

body.no-chrome .topbar, body.no-chrome .tabbar { display: none; }
body.no-chrome .outlet { max-width: none; padding: 0; }

/* Phone / tablet: compact top bar + bottom tabs. */
@media (max-width: 991.98px) {
  :root { --top-h: 56px; --tab-h: 58px; --gutter: 16px; --tab-room: calc(var(--tab-h) + var(--gutter)); }
  .tb-nav, .tb-user { display: none; }
  .tb-title { display: block; }
  .tb-logo img { height: 20px; }
  .tb-account { padding: 4px; }
  .tb-clock { padding: 4px 8px 4px 4px; gap: 8px; }
  /* the back button sits on the right, just before the clock */
  .tb-title { order: 1; }
  .tb-back { order: 2; margin-left: auto; }
  .tb-clock { order: 3; }
}
/* Narrow phones: the clock needs the room; the tab bar already names the section. */
@media (max-width: 479.98px) {
  .tb-title { visibility: hidden; }
  .tb-time { font-size: 16px; }
}
/* Phone / tablet, continued: the bottom tab bar replaces the top bar's
   section links (hidden below 992px above), so it must appear at exactly the
   same width. It once sat inside the narrow-phone block, which left 480-991px
   (tablets) with no navigation at all. */
@media (max-width: 991.98px) {
  /* The tab bar floats like the header, the gutter above the bottom edge,
     with the header's look; .tabbar is the strip under it that blurs what
     scrolls past (the admin's .bottomblur), .tabbar-in the bar. */
  .tabbar {
    display: block; position: fixed; left: 0; right: 0; bottom: 0; z-index: 30;
    padding: 0 calc(var(--gutter) + var(--sar)) calc(var(--gutter) + var(--sab)) calc(var(--gutter) + var(--sal));
  }
  /* The shared blur strip (see .topbar::before), mirrored: under the bar. */
  .tabbar::before {
    --bar-edge: calc(var(--gutter) + var(--sal));
    --bar-strip: calc(var(--tab-room) + var(--sab));
    --bar-solid: linear-gradient(#000, #000) center bottom / calc(100% - 2 * var(--bar-edge)) calc(100% - var(--bar-radius)) no-repeat;
    -webkit-mask:
      linear-gradient(calc(360deg - var(--bar-blur-angle)), var(--bar-fade)) left bottom / calc(var(--bar-gutter) + 1px) 100% no-repeat,
      linear-gradient(var(--bar-blur-angle), var(--bar-fade)) right bottom / calc(var(--bar-gutter) + 1px) 100% no-repeat,
      var(--bar-solid);
    mask:
      linear-gradient(calc(360deg - var(--bar-blur-angle)), var(--bar-fade)) left bottom / calc(var(--bar-gutter) + 1px) 100% no-repeat,
      linear-gradient(var(--bar-blur-angle), var(--bar-fade)) right bottom / calc(var(--bar-gutter) + 1px) 100% no-repeat,
      var(--bar-solid);
  }
  /* the admin's footer bar: bg-animate-dark (half-opaque dark gradient with
     a slow 40 s drift over it) */
  .tabbar-in {
    position: relative; isolation: isolate; height: var(--tab-h);
    display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: 2px; padding: 5px;
    border-radius: .6rem; box-shadow: var(--bar-shadow);
    background: var(--tab-bg) 0% / 400% 400%;
    backdrop-filter: blur(2.5rem); -webkit-backdrop-filter: blur(2.5rem);
  }
  .tabbar-in::after {
    content: ""; position: absolute; inset: 0; z-index: -1; border-radius: inherit; pointer-events: none;
    background: var(--tab-bg-2) 0% / 400% 400%;
    animation: bg-dark-drift 40s ease-in-out infinite;
  }
  .tab {
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px; min-width: 0;
    border-radius: .6rem; color: rgba(232, 238, 247, .78); font-size: 10.5px; font-weight: 500;
  }
  .tab .ico { width: 18px; height: 18px; }
  /* the active section is a block, as in the desktop header */
  .tab.active { color: #fff; background: rgba(15, 23, 42, .5); box-shadow: var(--nav-shadow-in); }
  .outlet { padding-top: 16px; }
  .topbar-in { padding: 0 10px 0 14px; }
}
@media (max-width: 360px) { .tab span { font-size: 10px; } }
@keyframes bg-dark-drift { 0%, 100% { opacity: 0; } 50% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .tabbar-in::after { animation: none; opacity: 0; } }
@supports not (height: calc(1px * cos(0deg))) {
  .tabbar::before { -webkit-mask: none; mask: none; }
}

/* ------------------------------------------------------------------ page heads */
.page-head { display: flex; align-items: center; gap: 12px; margin-bottom: 18px; }
.page-head h1 { font-size: 26px; font-weight: 600; }
@media (max-width: 991.98px) { .page-head { display: none; } }

/* ------------------------------------------------------------------ buttons */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 42px; padding: 0 18px; border-radius: .6rem; border: 1px solid transparent;
  font-weight: 500; font-size: 14px; cursor: pointer; white-space: nowrap; user-select: none;
  transition: filter .15s, background .15s, border-color .15s, transform .08s;
}
.btn:active { transform: translateY(1px); }
.btn .ico { width: 18px; height: 18px; }
/* The admin panel's buttons: regular weight, the hard 3px block shadow;
   primary = its bg-animate blue gradient (far end crossfading over 10 s, on
   ::before so .busy can keep ::after for its spinner), secondary = #1e293b. */
.btn { font-weight: 400; box-shadow: var(--block-shadow); }
.btn-primary {
  position: relative; isolation: isolate; color: #fff; border-color: transparent;
  background-image: linear-gradient(315deg, #003373, #348e9f); background-size: 400% 400%; background-position: 0% 50%;
}
.btn-primary::before {
  content: ""; position: absolute; inset: -1px; z-index: -1; border-radius: inherit;
  background: inherit; background-position: 100% 50%; pointer-events: none;
  animation: btn-login-fade 10s ease infinite;
}
@media (prefers-reduced-motion: reduce) { .btn-primary::before { animation: none; opacity: 0; } }
/* the gradient's slow crossfade: decoration, only with motion on */
body:not(.motion) .btn-primary::before { animation: none; opacity: 0; }
.btn-primary:hover { filter: brightness(1.08); }
.btn-secondary { background: var(--btn-2); color: var(--text); border-color: var(--btn-2); }
.btn-secondary:hover { background: var(--btn-2-hover); border-color: var(--btn-2-hover); }
.btn-ghost { background: transparent; color: var(--muted); box-shadow: none; }
.btn-ghost:hover { color: var(--text); background: var(--hover); }
.btn-danger { background: rgba(229, 83, 75, .14); color: var(--danger-text); border-color: rgba(229, 83, 75, .35); }
.btn-danger:hover { background: rgba(229, 83, 75, .24); }
.btn-sm { min-height: 34px; padding: 0 12px; font-size: 13px; border-radius: .6rem; }
.btn-lg { min-height: 50px; font-size: 15px; }
.btn-block { display: flex; width: 100%; }
.btn[disabled] { opacity: .6; cursor: default; }
/* A title the server no longer has (views/movie.js): solid red, not dimmed. */
.btn.btn-unavailable, .btn.btn-unavailable[disabled] { background: var(--danger); border-color: var(--danger); color: #fff; opacity: 1; box-shadow: none; }
.btn.busy { position: relative; color: transparent !important; }
.btn.busy::after { content: ""; position: absolute; width: 18px; height: 18px; border-radius: 50%; border: 2px solid rgba(255, 255, 255, .35); border-top-color: #fff; animation: spin .8s linear infinite; }
.icon-btn {
  width: 40px; height: 40px; flex: none; display: inline-grid; place-items: center; border-radius: 50%;
  background: transparent; border: 0; color: inherit; cursor: pointer; transition: background .15s;
}
.icon-btn:hover { background: var(--hover-2); }
.fav-btn.on { color: var(--warning); }

.chip {
  display: inline-flex; align-items: center; gap: 6px; min-height: 32px; padding: 0 14px; border-radius: 999px;
  background: var(--card); border: 1px solid var(--line-2); color: var(--text); font-size: 13px; font-weight: 500; cursor: pointer; white-space: nowrap;
}
.chip .ico { width: 16px; height: 16px; }
.chip:hover { border-color: var(--chip-hover); }
.chip.active { background: var(--teal-soft); border-color: var(--teal); color: var(--teal-text); }
.chip-warn { background: rgba(240, 169, 46, .14); border-color: rgba(240, 169, 46, .45); color: var(--warn-text); }
.chip-sm { min-height: 22px; padding: 0 8px; font-size: 11px; }
/* A chips row scrolls sideways, so it clips: room inside it for a focused
   chip's ring (4px), the negative margin keeping it in place. */
.chips { display: flex; gap: 8px; overflow-x: auto; scrollbar-width: none; padding: 6px; margin: -6px; }
.chips::-webkit-scrollbar { display: none; }

.seg { display: inline-flex; padding: 3px; border-radius: .6rem; background: var(--surface); border: 1px solid var(--line); }
.seg button { border: 0; background: transparent; color: var(--muted); padding: 7px 14px; border-radius: .6rem; cursor: pointer; font-weight: 500; font-size: 13px; }
.seg button.on { background: var(--line-2); color: var(--text); }
.seg-wide { display: flex; margin-bottom: 14px; }
.seg-wide button { flex: 1; }

/* ------------------------------------------------------------------ inputs */
.field { display: grid; gap: 6px; }
.field-label { font-size: 13px; font-weight: 500; color: var(--muted); }
.pl-form { display: grid; gap: 16px; padding-bottom: 8px; }
.pl-url { display: flex; gap: 8px; }
.pl-url .input { flex: 1; min-width: 0; font-size: 13px; }
.pl-url .btn { flex: none; width: 46px; padding: 0; justify-content: center; }
.pl-legacy { display: grid; grid-template-columns: auto 1fr; align-items: center; column-gap: 10px; cursor: pointer; }
.pl-legacy[hidden] { display: none; }
.pl-legacy input { width: 18px; height: 18px; accent-color: var(--teal); }
.pl-legacy .muted { grid-column: 2; font-size: 13px; }
/* Account buttons sit in the same dark fill as the select boxes. */
.account-grid .btn-secondary,
.pl-url .btn-secondary { background: var(--field); border-color: var(--field); box-shadow: var(--block-shadow-in); }
.account-grid .btn-secondary:hover,
.pl-url .btn-secondary:hover { background: var(--hover-solid); border-color: var(--hover-solid); }
.input {
  width: 100%; min-height: 46px; padding: 0 14px; border-radius: .6rem;
  background: var(--field); border: 1px solid var(--line); color: var(--text); font: inherit;
  transition: border-color .15s, box-shadow .15s;
}
/* iOS Safari zooms in on a focused field under 16px and stays zoomed */
@media (max-width: 991.98px) { .input { font-size: 16px; } }
.input::placeholder { color: var(--placeholder); }
.input:focus { outline: none; border-color: var(--teal); box-shadow: 0 0 0 3px rgba(var(--teal-rgb), .22); }
.input-wrap { position: relative; display: block; }
.input-wrap .input { padding-right: 48px; }
.input-btn { position: absolute; right: 4px; top: 50%; transform: translateY(-50%); width: 40px; height: 40px; display: grid; place-items: center; border: 0; background: transparent; color: var(--muted); border-radius: .6rem; cursor: pointer; }
.input-btn:hover { color: var(--text); }
.check, .check-row { display: flex; align-items: center; gap: 10px; cursor: pointer; font-size: 14px; }
.check input, .check-row input { width: 18px; height: 18px; accent-color: var(--teal); margin: 0; flex: none; }
input[type="search"]::-webkit-search-cancel-button { display: none; }

/* ------------------------------------------------------------------ cards / surfaces */
.card { background: var(--card-grad); border: 1px solid var(--line); border-radius: var(--radius); padding: 20px; }
.card-head { display: flex; align-items: center; justify-content: space-between; margin: -4px 0 14px; }
.card-head h2 { display: flex; align-items: center; gap: 10px; font-size: 16px; }
.card-head h2 .ico { color: var(--teal); }
.hint-card { display: flex; align-items: center; gap: 14px; padding: 18px 20px; border-radius: var(--radius); background: var(--card); border: 1px dashed var(--line-2); color: var(--muted); margin: 8px 0 28px; }
.hint-card .ico { color: var(--warning); width: 24px; height: 24px; }
.note { margin-top: 14px; padding: 10px 12px; border-radius: var(--radius-sm); background: var(--surface); color: var(--muted); font-size: 13px; }
.coming-soon { display: grid; justify-items: center; text-align: center; gap: 10px; padding: 56px 20px; }
.coming-soon > .ico { width: 44px; height: 44px; color: var(--teal); }
.coming-soon .btn { margin-top: 10px; }

/* ------------------------------------------------------------------ rails */
.rail-section { margin: 0 0 30px; }
.section-head { position: relative; z-index: 1; display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 12px; min-height: 30px; }
.section-head h2 { font-size: 18px; font-weight: 600; }
.section-head .count { color: var(--muted); font-weight: 500; font-size: 14px; margin-left: 6px; }
.see-all { display: inline-flex; align-items: center; gap: 2px; color: var(--teal); font-size: 13px; font-weight: 500; padding: 4px 6px; border-radius: .6rem; }
.see-all .ico { width: 16px; height: 16px; }
/* Rows run from screen edge to screen edge (the next card peeks in at the
   edge, and along the row the one before), on the header's grid: the first
   card starts where the header starts. --row-edge is the screen edge to the
   header, --row-w the header's width. */
:root {
  --row-edge: calc(max(0px, (100vw - 1680px) / 2) + var(--gutter));
  --row-w: calc(min(100vw, 1680px) - 2 * var(--gutter));
}
/* edge to edge must not make the page scroll sideways where a scrollbar
   takes part of 100vw. On #app, not html: clip on the root element turns off
   the sticky header. */
#app { overflow-x: clip; }
.rail-wrap { position: relative; margin: 0 calc(50% - 50vw); }
.rail {
  display: grid; grid-auto-flow: column; gap: 14px; overflow-x: auto; overscroll-behavior-x: contain;
  scroll-snap-type: x proximity; scroll-padding: 0 var(--row-edge);
  /* room inside the row (which clips) for a focused card's ring and its
     upward zoom; the negative margins keep the row where it was */
  padding: 20px var(--row-edge) 12px; margin: -16px 0 -4px;
  scrollbar-width: none;
}
.rail::-webkit-scrollbar { display: none; }
/* a row being dragged with the mouse (core/ui.js enableDragScroll) */
.is-dragging { cursor: grabbing; user-select: none; }
.is-dragging * { cursor: grabbing; }
.rail > * { scroll-snap-align: start; }
/* Poster rows divide the width exactly, as many across as the hero shows (8,
   7 on narrower desktops, 6 below that, 3 on phones), so no card is cut at
   the right edge. 100cqw is the row's full-bleed width (.rail-wrap). */
.rail.shape-poster { --rail-n: 8; grid-auto-columns: calc((var(--row-w) - (var(--rail-n) - 1) * 14px) / var(--rail-n)); }
@media (max-width: 1399.98px) { .rail.shape-poster { --rail-n: 7; } }
@media (max-width: 1199.98px) { .rail.shape-poster { --rail-n: 6; } }
.rail.shape-wide { grid-auto-columns: 340px; }
.rail.shape-square { grid-auto-columns: 164px; }
.rail .hint { color: var(--muted); padding: 8px 0; }
.rail-btn {
  position: absolute; top: var(--rb-top, 36%); transform: translateY(-50%); z-index: 2; width: 42px; height: 42px; border-radius: 50%;
  display: grid; place-items: center; border: 1px solid var(--line-2); background: var(--rail-btn); color: var(--text);
  cursor: pointer; opacity: 0; pointer-events: none; transition: opacity .15s; box-shadow: var(--shadow);
}
.rail-btn.prev { left: 10px; }
.rail-btn.next { right: 10px; }
@media (hover: hover) and (min-width: 992px) {
  .rail-section.can-prev:hover .rail-btn.prev, .rail-section.can-next:hover .rail-btn.next { opacity: 1; pointer-events: auto; }
}
@media (max-width: 991.98px) {
  .rail { gap: 10px; }
  /* poster rows: three across inside the page gutters */
  .rail.shape-poster { grid-auto-columns: calc((var(--row-w) - 2 * 10px) / 3); }
  .rail.shape-wide { grid-auto-columns: 260px; }
  .rail.shape-square { grid-auto-columns: 120px; }
  .section-head h2 { font-size: 16px; }
}

/* ------------------------------------------------------------------ card items (posters / tiles) */
.card-item {
  display: flex; flex-direction: column; gap: 6px; min-width: 0; text-align: left;
  background: none; border: 0; padding: 0; cursor: pointer; color: inherit; border-radius: var(--radius);
}
.card-media {
  position: relative; display: block; width: 100%; aspect-ratio: 2 / 3; border-radius: var(--radius); overflow: hidden;
  background: var(--card); box-shadow: var(--shadow-card);
  transition: transform .18s ease, box-shadow .18s ease;
  transform-origin: 50% 100%; /* the focus zoom grows upward, clear of the title */
}
.shape-wide .card-media { aspect-ratio: 16 / 9; }
.shape-square .card-media { aspect-ratio: 1; background: var(--thumb-grad); }
.card-item:hover .card-media { transform: translateY(-2px); box-shadow: var(--shadow-lift); }
.card-item:focus-visible { outline: none; }
.card-item:focus-visible .card-media, body.kbd .card-item:focus .card-media { box-shadow: var(--ring); transform: scale(1.03); }
body.kbd .card-item:focus { outline: none; }
.card-title { font-size: 13.5px; font-weight: 500; line-height: 1.3; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.card-sub { font-size: 12px; color: var(--muted); margin-top: -3px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-variant-numeric: tabular-nums; }
/* rating / year / running time, dot separated as on the detail page */
.card-sub .cm > * + *::before { content: ""; display: inline-block; width: 3px; height: 3px; border-radius: 50%; background: currentColor; opacity: .7; margin: 0 6px; vertical-align: middle; }
.card-sub .cm-rate .ico { display: inline-block; width: 11px; height: 11px; color: var(--warning); margin-right: 3px; vertical-align: -1px; }
@media (max-width: 991.98px) {
  /* the narrower posters below desktop: the whole line still fits */
  .card-sub { font-size: 11px; letter-spacing: -.01em; }
  .card-sub .cm > * + *::before { margin: 0 3px; }
  .card-sub .cm-rate .ico { width: 10px; height: 10px; margin-right: 2px; }
}
.card-badge { position: absolute; top: 8px; left: 8px; padding: 2px 8px; border-radius: .6rem; font-size: 11px; font-weight: 600; background: rgba(15, 23, 42, .85); color: #e8eef7; letter-spacing: .03em; }
.card-badge.live { background: var(--danger); color: #fff; }
.card-progress { position: absolute; left: 0; right: 0; bottom: 0; height: 4px; background: rgba(0, 0, 0, .55); }
.card-progress i { display: block; height: 100%; background: var(--teal); border-radius: 0 2px 2px 0; }
.card-remove {
  position: absolute; top: 6px; right: 6px; width: 28px; height: 28px; border-radius: 50%; display: grid; place-items: center;
  background: rgba(15, 23, 42, .82); color: #e8eef7; opacity: 0; transition: opacity .15s; z-index: 2;
}
.card-remove .ico { width: 15px; height: 15px; }
.card-item:hover .card-remove, .card-item:focus-within .card-remove { opacity: 1; }
@media (hover: none) { .card-remove { opacity: .85; } }

/* Images: fallback underneath, picture fades in on top. */
.thumb { position: absolute; inset: 0; display: block; }
.thumb img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: 0; transition: opacity .25s; }
.thumb.fit-contain img { object-fit: contain; padding: 14%; }
.thumb.loaded img { opacity: 1; }
.thumb.broken img { display: none; }
.thumb-fb { position: absolute; inset: 0; display: grid; place-items: center; color: var(--faint); background: var(--thumb-grad); }
.thumb.loaded .thumb-fb { visibility: hidden; }
.thumb-fb .ico { width: 34%; height: 34%; max-width: 48px; max-height: 48px; }
.thumb-initials { font-weight: 600; font-size: 22px; color: var(--initials); letter-spacing: .02em; }

/* ------------------------------------------------------------------ grids and lists */
.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 20px 16px; }
@media (max-width: 991.98px) { .grid { grid-template-columns: repeat(auto-fill, minmax(104px, 1fr)); gap: 16px 10px; } }
.sentinel { height: 1px; }
.list { display: grid; gap: 6px; }
/* Search's channels: three across on a wide screen, two on a tablet */
@media (min-width: 600px) { .list.sr-live { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; } }
@media (min-width: 992px) { .list.sr-live { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.row { display: flex; align-items: center; gap: 4px; background: var(--card); border: 1px solid var(--line); border-radius: var(--radius); padding: 4px 6px 4px 4px; }
.row:hover { border-color: var(--line-2); }
.row-main { flex: 1; min-width: 0; display: flex; align-items: center; gap: 14px; padding: 6px 8px; border: 0; background: none; text-align: left; cursor: pointer; border-radius: .6rem; color: inherit; }
.row-logo { position: relative; width: 52px; height: 52px; flex: none; border-radius: .6rem; overflow: hidden; background: var(--thumb-grad); }
.row-logo .thumb.fit-contain img { padding: 10%; }
.row-text { display: grid; min-width: 0; gap: 2px; flex: 1; }
.row-title { font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.row-sub { font-size: 12.5px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ------------------------------------------------------------------ states / skeletons */
.empty { display: grid; justify-items: center; gap: 12px; text-align: center; padding: 48px 16px; color: var(--muted); }
.empty > .ico { width: 36px; height: 36px; color: var(--faint); }
.empty.error > .ico { color: var(--danger); }
.empty.subtle { padding: 32px 16px; }
.empty p { max-width: 420px; }
/* The shimmer repaints every frame (background-position): a few passes, then
   still, so the placeholders of rails not loaded yet cost nothing. */
.sk, .skeleton { display: block; background: linear-gradient(90deg, var(--sk-1) 0%, var(--sk-2) 50%, var(--sk-1) 100%); background-size: 200% 100%; border-radius: .6rem; }
/* The shimmer repaints every placeholder each frame (a background, not a
   transform): a loading Home has a couple of hundred. Only with motion on
   (body.motion: off by default on TVs, set-top boxes and low-memory
   devices), and twice rather than four times. */
body.motion .sk, body.motion .skeleton { animation: shimmer 1.3s ease-in-out 2; }
.card-media.sk { box-shadow: none; }
.sk-line { height: 12px; margin: 6px 0; width: 90%; }
.sk-line.short { width: 55%; }
.sk-title { height: 20px; width: 40%; margin: 8px 0 10px; }
.sk-cats { display: grid; gap: .5rem; padding-bottom: 3px; }
.sk-cat { height: 38px; box-shadow: var(--block-shadow); }
@media (max-width: 991.98px) { .sk-cat { height: 60px; } }
.sk-hero { height: 220px; border-radius: var(--radius); margin-bottom: 18px; }
.row-logo.sk { border-radius: .6rem; }
@keyframes shimmer { 0% { background-position: 100% 0; } 100% { background-position: -100% 0; } }
.spinner { width: 36px; height: 36px; border-radius: 50%; border: 3px solid rgba(var(--teal-rgb), .2); border-top-color: var(--teal); animation: spin .8s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }

/* Pull to refresh (core/pull.js): a round chip that slides out from under the
   top bar with the finger, turns past the threshold, spins while refreshing. */
.pull {
  position: fixed; left: 50%; top: var(--pull-top, 0px); z-index: 29; width: 40px; height: 40px; margin-left: -20px;
  display: grid; place-items: center; border-radius: 50%; background: var(--surface); color: var(--muted);
  box-shadow: var(--block-shadow); opacity: 0; pointer-events: none;
  transform: translateY(calc(var(--pull, 0px) - 44px)); transition: transform .22s ease, opacity .22s ease, color .15s;
}
.pull.on { transition: color .15s; }
.pull .ico { width: 20px; height: 20px; transform: rotate(var(--pull-turn, 0deg)); }
.pull.ready, .pull.busy { color: var(--teal); }
.pull.busy .ico { animation: spin .8s linear infinite; }
html.can-pull, html.can-pull body { overscroll-behavior-y: contain; }

/* ------------------------------------------------------------------ toast */
.toast-stack { position: fixed; left: 50%; transform: translateX(-50%); bottom: calc(24px + var(--tab-room) + var(--sab)); z-index: 90; display: grid; gap: 8px; justify-items: center; pointer-events: none; width: min(92vw, 440px); }
.toast { padding: 11px 18px; border-radius: .6rem; background: var(--toast); border: 1px solid var(--line-2); box-shadow: var(--shadow); font-size: 14px; opacity: 0; transform: translateY(8px); transition: opacity .2s, transform .2s; text-align: center; }
.toast.in { opacity: 1; transform: none; }
.toast-ok { border-color: rgba(46, 196, 166, .5); }
.toast-warn { border-color: rgba(240, 169, 46, .55); }
.toast-error { border-color: rgba(229, 83, 75, .6); }
html.player-open .toast-stack { bottom: 24px; }
/* A channel number being typed on a remote (core/channel-number.js) */
.ch-number { position: fixed; right: 32px; top: calc(var(--head-h) + var(--sat) + 16px); z-index: 95; min-width: 96px; padding: 8px 18px; border-radius: .6rem; background: var(--toast); border: 1px solid var(--line-2); box-shadow: var(--shadow); color: var(--text); font-size: 34px; font-weight: 700; letter-spacing: 3px; text-align: center; }

/* ------------------------------------------------------------------ modal */
.modal-backdrop { position: fixed; inset: 0; z-index: 80; display: grid; place-items: center; padding: 16px; background: var(--backdrop); backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px); opacity: 0; transition: opacity .16s; }
.modal-backdrop.in { opacity: 1; }
.modal { width: min(440px, 100%); max-height: calc(var(--dvh) - 32px); display: flex; flex-direction: column; background: var(--card); border: 1px solid var(--line-2); border-radius: .6rem; box-shadow: var(--shadow); transform: translateY(8px) scale(.98); transition: transform .16s; }
.modal.wide { width: min(620px, 100%); }
.modal-backdrop.in .modal { transform: none; }
.modal-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 16px 16px 0 22px; }
.modal-head h2 { font-size: 18px; }
.modal-body { padding: 14px 22px; overflow: auto; }
.modal-body > p { color: var(--muted); }
.modal-actions { display: flex; justify-content: flex-end; gap: 10px; padding: 8px 22px 20px; }
/* Secondary buttons stand out from the dialog's own fill (--card), which is
   about the colour they have on the page. */
.modal .btn-secondary { background: var(--btn-2-in); border-color: var(--btn-2-in); }
.modal .btn-secondary:hover { background: var(--btn-2-in-hover); border-color: var(--btn-2-in-hover); }

.pin { display: grid; justify-items: center; gap: 16px; }
.pin-sub { color: var(--muted); text-align: center; min-height: 1.5em; }
.pin-dots { display: flex; gap: 14px; }
.pin-dots span { width: 14px; height: 14px; border-radius: 50%; border: 2px solid var(--line-2); transition: background .12s, border-color .12s; }
.pin-dots span.on { background: var(--teal); border-color: var(--teal); }
.pin-pad { display: grid; grid-template-columns: repeat(3, 72px); gap: 10px; }
.pin-key { height: 56px; border-radius: .6rem; border: 1px solid var(--line-2); background: var(--surface); font-size: 22px; font-weight: 500; cursor: pointer; display: grid; place-items: center; }
.pin-key:hover { background: var(--line); }
.pin-fn { font-size: 15px; color: var(--muted); }
.shake { animation: shake .35s; }
@keyframes shake { 20%, 60% { transform: translateX(-8px); } 40%, 80% { transform: translateX(8px); } }
.pin-modal .modal-actions { justify-content: center; }

/* ------------------------------------------------------------------ login */
body.login-page { overflow: hidden; }
.login-page .body-full { position: fixed; inset: 0; overflow: hidden; background: linear-gradient(315deg, #003373, #348e9f); }
.login-page .vertical-center { position: relative; z-index: 1; min-height: 100%; display: grid; place-items: center; padding: calc(24px + var(--sat)) 16px calc(24px + var(--sab)); overflow-y: auto; height: 100%; }
/* glass: the card is see-through over the blurred wall (js/login-wall.js also
   sets the blur); the fields, buttons, tiles and keys on it stay solid */
.login-card {
  width: min(460px, 100%); padding: 40px 36px 34px;
  background: rgba(22, 31, 52, .5); border: 1px solid rgba(255, 255, 255, .14);
  -webkit-backdrop-filter: blur(16px) saturate(1.2); backdrop-filter: blur(16px) saturate(1.2);
  border-radius: .6rem; box-shadow: inset 0 1px 0 rgba(255, 255, 255, .06), 0 30px 80px rgba(0, 0, 0, .45);
}
.login-logo { text-align: center; margin-bottom: 10px; }
.login-logo img { width: 280px; max-width: 100%; height: auto; }
.login-lead { text-align: center; color: #b3c0d6; font-size: 14px; margin-bottom: 22px; }
.login-fields { display: grid; gap: 14px; padding: 18px; border-radius: .6rem; background: rgba(12, 18, 32, .45); border: 1px solid rgba(255, 255, 255, .05); margin-bottom: 16px; }
.login-fields .field-label { color: #d5deeb; }
.login-fields .input { background: #0c1221; border-color: rgba(255, 255, 255, .08); }
.login-fields .check { color: #b3c0d6; font-size: 13px; margin-top: 2px; }
.login-error { margin: 0 0 14px; padding: 10px 12px; border-radius: .6rem; background: rgba(229, 83, 75, .14); border: 1px solid rgba(229, 83, 75, .4); color: #ffb3ae; font-size: 13.5px; }
@media (max-width: 480px) { .login-card { padding: 30px 20px 24px; } .login-fields { padding: 14px; } }
/* Light: the panel login's look (the lighter poster wall from js/login-wall.js;
   a brand-blue card, so the operator's logo shows as uploaded, white text,
   light inputs). */
:root[data-theme="light"] .login-page .body-full { background: linear-gradient(315deg, #6096ce, #96cede); }
:root[data-theme="light"] .login-card { background: linear-gradient(315deg, rgba(0, 51, 115, .55), rgba(52, 142, 159, .55)); border-color: rgba(255, 255, 255, .12); box-shadow: 0 3px 0 0 #10466e, 0 30px 80px rgba(16, 27, 46, .25); }
:root[data-theme="light"] .login-lead, :root[data-theme="light"] .login-fields .check { color: rgba(255, 255, 255, .85); }
:root[data-theme="light"] .login-fields { background: rgba(255, 255, 255, .12); border-color: rgba(255, 255, 255, .1); }
:root[data-theme="light"] .login-fields .field-label { color: #fff; }
:root[data-theme="light"] .login-fields .input { background: #eef3f9; border-color: transparent; color: #101b2e; }
:root[data-theme="light"] .login-fields .input::placeholder { color: #5a6b84; }
:root[data-theme="light"] .login-fields .input-btn { color: #46566e; }
/* the panel's light login button: its pastel brand blue with ink */
:root[data-theme="light"] .btn-login { background-image: linear-gradient(315deg, #b1d2f3, #abe2ed); color: #101b2e; box-shadow: 0 3px 0 0 #10466e; }
:root[data-theme="light"] .btn-login::before { display: none; }
/* The admin panel's login button (btn-info bg-animate login-btn): the default
   blue gradient, uppercase label, the hard 3px block shadow, .6rem corners. */
.btn-login {
  min-height: 4rem; padding: .75rem 1rem; border: 0; border-radius: .6rem;
  background-image: linear-gradient(315deg, #003373, #348e9f); background-size: 400% 400%; background-position: 0% 50%;
  color: #fff; font-size: 1.05rem; font-weight: 400; text-transform: uppercase;
  box-shadow: 0 3px 0 0 #0f172a;
}
/* The admin's bg-animate pan: an overlay holding the other end of the
   gradient fades in and out over 10 s (opacity only, so it stays on the GPU). */
.btn-login { position: relative; isolation: isolate; }
.btn-login::before {
  content: ""; position: absolute; inset: 0; z-index: -1; border-radius: inherit;
  background: inherit; background-position: 100% 50%; pointer-events: none;
  animation: btn-login-fade 10s ease infinite;
}
@keyframes btn-login-fade { 0%, 100% { opacity: 0; } 50% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .btn-login::before { animation: none; opacity: 0; } }
/* the gradient's slow crossfade: decoration, only with motion on */
body:not(.motion) .btn-login::before { animation: none; opacity: 0; }
.btn-login:hover { filter: brightness(1.08); }
.btn-login:disabled { filter: saturate(.6) brightness(.85); cursor: default; }

/* ------------------------------------------------------------------ home */
/* Featured row: one collection's row in a box over the blurred backdrop of
   the title hovered in it; the heading sits above the box. Two stacked
   images crossfade. Desktop fits a whole number of posters (8 on wide
   screens) across the box; the gap is wider than the side padding so the
   next poster starts past the box edge instead of peeking in. */
.home-expiry { display: inline-flex; margin-bottom: 16px; }
.home-feature { margin-bottom: 30px; --hf-n: 8; --hf-gap: 22px; --hf-pad: 16px; }
.hf-box {
  /* clip, not hidden: a hidden box is still a scroll container, and focusing
     or scrolling a poster into view scrolled it, sliding the row up under
     its top edge (the zoomed poster cut off). Clip cannot be scrolled. */
  position: relative; overflow: hidden; overflow: clip; isolation: isolate; border-radius: .6rem;
  background: var(--thumb-grad); box-shadow: var(--block-shadow);
}
.hf-bg { position: absolute; inset: 0; z-index: -1; }
.hf-img {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
  opacity: 0; filter: blur(16px) saturate(1.1); transform: scale(1.1);
  transition: opacity 1.4s ease-in-out;
}
.hf-img.on { opacity: 1; }
.hf-img.blur { filter: blur(28px) saturate(1.1); }
.hf-bg::after { content: ""; position: absolute; inset: 0; background: var(--hf-veil); }
.hf-body .rail-section { margin: 0; }
.hf-body .card-title, .hf-body .card-sub { color: var(--hf-text); text-shadow: var(--hf-shadow); }
.hf-body .rail-wrap { margin: 0; }
.hf-body .rail {
  /* the box clips too: no pull-up, its padding is the focused poster's room.
     The focus zoom (scale 1.03 from the bottom edge, plus the 4px ring)
     grows a poster upward by 3% of its height, which on the big three-across
     posters is more than the padding; so the top padding is at least that
     growth: column width x 1.5 (2:3 poster) x 3%, plus the ring and 2px. */
  gap: var(--hf-gap); margin: 0; scroll-padding: 0 var(--hf-pad);
  padding: max(var(--hf-pad), calc((100% - 2 * var(--hf-pad) - (var(--hf-n) - 1) * var(--hf-gap)) / var(--hf-n) * .045 + 6px))
           var(--hf-pad) calc(var(--hf-pad) - 4px);
  grid-auto-columns: calc((100% - (var(--hf-n) - 1) * var(--hf-gap)) / var(--hf-n));
}
@media (prefers-reduced-motion: reduce) { .hf-img { transition: none; } }

/* ------------------------------------------------------------------ Home stage
   views/home-stage.js, on screens at least 992 x 640: the focused title's
   backdrop fills the screen behind everything, its logo (or name), facts and
   plot sit top left, and one row of cards shows at the bottom, the page's
   bottom padding below it. Text here is always light: it sits on artwork. */
.home-stage {
  position: relative; display: flex; flex-direction: column;
  height: calc(100vh - var(--head-h) - var(--sat) - 24px - 48px - var(--sab));
  color: #fff;
}
.home-stage > .home-expiry { align-self: flex-start; }
/* the backdrop under the page's content (z-index 0; the content is lifted
   above it, a negative index would put it under the body's background) */
.hs-bg { position: fixed; inset: 0; z-index: 0; overflow: hidden; background: #0b1222; pointer-events: none; }
.home-stage > :not(.hs-bg) { position: relative; z-index: 1; }
.hs-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: center 20%; opacity: 0; transition: opacity .6s ease; }
.hs-img.on { opacity: 1; }
.hs-bg::after {
  content: ""; position: absolute; inset: 0;
  background:
    linear-gradient(90deg, rgba(11, 18, 34, .94) 0%, rgba(11, 18, 34, .72) 34%, rgba(11, 18, 34, .2) 66%, rgba(11, 18, 34, 0) 100%),
    linear-gradient(0deg, rgba(11, 18, 34, .96) 0%, rgba(11, 18, 34, .7) 30%, rgba(11, 18, 34, 0) 58%);
}
.hs-info { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; justify-content: flex-end; gap: 12px; max-width: min(680px, 48%); padding-bottom: 28px; overflow: hidden; }
.hs-info > * { flex: none; }
.hs-logo { display: block; width: min(440px, 100%); height: 130px; }
.hs-logo img { display: block; width: 100%; height: 100%; object-fit: contain; object-position: left bottom; opacity: 0; transition: opacity .25s; filter: drop-shadow(0 2px 10px rgba(0, 0, 0, .45)); }
.hs-logo img.on { opacity: 1; }
.hs-name { margin: 0; font-size: 40px; line-height: 1.1; font-weight: 700; text-shadow: 0 2px 12px rgba(0, 0, 0, .6); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.hs-facts { display: flex; flex-wrap: wrap; align-items: center; row-gap: 4px; font-size: 15px; font-weight: 600; color: #e6ecf5; font-variant-numeric: tabular-nums; }
.hs-facts > * + *::before { content: ""; display: inline-block; vertical-align: middle; width: 4px; height: 4px; border-radius: 50%; background: rgba(255, 255, 255, .5); margin: 0 10px; }
.hs-genre { font-size: 14px; color: #c9d4e5; }
.hs-plot { margin: 0; font-size: 16px; line-height: 1.55; color: #dbe3ef; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; text-shadow: 0 1px 6px rgba(0, 0, 0, .5); }
/* the one-row window: the rows' column moves inside it (home-stage.js) */
/* The window is edge to edge like the rows in it (--row-edge); the row titles
   in it keep to the header's grid. */
.hs-rows { flex: none; position: relative; overflow: hidden; transition: height .25s ease; margin: 0 calc(50% - 50vw); }
.home-stage .rail-wrap { margin: 0; }
.home-stage .section-head { padding-left: var(--row-edge); padding-right: var(--row-edge); }
.hs-rows > .home-sections { position: relative; transition: transform .35s cubic-bezier(.2, .8, .25, 1); }
.hs-rows > .home-sections.hs-instant, .hs-rows:has(.hs-instant) { transition: none; }
.home-stage .home-sec > .rail-section, .home-stage .home-sec > * { margin-bottom: 0; }
.home-stage .rail-section { padding-bottom: 4px; }
.home-stage .section-head h2 { color: #fff; text-shadow: 0 1px 6px rgba(0, 0, 0, .5); }
.home-stage .card-title { color: #fff; }
.home-stage .card-sub { color: #c9d4e5; }
.home-stage .hint-card { display: none; }
/* eight posters across at any width: the first starts where the header
   starts and the eighth ends where it ends (as .rail.shape-poster, n = 8) */
.home-stage .rail.shape-poster { grid-auto-columns: calc((var(--row-w) - 7 * 14px) / 8); }
/* the selected card shows as selected whether the arrows or the pointer chose it */
.home-stage .card-item:focus .card-media { box-shadow: var(--ring); }
.home-stage .card-item:focus { outline: none; }
/* 720p-class screens (a TV box): room for one line of title and two of plot */
@media (max-height: 820px) {
  .hs-info { gap: 8px; padding-bottom: 18px; }
  .hs-name { font-size: 30px; -webkit-line-clamp: 1; }
  .hs-logo { width: min(320px, 100%); height: 90px; }
  .hs-facts { font-size: 13px; }
  .hs-genre { font-size: 12.5px; }
  .hs-plot { font-size: 13.5px; line-height: 1.5; -webkit-line-clamp: 2; }
}
@media (prefers-reduced-motion: reduce) { .hs-img, .hs-rows, .hs-rows > .home-sections { transition: none; } }
@media (max-width: 1399.98px) { .home-feature { --hf-n: 7; } }
@media (max-width: 1199.98px) { .home-feature { --hf-n: 6; } }
@media (max-width: 991.98px) {
  /* three posters across the box, its padding kept after the last one */
  .home-feature { margin-bottom: 22px; --hf-n: 3; --hf-gap: 12px; --hf-pad: 12px; }
}

/* Favorites + Recent channels share one row. Each group's label sticks to
   the row's left edge while that group is in view, so "Recent" takes over
   slot one once only recent channels are showing. */
.rail-groups .section-head { display: none; }
.rail-groups .rail { grid-auto-columns: max-content; }
.rail-groups .rail > * { scroll-snap-align: none; }
.rgroup { display: flex; flex-direction: column; min-width: 0; }
.rg-label {
  position: sticky; left: 0; align-self: flex-start; width: max-content;
  font-size: 18px; font-weight: 600; min-height: 30px; display: flex; align-items: center; margin-bottom: 12px;
}
.rg-tv { margin-left: 8px; padding: 1px 7px; border-radius: .6rem; font-size: 11px; font-weight: 600; letter-spacing: .04em; background: rgba(var(--teal-rgb), .16); color: var(--teal); }
.rg-items { display: grid; grid-auto-flow: column; grid-auto-columns: 164px; gap: 14px; }
.rg-items > * { scroll-snap-align: start; }
.rg-items.rg-wide { grid-auto-columns: calc((100cqw - 5 * 14px) / 6); }
/* Home's wide rows (Continue Watching, the channels' Favorites / Recent,
   Events on now): four across the header's width on a desktop or TV */
@media (min-width: 992px) {
  .home-sections .rail.shape-wide, .home-sections .rg-items.rg-wide { grid-auto-columns: calc((var(--row-w) - 3 * 14px) / 4); }
}
/* the row is the size container, so six channel tiles fill its width */
.rail-groups .rail { container-type: inline-size; }
/* the rail is shape-square; the channel groups override its tile ratio */
.rg-items.rg-wide .card-media { aspect-ratio: 16 / 9; }
/* Live frame cards: the frame covers the logo; once it loads the logo moves
   to a small corner badge. With no frame (404) the centred logo stays. */
.card-media .lc-logo, .card-media .lc-frame { position: absolute; inset: 0; }
.card-media .lc-logo { background: var(--thumb-grad); }
.card-media .lc-logo .thumb.fit-contain img { padding: 16% 26%; }
.card-media .lc-frame .thumb.broken { display: none; }
.card-media .lc-frame .thumb-fb { display: none; }
.card-media .lc-corner {
  position: absolute; top: 8px; right: 10px; width: 64px; height: 30px; display: none;
  filter: drop-shadow(0 0 6px rgba(0, 0, 0, .7));
}
.card-media .lc-corner .thumb { background: none; }
.card-media .lc-corner .thumb img { padding: 0; object-position: right top; }
.card-media .lc-corner .thumb-fb { display: none; }
.card-media:has(.lc-frame .thumb.loaded) .lc-corner { display: block; }
.card-item:hover .card-media:has(.card-remove) .lc-corner { opacity: 0; }
@media (max-width: 991.98px) {
  .rg-label { font-size: 16px; }
  .rg-items { grid-auto-columns: 120px; gap: 10px; }
  .rg-items.rg-wide { grid-auto-columns: calc((100cqw - 10px) / 2); }
  /* Continue Watching: two cards across, like the favorite channels above */
  .rail-cont .rail.shape-wide { grid-auto-columns: calc((var(--row-w) - 10px) / 2); }
}
/* rails size their cards from the row's full width (cqw) */
.rail-wrap { container-type: inline-size; }

/* ------------------------------------------------------------------ search */
.search-box { position: relative; display: flex; align-items: center; margin-bottom: 22px; }
.search-box > .ico { position: absolute; left: 16px; color: var(--muted); pointer-events: none; }
.search-box .input { min-height: 52px; padding-left: 48px; padding-right: 48px; font-size: 16px; border-radius: .6rem; }
/* suggestions under the box (views/search.js) */
.sr-sugg { position: absolute; left: 0; right: 0; top: calc(100% + 6px); z-index: 30; display: grid; gap: 2px; padding: 8px; border-radius: .6rem; background: var(--popover); border: 1px solid var(--line-2); box-shadow: 0 14px 34px rgba(0, 0, 0, .35); }
.sr-sugg[hidden] { display: none; }
.sr-sugh { margin: 2px 8px 6px; color: var(--muted); font-size: 11.5px; font-weight: 600; letter-spacing: .05em; text-transform: uppercase; }
.sr-sg { display: flex; align-items: center; gap: 12px; min-width: 0; padding: 9px 10px; border: 0; border-radius: .6rem; background: none; color: var(--text); font: inherit; font-size: 14.5px; text-align: left; cursor: pointer; }
.sr-sg:hover, .sr-sg:focus { background: var(--hover-2); outline: none; }
body.kbd .sr-sg:focus { box-shadow: inset 0 0 0 2px var(--teal); }
.sr-sg-name { flex: 1; }
.sr-sg-kind { flex: none; color: var(--muted); font-size: 12.5px; }
.result-group { margin-bottom: 30px; }
.result-group .list { max-width: 760px; }
/* events: 16:9 cards, four across on a wide screen, two on a tablet */
.grid.sr-events { grid-template-columns: minmax(0, 1fr); }
@media (min-width: 600px) { .grid.sr-events { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 992px) { .grid.sr-events { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
/* the channels use the full width, in columns */
.result-group .list.sr-live { max-width: none; }

/* ------------------------------------------------------------------ account */
/* six tiles, the MAG app's Account: three by two on a wide screen, two
   columns on a tablet, one on a phone; a row's tiles share its height */
.account-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); grid-auto-rows: 1fr; gap: 18px; }
@media (max-width: 1199.98px) { .account-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 719.98px) { .account-grid { grid-template-columns: minmax(0, 1fr); grid-auto-rows: auto; gap: 14px; } }
.account-head { display: flex; align-items: baseline; gap: 18px; flex-wrap: wrap; }
.account-welcome { margin: 0; color: var(--text-3); font-size: 14px; }
.account-grid .setting p { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.setting > select.input, .setting > .select2-container { flex: none; width: 168px !important; }
@media (max-width: 400px) { .setting > select.input, .setting > .select2-container { width: 136px !important; } }
.kv { margin: 0; display: grid; }
.kv > div { display: flex; justify-content: space-between; align-items: center; gap: 16px; padding: 10px 0; border-top: 1px solid var(--line); }
.kv > div:first-child { border-top: 0; padding-top: 2px; }
.kv dt { color: var(--muted); font-size: 14px; }
.kv dd { margin: 0; text-align: right; font-weight: 500; display: flex; align-items: center; gap: 8px; }
.status-dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; }
.status-dot.ok { background: var(--ok); box-shadow: 0 0 0 3px rgba(var(--teal-rgb), .2); }
.status-dot.bad { background: var(--danger); box-shadow: 0 0 0 3px rgba(229, 83, 75, .2); }
/* Subscription's rows spread over its card, as tall as the row's others (views/account.js) */
.card.ac-sub { display: flex; flex-direction: column; }
.ac-sub .kv { flex: 1; grid-auto-rows: 1fr; }
/* the Activation Code dialog (views/account.js) */
.ac-code p { margin: 0 0 12px; }
.ac-code-box { margin: 4px 0 14px; padding: 18px 12px; border-radius: .6rem; background: var(--card-2); border: 1px solid var(--line); text-align: center; }
.ac-code-digits { font-size: 30px; font-weight: 600; letter-spacing: .06em; font-variant-numeric: tabular-nums; color: var(--text); }
.ac-code-err { color: var(--danger-text); }
.ac-code-actions { display: flex; align-items: center; gap: 8px; margin-top: 18px; }
.ac-code-actions .ac-code-close { margin-left: auto; }
.ac-code-actions .btn-icon { width: 42px; padding: 0; justify-content: center; }
.ac-code-actions .btn-icon .ico { width: 18px; height: 18px; }
.setting { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 12px 0; border-top: 1px solid var(--line); }
.setting:first-of-type { border-top: 0; padding-top: 2px; }
.setting p { font-size: 13px; }
.setting b { font-weight: 500; }
.setting-stack { flex-direction: column; align-items: stretch; gap: 10px; }
select.input {
  appearance: none; cursor: pointer; padding-right: 40px; box-shadow: var(--block-shadow-in);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%238b9ab3' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 12px center; background-size: 18px;
}
select.input:disabled { opacity: .6; cursor: default; }
select.input option, select.input optgroup { background: var(--popover); color: var(--text); }
/* select2 (every select in the player), styled like .input; dropdown as in
   the panel. */
.select2-container .select2-selection--single {
  height: 46px; border: 0; border-radius: .6rem; background: var(--field); box-shadow: var(--block-shadow-in); outline: 0;
}
.select2-container .select2-selection--single .select2-selection__rendered { line-height: 46px; padding: 0 40px 0 14px; color: var(--text); }
.select2-container .select2-selection--single .select2-selection__arrow { height: 46px; width: 36px; right: 4px; }
.select2-container .select2-selection--single .select2-selection__arrow b { border-color: var(--muted) transparent transparent; border-width: 6px 6px 0; margin-left: -6px; margin-top: -3px; }
.select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b { border-color: transparent transparent var(--muted); border-width: 0 6px 6px; }
.select2-container--focus .select2-selection--single, .select2-container--open .select2-selection--single { box-shadow: var(--block-shadow-in), 0 0 0 3px rgba(var(--teal-rgb), .22); }
.select2-container--default.select2-container--disabled .select2-selection--single { background: var(--field); opacity: .6; cursor: default; }
.select2-dropdown { background: var(--popover); border: 0; border-radius: .6rem; box-shadow: var(--shadow-pop); overflow: hidden; color: var(--text); z-index: 1100; }
.select2-container--default .select2-search--dropdown { padding: 10px; }
.s2-nosearch .select2-search--dropdown { display: none; }
.select2-container--default .select2-search--dropdown .select2-search__field {
  height: 38px; padding: 0 10px; border: 1px solid var(--line); border-radius: .6rem; background: var(--field); color: var(--text); font: inherit; outline: 0;
}
@media (max-width: 991.98px) { .select2-container--default .select2-search--dropdown .select2-search__field { font-size: 16px; } }
.select2-container--default .select2-results > .select2-results__options { max-height: 320px; }
.select2-results__option { padding: 8px 14px; font-size: 14px; }
.select2-container--default .select2-results__group { padding: 10px 14px 4px; font-size: 12px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; color: var(--muted); }
.select2-container--default .select2-results__option--group { padding: 0; }
.select2-container--default .select2-results__option--group .select2-results__option { padding-left: 22px; }
.select2-container--default .select2-results__option--selected { background: var(--btn-2); color: var(--text-2); }
.select2-container--default .select2-results__option--highlighted.select2-results__option--selectable { background: #5089de; color: #fff; }
.select2-results__message { color: var(--muted); }
/* Phones: a button stays beside its text, which wraps in the room left; only
   a row with a wide segmented control drops it to its own line. */
.setting > :first-child { flex: 1 1 auto; min-width: 0; }
.setting > .btn { flex: none; white-space: nowrap; }
@media (max-width: 480px) { .setting:has(> .seg) { flex-wrap: wrap; } .setting > .seg { margin-left: auto; } }
.hide-list { display: grid; gap: 2px; max-height: 50vh; overflow: auto; margin: 0 -6px; padding: 0 6px; }
.check-row { padding: 9px 8px; border-radius: .6rem; }
.check-row:hover { background: var(--surface); }
.check-row span:first-of-type { flex: 1; }
/* Home page layout (views/account.js): one row per Home section, Up / Down. */
.lay-list { display: grid; gap: 2px; max-height: 55vh; overflow: auto; margin: 0 -6px; padding: 0 6px; }
.lay-row { display: flex; align-items: center; gap: 8px; min-width: 0; padding: 4px 4px 4px 8px; border-radius: .6rem; font-size: 14px; }
.lay-row:hover, .lay-row:focus-within { background: var(--surface); }
.lay-n { width: 22px; flex: none; color: var(--muted); font-size: 12px; text-align: right; font-variant-numeric: tabular-nums; }
.lay-name { flex: 1; min-width: 0; line-height: 1.3; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.lay-row .icon-btn { flex: none; }
.lay-row .icon-btn[disabled] { opacity: .3; }
/* The top row: the featured collection (Home's hero). */
.lay-row.lay-featured { background: var(--teal-soft); box-shadow: inset 3px 0 0 var(--teal); }
.lay-row.lay-featured .lay-name { font-weight: 600; }
.chip.chip-featured { background: var(--teal); border-color: var(--teal); color: var(--on-teal); }
/* The grip: two columns of dots; grabbing it drags the row (touch included). */
.lay-grip { width: 14px; height: 22px; flex: none; cursor: grab; touch-action: none; opacity: .55;
  background: radial-gradient(circle, var(--muted) 1.6px, transparent 1.9px) 0 0 / 7px 7px; }
.lay-grip:hover { opacity: 1; }
.lay-list.is-dragging { cursor: grabbing; user-select: none; }
.lay-list.is-dragging .lay-grip { cursor: grabbing; }
.lay-row.dragging { background: var(--line-2); box-shadow: var(--shadow-lift); position: relative; z-index: 1; }
.lay-row.dragging .lay-grip { opacity: 1; }
.lay-row.dropped { background: var(--teal-soft); transition: background .6s; }

/* ------------------------------------------------------------------ player */
.player { position: fixed; inset: 0; z-index: 60; display: flex; flex-direction: column; background: #0b1120; padding: var(--sat) var(--sar) 0 var(--sal); }
.player-bar { display: flex; align-items: center; gap: 10px; height: 60px; padding: 0 12px; background: linear-gradient(90deg, rgba(39, 101, 121, .9), rgba(6, 44, 92, .9)); flex: none; }
.pb-title { flex: 1; min-width: 0; display: flex; align-items: center; gap: 12px; }
.pb-logo { position: relative; width: 40px; height: 40px; border-radius: .6rem; overflow: hidden; flex: none; background: rgba(0, 0, 0, .25); }
.pb-logo .thumb-fb { background: transparent; }
.pb-logo .thumb-initials { font-size: 14px; }
.pb-text { display: grid; min-width: 0; }
.pb-name { font-weight: 600; font-size: 16px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pb-sub { font-size: 12.5px; color: rgba(232, 238, 247, .72); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pb-sub:empty { display: none; }
.pb-actions { display: flex; align-items: center; gap: 6px; flex: none; }
.player-body { flex: 1; min-height: 0; display: grid; grid-template-columns: minmax(0, 1fr) 380px; }
.player-stage { position: relative; background: #000; min-height: 0; display: grid; }
.player-stage:fullscreen { width: 100vw; height: 100vh; }
.pv { position: absolute; inset: 0; }
.pv video { display: block; }
.p-spinner { position: absolute; inset: 0; display: grid; place-items: center; pointer-events: none; }
.p-status { position: absolute; inset: 0; display: grid; place-items: center; padding: 20px; background: rgba(5, 10, 20, .55); z-index: 3; }
.p-status-box { max-width: 460px; text-align: center; display: grid; justify-items: center; gap: 14px; padding: 22px 24px; border-radius: .6rem; background: rgba(23, 32, 51, .94); border: 1px solid var(--line-2); box-shadow: var(--shadow); }
.p-status-box.error .ico { color: var(--danger); width: 30px; height: 30px; }
.p-status-btns { display: flex; gap: 10px; flex-wrap: wrap; justify-content: center; }
/* a message over the picture (a failed start, an error) takes the place of
   "Tap for sound": they share the same spot */
.p-status:not([hidden]) ~ .p-unmute, .ch-status:not([hidden]) ~ .p-unmute { display: none; }
.p-unmute { position: absolute; top: 14px; right: 14px; z-index: 4; display: inline-flex; align-items: center; gap: 8px; padding: 8px 14px; border-radius: 999px; border: 0; background: rgba(15, 23, 42, .85); color: #fff; font-weight: 500; font-size: 13px; cursor: pointer; }
.p-controls { position: absolute; left: 0; right: 0; bottom: 0; z-index: 2; display: flex; align-items: center; gap: 6px; padding: 28px 12px 10px; background: linear-gradient(transparent, rgba(0, 0, 0, .7)); opacity: 0; transition: opacity .2s; }
.player[data-kind="vod"] .p-controls { display: none; }
.player-stage:hover .p-controls, .player-stage:focus-within .p-controls, .player-stage.show-ui .p-controls { opacity: 1; }
@media (hover: none) { .p-controls { opacity: 1; } }
.p-controls .icon-btn { color: #fff; }
/* Live sound control (core/volume.js): the button, and a slider where there is
   a mouse (touch screens use their own volume buttons). */
.vol-ctl { display: inline-flex; align-items: center; }
.vol-ctl .icon-btn { color: #fff; }
.vol-range {
  -webkit-appearance: none; appearance: none; width: 84px; height: 4px; margin: 0 10px 0 2px; padding: 0;
  border-radius: 999px; outline: none; cursor: pointer;
  background: linear-gradient(to right, var(--teal) var(--vol, 100%), rgba(255, 255, 255, .28) var(--vol, 100%));
}
.vol-range::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 12px; height: 12px; border-radius: 50%; border: 0; background: #fff; box-shadow: 0 1px 3px rgba(0, 0, 0, .5); }
.vol-range::-moz-range-thumb { width: 12px; height: 12px; border-radius: 50%; border: 0; background: #fff; box-shadow: 0 1px 3px rgba(0, 0, 0, .5); }
.vol-range::-moz-range-track { background: transparent; }
@media (hover: none) { .vol-range { display: none; } }
/* Movie / episode controls (core/vod-controls.js): the seek bar over a row of
   the same buttons as the live bar; they fade after a few seconds of playback. */
.pc { position: absolute; left: 0; right: 0; bottom: 0; z-index: 3; display: none; padding: 44px 12px 8px; background: linear-gradient(transparent, rgba(0, 0, 0, .78)); transition: opacity .25s; }
.player-stage.pc-on .pc { display: block; }
.player-stage.pc-idle .pc { opacity: 0; pointer-events: none; }
.player-stage.pc-idle { cursor: none; }
.pc-row { display: flex; align-items: center; gap: 4px; min-width: 0; }
/* the picture's fit (Fit / Fill / Stretch) */
.pc-aspect { min-width: 70px; min-height: 36px; padding: 0 10px; color: #fff; font-size: 13px; }
.pc-aspect:hover { background: rgba(255, 255, 255, .12); color: #fff; }
@media (max-width: 480px) { .pc-aspect { display: none; } }
.pc .icon-btn { color: #fff; flex: none; }
.pc .icon-btn.on { color: var(--teal); }
.pc-time { margin-left: 6px; color: rgba(255, 255, 255, .92); font-size: 13px; font-variant-numeric: tabular-nums; white-space: nowrap; }
.pc-seek { position: relative; height: 20px; margin: 0 6px 2px; display: flex; align-items: center; cursor: pointer; touch-action: none; border-radius: 999px; }
.pc-seek:focus-visible { outline-offset: 4px; }
.pc-rail { position: relative; flex: 1; height: 4px; border-radius: 999px; background: rgba(255, 255, 255, .24); overflow: hidden; transition: height .15s; }
.pc-seek:hover .pc-rail, .pc-seek.drag .pc-rail, .pc-seek:focus-visible .pc-rail { height: 6px; }
.pc-buf, .pc-fill { position: absolute; left: 0; top: 0; bottom: 0; width: 0; }
.pc-buf { background: rgba(255, 255, 255, .32); }
.pc-fill { background: var(--teal); }
.pc-knob { position: absolute; top: 50%; left: 0; width: 14px; height: 14px; margin: -7px 0 0 -7px; border-radius: 50%; background: #fff; box-shadow: 0 1px 4px rgba(0, 0, 0, .5); transform: scale(0); transition: transform .15s; pointer-events: none; }
.pc-seek:hover .pc-knob, .pc-seek.drag .pc-knob, .pc-seek:focus-visible .pc-knob { transform: scale(1); }
.pc-tip { position: absolute; bottom: 24px; left: 0; padding: 3px 8px; border-radius: .6rem; background: rgba(15, 23, 42, .94); color: #fff; font-size: 12px; font-variant-numeric: tabular-nums; white-space: nowrap; pointer-events: none; }
.pc-xcode { display: inline-flex; align-items: center; gap: 7px; margin-left: 8px; padding: 4px 10px 4px 8px; border-radius: .6rem; background: rgba(15, 23, 42, .72); border: 1px solid rgba(46, 196, 166, .35); color: rgba(255, 255, 255, .92); font-size: 12px; font-weight: 500; white-space: nowrap; cursor: default; }
.pc-xcode .ring { width: 9px; height: 9px; border-radius: 50%; background: var(--teal); box-shadow: 0 0 8px rgba(46, 196, 166, .6); animation: pc-pulse 1.4s ease-in-out infinite; }
@keyframes pc-pulse { 50% { opacity: .35; } }
@media (prefers-reduced-motion: reduce) { .pc-xcode .ring { animation: none; } }
.pc-big { position: absolute; left: 50%; top: 50%; z-index: 2; width: 72px; height: 72px; margin: -36px 0 0 -36px; display: grid; place-items: center; border: 0; border-radius: 50%; background: rgba(15, 23, 42, .72); color: #fff; cursor: pointer; backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); }
.pc-big .ico { width: 30px; height: 30px; margin-left: 4px; }
.pc-big:hover { background: rgba(23, 32, 51, .9); }
.pc-menu { position: absolute; bottom: 62px; left: 0; z-index: 5; min-width: 210px; max-width: min(320px, calc(100% - 16px)); max-height: min(60vh, 340px); overflow-y: auto; display: grid; gap: 2px; padding: 6px; border-radius: .6rem; background: rgba(23, 32, 51, .97); border: 1px solid var(--line-2); box-shadow: var(--shadow); }
.pc-menu-title { padding: 6px 10px 4px; color: var(--muted); font-size: 11px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; }
.pc-opt { display: flex; align-items: center; gap: 10px; padding: 8px 10px; border: 0; border-radius: .6rem; background: none; color: var(--text); font: inherit; font-size: 14px; text-align: left; cursor: pointer; }
.pc-opt:hover, .pc-opt:focus-visible, body.kbd .pc-opt:focus { background: rgba(255, 255, 255, .08); outline: none; }
.pc-opt .ico { flex: none; width: 16px; height: 16px; color: var(--teal); visibility: hidden; }
.pc-opt.on .ico { visibility: visible; }
/* Subtitles (core/vod-controls.js draws them): low over the picture, lifted
   clear of the controls while they show. */
.pc-sub { position: absolute; left: 6%; right: 6%; bottom: 7%; z-index: 2; text-align: center; pointer-events: none; transition: bottom .25s;
  color: #fff; font: 500 clamp(15px, 2.4vw, 34px)/1.4 "Poppins", system-ui, sans-serif; }
.pc-sub span { padding: .08em .45em; border-radius: .6rem; background: rgba(0, 0, 0, .66); -webkit-box-decoration-break: clone; box-decoration-break: clone; }
.player-stage.pc-on:not(.pc-idle) .pc-sub { bottom: calc(7% + 64px); }
@media (max-width: 480px) {
  .pc { padding: 32px 6px 4px; }
  .pc .icon-btn { width: 34px; height: 34px; }
  .pc-time { font-size: 12px; margin-left: 2px; }
  .pc-xcode { padding: 4px 6px; margin-left: 4px; }
  .pc-xcode-text { display: none; }
}
@media (max-width: 340px) { .pc-back, .pc-fwd { display: none; } }
.live-pill { display: inline-flex; align-items: center; gap: 6px; padding: 3px 10px 3px 8px; border-radius: .6rem; background: var(--danger); color: #fff; font-size: 12px; font-weight: 600; letter-spacing: .04em; }
.live-pill .ico { width: 14px; height: 14px; }
.p-overlay { position: absolute; right: 18px; bottom: 70px; z-index: 4; }
.p-next-box { width: 300px; padding: 16px 18px; border-radius: .6rem; background: rgba(23, 32, 51, .95); border: 1px solid var(--line-2); box-shadow: var(--shadow); display: grid; gap: 6px; }
.p-next-box p { color: var(--muted); font-size: 13px; }
.p-next-box .p-status-btns { justify-content: flex-start; margin-top: 6px; }

.player-info { background: var(--surface); border-left: 1px solid var(--line); overflow-x: hidden; overflow-y: auto; padding: 18px; display: grid; grid-template-columns: minmax(0, 1fr); align-content: start; gap: 16px; }
.pi-zap { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
/* An event's feeds (player.openLive feeds): one button each, the playing one
   filled. */
.pi-feeds { display: grid; gap: 8px; }
.pi-feeds .btn { min-width: 0; justify-content: flex-start; padding: 0 12px; }
.pi-zap .btn { min-width: 0; justify-content: flex-start; padding: 0 12px; }
.pi-zap .btn:last-child { justify-content: flex-end; }
.pi-zap .btn:only-child { grid-column: 1 / -1; }
.pi-epg { display: grid; gap: 14px; }
.pi-now { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius); padding: 14px 16px; display: grid; gap: 6px; }
.pi-now h3 { font-size: 17px; }
.pi-label { color: var(--teal); font-size: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: .05em; }
.pi-bar { display: block; height: 4px; border-radius: 2px; background: var(--line); overflow: hidden; }
.pi-bar i { display: block; height: 100%; background: var(--teal); }
.pi-desc { color: #b3c0d6; font-size: 13.5px; line-height: 1.55; }
.pi-next { list-style: none; margin: 0; padding: 0; display: grid; }
.pi-next li { display: flex; gap: 12px; padding: 9px 4px; border-top: 1px solid var(--line); font-size: 14px; }
.pi-next li:first-child { border-top: 0; }
.pi-time { color: var(--muted); font-variant-numeric: tabular-nums; flex: none; width: 64px; }
.pi-ptitle { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pi-ptitle b { color: var(--teal); font-weight: 600; margin-right: 4px; }
/* A movie or episode (player.openVod panel): the backdrop runs to the
   panel's edges and fades into it, the poster overlaps its foot. */
.pv-head { margin: -18px -18px 0; }
.pv-art { position: relative; height: 168px; overflow: hidden; background: var(--card); }
.pv-art .thumb img { object-position: center 25%; }
.pv-art .thumb-fb { display: none; }
.pv-art::after { content: ""; position: absolute; inset: 0; background: linear-gradient(rgba(23, 32, 51, .1) 30%, var(--surface)); }
.pv-id { position: relative; display: flex; align-items: flex-end; gap: 14px; margin-top: -72px; padding: 0 18px; }
.pv-poster { position: relative; flex: none; width: 96px; aspect-ratio: 2 / 3; border-radius: var(--radius); overflow: hidden; background: var(--card); box-shadow: var(--block-shadow), 0 10px 24px rgba(0, 0, 0, .45); }
.pv-poster.is-logo { aspect-ratio: 3 / 2; background: var(--thumb-grad); }
.pv-poster.is-logo .thumb.fit-contain img { padding: 8% 10%; }
.pv-text { min-width: 0; display: grid; gap: 3px; padding-bottom: 2px; }
.pv-title { font-size: 19px; line-height: 1.25; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.pv-series { color: #c9d4e5; font-size: 13.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pv-tags { display: flex; flex-wrap: wrap; align-items: center; row-gap: 4px; margin-top: 3px; color: #c9d4e5; font-size: 13px; font-variant-numeric: tabular-nums; }
.pv-tags > * { display: inline-flex; align-items: center; }
.pv-tags > * + *::before { content: ""; width: 3px; height: 3px; border-radius: 50%; background: #5b6b86; margin: 0 8px; }
.pv-rate { gap: 4px; color: #ffd58a; font-weight: 600; }
.pv-rate .ico { width: 13px; height: 13px; color: var(--warning); }
.pv-tags .vd-age { border: 1px solid rgba(255, 255, 255, .35); border-radius: 4px; padding: 0 5px; font-size: 11.5px; line-height: 16px; }
/* An event (paintEventPanel): wide artwork, the event's logo in the poster's
   place, then when it is on with a progress bar while live. */
.pv-event .pv-art .thumb.fit-contain img { padding: 18px 24%; }
/* No tall poster to carry the text below the artwork: only its last
   40px sit over the artwork's fade. */
.pv-event .pv-id { margin-top: -40px; }
.pv-event.no-art .pv-art { display: none; }
.pv-event.no-art .pv-id { margin-top: 18px; }
.pv-logo { width: 84px; aspect-ratio: 1 / 1; background: var(--card-2); }
.pv-logo .thumb img { padding: 12%; }
.pv-when { display: grid; gap: 8px; }
.pv-when-line { display: flex; flex-wrap: wrap; align-items: center; row-gap: 4px; color: var(--muted); font-size: 13px; font-variant-numeric: tabular-nums; }
.pv-when-line > * + *::before { content: ""; display: inline-block; vertical-align: middle; width: 3px; height: 3px; border-radius: 50%; background: #5b6b86; margin: 0 8px; }
.pv-when-st { color: var(--text-2); font-weight: 600; }
.pv-when-st.live { padding: 1px 8px; border-radius: 4px; background: var(--danger); color: #fff; font-size: 11.5px; letter-spacing: .04em; }
.pv-when-line > .pv-when-st.live + *::before { display: none; }
.pv-when-line > .pv-when-st.live + * { margin-left: 10px; }
.pv-ends { display: flex; align-items: center; gap: 8px; color: var(--muted); font-size: 13px; font-variant-numeric: tabular-nums; }
.pv-ends::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: var(--teal); flex: none; }
.pv-genres { display: flex; flex-wrap: wrap; gap: 6px; }
.pv-genre { padding: 2px 10px; border-radius: 999px; background: rgba(255, 255, 255, .06); border: 1px solid rgba(255, 255, 255, .1); font-size: 12px; color: #dbe3ef; }
.pv-facts { margin: 0; display: grid; gap: 6px; font-size: 13px; }
.pv-facts > div { display: grid; grid-template-columns: 70px minmax(0, 1fr); gap: 10px; }
.pv-facts dt { color: var(--muted); }
.pv-facts dd { margin: 0; color: #d3dcea; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
/* a series: the playing episode, then the ones still to come */
.pv-eps { display: grid; gap: 10px; padding-top: 14px; border-top: 1px solid var(--line); }
.pv-eps-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; font-size: 12.5px; }
.pv-ep-list { display: grid; gap: 4px; }
.pv-ep-season { color: var(--muted); font-size: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: .05em; padding: 10px 2px 2px; }
.pv-ep {
  display: grid; grid-template-columns: 124px minmax(0, 1fr); gap: 12px; align-items: center; width: calc(100% + 12px); padding: 6px; margin: 0 -6px;
  background: none; border: 0; border-radius: var(--radius); color: inherit; text-align: left; cursor: pointer;
}
.pv-ep:hover, .pv-ep:focus-visible, body.kbd .pv-ep:focus { background: var(--card); outline: none; }
body.kbd .pv-ep:focus, .pv-ep:focus-visible { box-shadow: var(--ring); }
.pv-ep.is-current { cursor: default; background: var(--teal-soft); }
.pv-ep-thumb { position: relative; display: block; aspect-ratio: 16 / 9; border-radius: .5rem; overflow: hidden; background: var(--card); }
.pv-ep-now { position: absolute; inset: 0; z-index: 2; display: flex; align-items: center; justify-content: center; gap: 5px; background: rgba(6, 12, 26, .55); color: #fff; font-size: 12px; font-weight: 600; }
.pv-ep-now .ico { width: 14px; height: 14px; color: var(--teal); }
.pv-ep-tick { position: absolute; top: 5px; right: 5px; z-index: 2; width: 20px; height: 20px; border-radius: 50%; display: grid; place-items: center; background: var(--teal); color: #062c5c; }
.pv-ep-tick .ico { width: 13px; height: 13px; stroke-width: 2.6; }
.pv-ep-text { display: grid; gap: 2px; min-width: 0; }
.pv-ep-code { color: var(--teal); font-size: 11.5px; font-weight: 600; letter-spacing: .03em; }
.pv-ep-title { font-size: 13.5px; font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pv-ep-meta { color: var(--muted); font-size: 12px; }
.pv-ep.is-watched .pv-ep-title { color: #b3c0d6; }
@media (max-width: 1099.98px) {
  /* under the video: the artwork is already above, keep the banner short */
  .pv-art { height: 120px; }
  .pv-id { margin-top: -56px; }
  .pv-poster { width: 80px; }
}
.show-phone { display: none; }

@media (max-width: 1099.98px) {
  .player-body { grid-template-columns: 1fr; grid-template-rows: auto 1fr; overflow-y: auto; }
  .player-stage { aspect-ratio: 16 / 9; max-height: 62vh; width: 100%; }
  .player-info { border-left: 0; border-top: 1px solid var(--line); padding-bottom: calc(18px + var(--sab)); }
}
@media (max-width: 991.98px) {
  .player-bar { height: 56px; padding: 0 6px; }
  .hide-phone { display: none; }
  .show-phone { display: flex; }
  .pb-logo { width: 34px; height: 34px; }
  .p-next-box { width: auto; }
  /* phones: the video is short, so the up-next card sits under it, not on it */
  .p-overlay { position: static; margin: 12px 12px 0; }
}
@media (orientation: landscape) and (max-height: 500px) {
  .player-bar { height: 48px; }
  .player-stage { max-height: none; height: calc(var(--dvh) - 48px - var(--sat)); aspect-ratio: auto; }
}

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

/* ------------------------------------------------------------------ Overcast blocks
   Standalone blocks like the panel's table rows and inputs: a solid surface,
   no border, rounded, the hard 3px bottom shadow. */
.card, .hint-card, .row, .note { border-color: transparent; box-shadow: var(--block-shadow); }
.pi-now { border-color: transparent; box-shadow: var(--block-shadow-in); }
.card-media { box-shadow: var(--block-shadow); }
.card-item:hover .card-media { box-shadow: var(--block-shadow), var(--shadow-lift); }
.card-item:focus-visible .card-media, body.kbd .card-item:focus .card-media { box-shadow: var(--ring); }
.card-media.sk { box-shadow: var(--block-shadow); }
.hf-body .card-media { box-shadow: var(--hf-edge); }
.hf-body .card-item:hover .card-media { box-shadow: var(--hf-edge), var(--shadow-lift); }
.input { border-color: transparent; box-shadow: var(--block-shadow-in); }
.input:focus { border-color: var(--teal); box-shadow: var(--block-shadow-in), 0 0 0 3px rgba(var(--teal-rgb), .22); }
.seg, .pin-key { border-color: transparent; box-shadow: var(--block-shadow-in); }

/* ------------------------------------------------------------------ scrollbars
   The admin panel's thin scrollbars (app.dark.css). WebKit/Blink only read
   these while no scroller sets the standard scrollbar-width/-color, so those
   are kept to Firefox, which has no ::-webkit-scrollbar. */
::-webkit-scrollbar { width: .35rem; height: .35rem; background-color: var(--scroll-track); }
::-webkit-scrollbar-thumb { -webkit-box-shadow: inset 0 0 .375rem rgba(0, 0, 0, .3); background-color: var(--scroll-thumb); border-radius: .5rem; }
@supports (-moz-appearance: none) {
  * { scrollbar-width: thin; scrollbar-color: var(--scroll-thumb) var(--scroll-track); }
  .chips, .rail { scrollbar-width: none; }
}
/* Keyboard / remote navigation (core/ui.js html.kbd-nav): scrollbars go
   transparent, keeping their width so nothing shifts, until the mouse moves. */
html.kbd-nav ::-webkit-scrollbar, html.kbd-nav ::-webkit-scrollbar-thumb { background-color: transparent; -webkit-box-shadow: none; }
@supports (-moz-appearance: none) {
  html.kbd-nav * { scrollbar-color: transparent transparent; }
}

/* ------------------------------------------------------------------ motion
   core/motion.js marks controls as they appear while a page enters; with
   body.motion off (Account > Animations, or the device default) none of this
   runs. Only translate / scale / opacity animate, through the individual
   transform properties so a control's own transform (hover lifts, the login
   wall's 3D tilt) is left alone. The easing overshoots slightly, like the
   release film's springs. */
@keyframes wp-rise { from { opacity: 0; translate: 0 22px; scale: .97; } }
@keyframes wp-slide { from { opacity: 0; translate: -20px 0; } }
@keyframes wp-settle { from { opacity: 0; scale: 1.06; } }
body.motion .wp-wait { opacity: 0; }
body.motion .wp-in { animation: wp-rise .6s cubic-bezier(.2, .9, .25, 1.04) var(--wp-d, 0ms) backwards; }
body.motion .wp-in.wp-x { animation-name: wp-slide; animation-duration: .5s; }
body.motion .wp-in.wp-fade { animation: wp-settle 1s cubic-bezier(.25, .8, .25, 1) var(--wp-d, 0ms) backwards; }
body.motion .wp-in.wp-quick { animation-duration: .35s; }
/* Sign-in: the card falls back and blurs as the wall rushes past... */
@keyframes wp-card-out { to { opacity: 0; scale: .9; filter: blur(6px); } }
@keyframes wp-wall-out { to { opacity: 0; scale: 1.25; } }
body.motion .wp-leave .login-card { animation: wp-card-out .5s cubic-bezier(.5, 0, .75, 0) forwards; }
body.motion.wp-leave .login-wall { animation: wp-wall-out .55s cubic-bezier(.5, 0, .75, 0) forwards; }
/* ...and after the reload Home zooms in from slightly large while the bars
   drop and lift into place (then its controls cascade in as above). */
@keyframes wp-zoom-in { from { opacity: 0; scale: 1.07; } }
@keyframes wp-drop { from { opacity: 0; translate: 0 -80px; } }
@keyframes wp-lift { from { opacity: 0; translate: 0 80px; } }
body.motion.wp-arrive .outlet { animation: wp-zoom-in .9s cubic-bezier(.2, .9, .25, 1) backwards; transform-origin: 50% 30%; }
body.motion.wp-arrive .topbar-in { animation: wp-drop .7s cubic-bezier(.2, .9, .25, 1.04) .05s backwards; }
body.motion.wp-arrive .tabbar-in { animation: wp-lift .7s cubic-bezier(.2, .9, .25, 1.04) .15s backwards; }
/* The player opening: the overlay fades in, the picture settles from slightly
   small, the bar drops in and the side panel's details rise in turn. Only
   while it opens (core/player.js: .wp-opening), as its info is redrawn. */
@keyframes wp-fade-in { from { opacity: 0; } }
@keyframes wp-stage-in { from { opacity: 0; scale: .94; } }
@keyframes wp-bar-in { from { opacity: 0; translate: 0 -24px; } }
body.motion .player.wp-opening { animation: wp-fade-in .3s ease-out; }
/* closing: the opening played backwards, quicker (core/player.js hides it after) */
@keyframes wp-fade-out { to { opacity: 0; } }
@keyframes wp-stage-out { to { opacity: 0; scale: .94; } }
@keyframes wp-bar-out { to { opacity: 0; translate: 0 -24px; } }
@keyframes wp-info-out { to { opacity: 0; translate: 0 22px; } }
body.motion .player.wp-closing { pointer-events: none; animation: wp-fade-out .3s ease-in .02s forwards; }
body.motion .player.wp-closing .player-bar { animation: wp-bar-out .26s ease-in forwards; }
body.motion .player.wp-closing .player-stage { animation: wp-stage-out .28s ease-in forwards; }
body.motion .player.wp-closing .player-info > * { animation: wp-info-out .24s ease-in forwards; }
body.motion .player.wp-opening .player-bar { animation: wp-bar-in .5s cubic-bezier(.2, .9, .25, 1.04) .05s backwards; }
body.motion .player.wp-opening .player-stage { animation: wp-stage-in .7s cubic-bezier(.2, .9, .25, 1.04) .08s backwards; }
body.motion .player.wp-opening .player-info > * { animation: wp-rise .6s cubic-bezier(.2, .9, .25, 1.04) calc(.2s + var(--wp-n, 0) * 60ms) backwards; }
.player-info > :nth-child(2) { --wp-n: 1; }
.player-info > :nth-child(3) { --wp-n: 2; }
.player-info > :nth-child(4) { --wp-n: 3; }
.player-info > :nth-child(5) { --wp-n: 4; }
.player-info > :nth-child(n+6) { --wp-n: 5; }

/* a card's menu (core/itemmenu.js): its picture, name, then its actions */
.item-menu { width: min(420px, calc(100vw - 32px)); }
.item-menu .modal-body { padding-top: 22px; }
.im { display: grid; gap: 14px; justify-items: center; text-align: center; }
.im-art { position: relative; display: block; width: 120px; aspect-ratio: 2 / 3; border-radius: var(--radius); overflow: hidden; background: var(--thumb-grad); box-shadow: var(--block-shadow); }
.im-wide .im-art { width: 240px; aspect-ratio: 16 / 9; }
.im-logo .im-art { width: 120px; aspect-ratio: 3 / 2; }
.im-logo .im-art .thumb.fit-contain img { padding: 10% 14%; }
.im-text { display: grid; gap: 4px; min-width: 0; max-width: 100%; }
.im-title { margin: 0; font-size: 18px; line-height: 1.3; }
.im-sub { margin: 0; color: var(--muted); font-size: 13.5px; }
.im-acts { display: grid; gap: 8px; width: 100%; }
.im-act { justify-content: flex-start; }
.im-act.on .ico { color: var(--teal); }
.im-act[data-value='"fav"'].on .ico { color: var(--warning); }
.item-menu .modal-actions { justify-content: stretch; }
.item-menu .modal-actions .btn { flex: 1; }
/* Mark as Watched on a movie's page */
.vd-watch { width: 52px; padding: 0; justify-content: center; }
.vd-watch.on { color: var(--teal); }
