From 12936731b3e0caa742131deeed996e4d6cb60b03 Mon Sep 17 00:00:00 2001 From: 3dtours Date: Mon, 28 Sep 2026 18:21:22 +0700 Subject: [PATCH] web: keep the catalogue on one screen Pin the thumbnail strip to the bottom edge of the window, let the wall of thumbs scroll inside the stage with its own scrollbar, and letterbox the preview so the frame fits the screen instead of growing the page. --- docker/frontend/src/Library.tsx | 2 +- docker/frontend/src/styles/app.css | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/docker/frontend/src/Library.tsx b/docker/frontend/src/Library.tsx index 42cded5..acccee5 100644 --- a/docker/frontend/src/Library.tsx +++ b/docker/frontend/src/Library.tsx @@ -217,7 +217,7 @@ export function Library() { ); return ( -
+
diff --git a/docker/frontend/src/styles/app.css b/docker/frontend/src/styles/app.css index 0011692..6471ed1 100644 --- a/docker/frontend/src/styles/app.css +++ b/docker/frontend/src/styles/app.css @@ -994,6 +994,33 @@ input[type="range"] { width: 100%; accent-color: var(--accent); } .adm-danger { color: var(--danger); border-color: var(--border); } .adm-danger:hover:not(:disabled) { border-color: var(--danger); } +/* The catalogue is one screen and never grows: the frame on the stage, the tree + beside it, and the strip pinned to the bottom edge. Whatever overflows scrolls + inside its own panel, so the page itself has no scrollbar to hide the strip + below the fold. Scoped to `.lib-root` — /admin shares the .adm-* blocks and + still scrolls as a page. */ +.lib-root { display: flex; flex-direction: column; height: 100%; overflow: hidden; padding-bottom: 12px; } +.lib-root .adm-frame { flex: 1 1 auto; min-height: 0; } +.lib-root .adm-pane { display: flex; flex-direction: column; min-height: 0; overflow: hidden; } +.lib-root .adm-note { flex: 0 0 auto; } +/* The column: title and the folder's own chips stay put, the split takes what + is left, the strip keeps its natural height on the bottom. */ +.lib-root .adm-col { flex: 1 1 auto; min-height: 0; } +.lib-root .adm-col > .adm-split { flex: 1 1 auto; min-height: 0; align-items: stretch; } +.lib-root .adm-col > .adm-filmstrip { flex: 0 0 auto; } +.lib-root .adm-album-list { max-height: none; flex: 1 1 auto; min-height: 0; } +.lib-root .adm-stage { min-height: 0; overflow: hidden; } +/* The frame fills the stage and the stage fits the window: `object-fit` letterboxes + it inside that box, so a 3:2 or a 4:3 frame stays whole and never pushes the + strip off screen. */ +.lib-root .adm-stage-img { flex: 1 1 auto; min-height: 0; width: 100%; aspect-ratio: auto; object-fit: contain; } +.lib-root .adm-stage > .lib-noimg { flex: 1 1 auto; min-height: 0; aspect-ratio: auto; } +.lib-root .adm-stage > .adm-meta, +.lib-root .adm-stage > .chip-row { flex: 0 0 auto; } +/* All thumbs: the wall scrolls down inside the stage, and its own scrollbar on + the right edge is what reaches the frames below. */ +.lib-root .adm-grid { flex: 1 1 auto; min-height: 0; overflow-y: auto; padding-right: 6px; } + /* Settings drawer: the tabs that organise the page, plus the three panels. */ /* The management frame: a bordered box whose left column is the menu and whose right side is the pane for the chosen section. */