Current shipping vinyl: pressed grooves, copper-bordered label rim, full album art on the label. Reference baseline for everything below.
+diff --git a/media_server/static/css/styles.css b/media_server/static/css/styles.css index 4cfb1c8..19d8477 100644 --- a/media_server/static/css/styles.css +++ b/media_server/static/css/styles.css @@ -2768,36 +2768,6 @@ button.primary svg { } } -/* Footer */ -footer { - text-align: center; - padding: 0.75rem 1rem; - margin-top: 0.5rem; - color: var(--text-muted); - font-size: 0.75rem; - transition: padding-bottom 0.3s ease-in-out; -} - -body.mini-player-visible footer { - padding-bottom: 70px; -} - -footer a { - color: var(--accent); - text-decoration: none; - transition: color 0.2s; -} - -footer a:hover { - color: var(--accent-hover); - text-decoration: underline; -} - -footer .separator { - margin: 0 0.5rem; - color: var(--text-muted); -} - /* ======================================== Media Browser Styles ======================================== */ @@ -3926,14 +3896,6 @@ html { padding-right: max(1rem, env(safe-area-inset-right)); } -footer { - padding-bottom: max(0.75rem, env(safe-area-inset-bottom)); -} - -body.mini-player-visible footer { - padding-bottom: calc(70px + env(safe-area-inset-bottom, 0px)); -} - .connection-banner { padding-top: max(10px, env(safe-area-inset-top)); } @@ -3991,13 +3953,17 @@ body.mini-player-visible footer { ════════════════════════════════════════════════════════════════ */ /* ─── Container & header ────────────────────────────────────── */ +/* The footer was removed in favour of an About dialog, so the page + bottom is now whatever the active tab content ends with. A 64px + bottom pad left a visible dead band under the player view; 24px + keeps a breath of breathing room without painting an empty page. */ .container { max-width: 1280px; - padding: 56px 48px 64px; + padding: 56px 48px 24px; } @media (max-width: 720px) { - .container { padding: 48px 18px 56px; } + .container { padding: 48px 18px 24px; } } /* ─── Folio marks (page corners, all tabs) ────────────────── */ @@ -4450,9 +4416,15 @@ header .brand-sub { } /* ─── Vinyl stage ──────────────────────────────────────────── */ +/* Aspect-ratio is intentionally wider than tall: the sleeve+disc + composition only fills the top ~82% of a square; a strict 1:1 stage + left an ~18% empty band below the disc and forced the grid row + taller than the masthead column, painting a large dead gap at the + bottom of the page. 1:0.85 trims that band while keeping the disc + (bottom anchor at top:19.4% + 63% = 82.4% of height) safely inside. */ .album-art-container.vinyl-stage { position: relative; - aspect-ratio: 1; + aspect-ratio: 1 / 0.85; width: 100%; max-width: none; padding: 0; @@ -4589,7 +4561,7 @@ header .brand-sub { top: 26%; right: -6%; width: 36%; - height: 36%; + aspect-ratio: 1; pointer-events: none; transform-origin: 88% 12%; transform: rotate(-22deg); @@ -6506,38 +6478,60 @@ dialog::backdrop { .toast.info { border-color: var(--rule-strong); box-shadow: 0 14px 40px rgba(0,0,0,0.5); } /* ═══════════════════════════════════════════════════════════════ - FOOTER (colophon) + ABOUT DIALOG (colophon) ═══════════════════════════════════════════════════════════════ */ -footer { - margin-top: 36px; - padding: 20px 0 0; - border-top: 1px solid var(--rule-strong); - background: transparent; +.about-dialog { + max-width: 520px; +} +.about-credit { + font-family: var(--serif); + font-style: italic; + font-size: 17px; + line-height: 1.5; + color: var(--ink-soft); + margin: 0 0 22px; + font-variation-settings: 'opsz' 30; +} +.about-credit strong { + font-style: italic; + font-weight: 400; + font-size: 22px; + color: var(--ink); + letter-spacing: 0.01em; + font-variation-settings: 'opsz' 60; + display: block; + margin-top: 2px; +} +.about-links { + list-style: none; + margin: 0; + padding: 0; + border-top: 1px solid var(--rule); +} +.about-links li { + display: flex; + flex-direction: column; + gap: 4px; + padding: 14px 0; + border-bottom: 1px solid var(--rule); +} +.about-links-label { font-family: var(--mono); font-size: 10px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--ink-faint); - text-align: center; } -footer a { +.about-links a { + font-family: var(--mono); + font-size: 12px; color: var(--copper); text-decoration: none; border-bottom: 1px solid transparent; transition: border-color 200ms var(--ease); + word-break: break-all; } -footer a:hover { border-bottom-color: var(--copper); } -footer strong { - font-family: var(--serif); - font-style: italic; - font-weight: 400; - font-size: 14px; - color: var(--ink-soft); - letter-spacing: 0.01em; - text-transform: none; - font-variation-settings: 'opsz' 30; -} -footer .separator { color: var(--ink-ghost); margin: 0 8px; } +.about-links a:hover { border-bottom-color: var(--copper); } /* ═══════════════════════════════════════════════════════════════ DISPLAY container (monitors tab) @@ -6597,7 +6591,6 @@ footer .separator { color: var(--ink-ghost); margin: 0 8px; } .auth-modal h2 { font-size: 28px; } .settings-section { padding: 20px; } .settings-section summary { font-size: 22px; } - footer { font-size: 9px; } } /* ════════════════════════════════════════════════════════════════ @@ -8707,14 +8700,6 @@ select option { padding: 0 !important; } - /* ─── Footer: ultra-compact ───────────────────────────── */ - footer { - font-size: 10px !important; - padding: 12px 12px !important; - letter-spacing: 0.04em; - } - footer .separator { margin: 0 4px !important; } - /* Auth modal: full-bleed feel on phones */ .auth-modal { width: 92% !important; diff --git a/media_server/static/index.html b/media_server/static/index.html index 9a76aff..86de2fa 100644 --- a/media_server/static/index.html +++ b/media_server/static/index.html @@ -91,6 +91,9 @@ +
Five renderings of the same disc · Hover variant 04 for the sleeve reveal
+ ← Return to player +Current shipping vinyl: pressed grooves, copper-bordered label rim, full album art on the label. Reference baseline for everything below.
+Vinyl peeks out of a square cardstock sleeve — paper grain, ring-wear circle, worn-corner notch. The album art lives on the sleeve; the disc gets a plain typographic label. Reads instantly as "record on a turntable", not "spinning disc."
+Three layers added to the existing vinyl: a fixed reflection sweep (doesn't rotate with the disc — the studio-light look), paper grain on the label so the print sits in cardstock, and a dead-wax engraving of the master‑lacquer code spinning with the disc. Off-center spindle by 1.5%. Highest visual ROI for the smallest amount of new code.
+Same disc, but the album art on the label is color-graded — duotone copper/emerald, deeper saturation drop, vignette around the label rim. Effect: every album cover ends up looking like it came from the same pressing plant, matching the Studio Reference chrome.
+Hover this card — the disc slides out of the sleeve and starts spinning. In production, this would be wired to the play/pause state: paused = tucked-in sleeve view, playing = disc revealed and spinning. Most evocative, also the most code (animation choreography + state coupling).
+diff --git a/media_server/static/js/app.js b/media_server/static/js/app.js index beafb85..70ffc81 100644 --- a/media_server/static/js/app.js +++ b/media_server/static/js/app.js @@ -14,6 +14,7 @@ import { VOLUME_THROTTLE_MS, VOLUME_RELEASE_DELAY_MS, changeLocale, t, setAuthRequired, + showAboutDialog, closeAboutDialog, } from './core.js'; // Layer 1: Player (tabs, theme, accent, vinyl, visualizer, UI) @@ -129,6 +130,8 @@ Object.assign(window, { toggleDisplayPower, // Audio device onAudioDeviceChanged, + // About + showAboutDialog, closeAboutDialog, }); // ============================================================ @@ -399,6 +402,16 @@ window.addEventListener('DOMContentLoaded', async () => { } }); + // About dialog backdrop click to close + const aboutDialog = document.getElementById('aboutDialog'); + if (aboutDialog) { + aboutDialog.addEventListener('click', (e) => { + if (e.target === aboutDialog) { + closeAboutDialog(); + } + }); + } + // Delegated click handlers for link table actions (XSS-safe) document.getElementById('linksTableBody').addEventListener('click', (e) => { const btn = e.target.closest('[data-action]'); diff --git a/media_server/static/js/core.js b/media_server/static/js/core.js index 6b7959c..2215702 100644 --- a/media_server/static/js/core.js +++ b/media_server/static/js/core.js @@ -397,6 +397,16 @@ export function closeDialog(dialog) { }, { once: true }); } +export function showAboutDialog() { + const dialog = document.getElementById('aboutDialog'); + if (dialog) dialog.showModal(); +} + +export function closeAboutDialog() { + const dialog = document.getElementById('aboutDialog'); + if (dialog) closeDialog(dialog); +} + export function showConfirm(message) { return new Promise((resolve) => { const dialog = document.getElementById('confirmDialog'); diff --git a/media_server/static/locales/en.json b/media_server/static/locales/en.json index 15cefe4..172edc5 100644 --- a/media_server/static/locales/en.json +++ b/media_server/static/locales/en.json @@ -259,8 +259,13 @@ "links.msg.load_failed": "Failed to load link details", "links.confirm.delete": "Are you sure you want to delete the link \"{name}\"?", "links.confirm.unsaved": "You have unsaved changes. Are you sure you want to discard them?", - "footer.created_by": "Created by", - "footer.source_code": "Source Code", + "about.button_title": "About", + "about.title": "About", + "about.created_by": "Created by", + "about.email": "Email", + "about.repository": "Repository", + "about.source_code": "Source Code", + "dialog.close": "Close", "update.available": "Update available: v{version}", "update.view_release": "View Release" } diff --git a/media_server/static/locales/ru.json b/media_server/static/locales/ru.json index 340a5cd..7b7d3f7 100644 --- a/media_server/static/locales/ru.json +++ b/media_server/static/locales/ru.json @@ -259,8 +259,13 @@ "links.msg.load_failed": "Не удалось загрузить данные ссылки", "links.confirm.delete": "Вы уверены, что хотите удалить ссылку \"{name}\"?", "links.confirm.unsaved": "У вас есть несохраненные изменения. Вы уверены, что хотите отменить их?", - "footer.created_by": "Создано", - "footer.source_code": "Исходный код", + "about.button_title": "О программе", + "about.title": "О программе", + "about.created_by": "Создано", + "about.email": "Эл. почта", + "about.repository": "Репозиторий", + "about.source_code": "Исходный код", + "dialog.close": "Закрыть", "update.available": "Доступно обновление: v{version}", "update.view_release": "Перейти к релизу" } diff --git a/media_server/static/vinyl-variants-mockup.html b/media_server/static/vinyl-variants-mockup.html new file mode 100644 index 0000000..c7b6034 --- /dev/null +++ b/media_server/static/vinyl-variants-mockup.html @@ -0,0 +1,911 @@ + + +
+ + +
+ + + + +
+