From 914bd7cd6aa14e839332a98d91c30b19865b0cf2 Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Sun, 17 May 2026 15:25:52 +0300 Subject: Restructure repo: move Go server into player-server/ --- web/css/components.css | 262 ------------------ web/css/layout.css | 729 ------------------------------------------------- web/css/lightbox.css | 79 ------ web/css/login.css | 65 ----- web/css/player.css | 302 -------------------- web/css/theme.css | 117 -------- 6 files changed, 1554 deletions(-) delete mode 100644 web/css/components.css delete mode 100644 web/css/layout.css delete mode 100644 web/css/lightbox.css delete mode 100644 web/css/login.css delete mode 100644 web/css/player.css delete mode 100644 web/css/theme.css (limited to 'web/css') diff --git a/web/css/components.css b/web/css/components.css deleted file mode 100644 index a81753a..0000000 --- a/web/css/components.css +++ /dev/null @@ -1,262 +0,0 @@ -/* Buttons */ -.btn { - display: inline-flex; - align-items: center; - justify-content: center; - gap: 0.35rem; - padding: 0.5rem 0.85rem; - border-radius: var(--radius-sm); - border: 1px solid transparent; - font-size: 0.85rem; - font-weight: 600; - line-height: 1.2; - cursor: pointer; - background: var(--bg-elevated); - color: var(--text-primary); - transition: background var(--transition-fast), border-color var(--transition-fast), transform 80ms ease; -} -.btn:hover { background: var(--bg-surface-hover); } -.btn:active { transform: translateY(1px); } -.btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; } - -.btn-primary { - background: var(--accent); - color: var(--text-inverse); - border-color: var(--accent-active); -} -.btn-primary:hover { background: var(--accent-hover); } -.btn-danger { - background: var(--danger); - color: var(--text-inverse); - border-color: var(--danger-active); -} -.btn-danger:hover { background: var(--danger-hover); } -.btn-ghost { - background: transparent; - color: var(--text-secondary); - border-color: var(--border); -} -.btn-ghost:hover { color: var(--text-primary); background: var(--bg-surface-hover); } -.btn-sm { padding: 0.3rem 0.55rem; font-size: 0.78rem; } -.btn-lg { padding: 0.65rem 1.1rem; font-size: 0.95rem; } - -/* Icon buttons */ -.icon-btn { - width: 2.25rem; - height: 2.25rem; - border-radius: var(--radius-sm); - background: transparent; - border: 1px solid transparent; - color: var(--text-secondary); - cursor: pointer; - display: inline-flex; - align-items: center; - justify-content: center; - font-size: 1.05rem; - line-height: 1; - padding: 0; - transition: background var(--transition-fast), color var(--transition-fast); -} -.icon-btn:hover { background: var(--bg-surface-hover); color: var(--text-primary); } -.icon-btn.active { color: var(--accent); background: var(--accent-soft); } - -/* Forms */ -input, textarea, select { - font: inherit; - color: var(--text-primary); - background: var(--bg-elevated); - border: 1px solid var(--border); - border-radius: var(--radius-sm); - padding: 0.5rem 0.65rem; - width: 100%; -} -input:focus, textarea:focus, select:focus { - outline: none; - border-color: var(--accent); - box-shadow: 0 0 0 3px var(--accent-soft); -} -label { - display: block; - font-size: 0.8rem; - font-weight: 600; - margin: 0.35rem 0 0.2rem; - color: var(--text-secondary); -} - -.input-sm { - width: auto; - min-width: 5rem; - max-width: 8rem; - padding: 0.35rem 0.5rem; - font-size: 0.78rem; -} - -/* Error message */ -.error-message { - color: var(--danger); - font-size: 0.85rem; - min-height: 1.25rem; - margin: 0.35rem 0 0; -} - -/* Search bar */ -.search-bar { - position: relative; - display: flex; - align-items: center; - gap: 0.4rem; - background: var(--bg-elevated); - border: 1px solid var(--border); - border-radius: var(--radius-md); - padding: 0.25rem 0.6rem; - max-width: min(100%, 72rem); - width: 100%; -} -.search-overlay { - position: fixed; - inset: 1rem 1rem auto 1rem; - z-index: 90; - display: flex; - justify-content: center; - pointer-events: none; -} -.search-overlay.hidden { - display: none; -} -.search-overlay-bar { - align-items: flex-start; - flex-wrap: wrap; - max-width: min(72rem, calc(100vw - 2rem)); - box-shadow: var(--shadow-lg); - pointer-events: auto; -} -.search-bar input { - background: transparent; - border: none; - padding: 0.35rem 0.2rem; - flex: 1 1 18rem; - min-width: 8rem; -} -.search-bar input:focus { box-shadow: none; } -.tag-filter-list { - display: flex; - align-items: center; - flex-wrap: wrap; - gap: 0.3rem; - flex: 1 1 18rem; - min-width: 0; - max-width: none; -} -.tag-filter-chip { - display: inline-flex; - align-items: center; - flex: 0 0 auto; - max-width: 9rem; - min-height: 2rem; - padding: 0.25rem 0.5rem; - border: 1px solid var(--border); - border-radius: var(--radius-sm); - background: transparent; - color: var(--text-secondary); - font: inherit; - font-size: 0.78rem; - cursor: pointer; -} -.tag-filter-chip:hover, -.tag-filter-chip:focus-visible { - background: var(--bg-surface-hover); - color: var(--text-primary); - outline: none; -} -.tag-filter-chip.active { - border-color: var(--accent); - background: var(--accent-soft); - color: var(--text-primary); -} -.tag-filter-chip span { - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} -/* Search syntax help tooltip */ -.search-help { - position: absolute; - top: calc(100% + 0.5rem); - left: 0; - background: var(--bg-surface); - border: 1px solid var(--border-strong); - border-radius: var(--radius-md); - box-shadow: var(--shadow-lg); - padding: 0.6rem 0.75rem; - font-size: 0.78rem; - color: var(--text-secondary); - z-index: 45; - max-width: 22rem; - line-height: 1.5; -} -.search-help-title { - font-weight: 600; - color: var(--text-primary); - margin-bottom: 0.35rem; - font-size: 0.82rem; -} -.search-help-row { - display: flex; - flex-wrap: wrap; - align-items: center; - gap: 0.35rem; -} -.search-help-row code { - font-family: var(--font-mono); - font-size: 0.75rem; - background: var(--bg-elevated); - border: 1px solid var(--border); - border-radius: var(--radius-sm); - padding: 0.15rem 0.35rem; - color: var(--text-primary); -} - -/* Toast */ -.toast { - position: fixed; - bottom: 1rem; - right: 1rem; - background: var(--bg-surface); - color: var(--text-primary); - border: 1px solid var(--border-strong); - border-radius: var(--radius-md); - box-shadow: var(--shadow-lg); - padding: 0.65rem 0.9rem; - z-index: 110; - font-size: 0.85rem; - transform: translateY(120%); - opacity: 0; - transition: transform var(--transition-base), opacity var(--transition-base); -} -.toast.show { transform: translateY(0); opacity: 1; } -.toast.info { border-left: 4px solid var(--accent); } -.toast.success { border-left: 4px solid var(--success); } -.toast.error { border-left: 4px solid var(--danger); } - -/* Share rows */ -.share-row { cursor: pointer; outline: none; } -.share-row.selected { background: var(--accent-soft); border-left: 3px solid var(--accent); padding-left: calc(0.25rem - 3px); } -.share-row:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; } - -.shares-hint { - font-size: 0.75rem; - color: var(--text-secondary); - padding: 0.5rem 0.25rem; - text-align: center; - border-top: 1px solid var(--border); -} -.shares-hint kbd { - display: inline-block; - padding: 0.08rem 0.3rem; - font-family: inherit; - font-size: 0.7rem; - background: var(--bg-elevated); - border: 1px solid var(--border); - border-radius: var(--radius-sm); - color: var(--text-primary); -} diff --git a/web/css/layout.css b/web/css/layout.css deleted file mode 100644 index bc71bdd..0000000 --- a/web/css/layout.css +++ /dev/null @@ -1,729 +0,0 @@ -/* Reset & base */ -*, *::before, *::after { box-sizing: border-box; } -html, body { - height: 100%; -} -body { - margin: 0; - font-family: var(--font-sans); - background: var(--bg-body); - color: var(--text-primary); - line-height: 1.45; -} - -/* Header */ -.site-header { - position: fixed; - inset: 0 0 auto 0; - height: var(--header-height); - background: var(--bg-surface); - border-bottom: 1px solid var(--border); - display: flex; - align-items: center; - gap: var(--gap); - padding: 0 1rem; - z-index: 50; - transform: translateY(calc(-100% + 0.45rem)); - transition: transform var(--transition-base); -} -.site-header::after { - content: ""; - position: absolute; - left: 0; - right: 0; - bottom: -0.45rem; - height: 0.45rem; -} -.site-header:hover, -.site-header:focus-within { - transform: translateY(0); -} -.header-main { - display: flex; - align-items: center; - gap: var(--gap); - flex: 1 1 auto; - min-width: 0; -} -.site-header .logo { - font-weight: 700; - letter-spacing: 0.04em; - color: var(--text-primary); - text-decoration: none; - display: inline-flex; - align-items: center; - gap: 0.35rem; -} -.site-header .logo-img { - height: 1.5rem; - width: auto; - display: block; -} -.site-header .spacer { flex: 1 1 auto; } - -.scan-indicator { - position: fixed; - top: 0.75rem; - right: 0.75rem; - z-index: 120; - display: inline-flex; - align-items: center; - gap: 0.4rem; - max-width: min(22rem, calc(100vw - 1.5rem)); - padding: 0.25rem 0.55rem; - border: 1px solid var(--border); - border-radius: var(--radius-sm); - background: var(--bg-elevated); - color: var(--text-secondary); - box-shadow: var(--shadow-sm); - font-size: 0.78rem; - line-height: 1.2; - pointer-events: none; - white-space: nowrap; -} -.scan-indicator.hidden { - display: none; -} -.scan-indicator span:last-child { - overflow: hidden; - text-overflow: ellipsis; -} -.scan-dot { - width: 0.5rem; - height: 0.5rem; - flex: 0 0 auto; - border-radius: 50%; - background: var(--accent); - box-shadow: 0 0 0 0 var(--accent-soft); - animation: scanPulse 1.4s ease-out infinite; -} -@keyframes scanPulse { - 0% { box-shadow: 0 0 0 0 var(--accent-soft); } - 100% { box-shadow: 0 0 0 0.45rem transparent; } -} - -/* Sidebar */ -.sidebar { - position: fixed; - inset: var(--header-height) auto 0 0; - width: var(--sidebar-width); - background: var(--bg-surface); - border-right: 1px solid var(--border); - overflow: auto; - padding: 0.75rem 0.5rem; - display: none; /* hidden by default */ - flex-direction: column; - gap: 0.25rem; - z-index: 40; -} -.sidebar.open { - display: flex; -} -.sidebar h2 { - font-size: 0.75rem; - text-transform: uppercase; - letter-spacing: 0.08em; - color: var(--text-muted); - margin: 0.5rem 0.5rem 0.25rem; - padding-bottom: 0.25rem; - border-bottom: 1px solid var(--border); -} -.sidebar .set-item { - display: block; - padding: 0.4rem 0.6rem; - border-radius: var(--radius-sm); - color: var(--text-secondary); - text-decoration: none; - cursor: pointer; - user-select: none; -} -.sidebar .set-item:hover, -.sidebar .set-item:focus-visible { - background: var(--bg-surface-hover); - color: var(--text-primary); - outline: none; -} -.sidebar .set-item.active { - background: var(--accent-soft); - color: var(--accent); - font-weight: 600; -} -.sidebar .set-item.selected { - border: 2px solid var(--accent); - background: var(--bg-elevated); - color: var(--text-primary); - font-weight: 600; -} -.sidebar-header { - display: flex; - align-items: center; - justify-content: space-between; -} - -/* Main layout */ -.page { - padding-top: var(--header-height); - min-height: 100vh; -} -.page.has-sidebar { - padding-left: var(--sidebar-width); -} -.main-content { - padding: var(--gap); - max-width: 100%; -} - -/* Breadcrumb bar */ -.breadcrumb-bar { - display: flex; - align-items: center; - gap: 0.35rem; - flex-wrap: wrap; - margin-bottom: 0.75rem; - font-size: 0.85rem; -} -.breadcrumb-bar.hidden { display: none !important; } -.breadcrumb-bar button { - background: transparent; - border: none; - color: var(--accent); - padding: 0.15rem 0.25rem; - cursor: pointer; - font: inherit; - border-radius: var(--radius-sm); -} -.breadcrumb-bar button:hover { background: var(--accent-soft); } -.breadcrumb-bar .breadcrumb-sep { color: var(--text-muted); user-select: none; } - -/* Folder card placeholder */ -.folder-card .thumb-wrap .placeholder { font-size: 3rem; } -.set-card .thumb-wrap .placeholder { font-size: 3rem; } -.set-card .thumb-wrap img + .placeholder { display: none; } - -/* Media grid */ -.media-grid { - display: grid; - grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr)); - gap: var(--gap); -} -.media-pager { - display: flex; - align-items: center; - justify-content: space-between; - gap: 0.75rem; - padding: 0.5rem 0.65rem; - border: 1px solid var(--border); - border-radius: var(--radius-sm); - background: var(--bg-surface); -} -.media-pager-top { - margin-bottom: 0.1rem; -} -.media-pager-bottom { - margin-top: 0.1rem; -} -.media-page-summary { - color: var(--text-secondary); - font-size: 0.85rem; -} -.media-card { - position: relative; - background: var(--bg-surface); - border: 1px solid var(--border); - border-radius: var(--radius-md); - overflow: hidden; - cursor: pointer; - transition: transform var(--transition-fast), box-shadow var(--transition-fast), border-color var(--transition-fast); -} -.media-card:hover { - box-shadow: var(--shadow-md); - border-color: var(--border-strong); -} -.media-card.selected { - border-color: var(--selected-border); - background: var(--selected-bg); -} -.media-card.playing { - border-color: var(--playing-border); - background: var(--playing-bg); -} -.media-card .thumb-wrap { - position: relative; - aspect-ratio: 16 / 9; - background: var(--bg-elevated); - display: flex; - align-items: center; - justify-content: center; - overflow: hidden; -} -.media-card .thumb-wrap img { - width: 100%; - height: 100%; - object-fit: cover; - display: block; -} -.media-card .thumb-wrap .placeholder { - color: var(--text-muted); - font-size: 0.85rem; -} -.media-card .meta { - padding: 0.55rem 0.65rem; - display: flex; - flex-direction: column; - gap: 0.15rem; - min-height: 3.5rem; -} -.media-card .title { - font-size: 0.9rem; - font-weight: 600; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} -.media-card .subtitle { - font-size: 0.78rem; - color: var(--text-secondary); - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} -.media-card .badge { - position: absolute; - top: 0.35rem; - right: 0.35rem; - font-size: 0.65rem; - padding: 0.15rem 0.4rem; - border-radius: var(--radius-sm); - background: var(--bg-overlay); - color: var(--text-primary); -} - -.media-card .card-actions { - position: absolute; - bottom: 0.35rem; - left: 0; - right: 0; - display: flex; - gap: 0.25rem; - justify-content: center; - opacity: 0; - transition: opacity var(--transition-fast); - z-index: 2; -} -.media-card:hover .card-actions, -.media-card.selected .card-actions, -.media-card.playing .card-actions { - opacity: 1; -} - -/* Audio row variant */ -.media-row { - display: flex; - align-items: center; - gap: 0.75rem; - padding: 0.5rem 0.75rem; - background: var(--bg-surface); - border: 1px solid var(--border); - border-radius: var(--radius-md); - cursor: pointer; - transition: border-color var(--transition-fast), background var(--transition-fast); -} -.media-row:hover { - background: var(--bg-surface-hover); - border-color: var(--border-strong); -} -.media-row.selected { - border-color: var(--selected-border); - background: var(--selected-bg); -} -.media-row.playing { - border-color: var(--playing-border); - background: var(--playing-bg); -} -.media-row .row-icon { - color: var(--text-muted); - font-size: 1.1rem; -} -.media-row .row-body { - min-width: 0; - flex: 1 1 auto; -} -.media-row .row-title { - font-size: 0.9rem; - font-weight: 600; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} -.media-row .row-meta { - font-size: 0.78rem; - color: var(--text-secondary); -} -.media-row .row-duration { - font-size: 0.78rem; - color: var(--text-muted); - white-space: nowrap; -} - -.media-row .row-cover { - width: 2.8rem; - height: 2.8rem; - object-fit: cover; - border-radius: var(--radius-sm); - flex-shrink: 0; - background: var(--bg-elevated); -} - -/* Hide row action buttons unless hovered/selected/playing */ -.media-row button[data-action] { - opacity: 0; - transition: opacity var(--transition-fast); -} -.media-row:hover button[data-action], -.media-row.selected button[data-action], -.media-row.playing button[data-action] { - opacity: 1; -} - -/* Modal */ -.modal-overlay { - position: fixed; - inset: 0; - background: var(--bg-overlay); - display: grid; - place-items: center; - z-index: 100; - opacity: 0; - visibility: hidden; - transition: opacity var(--transition-base), visibility var(--transition-base); -} -.modal-overlay.open { - opacity: 1; - visibility: visible; -} -.modal { - background: var(--bg-surface); - border: 1px solid var(--border-strong); - border-radius: var(--radius-lg); - box-shadow: var(--shadow-lg); - width: min(40rem, 92vw); - max-height: 86vh; - overflow: auto; - padding: 1.25rem; -} -.modal-header { - display: flex; - align-items: center; - gap: 0.5rem; - margin-bottom: 0.75rem; -} -.modal-header h3 { margin: 0; font-size: 1.1rem; } -.modal-header .spacer { flex: 1 1 auto; } - -/* Help modal */ -.help-modal { - width: min(64rem, 96vw); -} -.help-content { - overflow: auto; -} -.help-shortcuts { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr)); - gap: 0.35rem 0.75rem; - font-size: 0.88rem; -} -.help-row { - display: grid; - grid-template-columns: minmax(4.6rem, auto) 1fr; - align-items: center; - gap: 0.5rem; - min-height: 2rem; - padding: 0.25rem 0.35rem; - border-bottom: 1px solid var(--border); -} -.help-row > span:first-child { - white-space: nowrap; - font-family: var(--font-mono); -} -.help-content kbd { - display: inline-block; - padding: 0.15rem 0.4rem; - border-radius: var(--radius-sm); - background: var(--bg-elevated); - border: 1px solid var(--border-strong); - font-size: 0.8rem; - min-width: 1.6rem; - text-align: center; -} -.help-shares { - line-height: 1.7; -} - -/* Media info modal */ -.media-info-table { - width: 100%; - border-collapse: collapse; - font-size: 0.9rem; -} -.media-info-table th, -.media-info-table td { - padding: 0.45rem 0.5rem; - border-bottom: 1px solid var(--border); - vertical-align: top; -} -.media-info-table th { - width: 11rem; - color: var(--text-secondary); - font-weight: 600; - text-align: left; -} -.media-info-table td { - color: var(--text-primary); - overflow-wrap: anywhere; -} -.media-info-raw { - margin-top: 1rem; - font-size: 0.85rem; -} -.media-info-raw summary { - cursor: pointer; - color: var(--text-secondary); -} -.media-info-raw pre { - max-height: 18rem; - overflow: auto; - padding: 0.75rem; - border: 1px solid var(--border); - border-radius: var(--radius-sm); - background: var(--bg-elevated); - color: var(--text-primary); - white-space: pre-wrap; - overflow-wrap: anywhere; -} - -/* Responsive */ -@media (max-width: 860px) { - :root { - --header-height: 3rem; - --sidebar-width: 0; - } - .site-header { - gap: 0.35rem; - padding: 0 0.5rem; - } - .header-main { - gap: 0.35rem; - } - .search-bar { - max-width: none; - min-width: 0; - flex: 1 1 auto; - } - .sidebar { - position: fixed; - inset: var(--header-height) auto auto 0; - width: 100%; - height: auto; - max-height: 70vh; - border-right: none; - border-bottom: 1px solid var(--border); - display: none; - } - .sidebar.open { display: flex; } - .page { padding-left: 0; } - .page.has-sidebar { padding-left: 0; } - .player { inset: auto 0 0 0 !important; } - .toolbar { - flex-wrap: wrap; - gap: 0.35rem; - } - .toolbar .input-sm { - min-width: 4.5rem; - max-width: none; - flex: 1 1 4.5rem; - } - .site-header .logo { - font-size: 0.9rem; - } - #theme-toggle, - #user-name { - display: none; - } - #logout-btn { - padding: 0.3rem 0.5rem; - font-size: 0.75rem; - } - .media-grid { grid-template-columns: repeat(auto-fill, minmax(10rem, 1fr)); } -} - -@media (max-width: 520px) { - .media-grid { grid-template-columns: repeat(2, 1fr); } - .toolbar .input-sm { - min-width: 3.5rem; - } -} - -/* Utilities */ -.hidden { display: none !important; } -.overflow-hidden { overflow: hidden; } - -/* Layout helpers */ -.flex { display: flex; } -.flex-wrap { flex-wrap: wrap; } -.justify-end { justify-content: flex-end; } -.align-center { align-items: center; } -.gap-1 { gap: 0.25rem; } -.gap-2 { gap: 0.5rem; } -.gap-3 { gap: 0.75rem; } -.gap-4 { gap: 1rem; } -.mt-1 { margin-top: 0.25rem; } -.mt-2 { margin-top: 0.5rem; } -.mt-3 { margin-top: 0.75rem; } -.my-1 { margin: 0.25rem 0; } -.mb-2 { margin-bottom: 0.5rem; } -.py-1 { padding-top: 0.25rem; padding-bottom: 0.25rem; } -.border-b { border-bottom: 1px solid var(--border); } -.text-sm { font-size: 0.85rem; } -.text-xs { font-size: 0.8rem; } -.text-75 { font-size: 0.75rem; } -.text-90 { font-size: 0.9rem; } -.text-muted { color: var(--text-muted); } -.text-danger { color: var(--danger); } -.flex-1-18 { flex: 1 1 18rem; } -.flex-col { flex-direction: column; } -.truncate { - min-width: 0; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} -.set-row { - display: flex; - align-items: center; - gap: 0.25rem; - padding-right: 0.25rem; -} -.tag-chip { - display: inline-flex; - align-items: center; - gap: 0.2rem; - padding: 0.2rem 0.5rem; - border-radius: var(--radius-sm); - background: var(--accent-soft); - color: var(--accent); - font-size: 0.78rem; -} -.grid-full { grid-column: 1 / -1; } - -/* Toolbar */ -.toolbar { - display: flex; - align-items: center; - gap: 0.5rem; - margin-bottom: 0.75rem; -} - -/* Empty state hint */ -.empty-hint { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - min-height: 50vh; - gap: 0.5rem; - text-align: center; -} -.empty-hint p { - margin: 0; - font-size: 1.1rem; - color: var(--text-secondary); -} -.empty-hint kbd { - display: inline-block; - padding: 0.15rem 0.4rem; - border-radius: var(--radius-sm); - background: var(--bg-elevated); - border: 1px solid var(--border-strong); - font-family: var(--font-mono); - font-size: 0.85rem; -} -.empty-hint.hidden { display: none !important; } - -/* Modal sizes */ -.modal-wide { width: min(56rem, 96vw); } - -/* Admin lists */ -.admin-list { - list-style: none; - padding: 0; - margin: 0; - display: flex; - flex-direction: column; - gap: 0.35rem; -} -.admin-list li { - display: flex; - align-items: center; - justify-content: space-between; - padding: 0.25rem 0.35rem; - border-radius: var(--radius-sm); -} -.admin-list li.is-admin { - background: var(--accent-soft); -} - -#admin-permissions { - max-width: 100%; - overflow-x: auto; -} - -.admin-table { - width: max-content; - min-width: 100%; - border-collapse: collapse; - font-size: 0.82rem; -} - -.admin-table th, -.admin-table td { - padding: 0.35rem 0.45rem; - border-bottom: 1px solid var(--border); - text-align: left; - vertical-align: middle; - white-space: nowrap; -} - -.admin-table th:first-child, -.admin-table td:first-child { - max-width: 12rem; - overflow: hidden; - text-overflow: ellipsis; -} - -.admin-table .perm-select { - min-width: 5.5rem; -} - -.podcast-feed-row { - display: flex; - align-items: center; - gap: 0.5rem; - padding: 0.35rem 0; - border-bottom: 1px solid var(--border); -} - -.podcast-feed-cover { - width: 2.5rem; - height: 2.5rem; - border-radius: var(--radius-sm); - object-fit: cover; - background: var(--bg-elevated); - border: 1px solid var(--border); - flex: 0 0 auto; -} - -.btn-download-episode { - align-self: flex-start; - margin-top: 0.2rem; -} diff --git a/web/css/lightbox.css b/web/css/lightbox.css deleted file mode 100644 index 83bf946..0000000 --- a/web/css/lightbox.css +++ /dev/null @@ -1,79 +0,0 @@ -.lightbox-overlay { - position: fixed; - inset: 0; - z-index: 80; - background: var(--bg-overlay); - display: none; - place-items: center; -} -.lightbox-overlay.open { - display: grid; -} - -.lightbox-stage { - width: 90vw; - height: 85vh; - display: grid; - place-items: center; - overflow: hidden; -} -#lightbox-image { - max-width: 100%; - max-height: 100%; - object-fit: contain; - transition: transform 0.15s ease; - user-select: none; - cursor: zoom-in; -} - -.lightbox-nav { - position: absolute; - top: 50%; - transform: translateY(-50%); - background: var(--bg-surface); - border: 1px solid var(--border); - font-size: 2rem; - padding: 0.5rem 1rem; - cursor: pointer; -} -.lightbox-prev { - left: 1rem; -} -.lightbox-next { - right: 1rem; -} -.lightbox-close { - position: absolute; - top: 1rem; - right: 1rem; - background: var(--bg-surface); - border: 1px solid var(--border); - cursor: pointer; -} - -.lightbox-toolbar { - position: absolute; - bottom: 1rem; - left: 50%; - transform: translateX(-50%); - display: flex; - gap: 0.5rem; - align-items: center; - background: var(--bg-surface); - padding: 0.5rem 1rem; - border-radius: var(--radius-lg); - border: 1px solid var(--border); -} -.lightbox-meta { - font-size: 0.875rem; - color: var(--text-secondary); - margin-left: 0.5rem; - white-space: nowrap; -} -.lightbox-counter { - font-size: 0.875rem; - color: var(--text-secondary); - margin-left: 0.5rem; - white-space: nowrap; - font-variant-numeric: tabular-nums; -} diff --git a/web/css/login.css b/web/css/login.css deleted file mode 100644 index a7b3ae0..0000000 --- a/web/css/login.css +++ /dev/null @@ -1,65 +0,0 @@ -/* Login / bootstrap page layout */ -*, *::before, *::after { box-sizing: border-box; } -html, body { min-height: 100%; } -body { - margin: 0; - font-family: var(--font-sans); - background: var(--bg-body); - color: var(--text-primary); -} -.login-container { - min-height: 100vh; - min-height: 100dvh; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - gap: 1rem; - padding: 2rem 1rem; - background: var(--bg-body); -} -.login-brand { - width: min(100%, 24rem); - display: flex; - align-items: center; - justify-content: center; - gap: 0.75rem; -} -.login-container h1 { - margin: 0; - color: var(--text-primary); - font-size: 1.55rem; - line-height: 1.1; -} -.login-container .subtitle { - margin: 0.3rem 0 0; - color: var(--text-secondary); - font-size: 0.85rem; -} -.login-form { - width: 100%; - max-width: 24rem; - background: var(--bg-surface); - border: 1px solid var(--border); - border-radius: var(--radius-md); - box-shadow: var(--shadow-md); - padding: 1.35rem; -} -.login-form label { - margin: 0 0 0.35rem; - color: var(--text-secondary); -} -.login-form input { - margin-bottom: 0.85rem; -} -.login-form .btn { - width: 100%; - margin-top: 0.15rem; -} - -.login-logo { - width: 3rem; - height: 3rem; - display: block; - flex: 0 0 auto; -} diff --git a/web/css/player.css b/web/css/player.css deleted file mode 100644 index 45d80bc..0000000 --- a/web/css/player.css +++ /dev/null @@ -1,302 +0,0 @@ -/* Player */ -.player { - position: fixed; - inset: auto auto 1rem 1rem; - width: var(--floating-w, 320px); - height: var(--floating-h, 240px); - background: var(--player-bg); - color: var(--text-primary); - border: 1px solid var(--border); - border-radius: 0.5rem; - box-shadow: 0 8px 32px rgba(0,0,0,0.4); - overflow: hidden; - z-index: 60; - display: none; /* hidden by default until something plays */ - transition: inset var(--transition-base), width var(--transition-base), height var(--transition-base), box-shadow var(--transition-base); -} -.player.open { - display: flex; - flex-direction: column; -} -.player .stage { - flex: 1 1 auto; - position: relative; - height: auto; - background: var(--player-stage-bg); - overflow: hidden; -} -.player .big-play .play-icon { - width: 2rem; - height: 2rem; - font-size: 0.8rem; -} -.player.minimized { - inset: auto auto 1rem 1rem; - width: min(20rem, calc(100vw - 2rem)); - border: 1px solid var(--border); - border-radius: var(--radius-sm); - box-shadow: 0 8px 32px rgba(0,0,0,0.4); - overflow: hidden; -} -.player.minimized .stage, -.player.minimized .controls { - display: none; -} -.player .player-restore { - display: none; -} -.player.minimized .player-restore { - display: flex; - align-items: center; - width: 100%; - min-height: 2.25rem; - padding: 0.45rem 0.65rem; - border: 0; - background: var(--player-bg); - color: var(--text-secondary); - cursor: pointer; - font: inherit; - font-size: 0.8rem; - text-align: left; -} -.player.minimized .player-restore:hover { - color: var(--text-primary); - background: var(--bg-surface-hover); -} -.player.minimized .player-restore span { - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} -.player.is-fullscreen { - inset: 0; - width: auto; - height: auto; - border: 0; - border-radius: 0; - box-shadow: none; - background: var(--player-stage-bg); - display: flex; - flex-direction: column; - justify-content: center; -} - -.detach-page { - margin: 0; - width: 100vw; - height: 100vh; - overflow: hidden; - background: var(--bg-body); -} - -/* Detached popup: fill the whole popup window */ -.player.detached { - position: relative; - inset: 0; - width: 100%; - height: 100%; - border-radius: 0; - border: none; - box-shadow: none; - display: flex; - flex-direction: column; -} -.player.detached .stage { - flex: 1 1 auto; - height: auto !important; - overflow: hidden; -} -.player.detached .controls { - flex: 0 0 auto; -} - -.player.is-fullscreen .stage { - flex: 1 1 auto; - height: auto; - display: flex; - align-items: center; - justify-content: center; -} - -.player video, .player audio { - width: 100%; - height: 100%; - display: block; - object-fit: contain; -} -.player.is-fullscreen video, .player.is-fullscreen audio { - max-height: 100%; -} - -.player.crop-mode video { - object-fit: cover; - object-position: var(--crop-x, 50%) var(--crop-y, 50%); -} - -.crop-indicator { - font-size: 0.75rem; - color: var(--text-secondary); - padding: 0 0.25rem; - user-select: none; -} - -/* Cover art for audio playback */ -.player .cover-art { - width: 100%; - height: 100%; - object-fit: contain; - display: block; - background: var(--player-stage-bg); -} - -/* Image viewer inside player */ -.player .media-image { - width: 100%; - height: 100%; - object-fit: contain; - display: block; - transition: transform 0.15s ease; - user-select: none; -} -.player .media-image.hidden { - display: none; -} - -/* Show/hide controls per media type */ -.player.has-image .video-only { - display: none !important; -} -.player:not(.has-image) .image-only { - display: none !important; -} - -/* Overlay controls */ -.player .controls { - flex: 0 0 auto; - display: flex; - align-items: center; - gap: 0.35rem; - padding: 0.35rem 0.5rem; - border-top: 1px solid var(--border); -} -.player .controls .spacer { flex: 1 1 auto; } - -.player .time { - font-family: var(--font-mono); - font-size: 0.78rem; - color: var(--text-secondary); - white-space: nowrap; -} - -/* Progress bar */ -.progress-track { - position: relative; - flex: 1 1 auto; - height: 0.35rem; - background: var(--player-progress-bg); - border-radius: 999px; - cursor: pointer; - overflow: hidden; -} -.progress-track:hover { height: 0.5rem; } -.progress-buffered { - position: absolute; - inset: 0; - width: 100%; - border-radius: 999px; - background: transparent; - pointer-events: none; - z-index: 1; -} -.progress-fill { - position: absolute; - inset: 0 auto 0 0; - width: 0%; - background: var(--player-progress-fill); - border-radius: 999px; - transition: width 120ms linear; - z-index: 2; -} -.progress-thumb { - position: absolute; - top: 50%; - width: 0.9rem; - height: 0.9rem; - background: var(--player-thumb); - border-radius: 50%; - transform: translate(-50%, -50%) scale(0); - transition: transform var(--transition-fast); - pointer-events: none; - z-index: 3; -} -.progress-track:hover .progress-thumb, -.progress-track:focus-within .progress-thumb { - transform: translate(-50%, -50%) scale(1); -} - -/* Touch-friendly progress bar */ -.progress-track { - touch-action: none; -} - -@media (max-width: 520px) { - .player .controls { - gap: 0.35rem; - padding: 0.4rem 0.5rem; - } - .volume-slider { - width: 3.5rem; - } - .big-play .play-icon { - width: 2.8rem; - height: 2.8rem; - font-size: 1rem; - } -} -.volume-control { - display: flex; - align-items: center; - gap: 0.25rem; -} -.volume-slider { - width: 5rem; - height: 0.25rem; - cursor: pointer; - accent-color: var(--accent); -} - -.detached-bar { - position: fixed; - inset: auto 0 0 0; - background: var(--player-bg); - color: var(--text-primary); - border-top: 1px solid var(--border); - z-index: 59; - padding: 0.5rem 0.75rem; - text-align: center; - font-size: 0.85rem; -} -.detached-bar.hidden { - display: none; -} - -/* Big play button */ -.big-play { - position: absolute; - inset: 0; - display: grid; - place-items: center; - background: var(--overlay-dim); - cursor: pointer; - z-index: 5; -} -.big-play .play-icon { - width: 3.5rem; - height: 3.5rem; - border-radius: 50%; - background: var(--overlay-button-bg); - color: var(--overlay-button-color); - display: grid; - place-items: center; - font-size: 1.25rem; -} diff --git a/web/css/theme.css b/web/css/theme.css deleted file mode 100644 index 2649dea..0000000 --- a/web/css/theme.css +++ /dev/null @@ -1,117 +0,0 @@ -:root { - /* Core palette */ - --bg-body: #0f1117; - --bg-surface: #161920; - --bg-surface-hover: #1b1f27; - --bg-elevated: #1e222c; - --bg-overlay: rgba(0,0,0,0.65); - - /* Text */ - --text-primary: #e6e8ef; - --text-secondary: #a3a8b8; - --text-muted: #6b7280; - --text-inverse: #0b0d12; - - /* Accent */ - --accent: #5e9eff; - --accent-hover: #7cb2ff; - --accent-active: #3d8bf7; - --accent-soft: rgba(94,158,255,0.18); - - /* Borders */ - --border: #252a36; - --border-strong: #2e3546; - - /* Feedback */ - --danger: #f25c5c; - --danger-active: #b91c1c; - --danger-hover: #e04e4e; - --danger-soft: rgba(242,92,92,0.18); - --success: #3ddc84; - --success-soft: rgba(61,220,132,0.18); - --warn: #ffb300; - - /* Player */ - --player-bg: #0b0d12; - --player-stage-bg: #000; - --player-progress-bg: #2e3546; - --player-progress-buffered: #4a5367; - --player-progress-fill: #5e9eff; - --player-thumb: #7cb2ff; - --overlay-dim: rgba(0,0,0,0.35); - --overlay-button-bg: rgba(255,255,255,0.9); - --overlay-button-color: #000; - - /* Selection */ - --selected-bg: rgba(94,158,255,0.25); - --selected-border: #5e9eff; - --playing-bg: rgba(61,220,132,0.18); - --playing-border: #3ddc84; - - /* Layout */ - --header-height: 3.25rem; - --sidebar-width: 16rem; - --gap: 0.75rem; - --radius-sm: 0.375rem; - --radius-md: 0.625rem; - --radius-lg: 0.875rem; - - /* Typography */ - --font-sans: ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, "Apple Color Emoji", "Segoe UI Emoji"; - --font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; - - /* Shadows */ - --shadow-sm: 0 1px 2px rgba(0,0,0,0.35); - --shadow-md: 0 4px 12px rgba(0,0,0,0.45); - --shadow-lg: 0 10px 28px rgba(0,0,0,0.55); - - /* Transitions */ - --transition-fast: 120ms ease; - --transition-base: 200ms ease; -} - -/* Light theme overrides */ -[data-theme="light"] { - --bg-body: #f4f5f8; - --bg-surface: #ffffff; - --bg-surface-hover: #f0f2f7; - --bg-elevated: #ffffff; - --bg-overlay: rgba(0,0,0,0.35); - - --text-primary: #12131a; - --text-secondary: #4a4f5e; - --text-muted: #8b90a0; - --text-inverse: #ffffff; - - --accent: #2b6cb0; - --accent-hover: #1a5490; - --accent-active: #17447a; - --accent-soft: rgba(43,108,176,0.14); - - --border: #d6dae4; - --border-strong: #c3c9d6; - - --danger: #c53030; - --danger-soft: rgba(197,48,48,0.14); - --success: #258855; - --success-soft: rgba(37,136,85,0.14); - - --player-bg: #0b0d12; - --player-stage-bg: #000; - --player-progress-bg: #d6dae4; - --player-progress-buffered: #aab4c4; - --player-progress-fill: #2b6cb0; - --player-thumb: #1a5490; - --overlay-dim: rgba(0,0,0,0.35); - --overlay-button-bg: rgba(255,255,255,0.9); - --overlay-button-color: #000; - - --selected-bg: rgba(43,108,176,0.18); - --selected-border: #2b6cb0; - --playing-bg: rgba(37,136,85,0.14); - --playing-border: #258855; - - --shadow-sm: 0 1px 2px rgba(0,0,0,0.08); - --shadow-md: 0 4px 12px rgba(0,0,0,0.10); - --shadow-lg: 0 10px 28px rgba(0,0,0,0.12); -} -- cgit v1.2.3