Spaces:
Running
Running
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>Financial Toolkit Pro</title> | |
<script src="https://cdn.tailwindcss.com"></script> | |
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
<style> | |
:root { | |
--primary: #4f46e5; | |
--secondary: #10b981; | |
--dark: #1e293b; | |
--light: #f8fafc; | |
} | |
body { | |
background-color: #f1f5f9; | |
color: var(--dark); | |
font-family: 'Inter', sans-serif; | |
} | |
.card { | |
background: white; | |
border-radius: 12px; | |
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); | |
transition: all 0.3s ease; | |
} | |
.card:hover { | |
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); | |
transform: translateY(-2px); | |
} | |
.input-group { | |
position: relative; | |
margin-bottom: 1.5rem; | |
} | |
.input-group label { | |
display: block; | |
margin-bottom: 0.5rem; | |
font-weight: 500; | |
color: #64748b; | |
} | |
.input-group input, .input-group select { | |
width: 100%; | |
padding: 0.75rem; | |
border: 1px solid #e2e8f0; | |
border-radius: 8px; | |
font-size: 1rem; | |
transition: all 0.2s; | |
} | |
.input-group input:focus, .input-group select:focus { | |
outline: none; | |
border-color: var(--primary); | |
box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.1); | |
} | |
.input-group .input-icon { | |
position: absolute; | |
right: 12px; | |
top: 38px; | |
color: #94a3b8; | |
} | |
.btn { | |
padding: 0.75rem 1.5rem; | |
border-radius: 8px; | |
font-weight: 600; | |
cursor: pointer; | |
transition: all 0.2s; | |
border: none; | |
} | |
.btn-primary { | |
background-color: var(--primary); | |
color: white; | |
} | |
.btn-primary:hover { | |
background-color: #4338ca; | |
} | |
.btn-secondary { | |
background-color: var(--secondary); | |
color: white; | |
} | |
.btn-secondary:hover { | |
background-color: #0d9488; | |
} | |
.result-card { | |
background-color: #f8fafc; | |
border-left: 4px solid var(--primary); | |
padding: 1.5rem; | |
border-radius: 8px; | |
margin-top: 1.5rem; | |
} | |
.result-value { | |
font-size: 1.5rem; | |
font-weight: 700; | |
color: var(--primary); | |
} | |
.tab { | |
padding: 0.75rem 1rem; | |
border-radius: 8px; | |
cursor: pointer; | |
font-weight: 500; | |
transition: all 0.2s; | |
} | |
.tab.active { | |
background-color: var(--primary); | |
color: white; | |
} | |
.tab:hover:not(.active) { | |
background-color: #e2e8f0; | |
} | |
.tooltip { | |
position: relative; | |
display: inline-block; | |
} | |
.tooltip .tooltip-text { | |
visibility: hidden; | |
width: 200px; | |
background-color: var(--dark); | |
color: #fff; | |
text-align: center; | |
border-radius: 6px; | |
padding: 0.5rem; | |
position: absolute; | |
z-index: 1; | |
bottom: 125%; | |
left: 50%; | |
margin-left: -100px; | |
opacity: 0; | |
transition: opacity 0.3s; | |
} | |
.tooltip:hover .tooltip-text { | |
visibility: visible; | |
opacity: 1; | |
} | |
.amortization-table { | |
width: 100%; | |
border-collapse: collapse; | |
margin-top: 1rem; | |
font-size: 0.875rem; | |
} | |
.amortization-table th { | |
background-color: #e2e8f0; | |
padding: 0.5rem; | |
text-align: left; | |
} | |
.amortization-table td { | |
padding: 0.5rem; | |
border-bottom: 1px solid #e2e8f0; | |
} | |
.amortization-table tr:hover { | |
background-color: #f1f5f9; | |
} | |
.visual-container { | |
margin-top: 1.5rem; | |
padding: 1rem; | |
background-color: #f8fafc; | |
border-radius: 8px; | |
border-left: 4px solid var(--secondary); | |
} | |
.visual-title { | |
font-weight: 600; | |
margin-bottom: 0.5rem; | |
color: var(--dark); | |
} | |
.bar-container { | |
height: 24px; | |
background-color: #e2e8f0; | |
border-radius: 12px; | |
margin: 0.5rem 0; | |
overflow: hidden; | |
position: relative; | |
} | |
.bar-fill { | |
height: 100%; | |
border-radius: 12px; | |
transition: width 0.5s ease; | |
} | |
.bar-label { | |
position: absolute; | |
top: 50%; | |
transform: translateY(-50%); | |
left: 8px; | |
color: white; | |
font-weight: 500; | |
font-size: 0.75rem; | |
text-shadow: 0 1px 1px rgba(0,0,0,0.3); | |
} | |
.pie-chart { | |
width: 160px; | |
height: 160px; | |
border-radius: 50%; | |
background: conic-gradient( | |
var(--primary) 0% 30%, | |
var(--secondary) 30% 70%, | |
#f59e0b 70% 100% | |
); | |
margin: 0 auto; | |
} | |
.legend { | |
display: flex; | |
flex-wrap: wrap; | |
gap: 0.5rem; | |
margin-top: 1rem; | |
justify-content: center; | |
} | |
.legend-item { | |
display: flex; | |
align-items: center; | |
font-size: 0.75rem; | |
} | |
.legend-color { | |
width: 12px; | |
height: 12px; | |
border-radius: 2px; | |
margin-right: 4px; | |
} | |
.scrollable-table { | |
max-height: 300px; | |
overflow-y: auto; | |
margin-top: 1rem; | |
border: 1px solid #e2e8f0; | |
border-radius: 8px; | |
} | |
@media (max-width: 768px) { | |
.calculator-grid { | |
grid-template-columns: 1fr; | |
} | |
} | |
</style> | |
</head> | |
<body class="min-h-screen"> | |
<div class="container mx-auto px-4 py-8"> | |
<!-- Header --> | |
<header class="mb-10 text-center"> | |
<h1 class="text-4xl font-bold text-gray-800 mb-2">Financial Toolkit Pro</h1> | |
<p class="text-lg text-gray-600">Your comprehensive financial calculation dashboard</p> | |
</header> | |
<!-- Navigation Tabs --> | |
<div class="flex flex-wrap gap-2 mb-8 justify-center"> | |
<div class="tab active" data-tab="mortgage">Mortgage Calculator</div> | |
<div class="tab" data-tab="ltv">LTV Calculator</div> | |
<div class="tab" data-tab="dti">DTI Calculator</div> | |
<div class="tab" data-tab="dsr">DSR Calculator</div> | |
<div class="tab" data-tab="roi">ROI Calculator</div> | |
<div class="tab" data-tab="npv">NPV Calculator</div> | |
</div> | |
<!-- Calculator Grid --> | |
<div class="calculator-grid grid grid-cols-1 lg:grid-cols-2 gap-6"> | |
<!-- Mortgage Calculator --> | |
<div class="card p-6" id="mortgage-calculator"> | |
<h2 class="text-xl font-bold mb-4 text-gray-800 flex items-center gap-2"> | |
<i class="fas fa-home text-indigo-500"></i> | |
Mortgage Calculator | |
</h2> | |
<div class="input-group"> | |
<label for="mortgage-amount">Loan Amount ($)</label> | |
<input type="number" id="mortgage-amount" placeholder="300,000"> | |
<i class="fas fa-dollar-sign input-icon"></i> | |
</div> | |
<div class="input-group"> | |
<label for="mortgage-rate">Interest Rate (%)</label> | |
<input type="number" id="mortgage-rate" placeholder="3.5" step="0.01"> | |
<i class="fas fa-percent input-icon"></i> | |
</div> | |
<div class="input-group"> | |
<label for="mortgage-term">Loan Term (years)</label> | |
<input type="number" id="mortgage-term" placeholder="30"> | |
</div> | |
<button class="btn btn-primary w-full mt-2" onclick="calculateMortgage()"> | |
Calculate Payment | |
</button> | |
<div class="result-card" id="mortgage-result" style="display: none;"> | |
<h3 class="font-semibold text-gray-700">Monthly Payment</h3> | |
<div class="result-value" id="monthly-payment">$0.00</div> | |
<div class="mt-2 text-sm text-gray-600"> | |
<div>Total Interest: <span id="total-interest">$0.00</span></div> | |
<div>Total Payment: <span id="total-payment">$0.00</span></div> | |
</div> | |
</div> | |
</div> | |
<!-- Mortgage Amortization Table --> | |
<div class="card p-6" id="mortgage-amortization" style="display: none;"> | |
<h2 class="text-xl font-bold mb-4 text-gray-800 flex items-center gap-2"> | |
<i class="fas fa-table text-indigo-500"></i> | |
Amortization Schedule | |
</h2> | |
<div class="visual-container"> | |
<div class="visual-title">Payment Breakdown (First 5 Years)</div> | |
<div class="pie-chart"></div> | |
<div class="legend"> | |
<div class="legend-item"><span class="legend-color" style="background-color: #4f46e5;"></span> Principal</div> | |
<div class="legend-item"><span class="legend-color" style="background-color: #10b981;"></span> Interest</div> | |
<div class="legend-item"><span class="legend-color" style="background-color: #f59e0b;"></span> Other</div> | |
</div> | |
</div> | |
<div class="scrollable-table"> | |
<table class="amortization-table" id="amortization-table"> | |
<thead> | |
<tr> | |
<th>Year</th> | |
<th>Principal</th> | |
<th>Interest</th> | |
<th>Balance</th> | |
</tr> | |
</thead> | |
<tbody id="amortization-body"> | |
<!-- Filled by JavaScript --> | |
</tbody> | |
</table> | |
</div> | |
</div> | |
<!-- LTV Calculator --> | |
<div class="card p-6" id="ltv-calculator" style="display: none;"> | |
<h2 class="text-xl font-bold mb-4 text-gray-800 flex items-center gap-2"> | |
<i class="fas fa-percentage text-green-500"></i> | |
Loan-to-Value (LTV) Calculator | |
</h2> | |
<div class="input-group"> | |
<label for="loan-amount">Loan Amount ($)</label> | |
<input type="number" id="loan-amount" placeholder="250,000"> | |
<i class="fas fa-dollar-sign input-icon"></i> | |
</div> | |
<div class="input-group"> | |
<label for="property-value">Property Value ($)</label> | |
<input type="number" id="property-value" placeholder="300,000"> | |
<i class="fas fa-dollar-sign input-icon"></i> | |
</div> | |
<button class="btn btn-primary w-full mt-2" onclick="calculateLTV()"> | |
Calculate LTV | |
</button> | |
<div class="result-card" id="ltv-result" style="display: none;"> | |
<h3 class="font-semibold text-gray-700">Loan-to-Value Ratio</h3> | |
<div class="result-value" id="ltv-ratio">0%</div> | |
<div class="mt-2 text-sm text-gray-600"> | |
<span id="ltv-assessment">LTV assessment will appear here</span> | |
</div> | |
</div> | |
</div> | |
<!-- LTV Visualization --> | |
<div class="card p-6" id="ltv-visualization" style="display: none;"> | |
<h2 class="text-xl font-bold mb-4 text-gray-800 flex items-center gap-2"> | |
<i class="fas fa-chart-pie text-green-500"></i> | |
LTV Visualization | |
</h2> | |
<div class="visual-container"> | |
<div class="visual-title">Loan vs. Property Value</div> | |
<div class="bar-container"> | |
<div class="bar-fill" id="ltv-bar" style="width: 0%; background-color: var(--primary);"></div> | |
<div class="bar-label" id="ltv-bar-label">0%</div> | |
</div> | |
<div class="grid grid-cols-2 gap-4 mt-4"> | |
<div class="p-3 bg-blue-50 rounded-lg"> | |
<div class="text-sm text-gray-600">Loan Amount</div> | |
<div class="font-semibold text-blue-600" id="visual-loan-amount">$0</div> | |
</div> | |
<div class="p-3 bg-green-50 rounded-lg"> | |
<div class="text-sm text-gray-600">Property Value</div> | |
<div class="font-semibold text-green-600" id="visual-property-value">$0</div> | |
</div> | |
</div> | |
</div> | |
<div class="mt-4 p-4 bg-yellow-50 rounded-lg"> | |
<h4 class="font-semibold text-yellow-800 mb-2">LTV Risk Levels</h4> | |
<div class="text-sm text-yellow-700"> | |
<div class="flex items-center mb-1"><span class="inline-block w-3 h-3 bg-green-500 rounded-full mr-2"></span> <80%: Excellent (Best rates)</div> | |
<div class="flex items-center mb-1"><span class="inline-block w-3 h-3 bg-yellow-500 rounded-full mr-2"></span> 80-90%: Good (May need PMI)</div> | |
<div class="flex items-center"><span class="inline-block w-3 h-3 bg-red-500 rounded-full mr-2"></span> >90%: High Risk (Difficult to qualify)</div> | |
</div> | |
</div> | |
</div> | |
<!-- DTI Calculator --> | |
<div class="card p-6" id="dti-calculator" style="display: none;"> | |
<h2 class="text-xl font-bold mb-4 text-gray-800 flex items-center gap-2"> | |
<i class="fas fa-calculator text-blue-500"></i> | |
Debt-to-Income (DTI) Calculator | |
</h2> | |
<div class="input-group"> | |
<label for="monthly-debt">Monthly Debt Payments ($)</label> | |
<input type="number" id="monthly-debt" placeholder="1,500"> | |
<i class="fas fa-dollar-sign input-icon"></i> | |
</div> | |
<div class="input-group"> | |
<label for="gross-income">Gross Monthly Income ($)</label> | |
<input type="number" id="gross-income" placeholder="6,000"> | |
<i class="fas fa-dollar-sign input-icon"></i> | |
</div> | |
<button class="btn btn-primary w-full mt-2" onclick="calculateDTI()"> | |
Calculate DTI | |
</button> | |
<div class="result-card" id="dti-result" style="display: none;"> | |
<h3 class="font-semibold text-gray-700">Debt-to-Income Ratio</h3> | |
<div class="result-value" id="dti-ratio">0%</div> | |
<div class="mt-2 text-sm text-gray-600"> | |
<span id="dti-assessment">DTI assessment will appear here</span> | |
</div> | |
</div> | |
</div> | |
<!-- DTI Visualization --> | |
<div class="card p-6" id="dti-visualization" style="display: none;"> | |
<h2 class="text-xl font-bold mb-4 text-gray-800 flex items-center gap-2"> | |
<i class="fas fa-chart-bar text-blue-500"></i> | |
DTI Visualization | |
</h2> | |
<div class="visual-container"> | |
<div class="visual-title">Income vs. Debt</div> | |
<div class="grid grid-cols-2 gap-4 mb-4"> | |
<div class="p-3 bg-blue-50 rounded-lg"> | |
<div class="text-sm text-gray-600">Monthly Income</div> | |
<div class="font-semibold text-blue-600" id="visual-income">$0</div> | |
</div> | |
<div class="p-3 bg-purple-50 rounded-lg"> | |
<div class="text-sm text-gray-600">Monthly Debt</div> | |
<div class="font-semibold text-purple-600" id="visual-debt">$0</div> | |
</div> | |
</div> | |
<div class="bar-container"> | |
<div class="bar-fill" id="dti-bar" style="width: 0%; background-color: var(--primary);"></div> | |
<div class="bar-label" id="dti-bar-label">0%</div> | |
</div> | |
</div> | |
<div class="mt-4 p-4 bg-blue-50 rounded-lg"> | |
<h4 class="font-semibold text-blue-800 mb-2">DTI Guidelines</h4> | |
<div class="text-sm text-blue-700"> | |
<div class="flex items-center mb-1"><span class="inline-block w-3 h-3 bg-green-500 rounded-full mr-2"></span> <36%: Ideal for most lenders</div> | |
<div class="flex items-center mb-1"><span class="inline-block w-3 h-3 bg-yellow-500 rounded-full mr-2"></span> 36-43%: Acceptable but may limit options</div> | |
<div class="flex items-center"><span class="inline-block w-3 h-3 bg-red-500 rounded-full mr-2"></span> >43%: May have difficulty qualifying</div> | |
</div> | |
</div> | |
</div> | |
<!-- DSR Calculator --> | |
<div class="card p-6" id="dsr-calculator" style="display: none;"> | |
<h2 class="text-xl font-bold mb-4 text-gray-800 flex items-center gap-2"> | |
<i class="fas fa-scale-balanced text-purple-500"></i> | |
Debt Service Ratio (DSR) Calculator | |
</h2> | |
<div class="input-group"> | |
<label for="annual-debt">Annual Debt Service ($)</label> | |
<input type="number" id="annual-debt" placeholder="18,000"> | |
<i class="fas fa-dollar-sign input-icon"></i> | |
</div> | |
<div class="input-group"> | |
<label for="net-income">Net Annual Income ($)</label> | |
<input type="number" id="net-income" placeholder="72,000"> | |
<i class="fas fa-dollar-sign input-icon"></i> | |
</div> | |
<button class="btn btn-primary w-full mt-2" onclick="calculateDSR()"> | |
Calculate DSR | |
</button> | |
<div class="result-card" id="dsr-result" style="display: none;"> | |
<h3 class="font-semibold text-gray-700">Debt Service Ratio</h3> | |
<div class="result-value" id="dsr-ratio">0%</div> | |
<div class="mt-2 text-sm text-gray-600"> | |
<span id="dsr-assessment">DSR assessment will appear here</span> | |
</div> | |
</div> | |
</div> | |
<!-- DSR Visualization --> | |
<div class="card p-6" id="dsr-visualization" style="display: none;"> | |
<h2 class="text-xl font-bold mb-4 text-gray-800 flex items-center gap-2"> | |
<i class="fas fa-chart-line text-purple-500"></i> | |
DSR Visualization | |
</h2> | |
<div class="visual-container"> | |
<div class="visual-title">Income Coverage</div> | |
<div class="grid grid-cols-2 gap-4 mb-4"> | |
<div class="p-3 bg-green-50 rounded-lg"> | |
<div class="text-sm text-gray-600">Net Income</div> | |
<div class="font-semibold text-green-600" id="visual-net-income">$0</div> | |
</div> | |
<div class="p-3 bg-red-50 rounded-lg"> | |
<div class="text-sm text-gray-600">Debt Service</div> | |
<div class="font-semibold text-red-600" id="visual-annual-debt">$0</div> | |
</div> | |
</div> | |
<div class="bar-container"> | |
<div class="bar-fill" id="dsr-bar" style="width: 0%; background-color: var(--secondary);"></div> | |
<div class="bar-label" id="dsr-bar-label">0%</div> | |
</div> | |
</div> | |
<div class="mt-4 p-4 bg-purple-50 rounded-lg"> | |
<h4 class="font-semibold text-purple-800 mb-2">DSR Risk Levels</h4> | |
<div class="text-sm text-purple-700"> | |
<div class="flex items-center mb-1"><span class="inline-block w-3 h-3 bg-green-500 rounded-full mr-2"></span> <20%: Excellent coverage</div> | |
<div class="flex items-center mb-1"><span class="inline-block w-3 h-3 bg-yellow-500 rounded-full mr-2"></span> 20-35%: Manageable</div> | |
<div class="flex items-center"><span class="inline-block w-3 h-3 bg-red-500 rounded-full mr-2"></span> >35%: Potentially unsustainable</div> | |
</div> | |
</div> | |
</div> | |
<!-- ROI Calculator --> | |
<div class="card p-6" id="roi-calculator" style="display: none;"> | |
<h2 class="text-xl font-bold mb-4 text-gray-800 flex items-center gap-2"> | |
<i class="fas fa-chart-line text-teal-500"></i> | |
Return on Investment (ROI) Calculator | |
</h2> | |
<div class="input-group"> | |
<label for="investment-gain">Investment Gain ($)</label> | |
<input type="number" id="investment-gain" placeholder="50,000"> | |
<i class="fas fa-dollar-sign input-icon"></i> | |
</div> | |
<div class="input-group"> | |
<label for="investment-cost">Investment Cost ($)</label> | |
<input type="number" id="investment-cost" placeholder="200,000"> | |
<i class="fas fa-dollar-sign input-icon"></i> | |
</div> | |
<button class="btn btn-primary w-full mt-2" onclick="calculateROI()"> | |
Calculate ROI | |
</button> | |
<div class="result-card" id="roi-result" style="display: none;"> | |
<h3 class="font-semibold text-gray-700">Return on Investment</h3> | |
<div class="result-value" id="roi-percentage">0%</div> | |
<div class="mt-2 text-sm text-gray-600"> | |
<span id="roi-assessment">ROI assessment will appear here</span> | |
</div> | |
</div> | |
</div> | |
<!-- ROI Visualization --> | |
<div class="card p-6" id="roi-visualization" style="display: none;"> | |
<h2 class="text-xl font-bold mb-4 text-gray-800 flex items-center gap-2"> | |
<i class="fas fa-chart-pie text-teal-500"></i> | |
ROI Visualization | |
</h2> | |
<div class="visual-container"> | |
<div class="visual-title">Investment Performance</div> | |
<div class="grid grid-cols-2 gap-4 mb-4"> | |
<div class="p-3 bg-blue-50 rounded-lg"> | |
<div class="text-sm text-gray-600">Cost</div> | |
<div class="font-semibold text-blue-600" id="visual-investment-cost">$0</div> | |
</div> | |
<div class="p-3 bg-green-50 rounded-lg"> | |
<div class="text-sm text-gray-600">Gain</div> | |
<div class="font-semibold text-green-600" id="visual-investment-gain">$0</div> | |
</div> | |
</div> | |
<div class="flex items-center justify-center"> | |
<div class="w-32 h-32 rounded-full flex items-center justify-center border-4 border-teal-200" id="roi-circle"> | |
<div class="text-xl font-bold text-teal-600" id="roi-circle-value">0%</div> | |
</div> | |
</div> | |
</div> | |
<div class="mt-4 p-4 bg-teal-50 rounded-lg"> | |
<h4 class="font-semibold text-teal-800 mb-2">ROI Interpretation</h4> | |
<div class="text-sm text-teal-700"> | |
<div class="flex items-center mb-1"><span class="inline-block w-3 h-3 bg-green-500 rounded-full mr-2"></span> Positive: Profitable investment</div> | |
<div class="flex items-center mb-1"><span class="inline-block w-3 h-3 bg-red-500 rounded-full mr-2"></span> Negative: Losing investment</div> | |
<div class="flex items-center"><span class="inline-block w-3 h-3 bg-gray-500 rounded-full mr-2"></span> Zero: Break-even point</div> | |
</div> | |
</div> | |
</div> | |
<!-- NPV Calculator --> | |
<div class="card p-6" id="npv-calculator" style="display: none;"> | |
<h2 class="text-xl font-bold mb-4 text-gray-800 flex items-center gap-2"> | |
<i class="fas fa-coins text-amber-500"></i> | |
Net Present Value (NPV) Calculator | |
</h2> | |
<div class="input-group"> | |
<label for="initial-investment">Initial Investment ($)</label> | |
<input type="number" id="initial-investment" placeholder="100,000"> | |
<i class="fas fa-dollar-sign input-icon"></i> | |
</div> | |
<div class="input-group"> | |
<label for="discount-rate">Discount Rate (%)</label> | |
<input type="number" id="discount-rate" placeholder="5" step="0.1"> | |
<i class="fas fa-percent input-icon"></i> | |
</div> | |
<div class="input-group"> | |
<label for="cash-flows">Cash Flows (comma separated, $)</label> | |
<input type="text" id="cash-flows" placeholder="30,000, 35,000, 40,000"> | |
</div> | |
<button class="btn btn-primary w-full mt-2" onclick="calculateNPV()"> | |
Calculate NPV | |
</button> | |
<div class="result-card" id="npv-result" style="display: none;"> | |
<h3 class="font-semibold text-gray-700">Net Present Value</h3> | |
<div class="result-value" id="npv-value">$0.00</div> | |
<div class="mt-2 text-sm text-gray-600"> | |
<span id="npv-assessment">NPV assessment will appear here</span> | |
</div> | |
</div> | |
</div> | |
<!-- NPV Visualization --> | |
<div class="card p-6" id="npv-visualization" style="display: none;"> | |
<h2 class="text-xl font-bold mb-4 text-gray-800 flex items-center gap-2"> | |
<i class="fas fa-chart-line text-amber-500"></i> | |
NPV Cash Flow Timeline | |
</h2> | |
<div class="visual-container"> | |
<div class="visual-title">Discounted Cash Flows</div> | |
<div class="h-48 flex items-end justify-center gap-1" id="npv-chart"> | |
<!-- Bars will be added by JavaScript --> | |
</div> | |
</div> | |
<div class="mt-4 p-4 bg-amber-50 rounded-lg"> | |
<h4 class="font-semibold text-amber-800 mb-2">NPV Decision Rule</h4> | |
<div class="text-sm text-amber-700"> | |
<div class="flex items-center mb-1"><span class="inline-block w-3 h-3 bg-green-500 rounded-full mr-2"></span> Positive NPV: Accept project (adds value)</div> | |
<div class="flex items-center mb-1"><span class="inline-block w-3 h-3 bg-red-500 rounded-full mr-2"></span> Negative NPV: Reject project (destroys value)</div> | |
<div class="flex items-center"><span class="inline-block w-3 h-3 bg-gray-500 rounded-full mr-2"></span> Zero NPV: Indifferent (no value change)</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
<!-- Financial Glossary --> | |
<div class="mt-12 card p-6"> | |
<h2 class="text-xl font-bold mb-4 text-gray-800"> | |
<i class="fas fa-book mr-2 text-indigo-500"></i> | |
Financial Terms Glossary | |
</h2> | |
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4"> | |
<div class="p-4 border border-gray-200 rounded-lg"> | |
<h3 class="font-semibold text-indigo-600 mb-2">LTV (Loan-to-Value)</h3> | |
<p class="text-sm text-gray-600">The ratio of a loan to the value of the asset purchased, expressed as a percentage.</p> | |
</div> | |
<div class="p-4 border border-gray-200 rounded-lg"> | |
<h3 class="font-semibold text-indigo-600 mb-2">DTI (Debt-to-Income)</h3> | |
<p class="text-sm text-gray-600">A personal finance measure comparing an individual's debt payments to their overall income.</p> | |
</div> | |
<div class="p-4 border border-gray-200 rounded-lg"> | |
<h3 class="font-semibold text-indigo-600 mb-2">DSR (Debt Service Ratio)</h3> | |
<p class="text-sm text-gray-600">Measures the cash flow available to meet annual interest and principal payments on debt.</p> | |
</div> | |
<div class="p-4 border border-gray-200 rounded-lg"> | |
<h3 class="font-semibold text-indigo-600 mb-2">ROI (Return on Investment)</h3> | |
<p class="text-sm text-gray-600">A performance measure used to evaluate the efficiency of an investment.</p> | |
</div> | |
<div class="p-4 border border-gray-200 rounded-lg"> | |
<h3 class="font-semibold text-indigo-600 mb-2">NPV (Net Present Value)</h3> | |
<p class="text-sm text-gray-600">The difference between the present value of cash inflows and outflows over a period of time.</p> | |
</div> | |
<div class="p-4 border border-gray-200 rounded-lg"> | |
<h3 class="font-semibold text-indigo-600 mb-2">Amortization</h3> | |
<p class="text-sm text-gray-600">The process of spreading out a loan into a series of fixed payments over time.</p> | |
</div> | |
</div> | |
</div> | |
</div> | |
<script> | |
// Tab switching functionality | |
document.querySelectorAll('.tab').forEach(tab => { | |
tab.addEventListener('click', () => { | |
// Remove active class from all tabs | |
document.querySelectorAll('.tab').forEach(t => t.classList.remove('active')); | |
// Add active class to clicked tab | |
tab.classList.add('active'); | |
// Hide all calculators and visualizations | |
document.querySelectorAll('.card[id$="-calculator"], .card[id$="-visualization"], #mortgage-amortization').forEach(calc => { | |
calc.style.display = 'none'; | |
}); | |
// Show selected calculator and its visualization | |
const tabName = tab.getAttribute('data-tab'); | |
document.getElementById(`${tabName}-calculator`).style.display = 'block'; | |
// Special case for mortgage which has amortization table | |
if (tabName === 'mortgage') { | |
document.getElementById('mortgage-amortization').style.display = 'block'; | |
} else { | |
document.getElementById(`${tabName}-visualization`).style.display = 'block'; | |
} | |
}); | |
}); | |
// Format currency | |
function formatCurrency(amount) { | |
return new Intl.NumberFormat('en-US', { | |
style: 'currency', | |
currency: 'USD', | |
minimumFractionDigits: 2, | |
maximumFractionDigits: 2 | |
}).format(amount); | |
} | |
// Format percentage | |
function formatPercentage(value) { | |
return value.toFixed(2) + '%'; | |
} | |
// Mortgage Calculator | |
function calculateMortgage() { | |
const amount = parseFloat(document.getElementById('mortgage-amount').value) || 0; | |
const rate = parseFloat(document.getElementById('mortgage-rate').value) || 0; | |
const term = parseFloat(document.getElementById('mortgage-term').value) || 0; | |
if (amount <= 0 || rate <= 0 || term <= 0) { | |
alert('Please enter valid values for all fields'); | |
return; | |
} | |
const monthlyRate = rate / 100 / 12; | |
const payments = term * 12; | |
// Calculate monthly payment | |
const monthlyPayment = amount * | |
(monthlyRate * Math.pow(1 + monthlyRate, payments)) / | |
(Math.pow(1 + monthlyRate, payments) - 1); | |
// Calculate total payment and interest | |
const totalPayment = monthlyPayment * payments; | |
const totalInterest = totalPayment - amount; | |
// Display results | |
document.getElementById('monthly-payment').textContent = formatCurrency(monthlyPayment); | |
document.getElementById('total-interest').textContent = formatCurrency(totalInterest); | |
document.getElementById('total-payment').textContent = formatCurrency(totalPayment); | |
document.getElementById('mortgage-result').style.display = 'block'; | |
// Generate amortization table | |
generateAmortizationTable(amount, rate, term, monthlyPayment); | |
} | |
// Generate amortization table | |
function generateAmortizationTable(amount, rate, term, monthlyPayment) { | |
const tableBody = document.getElementById('amortization-body'); | |
tableBody.innerHTML = ''; | |
let balance = amount; | |
const monthlyRate = rate / 100 / 12; | |
const totalPayments = term * 12; | |
let totalInterest = 0; | |
// Calculate for each year | |
for (let year = 1; year <= term; year++) { | |
let yearInterest = 0; | |
let yearPrincipal = 0; | |
// Calculate for each month in the year | |
for (let month = 1; month <= 12 && (year-1)*12+month <= totalPayments; month++) { | |
const interestPayment = balance * monthlyRate; | |
const principalPayment = monthlyPayment - interestPayment; | |
yearInterest += interestPayment; | |
yearPrincipal += principalPayment; | |
balance -= principalPayment; | |
} | |
totalInterest += yearInterest; | |
// Add row to table | |
const row = document.createElement('tr'); | |
row.innerHTML = ` | |
<td>${year}</td> | |
<td>${formatCurrency(yearPrincipal)}</td> | |
<td>${formatCurrency(yearInterest)}</td> | |
<td>${formatCurrency(balance)}</td> | |
`; | |
tableBody.appendChild(row); | |
} | |
// Show the amortization table | |
document.getElementById('mortgage-amortization').style.display = 'block'; | |
} | |
// LTV Calculator | |
function calculateLTV() { | |
const loanAmount = parseFloat(document.getElementById('loan-amount').value) || 0; | |
const propertyValue = parseFloat(document.getElementById('property-value').value) || 0; | |
if (loanAmount <= 0 || propertyValue <= 0) { | |
alert('Please enter valid values for all fields'); | |
return; | |
} | |
const ltv = (loanAmount / propertyValue) * 100; | |
// Display results | |
document.getElementById('ltv-ratio').textContent = formatPercentage(ltv); | |
// Update visualization | |
document.getElementById('ltv-bar').style.width = `${Math.min(100, ltv)}%`; | |
document.getElementById('ltv-bar-label').textContent = formatPercentage(ltv); | |
document.getElementById('visual-loan-amount').textContent = formatCurrency(loanAmount); | |
document.getElementById('visual-property-value').textContent = formatCurrency(propertyValue); | |
// Assessment | |
let assessment = ''; | |
if (ltv <= 80) { | |
assessment = 'Excellent - You may qualify for the best mortgage rates.'; | |
document.getElementById('ltv-bar').style.backgroundColor = '#10b981'; | |
} else if (ltv <= 90) { | |
assessment = 'Good - You may need to pay Private Mortgage Insurance (PMI).'; | |
document.getElementById('ltv-bar').style.backgroundColor = '#f59e0b'; | |
} else { | |
assessment = 'High Risk - You may have difficulty qualifying for a loan.'; | |
document.getElementById('ltv-bar').style.backgroundColor = '#ef4444'; | |
} | |
document.getElementById('ltv-assessment').textContent = assessment; | |
document.getElementById('ltv-result').style.display = 'block'; | |
document.getElementById('ltv-visualization').style.display = 'block'; | |
} | |
// DTI Calculator | |
function calculateDTI() { | |
const monthlyDebt = parseFloat(document.getElementById('monthly-debt').value) || 0; | |
const grossIncome = parseFloat(document.getElementById('gross-income').value) || 0; | |
if (monthlyDebt <= 0 || grossIncome <= 0) { | |
alert('Please enter valid values for all fields'); | |
return; | |
} | |
const dti = (monthlyDebt / grossIncome) * 100; | |
// Display results | |
document.getElementById('dti-ratio').textContent = formatPercentage(dti); | |
// Update visualization | |
document.getElementById('dti-bar').style.width = `${Math.min(100, dti)}%`; | |
document.getElementById('dti-bar-label').textContent = formatPercentage(dti); | |
document.getElementById('visual-income').textContent = formatCurrency(grossIncome); | |
document.getElementById('visual-debt').textContent = formatCurrency(monthlyDebt); | |
// Assessment | |
let assessment = ''; | |
if (dti <= 35) { | |
assessment = 'Excellent - You have a healthy debt-to-income ratio.'; | |
document.getElementById('dti-bar').style.backgroundColor = '#10b981'; | |
} else if (dti <= 43) { | |
assessment = 'Good - Most lenders will approve loans with this DTI.'; | |
document.getElementById('dti-bar').style.backgroundColor = '#f59e0b'; | |
} else if (dti <= 50) { | |
assessment = 'Fair - You may qualify but could face higher rates.'; | |
document.getElementById('dti-bar').style.backgroundColor = '#ef4444'; | |
} else { | |
assessment = 'High Risk - You may have difficulty qualifying for new credit.'; | |
document.getElementById('dti-bar').style.backgroundColor = '#dc2626'; | |
} | |
document.getElementById('dti-assessment').textContent = assessment; | |
document.getElementById('dti-result').style.display = 'block'; | |
document.getElementById('dti-visualization').style.display = 'block'; | |
} | |
// DSR Calculator | |
function calculateDSR() { | |
const annualDebt = parseFloat(document.getElementById('annual-debt').value) || 0; | |
const netIncome = parseFloat(document.getElementById('net-income').value) || 0; | |
if (annualDebt <= 0 || netIncome <= 0) { | |
alert('Please enter valid values for all fields'); | |
return; | |
} | |
const dsr = (annualDebt / netIncome) * 100; | |
// Display results | |
document.getElementById('dsr-ratio').textContent = formatPercentage(dsr); | |
// Update visualization | |
document.getElementById('dsr-bar').style.width = `${Math.min(100, dsr)}%`; | |
document.getElementById('dsr-bar-label').textContent = formatPercentage(dsr); | |
document.getElementById('visual-net-income').textContent = formatCurrency(netIncome); | |
document.getElementById('visual-annual-debt').textContent = formatCurrency(annualDebt); | |
// Assessment | |
let assessment = ''; | |
if (dsr <= 20) { | |
assessment = 'Excellent - Very comfortable debt service coverage.'; | |
document.getElementById('dsr-bar').style.backgroundColor = '#10b981'; | |
} else if (dsr <= 35) { | |
assessment = 'Good - Manageable debt service obligations.'; | |
document.getElementById('dsr-bar').style.backgroundColor = '#f59e0b'; | |
} else if (dsr <= 50) { | |
assessment = 'Fair - Approaching high debt service levels.'; | |
document.getElementById('dsr-bar').style.backgroundColor = '#ef4444'; | |
} else { | |
assessment = 'High Risk - Debt service may be unsustainable.'; | |
document.getElementById('dsr-bar').style.backgroundColor = '#dc2626'; | |
} | |
document.getElementById('dsr-assessment').textContent = assessment; | |
document.getElementById('dsr-result').style.display = 'block'; | |
document.getElementById('dsr-visualization').style.display = 'block'; | |
} | |
// ROI Calculator | |
function calculateROI() { | |
const gain = parseFloat(document.getElementById('investment-gain').value) || 0; | |
const cost = parseFloat(document.getElementById('investment-cost').value) || 0; | |
if (cost <= 0) { | |
alert('Please enter valid values for all fields'); | |
return; | |
} | |
const roi = ((gain - cost) / cost) * 100; | |
// Display results | |
document.getElementById('roi-percentage').textContent = formatPercentage(roi); | |
// Update visualization | |
document.getElementById('roi-circle-value').textContent = formatPercentage(roi); | |
document.getElementById('visual-investment-cost').textContent = formatCurrency(cost); | |
document.getElementById('visual-investment-gain').textContent = formatCurrency(gain); | |
// Set circle color based on ROI | |
const roiCircle = document.getElementById('roi-circle'); | |
if (roi > 0) { | |
roiCircle.style.borderColor = '#10b981'; | |
roiCircle.style.backgroundColor = '#ecfdf5'; | |
} else if (roi < 0) { | |
roiCircle.style.borderColor = '#ef4444'; | |
roiCircle.style.backgroundColor = '#fee2e2'; | |
} else { | |
roiCircle.style.borderColor = '#9ca3af'; | |
roiCircle.style.backgroundColor = '#f3f4f6'; | |
} | |
// Assessment | |
let assessment = ''; | |
if (roi > 0) { | |
assessment = 'Positive Return - Your investment is profitable.'; | |
} else if (roi < 0) { | |
assessment = 'Negative Return - Your investment is losing money.'; | |
} else { | |
assessment = 'Break Even - Your investment has neither gained nor lost value.'; | |
} | |
document.getElementById('roi-assessment').textContent = assessment; | |
document.getElementById('roi-result').style.display = 'block'; | |
document.getElementById('roi-visualization').style.display = 'block'; | |
} | |
// NPV Calculator | |
function calculateNPV() { | |
const initialInvestment = parseFloat(document.getElementById('initial-investment').value) || 0; | |
const discountRate = parseFloat(document.getElementById('discount-rate').value) || 0; | |
const cashFlowsInput = document.getElementById('cash-flows').value; | |
if (isNaN(initialInvestment) || isNaN(discountRate) || !cashFlowsInput) { | |
alert('Please enter valid values for all fields'); | |
return; | |
} | |
// Parse cash flows | |
const cashFlows = cashFlowsInput.split(',').map(item => { | |
return parseFloat(item.trim()) || 0; | |
}); | |
// Calculate NPV | |
let npv = -initialInvestment; | |
const rate = discountRate / 100; | |
// Clear previous chart | |
const npvChart = document.getElementById('npv-chart'); | |
npvChart.innerHTML = ''; | |
// Calculate discounted cash flows and create chart bars | |
let maxHeight = 0; | |
const discountedFlows = []; | |
for (let i = 0; i < cashFlows.length; i++) { | |
const discounted = cashFlows[i] / Math.pow(1 + rate, i + 1); | |
discountedFlows.push(discounted); | |
if (Math.abs(discounted) > maxHeight) { | |
maxHeight = Math.abs(discounted); | |
} | |
} | |
// Add initial investment bar | |
const initialBar = document.createElement('div'); | |
initialBar.className = 'flex flex-col items-center w-8'; | |
const initialHeight = (Math.abs(initialInvestment) / maxHeight) * 100; | |
initialBar.innerHTML = ` | |
<div class="w-full bg-red-500 rounded-t-sm" style="height: ${initialHeight}%"></div> | |
<div class="text-xs mt-1">Year 0</div> | |
<div class="text-xs">${formatCurrency(-initialInvestment)}</div> | |
`; | |
npvChart.appendChild(initialBar); | |
// Add cash flow bars | |
for (let i = 0; i < discountedFlows.length; i++) { | |
const discounted = discountedFlows[i]; | |
npv += discounted; | |
const bar = document.createElement('div'); | |
bar.className = 'flex flex-col items-center w-8'; | |
const height = (Math.abs(discounted) / maxHeight) * 100; | |
const color = discounted >= 0 ? 'bg-green-500' : 'bg-red-500'; | |
bar.innerHTML = ` | |
<div class="w-full ${color} rounded-t-sm" style="height: ${height}%"></div> | |
<div class="text-xs mt-1">Year ${i+1}</div> | |
<div class="text-xs">${formatCurrency(discounted)}</div> | |
`; | |
npvChart.appendChild(bar); | |
} | |
// Display results | |
document.getElementById('npv-value').textContent = formatCurrency(npv); | |
// Assessment | |
let assessment = ''; | |
if (npv > 0) { | |
assessment = 'Positive NPV - This investment adds value and should be considered.'; | |
} else if (npv < 0) { | |
assessment = 'Negative NPV - This investment would destroy value.'; | |
} else { | |
assessment = 'Break Even - The investment neither adds nor subtracts value.'; | |
} | |
document.getElementById('npv-assessment').textContent = assessment; | |
document.getElementById('npv-result').style.display = 'block'; | |
document.getElementById('npv-visualization').style.display = 'block'; | |
} | |
</script> | |
</html> |