diff --git a/src/pages/Albums.tsx b/src/pages/Albums.tsx index 598cd610..15b2b678 100644 --- a/src/pages/Albums.tsx +++ b/src/pages/Albums.tsx @@ -188,7 +188,7 @@ export default function Albums() { return (
-
+

{selectionMode && selectedIds.size > 0 ? t('albums.selectionCount', { count: selectedIds.size }) diff --git a/src/pages/Artists.tsx b/src/pages/Artists.tsx index 64726816..0778e598 100644 --- a/src/pages/Artists.tsx +++ b/src/pages/Artists.tsx @@ -172,77 +172,79 @@ export default function Artists() { return (
-
-
-

- {selectionMode && selectedIds.size > 0 - ? t('artists.selectionCount', { count: selectedIds.size }) - : t('artists.title')} -

- setFilter(e.target.value)} - id="artist-filter-input" - /> +
+
+
+

+ {selectionMode && selectedIds.size > 0 + ? t('artists.selectionCount', { count: selectedIds.size }) + : t('artists.title')} +

+ setFilter(e.target.value)} + id="artist-filter-input" + /> +
+ +
+ {!(selectionMode && selectedIds.size > 0) && (<> + + + + + )} + +
-
- {!(selectionMode && selectedIds.size > 0) && (<> - - - - - )} - +
+ {ALPHABET.map(l => ( + + ))}
-
- {ALPHABET.map(l => ( - - ))} -
- {loading &&
} {!loading && viewMode === 'grid' && ( diff --git a/src/pages/NewReleases.tsx b/src/pages/NewReleases.tsx index f1a2181d..b7b836bf 100644 --- a/src/pages/NewReleases.tsx +++ b/src/pages/NewReleases.tsx @@ -137,7 +137,7 @@ export default function NewReleases() { return (
-
+

{selectionMode && selectedIds.size > 0 ? t('albums.selectionCount', { count: selectedIds.size }) diff --git a/src/styles/layout.css b/src/styles/layout.css index 1d3f9357..ae9d2b4b 100644 --- a/src/styles/layout.css +++ b/src/styles/layout.css @@ -1031,6 +1031,33 @@ contain: paint; } +/* Every page re-uses .content-body as its outer wrapper, but App.tsx already + renders one around 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; diff --git a/src/styles/theme.css b/src/styles/theme.css index b31c994b..da05384c 100644 --- a/src/styles/theme.css +++ b/src/styles/theme.css @@ -4035,7 +4035,7 @@ select.input.input:focus { to { opacity: 1; - transform: translateY(0); + transform: none; } }