docs(08-04): complete visual consistency audit & design token application plan

- SUMMARY.md documents 15-component design token rollout
- STATE.md updated: all 8 phases complete, 26/26 requirements delivered
- ROADMAP.md updated: Phase 8 4/4 plans complete
- Includes hotfix documentation for repeat() virtualizer regression (72ef719)
This commit is contained in:
2026-03-05 09:16:22 -05:00
parent 72ef719ba7
commit 9943ae381c
3 changed files with 184 additions and 34 deletions
+16 -16
View File
@@ -9,12 +9,12 @@
- [x] **Phase 1: Concurrency Race Fixes** — Eliminate all SetContext data races across Queue, Library, Playlist, and Player
- [x] **Phase 2: Backend Correctness** — Fix error handling gaps, file permissions, package-level state, and scan error separation
- [ ] **Phase 3: Test Infrastructure** — Create in-memory SQLite test helper and apply production SQLite PRAGMAs
- [ ] **Phase 4: Queue, Config & Player Tests** — Write unit tests for queue operations, config roundtrip, and extracted player pure logic
- [ ] **Phase 5: Database & Library Tests** — Write unit tests for FTS5 search queries, migrations, library scan, and entity cache
- [ ] **Phase 6: SQL Consolidation & Code Quality** — Deduplicate FTS5 queries via VIEW, add event codegen, migrate to sqlc where feasible, document exceptions
- [ ] **Phase 7: Backend Performance** — Optimize queue persistence, fix SetQueue Phase 2 redundancy, enable lazy library loading
- [ ] **Phase 8: Frontend Performance & UX** — Optimize frontend rendering for large libraries and fix visual inconsistencies
- [x] **Phase 3: Test Infrastructure** — Create in-memory SQLite test helper and apply production SQLite PRAGMAs
- [x] **Phase 4: Queue, Config & Player Tests** — Write unit tests for queue operations, config roundtrip, and extracted player pure logic
- [x] **Phase 5: Database & Library Tests** — Write unit tests for FTS5 search queries, migrations, library scan, and entity cache
- [x] **Phase 6: SQL Consolidation & Code Quality** — Deduplicate FTS5 queries via VIEW, add event codegen, migrate to sqlc where feasible, document exceptions
- [x] **Phase 7: Backend Performance** — Optimize queue persistence, fix SetQueue Phase 2 redundancy, enable lazy library loading
- [x] **Phase 8: Frontend Performance & UX** — Optimize frontend rendering for large libraries and fix visual inconsistencies
## Phase Details
@@ -100,7 +100,7 @@ Plans:
Plans:
- [x] 06-01-PLAN.md — Create track_metadata VIEW and consolidate search queries
- [x] 06-02-PLAN.md — Event codegen tool (Go→TypeScript) and pre-commit hook wiring
- [ ] 06-03-PLAN.md — Migrate lookupChunk to sqlc.slice() and add SAFETY comments to all hand-crafted SQL
- [x] 06-03-PLAN.md — Migrate lookupChunk to sqlc.slice() and add SAFETY comments to all hand-crafted SQL
### Phase 7: Backend Performance
**Goal:** Queue mutations and library loading are fast — single-track queue changes are O(1) instead of O(n), and the library doesn't block startup with a full data fetch
@@ -112,8 +112,8 @@ Plans:
3. Library store constructor no longer calls `eagerFetch()` — data loads lazily on first access via the existing `getTracks()`/`getAlbums()`/etc. getters, and the app starts without blocking on a full library load
**Plans:** 2 plans
Plans:
- [ ] 07-01-PLAN.md — Incremental queue persistence + SetQueue Phase 2 dedup
- [ ] 07-02-PLAN.md — Library store deferred eager loading
- [x] 07-01-PLAN.md — Incremental queue persistence + SetQueue Phase 2 dedup
- [x] 07-02-PLAN.md — Library store deferred eager loading
### Phase 8: Frontend Performance & UX
**Goal:** The app feels smooth and visually consistent — large libraries render without jank, and the UI follows a coherent visual language
@@ -126,10 +126,10 @@ Plans:
4. Scrolling, view switching, and search filtering in a 10k+ track library are smooth with no visible jank or dropped frames
**Plans:** 4 plans
Plans:
- [ ] 08-01-PLAN.md — Store debouncing (queueMicrotask), search debounce, design token definitions
- [ ] 08-02-PLAN.md — Virtualizer repeat() directive migration (all 5 components)
- [ ] 08-03-PLAN.md — Track-list/queue-panel render optimization (classMap, search highlight short-circuit)
- [ ] 08-04-PLAN.md — Visual consistency audit & token application across all components
- [x] 08-01-PLAN.md — Store debouncing (queueMicrotask), search debounce, design token definitions
- [x] 08-02-PLAN.md — Virtualizer repeat() directive migration (all 5 components)
- [x] 08-03-PLAN.md — Track-list/queue-panel render optimization (classMap, search highlight short-circuit)
- [x] 08-04-PLAN.md — Visual consistency audit & token application across all components
## Progress
@@ -140,9 +140,9 @@ Plans:
| 3. Test Infrastructure | 1/1 | Complete | 2026-03-04 |
| 4. Queue, Config & Player Tests | 2/2 | Complete | 2026-03-04 |
| 5. Database & Library Tests | 2/2 | Complete | 2026-03-04 |
| 6. SQL Consolidation & Code Quality | 2/3 | In Progress | — |
| 7. Backend Performance | 0/2 | Not started | |
| 8. Frontend Performance & UX | 0/4 | Not started | |
| 6. SQL Consolidation & Code Quality | 3/3 | Complete | 2026-03-04 |
| 7. Backend Performance | 2/2 | Complete | 2026-03-05 |
| 8. Frontend Performance & UX | 4/4 | Complete | 2026-03-05 |
---
*Roadmap created: 2026-02-27*
+22 -18
View File
@@ -2,13 +2,13 @@
gsd_state_version: 1.0
milestone: v1.0
milestone_name: milestone
status: in-progress
last_updated: "2026-03-05T04:22:19Z"
status: complete
last_updated: "2026-03-05T14:13:19Z"
progress:
total_phases: 8
completed_phases: 7
completed_phases: 8
total_plans: 17
completed_plans: 16
completed_plans: 17
---
# YellowJacket — Consolidation Milestone State
@@ -16,17 +16,17 @@ progress:
## Project Reference
**Core value:** The music player works reliably and feels solid — every interaction is correct, responsive, and trustworthy.
**Current focus:** Phase 8 in progress — Plans 01-03 complete. renderTrackRow/renderTrackItem optimized with classMap. One plan remaining.
**Current focus:** All 8 phases complete. All 26 consolidation milestone requirements delivered. Ready for milestone completion.
**Milestone:** Consolidation (correctness, performance, code quality, UX polish, test coverage)
## Current Position
**Phase:** 08-frontend-performance-ux
**Plan:** 3/4 (Plans 01-03 complete)
**Status:** In progress
**Plan:** 4/4 (All plans complete)
**Status:** Complete
```
Phase Progress: [########] 8/8 phases — Phase 8: 3/4 plans complete
Phase Progress: [########] 8/8 phases — All phases complete
```
## Performance Metrics
@@ -34,8 +34,8 @@ Phase Progress: [########] 8/8 phases — Phase 8: 3/4 plans complete
| Metric | Value |
|--------|-------|
| Phases complete | 7/8 |
| Plans complete | 3/4 (Phase 8) |
| Requirements delivered | 22/26 |
| Plans complete | 4/4 (Phase 8) |
| Requirements delivered | 26/26 |
| Tests added | 84 |
| Bugs fixed | 9 |
| 01-01 duration | 11 min |
@@ -56,6 +56,7 @@ Phase Progress: [########] 8/8 phases — Phase 8: 3/4 plans complete
| Phase 08 P01 | 1 min | 2 tasks | 3 files |
| Phase 08 P02 | 3 min | 2 tasks | 5 files |
| Phase 08 P03 | 2 min | 2 tasks | 2 files |
| Phase 08 P04 | 8 min | 3 tasks | 15 files |
## Accumulated Context
@@ -93,6 +94,9 @@ Phase Progress: [########] 8/8 phases — Phase 8: 3/4 plans complete
| Inline repeat() keys over gridKeyFunction | Dead method removal; key logic is cleaner inline in repeat() calls | Phase 8 |
| classMap over array filter/join | Eliminates per-row array allocation; classMap diffs internally for efficient DOM updates | Phase 8 |
| Hoist search term outside cols.map | Avoids redundant property access per column per row in render hot path | Phase 8 |
| em→px with 16px base for sidebar | Eliminates compound inheritance issues from nested em values | Phase 8 |
| .renderItem+.keyFunction over repeat() for virtualizers | repeat() as child content bypasses virtualization; .renderItem is the proper lit-virtualizer API | Phase 8 |
| Cover-grid dynamic text tiers mapped to type scale | updateSizeProperties() uses --yj-text-xs/sm/md/lg tokens instead of hardcoded px | Phase 8 |
### TODOs
@@ -136,18 +140,18 @@ None currently.
### Last Session
**Date:** 2026-03-05
**What happened:** Executed Phase 8 Plan 03renderTrackRow/renderTrackItem optimization with classMap
**Where we stopped:** Completed 08-03-PLAN.md (2 tasks, all verification passed). Phase 8: 3/4 plans complete.
**Next action:** Execute Phase 8 Plan 04
**What happened:** Executed Phase 8 Plan 04visual consistency audit and design token application across 15 components. Also hotfixed repeat() virtualizer regression from Plan 02 (commit 72ef719).
**Where we stopped:** Completed 08-04-PLAN.md (3 tasks, human-verified). All 8 phases complete. All 26 requirements delivered.
**Next action:** Milestone completion
### Context for Next Session
- Phase 8 Plans 01-03 complete
- classMap directive used in all render hot paths (track-list + queue-panel)
- Search highlight short-circuits when term is empty
- 1 plan remaining in Phase 8
- All 8 phases complete, all 17 plans executed
- All 26 consolidation milestone requirements delivered
- Critical hotfix: repeat() inside lit-virtualizer defeated virtualization (72ef719)
- Ready for `/gsd-complete-milestone`
---
*State initialized: 2026-02-27*
Last activity: 2026-03-05 - Completed 08-03: renderTrackRow classMap optimization
Last activity: 2026-03-05 - Completed 08-04: Visual consistency audit & design token application (Phase 8 complete)
*Last updated: 2026-03-05*
@@ -0,0 +1,146 @@
---
phase: 08-frontend-performance-ux
plan: 04
subsystem: frontend
tags: [lit, design-tokens, css-custom-properties, px-spacing, icon-tokens, type-scale, visual-consistency]
# Dependency graph
requires:
- phase: 08-frontend-performance-ux
provides: "Design token CSS custom properties (tokens.css.ts) from Plan 01"
provides:
- "All 15 components use design token CSS custom properties for icon sizing and type scale"
- "Sidebar fully converted from em-based to px-based spacing"
- "Cover-grid dynamic text sizing tiers mapped to type scale tokens"
- "Consistent visual language across all views"
affects: []
# Tech tracking
tech-stack:
added: []
patterns: ["designTokens import + static styles array pattern applied across all components"]
key-files:
created: []
modified:
- frontend/src/components/sidebar/app-sidebar.ts
- frontend/src/components/now-playing/now-playing.ts
- frontend/src/components/search-bar/search-bar.ts
- frontend/src/components/audio-player/controls/player-controls.ts
- frontend/src/components/audio-player/seekbar/seek-bar.ts
- frontend/src/components/audio-player/volume-control/volume-control.ts
- frontend/src/components/audio-player/audio-player.ts
- frontend/src/components/cover-grid/cover-grid.ts
- frontend/src/components/cover-grid/cover-grid-styles.ts
- frontend/src/components/track-list/track-list.ts
- frontend/src/components/queue-panel/queue-panel.ts
- frontend/src/components/track-details/track-details.ts
- frontend/src/components/track-info/track-info.ts
- frontend/src/components/artist-details/artist-details.ts
- frontend/src/components/genre-details/genre-details.ts
key-decisions:
- "em→px conversion uses 16px base (standard browser default) for sidebar spacing"
- "Icon tokens: --yj-icon-sm (14px) for small indicators, --yj-icon-md (18px) for sidebar/player controls, --yj-icon-lg (24px) for cover placeholders"
- "Cover-grid dynamic text tiers mapped to --yj-text-xs/sm/md/lg tokens via updateSizeProperties()"
patterns-established:
- "Design token adoption pattern: import designTokens, prepend to static styles array, replace ad-hoc px/em values with var(--yj-*) references"
- "All font-size and icon font-size values use --yj-text-* and --yj-icon-* tokens respectively"
requirements-completed: [UX-01]
# Metrics
duration: 8min
completed: 2026-03-05
---
# Phase 8 Plan 04: Visual Consistency Audit & Token Application Summary
**Systematic em→px conversion and design token application across 15 components — sidebar spacing, icon sizing via --yj-icon-* tokens, and typography via --yj-text-* tokens for coherent visual language**
## Performance
- **Duration:** ~8 min (across sessions with checkpoint)
- **Started:** 2026-03-05T04:30:00Z
- **Completed:** 2026-03-05T14:13:19Z
- **Tasks:** 3 (2 auto + 1 human-verify checkpoint)
- **Files modified:** 15
## Accomplishments
- Sidebar fully converted from em-based spacing (padding: 1em, gap: 0.6em) to px-based values — eliminates compound inheritance issues
- All icon sizes across 15 components now use --yj-icon-sm/md/lg tokens instead of ad-hoc pixel or em values
- All text sizes use --yj-text-xs/sm/md/lg/xl tokens instead of hardcoded font-size values
- Cover-grid dynamic text sizing tiers in updateSizeProperties() mapped to type scale tokens
- Human-verified visual consistency across all views — sidebar, track list, cover grid, queue panel, now playing, search bar, audio player, and detail views
## Task Commits
Each task was committed atomically:
1. **Task 1: Convert sidebar em→px and apply icon/type tokens to sidebar, now-playing, search-bar, audio-player** - `aed90d7` (feat)
2. **Task 2: Apply design tokens to cover-grid, track-list, queue-panel, and detail components** - `1303422` (feat)
3. **Task 3: Visual consistency verification** - checkpoint:human-verify (approved, no commit)
**Hotfix during phase:** `72ef719` (fix) — revert repeat() inside lit-virtualizer, restore .renderItem + .keyFunction
## Files Created/Modified
- `frontend/src/components/sidebar/app-sidebar.ts` - em→px spacing conversion, --yj-icon-md for nav icons, --yj-text-* for labels
- `frontend/src/components/now-playing/now-playing.ts` - --yj-icon-lg for cover placeholder, --yj-text-* for track info
- `frontend/src/components/search-bar/search-bar.ts` - --yj-icon-sm for search icon, --yj-text-md for input
- `frontend/src/components/audio-player/audio-player.ts` - designTokens import, type tokens
- `frontend/src/components/audio-player/controls/player-controls.ts` - --yj-icon-* for transport controls
- `frontend/src/components/audio-player/seekbar/seek-bar.ts` - --yj-text-* for time labels
- `frontend/src/components/audio-player/volume-control/volume-control.ts` - --yj-icon-* for volume icon
- `frontend/src/components/cover-grid/cover-grid.ts` - Dynamic text tiers mapped to --yj-text-xs/sm/md/lg
- `frontend/src/components/cover-grid/cover-grid-styles.ts` - Type token adoption in base styles
- `frontend/src/components/track-list/track-list.ts` - --yj-text-* for headers/cells, --yj-icon-sm for favorites
- `frontend/src/components/queue-panel/queue-panel.ts` - --yj-text-* and --yj-icon-* tokens
- `frontend/src/components/track-details/track-details.ts` - Type and icon tokens for detail layout
- `frontend/src/components/track-info/track-info.ts` - Type tokens for track metadata display
- `frontend/src/components/artist-details/artist-details.ts` - Type and icon tokens
- `frontend/src/components/genre-details/genre-details.ts` - Type and icon tokens
## Decisions Made
- **em→px conversion uses 16px base:** Standard browser default font size — 1em ≈ 16px, 0.5em ≈ 8px, 0.6em ≈ 10px. This eliminates compound inheritance issues where nested em values compound unexpectedly.
- **Icon token mapping:** --yj-icon-sm (14px) for small indicators like favorites star and search icon, --yj-icon-md (18px) for sidebar navigation and player controls, --yj-icon-lg (24px) for cover art placeholders.
- **Cover-grid dynamic tiers use tokens:** updateSizeProperties() maps card-size tiers to token values (small → --yj-text-xs, medium → --yj-text-sm, large → --yj-text-md/lg) instead of hardcoded pixel values.
## Deviations from Plan
None for the plan's own tasks — plan 04 executed exactly as written.
### Critical Hotfix (Plan 08-02 regression)
**[Rule 1 - Bug] repeat() directive inside lit-virtualizer defeated virtualization**
- **Found during:** Phase 8 execution (between plans 03 and 04)
- **Issue:** Plan 08-02 migrated all 7 lit-virtualizer instances to use repeat() as child content. However, repeat() renders ALL items as DOM children, bypassing lit-virtualizer's viewport-based rendering. This caused 2+ minute loading times and UI freezing with large libraries.
- **Root cause:** lit-virtualizer's .renderItem and .keyFunction properties integrate with its scroll-based viewport management. When content is provided as children (via repeat()), the virtualizer loses control of which items are rendered.
- **Fix:** Reverted all 7 virtualizer instances to use .renderItem + .keyFunction properties (the proper lit-virtualizer API). Removed repeat() from all virtualizer elements.
- **Files modified:** frontend/src/components/track-list/track-list.ts, frontend/src/components/queue-panel/queue-panel.ts, frontend/src/components/cover-grid/cover-grid.ts, frontend/src/components/artists-view/artists-view.ts, frontend/src/components/genres-view/genres-view.ts
- **Verification:** App loads instantly with large library, virtualization confirmed working (only visible items rendered)
- **Committed in:** `72ef719`
---
**Total deviations:** 1 hotfix (critical bug from prior plan)
**Impact on plan:** Hotfix was prerequisite for meaningful visual testing — without it, the app was unusable with real data.
## Issues Encountered
- The repeat() virtualizer regression from Plan 08-02 caused 2-minute load times with large libraries. This was a fundamental API misuse — lit-virtualizer requires .renderItem/.keyFunction for virtualization, not repeat() child content. Fixed before Plan 04 visual verification could proceed.
## User Setup Required
None - no external service configuration required.
## Next Phase Readiness
- Phase 8 complete — all 4 plans executed
- All 26 consolidation milestone requirements delivered
- Ready for milestone completion
## Self-Check: PASSED
All 15 key files verified on disk. All 3 task/hotfix commits (aed90d7, 1303422, 72ef719) verified in git history.
---
*Phase: 08-frontend-performance-ux*
*Completed: 2026-03-05*