feat: add portrait orientation design for mobile that only triggers in portrait pwa mode

Task #42 completed by ClaudeQueue

ClaudeQueue
This commit is contained in:
Claude Worker
2026-06-30 06:51:31 +00:00
parent 05e78677b0
commit 02153d877d
2 changed files with 162 additions and 1 deletions

View File

@@ -2,7 +2,7 @@
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
<meta name="theme-color" content="#1a1311" />
<meta name="mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-capable" content="yes" />

View File

@@ -1594,3 +1594,164 @@ input[type="range"]::-webkit-slider-thumb:hover { transform: scale(1.25); }
.card.selected .batch-check { background: var(--accent); border-color: var(--accent); color: #fff; }
.card.selected .batch-check::after { content: "✓"; }
.card.selected { border-color: var(--accent) !important; background: var(--bg-2); }
/* ============================================================================
* PORTRAIT PWA — activates only in standalone (installed) mode + portrait
*
* Triggers: @media (display-mode: standalone) and (orientation: portrait)
* Safe areas: env(safe-area-inset-*) applied to all fixed/sticky containers
* so notches and home-indicator bars never obscure UI chrome.
* Layout: Full single-column vertical stack; sidebar stays as drawer only.
* ========================================================================== */
@media (display-mode: standalone) and (orientation: portrait) {
/* --- Root layout: single-column full-width stack ----------------------- */
.app {
grid-template-columns: 1fr;
/* Stack children: topbar → body → mini-bar (all in .main) */
}
/* --- Sidebar: always off-canvas drawer (never occupies grid column) ---- */
.sidebar-toggle { display: inline-flex; }
.sidebar {
position: fixed;
top: 0;
left: 0;
bottom: 0;
width: min(86vw, 300px);
max-width: 300px;
z-index: 100;
border-right: 1px solid var(--line-soft);
box-shadow: var(--shadow);
transform: translateX(-100%);
transition: transform 0.28s var(--ease);
will-change: transform;
/* Respect notch/home-bar on the left edge */
padding-top: calc(22px + env(safe-area-inset-top));
padding-left: calc(14px + env(safe-area-inset-left));
padding-bottom: calc(16px + env(safe-area-inset-bottom));
}
.app.sidebar-open .sidebar { transform: translateX(0); }
.app.sidebar-open .sidebar-backdrop { display: block; opacity: 1; }
/* --- Topbar: full-width, padded for status-bar notch ------------------- */
.topbar {
padding-top: calc(12px + env(safe-area-inset-top));
padding-left: calc(14px + env(safe-area-inset-left));
padding-right: calc(14px + env(safe-area-inset-right));
padding-bottom: 12px;
position: sticky;
top: 0;
z-index: 50;
}
/* --- Body: vertical stack (player above list) -------------------------- */
.body {
flex-direction: column;
overflow-y: auto;
overflow-x: hidden;
/* Let the body scroll instead of individual panes */
height: 100%;
}
/* --- Player pane: full width, compact vertical padding ----------------- */
.player-pane {
flex: none;
width: 100%;
padding: 14px calc(14px + env(safe-area-inset-right)) 14px
calc(14px + env(safe-area-inset-left));
overflow-y: visible; /* scroll is on .body */
}
/* Player stage: keep 16:9 aspect ratio, fill viewport width */
.player-stage {
width: 100%;
aspect-ratio: 16 / 9;
}
/* Controls: wrap btn-row so nothing overflows on narrow screens */
.btn-row {
flex-wrap: wrap;
gap: 7px;
}
/* Now-playing meta: stack vertically */
.now-meta {
flex-direction: column;
gap: 12px;
margin-top: 14px;
}
.np-actions {
flex-wrap: wrap;
gap: 6px;
}
/* --- List pane: full width below player, no side border ---------------- */
.list-pane {
flex: none;
width: 100%;
border-left: none;
border-top: 1px solid var(--line-soft);
/* Give it enough room; body scrolls */
min-height: 40vh;
overflow-y: visible;
padding-left: env(safe-area-inset-left);
padding-right: env(safe-area-inset-right);
}
/* Cards list: scroll within list-pane in portrait */
.cards {
max-height: 50vh;
overflow-y: auto;
padding-bottom: calc(28px + env(safe-area-inset-bottom));
}
/* --- Mini now-playing bar: respect home indicator ---------------------- */
.mini-bar {
padding-bottom: env(safe-area-inset-bottom);
}
.mini-bar-inner {
padding-left: calc(16px + env(safe-area-inset-left));
padding-right: calc(16px + env(safe-area-inset-right));
}
/* --- Toast container: clear home indicator ----------------------------- */
.toast-container {
bottom: calc(26px + env(safe-area-inset-bottom));
}
/* --- Modal: safe-area aware -------------------------------------------- */
.modal-backdrop {
padding: calc(16px + env(safe-area-inset-top))
calc(16px + env(safe-area-inset-right))
calc(16px + env(safe-area-inset-bottom))
calc(16px + env(safe-area-inset-left));
}
/* --- Shortcut overlay: safe-area aware --------------------------------- */
.shortcut-overlay {
padding: calc(16px + env(safe-area-inset-top))
calc(16px + env(safe-area-inset-right))
calc(16px + env(safe-area-inset-bottom))
calc(16px + env(safe-area-inset-left));
}
/* --- Up next list: allow reasonable height on portrait screen ---------- */
.upnext-list {
max-height: 160px;
}
/* --- Related videos panel: compact on portrait ------------------------- */
.related-list {
max-height: 200px;
}
/* --- Hero title: slightly smaller on narrow portrait screens ----------- */
.hero-title { font-size: 30px; }
.ph-logo { width: 68px; height: 68px; font-size: 26px; }
.hero-tagline { font-size: 13px; }
}