303 lines
12 KiB
HTML
303 lines
12 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="de">
|
|
<head>
|
|
<meta charset="UTF-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
<title>Kaufen oder Mieten?</title>
|
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet" />
|
|
<link rel="stylesheet" href="style.css" />
|
|
</head>
|
|
<body>
|
|
|
|
<header>
|
|
<div class="header-inner">
|
|
<h1>Kaufen oder Mieten?</h1>
|
|
<p class="subtitle">Kein Bauchgefühl. Nur Zahlen.</p>
|
|
</div>
|
|
</header>
|
|
|
|
<main>
|
|
|
|
<!-- Shared inputs -->
|
|
<section class="inputs-shared card">
|
|
<div class="input-group">
|
|
<label for="start_capital">Startkapital <span class="hint">(verfügbares Eigenkapital gesamt)</span></label>
|
|
<div class="num-unit euro-input">
|
|
<span class="unit prefix">€</span>
|
|
<input type="number" id="start_capital" min="0" max="10000000" step="1000" value="100000" />
|
|
</div>
|
|
</div>
|
|
<div class="input-group">
|
|
<label for="years">Zeithorizont</label>
|
|
<div class="slider-row">
|
|
<input type="range" id="years_slider" min="2" max="40" step="1" value="15" />
|
|
<div class="num-unit">
|
|
<input type="number" id="years" min="2" max="40" value="15" />
|
|
<span class="unit">Jahre</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="input-group">
|
|
<label for="invest_return">ETF-Rendite (p.a.)</label>
|
|
<div class="slider-row">
|
|
<input type="range" id="invest_return_slider" min="1" max="15" step="0.1" value="6" />
|
|
<div class="num-unit">
|
|
<input type="number" id="invest_return" min="1" max="15" step="0.1" value="6" />
|
|
<span class="unit">%</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="input-group">
|
|
<label for="tax_rate">Abgeltungssteuer (inkl. Soli)</label>
|
|
<div class="slider-row">
|
|
<input type="range" id="tax_rate_slider" min="0" max="50" step="0.1" value="26.375" />
|
|
<div class="num-unit">
|
|
<input type="number" id="tax_rate" min="0" max="50" step="0.1" value="26.375" />
|
|
<span class="unit">%</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Two-column inputs -->
|
|
<div class="inputs-columns">
|
|
|
|
<!-- Buy inputs -->
|
|
<section class="card inputs-buy">
|
|
<h2 class="col-header buy-header">Kaufen</h2>
|
|
|
|
<div class="input-group">
|
|
<label for="home_price">Kaufpreis</label>
|
|
<div class="num-unit euro-input">
|
|
<span class="unit prefix">€</span>
|
|
<input type="number" id="home_price" min="50000" max="5000000" step="1000" value="400000" />
|
|
</div>
|
|
</div>
|
|
|
|
<div class="input-group">
|
|
<label for="down_pct">Eigenkapital</label>
|
|
<div class="slider-row">
|
|
<input type="range" id="down_pct_slider" min="0" max="100" step="1" value="25" />
|
|
<div class="num-unit">
|
|
<input type="number" id="down_pct" min="0" max="100" step="1" value="25" />
|
|
<span class="unit">%</span>
|
|
</div>
|
|
</div>
|
|
<span class="cap-msg" id="down_pct_cap">Maximum gegeben das Startkapital</span>
|
|
</div>
|
|
|
|
<div class="input-group">
|
|
<label for="interest_rate">Zinssatz (p.a.)</label>
|
|
<div class="slider-row">
|
|
<input type="range" id="interest_rate_slider" min="0.5" max="12" step="0.05" value="3.8" />
|
|
<div class="num-unit">
|
|
<input type="number" id="interest_rate" min="0.5" max="12" step="0.05" value="3.8" />
|
|
<span class="unit">%</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="input-group">
|
|
<label for="loan_years">Tilgungsdauer</label>
|
|
<div class="slider-row">
|
|
<input type="range" id="loan_years_slider" min="5" max="40" step="1" value="20" />
|
|
<div class="num-unit">
|
|
<input type="number" id="loan_years" min="5" max="40" step="1" value="20" />
|
|
<span class="unit">Jahre</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="input-group">
|
|
<label for="closing_buy_pct">Kaufnebenkosten <span class="hint">(Steuer + Notar + Makler)</span></label>
|
|
<div class="slider-row">
|
|
<input type="range" id="closing_buy_pct_slider" min="3" max="20" step="0.1" value="10" />
|
|
<div class="num-unit">
|
|
<input type="number" id="closing_buy_pct" min="3" max="20" step="0.1" value="10" />
|
|
<span class="unit">%</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="input-group toggle-group">
|
|
<label class="toggle-label" for="finance_nebenkosten">
|
|
<span>Nebenkosten mitfinanzieren</span>
|
|
<span class="hint">in Hypothek einrechnen</span>
|
|
</label>
|
|
<label class="toggle-switch">
|
|
<input type="checkbox" id="finance_nebenkosten" />
|
|
<span class="toggle-track"><span class="toggle-thumb"></span></span>
|
|
</label>
|
|
</div>
|
|
|
|
<div class="input-group">
|
|
<label for="closing_sell_pct">Verkaufsnebenkosten <span class="hint">(Makler)</span></label>
|
|
<div class="slider-row">
|
|
<input type="range" id="closing_sell_pct_slider" min="0" max="10" step="0.1" value="3.57" />
|
|
<div class="num-unit">
|
|
<input type="number" id="closing_sell_pct" min="0" max="10" step="0.1" value="3.57" />
|
|
<span class="unit">%</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="input-group">
|
|
<label for="appreciation">Wertsteigerung (p.a.)</label>
|
|
<div class="slider-row">
|
|
<input type="range" id="appreciation_slider" min="-2" max="10" step="0.1" value="2.5" />
|
|
<div class="num-unit">
|
|
<input type="number" id="appreciation" min="-2" max="10" step="0.1" value="2.5" />
|
|
<span class="unit">%</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="input-group">
|
|
<label for="prop_tax_rate">Grundsteuer (p.a.)</label>
|
|
<div class="slider-row">
|
|
<input type="range" id="prop_tax_rate_slider" min="0.1" max="2" step="0.05" value="0.35" />
|
|
<div class="num-unit">
|
|
<input type="number" id="prop_tax_rate" min="0.1" max="2" step="0.05" value="0.35" />
|
|
<span class="unit">%</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="input-group">
|
|
<label for="maint_rate">Instandhaltung (p.a.)</label>
|
|
<div class="slider-row">
|
|
<input type="range" id="maint_rate_slider" min="0.1" max="3" step="0.1" value="1" />
|
|
<div class="num-unit">
|
|
<input type="number" id="maint_rate" min="0.1" max="3" step="0.1" value="1" />
|
|
<span class="unit">%</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="input-group">
|
|
<label for="insurance">Gebäudeversicherung (p.a.)</label>
|
|
<div class="num-unit euro-input">
|
|
<span class="unit prefix">€</span>
|
|
<input type="number" id="insurance" min="0" max="10000" step="100" value="800" />
|
|
</div>
|
|
</div>
|
|
|
|
</section>
|
|
|
|
<!-- Rent inputs -->
|
|
<section class="card inputs-rent">
|
|
<h2 class="col-header rent-header">Mieten</h2>
|
|
|
|
<div class="input-group">
|
|
<label for="monthly_rent">Kaltmiete (monatlich)</label>
|
|
<div class="num-unit euro-input">
|
|
<span class="unit prefix">€</span>
|
|
<input type="number" id="monthly_rent" min="200" max="20000" step="50" value="1400" />
|
|
</div>
|
|
</div>
|
|
|
|
<div class="input-group">
|
|
<label for="rent_increase">Mieterhöhung (p.a.)</label>
|
|
<div class="slider-row">
|
|
<input type="range" id="rent_increase_slider" min="0" max="10" step="0.1" value="2.5" />
|
|
<div class="num-unit">
|
|
<input type="number" id="rent_increase" min="0" max="10" step="0.1" value="2.5" />
|
|
<span class="unit">%</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="input-group">
|
|
<label for="renters_ins">Haftpflicht / Hausrat (p.a.)</label>
|
|
<div class="num-unit euro-input">
|
|
<span class="unit prefix">€</span>
|
|
<input type="number" id="renters_ins" min="0" max="2000" step="50" value="200" />
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Spacer info card -->
|
|
<div class="info-box">
|
|
<p>Der Mieter investiert das nicht ausgegebene Eigenkapital + Nebenkosten in einen ETF. Wenn Kaufen teurer ist, fließt die monatliche Differenz ebenfalls ins Portfolio.</p>
|
|
</div>
|
|
|
|
</section>
|
|
</div>
|
|
|
|
<!-- Results -->
|
|
<section class="results">
|
|
<div class="result-cards">
|
|
<div class="result-card buy-card">
|
|
<div class="result-label">Nettovermögen Kauf</div>
|
|
<div class="result-value" id="res_buyer_nw">—</div>
|
|
<div class="result-sub" id="res_buy_cost">Gesamtausgaben: —</div>
|
|
<div class="result-sub" style="color:var(--text-hint)">inkl. Verkaufskosten</div>
|
|
</div>
|
|
<div class="result-card rent-card">
|
|
<div class="result-label">Nettovermögen Miete</div>
|
|
<div class="result-value" id="res_renter_nw">—</div>
|
|
<div class="result-sub" id="res_rent_cost">Gesamtausgaben: —</div>
|
|
</div>
|
|
<div class="result-card breakeven-card">
|
|
<div class="result-label">Break-Even</div>
|
|
<div class="result-value" id="res_breakeven">—</div>
|
|
<div class="result-sub" id="res_winner_badge"></div>
|
|
</div>
|
|
</div>
|
|
<div class="monthly-payment-note" id="res_monthly_payment"></div>
|
|
</section>
|
|
|
|
<!-- Charts -->
|
|
<section class="charts card">
|
|
<div class="chart-title">Nettovermögen im Zeitverlauf</div>
|
|
<div class="chart-legend">
|
|
<span class="legend-dot buy-dot"></span> Kaufen
|
|
<span class="legend-dot rent-dot"></span> Mieten (ETF)
|
|
</div>
|
|
<div class="chart-wrap"><canvas id="chart_nw"></canvas></div>
|
|
</section>
|
|
|
|
<section class="charts card">
|
|
<div class="chart-title">Kumulierte Ausgaben (Cash out-of-pocket)</div>
|
|
<div class="chart-legend">
|
|
<span class="legend-dot buy-dot"></span> Kaufen
|
|
<span class="legend-dot rent-dot"></span> Mieten
|
|
</div>
|
|
<div class="chart-wrap"><canvas id="chart_cost"></canvas></div>
|
|
</section>
|
|
|
|
<!-- Yearly table -->
|
|
<section class="card table-section">
|
|
<button class="table-toggle" id="table_toggle" aria-expanded="false">
|
|
<span class="toggle-icon">▶</span> Jährliche Übersicht anzeigen
|
|
</button>
|
|
<div class="table-wrap" id="table_wrap" hidden>
|
|
<table id="breakdown_table">
|
|
<thead>
|
|
<tr>
|
|
<th>Jahr</th>
|
|
<th>Nettovermögen Kauf</th>
|
|
<th>Nettovermögen Miete</th>
|
|
<th>Ausgaben Kauf</th>
|
|
<th>Ausgaben Miete</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="table_body"></tbody>
|
|
</table>
|
|
</div>
|
|
</section>
|
|
|
|
</main>
|
|
|
|
<footer>
|
|
<p>Diese Berechnung dient nur zur Orientierung — kein Finanzberatungsersatz.</p>
|
|
</footer>
|
|
|
|
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.4/dist/chart.umd.min.js"></script>
|
|
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-annotation@3.0.1/dist/chartjs-plugin-annotation.min.js"></script>
|
|
<script src="calc.js"></script>
|
|
<script src="ui.js"></script>
|
|
</body>
|
|
</html>
|