ui(mobile): Pocket Edition layout + tablet tab range fix

- Pocket Edition (<=720px): bottom-fixed tab nav with frosted
  backdrop, copper hairline + glow on active, mono numerals +
  abbreviated labels (legacy rule was hiding labels under 600px).
- Single-column hero player tab: centered vinyl + tonearm,
  clamp(28..38px) title, full-width volume row replacing the desktop
  VU cluster (the analog meter is decorative on a phone).
- Mini-player floats above the bottom nav, condensed to art + title +
  play/pause with the hairline progress on the top edge.
- Library pagination stacks to full-width buttons; settings tables
  reflow to card-style rows so no columns drop off-screen.
- Tablet 721-980px: editorial top tabs but with compressed padding so
  all five labels fit without clipping.
- Side-by-side player threshold bumped 980 -> 1240 so the right
  column has genuine room for controls + VU cluster (was clipping
  off the edge at 981-1240px). flex-wrap on .controls as safety net.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-04-25 12:16:51 +03:00
parent b09569f390
commit f85ce77f14
+623 -1
View File
@@ -4375,6 +4375,18 @@ header .brand-sub {
box-shadow: 0 0 12px var(--copper-glow);
}
/* Tablet range: editorial top-tabs but compressed so all 5 labels fit. */
@media (min-width: 721px) and (max-width: 980px) {
.tab-btn {
padding: 14px 12px 12px;
font-size: 12px;
gap: 8px;
}
.tab-btn.active { font-size: 15px; }
.tab-btn .tab-num { font-size: 9px; letter-spacing: 0.12em; }
.container { padding-left: 28px; padding-right: 28px; }
}
/* ─── Update + connection banners (editorial) ────────────────── */
.update-banner,
.connection-banner {
@@ -4512,7 +4524,7 @@ header .brand-sub {
margin-top: 28px;
}
@media (max-width: 980px) {
@media (max-width: 1240px) {
.player-layout,
.now-playing {
grid-template-columns: 1fr;
@@ -5982,6 +5994,25 @@ dialog {
padding: 0;
max-width: 560px;
width: 90%;
max-height: 90vh;
}
dialog[open] {
display: flex;
flex-direction: column;
}
dialog form {
display: flex;
flex-direction: column;
min-height: 0;
flex: 1 1 auto;
}
.dialog-header { flex: 0 0 auto; }
.dialog-footer { flex: 0 0 auto; }
.dialog-body {
flex: 1 1 auto;
min-height: 0;
overflow-y: auto;
overscroll-behavior: contain;
}
dialog::backdrop {
background: rgba(14, 13, 11, 0.7);
@@ -6442,6 +6473,17 @@ footer .separator { color: var(--ink-ghost); margin: 0 8px; }
.mini-player { padding: 12px 16px; gap: 16px; }
.tab-btn { padding: 14px 12px 12px; font-size: 12px; }
.tab-btn.active { font-size: 15px; }
/* Override legacy mobile rule that hid every .tab-btn span (numbers + labels) */
.tab-btn span { display: inline; }
.tab-btn .tab-num { display: none; }
.tab-bar {
flex-wrap: nowrap;
overflow-x: auto;
overscroll-behavior-x: contain;
scrollbar-width: none;
}
.tab-bar::-webkit-scrollbar { display: none; }
.tab-btn { flex: 0 0 auto; }
.breadcrumb { font-size: 14px; }
.browser-toolbar { flex-wrap: wrap; }
.auth-modal { padding: 28px 22px; }
@@ -6914,6 +6956,8 @@ body.audio-spectrum-live .now-playing .spectrum span {
gap: 18px;
margin-top: 0;
justify-content: flex-start;
flex-wrap: wrap;
row-gap: 16px;
}
.now-playing .btn-trans {
@@ -8176,3 +8220,581 @@ select option {
.settings-container .settings-section summary { font-size: 20px; }
.browser-container .breadcrumb { font-size: 15px; }
}
/* ════════════════════════════════════════════════════════════════════
STUDIO REFERENCE — POCKET EDITION
Dedicated mobile layout. Bottom-nav, single-column hero player,
compact chrome. Last in the cascade so it overrides all preceding
legacy + editorial rules.
════════════════════════════════════════════════════════════════════ */
@media (max-width: 720px) {
:root {
--pocket-nav-h: 62px;
--pocket-mini-h: 60px;
}
/* ─── Top folio strip ───────────────────────────────────
Collapse the two corner folios into a single hairline strip at
the very top. Right folio (volume / version) is redundant on
phones — tuck it behind the nav into the version label only.
*/
body > .folio.tl {
top: 0 !important;
left: 0 !important;
right: auto !important;
width: auto;
padding: 7px 12px 7px max(12px, env(safe-area-inset-left));
font-size: 8.5px !important;
letter-spacing: 0.18em !important;
background: linear-gradient(180deg, rgba(14, 13, 11, 0.7) 30%, transparent 100%);
-webkit-backdrop-filter: blur(8px);
backdrop-filter: blur(8px);
}
:root[data-theme="light"] body > .folio.tl {
background: linear-gradient(180deg, rgba(245, 241, 234, 0.85) 30%, transparent 100%);
}
/* Right folio (volume / version) is redundant on phones — hide it.
Version is still discoverable via Settings / About in the API. */
body > .folio.tr { display: none !important; }
/* ─── Container: leave room for top folio + bottom nav + mini-player ─── */
.container {
padding-top: 40px !important;
padding-bottom: calc(var(--pocket-nav-h) + 24px + env(safe-area-inset-bottom)) !important;
}
body.mini-player-visible .container {
padding-bottom: calc(var(--pocket-nav-h) + var(--pocket-mini-h) + 16px + env(safe-area-inset-bottom)) !important;
}
/* ─── Header: tight 2-row layout ───────────────────────── */
header {
grid-template-columns: 1fr !important;
gap: 8px !important;
margin-bottom: 18px !important;
padding-bottom: 14px !important;
}
header .brand-name { font-size: 22px !important; }
header .brand-sub {
font-size: 8px !important;
letter-spacing: 0.4em !important;
margin-top: 4px !important;
}
.header-toolbar {
grid-column: 1 !important;
justify-self: center !important;
flex-wrap: wrap;
justify-content: center;
gap: 0 !important;
}
.header-btn,
.header-btn-logout,
.header-link {
width: 34px !important;
height: 34px !important;
}
.header-toolbar-sep { display: none !important; }
/* Header links preserve their distinctive look but shrink */
.header-locale {
height: 34px !important;
padding: 0 8px !important;
font-size: 10px !important;
}
/* ─── Bottom Tab Bar (replaces top tab bar) ────────────── */
.tab-bar {
position: fixed !important;
bottom: 0 !important;
left: 0 !important;
right: 0 !important;
margin: 0 !important;
padding: 0 max(8px, env(safe-area-inset-left)) env(safe-area-inset-bottom) max(8px, env(safe-area-inset-right)) !important;
background: rgba(14, 13, 11, 0.94) !important;
-webkit-backdrop-filter: blur(20px) saturate(180%);
backdrop-filter: blur(20px) saturate(180%);
border: 0 !important;
border-top: 1px solid var(--rule-strong) !important;
z-index: 999;
overflow: visible !important;
display: grid;
grid-template-columns: repeat(5, 1fr);
gap: 0;
box-shadow: 0 -10px 30px rgba(0, 0, 0, 0.35);
}
:root[data-theme="light"] .tab-bar {
background: rgba(245, 241, 234, 0.92) !important;
box-shadow: 0 -10px 30px rgba(0, 0, 0, 0.10);
}
/* Hairline copper accent strip floating above active tab */
.tab-bar::before {
content: "";
position: absolute;
top: -1px;
left: 16px;
right: 16px;
height: 1px;
background: linear-gradient(90deg,
transparent 0%,
var(--copper) 30%,
var(--copper-hi) 50%,
var(--copper) 70%,
transparent 100%);
opacity: 0.35;
pointer-events: none;
}
/* Re-enable labels (legacy mobile rule hid all spans inside .tab-btn) */
.tab-btn span,
.tab-btn span:not(.tab-num) {
display: inline-block !important;
}
.tab-btn {
height: var(--pocket-nav-h) !important;
padding: 10px 4px !important;
display: flex !important;
flex-direction: column !important;
align-items: center !important;
justify-content: center !important;
gap: 4px !important;
font-family: var(--mono) !important;
font-style: normal !important;
font-size: 9.5px !important;
font-weight: 400 !important;
letter-spacing: 0.12em !important;
text-transform: uppercase;
color: var(--ink-faint) !important;
line-height: 1 !important;
}
.tab-btn .tab-num {
font-size: 11px !important;
letter-spacing: 0.2em !important;
color: var(--ink-mute) !important;
}
.tab-btn span:not(.tab-num) {
font-family: var(--mono) !important;
font-size: 9px !important;
letter-spacing: 0.1em !important;
max-width: 100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.tab-btn:hover {
color: var(--ink-soft) !important;
}
.tab-btn.active {
color: var(--copper) !important;
font-family: var(--mono) !important;
font-style: normal !important;
font-size: 9.5px !important;
}
.tab-btn.active .tab-num,
.tab-btn.active span:not(.tab-num) {
color: var(--copper) !important;
}
/* Active marker: copper bar at TOP of tab (hairline + glow) */
.tab-btn.active::after {
top: -1px !important;
bottom: auto !important;
left: 14% !important;
right: 14% !important;
height: 2px !important;
background: var(--copper) !important;
box-shadow:
0 0 12px var(--copper-glow),
0 0 28px var(--copper-glow) !important;
}
/* ─── Mini-player: float above bottom nav ─────────────── */
.mini-player {
bottom: calc(var(--pocket-nav-h) + env(safe-area-inset-bottom)) !important;
padding: 9px 14px !important;
gap: 12px !important;
border-top: 1px solid var(--rule);
border-bottom: 1px solid var(--rule);
background: rgba(33, 30, 24, 0.92) !important;
-webkit-backdrop-filter: blur(24px) saturate(160%);
backdrop-filter: blur(24px) saturate(160%);
box-shadow: 0 -4px 14px rgba(0, 0, 0, 0.25);
}
:root[data-theme="light"] .mini-player {
background: rgba(255, 252, 246, 0.94) !important;
}
.mini-player::before {
height: 1px !important;
}
.mini-album-art {
width: 38px !important;
height: 38px !important;
border-radius: 2px;
}
.mini-player-info {
min-width: 0 !important;
flex: 1;
gap: 10px !important;
}
.mini-track-title {
font-family: var(--serif);
font-style: italic;
font-weight: 400;
font-size: 13px !important;
color: var(--ink) !important;
font-variation-settings: 'opsz' 30;
}
.mini-artist {
font-family: var(--mono);
font-size: 9.5px !important;
letter-spacing: 0.08em;
text-transform: uppercase;
color: var(--ink-mute) !important;
}
.mini-progress-container {
display: none !important; /* progress lives on the ::before line */
}
.mini-volume-container { display: none !important; }
.mini-controls { gap: 4px !important; }
.mini-nav-btn { display: none !important; }
.mini-control-btn {
width: 38px !important;
height: 38px !important;
background: transparent !important;
border: 1px solid var(--rule-strong) !important;
border-radius: 50%;
}
.mini-control-btn:hover {
border-color: var(--copper) !important;
background: rgba(224, 128, 56, 0.08) !important;
color: var(--copper) !important;
}
.mini-control-btn svg {
width: 16px !important;
height: 16px !important;
}
/* ─── Player tab — single column hero ─────────────────── */
.player-layout,
.now-playing {
grid-template-columns: 1fr !important;
gap: 28px !important;
margin-top: 4px !important;
}
/* Vinyl stage: centered, capped at sensible touch size */
.album-art-container.vinyl-stage {
max-width: 320px;
width: 78%;
margin: 0 auto !important;
}
.vinyl-stage .vinyl { width: 92%; }
.vinyl-stage .vinyl-label {
box-shadow:
inset 0 0 24px rgba(0, 0, 0, 0.4),
0 0 0 3px var(--bg-deep),
0 0 0 4px var(--copper-lo);
}
.vinyl-stage .tonearm {
top: -8% !important;
right: -6% !important;
width: 60% !important;
height: 60% !important;
}
/* Track masthead text: centered, condensed cadence */
.track-masthead { text-align: center; }
.track-masthead > .kicker {
margin-bottom: 14px !important;
gap: 10px !important;
justify-content: center;
font-size: 9px !important;
letter-spacing: 0.36em !important;
}
.track-masthead > .kicker::before { flex-basis: 18px !important; }
.track-masthead > .kicker::after { flex-basis: 18px !important; flex-grow: 0 !important; }
.now-playing #track-title,
.player-layout #track-title {
font-size: clamp(28px, 8vw, 38px) !important;
line-height: 1 !important;
margin-bottom: 10px !important;
letter-spacing: -0.02em !important;
}
.now-playing #artist,
.player-layout #artist {
font-size: 17px !important;
margin-bottom: 4px !important;
}
.now-playing #album,
.player-layout #album {
font-size: 10px !important;
letter-spacing: 0.18em !important;
text-transform: uppercase;
color: var(--ink-mute) !important;
}
/* Meta-grid: 2 columns side-by-side with hairline divider */
.now-playing .meta-grid,
.meta-grid.meta-grid-2,
.player-layout .meta-grid {
grid-template-columns: 1fr 1fr !important;
margin-top: 22px !important;
}
.now-playing .meta-cell,
.meta-grid .meta-cell,
.player-layout .meta-cell {
border-right: 1px solid var(--rule) !important;
border-bottom: 0 !important;
padding: 12px 14px !important;
text-align: left;
min-width: 0;
}
.now-playing .meta-cell:nth-child(2n),
.meta-grid .meta-cell:nth-child(2n),
.player-layout .meta-cell:nth-child(2n) {
border-right: 0 !important;
padding-right: 0 !important;
}
.now-playing .meta-cell:first-child,
.meta-grid .meta-cell:first-child,
.player-layout .meta-cell:first-child {
padding-left: 0 !important;
}
.meta-cell .label,
.meta-cell .meta-label {
font-size: 8.5px !important;
letter-spacing: 0.28em !important;
}
.meta-cell .value,
.meta-cell .meta-value {
font-size: 14px !important;
}
/* Spectrum: shrink so it doesn't dominate */
.now-playing .spectrum,
.player-layout .spectrum {
height: 26px !important;
margin: 18px 0 4px 0 !important;
}
/* Transport: bigger touch targets, centered, no wrap */
.transport { margin-top: 14px !important; }
.progress-row {
gap: 12px !important;
margin-bottom: 22px !important;
}
.progress-row .timecode { font-size: 11px !important; }
.now-playing .controls,
.player-layout .controls {
justify-content: center !important;
gap: 28px !important;
flex-wrap: nowrap !important;
}
.now-playing .controls .btn-trans,
.player-layout .controls .btn-trans {
width: 50px !important;
height: 50px !important;
}
.now-playing .controls .btn-trans.primary,
.player-layout .controls .btn-trans.primary {
width: 68px !important;
height: 68px !important;
}
.now-playing .controls .btn-trans svg { width: 20px !important; height: 20px !important; }
.now-playing .controls .btn-trans.primary svg { width: 26px !important; height: 26px !important; }
/* VU meter is decorative on a phone — hide it. Volume becomes
its own full-width hairline row beneath the controls. */
.now-playing .vu-cluster,
.player-layout .vu-cluster {
display: flex !important;
flex-direction: row !important;
align-items: center;
justify-content: space-between;
gap: 14px !important;
width: 100% !important;
margin: 18px 0 0 0 !important;
padding-top: 16px !important;
border-top: 1px solid var(--rule);
}
.now-playing .vu-meter,
.player-layout .vu-meter { display: none !important; }
.now-playing .vu-readout,
.player-layout .vu-readout {
flex-direction: row !important;
gap: 14px !important;
font-size: 9.5px !important;
letter-spacing: 0.12em !important;
white-space: nowrap;
}
.now-playing .vu-volume,
.player-layout .vu-volume {
flex: 1 1 auto !important;
min-width: 0 !important;
border-right: 0 !important;
margin-right: 0 !important;
padding-right: 0 !important;
justify-content: flex-end;
gap: 12px !important;
}
.now-playing .vu-volume #volume-slider,
.player-layout .vu-volume #volume-slider {
flex: 1 1 auto !important;
width: 100% !important;
max-width: 200px;
height: 3px !important;
}
.now-playing .vu-volume #volume-slider::-webkit-slider-thumb,
.player-layout .vu-volume #volume-slider::-webkit-slider-thumb {
width: 14px !important;
height: 14px !important;
}
.now-playing .vu-volume .mute-btn,
.player-layout .vu-volume .mute-btn {
width: 36px !important;
height: 36px !important;
}
.now-playing .vu-volume .mute-btn svg,
.player-layout .vu-volume .mute-btn svg {
width: 16px !important;
height: 16px !important;
}
/* ─── Library / Browser polish ────────────────────────── */
.browser-container .browser-toolbar {
flex-wrap: wrap !important;
gap: 10px !important;
}
.browser-container .browser-toolbar-right {
margin-left: 0 !important;
}
.browser-search-wrapper {
flex-basis: 100% !important;
order: 10;
max-width: none !important;
}
/* Pagination: column stack, big tap targets */
.pagination {
flex-direction: column !important;
align-items: stretch !important;
gap: 10px !important;
padding: 18px 0 !important;
border-top: 1px solid var(--rule);
margin-top: 20px;
}
.pagination button {
width: 100% !important;
min-height: 42px;
font-family: var(--mono);
font-size: 11px;
letter-spacing: 0.16em;
text-transform: uppercase;
}
.pagination .pagination-center {
justify-content: center;
order: -1;
}
.pagination-showing {
text-align: center !important;
font-family: var(--mono);
font-size: 10px;
letter-spacing: 0.12em;
color: var(--ink-faint);
}
/* ─── Settings: card-like rows for tables ─────────────── */
.settings-container .scripts-table thead { display: none; }
.settings-container .scripts-table,
.settings-container .scripts-table tbody,
.settings-container .scripts-table tr,
.settings-container .scripts-table td {
display: block !important;
width: 100% !important;
}
.settings-container .scripts-table tr {
border: 1px solid var(--rule) !important;
padding: 14px !important;
margin-bottom: 12px !important;
background: rgba(33, 30, 24, 0.32);
}
:root[data-theme="light"] .settings-container .scripts-table tr {
background: rgba(255, 252, 246, 0.6);
}
.settings-container .scripts-table td {
padding: 4px 0 !important;
border: 0 !important;
font-family: var(--sans);
font-size: 13px;
}
.settings-container .scripts-table td:not(:last-child) {
border-bottom: 1px dashed var(--rule) !important;
padding-bottom: 8px !important;
margin-bottom: 8px !important;
}
/* Empty-state row keeps its own block layout */
.settings-container .scripts-table tr:has(.empty-state),
.settings-container .scripts-table tr td.empty-state {
background: transparent;
border: 0 !important;
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;
padding: 28px 22px !important;
}
}
/* ─── Tighter breakpoint for compact phones (<= 420px) ─── */
@media (max-width: 420px) {
.tab-btn span:not(.tab-num) { font-size: 8px !important; }
.tab-btn .tab-num { font-size: 10px !important; }
/* Fewest icons in header — surface only critical chrome */
header .brand-sub { display: none !important; }
header .brand-name { font-size: 20px !important; }
.header-btn[title="API Documentation"],
.header-btn[title="Dynamic background"] {
display: none !important;
}
/* Tonearm + vinyl tighter still */
.album-art-container.vinyl-stage { width: 84%; }
.vinyl-stage .tonearm {
top: -10% !important;
right: -8% !important;
width: 64% !important;
height: 64% !important;
}
.now-playing #track-title,
.player-layout #track-title {
font-size: clamp(24px, 8.5vw, 32px) !important;
}
/* Transport: keep readable but shrink the gap */
.now-playing .controls,
.player-layout .controls { gap: 22px !important; }
.now-playing .controls .btn-trans,
.player-layout .controls .btn-trans { width: 46px !important; height: 46px !important; }
.now-playing .controls .btn-trans.primary,
.player-layout .controls .btn-trans.primary { width: 60px !important; height: 60px !important; }
/* Folio strip text shrinks */
body > .folio.tl,
body > .folio.tr { font-size: 7.5px !important; letter-spacing: 0.14em !important; }
/* Mini-player: shave one icon */
.mini-player { padding: 8px 12px !important; gap: 10px !important; }
.mini-album-art { width: 34px !important; height: 34px !important; }
.mini-control-btn { width: 36px !important; height: 36px !important; }
}