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> |