# Stream / Player / Radio Revamp — Plan Goal: bring the audio stream + media-player + radio system to Spotify/Apple-level polish and feature set. Target stack: **plain JS** (`webui/static/media-player.js`), not the React migration. Intended architecture direction: **multi-listener** (final call deferred to Phase 3; Phases 0–2 stay compatible either way). Rule for every phase: kettui standard — importable/testable logic, seam-level + differential tests, break nothing, ship one reviewable phase at a time. --- ## Phase 0 — Make it provable (foundation, no user-visible change) - [x] **0a. Extract radio selection logic into testable `core/radio/`.** DONE (commit cbc001e2). `core/radio/selection.py` owns parse_tags/merge_tags/same_artist_cap/build_like_conditions/RadioCollector; DB method delegates. 29 tests, refactor-equivalence proven (behavioral tests pass against old AND new). - [ ] **0b. Centralize frontend player state.** ~10 scattered `np*` globals in `media-player.js` → one `PlayerState` object. Seam for every later frontend phase. No behavior change. ## Phase 1 — Polish / feel (frontend) - [x] Persistent queue across refresh (localStorage) — commit a8985b31 - [x] Drag-to-reorder queue; duration + art per queue item — ffbe669c + 3461d923 - [x] Seek tooltip (hover timestamp) — 112ecbb2 - [x] Crossfade via dual-`