# Web UI Player — Design Spec **Date:** 2026-04-24 **Status:** Design approved **Follows:** [Web UI Library Views](2026-04-23-web-ui-library-views-design.md) — tracks surfaced by the library plan finally become playable. ## Goal Let an authenticated user click any track on an album page and hear it — plus skip/seek/shuffle/repeat/volume, a persistent bottom-bar UI, and OS-level media controls via the MediaSession API. After this lands, the web client is a functional music player for sequential playback through the library. ## Non-goals Explicit YAGNI — kept out of this plan so scope stays tight: - **No server-side listen-history recording.** The spec's `play_events` / `sessions` tables exist in the server design but no `/api/*` endpoints are implemented yet. Once those land, a follow-up "session reporting" sub-plan wires the player to POST events. - **No scrobbling to ListenBrainz.** Dependent on server event endpoints + scrobble queue — later plan. - **No contextual likes or "like this vibe".** Out of scope until session reporting exists. - **No cross-refresh persistence.** Reload drops playback state (queue, position, current track). Volume is the only thing that persists. - **No queue UI / "up next" panel.** The user sees the current track in the bar; they don't get a separate list view of what's coming. Queue visibility is a natural follow-up. - **No keyboard shortcuts.** Space/arrow keys don't control playback in this plan — a separate "keyboard shortcuts" sub-plan will add them. - **No crossfade, gapless playback, replay-gain, equalizer.** Baseline HTMLAudio only. - **No cast / AirPlay / Chromecast.** Browser-local playback only. - **No keyboard-driven seeking beyond the native `` behavior.** ## Architecture **Single global player store** as a Svelte 5 rune module — imported by `+layout.svelte`, `Shell`, `PlayerBar`, and `TrackRow`. The store is pure state + action functions; it never touches the `