Files
yellowjacket/.planning/milestones/v1.0-phases/08-frontend-performance-ux/08-04-PLAN.md
T
yonlu 6ce0661fca chore: complete v1.0 Consolidation milestone
Archive milestone artifacts:
- milestones/v1.0-ROADMAP.md (full roadmap archive)
- milestones/v1.0-REQUIREMENTS.md (26/26 requirements complete)
- milestones/v1.0-phases/ (8 phase directories with plans, summaries, verifications)

Updated:
- PROJECT.md: full evolution review, all consolidation requirements validated
- ROADMAP.md: collapsed to milestone summary with archive link
- STATE.md: reset for next milestone
- MILESTONES.md: created with stats and accomplishments
- RETROSPECTIVE.md: created with lessons learned

Deleted:
- REQUIREMENTS.md (archived, fresh for next milestone)

8 phases, 17 plans, 34 tasks, 84 tests added, 6 days
2026-03-05 09:34:43 -05:00

268 lines
13 KiB
Markdown

---
phase: 08-frontend-performance-ux
plan: 04
type: execute
wave: 2
depends_on:
- "08-01"
files_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
autonomous: false
requirements:
- UX-01
must_haves:
truths:
- "All components use px-based spacing (no em-based padding/gap/margin in sidebar or anywhere)"
- "Icon sizes reference --yj-icon-sm/md/lg tokens instead of ad-hoc pixel or em values"
- "Typography references --yj-text-xs/sm/md/lg/xl tokens instead of ad-hoc font-size values"
- "Cover-grid dynamic text sizing tiers map to the type scale tokens"
- "Visual consistency is verified by human inspection across all views"
artifacts:
- path: "frontend/src/components/sidebar/app-sidebar.ts"
provides: "px-based spacing, icon tokens"
contains: "--yj-icon-"
- path: "frontend/src/components/now-playing/now-playing.ts"
provides: "Icon tokens for cover placeholder"
contains: "--yj-icon-lg"
- path: "frontend/src/components/search-bar/search-bar.ts"
provides: "Icon and type scale tokens"
contains: "--yj-icon-sm"
- path: "frontend/src/components/cover-grid/cover-grid.ts"
provides: "Dynamic text sizing mapped to type scale tokens"
contains: "--yj-text-"
key_links:
- from: "all components"
to: "frontend/src/styles/tokens.css.ts"
via: "import { designTokens } and include in static styles"
pattern: "designTokens"
---
<objective>
Systematically audit and fix visual inconsistencies across all components — convert em-based spacing to px, apply icon size tokens, apply type scale tokens, and ensure coherent visual language.
Purpose: The codebase has evolved with ad-hoc values (0.9em icons in sidebar, 24px in now-playing, 14px in search-bar, 11-16px dynamic text in cover-grid). This pass replaces them with the design tokens defined in Plan 01, creating a single source of truth for sizing.
Output: All components use consistent design tokens. Human-verified visual quality.
</objective>
<execution_context>
@/home/caleb/.config/opencode/get-shit-done/workflows/execute-plan.md
@/home/caleb/.config/opencode/get-shit-done/templates/summary.md
</execution_context>
<context>
@.planning/PROJECT.md
@.planning/ROADMAP.md
@.planning/STATE.md
@.planning/phases/08-frontend-performance-ux/08-CONTEXT.md
@.planning/phases/08-frontend-performance-ux/08-01-SUMMARY.md
@frontend/src/styles/tokens.css.ts
@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/cover-grid/cover-grid.ts
@frontend/src/components/cover-grid/cover-grid-styles.ts
<interfaces>
<!-- Design tokens from Plan 01 -->
From frontend/src/styles/tokens.css.ts:
```typescript
export const designTokens = css`
:host {
--yj-icon-sm: 14px;
--yj-icon-md: 18px;
--yj-icon-lg: 24px;
--yj-text-xs: 11px;
--yj-text-sm: 12px;
--yj-text-md: 13px;
--yj-text-lg: 15px;
--yj-text-xl: 18px;
}
`;
```
How to use in a component:
```typescript
import { designTokens } from '../../styles/tokens.css';
@customElement('my-component')
export class MyComponent extends LitElement {
static styles = [designTokens, css`
.icon { font-size: var(--yj-icon-md); }
.label { font-size: var(--yj-text-sm); }
`];
}
```
Known inconsistencies to fix:
- app-sidebar.ts: em-based spacing (padding: 1em, gap: 0.6em, padding: 0.5em), icon 0.9em/1.1em, border-radius: 5px
- now-playing.ts: cover placeholder icon font-size: 24px → --yj-icon-lg
- search-bar.ts: search icon font-size: 14px → --yj-icon-sm, input font-size: 13px → --yj-text-md
- cover-grid.ts: dynamic text sizing tiers (11px/10px, 14px/12px, 16px/13px) in updateSizeProperties()
- Various components: ad-hoc font-size values that should map to type scale
</interfaces>
</context>
<tasks>
<task type="auto">
<name>Task 1: Convert sidebar em-based spacing to px and apply icon/type tokens to sidebar, now-playing, search-bar, and audio-player components</name>
<files>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</files>
<action>
For EACH component listed, read the file first, then:
1. Import designTokens: `import { designTokens } from '../../styles/tokens.css';` (adjust relative path based on file location)
2. Add designTokens to the component's `static styles` array (prepend it so tokens are available to component styles)
3. Apply the following conversions:
**app-sidebar.ts:**
- Convert ALL em-based values to px equivalents:
- `padding: 1em``padding: 16px`
- `gap: 0.6em``gap: 10px`
- `padding: 0.5em``padding: 8px`
- Any other em values → compute px (base is ~16px for desktop)
- Icon font-size `0.9em``var(--yj-icon-md)` (was ~14px, md=18px is closer to sidebar intent)
- Icon font-size `1.1em` (collapsed mode) → `var(--yj-icon-md)` (same token, consistent)
- Audit ALL font-size values and replace with appropriate --yj-text-* tokens
- `border-radius: 5px` → keep as-is (border-radius doesn't need tokenizing)
**now-playing.ts:**
- Cover placeholder icon `font-size: 24px``font-size: var(--yj-icon-lg)`
- Audit all font-size values → replace with --yj-text-* tokens
**search-bar.ts:**
- Search icon `font-size: 14px``font-size: var(--yj-icon-sm)`
- Input `font-size: 13px``font-size: var(--yj-text-md)`
- Audit all other font-size values
**audio-player components (player-controls.ts, seek-bar.ts, volume-control.ts, audio-player.ts):**
- Read each file, audit for ad-hoc font-size and icon-size values
- Replace with appropriate --yj-text-* and --yj-icon-* tokens
- Convert any em-based spacing to px if found
**General rules:**
- When mapping existing px values to tokens, pick the NEAREST token value. If 12px → --yj-text-sm (12px). If 13px → --yj-text-md (13px). If 14px and it's text → --yj-text-sm or --yj-text-md based on context. If 14px and it's an icon → --yj-icon-sm (14px).
- Do NOT change values that are layout-specific (width, height, margins for positioning). Only convert font-size, icon font-size, and em-based spacing.
- Do NOT change color values — those already use --yj- tokens.
</action>
<verify>
<automated>cd frontend && npx tsc --noEmit 2>&1 | head -30</automated>
</verify>
<done>Sidebar uses px-based spacing throughout. All icon sizes in sidebar, now-playing, search-bar, and audio-player use --yj-icon-* tokens. All text sizes in these components use --yj-text-* tokens. No em-based spacing remains. TypeScript compiles.</done>
</task>
<task type="auto">
<name>Task 2: Apply design tokens to cover-grid dynamic text sizing, track-list, queue-panel, and remaining detail/info components</name>
<files>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</files>
<action>
For EACH component, read the file, import designTokens, add to static styles, then audit and fix:
**cover-grid.ts — Dynamic text sizing:**
The updateSizeProperties() method has hardcoded px values for text sizing tiers based on card size:
- Small cards: 11px/10px → map to `--yj-text-xs` (11px) / computed smaller
- Medium cards: 14px/12px → map to `--yj-text-lg` (15px) / `--yj-text-sm` (12px) — or adjust
- Large cards: 16px/13px → map to values near `--yj-text-lg`/`--yj-text-md`
For the dynamic sizing tiers, the approach depends on how they're applied:
- If set as inline styles or CSS custom properties on the element, replace hardcoded values with references to the tokens: `var(--yj-text-xs)`, `var(--yj-text-sm)`, etc.
- If set programmatically in JS (this.style.setProperty), use the token values directly or set CSS custom properties that reference the tokens
- The goal is that card text sizes use the SAME scale as everything else, not independent magic numbers
Read the updateSizeProperties() method carefully to understand the tier logic before modifying.
**cover-grid-styles.ts:**
- Audit for ad-hoc font-size values, replace with --yj-text-* tokens
**track-list.ts:**
- Import designTokens (if not already from Plan 03)
- Audit ALL font-size values in styles — header, cells, sort labels, etc.
- Replace with --yj-text-* tokens
- Audit icon sizes (favorites icon was noted as 12px) → --yj-icon-sm
**queue-panel.ts:**
- Import designTokens (if not already from Plan 03)
- Audit font-size values → --yj-text-* tokens
- Audit icon sizes → --yj-icon-* tokens
**track-details.ts, track-info.ts, artist-details.ts, genre-details.ts:**
- Read each file, audit for font-size and icon-size values
- Import designTokens, add to static styles
- Replace ad-hoc values with tokens
**Same rules as Task 1:** Only convert font-size, icon sizes, em-based spacing. Don't change layout dimensions or colors.
</action>
<verify>
<automated>cd frontend && npx tsc --noEmit 2>&1 | head -30</automated>
</verify>
<done>Cover-grid dynamic text tiers use type scale tokens. Track-list, queue-panel, and detail components use design tokens for all font-size and icon-size values. No meaningful ad-hoc font-size values remain across audited components. TypeScript compiles.</done>
</task>
<task type="checkpoint:human-verify" gate="blocking">
<name>Task 3: Visual consistency verification</name>
<files>n/a</files>
<action>
Human verifies visual consistency after Tasks 1-2.
What was built:
- Sidebar: px-based spacing, icon tokens, type tokens
- Now-playing: icon tokens, type tokens
- Search bar: icon and type tokens
- Audio player: icon and type tokens
- Cover grid: dynamic text sizing mapped to type scale
- Track list: type and icon tokens
- Queue panel: type and icon tokens
- Detail/info views: type and icon tokens
How to verify — run the app and check each view:
1. Sidebar — Icons are consistent size, text is readable, spacing looks balanced (no too-tight or too-loose areas from em→px conversion)
2. Track list — Column headers, cell text, and sort indicators look consistent. Favorites icon is appropriately sized.
3. Cover grid — Album names scale with card size using the type scale tiers. Small, medium, and large cards all have readable text.
4. Queue panel — Track names, durations, and icons are consistently sized
5. Now playing — Cover placeholder icon is appropriately sized, track info text is consistent
6. Search bar — Search icon and input text are balanced
7. Audio player — Play/pause/skip icons, seek bar labels, volume icon are consistent
8. Detail views — Artist details, genre details, track details/info all use consistent typography
9. Overall — No view has text that looks noticeably different in size from the same-purpose text in another view
</action>
<verify>Human visual inspection — type "approved" or describe specific visual issues to fix</verify>
<done>All views pass visual consistency check — no em-based spacing, icon sizes are consistent, typography follows the type scale, and no jarring size mismatches between views.</done>
</task>
</tasks>
<verification>
1. `cd frontend && npx tsc --noEmit` compiles without errors
2. `grep -r "0\.\d*em" frontend/src/components/sidebar/` returns no em-based spacing
3. `grep -rn "font-size:" frontend/src/components/ | grep -v "var(--yj-"` shows minimal remaining ad-hoc values (only layout-specific sizes)
4. All components that have styles import designTokens
5. Human verification confirms visual consistency
</verification>
<success_criteria>
- Zero em-based spacing values in sidebar
- All icon sizes use --yj-icon-sm/md/lg tokens
- All text sizes use --yj-text-xs/sm/md/lg/xl tokens (with minimal justified exceptions)
- Cover-grid dynamic text tiers map to the type scale
- Human approves visual consistency across all views
- TypeScript compiles without errors
</success_criteria>
<output>
After completion, create `.planning/phases/08-frontend-performance-ux/08-04-SUMMARY.md`
</output>