Apply the tier gating to routes and navigation on top of the #298 UI
guard:
- App.tsx: pathless RequireFeature layout-routes grouping /balance,
/balance/accounts, /balance/snapshot under "balance"; /reports/
highlights|compare|category|cartes under "reports-advanced"; /budget
under "budget"; /adjustments under "adjustments". The /reports hub and
/reports/trends stay Free and ungated.
- NavItem gains an optional `feature?: FeatureKey`; set in NAV_ITEMS on
budget, adjustments and balance only — NOT on reports (Free hub).
- Sidebar: local NavLock child component (hook at component top level)
renders a lock badge only when the license is ready AND the feature is
not allowed — no locked flash at boot; items stay clickable and lead
to the upsell via the gated route. Tooltip/aria reuse nav.locked.
- ReportsPage hub: single useEntitlement("reports-advanced") call
drives a `locked` badge on the 4 advanced tiles via a new additive
HubReportNavCard `locked?` prop; the Trends tile is never locked.
- Pure contract test on NAV_ITEMS (gated trio present, reports/Free
items ungated, exactly 3 of 9 gated).
No new i18n strings (nav.locked shipped with #298), no DB migration.
Changelog centralized in #302.
Resolves#299
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>