Files
SimpleFinanceDash/.planning/phases/03-collapsible-dashboard-sections/03-CONTEXT.md
2026-04-02 14:29:36 +02:00

5.8 KiB

Phase 3: Collapsible Dashboard Sections - Context

Gathered: 2026-03-16 Status: Ready for planning

## Phase Boundary

Complete the dashboard hybrid view with collapsible per-category sections that show individual line items, group totals, and variance indicators. Add carryover amount display to the balance card. Sections sit below the chart grid and above QuickAdd. This phase does not add editing capabilities or navigation links — the dashboard remains a read-only summary.

## Implementation Decisions

Section header design

  • Badge-style chips for totals: two small colored badges showing [Budget $X] and [Actual $X] right-aligned in the header row
  • Left border accent using the category's CSS variable color (thick colored left border on the header row)
  • Difference shown in header with color coding: green (--color-on-budget) when under/on budget, red (--color-over-budget) when over budget
  • Chevron-right icon that rotates to chevron-down when expanded (standard Radix Collapsible pattern)
  • Group label (from categoryLabels in palette.ts) on the left, badges and difference on the right

Line-item table columns

  • Four columns: Item Name, Budgeted, Actual, Difference
  • No tier badge — keep it clean for the dashboard summary view
  • No notes column — full detail lives on BudgetDetailPage
  • Difference column uses red text when over budget (--color-over-budget), no full-row tint
  • Footer row with bold group totals summing Budget, Actual, and Diff columns
  • Read-only — no clickable rows, no navigation links to BudgetDetailPage

Default expand/collapse behavior

  • Smart default: over-budget sections auto-expand on load, on/under-budget sections start collapsed
  • Over-budget logic is direction-aware:
    • Spending categories (bill, variable_expense, debt): actual > budget = over budget (expand)
    • Income category: actual < budget = under-earned (expand)
    • Savings/investment categories: actual < budget = under-saved (expand)
  • Empty category groups (no items of that type) are hidden entirely — only show sections with at least one budget item
  • Expand/collapse state resets on month navigation — smart defaults recalculate per month

Carryover display

  • Subtitle line below balance amount on the balance StatCard: "Includes $X carryover" when non-zero
  • Carryover is included in the balance calculation: Balance = Income Actual - Expenses Actual + Carryover
  • When carryover is zero, the subtitle line is hidden entirely (clean card for the common case)
  • Negative carryover is supported: shown with red styling (e.g., "Includes -$150 carryover"), deducts from balance

Claude's Discretion

  • Smooth collapse/expand CSS animation details (timing, easing)
  • Preventing ResizeObserver loop errors when toggling rapidly (success criteria #3)
  • Preventing chart resize jank when sections toggle (success criteria #3)
  • Exact spacing between section headers and between sections and the chart grid above
  • Table cell alignment and typography within line items
  • DashboardSkeleton updates for the collapsible sections area
  • How to derive and memoize per-group data from budget items
## Specific Ideas

No specific references — open to standard approaches within the established design system.

<code_context>

Existing Code Insights

Reusable Assets

  • collapsible.tsx (ui/): Radix Collapsible primitive already installed — Collapsible, CollapsibleTrigger, CollapsibleContent exports ready to use
  • categoryColors (palette.ts): CSS variable map for all 6 category types — use for left border accent colors
  • categoryLabels (palette.ts): English/German labels for all 6 types — use for section header labels
  • Table/TableBody/TableCell/TableFooter/TableHead/TableHeader/TableRow (ui/table.tsx): Full table primitive set for line items
  • Badge (ui/badge.tsx): Use for budget/actual chips in section headers
  • StatCard (components/dashboard/StatCard.tsx): Balance card that needs carryover subtitle
  • SummaryStrip (components/dashboard/SummaryStrip.tsx): Orchestrates StatCards — may need carryover prop threading
  • formatCurrency (lib/format.ts): Currency formatting for all monetary values
  • ChevronRight/ChevronDown from lucide-react: Expand/collapse icons

Established Patterns

  • Two-tier OKLCH color pattern: text at ~0.55 lightness, chart fills at ~0.65-0.70 (Phase 1) — section border accents should use fill-tier lightness
  • Semantic status tokens: --color-over-budget (red) and --color-on-budget (green) for difference indicators (Phase 1)
  • Components accept t() as prop to stay presentational (Phase 1) — new section components should follow this
  • useMemo hooks declared before early returns for Rules of Hooks compliance (Phase 2)
  • EXPENSE_TYPES / CATEGORY_TYPES constants already define category ordering — reuse for section order
  • DashboardContent pattern: inner component receives budget data, derives per-type totals (Phase 2)

Integration Points

  • DashboardContent (DashboardPage.tsx): Currently renders SummaryStrip → chart grid → QuickAdd. Collapsible sections insert between chart grid and QuickAdd.
  • useBudgetDetail(id): Returns { budget, items } where items have category joins — items need grouping by category.type for sections
  • Budget.carryover_amount: Field already exists on the Budget type — needs to flow from DashboardContent → SummaryStrip → StatCard
  • useMonthParam: Month navigation resets expand/collapse state — state should be local React state (useState), not URL params
  • i18n: New keys needed for section headers, table column labels, carryover subtitle, and empty states

</code_context>

## Deferred Ideas

None — discussion stayed within phase scope.


Phase: 03-collapsible-dashboard-sections Context gathered: 2026-03-16