- Add Badge import to BillsTracker, VariableExpenses, DebtTracker
- Render outline Badge after category name showing tier (Fixed/Variable/One-off)
- Use i18n keys template.fixed, template.variable, template.oneOff
- Badge is purely informational with variant="outline" for subtle appearance
- Create TemplatePage with add form (category/tier/amount), items table, and empty state
- Add /template route to App.tsx with TemplatePage component
- Add Template nav item to sidebar (between Categories and Settings)
- Add template and nav.template i18n keys for EN and DE
- Fix unused import in useTemplate hook
- Add ItemTier type and TemplateItem/TemplateDetail interfaces to api.ts
- Add item_tier field to BudgetItem interface
- Add template API object with get/updateName/addItem/updateItem/deleteItem/reorder
- Add generate function to budgets API object
- Create useTemplate hook with CRUD operations and reorder logic
- Add /api/template route group: GET, PUT /, POST/PUT/DELETE items, PUT items/reorder
- Add POST /api/budgets/generate before /{id} routes to avoid chi treating 'generate' as an id param
- /items/reorder registered before /items/{itemId} for correct static-before-param routing
- Create 002_templates.sql: item_tier enum, ALTER budget_items, templates and template_items tables with CHECK constraint
- Add ItemTier type with fixed/variable/one_off constants to models.go
- Add ItemTier field to BudgetItem struct
- Add Template, TemplateItem, TemplateDetail structs
- Import useAuth in DashboardPage and derive userLocale with fallback to 'en'
- Pass locale={userLocale} to AvailableBalance and ExpenseBreakdown
- Add useAuth mock to DashboardPage test to avoid i18n initReactI18next import error
- Add locale?: string prop to ExpenseBreakdown and AvailableBalance
- Replace bare <Tooltip /> in ExpenseBreakdown with custom content renderer
- Add Tooltip import and custom content renderer to AvailableBalance
- Pass locale to formatCurrency in AvailableBalance center text
- Tooltip styled with shadcn design tokens (bg-background, border-border/50, shadow-xl)
- Test English default locale uses comma grouping (1,234.56)
- Test explicit 'en' locale formatting
- Test 'de' locale uses period grouping and comma decimal (1.234,56)
- Test USD with dollar sign
- Test zero and negative amounts
- Test empty string locale fallback (no RangeError)
- Test default arg does NOT produce German formatting
- Add flashRowId/errorRowId state and triggerFlash helper to BillsTracker, VariableExpenses, DebtTracker
- Apply inline color-mix style to data rows for green/red 600ms flash on save success/error
- Wire onSaveSuccess/onSaveError callbacks to InlineEditCell in all three components
- Add tinted skeleton placeholder (palette.*.light) when no items exist for the section
- Create 03-02-SUMMARY.md documenting EmptyState component and delete confirmation dialog
- Update STATE.md with progress (88%), decisions, and session info
- Update ROADMAP.md with Phase 3 plan progress (3/4 summaries)
- Create shared EmptyState component with icon, heading, subtext, and optional CTA button
- DashboardPage: show EmptyState when no budgets exist with Create CTA; replace plain Card fallback with EmptyState for no-current-budget case
- CategoriesPage: add loading state to prevent empty-state flash on initial load; show EmptyState when no categories exist
- BudgetSetup.test.tsx: smoke test + 2 it.skip for IXTN-01 spinner/disable
- CategoriesPage.test.tsx: smoke test + 4 it.skip for IXTN-05 and STATE-02
- DashboardPage.test.tsx: smoke test + 2 it.skip for STATE-01 and STATE-03
- BillsTracker.test.tsx: smoke test + 3 it.skip for STATE-03 and IXTN-03
- Add Pencil icon in display mode (opacity-0, group-hover:opacity-100)
- Add onSaveSuccess optional callback fired after successful save
- Add onSaveError optional callback fired + value reverted on save failure
- Wrap onSave in try/catch in handleBlur