# UI Rework Plan > Status: **planned, not started.** This document captures the target direction for a > richer player UI (reference: the "LocalTunes" three-pane mockup) and what it implies for > both the frontend and the backend. It is a plan to execute later, not a description of the > current app. ## 1. Vision Move from the current functional-but-plain single-content-column layout to a polished, artwork-forward **three-pane music player** in the spirit of modern desktop players (Spotify / Apple Music / the LocalTunes reference): - **Left:** persistent navigation rail (library sections + a personal/"your music" group). - **Center:** scrollable content (Home, Library, Vibe, etc.) — artwork-rich cards, horizontal carousels, hover-to-play. - **Right:** persistent **Now Playing** panel — large artwork, track info, transport, and an **Up Next / queue** list. - **Bottom:** full-width global **playback bar** (shuffle / prev / play / next / repeat, scrubber, volume, queue toggle) that's always visible regardless of route. - **Top:** global search field + (future) user/account menu. Accent-driven, rounded, soft-gradient cards; dark by default but fully themeable via tokens. ## 2. Layout structure ``` ┌────────────────────────────────────────────────────────────────────────────┐ │ Top bar: [logo] [ global search ⌘K ] [bell] [avatar ▾] │ ├───────────────┬────────────────────────────────────────────┬───────────────┤ │ Nav rail │ Content (router Outlet) │ Now Playing │ │ - Home │ Good evening 👋 │ [ artwork ] │ │ - Songs │ Quick Access cards │ Title/Artist │ │ - Albums │ Recently Played (carousel, View all) │ scrubber │ │ - Artists │ Made for you (mixes carousel) │ transport │ │ - Genres │ ... │ Up Next list │ │ - Playlists │ │ │ │ - Folder │ │ (collapsible)│ │ ────────── │ │ │ │ Now Playing │ │ │ │ Recently … │ │ │ │ Most Played │ │ │ │ Favorites │ │ │ │ ────────── │ │ │ │ Settings │ │ │ │ Theme │ │ │ │ About │ │ │ ├───────────────┴────────────────────────────────────────────┴───────────────┤ │ Bottom bar: [art] Title/Artist ♥ ⇄ ◀ ▶▶ ⏯ ▶▶ ↻ 🔊────── queue ▤ │ └──────────────────────────────────────────────────────────────────────────────┘ ``` The right Now-Playing panel and the bottom bar are partly redundant by design (desktop players do this): the bottom bar is the always-on minimal transport; the right panel is the expanded view with queue and large art, and is collapsible. ## 3. Design tokens / theming This rework is the right moment to finish theming. Today only the shell consumes tokens (`--bg`, `--surface`, `--text`, `--accent` from `src/lib/theme.ts`). Target: - **Expand the token set:** `--bg`, `--bg-elevated`, `--surface`, `--surface-hover`, `--border`, `--text`, `--text-muted`, `--accent`, `--accent-hover`, `--on-accent`, plus gradient stops for cards (`--card-grad-a/b`). - **Drive Tailwind from the tokens:** extend `tailwind.config.js` `theme.colors` to reference the CSS variables (e.g. `bg: 'var(--bg)'`, `surface: 'var(--surface)'`, `accent: 'var(--accent)'`) so components use semantic classes (`bg-surface`, `text-muted`, `bg-accent`) instead of hard-coded `bg-zinc-900` etc. This makes every component themeable without per-component edits. - Keep the existing presets (Dark / Midnight / Forest / Plum), add a light option, and keep `initTheme()` applying the persisted choice before first paint. - The reference's purple accent → add a "Default (Purple)" preset. ## 4. Component inventory (new / reworked) | Component | Purpose | | :--- | :--- | | `AppShell` | 3-pane grid (rail / content / now-playing) + top bar + bottom bar. Replaces `Layout`. | | `NavRail` | Sections + personal group + settings group; active state via `--accent`. | | `TopBar` | Global search (debounced, ⌘K focus), account menu (stub until auth). | | `NowPlayingPanel` | Right rail: large art, info, scrubber, transport, Up Next queue (reorder/remove). Collapsible. | | `PlaybackBar` | Bottom global transport (always visible). Reworks `NowPlayingBar`. | | `MediaCard` | Square artwork card with hover play overlay (used by carousels + grids). | | `Carousel` / `ShelfRow` | Horizontal scroll row with title + "View all". | | `QuickAccessCard` | Wide gradient card (Favorites / Recently Added / Most Played / Folder). | | `TrackRow` | Reusable list row (replaces the per-page `LibraryTrackRow`) with art, actions, now-playing highlight. | | `Artwork` | Resolves album/track artwork URL with a graceful gradient placeholder fallback. | State: keep Zustand `usePlaybackStore` (current/queue/isPlaying/position/volume) and `useVibeStore`; add a small `useUiStore` for panel collapse + theme if useful. The Up Next list is just the playback `queue`. ## 5. Backend work this UI implies (gaps) The mockup assumes data we don't serve yet. Each is a discrete backend task: 1. **Artwork serving** — `albums.artwork_id` / Cover-Art URLs are stored but never served. Need `GET /api/albums/:id/artwork` (and/or per-track) that streams/redirects to the cached cover, plus a placeholder when absent. Without this every card is a gradient placeholder. 2. **Playlists** — the rail shows "Playlists"; there are no playlist tables/endpoints. Needs `playlists` + `playlist_track` schema and CRUD + reorder endpoints. (Net-new feature.) 3. **"Most Played"** — derivable now via `GET /api/tracks?sort_by=play_count&order=DESC`. Wire a dedicated view/shelf. 4. **"Recently Added"** — needs reliable `mtime`/`created_at` sorting (currently sorted client-side). Consider a `created_at` column + a sorted endpoint. 5. **"Made for you" mixes** — map to the Vibe engine: per-genre/seed mixes via `/api/vibe/from-genre` and saved seeds. No new engine work, just presentation + maybe a "mixes" endpoint that returns a handful of seed suggestions. 6. **Folder browse** — the rail shows "Folder"; there's no filesystem-browse endpoint. Needs a sandboxed `GET /api/library/browse?path=` under `MUSIC_DIR` (reuse the stream route's traversal guard). Optional / later. 7. **Typesense search** — the redesigned top-bar search wants fast fuzzy results; finish the Typesense indexing pipeline (collection + reindex job + index-on-enrich) so search graduates from the Postgres ILIKE fallback. (Already tracked in `progress.md`.) ## 6. Suggested phasing 1. **Tokenise theming** — extend tokens + wire Tailwind to CSS vars; migrate existing components to semantic colour classes. (Unblocks real theming; low risk, high leverage.) 2. **AppShell + PlaybackBar + NowPlayingPanel** — the structural 3-pane shell with the always-on transport and queue, reusing the current playback store/audio engine. 3. **MediaCard / Carousel / Artwork** + **artwork backend endpoint** — make the content artwork-forward; redesign Home around Quick Access + shelves. 4. **Library/Discover/Vibe pages** restyled onto the new components. 5. **New features as desired:** Playlists, Folder browse, Most Played/Recently Added shelves, Typesense search. ## 7. Non-goals (for the first rework pass) - Auth / multi-user (still single-user). - Mobile/responsive layout (target desktop first; the 3-pane collapses later). - Real-time collaborative features. ## 8. Open questions - Keep both the right Now-Playing panel **and** the bottom bar, or collapse to one? (Plan assumes both, panel collapsible.) - Artwork storage: serve via a backend proxy/cache, or store files locally and serve static? - Playlists: is this in scope for the rework, or a separate feature track?