# Phase 5: Design System Token Rework - Pattern Map **Mapped:** 2026-04-20 **Files analyzed:** 14 files (1 CSS + 2 chart components + 1 shared component + 9 pages + 1 component) **Analogs found:** 14 / 14 (all files are modifications of existing code — no new files created) --- ## File Classification | Modified File | Role | Data Flow | Closest Analog / Self | Match Quality | |---|---|---|---|---| | `src/index.css` | config (CSS tokens) | transform | self — no analog needed | self | | `src/components/dashboard/charts/SpendBarChart.tsx` | component (chart) | transform | `src/components/dashboard/charts/IncomeBarChart.tsx` | exact | | `src/components/dashboard/charts/IncomeBarChart.tsx` | component (chart) | transform | `src/components/dashboard/charts/SpendBarChart.tsx` | exact | | `src/components/dashboard/charts/ExpenseDonutChart.tsx` | component (chart) | transform | `SpendBarChart.tsx` / `IncomeBarChart.tsx` | role-match | | `src/components/shared/PageShell.tsx` | component (layout) | request-response | self | self | | `src/components/dashboard/DashboardSkeleton.tsx` | component (skeleton) | request-response | `CategoriesPage.tsx` skeleton block | role-match | | `src/components/dashboard/CategorySection.tsx` | component (list item) | request-response | `BudgetDetailPage.tsx` group heading | role-match | | `src/components/dashboard/charts/ChartEmptyState.tsx` | component (empty state) | request-response | self | self | | `src/components/QuickAddPicker.tsx` | component (picker) | request-response | `BudgetDetailPage.tsx` select label dot | role-match | | `src/pages/DashboardPage.tsx` | page | request-response | self | self | | `src/pages/BudgetListPage.tsx` | page | request-response | `DashboardPage.tsx` / `BudgetDetailPage.tsx` | role-match | | `src/pages/BudgetDetailPage.tsx` | page | CRUD | `CategoriesPage.tsx` / `TemplatePage.tsx` | exact | | `src/pages/TemplatePage.tsx` | page | CRUD | `BudgetDetailPage.tsx` / `CategoriesPage.tsx` | exact | | `src/pages/CategoriesPage.tsx` | page | CRUD | `BudgetDetailPage.tsx` / `TemplatePage.tsx` | exact | | `src/pages/QuickAddPage.tsx` | page | CRUD | `CategoriesPage.tsx` | role-match | | `src/pages/SettingsPage.tsx` | page | request-response | `CategoriesPage.tsx` | role-match | | `src/pages/LoginPage.tsx` | page | request-response | `SettingsPage.tsx` | role-match | | `src/pages/RegisterPage.tsx` | page | request-response | `SettingsPage.tsx` | role-match | --- ## Pattern Assignments ### `src/index.css` (config, CSS tokens) **Analog:** self — authoritative token source, no external analog needed. **Current `@theme inline` block** (lines 1-99, full file): ```css @import "tailwindcss"; @custom-variant dark (&:is(.dark *)); @theme inline { --color-background: oklch(0.98 0.005 260); /* → 0.01 chroma (warm) */ --color-foreground: oklch(0.25 0.02 260); /* ... (base tokens unchanged) ... */ /* Category fill tokens — RAISE chroma to 0.22+ */ --color-income-fill: oklch(0.68 0.19 155); /* → 0.22 */ --color-bill-fill: oklch(0.65 0.19 25); /* → 0.22 */ --color-variable-expense-fill: oklch(0.70 0.18 50); /* → 0.22 */ --color-debt-fill: oklch(0.60 0.20 355); /* → 0.23 */ --color-saving-fill: oklch(0.68 0.18 220); /* → 0.22 */ --color-investment-fill: oklch(0.65 0.18 285); /* → 0.22 */ /* Chart vars — DELETE these 5 lines entirely */ --color-chart-1: oklch(0.72 0.14 155); --color-chart-2: oklch(0.7 0.14 25); --color-chart-3: oklch(0.72 0.14 50); --color-chart-4: oklch(0.65 0.16 355); --color-chart-5: oklch(0.72 0.14 220); --radius: 0.625rem; /* → 0 */ } @layer base { * { @apply border-border; } body { @apply bg-background text-foreground; font-feature-settings: "rlig" 1, "calt" 1; } } ``` **Changes to make in this file:** 1. Line 7: `--color-background: oklch(0.98 0.005 260)` → `oklch(0.98 0.01 260)` 2. Lines 65-70: raise all six `--color-*-fill` chroma values to 0.22+ per CONTEXT.md 3. Lines 52-57: delete `--color-chart-1` through `--color-chart-5` entirely 4. Line 72: `--radius: 0.625rem` → `--radius: 0` 5. After `@layer base` block: add CSS override selectors for Recharts and Sonner (see Shared Patterns section below) --- ### `src/components/dashboard/charts/SpendBarChart.tsx` (component, transform) **Analog:** `src/components/dashboard/charts/IncomeBarChart.tsx` **Current `Bar` radius props** (lines 64-80): ```tsx /* → radius={0} */ {data.map((entry, index) => ( entry.budgeted ? "var(--color-over-budget)" : `var(--color-${entry.type}-fill)` /* already correct — no change */ } /> ))} ``` **Changes to make in this file:** - Line 67: `radius={4}` → `radius={0}` - Line 69: `radius={4}` → `radius={0}` - `chartConfig` (lines 31-34): no change needed — `actual` already references `--color-muted-foreground`, `budgeted` references `--color-budget-bar-bg`; neither references deleted `--color-chart-*` vars. --- ### `src/components/dashboard/charts/IncomeBarChart.tsx` (component, transform) **Analog:** `src/components/dashboard/charts/SpendBarChart.tsx` **Current `Bar` radius props** (lines 54-69): ```tsx /* → radius={0} */ {data.map((entry, index) => ( entry.budgeted ? "var(--color-over-budget)" : "var(--color-income-fill)" /* already correct — no change */ } /> ))} ``` **Current `chartConfig`** (lines 26-29): ```tsx const chartConfig = { budgeted: { label: "Budgeted", color: "var(--color-budget-bar-bg)" }, actual: { label: "Actual", color: "var(--color-income-fill)" }, /* already references fill token */ } satisfies ChartConfig ``` **Changes to make in this file:** - Line 57: `radius={[4, 4, 0, 0]}` → `radius={0}` - Line 59: `radius={[4, 4, 0, 0]}` → `radius={0}` - `chartConfig`: no change needed — already references `--color-income-fill`, not a deleted `--color-chart-*` var. --- ### `src/components/dashboard/charts/ExpenseDonutChart.tsx` (component, transform) **Analog:** self — already uses `var(--color-${entry.type}-fill)` pattern throughout. **The one hardcoded `rounded-full`** (line 141): ```tsx /* Before */ /* After — remove rounded-full entirely */ ``` **Changes to make in this file:** - Line 141: remove `rounded-full` from className string. - No `ChartConfig` changes needed — `ExpenseDonutChart` builds its config dynamically from data using `var(--color-${entry.type}-fill)` (lines 47-51), which is already the correct post-rework pattern. --- ### `src/components/shared/PageShell.tsx` (component, layout) **Current spacing** (line 15): ```tsx
/* → gap-8 */ ``` **Changes to make in this file:** - Line 15: `gap-6` → `gap-8` This single change propagates the header-to-content gap increase to all 9 pages that use `PageShell`. --- ### `src/components/dashboard/DashboardSkeleton.tsx` (component, skeleton) **Analog:** Skeleton patterns from `CategoriesPage.tsx` lines 98-114 and `BudgetDetailPage.tsx` lines 284-306. **Hardcoded `rounded-*` locations in this file:** ```tsx /* Line 35 — chart placeholder */ /* remove rounded-md */ /* Line 43 — chart placeholder */ /* remove rounded-md */ /* Line 51 — chart placeholder */ /* remove rounded-md */ /* Line 59 — collapsible section row */
/* remove rounded-md */ /* Lines 63-64 — inline summary badges */ /* remove rounded-full — CRITICAL: rounded-full is 9999px, not from --radius */ /* remove rounded-full */ ``` **Also: spacing upgrades**: ```tsx /* Line 20 — top-level container */
/* → gap-8 */ /* Line 22 — summary cards grid */
/* → gap-6 */ /* Line 29 — chart grid */
/* → gap-8 */ ``` --- ### `src/components/dashboard/CategorySection.tsx` (component, list item) **Analog:** Group heading divs in `BudgetDetailPage.tsx` lines 352-356, `CategoriesPage.tsx` lines 134-137, `TemplatePage.tsx` lines 292-295. **The hardcoded `rounded-md`** (line 73): ```tsx /* Before */