Per the desired model: video Settings has its OWN server settings, separate from music. The 'Video Source' group now holds the Plex/Jellyfin pick AND the Movies/TV library mapping (moved out of music's Plex panel so it's not coupled to the music active server). The whole MUSIC 'Server Connections' group is hidden on the video side. Video reuses the shared Plex/Jellyfin credentials: the picker shows both servers, the configured ones selectable, the rest 'not connected — set up in Music settings'. Music settings keep their own server settings, untouched.
1504 lines
80 KiB
CSS
1504 lines
80 KiB
CSS
/*
|
|
* 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;
|
|
}
|
|
|
|
/* ── 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: only the bits not covered by music's global
|
|
.em-* classes, ALL scoped to #vem-overlay so music is never affected. ───── */
|
|
#vem-overlay .vem-logo { width: 22px; height: 22px; object-fit: contain; }
|
|
#vem-overlay .vem-logo--tvdb { filter: invert(1); }
|
|
#vem-overlay .vem-icon {
|
|
width: 34px;
|
|
height: 34px;
|
|
border-radius: 9px;
|
|
background: rgba(255, 255, 255, 0.06);
|
|
border: 1px solid rgba(255, 255, 255, 0.12);
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
font-size: 11px;
|
|
font-weight: 800;
|
|
color: #fff;
|
|
flex-shrink: 0;
|
|
}
|
|
#vem-overlay .em-panel-header { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 6px; }
|
|
#vem-overlay .em-ph-main { display: flex; align-items: center; gap: 8px; font-size: 16px; }
|
|
#vem-overlay .em-ph-status { color: var(--text-secondary, #9aa0aa); font-size: 13px; }
|
|
#vem-overlay .em-ph-current { color: var(--text-secondary, #9aa0aa); font-size: 12px; opacity: 0.85; }
|
|
#vem-overlay .em-pause-btn {
|
|
margin-left: auto;
|
|
padding: 7px 16px;
|
|
border-radius: 9px;
|
|
border: 1px solid rgba(255, 255, 255, 0.12);
|
|
background: rgba(255, 255, 255, 0.06);
|
|
color: var(--text-primary, #e8e8ea);
|
|
font-size: 13px;
|
|
font-weight: 600;
|
|
cursor: pointer;
|
|
}
|
|
#vem-overlay .em-pause-btn:disabled { opacity: 0.45; cursor: default; }
|
|
#vem-overlay .em-unmatched-controls { display: flex; align-items: center; justify-content: space-between; margin: 14px 0 8px; }
|
|
#vem-overlay .em-section-sub { color: var(--text-secondary, #9aa0aa); font-size: 13px; }
|
|
#vem-overlay .em-retry-all-btn {
|
|
padding: 6px 14px;
|
|
border-radius: 8px;
|
|
border: 1px solid rgba(var(--accent-rgb, 88 101 242), 0.4);
|
|
background: rgba(var(--accent-rgb, 88 101 242), 0.12);
|
|
color: rgb(var(--accent-light-rgb, var(--accent-rgb, 88 101 242)));
|
|
font-size: 12px;
|
|
font-weight: 600;
|
|
cursor: pointer;
|
|
}
|
|
#vem-overlay .em-item {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 12px;
|
|
padding: 8px 10px;
|
|
border-radius: 10px;
|
|
border: 1px solid rgba(255, 255, 255, 0.05);
|
|
margin-bottom: 6px;
|
|
}
|
|
#vem-overlay .em-item-img {
|
|
width: 38px;
|
|
height: 56px;
|
|
object-fit: cover;
|
|
border-radius: 6px;
|
|
background: rgba(255, 255, 255, 0.06);
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
font-size: 18px;
|
|
flex-shrink: 0;
|
|
}
|
|
#vem-overlay .em-item-meta { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }
|
|
#vem-overlay .em-item-name { font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
#vem-overlay .em-item-sub { font-size: 12px; color: var(--text-secondary, #9aa0aa); }
|
|
#vem-overlay .em-item-retry {
|
|
padding: 5px 12px;
|
|
border-radius: 7px;
|
|
border: 1px solid rgba(255, 255, 255, 0.12);
|
|
background: transparent;
|
|
color: var(--text-secondary, #9aa0aa);
|
|
font-size: 12px;
|
|
cursor: pointer;
|
|
}
|
|
#vem-overlay .em-item-retry:hover { color: #fff; border-color: rgba(255, 255, 255, 0.25); }
|
|
#vem-overlay .em-empty { padding: 30px; text-align: center; color: var(--text-secondary, #9aa0aa); }
|
|
#vem-overlay .em-pager { display: flex; align-items: center; justify-content: center; gap: 12px; margin-top: 12px; }
|
|
#vem-overlay .em-pg {
|
|
width: 30px;
|
|
height: 30px;
|
|
border-radius: 8px;
|
|
border: 1px solid rgba(255, 255, 255, 0.12);
|
|
background: rgba(255, 255, 255, 0.05);
|
|
color: var(--text-primary, #e8e8ea);
|
|
cursor: pointer;
|
|
}
|
|
#vem-overlay .em-pg:disabled { opacity: 0.4; cursor: default; }
|
|
#vem-overlay .em-pg-info { font-size: 13px; color: var(--text-secondary, #9aa0aa); }
|
|
|
|
/* ── 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; }
|
|
.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; }
|
|
.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);
|
|
}
|
|
/* "Now processing" chip pulses in the worker's accent — clear live signal. */
|
|
#vem-overlay .em-ph-current {
|
|
color: rgb(var(--em-accent-rgb));
|
|
text-shadow: 0 0 12px rgba(var(--em-accent-rgb), 0.55);
|
|
animation: vemNowPulse 1.8s ease-in-out infinite;
|
|
}
|
|
@keyframes vemNowPulse { 0%, 100% { opacity: 0.78; } 50% { opacity: 1; } }
|
|
/* 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; }
|
|
|
|
/* ── 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); }
|
|
#vem-overlay .vem-glyph { font-size: 20px; line-height: 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; animation: vd-fade 0.6s ease; }
|
|
.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;
|
|
}
|
|
.vd-billboard--trailer .vd-bb-bg { opacity: 0; transition: opacity 0.6s ease; }
|
|
.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; }
|
|
|
|
/* ── settings: Video Source panel ────────────────────────────────────────── */
|
|
.vid-source-using { font-size: 14px; color: var(--text-primary, #fff); display: flex; align-items: center; gap: 8px; }
|
|
.vid-source-check { color: #22c55e; font-weight: 800; }
|
|
.vid-source-none { font-size: 13.5px; line-height: 1.6; color: rgba(255, 255, 255, 0.72); }
|
|
.vid-source-none strong { color: #fff; }
|
|
.vid-source-pick { display: flex; gap: 10px; margin-bottom: 10px; }
|
|
.vid-source-btn {
|
|
padding: 8px 18px; border-radius: 8px; cursor: pointer; font-size: 13px; 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.18s ease;
|
|
}
|
|
.vid-source-btn:hover { background: rgba(255, 255, 255, 0.12); color: #fff; }
|
|
.vid-source-btn.active { background: rgba(56, 189, 248, 0.9); border-color: transparent; color: #fff; }
|
|
.vid-source-btn--off { opacity: 0.45; cursor: not-allowed; }
|
|
.vid-source-btn--off:hover { background: rgba(255, 255, 255, 0.06); color: rgba(255, 255, 255, 0.8); }
|
|
.vid-source-off { font-size: 11px; opacity: 0.85; }
|
|
|
|
/* 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; }
|