diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md
index b3e03e8..c4ac8fe 100644
--- a/.planning/ROADMAP.md
+++ b/.planning/ROADMAP.md
@@ -29,7 +29,10 @@ Decimal phases appear between their surrounding integers in numeric order.
3. FinancialOverview and AvailableBalance render as visually dominant hero elements with clear typographic hierarchy above secondary content
4. Amount values across all tables and summaries show green for positive, destructive red for negative, and amber for over-budget — applied consistently
5. A single `lib/palette.ts` file exists as the source of truth for all category-to-color mappings; `InlineEditCell.tsx` is extracted as a shared component replacing three duplicated local definitions
-**Plans**: TBD
+**Plans:** 2 plans
+Plans:
+- [ ] 01-01-PLAN.md — CSS token foundation, palette.ts module, and test infrastructure
+- [ ] 01-02-PLAN.md — Component wiring, InlineEditCell extraction, and visual verification
### Phase 2: Layout and Brand Identity
**Goal**: Users encounter a visually branded, polished experience on every high-visibility surface — login page, sidebar, and dashboard layout — establishing the perceptual quality bar for the entire app
@@ -72,7 +75,7 @@ Phases execute in numeric order: 1 → 2 → 3 → 4
| Phase | Plans Complete | Status | Completed |
|-------|----------------|--------|-----------|
-| 1. Design Token Foundation | 0/TBD | Not started | - |
+| 1. Design Token Foundation | 0/2 | Planning complete | - |
| 2. Layout and Brand Identity | 0/TBD | Not started | - |
| 3. Interaction Quality and Completeness | 0/TBD | Not started | - |
| 4. Chart Polish and Bug Fixes | 0/TBD | Not started | - |
diff --git a/.planning/phases/01-design-token-foundation/01-01-PLAN.md b/.planning/phases/01-design-token-foundation/01-01-PLAN.md
new file mode 100644
index 0000000..956cf10
--- /dev/null
+++ b/.planning/phases/01-design-token-foundation/01-01-PLAN.md
@@ -0,0 +1,254 @@
+---
+phase: 01-design-token-foundation
+plan: 01
+type: execute
+wave: 1
+depends_on: []
+files_modified:
+ - frontend/src/index.css
+ - frontend/src/lib/palette.ts
+ - frontend/src/lib/palette.test.ts
+ - frontend/src/test-setup.ts
+ - frontend/vite.config.ts
+ - frontend/package.json
+autonomous: true
+requirements:
+ - DSGN-01
+ - DSGN-02
+ - DSGN-05
+
+must_haves:
+ truths:
+ - "All shadcn CSS variables in :root use pastel oklch values with non-zero chroma (no oklch(L 0 0) neutrals remain except --card which stays pure white)"
+ - "palette.ts exports typed color objects for all 7 category types with 3 shades each (light, medium, base)"
+ - "headerGradient() returns a valid CSSProperties object with a linear-gradient background"
+ - "amountColorClass() returns text-success for positive income, text-warning for over-budget expenses, text-destructive for negative available"
+ - "Custom --success and --warning CSS tokens exist in :root and are registered in @theme inline"
+ artifacts:
+ - path: "frontend/src/index.css"
+ provides: "Pastel oklch CSS variables for all shadcn tokens, plus --success and --warning semantic tokens"
+ contains: "--success"
+ - path: "frontend/src/lib/palette.ts"
+ provides: "Single source of truth for category colors with typed exports"
+ exports: ["palette", "CategoryType", "CategoryShades", "headerGradient", "overviewHeaderGradient", "amountColorClass"]
+ - path: "frontend/src/lib/palette.test.ts"
+ provides: "Unit tests for palette exports, headerGradient, and amountColorClass"
+ min_lines: 40
+ key_links:
+ - from: "frontend/src/index.css"
+ to: "frontend/src/lib/palette.ts"
+ via: "--chart-* CSS vars synced with palette base colors"
+ pattern: "chart-[1-5]"
+ - from: "frontend/src/lib/palette.ts"
+ to: "@/lib/utils"
+ via: "amountColorClass returns Tailwind utility classes that reference CSS variables"
+ pattern: "text-success|text-warning|text-destructive"
+---
+
+
+Establish the pastel CSS variable system and palette.ts module that all subsequent visual work depends on.
+
+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.
+
+
+
+@/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-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`
+
+2. Update `frontend/vite.config.ts` — add a `test` block inside `defineConfig`:
+ ```
+ test: {
+ environment: 'jsdom',
+ globals: true,
+ setupFiles: ['./src/test-setup.ts'],
+ }
+ ```
+ Import `/// ` at the top of the file.
+
+3. Create `frontend/src/test-setup.ts`:
+ ```typescript
+ import '@testing-library/jest-dom'
+ ```
+
+4. 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.
+
+
+
+ Task 2: Replace CSS tokens with pastel oklch values and add success/warning tokens
+ frontend/src/index.css
+
+ - Manual verification: every oklch value in :root has chroma > 0 (except --card which stays oklch(1 0 0) per locked decision "cards stay pure white")
+ - --success and --warning tokens exist in :root
+ - --color-success and --color-warning are registered in @theme inline
+ - --chart-1 through --chart-5 map to category base colors (bill, variable_expense, debt, saving, investment)
+
+
+Replace ALL zero-chroma oklch values in the `:root` block of `frontend/src/index.css` with pastel-tinted equivalents. Follow these locked decisions:
+
+**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:**
+```css
+--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.
+
+
+
+ Task 3: Create palette.ts and palette.test.ts
+ frontend/src/lib/palette.ts, frontend/src/lib/palette.test.ts
+
+ - palette exports all 7 CategoryType values: income, bill, variable_expense, debt, saving, investment, carryover
+ - Each category has 3 shades: light, medium, base — all non-empty oklch strings
+ - headerGradient('bill') returns { background: 'linear-gradient(to right, ...)' }
+ - overviewHeaderGradient() returns a multi-stop gradient for FinancialOverview
+ - amountColorClass({ type: 'income', actual: 100, budgeted: 0, isIncome: true }) returns 'text-success'
+ - amountColorClass({ type: 'income', actual: 0, budgeted: 0, isIncome: true }) returns ''
+ - amountColorClass({ type: 'bill', actual: 200, budgeted: 100 }) returns 'text-warning'
+ - amountColorClass({ type: 'bill', actual: 100, budgeted: 100 }) returns '' (exactly on budget = normal)
+ - amountColorClass({ type: 'bill', actual: 50, budgeted: 100 }) returns '' (under budget = normal)
+ - amountColorClass({ type: 'bill', actual: 0, budgeted: 0, isAvailable: true }) returns ''
+ - amountColorClass({ type: 'bill', actual: 500, budgeted: 0, isAvailable: true }) returns 'text-success'
+ - amountColorClass({ type: 'bill', actual: -100, budgeted: 0, isAvailable: true }) returns 'text-destructive'
+
+
+**Write tests first (RED):**
+
+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:
+
+1. `CategoryType` — union type of all 7 category strings
+2. `CategoryShades` — interface with `light`, `medium`, `base` string fields
+3. `palette` — `Record` 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
+
+4. `headerGradient(type: CategoryType): React.CSSProperties` — returns `{ background: 'linear-gradient(to right, ${light}, ${medium})' }`
+
+5. `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
+
+6. `amountColorClass(opts)` — implements the locked amount coloring rules:
+ - `isAvailable` or `isIncome` path: 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
+
+
+
+- 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
+
+
+
diff --git a/.planning/phases/01-design-token-foundation/01-02-PLAN.md b/.planning/phases/01-design-token-foundation/01-02-PLAN.md
new file mode 100644
index 0000000..d73ed46
--- /dev/null
+++ b/.planning/phases/01-design-token-foundation/01-02-PLAN.md
@@ -0,0 +1,335 @@
+---
+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
+
+
+