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
268 lines
13 KiB
Markdown
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>
|