forked from Keelrleek/SoulStream
73a677d35c7a18ab414f3a703df47c8c60bf0ec2
3
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
73a677d35c |
one listener bar, five surfaces: the search page's pill wins and the heat wash is retired
Kyle asked for the popularity bars to match the search page "to keep a
consistent design across the board". They were two designs, and one of them had
quietly drifted into a third.
THE SEARCH PAGE'S PILL IS NOW THE APP-WIDE DESIGN: a visible
rgba(255,255,255,0.07) track, a solid var(--accent) fill scaled by the shared
curve, the full comma-formatted count standing centred on top, 17px tall with
a 4px radius. The album page, the artist page's open-in-place album panel, the
discography's record sections and the artist page's Popular list all draw it.
WHAT WENT AWAY IS THE HEAT WASH. Those three surfaces drove the fill's COLOUR
and ALPHA from the count (--t on the row, alpha ramping 0.30-0.85 via a double
color-mix, digits ramping with it), so length and colour told one story twice
and every page read as a different design. Length is the only encoding now, and
listenerHeat is deleted from listenerBars.js — nothing computes a temperature
any more. The dark-glass CONTRACT's deliberate exclusion for these bars ("their
alpha IS the data encoding") is moot and marked so.
THE DISCOGRAPHY HAD DRIFTED FURTHEST and is the reason this mattered: it
computed peak/heat inline with a LINEAR share, a 6% floor and abbreviated
labels ("12K"), against everyone else's COUNT_GAMMA 0.42 curve, browser-measured
max-content floor and full figures. It now imports listenerBars.js like the
rest, so no two surfaces can disagree about how big a hit is — the reason the
module exists.
THE POPULAR LIST joins them: it was plain right-aligned muted text, deliberately
not accent so the row's own `.now` accent stayed distinct (the ♫ rank and title
still carry that). Its column widened 62px -> 96px, the pill's width, and its
peak is taken over the WHOLE list rather than the visible five so the bars do
not re-scale on Show more.
Kept throughout: unknown counts render an em dash with NO bar (a floor-width
pill behind a dash reads as a measured tiny value), and a column drops entirely
when Last.fm knew nothing.
Verified live against the running app — computed styles on the album and artist
pages match the search bar value-for-value. 98/98 tests.
|
||
|
|
547cee6649 |
dark glass gets a surface ladder, and the 200-750ms stalls are dead - two sessions of uncommitted work landing together
SURFACES: panes add black, surfaces INSIDE panes add white. Every pane stands on 0.7075 black over the acrylic (.content 0.35 over .app 0.55), so a translucent black card nets 0.81 - darker than its own pane and inside the ~0.85 band already rejected once on the artist page. Solid mode's ladder is measured UPWARD from #121212 (+6/+18/+24), so glass elevates with WHITE: new --glass-surface/-hover/-press/-hairline/-well/-ring under :root.glass (0.03/0.08/0.11/0.10/0.18), which is independently the vocabulary .btn-ghost:hover and .ax-ghost:hover already shipped. The four solid tokens are NEVER redefined - they are consumed inside color-mix() and gradient stops where an alpha multiplies through and kills the call site (0.74 x 0.03 = an invisible chip; the album row's text-overflow fade works by BEING opaque), and they paint modal chrome that has to stay solid. 129 additive :global(:root.glass) declarations across 18 files, all 129 verified inside a glass block by walking the diff - solid mode byte-identical, confirmed structurally, by computed style with the class off, and visually. Three of them are not colour swaps: the album row's .rowbtns shim was OCCLUDING the last ~19px of the listeners bar and nothing translucent can occlude, so .tcount masks out just before the buttons instead; Playlist's banner scrim and the discography's pinned ambience both landed on opaque --bg-base and now dissolve like the album banner; and the 0.9 black hero tint on Home/CatalogSearch/Discography paints straight onto the pane when there is no artwork, so :first-child (the {#if} renders no element) flips it to white. Menus, dialogs, toasts and the import surfaces stay opaque deliberately, and the Settings copy for the mode now says so instead of claiming cards do. Measured with a known ground substituted behind the transparent window, since CDP never sees the acrylic: library toolbar chroma +2 as shipped, +16 with a white fill AND its backdrop-filter dropped, +30 for the bare pane beside it. RESIZE: Windows drops the legacy accent-policy acrylic for the whole of a live resize and the window stays transparent through it, so the desktop punches through sharp - measured by toggling window_glass alone, desktop icon labels readable through the titlebar. The blur cannot be kept (documented since Win10 2004, and the modern DWM backdrop was already rejected for the overlay-promotion blink), so armGlassResizeGuard grounds the canvas to --bg-sidebar for the length of the gesture. STALLS: "choppy but the FPS says 144" was 200-750ms MAIN-THREAD TASKS, not frame pacing - idle-scheduled work fires at scroll pauses by definition. Twin bake moved to display resolution and off the ready task (was a same-task 4K WebGL readback plus software blur, 100-170ms per rotation AND per artist entry); gl.finish() -> gl.flush() in buildMaster, which had been draining the whole 4K EASU/RCAS/grade chain on the main thread; copyCanvas realloc guarded; one app-wide scroll clock in scrollbar.js (markAppScroll/appScrollIdleFor) so all three periscopes stop cloning mid-gesture on ANY pane rather than only their own; bounded reclone with the querySelectorAll census deleted, the gate widened 250->1000ms, and the build/attach split across an idle callback and a rAF behind a generation guard; the hero rotation tick gated on scroll recency and its payload cache sized to the working set (2->4 entries, 24->32MiB, 32->64MiB); sessionTick no longer force-rewrites every 12s while merely PAUSED. Scroll storm went from 109-616ms long tasks to zero. Hover recalc and GC were measured innocent - do not re-chase them. 98/98 tests throughout. |
||
|
|
34313e6035 |
discography: the whole catalogue on a page of its own
"Show all" beside the artist page's Discography head opens every release as a stack of album-page heroes with their tracklists — the shapes Kyle picked off the mock: the search page's top-result card as a compact header, the album hero at --cover-scale 0.45 per record, a per-record accent sampled from its own cover, the year rail and the tab summary. The tab row does not stick and there is no Playing badge. Records the artist page has not fetched are shown rather than hidden, and the entrance is the W1 stagger — 300ms in, 55ms per row, 28px of lift, eight rows. It does not re-file the releases. catalog.discoTabs is the artist page's OWN computed tab list, published as it derives it and republished as the evidence improves. It has to work this way: the filing depends on the background description harvest that runs while you look at the artist page and on the MusicBrainz type hints from the deferred identity pass, neither of which is derivable from the payload — so a second classifier would read neither and would quietly file some releases differently from the page that linked to it. One list, computed once, handed over. If the tabs in hand belong to somebody else, opening a discography lands on the artist page instead, which republishes them and puts "Show all" one click away; an empty discography would be a lie about the catalogue. The page's CSS was extracted from src/ rather than retyped — CatalogAlbum's record section, CatalogSearch's header card and PlayerBar's menu, pulled through the same rule-matcher the mockup generator uses — so it inherits the app's measurements instead of approximating them. Verified against the running app: artwork 108px, record hero 114.3, header 147.5, header top 78, bar offset 0, ambience banner 0, rail centring error 0 and 12.8px of clearance at every scroll depth and pane width. Pond files 12+16+2+2 = 32 families on both pages. It is the one page exempt from BAR_VIEWS' padding-top rule, deliberately: its blurred ambience layer has to begin at the very top of the pane, and a padding there would start it halfway through the glass bar. It takes the inset on its header's margin instead, which lands in the same place. |