117 lines
6.1 KiB
HTML
117 lines
6.1 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<!-- retire-planner v1 -->
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||
<meta name="theme-color" content="#f7f9fc">
|
||
<title>Retire Planner — Canadian retirement, modelled properly</title>
|
||
<meta name="description" data-i18n-attr="content:doc.desc" content="A Canadian retirement calculator with real CPP/OAS/GIS/RRIF mechanics and live 2026 tax rates. 100% client-side — answers never leave your browser.">
|
||
<link rel="stylesheet" href="style.css">
|
||
</head>
|
||
<body>
|
||
<header class="hdr">
|
||
<div class="hdr-in">
|
||
<span class="logo">🍁 <b data-i18n="brand">Retire Planner</b></span>
|
||
<span class="lang-toggle" role="group" aria-label="Language / Langue">
|
||
<button id="lang-en" class="lang-btn" aria-pressed="true">EN</button><button id="lang-fr" class="lang-btn" aria-pressed="false">FR</button>
|
||
</span>
|
||
<span class="pill" data-i18n="hdr.pill" data-i18n-attr="title:hdr.pillTitle" title="No server, no tracking, no accounts">🔒 100% client-side — answers never leave your browser</span>
|
||
<button id="btn-restart" class="ghost" data-i18n="hdr.startOver" hidden>Start over</button>
|
||
</div>
|
||
</header>
|
||
|
||
<main>
|
||
<!-- INTRO -->
|
||
<section id="scr-intro" class="scr">
|
||
<h1 data-i18n="intro.h1">Will you actually run out of money?</h1>
|
||
<p class="lede" data-i18n-html="intro.lede">Most Canadian retirement calculators stop at “your RRSP grows at 6%”. This one models <b>real CPP/OAS/GIS/RRIF mechanics</b>, provincial taxes fetched live, and the tax cliff most planners won't show you.</p>
|
||
<ul class="ticks">
|
||
<li data-i18n="intro.tick1">CPP early/late (−0.6%/mo before 65, +0.7% after), OAS deferral, clawback & GIS</li>
|
||
<li data-i18n="intro.tick2">Live 2026 federal + all 13 province/territory tax tables</li>
|
||
<li data-i18n="intro.tick3">RRIF minimums at 71, pension splitting, tax-smart drawdown</li>
|
||
<li data-i18n="intro.tick4">Couples: joint taxes, split pensions, household GIS</li>
|
||
</ul>
|
||
<p class="privacy" data-i18n="intro.privacy">🔒 100% client-side — answers never leave your browser. No account, no tracking, nothing is sent anywhere.</p>
|
||
<button id="btn-begin" class="cta" data-i18n="intro.cta">Build my retirement plan →</button>
|
||
<p class="fine" data-i18n="intro.fine">~2 minutes. Works on one screen at a time; you can change anything later.</p>
|
||
</section>
|
||
|
||
<!-- QUESTIONNAIRE -->
|
||
<section id="scr-quiz" class="scr" hidden>
|
||
<div class="quiz-wrap">
|
||
<div class="quiz-main">
|
||
<div class="prog"><div id="prog-bar"></div></div>
|
||
<div class="step-nav">
|
||
<button id="btn-back" class="ghost" data-i18n="quiz.back">← Back</button>
|
||
<span id="step-count" class="step-count"></span>
|
||
</div>
|
||
<div id="step-body"></div>
|
||
<button id="btn-next" class="cta" data-i18n="quiz.next">Next →</button>
|
||
</div>
|
||
<aside class="panel" id="panel">
|
||
<div class="panel-h" data-i18n="panel.title">Your plan so far</div>
|
||
<div id="panel-chips" class="chips"></div>
|
||
<div id="panel-insight" class="insight"></div>
|
||
</aside>
|
||
</div>
|
||
</section>
|
||
|
||
<div id="scrim" hidden></div>
|
||
|
||
<!-- RESULTS -->
|
||
<section id="scr-results" class="scr" hidden>
|
||
<div id="vision-card" class="vision"></div>
|
||
<h2 id="verdict-h" data-i18n="r.verdictH">Your plan, in one line</h2>
|
||
<p id="verdict" class="verdict"></p>
|
||
|
||
<div class="cards" id="gap-cards"></div>
|
||
|
||
<!-- Chart titles/captions render inside each card's .chart-h via app.js chart() (round 2 Fix 2) -->
|
||
<div id="g1" class="chartbox"></div>
|
||
<div id="g2" class="chartbox"></div>
|
||
<div id="ps-card" class="chartbox" hidden></div>
|
||
<div id="g3" class="chartbox"></div>
|
||
<div id="g4" class="chartbox"></div>
|
||
<p id="g4-note" class="cap"></p>
|
||
|
||
<details class="whatif" id="whatif">
|
||
<summary data-i18n-html="r.whatif"><b>Try a what-if</b> — move a slider, watch the plan update</summary>
|
||
<div class="wi-grid">
|
||
<label><span data-i18n="r.wiSpend">Annual spending</span> <output id="wi-spend-o"></output>
|
||
<input type="range" id="wi-spend" min="20000" max="150000" step="1000"></label>
|
||
<label><span data-i18n="r.wiCtrb">Monthly savings</span> <output id="wi-ctrb-o"></output>
|
||
<input type="range" id="wi-ctrb" min="0" max="5000" step="50"></label>
|
||
<label><span data-i18n="r.wiRet">Retirement age</span> <output id="wi-ret-o"></output>
|
||
<input type="range" id="wi-ret" min="55" max="72" step="1"></label>
|
||
<label><span data-i18n="r.wiCpp">CPP starts at</span> <output id="wi-cpp-o"></output>
|
||
<input type="range" id="wi-cpp" min="60" max="70" step="1"></label>
|
||
</div>
|
||
</details>
|
||
|
||
<details class="yearly">
|
||
<summary id="yr-summary">Year-by-year detail (<span id="yr-n">0</span> years)</summary>
|
||
<div class="tbl-wrap"><table id="yr-table"></table></div>
|
||
</details>
|
||
|
||
<div class="disclaimer">
|
||
<p data-i18n-html="d.main"><b>Estimates only — not financial advice.</b> Simplified model: GIS uses a simplified 50% phase-out; Quebec shown with the 16.5% federal abatement (QPP and Quebec payroll taxes not modelled); federal public service pension (PSSA) modelled when enabled — other DB pensions not; returns are constant real rates; Ontario surtax modelled on base tax.</p>
|
||
<p class="stamp" id="stamp">tax rates 2026</p>
|
||
<p class="privacy" data-i18n="d.privacy">🔒 100% client-side — answers never leave your browser. Your answers are saved only in this browser (localStorage).</p>
|
||
<div class="btn-row">
|
||
<button id="btn-print" class="ghost" data-i18n="res.print">🖨 Print / save PDF</button>
|
||
<button id="btn-share" class="ghost" data-i18n="res.share">🔗 Copy link with my answers</button>
|
||
<button id="btn-edit" class="ghost" data-i18n="res.edit">✎ Edit answers</button>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
</main>
|
||
|
||
<script src="engine/canada.js"></script>
|
||
<script src="engine/engine.js"></script>
|
||
<script src="engine/pspension.js"></script>
|
||
<script src="i18n.js"></script>
|
||
<script src="app.js"></script>
|
||
</body>
|
||
</html>
|