Files
ytplayer/frontend/theme-classic.css
Jonathan Sykes 9e960cf70f iPhone background audio in every playback mode; Classic playlist card actions; export sheet bar
- Dual mode (separate video + audio, used by adaptive streams and the iPhone EQ
  copies): going to the background now makes the audio the master, so progress,
  Now Playing and auto-advance keep working while iOS has the video suspended
  (the paused video used to be the only source of "ended", so playback stopped
  after the current song). The picture is re-synced on return.
- A track that starts while the app is in the background (auto-advance, the
  lock-screen Next button) starts as audio — iOS will not start a <video> there —
  and gets its picture back at the same position when the app returns.
- The handoff also runs on pagehide and when iOS pauses the master video while
  the page is hidden, for when visibilitychange arrives too late.
- Classic: playlist cards place their three actions as a 2x2 block (note + add
  on top, remove below) instead of the note button wrapping to the bottom-left.
- Save to this device: hide the full progress bar once the file is ready; it
  read as a squashed, broken button above "Save to Photos / Files".
2026-10-03 17:46:23 +08:00

238 lines
20 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.

/* Classic: a media workspace. Keep all overrides inside this layout. */
html[data-layout="classic"] {
--radius: 12px;
--radius-sm: 8px;
--classic-stacked: 0;
--classic-zoom: 1;
--classic-space: 24px;
--classic-nav-height: 0px;
--classic-mini-height: 0px;
--classic-rail-height: 0px;
--classic-clearance: calc(var(--classic-nav-height) + var(--classic-mini-height) + var(--classic-rail-height));
--accent-glow: transparent;
}
html[data-layout="classic"][data-font="small"] { --classic-zoom: .9; }
html[data-layout="classic"][data-font="large"] { --classic-zoom: 1.12; }
html[data-layout="classic"][data-font="xl"] { --classic-zoom: 1.26; }
html[data-layout="classic"][data-theme="dark"] {
--bg: #121315;
--bg-1: #18191c;
--bg-2: #202226;
--bg-3: #2b2e33;
--line: #42464d;
--line-soft: #2b2e33;
--text: #f3f1ed;
--text-2: #c3c4c7;
--text-dim: #a1a5ac;
--accent: #f06b53;
--accent-bright: #ff947e;
--accent-deep: #c6442f;
}
html[data-layout="classic"][data-theme="light"] { --text-dim: #625e59; --accent-deep: #b43623; }
html[data-layout="classic"][data-theme] .hero-title { background: none; -webkit-text-fill-color: var(--text); }
html[data-layout="classic"] body::before,
html[data-layout="classic"] body::after { display: none; }
html[data-layout="classic"] ::selection { background: var(--accent); color: var(--bg); }
html[data-layout="classic"] :is(input, textarea) { caret-color: var(--accent); }
html[data-layout="classic"] :is(button, a, input, select, textarea, [tabindex]):focus-visible {
outline: 2px solid var(--accent);
outline-offset: 3px;
}
html[data-layout="classic"] :is(button, input, select, textarea) { font-family: var(--ui); }
html[data-layout="classic"] :is(input, textarea)::placeholder { color: var(--text-dim); opacity: 1; }
html[data-layout="classic"] .app { grid-template-columns: 232px minmax(0, 1fr); height: calc(100dvh / var(--classic-zoom)); }
html[data-layout="classic"] .main { min-width: 0; min-height: 0; padding-bottom: var(--classic-mini-height); }
html[data-layout="classic"] .body { min-height: 0; flex-direction: row; }
html[data-layout="classic"] .sidebar {
background: var(--bg-1); padding: 28px 12px 20px;
border-right: 1px solid var(--line-soft);
}
html[data-layout="classic"] .brand { font-size: 21px; padding: 0 12px 28px; gap: 10px; }
html[data-layout="classic"] .brand-mark { background: var(--accent-deep); box-shadow: none; border-radius: 8px; }
html[data-layout="classic"] .nav { gap: 2px; }
html[data-layout="classic"] .nav-item { display: flex; align-items: center; gap: 12px; min-height: 44px; padding: 10px 12px; letter-spacing: 0; }
html[data-layout="classic"] .nav-item::before { display: none; }
html[data-layout="classic"] .nav-item.active { background: var(--bg-3); color: var(--text); }
html[data-layout="classic"] .nav-item.active .classic-nav-icon { color: var(--accent); }
html[data-layout="classic"] .nav-badge { margin-left: auto; }
html[data-layout="classic"] .legacy-nav-icon { display: none; }
html[data-layout="classic"] .classic-nav-icon { display: inline-block; flex: none; width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
html[data-layout="classic"] .pl-header { margin-top: 16px; font: 600 13px var(--ui); letter-spacing: 0; text-transform: none; }
html[data-layout="classic"] .playlist-item { min-height: 44px; border-radius: 8px; }
html[data-layout="classic"] .topbar {
background: var(--bg); border-bottom: 1px solid var(--line-soft); backdrop-filter: none;
padding: 18px var(--classic-space); gap: 12px; flex: none;
}
html[data-layout="classic"] .search-form { width: 100%; min-width: 0; max-width: 860px; gap: 8px; }
html[data-layout="classic"] #searchInput { min-width: 0; font-size: 16px; padding: 11px 14px; min-height: 46px; border-radius: 8px; background: var(--bg-1); box-shadow: none; }
html[data-layout="classic"] .search-btn { min-height: 46px; padding: 0 22px; border-radius: 8px; background: var(--bg-3); color: var(--text); box-shadow: none; transform: none; }
html[data-layout="classic"] .search-btn:hover { background: var(--accent-deep); color: #fff; }
html[data-layout="classic"] .sidebar-toggle { min-width: 44px; min-height: 44px; border-radius: 8px; box-shadow: none; }
html[data-layout="classic"] .player-pane {
container-type: inline-size;
flex: 1 1 0; min-width: 0; min-height: 0; gap: 0;
padding: var(--classic-space); padding-bottom: calc(var(--classic-space) + var(--classic-mini-height));
overflow-y: auto;
}
html[data-layout="classic"] .player-stage { border-radius: 12px; box-shadow: none; flex: none; }
html[data-layout="classic"] .player-pane:not(.empty) .player-stage { box-shadow: none; }
html[data-layout="classic"] .player-pane.empty .player-stage {
aspect-ratio: auto; min-height: 0; max-height: none; flex: none; overflow: visible; background: transparent;
}
html[data-layout="classic"] .player-pane.empty #video { display: none; }
html[data-layout="classic"] .player-placeholder {
position: relative; inset: auto; width: 100%; padding: 48px 16px; background: transparent; text-align: left;
}
html[data-layout="classic"] .hero { align-items: flex-start; max-width: 620px; gap: 24px; animation: none; }
html[data-layout="classic"] .ph-logo { width: 52px; height: 52px; border-radius: 12px; background: var(--accent-deep); color: #fff; box-shadow: none; border: 0; animation: none; font-size: 20px; }
html[data-layout="classic"] .hero-title { font-size: clamp(36px, 4vw, 60px); line-height: 1.05; letter-spacing: -0.035em; background: none; color: var(--text); -webkit-text-fill-color: var(--text); margin: 0; }
html[data-layout="classic"] .hero-tagline { font-size: 17px; line-height: 1.65; max-width: 45ch; color: var(--text-2); text-align: left; margin: 0; }
html[data-layout="classic"] .hero-pills { justify-content: flex-start; gap: 8px 16px; }
html[data-layout="classic"] .hero-pill { padding: 0; background: none; border: 0; font: 500 13px var(--ui); color: var(--text-2); box-shadow: none; }
html[data-layout="classic"] .hero-suggests { justify-content: flex-start; gap: 8px; padding-top: 24px; border-top: 1px solid var(--line-soft); width: 100%; }
html[data-layout="classic"] .hero-suggests-label { flex-basis: 100%; text-align: left; font: 600 14px var(--ui); text-transform: none; letter-spacing: 0; }
html[data-layout="classic"] .chip { min-height: 44px; padding: 10px 14px; background: var(--bg-2); border: 1px solid var(--line-soft); border-radius: 8px; font: 500 14px var(--ui); color: var(--text); transform: none; }
html[data-layout="classic"] .player-placeholder.showing-playlists { padding: 8px 0 24px; }
html[data-layout="classic"] .home-pl { overflow: visible; max-height: none; animation: none; gap: 24px; }
html[data-layout="classic"] .home-pl-title { font-size: 28px; }
html[data-layout="classic"] .home-pl-new { min-height: 44px; padding: 8px 14px; }
html[data-layout="classic"] .home-pl-grid { overflow: visible; grid-template-columns: repeat(auto-fill, minmax(138px, 1fr)); gap: 24px 16px; max-height: none; mask-image: none; -webkit-mask-image: none; }
html[data-layout="classic"] .home-pl-name { font: 600 14px/1.4 var(--ui); }
html[data-layout="classic"] #controls { padding: 18px 0; margin-top: 8px; border: 0; border-bottom: 1px solid var(--line-soft); border-radius: 0; background: transparent; box-shadow: none; gap: 14px; }
html[data-layout="classic"] #controls .deck-main { grid-template-columns: repeat(5, auto); gap: 14px; }
html[data-layout="classic"] #controls .deck-main .skip10 { display: grid; }
html[data-layout="classic"] #controls .deck-main .ctrl { width: 48px; height: 48px; border-radius: 12px; }
html[data-layout="classic"] #controls .deck-main .ctrl.play { width: 64px; height: 64px; border-radius: 50%; background: var(--accent); color: #171719; box-shadow: none; }
html[data-layout="classic"] #controls .deck-main .ctrl.play:hover { background: var(--accent-bright); }
html[data-layout="classic"] #controls .ctrl.active svg { filter: none; }
html[data-layout="classic"] #controls .time { font: 12px var(--mono); font-variant-numeric: tabular-nums; }
html[data-layout="classic"] #controls .deck-vol { padding: 0; gap: 12px; }
html[data-layout="classic"] #controls .vol-pod { flex: 1; min-width: 0; display: flex; align-items: center; gap: 12px; }
html[data-layout="classic"] #controls .deck-vol .ctrl { width: 44px; height: 44px; }
html[data-layout="classic"] #controls .dk-quick { flex-wrap: wrap; gap: 8px; }
html[data-layout="classic"] #controls .dk-quick #fsBtn { min-height: 48px; height: auto; border-radius: 8px; background: var(--bg-2); }
html[data-layout="classic"] #controls .dk-more { min-height: 48px; border-radius: 8px; padding: 8px 12px; }
html[data-layout="classic"] #nowPlayingMeta { margin-top: 24px; gap: 18px; }
html[data-layout="classic"] #nowPlayingMeta .np-title { font-size: clamp(22px, 2vw, 30px); line-height: 1.25; letter-spacing: -0.02em; overflow-wrap: anywhere; }
html[data-layout="classic"] #nowPlayingMeta .np-channel { color: var(--text-2); font-size: 14px; }
html[data-layout="classic"] #nowPlayingMeta .np-actions :is(.np-btn, #saveBtn, #queueBtn, #addPlaylistBtn, #addBtn, #serviceBtn) { flex: 1 1 120px; min-height: 44px; height: auto; padding: 10px 12px; border-radius: 8px; font-size: 13px; background: var(--bg-2); color: var(--text); box-shadow: none; white-space: normal; }
html[data-layout="classic"] #nowPlayingMeta .np-actions #saveBtn.done { color: var(--text); background: var(--bg-3); }
html[data-layout="classic"] .np-more { border-radius: 8px; min-height: 44px; background: transparent; box-shadow: none; }
html[data-layout="classic"] :is(.notes-panel, .upnext, .related-panel) { border-radius: 12px; background: var(--bg-1); box-shadow: none; margin-top: 24px; }
html[data-layout="classic"] .notes-tabs { flex-wrap: wrap; padding: 8px; gap: 4px; border-bottom: 1px solid var(--line-soft); }
html[data-layout="classic"] .notes-tab { min-height: 44px; padding: 8px 10px; font: 600 13px var(--ui); letter-spacing: 0; text-transform: none; border-radius: 8px; }
html[data-layout="classic"] .notes-tab.active { color: var(--text); background: var(--bg-3); box-shadow: none; }
html[data-layout="classic"] .lyr-line.active { background: var(--bg-3); box-shadow: none; color: var(--accent-bright); }
html[data-layout="classic"] .list-pane { flex: 0 0 clamp(340px, 29%, 420px); width: auto; min-width: 0; min-height: 0; background: var(--bg-1); overflow-y: auto; padding-bottom: var(--classic-mini-height); }
html[data-layout="classic"] .list-header { padding: 24px 20px 16px; gap: 16px; }
html[data-layout="classic"] .list-header h2 { font-size: 26px; line-height: 1.2; }
html[data-layout="classic"] #listActions button { min-height: 44px; height: auto; border-radius: 8px; padding: 8px 12px; }
html[data-layout="classic"] #listActions button.la-primary { background: var(--accent-deep); color: #fff; box-shadow: none; font-size: 14px; }
html[data-layout="classic"] :is(.list-icon-btn, .list-title-actions .list-icon-btn) { width: 44px; height: 44px; border-radius: 8px; }
html[data-layout="classic"] .cards { flex: none; overflow: visible; padding: 4px 12px 24px; gap: 0; }
html[data-layout="classic"] .card { display: grid; grid-template-columns: 88px minmax(0, 1fr) 44px; padding: 12px 8px; gap: 0 12px; border-radius: 0; border: 0; border-bottom: 1px solid var(--line-soft); animation: none; box-shadow: none; }
html[data-layout="classic"] .card .thumb { grid-column: 1; grid-row: 1 / span 2; width: 88px; }
html[data-layout="classic"] .card-info { grid-column: 2; grid-row: 1 / span 2; align-self: center; }
html[data-layout="classic"] .card-menu { grid-column: 3; grid-row: 1; }
html[data-layout="classic"] .card-del { grid-column: 3; grid-row: 2; }
html[data-layout="classic"] .batch-check { position: absolute; left: 8px; top: 12px; z-index: 2; }
html[data-layout="classic"] .card.playing { background: var(--bg-3); box-shadow: inset 2px 0 var(--accent); }
html[data-layout="classic"] .card.playing::after { display: none; }
html[data-layout="classic"] .thumb { width: 100px; border-radius: 6px; align-self: flex-start; }
html[data-layout="classic"] .card:hover .thumb img { transform: none; }
html[data-layout="classic"] .card-title { font-size: 14px; line-height: 1.45; }
html[data-layout="classic"] .card-channel { font-size: 12px; color: var(--text-dim); }
html[data-layout="classic"] :is(.card-menu, .card-del) { min-width: 44px; min-height: 44px; opacity: 1; }
html[data-layout="classic"] .settings { padding: 8px 20px 28px; overflow: visible; }
html[data-layout="classic"] .settings :is(input:not([type="checkbox"]):not([type="range"]), select, button) { min-height: 44px; max-width: 100%; }
html[data-layout="classic"] :is(.modal, .shortcut-panel, .more-sheet) { background: var(--bg-1); border-radius: 12px; max-width: 100%; box-shadow: var(--shadow); }
html[data-layout="classic"] :is(.modal, .more-sheet) button { min-height: 44px; }
html[data-layout="classic"] .mini-bar { left: 232px; bottom: 0; background: var(--bg-2); border-top: 1px solid var(--line); padding: 0; }
html[data-layout="classic"] .mini-bar-inner { background: var(--bg-2); border-radius: 0; box-shadow: none; backdrop-filter: none; padding: 10px 20px; }
html[data-layout="classic"] .mini-bar button { min-width: 44px; min-height: 44px; }
html[data-layout="classic"] .bottom-nav { display: none; background: var(--bg-1); backdrop-filter: none; }
html[data-layout="classic"] .bottom-nav-icon { background: none; border-radius: 0; box-shadow: none; }
html[data-layout="classic"] .bottom-nav-btn.active .bottom-nav-icon { background: none; color: var(--accent); box-shadow: none; }
html[data-layout="classic"] .bottom-nav-label { font: 500 11px var(--ui); letter-spacing: 0; }
html[data-layout="classic"] .sec-rail { top: auto; left: 50%; right: auto; bottom: calc(var(--classic-nav-height) + var(--classic-mini-height)); transform: translateX(-50%); flex-direction: row; flex-wrap: wrap; justify-content: center; width: max-content; max-width: calc(100% - 24px); gap: 4px; padding: 4px; border: 0; border-radius: 8px 8px 0 0; background: var(--bg-2); box-shadow: none; backdrop-filter: none; }
html[data-layout="classic"] body:has(#miniBar:not(.hidden)) .sec-rail { bottom: calc(var(--classic-nav-height) + var(--classic-mini-height)); transform: translateX(-50%); }
html[data-layout="classic"] .sec-rail-btn { width: 44px; height: 44px; border-radius: 8px; }
html[data-layout="classic"] .sec-rail-label { right: auto; bottom: 48px; }
html[data-layout="classic"] .toast-container { bottom: calc(var(--classic-clearance) + 16px); }
html[data-layout="classic"] .empty-state { animation: none; padding: 32px 20px; }
html[data-layout="classic"] .empty-cta { background: var(--accent-deep); color: #fff; min-height: 44px; box-shadow: none; transform: none; }
html[data-layout="classic"][data-density="compact"] { --classic-space: 16px; }
html[data-layout="classic"][data-density="compact"] .card { padding-block: 6px; }
html[data-layout="classic"][data-density="compact"] .thumb { width: 88px; }
@media (min-width: 1201px) {
html[data-layout="classic"] .player-pane:not(.empty) .player-stage { width: min(100%, calc(42dvh * 16 / 9)); align-self: center; }
}
@container (min-width: 620px) {
html[data-layout="classic"] #controls { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 14px 24px; }
html[data-layout="classic"] #controls :is(.seek-row, .dk-quick) { grid-column: 1 / -1; }
html[data-layout="classic"] #controls .deck-main { gap: 8px; justify-content: start; }
html[data-layout="classic"] #controls .deck-main .ctrl { width: 44px; height: 44px; }
html[data-layout="classic"] #controls .deck-main .ctrl.play { width: 56px; height: 56px; }
}
@container (max-width: 300px) {
html[data-layout="classic"] #controls .deck-main { grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 0; }
html[data-layout="classic"] #controls .deck-main .ctrl,
html[data-layout="classic"] #controls .deck-main .ctrl.play { width: 44px; height: 44px; }
}
@media (max-width: 420px) {
html[data-layout="classic"][data-font="xl"] .bottom-nav { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
/* CSS owns the stacked breakpoint; JS reads this flag for scrolling. */
@media (max-width: 1200px) {
html[data-layout="classic"] { --classic-stacked: 1; }
html[data-layout="classic"] .main { padding-bottom: var(--classic-clearance); }
html[data-layout="classic"] .body { flex-direction: column; overflow-y: auto; overflow-x: hidden; overscroll-behavior: contain; scroll-padding-block: 16px; padding-bottom: 24px; }
html[data-layout="classic"] .player-pane { flex: none; width: 100%; overflow: visible; padding-bottom: 24px; }
html[data-layout="classic"] .list-pane { flex: none; width: 100%; min-height: 100%; overflow: visible; border-left: 0; border-top: 1px solid var(--line-soft); padding-bottom: 24px; }
html[data-layout="classic"] .cards { max-height: none; overflow: visible; }
html[data-layout="classic"] .player-placeholder { padding-block: 32px; }
}
@media (max-width: 860px) {
html[data-layout="classic"] { --classic-space: 16px; }
html[data-layout="classic"] .app { grid-template-columns: minmax(0, 1fr); }
html[data-layout="classic"] .topbar { padding: calc(10px + env(safe-area-inset-top)) max(12px, env(safe-area-inset-right)) 10px max(12px, env(safe-area-inset-left)); gap: 8px; }
html[data-layout="classic"] .search-form { gap: 6px; }
html[data-layout="classic"] .search-btn { padding-inline: 12px; font-size: 13px; }
html[data-layout="classic"] #searchInput { padding-inline: 10px; }
html[data-layout="classic"] .sidebar { padding-top: calc(24px + env(safe-area-inset-top)); padding-bottom: calc(24px + env(safe-area-inset-bottom)); z-index: 350; }
html[data-layout="classic"] .sidebar-backdrop { z-index: 340; }
html[data-layout="classic"] .player-pane { padding-inline: max(16px, env(safe-area-inset-left)) max(16px, env(safe-area-inset-right)); }
html[data-layout="classic"] .player-placeholder { padding: 24px 8px 32px; }
html[data-layout="classic"] .hero { gap: 24px; }
html[data-layout="classic"] .hero-title { font-size: 42px; }
html[data-layout="classic"] .hero-tagline { font-size: 16px; }
html[data-layout="classic"] .hero-pills { gap: 8px 12px; }
html[data-layout="classic"] .home-pl-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
html[data-layout="classic"] .home-pl-title { font-size: 26px; }
html[data-layout="classic"] .bottom-nav { display: flex; padding: 6px env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left); }
html[data-layout="classic"] .bottom-nav-btn { min-width: 44px; min-height: 58px; padding: 6px 0 8px; gap: 5px; color: var(--text-dim); }
html[data-layout="classic"] .bottom-nav-btn.active { color: var(--text); }
html[data-layout="classic"] .mini-bar { left: 0; bottom: var(--classic-nav-height); }
html[data-layout="classic"] .mini-bar-inner { padding: 8px max(12px, env(safe-area-inset-right)) 8px max(12px, env(safe-area-inset-left)); gap: 8px; }
html[data-layout="classic"] .list-header { padding: 24px 16px 16px; }
html[data-layout="classic"] .settings { padding-inline: 16px; }
html[data-layout="classic"] :is(.modal-backdrop, .shortcut-overlay) { padding: 16px; }
html[data-layout="classic"] .shortcut-panel { min-width: 0; width: 100%; padding: 24px; }
}
@media (max-width: 380px) {
html[data-layout="classic"] .thumb { width: 88px; }
}
/* Playlist cards carry a third action (✎ note). Without its own cell it
wrapped to a new row at the bottom-left; give the actions a 2×2 block:
✎ + on top, × under +. */
html[data-layout="classic"] .card:has(.card-note-btn) { grid-template-columns: 88px minmax(0, 1fr) 44px 44px; gap: 4px 12px; }
html[data-layout="classic"] .card:has(.card-note-btn) .card-note-btn { grid-column: 3; grid-row: 1; align-self: start; justify-self: center; width: 44px; height: 44px; border-radius: 8px; opacity: 1; }
html[data-layout="classic"] .card:has(.card-note-btn) .card-menu { grid-column: 4; grid-row: 1; }
html[data-layout="classic"] .card:has(.card-note-btn) .card-del { grid-column: 4; grid-row: 2; }
html[data-layout="classic"] .card:has(.card-note-btn) { column-gap: 8px; }