Every track list (album, Liked, Search, Search → Tracks, playlist,
History) now draws its rows with TrackListRow inside a TrackList box,
in place of four row components that had drifted apart:
- TrackListRow owns the look: lead column, title over "artist · album",
like, radio, add to queue, menu, duration, then a trailing slot. It
also owns the stripe, hover, the now-playing band and the
unavailable state. The stripe is dropped on now-playing and selected
rows, where Tailwind would otherwise let `odd:` win.
- TrackRow, PlaylistTrackRow and HistoryRow are wrappers that keep only
their behaviour: track number and multi-select; grip, remove and
dead-entry states; cover and timestamp. Playlist and History rows
gain radio, add and the menu, so every list offers the same actions.
- The radio control is Lucide's Radio icon, not the 📻 emoji.
- Enter on a control inside a row now belongs to that control. The old
TrackRow played the track when Enter was pressed on "add to queue".
- TrackList has no fill, so the stripe shows on playlists too.
Drag reorder (#5393): neodrag kept the drop offset, so after the list
re-rendered the dragged row sat between two slots. reorderDrag, shared
by the playlist and queue rows:
- snaps the row to whole rows while dragging;
- resets it to its slot on drop;
- on playlists, gives the touch gesture to the grip only, so the list
still scrolls by touch.
The playlist page reorders optimistically and rolls back on error.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Merges Renovate's kit 3 (PR #149) and adapter-static 4 (PR #148) bumps,
plus the migration they need. The mechanical part is `sv migrate
sveltekit-3`, run one task at a time and reviewed:
- svelte.config.js is gone. Its options move into sveltekit() in
vite.config.ts, exported as kitOptions so vitest.config.ts runs the
same kit setup, including the $test-utils alias the tests import.
- $lib becomes #lib through package.json "imports". There is no
src/lib/index, so only the "#lib/*" entry is kept.
- tsconfig extends $app/tsconfig.
- Peer floors raised to kit 3's requirements: svelte ^5.57.1, vite
^8.0.12, svelte-check ^4.7.5.
By hand, from the codemod's list of non-automated tasks:
- goto's replaceState option is now replace; keepFocus becomes
reset: false. For the search typeahead, reset: false also stops the
scroll-to-top, which is wanted while typing.
- The test setup mocks drop pushState/replaceState and $app/paths
base/assets, which kit 3 removed, and mock refreshAll in place of
invalidateAll.
- The other flagged files only read page.url or goto internal routes,
so they needed no change.
TypeScript goes to ^6, not the ^7 Renovate offers: kit 3 declares
typescript ^6 as a peer and svelte-check 4.7 accepts ^5 || ^6. Move to
7 once both accept it.
With Tailwind 4 and kit 3 in, `npm audit` on the whole tree reports 0,
so the web lane now audits every dependency rather than only what
ships to browsers.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The raw accent fails AA as text on every dark surface, not only on its
own tint: 3.04:1 on the page, 2.70 on iron, 2.21 on slate, against 4.5.
accent-fg (the house formula, 45% toward parchment) measures 5.62 at
worst across both modes. The operator chose the readable colour over the
signature teal for text, on 2026-10-08.
- 36 sites swap. They are 35 Tailwind uses: links, "Now playing", the
ingest progress line, active shuffle/repeat, the liked heart, the app
download icon and its hover. The last is the alphabet rail's pending
spinner in CSS. Icons follow the text: as graphics they need only
3:1, and the raw accent misses even that on iron.
- check-tint-contrast adds accent to TEXT_NEVER_RAW, so a new raw
text-accent or color: var(--fs-accent) fails the web lane. Run against
the files before the swap, it finds all 36. Borders, rings and fills
keep the raw accent.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Add browser tab titles to all 18 static page routes using the pageTitle()
helper from $lib/branding. Titles follow the Minstrel · Section format.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add Artists and Albums nav entries, rename root label from Library to
Home. Migrate all three ArtistRow call sites (search, search/artists,
library/liked) to ArtistCard with grid wrapper; delete ArtistRow
component and its test.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Reads ?q= reactively; runs createSearchQuery (limit=10) when q is
non-empty. Renders Artists/Albums/Tracks sections reusing ArtistRow,
AlbumCard, TrackRow. Track click uses onPlay prop to call
playRadio(track.id) instead of the default playQueue. Empty facets
hide; 'See all N →' link points to overflow pages when total > items.
Empty q shows 'Start typing'; error → ApiErrorBanner; loading →
SearchSkeleton via useDelayed.