Files

10 KiB

phase, slug, status, shadcn_initialized, preset, created
phase slug status shadcn_initialized preset created
5 design-system-token-rework draft true new-york / neutral / lucide 2026-04-20

Phase 5 — UI Design Contract

Visual and interaction contract for Phase 5: Design System Token Rework. Generated by gsd-ui-researcher, verified by gsd-ui-checker.

This phase is a pure token and spacing rework — no new components, no new features. Every entry in this contract describes what must be TRUE after the change, not before.


Design System

Property Value Source
Tool shadcn/ui components.json
Style new-york components.json
Preset neutral base, cssVariables: true components.json
Component library Radix UI (via shadcn) components.json
Icon library lucide-react components.json
Font Inter (--font-sans) src/index.css

Spacing Scale

Declared values (all multiples of 4):

Token px Value Tailwind Class Usage
xs 4px gap-1 / p-1 Icon gaps, inline tight spacing
sm 8px gap-2 / p-2 Compact inline elements, badge padding
md 16px gap-4 / p-4 Default inline element spacing
lg 24px gap-6 / p-6 Card internal padding (upgraded from p-4)
xl 32px gap-8 Section gaps between cards and sections (upgraded from gap-6)
2xl 48px gap-12 Major section breaks, page-level vertical rhythm
3xl 64px py-16 Auth page vertical centering, hero areas

Phase 5 spacing changes (from CONTEXT.md):

  • Card internal padding: p-4p-6 across all 9 pages
  • Section gaps: gap-4gap-6, gap-6gap-8 across all pages
  • Page header bottom margin: standardize to mb-6 everywhere
  • Section-to-section gap: standardize to gap-8

Exceptions: none — 8-point scale applies without exception.


Typography

Role Size Tailwind Weight Weight Class Line Height Usage
Caption 12px text-xs 400 font-normal 1.5 Subtitles, secondary metadata
Body / Label 14px text-sm 500 font-medium 1.5 Table cells, form labels, card labels, stat subtitles
Base 16px text-base 500 font-medium 1.5 Card titles (e.g. chart section headings)
Heading 24px text-2xl 600 font-semibold 1.2 Page titles (PageShell h1), auth card titles, template names

Source: Existing usage in PageShell, StatCard, DashboardPage, LoginPage, RegisterPage confirmed these four sizes as the complete in-use set.

Weights used: exactly 2 — font-medium (500) for body/data, font-semibold (600) for headings. The rare font-bold (700) occurrences in StatCard value display are reclassified as font-semibold for consistency.


Color

Base UI Tokens (post-rework values)

Role OKLCH Value Usage
Background (dominant, 60%) oklch(0.98 0.01 260) Page background — chroma lifted 0.005→0.01 for subtle warmth
Card / Popover (secondary, 30%) oklch(1 0 0) Cards, modals, popovers, sidebar surface
Sidebar oklch(0.97 0.008 260) Sidebar background — no change
Primary accent (10%) oklch(0.55 0.15 260) Active nav items, primary buttons, focus rings
Secondary / Muted oklch(0.93 0.02 260) Secondary buttons, muted chip backgrounds
Border / Input oklch(0.88 0.01 260) All borders and input outlines
Destructive oklch(0.6 0.2 25) Delete actions, error alerts only

Accent reserved for: primary action buttons, active sidebar navigation item, focus ring outlines, primary CTA buttons. No other elements may use the primary OKLCH(0.55 0.15 260) value.

Category Text Colors (WCAG 4.5:1 contrast on white — no change to lightness/chroma)

Token OKLCH Value Hue
--color-income oklch(0.55 0.17 155) Green
--color-bill oklch(0.55 0.17 25) Orange-red
--color-variable-expense oklch(0.58 0.16 50) Amber
--color-debt oklch(0.52 0.18 355) Red
--color-saving oklch(0.55 0.16 220) Blue
--color-investment oklch(0.55 0.16 285) Violet

Category Fill Colors (post-rework — chroma raised to 0.22+)

These replace the current fill tokens (C=0.18-0.20). Exact values are at Claude's discretion per CONTEXT.md as long as chroma >= 0.22 and the fills remain visually distinct from each other.

Token Target OKLCH Constraint
--color-income-fill oklch(0.72 0.22 155) C >= 0.22, L ~0.70-0.75
--color-bill-fill oklch(0.70 0.22 25) C >= 0.22, L ~0.68-0.73
--color-variable-expense-fill oklch(0.74 0.22 50) C >= 0.22, L ~0.70-0.76
--color-debt-fill oklch(0.66 0.23 355) C >= 0.22, L ~0.64-0.70
--color-saving-fill oklch(0.72 0.22 220) C >= 0.22, L ~0.70-0.75
--color-investment-fill oklch(0.68 0.22 285) C >= 0.22, L ~0.65-0.72

Chart Colors (post-rework — aligned to fill tokens)

