- Extract shared TOOLTIP_STYLE and ACTIVE_DOT to utils/chartTheme.ts so
all four chart files use one source of truth
- itemStyle now uses card-foreground (not muted-foreground) — guarantees
tooltip text is readable on all themes including Terminal, Vault, Synthwave
- cursor now uses primary at 12% opacity — always visible and thematic,
replaces near-invisible muted-foreground at 8% opacity
- activeDot is now explicit on every Line/Area — prevents Recharts default
white dot breaking dark themes
- Terminal: muted-foreground bumped 38%→55% lightness, border lightened,
warning brightened, text-shadow scoped to headings/labels/table cells
(was applying to every p and span, causing tooltip glow bleed)
- Synthwave: muted-foreground bumped 56%→68% lightness for legibility
- Vault: muted-foreground bumped 52%→60% lightness
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Recurring service: auto-detects direct debits/subscriptions from CSV imports
using frequency analysis; manual toggle in transaction detail drawer
- Subscriptions page (/subscriptions): groups recurring payments with monthly
cost equivalents, next-payment badges, and re-scan trigger
- UK Tax page (/tax): payslips/P60 entry, income tax + NI + CGT + dividend tax
calculations, configurable rate tables per tax year (pre-seeded 2024/25 and
2025/26), editable in-app so Budget changes need no rebuild
- Migration 0006: tax_rate_configs, tax_profiles, payslips, manual_cgt_disposals
with RLS; seeds 2025/2026 rate configs for existing users
- Chart tooltip fix: all Recharts tooltips now use TOOLTIP_STYLE constant so
they render correctly across all dark/light themes
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add four portfolio charts: allocation donut by holding, allocation
donut by asset type, cost basis vs current value bar, return % bar
- Fix asset search to use yf.Search() full-text instead of ticker-only
lookup — name searches like "vanguard ftse all world" now work
- Fix holding creation double-quantity bug: holdings now created with
quantity=0 so buy transaction is sole source of quantity/cost basis
- Add per-share / total price toggle in Add Holding modal with live
calculated equivalent shown as you type
- Add ErrorBoundary in AppShell so render errors show a message instead
of a blank page
- Fix donut charts using || instead of ?? when falling back from
current_value to cost_basis_total (0 was not falling through ??)
- Allow HoldingCreate.quantity >= 0 (was gt=0) to support zero-init
- Fix error display for Pydantic v2 array-of-objects validation errors
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>