diff --git a/media_server/static/css/styles.css b/media_server/static/css/styles.css index d142033..f0275a5 100644 --- a/media_server/static/css/styles.css +++ b/media_server/static/css/styles.css @@ -4291,13 +4291,14 @@ header .brand-sub { box-shadow: 0 14px 40px rgba(0,0,0,0.5); } -/* ─── Tab bar (numbered editorial) ──────────────────────────── */ +/* ─── Tab bar (numbered editorial) — only the bottom rule is visible */ .tab-bar { - background: transparent; - border-bottom: 1px solid var(--rule); - padding: 0; - margin: 14px 0 36px; - border-radius: 0; + background: transparent !important; + border: 0 !important; + border-bottom: 1px solid var(--rule-strong) !important; + padding: 0 !important; + margin: 14px 0 36px !important; + border-radius: 0 !important; gap: 0; position: relative; overflow-x: auto; @@ -7149,3 +7150,828 @@ body.audio-spectrum-live .now-playing .spectrum span { padding-left: 0; } } + +/* ════════════════════════════════════════════════════════════════ + STUDIO REFERENCE — editorial styling for non-player tabs + (Library, Quick Access, Settings, Display) + ════════════════════════════════════════════════════════════════ */ + +/* Common: each tab container is a flat editorial canvas (no card chrome) */ +.browser-container, +.scripts-container, +.settings-container, +.display-container, +.script-management { + background: transparent !important; + border: 0 !important; + padding: 0 !important; + box-shadow: none !important; + margin-top: 14px; +} + +/* ─── LIBRARY (browser) ───────────────────────────────────── */ + +/* Breadcrumb — italic serif, copper terminal */ +.browser-container .breadcrumb { + background: transparent !important; + border: 0 !important; + border-bottom: 1px solid var(--rule) !important; + border-radius: 0 !important; + padding: 14px 0 !important; + margin-bottom: 24px; + font-family: var(--serif); + font-style: italic; + font-size: 18px; + font-variation-settings: 'opsz' 30; + color: var(--ink-soft); + display: flex; + align-items: center; + gap: 4px; + flex-wrap: wrap; +} +.browser-container .breadcrumb-home, +.browser-container .breadcrumb-item { + color: var(--ink-soft); + text-decoration: none; + cursor: pointer; + transition: color 180ms var(--ease); + background: transparent; + border: 0; + padding: 0; + font-family: inherit; + font-style: italic; + font-size: inherit; +} +.browser-container .breadcrumb-home:hover, +.browser-container .breadcrumb-item:hover { color: var(--copper); } +.browser-container .breadcrumb-item:last-of-type { + color: var(--ink); + font-weight: 500; +} +.browser-container .breadcrumb-separator { + color: var(--ink-faint); + margin: 0 8px; + font-style: normal; + opacity: 1; + font-family: var(--mono); + font-size: 14px; +} + +/* Toolbar — hairline groups, no card */ +.browser-container .browser-toolbar { + background: transparent !important; + border: 0 !important; + border-bottom: 1px solid var(--rule) !important; + border-radius: 0 !important; + padding: 0 0 16px 0 !important; + margin-bottom: 28px; + gap: 14px; + display: flex; + align-items: center; + flex-wrap: wrap; +} +.browser-container .browser-toolbar-left { + display: flex; + align-items: center; + gap: 10px; +} +.browser-container .browser-toolbar-right { + margin-left: auto; + display: flex; + align-items: center; + gap: 10px; +} + +/* View-toggle: square hairline pills with copper active */ +.browser-container .view-toggle { + display: flex; + background: transparent !important; + border: 1px solid var(--rule-strong) !important; + border-radius: 0 !important; + padding: 0 !important; + overflow: hidden; +} +.browser-container .view-toggle-btn, +.browser-container .browser-refresh-btn, +.browser-container .browser-play-all-btn { + background: transparent !important; + border: 0 !important; + border-radius: 0 !important; + color: var(--ink-mute) !important; + width: 36px !important; + height: 36px !important; + padding: 0 !important; + display: inline-flex !important; + align-items: center; + justify-content: center; + cursor: pointer; + transition: all 180ms var(--ease); + box-sizing: border-box; +} +.browser-container .view-toggle .view-toggle-btn { + border-right: 1px solid var(--rule-strong) !important; +} +.browser-container .view-toggle .view-toggle-btn:last-child { + border-right: 0 !important; +} +.browser-container .view-toggle-btn:hover, +.browser-container .browser-refresh-btn:hover, +.browser-container .browser-play-all-btn:hover { + color: var(--copper) !important; + background: rgba(224, 128, 56, 0.06) !important; +} +.browser-container .view-toggle-btn.active { + background: var(--ink) !important; + color: var(--bg-deep) !important; +} +.browser-container .browser-refresh-btn, +.browser-container .browser-play-all-btn { + border: 1px solid var(--rule-strong) !important; +} +.browser-container .browser-play-all-btn { + color: var(--copper) !important; + border-color: var(--copper) !important; +} + +/* Search — underline-only editorial input */ +.browser-container .browser-search-wrapper { + background: transparent !important; + border: 0 !important; + border-bottom: 1px solid var(--rule-strong) !important; + border-radius: 0 !important; + padding: 4px 0 !important; + display: inline-flex; + align-items: center; + gap: 8px; + transition: border-color 180ms var(--ease); + min-width: 220px; +} +.browser-container .browser-search-wrapper:focus-within { + border-bottom-color: var(--copper) !important; +} +.browser-container .browser-search-input { + background: transparent !important; + border: 0 !important; + color: var(--ink) !important; + font-family: var(--sans); + font-size: 14px; + padding: 4px 0 !important; + outline: none; + flex: 1; + min-width: 0; +} +.browser-container .browser-search-input::placeholder { color: var(--ink-mute); } +.browser-container .browser-search-icon { color: var(--ink-mute); flex-shrink: 0; } +.browser-container .browser-search-clear { + background: transparent !important; + border: 0 !important; + color: var(--ink-mute); + cursor: pointer; + padding: 0 !important; +} +.browser-container .browser-search-clear:hover { color: var(--copper); } + +/* Items per page label + select */ +.browser-container .items-per-page-label { + font-family: var(--mono); + font-size: 10px; + letter-spacing: 0.18em; + text-transform: uppercase; + color: var(--ink-mute); + display: inline-flex; + align-items: center; + gap: 8px; +} +.browser-container .items-per-page-label select { + background: transparent !important; + border: 1px solid var(--rule-strong) !important; + color: var(--ink) !important; + border-radius: 0 !important; + font-family: var(--mono); + font-size: 11px; + padding: 6px 10px !important; + cursor: pointer; +} + +/* Browser grid — editorial cards */ +.browser-container .browser-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); + gap: 32px 24px; + padding: 0 !important; +} +.browser-container .browser-item { + background: transparent !important; + border: 0 !important; + border-radius: 0 !important; + padding: 0 !important; + cursor: pointer; + transition: transform 280ms var(--ease); +} +.browser-container .browser-item:hover { + transform: translateY(-3px); + background: transparent !important; + box-shadow: none !important; +} +.browser-container .browser-thumb-wrapper { + position: relative; + aspect-ratio: 1; + background: var(--bg-card); + border: 1px solid var(--rule); + border-radius: 0 !important; + overflow: hidden; + box-shadow: 0 14px 30px -10px rgba(0,0,0,0.5); + transition: all 280ms var(--ease); + margin-bottom: 14px; +} +.browser-container .browser-item:hover .browser-thumb-wrapper { + border-color: var(--copper); + box-shadow: 0 20px 40px -10px rgba(0,0,0,0.65); +} +.browser-container .browser-thumbnail { + width: 100%; + height: 100%; + object-fit: cover; + border-radius: 0 !important; +} +.browser-container .browser-icon { + color: var(--ink-mute); +} +.browser-container .browser-item-info { padding: 0; } +.browser-container .browser-item-name { + font-family: var(--serif); + font-style: normal; + font-weight: 400; + font-size: 16px; + color: var(--ink); + font-variation-settings: 'opsz' 18; + letter-spacing: 0; + line-height: 1.25; + margin-bottom: 4px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} +.browser-container .browser-item-meta, +.browser-container .browser-item-type { + font-family: var(--mono); + font-size: 10px; + letter-spacing: 0.12em; + text-transform: uppercase; + color: var(--ink-mute); +} +.browser-container .browser-play-overlay { + background: rgba(14, 13, 11, 0.55); +} +.browser-container .browser-play-overlay svg { + fill: var(--ink); + filter: drop-shadow(0 4px 12px rgba(0,0,0,0.6)); +} +.browser-container .browser-empty { + grid-column: 1 / -1; + color: var(--ink-mute); + font-family: var(--serif); + font-style: italic; + font-size: 16px; + text-align: center; + padding: 60px 20px; + font-variation-settings: 'opsz' 30; +} + +/* List view — editorial table */ +.browser-container .browser-list { + background: transparent !important; + border: 1px solid var(--rule); + border-radius: 0 !important; +} +.browser-container .browser-list-header { + background: var(--bg-paper) !important; + border-bottom: 1px solid var(--rule-strong) !important; + color: var(--ink-mute) !important; + font-family: var(--mono); + font-size: 10px; + letter-spacing: 0.18em; + text-transform: uppercase; + padding: 12px 16px; +} +.browser-container .browser-list-item { + border-bottom: 1px solid var(--rule); + transition: background 180ms var(--ease); + padding: 10px 16px; +} +.browser-container .browser-list-item:hover { background: var(--bg-paper); } +.browser-container .browser-list-name { + font-family: var(--serif); + font-style: normal; + font-size: 15px; + color: var(--ink); + font-variation-settings: 'opsz' 18; +} +.browser-container .browser-list-bitrate, +.browser-container .browser-list-duration, +.browser-container .browser-list-size { + font-family: var(--mono); + font-size: 11px; + color: var(--ink-mute); + font-variant-numeric: tabular-nums; +} + +/* Pagination — hairline buttons */ +.browser-container .pagination { + background: transparent !important; + border: 0 !important; + border-top: 1px solid var(--rule) !important; + margin-top: 36px; + padding-top: 22px !important; + display: flex; + align-items: center; + gap: 18px; +} +.browser-container .pagination button { + background: transparent !important; + border: 1px solid var(--rule-strong) !important; + color: var(--ink-soft) !important; + border-radius: 0 !important; + font-family: var(--mono); + font-size: 11px; + letter-spacing: 0.18em; + text-transform: uppercase; + padding: 8px 16px !important; + transition: all 180ms var(--ease); + cursor: pointer; +} +.browser-container .pagination button:hover:not(:disabled) { + color: var(--copper) !important; + border-color: var(--copper) !important; +} +.browser-container .pagination button:disabled { opacity: 0.35; cursor: not-allowed; } +.browser-container .pagination-center { + display: inline-flex; + align-items: center; + gap: 8px; + font-family: var(--mono); + font-size: 11px; + color: var(--ink-mute); +} +.browser-container .page-input { + background: transparent !important; + border: 1px solid var(--rule-strong) !important; + color: var(--ink) !important; + border-radius: 0 !important; + font-family: var(--mono); + font-size: 11px; + padding: 6px 8px !important; + width: 60px; + text-align: center; +} +.browser-container .pagination-showing { + margin-left: auto; + font-family: var(--mono); + font-size: 10px; + letter-spacing: 0.12em; + text-transform: uppercase; + color: var(--ink-faint); +} + +/* ─── QUICK ACCESS — console rail ─────────────────────────── */ +.scripts-container .scripts-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); + gap: 1px; + background: var(--rule); + border: 1px solid var(--rule-strong); + padding: 0; + margin: 0; +} +.scripts-container .script-btn, +.scripts-container .link-card { + background: var(--bg-card) !important; + border: 0 !important; + border-radius: 0 !important; + padding: 26px 18px !important; + color: var(--ink) !important; + transition: all 200ms var(--ease) !important; + text-align: center; + display: flex !important; + flex-direction: column !important; + align-items: center !important; + justify-content: center !important; + cursor: pointer; + min-height: 120px; +} +.scripts-container .script-btn:hover, +.scripts-container .link-card:hover { + background: var(--bg-card-2) !important; + color: var(--copper) !important; + transform: none !important; +} +.scripts-container .script-btn .browser-icon, +.scripts-container .link-card .browser-icon { + color: var(--ink-soft); + margin-bottom: 14px; + font-size: 22px; + width: 32px; + height: 32px; + display: flex; + align-items: center; + justify-content: center; + transition: all 200ms var(--ease); +} +.scripts-container .script-btn:hover .browser-icon, +.scripts-container .link-card:hover .browser-icon { + color: var(--copper); + transform: translateY(-2px); +} +.scripts-container .script-btn .browser-item-name, +.scripts-container .link-card .browser-item-name { + font-family: var(--serif); + font-style: italic; + font-weight: 400; + font-size: 15px; + color: inherit; + font-variation-settings: 'opsz' 18; + letter-spacing: 0; + line-height: 1.2; + margin: 0; +} +.scripts-container .scripts-empty { + grid-column: 1 / -1; + background: var(--bg-card); + padding: 80px 24px; + color: var(--ink-mute); + font-family: var(--serif); + font-style: italic; + font-size: 16px; + text-align: center; + font-variation-settings: 'opsz' 30; + border: 1px dashed var(--rule-strong); +} +.scripts-container .scripts-empty p { color: inherit; } + +/* ─── SETTINGS — numbered editorial cards ─────────────────── */ +.settings-container { counter-reset: sr-section; } + +.settings-container .settings-section { + background: var(--bg-card) !important; + border: 1px solid var(--rule) !important; + border-radius: 0 !important; + padding: 28px 32px !important; + margin-bottom: 16px; + box-shadow: none !important; + transition: border-color 200ms var(--ease); + position: relative; + counter-increment: sr-section; +} +.settings-container .settings-section:hover { + border-color: var(--rule-strong) !important; +} + +.settings-container .settings-section summary { + font-family: var(--serif); + font-weight: 400; + font-style: normal; + font-size: 24px; + letter-spacing: -0.015em; + color: var(--ink); + font-variation-settings: 'opsz' 60; + padding: 0 0 14px 0 !important; + border: 0 !important; + background: transparent !important; + cursor: pointer; + list-style: none; + position: relative; + display: flex; + align-items: baseline; + gap: 14px; +} +.settings-container .settings-section summary::-webkit-details-marker { display: none; } +.settings-container .settings-section summary::before { + content: "5." counter(sr-section, decimal-leading-zero); + font-family: var(--mono); + font-style: normal; + font-size: 10px; + letter-spacing: 0.22em; + color: var(--copper); + flex-shrink: 0; + line-height: 2.2; +} +.settings-container .settings-section summary::after { + content: "↓"; + margin-left: auto; + font-family: var(--sans); + font-size: 16px; + color: var(--ink-mute); + transition: transform 240ms var(--ease); + font-weight: 400; +} +.settings-container .settings-section[open] summary::after { + transform: rotate(180deg); +} + +.settings-container .settings-section-content { + padding-top: 18px; + border-top: 1px solid var(--rule); +} + +.settings-container .settings-section-description { + font-family: var(--serif); + font-style: italic; + font-size: 14px; + color: var(--ink-soft); + line-height: 1.55; + font-variation-settings: 'opsz' 18; + margin-bottom: 22px; +} + +/* Settings tables */ +.settings-container .scripts-table { + border: 1px solid var(--rule); + border-collapse: collapse; + width: 100%; + background: transparent; + font-family: var(--sans); +} +.settings-container .scripts-table thead { + background: var(--bg-paper); +} +.settings-container .scripts-table th { + font-family: var(--mono); + font-size: 10px; + letter-spacing: 0.18em; + text-transform: uppercase; + color: var(--ink-mute); + padding: 12px 14px; + text-align: left; + border-bottom: 1px solid var(--rule-strong); + font-weight: 400; +} +.settings-container .scripts-table td { + padding: 14px; + border-bottom: 1px solid var(--rule); + color: var(--ink-soft); + font-size: 13px; + vertical-align: middle; +} +.settings-container .scripts-table tr:last-child td { border-bottom: 0; } +.settings-container .scripts-table tr:hover td { background: rgba(255,255,255,0.02); } +.settings-container .scripts-table .name-with-icon { + color: var(--ink); + font-family: var(--serif); + font-style: normal; + font-size: 15px; + font-variation-settings: 'opsz' 18; +} +.settings-container .scripts-table .path-cell, +.settings-container .scripts-table .mono { + font-family: var(--mono); + font-size: 11px; + color: var(--ink-mute); +} + +/* Add card — editorial dashed border */ +.settings-container .add-card { + background: transparent !important; + border: 1px dashed var(--rule-strong) !important; + border-radius: 0 !important; + padding: 16px !important; + margin-top: 16px; + transition: all 200ms var(--ease); + color: var(--ink-mute) !important; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; +} +.settings-container .add-card:hover { + border-color: var(--copper) !important; + border-style: solid !important; + color: var(--copper) !important; + background: rgba(224, 128, 56, 0.04) !important; +} +.settings-container .add-card-icon { + font-family: var(--serif); + font-weight: 300; + font-size: 24px; + color: inherit; + line-height: 1; +} + +/* Audio device selector inside settings */ +.settings-container .audio-device-selector { + display: flex; + flex-direction: column; + gap: 14px; +} +.settings-container .audio-device-selector label { + display: flex; + flex-direction: column; + gap: 8px; + font-family: var(--mono); + font-size: 10px; + letter-spacing: 0.18em; + text-transform: uppercase; + color: var(--ink-mute); +} +.settings-container .audio-device-selector select { + background: transparent !important; + border: 1px solid var(--rule-strong) !important; + color: var(--ink) !important; + border-radius: 0 !important; + font-family: var(--sans); + font-size: 13px; + padding: 10px 12px !important; + cursor: pointer; +} +.settings-container .audio-device-status { + font-family: var(--mono); + font-size: 11px; + letter-spacing: 0.12em; + text-transform: uppercase; + padding: 8px 12px; + border: 1px solid var(--rule); + background: var(--bg-paper); + display: inline-flex; + align-items: center; + gap: 8px; +} +.settings-container .audio-device-status.active { color: var(--jade); border-color: var(--jade); } +.settings-container .audio-device-status.available { color: var(--amber); border-color: var(--amber); } +.settings-container .audio-device-status.unavailable { color: var(--rust); border-color: var(--rust); } +.settings-container .audio-device-status::before { + content: "●"; + font-size: 10px; + color: currentColor; +} + +/* Folder badges */ +.settings-container .folder-disabled-badge, +.settings-container .folder-unavailable-badge { + background: transparent !important; + border: 1px solid currentColor !important; + border-radius: 0 !important; + font-family: var(--mono); + font-size: 9px; + letter-spacing: 0.18em; + text-transform: uppercase; + padding: 3px 8px !important; + color: var(--amber); +} +.settings-container .folder-unavailable-badge { color: var(--rust); } + +/* Empty state */ +.settings-container .empty-state { + color: var(--ink-mute); + font-family: var(--serif); + font-style: italic; + font-size: 14px; + font-variation-settings: 'opsz' 18; + padding: 40px 20px; + text-align: center; +} +.settings-container .empty-state-illustration { + color: var(--ink-faint); +} +.settings-container .empty-state-illustration svg { + width: 48px; + height: 48px; + margin-bottom: 14px; + fill: none; + stroke: currentColor; + stroke-width: 1.5; +} + +/* Action buttons (edit/delete inside table rows) */ +.settings-container .action-btn, +.settings-container .action-buttons button { + background: transparent !important; + border: 1px solid var(--rule-strong) !important; + color: var(--ink-soft) !important; + border-radius: 0 !important; + width: 30px; + height: 30px; + padding: 0 !important; + display: inline-flex !important; + align-items: center; + justify-content: center; + cursor: pointer; + transition: all 180ms var(--ease); +} +.settings-container .action-btn:hover, +.settings-container .action-buttons button:hover { + color: var(--copper) !important; + border-color: var(--copper) !important; +} +.settings-container .action-btn.danger:hover, +.settings-container .action-buttons button.danger:hover { + color: var(--rust) !important; + border-color: var(--rust) !important; +} + +/* ─── DISPLAY tab ─────────────────────────────────────────── */ +.display-container .display-monitors { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); + gap: 18px; +} +.display-container .display-monitors > .empty-state-illustration { + grid-column: 1 / -1; + text-align: center; + padding: 80px 24px; + color: var(--ink-mute); + font-family: var(--serif); + font-style: italic; + font-size: 16px; + font-variation-settings: 'opsz' 30; + border: 1px dashed var(--rule); +} +.display-container .display-monitors > .empty-state-illustration svg { + width: 56px; + height: 56px; + margin-bottom: 14px; + color: var(--ink-faint); +} + +/* Monitor card (rendered by JS — accept any direct children as cards) */ +.display-container .display-monitors > div:not(.empty-state-illustration) { + background: var(--bg-card); + border: 1px solid var(--rule); + padding: 22px 24px; + transition: border-color 200ms var(--ease); + border-radius: 0; +} +.display-container .display-monitors > div:not(.empty-state-illustration):hover { + border-color: var(--rule-strong); +} + +/* Headings inside any monitor card */ +.display-container .display-monitors h3 { + font-family: var(--serif); + font-style: normal; + font-weight: 400; + font-size: 18px; + color: var(--ink); + font-variation-settings: 'opsz' 30; + letter-spacing: -0.01em; + margin-bottom: 8px; +} +.display-container .display-monitors button { + background: transparent; + border: 1px solid var(--rule-strong); + color: var(--ink-soft); + border-radius: 0; + font-family: var(--mono); + font-size: 10px; + letter-spacing: 0.18em; + text-transform: uppercase; + padding: 8px 14px; + cursor: pointer; + transition: all 180ms var(--ease); +} +.display-container .display-monitors button:hover { + color: var(--copper); + border-color: var(--copper); +} + +/* ─── ICON SELECT POPUP & TRIGGER (used by settings dialogs) ─── */ +.icon-select-trigger { + background: transparent !important; + border: 1px solid var(--rule-strong) !important; + border-radius: 0 !important; + color: var(--ink) !important; + font-family: var(--mono); + font-size: 12px; + padding: 8px 12px !important; + cursor: pointer; + transition: border-color 180ms var(--ease); +} +.icon-select-trigger:hover { + border-color: var(--copper) !important; + color: var(--copper) !important; +} +.icon-select-popup { + background: var(--bg-card) !important; + border: 1px solid var(--rule-strong) !important; + border-radius: 0 !important; + box-shadow: 0 14px 40px rgba(0,0,0,0.5) !important; +} +.icon-select-cell { + border-radius: 0 !important; + color: var(--ink-soft) !important; + font-family: var(--mono); + font-size: 10px; +} +.icon-select-cell:hover { + background: rgba(224, 128, 56, 0.06) !important; + color: var(--copper) !important; +} + +/* Mobile: tighten padding for non-player tabs */ +@media (max-width: 720px) { + .browser-container .browser-grid { gap: 22px 16px; } + .scripts-container .scripts-grid { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); } + .scripts-container .script-btn, + .scripts-container .link-card { padding: 18px 12px !important; min-height: 100px; } + .settings-container .settings-section { padding: 20px !important; } + .settings-container .settings-section summary { font-size: 20px; } + .browser-container .breadcrumb { font-size: 15px; } +}