AI Wealth Projection & Retirement Planner
Model your financial future and plan your retirement with AI-powered insights.
Step 1: Your Current Financial Snapshot
Step 2: Your Retirement Lifestyle Goals
This will be adjusted for inflation in the projection.
Major Post-Retirement Expenses
Step 3: Model Your Retirement Scenarios
Economic Assumptions
AI Scenario Analysis
Select a scenario to get AI-powered advice and automatically adjust your assumptions.
Your Retirement Projection Results
Retirement Goal
--
Nest Egg at Retirement
$0
Funds Depleted At Age
--
Wealth Projection Timeline
Could not retrieve AI analysis. Please try again.
`; document.getElementById('ai-scenario-response-container').classList.remove('hidden'); } finally { btnText.style.display = 'inline-block'; spinner.style.display = 'none'; btn.disabled = false; } }; // --- PROJECTION LOGIC (TAB 4) --- const runProjection = () => { updateDataFromDOM(); const { finances, goals, assumptions } = plannerData; const { currentAge, retirementAge, currentSavings, monthlyContribution } = finances; const { retirementIncome, expenseEvents } = goals; const { annualReturn, postRetirementReturn, inflationRate } = assumptions; let balance = currentSavings; const projectionData = [{ x: currentAge, y: balance }]; let depletionAge = "Never"; let goalMet = false; for (let age = currentAge + 1; age <= MAX_AGE; age++) { if (age <= retirementAge) { // Accumulation phase balance = (balance + (monthlyContribution * 12)) * (1 + annualReturn); } else { // Distribution phase const inflationFactor = Math.pow(1 + inflationRate, age - currentAge); const inflationAdjustedWithdrawal = retirementIncome * inflationFactor; const eventExpense = expenseEvents.find(e => e.age === age)?.amount || 0; balance -= (inflationAdjustedWithdrawal + eventExpense); balance *= (1 + postRetirementReturn); } projectionData.push({ x: age, y: balance }); if (balance < 0 && depletionAge === "Never") { depletionAge = age; } } goalMet = depletionAge === "Never"; displayResults(projectionData, goalMet, depletionAge); }; const displayResults = (projectionData, goalMet, depletionAge) => { const nestEgg = projectionData.find(p => p.x === plannerData.finances.retirementAge)?.y || 0; document.getElementById('nest-egg-value').textContent = formatCurrency(nestEgg); document.getElementById('depletion-age').textContent = depletionAge; const statusEl = document.getElementById('retirement-goal-status'); const successCard = document.getElementById('success-card'); statusEl.textContent = goalMet ? "On Track" : "Needs Review"; successCard.className = 'p-4 rounded-lg'; // reset successCard.classList.add(goalMet ? 'bg-green-100' : 'bg-red-100'); statusEl.classList.add(goalMet ? 'text-green-800' : 'text-red-800'); // Render Chart const ctx = document.getElementById('projection-chart').getContext('2d'); if (projectionChartInstance) projectionChartInstance.destroy(); projectionChartInstance = new Chart(ctx, { type: 'line', data: { datasets: [{ label: 'Projected Wealth', data: projectionData, borderColor: '#1D4ED8', backgroundColor: 'rgba(29, 78, 216, 0.1)', fill: true, tension: 0.1 }] }, options: { parsing: { xAxisKey: 'x', yAxisKey: 'y' }, plugins: { tooltip: { callbacks: { label: (c) => `${c.dataset.label}: ${formatCurrency(c.raw.y)}` } }, }, scales: { y: { ticks: { callback: (v) => formatCurrency(v) } } } } }); }; // --- PDF DOWNLOAD --- window.downloadPDF = async () => { const btn = document.getElementById('pdf-button-container').querySelector('button'); btn.disabled = true; const { jsPDF } = window.jspdf; const content = document.getElementById('summary-content'); try { const canvas = await html2canvas(content, { scale: 2 }); const imgData = canvas.toDataURL('image/png'); const pdf = new jsPDF({ orientation: 'p', unit: 'mm', format: 'a4' }); const pdfWidth = pdf.internal.pageSize.getWidth(); let imgWidth = pdfWidth - 20; let imgHeight = canvas.height * imgWidth / canvas.width; pdf.addImage(imgData, 'PNG', 10, 10, imgWidth, imgHeight); pdf.save(`Retirement_Plan_${new Date().toISOString().slice(0, 10)}.pdf`); } finally { btn.disabled = false; } }; // --- INITIALIZATION --- const init = () => { addExpenseEventRow(); window.changeTab(0); }; init(); });