<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Cost of Capital Calculator | Canadian Private Companies</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.4.1/chart.umd.min.js"></script>
<style>
, ::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
:root {
--navy: #1a2e4a;
--navy-light: #243d61;
--blue: #2563eb;
--blue-light: #3b82f6;
--teal: #0d9488;
--teal-light: #14b8a6;
--amber: #d97706;
--red: #dc2626;
--gray-50: #f8fafc;
--gray-100: #f1f5f9;
--gray-200: #e2e8f0;
--gray-300: #cbd5e1;
--gray-500: #64748b;
--gray-700: #334155;
--gray-900: #0f172a;
--white: #ffffff;
--radius: 10px;
--shadow: 0 4px 16px rgba(0,0,0,0.10);
--shadow-sm: 0 2px 6px rgba(0,0,0,0.07);
}
body {
font-family: 'Segoe UI', system-ui, -apple-system, sans-serif;
background: var(--gray-50);
color: var(--gray-900);
min-height: 100vh;
line-height: 1.5;
}
/* Header */
.header {
background: linear-gradient(135deg, var(--navy) 0%, var(--navy-light) 100%);
color: var(--white);
padding: 36px 40px 32px;
border-bottom: 3px solid var(--blue);
}
.header-inner { max-width: 1100px; margin: 0 auto; }
.header h1 { font-size: 1.75rem; font-weight: 700; letter-spacing: -0.02em; margin-bottom: 6px; }
.header p { color: #94b4d8; font-size: 0.95rem; max-width: 600px; }
/* Layout */
.main { max-width: 1100px; margin: 0 auto; padding: 32px 20px 60px; }
.layout {
display: grid;
grid-template-columns: 1fr 420px;
gap: 28px;
align-items: start;
}
@media (max-width: 900px) {
.layout { grid-template-columns: 1fr; }
}
/* Cards */
.card {
background: var(--white);
border-radius: var(--radius);
box-shadow: var(--shadow-sm);
border: 1px solid var(--gray-200);
overflow: hidden;
}
.card-header {
padding: 18px 24px 14px;
border-bottom: 1px solid var(--gray-100);
display: flex;
align-items: center;
gap: 10px;
}
.card-header .icon {
width: 32px; height: 32px;
border-radius: 8px;
display: flex; align-items: center; justify-content: center;
font-size: 1rem;
flex-shrink: 0;
}
.icon-debt { background: #dbeafe; }
.icon-equity { background: #d1fae5; }
.icon-company { background: #fef3c7; }
.icon-results { background: #ede9fe; }
.card-header h2 { font-size: 1rem; font-weight: 600; color: var(--gray-900); }
.card-header span.subtitle { font-size: 0.8rem; color: var(--gray-500); margin-top: 1px; display: block; }
.card-body { padding: 20px 24px; }
/* Form elements */
.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.form-group { display: flex; flex-direction: column; gap: 5px; }
.form-group.full { grid-column: 1 / -1; }
label {
font-size: 0.8rem;
font-weight: 600;
color: var(--gray-700);
display: flex;
align-items: center;
gap: 5px;
}
.tooltip-icon {
display: inline-flex;
align-items: center;
justify-content: center;
width: 16px; height: 16px;
background: var(--gray-200);
border-radius: 50%;
font-size: 0.65rem;
font-weight: 700;
color: var(--gray-500);
cursor: default;
position: relative;
}
.tooltip-icon:hover::after {
content: attr(data-tip);
position: absolute;
left: 50%;
bottom: calc(100% + 8px);
transform: translateX(-50%);
background: var(--gray-900);
color: #fff;
font-size: 0.75rem;
font-weight: 400;
padding: 7px 11px;
border-radius: 6px;
white-space: normal;
width: 220px;
line-height: 1.4;
z-index: 999;
box-shadow: 0 4px 12px rgba(0,0,0,0.2);
pointer-events: none;
}
input[type="number"], select {
height: 40px;
border: 1.5px solid var(--gray-200);
border-radius: 7px;
padding: 0 12px;
font-size: 0.9rem;
color: var(--gray-900);
background: var(--white);
transition: border-color 0.15s;
width: 100%;
outline: none;
}
input[type="number"]:focus, select:focus {
border-color: var(--blue);
box-shadow: 0 0 0 3px rgba(37,99,235,0.1);
}
.input-with-unit {
position: relative;
}
.input-with-unit input {
padding-right: 36px;
}
.input-unit {
position: absolute;
right: 12px;
top: 50%;
transform: translateY(-50%);
font-size: 0.85rem;
color: var(--gray-500);
pointer-events: none;
font-weight: 500;
}
.computed-field {
height: 40px;
border: 1.5px solid var(--gray-200);
border-radius: 7px;
padding: 0 12px;
font-size: 0.9rem;
color: var(--gray-500);
background: var(--gray-50);
display: flex;
align-items: center;
font-weight: 600;
}
.computed-field.highlight {
background: #eff6ff;
border-color: #bfdbfe;
color: var(--blue);
}
/* Slider */
.slider-group { margin-top: 4px; }
.slider-labels {
display: flex;
justify-content: space-between;
font-size: 0.72rem;
color: var(--gray-500);
margin-bottom: 5px;
}
input[type="range"] {
width: 100%;
height: 5px;
-webkit-appearance: none;
appearance: none;
background: var(--gray-200);
border-radius: 4px;
outline: none;
cursor: pointer;
}
input[type="range"]::-webkit-slider-thumb {
-webkit-appearance: none;
width: 18px; height: 18px;
border-radius: 50%;
background: var(--blue);
cursor: pointer;
border: 2px solid #fff;
box-shadow: 0 1px 4px rgba(0,0,0,0.2);
}
.slider-value-display {
text-align: center;
font-size: 0.8rem;
color: var(--gray-700);
margin-top: 6px;
font-weight: 600;
}
/* Section divider */
.section-note {
font-size: 0.78rem;
color: var(--gray-500);
background: var(--gray-50);
border: 1px solid var(--gray-200);
border-radius: 7px;
padding: 10px 14px;
margin-bottom: 16px;
line-height: 1.5;
}
.section-note strong { color: var(--gray-700); }
/* Results panel */
.results-panel { position: sticky; top: 20px; }
.result-number {
font-size: 2.4rem;
font-weight: 800;
line-height: 1;
margin: 4px 0 2px;
letter-spacing: -0.03em;
}
.result-label {
font-size: 0.75rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.05em;
color: var(--gray-500);
}
.result-sublabel {
font-size: 0.8rem;
color: var(--gray-500);
margin-top: 3px;
}
.results-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 12px;
margin-bottom: 20px;
}
.result-box {
border-radius: 9px;
padding: 16px 18px;
border: 1.5px solid transparent;
}
.result-box-debt {
background: #eff6ff;
border-color: #bfdbfe;
}
.result-box-debt .result-number { color: var(--blue); }
.result-box-equity {
background: #f0fdf4;
border-color: #bbf7d0;
}
.result-box-equity .result-number { color: var(--teal); }
.insight-box {
background: linear-gradient(135deg, #1e3a5f 0%, #1a2e4a 100%);
border-radius: 9px;
padding: 18px 20px;
color: var(--white);
margin-bottom: 20px;
}
.insight-box .insight-headline {
font-size: 1.05rem;
font-weight: 700;
margin-bottom: 6px;
line-height: 1.3;
}
.insight-box .insight-body {
font-size: 0.82rem;
color: #94b4d8;
line-height: 1.5;
}
.chart-container {
position: relative;
height: 180px;
margin-bottom: 20px;
}
/* Build-up breakdown */
.breakdown-table {
width: 100%;
font-size: 0.82rem;
border-collapse: collapse;
}
.breakdown-table td {
padding: 6px 4px;
border-bottom: 1px solid var(--gray-100);
}
.breakdown-table td:last-child { text-align: right; font-weight: 600; color: var(--gray-700); }
.breakdown-table .total-row td {
border-top: 2px solid var(--gray-200);
border-bottom: none;
font-weight: 700;
font-size: 0.88rem;
color: var(--teal);
padding-top: 10px;
}
.breakdown-table .component-name { color: var(--gray-600); }
.dot {
display: inline-block;
width: 8px; height: 8px;
border-radius: 50%;
margin-right: 7px;
vertical-align: middle;
}
.disclaimer {
font-size: 0.72rem;
color: var(--gray-500);
line-height: 1.5;
margin-top: 16px;
padding-top: 14px;
border-top: 1px solid var(--gray-200);
}
/* Tabs for advanced mode */
.toggle-advanced {
font-size: 0.78rem;
color: var(--blue);
background: none;
border: none;
cursor: pointer;
padding: 8px 0 2px;
font-weight: 600;
display: flex;
align-items: center;
gap: 4px;
}
.toggle-advanced:hover { color: var(--navy); }
.advanced-section { margin-top: 14px; }
.divider { height: 1px; background: var(--gray-100); margin: 18px 0; }
@media (max-width: 600px) {
.header { padding: 24px 20px; }
.header h1 { font-size: 1.35rem; }
.form-grid { grid-template-columns: 1fr; }
.results-grid { grid-template-columns: 1fr; }
.result-number { font-size: 2rem; }
.lc-grid { grid-template-columns: 1fr; }
.lc-metrics-grid { grid-template-columns: 1fr; }
}
/* ── Lifetime Cost Analysis ── */
.lifetime-section { margin-top: 28px; }
.lc-grid {
display: grid;
grid-template-columns: 400px 1fr;
gap: 28px;
align-items: start;
}
.lc-metrics-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 10px;
margin-top: 18px;
}
.lc-metric {
border-radius: 8px;
padding: 13px 15px;
border: 1.5px solid var(--gray-200);
background: var(--gray-50);
}
.lc-metric.lc-debt { background: #eff6ff; border-color: #bfdbfe; }
.lc-metric.lc-equity { background: #f0fdf4; border-color: #bbf7d0; }
.lc-metric.lc-amber { background: #fffbeb; border-color: #fde68a; }
.lc-metric-label {
font-size: 0.7rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.05em;
color: var(--gray-500);
margin-bottom: 3px;
}
.lc-metric-value {
font-size: 1.3rem;
font-weight: 800;
letter-spacing: -0.02em;
line-height: 1.1;
}
.lc-metric.lc-debt .lc-metric-value { color: var(--blue); }
.lc-metric.lc-equity .lc-metric-value { color: var(--teal); }
.lc-metric.lc-amber .lc-metric-value { color: var(--amber); }
.lc-metric-sub { font-size: 0.73rem; color: var(--gray-500); margin-top: 2px; }
.lc-chart-container { position: relative; height: 280px; margin-bottom: 18px; }
.lc-insight {
background: linear-gradient(135deg, #1e3a5f 0%, #1a2e4a 100%);
border-radius: 9px;
padding: 18px 20px;
color: var(--white);
}
.lc-insight-headline { font-size: 1rem; font-weight: 700; margin-bottom: 6px; line-height: 1.3; }
.lc-insight-body { font-size: 0.81rem; color: #94b4d8; line-height: 1.55; }
</style>
</head>
<body>
<div class="header">
<div class="header-inner">
<h1>Cost of Capital Calculator</h1>
<p>Compare the true after-tax cost of debt against the cost of equity for Canadian private companies — and understand why debt is often less expensive than it appears.</p>
</div>
</div>
<div class="main">
<div class="layout">
<!-- LEFT: Inputs -->
<div class="inputs-column">
<!-- Company Profile -->
<div class="card" style="margin-bottom: 20px;">
<div class="card-header">
<div class="icon icon-company">🏢</div>
<div>
<h2>Company Profile</h2>
<span class="subtitle">Used to calibrate size premium & tax rate</span>
</div>
</div>
<div class="card-body">
<div class="form-grid">
<div class="form-group">
<label>Province / Territory
<span class="tooltip-icon" data-tip="Determines your combined federal + provincial corporate tax rate, which affects the after-tax cost of debt.">?</span>
</label>
<select id="province" onchange="onProvinceChange()">
<option value="AB">Alberta</option>
<option value="BC">British Columbia</option>
<option value="MB">Manitoba</option>
<option value="NB">New Brunswick</option>
<option value="NL">Newfoundland & Labrador</option>
<option value="NS">Nova Scotia</option>
<option value="ON" selected>Ontario</option>
<option value="PE">Prince Edward Island</option>
<option value="QC">Québec</option>
<option value="SK">Saskatchewan</option>
</select>
</div>
<div class="form-group">
<label>Company Type
<span class="tooltip-icon" data-tip="CCPCs (Canadian Controlled Private Corporations) qualify for the Small Business Deduction on the first $500K of active business income, resulting in a much lower tax rate.">?</span>
</label>
<select id="companyType" onchange="onCompanyTypeChange()">
<option value="sbd">CCPC — Small Business</option>
<option value="general">CCPC — General Rate</option>
<option value="other">Non-CCPC</option>
</select>
</div>
<div class="form-group">
<label>Annual Revenue (CAD)
<span class="tooltip-icon" data-tip="Revenue range determines the size premium. Smaller companies carry more risk and require higher returns from equity investors.">?</span>
</label>
<select id="revenueRange" onchange="calculate()">
<option value="grp1" selected>$3M – $10M</option>
<option value="grp2">$11M – $25M</option>
<option value="grp3">$26M – $50M</option>
</select>
</div>
<div class="form-group">
<label>Industry
<span class="tooltip-icon" data-tip="Different industries carry different systematic risk, which adjusts the equity cost up or down from the base market premium.">?</span>
</label>
<select id="industry" onchange="calculate()">
<optgroup label="Primary & Resources">
<option value="agriculture">Agriculture / Agribusiness</option>
<option value="mining">Mining & Extraction</option>
<option value="oilgas">Oil & Gas (Midstream/Services)</option>
<option value="forestry">Forestry & Lumber</option>
</optgroup>
<optgroup label="Industrial">
<option value="manufacturing">Manufacturing — General</option>
<option value="mfg_food">Manufacturing — Food & Beverage</option>
<option value="mfg_auto">Manufacturing — Auto Parts</option>
<option value="construction">Construction & Contracting</option>
<option value="engineering">Engineering & Trades</option>
<option value="transport">Transportation & Logistics</option>
<option value="warehousing">Warehousing & Storage</option>
</optgroup>
<optgroup label="Trade & Consumer">
<option value="wholesale">Wholesale / Distribution</option>
<option value="retail">Retail — General</option>
<option value="retail_auto">Retail — Auto Dealership</option>
<option value="food_service">Food Service & Restaurants</option>
<option value="hospitality">Hospitality & Accommodation</option>
</optgroup>
<optgroup label="Services">
<option value="professional">Professional Services (Legal, Accounting)</option>
<option value="consulting">Consulting & Advisory</option>
<option value="marketing">Marketing & Media</option>
<option value="staffing">Staffing & Recruitment</option>
<option value="facilities">Facilities & Property Services</option>
<option value="security">Security & Investigation</option>
</optgroup>
<optgroup label="Technology">
<option value="tech_software">Technology — Software / SaaS</option>
<option value="tech_it">Technology — IT Services / MSP</option>
<option value="tech_hardware">Technology — Hardware</option>
</optgroup>
<optgroup label="Healthcare & Education">
<option value="healthcare">Healthcare — Clinical / Dental</option>
<option value="homecare">Healthcare — Home Care</option>
<option value="pharma">Pharmaceutical / Life Sciences</option>
<option value="education">Education & Training</option>
</optgroup>
<optgroup label="Real Estate & Finance">
<option value="realestate">Real Estate Services / Brokerage</option>
<option value="finance">Financial Services (non-bank)</option>
<option value="insurance">Insurance Brokerage</option>
</optgroup>
<optgroup label="Other">
<option value="other" selected>Other / General</option>
</optgroup>
</select>
</div>
</div>
</div>
</div>
<!-- Cost of Debt -->
<div class="card" style="margin-bottom: 20px;">
<div class="card-header">
<div class="icon icon-debt">💳</div>
<div>
<h2>Cost of Debt</h2>
<span class="subtitle">Interest is tax-deductible — your real cost is lower</span>
</div>
</div>
<div class="card-body">
<div class="section-note">
Interest payments on business debt are tax-deductible in Canada. This means the government effectively subsidizes a portion of your borrowing cost. <strong>The after-tax rate is the true cost.</strong>
</div>
<div class="form-grid">
<div class="form-group">
<label>Interest Rate on Debt
<span class="tooltip-icon" data-tip="The nominal annual interest rate on your loan, line of credit, or bond. Use your current or proposed rate.">?</span>
</label>
<div class="input-with-unit">
<input type="number" id="interestRate" value="7.5" min="0" max="30" step="0.25" oninput="calculate()" />
<span class="input-unit">%</span>
</div>
</div>
<div class="form-group">
<label>Combined Corporate Tax Rate
<span class="tooltip-icon" data-tip="Auto-populated based on your province and company type. You can override this. Includes federal + provincial rates.">?</span>
</label>
<div class="input-with-unit">
<input type="number" id="taxRate" value="12.2" min="0" max="50" step="0.1" oninput="calculate()" />
<span class="input-unit">%</span>
</div>
</div>
<div class="form-group full">
<label>After-Tax Cost of Debt</label>
<div class="computed-field highlight" id="afterTaxDebt">—</div>
</div>
</div>
<div class="divider"></div>
<p style="font-size:0.78rem; color:var(--gray-500);">Formula: <em>After-tax cost = Interest Rate × (1 − Tax Rate)</em></p>
</div>
</div>
<!-- Cost of Equity -->
<div class="card">
<div class="card-header">
<div class="icon icon-equity">📈</div>
<div>
<h2>Cost of Equity</h2>
<span class="subtitle">Build-up method — standard for Canadian private companies</span>
</div>
</div>
<div class="card-body">
<div class="section-note">
Equity doesn't have an interest rate, but it has an <strong>implicit cost</strong> — the return equity investors require. For private lower-market companies, this is estimated using the build-up method.
</div>
<!-- Risk-free + ERP (readonly unless advanced) -->
<div class="form-grid" style="margin-bottom: 16px;">
<div class="form-group">
<label>Risk-Free Rate (GoC 10-Yr)
<span class="tooltip-icon" data-tip="The yield on the Government of Canada 10-year bond. This is the baseline 'risk-free' return. Pre-populated at current approximate levels — update as needed.">?</span>
</label>
<div class="input-with-unit">
<input type="number" id="riskFreeRate" value="3.25" min="0" max="10" step="0.05" oninput="calculate()" />
<span class="input-unit">%</span>
</div>
</div>
<div class="form-group">
<label>Equity Risk Premium
<span class="tooltip-icon" data-tip="The excess return investors expect from the equity market over the risk-free rate. 5.5% reflects the long-run Canadian equity premium (Kroll/Duff & Phelps, 2024).">?</span>
</label>
<div class="input-with-unit">
<input type="number" id="erp" value="5.50" min="0" max="15" step="0.25" oninput="calculate()" />
<span class="input-unit">%</span>
</div>
</div>
</div>
<!-- Size Premium (computed) -->
<div class="form-grid" style="margin-bottom: 16px;">
<div class="form-group">
<label>Size Premium
<span class="tooltip-icon" data-tip="Smaller companies are riskier. This premium compensates equity investors for the additional risk of investing in a lower-market private company vs. a large-cap public firm.">?</span>
</label>
<div class="computed-field" id="sizePremiumDisplay">—</div>
</div>
<div class="form-group">
<label>Industry Risk Premium
<span class="tooltip-icon" data-tip="Derived from Damodaran unlevered betas by sector (NYU Stern, Jan 2025). Formula: IRP = (β_unlevered − 1.0) × ERP. Adjusted for Canadian LMM private company context where public-market betas understate actual risk.">?</span>
</label>
<div class="computed-field" id="industryPremiumDisplay">—</div>
</div>
</div>
<!-- Company-specific risk slider -->
<div class="form-group full" style="margin-bottom: 8px;">
<label>Company-Specific Risk
<span class="tooltip-icon" data-tip="Captures risks unique to your company: key-person dependency, customer concentration, management depth, financial history, and operational complexity.">?</span>
</label>
<div class="slider-group">
<div class="slider-labels">
<span>Low Risk</span>
<span>Moderate</span>
<span>High Risk</span>
</div>
<input type="range" id="specificRisk" min="1" max="3" step="1" value="2" oninput="onSliderChange()" />
<div class="slider-value-display" id="specificRiskLabel">—</div>
</div>
</div>
<div class="divider"></div>
<div class="form-group full">
<label>Cost of Equity (Estimated)</label>
<div class="computed-field highlight" id="costOfEquityDisplay" style="background:#f0fdf4; border-color:#bbf7d0; color:var(--teal);">—</div>
</div>
</div>
</div>
</div><!-- end inputs column -->
<!-- RIGHT: Results Panel -->
<div class="results-panel">
<div class="card">
<div class="card-header">
<div class="icon icon-results">📊</div>
<div>
<h2>Your Results</h2>
<span class="subtitle">Cost of debt vs. cost of equity</span>
</div>
</div>
<div class="card-body">
<div class="results-grid">
<div class="result-box result-box-debt">
<div class="result-label">After-Tax Cost of Debt</div>
<div class="result-number" id="result-debt">—</div>
<div class="result-sublabel">per year</div>
</div>
<div class="result-box result-box-equity">
<div class="result-label">Cost of Equity</div>
<div class="result-number" id="result-equity">—</div>
<div class="result-sublabel">per year</div>
</div>
</div>
<div class="insight-box" id="insightBox">
<div class="insight-headline" id="insightHeadline">Fill in the inputs to see your comparison</div>
<div class="insight-body" id="insightBody">Your after-tax cost of debt will appear here alongside an estimate of your cost of equity.</div>
</div>
<div class="chart-container">
<canvas id="comparisonChart"></canvas>
</div>
<!-- Build-up Breakdown -->
<div style="margin-bottom: 12px;">
<div style="font-size:0.8rem; font-weight:700; color:var(--gray-700); margin-bottom: 10px; text-transform:uppercase; letter-spacing:0.04em;">
Equity Cost Build-Up
</div>
<table class="breakdown-table">
<tbody id="breakdownBody">
<tr>
<td><span class="dot" style="background:#60a5fa;"></span><span class="component-name">Risk-Free Rate (GoC 10-yr)</span></td>
<td id="bd-rf">—</td>
</tr>
<tr>
<td><span class="dot" style="background:#34d399;"></span><span class="component-name">Equity Risk Premium</span></td>
<td id="bd-erp">—</td>
</tr>
<tr>
<td><span class="dot" style="background:#fb923c;"></span><span class="component-name">Size Premium</span></td>
<td id="bd-size">—</td>
</tr>
<tr>
<td><span class="dot" style="background:#a78bfa;"></span><span class="component-name">Industry Risk Premium</span></td>
<td id="bd-ind">—</td>
</tr>
<tr>
<td><span class="dot" style="background:#f472b6;"></span><span class="component-name">Company-Specific Risk</span></td>
<td id="bd-cs">—</td>
</tr>
<tr class="total-row">
<td><strong>Total Cost of Equity</strong></td>
<td id="bd-total">—</td>
</tr>
</tbody>
</table>
</div>
<div class="disclaimer">
This calculator provides educational estimates only. Industry risk premiums are derived from Damodaran unlevered betas by sector (NYU Stern, Jan 2025) using the formula IRP = (β − 1.0) × ERP, adjusted for Canadian LMM context. Tax rates are approximate (2025/2026) and should be confirmed with your accountant. Results should not be relied upon for investment or financing decisions without professional advice.
</div>
</div>
</div>
</div><!-- end results panel -->
</div><!-- end layout -->
<!-- ── Lifetime Cost Analysis ── -->
<div class="lifetime-section">
<div class="card">
<div class="card-header">
<div class="icon" style="background:#fef3c7; font-size:1.1rem;">⏳</div>
<div>
<h2>Lifetime Cost Analysis</h2>
<span class="subtitle">Debt disappears when repaid — equity stays and grows with your company</span>
</div>
</div>
<div class="card-body">
<div class="lc-grid">
<!-- Left: inputs + metrics -->
<div>
<div class="section-note">
Enter the financing amount, loan term, and company valuation to compare what debt truly costs over time versus the permanent, compounding claim of equity.
</div>
<div class="form-grid" style="margin-top:16px;">
<div class="form-group">
<label>Capital Required (CAD)
<span class="tooltip-icon" data-tip="The amount of financing needed. The same dollar amount is used for both scenarios — debt vs. equity — so the comparison is apples-to-apples.">?</span>
</label>
<div class="input-with-unit">
<input type="number" id="lcCapital" value="2000000" min="100000" step="100000" oninput="calculateLifetime()" />
<span class="input-unit" style="right:8px; font-size:0.75rem;">CAD</span>
</div>
</div>
<div class="form-group">
<label>Loan Term
<span class="tooltip-icon" data-tip="After this many years, the debt is repaid and the interest cost drops to zero permanently. Equity has no equivalent end date.">?</span>
</label>
<select id="lcDebtTerm" onchange="calculateLifetime()">
<option value="3">3 years</option>
<option value="5" selected>5 years</option>
<option value="7">7 years</option>
<option value="10">10 years</option>
</select>
</div>
<div class="form-group">
<label>Current Company Valuation
<span class="tooltip-icon" data-tip="Determines what equity % an investor receives for the same capital. A $2M investment into a $10M company = 20% ownership — and 20% of all future growth.">?</span>
</label>
<div class="input-with-unit">
<input type="number" id="lcCompanyValue" value="8000000" min="500000" step="500000" oninput="calculateLifetime()" />
<span class="input-unit" style="right:8px; font-size:0.75rem;">CAD</span>
</div>
</div>
<div class="form-group">
<label>Annual Growth Rate
<span class="tooltip-icon" data-tip="As company value grows, the equity stake is worth more each year — so the implied annual equity cost grows with it. Debt costs stay fixed regardless of growth.">?</span>
</label>
<div class="slider-group">
<div class="slider-labels"><span>3%</span><span>10%</span><span>20%</span></div>
<input type="range" id="lcGrowth" min="3" max="20" step="1" value="8" oninput="calculateLifetime()" />
<div class="slider-value-display" id="lcGrowthLabel">8% per year</div>
</div>
</div>
</div>
<!-- Metrics -->
<div class="lc-metrics-grid">
<div class="lc-metric lc-debt">
<div class="lc-metric-label">Total Debt Cost (After-Tax)</div>
<div class="lc-metric-value" id="lc-total-debt">—</div>
<div class="lc-metric-sub" id="lc-debt-sub">over loan term, then $0 forever</div>
</div>
<div class="lc-metric lc-equity">
<div class="lc-metric-label">Equity Stake Sold</div>
<div class="lc-metric-value" id="lc-equity-pct">—</div>
<div class="lc-metric-sub">permanent share of company</div>
</div>
<div class="lc-metric lc-equity">
<div class="lc-metric-label">Implied Equity Cost — Year 1</div>
<div class="lc-metric-value" id="lc-eq-cost-now">—</div>
<div class="lc-metric-sub">expected return owed to investor</div>
</div>
<div class="lc-metric lc-equity">
<div class="lc-metric-label">Implied Equity Cost — Year 10</div>
<div class="lc-metric-value" id="lc-eq-cost-10">—</div>
<div class="lc-metric-sub">grows every year as company grows</div>
</div>
<div class="lc-metric lc-amber" style="grid-column: 1 / -1;">
<div class="lc-metric-label">Equity Break-Even Year</div>
<div class="lc-metric-value" id="lc-breakeven">—</div>
<div class="lc-metric-sub" id="lc-breakeven-sub">Year when cumulative equity cost exceeds total lifetime debt cost</div>
</div>
</div>
</div>
<!-- Right: chart + insight -->
<div>
<div style="font-size:0.8rem; font-weight:700; color:var(--gray-700); margin-bottom:12px; text-transform:uppercase; letter-spacing:0.04em;">Cumulative Cost — 15-Year Horizon</div>
<div class="lc-chart-container">
<canvas id="lifetimeChart"></canvas>
</div>
<div class="lc-insight">
<div class="lc-insight-headline" id="lcInsightHeadline">—</div>
<div class="lc-insight-body" id="lcInsightBody">—</div>
</div>
</div>
</div>
</div>
</div>
</div><!-- end lifetime section -->
</div><!-- end main -->
<script>
// ─────────────────────────────────────────────
// DATA TABLES
// ─────────────────────────────────────────────
// Combined federal + provincial corporate tax rates (2025/2026 approx.)
const TAX_RATES = {
// [sbd, general, non-ccpc]
AB: [11.0, 23.0, 23.0],
BC: [11.0, 27.0, 27.0],
MB: [9.0, 27.0, 27.0],
NB: [12.5, 29.0, 29.0],
NL: [12.5, 30.0, 30.0],
NS: [14.5, 29.5, 29.5],
ON: [12.2, 26.5, 26.5],
PE: [16.0, 31.0, 31.0],
QC: [14.5, 26.5, 26.5],
SK: [11.0, 27.0, 27.0],
};
// Size premiums by revenue range
const SIZE_PREMIUMS = {
grp1: 6.0, // $3M – $10M
grp2: 5.0, // $11M – $25M
grp3: 4.0, // $26M – $50M
};
// Industry Risk Premiums — sourced from Damodaran "Betas by Sector" (NYU Stern, Jan 2025).
// Methodology: IRP = (β_unlevered − 1.0) × 5.5% ERP, adjusted for Canadian LMM context.
// Where large-cap public betas understate LMM risk, premiums are adjusted upward.
// Reference: https://pages.stern.nyu.edu/~adamodar/New_Home_Page/datafile/Betas.html
const INDUSTRY_PREMIUMS = {
// Primary & Resources
agriculture: -0.50, // β≈0.62; defensive but commodity/weather risk; LMM adj → -0.50%
mining: 1.00, // β≈0.98; junior/small mining capital-intensive & cyclical → +1.00%
oilgas: 1.00, // β≈1.17 (O&G services); commodity price exposure → +1.00%
forestry: 0.25, // β≈0.61; commodity-linked, stable demand; LMM adj → +0.25%
// Industrial
manufacturing: 0.00, // β≈0.98; near-market average → 0.00%
mfg_food: -0.50, // β≈0.57; non-cyclical defensive demand → -0.50%
mfg_auto: 0.50, // β≈1.00; OEM dependency, inventory & cyclicality risk → +0.50%
construction: 0.75, // β≈0.94; project risk, payment cycles, weather → +0.75%
engineering: 0.50, // β≈0.94; similar to construction; contract risk → +0.50%
transport: 0.25, // β≈0.82; fuel/capacity exposure, adjusted up for LMM → +0.25%
warehousing: -0.25, // β≈0.73; stable recurring contracts → -0.25%
// Trade & Consumer
wholesale: -0.25, // β≈0.68; low-margin but stable volumes → -0.25%
retail: 0.25, // β≈0.85; consumer cyclicality → +0.25%
retail_auto: 0.25, // β≈0.90; big-ticket cyclical, floor-plan risk → +0.25%
food_service: 1.00, // β≈1.01; high failure rate, thin margins, labour intensity → +1.00%
hospitality: 1.25, // β≈1.10; high fixed costs, economic cycle leverage → +1.25%
// Services
professional: -0.75, // β≈0.73; defensive recurring revenue, low capex → -0.75%
consulting: -0.50, // β≈0.80; project-based, key-person risk → -0.50%
marketing: 0.50, // β≈1.14; discretionary ad spend, cyclical → +0.50%
staffing: 0.25, // β≈0.97; economic bellwether, working capital sensitive → +0.25%
facilities: -0.25, // β≈0.82; essential services, long-term contracts → -0.25%
security: 0.00, // β≈0.82; recurring essential services, sticky contracts → 0.00%
// Technology
tech_software: 1.75, // β≈1.20; R&D, competition, churn risk amplified at LMM scale → +1.75%
tech_it: 0.75, // β≈0.98; recurring MSP contracts moderate risk → +0.75%
tech_hardware: 1.00, // β≈1.00; inventory, capex, supply chain risk → +1.00%
// Healthcare & Education
healthcare: -0.75, // β≈0.63; highly defensive, regulated, fee-for-service → -0.75%
homecare: -0.25, // β≈0.73; stable government-funded demand → -0.25%
pharma: 0.75, // β≈1.12; R&D risk, regulatory hurdles → +0.75%
education: -0.50, // β≈0.68; stable enrollment, regulated sector → -0.50%
// Real Estate & Finance
realestate: -0.25, // β≈0.68; commission-based, market-linked volumes → -0.25%
finance: 0.25, // β≈0.65; regulated, relatively stable but credit-cycle risk → +0.25%
insurance: -0.50, // β≈0.65; recurring premiums, low cyclicality → -0.50%
// Other
other: 0.00, // Market average
};
// Company-specific risk premiums
const SPECIFIC_RISK = {
1: { label: 'Low — Diversified, stable, strong management', value: 1.5 },
2: { label: 'Moderate — Some concentration, limited depth', value: 3.0 },
3: { label: 'High — Key-person, concentrated revenue, early-stage', value: 5.0 },
};
// ─────────────────────────────────────────────
// CHART INIT
// ─────────────────────────────────────────────
let chart;
function initChart() {
const ctx = document.getElementById('comparisonChart').getContext('2d');
chart = new Chart(ctx, {
type: 'bar',
data: {
labels: ['After-Tax Cost of Debt', 'Cost of Equity'],
datasets: [{
data: [0, 0],
backgroundColor: ['rgba(37,99,235,0.15)', 'rgba(13,148,136,0.15)'],
borderColor: ['rgba(37,99,235,0.9)', 'rgba(13,148,136,0.9)'],
borderWidth: 2,
borderRadius: 7,
borderSkipped: false,
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: { display: false },
tooltip: {
callbacks: {
label: ctx => ` ${ctx.parsed.y.toFixed(2)}%`
}
}
},
scales: {
y: {
beginAtZero: true,
grid: { color: 'rgba(0,0,0,0.05)' },
ticks: {
callback: v => v + '%',
font: { size: 11 }
}
},
x: {
grid: { display: false },
ticks: { font: { size: 11 } }
}
}
}
});
}
// ─────────────────────────────────────────────
// EVENT HANDLERS
// ─────────────────────────────────────────────
function onProvinceChange() {
onCompanyTypeChange();
}
function onCompanyTypeChange() {
const province = document.getElementById('province').value;
const type = document.getElementById('companyType').value;
const rates = TAX_RATES[province];
let rate;
if (type === 'sbd') rate = rates[0];
else if (type === 'general') rate = rates[1];
else rate = rates[2];
document.getElementById('taxRate').value = rate.toFixed(1);
calculate();
}
function onSliderChange() {
calculate();
}
// ─────────────────────────────────────────────
// MAIN CALCULATION
// ─────────────────────────────────────────────
function calculate() {
const interestRate = parseFloat(document.getElementById('interestRate').value) || 0;
const taxRate = parseFloat(document.getElementById('taxRate').value) || 0;
const riskFreeRate = parseFloat(document.getElementById('riskFreeRate').value) || 0;
const erp = parseFloat(document.getElementById('erp').value) || 0;
const revenueRange = document.getElementById('revenueRange').value;
const industry = document.getElementById('industry').value;
const sliderVal = parseInt(document.getElementById('specificRisk').value);
// Cost of Debt
const afterTaxDebt = interestRate * (1 - taxRate / 100);
// Cost of Equity (build-up)
const sizePrem = SIZE_PREMIUMS[revenueRange];
const indPrem = INDUSTRY_PREMIUMS[industry];
const csRisk = SPECIFIC_RISK[sliderVal].value;
const csLabel = SPECIFIC_RISK[sliderVal].label;
const costEquity = riskFreeRate + erp + sizePrem + indPrem + csRisk;
// ── Update inputs display ──
document.getElementById('afterTaxDebt').textContent = afterTaxDebt.toFixed(2) + '%';
document.getElementById('sizePremiumDisplay').textContent = (sizePrem >= 0 ? '+' : '') + sizePrem.toFixed(1) + '%';
document.getElementById('industryPremiumDisplay').textContent = (indPrem >= 0 ? '+' : '') + indPrem.toFixed(1) + '%';
document.getElementById('specificRiskLabel').textContent = csLabel;
document.getElementById('costOfEquityDisplay').textContent = costEquity.toFixed(2) + '%';
// ── Update results ──
document.getElementById('result-debt').textContent = afterTaxDebt.toFixed(2) + '%';
document.getElementById('result-equity').textContent = costEquity.toFixed(2) + '%';
// ── Build-up breakdown ──
document.getElementById('bd-rf').textContent = riskFreeRate.toFixed(2) + '%';
document.getElementById('bd-erp').textContent = erp.toFixed(2) + '%';
document.getElementById('bd-size').textContent = '+' + sizePrem.toFixed(2) + '%';
document.getElementById('bd-ind').textContent = (indPrem >= 0 ? '+' : '') + indPrem.toFixed(2) + '%';
document.getElementById('bd-cs').textContent = '+' + csRisk.toFixed(2) + '%';
document.getElementById('bd-total').textContent = costEquity.toFixed(2) + '%';
// ── Insight box ──
const diff = costEquity - afterTaxDebt;
const multiple = (costEquity / afterTaxDebt).toFixed(1);
document.getElementById('insightHeadline').textContent =
`Equity costs ${diff.toFixed(1)} percentage points more than debt`;
document.getElementById('insightBody').textContent =
`Your after-tax cost of debt is ${afterTaxDebt.toFixed(2)}%, while equity investors in a company like yours would typically require a ${costEquity.toFixed(1)}% return — ${multiple}× higher. Debt is generally the less expensive source of capital.`;
// ── Bar Chart ──
chart.data.datasets[0].data = [
parseFloat(afterTaxDebt.toFixed(2)),
parseFloat(costEquity.toFixed(2))
];
chart.options.scales.y.max = Math.ceil(costEquity 1.2 / 5) 5;
chart.update('none');
// ── Trigger lifetime recalc (rates have changed) ──
calculateLifetime();
}
// ─────────────────────────────────────────────
// LIFETIME COST ANALYSIS
// ─────────────────────────────────────────────
let lifetimeChart;
function fmtCAD(v) {
if (v >= 1000000) return '$' + (v / 1000000).toFixed(2) + 'M';
if (v >= 1000) return '$' + (v / 1000).toFixed(0) + 'K';
return '$' + Math.round(v);
}
function fmtCADShort(v) {
if (v >= 1000000) return '$' + (v / 1000000).toFixed(1) + 'M';
if (v >= 1000) return '$' + Math.round(v / 1000) + 'K';
return '$' + Math.round(v);
}
function initLifetimeChart() {
const ctx = document.getElementById('lifetimeChart').getContext('2d');
lifetimeChart = new Chart(ctx, {
type: 'line',
data: {
labels: [],
datasets: [
{
label: 'Debt — Cumulative After-Tax Cost',
data: [],
borderColor: 'rgba(37,99,235,0.9)',
backgroundColor: 'rgba(37,99,235,0.07)',
fill: true,
tension: 0,
borderWidth: 2.5,
pointRadius: 2.5,
pointBackgroundColor: 'rgba(37,99,235,0.9)',
},
{
label: 'Equity — Cumulative Implied Cost',
data: [],
borderColor: 'rgba(13,148,136,0.9)',
backgroundColor: 'rgba(13,148,136,0.07)',
fill: true,
tension: 0.25,
borderWidth: 2.5,
pointRadius: 2.5,
pointBackgroundColor: 'rgba(13,148,136,0.9)',
}
]
},
options: {
responsive: true,
maintainAspectRatio: false,
interaction: { mode: 'index', intersect: false },
plugins: {
legend: {
position: 'top',
labels: { font: { size: 11 }, boxWidth: 14, padding: 14 }
},
tooltip: {
callbacks: {
label: ctx => ` ${ctx.dataset.label}: ${fmtCAD(ctx.parsed.y)}`
}
}
},
scales: {
y: {
beginAtZero: true,
grid: { color: 'rgba(0,0,0,0.05)' },
ticks: { callback: v => fmtCADShort(v), font: { size: 11 } }
},
x: {
grid: { display: false },
ticks: { font: { size: 11 } }
}
}
}
});
}
function calculateLifetime() {
const capital = parseFloat(document.getElementById('lcCapital').value) || 2000000;
const debtTerm = parseInt(document.getElementById('lcDebtTerm').value) || 5;
const companyValue = parseFloat(document.getElementById('lcCompanyValue').value) || 8000000;
const growthRate = parseFloat(document.getElementById('lcGrowth').value) || 8;
// Pull rates from the main calculator displays
const afterTaxDebtRate = parseFloat(document.getElementById('afterTaxDebt').textContent) || 0;
const coE = parseFloat(document.getElementById('costOfEquityDisplay').textContent) || 0;
document.getElementById('lcGrowthLabel').textContent = growthRate + '% per year';
const g = growthRate / 100;
const equityFraction = capital / companyValue;
const annualDebtCost = capital * (afterTaxDebtRate / 100);
const totalDebtCost = annualDebtCost * debtTerm;
// Year-by-year cumulative costs (years 0–15)
const HORIZON = 15;
const debtCum = [0];
const equityCum = [0];
let breakEvenYear = null;
for (let t = 1; t <= HORIZON; t++) {
// Debt: interest accrues during term only, then permanently zero
debtCum.push(debtCum[t - 1] + (t <= debtTerm ? annualDebtCost : 0));
// Equity: the investor's expected annual return = equity% × company value at yr t × CoE
// = (capital / V₀) × V₀ × (1+g)^t × CoE = capital × (1+g)^t × CoE
const eqThisYear = capital Math.pow(1 + g, t) (coE / 100);
equityCum.push(equityCum[t - 1] + eqThisYear);
// Break-even: first year cumulative equity exceeds total debt cost
if (breakEvenYear === null && equityCum[t] >= totalDebtCost && totalDebtCost > 0) {
breakEvenYear = t;
}
}
const eqCostYr1 = capital Math.pow(1 + g, 1) (coE / 100);
const eqCostYr10 = capital Math.pow(1 + g, 10) (coE / 100);
const cumEq15 = equityCum[HORIZON];
const multiple = totalDebtCost > 0 ? (cumEq15 / totalDebtCost).toFixed(1) : '—';
// ── Metrics ──
document.getElementById('lc-total-debt').textContent = fmtCAD(totalDebtCost);
document.getElementById('lc-debt-sub').textContent = `over ${debtTerm}-yr term, then $0 forever`;
document.getElementById('lc-equity-pct').textContent = (equityFraction * 100).toFixed(1) + '%';
document.getElementById('lc-eq-cost-now').textContent = fmtCAD(eqCostYr1) + '/yr';
document.getElementById('lc-eq-cost-10').textContent = fmtCAD(eqCostYr10) + '/yr';
if (breakEvenYear !== null) {
document.getElementById('lc-breakeven').textContent = 'Year ' + breakEvenYear;
document.getElementById('lc-breakeven-sub').textContent =
`By year ${breakEvenYear}, the equity's cumulative cost already exceeds your entire debt cost`;
} else {
document.getElementById('lc-breakeven').textContent = '> 15 yrs';
document.getElementById('lc-breakeven-sub').textContent =
'Equity break-even extends beyond the 15-year analysis horizon at this growth rate';
}
// ── Insight ──
document.getElementById('lcInsightHeadline').textContent =
`By year 15, equity will have cost ${fmtCAD(cumEq15)} — ${multiple}× the total debt cost of ${fmtCAD(totalDebtCost)}`;
document.getElementById('lcInsightBody').textContent =
`Your ${fmtCAD(capital)} loan costs ${fmtCAD(annualDebtCost)}/yr after tax and is fully retired after ${debtTerm} years. ` +
`Giving up ${(equityFraction * 100).toFixed(1)}% equity means the investor's implied annual return grows from ` +
`${fmtCAD(eqCostYr1)}/yr today to ${fmtCAD(eqCostYr10)}/yr by year 10 as your company grows at ${growthRate}% per year — ` +
`and that obligation never ends unless you buy them out.`;
// ── Chart ──
const labels = Array.from({ length: HORIZON + 1 }, (_, i) => i === 0 ? 'Today' : `Yr ${i}`);
lifetimeChart.data.labels = labels;
lifetimeChart.data.datasets[0].data = debtCum;
lifetimeChart.data.datasets[1].data = equityCum;
lifetimeChart.update('none');
}
// ─────────────────────────────────────────────
// INIT
// ─────────────────────────────────────────────
document.addEventListener('DOMContentLoaded', () => {
initChart();
initLifetimeChart();
calculate(); // calculate() now calls calculateLifetime() at end
});
</script>
</body>
</html>