The --color-chart-1 through --color-chart-5 variables are REMOVED. Chart components reference --color-*-fill tokens directly. This eliminates the duplicate color system.

Removed Replaced by
--color-chart-1 --color-income-fill
--color-chart-2 --color-bill-fill
--color-chart-3 --color-variable-expense-fill
--color-chart-4 --color-debt-fill
--color-chart-5 --color-saving-fill

Corner Radius

Token Current Value Post-Rework Value Effect
--radius 0.625rem (10px) 0rem (0px) All shadcn components become sharp-cornered

Third-party overrides required (applied via CSS selectors in src/index.css):

  • Recharts bar elements: force rx="0" ry="0" or CSS border-radius: 0
  • Sonner toast container: override .sonner-toast border-radius to 0

Copywriting Contract

Phase 5 is a pure visual rework — no new user-facing copy is introduced. The following existing copy elements remain unchanged and are documented here as the confirmed contract.

Element Copy Notes
Primary CTA (Budget List) "New Budget" Existing — unchanged
Primary CTA (Template) "Add item" Existing — unchanged
Primary CTA (Categories) "New Category" Existing — unchanged
Empty state (Dashboard) Translation key: dashboard.noBudgetForMonth Existing — no copy changes this phase
Error state (auth forms) Translation key: auth.error + specific message Existing — no copy changes this phase
Destructive actions None introduced in this phase Token rework only

No new destructive actions are introduced. No new confirmation dialogs. No new empty states.


Component Inventory

Components affected by token changes (no code changes required — token cascade handles it):

Component Location Rounding Source Change Required
Button src/components/ui/button.tsx --radius token Automatic via --radius: 0
Card src/components/ui/card.tsx --radius token Automatic; padding class updated to p-6
Input src/components/ui/input.tsx --radius token Automatic via --radius: 0
Badge src/components/ui/badge.tsx --radius token Automatic via --radius: 0
Select src/components/ui/select.tsx --radius token Automatic via --radius: 0
Sheet src/components/ui/sheet.tsx --radius token Automatic via --radius: 0
Dialog src/components/ui/dialog.tsx --radius token Automatic via --radius: 0
Popover src/components/ui/popover.tsx --radius token Automatic via --radius: 0
Sidebar src/components/ui/sidebar.tsx --radius token Automatic via --radius: 0
Dropdown Menu src/components/ui/dropdown-menu.tsx --radius token Automatic via --radius: 0
Recharts bars SpendBarChart, IncomeBarChart SVG rx/ry attrs Explicit CSS override needed
Sonner toasts src/components/ui/sonner.tsx Sonner inline styles CSS selector override needed
Category swatches CategoriesPage, CategorySection Hardcoded rounded-* Audit and remove rounded-* classes
Budget progress bars BudgetDetailPage Hardcoded rounded-* Audit and remove rounded-* classes

Pages to audit for inline rounded-* classes (must be zero after this phase):

  1. DashboardPage — CategorySection swatches, StatCard
  2. BudgetListPage — budget item rows
  3. BudgetDetailPage — progress bars, budget row items
  4. TemplatePage — template item rows, category group headers
  5. CategoriesPage — category color swatches
  6. QuickAddPage — picker items
  7. SettingsPage — form elements
  8. LoginPage — auth card
  9. RegisterPage — auth card

Registry Safety

Registry Blocks Used Safety Gate
shadcn official (new-york) button, card, badge, input, label, select, sheet, dialog, popover, sidebar, dropdown-menu, separator, skeleton, table, tooltip, sonner, chart, collapsible not required
Third-party none not applicable

No third-party registries. No vetting gate required.


Interaction Contract

Phase 5 introduces no new interaction patterns. Existing interactions are preserved. The following are confirmed unchanged:

  • Collapsible sections: 200ms ease-out open/close animation (--animate-collapsible-open/close) — no change
  • Sidebar navigation: active state uses primary color — no change to behavior
  • Form validation: error states use --color-destructive — no change
  • Chart tooltips: Recharts default — style override via chart.tsx config only

Visual Regression Checklist

The executor must perform a manual visual pass after all token changes confirming:

  • No pill buttons visible on any of the 9 pages
  • No rounded cards visible on any of the 9 pages
  • No rounded inputs visible on any of the 9 pages
  • Category fill colors are visibly colorful against white (not grey-tinted)
  • Category text colors still appear dark/readable (not washed out by chroma increase)
  • Section gaps feel generous — no visual crowding between cards
  • Card internal padding feels spacious — content not flush against card edges
  • Page headers have consistent bottom margin before first content section
  • Recharts bars are square-ended (no rounded caps)
  • Sonner toasts have sharp corners

Checker Sign-Off

  • Dimension 1 Copywriting: PASS
  • Dimension 2 Visuals: PASS
  • Dimension 3 Color: PASS
  • Dimension 4 Typography: PASS
  • Dimension 5 Spacing: PASS
  • Dimension 6 Registry Safety: PASS

Approval: pending