From 35729c1f9e2782362649e74da46da8faa1be99ce Mon Sep 17 00:00:00 2001 From: KeelrLeek <156356974+KeelrLeek@users.noreply.github.com> Date: Tue, 28 Jul 2026 17:40:22 -0500 Subject: [PATCH] navigation: state the bar's geometry instead of collapsing a margin for it Hoisting the glass bar out of the pages (8017c0d) dropped the artist page's hero 24px, so the artwork began below the bar instead of running under it. The bar used to be each page's FIRST CHILD, and its `margin-top: -24px` collapsed through the page root -- pulling `.artist-page` itself up to the top of the pane, where the hero could sit behind the bar. As a sibling it cannot do that, so the root fell back to the pane's padding edge and took the artwork with it: `.artist-page` is `position: relative` and the whole `.hero-bg` stack is positioned against its box. Diffing every element in the page against the previous build, 16 moved and all by exactly +24: .hero-bg, .hero-seed, .gpu-hero, canvas.banner (the visible one), the twins, .seam-clip/.seam-tail and .sheetclip. The other 94 did not move at all -- the flow content was never the problem, which is why this did not show up as content shifting. That geometry is now stated rather than emergent. The bar's margin-bottom is -bar-h, so its net flow contribution is -pane-pad: it consumes no height of its own AND cancels the pane's top padding, leaving the page's box flush with the top of the pane. Each page under the bar hands that inset back with `padding-top: var(--pane-pad)`, which is a no-op for the hero (padding does not move a positioned ancestor's padding-box top) and restores every flow child. The pane's 24px is now a named custom property rather than a number repeated in four rules with a comment warning they are tied. Verified against the pre-hoist build element by element: 87 artist-page elements compared, ZERO moved, including canvas.banner back at 84 and the Fanart wordmark at 883. Album page root 38, hero 62, tracklist 514 -- identical. The bar still paints above the hero (elementFromPoint at its centre returns the bar), arrival still animates only the arriving crumb, Back still animates nothing, and a page with no bar is untouched at the pane's padding edge. 85 JS tests pass. The verification that let this through checked the page's top against my own model of the layout rather than against the previous build, and the model omitted margin collapsing. The before/after element diff above is the check that would have caught it. --- src/App.svelte | 18 +++++++++++---- src/components/GlassBar.svelte | 42 +++++++++++++++++++++++++--------- src/views/CatalogAlbum.svelte | 8 +++++++ src/views/CatalogArtist.svelte | 6 +++++ 4 files changed, 59 insertions(+), 15 deletions(-) diff --git a/src/App.svelte b/src/App.svelte index 61afb2c..08b4b2b 100644 --- a/src/App.svelte +++ b/src/App.svelte @@ -44,7 +44,12 @@ here and lives above whichever view is current — see the note at the top of GlassBar.svelte for what a per-view instance cost. Views that do not show it yet hide it; the component is never unmounted, so its crumb - memory survives every navigation, including out to Home and back. */ + memory survives every navigation, including out to Home and back. + + A page added here MUST also take `padding-top: var(--pane-pad)`: the bar + cancels the pane's top padding so a page's artwork can run underneath it, + and the page restores that inset for its own content. Without it the page + renders 24px too high; with it but not listed here, 24px too low. */ const BAR_VIEWS = new Set(["catalogArtist", "catalogAlbum"]); initEvents(); @@ -72,8 +77,9 @@
+ padding. It consumes no flow height of its own AND cancels the + pane's top padding, so the page after it begins flush with the top + of the pane and its artwork runs under the bar. -->
@@ -137,12 +143,16 @@ away with the content, keeping the seam colors identical at every scroll position. */ background-attachment: local; + /* The pane's top padding, named because three other rules are tied to + it: the glass bar bleeds up over it, cancels it for what follows, and + each page under the bar restores it as its own padding-top. */ + --pane-pad: 24px; border-radius: var(--radius); overflow-y: auto; overflow-anchor: none; /* Main scroll pane: no elastic rubber-band at its edges. Inner regions deliberately do NOT set this, so their wheel chains here. */ overscroll-behavior: none; - padding: 24px 28px; + padding: var(--pane-pad) 28px; } diff --git a/src/components/GlassBar.svelte b/src/components/GlassBar.svelte index 3b7b4b4..0c07947 100644 --- a/src/components/GlassBar.svelte +++ b/src/components/GlassBar.svelte @@ -125,23 +125,43 @@