chore: merge executor worktree (worktree-agent-a2b5acd5)
This commit is contained in:
110
.planning/phases/05-design-system-token-rework/05-03-SUMMARY.md
Normal file
110
.planning/phases/05-design-system-token-rework/05-03-SUMMARY.md
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
---
|
||||||
|
phase: 05-design-system-token-rework
|
||||||
|
plan: "03"
|
||||||
|
subsystem: frontend/pages
|
||||||
|
tags: [design-system, pages, spacing, rounding, tailwind]
|
||||||
|
dependency_graph:
|
||||||
|
requires: [05-01, 05-02]
|
||||||
|
provides: [clean-pages-no-rounding, upgraded-page-spacing]
|
||||||
|
affects: [all-9-pages]
|
||||||
|
tech_stack:
|
||||||
|
added: []
|
||||||
|
patterns: [tailwind-utility-sweep, rounding-removal, spacing-upgrade]
|
||||||
|
key_files:
|
||||||
|
modified:
|
||||||
|
- src/pages/DashboardPage.tsx
|
||||||
|
- src/pages/BudgetListPage.tsx
|
||||||
|
- src/pages/BudgetDetailPage.tsx
|
||||||
|
- src/pages/TemplatePage.tsx
|
||||||
|
- src/pages/CategoriesPage.tsx
|
||||||
|
- src/pages/QuickAddPage.tsx
|
||||||
|
- src/pages/SettingsPage.tsx
|
||||||
|
decisions:
|
||||||
|
- "LoginPage and RegisterPage required no changes: no rounded-* classes present and CardContent already uses shadcn px-6 default padding"
|
||||||
|
metrics:
|
||||||
|
duration: "129s"
|
||||||
|
completed: "2026-04-20T15:16:38Z"
|
||||||
|
tasks_completed: 2
|
||||||
|
files_modified: 7
|
||||||
|
---
|
||||||
|
|
||||||
|
# Phase 05 Plan 03: Page Rounding Sweep and Spacing Upgrade Summary
|
||||||
|
|
||||||
|
Removed all hardcoded `rounded-*` Tailwind classes from 7 of 9 pages (2 required no changes) and upgraded section spacing throughout. Build passes cleanly with zero rounded-* remaining in src/pages/.
|
||||||
|
|
||||||
|
## Tasks Completed
|
||||||
|
|
||||||
|
| Task | Name | Commit | Files |
|
||||||
|
|------|------|--------|-------|
|
||||||
|
| 1 | Remove rounded-* and upgrade spacing on all 9 pages | 00670af | DashboardPage, BudgetListPage, BudgetDetailPage, TemplatePage, CategoriesPage, QuickAddPage, SettingsPage |
|
||||||
|
| 2 | Visual verification (checkpoint) | auto-approved | — |
|
||||||
|
|
||||||
|
## Changes Per File
|
||||||
|
|
||||||
|
**DashboardPage.tsx**
|
||||||
|
- `space-y-6` -> `space-y-8` on main content wrapper
|
||||||
|
- `gap-6` -> `gap-8` on 3-column chart grid
|
||||||
|
|
||||||
|
**BudgetListPage.tsx**
|
||||||
|
- Removed `rounded-md` from template toggle checkbox row (`flex items-center gap-3 border p-3`)
|
||||||
|
|
||||||
|
**BudgetDetailPage.tsx**
|
||||||
|
- Skeleton group heading: removed `rounded-sm`
|
||||||
|
- Skeleton summary box: removed `rounded-md`
|
||||||
|
- Live group heading: removed `rounded-sm`
|
||||||
|
- Overall totals summary box: removed `rounded-md`
|
||||||
|
- SelectLabel category dot: removed `rounded-full`
|
||||||
|
|
||||||
|
**TemplatePage.tsx**
|
||||||
|
- Skeleton outer wrapper: `gap-6` -> `gap-8`
|
||||||
|
- Skeleton group heading: removed `rounded-sm`
|
||||||
|
- Skeleton badge placeholder: removed `rounded-full`
|
||||||
|
- Skeleton icon button placeholder: removed `rounded-md`
|
||||||
|
- Live outer wrapper: `gap-6` -> `gap-8`
|
||||||
|
- Live grouped items section: `space-y-6` -> `space-y-8`
|
||||||
|
- Live group heading: removed `rounded-sm`
|
||||||
|
- SelectLabel category dot: removed `rounded-full`
|
||||||
|
|
||||||
|
**CategoriesPage.tsx**
|
||||||
|
- Skeleton group heading: removed `rounded-sm`
|
||||||
|
- Skeleton badge placeholder: removed `rounded-full`
|
||||||
|
- Skeleton icon button placeholder: removed `rounded-md`
|
||||||
|
- Skeleton section container: `space-y-6` -> `space-y-8`
|
||||||
|
- Live grouped items section: `space-y-6` -> `space-y-8`
|
||||||
|
- Live group heading: removed `rounded-sm`
|
||||||
|
|
||||||
|
**QuickAddPage.tsx**
|
||||||
|
- Skeleton icon badge placeholder: removed `rounded-full`
|
||||||
|
- Skeleton action button placeholder: removed `rounded-md`
|
||||||
|
|
||||||
|
**SettingsPage.tsx**
|
||||||
|
- Both `CardContent` instances (skeleton + live): `space-y-4` -> `space-y-6`
|
||||||
|
|
||||||
|
**LoginPage.tsx / RegisterPage.tsx**
|
||||||
|
- No changes required: no `rounded-*` classes; Card rounding controlled by `--radius: 0` token cascade from 05-01
|
||||||
|
|
||||||
|
## Deviations from Plan
|
||||||
|
|
||||||
|
None - plan executed exactly as written. Line number references in PATTERNS.md were accurate.
|
||||||
|
|
||||||
|
## Checkpoint: Task 2
|
||||||
|
|
||||||
|
**Type:** human-verify
|
||||||
|
**Auto-approved:** Yes (autonomous wave execution)
|
||||||
|
**What was verified:** All 9 pages swept for rounded-* removal and spacing upgrade. Build passes. grep confirms zero rounded-full/sm/md/lg in src/pages/.
|
||||||
|
|
||||||
|
## Known Stubs
|
||||||
|
|
||||||
|
None.
|
||||||
|
|
||||||
|
## Threat Flags
|
||||||
|
|
||||||
|
None — pure CSS class changes in JSX, no new network surface.
|
||||||
|
|
||||||
|
## Self-Check: PASSED
|
||||||
|
|
||||||
|
- 7 files modified and committed at 00670af
|
||||||
|
- `bun run build` exits 0
|
||||||
|
- `grep -rn "rounded-full\|rounded-sm\|rounded-md\|rounded-lg" src/pages/` returns no matches
|
||||||
|
- DashboardPage.tsx contains `space-y-8` and `gap-8` (verified)
|
||||||
|
- SettingsPage.tsx contains `space-y-6` in CardContent (verified, both instances)
|
||||||
@@ -287,7 +287,7 @@ export default function BudgetDetailPage() {
|
|||||||
<Skeleton className="h-4 w-24" />
|
<Skeleton className="h-4 w-24" />
|
||||||
{[1, 2, 3].map((i) => (
|
{[1, 2, 3].map((i) => (
|
||||||
<div key={i} className="space-y-2">
|
<div key={i} className="space-y-2">
|
||||||
<div className="flex items-center gap-3 rounded-sm border-l-4 border-muted bg-muted/30 px-3 py-2">
|
<div className="flex items-center gap-3 border-l-4 border-muted bg-muted/30 px-3 py-2">
|
||||||
<Skeleton className="h-4 w-28" />
|
<Skeleton className="h-4 w-28" />
|
||||||
</div>
|
</div>
|
||||||
{[1, 2].map((j) => (
|
{[1, 2].map((j) => (
|
||||||
@@ -300,7 +300,7 @@ export default function BudgetDetailPage() {
|
|||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
<Skeleton className="h-20 w-full rounded-md" />
|
<Skeleton className="h-20 w-full" />
|
||||||
</div>
|
</div>
|
||||||
</PageShell>
|
</PageShell>
|
||||||
)
|
)
|
||||||
@@ -350,7 +350,7 @@ export default function BudgetDetailPage() {
|
|||||||
<div key={type}>
|
<div key={type}>
|
||||||
{/* Group heading */}
|
{/* Group heading */}
|
||||||
<div
|
<div
|
||||||
className="mb-2 flex items-center gap-3 rounded-sm border-l-4 bg-muted/30 px-3 py-2"
|
className="mb-2 flex items-center gap-3 border-l-4 bg-muted/30 px-3 py-2"
|
||||||
style={{ borderLeftColor: categoryColors[type] }}
|
style={{ borderLeftColor: categoryColors[type] }}
|
||||||
>
|
>
|
||||||
<span className="text-sm font-semibold">{t(`categories.types.${type}`)}</span>
|
<span className="text-sm font-semibold">{t(`categories.types.${type}`)}</span>
|
||||||
@@ -436,7 +436,7 @@ export default function BudgetDetailPage() {
|
|||||||
})}
|
})}
|
||||||
|
|
||||||
{/* Overall totals */}
|
{/* Overall totals */}
|
||||||
<div className="rounded-md border p-4">
|
<div className="border p-4">
|
||||||
<div className="grid grid-cols-3 gap-4 text-sm">
|
<div className="grid grid-cols-3 gap-4 text-sm">
|
||||||
<div>
|
<div>
|
||||||
<p className="text-muted-foreground">{t("budgets.budgeted")}</p>
|
<p className="text-muted-foreground">{t("budgets.budgeted")}</p>
|
||||||
@@ -494,7 +494,7 @@ export default function BudgetDetailPage() {
|
|||||||
<SelectGroup key={type}>
|
<SelectGroup key={type}>
|
||||||
<SelectLabel className="flex items-center gap-1.5">
|
<SelectLabel className="flex items-center gap-1.5">
|
||||||
<div
|
<div
|
||||||
className="size-2 rounded-full"
|
className="size-2"
|
||||||
style={{ backgroundColor: categoryColors[type] }}
|
style={{ backgroundColor: categoryColors[type] }}
|
||||||
/>
|
/>
|
||||||
{t(`categories.types.${type}`)}
|
{t(`categories.types.${type}`)}
|
||||||
|
|||||||
@@ -240,7 +240,7 @@ export default function BudgetListPage() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Template toggle */}
|
{/* Template toggle */}
|
||||||
<div className="flex items-center gap-3 rounded-md border p-3">
|
<div className="flex items-center gap-3 border p-3">
|
||||||
<input
|
<input
|
||||||
id="use-template"
|
id="use-template"
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
|
|||||||
@@ -95,17 +95,17 @@ export default function CategoriesPage() {
|
|||||||
|
|
||||||
if (loading) return (
|
if (loading) return (
|
||||||
<PageShell title={t("categories.title")}>
|
<PageShell title={t("categories.title")}>
|
||||||
<div className="space-y-6">
|
<div className="space-y-8">
|
||||||
{[1, 2, 3].map((i) => (
|
{[1, 2, 3].map((i) => (
|
||||||
<div key={i} className="space-y-2">
|
<div key={i} className="space-y-2">
|
||||||
<div className="flex items-center gap-3 rounded-sm border-l-4 border-muted bg-muted/30 px-3 py-2">
|
<div className="flex items-center gap-3 border-l-4 border-muted bg-muted/30 px-3 py-2">
|
||||||
<Skeleton className="h-4 w-28" />
|
<Skeleton className="h-4 w-28" />
|
||||||
</div>
|
</div>
|
||||||
{[1, 2].map((j) => (
|
{[1, 2].map((j) => (
|
||||||
<div key={j} className="flex items-center gap-4 px-4 py-2.5 border-b border-border">
|
<div key={j} className="flex items-center gap-4 px-4 py-2.5 border-b border-border">
|
||||||
<Skeleton className="h-4 w-36" />
|
<Skeleton className="h-4 w-36" />
|
||||||
<Skeleton className="h-5 w-16 rounded-full" />
|
<Skeleton className="h-5 w-16" />
|
||||||
<Skeleton className="ml-auto h-7 w-7 rounded-md" />
|
<Skeleton className="ml-auto h-7 w-7" />
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
@@ -127,11 +127,11 @@ export default function CategoriesPage() {
|
|||||||
{categories.length === 0 ? (
|
{categories.length === 0 ? (
|
||||||
<p className="text-muted-foreground">{t("categories.empty")}</p>
|
<p className="text-muted-foreground">{t("categories.empty")}</p>
|
||||||
) : (
|
) : (
|
||||||
<div className="space-y-6">
|
<div className="space-y-8">
|
||||||
{grouped.map(({ type, items }) => (
|
{grouped.map(({ type, items }) => (
|
||||||
<div key={type}>
|
<div key={type}>
|
||||||
<div
|
<div
|
||||||
className="mb-2 flex items-center gap-3 rounded-sm border-l-4 bg-muted/30 px-3 py-2"
|
className="mb-2 flex items-center gap-3 border-l-4 bg-muted/30 px-3 py-2"
|
||||||
style={{ borderLeftColor: categoryColors[type] }}
|
style={{ borderLeftColor: categoryColors[type] }}
|
||||||
>
|
>
|
||||||
<span className="text-sm font-semibold">{t(`categories.types.${type}`)}</span>
|
<span className="text-sm font-semibold">{t(`categories.types.${type}`)}</span>
|
||||||
|
|||||||
@@ -183,7 +183,7 @@ function DashboardContent({ budgetId }: { budgetId: string }) {
|
|||||||
const carryoverIsNegative = carryover < 0
|
const carryoverIsNegative = carryover < 0
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="space-y-6">
|
<div className="space-y-8">
|
||||||
{/* Summary cards */}
|
{/* Summary cards */}
|
||||||
<SummaryStrip
|
<SummaryStrip
|
||||||
income={{
|
income={{
|
||||||
@@ -204,7 +204,7 @@ function DashboardContent({ budgetId }: { budgetId: string }) {
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
{/* 3-column chart grid */}
|
{/* 3-column chart grid */}
|
||||||
<div className="grid gap-6 md:grid-cols-2 lg:grid-cols-3">
|
<div className="grid gap-8 md:grid-cols-2 lg:grid-cols-3">
|
||||||
<Card>
|
<Card>
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle className="text-base">{t("dashboard.expenseDonut")}</CardTitle>
|
<CardTitle className="text-base">{t("dashboard.expenseDonut")}</CardTitle>
|
||||||
|
|||||||
@@ -95,9 +95,9 @@ export default function QuickAddPage() {
|
|||||||
<div className="space-y-1">
|
<div className="space-y-1">
|
||||||
{[1, 2, 3, 4, 5].map((i) => (
|
{[1, 2, 3, 4, 5].map((i) => (
|
||||||
<div key={i} className="flex items-center gap-4 px-4 py-2.5 border-b border-border">
|
<div key={i} className="flex items-center gap-4 px-4 py-2.5 border-b border-border">
|
||||||
<Skeleton className="h-5 w-10 rounded-full" />
|
<Skeleton className="h-5 w-10" />
|
||||||
<Skeleton className="h-4 w-36" />
|
<Skeleton className="h-4 w-36" />
|
||||||
<Skeleton className="ml-auto h-7 w-7 rounded-md" />
|
<Skeleton className="ml-auto h-7 w-7" />
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ export default function SettingsPage() {
|
|||||||
<PageShell title={t("settings.title")}>
|
<PageShell title={t("settings.title")}>
|
||||||
<div className="max-w-lg">
|
<div className="max-w-lg">
|
||||||
<Card>
|
<Card>
|
||||||
<CardContent className="space-y-4 pt-6">
|
<CardContent className="space-y-6 pt-6">
|
||||||
{[1, 2, 3].map((i) => (
|
{[1, 2, 3].map((i) => (
|
||||||
<div key={i} className="space-y-2">
|
<div key={i} className="space-y-2">
|
||||||
<Skeleton className="h-4 w-24" />
|
<Skeleton className="h-4 w-24" />
|
||||||
@@ -84,7 +84,7 @@ export default function SettingsPage() {
|
|||||||
<PageShell title={t("settings.title")}>
|
<PageShell title={t("settings.title")}>
|
||||||
<div className="max-w-lg">
|
<div className="max-w-lg">
|
||||||
<Card>
|
<Card>
|
||||||
<CardContent className="space-y-4 pt-6">
|
<CardContent className="space-y-6 pt-6">
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label>{t("settings.displayName")}</Label>
|
<Label>{t("settings.displayName")}</Label>
|
||||||
<Input
|
<Input
|
||||||
|
|||||||
@@ -239,23 +239,23 @@ export default function TemplatePage() {
|
|||||||
// ------------------------------------------------------------------
|
// ------------------------------------------------------------------
|
||||||
|
|
||||||
if (loading) return (
|
if (loading) return (
|
||||||
<div className="flex flex-col gap-6">
|
<div className="flex flex-col gap-8">
|
||||||
<div className="flex items-start justify-between gap-4">
|
<div className="flex items-start justify-between gap-4">
|
||||||
<Skeleton className="h-8 w-48" />
|
<Skeleton className="h-8 w-48" />
|
||||||
<Skeleton className="h-9 w-24" />
|
<Skeleton className="h-9 w-24" />
|
||||||
</div>
|
</div>
|
||||||
<div className="space-y-6">
|
<div className="space-y-8">
|
||||||
{[1, 2].map((i) => (
|
{[1, 2].map((i) => (
|
||||||
<div key={i} className="space-y-2">
|
<div key={i} className="space-y-2">
|
||||||
<div className="flex items-center gap-3 rounded-sm border-l-4 border-muted bg-muted/30 px-3 py-2">
|
<div className="flex items-center gap-3 border-l-4 border-muted bg-muted/30 px-3 py-2">
|
||||||
<Skeleton className="h-4 w-28" />
|
<Skeleton className="h-4 w-28" />
|
||||||
</div>
|
</div>
|
||||||
{[1, 2, 3].map((j) => (
|
{[1, 2, 3].map((j) => (
|
||||||
<div key={j} className="flex items-center gap-4 px-4 py-2.5 border-b border-border">
|
<div key={j} className="flex items-center gap-4 px-4 py-2.5 border-b border-border">
|
||||||
<Skeleton className="h-4 w-36" />
|
<Skeleton className="h-4 w-36" />
|
||||||
<Skeleton className="h-5 w-16 rounded-full" />
|
<Skeleton className="h-5 w-16" />
|
||||||
<Skeleton className="ml-auto h-4 w-20" />
|
<Skeleton className="ml-auto h-4 w-20" />
|
||||||
<Skeleton className="h-7 w-7 rounded-md" />
|
<Skeleton className="h-7 w-7" />
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
@@ -265,7 +265,7 @@ export default function TemplatePage() {
|
|||||||
)
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col gap-6">
|
<div className="flex flex-col gap-8">
|
||||||
{/* Header — mirrors PageShell's flex items-start justify-between gap-4 layout */}
|
{/* Header — mirrors PageShell's flex items-start justify-between gap-4 layout */}
|
||||||
<div className="flex items-start justify-between gap-4">
|
<div className="flex items-start justify-between gap-4">
|
||||||
<TemplateName
|
<TemplateName
|
||||||
@@ -284,12 +284,12 @@ export default function TemplatePage() {
|
|||||||
{items.length === 0 ? (
|
{items.length === 0 ? (
|
||||||
<p className="text-muted-foreground">{t("template.empty")}</p>
|
<p className="text-muted-foreground">{t("template.empty")}</p>
|
||||||
) : (
|
) : (
|
||||||
<div className="space-y-6">
|
<div className="space-y-8">
|
||||||
{grouped.map(({ type, items: groupItems }) => (
|
{grouped.map(({ type, items: groupItems }) => (
|
||||||
<div key={type}>
|
<div key={type}>
|
||||||
{/* Group heading */}
|
{/* Group heading */}
|
||||||
<div
|
<div
|
||||||
className="mb-2 flex items-center gap-3 rounded-sm border-l-4 bg-muted/30 px-3 py-2"
|
className="mb-2 flex items-center gap-3 border-l-4 bg-muted/30 px-3 py-2"
|
||||||
style={{ borderLeftColor: categoryColors[type] }}
|
style={{ borderLeftColor: categoryColors[type] }}
|
||||||
>
|
>
|
||||||
<span className="text-sm font-semibold">{t(`categories.types.${type}`)}</span>
|
<span className="text-sm font-semibold">{t(`categories.types.${type}`)}</span>
|
||||||
@@ -382,7 +382,7 @@ export default function TemplatePage() {
|
|||||||
<SelectGroup key={type}>
|
<SelectGroup key={type}>
|
||||||
<SelectLabel className="flex items-center gap-1.5">
|
<SelectLabel className="flex items-center gap-1.5">
|
||||||
<div
|
<div
|
||||||
className="size-2 rounded-full"
|
className="size-2"
|
||||||
style={{ backgroundColor: categoryColors[type] }}
|
style={{ backgroundColor: categoryColors[type] }}
|
||||||
/>
|
/>
|
||||||
{t(`categories.types.${type}`)}
|
{t(`categories.types.${type}`)}
|
||||||
|
|||||||
Reference in New Issue
Block a user