--- phase: 01-design-token-foundation plan: 02 type: execute wave: 2 depends_on: ["01-01"] files_modified: - frontend/src/components/BillsTracker.tsx - frontend/src/components/VariableExpenses.tsx - frontend/src/components/DebtTracker.tsx - frontend/src/components/AvailableBalance.tsx - frontend/src/components/ExpenseBreakdown.tsx - frontend/src/components/FinancialOverview.tsx - frontend/src/components/InlineEditCell.tsx - frontend/src/components/InlineEditCell.test.tsx autonomous: false requirements: - DSGN-03 - DSGN-04 - DSGN-05 - FIX-02 must_haves: truths: - "Card headers on BillsTracker, VariableExpenses, DebtTracker, AvailableBalance, ExpenseBreakdown use palette-driven gradients — no hardcoded Tailwind color classes remain" - "FinancialOverview header uses a multi-pastel gradient from overviewHeaderGradient()" - "FinancialOverview and AvailableBalance have hero typography (text-2xl titles, p-6 padding) while other cards have regular typography (text-base titles, px-4 py-3 padding)" - "AvailableBalance center amount is text-3xl font-bold with green/red color coding" - "Actual amount columns show green for positive income, amber for over-budget expenses, red for negative available — budget column stays neutral" - "InlineEditCell.tsx is a shared component replacing three duplicate InlineEditRow functions" - "FinancialOverview rows are tinted with their category's light shade" artifacts: - path: "frontend/src/components/InlineEditCell.tsx" provides: "Shared inline edit cell component" exports: ["InlineEditCell"] min_lines: 25 - path: "frontend/src/components/InlineEditCell.test.tsx" provides: "Unit tests for InlineEditCell" min_lines: 30 - path: "frontend/src/components/BillsTracker.tsx" provides: "Bills section with palette gradient header and InlineEditCell" contains: "headerGradient" - path: "frontend/src/components/FinancialOverview.tsx" provides: "Hero overview with multi-gradient header and category-tinted rows" contains: "overviewHeaderGradient" key_links: - from: "frontend/src/components/BillsTracker.tsx" to: "frontend/src/lib/palette.ts" via: "import headerGradient and amountColorClass" pattern: "import.*palette" - from: "frontend/src/components/InlineEditCell.tsx" to: "frontend/src/components/BillsTracker.tsx" via: "BillsTracker imports and uses InlineEditCell instead of local InlineEditRow" pattern: "InlineEditCell" - from: "frontend/src/components/AvailableBalance.tsx" to: "frontend/src/lib/palette.ts" via: "Chart Cell fill uses palette[type].base instead of PASTEL_COLORS array" pattern: "palette.*base" --- Wire the palette.ts module into all dashboard components — replace hardcoded gradients, apply hero typography, add amount coloring, and extract InlineEditCell. Purpose: This transforms the visual appearance of the dashboard from generic neutrals to a cohesive pastel-themed experience. Every component now reads from the token system established in Plan 01. Output: All 6 dashboard components updated, InlineEditCell extracted and tested. @/home/jean-luc-makiola/.claude/get-shit-done/workflows/execute-plan.md @/home/jean-luc-makiola/.claude/get-shit-done/templates/summary.md @.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-01-SUMMARY.md @frontend/src/lib/palette.ts @frontend/src/index.css @frontend/src/components/BillsTracker.tsx @frontend/src/components/VariableExpenses.tsx @frontend/src/components/DebtTracker.tsx @frontend/src/components/AvailableBalance.tsx @frontend/src/components/ExpenseBreakdown.tsx @frontend/src/components/FinancialOverview.tsx From src/lib/palette.ts (created in Plan 01): ```typescript export type CategoryType = 'income' | 'bill' | 'variable_expense' | 'debt' | 'saving' | 'investment' | 'carryover' export interface CategoryShades { light: string // oklch — row backgrounds, tinted surfaces medium: string // oklch — header gradient to-color, badges base: string // oklch — chart fills, text accents } export const palette: Record export function headerGradient(type: CategoryType): React.CSSProperties export function overviewHeaderGradient(): React.CSSProperties export function amountColorClass(opts: { type: CategoryType actual: number budgeted: number isIncome?: boolean isAvailable?: boolean }): string ``` From src/lib/utils.ts: ```typescript export function cn(...inputs: ClassValue[]): string ``` From src/lib/format.ts: ```typescript export function formatCurrency(value: number, currency: string): string ``` Task 1: Extract InlineEditCell and wire palette into all components frontend/src/components/InlineEditCell.tsx, frontend/src/components/InlineEditCell.test.tsx, frontend/src/components/BillsTracker.tsx, frontend/src/components/VariableExpenses.tsx, frontend/src/components/DebtTracker.tsx, frontend/src/components/AvailableBalance.tsx, frontend/src/components/ExpenseBreakdown.tsx, frontend/src/components/FinancialOverview.tsx - InlineEditCell renders formatted currency in display mode - InlineEditCell shows an Input on click (enters edit mode) - InlineEditCell calls onSave with parsed number on blur/Enter - InlineEditCell does NOT call onSave if value unchanged or NaN **Part A — Write InlineEditCell tests (RED):** Create `frontend/src/components/InlineEditCell.test.tsx` with tests: - "renders formatted currency value in display mode" - "enters edit mode on click" - "calls onSave with parsed number on blur" - "does not call onSave when value unchanged" - "calls onSave on Enter key" Use `@testing-library/react` render + `@testing-library/user-event`. Mock `formatCurrency` from `@/lib/format` if needed, or just test the DOM output. Run tests — they must FAIL. **Part B — Create InlineEditCell (GREEN):** Create `frontend/src/components/InlineEditCell.tsx` following the pattern from RESEARCH.md Pattern 5. Props interface: ```typescript interface InlineEditCellProps { value: number currency: string onSave: (value: number) => Promise className?: string } ``` The component renders a `` that: - In display mode: shows a `` with `formatCurrency(value, currency)`, `cursor-pointer rounded px-2 py-1 hover:bg-muted` - On click: switches to edit mode with ``, autofocused - On blur or Enter: parses the input, calls `onSave` if value changed and is a valid number, then returns to display mode Run tests — they must PASS. **Part C — Wire palette into all 6 dashboard components:** For each component, apply these changes: **BillsTracker.tsx:** 1. Remove the private `InlineEditRow` function (lines ~59-110) 2. Add imports: `import { headerGradient, amountColorClass } from '@/lib/palette'` and `import { InlineEditCell } from '@/components/InlineEditCell'` 3. Replace `` with `` 4. Replace the `` usage with `` inside the existing ``. The caller keeps the label and budget cells; InlineEditCell replaces only the actual amount cell. 5. Add `amountColorClass({ type: 'bill', actual, budgeted })` as `className` on the InlineEditCell for amount coloring. Budget column stays neutral (no color class). **VariableExpenses.tsx:** 1. Remove the private `InlineEditRow` function (lines ~86-142) 2. Add same imports as BillsTracker 3. Replace `` with `` 4. Replace `` with `` for the actual cell. Keep the "remaining" cell in VariableExpenses — it's NOT part of InlineEditCell. 5. Add amount coloring to the InlineEditCell className. **DebtTracker.tsx:** 1. Remove the private `InlineEditRow` function (lines ~61-112) 2. Add same imports 3. Replace `` with `` 4. Replace `` with `` for the actual cell 5. Add amount coloring **AvailableBalance.tsx:** 1. Remove the `PASTEL_COLORS` array constant 2. Add imports: `import { palette, headerGradient, type CategoryType } from '@/lib/palette'` 3. Replace `` with `` (hero padding per locked decision) 4. Update `` to `className="text-2xl font-semibold"` (hero typography) 5. Replace `` 6. Style the center donut amount: `text-3xl font-bold tabular-nums` with `cn()` applying `text-success` when available >= 0, `text-destructive` when negative 7. Add small `text-xs text-muted-foreground` label "Available" (or translated equivalent) below the center amount **ExpenseBreakdown.tsx:** 1. Remove the `PASTEL_COLORS` array constant 2. Add imports: `import { palette, type CategoryType } from '@/lib/palette'` 3. Replace `` with `` 4. Replace `` **FinancialOverview.tsx:** 1. Add imports: `import { palette, overviewHeaderGradient, amountColorClass, type CategoryType } from '@/lib/palette'` 2. Replace `` with `` (hero padding) 3. Update `` to `className="text-2xl font-semibold"` (hero typography) 4. Tint each summary row with its category's light shade: add `style={{ backgroundColor: palette[categoryType].light }}` to each `` that represents a category 5. Apply `amountColorClass()` to actual amount cells. For the income row, pass `isIncome: true`. For the remaining/available summary row, pass `isAvailable: true`. Budget column stays neutral. **CRITICAL anti-patterns to avoid:** - Do NOT add `style` to `` — only to `` for gradients - Do NOT color the budget column — only actual gets colored - Do NOT use raw Tailwind color classes like `text-green-600` — use `text-success` from the semantic token - Do NOT edit any files in `src/components/ui/` - Do NOT use Tailwind v3 bracket syntax `bg-[--var]` — use v4 parenthesis syntax `bg-(--var)` if needed cd /home/jean-luc-makiola/Development/projects/SimpleFinanceDash/frontend && bun vitest run --reporter=verbose - InlineEditCell.test.tsx passes all tests - palette.test.ts still passes (no regressions) - No `InlineEditRow` private function exists in BillsTracker, VariableExpenses, or DebtTracker - No `PASTEL_COLORS` array exists in AvailableBalance or ExpenseBreakdown - No `bg-gradient-to-r from-blue-50` or similar hardcoded gradient classes exist in any dashboard component - All 6 dashboard components import from `@/lib/palette` - FinancialOverview and AvailableBalance use hero sizing (text-2xl, p-6/px-6 py-5) - Amount coloring uses amountColorClass() — only on actual column Task 2: Build verification — ensure app compiles and no hardcoded colors remain frontend/src/components/BillsTracker.tsx, frontend/src/components/VariableExpenses.tsx, frontend/src/components/DebtTracker.tsx, frontend/src/components/AvailableBalance.tsx, frontend/src/components/ExpenseBreakdown.tsx, frontend/src/components/FinancialOverview.tsx 1. Run the Vite build to confirm no TypeScript errors: `cd frontend && bun run build` 2. Run the full test suite: `cd frontend && bun vitest run` 3. Verify no hardcoded gradient color classes remain in dashboard components: `grep -rn "from-blue-50\|from-amber-50\|from-orange-50\|from-sky-50\|from-pink-50\|from-sky-50 to-indigo-50\|PASTEL_COLORS" frontend/src/components/` This should return zero results. 4. Verify no raw Tailwind color utilities for amount coloring: `grep -rn "text-green-\|text-red-\|text-amber-" frontend/src/components/` This should return zero results (all amount colors use text-success, text-warning, text-destructive). 5. Verify InlineEditRow is fully removed: `grep -rn "InlineEditRow" frontend/src/components/` This should return zero results. If any issues are found, fix them before proceeding. cd /home/jean-luc-makiola/Development/projects/SimpleFinanceDash/frontend && bun run build 2>&1 | tail -5 && bun vitest run 2>&1 | tail -5 Vite production build succeeds with zero errors. All tests pass. No hardcoded gradient classes, PASTEL_COLORS arrays, InlineEditRow functions, or raw Tailwind color utilities exist in dashboard components. Task 3: Visual verification of pastel design token system Human verifies the complete pastel design token system and visual dashboard overhaul. What was built: - All shadcn components display in pastel tones (lavender-tinted backgrounds, borders, and surfaces) - Card headers have category-specific pastel gradients (blue for bills, amber for variable expenses, rose for debt, etc.) - FinancialOverview and AvailableBalance are visually dominant hero elements with larger text and more padding - AvailableBalance donut center shows the amount in green (positive) or red (negative) - Amount coloring: green for positive income, amber for over-budget expenses, red for negative available - FinancialOverview rows are tinted with their category's pastel shade - Charts use category colors from palette.ts (same colors as table headers) - InlineEditCell is extracted as a shared component (click to edit actual amounts) How to verify: 1. Start the app: `cd frontend && bun run dev` (ensure backend is running or use `docker compose up db` for database) 2. Open http://localhost:5173 in browser 3. Check these specific items: a. Background tint: The page background should have a very subtle lavender tint; cards should be pure white floating on it b. Card headers: Each section (Bills, Variable Expenses, Debt) should have a distinct pastel gradient header color — blue, amber, rose respectively c. Hero elements: FinancialOverview and AvailableBalance should look visually larger/more prominent than other cards d. Donut center: The available amount in the donut chart should be large text, colored green if positive or red if negative e. Amount coloring: In any tracker, if an actual amount exceeds budget, it should show amber. Income actual amounts should be green. Remaining/available should be green (positive) or red (negative) f. Row tinting: FinancialOverview summary rows should each have a subtle category-colored background g. Inline editing: Click any actual amount in Bills/Variable Expenses/Debt — it should enter edit mode with an input field h. Chart colors: Donut/bar chart segments should use the same colors as their corresponding card headers Human visual inspection of dashboard at http://localhost:5173 User confirms pastel theme, hero hierarchy, amount coloring, row tinting, inline editing, and chart colors all look correct. 1. `cd frontend && bun run build` — zero TypeScript errors 2. `cd frontend && bun vitest run` — all tests pass 3. `grep -rn "PASTEL_COLORS\|InlineEditRow\|from-blue-50\|from-amber-50\|from-orange-50\|from-sky-50\|from-pink-50" frontend/src/components/` — zero results 4. `grep -rn "text-green-\|text-red-\|text-amber-" frontend/src/components/` — zero results 5. Visual inspection confirms pastel theme, hero hierarchy, amount coloring, and inline editing - All 6 dashboard components use palette.ts for gradients (no hardcoded Tailwind color classes) - FinancialOverview and AvailableBalance have hero typography and padding - Amount coloring follows locked rules: green income, amber over-budget, red negative - InlineEditCell is the single shared component for inline editing (3 duplicates removed) - Charts use palette.ts base colors matching their card header categories - Vite build succeeds, all tests pass - User approves visual result at checkpoint After completion, create `.planning/phases/01-design-token-foundation/01-02-SUMMARY.md`