feat(ux): sticky header on Albums, NewReleases, Artists

Header with search/sort/genre/year controls now pins to top while
scrolling, so filters stay reachable. Nested .content-body (App.tsx
wraps routes) was becoming the sticky anchor and swallowing the effect —
fixed with .content-body .content-body { overflow: visible }.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Psychotoxical
2026-04-18 22:24:22 +02:00
parent c96eb0a805
commit 4f2c313bb7
5 changed files with 98 additions and 69 deletions
+27
View File
@@ -1031,6 +1031,33 @@
contain: paint;
}
/* Every page re-uses .content-body as its outer wrapper, but App.tsx already
renders one around <Routes /> as the scroll container. The inner one must
not establish its own scroll ancestor — otherwise `position: sticky`
children anchor to a container that never scrolls, and the header just
scrolls along with the content. Padding stays: the outer App.tsx
content-body has `padding: 0` inline, the inner one is what gives each
page its breathing room. */
.content-body .content-body {
overflow: visible;
}
/* Sticky page header: keeps page title + filter/search bar visible while the
body scrolls. Negative horizontal margins (+ matching padding) make the
background flush with the scroll container edges so the sticky block looks
like a real bar, not a floating island. `top: 0` clamps below the content-
body's own padding-top; the residual 24px gap above the sticky block while
scrolling is intentional — gives the bar visual breathing room. */
.page-sticky-header {
position: sticky;
top: 0;
z-index: 5;
background: var(--bg-app);
margin: 0 calc(-1 * var(--space-6)) var(--space-5);
padding: var(--space-4) var(--space-6);
border-bottom: 1px solid var(--border-subtle);
}
/* ─── Offline Banner ─── */
.offline-banner {
display: flex;
+1 -1
View File
@@ -4035,7 +4035,7 @@ select.input.input:focus {
to {
opacity: 1;
transform: translateY(0);
transform: none;
}
}