Generated by /plan-eng-review on 2026-03-22. Prioritized by impact.
What: Move the 130-calculator metadata array from index.astro into a shared TypeScript module. Why: index.astro is 80KB / 2064 lines with hardcoded data. No single source of truth. Every new calculator requires editing this massive file. Effort: human: ~2 days / CC: ~20 min Depends on: Nothing
What: Extract the repeated setup pattern (tracking, localStorage, memoized results, updateInput) into useCalculatorBase<TInputs, TResults>. Migrate all 130 components.
Why: ~40 lines of identical boilerplate per calculator. 5,200+ duplicated lines total. Pattern changes require editing 130 files.
Effort: human: ~1 week / CC: ~45 min
Depends on: Nothing (pairs well with TODO-1)
What: (a) Scan all 113 test files for toBeDefined()-only assertions, replace with real value checks. (b) Add tests for useLocalStorage, useDebounce, useCalculatorTracking hooks.
Why: Stub tests (e.g., mortgage: 3/5 TODO placeholders) create false confidence. Hooks are shared infrastructure with zero coverage.
Effort: human: ~2 days / CC: ~30 min
Depends on: Nothing
What: Install Playwright, write 10-15 smoke tests: homepage loads, calculator renders, mobile menu, View Transitions, keyboard shortcuts, share URLs. Why: Zero E2E tests. Can't catch hydration failures, layout shifts, mobile UX bugs, or ViewTransition state loss (documented in LEARNINGS.md). Effort: human: ~2 days / CC: ~30 min Depends on: Nothing
What: Merge NumberInput.tsx into Input.tsx as a 'number' variant. Remove NumberInput. Update all imports. Why: Two components with overlapping functionality (numeric input + spin controls). Creates confusion and duplicates logic. Effort: human: ~4h / CC: ~20 min Depends on: Nothing
What: Change defaultStrategy: 'viewport' to 'hover' in astro.config.mjs (line 68).
Why: 130+ calculator links on homepage fire 130+ prefetch requests on scroll. Wastes mobile bandwidth, competes with ad loading.
Effort: human: ~10 min / CC: ~1 min
Depends on: Nothing
What: Add a build-time check that validates calculatorConfigs.ts entries match actual calculator types.ts exports. Catch field name mismatches at build, not runtime.
Why: Manual registry with no validation. Wrong field names silently fail, breaking cross-calculator data sharing.
Effort: human: ~2h / CC: ~10 min
Depends on: Nothing
What: Start dev server, run gstack /qa skill for automated browser QA across homepage, top calculators, mobile menu, ads, and View Transitions.
Why: No automated visual/interaction testing has been performed. E2E suite (TODO-5) covers regression; this is a one-time audit for existing bugs.
Effort: human: ~2h / CC: ~30 min
Depends on: Nothing
What: Run gstack /design-review skill against live site. Checks spacing, hierarchy, mobile responsiveness, dark theme consistency, ad layout shifts, and accessibility.
Why: Revenue-generating site with ads. Visual regressions or inconsistent spacing hurt trust and click-through.
Effort: human: ~2h / CC: ~30 min
Depends on: Nothing
What: Run gstack /codex for an adversarial second opinion from OpenAI Codex CLI. Cross-model review catches blind spots.
Why: Single-model reviews have systematic blind spots. Codex challenge mode tries to break the code.
Effort: human: ~30 min / CC: ~15 min
Depends on: Nothing
What: Refactor the 270-line hook to separate shortcut registration logic from imperative DOM-based overlay/toast UI. Move UI to a KeyboardShortcutHelp.astro component. Why: Hook creates HTML elements via document.createElement inside a Preact component, bypassing virtual DOM. IDs can clash, cleanup isn't guaranteed, styling via inline strings. Effort: human: ~4h / CC: ~15 min Depends on: Nothing
What: Delete unused delay utilities and --gradient-mesh property (~20 lines).