12 KiB
phase, plan, type, wave, depends_on, files_modified, autonomous, requirements, must_haves
| phase | plan | type | wave | depends_on | files_modified | autonomous | requirements | must_haves | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 01-design-token-foundation | 01 | execute | 1 |
|
true |
|
|
Purpose: This is the foundation layer. Every component change in Plan 02 references the tokens and palette created here. Without this, component wiring would hardcode new values instead of referencing a single source of truth. Output: Pastel-tinted index.css, typed palette.ts with helpers, passing unit tests.
<execution_context> @/home/jean-luc-makiola/.claude/get-shit-done/workflows/execute-plan.md @/home/jean-luc-makiola/.claude/get-shit-done/templates/summary.md </execution_context>
@.planning/PROJECT.md @.planning/ROADMAP.md @.planning/STATE.md @.planning/phases/01-design-token-foundation/01-CONTEXT.md @.planning/phases/01-design-token-foundation/01-RESEARCH.md @.planning/phases/01-design-token-foundation/01-VALIDATION.md@frontend/src/index.css @frontend/vite.config.ts @frontend/package.json
Task 1: Install test infrastructure and set up vitest frontend/package.json, frontend/vite.config.ts, frontend/src/test-setup.ts 1. Install test dependencies: `cd frontend && bun add -d vitest @testing-library/react @testing-library/jest-dom @testing-library/user-event jsdom`-
Update
frontend/vite.config.ts— add atestblock insidedefineConfig:test: { environment: 'jsdom', globals: true, setupFiles: ['./src/test-setup.ts'], }Import
/// <reference types="vitest" />at the top of the file. -
Create
frontend/src/test-setup.ts:import '@testing-library/jest-dom' -
Verify the test runner starts:
cd frontend && bun vitest run --reporter=verbose(should exit 0 with "no test files found" or similar). cd /home/jean-luc-makiola/Development/projects/SimpleFinanceDash/frontend && bun vitest run --reporter=verbose 2>&1 | tail -5 vitest runs successfully with zero failures. test-setup.ts imports jest-dom matchers. vite.config.ts has test block with jsdom environment.
Background and surface tokens (lavender tint, hue ~290):
--background: oklch(0.98 0.005 290)— very subtle lavender tint--card: oklch(1 0 0)— KEEP pure white (cards float on tinted bg)--card-foreground: oklch(0.145 0.005 290)— near-black with slight tint--popover: oklch(1 0 0)— pure white like cards--popover-foreground: oklch(0.145 0.005 290)--foreground: oklch(0.145 0.005 290)
Primary/accent tokens (soft lavender-blue, hue ~260-280):
--primary: oklch(0.50 0.12 260)— soft lavender-blue--primary-foreground: oklch(0.99 0.005 290)--secondary: oklch(0.95 0.015 280)--secondary-foreground: oklch(0.25 0.01 280)--muted: oklch(0.95 0.010 280)--muted-foreground: oklch(0.50 0.01 280)--accent: oklch(0.94 0.020 280)--accent-foreground: oklch(0.25 0.01 280)--ring: oklch(0.65 0.08 260)— tinted focus ring--border: oklch(0.91 0.008 280)— subtle lavender border--input: oklch(0.91 0.008 280)
Sidebar tokens (slightly more distinct lavender):
--sidebar: oklch(0.97 0.012 280)--sidebar-foreground: oklch(0.20 0.01 280)--sidebar-primary: oklch(0.50 0.12 260)--sidebar-primary-foreground: oklch(0.99 0.005 290)--sidebar-accent: oklch(0.93 0.020 280)--sidebar-accent-foreground: oklch(0.25 0.01 280)--sidebar-border: oklch(0.90 0.010 280)--sidebar-ring: oklch(0.65 0.08 260)
Chart tokens (mapped to category base colors — synced with palette.ts):
--chart-1: oklch(0.76 0.12 250)— bill (blue)--chart-2: oklch(0.80 0.14 85)— variable_expense (amber)--chart-3: oklch(0.76 0.13 15)— debt (rose)--chart-4: oklch(0.75 0.13 280)— saving (violet)--chart-5: oklch(0.76 0.12 320)— investment (pink)
NEW semantic tokens — add to :root block:
--success: oklch(0.55 0.15 145)— green for positive amounts--success-foreground: oklch(0.99 0 0)--warning: oklch(0.70 0.14 75)— amber for over-budget--warning-foreground: oklch(0.99 0 0)
NEW @theme inline additions — add these lines:
--color-success: var(--success);
--color-success-foreground: var(--success-foreground);
--color-warning: var(--warning);
--color-warning-foreground: var(--warning-foreground);
Do NOT modify the .dark block (dark mode is out of scope). Do NOT touch the @layer base block.
cd /home/jean-luc-makiola/Development/projects/SimpleFinanceDash && grep -c "oklch.*0 0)" frontend/src/index.css | head -1
The :root block has zero remaining zero-chroma neutral tokens (except --card and --popover which are intentionally pure white). --success and --warning tokens exist in :root and are registered in @theme inline. All chart tokens map to category base colors. The .dark block is unchanged.
Create frontend/src/lib/palette.test.ts with tests covering all behaviors listed above. Group into describe blocks: "palette exports", "headerGradient", "overviewHeaderGradient", "amountColorClass".
Run tests — they must FAIL (module not found).
Write implementation (GREEN):
Create frontend/src/lib/palette.ts with these exports:
-
CategoryType— union type of all 7 category strings -
CategoryShades— interface withlight,medium,basestring fields -
palette—Record<CategoryType, CategoryShades>with oklch values per locked decisions:- income: hue 145 (green), light L=0.96 C=0.04, medium L=0.88 C=0.08, base L=0.76 C=0.14
- bill: hue 250 (blue), light L=0.96 C=0.03, medium L=0.88 C=0.07, base L=0.76 C=0.12
- variable_expense: hue 85 (amber), light L=0.97 C=0.04, medium L=0.90 C=0.08, base L=0.80 C=0.14
- debt: hue 15 (rose), light L=0.96 C=0.04, medium L=0.88 C=0.08, base L=0.76 C=0.13
- saving: hue 280 (violet), light L=0.95 C=0.04, medium L=0.87 C=0.08, base L=0.75 C=0.13
- investment: hue 320 (pink), light L=0.96 C=0.04, medium L=0.88 C=0.07, base L=0.76 C=0.12
- carryover: hue 210 (sky), light L=0.96 C=0.03, medium L=0.88 C=0.06, base L=0.76 C=0.11
-
headerGradient(type: CategoryType): React.CSSProperties— returns{ background: 'linear-gradient(to right, ${light}, ${medium})' } -
overviewHeaderGradient(): React.CSSProperties— returns a multi-stop gradient using carryover.light, saving.light, and income.light (sky via lavender to green) for the FinancialOverview header -
amountColorClass(opts)— implements the locked amount coloring rules:isAvailableorisIncomepath: positive → 'text-success', negative → 'text-destructive', zero → ''- Expense path: actual > budgeted → 'text-warning', else → ''
IMPORTANT: The base colors for bill, variable_expense, debt, saving, investment MUST match the --chart-1 through --chart-5 values set in Task 2's index.css. These are the same oklch strings.
Run tests — they must PASS. cd /home/jean-luc-makiola/Development/projects/SimpleFinanceDash/frontend && bun vitest run src/lib/palette.test.ts --reporter=verbose All palette.test.ts tests pass. palette.ts exports all 7 categories with 3 shades each. headerGradient returns valid gradient CSSProperties. amountColorClass correctly returns text-success/text-warning/text-destructive/empty string per the locked rules.
1. `cd frontend && bun vitest run --reporter=verbose` — all tests pass 2. `grep -c "oklch.*0 0)" frontend/src/index.css` — returns a small number (only --card and --popover intentionally white) 3. `grep "success\|warning" frontend/src/index.css` — shows the new semantic tokens 4. palette.ts exports are importable: `cd frontend && bun -e "import { palette } from './src/lib/palette'; console.log(Object.keys(palette).length)"` — prints 7<success_criteria>
- Zero zero-chroma neutrals remain in :root (except intentional pure white on --card/--popover)
- palette.ts is the single source of truth for 7 category types x 3 shades
- headerGradient and amountColorClass helpers work correctly per unit tests
- --success and --warning CSS variables are usable as Tailwind utilities (text-success, text-warning)
- --chart-1 through --chart-5 values match palette.ts base colors
- vitest runs with all tests green </success_criteria>