soulsync/webui/static/video/video-side.css
BoulderBadgeDad 7e0726d5eb video Downloads page: smooth in-place updates (no more blink) + polish
The blink was every poll re-running each card's entrance animation via innerHTML
churn. Now cards are created ONCE and PATCHED in place (data-st attribute swaps,
progress width glides over a 1.4s transition, meta only rewrites when its text
changes), so nothing re-animates on a tick — the music-downloads smoothness.

Also: adaptive polling (1.5s while active, 6s idle), border/pill colours TRANSITION
on status change, downloading cards get an accent tint + glow, a relative 'started Xs
ago', and the % moved inline. Balance clean.
2026-06-19 15:10:04 -07:00

3378 lines
223 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* SoulSync — Video side shell styling.
*
* Loaded AFTER style.css so these rules win where specificity ties. Everything
* keys off body[data-side="music|video"] (set by video-side.js). The music side
* is the default and is never affected — these rules only do something once the
* body flips to data-side="video".
*/
/* ── The Music ↔ Video header toggle (animated sliding pill) ────────────── */
.side-toggle {
position: relative;
display: flex;
margin-top: 12px;
padding: 4px;
background: rgba(0, 0, 0, 0.28);
border: 1px solid rgba(255, 255, 255, 0.07);
border-radius: 11px;
box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.35);
isolation: isolate;
}
/* The thumb that slides under the active side. Positioned over the left half by
default; slides to the right half when body[data-side="video"]. */
.side-toggle-thumb {
position: absolute;
z-index: 0;
top: 4px;
bottom: 4px;
left: 4px;
width: calc(50% - 4px);
border-radius: 8px;
background: linear-gradient(135deg,
rgb(var(--accent-rgb, 88 101 242)),
rgba(var(--accent-rgb, 88 101 242), 0.82));
box-shadow: 0 3px 10px rgba(var(--accent-rgb, 88 101 242), 0.35);
transition: transform 0.28s cubic-bezier(0.34, 1.3, 0.5, 1);
}
body[data-side="video"] .side-toggle-thumb {
transform: translateX(100%);
}
.side-toggle-btn {
position: relative;
z-index: 1;
flex: 1;
display: flex;
align-items: center;
justify-content: center;
gap: 6px;
padding: 7px 6px;
font-size: 11.5px;
font-weight: 600;
letter-spacing: 0.02em;
color: var(--text-secondary, #9aa0aa);
background: transparent;
border: none;
border-radius: 8px;
cursor: pointer;
transition: color 0.2s ease;
}
.side-toggle-btn .side-toggle-icon {
width: 14px;
height: 14px;
flex: none;
opacity: 0.85;
transition: opacity 0.2s ease;
}
.side-toggle-btn:not(.active):hover {
color: var(--text-primary, #e8e8ea);
}
.side-toggle-btn.active {
color: #fff;
}
.side-toggle-btn.active .side-toggle-icon {
opacity: 1;
}
/* ── Nav swap: music nav vs video nav ──────────────────────────────────── */
/* The video nav reuses .sidebar-nav layout (same class) — only visibility
differs. Hidden by default (music side); shown when data-side="video". */
.video-nav {
display: none;
}
body[data-side="video"] nav.sidebar-nav:not(.video-nav) {
display: none;
}
body[data-side="video"] .video-nav {
display: flex;
}
/* ── Page visibility per side ──────────────────────────────────────────── */
/* Music pages hidden on the video side; video pages hidden on the music side.
The music router still controls .page.active among music pages; we just hide
the whole set while the video side is showing. */
body[data-side="music"] .page.video-page {
display: none !important;
}
body[data-side="video"] .page:not(.video-page) {
display: none !important;
}
body[data-side="video"] .page.video-page {
display: block;
}
/* ── Service status: not needed on the video side (for now) ─────────────── */
body[data-side="video"] .status-section {
display: none;
}
/* ── Shared pages: show the REAL music page on the video side ───────────── */
/* For now Settings is shown identically (no hiding of music-only bits yet).
The id selector + extra attribute outrank the blanket music-page hide rule. */
body[data-side="video"][data-video-page="video-settings"] #settings-page {
display: block !important;
}
body[data-side="video"][data-video-page="video-settings"] #video-page-host {
display: none !important;
}
/* Video-only additions inside the shared settings page (e.g. the Movies/TV
library mapping) — hidden on the music side. */
body[data-side="music"] [data-video-only] {
display: none !important;
}
/* Conversely, the music-library picker is irrelevant on the video side — hide
it there (the Movies/TV mapping is its replacement). */
body[data-side="video"] #plex-library-selector-container,
body[data-side="video"] #jellyfin-library-selector-container,
body[data-side="video"] #navidrome-folder-selector-container {
display: none !important;
}
/* Music-only settings sections (e.g. the music API services) are hidden on the
video side; their video counterparts carry data-video-only. */
body[data-side="video"] [data-music-only] {
display: none !important;
}
/* The whole Library tab is music-specific today (file-org templates, music
paths, post-processing, conversion, stats) — hide it all on the video side.
Future video library settings just need data-video-only to stay visible. */
body[data-side="video"] [data-stg="library"]:not([data-video-only]) {
display: none !important;
}
/* The video side has its OWN server section (Video Source above) and reuses the
shared Plex/Jellyfin credentials — so hide music's Server Connections group
entirely on the video side. Video never configures or selects the MUSIC server. */
body[data-side="video"] .settings-group[data-stg="connections"]:not([data-video-only]) {
display: none !important;
}
/* The Downloads tab is almost entirely music-specific (streaming sources, music
quality profile, retry logic). Hide EVERY music download element on the video
side — not just .settings-group, but also the quality-profile tile + the
collapsible section headers/bodies (#quality-profile-tile, .settings-section-*).
The video-only ones (folders, video source/hybrid, video quality) replace them.
The shared "Indexers & Downloaders" tab is NOT hidden — it's identical for both. */
body[data-side="video"] [data-stg="downloads"]:not([data-video-only]) {
display: none !important;
}
/* ── Dashboard header: match music, minus the sweep animation ──────────── */
/* The header reuses music's .dashboard-header markup/CSS for an identical look;
we only mute the ambient sweep on the video side (equiv may return later,
driven by meta sources). Scoped to data-side="video" so music is untouched. */
body[data-side="video"] .dashboard-header-sweep {
display: none;
}
/* ── Dashboard enrichment-worker buttons (isolated; music untouched) ────── */
.video-enrich-container { position: relative; }
/* Mirrors music's .musicbrainz-button accent treatment, driven by --ve-accent. */
.video-enrich-button {
position: relative;
width: 46px;
height: 46px;
border-radius: 50%;
border: 1.5px solid rgba(var(--ve-accent, 88, 101, 242), 0.25);
background: rgba(18, 18, 22, 0.85);
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
box-shadow: 0 4px 16px rgba(var(--ve-accent, 88, 101, 242), 0.2),
0 2px 8px rgba(0, 0, 0, 0.15), inset 0 1px 0 rgba(255, 255, 255, 0.08);
}
.video-enrich-button:hover {
transform: scale(1.05);
border-color: rgba(var(--ve-accent, 88, 101, 242), 0.4);
box-shadow: 0 6px 20px rgba(var(--ve-accent, 88, 101, 242), 0.3),
0 3px 12px rgba(0, 0, 0, 0.2), inset 0 1px 0 rgba(255, 255, 255, 0.12);
}
.video-enrich-button.active,
.video-enrich-button.complete {
border-color: rgba(var(--ve-accent, 88, 101, 242), 0.5);
box-shadow: 0 6px 24px rgba(var(--ve-accent, 88, 101, 242), 0.4),
0 3px 12px rgba(0, 0, 0, 0.2), inset 0 1px 0 rgba(255, 255, 255, 0.12);
}
/* Paused → amber accent, identical to music's .musicbrainz-button.paused. */
.video-enrich-button.paused {
background: linear-gradient(135deg, rgba(255, 193, 7, 0.12) 0%, rgba(255, 152, 0, 0.18) 100%);
border-color: rgba(255, 193, 7, 0.35);
box-shadow: 0 4px 16px rgba(255, 193, 7, 0.2),
0 2px 8px rgba(0, 0, 0, 0.15), inset 0 1px 0 rgba(255, 255, 255, 0.08);
}
.video-enrich-button.paused:hover {
border-color: rgba(255, 193, 7, 0.5);
box-shadow: 0 6px 20px rgba(255, 193, 7, 0.3), 0 3px 12px rgba(0, 0, 0, 0.2);
}
.video-enrich-button.disabled { opacity: 0.4; cursor: default; }
.video-enrich-logo {
width: 24px;
height: 24px;
object-fit: contain;
opacity: 0.85;
position: relative;
z-index: 1;
filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.3));
transition: opacity 0.3s ease;
}
.video-enrich-button:hover .video-enrich-logo { opacity: 1; }
/* The TVDB brand mark is dark — invert it so it reads on the dark UI. */
.video-enrich-button[data-video-enrich="tvdb"] .video-enrich-logo {
filter: invert(1) drop-shadow(0 2px 4px rgba(0, 0, 0, 0.3));
}
.video-enrich-spinner {
position: absolute;
width: 46px;
height: 46px;
border: 3px solid transparent;
border-top-color: rgba(var(--ve-accent, 88, 101, 242), 0.8);
border-right-color: rgba(var(--ve-accent, 88, 101, 242), 0.5);
border-radius: 50%;
opacity: 0;
transition: opacity 0.3s ease;
pointer-events: none;
}
.video-enrich-button.active .video-enrich-spinner { opacity: 1; animation: video-enrich-spin 1.2s linear infinite; }
@keyframes video-enrich-spin { to { transform: rotate(360deg); } }
/* Tint the reused .tooltip-content with the service accent (music's default is
MusicBrainz purple; each service overrides — so we do the same per video svc). */
.video-enrich-tooltip .tooltip-content {
border-color: rgba(var(--ve-accent, 88, 101, 242), 0.3);
box-shadow: 0 12px 40px rgba(0, 0, 0, 0.5),
0 6px 20px rgba(var(--ve-accent, 88, 101, 242), 0.25), inset 0 1px 0 rgba(255, 255, 255, 0.1);
}
.video-enrich-tooltip .tooltip-header { color: rgba(var(--ve-accent, 88, 101, 242), 0.95); }
.video-enrich-tooltip .tooltip-content::before { border-bottom-color: rgba(var(--ve-accent, 88, 101, 242), 0.3); }
.video-enrich-tooltip [data-video-enrich-status] { color: rgb(var(--ve-accent, 88, 101, 242)); font-weight: 600; }
/* Paused status text goes amber too, matching music. */
.video-enrich-button.paused ~ .video-enrich-tooltip [data-video-enrich-status] { color: #ffc107; }
/* Positioning wrapper only — the content reuses music's shared .tooltip-content
/ .tooltip-header / .tooltip-body styling, so it looks identical to the music
enrichment tooltips. */
.video-enrich-tooltip {
position: absolute;
left: 50%;
top: calc(100% + 12px);
transform: translateX(-50%) translateY(-5px);
z-index: 5000;
opacity: 0;
visibility: hidden;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
pointer-events: none;
}
.video-enrich-container:hover .video-enrich-tooltip {
opacity: 1;
visibility: visible;
transform: translateX(-50%) translateY(0);
}
/* The Manage Workers button reuses music's .em-manage-btn* classes verbatim
(see index.html), so it needs no styling of its own here — identical by reuse. */
/* Service logo in the settings API-config frame headers (TMDB/TVDB). */
.video-svc-logo { width: 18px; height: 18px; object-fit: contain; margin-right: 2px; }
.video-svc-logo--tvdb { filter: invert(1); }
/* ── Video Manage-Workers modal ─────────────────────────────────────────────
The modal now emits the music modal's exact markup (.em-hero / .em-row /
.em-icon / .em-btn / .em-pager / .em-card), so it inherits music's global
.em-* styling with no bespoke rules here. Live-status glows are further down;
the YouTube-dates panel (its own no-queue layout) keeps its .vem-yt-* block. */
/* ── Subpages: one built video page shown at a time ────────────────────── */
/* Each real page is a .video-subpage inside #video-page-host; the controller
toggles the [hidden] attribute. Be explicit so no reused .dash-* rule can
resurrect a hidden page. */
.video-subpage[hidden],
.video-placeholder-slot[hidden] {
display: none !important;
}
/* ── Placeholder content (for pages not built yet) ─────────────────────── */
.video-placeholder-slot {
padding: 48px 40px;
}
.video-placeholder-slot .header-title {
font-size: 22px;
font-weight: 700;
}
.video-placeholder-note {
margin-top: 10px;
color: var(--text-secondary, #9aa0aa);
font-size: 14px;
}
/* Empty-state line inside reused dashboard cards (e.g. Recent Downloads). */
.video-empty-note {
margin: 0;
padding: 8px 2px;
color: var(--text-secondary, #9aa0aa);
font-size: 14px;
}
/* ── Library page ──────────────────────────────────────────────────────── */
/* The grid/cards/search/alphabet all reuse the music library CSS verbatim.
The only video-specific bit is the Movies/Shows tab pill. */
.video-library-tabs {
display: flex;
gap: 6px;
padding: 4px;
margin: 0 auto 4px;
width: max-content;
background: rgba(0, 0, 0, 0.25);
border: 1px solid rgba(255, 255, 255, 0.07);
border-radius: 12px;
}
.video-lib-tab {
padding: 8px 22px;
font-size: 13px;
font-weight: 600;
color: var(--text-secondary, #9aa0aa);
background: transparent;
border: none;
border-radius: 9px;
cursor: pointer;
transition: background 0.15s ease, color 0.15s ease;
}
.video-lib-tab:hover { color: var(--text-primary, #e8e8ea); }
.video-lib-tab.active {
color: #fff;
background: rgb(var(--accent-rgb, 88 101 242));
}
.video-library-filters {
display: flex;
gap: 10px;
justify-content: center;
margin: 4px 0;
}
/* Resolution chip on a poster card (top-left, above the gradient overlay). */
.library-artist-card .video-card-badge {
position: absolute;
top: 8px;
left: 8px;
z-index: 3;
padding: 2px 7px;
font-size: 11px;
font-weight: 700;
letter-spacing: 0.02em;
color: #fff;
background: rgba(0, 0, 0, 0.7);
border: 1px solid rgba(255, 255, 255, 0.18);
border-radius: 5px;
backdrop-filter: blur(4px);
}
/* ════════════════════════════════════════════════════════════════════════════
Video detail page — NETFLIX style (isolated .vd-*; NOT the music layout).
--vd-accent-rgb is sampled from the poster at load for a per-show glow.
════════════════════════════════════════════════════════════════════════════ */
/* Break out of the host .page's 40px/90px padding so the billboard is truly
edge-to-edge (Netflix full-bleed) — no bare gaps around it. */
.vd-page { --vd-accent-rgb: var(--accent-rgb, 88, 101, 242); position: relative; margin: -40px -40px -90px; }
/* Sticky so it stays reachable on these long detail pages (negative bottom margin
pulls the billboard up under it, keeping the full-bleed overlay look). */
.vd-back {
position: sticky; top: 14px; z-index: 8; width: max-content;
margin: 0 0 -42px 22px;
display: inline-flex; align-items: center; gap: 7px;
padding: 8px 15px; border-radius: 999px;
background: rgba(0,0,0,0.55); border: 1px solid rgba(255,255,255,0.14);
color: #fff; font-size: 13px; font-weight: 600; cursor: pointer;
backdrop-filter: blur(10px); transition: background 0.2s ease, transform 0.2s ease;
}
.vd-back:hover { background: rgba(0,0,0,0.8); transform: translateX(-2px); }
.vd-back [data-vd-back-label] {
display: inline-block; max-width: 230px; overflow: hidden; text-overflow: ellipsis;
white-space: nowrap; vertical-align: bottom;
}
/* ── Billboard ─────────────────────────────────────────────────────────────── */
.vd-billboard { position: relative; width: 100%; min-height: 76vh; display: flex; align-items: flex-end; overflow: hidden; }
.vd-bb-bg {
position: absolute; inset: 0; background-size: cover; background-position: center 18%;
z-index: 0; transform: scale(1.02); animation: vdKenburns 24s ease-out forwards;
}
.vd-bb-bg--poster { background-position: center 28%; }
.vd-bb-bg--empty { background: radial-gradient(120% 90% at 70% 0%, rgba(var(--vd-accent-rgb), 0.4), #0b0b0f 65%); }
@keyframes vdKenburns { to { transform: scale(1.1); } }
.vd-bb-fade {
position: absolute; inset: 0; z-index: 1; pointer-events: none;
background:
linear-gradient(0deg, var(--bg-primary, #0b0b0f) 2%, rgba(11,11,15,0.55) 32%, rgba(11,11,15,0.1) 62%, rgba(11,11,15,0.45) 100%),
linear-gradient(90deg, rgba(11,11,15,0.92) 0%, rgba(11,11,15,0.55) 38%, transparent 72%);
}
.vd-bb-content {
position: relative; z-index: 2; max-width: 720px; padding: 0 0 52px 56px;
animation: vdRise 0.7s cubic-bezier(0.2, 0.7, 0.2, 1) both;
}
@keyframes vdRise { from { opacity: 0; transform: translateY(26px); } to { opacity: 1; transform: none; } }
.vd-title {
font-size: clamp(2.6em, 5vw, 4.4em); line-height: 0.98; font-weight: 900; margin: 0 0 18px;
color: #fff; letter-spacing: -0.02em; text-shadow: 0 4px 30px rgba(0,0,0,0.7);
}
.vd-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 14px; margin-bottom: 16px;
font-size: 14px; font-weight: 600; color: rgba(255,255,255,0.82); }
.vd-meta > span { position: relative; }
.vd-meta > span + span::before { content: ''; position: absolute; left: -8px; top: 50%; width: 3px; height: 3px;
border-radius: 50%; background: rgba(255,255,255,0.4); transform: translateY(-50%); }
.vd-match { color: #4ade80 !important; font-weight: 800; }
.vd-score { color: #fbbf24 !important; font-weight: 800; }
.vd-tagline { font-size: 16px; font-style: italic; color: rgba(255,255,255,0.7); margin: -8px 0 14px;
text-shadow: 0 2px 12px rgba(0,0,0,0.6); }
.vd-genres { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 16px; }
.vd-genre { padding: 5px 13px; border-radius: 999px; font-size: 12.5px; font-weight: 600;
color: rgba(255,255,255,0.85); background: rgba(255,255,255,0.08); border: 1px solid rgba(255,255,255,0.14);
backdrop-filter: blur(6px); }
.vd-meta-rating { padding: 1px 7px; border: 1px solid rgba(255,255,255,0.35); border-radius: 4px; font-size: 12px; }
/* Subtitle availability (OpenSubtitles backfill) — a labeled chip row of the
languages subtitles exist in. Cooler blue tint to read as "captions", distinct
from the neutral genre chips. */
.vd-subs { display: flex; flex-wrap: wrap; align-items: center; gap: 7px; margin-top: 12px; }
.vd-sub-label { display: inline-flex; align-items: center; gap: 6px; font-size: 11px; font-weight: 700;
letter-spacing: 0.08em; text-transform: uppercase; color: rgba(120,170,255,0.9); margin-right: 2px; }
.vd-sub-label::before { content: 'CC'; font: 700 9px/1.2 'JetBrains Mono', ui-monospace, monospace;
padding: 2px 4px; border-radius: 3px; background: rgba(120,170,255,0.18); border: 1px solid rgba(120,170,255,0.35); }
.vd-sub { padding: 4px 11px; border-radius: 999px; font-size: 12px; font-weight: 600;
color: rgba(200,220,255,0.92); background: rgba(120,170,255,0.1); border: 1px solid rgba(120,170,255,0.22); }
.vd-sub--more { color: rgba(255,255,255,0.55); background: rgba(255,255,255,0.06); border-color: rgba(255,255,255,0.12); }
.vd-status { color: rgb(var(--vd-accent-rgb)); }
.vd-overview { font-size: 16px; line-height: 1.6; color: rgba(255,255,255,0.86); margin: 0 0 22px; max-width: 640px;
text-shadow: 0 2px 12px rgba(0,0,0,0.6);
display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
/* Action buttons + source links reuse the music artist-detail classes verbatim
(.library-artist-watchlist-btn / .discog-download-btn / .artist-hero-badge);
only the billboard-specific bits live here. */
.vd-actions { margin-bottom: 16px; }
.vd-links { margin-bottom: 16px; }
.vd-links .artist-hero-badge[title="TVDB"] img { filter: invert(1); }
.vd-loading { padding: 50px 0; text-align: center; color: rgba(255,255,255,0.55); }
/* ── Episodes ──────────────────────────────────────────────────────────────── */
.vd-body { padding: 30px 56px 70px; }
.vd-ep-toolbar { display: flex; align-items: center; justify-content: space-between; margin-bottom: 20px; }
.vd-ep-heading { font-size: 22px; font-weight: 800; color: #fff; margin: 0; }
.vd-toolbar-right { display: flex; align-items: center; gap: 12px; }
.vd-missing-toggle {
padding: 8px 14px; border-radius: 8px; cursor: pointer; font-size: 12.5px; font-weight: 700;
background: rgba(255,255,255,0.06); border: 1px solid rgba(255,255,255,0.14); color: rgba(255,255,255,0.8);
transition: all 0.2s ease;
}
.vd-missing-toggle:hover { background: rgba(255,255,255,0.1); }
.vd-missing-toggle--on { background: rgba(var(--vd-accent-rgb), 0.22); border-color: rgba(var(--vd-accent-rgb), 0.6); color: #fff; }
/* view toggle (rail / timeline / pills / dropdown) */
.vd-view-toggle { display: inline-flex; gap: 2px; padding: 3px; border-radius: 9px;
background: rgba(255,255,255,0.05); border: 1px solid rgba(255,255,255,0.1); }
.vd-vt-btn { width: 34px; height: 30px; border: 0; border-radius: 6px; background: transparent; cursor: pointer;
color: rgba(255,255,255,0.55); font-size: 14px; transition: all 0.18s ease; }
.vd-vt-btn:hover { background: rgba(255,255,255,0.08); color: #fff; }
.vd-vt-btn--active { background: rgba(var(--vd-accent-rgb), 0.85); color: #fff; box-shadow: 0 2px 10px rgba(var(--vd-accent-rgb), 0.4); }
.vd-season-nav { margin-bottom: 26px; }
.vd-season-nav:empty { margin: 0; }
/* — rail — */
.vd-rail { display: flex; gap: 14px; overflow-x: auto; padding: 6px 2px 14px; scroll-snap-type: x proximity; }
.vd-rail::-webkit-scrollbar { height: 8px; }
.vd-rail::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.15); border-radius: 4px; }
.vd-rcard { flex: 0 0 150px; width: 150px; text-align: left; padding: 0; cursor: pointer; scroll-snap-align: start;
border-radius: 12px; overflow: hidden; background: rgba(18,18,22,1); border: 1px solid rgba(255,255,255,0.07);
box-shadow: 0 4px 16px rgba(0,0,0,0.3); transition: transform 0.3s cubic-bezier(0.4,0,0.2,1), box-shadow 0.3s ease, border-color 0.3s ease; }
.vd-rcard:hover { transform: translateY(-5px); border-color: rgba(var(--vd-accent-rgb), 0.3);
box-shadow: 0 12px 36px rgba(0,0,0,0.5), 0 0 22px rgba(var(--vd-accent-rgb), 0.16); }
.vd-rcard--active { border-color: rgba(var(--vd-accent-rgb), 0.7); box-shadow: 0 12px 36px rgba(0,0,0,0.5), 0 0 26px rgba(var(--vd-accent-rgb), 0.32); }
.vd-rcard-art { position: relative; aspect-ratio: 2/3; overflow: hidden;
background: linear-gradient(135deg, rgba(var(--vd-accent-rgb), 0.2), rgba(var(--vd-accent-rgb), 0.05)); }
.vd-rcard-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.vd-rcard-fb { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; font-size: 36px; opacity: 0.32; }
.vd-rcard-grad { position: absolute; inset: 0; background: linear-gradient(180deg, transparent 50%, rgba(10,10,14,0.85)); }
.vd-rcard-pct { position: absolute; top: 7px; right: 7px; padding: 2px 8px; border-radius: 999px; font-size: 11px; font-weight: 800;
color: #fff; background: rgba(0,0,0,0.55); backdrop-filter: blur(4px); }
.vd-rcard-info { padding: 10px 12px 12px; display: flex; flex-direction: column; gap: 5px; }
.vd-rcard-name { font-size: 13.5px; font-weight: 700; color: #fff; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.vd-rcard-sub { font-size: 11.5px; color: rgba(255,255,255,0.55); }
.vd-rcard-bar { height: 5px; border-radius: 999px; background: rgba(255,255,255,0.1); overflow: hidden; }
.vd-rcard-bar > span { display: block; height: 100%; border-radius: 999px;
background: linear-gradient(90deg, rgb(var(--vd-accent-rgb)), rgba(var(--vd-accent-rgb), 0.5)); }
/* — timeline — */
.vd-timeline { display: flex; gap: 6px; align-items: stretch; }
.vd-tseg { position: relative; min-width: 84px; height: 76px; padding: 0; cursor: pointer; overflow: hidden;
border-radius: 10px; border: 1px solid rgba(255,255,255,0.1); background: rgba(255,255,255,0.04);
transition: all 0.25s ease; }
.vd-tseg:hover { border-color: rgba(var(--vd-accent-rgb), 0.45); transform: translateY(-2px); }
.vd-tseg--active { border-color: rgba(var(--vd-accent-rgb), 0.75); box-shadow: 0 6px 22px rgba(var(--vd-accent-rgb), 0.28); }
.vd-tseg-fill { position: absolute; left: 0; bottom: 0; top: 0; border-radius: 9px 0 0 9px;
background: linear-gradient(180deg, rgba(var(--vd-accent-rgb), 0.45), rgba(var(--vd-accent-rgb), 0.18)); }
.vd-tseg-label { position: relative; z-index: 1; display: flex; flex-direction: column; gap: 3px; padding: 12px 14px; height: 100%; justify-content: center; }
.vd-tseg-name { font-size: 14px; font-weight: 700; color: #fff; white-space: nowrap; }
.vd-tseg-meta { font-size: 12px; color: rgba(255,255,255,0.7); }
/* — pills — */
.vd-pills { display: flex; flex-wrap: wrap; gap: 9px; }
.vd-pill-btn { display: inline-flex; align-items: center; gap: 9px; padding: 9px 16px; border-radius: 999px; cursor: pointer;
background: rgba(255,255,255,0.05); border: 1px solid rgba(255,255,255,0.14); color: rgba(255,255,255,0.82);
font-size: 13.5px; font-weight: 700; transition: all 0.2s ease; }
.vd-pill-btn:hover { background: rgba(255,255,255,0.1); border-color: rgba(var(--vd-accent-rgb), 0.4); }
.vd-pill-btn--active { background: rgba(var(--vd-accent-rgb), 0.9); border-color: transparent; color: #fff;
box-shadow: 0 4px 16px rgba(var(--vd-accent-rgb), 0.4); }
.vd-pill-meta { font-size: 11.5px; opacity: 0.8; }
.vd-pill-btn--active .vd-pill-meta { opacity: 0.95; }
.vd-ep-empty { padding: 40px 0; text-align: center; color: rgba(255,255,255,0.5); }
/* season dropdown */
.vd-season-select { position: relative; display: inline-block; }
.vd-ss-btn {
display: inline-flex; align-items: center; gap: 12px; padding: 10px 16px; min-width: 150px;
justify-content: space-between; border-radius: 8px; cursor: pointer;
background: rgba(255,255,255,0.06); border: 1px solid rgba(255,255,255,0.16);
color: #fff; font-size: 14px; font-weight: 700; transition: all 0.2s ease;
}
.vd-ss-btn:hover { background: rgba(255,255,255,0.1); border-color: rgba(var(--vd-accent-rgb), 0.5); }
.vd-ss-caret { font-size: 11px; opacity: 0.7; }
.vd-ss-menu {
position: absolute; top: calc(100% + 8px); right: 0; min-width: 220px; z-index: 20;
background: rgba(20,20,26,0.98); border: 1px solid rgba(255,255,255,0.12); border-radius: 10px;
box-shadow: 0 16px 44px rgba(0,0,0,0.6); padding: 6px; overflow: hidden;
opacity: 0; transform: translateY(-8px) scale(0.98); pointer-events: none;
transition: opacity 0.2s ease, transform 0.2s ease;
}
.vd-ss-menu--open { opacity: 1; transform: none; pointer-events: auto; }
.vd-ss-opt {
width: 100%; display: flex; align-items: center; justify-content: space-between; gap: 14px;
padding: 10px 13px; border-radius: 7px; cursor: pointer; background: transparent; border: 0;
color: rgba(255,255,255,0.85); font-size: 14px; font-weight: 600; text-align: left; transition: background 0.15s ease;
}
.vd-ss-opt:hover { background: rgba(255,255,255,0.07); }
.vd-ss-opt--active { color: #fff; background: rgba(var(--vd-accent-rgb), 0.2); }
.vd-ss-opt-meta { font-size: 12px; color: rgba(255,255,255,0.5); }
/* episode rows */
.vd-episodes { border-top: 1px solid rgba(255,255,255,0.08); }
.vd-ep-anim .vd-ep { animation: vdEpIn 0.4s cubic-bezier(0.2,0.7,0.2,1) both; }
.vd-ep-anim .vd-ep:nth-child(2) { animation-delay: 0.03s; }
.vd-ep-anim .vd-ep:nth-child(3) { animation-delay: 0.06s; }
.vd-ep-anim .vd-ep:nth-child(4) { animation-delay: 0.09s; }
.vd-ep-anim .vd-ep:nth-child(n+5) { animation-delay: 0.12s; }
@keyframes vdEpIn { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: none; } }
.vd-ep {
display: grid; grid-template-columns: 48px 150px 1fr auto auto; align-items: center; gap: 20px;
padding: 18px 14px; border-bottom: 1px solid rgba(255,255,255,0.06);
transition: background 0.2s ease; cursor: pointer;
}
.vd-ep-chev { color: rgba(255,255,255,0.35); font-size: 16px; transition: transform 0.25s ease, color 0.2s ease; }
.vd-ep:hover .vd-ep-chev { color: rgba(255,255,255,0.7); }
.vd-ep--open .vd-ep-chev { transform: rotate(180deg); color: rgb(var(--vd-accent-rgb)); }
.vd-ep:hover { background: rgba(255,255,255,0.04); }
.vd-ep-index { font-size: 22px; font-weight: 800; color: rgba(255,255,255,0.4); text-align: center; }
.vd-ep:hover .vd-ep-index { color: rgb(var(--vd-accent-rgb)); }
.vd-ep-thumb {
position: relative; width: 150px; aspect-ratio: 16 / 9; border-radius: 8px; overflow: hidden;
background: linear-gradient(135deg, rgba(var(--vd-accent-rgb), 0.28), rgba(0,0,0,0.5));
display: flex; align-items: center; justify-content: center;
box-shadow: 0 4px 14px rgba(0,0,0,0.4);
}
.vd-ep-still { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.vd-ep-thumb-ic { position: relative; z-index: 1; font-size: 20px; color: #fff; opacity: 0; transform: scale(0.7);
transition: all 0.25s ease; text-shadow: 0 2px 10px rgba(0,0,0,0.7); }
.vd-ep:hover .vd-ep-thumb-ic { opacity: 1; transform: scale(1); }
.vd-ep:hover .vd-ep-still { filter: brightness(0.7); transition: filter 0.25s ease; }
/* YouTube duration badge — bottom-right of the thumb (like the real player) */
.vd-ep-dur {
position: absolute; z-index: 2; right: 5px; bottom: 5px;
padding: 1px 5px; border-radius: 4px; font-size: 11px; font-weight: 700; line-height: 1.4;
color: #fff; background: rgba(0, 0, 0, 0.82); letter-spacing: 0.02em;
}
/* YouTube video thumbnails are play buttons (stream in-app via the embed overlay) */
.vd-ep-thumb--play, .vd-yt-plvid-thumb { cursor: pointer; }
.vd-ep-thumb--play .vd-ep-thumb-ic { opacity: 0.92; transform: scale(1); } /* always show the play hint */
.vd-ep-thumb--play:hover .vd-ep-thumb-ic { opacity: 1; transform: scale(1.15); }
/* Channel search + sort controls (above the year pills) */
.vd-season-nav--yt { display: flex; flex-direction: column; gap: 14px; }
.vd-yt-controls { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.vd-yt-search { position: relative; flex: 1 1 240px; min-width: 200px; }
.vd-yt-search-ic { position: absolute; left: 12px; top: 50%; transform: translateY(-50%);
font-size: 15px; color: rgba(255, 255, 255, 0.4); pointer-events: none; }
.vd-yt-search-in {
width: 100%; padding: 9px 12px 9px 34px; border-radius: 10px;
background: rgba(255, 255, 255, 0.06); border: 1px solid rgba(255, 255, 255, 0.12);
color: #fff; font-size: 13.5px;
}
.vd-yt-search-in:focus { outline: none; border-color: rgba(var(--vd-accent-rgb, 255 59 59), 0.6);
background: rgba(255, 255, 255, 0.09); }
.vd-yt-sort {
padding: 9px 12px; border-radius: 10px; background: rgba(255, 255, 255, 0.06);
border: 1px solid rgba(255, 255, 255, 0.12); color: #fff; font-size: 13px; font-weight: 600; cursor: pointer;
}
.vd-yt-sort:focus { outline: none; border-color: rgba(var(--vd-accent-rgb, 255 59 59), 0.6); }
.vd-ep-info { min-width: 0; }
.vd-ep-top { display: flex; align-items: baseline; gap: 12px; margin-bottom: 5px; }
.vd-ep-title { font-size: 15.5px; font-weight: 700; color: #fff; }
.vd-ep-rt { font-size: 12.5px; color: rgba(255,255,255,0.5); white-space: nowrap; }
.vd-ep-desc { margin: 0; font-size: 13.5px; line-height: 1.5; color: rgba(255,255,255,0.62);
display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.vd-ep-badge { font-size: 11px; font-weight: 800; text-transform: uppercase; letter-spacing: 0.6px;
padding: 5px 12px; border-radius: 999px; white-space: nowrap; }
.vd-ep--owned .vd-ep-badge { color: #4ade80; background: rgba(74,222,128,0.12); border: 1px solid rgba(74,222,128,0.32); }
.vd-ep--missing .vd-ep-badge { color: rgba(255,255,255,0.5); background: rgba(255,255,255,0.05); border: 1px solid rgba(255,255,255,0.12); }
.vd-ep--missing .vd-ep-index, .vd-ep--missing .vd-ep-title { opacity: 0.7; }
@media (max-width: 820px) {
.vd-bb-content { padding-left: 24px; }
.vd-body { padding: 24px 22px 60px; }
.vd-ep { grid-template-columns: 36px 1fr auto; }
.vd-ep-thumb { display: none; }
}
.video-card--clickable { cursor: pointer; }
/* ── Manage-Workers modal: live status + glow (scoped to #vem-overlay; the
music modal's shared .em-* styles are never touched). ───────────────────── */
#vem-overlay .em-dot--running { animation: vemDotPulse 1.5s ease-in-out infinite; }
@keyframes vemDotPulse {
0%, 100% { box-shadow: 0 0 8px #1db954; }
50% { box-shadow: 0 0 16px 3px #1db954; }
}
/* The selected worker's rail row carries a live accent glow. */
#vem-overlay .em-worker-row.active {
box-shadow: inset 0 0 0 1px rgba(var(--row-accent), 0.45),
0 0 22px rgba(var(--row-accent), 0.20);
}
/* Active "Process first" / kind selection glow in the worker accent. */
#vem-overlay .em-global-tabs button.active,
#vem-overlay .em-card--current {
box-shadow: 0 0 18px rgba(var(--em-accent-rgb), 0.28);
}
/* ── Cast & crew section (detail page) ───────────────────────────────────── */
.vd-cast-section { margin-top: 46px; }
.vd-section-h { font-size: 22px; font-weight: 800; color: #fff; margin: 0 0 16px; }
.vd-crew { display: flex; flex-wrap: wrap; gap: 8px 24px; margin-bottom: 24px;
color: rgba(255, 255, 255, 0.72); font-size: 14px; }
.vd-crew-job { color: rgba(255, 255, 255, 0.45); font-weight: 600; }
.vd-cast { display: flex; gap: 18px; overflow-x: auto; padding-bottom: 12px; scroll-snap-type: x proximity; }
.vd-cast::-webkit-scrollbar { height: 8px; }
.vd-cast::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, 0.15); border-radius: 4px; }
.vd-cast-card { flex: 0 0 116px; width: 116px; scroll-snap-align: start; text-align: center; }
.vd-cast-photo {
width: 116px; height: 116px; border-radius: 50%; object-fit: cover; display: block; margin: 0 auto 10px;
box-shadow: 0 6px 18px rgba(0, 0, 0, 0.45); border: 2px solid rgba(255, 255, 255, 0.08);
transition: transform 0.25s ease, border-color 0.25s ease;
}
.vd-cast-photo--ph {
display: flex; align-items: center; justify-content: center; font-size: 40px; font-weight: 800;
color: rgba(255, 255, 255, 0.55);
background: linear-gradient(135deg, rgba(var(--vd-accent-rgb), 0.32), rgba(var(--vd-accent-rgb), 0.1));
}
.vd-cast-card:hover .vd-cast-photo { transform: translateY(-3px); border-color: rgba(var(--vd-accent-rgb), 0.6); }
.vd-cast-name { display: block; font-size: 13.5px; font-weight: 700; color: #fff; line-height: 1.3;
white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.vd-cast-char { display: block; font-size: 12px; color: rgba(255, 255, 255, 0.55); line-height: 1.3;
white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* ── Movie detail: details strip ─────────────────────────────────────────── */
.vd-details { margin-bottom: 8px; }
.vd-detail-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 14px 28px; max-width: 760px; }
.vd-detail-row { display: flex; flex-direction: column; gap: 3px; }
.vd-detail-k { font-size: 11px; text-transform: uppercase; letter-spacing: 0.6px; color: rgba(255, 255, 255, 0.45); }
.vd-detail-v { font-size: 14.5px; font-weight: 600; color: #fff; }
/* ── Clearlogo title (replaces the text title when available) ─────────────── */
.vd-logo {
display: block; max-width: min(440px, 60%); max-height: 150px; width: auto; height: auto;
margin: 0 0 16px; object-fit: contain; object-position: left bottom;
filter: drop-shadow(0 4px 24px rgba(0, 0, 0, 0.7));
animation: vdRise 0.7s cubic-bezier(0.2, 0.7, 0.2, 1) both;
}
/* Keep the title for screen readers, but hide it visually when the logo shows. */
.vd-title--logo {
position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}
/* ── Detail extras: trailer button, providers, More Like This, trailer modal ── */
.vd-trailer-btn {
display: inline-flex; align-items: center; gap: 8px; padding: 7px 18px; border-radius: 8px;
font-size: 12.5px; font-weight: 800; letter-spacing: 0.02em; cursor: pointer;
color: #fff; background: rgb(var(--vd-accent-rgb)); border: 1px solid transparent;
box-shadow: 0 6px 18px rgba(var(--vd-accent-rgb), 0.4); transition: all 0.2s ease;
}
.vd-trailer-btn:hover { transform: translateY(-1px); filter: brightness(1.08);
box-shadow: 0 8px 22px rgba(var(--vd-accent-rgb), 0.55); }
.vd-trailer-ic { font-size: 12px; }
.vd-providers-section, .vd-similar-section, .vd-collection-section { margin-top: 40px; }
.vd-sim-year { display: block; font-size: 11px; color: rgba(255, 255, 255, 0.45); margin-top: 2px; }
.vd-providers { display: flex; flex-wrap: wrap; gap: 14px; }
.vd-prov { display: flex; flex-direction: column; align-items: center; gap: 7px; width: 78px; text-align: center; }
.vd-prov img, .vd-prov-ph {
width: 56px; height: 56px; border-radius: 14px; object-fit: cover;
box-shadow: 0 4px 14px rgba(0, 0, 0, 0.4); border: 1px solid rgba(255, 255, 255, 0.1);
}
.vd-prov-ph { display: flex; align-items: center; justify-content: center; font-size: 24px; font-weight: 800;
color: #fff; background: linear-gradient(135deg, rgba(var(--vd-accent-rgb), 0.4), rgba(var(--vd-accent-rgb), 0.1)); }
.vd-prov-name { font-size: 11.5px; color: rgba(255, 255, 255, 0.7); line-height: 1.25;
overflow: hidden; text-overflow: ellipsis; }
/* Clickable provider / server tiles (anchors). */
a.vd-prov { text-decoration: none; color: inherit; cursor: pointer; transition: transform 0.2s ease; }
a.vd-prov:hover { transform: translateY(-4px); }
a.vd-prov:hover .vd-prov-name { color: #fff; }
a.vd-prov:hover img, a.vd-prov:hover .vd-prov-ph { border-color: rgba(var(--vd-accent-rgb), 0.6); }
/* "Play on your server" tile — leads the row, glows green like the owned ribbon. */
.vd-prov--server .vd-prov-play {
background: linear-gradient(135deg, #22c55e, #15803d); color: #fff; font-size: 22px;
box-shadow: 0 6px 18px rgba(34, 197, 94, 0.45); border-color: rgba(255, 255, 255, 0.2);
}
/* The actual Plex/Jellyfin logo on a dark tile with a green "you own it" glow. */
.vd-prov--server .vd-prov-server-logo {
background: rgba(10, 12, 16, 0.9); padding: 11px;
box-shadow: 0 6px 18px rgba(34, 197, 94, 0.42); border-color: rgba(34, 197, 94, 0.55);
}
.vd-prov-server-logo img {
width: 100%; height: 100%; object-fit: contain;
border: 0; border-radius: 0; box-shadow: none;
}
.vd-prov--server .vd-prov-name { color: #6ee7a0; font-weight: 700; }
/* streaming providers are informational badges (no per-provider link exists) */
.vd-prov--badge { cursor: default; }
/* the single real "where to watch" link (JustWatch/TMDB aggregate page) */
.vd-prov--more .vd-prov-more-ic {
display: flex; align-items: center; justify-content: center; font-size: 24px; font-weight: 800;
color: rgb(var(--vd-accent-rgb)); background: rgba(var(--vd-accent-rgb), 0.16);
border-color: rgba(var(--vd-accent-rgb), 0.4);
}
.vd-prov--more .vd-prov-name { color: rgb(var(--vd-accent-rgb)); font-weight: 700; }
.vd-similar { display: flex; gap: 16px; overflow-x: auto; padding-bottom: 12px; scroll-snap-type: x proximity; }
.vd-similar::-webkit-scrollbar { height: 8px; }
.vd-similar::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, 0.15); border-radius: 4px; }
.vd-sim-card { flex: 0 0 130px; width: 130px; scroll-snap-align: start; text-decoration: none; color: inherit;
transition: transform 0.25s ease; }
.vd-sim-card:hover { transform: translateY(-4px); }
.vd-sim-poster { width: 130px; aspect-ratio: 2/3; border-radius: 10px; object-fit: cover; display: block; margin-bottom: 8px;
box-shadow: 0 6px 18px rgba(0, 0, 0, 0.45); border: 1px solid rgba(255, 255, 255, 0.08); }
.vd-sim-poster--ph { display: flex; align-items: center; justify-content: center; font-size: 34px;
background: linear-gradient(135deg, rgba(var(--vd-accent-rgb), 0.28), rgba(0, 0, 0, 0.5)); }
.vd-sim-title { display: block; font-size: 12.5px; font-weight: 600; color: rgba(255, 255, 255, 0.85); line-height: 1.3;
display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.vd-trailer-overlay {
position: fixed; inset: 0; z-index: 9000; display: none; align-items: center; justify-content: center;
background: rgba(0, 0, 0, 0.85); backdrop-filter: blur(6px);
}
.vd-trailer-overlay--open { display: flex; animation: vdFade 0.2s ease both; }
@keyframes vdFade { from { opacity: 0; } to { opacity: 1; } }
.vd-trailer-box { position: relative; width: min(1100px, 92vw); aspect-ratio: 16/9;
border-radius: 12px; overflow: hidden; box-shadow: 0 24px 80px rgba(0, 0, 0, 0.7); }
.vd-trailer-box iframe { width: 100%; height: 100%; border: 0; display: block; }
.vd-trailer-close {
position: absolute; top: -44px; right: 0; width: 36px; height: 36px; border-radius: 50%;
background: rgba(255, 255, 255, 0.12); border: 1px solid rgba(255, 255, 255, 0.2); color: #fff;
font-size: 22px; line-height: 1; cursor: pointer; transition: background 0.2s ease;
}
.vd-trailer-close:hover { background: rgba(255, 255, 255, 0.25); }
/* ── Rating badges (IMDb / Rotten Tomatoes / Metacritic, via OMDb) ────────── */
.vd-ratings { display: flex; flex-wrap: wrap; gap: 10px; margin: -4px 0 16px; }
.vd-rt {
display: inline-flex; align-items: center; gap: 7px; padding: 5px 12px; border-radius: 8px;
font-size: 14px; font-weight: 800; color: #fff; background: rgba(0, 0, 0, 0.4);
border: 1px solid rgba(255, 255, 255, 0.12); backdrop-filter: blur(6px);
}
.vd-rt-tag { font-size: 11px; font-weight: 900; padding: 1px 5px; border-radius: 4px; letter-spacing: 0.02em; }
.vd-rt-ic { font-size: 15px; line-height: 1; }
.vd-rt--imdb .vd-rt-tag { background: #f5c518; color: #000; }
.vd-rt--rt { }
.vd-rt--mc .vd-rt-tag { background: #fff; color: #000; }
.vd-rt--mc-good .vd-rt-tag { background: #6c3; color: #000; }
.vd-rt--mc-mid .vd-rt-tag { background: #fc3; color: #000; }
.vd-rt--mc-bad .vd-rt-tag { background: #f00; color: #fff; }
.vd-rt--trakt .vd-rt-tag { background: #ed1c24; color: #fff; }
.vd-rt--tvmaze .vd-rt-tag { background: #3dd6c0; color: #00211d; }
.vd-rt--anilist .vd-rt-tag { background: #02a9ff; color: #fff; }
/* DeArrow crowd title (YouTube video expand panel) */
.vd-dearrow { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; font-weight: 600; color: #cfe0ff; }
.vd-dearrow-tag { font-size: 10px; font-weight: 900; letter-spacing: 0.04em; padding: 2px 6px; border-radius: 4px;
background: #1f77ce; color: #fff; }
/* ── OMDb worker uses a ★ glyph (no clean brand logo) ─────────────────────── */
.video-enrich-glyph {
position: relative; z-index: 1; font-size: 22px; line-height: 1;
color: rgb(var(--ve-accent, 245, 197, 24));
filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.4)); transition: transform 0.3s ease;
}
.video-enrich-button:hover .video-enrich-glyph { transform: scale(1.1); }
/* ══════════════════════════════════════════════════════════════════════════
In-app SEARCH + PERSON pages — cinematic, Netflix-grade (isolated, video).
Shares the detail page's language: --vd-accent-rgb glow, full-bleed feel,
poster cards with hover lift + gradient overlay, rise/fade entrances.
════════════════════════════════════════════════════════════════════════ */
/* ── shared poster/portrait card (search results + filmography) ───────────── */
.vsr-grid {
display: grid; grid-template-columns: repeat(auto-fill, minmax(168px, 1fr));
gap: 22px 20px;
}
.vsr-card {
position: relative; display: flex; flex-direction: column; text-decoration: none;
color: inherit; cursor: pointer; border-radius: 14px;
animation: vsr-pop 0.45s cubic-bezier(0.2, 0.7, 0.2, 1) both;
}
@keyframes vsr-pop { from { opacity: 0; transform: translateY(14px) scale(0.97); } to { opacity: 1; transform: none; } }
.vsr-poster {
position: relative; aspect-ratio: 2 / 3; border-radius: 14px; overflow: hidden;
background: linear-gradient(145deg, rgba(var(--vd-accent-rgb), 0.22), rgba(8, 8, 12, 0.9));
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.45);
border: 1px solid rgba(255, 255, 255, 0.06);
transition: transform 0.32s cubic-bezier(0.2, 0.7, 0.2, 1), box-shadow 0.32s ease, border-color 0.32s ease;
}
.vsr-poster img { width: 100%; height: 100%; object-fit: cover; display: block;
transition: transform 0.5s cubic-bezier(0.2, 0.7, 0.2, 1); }
.vsr-poster .library-artist-image-fallback,
.vsr-poster-ph {
width: 100%; height: 100%; display: flex; align-items: center; justify-content: center;
font-size: 46px; color: rgba(255, 255, 255, 0.4);
}
.vsr-card:hover .vsr-poster {
transform: translateY(-8px);
border-color: rgba(var(--vd-accent-rgb), 0.55);
box-shadow: 0 20px 46px rgba(0, 0, 0, 0.6), 0 0 30px rgba(var(--vd-accent-rgb), 0.32);
}
.vsr-card:hover .vsr-poster img { transform: scale(1.08); }
/* gradient + hover affordance */
.vsr-poster::after {
content: ''; position: absolute; inset: 0; pointer-events: none; opacity: 0;
background: linear-gradient(0deg, rgba(0, 0, 0, 0.55) 0%, transparent 45%);
transition: opacity 0.3s ease;
}
.vsr-card:hover .vsr-poster::after { opacity: 1; }
/* hover affordance = "view details" (an info badge), NOT a play button */
.vsr-peek {
position: absolute; left: 50%; top: 50%; z-index: 3;
width: 44px; height: 44px; border-radius: 50%; display: flex; align-items: center; justify-content: center;
background: rgba(var(--vd-accent-rgb), 0.92); color: #fff;
font-family: Georgia, 'Times New Roman', serif; font-style: italic; font-weight: 700; font-size: 22px;
transform: translate(-50%, -50%) scale(0.5); opacity: 0;
box-shadow: 0 6px 20px rgba(var(--vd-accent-rgb), 0.5);
transition: transform 0.3s cubic-bezier(0.2, 0.9, 0.3, 1.4), opacity 0.25s ease;
}
.vsr-card:hover .vsr-peek { transform: translate(-50%, -50%) scale(1); opacity: 1; }
/* ribbon + rating chips */
.vsr-ribbon {
position: absolute; top: 10px; left: 10px; z-index: 2;
font-size: 10px; font-weight: 800; letter-spacing: 0.5px; text-transform: uppercase;
padding: 4px 9px; border-radius: 7px; color: #fff;
backdrop-filter: blur(8px); box-shadow: 0 3px 12px rgba(0, 0, 0, 0.5);
}
.vsr-ribbon--owned { background: rgba(34, 197, 94, 0.95); }
.vsr-ribbon--preview { background: rgba(255, 255, 255, 0.16); border: 1px solid rgba(255, 255, 255, 0.28); }
.vsr-rating {
position: absolute; top: 10px; right: 10px; z-index: 2;
display: inline-flex; align-items: center; gap: 3px;
font-size: 11.5px; font-weight: 800; color: #fde68a;
padding: 3px 8px; border-radius: 7px; background: rgba(0, 0, 0, 0.62); backdrop-filter: blur(6px);
}
.vsr-info { padding: 11px 4px 0; min-width: 0; }
.vsr-info--center { text-align: center; }
.vsr-name {
display: block; font-size: 14px; font-weight: 700; color: #fff; line-height: 1.3;
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
transition: color 0.2s ease;
}
.vsr-card:hover .vsr-name { color: rgb(var(--vd-accent-rgb)); }
.vsr-sub { display: block; font-size: 12px; color: rgba(255, 255, 255, 0.5); margin-top: 3px;
white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* people = circular portrait card */
.vsr-card--person .vsr-poster {
aspect-ratio: 1 / 1; border-radius: 50%;
background: linear-gradient(145deg, rgba(var(--vd-accent-rgb), 0.3), rgba(8, 8, 12, 0.9));
}
.vsr-card--person:hover .vsr-poster { border-radius: 50%; }
.vsr-card--person .vsr-poster::after { border-radius: 50%; }
/* ── SEARCH page ──────────────────────────────────────────────────────────── */
.vsr-page { --vd-accent-rgb: var(--accent-rgb, 88, 101, 242); position: relative; margin: -40px -40px 0; }
.vsr-hero {
position: relative; overflow: hidden;
padding: 48px 56px 30px; text-align: center;
}
.vsr-hero-glow {
position: absolute; inset: -40% 0 auto 0; height: 360px; z-index: 0; pointer-events: none;
background: radial-gradient(60% 100% at 50% 0%, rgba(var(--vd-accent-rgb), 0.28), transparent 70%);
animation: vsr-glow 7s ease-in-out infinite alternate;
}
@keyframes vsr-glow { from { opacity: 0.65; } to { opacity: 1; } }
.vsr-hero-title {
position: relative; z-index: 1; margin: 0 0 8px;
font-size: clamp(2em, 4vw, 3em); font-weight: 900; letter-spacing: -0.02em; color: #fff;
text-shadow: 0 4px 30px rgba(0, 0, 0, 0.6);
}
.vsr-hero-sub { position: relative; z-index: 1; margin: 0 0 26px; font-size: 14.5px; color: rgba(255, 255, 255, 0.6); }
.vsr-searchbar {
position: relative; z-index: 1; display: flex; align-items: center; gap: 12px;
max-width: 660px; margin: 0 auto; padding: 0 20px; height: 58px;
background: rgba(255, 255, 255, 0.06); border: 1px solid rgba(255, 255, 255, 0.12);
border-radius: 16px; backdrop-filter: blur(14px);
box-shadow: 0 10px 34px rgba(0, 0, 0, 0.4); transition: border-color 0.25s ease, box-shadow 0.25s ease;
}
.vsr-searchbar:focus-within {
border-color: rgba(var(--vd-accent-rgb), 0.65);
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.5), 0 0 0 4px rgba(var(--vd-accent-rgb), 0.18);
}
.vsr-search-ic { font-size: 19px; opacity: 0.7; }
.vsr-input {
flex: 1; min-width: 0; height: 100%; border: 0; background: transparent; outline: none;
color: #fff; font-size: 17px; font-weight: 500;
}
.vsr-input::placeholder { color: rgba(255, 255, 255, 0.4); }
.vsr-body { padding: 6px 56px 70px; }
.vsr-results { display: flex; flex-direction: column; gap: 40px; }
.vsr-group { animation: vsr-fade 0.4s ease both; }
@keyframes vsr-fade { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
.vsr-group-title {
display: flex; align-items: center; gap: 11px; margin: 0 0 18px;
font-size: 20px; font-weight: 800; color: #fff; letter-spacing: -0.01em;
}
.vsr-group-ic { font-size: 19px; }
.vsr-group-count {
font-size: 12px; font-weight: 700; color: rgba(255, 255, 255, 0.6);
background: rgba(var(--vd-accent-rgb), 0.18); border: 1px solid rgba(var(--vd-accent-rgb), 0.3);
border-radius: 999px; padding: 2px 10px;
}
.vsr-state { padding: 70px 20px; text-align: center; }
.vsr-state-ic {
font-size: 56px; margin-bottom: 16px; display: inline-block;
filter: drop-shadow(0 6px 18px rgba(var(--vd-accent-rgb), 0.4));
animation: vsr-float 4s ease-in-out infinite;
}
@keyframes vsr-float { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-8px); } }
.vsr-state-title { font-size: 21px; font-weight: 800; color: #fff; margin-bottom: 8px; }
.vsr-state-sub { font-size: 14px; color: rgba(255, 255, 255, 0.55); max-width: 460px; margin: 0 auto; line-height: 1.6; }
.vsr-loading { padding: 60px 0; text-align: center; color: rgba(255, 255, 255, 0.6); }
/* ══════════════════════════════════════════════════════════════════════════
PERSON page — cinematic bio + filmography
════════════════════════════════════════════════════════════════════════ */
.vp-page {
--vd-accent-rgb: var(--accent-rgb, 88, 101, 242);
position: relative; margin: -40px -40px -90px; min-height: 80vh;
}
/* Cinematic hero: a blurred-portrait wash + an accent colour mesh, capped by a
vignette and a fade into the page. Layers are static (painted once) so the
hero stays cheap. */
.vp-ambient {
position: absolute; inset: 0 0 auto 0; height: 560px; z-index: 0; overflow: hidden;
-webkit-mask-image: linear-gradient(180deg, #000 62%, transparent);
mask-image: linear-gradient(180deg, #000 62%, transparent);
}
.vp-ambient::before {
content: ''; position: absolute; inset: -80px; background-size: cover; background-position: center 18%;
background-image: var(--vp-bg, none); filter: blur(54px) saturate(1.35); transform: scale(1.2);
opacity: 0.5;
}
.vp-ambient::after {
content: ''; position: absolute; inset: 0;
background:
radial-gradient(80% 90% at 16% -10%, rgba(var(--vd-accent-rgb), 0.42), transparent 60%),
radial-gradient(70% 80% at 100% 0%, rgba(var(--vd-accent-rgb), 0.2), transparent 65%),
radial-gradient(120% 80% at 50% 120%, rgba(0, 0, 0, 0.5), transparent 60%),
linear-gradient(180deg, rgba(11,11,15,0.25) 0%, rgba(11,11,15,0.62) 58%, var(--bg-primary, #0b0b0f) 100%);
}
.vp-page[data-has-bg="0"] .vp-ambient::before {
background-image: radial-gradient(80% 120% at 30% 0%, rgba(var(--vd-accent-rgb), 0.55), transparent 70%);
filter: none; opacity: 0.8;
}
.vp-page .vd-back { z-index: 6; }
.vp-hero {
position: relative; z-index: 2; display: flex; gap: 40px; align-items: flex-end;
padding: 150px 56px 34px; animation: vdRise 0.7s cubic-bezier(0.2, 0.7, 0.2, 1) both;
}
@keyframes vdRise { from { opacity: 0; transform: translateY(26px); } to { opacity: 1; transform: none; } }
/* Portrait: a frame with a slowly-rotating accent gradient ring (GPU transform —
cheap) + a gentle float. */
.vp-photo-wrap {
position: relative; flex: 0 0 auto; width: 200px; height: 200px;
animation: vp-float 7s ease-in-out infinite;
}
@keyframes vp-float { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-9px); } }
.vp-photo-ring {
position: absolute; inset: -7px; border-radius: 50%; z-index: 0;
background: conic-gradient(from 0deg,
rgba(var(--vd-accent-rgb), 0.95), rgba(var(--vd-accent-rgb), 0.04) 38%,
rgba(var(--vd-accent-rgb), 0.55) 72%, rgba(var(--vd-accent-rgb), 0.95));
-webkit-mask: radial-gradient(closest-side, transparent calc(100% - 9px), #000 calc(100% - 8px));
mask: radial-gradient(closest-side, transparent calc(100% - 9px), #000 calc(100% - 8px));
animation: vp-spin 18s linear infinite; will-change: transform; opacity: 0.9;
}
@keyframes vp-spin { to { transform: rotate(360deg); } }
.vp-photo-frame {
position: absolute; inset: 0; border-radius: 50%; overflow: hidden; z-index: 1;
background: linear-gradient(145deg, rgba(var(--vd-accent-rgb), 0.42), rgba(8, 8, 12, 0.92));
display: flex; align-items: center; justify-content: center;
box-shadow: 0 22px 56px rgba(0, 0, 0, 0.62), 0 0 60px rgba(var(--vd-accent-rgb), 0.32),
inset 0 0 0 2px rgba(255, 255, 255, 0.07);
}
.vp-photo { width: 100%; height: 100%; object-fit: cover; }
.vp-photo-ph { font-size: 80px; opacity: 0.55; }
.vp-hero-info { flex: 1; min-width: 0; padding-bottom: 10px; }
.vp-role {
display: inline-block; margin-bottom: 12px; font-size: 12px; font-weight: 800;
letter-spacing: 1.4px; text-transform: uppercase; color: rgb(var(--vd-accent-rgb));
padding: 5px 13px; border-radius: 999px;
background: rgba(var(--vd-accent-rgb), 0.14); border: 1px solid rgba(var(--vd-accent-rgb), 0.34);
text-shadow: 0 0 18px rgba(var(--vd-accent-rgb), 0.5);
}
.vp-name {
margin: 0 0 14px; font-size: clamp(2.4em, 5vw, 3.8em); font-weight: 900;
line-height: 0.98; letter-spacing: -0.025em;
background: linear-gradient(180deg, #fff 55%, rgba(255, 255, 255, 0.72));
-webkit-background-clip: text; background-clip: text; color: transparent;
filter: drop-shadow(0 6px 30px rgba(0, 0, 0, 0.6));
}
.vp-meta { display: flex; flex-wrap: wrap; gap: 9px; }
.vp-meta span {
font-size: 12.5px; font-weight: 600; color: rgba(255, 255, 255, 0.82);
padding: 5px 12px; border-radius: 999px;
background: rgba(255, 255, 255, 0.08); border: 1px solid rgba(255, 255, 255, 0.14); backdrop-filter: blur(6px);
}
@media (prefers-reduced-motion: reduce) {
.vp-photo-wrap { animation: none; }
.vp-photo-ring { animation: none; }
}
.vp-body { position: relative; z-index: 2; padding: 16px 56px 60px; }
.vp-bio {
font-size: 15px; line-height: 1.7; color: rgba(255, 255, 255, 0.8);
max-width: 920px; margin: 0 0 6px; white-space: pre-line;
display: -webkit-box; -webkit-line-clamp: 5; -webkit-box-orient: vertical; overflow: hidden;
}
.vp-bio.vp-bio--open { -webkit-line-clamp: 99; }
.vp-bio-more {
background: none; border: 0; color: rgb(var(--vd-accent-rgb)); font-weight: 700; font-size: 13.5px;
cursor: pointer; padding: 4px 0; margin: 0 0 30px; display: inline-block;
}
.vp-bio-more[hidden] { display: none; }
/* Known For — a horizontal hero rail of the person's best-known titles */
.vp-known-section { position: relative; z-index: 2; margin-bottom: 38px; }
.vp-known-title { margin: 0 0 16px; }
.vp-known-rail {
display: flex; gap: 18px; overflow-x: auto; padding: 4px 2px 14px; scroll-snap-type: x proximity;
}
.vp-known-rail::-webkit-scrollbar { height: 8px; }
.vp-known-rail::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, 0.15); border-radius: 4px; }
.vp-known-rail .vsr-card { flex: 0 0 152px; width: 152px; scroll-snap-align: start; }
/* Long filmography grids can be hundreds of cards — let the browser skip
rendering the off-screen ones (cheap scrolling) and don't replay the entrance
animation as cards recycle in and out of view. */
.vp-credits-section .vsr-grid > .vsr-card {
content-visibility: auto;
contain-intrinsic-size: auto 300px;
animation: none;
}
.vp-credits-section { position: relative; z-index: 2; }
.vp-credits-head {
display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 14px; margin-bottom: 16px;
}
.vp-credits-title { font-size: 22px; font-weight: 800; color: #fff; margin: 0; }
.vp-credit-filters { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 14px; margin-bottom: 20px; }
.vp-credit-tabs { display: flex; gap: 8px; }
/* The ownership group sits after a faint divider so it reads as a second axis. */
.vp-own-tabs { position: relative; padding-left: 14px; }
.vp-own-tabs::before {
content: ''; position: absolute; left: 0; top: 14%; height: 72%; width: 1px;
background: rgba(255, 255, 255, 0.16);
}
/* "In Library" filter glows green (matches the owned ribbon) when active. */
.vp-own-tabs [data-vp-own="owned"].vp-tab--active {
background: rgba(34, 197, 94, 0.92); box-shadow: 0 4px 16px rgba(34, 197, 94, 0.4);
}
.vp-credits-empty {
padding: 44px 20px; text-align: center; font-size: 14px; color: rgba(255, 255, 255, 0.55);
}
.vp-dept-tabs [data-vp-dept].vp-tab--active {
background: rgba(var(--vd-accent-rgb, 99, 102, 241), 0.92); border-color: transparent; color: #fff;
}
.vp-dept-tabs:empty { display: none; }
.vp-sort {
background: rgba(255, 255, 255, 0.06); border: 1px solid rgba(255, 255, 255, 0.14);
color: rgba(255, 255, 255, 0.85); border-radius: 9px; padding: 8px 12px; font-size: 13px;
font-weight: 600; cursor: pointer; outline: none;
}
.vp-sort:hover { background: rgba(255, 255, 255, 0.1); }
.vp-sort option { background: #16161c; color: #fff; }
.vp-tab {
background: rgba(255, 255, 255, 0.06); border: 1px solid rgba(255, 255, 255, 0.1);
color: rgba(255, 255, 255, 0.7); border-radius: 999px; padding: 7px 16px; cursor: pointer;
font-size: 13px; font-weight: 700; display: inline-flex; align-items: center; gap: 7px;
transition: all 0.18s ease;
}
.vp-tab:hover { background: rgba(255, 255, 255, 0.12); color: #fff; }
.vp-tab--active {
background: rgba(var(--vd-accent-rgb), 0.92); border-color: transparent; color: #fff;
box-shadow: 0 4px 16px rgba(var(--vd-accent-rgb), 0.4);
}
.vp-tab-count { font-size: 11px; opacity: 0.85; }
/* cast card on the detail page becomes a real link → person */
.vd-cast-card--link { cursor: pointer; text-decoration: none; }
.vd-cast-card--link:hover .vd-cast-name { color: rgb(var(--vd-accent-rgb)); }
.vd-status--preview {
color: #fff !important;
background: rgba(255, 255, 255, 0.16); border: 1px solid rgba(255, 255, 255, 0.3);
padding: 2px 10px; border-radius: 999px; font-size: 12px; font-weight: 700;
}
@media (max-width: 720px) {
.vsr-page, .vp-page { margin-left: -20px; margin-right: -20px; }
.vsr-hero { padding: 34px 22px 22px; }
.vsr-body, .vp-body { padding-left: 22px; padding-right: 22px; }
.vp-hero { flex-direction: column; align-items: center; text-align: center; padding: 104px 22px 24px; }
.vp-meta { justify-content: center; }
.vsr-grid { grid-template-columns: repeat(auto-fill, minmax(128px, 1fr)); gap: 16px 14px; }
.vp-photo-wrap { width: 150px; height: 150px; }
}
/* ── billboard: Play CTA, crew line, next-episode, season overview ────────── */
/* Matches .vd-trailer-btn exactly (consistent with the other hero buttons) —
just green to read as "owned / play". */
.vd-play-btn {
display: inline-flex; align-items: center; gap: 7px; padding: 7px 18px; border-radius: 8px;
font-size: 12.5px; font-weight: 800; letter-spacing: 0.02em; cursor: pointer; text-decoration: none;
color: #fff; border: 1px solid transparent;
/* deeper green so the light Plex/Jellyfin wordmark reads clearly on it */
background: linear-gradient(135deg, #1fae54, #15803d);
box-shadow: 0 6px 18px rgba(34, 197, 94, 0.4); transition: all 0.2s ease;
}
.vd-play-btn:hover { transform: translateY(-1px); filter: brightness(1.1);
box-shadow: 0 8px 22px rgba(34, 197, 94, 0.55); }
.vd-play-logo { height: 15px; width: auto; position: relative; top: 0.5px; }
.vd-play-ic { font-size: 12px; }
.vd-crew-line { font-size: 14px; color: rgba(255, 255, 255, 0.84); margin: 2px 0 14px;
text-shadow: 0 2px 12px rgba(0, 0, 0, 0.6); }
.vd-crew-line-k { color: rgba(255, 255, 255, 0.5); font-weight: 600; margin-right: 4px; }
.vd-next-ep {
display: inline-flex; align-items: center; flex-wrap: wrap; gap: 10px; margin: 2px 0 14px;
font-size: 13.5px; color: rgba(255, 255, 255, 0.9); text-shadow: 0 2px 12px rgba(0, 0, 0, 0.6);
}
.vd-next-ep-badge {
font-size: 11.5px; font-weight: 800; letter-spacing: 0.5px; text-transform: uppercase;
color: rgb(var(--vd-accent-rgb)); padding: 4px 11px; border-radius: 999px;
background: rgba(var(--vd-accent-rgb), 0.16); border: 1px solid rgba(var(--vd-accent-rgb), 0.36);
}
.vd-next-ep-code { font-weight: 800; }
.vd-next-ep-name { color: rgba(255, 255, 255, 0.72); font-style: italic; }
.vd-next-ep-when { color: rgba(255, 255, 255, 0.6); }
.vd-season-overview {
font-size: 14px; line-height: 1.6; color: rgba(255, 255, 255, 0.7);
max-width: 880px; margin: -8px 0 22px;
}
/* ── detail skeleton loader (shimmer billboard while data loads) ──────────── */
.vd-skel {
position: absolute; top: 0; left: 0; right: 0; height: 76vh; min-height: 470px; z-index: 5; overflow: hidden;
background: radial-gradient(120% 90% at 70% 0%, rgba(var(--vd-accent-rgb, 88, 101, 242), 0.18), var(--bg-primary, #0b0b0f) 60%);
}
.vd-skel-content { position: absolute; left: 56px; bottom: 60px; width: min(60%, 600px); }
.skel-shine {
border-radius: 8px;
background: linear-gradient(100deg, rgba(255,255,255,0.05) 30%, rgba(255,255,255,0.14) 50%, rgba(255,255,255,0.05) 70%);
background-size: 200% 100%; animation: vd-skel-shine 1.4s ease-in-out infinite;
}
@keyframes vd-skel-shine { from { background-position: 200% 0; } to { background-position: -200% 0; } }
.vd-skel-logo { height: 54px; width: 320px; max-width: 80%; margin-bottom: 22px; }
.vd-skel-meta { height: 16px; width: 280px; max-width: 70%; margin-bottom: 22px; }
.vd-skel-text { height: 13px; width: 100%; margin-bottom: 10px; }
.vd-skel-text.short { width: 70%; margin-bottom: 26px; }
.vd-skel-btns { display: flex; gap: 12px; }
.vd-skel-btns span { height: 44px; width: 130px; border-radius: 10px; display: block; }
@media (max-width: 720px) {
.vd-skel-content { left: 22px; right: 22px; width: auto; bottom: 60px; }
}
@media (prefers-reduced-motion: reduce) { .skel-shine { animation: none; } }
/* clickable crew / director names → person page */
.vd-person-link { color: inherit; text-decoration: none; border-bottom: 1px solid transparent; transition: color 0.18s ease, border-color 0.18s ease; }
.vd-person-link:hover { color: rgb(var(--vd-accent-rgb)); border-bottom-color: rgba(var(--vd-accent-rgb), 0.5); }
/* "fetching full episode list" banner (shown while the TMDB cascade runs) */
.vd-ep-syncing {
display: flex; align-items: center; gap: 11px; margin: 0 0 18px; padding: 12px 16px;
border-radius: 10px; font-size: 13.5px; color: rgba(255, 255, 255, 0.78);
background: rgba(var(--vd-accent-rgb), 0.1); border: 1px solid rgba(var(--vd-accent-rgb), 0.26);
}
.vd-ep-syncing-spin {
flex: 0 0 auto; width: 16px; height: 16px; border-radius: 50%;
border: 2px solid rgba(var(--vd-accent-rgb), 0.3); border-top-color: rgb(var(--vd-accent-rgb));
animation: vd-ep-spin 0.8s linear infinite;
}
@keyframes vd-ep-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .vd-ep-syncing-spin { animation: none; } }
/* A class with an explicit `display` (e.g. .vd-ep-syncing/.vd-next-ep) otherwise
beats the UA [hidden]{display:none}, so toggling el.hidden wouldn't hide it.
Guarantee hidden always hides on the video detail/search/person pages. */
.vd-page [hidden], .vp-page [hidden], .vsr-page [hidden] { display: none !important; }
/* ══════════════════════════════════════════════════════════════════════════
Detail extras: Details/keywords, Videos, Photos gallery + lightbox, full cast
════════════════════════════════════════════════════════════════════════ */
.vd-section-head { display: flex; align-items: center; justify-content: space-between; gap: 14px; margin-bottom: 16px; }
.vd-section-head .vd-section-h { margin: 0; }
.vd-viewall {
background: rgba(255, 255, 255, 0.06); border: 1px solid rgba(255, 255, 255, 0.14);
color: rgba(255, 255, 255, 0.8); border-radius: 999px; padding: 6px 14px; font-size: 12.5px;
font-weight: 700; cursor: pointer; transition: all 0.18s ease;
}
.vd-viewall:hover { background: rgba(var(--vd-accent-rgb), 0.2); border-color: rgba(var(--vd-accent-rgb), 0.5); color: #fff; }
.vd-facts-section, .vd-videos-section, .vd-gallery-section { margin-top: 44px; }
.vd-keywords { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 18px; }
.vd-kw {
padding: 5px 12px; border-radius: 999px; font-size: 12px; color: rgba(255, 255, 255, 0.7);
background: rgba(255, 255, 255, 0.06); border: 1px solid rgba(255, 255, 255, 0.12);
}
/* videos rail */
.vd-videos { display: flex; gap: 16px; overflow-x: auto; padding-bottom: 12px; scroll-snap-type: x proximity; }
.vd-videos::-webkit-scrollbar, .vd-gallery::-webkit-scrollbar { height: 8px; }
.vd-videos::-webkit-scrollbar-thumb, .vd-gallery::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, 0.15); border-radius: 4px; }
.vd-video-card { flex: 0 0 240px; width: 240px; scroll-snap-align: start; background: none; border: 0; padding: 0; cursor: pointer; text-align: left; }
.vd-video-thumb {
position: relative; display: block; aspect-ratio: 16 / 9; border-radius: 10px; overflow: hidden; background: #000;
box-shadow: 0 6px 18px rgba(0, 0, 0, 0.4); transition: transform 0.25s ease, box-shadow 0.25s ease;
}
.vd-video-thumb img { width: 100%; height: 100%; object-fit: cover; }
.vd-video-play {
position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
font-size: 30px; color: #fff; background: rgba(0, 0, 0, 0.25); text-shadow: 0 2px 12px rgba(0, 0, 0, 0.7);
}
.vd-video-card:hover .vd-video-thumb { transform: translateY(-4px); box-shadow: 0 12px 30px rgba(0, 0, 0, 0.55); }
.vd-video-name { display: block; margin-top: 9px; font-size: 13px; font-weight: 600; color: #fff;
white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.vd-video-type { display: block; font-size: 11.5px; color: rgba(255, 255, 255, 0.5); }
/* photos rail */
.vd-gallery { display: flex; gap: 14px; overflow-x: auto; padding-bottom: 12px; scroll-snap-type: x proximity; }
.vd-shot {
flex: 0 0 280px; width: 280px; aspect-ratio: 16 / 9; scroll-snap-align: start; padding: 0; border: 0; cursor: pointer;
border-radius: 10px; overflow: hidden; background: #000; box-shadow: 0 6px 18px rgba(0, 0, 0, 0.4);
transition: transform 0.25s ease, box-shadow 0.25s ease;
}
.vd-shot img { width: 100%; height: 100%; object-fit: cover; }
.vd-shot:hover { transform: translateY(-4px); box-shadow: 0 12px 30px rgba(0, 0, 0, 0.55); }
/* lightbox + full-cast modal share the accent fallback (they live on <body>) */
.vd-lightbox, .vd-cast-modal { --vd-accent-rgb: var(--accent-rgb, 88, 101, 242); }
.vd-lightbox {
position: fixed; inset: 0; z-index: 1000; display: none; align-items: center; justify-content: center;
background: rgba(0, 0, 0, 0.92); backdrop-filter: blur(6px);
}
.vd-lightbox--open { display: flex; animation: vd-fade 0.2s ease; }
@keyframes vd-fade { from { opacity: 0; } to { opacity: 1; } }
.vd-lb-img { max-width: 92vw; max-height: 88vh; border-radius: 8px; box-shadow: 0 20px 60px rgba(0, 0, 0, 0.7); }
.vd-lb-close { position: absolute; top: 20px; right: 24px; width: 42px; height: 42px; border-radius: 50%; border: 0; cursor: pointer;
background: rgba(255, 255, 255, 0.12); color: #fff; font-size: 24px; }
.vd-lb-close:hover { background: rgba(255, 255, 255, 0.22); }
.vd-lb-nav { position: absolute; top: 50%; transform: translateY(-50%); width: 52px; height: 52px; border-radius: 50%; border: 0; cursor: pointer;
background: rgba(255, 255, 255, 0.1); color: #fff; font-size: 30px; line-height: 1; }
.vd-lb-nav:hover { background: rgba(255, 255, 255, 0.22); }
.vd-lb-prev { left: 24px; }
.vd-lb-next { right: 24px; }
.vd-lb-count { position: absolute; bottom: 22px; left: 50%; transform: translateX(-50%); font-size: 13px; color: rgba(255, 255, 255, 0.7); }
.vd-cast-modal {
position: fixed; inset: 0; z-index: 1000; display: none; align-items: center; justify-content: center;
background: rgba(0, 0, 0, 0.75); backdrop-filter: blur(6px); padding: 30px;
}
.vd-cast-modal--open { display: flex; animation: vd-fade 0.2s ease; }
.vd-cm-box {
background: #16161c; border: 1px solid rgba(255, 255, 255, 0.1); border-radius: 16px;
width: min(960px, 96vw); max-height: 86vh; overflow: hidden; display: flex; flex-direction: column;
box-shadow: 0 30px 80px rgba(0, 0, 0, 0.6);
}
.vd-cm-head { display: flex; align-items: center; justify-content: space-between; padding: 18px 22px; border-bottom: 1px solid rgba(255, 255, 255, 0.08); }
.vd-cm-head h3 { margin: 0; font-size: 18px; font-weight: 800; color: #fff; }
.vd-cm-close { width: 36px; height: 36px; border-radius: 50%; border: 0; cursor: pointer; background: rgba(255, 255, 255, 0.08); color: #fff; font-size: 22px; }
.vd-cm-close:hover { background: rgba(255, 255, 255, 0.18); }
.vd-cm-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(116px, 1fr)); gap: 18px; padding: 22px; overflow-y: auto; }
.vd-cm-card { text-decoration: none; text-align: center; color: inherit; cursor: pointer; }
.vd-cm-photo {
width: 84px; height: 84px; border-radius: 50%; object-fit: cover; display: block; margin: 0 auto 9px;
border: 2px solid rgba(255, 255, 255, 0.08); transition: transform 0.2s ease, border-color 0.2s ease;
}
.vd-cm-photo--ph { display: flex; align-items: center; justify-content: center; font-size: 30px; font-weight: 800;
color: rgba(255, 255, 255, 0.5); background: linear-gradient(135deg, rgba(var(--vd-accent-rgb), 0.32), rgba(var(--vd-accent-rgb), 0.1)); }
.vd-cm-card:hover .vd-cm-photo { transform: translateY(-3px); border-color: rgba(var(--vd-accent-rgb), 0.6); }
.vd-cm-name { display: block; font-size: 13px; font-weight: 700; color: #fff; line-height: 1.3; }
.vd-cm-char { display: block; font-size: 12px; color: rgba(255, 255, 255, 0.55); line-height: 1.3; }
.vd-cm-eps { display: block; font-size: 11px; color: rgb(var(--vd-accent-rgb)); margin-top: 2px; font-weight: 600; }
/* ── person: photos rail + also-known-as ─────────────────────────────────── */
.vp-aka { font-size: 13.5px; color: rgba(255, 255, 255, 0.6); margin: 0 0 18px; font-style: italic; }
.vp-photos-section { position: relative; z-index: 2; margin-bottom: 38px; }
.vp-photos { display: flex; gap: 14px; overflow-x: auto; padding-bottom: 12px; scroll-snap-type: x proximity; }
.vp-photos::-webkit-scrollbar { height: 8px; }
.vp-photos::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, 0.15); border-radius: 4px; }
.vp-photo-thumb {
flex: 0 0 120px; width: 120px; aspect-ratio: 2 / 3; scroll-snap-align: start; padding: 0; border: 0; cursor: pointer;
border-radius: 10px; overflow: hidden; background: #000; box-shadow: 0 6px 18px rgba(0, 0, 0, 0.4);
transition: transform 0.25s ease, box-shadow 0.25s ease;
}
.vp-photo-thumb img { width: 100%; height: 100%; object-fit: cover; }
.vp-photo-thumb:hover { transform: translateY(-4px); box-shadow: 0 12px 30px rgba(0, 0, 0, 0.55); }
/* ── featured review ─────────────────────────────────────────────────────── */
.vd-review-section { margin-top: 44px; }
.vd-review {
max-width: 880px; padding: 20px 22px; border-radius: 14px;
background: rgba(255, 255, 255, 0.04); border: 1px solid rgba(255, 255, 255, 0.08);
}
.vd-review-head { display: flex; align-items: center; gap: 14px; margin-bottom: 12px; }
.vd-review-author { font-size: 15px; font-weight: 800; color: #fff; }
.vd-review-rating { font-size: 13px; font-weight: 800; color: #fbbf24; }
.vd-review-date { font-size: 12.5px; color: rgba(255, 255, 255, 0.45); }
.vd-review-body {
margin: 0; font-size: 14.5px; line-height: 1.7; color: rgba(255, 255, 255, 0.8); white-space: pre-line;
display: -webkit-box; -webkit-line-clamp: 6; -webkit-box-orient: vertical; overflow: hidden;
}
.vd-review-body--open { -webkit-line-clamp: 999; }
.vd-review-more {
background: none; border: 0; color: rgb(var(--vd-accent-rgb)); font-weight: 700; font-size: 13.5px;
cursor: pointer; padding: 8px 0 0;
}
/* ── billboard autoplay trailer ──────────────────────────────────────────── */
.vd-bb-trailer { position: absolute; inset: 0; z-index: 0; overflow: hidden; background: #000; opacity: 0; }
.vd-bb-trailer iframe {
position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
width: 100vw; height: 56.25vw; min-height: 100%; min-width: 177.78vh; border: 0; pointer-events: none;
}
/* Reveal — only once the trailer is actually PLAYING (gated in video-detail.js).
The trailer wipes in left→right behind a soft feathered edge while it
crossfades, so the backdrop appears to roll away from the left AND fade —
"both a rollover and a fade." @property animates the mask gradient smoothly;
browsers without it still get the opacity crossfade. */
@property --vd-wipe { syntax: '<percentage>'; inherits: false; initial-value: 0%; }
.vd-billboard--trailer .vd-bb-trailer {
-webkit-mask-image: linear-gradient(100deg, #000 var(--vd-wipe), transparent calc(var(--vd-wipe) + 16%));
mask-image: linear-gradient(100deg, #000 var(--vd-wipe), transparent calc(var(--vd-wipe) + 16%));
animation: vdTrailerWipeIn 1.15s cubic-bezier(0.62, 0.04, 0.18, 1) forwards;
}
@keyframes vdTrailerWipeIn { from { --vd-wipe: -16%; opacity: 0; } to { --vd-wipe: 116%; opacity: 1; } }
.vd-billboard--trailer .vd-bb-bg { animation: vdBgFadeOut 1.15s ease forwards; }
@keyframes vdBgFadeOut { from { opacity: 1; } to { opacity: 0; } }
/* Restore — when the trailer ends, fade the original backdrop back in and the
trailer out, then it's torn down. */
.vd-billboard--restoring .vd-bb-bg { animation: vdBgFadeIn 0.9s ease forwards; }
@keyframes vdBgFadeIn { from { opacity: 0; } to { opacity: 1; } }
.vd-billboard--restoring .vd-bb-trailer { animation: vdTrailerFadeOut 0.7s ease forwards; }
@keyframes vdTrailerFadeOut { from { opacity: 1; } to { opacity: 0; } }
@media (prefers-reduced-motion: reduce) {
.vd-billboard--trailer .vd-bb-trailer { -webkit-mask-image: none; mask-image: none; animation: vd-fade 0.4s ease forwards; }
.vd-billboard--trailer .vd-bb-bg { animation: vdBgFadeOut 0.4s ease forwards; }
}
.vd-bb-tctrls { position: absolute; bottom: 20px; right: 24px; z-index: 4; display: flex; gap: 8px; }
.vd-bb-tbtn {
width: 38px; height: 38px; border-radius: 50%; border: 1px solid rgba(255, 255, 255, 0.25); cursor: pointer;
background: rgba(0, 0, 0, 0.5); color: #fff; font-size: 15px; backdrop-filter: blur(8px); transition: all 0.2s ease;
}
.vd-bb-tbtn:hover { background: rgba(0, 0, 0, 0.78); transform: translateY(-1px); }
/* settings: detail-pages preference toggle */
.vid-pref-row { display: flex; align-items: center; gap: 10px; cursor: pointer; font-size: 14px; color: var(--text-primary, #fff); }
.vid-pref-row input { width: 16px; height: 16px; cursor: pointer; accent-color: #38bdf8; }
/* ── owned media: multiple versions/editions ─────────────────────────────── */
.vd-versions { margin-top: 18px; }
.vd-versions-h { font-size: 11px; text-transform: uppercase; letter-spacing: 0.6px; color: rgba(255, 255, 255, 0.45); margin-bottom: 8px; }
.vd-version {
display: inline-block; margin: 0 8px 8px 0; padding: 7px 13px; border-radius: 8px;
font-size: 13px; font-weight: 600; color: rgba(255, 255, 255, 0.85);
background: rgba(255, 255, 255, 0.05); border: 1px solid rgba(255, 255, 255, 0.1);
}
/* ── episode expand (guest stars + bigger still) ─────────────────────────── */
.vd-ep-extra {
display: flex; gap: 22px; padding: 6px 14px 24px 82px;
border-bottom: 1px solid rgba(255, 255, 255, 0.06);
animation: vsr-fade 0.3s ease;
}
.vd-ep-extra-still { width: 240px; aspect-ratio: 16 / 9; object-fit: cover; border-radius: 10px; flex: 0 0 auto;
box-shadow: 0 6px 18px rgba(0, 0, 0, 0.4); }
.vd-ep-extra-body { flex: 1; min-width: 0; }
.vd-ep-extra-ov { margin: 0 0 16px; font-size: 14px; line-height: 1.6; color: rgba(255, 255, 255, 0.8); }
.vd-ep-extra-empty { color: rgba(255, 255, 255, 0.45); font-size: 13.5px; padding: 4px 0; }
.vd-ep-extra-gh { font-size: 11px; text-transform: uppercase; letter-spacing: 0.6px; color: rgba(255, 255, 255, 0.45); margin-bottom: 12px; }
.vd-ep-guests { display: flex; flex-wrap: wrap; gap: 16px; }
.vd-guest { width: 92px; text-align: center; text-decoration: none; color: inherit; }
a.vd-guest { cursor: pointer; transition: transform 0.18s ease; }
a.vd-guest:hover { transform: translateY(-3px); }
a.vd-guest:hover .vd-guest-name { color: rgb(var(--vd-accent-rgb)); }
.vd-guest-photo {
width: 64px; height: 64px; border-radius: 50%; object-fit: cover; display: block; margin: 0 auto 7px;
border: 2px solid rgba(255, 255, 255, 0.08);
}
.vd-guest-photo--ph { display: flex; align-items: center; justify-content: center; font-size: 24px; font-weight: 800;
color: rgba(255, 255, 255, 0.5); background: linear-gradient(135deg, rgba(var(--vd-accent-rgb), 0.3), rgba(var(--vd-accent-rgb), 0.08)); }
.vd-guest-name { display: block; font-size: 12px; font-weight: 700; color: #fff; line-height: 1.25; }
.vd-guest-char { display: block; font-size: 11px; color: rgba(255, 255, 255, 0.5); line-height: 1.25; }
@media (max-width: 720px) {
.vd-ep-extra { flex-direction: column; padding-left: 14px; }
.vd-ep-extra-still { width: 100%; }
}
.vid-pref-row--select { justify-content: space-between; cursor: default; }
.vid-pref-row--select select {
background: rgba(255, 255, 255, 0.06); border: 1px solid rgba(255, 255, 255, 0.14);
color: var(--text-primary, #fff); border-radius: 8px; padding: 7px 10px; font-size: 13px; cursor: pointer;
}
.vid-pref-row--select select option { background: #16161c; color: #fff; }
/* Server Connection mirrors the music server picker (.server-toggle-container /
.server-config-container) — no video-specific styling needed beyond those
shared classes. */
/* library: no-server gate banner */
.video-noserver {
margin: 0 0 18px; padding: 16px 18px; border-radius: 12px; font-size: 14px; line-height: 1.6;
color: rgba(255, 255, 255, 0.85);
background: rgba(245, 158, 11, 0.1); border: 1px solid rgba(245, 158, 11, 0.32);
}
.video-noserver.hidden { display: none; }
/* Navidrome + SoulSync Standalone are music-only — don't offer them as server
options on the VIDEO side (scoped to body[data-side="video"], so the music side
is untouched). The "Video Source" panel governs which video server is used. */
body[data-side="video"] #navidrome-toggle,
body[data-side="video"] #soulsync-toggle { display: none; }
/* ── Calendar — the Week Grid (every episode, air times, breathing cells) ──── */
.vcal-page { --vcal-accent: var(--accent-rgb, 88, 101, 242); color: var(--text-primary, #fff); padding: 0 0 70px; }
.vcal-head { position: relative; padding: 30px 40px 18px; overflow: hidden; }
.vcal-head-glow {
position: absolute; top: -190px; left: 50%; transform: translateX(-50%);
width: 860px; height: 390px; pointer-events: none; z-index: 0;
background: radial-gradient(56% 70% at 50% 0%, rgba(var(--vcal-accent), 0.26), transparent 70%); filter: blur(10px);
}
.vcal-title { position: relative; z-index: 1; font-size: 36px; font-weight: 800; letter-spacing: -0.025em; margin: 0; }
.vcal-sub { position: relative; z-index: 1; margin: 7px 0 0; color: rgba(255, 255, 255, 0.55); font-size: 14px; font-weight: 600; }
.vcal-body { padding: 4px 40px 0; }
.vcal-loading { padding: 90px 0; text-align: center; }
.vcal-grid { border-radius: 20px; overflow: hidden; border: 1px solid rgba(255, 255, 255, 0.07);
background: linear-gradient(180deg, #0d0d12, #0a0a0e); box-shadow: 0 30px 80px rgba(0, 0, 0, 0.45); }
.vcal-grid.hidden { display: none; }
/* EPG guide — a frozen time-rail (rows = time-of-day) × 7 day columns with a
frozen header row, so the whole week reads on ONE shared time axis. */
.vcal-cols { display: grid; grid-template-columns: 84px repeat(7, minmax(150px, 1fr)); align-items: stretch; }
/* sticky top-left corner */
.vcal-guide-corner { position: sticky; top: 0; left: 0; z-index: 6;
background: linear-gradient(180deg, rgba(15, 15, 20, 0.97), rgba(13, 13, 18, 0.88));
backdrop-filter: blur(12px); border-bottom: 1px solid rgba(255, 255, 255, 0.07); }
/* day header — sticky top */
.vcal-dayhead { position: sticky; top: 0; z-index: 4; padding: 15px 14px 13px;
background: linear-gradient(180deg, rgba(15, 15, 20, 0.96), rgba(13, 13, 18, 0.85));
backdrop-filter: blur(12px); border-bottom: 1px solid rgba(255, 255, 255, 0.07);
border-left: 1px solid rgba(255, 255, 255, 0.05); }
.vcal-dayhead-wd { display: block; font-size: 14px; font-weight: 800; letter-spacing: -0.01em; color: #fff; }
.vcal-dayhead-date { display: block; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em;
color: rgba(255, 255, 255, 0.4); margin-top: 2px; }
.vcal-dayhead-n { position: absolute; top: 14px; right: 13px; font-size: 11px; font-weight: 800; color: rgba(255, 255, 255, 0.6);
background: rgba(255, 255, 255, 0.08); padding: 3px 9px; border-radius: 999px; }
.vcal-dayhead--today { background: linear-gradient(180deg, rgba(var(--vcal-accent), 0.24), rgba(13, 13, 18, 0.86));
border-bottom-color: rgba(var(--vcal-accent), 0.55);
box-shadow: 0 1px 0 rgba(var(--vcal-accent), 0.55), 0 12px 28px -14px rgba(var(--vcal-accent), 0.6); }
.vcal-dayhead--today .vcal-dayhead-wd { color: hsl(232, 100%, 84%); }
.vcal-dayhead--today .vcal-dayhead-n { background: rgba(var(--vcal-accent), 0.9); color: #fff; }
/* time rail — sticky left, labels the band */
.vcal-rail { position: sticky; left: 0; z-index: 2; display: flex; flex-direction: column; gap: 2px;
padding: 17px 12px; border-top: 1px solid rgba(255, 255, 255, 0.05);
background: linear-gradient(90deg, rgba(255, 255, 255, 0.025), rgba(255, 255, 255, 0.004)); }
.vcal-rail-label { font-size: 12.5px; font-weight: 800; letter-spacing: -0.01em; color: rgba(255, 255, 255, 0.8); }
.vcal-rail small { font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; color: rgba(255, 255, 255, 0.3); }
.vcal-rail--prime .vcal-rail-label { color: hsl(44, 100%, 72%); }
.vcal-rail--prime small { color: hsla(44, 90%, 60%, 0.6); }
/* one day×band cell */
.vcal-slot { display: flex; flex-direction: column; gap: 15px; padding: 17px 13px; min-width: 0;
border-top: 1px solid rgba(255, 255, 255, 0.05); border-left: 1px solid rgba(255, 255, 255, 0.05); }
.vcal-slot--today { background: linear-gradient(180deg, rgba(var(--vcal-accent), 0.07), rgba(var(--vcal-accent), 0.015)); }
.vcal-slot--empty { align-items: center; justify-content: center; padding: 0; }
.vcal-slot-dot { width: 4px; height: 4px; border-radius: 50%; background: rgba(255, 255, 255, 0.07); }
/* live "now" intersection — today column × current time-of-day band */
.vcal-slot--now { box-shadow: inset 3px 0 0 rgba(var(--vcal-accent), 0.95), inset 0 0 34px -12px rgba(var(--vcal-accent), 0.5);
background: linear-gradient(180deg, rgba(var(--vcal-accent), 0.12), rgba(var(--vcal-accent), 0.03)); }
/* staggered entrance — only on a fresh load/week-change (class added by JS),
keyed off the per-card --i (cycles every 24). Filter re-renders don't get it. */
.vcal-cols.vcal-animate-in .vcal-card { animation: vcalCardIn 0.5s cubic-bezier(0.2, 0.7, 0.2, 1) both;
animation-delay: calc(var(--i, 0) * 0.022s); }
@keyframes vcalCardIn { from { opacity: 0; transform: translateY(10px) scale(0.985); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .vcal-cols.vcal-animate-in .vcal-card { animation: none; } }
/* week-change crossfade */
.vcal-grid { transition: opacity 0.22s ease; }
.vcal-grid.vcal-fading { opacity: 0.32; }
/* keyboard focus — mirrors hover + a clear ring (cards are real <a>s) */
.vcal-cell:focus-visible { outline: none; --ty: -6px; --sc: 1.04; z-index: 3; }
.vcal-cell:focus-visible .vcal-card { border-color: hsla(var(--vcal-show), 80%, 64%, 0.85);
box-shadow: 0 0 0 2px hsla(var(--vcal-show), 82%, 62%, 0.9), 0 18px 40px rgba(0, 0, 0, 0.5); }
/* Episode cell — one clean card (art + info), breathing colour halo behind it */
.vcal-cell { --vcal-show: var(--vcal-h, 230); position: relative; display: block; text-decoration: none; color: inherit;
transform: perspective(760px) translateY(var(--ty, 0px)) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg)) scale(var(--sc, 1));
transition: transform 0.16s ease; }
/* Calm by default; the colour only comes alive on hover. */
.vcal-glow { position: absolute; inset: -11px; z-index: 0; border-radius: 22px; pointer-events: none;
background: radial-gradient(closest-side, hsla(var(--vcal-show), 90%, 55%, 0.6), transparent 76%);
opacity: 0.06; animation: vcalBreathe 7s ease-in-out infinite; animation-delay: calc(var(--i) * -0.5s);
transition: opacity 0.25s ease; }
@keyframes vcalBreathe { 0%, 100% { opacity: 0.04; } 50% { opacity: 0.13; } }
.vcal-card { position: relative; z-index: 1; display: block; border-radius: 14px; overflow: hidden;
border: 1px solid rgba(255, 255, 255, 0.08); background: #14141a;
transition: border-color 0.2s ease, box-shadow 0.2s ease; }
.vcal-art { position: relative; display: block; aspect-ratio: 16 / 9; overflow: hidden;
background: linear-gradient(135deg, hsl(var(--vcal-show), 42%, 22%), #0a0a0e 90%); }
/* skeleton shimmer shown until the image fades in */
.vcal-art::before { content: ''; position: absolute; inset: 0; z-index: 0;
background: linear-gradient(100deg, transparent 16%, rgba(255, 255, 255, 0.05) 38%,
rgba(255, 255, 255, 0.10) 50%, rgba(255, 255, 255, 0.05) 62%, transparent 84%);
background-size: 220% 100%; animation: vcalShimmer 1.5s ease-in-out infinite; }
.vcal-cell-img { position: relative; z-index: 1; width: 100%; height: 100%; object-fit: cover; display: block;
opacity: 0; transition: opacity 0.5s ease; }
.vcal-cell-img.vcal-loaded { opacity: 1; }
@keyframes vcalShimmer { 0% { background-position: 200% 0; } 100% { background-position: -130% 0; } }
@media (prefers-reduced-motion: reduce) { .vcal-art::before { animation: none; } .vcal-cell-img { transition: none; } }
.vcal-art-scrim { position: absolute; inset: 0; z-index: 2; background: linear-gradient(0deg, rgba(0, 0, 0, 0.45), transparent 55%); }
.vcal-flag { position: absolute; top: 8px; right: 8px; z-index: 3; width: 22px; height: 22px; border-radius: 50%;
display: flex; align-items: center; justify-content: center; font-size: 12px; font-weight: 900;
background: rgba(108, 211, 145, 0.94); color: #07130c; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.5); }
.vcal-info { display: block; padding: 9px 11px 11px; }
.vcal-time { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 800; letter-spacing: 0.01em;
color: hsl(var(--vcal-show), 85%, 80%); }
.vcal-time-dot { width: 6px; height: 6px; border-radius: 50%; background: hsl(var(--vcal-show), 85%, 62%);
box-shadow: 0 0 8px hsl(var(--vcal-show), 85%, 60%); }
.vcal-time--none { color: rgba(255, 255, 255, 0.32); font-weight: 700; }
.vcal-show { display: block; font-size: 13.5px; font-weight: 800; line-height: 1.25; margin-top: 5px;
overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.vcal-meta { display: block; font-size: 11.5px; color: rgba(255, 255, 255, 0.5); margin-top: 2px;
overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.vcal-se { font-weight: 800; color: rgba(255, 255, 255, 0.72); }
.vcal-ep { margin-left: 6px; }
.vcal-cell:hover { --ty: -6px; --sc: 1.04; z-index: 3; }
.vcal-cell:hover .vcal-glow { opacity: 0.6 !important; animation-play-state: paused; }
.vcal-cell:hover .vcal-card { border-color: hsla(var(--vcal-show), 78%, 62%, 0.7);
box-shadow: 0 22px 46px rgba(0, 0, 0, 0.55), 0 0 30px hsla(var(--vcal-show), 78%, 55%, 0.34); }
@media (prefers-reduced-motion: reduce) {
.vcal-glow { animation: none; opacity: 0.08; }
.vcal-cell { transform: none; } .vcal-cell:hover { --ty: 0px; --sc: 1; }
}
/* Empty state */
.vcal-state { text-align: center; padding: 90px 20px; color: rgba(255, 255, 255, 0.6); }
.vcal-state-ic { font-size: 48px; opacity: 0.55; }
.vcal-state-title { font-size: 20px; font-weight: 800; color: #fff; margin-top: 12px; }
.vcal-state-sub { font-size: 14px; margin-top: 6px; }
@media (max-width: 900px) { .vcal-head, .vcal-body { padding-left: 18px; padding-right: 18px; } .vcal-cols { overflow-x: auto; } }
/* ── Calendar — episode modal ─────────────────────────────────────────────── */
.vcm-overlay { position: fixed; inset: 0; z-index: 9000; display: flex; align-items: center; justify-content: center;
padding: 24px; background: rgba(5, 5, 8, 0.72); backdrop-filter: blur(9px); opacity: 0; transition: opacity 0.2s ease; }
.vcm-overlay.vcm-open { opacity: 1; }
.vcm-modal { --vcm-h: 230; position: relative; width: min(700px, 100%); max-height: 90vh; overflow-y: auto;
border-radius: 22px; background: #101015; border: 1px solid rgba(255, 255, 255, 0.08);
box-shadow: 0 50px 130px rgba(0, 0, 0, 0.72); transform: translateY(16px) scale(0.985);
transition: transform 0.26s cubic-bezier(0.2, 0.7, 0.2, 1); }
.vcm-overlay.vcm-open .vcm-modal { transform: none; }
.vcm-modal::-webkit-scrollbar { width: 9px; }
.vcm-modal::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, 0.14); border-radius: 5px; }
.vcm-close { position: absolute; top: 14px; right: 14px; z-index: 3; width: 36px; height: 36px; border-radius: 50%;
border: 1px solid rgba(255, 255, 255, 0.18); background: rgba(0, 0, 0, 0.45); color: #fff; font-size: 22px; cursor: pointer;
backdrop-filter: blur(6px); display: flex; align-items: center; justify-content: center; line-height: 1; transition: all 0.15s ease; }
.vcm-close:hover { background: rgba(0, 0, 0, 0.72); border-color: rgba(255, 255, 255, 0.4); }
.vcm-hero { position: relative; min-height: 210px; border-radius: 22px 22px 0 0; overflow: hidden; display: flex; align-items: flex-end; }
.vcm-hero-bg { position: absolute; inset: 0; background-size: cover; background-position: center 28%; transform: scale(1.05); }
.vcm-hero-scrim { position: absolute; inset: 0;
background: linear-gradient(0deg, #101015 3%, rgba(16, 16, 21, 0.45) 52%, rgba(16, 16, 21, 0.15)),
radial-gradient(130% 110% at 0% 100%, hsla(var(--vcm-h), 72%, 45%, 0.38), transparent 60%); }
.vcm-hero-content { position: relative; z-index: 1; padding: 24px 26px 18px; width: 100%; }
.vcm-eyebrow { font-size: 12px; font-weight: 800; text-transform: uppercase; letter-spacing: 0.06em; color: hsl(var(--vcm-h), 82%, 80%); }
.vcm-eyebrow:empty { display: none; }
.vcm-show { font-size: 27px; font-weight: 800; letter-spacing: -0.02em; margin: 6px 0 0; line-height: 1.1; }
.vcm-genres { display: flex; gap: 7px; margin-top: 11px; flex-wrap: wrap; }
.vcm-genre { font-size: 11px; font-weight: 700; padding: 3px 10px; border-radius: 999px; background: rgba(255, 255, 255, 0.1); color: rgba(255, 255, 255, 0.82); }
.vcm-body { padding: 20px 26px; }
.vcm-ep { display: grid; grid-template-columns: 176px 1fr; gap: 20px; }
.vcm-ep-still { position: relative; aspect-ratio: 16 / 9; border-radius: 12px; overflow: hidden;
background: linear-gradient(135deg, hsl(var(--vcm-h), 48%, 28%), #0b0b0f); }
.vcm-ep-still img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; z-index: 1;
opacity: 0; transition: opacity 0.45s ease; }
.vcm-ep-still img.vcm-loaded { opacity: 1; }
.vcm-ep-fb { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; font-size: 24px; color: rgba(255, 255, 255, 0.3); }
.vcm-ep-main { min-width: 0; }
.vcm-ep-se { font-size: 12px; font-weight: 800; color: hsl(var(--vcm-h), 82%, 78%); letter-spacing: 0.03em; }
.vcm-ep-title { font-size: 20px; font-weight: 800; margin: 3px 0 0; line-height: 1.2; }
.vcm-when { font-size: 13px; color: rgba(255, 255, 255, 0.62); margin-top: 8px; font-weight: 600; }
.vcm-tags { display: flex; gap: 8px; margin-top: 13px; flex-wrap: wrap; align-items: center; }
.vcm-badge { font-size: 11px; font-weight: 800; padding: 4px 11px; border-radius: 999px; }
.vcm-badge--have { background: rgba(108, 211, 145, 0.16); color: #6cd391; }
.vcm-badge--miss { background: rgba(255, 255, 255, 0.08); color: rgba(255, 255, 255, 0.55); }
.vcm-tag { font-size: 11.5px; font-weight: 700; color: rgba(255, 255, 255, 0.62); }
.vcm-tag--star { color: rgba(245, 197, 24, 0.95); }
.vcm-ep-ov { font-size: 13.5px; line-height: 1.6; color: rgba(255, 255, 255, 0.8); margin: 15px 0 0; }
.vcm-ep-ov--none { color: rgba(255, 255, 255, 0.35); font-style: italic; }
.vcm-about { margin-top: 22px; padding-top: 18px; border-top: 1px solid rgba(255, 255, 255, 0.07); }
.vcm-about-h { font-size: 12px; font-weight: 800; text-transform: uppercase; letter-spacing: 0.05em; color: rgba(255, 255, 255, 0.5); margin: 0 0 8px; }
.vcm-about-ov { font-size: 13.5px; line-height: 1.6; color: rgba(255, 255, 255, 0.72); margin: 0; }
.vcm-actions { display: flex; justify-content: flex-end; gap: 10px; padding: 4px 26px 24px; }
.vcm-btn { font-size: 13px; font-weight: 800; padding: 11px 18px; border-radius: 12px; cursor: pointer; border: 1px solid transparent; transition: all 0.15s ease; }
.vcm-btn--ghost { background: rgba(255, 255, 255, 0.06); border-color: rgba(255, 255, 255, 0.12); color: rgba(255, 255, 255, 0.82); }
.vcm-btn--ghost:hover { background: rgba(255, 255, 255, 0.12); color: #fff; }
.vcm-btn--primary { background: hsl(var(--vcm-h), 68%, 52%); color: #fff; box-shadow: 0 8px 24px hsla(var(--vcm-h), 70%, 45%, 0.4); }
.vcm-btn--primary:hover { filter: brightness(1.08); transform: translateY(-1px); }
@media (max-width: 560px) {
.vcm-ep { grid-template-columns: 1fr; }
.vcm-ep-still { max-width: 240px; }
.vcm-actions { flex-direction: column-reverse; }
.vcm-btn { width: 100%; }
}
/* ── Calendar — featured "next up" billboard ──────────────────────────────── */
.vcal-hero-wrap { padding: 4px 40px 8px; perspective: 1400px; }
.vcal-hero-wrap:empty { display: none; }
.vcal-bb { --vcal-h: 230; position: relative; display: flex; align-items: flex-end; min-height: 306px;
border-radius: 22px; overflow: hidden; cursor: pointer; border: 1px solid rgba(255, 255, 255, 0.08);
box-shadow: 0 34px 90px rgba(0, 0, 0, 0.55);
transform: rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg)) scale(var(--sc, 1));
transition: transform 0.18s ease, box-shadow 0.3s ease; will-change: transform; }
.vcal-bb:hover { --sc: 1.012; box-shadow: 0 44px 110px rgba(0, 0, 0, 0.62), 0 0 60px hsla(var(--vcal-h), 72%, 50%, 0.22); }
.vcal-bb-bg { position: absolute; inset: 0; background-size: cover; background-position: center 22%; transform: scale(1.08); }
.vcal-bb-scrim { position: absolute; inset: 0;
background: linear-gradient(90deg, rgba(8, 8, 12, 0.94) 0%, rgba(8, 8, 12, 0.62) 42%, transparent 78%),
linear-gradient(0deg, rgba(8, 8, 12, 0.82), transparent 58%),
radial-gradient(120% 130% at 0% 100%, hsla(var(--vcal-h), 72%, 45%, 0.42), transparent 58%); }
.vcal-bb-content { position: relative; z-index: 1; padding: 34px 42px 34px; max-width: 640px; }
.vcal-bb-eyebrow { display: inline-flex; align-items: center; gap: 8px; font-size: 12px; font-weight: 800;
letter-spacing: 0.09em; text-transform: uppercase; color: hsl(var(--vcal-h), 88%, 80%); }
.vcal-bb-dot { width: 7px; height: 7px; border-radius: 50%; background: hsl(var(--vcal-h), 88%, 62%);
box-shadow: 0 0 12px hsl(var(--vcal-h), 88%, 60%); animation: vcalPulse 2s ease-in-out infinite; }
@keyframes vcalPulse { 0%, 100% { opacity: 1; transform: scale(1); } 50% { opacity: 0.45; transform: scale(0.6); } }
.vcal-bb-title { font-size: 42px; font-weight: 900; letter-spacing: -0.03em; line-height: 1.02; margin: 11px 0 0;
text-shadow: 0 2px 20px rgba(0, 0, 0, 0.6); }
.vcal-bb-sub { font-size: 15px; color: rgba(255, 255, 255, 0.82); margin-top: 9px; font-weight: 600; }
.vcal-bb-se { font-weight: 800; color: #fff; }
.vcal-bb-actions { display: flex; align-items: center; gap: 14px; margin-top: 22px; }
.vcal-bb-btn { display: inline-flex; align-items: center; font-size: 13.5px; font-weight: 800; padding: 12px 22px;
border-radius: 12px; background: #fff; color: #0a0a0e; box-shadow: 0 10px 28px rgba(0, 0, 0, 0.45);
transition: transform 0.15s ease; }
.vcal-bb:hover .vcal-bb-btn { transform: translateY(-2px); }
.vcal-bb-badge { font-size: 12px; font-weight: 800; padding: 6px 13px; border-radius: 999px;
background: rgba(108, 211, 145, 0.18); color: #6cd391; }
@media (prefers-reduced-motion: reduce) { .vcal-bb { transform: none; } .vcal-bb-dot { animation: none; } }
/* "Next up" with 2-3 episodes → diagonal split panels; hover one to expand it */
/* fixed height (not min-height) so hovering — which re-wraps titles at new
widths — never changes the hero's height and shoves the page around */
.vcal-bb-multi { position: relative; display: flex; height: 306px; border-radius: 22px; overflow: hidden;
border: 1px solid rgba(255, 255, 255, 0.08); box-shadow: 0 34px 90px rgba(0, 0, 0, 0.55); background: #08080c; }
.vcal-bb-panel { --vcal-h: 230; position: relative; flex: 1 1 0; flex-grow: 1; min-width: 25%; overflow: hidden;
display: flex; align-items: flex-end; cursor: pointer;
clip-path: polygon(34px 0, 100% 0, calc(100% - 34px) 100%, 0 100%); margin-left: -34px;
transition: flex-grow 0.66s cubic-bezier(0.45, 0, 0.2, 1); }
/* outer edges of the strip stay straight; only the interior seams are diagonal */
.vcal-bb-panel:first-child { clip-path: polygon(0 0, 100% 0, calc(100% - 34px) 100%, 0 100%); margin-left: 0; }
.vcal-bb-panel:last-child { clip-path: polygon(34px 0, 100% 0, 100% 100%, 0 100%); }
/* soonest leads at rest; hovering any panel expands it and collapses the rest */
.vcal-bb-panel--lead { flex-grow: 2.3; }
.vcal-bb-multi:hover .vcal-bb-panel { flex-grow: 0.16; }
.vcal-bb-multi .vcal-bb-panel:hover { flex-grow: 9; }
.vcal-bb-panel::after { content: ''; position: absolute; inset: 0; background: rgba(0, 0, 0, 0.32);
opacity: 0; transition: opacity 0.55s ease; pointer-events: none; }
.vcal-bb-multi:hover .vcal-bb-panel:not(:hover)::after { opacity: 1; }
.vcal-bb-panel .vcal-bb-content { padding: 28px 30px 30px 50px; max-width: 540px; }
.vcal-bb-panel .vcal-bb-title { font-size: 28px;
display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
/* secondary panels tease just the title; sub + actions fade in on expand */
.vcal-bb-panel .vcal-bb-sub, .vcal-bb-panel .vcal-bb-actions { opacity: 0; transition: opacity 0.45s ease; }
.vcal-bb-panel--lead .vcal-bb-sub, .vcal-bb-panel--lead .vcal-bb-actions { opacity: 1; }
.vcal-bb-multi:hover .vcal-bb-panel--lead .vcal-bb-sub,
.vcal-bb-multi:hover .vcal-bb-panel--lead .vcal-bb-actions { opacity: 0; }
.vcal-bb-multi .vcal-bb-panel:hover .vcal-bb-sub,
.vcal-bb-multi .vcal-bb-panel:hover .vcal-bb-actions { opacity: 1; }
.vcal-bb-panel:hover .vcal-bb-btn { transform: translateY(-2px); }
@media (prefers-reduced-motion: reduce) { .vcal-bb-panel { transition: none; } }
@media (max-width: 900px) {
.vcal-hero-wrap { padding-left: 18px; padding-right: 18px; }
.vcal-bb-title { font-size: 30px; } .vcal-bb { min-height: 240px; }
/* stack the diagonal panels vertically on narrow screens */
.vcal-bb-multi { flex-direction: column; height: auto; }
.vcal-bb-panel, .vcal-bb-panel:first-child, .vcal-bb-panel:last-child { clip-path: none; margin-left: 0; min-width: 0; min-height: 150px; }
.vcal-bb-panel--lead, .vcal-bb-multi:hover .vcal-bb-panel, .vcal-bb-multi .vcal-bb-panel:hover { flex-grow: 1; }
.vcal-bb-panel .vcal-bb-sub, .vcal-bb-panel .vcal-bb-actions { opacity: 1; }
.vcal-bb-multi:hover .vcal-bb-panel:not(:hover)::after { opacity: 0; }
}
/* ── Calendar — header controls (week nav + filter) ───────────────────────── */
.vcal-head-row { position: relative; z-index: 1; display: flex; align-items: flex-end; justify-content: space-between; gap: 20px; flex-wrap: wrap; }
.vcal-controls { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.vcal-nav { display: inline-flex; align-items: center; gap: 2px; padding: 4px; border-radius: 12px;
background: rgba(255, 255, 255, 0.06); border: 1px solid rgba(255, 255, 255, 0.08); }
.vcal-nav-btn { width: 34px; height: 32px; border: 0; background: transparent; color: rgba(255, 255, 255, 0.75);
font-size: 20px; font-weight: 700; cursor: pointer; border-radius: 8px; line-height: 1; transition: all 0.15s ease; }
.vcal-nav-btn:hover { background: rgba(255, 255, 255, 0.1); color: #fff; }
.vcal-nav-today { border: 0; background: transparent; color: rgba(255, 255, 255, 0.82); font-size: 12.5px; font-weight: 800;
padding: 7px 12px; border-radius: 8px; cursor: pointer; transition: all 0.15s ease; }
.vcal-nav-today:hover:not(:disabled) { background: rgba(255, 255, 255, 0.1); color: #fff; }
.vcal-nav-today:disabled { opacity: 0.34; cursor: default; }
.vcal-filter { display: inline-flex; gap: 3px; padding: 4px; border-radius: 12px;
background: rgba(255, 255, 255, 0.06); border: 1px solid rgba(255, 255, 255, 0.08); }
.vcal-filter-btn { border: 0; background: transparent; color: rgba(255, 255, 255, 0.7); font-size: 12.5px; font-weight: 700;
padding: 7px 14px; border-radius: 8px; cursor: pointer; transition: all 0.15s ease; }
.vcal-filter-btn:hover { color: #fff; background: rgba(255, 255, 255, 0.08); }
.vcal-filter-btn--on { color: #fff; background: rgba(var(--vcal-accent), 0.9); box-shadow: 0 4px 14px rgba(var(--vcal-accent), 0.32); }
/* view switcher (cards ↔ compact) — mirrors the filter pill group, with icons */
.vcal-views { display: inline-flex; gap: 3px; padding: 4px; border-radius: 12px;
background: rgba(255, 255, 255, 0.06); border: 1px solid rgba(255, 255, 255, 0.08); }
.vcal-view-btn { display: inline-flex; align-items: center; gap: 6px; border: 0; background: transparent;
color: rgba(255, 255, 255, 0.7); font-size: 12.5px; font-weight: 700; padding: 7px 13px; border-radius: 8px;
cursor: pointer; transition: all 0.15s ease; }
.vcal-view-btn svg { opacity: 0.85; }
.vcal-view-btn:hover { color: #fff; background: rgba(255, 255, 255, 0.08); }
.vcal-view-btn--on { color: #fff; background: rgba(var(--vcal-accent), 0.9); box-shadow: 0 4px 14px rgba(var(--vcal-accent), 0.32); }
/* Compact view — drop the episode art to fit a lot more on screen */
.vcal-grid.vcal-view--compact .vcal-art { display: none; }
.vcal-grid.vcal-view--compact .vcal-slot { gap: 8px; padding: 13px 10px; }
.vcal-grid.vcal-view--compact .vcal-card { border-radius: 10px; }
.vcal-grid.vcal-view--compact .vcal-info { padding: 10px 12px; }
.vcal-grid.vcal-view--compact .vcal-show { margin-top: 4px; }
/* the art carried the library ✓ — surface ownership as a left accent stripe instead */
.vcal-grid.vcal-view--compact .vcal-cell--owned .vcal-card { box-shadow: inset 3px 0 0 #6cd391; }
.vcal-grid.vcal-view--compact .vcal-cell--owned .vcal-info { padding-left: 15px; }
/* catch-up button: queue already-aired missing episodes to the wishlist */
.vcal-addmissing { display: inline-flex; align-items: center; gap: 7px; padding: 9px 16px; border-radius: 11px;
border: 1px solid rgba(var(--accent-rgb, 88 101 242), 0.4); cursor: pointer; font-size: 12.5px; font-weight: 800;
color: #fff; background: rgba(var(--accent-rgb, 88 101 242), 0.16);
transition: background 0.15s ease, border-color 0.15s ease, transform 0.15s ease; }
.vcal-addmissing:hover { background: rgba(var(--accent-rgb, 88 101 242), 0.3); border-color: rgba(var(--accent-rgb, 88 101 242), 0.7); transform: translateY(-1px); }
.vcal-addmissing:disabled { opacity: 0.5; cursor: default; transform: none; }
.vcal-addmissing.hidden { display: none; }
.vcal-addmissing-ic { font-size: 15px; font-weight: 900; line-height: 1; }
@media (max-width: 720px) { .vcal-head-row { flex-direction: column; align-items: stretch; } .vcal-controls { justify-content: space-between; } }
/* ══════════════════════════════════════════════════════════════════════════
Watchlist — shared "add to watchlist" button (.vwl-btn) + the Watchlist page
(.vwlp-*). The button is the video mirror of the music ya-watchlist-btn.
══════════════════════════════════════════════════════════════════════════ */
/* Shared eye button — overlaid top-right on a show poster / person photo. */
.vwl-btn {
position: absolute; top: 8px; right: 8px; z-index: 4;
width: 30px; height: 30px; border-radius: 9px;
display: flex; align-items: center; justify-content: center;
background: rgba(0, 0, 0, 0.55); backdrop-filter: blur(8px);
border: 1px solid rgba(255, 255, 255, 0.14); color: rgba(255, 255, 255, 0.82);
cursor: pointer; opacity: 0; transform: translateY(-2px);
transition: opacity 0.18s ease, transform 0.18s ease, background 0.18s ease,
color 0.18s ease, border-color 0.18s ease; }
.vwl-btn:hover { background: rgba(0, 0, 0, 0.78); color: #fff; border-color: rgba(255, 255, 255, 0.3); }
.vwl-btn.active { opacity: 1; transform: none;
color: rgb(var(--accent-rgb, 88 101 242));
background: rgba(var(--accent-rgb, 88 101 242), 0.18);
border-color: rgba(var(--accent-rgb, 88 101 242), 0.55); }
.vwl-btn:disabled { opacity: 0.5; cursor: default; }
/* hover-reveal on the cards that host it (always shown once active / on touch) */
.library-artist-card:hover .vwl-btn, .vwlp-card:hover .vwl-btn,
.vd-cast-card:hover .vwl-btn, .vsr-card:hover .vwl-btn, .vd-sim-card:hover .vwl-btn {
opacity: 1; transform: none; }
@media (hover: none) { .vwl-btn { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .vwl-btn { transition: opacity 0.18s ease; transform: none; } }
/* ── Watchlist page ───────────────────────────────────────────────────────── */
.vwlp-page { color: var(--text-primary, #fff); padding: 0 0 70px; }
.vwlp-head { position: relative; padding: 30px 40px 0; overflow: hidden; }
.vwlp-head-glow { position: absolute; top: -190px; left: 50%; transform: translateX(-50%);
width: 860px; height: 390px; pointer-events: none; z-index: 0;
background: radial-gradient(56% 70% at 50% 0%, rgba(var(--accent-rgb, 88 101 242), 0.22), transparent 70%); filter: blur(10px); }
.vwlp-head-row { position: relative; z-index: 1; display: flex; align-items: flex-end;
justify-content: space-between; gap: 20px; flex-wrap: wrap; }
.vwlp-title { font-size: 36px; font-weight: 800; letter-spacing: -0.025em; margin: 0; }
.vwlp-sub { margin: 7px 0 0; color: rgba(255, 255, 255, 0.55); font-size: 14px; font-weight: 600; }
.vwlp-tabs { display: inline-flex; gap: 3px; padding: 4px; border-radius: 13px;
background: rgba(255, 255, 255, 0.06); border: 1px solid rgba(255, 255, 255, 0.08); }
.vwlp-tab { border: 0; background: transparent; color: rgba(255, 255, 255, 0.7);
font-size: 13px; font-weight: 800; padding: 8px 16px; border-radius: 9px; cursor: pointer;
display: inline-flex; align-items: center; gap: 8px; transition: all 0.15s ease; }
.vwlp-tab:hover { color: #fff; background: rgba(255, 255, 255, 0.07); }
.vwlp-tab--on { color: #fff; background: rgba(var(--accent-rgb, 88 101 242), 0.9);
box-shadow: 0 4px 14px rgba(var(--accent-rgb, 88 101 242), 0.32); }
.vwlp-tab-n { font-size: 11px; font-weight: 800; min-width: 20px; text-align: center;
padding: 1px 7px; border-radius: 999px; background: rgba(0, 0, 0, 0.25); color: inherit; }
.vwlp-tab--on .vwlp-tab-n { background: rgba(0, 0, 0, 0.28); }
.vwlp-body { padding: 26px 40px 0; }
.vwlp-loading { padding: 80px 0; text-align: center; }
.vwlp-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(158px, 1fr)); gap: 22px 20px; }
.vwlp-grid.hidden { display: none; }
.vwlp-card { position: relative; display: block; text-decoration: none; color: inherit;
transition: transform 0.16s ease; }
.vwlp-card:hover { transform: translateY(-5px); }
.vwlp-card-art { position: relative; aspect-ratio: 2 / 3; border-radius: 14px; overflow: hidden;
background: linear-gradient(140deg, #1a1a22, #0c0c10); border: 1px solid rgba(255, 255, 255, 0.07);
box-shadow: 0 14px 34px rgba(0, 0, 0, 0.4); transition: border-color 0.18s ease, box-shadow 0.18s ease; }
.vwlp-card:hover .vwlp-card-art { border-color: rgba(var(--accent-rgb, 88 101 242), 0.5);
box-shadow: 0 22px 50px rgba(0, 0, 0, 0.55), 0 0 24px rgba(var(--accent-rgb, 88 101 242), 0.22); }
.vwlp-card--person .vwlp-card-art { border-radius: 16px; }
.vwlp-card-img { width: 100%; height: 100%; object-fit: cover; display: block;
opacity: 0; transition: opacity 0.45s ease; }
.vwlp-card-img.vwlp-loaded { opacity: 1; }
.vwlp-card-ph { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
font-size: 40px; opacity: 0.5; }
.vwlp-card-scrim { position: absolute; inset: 0; pointer-events: none;
background: linear-gradient(0deg, rgba(0, 0, 0, 0.4), transparent 42%); }
.vwlp-card-info { padding: 9px 4px 0; }
.vwlp-card-title { display: block; font-size: 13.5px; font-weight: 700; line-height: 1.3;
overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.vwlp-state { text-align: center; padding: 90px 20px; color: rgba(255, 255, 255, 0.6); }
.vwlp-state.hidden { display: none; }
.vwlp-state-ic { font-size: 46px; opacity: 0.5; }
.vwlp-state-title { font-size: 20px; font-weight: 800; color: #fff; margin-top: 12px; }
.vwlp-state-sub { font-size: 14px; margin-top: 6px; max-width: 420px; margin-left: auto; margin-right: auto; }
@media (max-width: 900px) {
.vwlp-head, .vwlp-body { padding-left: 18px; padding-right: 18px; }
.vwlp-grid { grid-template-columns: repeat(auto-fill, minmax(128px, 1fr)); gap: 18px 14px; }
}
/* Ensure the show poster box is a positioning context for its .vwl-btn
(scoped to VIDEO cards so the shared music .library-artist-image is untouched). */
.video-card--clickable .library-artist-image { position: relative; }
/* ── Watchlist page — search toolbar + pagination ─────────────────────────── */
.vwlp-toolbar { padding: 18px 40px 0; display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.vwlp-search { position: relative; flex: 1; max-width: 420px; min-width: 220px; }
.vwlp-search-ic { position: absolute; left: 13px; top: 50%; transform: translateY(-50%);
color: rgba(255, 255, 255, 0.4); pointer-events: none; }
.vwlp-search-input { width: 100%; padding: 11px 14px 11px 38px; border-radius: 12px;
background: rgba(255, 255, 255, 0.05); border: 1px solid rgba(255, 255, 255, 0.1);
color: #fff; font-size: 14px; font-weight: 500; outline: none; transition: border-color 0.15s ease, background 0.15s ease; }
.vwlp-search-input::placeholder { color: rgba(255, 255, 255, 0.35); }
.vwlp-search-input:focus { border-color: rgba(var(--accent-rgb, 88 101 242), 0.6);
background: rgba(255, 255, 255, 0.07); }
.vwlp-pagination { display: flex; align-items: center; justify-content: center; gap: 16px; padding: 30px 0 4px; }
.vwlp-pagination.hidden { display: none; }
.vwlp-page-btn { padding: 9px 16px; border-radius: 10px; font-size: 13px; font-weight: 700;
background: rgba(255, 255, 255, 0.06); border: 1px solid rgba(255, 255, 255, 0.1);
color: rgba(255, 255, 255, 0.85); cursor: pointer; transition: all 0.15s ease; }
.vwlp-page-btn:hover:not(:disabled) { background: rgba(255, 255, 255, 0.12); color: #fff; }
.vwlp-page-btn:disabled { opacity: 0.35; cursor: default; }
.vwlp-page-info { font-size: 13px; font-weight: 700; color: rgba(255, 255, 255, 0.6); min-width: 110px; text-align: center; }
@media (max-width: 900px) { .vwlp-toolbar { padding-left: 18px; padding-right: 18px; } }
/* ══════════════════════════════════════════════════════════════════════════
"Get" button (.vget-btn) + detail/download modal (.vgm-*) — the terminal-
content counterpart to the watchlist eye (movies + ended shows).
══════════════════════════════════════════════════════════════════════════ */
.vget-btn {
position: absolute; top: 8px; right: 8px; z-index: 4;
width: 30px; height: 30px; border-radius: 9px;
display: flex; align-items: center; justify-content: center;
background: rgba(0, 0, 0, 0.55); backdrop-filter: blur(8px);
border: 1px solid rgba(255, 255, 255, 0.16); color: rgba(255, 255, 255, 0.88);
cursor: pointer; opacity: 0; transform: translateY(-2px);
transition: opacity 0.18s ease, transform 0.18s ease, background 0.18s ease, border-color 0.18s ease; }
.vget-btn:hover { background: rgba(var(--accent-rgb, 88 101 242), 0.92); color: #fff;
border-color: rgba(var(--accent-rgb, 88 101 242), 0.92); }
.library-artist-card:hover .vget-btn, .vwlp-card:hover .vget-btn,
.vsr-card:hover .vget-btn, .vd-sim-card:hover .vget-btn { opacity: 1; transform: none; }
@media (hover: none) { .vget-btn { opacity: 1; transform: none; } }
/* modal */
.vgm-overlay { position: fixed; inset: 0; z-index: 9100; display: flex; align-items: center; justify-content: center;
padding: 24px; background: rgba(5, 5, 8, 0.72); backdrop-filter: blur(9px); opacity: 0; transition: opacity 0.2s ease; }
.vgm-overlay.vgm-open { opacity: 1; }
.vgm-modal { position: relative; width: min(680px, 100%); max-height: 90vh; overflow-y: auto;
border-radius: 22px; background: #101015; border: 1px solid rgba(255, 255, 255, 0.08);
box-shadow: 0 50px 130px rgba(0, 0, 0, 0.72); transform: translateY(16px) scale(0.985);
transition: transform 0.26s cubic-bezier(0.2, 0.7, 0.2, 1); }
.vgm-overlay.vgm-open .vgm-modal { transform: none; }
.vgm-modal::-webkit-scrollbar { width: 9px; }
.vgm-modal::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, 0.14); border-radius: 5px; }
.vgm-close { position: absolute; top: 14px; right: 14px; z-index: 3; width: 36px; height: 36px; border-radius: 50%;
border: 1px solid rgba(255, 255, 255, 0.18); background: rgba(0, 0, 0, 0.45); color: #fff; font-size: 22px;
cursor: pointer; backdrop-filter: blur(6px); display: flex; align-items: center; justify-content: center;
line-height: 1; transition: all 0.15s ease; }
.vgm-close:hover { background: rgba(0, 0, 0, 0.72); border-color: rgba(255, 255, 255, 0.4); }
.vgm-hero { position: relative; min-height: 260px; border-radius: 22px 22px 0 0; overflow: hidden;
display: flex; align-items: flex-end; background-size: cover; background-position: center 22%; background-color: #16161d; }
.vgm-hero-scrim { position: absolute; inset: 0;
background: linear-gradient(0deg, #101015 4%, rgba(16, 16, 21, 0.5) 52%, rgba(16, 16, 21, 0.1)),
radial-gradient(130% 110% at 0% 100%, rgba(var(--accent-rgb, 88 101 242), 0.32), transparent 60%); }
.vgm-hero-content { position: relative; z-index: 1; padding: 26px 28px 20px; width: 100%; }
.vgm-eyebrow { font-size: 12px; font-weight: 800; text-transform: uppercase; letter-spacing: 0.05em;
color: rgba(255, 255, 255, 0.6); }
.vgm-eyebrow:empty { display: none; }
.vgm-title { font-size: 30px; font-weight: 900; letter-spacing: -0.025em; line-height: 1.05; margin: 8px 0 0;
text-shadow: 0 2px 18px rgba(0, 0, 0, 0.55); }
.vgm-meta { display: flex; gap: 16px; margin-top: 11px; flex-wrap: wrap; }
.vgm-meta-item { font-size: 13px; font-weight: 700; color: rgba(255, 255, 255, 0.78); }
.vgm-genres { display: flex; gap: 7px; margin-top: 12px; flex-wrap: wrap; }
.vgm-genres:empty { display: none; }
.vgm-genre { font-size: 11px; font-weight: 700; padding: 3px 10px; border-radius: 999px;
background: rgba(255, 255, 255, 0.1); color: rgba(255, 255, 255, 0.82); }
.vgm-body { padding: 20px 28px 4px; }
.vgm-overview { font-size: 14px; line-height: 1.65; color: rgba(255, 255, 255, 0.82); margin: 0; }
.vgm-overview--none { color: rgba(255, 255, 255, 0.4); font-style: italic; }
.vgm-actions { display: flex; justify-content: flex-end; gap: 10px; padding: 20px 28px 26px; }
.vgm-btn { font-size: 13px; font-weight: 800; padding: 11px 20px; border-radius: 12px; cursor: pointer;
border: 1px solid transparent; transition: all 0.15s ease; }
.vgm-btn--ghost { background: rgba(255, 255, 255, 0.06); border-color: rgba(255, 255, 255, 0.12); color: rgba(255, 255, 255, 0.82); }
.vgm-btn--ghost:hover { background: rgba(255, 255, 255, 0.12); color: #fff; }
.vgm-btn--primary { background: rgb(var(--accent-rgb, 88 101 242)); color: #fff;
box-shadow: 0 8px 24px rgba(var(--accent-rgb, 88 101 242), 0.4); }
.vgm-btn--primary:hover { filter: brightness(1.08); transform: translateY(-1px); }
@media (max-width: 560px) { .vgm-actions { flex-direction: column-reverse; } .vgm-btn { width: 100%; } }
/* ── Get-modal: poster + ratings + owned-note + next-up ───────────────────── */
/* Poster floats over the hero bottom-left; content shifts right to clear it. */
.vgm-poster { position: absolute; left: 28px; bottom: 18px; z-index: 2; width: 104px; aspect-ratio: 2 / 3;
object-fit: cover; border-radius: 10px; background: #16161d;
border: 1px solid rgba(255, 255, 255, 0.16);
box-shadow: 0 14px 34px rgba(0, 0, 0, 0.6), 0 0 0 1px rgba(0, 0, 0, 0.4); }
.vgm-poster[hidden] { display: none; }
.vgm-hero.vgm-has-poster .vgm-hero-content { padding-left: 152px; }
@media (max-width: 560px) { .vgm-poster { width: 78px; left: 20px; }
.vgm-hero.vgm-has-poster .vgm-hero-content { padding-left: 112px; } }
/* Ratings strip — branded source chips (IMDb / RT / Metacritic). */
.vgm-ratings { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 16px; }
.vgm-ratings[hidden] { display: none; }
.vgm-rating { display: inline-flex; align-items: baseline; gap: 6px; padding: 5px 11px; border-radius: 9px;
background: rgba(255, 255, 255, 0.05); border: 1px solid rgba(255, 255, 255, 0.09); }
.vgm-rating-src { font-size: 10px; font-weight: 800; text-transform: uppercase; letter-spacing: 0.04em;
color: rgba(255, 255, 255, 0.5); }
.vgm-rating-val { font-size: 14px; font-weight: 900; color: #fff; letter-spacing: -0.01em; }
.vgm-rating--imdb { background: rgba(245, 197, 24, 0.1); border-color: rgba(245, 197, 24, 0.32); }
.vgm-rating--imdb .vgm-rating-src { color: #f5c518; }
.vgm-rating--rt { background: rgba(250, 50, 11, 0.1); border-color: rgba(250, 50, 11, 0.3); }
.vgm-rating--rt .vgm-rating-src { color: #ff6446; }
.vgm-rating--mc { background: rgba(108, 211, 145, 0.1); border-color: rgba(108, 211, 145, 0.3); }
.vgm-rating--mc .vgm-rating-src { color: #6cd391; }
/* Owned-movie note — "in your library" with the best version's quality. */
.vgm-owned { display: flex; align-items: center; gap: 9px; margin-top: 16px; padding: 12px 14px; border-radius: 12px;
background: rgba(108, 211, 145, 0.08); border: 1px solid rgba(108, 211, 145, 0.26); }
.vgm-owned[hidden] { display: none; }
.vgm-owned-ic { font-size: 14px; font-weight: 900; color: #6cd391; flex-shrink: 0; }
.vgm-owned-txt { font-size: 13px; color: rgba(255, 255, 255, 0.7); }
.vgm-owned-txt strong { color: #8fe7af; font-weight: 800; }
/* Next-episode line — the soonest upcoming episode for an airing show. */
.vgm-next { display: flex; align-items: center; gap: 11px; margin-top: 16px; padding: 12px 14px; border-radius: 12px;
background: rgba(var(--accent-rgb, 88 101 242), 0.09); border: 1px solid rgba(var(--accent-rgb, 88 101 242), 0.26); }
.vgm-next[hidden] { display: none; }
.vgm-next-ic { font-size: 11px; color: rgb(var(--accent-rgb, 88 101 242)); flex-shrink: 0; }
.vgm-next-txt { font-size: 13px; color: rgba(255, 255, 255, 0.78); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.vgm-next-txt strong { color: #fff; font-weight: 800; }
.vgm-next-date { margin-left: auto; flex-shrink: 0; font-size: 12px; font-weight: 800; color: #c4cbff; }
/* Watchlist card richness — status pill + episode-count meta + sort select */
.vwlp-pill { position: absolute; top: 8px; left: 8px; z-index: 3;
font-size: 10.5px; font-weight: 800; text-transform: uppercase; letter-spacing: 0.03em;
padding: 3px 8px; border-radius: 7px; backdrop-filter: blur(6px);
background: rgba(0, 0, 0, 0.55); color: rgba(255, 255, 255, 0.9); border: 1px solid rgba(255, 255, 255, 0.12); }
.vwlp-pill--airing { background: rgba(108, 211, 145, 0.22); color: #8fe7af; border-color: rgba(108, 211, 145, 0.4); }
.vwlp-pill--soon { background: rgba(var(--accent-rgb, 88 101 242), 0.24); color: #c4cbff; border-color: rgba(var(--accent-rgb, 88 101 242), 0.45); }
.vwlp-pill--ended { background: rgba(255, 255, 255, 0.1); color: rgba(255, 255, 255, 0.6); }
.vwlp-card-meta { display: block; font-size: 11.5px; font-weight: 600; color: rgba(255, 255, 255, 0.45); margin-top: 3px; }
.vwlp-sort { padding: 11px 14px; border-radius: 12px; background: rgba(255, 255, 255, 0.05);
border: 1px solid rgba(255, 255, 255, 0.1); color: #fff; font-size: 13px; font-weight: 600;
cursor: pointer; outline: none; transition: border-color 0.15s ease; }
.vwlp-sort:focus { border-color: rgba(var(--accent-rgb, 88 101 242), 0.6); }
.vwlp-sort option { background: #16161d; color: #fff; }
/* The eye/get button anchors to these card roots (other surfaces). Position is
additive (no flow change); buttons are absolute top-right within them. */
.vsr-card, .vd-sim-card, .vd-cast-card { position: relative; }
.vd-cast-card:hover .vget-btn { opacity: 1; transform: none; }
/* Card control GROUP (eye + get can co-exist on an airing show). The wrapper is
positioned top-right; the buttons inside flow statically in a little row. */
.vcard-ctrls { position: absolute; top: 8px; right: 8px; z-index: 4; display: flex; gap: 6px; }
.vcard-ctrls .vwl-btn, .vcard-ctrls .vget-btn { position: static; top: auto; right: auto; }
/* ── Get-modal: season/episode selector + smarter footer ──────────────────── */
.vgm-eps { margin-top: 20px; padding-top: 18px; border-top: 1px solid rgba(255, 255, 255, 0.08); }
.vgm-eps[hidden] { display: none; }
.vgm-eps-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px; }
.vgm-eps-h { font-size: 13px; font-weight: 800; text-transform: uppercase; letter-spacing: 0.05em; color: rgba(255, 255, 255, 0.55); }
.vgm-eps-toggle { display: inline-flex; align-items: center; gap: 7px; font-size: 12.5px; font-weight: 700;
color: rgba(255, 255, 255, 0.6); cursor: pointer; user-select: none; }
.vgm-eps-toggle input { accent-color: rgb(var(--accent-rgb, 88 101 242)); width: 15px; height: 15px; cursor: pointer; }
.vgm-eps-list { display: flex; flex-direction: column; gap: 8px; }
.vgm-season { border: 1px solid rgba(255, 255, 255, 0.07); border-radius: 12px; background: rgba(255, 255, 255, 0.02); overflow: hidden; }
.vgm-season-head { display: flex; align-items: center; gap: 11px; padding: 12px 14px; cursor: pointer; transition: background 0.15s ease; }
.vgm-season-head:hover { background: rgba(255, 255, 255, 0.04); }
.vgm-season-check { display: inline-flex; align-items: center; }
.vgm-season-check input { accent-color: rgb(var(--accent-rgb, 88 101 242)); width: 17px; height: 17px; cursor: pointer; }
.vgm-season-check--lock { color: rgba(108, 211, 145, 0.85); font-size: 14px; font-weight: 900; width: 17px; justify-content: center; }
.vgm-season-name { font-size: 14px; font-weight: 800; color: #fff; }
.vgm-season-meta { font-size: 12px; font-weight: 600; color: rgba(255, 255, 255, 0.45); margin-left: auto; }
.vgm-season-chev { color: rgba(255, 255, 255, 0.4); transition: transform 0.2s ease; font-size: 13px; }
.vgm-season--open .vgm-season-chev { transform: rotate(180deg); }
.vgm-season-eps { display: none; padding: 2px 6px 8px; }
.vgm-season--open .vgm-season-eps { display: block; }
.vgm-season-loading { padding: 14px 12px; font-size: 12.5px; font-weight: 600; color: rgba(255, 255, 255, 0.4); text-align: center; }
.vgm-ep { display: flex; align-items: center; gap: 11px; padding: 8px 10px; border-radius: 9px; cursor: pointer; transition: background 0.12s ease; }
.vgm-ep:hover { background: rgba(255, 255, 255, 0.04); }
.vgm-eps--missing-only .vgm-ep--owned { display: none; }
.vgm-ep-ctrl { width: 18px; display: inline-flex; justify-content: center; flex-shrink: 0; }
.vgm-ep-cb { accent-color: rgb(var(--accent-rgb, 88 101 242)); width: 16px; height: 16px; cursor: pointer; }
.vgm-ep-lock { font-size: 13px; }
.vgm-ep--owned .vgm-ep-lock { color: rgba(108, 211, 145, 0.8); }
.vgm-ep--upcoming .vgm-ep-lock { color: rgba(255, 255, 255, 0.3); }
.vgm-ep-num { font-size: 11.5px; font-weight: 800; color: rgba(255, 255, 255, 0.4); min-width: 30px; flex-shrink: 0; }
.vgm-ep-title { flex: 1; min-width: 0; font-size: 13px; font-weight: 600; color: rgba(255, 255, 255, 0.9); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.vgm-ep--owned .vgm-ep-title, .vgm-ep--upcoming .vgm-ep-title { color: rgba(255, 255, 255, 0.45); }
.vgm-ep-date { font-size: 11.5px; font-weight: 600; color: rgba(255, 255, 255, 0.35); margin-left: 8px; flex-shrink: 0; }
.vgm-ep-badge { font-size: 10px; font-weight: 800; text-transform: uppercase; letter-spacing: 0.03em; padding: 2px 8px; border-radius: 6px; margin-left: 8px; flex-shrink: 0; }
.vgm-ep-badge--owned { background: rgba(108, 211, 145, 0.16); color: #6cd391; }
.vgm-ep-badge--missing { background: rgba(var(--accent-rgb, 88 101 242), 0.18); color: #c4cbff; }
.vgm-ep-badge--soon { background: rgba(255, 255, 255, 0.08); color: rgba(255, 255, 255, 0.5); }
/* footer */
.vgm-sel-count { margin-right: auto; font-size: 13px; font-weight: 700; color: rgba(255, 255, 255, 0.55); }
.vgm-btn--text { background: transparent; border-color: transparent; color: rgba(255, 255, 255, 0.6); padding: 11px 8px; }
.vgm-btn--text:hover { color: #fff; }
.vgm-btn:disabled { opacity: 0.4; cursor: default; transform: none !important; filter: none !important; }
/* "Add to watchlist" offer in the show get-modal (airing + not-yet-followed) */
.vgm-follow { margin-top: 14px; }
.vgm-follow[hidden] { display: none; }
.vgm-follow-row { display: flex; align-items: center; gap: 11px; padding: 13px 14px; border-radius: 12px; cursor: pointer;
background: rgba(var(--accent-rgb, 88 101 242), 0.1); border: 1px solid rgba(var(--accent-rgb, 88 101 242), 0.28); }
.vgm-follow-row:hover { background: rgba(var(--accent-rgb, 88 101 242), 0.14); }
.vgm-follow-row input { accent-color: rgb(var(--accent-rgb, 88 101 242)); width: 17px; height: 17px; cursor: pointer; flex-shrink: 0; }
.vgm-follow-txt { font-size: 13px; color: rgba(255, 255, 255, 0.82); }
.vgm-follow-txt strong { color: #fff; font-weight: 800; }
/* Fully-owned seasons hide while "Missing only" is on (turn it off to re-download). */
.vgm-eps--missing-only .vgm-season--owned { display: none; }
.vgm-eps-allowned { display: none; padding: 22px 14px; text-align: center; font-size: 13.5px; font-weight: 600; color: rgba(108, 211, 145, 0.85); }
.vgm-eps--missing-only .vgm-eps-allowned { display: block; }
/* ══════════════════════════════════════════════════════════════════════════
Get-modal — premium vibe pass: per-title hue glows + motion (--vgm-h set by JS)
══════════════════════════════════════════════════════════════════════════ */
.vgm-overlay { background: rgba(4, 4, 7, 0.78); }
.vgm-modal {
box-shadow: 0 60px 140px rgba(0, 0, 0, 0.75),
0 0 90px hsla(var(--vgm-h, 230), 75%, 55%, 0.20),
inset 0 1px 0 rgba(255, 255, 255, 0.06);
transform: translateY(22px) scale(0.96);
transition: transform 0.42s cubic-bezier(0.16, 1, 0.3, 1), opacity 0.3s ease,
width 0.4s cubic-bezier(0.16, 1, 0.3, 1);
}
.vgm-overlay.vgm-open .vgm-modal { transform: none; }
/* shows expand the modal for the season/episode picker */
.vgm-overlay.vgm-mode-dl-show .vgm-modal { width: min(940px, 100%); }
/* hero — slow Ken Burns drift, hue-tinted scrim, and a drifting light sweep */
.vgm-hero { animation: vgmKen 22s ease-in-out infinite alternate; }
@keyframes vgmKen { from { background-position: center 18%; } to { background-position: center 34%; } }
.vgm-hero-scrim {
background: linear-gradient(0deg, #101015 3%, rgba(16, 16, 21, 0.55) 50%, rgba(16, 16, 21, 0.05)),
radial-gradient(140% 120% at 0% 100%, hsla(var(--vgm-h, 230), 78%, 48%, 0.42), transparent 60%),
radial-gradient(120% 100% at 100% 0%, hsla(var(--vgm-h, 230), 80%, 62%, 0.18), transparent 55%);
}
.vgm-hero::after {
content: ''; position: absolute; inset: 0; z-index: 0; pointer-events: none;
background: linear-gradient(115deg, transparent 34%, hsla(var(--vgm-h, 230), 92%, 78%, 0.07) 49%, transparent 60%);
background-size: 250% 100%; animation: vgmSheen 9s ease-in-out infinite;
}
@keyframes vgmSheen { 0% { background-position: 170% 0; } 55%, 100% { background-position: -70% 0; } }
/* staggered content rise on open */
.vgm-overlay.vgm-open .vgm-hero-content > * { animation: vgmRise 0.55s cubic-bezier(0.2, 0.7, 0.2, 1) both; }
.vgm-hero-content > *:nth-child(1) { animation-delay: 0.05s; }
.vgm-hero-content > *:nth-child(2) { animation-delay: 0.11s; }
.vgm-hero-content > *:nth-child(3) { animation-delay: 0.17s; }
.vgm-hero-content > *:nth-child(4) { animation-delay: 0.23s; }
@keyframes vgmRise { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
.vgm-title { text-shadow: 0 2px 24px rgba(0, 0, 0, 0.65), 0 0 42px hsla(var(--vgm-h, 230), 80%, 55%, 0.28); }
/* poster — hue-aware halo + its own rise (it sits outside hero-content) */
.vgm-poster { box-shadow: 0 14px 34px rgba(0, 0, 0, 0.6), 0 0 0 1px rgba(0, 0, 0, 0.4),
0 0 28px -6px hsla(var(--vgm-h, 230), 80%, 58%, 0.5); }
.vgm-overlay.vgm-open .vgm-poster { animation: vgmRise 0.6s cubic-bezier(0.2, 0.7, 0.2, 1) 0.12s both; }
/* primary CTA — hue-aware gradient + glow + lift */
.vgm-btn--primary {
background: linear-gradient(135deg, hsl(var(--vgm-h, 230), 70%, 58%), hsl(var(--vgm-h, 230), 72%, 47%));
box-shadow: 0 10px 30px hsla(var(--vgm-h, 230), 70%, 45%, 0.45);
}
.vgm-btn--primary:hover:not(:disabled) { transform: translateY(-2px); filter: brightness(1.07);
box-shadow: 0 16px 42px hsla(var(--vgm-h, 230), 75%, 50%, 0.6); }
.vgm-btn--primary:active:not(:disabled) { transform: translateY(0); }
/* close button spins on hover */
.vgm-close { transition: transform 0.25s ease, background 0.2s ease, border-color 0.2s ease; }
.vgm-close:hover { transform: rotate(90deg); }
/* episode rows — accent edge slides in on hover */
.vgm-ep { position: relative; transition: background 0.14s ease, padding-left 0.14s ease; }
.vgm-ep:hover { padding-left: 14px; }
.vgm-ep::before { content: ''; position: absolute; left: 0; top: 8px; bottom: 8px; width: 2px; border-radius: 2px;
background: hsl(var(--vgm-h, 230), 82%, 62%); opacity: 0; transition: opacity 0.14s ease; }
.vgm-ep:hover::before { opacity: 0.75; }
/* the watchlist offer — gentle breathing glow so it invites the tick */
.vgm-follow-row { animation: vgmFollowPulse 3.6s ease-in-out infinite; }
@keyframes vgmFollowPulse {
0%, 100% { box-shadow: 0 0 0 1px rgba(var(--accent-rgb, 88 101 242), 0.28), 0 0 16px -7px rgba(var(--accent-rgb, 88 101 242), 0.45); }
50% { box-shadow: 0 0 0 1px rgba(var(--accent-rgb, 88 101 242), 0.55), 0 0 28px -4px rgba(var(--accent-rgb, 88 101 242), 0.65); }
}
@media (prefers-reduced-motion: reduce) {
.vgm-hero, .vgm-hero::after, .vgm-follow-row, .vgm-overlay.vgm-open .vgm-poster,
.vgm-overlay.vgm-open .vgm-hero-content > * { animation: none; }
.vgm-modal { transition: opacity 0.2s ease; }
}
/* ══════════════════════════════════════════════════════════════════════════
Discover page — trending hero slideshow + lazy genre/decade rails (.vdsc-*)
══════════════════════════════════════════════════════════════════════════ */
.vdsc-page { padding: 0 0 60px; }
/* ── hero slideshow ───────────────────────────────────────────────────────── */
.vdsc-hero { position: relative; height: 520px; border-radius: 20px; overflow: hidden;
margin: 4px 0 26px; background: #0d0d12; isolation: isolate; }
.vdsc-hero.hidden { display: none; }
.vdsc-slides { position: absolute; inset: 0; }
.vdsc-slide { position: absolute; inset: 0; background-size: cover; background-position: center 18%;
opacity: 0; transition: opacity 1.1s ease; transform: scale(1.06); }
.vdsc-slide--on { opacity: 1; animation: vdscKen 12s ease-out forwards; }
@keyframes vdscKen { from { transform: scale(1.12); } to { transform: scale(1.0); } }
.vdsc-slide-scrim { position: absolute; inset: 0;
background: linear-gradient(90deg, #0b0b10 6%, rgba(11, 11, 16, 0.72) 38%, rgba(11, 11, 16, 0.15) 70%, transparent),
linear-gradient(0deg, #0b0b10 2%, transparent 42%),
radial-gradient(120% 130% at 0% 100%, hsla(var(--vgm-h, 230), 80%, 50%, 0.34), transparent 58%); }
.vdsc-hero-body { position: absolute; left: 40px; bottom: 34px; z-index: 2; max-width: 560px;
animation: vdscRise 0.6s cubic-bezier(0.2, 0.7, 0.2, 1) both; }
@keyframes vdscRise { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: none; } }
.vdsc-hero-eyebrow { font-size: 12px; font-weight: 800; text-transform: uppercase; letter-spacing: 0.07em;
color: hsl(var(--vgm-h, 230), 85%, 78%); margin-bottom: 8px; }
.vdsc-hero-title { font-size: 38px; font-weight: 900; letter-spacing: -0.03em; line-height: 1.04; margin: 0;
color: #fff; text-shadow: 0 3px 26px rgba(0, 0, 0, 0.7), 0 0 46px hsla(var(--vgm-h, 230), 80%, 55%, 0.3); }
.vdsc-hero-pills { display: flex; flex-wrap: wrap; gap: 8px; margin: 13px 0 0; }
.vdsc-hero-pill { font-size: 12px; font-weight: 700; padding: 4px 11px; border-radius: 999px;
background: rgba(255, 255, 255, 0.12); color: rgba(255, 255, 255, 0.9); backdrop-filter: blur(4px); }
.vdsc-hero-ov { font-size: 14px; line-height: 1.6; color: rgba(255, 255, 255, 0.82); margin: 14px 0 0;
display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.vdsc-hero-cta { margin-top: 18px;
background: linear-gradient(135deg, hsl(var(--vgm-h, 230), 70%, 58%), hsl(var(--vgm-h, 230), 72%, 47%)) !important;
box-shadow: 0 12px 32px hsla(var(--vgm-h, 230), 70%, 45%, 0.5) !important; }
.vdsc-hero-cta:hover { transform: translateY(-2px); filter: brightness(1.07); }
.vdsc-dots { position: absolute; right: 26px; bottom: 26px; z-index: 3; display: flex; gap: 8px; }
.vdsc-dot { width: 9px; height: 9px; border-radius: 50%; border: none; cursor: pointer; padding: 0;
background: rgba(255, 255, 255, 0.32); transition: all 0.2s ease; }
.vdsc-dot--on { background: hsl(var(--vgm-h, 230), 85%, 65%); width: 26px; border-radius: 5px; }
/* ── Browse button (shared by the Browse panel + grid header) ─────────────── */
.vdsc-btn { padding: 10px 18px; border-radius: 10px; font-size: 13px; font-weight: 800; cursor: pointer;
border: 1px solid transparent; background: rgb(var(--accent-rgb, 88 101 242)); color: #fff;
box-shadow: 0 8px 22px rgba(var(--accent-rgb, 88 101 242), 0.34); transition: all 0.15s ease; }
.vdsc-btn:hover { filter: brightness(1.08); transform: translateY(-1px); }
.vdsc-btn--ghost { background: rgba(255, 255, 255, 0.06); border-color: rgba(255, 255, 255, 0.12);
color: rgba(255, 255, 255, 0.82); box-shadow: none; }
.vdsc-btn--ghost:hover { background: rgba(255, 255, 255, 0.12); color: #fff; }
/* ── shelves (lazy rails) ─────────────────────────────────────────────────── */
.vdsc-shelves.hidden, .vdsc-grid-wrap.hidden { display: none; }
.vdsc-shelf { margin: 0 0 30px; }
.vdsc-shelf-head { display: flex; align-items: center; justify-content: space-between; margin: 0 0 13px; }
.vdsc-shelf-title { font-size: 19px; font-weight: 800; letter-spacing: -0.01em; color: #fff; margin: 0; }
.vdsc-shelf-nav { display: flex; gap: 7px; }
.vdsc-arrow { width: 32px; height: 32px; border-radius: 50%; border: 1px solid rgba(255, 255, 255, 0.12);
background: rgba(255, 255, 255, 0.05); color: rgba(255, 255, 255, 0.8); font-size: 18px; line-height: 1;
cursor: pointer; display: flex; align-items: center; justify-content: center; transition: all 0.15s ease; }
.vdsc-arrow:hover { background: rgba(var(--accent-rgb, 88 101 242), 0.85); border-color: transparent; color: #fff; }
.vdsc-rail { display: flex; gap: 16px; overflow-x: auto; overflow-y: hidden; padding: 6px 2px 12px;
scroll-snap-type: x proximity; scrollbar-width: thin; }
.vdsc-rail::-webkit-scrollbar { height: 8px; }
.vdsc-rail::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, 0.14); border-radius: 4px; }
.vdsc-rail::-webkit-scrollbar-track { background: transparent; }
.vdsc-rail .vsr-card { flex: 0 0 162px; width: 162px; scroll-snap-align: start; }
/* skeleton shimmer while a rail loads */
.vdsc-skel { display: flex; gap: 16px; }
.vdsc-skel-card { flex: 0 0 162px; height: 280px; border-radius: 12px;
background: linear-gradient(100deg, rgba(255, 255, 255, 0.04) 30%, rgba(255, 255, 255, 0.09) 50%, rgba(255, 255, 255, 0.04) 70%);
background-size: 220% 100%; animation: vdscShimmer 1.4s ease-in-out infinite; }
@keyframes vdscShimmer { from { background-position: 180% 0; } to { background-position: -80% 0; } }
/* ── filter grid ──────────────────────────────────────────────────────────── */
.vdsc-grid { margin-top: 4px; }
.vdsc-more-wrap { display: flex; justify-content: center; margin-top: 26px; }
.vdsc-more { padding: 12px 30px; }
.vdsc-more.hidden { display: none; }
@media (max-width: 720px) {
.vdsc-hero { height: 420px; }
.vdsc-hero-body { left: 22px; bottom: 22px; right: 22px; }
.vdsc-hero-title { font-size: 27px; }
.vdsc-rail .vsr-card, .vdsc-skel-card { flex-basis: 132px; width: 132px; }
}
@media (prefers-reduced-motion: reduce) {
.vdsc-slide, .vdsc-slide--on { animation: none; transition: opacity 0.4s ease; transform: none; }
.vdsc-hero-body { animation: none; }
.vdsc-skel-card { animation: none; }
}
/* ── Discover v2: ambient glow + see-all + grid head + hide-owned + polish ─── */
.vdsc-page { position: relative; overflow-x: clip; }
.vdsc-hero, .vdsc-browse, .vdsc-shelves, .vdsc-grid-wrap { position: relative; z-index: 1; }
/* a faint page-top color bleed that follows the current hero slide's hue */
.vdsc-amb { position: absolute; top: -40px; left: 0; z-index: 0;
width: 100%; height: 580px; pointer-events: none; opacity: 0.5; transition: opacity 0.7s ease;
background: radial-gradient(58% 80% at 50% 0%, hsla(var(--vdsc-amb, 230), 82%, 55%, 0.22), transparent 70%); }
/* "See all" → opens the rail as a paged grid */
.vdsc-seeall { font-size: 12.5px; font-weight: 700; color: rgba(255, 255, 255, 0.5); background: none;
border: none; cursor: pointer; padding: 4px 9px; border-radius: 8px; margin-right: 4px;
transition: color 0.15s ease, background 0.15s ease; }
.vdsc-seeall:hover { color: #fff; background: rgba(255, 255, 255, 0.07); }
/* grid (category) header — back button + title */
.vdsc-grid-head { display: flex; align-items: center; gap: 16px; margin: 2px 0 22px; }
.vdsc-grid-title { font-size: 23px; font-weight: 800; letter-spacing: -0.01em; color: #fff; margin: 0; }
/* hide-owned toggle (sits at the far right of the filter bar) */
.vdsc-toggle { display: inline-flex; align-items: center; gap: 7px; margin-left: auto;
font-size: 13px; font-weight: 600; color: rgba(255, 255, 255, 0.7); cursor: pointer; user-select: none; }
.vdsc-toggle input { accent-color: rgb(var(--accent-rgb, 88 101 242)); width: 16px; height: 16px; cursor: pointer; }
.vdsc-hide-owned .vsr-card--owned { display: none; }
/* rails: a gentle fade-in when filled + per-title hue on hover */
.vdsc-shelf--in .vdsc-rail { animation: vdscFade 0.45s ease both; }
@keyframes vdscFade { from { opacity: 0.35; } to { opacity: 1; } }
.vdsc-rail .vsr-card, .vdsc-grid .vsr-card { transition: transform 0.2s ease, box-shadow 0.2s ease; }
.vdsc-rail .vsr-card:hover, .vdsc-grid .vsr-card:hover {
box-shadow: 0 14px 36px rgba(0, 0, 0, 0.5), 0 0 26px -6px hsla(var(--vgm-h, 230), 80%, 58%, 0.5); }
@media (prefers-reduced-motion: reduce) {
.vdsc-shelf--in .vdsc-rail { animation: none; }
.vdsc-amb { transition: none; }
}
/* ── Discover Browse panel — segmented controls + genre/era chips ──────────── */
.vdsc-browse { position: relative; z-index: 1; margin: 6px 0 28px; padding: 16px 18px 18px;
border-radius: 16px; border: 1px solid rgba(255, 255, 255, 0.08);
background: linear-gradient(180deg, rgba(255, 255, 255, 0.05), rgba(255, 255, 255, 0.02));
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.05), 0 18px 50px -30px rgba(var(--accent-rgb, 88 101 242), 0.5); }
.vdsc-browse-top { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
/* segments are now just a row of the same buttons (no sliding pill) */
.vdsc-seg { display: inline-flex; gap: 6px; }
.vdsc-seg::before { display: none; }
/* chip rows (genres, providers, eras) — horizontally scrollable */
.vdsc-chips { display: flex; gap: 8px; overflow-x: auto; padding: 4px 1px 7px; margin-top: 13px;
scrollbar-width: thin; }
.vdsc-chips::-webkit-scrollbar { height: 6px; }
.vdsc-chips::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, 0.13); border-radius: 3px; }
.vdsc-chips--era { margin-top: 0; }
/* Filter buttons (chips + segment buttons) — rounded-rect, each tinted from a
vibey palette (mirrors the music album-detail action buttons); active = filled. */
.vdsc-chip, .vdsc-seg-btn { flex: 0 0 auto; padding: 8px 15px; border-radius: 9px; cursor: pointer;
white-space: nowrap; font-size: 12.5px; font-weight: 700; letter-spacing: -0.01em;
color: rgba(var(--c, 200, 205, 230), 0.64);
background: rgba(var(--c, 200, 205, 230), 0.07);
border: 1px solid rgba(var(--c, 200, 205, 230), 0.18);
transition: color 0.15s ease, background 0.15s ease, border-color 0.15s ease, box-shadow 0.2s ease, transform 0.18s cubic-bezier(0.34, 1.4, 0.5, 1); }
.vdsc-chip:hover, .vdsc-seg-btn:hover { color: rgba(var(--c, 200, 205, 230), 0.96);
background: rgba(var(--c, 200, 205, 230), 0.14); border-color: rgba(var(--c, 200, 205, 230), 0.4); transform: translateY(-1px); }
.vdsc-chip--on, .vdsc-seg-btn--on { color: #fff; border-color: transparent; transform: translateY(-1px);
background: linear-gradient(135deg, rgba(var(--c, 120, 130, 240), 0.96), rgba(var(--c, 120, 130, 240), 0.6));
box-shadow: 0 9px 22px -9px rgba(var(--c, 120, 130, 240), 0.9),
0 0 0 1px rgba(var(--c, 120, 130, 240), 0.42), inset 0 1px 0 rgba(255, 255, 255, 0.25); }
/* Colours carry meaning, not position:
- segments (Movies/TV, sort) → the app accent (they're modes, not categories)
- genre chips → a thematic colour per genre (set inline by JS)
- provider chips → the service's brand colour (set inline in markup)
- era chips → a single warm amber; reset chips ('All/Any …') → neutral
so each --c is provided where it's meaningful and falls back to neutral here. */
.vdsc-seg-btn { --c: var(--accent-rgb, 29, 185, 84); }
.vdsc-chip--reset { --c: 148, 163, 184; } /* All genres / Any service / Any era */
.vdsc-chips--era .vdsc-chip { --c: 245, 158, 11; }
.vdsc-chips--era .vdsc-chip--reset { --c: 148, 163, 184; }
.vdsc-browse-bottom { display: flex; align-items: center; gap: 16px; margin-top: 12px; }
.vdsc-browse-bottom .vdsc-chips { flex: 1; min-width: 0; margin-top: 0; }
.vdsc-browse-go { flex: 0 0 auto; padding: 11px 22px;
box-shadow: 0 10px 26px -8px rgba(var(--accent-rgb, 88 101 242), 0.7); }
.vdsc-browse-go:hover { filter: brightness(1.08); transform: translateY(-1px); }
.vdsc-browse .vdsc-toggle { margin-left: auto; }
@media (max-width: 720px) {
.vdsc-browse-bottom { flex-direction: column; align-items: stretch; }
.vdsc-browse-go { width: 100%; }
}
/* no-TMDB empty state */
.vdsc-empty { text-align: center; padding: 86px 24px; }
.vdsc-empty.hidden { display: none; }
.vdsc-empty-ic { font-size: 46px; margin-bottom: 14px; opacity: 0.85; }
.vdsc-empty-title { font-size: 21px; font-weight: 800; color: #fff; margin-bottom: 9px; }
.vdsc-empty-sub { font-size: 14px; line-height: 1.6; color: rgba(255, 255, 255, 0.58); max-width: 440px; margin: 0 auto; }
.vdsc-empty-sub strong { color: rgba(255, 255, 255, 0.82); font-weight: 700; }
@media (prefers-reduced-motion: reduce) {
.vdsc-seg::before { transition: none; }
.vdsc-chip, .vdsc-chip:hover, .vdsc-chip--on { transition: color 0.15s ease, background 0.15s ease; transform: none; }
}
/* ── hero actions: View CTA + Trailer button ──────────────────────────────── */
.vdsc-hero-actions { display: flex; align-items: center; gap: 12px; margin-top: 18px; flex-wrap: wrap; }
.vdsc-hero-actions .vdsc-hero-cta { margin-top: 0; }
.vdsc-hero-trailer { display: inline-flex; align-items: center; gap: 8px; padding: 11px 19px; border-radius: 12px;
font-size: 13px; font-weight: 800; cursor: pointer; color: #fff; backdrop-filter: blur(6px);
background: rgba(255, 255, 255, 0.1); border: 1px solid rgba(255, 255, 255, 0.22);
transition: background 0.15s ease, border-color 0.15s ease, transform 0.15s ease; }
.vdsc-hero-trailer:hover { background: rgba(255, 255, 255, 0.18); border-color: rgba(255, 255, 255, 0.42); transform: translateY(-1px); }
.vdsc-tr-ic { font-size: 10px; }
/* "More like…" rails get a gradient title as a personalized cue */
.vdsc-shelf--ml .vdsc-shelf-title { color: #fff;
background: linear-gradient(90deg, #fff 35%, hsl(265 85% 78%) 100%);
-webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; }
/* ── trailer lightbox (in-app YouTube embed) ──────────────────────────────── */
.vdsc-tr-overlay { position: fixed; inset: 0; z-index: 9200; display: flex; align-items: center; justify-content: center;
padding: 24px; background: rgba(3, 3, 6, 0.86); backdrop-filter: blur(10px); opacity: 0; transition: opacity 0.2s ease; }
.vdsc-tr-overlay.vdsc-tr-open { opacity: 1; }
.vdsc-tr-box { position: relative; width: min(960px, 100%); }
.vdsc-tr-close { position: absolute; top: -46px; right: 0; width: 38px; height: 38px; border-radius: 50%;
border: 1px solid rgba(255, 255, 255, 0.2); background: rgba(0, 0, 0, 0.5); color: #fff; font-size: 22px; line-height: 1;
cursor: pointer; display: flex; align-items: center; justify-content: center;
transition: background 0.15s ease, transform 0.25s ease; }
.vdsc-tr-close:hover { background: rgba(0, 0, 0, 0.82); transform: rotate(90deg); }
.vdsc-tr-frame { position: relative; aspect-ratio: 16 / 9; border-radius: 14px; overflow: hidden; background: #000;
box-shadow: 0 40px 120px rgba(0, 0, 0, 0.7); display: flex; align-items: center; justify-content: center;
transform: scale(0.97); transition: transform 0.3s cubic-bezier(0.16, 1, 0.3, 1); }
.vdsc-tr-open .vdsc-tr-frame { transform: none; }
.vdsc-tr-frame iframe { width: 100%; height: 100%; border: 0; }
.vdsc-tr-none { color: rgba(255, 255, 255, 0.6); font-size: 15px; font-weight: 600; }
.vdsc-tr-title { margin-top: 14px; text-align: center; font-size: 15px; font-weight: 700; color: rgba(255, 255, 255, 0.85); }
@media (prefers-reduced-motion: reduce) { .vdsc-tr-frame { transition: none; } }
/* infinite-scroll sentinel (invisible trigger near the grid bottom) */
.vdsc-sentinel { height: 1px; width: 100%; }
/* keyboard focus rings (a11y) */
.vdsc-chip:focus-visible, .vdsc-seg-btn:focus-visible, .vdsc-arrow:focus-visible, .vdsc-seeall:focus-visible,
.vdsc-btn:focus-visible, .vdsc-hero-trailer:focus-visible, .vdsc-dot:focus-visible, .vdsc-toggle:focus-within,
.vdsc-page .vsr-card:focus-visible {
outline: 2px solid rgba(var(--accent-rgb, 88 101 242), 0.9); outline-offset: 2px; }
/* ── small screens ────────────────────────────────────────────────────────── */
@media (max-width: 640px) {
.vdsc-browse { padding: 13px 13px 15px; margin-bottom: 22px; }
.vdsc-browse-top { gap: 10px; }
.vdsc-shelf { margin-bottom: 24px; }
.vdsc-shelf-title { font-size: 16px; }
.vdsc-grid-head { flex-wrap: wrap; gap: 10px; }
.vdsc-grid-title { font-size: 18px; }
.vdsc-hero { height: 300px; margin-bottom: 20px; }
.vdsc-hero-body { left: 18px; right: 18px; bottom: 18px; }
.vdsc-hero-title { font-size: 23px; }
.vdsc-hero-ov { -webkit-line-clamp: 3; }
.vdsc-hero-actions { gap: 9px; }
.vdsc-hero-actions .discog-submit-btn, .vdsc-hero-trailer { flex: 1 1 auto; justify-content: center; }
.vdsc-dots { right: 16px; bottom: 16px; }
/* keep the trailer close button on-screen (it sits above the frame on desktop) */
.vdsc-tr-close { top: 6px; right: 6px; background: rgba(0, 0, 0, 0.65); }
}
/* ══════════════════════════════════════════════════════════════════════════
Wishlist page (.vwsh-*) — Movies grid + grouped TV show→season→episode tree
══════════════════════════════════════════════════════════════════════════ */
.vwsh-page { color: var(--text-primary, #fff); padding: 0 0 70px; }
.vwsh-head { position: relative; padding: 30px 40px 0; overflow: hidden; }
.vwsh-head-glow { position: absolute; top: -190px; left: 50%; transform: translateX(-50%);
width: 860px; height: 390px; pointer-events: none; z-index: 0;
background: radial-gradient(56% 70% at 50% 0%, rgba(var(--accent-rgb, 88 101 242), 0.22), transparent 70%); filter: blur(10px); }
.vwsh-head-row { position: relative; z-index: 1; display: flex; align-items: flex-end;
justify-content: space-between; gap: 20px; flex-wrap: wrap; }
.vwsh-title { font-size: 36px; font-weight: 800; letter-spacing: -0.025em; margin: 0; }
.vwsh-sub { margin: 7px 0 0; color: rgba(255, 255, 255, 0.55); font-size: 14px; font-weight: 600; }
.vwsh-tabs { display: inline-flex; gap: 3px; padding: 4px; border-radius: 13px;
background: rgba(255, 255, 255, 0.06); border: 1px solid rgba(255, 255, 255, 0.08); }
.vwsh-tab { border: 0; background: transparent; color: rgba(255, 255, 255, 0.7);
font-size: 13px; font-weight: 800; padding: 8px 16px; border-radius: 9px; cursor: pointer;
display: inline-flex; align-items: center; gap: 8px; transition: all 0.15s ease; }
.vwsh-tab:hover { color: #fff; background: rgba(255, 255, 255, 0.07); }
.vwsh-tab--on { color: #fff; background: rgba(var(--accent-rgb, 88 101 242), 0.9);
box-shadow: 0 4px 14px rgba(var(--accent-rgb, 88 101 242), 0.32); }
.vwsh-tab-n { font-size: 11px; font-weight: 800; min-width: 20px; text-align: center;
padding: 1px 7px; border-radius: 999px; background: rgba(0, 0, 0, 0.25); color: inherit; }
.vwsh-tab--on .vwsh-tab-n { background: rgba(0, 0, 0, 0.28); }
.vwsh-toolbar { padding: 18px 40px 0; display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.vwsh-body { padding: 26px 40px 0; }
.vwsh-search { position: relative; flex: 1; max-width: 420px; min-width: 220px; }
.vwsh-search-ic { position: absolute; left: 13px; top: 50%; transform: translateY(-50%); color: rgba(255, 255, 255, 0.35); }
.vwsh-search-input { width: 100%; padding: 11px 14px 11px 38px; border-radius: 11px; background: rgba(255, 255, 255, 0.05);
border: 1px solid rgba(255, 255, 255, 0.1); color: #fff; font-size: 13.5px; outline: none; transition: border-color 0.15s ease; }
.vwsh-search-input:focus { border-color: rgba(var(--accent-rgb, 29, 185, 84), 0.5); }
.vwsh-loading { padding: 50px; text-align: center; }
.vwsh-state { padding: 70px 24px; text-align: center; }
.vwsh-state.hidden, .vwsh-loading.hidden, .vwsh-pagination.hidden { display: none; }
.vwsh-state-ic { font-size: 42px; margin-bottom: 12px; opacity: 0.8; }
.vwsh-state-title { font-size: 19px; font-weight: 800; color: #fff; margin-bottom: 7px; }
.vwsh-state-sub { font-size: 13.5px; color: rgba(255, 255, 255, 0.5); max-width: 430px; margin: 0 auto; line-height: 1.55; }
.vwsh-pagination { display: flex; align-items: center; justify-content: center; gap: 16px; margin-top: 26px; }
.vwsh-page-btn { padding: 9px 16px; border-radius: 10px; background: rgba(255, 255, 255, 0.05);
border: 1px solid rgba(255, 255, 255, 0.1); color: #fff; font-size: 13px; font-weight: 700; cursor: pointer; }
.vwsh-page-btn:disabled { opacity: 0.4; cursor: default; }
.vwsh-page-info { font-size: 13px; color: rgba(255, 255, 255, 0.5); }
/* movies grid */
.vwsh-grid--movies { display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 22px 18px; }
.vwsh-movie { cursor: pointer; }
.vwsh-movie-art { position: relative; aspect-ratio: 2 / 3; border-radius: 12px; overflow: hidden; background: #16161d;
border: 1px solid rgba(255, 255, 255, 0.07); transition: border-color 0.18s ease, transform 0.18s ease; }
.vwsh-movie:hover .vwsh-movie-art { border-color: rgba(var(--accent-rgb, 29, 185, 84), 0.4); transform: translateY(-3px); }
.vwsh-movie-img { width: 100%; height: 100%; object-fit: cover; display: block; }
.vwsh-movie-ph { width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; font-size: 34px; opacity: 0.4; }
.vwsh-movie-scrim { position: absolute; inset: 0; background: linear-gradient(0deg, rgba(0, 0, 0, 0.5), transparent 45%); opacity: 0; transition: opacity 0.2s; }
.vwsh-movie:hover .vwsh-movie-scrim { opacity: 1; }
.vwsh-movie-info { padding: 8px 2px 0; }
.vwsh-movie-title { display: block; font-size: 13.5px; font-weight: 700; color: #fff; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.vwsh-movie-meta { display: block; font-size: 11.5px; color: rgba(255, 255, 255, 0.45); margin-top: 2px; }
/* shows = the "Nebula" (reuses the music wl-* orb/album/track design). EVERY
video enhancement is scoped under .vwsh-nebula (a class only the video field
gets) so the music wishlist's wl-* styling is never affected. */
.vwsh-nebula .wl-orb-remove { position: absolute; top: 0; right: 0; z-index: 6; width: 22px; height: 22px;
border-radius: 50%; border: 1px solid rgba(255, 255, 255, 0.15); background: rgba(0, 0, 0, 0.62);
color: rgba(255, 255, 255, 0.7); font-size: 11px; line-height: 1; cursor: pointer;
display: flex; align-items: center; justify-content: center; opacity: 0; transition: all 0.15s ease; }
.vwsh-nebula .wl-orb-group:hover .wl-orb-remove,
.vwsh-nebula .wl-orb-group.expanded .wl-orb-remove { opacity: 1; }
.vwsh-nebula .wl-orb-remove:hover { background: rgba(239, 68, 68, 0.85); border-color: transparent; color: #fff; }
/* #1 cinematic expand — blurred poster backdrop + hue glow behind the season fan */
.vwsh-nebula .wl-orb-group.expanded { overflow: hidden;
box-shadow: 0 14px 50px -12px hsla(var(--orb-hue, 230), 70%, 45%, 0.45);
border: 1px solid hsla(var(--orb-hue, 230), 70%, 55%, 0.25); }
.vwsh-nebula .wl-orb-group.expanded::before { content: ''; position: absolute; inset: 0; z-index: 0; pointer-events: none;
background-image: var(--vwsh-poster, none); background-size: cover; background-position: center;
filter: blur(28px) saturate(1.25); opacity: 0.4; transform: scale(1.25); }
.vwsh-nebula .wl-orb-group.expanded::after { content: ''; position: absolute; inset: 0; z-index: 0; pointer-events: none;
background: linear-gradient(180deg, hsla(var(--orb-hue, 230), 55%, 12%, 0.55), rgba(12, 12, 16, 0.92)); }
.vwsh-nebula .wl-orb-group.expanded > * { position: relative; z-index: 1; }
/* episode status dot (used in the episode-card meta line) */
.vwsh-nebula .vwsh-ep-dot { display: inline-block; vertical-align: middle; margin-right: 6px;
width: 7px; height: 7px; border-radius: 50%;
background: rgb(var(--accent-rgb, 29, 185, 84)); box-shadow: 0 0 6px rgba(var(--accent-rgb, 29, 185, 84), 0.6); }
.vwsh-nebula .vwsh-ep-dot--searching { background: #f59e0b; box-shadow: 0 0 6px rgba(245, 158, 11, 0.6); }
.vwsh-nebula .vwsh-ep-dot--downloading { background: #8ab0ff; box-shadow: 0 0 6px rgba(100, 149, 237, 0.6); }
.vwsh-nebula .vwsh-ep-dot--downloaded { background: #4ade80; box-shadow: 0 0 6px rgba(34, 197, 94, 0.6); }
.vwsh-nebula .vwsh-ep-dot--failed { background: #f87171; box-shadow: 0 0 6px rgba(248, 113, 113, 0.6); }
/* #5 sort select (toolbar) */
.vwsh-sort { padding: 11px 14px; border-radius: 12px; background: rgba(255, 255, 255, 0.05);
border: 1px solid rgba(255, 255, 255, 0.1); color: #fff; font-size: 13.5px; font-weight: 600;
cursor: pointer; outline: none; transition: border-color 0.15s ease; }
.vwsh-sort:focus { border-color: rgba(var(--accent-rgb, 29, 185, 84), 0.5); }
.vwsh-sort option { background: #16161d; color: #fff; }
/* video-only: square-ish bubbles (the music orbs are circles) */
.vwsh-nebula .wl-orb, .vwsh-nebula .wl-orb-glow, .vwsh-nebula .wl-orb-img,
.vwsh-nebula .wl-orb-initials, .vwsh-nebula .wl-orb-ring { border-radius: 24%; }
/* #4 acquisition progress — a thin bar across the bubble bottom (done ÷ wanted) */
.vwsh-nebula .vwsh-prog { position: absolute; left: 9%; right: 9%; bottom: 6px; height: 4px; z-index: 3;
border-radius: 3px; pointer-events: none;
background: linear-gradient(90deg, rgb(var(--accent-rgb, 29, 185, 84)) calc(var(--vwsh-prog, 0) * 100%),
rgba(255, 255, 255, 0.16) calc(var(--vwsh-prog, 0) * 100%));
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.5); }
/* bigger square bubbles so the posters breathe */
.vwsh-nebula .wl-orb.orb-sm { width: 84px; height: 84px; }
.vwsh-nebula .wl-orb.orb-md { width: 104px; height: 104px; }
.vwsh-nebula .wl-orb.orb-lg { width: 124px; height: 124px; }
/* expanded header — synopsis (left) · poster (middle) · cast (right). The side
columns hide (:empty) when there's nothing, so a collapsed/cast-less show just
shows the centered bubble (nebula grid unchanged). */
.vwsh-nebula .vwsh-xhead { display: flex; align-items: center; justify-content: center; gap: 24px; width: 100%; }
.vwsh-nebula .vwsh-xhead-mid { flex-shrink: 0; display: flex; flex-direction: column; align-items: center; gap: 6px; }
.vwsh-nebula .vwsh-info-syn { flex: 0 1 340px; min-width: 0; align-self: center; text-align: left;
font-size: 12.5px; line-height: 1.55; color: rgba(255, 255, 255, 0.62);
display: -webkit-box; -webkit-line-clamp: 8; -webkit-box-orient: vertical; overflow: hidden; }
.vwsh-nebula .vwsh-info-cast { flex: 0 1 340px; min-width: 0; align-self: center; display: flex; flex-wrap: wrap;
gap: 12px 10px; align-content: center; justify-content: flex-start; }
.vwsh-nebula .vwsh-info-syn:empty, .vwsh-nebula .vwsh-info-cast:empty { display: none; }
.vwsh-nebula .vwsh-cast { width: 56px; padding: 0; border: none; background: none; cursor: pointer;
display: flex; flex-direction: column; align-items: center; gap: 5px; }
.vwsh-nebula .vwsh-cast-img { position: relative; width: 46px; height: 46px; border-radius: 50%; overflow: hidden;
background: #1c1c24; border: 1px solid rgba(255, 255, 255, 0.12);
transition: transform 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease; }
.vwsh-nebula .vwsh-cast:hover .vwsh-cast-img { transform: translateY(-2px);
border-color: hsla(var(--orb-hue, 230), 70%, 62%, 0.75); box-shadow: 0 6px 16px -4px hsla(var(--orb-hue, 230), 70%, 50%, 0.6); }
.vwsh-nebula .vwsh-cast-img img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.vwsh-nebula .vwsh-cast--ph .vwsh-cast-img img { display: none; }
.vwsh-nebula .vwsh-cast-ini { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
font-size: 13px; font-weight: 800; color: rgba(255, 255, 255, 0.45); }
.vwsh-nebula .vwsh-cast-name { font-size: 9.5px; font-weight: 600; color: rgba(255, 255, 255, 0.55);
text-align: center; line-height: 1.2; max-width: 56px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.vwsh-nebula .vwsh-cast:hover .vwsh-cast-name { color: rgba(255, 255, 255, 0.85); }
@media (max-width: 640px) {
.vwsh-nebula .vwsh-xhead { flex-direction: column; gap: 14px; }
.vwsh-nebula .vwsh-info-syn { flex-basis: auto; text-align: center; }
.vwsh-nebula .vwsh-info-cast { flex-basis: auto; justify-content: center; }
}
.vwsh-nebula .vwsh-info-eyebrow { display: block; font-size: 10px; font-weight: 800; text-transform: uppercase;
letter-spacing: 0.05em; color: hsl(var(--orb-hue, 230) 80% 76%); margin-bottom: 6px; }
/* selected episode card */
.vwsh-nebula .vwsh-epc.vwsh-epc--sel { background: hsla(var(--orb-hue, 230), 48%, 22%, 0.5);
border-color: hsla(var(--orb-hue, 230), 70%, 58%, 0.65); }
/* season = a poster panel on the LEFT (→ show page), episode grid to its RIGHT */
.vwsh-nebula .vwsh-seasons { display: flex; flex-direction: column; gap: 20px; }
.vwsh-nebula .vwsh-szn { display: flex; align-items: flex-start; gap: 16px; }
.vwsh-nebula .vwsh-szn-side { position: relative; flex-shrink: 0; width: 108px; cursor: pointer; text-align: center;
padding: 7px 7px 9px; border-radius: 12px; border: 1px solid transparent; transition: background 0.15s ease, border-color 0.15s ease; }
.vwsh-nebula .vwsh-szn-side:hover { background: hsla(var(--orb-hue, 230), 45%, 22%, 0.4); border-color: hsla(var(--orb-hue, 230), 70%, 58%, 0.4); }
.vwsh-nebula .vwsh-szn-poster { width: 94px; aspect-ratio: 2 / 3; margin: 0 auto; border-radius: 8px; overflow: hidden; background: #16161d;
border: 1px solid rgba(255, 255, 255, 0.08); display: flex; align-items: center; justify-content: center;
transition: transform 0.15s ease, box-shadow 0.15s ease, border-color 0.15s ease; }
.vwsh-nebula .vwsh-szn-side:hover .vwsh-szn-poster { transform: translateY(-2px);
border-color: hsla(var(--orb-hue, 230), 75%, 62%, 0.6); box-shadow: 0 8px 20px hsla(var(--orb-hue, 230), 60%, 30%, 0.5); }
.vwsh-nebula .vwsh-szn-poster img { width: 100%; height: 100%; object-fit: cover; display: block; }
.vwsh-nebula .vwsh-szn-ph { font-size: 26px; opacity: 0.35; }
.vwsh-nebula .vwsh-szn-name { margin-top: 8px; font-size: 13px; font-weight: 800; color: #fff; }
.vwsh-nebula .vwsh-szn-count { margin-top: 2px; font-size: 11px; font-weight: 600; color: rgba(255, 255, 255, 0.42); }
.vwsh-nebula .vwsh-szn-go { margin-top: 5px; font-size: 10.5px; font-weight: 700; letter-spacing: 0.02em;
color: hsl(var(--orb-hue, 230) 80% 74%); opacity: 0; transition: opacity 0.15s ease; }
.vwsh-nebula .vwsh-szn-side:hover .vwsh-szn-go { opacity: 1; }
.vwsh-nebula .vwsh-szn-rm { position: absolute; top: 4px; right: 4px; width: 22px; height: 22px; border-radius: 50%; border: none;
background: rgba(0, 0, 0, 0.5); color: rgba(255, 255, 255, 0.55); font-size: 12px; cursor: pointer;
display: flex; align-items: center; justify-content: center; opacity: 0; transition: all 0.15s ease; }
.vwsh-nebula .vwsh-szn-side:hover .vwsh-szn-rm { opacity: 1; }
.vwsh-nebula .vwsh-szn-rm:hover { background: rgba(239, 68, 68, 0.9); color: #fff; }
.vwsh-nebula .vwsh-ep-grid { flex: 1; min-width: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(232px, 1fr)); gap: 10px;
max-height: 440px; overflow-y: auto; padding: 2px; scrollbar-width: thin; }
.vwsh-nebula .vwsh-epc { position: relative; display: flex; align-items: flex-start; gap: 11px; padding: 9px; cursor: pointer;
border-radius: 10px; background: rgba(255, 255, 255, 0.04); border: 1px solid rgba(255, 255, 255, 0.06);
transition: background 0.15s ease, border-color 0.15s ease; }
.vwsh-nebula .vwsh-epc:hover { background: rgba(255, 255, 255, 0.07); border-color: hsla(var(--orb-hue, 230), 60%, 55%, 0.35); }
.vwsh-nebula .vwsh-epc-thumb { position: relative; flex-shrink: 0; width: 92px; height: 52px; border-radius: 6px; overflow: hidden;
background: #16161d; border: 1px solid rgba(255, 255, 255, 0.08); }
.vwsh-nebula .vwsh-epc-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* no still → a quiet placeholder (faint icon) instead of loud diagonal stripes */
.vwsh-nebula .vwsh-epc-thumb--none { background: rgba(255, 255, 255, 0.03); }
.vwsh-nebula .vwsh-epc-thumb--none img { display: none; }
.vwsh-nebula .vwsh-epc-thumb--none::after { content: '📺'; position: absolute; inset: 0; display: flex;
align-items: center; justify-content: center; font-size: 17px; opacity: 0.22; }
.vwsh-nebula .vwsh-epc-body { flex: 1; min-width: 0; }
.vwsh-nebula .vwsh-epc-title { font-size: 12.5px; font-weight: 700; color: #fff; line-height: 1.3;
display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.vwsh-nebula .vwsh-epc:hover .vwsh-epc-title { color: hsl(var(--orb-hue, 230) 80% 80%); }
.vwsh-nebula .vwsh-epc-meta { margin-top: 3px; font-size: 11px; font-weight: 600; color: rgba(255, 255, 255, 0.42); }
.vwsh-nebula .vwsh-epc-ov { margin-top: 5px; font-size: 11px; line-height: 1.45; color: rgba(255, 255, 255, 0.5);
display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.vwsh-nebula .vwsh-epc-rm { flex-shrink: 0; width: 22px; height: 22px; border-radius: 50%; border: none;
background: rgba(0, 0, 0, 0.35); color: rgba(255, 255, 255, 0.45); font-size: 12px; cursor: pointer;
display: flex; align-items: center; justify-content: center; opacity: 0; transition: all 0.15s ease; }
.vwsh-nebula .vwsh-epc:hover .vwsh-epc-rm { opacity: 1; }
.vwsh-nebula .vwsh-epc-rm:hover { background: rgba(239, 68, 68, 0.85); color: #fff; }
/* status pills + remove button */
.vwsh-st { font-size: 10px; font-weight: 800; text-transform: uppercase; letter-spacing: 0.03em; padding: 3px 8px; border-radius: 6px; flex-shrink: 0; }
.vwsh-st--wanted { background: rgba(var(--accent-rgb, 29, 185, 84), 0.16); color: rgb(var(--accent-rgb, 29, 185, 84)); }
.vwsh-st--searching { background: rgba(245, 158, 11, 0.16); color: #f59e0b; }
.vwsh-st--downloading { background: rgba(100, 149, 237, 0.18); color: #8ab0ff; }
.vwsh-st--done { background: rgba(34, 197, 94, 0.18); color: #4ade80; }
.vwsh-st--failed { background: rgba(248, 113, 113, 0.16); color: #f87171; }
.vwsh-movie-art .vwsh-st { position: absolute; top: 8px; left: 8px; z-index: 2; backdrop-filter: blur(6px); }
.vwsh-rm { flex-shrink: 0; width: 26px; height: 26px; border-radius: 7px; border: 1px solid rgba(255, 255, 255, 0.12);
background: rgba(0, 0, 0, 0.35); color: rgba(255, 255, 255, 0.6); font-size: 17px; line-height: 1; cursor: pointer;
display: flex; align-items: center; justify-content: center; transition: all 0.15s ease; }
.vwsh-rm:hover { background: rgba(248, 113, 113, 0.85); border-color: transparent; color: #fff; }
.vwsh-rm:disabled { opacity: 0.4; cursor: default; }
.vwsh-movie-art .vwsh-rm { position: absolute; top: 8px; right: 8px; z-index: 3; opacity: 0; }
.vwsh-movie:hover .vwsh-movie-art .vwsh-rm { opacity: 1; }
.vwsh-season-head .vwsh-rm, .vwsh-ep .vwsh-rm { width: 24px; height: 24px; font-size: 15px; }
.vwsh-season-head .vwsh-rm { margin-left: 10px; }
@media (hover: none) { .vwsh-movie-art .vwsh-rm { opacity: 1; } }
@media (max-width: 900px) {
.vwsh-head, .vwsh-toolbar, .vwsh-body { padding-left: 18px; padding-right: 18px; }
.vwsh-grid--movies { grid-template-columns: repeat(auto-fill, minmax(128px, 1fr)); gap: 18px 14px; }
}
/* ══ YouTube channels (search chip · wishlist channel blocks · watchlist cards) ══
Scoped .vyt-* — never touches music wl-* or the TMDB vwsh-* nebula. */
.vyt-avatar--ph { display: inline-flex; align-items: center; justify-content: center;
background: linear-gradient(135deg, #ff3b3b, #b3122a); color: #fff; font-weight: 800; }
/* ── Search page: the pasted-channel Follow chip ─────────────────────────── */
.vyt-search { margin-top: 4px; }
.vyt-chip { border-radius: 16px; border: 1px solid rgba(255, 59, 59, 0.28);
background: linear-gradient(180deg, rgba(255, 59, 59, 0.07), rgba(255, 255, 255, 0.02));
padding: 16px 18px; max-width: 720px; }
.vyt-chip-head { display: flex; align-items: center; gap: 15px; }
.vyt-chip-avatar { flex-shrink: 0; width: 60px; height: 60px; border-radius: 50%; object-fit: cover;
font-size: 20px; border: 2px solid rgba(255, 59, 59, 0.5); }
.vyt-chip-meta { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.vyt-chip-badge { font-size: 10.5px; font-weight: 800; letter-spacing: 0.08em; text-transform: uppercase;
color: #ff6b6b; }
.vyt-chip-title { font-size: 19px; font-weight: 800; color: #fff; line-height: 1.15;
white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.vyt-chip-sub { font-size: 12.5px; font-weight: 600; color: rgba(255, 255, 255, 0.5); }
.vyt-follow { flex-shrink: 0; border: 0; cursor: pointer; border-radius: 999px; padding: 10px 20px;
font-size: 13px; font-weight: 800; background: #ff3b3b; color: #fff; transition: all 0.15s ease;
box-shadow: 0 6px 18px rgba(255, 59, 59, 0.35); }
.vyt-follow:hover { transform: translateY(-1px); background: #ff5252; }
.vyt-follow:disabled { opacity: 0.6; cursor: default; }
.vyt-follow--on { background: rgba(255, 255, 255, 0.1); color: #6cd391; box-shadow: none; }
.vyt-strip { display: flex; gap: 7px; margin-top: 14px; overflow: hidden; }
.vyt-strip-cell { flex: 1 1 0; min-width: 0; aspect-ratio: 16 / 9; border-radius: 7px; overflow: hidden;
background: #16161d; }
.vyt-strip-cell img { width: 100%; height: 100%; object-fit: cover; display: block; }
.vyt-miss { padding: 22px; border-radius: 14px; background: rgba(255, 255, 255, 0.03);
border: 1px dashed rgba(255, 255, 255, 0.12); color: rgba(255, 255, 255, 0.6); font-size: 13.5px; }
.vyt-miss code { background: rgba(255, 255, 255, 0.08); padding: 2px 7px; border-radius: 6px; color: #fff; }
/* ── Wishlist YouTube tab: channel block = header + flat video feed ───────── */
.vyt-field { display: flex; flex-direction: column; gap: 16px; }
.vyt-chan { border-radius: 16px; border: 1px solid rgba(255, 255, 255, 0.07);
background: rgba(255, 255, 255, 0.02); overflow: hidden; }
.vyt-chan-hd { display: flex; align-items: center; gap: 14px; padding: 13px 16px; cursor: pointer;
transition: background 0.15s ease; }
.vyt-chan-hd:hover { background: rgba(255, 59, 59, 0.06); }
.vyt-chan-avatar { flex-shrink: 0; width: 46px; height: 46px; border-radius: 50%; object-fit: cover;
font-size: 16px; border: 2px solid rgba(255, 59, 59, 0.45); }
.vyt-chan-meta { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.vyt-chan-title { font-size: 15.5px; font-weight: 800; color: #fff; line-height: 1.2;
white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.vyt-chan-sub { font-size: 11.5px; font-weight: 600; color: rgba(255, 255, 255, 0.42); }
.vyt-chan-link { flex-shrink: 0; font-size: 11.5px; font-weight: 800; color: #ff6b6b; text-decoration: none;
padding: 6px 11px; border-radius: 999px; border: 1px solid rgba(255, 59, 59, 0.3); }
.vyt-chan-link:hover { background: rgba(255, 59, 59, 0.12); }
.vyt-chan-unfollow { flex-shrink: 0; border: 1px solid rgba(255, 255, 255, 0.12); cursor: pointer;
background: rgba(255, 255, 255, 0.04); color: rgba(255, 255, 255, 0.6); font-size: 11.5px; font-weight: 700;
padding: 6px 13px; border-radius: 999px; transition: all 0.15s ease; }
.vyt-chan-unfollow:hover { background: rgba(239, 68, 68, 0.85); color: #fff; border-color: transparent; }
.vyt-chan-chev { flex-shrink: 0; color: rgba(255, 255, 255, 0.35); transition: transform 0.2s ease; }
.vyt-chan--collapsed .vyt-chan-chev { transform: rotate(-90deg); }
.vyt-vids { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 12px;
padding: 4px 16px 18px; }
.vyt-chan--collapsed .vyt-vids { display: none; }
.vyt-vid { border-radius: 11px; overflow: hidden; background: rgba(255, 255, 255, 0.03);
border: 1px solid rgba(255, 255, 255, 0.06); }
.vyt-vid-thumb { position: relative; aspect-ratio: 16 / 9; background: #16161d; }
.vyt-vid-img { width: 100%; height: 100%; object-fit: cover; display: block; }
.vyt-vid-thumb--none { background: rgba(255, 255, 255, 0.04); }
.vyt-vid-thumb--none::after { content: '▶'; position: absolute; inset: 0; display: flex; align-items: center;
justify-content: center; font-size: 22px; color: rgba(255, 59, 59, 0.4); }
.vyt-vid-rm { position: absolute; top: 7px; right: 7px; width: 24px; height: 24px; border-radius: 50%;
border: none; background: rgba(0, 0, 0, 0.55); color: rgba(255, 255, 255, 0.75); font-size: 12px;
cursor: pointer; display: flex; align-items: center; justify-content: center; opacity: 0; transition: all 0.15s ease; }
.vyt-vid:hover .vyt-vid-rm { opacity: 1; }
.vyt-vid-rm:hover { background: rgba(239, 68, 68, 0.9); color: #fff; }
.vyt-vid-body { padding: 9px 11px 11px; }
.vyt-vid-title { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
font-size: 12.5px; font-weight: 700; color: #fff; line-height: 1.3; }
.vyt-vid-date { display: block; margin-top: 4px; font-size: 11px; font-weight: 600; color: rgba(255, 255, 255, 0.4); }
/* ── Watchlist Channels tab: avatar cards ────────────────────────────────── */
.vyt-wgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 18px; }
.vyt-wcard { position: relative; display: flex; flex-direction: column; align-items: center; text-align: center; }
.vyt-wcard-art { display: block; width: 118px; height: 118px; border-radius: 50%; overflow: hidden;
border: 2px solid rgba(255, 59, 59, 0.4); transition: transform 0.15s ease, box-shadow 0.15s ease; }
.vyt-wcard-art:hover { transform: translateY(-3px); box-shadow: 0 10px 26px rgba(255, 59, 59, 0.35); }
/* Followed-playlist cards: a rounded square (not a circle) + a stacked-list badge */
.vyt-wcard--pl .vyt-wcard-art { position: relative; border-radius: 16px; }
.vyt-wcard-pl-ic { position: absolute; right: 7px; bottom: 7px; z-index: 2;
width: 26px; height: 26px; border-radius: 8px; display: flex; align-items: center; justify-content: center;
background: rgba(0, 0, 0, 0.74); color: #fff; font-size: 13px; }
.vyt-wcard-avatar { width: 100%; height: 100%; object-fit: cover; font-size: 34px; }
.vyt-wcard-unfollow { position: absolute; top: 4px; right: 50%; margin-right: -59px; width: 26px; height: 26px;
border-radius: 50%; border: none; background: rgba(0, 0, 0, 0.6); color: rgba(255, 255, 255, 0.7);
font-size: 12px; cursor: pointer; opacity: 0; transition: all 0.15s ease; }
.vyt-wcard:hover .vyt-wcard-unfollow { opacity: 1; }
.vyt-wcard-unfollow:hover { background: rgba(239, 68, 68, 0.9); color: #fff; }
.vyt-wcard-info { margin-top: 11px; display: flex; flex-direction: column; gap: 2px; max-width: 100%; }
.vyt-wcard-title { font-size: 13.5px; font-weight: 800; color: #fff; line-height: 1.2;
white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.vyt-wcard-meta { font-size: 11.5px; font-weight: 600; color: rgba(255, 255, 255, 0.42); }
/* ══ YouTube channel detail page (.vc-*) — opens like a show/movie ════════════ */
.vc-page { position: relative; max-width: 1240px; margin: 0 auto; padding: 0 30px 60px; }
.vc-banner { position: absolute; top: 0; left: 0; right: 0; height: 260px; z-index: 0;
background-size: cover; background-position: center; }
.vc-banner::after { content: ''; position: absolute; inset: 0;
background: linear-gradient(180deg, rgba(10,10,14,0.35), rgba(10,10,14,0.85) 70%, var(--bg, #0b0b0f)); }
.vc-page[data-has-banner="0"] .vc-banner {
background: radial-gradient(120% 150% at 20% 0%, rgba(255,59,59,0.22), transparent 60%); }
.vc-page .vd-back { position: relative; z-index: 2; margin: 18px 0 0; }
.vc-hero { position: relative; z-index: 1; display: flex; align-items: flex-end; gap: 26px;
padding-top: 120px; }
.vc-avatar-wrap { flex-shrink: 0; width: 132px; height: 132px; border-radius: 50%; overflow: hidden;
border: 4px solid rgba(255,59,59,0.55); box-shadow: 0 16px 40px rgba(0,0,0,0.55);
display: flex; align-items: center; justify-content: center; background: #16161d; }
.vc-avatar { width: 100%; height: 100%; object-fit: cover; display: block; }
.vc-avatar-ph { font-size: 46px; color: rgba(255,59,59,0.7); }
.vc-hero-info { flex: 1; min-width: 0; padding-bottom: 6px; }
.vc-eyebrow { font-size: 11.5px; font-weight: 800; letter-spacing: 0.1em; text-transform: uppercase; color: #ff6b6b; }
.vc-name { font-size: 40px; font-weight: 900; letter-spacing: -0.02em; color: #fff; margin: 6px 0 0; line-height: 1.05; }
.vc-meta { margin-top: 9px; font-size: 13.5px; font-weight: 600; color: rgba(255,255,255,0.62); }
.vc-meta .vc-dot { margin: 0 8px; opacity: 0.5; }
.vc-desc { margin: 14px 0 0; max-width: 760px; font-size: 13.5px; line-height: 1.55; color: rgba(255,255,255,0.62);
display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; white-space: pre-line; }
.vc-actions { display: flex; align-items: center; gap: 14px; margin-top: 18px; }
.vc-follow { border: 0; cursor: pointer; border-radius: 999px; padding: 11px 24px; font-size: 13.5px; font-weight: 800;
background: #ff3b3b; color: #fff; box-shadow: 0 8px 22px rgba(255,59,59,0.4); transition: all 0.15s ease; }
.vc-follow:hover { transform: translateY(-1px); background: #ff5252; }
.vc-follow:disabled { opacity: 0.6; cursor: default; }
.vc-follow--on { background: rgba(255,255,255,0.1); color: #6cd391; box-shadow: none; }
.vc-yt-link { font-size: 13px; font-weight: 800; color: #ff6b6b; text-decoration: none; padding: 10px 16px;
border-radius: 999px; border: 1px solid rgba(255,59,59,0.35); }
.vc-yt-link:hover { background: rgba(255,59,59,0.12); }
.vc-body { position: relative; z-index: 1; margin-top: 40px; }
.vc-videos-head { display: flex; align-items: baseline; gap: 12px; margin-bottom: 16px; }
.vc-videos-title { font-size: 20px; font-weight: 800; color: #fff; margin: 0; }
.vc-videos-count { font-size: 12.5px; font-weight: 600; color: rgba(255,255,255,0.4); }
.vc-videos { display: grid; grid-template-columns: repeat(auto-fill, minmax(264px, 1fr)); gap: 20px 16px; }
.vc-vid { display: flex; flex-direction: column; }
.vc-vid-thumb { position: relative; display: block; aspect-ratio: 16 / 9; border-radius: 12px; overflow: hidden;
background: #16161d; border: 1px solid rgba(255,255,255,0.07); }
.vc-vid-img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform 0.25s ease; }
.vc-vid-thumb:hover .vc-vid-img { transform: scale(1.05); }
.vc-vid-thumb--none { background: rgba(255,255,255,0.04); }
.vc-vid-thumb--none .vc-vid-img { display: none; }
.vc-vid-thumb--none::after { content: '▶'; position: absolute; inset: 0; display: flex; align-items: center;
justify-content: center; font-size: 26px; color: rgba(255,59,59,0.4); }
.vc-vid-dur { position: absolute; right: 7px; bottom: 7px; background: rgba(0,0,0,0.82); color: #fff;
font-size: 11px; font-weight: 700; padding: 2px 6px; border-radius: 5px; }
.vc-vid-play { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
font-size: 30px; color: #fff; opacity: 0; transition: opacity 0.2s ease; text-shadow: 0 2px 14px rgba(0,0,0,0.7); }
.vc-vid-thumb:hover .vc-vid-play { opacity: 0.92; }
.vc-vid-body { margin-top: 9px; flex: 1; }
.vc-vid-title { font-size: 13.5px; font-weight: 700; color: #fff; line-height: 1.3;
display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.vc-vid-meta { margin-top: 4px; font-size: 11.5px; font-weight: 600; color: rgba(255,255,255,0.42); }
.vc-wish { margin-top: 9px; align-self: flex-start; border: 1px solid rgba(255,255,255,0.14); cursor: pointer;
background: rgba(255,255,255,0.05); color: rgba(255,255,255,0.78); font-size: 12px; font-weight: 800;
padding: 7px 14px; border-radius: 999px; transition: all 0.15s ease; }
.vc-wish:hover { background: rgba(255,59,59,0.18); border-color: rgba(255,59,59,0.5); color: #fff; }
.vc-wish:disabled { opacity: 0.6; cursor: default; }
.vc-wish--on { background: rgba(108,211,145,0.16); border-color: rgba(108,211,145,0.4); color: #6cd391; }
.vc-empty { padding: 40px; text-align: center; color: rgba(255,255,255,0.5); font-size: 14px; }
@media (max-width: 720px) {
.vc-page { padding: 0 16px 50px; }
.vc-hero { flex-direction: column; align-items: flex-start; gap: 16px; padding-top: 90px; }
.vc-name { font-size: 28px; }
}
/* "Watch on YouTube" link inside the wishlist info-bar synopsis (YouTube videos) */
.vwsh-nebula .vwsh-yt-watch { display: inline-block; margin-top: 10px; font-size: 12px; font-weight: 800;
color: #ff6b6b; text-decoration: none; padding: 6px 13px; border-radius: 999px;
border: 1px solid rgba(255, 59, 59, 0.35); transition: all 0.15s ease; }
.vwsh-nebula .vwsh-yt-watch:hover { background: rgba(255, 59, 59, 0.14); color: #fff; }
/* ── channel page: tags ribbon, toolbar, load-more, inline detail, playlists ── */
.vc-tags { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 14px; }
.vc-tag { font-size: 11px; font-weight: 700; color: rgba(255,255,255,0.7); background: rgba(255,255,255,0.06);
border: 1px solid rgba(255,255,255,0.1); padding: 4px 10px; border-radius: 999px; }
.vc-section-title { font-size: 20px; font-weight: 800; color: #fff; margin: 0 0 16px; }
.vc-pl-section { margin-bottom: 40px; }
.vc-videos-head { display: flex; align-items: baseline; gap: 12px; }
.vc-tools { margin-left: auto; display: flex; align-items: center; gap: 10px; }
.vc-tool-btn { border: 1px solid rgba(255,255,255,0.14); background: rgba(255,255,255,0.05);
color: rgba(255,255,255,0.72); font-size: 12px; font-weight: 700; padding: 7px 13px; border-radius: 999px; cursor: pointer; transition: all 0.15s ease; }
.vc-tool-btn:hover { color: #fff; background: rgba(255,255,255,0.1); }
.vc-tool-btn--on { background: rgba(108,211,145,0.16); border-color: rgba(108,211,145,0.4); color: #6cd391; }
.vc-sort { background: rgba(255,255,255,0.06); border: 1px solid rgba(255,255,255,0.12); color: #fff;
font-size: 12px; font-weight: 700; padding: 7px 11px; border-radius: 9px; cursor: pointer; }
.vc-more { display: block; margin: 22px auto 0; border: 1px solid rgba(255,59,59,0.35); background: rgba(255,59,59,0.08);
color: #ff6b6b; font-size: 13px; font-weight: 800; padding: 11px 28px; border-radius: 999px; cursor: pointer; transition: all 0.15s ease; }
.vc-more:hover { background: rgba(255,59,59,0.16); color: #fff; }
/* clickable card body → inline detail panel */
.vc-vid-body { margin-top: 9px; flex: 1; cursor: pointer; }
.vc-vid-body:hover .vc-vid-title { color: #ff6b6b; }
.vc-vid-detail { margin-top: 8px; padding: 11px 12px; border-radius: 10px; background: rgba(255,255,255,0.04);
border: 1px solid rgba(255,255,255,0.07); }
.vc-vid-detail-load { font-size: 12px; color: rgba(255,255,255,0.5); }
.vc-vid-stats { font-size: 11.5px; font-weight: 700; color: #ff8a8a; margin-bottom: 6px; }
.vc-vid-desc { font-size: 12px; line-height: 1.55; color: rgba(255,255,255,0.62); white-space: pre-line;
max-height: 220px; overflow-y: auto; scrollbar-width: thin; }
/* playlists as collapsible "seasons" */
.vc-playlists { display: flex; flex-direction: column; gap: 10px; }
.vc-pl { border-radius: 12px; border: 1px solid rgba(255,255,255,0.07); background: rgba(255,255,255,0.02); overflow: hidden; }
.vc-pl-hd { display: flex; align-items: center; gap: 13px; padding: 10px 14px; cursor: pointer; transition: background 0.15s ease; }
.vc-pl-hd:hover { background: rgba(255,59,59,0.06); }
.vc-pl-thumb { flex-shrink: 0; width: 64px; height: 36px; border-radius: 6px; object-fit: cover; background: #16161d;
display: flex; align-items: center; justify-content: center; color: rgba(255,59,59,0.5); font-size: 14px; }
.vc-pl-meta { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.vc-pl-title { font-size: 14px; font-weight: 800; color: #fff; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.vc-pl-count { font-size: 11.5px; font-weight: 600; color: rgba(255,255,255,0.42); }
.vc-pl-chev { flex-shrink: 0; color: rgba(255,255,255,0.35); transition: transform 0.2s ease; }
/* Compact watchlist button on each playlist row (the standard button, shrunk) */
.vc-pl-watch { flex: 0 0 auto; padding: 6px 12px; font-size: 12px; }
.vc-pl-watch .watchlist-icon { font-size: 13px; }
.vc-pl--collapsed .vc-pl-chev { transform: rotate(-90deg); }
.vc-pl-vids { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 16px; padding: 6px 14px 16px; }
.vc-pl--collapsed .vc-pl-vids { display: none; }
.vc-pl-loading { padding: 14px; color: rgba(255,255,255,0.5); font-size: 13px; }
/* YouTube channel cards in the search results grid */
.vyt-result-grid { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); }
.vyt-result { display: flex; flex-direction: column; align-items: center; text-align: center; text-decoration: none;
padding: 14px 8px; border-radius: 14px; transition: background 0.15s ease; }
.vyt-result:hover { background: rgba(255, 59, 59, 0.07); }
.vyt-result-art { width: 92px; height: 92px; border-radius: 50%; overflow: hidden; border: 2px solid rgba(255,59,59,0.4);
display: flex; align-items: center; justify-content: center; background: #16161d; }
.vyt-result-avatar { width: 100%; height: 100%; object-fit: cover; font-size: 26px; }
.vyt-result-info { margin-top: 10px; display: flex; flex-direction: column; align-items: center; gap: 2px; max-width: 100%; }
.vyt-result-badge { font-size: 9.5px; font-weight: 800; letter-spacing: 0.08em; text-transform: uppercase; color: #ff6b6b; }
.vyt-result-title { font-size: 13px; font-weight: 800; color: #fff; line-height: 1.2; max-width: 100%;
white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.vyt-result-sub { font-size: 11px; font-weight: 600; color: rgba(255,255,255,0.42); }
/* ── YouTube channel rendered through the SHOW detail page (.vd-yt-*) ───────── */
.vd-status--yt { background: rgba(255,59,59,0.18); color: #ff8a8a; }
.vd-yt-follow { border: 0; cursor: pointer; border-radius: 999px; padding: 11px 24px; font-size: 13.5px; font-weight: 800;
background: #ff3b3b; color: #fff; box-shadow: 0 8px 22px rgba(255,59,59,0.4); transition: all 0.15s ease; }
.vd-yt-follow:hover { transform: translateY(-1px); background: #ff5252; }
.vd-yt-follow--on { background: rgba(255,255,255,0.12); color: #6cd391; box-shadow: none; }
.vd-yt-link { display: inline-flex; align-items: center; font-size: 13px; font-weight: 800; color: #ff6b6b;
text-decoration: none; padding: 10px 18px; border-radius: 999px; border: 1px solid rgba(255,59,59,0.35); }
.vd-yt-link:hover { background: rgba(255,59,59,0.12); }
.vd-section-h { font-size: 20px; font-weight: 800; color: #fff; margin: 0 0 16px; }
.vd-yt-pl-section { margin-top: 34px; }
/* YouTube episode rows have no index/badge → 4 columns (thumb · info · wish · chev) */
.vd-ep--yt { grid-template-columns: 150px 1fr auto auto; }
/* per-video Wish button inside an episode row */
/* Per-video wishlist toggle = the standard watchlist button (.library-artist-
watchlist-btn), shrunk for the dense rows; .watching → "on the wishlist" green. */
.vd-yt-wishbtn { flex-shrink: 0; align-self: center; padding: 5px 12px; font-size: 11.5px; white-space: nowrap; }
.vd-yt-wishbtn--icon { padding: 5px 9px; }
.vd-yt-wishbtn.watching { color: #6cd391;
background: linear-gradient(135deg, rgba(108,211,145,0.2) 0%, rgba(108,211,145,0.07) 100%);
border-color: rgba(108,211,145,0.4); }
.vd-yt-wishbtn.watching:hover:not(:disabled) {
background: linear-gradient(135deg, rgba(108,211,145,0.3) 0%, rgba(108,211,145,0.12) 100%);
box-shadow: 0 4px 16px rgba(108,211,145,0.2); }
/* playlist video chips */
.vd-yt-plvid { display: flex; flex-direction: column; }
.vd-yt-plvid-thumb { position: relative; display: block; aspect-ratio: 16/9; border-radius: 9px; overflow: hidden; background: #16161d; }
.vd-yt-plvid-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.vd-yt-plvid-play { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; font-size: 22px; color: #fff; opacity: 0; transition: opacity 0.2s ease; }
.vd-yt-plvid-thumb:hover .vd-yt-plvid-play { opacity: 0.9; }
.vd-yt-plvid-title { font-size: 12px; font-weight: 700; color: #fff; line-height: 1.3; margin-top: 7px;
display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.vd-yt-plvid .vd-yt-wishbtn { align-self: flex-start; margin-top: 7px; }
/* YouTube search-results loading state (skeleton cards + "searching…" label) */
.vsr-yt-loading { margin-left: 10px; font-size: 12px; font-weight: 600; color: #ff8a8a; opacity: 0.85; }
.vsr-yt-loading::after { content: ''; display: inline-block; width: 10px; height: 10px; margin-left: 7px;
vertical-align: -1px; border: 2px solid rgba(255,107,107,0.35); border-top-color: #ff6b6b; border-radius: 50%;
animation: vytSpin 0.7s linear infinite; }
@keyframes vytSpin { to { transform: rotate(360deg); } }
.vyt-skel { background: linear-gradient(100deg, rgba(255,255,255,0.05) 30%, rgba(255,255,255,0.12) 50%, rgba(255,255,255,0.05) 70%);
background-size: 200% 100%; animation: vytShimmer 1.3s ease-in-out infinite; }
@keyframes vytShimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }
.vyt-result--skel { pointer-events: none; }
.vyt-result--skel .vyt-result-art { border-color: rgba(255,255,255,0.08); }
.vyt-skel-line { height: 11px; border-radius: 5px; width: 78px; }
.vyt-skel-line--sm { height: 9px; width: 52px; }
@media (prefers-reduced-motion: reduce) { .vyt-skel, .vsr-yt-loading::after { animation: none; } }
/* YouTube Dates worker — simple panel in the Manage Workers modal (no match queue) */
.vem-yt-about { margin: 4px 2px 20px; font-size: 13px; line-height: 1.6; color: rgba(255,255,255,0.6); }
.vem-yt-stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; }
.vem-yt-stat { background: rgba(255,255,255,0.04); border: 1px solid rgba(255,255,255,0.07); border-radius: 12px;
padding: 18px 14px; text-align: center; }
.vem-yt-num { display: block; font-size: 28px; font-weight: 900; color: #fff; line-height: 1; }
.vem-yt-lbl { display: block; margin-top: 7px; font-size: 11.5px; font-weight: 600; letter-spacing: 0.02em;
color: rgba(255,255,255,0.45); }
/* =========================================================================
Video Quality Profile (Settings → Downloads, video side)
========================================================================= */
.vq-block { margin: 16px 0; }
.vq-label { font-size: 12px; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase;
color: rgba(255,255,255,0.65); margin-bottom: 9px; display: flex; align-items: center; gap: 10px; }
.vq-hint { font-size: 11px; font-weight: 500; text-transform: none; letter-spacing: 0;
color: rgba(255,255,255,0.4); }
/* Quality ladder rows reuse music's .hybrid-source-item styling (set in the shared
style.css) for parity with the Download Source list — no custom row CSS. The
cutoff is a separate loose resolution dropdown (not a per-row marker). */
/* cutoff dropdown */
.vq-select { width: 100%; max-width: 360px; padding: 10px 13px; border-radius: 10px;
background: rgba(255,255,255,0.05); border: 1px solid rgba(255,255,255,0.1); color: #fff;
font-size: 13.5px; font-weight: 600; cursor: pointer; outline: none; transition: border-color 0.15s; }
.vq-select:hover, .vq-select:focus { border-color: rgba(var(--accent-rgb),0.6); }
.vq-select option { background: #14181f; color: #fff; }
/* hard-reject chips (on = blocked) */
.vq-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.vq-chip { padding: 7px 14px; border-radius: 999px; cursor: pointer; font-size: 12.5px; font-weight: 600;
background: rgba(255,255,255,0.05); border: 1px solid rgba(255,255,255,0.12);
color: rgba(255,255,255,0.6); transition: all 0.15s; }
.vq-chip:hover { color: #fff; border-color: rgba(255,255,255,0.25); }
.vq-chip.on { background: rgba(239,68,68,0.18); border-color: rgba(239,68,68,0.55); color: #fecaca; }
.vq-chip.on::before { content: '⊘ '; font-weight: 800; }
/* preference rows (label + segmented control) */
.vq-prefs { display: flex; flex-direction: column; gap: 11px; }
.vq-pref-row { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.vq-pref-name { font-size: 13px; font-weight: 700; color: rgba(255,255,255,0.75);
min-width: 56px; }
/* codec + hdr row */
.vq-grid { display: flex; align-items: flex-end; gap: 28px; flex-wrap: wrap; margin: 16px 0; }
.vq-seg { display: inline-flex; background: rgba(255,255,255,0.05); border: 1px solid rgba(255,255,255,0.08);
border-radius: 10px; padding: 3px; gap: 2px; }
.vq-seg button { padding: 7px 14px; border: none; background: none; border-radius: 7px; cursor: pointer;
font-size: 12.5px; font-weight: 600; color: rgba(255,255,255,0.6); transition: all 0.15s; }
.vq-seg button:hover { color: #fff; }
.vq-seg button.active { background: rgb(var(--accent-rgb)); color: #06210f; }
/* custom checkbox (matches the rematch-modal feel) */
.vq-check { display: inline-flex; align-items: center; gap: 10px; cursor: pointer; user-select: none;
color: rgba(255,255,255,0.85); font-size: 13.5px; }
.vq-check input { display: none; }
.vq-check-box { width: 20px; height: 20px; flex: 0 0 20px; border-radius: 6px;
border: 2px solid rgba(255,255,255,0.2); display: grid; place-items: center; transition: all 0.15s; }
.vq-check input:checked + .vq-check-box { background: rgb(var(--accent-rgb)); border-color: transparent; }
.vq-check input:checked + .vq-check-box::after { content: '✓'; color: #06210f; font-size: 13px; font-weight: 900; }
/* size slider */
.vq-slider { -webkit-appearance: none; appearance: none; width: 100%; height: 6px; border-radius: 999px;
background: rgba(255,255,255,0.12); outline: none; cursor: pointer; }
.vq-slider::-webkit-slider-thumb { -webkit-appearance: none; width: 18px; height: 18px; border-radius: 50%;
background: rgb(var(--accent-rgb)); cursor: pointer; box-shadow: 0 2px 6px rgba(0,0,0,0.4); }
.vq-slider::-moz-range-thumb { width: 18px; height: 18px; border: none; border-radius: 50%;
background: rgb(var(--accent-rgb)); cursor: pointer; }
/* ── get-modal "Download" action button ───────────────────────────────────── */
.vgm-download-btn { display: inline-flex; align-items: center; gap: 7px; }
.vgm-download-btn .vgm-download-ic { font-size: 15px; font-weight: 900; line-height: 1; }
/* ── in-place download VIEW inside the get-modal (.vgm-dl + .vdl-* content) ─── */
.vgm-actions[hidden] { display: none; }
.vgm-dl[hidden] { display: none; }
.vgm-dl { animation: vgmRise 0.4s cubic-bezier(0.2, 0.7, 0.2, 1) both; }
.vgm-back { display: inline-flex; align-items: center; gap: 6px; margin-bottom: 16px; padding: 7px 13px;
border-radius: 9px; cursor: pointer; font-size: 12.5px; font-weight: 700;
background: rgba(255, 255, 255, 0.06); border: 1px solid rgba(255, 255, 255, 0.14); color: rgba(255, 255, 255, 0.85);
transition: all 0.15s ease; }
.vgm-back:hover { background: rgba(255, 255, 255, 0.12); border-color: rgba(255, 255, 255, 0.28); color: #fff; }
.vdl-section { margin-bottom: 20px; }
.vdl-section:last-child { margin-bottom: 0; }
.vdl-sec-label { font-size: 12px; font-weight: 800; letter-spacing: 0.05em; text-transform: uppercase;
color: rgba(255, 255, 255, 0.55); margin-bottom: 10px; }
.vdl-sec-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px; }
.vdl-sec-head .vdl-sec-label { margin-bottom: 0; }
/* target chips */
.vdl-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.vdl-chip { position: relative; overflow: hidden; padding: 6px 12px; border-radius: 999px; font-size: 12.5px; font-weight: 700;
background: hsla(var(--vgm-h, 220), 45%, 50%, 0.16); border: 1px solid hsla(var(--vgm-h, 220), 50%, 60%, 0.32);
color: #fff; animation: vdlPop 0.44s both; transition: transform 0.16s ease, box-shadow 0.16s ease; }
.vdl-chip:hover { transform: translateY(-2px); box-shadow: 0 7px 18px -7px hsla(var(--vgm-h, 220), 65%, 52%, 0.7); }
/* sheen sweep across each chip on entrance */
.vdl-chip::after { content: ''; position: absolute; inset: 0; transform: translateX(-130%);
background: linear-gradient(105deg, transparent 30%, rgba(255,255,255,0.28) 50%, transparent 70%);
animation: vdlSheen 0.9s ease 0.25s 1; }
.vdl-chip--ghost { background: rgba(255, 255, 255, 0.05); border-color: rgba(255, 255, 255, 0.1); color: rgba(255, 255, 255, 0.5); }
.vdl-chip--rej { background: rgba(239, 68, 68, 0.16); border-color: rgba(239, 68, 68, 0.4); color: #fecaca; }
.vdl-chip--req { background: rgba(245, 158, 11, 0.16); border-color: rgba(245, 158, 11, 0.4); color: #fde2b3; }
/* owned card + verdict */
.vdl-owned { margin-bottom: 20px; padding: 13px 15px; border-radius: 13px;
background: rgba(255, 255, 255, 0.04); border: 1px solid rgba(255, 255, 255, 0.08); }
.vdl-owned[hidden] { display: none; }
.vdl-owned-row { display: flex; align-items: center; gap: 9px; }
.vdl-owned-ic { font-size: 14px; font-weight: 900; color: #6cd391; flex-shrink: 0; }
.vdl-owned-txt { font-size: 13px; color: rgba(255, 255, 255, 0.72); flex: 1; min-width: 0; }
.vdl-owned-txt strong { color: #8fe7af; font-weight: 800; }
.vdl-verdict { flex-shrink: 0; padding: 4px 11px; border-radius: 999px; font-size: 11px; font-weight: 800;
letter-spacing: 0.02em; }
.vdl-verdict--pending { background: rgba(255, 255, 255, 0.08); color: rgba(255, 255, 255, 0.5);
animation: vdlBreathe 1.3s ease-in-out infinite; }
.vdl-verdict--ok { background: rgba(108, 211, 145, 0.18); color: #8fe7af;
animation: vdlBadge 0.5s cubic-bezier(0.2, 0.8, 0.2, 1) both; }
.vdl-verdict--up { background: rgba(245, 158, 11, 0.18); color: #fbcd7a;
animation: vdlBadge 0.5s cubic-bezier(0.2, 0.8, 0.2, 1) both, vdlUpGlow 2.4s ease-in-out 0.6s infinite; }
.vdl-reasons { margin-top: 10px; display: flex; flex-direction: column; gap: 5px; }
.vdl-reasons:empty { display: none; }
.vdl-reason { font-size: 12px; font-weight: 600; }
.vdl-reason--ok { color: rgba(143, 231, 175, 0.85); }
.vdl-reason--no { color: rgba(251, 205, 122, 0.92); }
/* sources */
.vdl-search-all { position: relative; overflow: hidden; padding: 6px 14px; border-radius: 9px; cursor: pointer;
font-size: 12px; font-weight: 800; background: rgb(var(--accent-rgb)); color: #06210f; border: none;
transition: filter 0.15s, transform 0.15s, box-shadow 0.3s; box-shadow: 0 0 0 0 rgba(var(--accent-rgb), 0.0);
animation: vdlPulse 2.8s ease-in-out infinite; }
.vdl-search-all:hover { filter: brightness(1.1); transform: translateY(-1px); }
.vdl-search-all::after { content: ''; position: absolute; inset: 0; transform: translateX(-130%);
background: linear-gradient(105deg, transparent 35%, rgba(255,255,255,0.5) 50%, transparent 65%); }
.vdl-search-all:hover::after { animation: vdlSheen 0.7s ease 1; }
.vdl-sources { display: flex; flex-direction: column; gap: 10px; }
/* each source carries its own brand colour (--src) so the row glows in-brand */
.vdl-src { --src: 130 130 150; position: relative; overflow: hidden; display: flex; align-items: center; gap: 13px;
padding: 12px 13px; border-radius: 14px; border: 1px solid rgba(var(--src), 0.22);
border-left: 3px solid rgb(var(--src));
background: linear-gradient(100deg, rgba(var(--src), 0.10), rgba(255, 255, 255, 0.025) 60%);
animation: vdlSlide 0.46s both; transition: transform 0.18s ease, border-color 0.18s ease, box-shadow 0.25s ease; }
.vdl-src[data-vdl-src="soulseek"] { --src: 74 163 255; }
.vdl-src[data-vdl-src="torrent"] { --src: 245 158 11; }
.vdl-src[data-vdl-src="usenet"] { --src: 168 85 247; }
.vdl-src[data-vdl-src="youtube"] { --src: 255 64 64; }
.vdl-src:hover { transform: translateY(-2px); border-color: rgba(var(--src), 0.55);
box-shadow: 0 12px 28px -12px rgba(var(--src), 0.75); }
/* brand icon tile */
.vdl-src-icon { flex-shrink: 0; width: 42px; height: 42px; border-radius: 12px; display: grid; place-items: center;
background: linear-gradient(140deg, rgba(var(--src), 0.38), rgba(var(--src), 0.12));
border: 1px solid rgba(var(--src), 0.45); box-shadow: 0 5px 16px -7px rgb(var(--src)); transition: transform 0.2s ease; }
.vdl-src:hover .vdl-src-icon { transform: scale(1.08) rotate(-4deg); }
.vdl-src-emoji { font-size: 19px; line-height: 1; }
.vdl-src-main { display: flex; flex-direction: column; gap: 3px; flex: 1; min-width: 0; }
.vdl-src-name { font-size: 14.5px; font-weight: 800; color: #fff; letter-spacing: -0.01em; }
.vdl-src-meta { display: inline-flex; align-items: center; gap: 7px; }
.vdl-src-dot { width: 7px; height: 7px; border-radius: 50%; background: rgb(var(--src)); flex-shrink: 0;
animation: vdlDot 2.2s ease-in-out infinite; }
.vdl-src--scanning .vdl-src-dot { animation-duration: 0.7s; }
.vdl-src-status { font-size: 11.5px; font-weight: 700; color: rgba(255, 255, 255, 0.45); white-space: nowrap; }
.vdl-src-status--soon { color: #fbcd7a; }
.vdl-src-status--scanning { color: rgb(var(--src)); }
.vdl-src-status--scanning::after { content: ''; animation: vdlDots 1.1s steps(1) infinite; }
/* moving scan bar along the bottom of a row while "searching" — in the source brand */
.vdl-src--scanning::before { content: ''; position: absolute; left: 0; bottom: 0; height: 2px; width: 38%;
border-radius: 2px; background: linear-gradient(90deg, transparent, rgb(var(--src)), transparent);
box-shadow: 0 0 10px 1px rgba(var(--src), 0.7); animation: vdlScan 0.9s ease-in-out infinite; }
.vdl-src-search { flex-shrink: 0; padding: 7px 14px; border-radius: 9px; cursor: pointer; font-size: 12px; font-weight: 800;
background: rgba(var(--src), 0.16); border: 1px solid rgba(var(--src), 0.4); color: #fff;
transition: all 0.15s; }
.vdl-src-search:hover { background: rgba(var(--src), 0.32); border-color: rgba(var(--src), 0.65);
box-shadow: 0 5px 14px -5px rgb(var(--src)); transform: translateY(-1px); }
.vdl-src-search:disabled { opacity: 0.55; cursor: default; transform: none; box-shadow: none; }
.vdl-src-empty { font-size: 13px; color: rgba(255, 255, 255, 0.5); padding: 12px 14px; border-radius: 12px;
background: rgba(255, 255, 255, 0.03); border: 1px dashed rgba(255, 255, 255, 0.12); }
@media (max-width: 560px) {
.vdl-src { flex-wrap: wrap; }
}
/* ── download-view vibe: staggered entrance + life ────────────────────────── */
/* the view's blocks rise in sequence */
.vgm-dl-content > * { animation: vdlRise 0.5s cubic-bezier(0.2, 0.7, 0.2, 1) both; }
.vgm-dl-content > *:nth-child(1) { animation-delay: 0.04s; }
.vgm-dl-content > *:nth-child(2) { animation-delay: 0.12s; }
.vgm-dl-content > *:nth-child(3) { animation-delay: 0.20s; }
.vgm-dl-content > *:nth-child(4) { animation-delay: 0.28s; }
/* chips + source rows cascade within their section */
.vdl-chip:nth-child(1) { animation-delay: 0.10s; }
.vdl-chip:nth-child(2) { animation-delay: 0.16s; }
.vdl-chip:nth-child(3) { animation-delay: 0.22s; }
.vdl-chip:nth-child(4) { animation-delay: 0.28s; }
.vdl-chip:nth-child(5) { animation-delay: 0.34s; }
.vdl-chip:nth-child(6) { animation-delay: 0.40s; }
.vdl-chip:nth-child(7) { animation-delay: 0.46s; }
.vdl-src:nth-child(1) { animation-delay: 0.14s; }
.vdl-src:nth-child(2) { animation-delay: 0.22s; }
.vdl-src:nth-child(3) { animation-delay: 0.30s; }
.vdl-reason { animation: vdlRise 0.4s ease both; }
@keyframes vdlRise { from { opacity: 0; transform: translateY(11px); } to { opacity: 1; transform: none; } }
@keyframes vdlSlide { from { opacity: 0; transform: translateX(-12px); } to { opacity: 1; transform: none; } }
@keyframes vdlPop {
0% { opacity: 0; transform: scale(0.78) translateY(4px); }
62% { opacity: 1; transform: scale(1.06); }
100% { transform: none; } }
@keyframes vdlBadge {
0% { opacity: 0; transform: scale(0.5); }
65% { opacity: 1; transform: scale(1.14); }
100% { transform: none; } }
@keyframes vdlSheen { from { transform: translateX(-130%); } to { transform: translateX(130%); } }
@keyframes vdlPulse {
0%, 100% { box-shadow: 0 0 0 0 rgba(var(--accent-rgb), 0.0); }
50% { box-shadow: 0 0 16px -2px rgba(var(--accent-rgb), 0.55); } }
@keyframes vdlUpGlow {
0%, 100% { box-shadow: 0 0 0 0 rgba(245, 158, 11, 0.0); }
50% { box-shadow: 0 0 14px -2px rgba(245, 158, 11, 0.6); } }
@keyframes vdlBreathe { 0%, 100% { opacity: 0.55; } 50% { opacity: 1; } }
@keyframes vdlScan {
0% { left: -38%; } 100% { left: 100%; } }
@keyframes vdlDot {
0%, 100% { box-shadow: 0 0 0 0 rgba(var(--src), 0.55); }
50% { box-shadow: 0 0 0 5px rgba(var(--src), 0); } }
@keyframes vdlDots {
0% { content: ''; } 25% { content: '.'; } 50% { content: '..'; } 75%, 100% { content: '...'; } }
/* respect reduced-motion: keep the layout, drop the motion */
@media (prefers-reduced-motion: reduce) {
.vgm-dl, .vgm-dl-content > *, .vdl-chip, .vdl-src, .vdl-reason, .vdl-src-dot,
.vdl-verdict--ok, .vdl-verdict--up, .vdl-verdict--pending, .vdl-search-all { animation: none !important; }
.vdl-chip::after, .vdl-search-all::after, .vdl-src--scanning::before { display: none; }
}
/* ── TV show download view: season/episode picker ─────────────────────────── */
.vdl-show-bar { display: flex; align-items: center; gap: 13px; flex-wrap: wrap; margin: 2px 0 16px;
padding: 11px 14px; border-radius: 13px; background: rgba(255, 255, 255, 0.04);
border: 1px solid rgba(255, 255, 255, 0.08); animation: vdlRise 0.45s both; }
.vdl-allchk { display: inline-flex; align-items: center; gap: 8px; cursor: pointer; font-size: 12.5px;
font-weight: 800; color: rgba(255, 255, 255, 0.85); white-space: nowrap; }
.vdl-show-summary { flex: 1; min-width: 120px; font-size: 12px; font-weight: 600; color: rgba(255, 255, 255, 0.5); }
.vdl-search-sel:disabled { animation: none; opacity: 0.45; cursor: default; box-shadow: none; }
.vdl-seasons input[type="checkbox"], .vdl-show-bar input[type="checkbox"] {
accent-color: rgb(var(--accent-rgb)); width: 16px; height: 16px; cursor: pointer; flex-shrink: 0; margin: 0; }
.vdl-seasons { display: flex; flex-direction: column; gap: 9px; }
.vdl-season { border-radius: 13px; border: 1px solid rgba(255, 255, 255, 0.08);
background: rgba(255, 255, 255, 0.025); overflow: hidden; animation: vdlSlide 0.42s both; }
.vdl-season:hover { border-color: rgba(255, 255, 255, 0.14); }
.vdl-season-head { display: flex; align-items: center; gap: 11px; padding: 12px 14px; cursor: pointer;
transition: background 0.15s ease; }
.vdl-season-head:hover { background: rgba(255, 255, 255, 0.04); }
.vdl-season-name { font-size: 14px; font-weight: 800; color: #fff; letter-spacing: -0.01em; }
.vdl-season-meta { flex: 1; font-size: 11.5px; font-weight: 600; color: rgba(255, 255, 255, 0.45); }
.vdl-season-search { flex-shrink: 0; width: 32px; height: 28px; border-radius: 8px; cursor: pointer; font-size: 13px;
background: rgba(var(--accent-rgb), 0.16); border: 1px solid rgba(var(--accent-rgb), 0.35); color: #fff;
transition: all 0.15s ease; }
.vdl-season-search:hover { background: rgba(var(--accent-rgb), 0.3); border-color: rgba(var(--accent-rgb), 0.6);
transform: translateY(-1px); }
.vdl-season-chev { flex-shrink: 0; font-size: 13px; color: rgba(255, 255, 255, 0.5); transition: transform 0.25s ease; }
.vdl-season--open .vdl-season-chev { transform: rotate(180deg); }
.vdl-season-body { max-height: 0; overflow: hidden; transition: max-height 0.32s cubic-bezier(0.2, 0.7, 0.2, 1); }
.vdl-season--open .vdl-season-body { max-height: 5000px; }
.vdl-season-empty { padding: 12px 16px; font-size: 12.5px; color: rgba(255, 255, 255, 0.4); }
.vdl-ep { position: relative; border-top: 1px solid rgba(255, 255, 255, 0.05); }
.vdl-ep-head { display: flex; align-items: center; gap: 10px; padding: 9px 14px 9px 16px; cursor: pointer;
transition: background 0.14s ease; }
.vdl-ep-head:hover { background: rgba(255, 255, 255, 0.035); }
.vdl-ep--owned { opacity: 0.62; }
.vdl-ep--owned:hover { opacity: 0.85; }
.vdl-ep-cell { flex-shrink: 0; display: inline-flex; align-items: center; justify-content: center; width: 18px; }
.vdl-ep-lock { color: rgba(255, 255, 255, 0.3); font-size: 13px; }
.vdl-ep-num { flex-shrink: 0; font: 800 11px/1 'JetBrains Mono', ui-monospace, monospace;
color: rgba(255, 255, 255, 0.5); min-width: 26px; }
.vdl-ep-title { flex: 1; min-width: 0; font-size: 13px; font-weight: 600; color: rgba(255, 255, 255, 0.92);
white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.vdl-ep-status { flex-shrink: 0; font-size: 11px; font-weight: 700; color: rgba(255, 255, 255, 0.4); white-space: nowrap; }
.vdl-ep-status:empty { display: none; }
.vdl-ep-status--scanning { color: hsl(var(--vgm-h, 220), 80%, 72%); }
.vdl-ep-status--scanning::after { content: ''; animation: vdlDots 1.1s steps(1) infinite; }
.vdl-ep-status--soon { color: #fbcd7a; }
.vdl-ep-badge { flex-shrink: 0; font-size: 9.5px; font-weight: 800; letter-spacing: 0.02em; padding: 2px 8px;
border-radius: 999px; text-transform: uppercase; }
.vdl-ep-badge--owned { background: rgba(108, 211, 145, 0.16); color: #8fe7af; }
.vdl-ep-badge--missing { background: hsla(var(--vgm-h, 220), 50%, 55%, 0.2); color: #fff; }
.vdl-ep-badge--soon { background: rgba(255, 255, 255, 0.08); color: rgba(255, 255, 255, 0.5); }
.vdl-ep-chev { flex-shrink: 0; font-size: 12px; color: rgba(255, 255, 255, 0.38); transition: transform 0.22s ease; }
.vdl-ep--open .vdl-ep-chev { transform: rotate(180deg); }
.vdl-ep--scanning::before { content: ''; position: absolute; left: 0; bottom: 0; height: 2px; width: 36%;
border-radius: 2px; background: linear-gradient(90deg, transparent, hsl(var(--vgm-h, 220), 85%, 62%), transparent);
box-shadow: 0 0 9px 1px hsla(var(--vgm-h, 220), 85%, 62%, 0.7); animation: vdlScan 0.9s ease-in-out infinite; }
/* inline per-episode source search */
.vdl-ep-search { max-height: 0; overflow: hidden; transition: max-height 0.3s cubic-bezier(0.2, 0.7, 0.2, 1); }
.vdl-ep--open .vdl-ep-search { max-height: 360px; }
.vdl-ep-srcs { display: flex; flex-direction: column; gap: 7px; padding: 3px 14px 12px 42px; }
.vdl-src--mini { padding: 8px 11px; border-radius: 10px; animation: none; }
.vdl-src--mini .vdl-src-icon { width: 32px; height: 32px; border-radius: 9px; }
.vdl-src--mini .vdl-src-emoji { font-size: 15px; }
.vdl-src--mini .vdl-src-name { font-size: 13px; }
@media (prefers-reduced-motion: reduce) {
.vdl-show-bar, .vdl-season, .vdl-ep--scanning::before { animation: none !important; }
}
/* ── search results (movie/episode/season/series) ─────────────────────────── */
.vdl-results { margin-top: 12px; }
.vdl-results[hidden] { display: none; }
.vdl-results--season { margin: 2px 14px 12px 14px; }
.vdl-ep--open .vdl-ep-search { max-height: 2400px; } /* room for result cards */
.vdl-res-loading { display: flex; align-items: center; gap: 9px; font-size: 12.5px; font-weight: 600;
color: rgba(255, 255, 255, 0.6); padding: 9px 2px; }
.vdl-res-spin { width: 14px; height: 14px; border-radius: 50%; flex-shrink: 0;
border: 2px solid rgba(255, 255, 255, 0.2); border-top-color: rgb(var(--accent-rgb)); animation: vdlSpin 0.7s linear infinite; }
@keyframes vdlSpin { to { transform: rotate(360deg); } }
.vdl-res-empty { font-size: 12.5px; color: rgba(255, 255, 255, 0.45); padding: 9px 2px; }
.vdl-res-head { display: flex; align-items: center; gap: 8px; font-size: 11.5px; font-weight: 700;
color: rgba(255, 255, 255, 0.5); margin: 4px 0 10px; }
.vdl-res-head strong { color: #fff; }
.vdl-res-okn { color: #8fe7af; }
.vdl-res-live, .vdl-res-demo { margin-left: auto; font-size: 10px; font-weight: 800; padding: 2px 8px; border-radius: 999px;
text-transform: uppercase; letter-spacing: 0.04em; }
.vdl-res-live { background: rgba(108, 211, 145, 0.16); color: #8fe7af; }
.vdl-res-demo { background: rgba(245, 158, 11, 0.14); color: #fbcd7a; }
.vdl-res-err { color: #fbcd7a; }
/* result row: [resolution tile] [body: summary + name + meta] [grab] */
.vdl-res { display: flex; align-items: stretch; gap: 12px; border-radius: 13px;
border: 1px solid rgba(255, 255, 255, 0.08); background: rgba(255, 255, 255, 0.035);
padding: 11px 12px; margin-bottom: 8px; animation: vdlRise 0.4s both;
transition: border-color 0.15s ease, background 0.15s ease, transform 0.15s ease; }
.vdl-res:hover { border-color: rgba(var(--accent-rgb), 0.4); background: rgba(255, 255, 255, 0.06); transform: translateY(-1px); }
.vdl-res--rejected { opacity: 0.5; }
.vdl-res--rejected:hover { opacity: 0.82; }
/* resolution tile — the quick-scan anchor */
.vdl-res-res { flex-shrink: 0; width: 52px; display: flex; align-items: center; justify-content: center;
border-radius: 10px; font-size: 14px; font-weight: 900; letter-spacing: -0.02em; color: #06210f; }
.vdl-res-res--4k { background: linear-gradient(140deg, #ffd76a, #f0a830); }
.vdl-res-res--1080 { background: linear-gradient(140deg, rgba(var(--accent-rgb), 1), rgba(var(--accent-rgb), 0.7)); }
.vdl-res-res--720 { background: linear-gradient(140deg, #8fb3ff, #5f86d6); }
.vdl-res-res--sd { background: linear-gradient(140deg, rgba(255,255,255,0.4), rgba(255,255,255,0.22)); color: #11141a; }
.vdl-res-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 5px; }
.vdl-res-line1 { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.vdl-res-summary { font-size: 13.5px; font-weight: 800; color: #fff; letter-spacing: -0.01em; }
.vdl-res-tag { font-size: 9.5px; font-weight: 800; letter-spacing: 0.03em; padding: 2px 7px; border-radius: 5px;
text-transform: uppercase; background: rgba(255, 255, 255, 0.1); color: rgba(255, 255, 255, 0.85); }
.vdl-res-tag--hdr { background: linear-gradient(100deg, rgba(245, 158, 11, 0.4), rgba(168, 85, 247, 0.4)); color: #fff; }
.vdl-res-verdict { margin-left: auto; font-size: 10.5px; font-weight: 800; padding: 3px 9px; border-radius: 999px; white-space: nowrap; }
.vdl-res-verdict--ok { background: rgba(108, 211, 145, 0.18); color: #8fe7af; }
.vdl-res-verdict--no { background: rgba(245, 158, 11, 0.14); color: #fbcd7a; max-width: 60%; overflow: hidden; text-overflow: ellipsis; }
.vdl-res-name { font: 500 11px/1.3 'JetBrains Mono', ui-monospace, monospace; color: rgba(255, 255, 255, 0.42);
white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.vdl-res-meta { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin-top: 1px; }
.vdl-res-stat { display: inline-flex; align-items: center; gap: 4px; font-size: 11.5px; font-weight: 700;
color: rgba(255, 255, 255, 0.6); }
.vdl-res-ico { font-size: 11px; opacity: 0.8; }
.vdl-res-seed { color: #8fe7af; }
.vdl-res-grp { font-family: 'JetBrains Mono', ui-monospace, monospace; color: rgba(255, 255, 255, 0.4); font-weight: 600; }
.vdl-res-grab { flex-shrink: 0; align-self: center; width: 34px; height: 34px; border-radius: 10px; cursor: pointer;
font-size: 16px; font-weight: 900; background: rgb(var(--accent-rgb)); color: #06210f; border: none;
transition: filter 0.15s ease, transform 0.15s ease; }
.vdl-res-grab:hover { filter: brightness(1.12); transform: translateY(-1px) scale(1.04); }
.vdl-btn--busy { opacity: 0.7; cursor: progress; }
/* per-source block (row + its own results) */
.vdl-src-block { display: flex; flex-direction: column; }
.vdl-src-block .vdl-results { margin: 8px 0 2px; }
@media (prefers-reduced-motion: reduce) { .vdl-res, .vdl-res-spin { animation: none !important; } }
/* ── Downloads page (.vdpg-*) ─────────────────────────────────────────────── */
.vdpg-page { max-width: 1000px; margin: 0 auto; padding: 8px 4px 40px; }
.vdpg-head { position: relative; margin-bottom: 22px; padding: 6px 2px; overflow: hidden; }
.vdpg-head-glow { position: absolute; inset: -40% -10% auto -10%; height: 200px; pointer-events: none;
background: radial-gradient(60% 100% at 30% 0%, rgba(var(--accent-rgb), 0.18), transparent 70%); }
.vdpg-head-row { position: relative; display: flex; align-items: flex-end; justify-content: space-between; gap: 16px; }
.vdpg-title { font-size: 34px; font-weight: 900; letter-spacing: -0.03em; margin: 0; color: #fff; }
.vdpg-sub { margin: 6px 0 0; font-size: 13.5px; font-weight: 600; color: rgba(255, 255, 255, 0.5); }
.vdpg-clear { flex-shrink: 0; padding: 9px 16px; border-radius: 10px; cursor: pointer; font-size: 12.5px; font-weight: 800;
background: rgba(255, 255, 255, 0.06); border: 1px solid rgba(255, 255, 255, 0.14); color: rgba(255, 255, 255, 0.85);
transition: all 0.15s ease; }
.vdpg-clear:hover { background: rgba(239, 68, 68, 0.16); border-color: rgba(239, 68, 68, 0.45); color: #fecaca; }
.vdpg-clear[hidden] { display: none; }
.vdpg-list { display: flex; flex-direction: column; gap: 11px; }
/* card is created ONCE then patched in place — the entrance animation plays a single
time on mount, never on a poll (that was the old 'blink'). */
.vdpg-item { display: flex; gap: 15px; padding: 15px 17px; border-radius: 16px; align-items: center;
background: rgba(255, 255, 255, 0.035); border: 1px solid rgba(255, 255, 255, 0.08); border-left: 3px solid transparent;
animation: vdlRise 0.45s both;
transition: border-color 0.3s ease, background 0.25s ease, transform 0.18s ease; }
.vdpg-item:hover { transform: translateY(-2px); border-color: rgba(255, 255, 255, 0.16); background: rgba(255, 255, 255, 0.055); }
.vdpg-item[data-st="dl"] { border-left-color: rgb(var(--accent-rgb));
background: linear-gradient(100deg, rgba(var(--accent-rgb), 0.06), rgba(255, 255, 255, 0.03) 55%); }
.vdpg-item[data-st="ok"] { border-left-color: #6cd391; }
.vdpg-item[data-st="fail"] { border-left-color: #ef4444; }
.vdpg-item[data-st="q"] { border-left-color: rgba(255, 255, 255, 0.3); }
.vdpg-ic { flex-shrink: 0; width: 50px; height: 50px; border-radius: 13px; display: grid; place-items: center;
font-size: 24px; background: rgba(255, 255, 255, 0.05); border: 1px solid rgba(255, 255, 255, 0.08); }
.vdpg-item[data-st="dl"] .vdpg-ic { background: rgba(var(--accent-rgb), 0.12); border-color: rgba(var(--accent-rgb), 0.3); }
.vdpg-body { flex: 1; min-width: 0; }
.vdpg-row1 { display: flex; align-items: center; gap: 10px; }
.vdpg-name { font-size: 15.5px; font-weight: 800; color: #fff; letter-spacing: -0.01em;
white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.vdpg-pill { flex-shrink: 0; font-size: 10px; font-weight: 900; letter-spacing: 0.04em; text-transform: uppercase;
padding: 3px 9px; border-radius: 999px; background: rgba(255, 255, 255, 0.1); color: rgba(255, 255, 255, 0.6);
transition: background 0.25s ease, color 0.25s ease; }
.vdpg-pill[data-st="dl"] { background: rgba(var(--accent-rgb), 0.18); color: rgb(var(--accent-rgb)); animation: vdpgPulse 1.6s ease-in-out infinite; }
.vdpg-pill[data-st="ok"] { background: rgba(108, 211, 145, 0.18); color: #8fe7af; }
.vdpg-pill[data-st="fail"] { background: rgba(239, 68, 68, 0.18); color: #fca5a5; }
.vdpg-rel { font: 500 11px/1.3 'JetBrains Mono', ui-monospace, monospace; color: rgba(255, 255, 255, 0.4);
margin-top: 4px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.vdpg-rel:empty { display: none; }
.vdpg-bar { margin-top: 10px; height: 7px; border-radius: 999px; background: rgba(255, 255, 255, 0.1); overflow: hidden; }
.vdpg-bar-fill { height: 100%; width: 0; border-radius: 999px; transition: width 1.4s cubic-bezier(0.3, 0.8, 0.3, 1);
background: linear-gradient(90deg, rgba(var(--accent-rgb), 0.7), rgb(var(--accent-rgb))); position: relative; }
.vdpg-bar-fill::after { content: ''; position: absolute; inset: 0; border-radius: 999px;
background: linear-gradient(100deg, transparent 30%, rgba(255, 255, 255, 0.35) 50%, transparent 70%);
animation: vdpgShimmer 1.6s linear infinite; }
.vdpg-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 13px; margin-top: 9px; font-size: 11.5px;
font-weight: 600; color: rgba(255, 255, 255, 0.55); }
.vdpg-m { display: inline-flex; align-items: center; }
.vdpg-dest { color: #8fe7af; font-family: 'JetBrains Mono', ui-monospace, monospace; font-size: 11px;
max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.vdpg-err { color: #fca5a5; }
.vdpg-empty { text-align: center; padding: 70px 20px; color: rgba(255, 255, 255, 0.45); animation: vdlRise 0.5s both; }
.vdpg-empty-ic { font-size: 46px; opacity: 0.5; }
.vdpg-empty-t { font-size: 17px; font-weight: 800; color: rgba(255, 255, 255, 0.7); margin-top: 12px; }
.vdpg-empty-s { font-size: 13px; margin-top: 6px; }
@keyframes vdpgPulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.55; } }
@keyframes vdpgShimmer { from { transform: translateX(-100%); } to { transform: translateX(100%); } }
@media (prefers-reduced-motion: reduce) {
.vdpg-item, .vdpg-pill[data-st="dl"], .vdpg-bar-fill::after { animation: none !important; }
.vdpg-bar-fill { transition: none; }
}