dark glass, the whole app: frost on every pane, and the periscope pattern for every glass bar the frost sits under - backdrop-filter black-flattens over see-through ground (measured 3-vs-40), so bars over frost blur a scroll-synced clone behind a static band cut instead; the bar moved out of the scroller (pane shell, inner .content keeping the closest-contract, the old negative-margin flow replayed by a spacer after the artist page's sticky physics named the scrollport padding sacred); painted pages declare data-painted and keep the real backdrop bar, which is how the artist hero runs under the glass again; np wash rides the scroll away and dissolves to frost like the album banner; perf measured to vsync - 142px blur wraps (27.9ms frames down to 6.9), idle scroll-gated reclones, clip-path band, content-visibility on library rows, async cover decode; mini frosts over the mini:glass channel and the rest-frame flags ride window config because the env-var lane dies on some webview2 runtimes

This commit is contained in:
KeelrLeek committed 2026-08-26 14:55:25 -05:00
1 parent 225c9139aa
commit 6ba1864498
16 files changed
+821 -117

No files matched your search

+76 -20
View File
@@ -137,14 +137,18 @@
scrim intercepts pointer input and the dialog traps the keyboard.
The titlebar stays live for window chrome. -->
<Sidebar />
<main class="content" use:floatScroll inert={previewUi.open || undefined}>
<!-- First child of the scroll pane: the bar's sticky pin and its
negative bleed margins are measured against THIS element's
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. -->
<!-- The pane is a SHELL with the bar floating absolute over an inner
scroller — the same bar-over-scroller relationship the sidebar's
gbar and the np head have, which is what lets the dark-glass band
mask sit statically on the scroller (a bar INSIDE the scroller
would be masked with it; the per-frame page-mask this replaces
never tracked cleanly). The inner div KEEPS the .content class:
every page resolves its scroll pane via closest(".content"). -->
<main class="pane-shell" class:barless={!BAR_VIEWS.has(ui.view)} inert={previewUi.open || undefined}>
<GlassBar hidden={!BAR_VIEWS.has(ui.view)} />
<CurrentView />
<div class="content" use:floatScroll>
<CurrentView />
</div>
</main>
<NowPlaying />
<PlayerBar />
@@ -224,7 +228,17 @@
acrylic. The panes above it all paint their own opaque surfaces and
must stay untouched. */
:global(:root.glass) .app {
background: rgba(0, 0, 0, 0.7);
background: rgba(0, 0, 0, 0.55);
}
/* Dark glass, the content pane (TEST, album page first — 2026-08-26):
the pane joins the frost at the shared 0.35. The top-highlight
gradient is a solid-mode grounding for hero seams; under glass the
hero tails are thinned instead (see CatalogAlbum), so the frost is
flat here. GlassBar drops its backdrop under glass for the same
measured reason as every other bar (slab over frost). */
:global(:root.glass) .content {
background: rgba(0, 0, 0, 0.35);
}
/* Collapsed left nav: narrow the sidebar column to an icon rail. The
@@ -250,8 +264,30 @@
--nowplaying-width: var(--nowplaying-rail);
}
.content {
/* The shell: grid cell, corner clip, and the two named lengths — on the
SHELL so both the bar (its child now) and every page (descendants of
the scroller) inherit them. Purely structural; all paint and scroll
behavior stays on the inner .content below. */
.pane-shell {
grid-area: content;
position: relative;
border-radius: var(--radius);
overflow: hidden;
/* The pane's top padding, named because three other rules are tied to
it: the glass bar's height pairs with it and each page under the bar
restores it as its own padding-top. */
--pane-pad: 24px;
/* The glass bar's height, declared HERE rather than on the bar so pages
can clear it. A page with a hero (artist, album) wants its artwork to
run underneath the bar and only takes --pane-pad back; a page with no
artwork behind the bar (search) has to start below it, or its first
heading sits under the frost at rest. */
--bar-h: 46px;
}
.content {
position: absolute;
inset: 0;
background: linear-gradient(var(--bg-highlight) 0, var(--bg-base) 240px);
/* The highlight wash belongs to the top of the PAGE, not the viewport:
anchored to the pane (default `scroll`), the gradient stays put
@@ -261,22 +297,42 @@
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;
/* The glass bar's height, declared HERE rather than on the bar so pages
can clear it. A page with a hero (artist, album) wants its artwork to
run underneath the bar and only takes --pane-pad back; a page with no
artwork behind the bar (search) has to start below it, or its first
heading sits under the frost at rest. */
--bar-h: 46px;
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;
/* The ORIGINAL padding, all views: the artist page's pinned/sticky
physics are tuned against a scrollport with this exact top
padding — zeroing it shifted every sticky offset 24px and the
page collapsed into itself (2026-08-26). The bar's old job of
cancelling this padding for what follows (so hero pages start
flush at the pane top) is reproduced by the spacer below. */
padding: var(--pane-pad) 28px;
}
/* The absolute bar contributes no flow, so this zero-height spacer
replays its old net-flow trick: on bar views, pull everything after
it up by exactly --pane-pad — the page's box starts flush at the
pane top, and each hero page restores its own inset, precisely the
pre-restructure contract. Barless views keep the classic inset. */
:global(.pane-shell:not(.barless) > .content)::before {
content: "";
display: block;
height: 0;
margin-bottom: calc(-1 * var(--pane-pad));
}
/* Dark glass: the band cut, the sidebar's exact move — static, in the
scroller's own box coordinates, with the bar safely OUTSIDE as a
sibling. clip-path, NOT mask-image: the cut is a hard edge, and a
rectangle clip stays on the compositor's fast path where an alpha
mask forced the 7k-node library through ~14ms raster frames
(measured 2026-08-26). Skipped on barless views. */
:global(:root.glass) .pane-shell:not(.barless) > .content {
clip-path: inset(var(--bar-h) 0 0 0);
}
/* Painted pages (data-painted roots) keep their content running under
the bar for the real backdrop to sample — GlassBar's periscope effect
lifts this clip INLINE when it toggles .painted-page (an inline write
outranks this rule without a specificity war). */
</style>