The header is now three equal sections — navigation tabs (left), the
search field (center, so it lands at the window center), and the user
element (right) — fixing the tabs stretching to full width under the
search field.
- Nav tabs regain Lucide icons (compass, library, hard-drive,
cassette-tape) and use a 12px label.
- The user element uses a hamburger icon instead of the QBZ logo, which
aliased badly as a scaled PNG.
- Responsive: below 1140px the tabs drop their icons; below 960px the
search field narrows to 70%.
cc
Adds 28 Lucide icons (the same set the QBZ Svelte app uses) as SVGs
under ui/assets/icons/, plus a QbzIcon primitive — an Image wrapper that
applies `colorize` so a monochrome SVG renders in any theme color.
cc
Corrections from testing feedback:
- Remove the greeting — the current QBZ discovery view has no greeting,
only the tab selector. Drops HomeState.greeting and the chrono dep.
- Quality badge is now the icon-only badge (hi-res.svg, or cd.svg in a
framed square), not a numeric text pill. AlbumCardItem carries a
quality tier instead of a quality string.
- Tighten the album card: deterministic 274px height, title and artist
in a 2px-spaced stack — removes the large gap between them.
- SectionRow no longer scrolls vertically (vertical-scrollbar-policy
always-off, height pinned to the card height).
- Artwork is downscaled to 264px on decode instead of holding ~600px
source textures.
cc
M1 progress. Adds the foundation token layer (palette, semantic
colors, spacing, radius, typography) bound to the QBZ dark theme,
three primitives (QbzCheckbox, QbzPrimaryButton, QbzTextLink), and
the LoginScreen feature component.
The login screen mirrors the Svelte LoginView: centered card, logo,
QBZ wordmark, Qobuz ToS checkbox, "Sign in via Browser" button,
system-browser and offline links, and the legal disclaimer. Colors
are lifted verbatim from src/app.css; strings use @tr() markers.
Rust side: typed AppCommand enum; UI callbacks dispatch through it.
M2 wires the command handler to AppRuntime.
cc