Kalkulator KPR

<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Kalkulator KPR Terlengkap — Cicil Cerdas</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700&family=DM+Mono:wght@400;500&display=swap" rel="stylesheet">
<style>
:root {
  --green: #0B6E4F;
  --green-mid: #1A9E75;
  --green-light: #D6F5EB;
  --green-glow: #2FD99A;
  --amber: #C87B00;
  --amber-light: #FFF3D6;
  --red: #C0392B;
  --red-light: #FDECEA;
  --blue: #1A5FA5;
  --blue-light: #E6F0FB;
  --gray-0: #F7F8FA;
  --gray-1: #EFF1F5;
  --gray-2: #DDE1EA;
  --gray-3: #A8B0C0;
  --gray-4: #6B7585;
  --gray-5: #3A3F4B;
  --gray-6: #1C2028;
  --text: #1C2028;
  --font: 'Plus Jakarta Sans', sans-serif;
  --mono: 'DM Mono', monospace;
  --radius: 14px;
  --radius-sm: 8px;
  --shadow: 0 2px 12px rgba(0,0,0,0.07);
}
* { box-sizing: border-box; margin: 0; padding: 0; }
body { font-family: var(--font); background: var(--gray-0); color: var(--text); min-height: 100vh; }

/* HEADER */
header { background: var(--green); }
.header-inner { max-width: 1000px; margin: 0 auto; padding: 20px 24px 0; }
.logo { display: flex; align-items: center; gap: 10px; margin-bottom: 18px; }
.logo-mark { width: 36px; height: 36px; background: var(--green-glow); border-radius: 10px; display: flex; align-items: center; justify-content: center; font-weight: 700; font-size: 15px; color: var(--green); }
.logo-text { font-size: 17px; font-weight: 700; color: white; letter-spacing: -0.3px; }
.logo-sub { font-size: 10px; color: rgba(255,255,255,0.55); }
.header-hero h1 { font-size: 24px; font-weight: 700; color: white; letter-spacing: -0.4px; margin-bottom: 5px; }
.header-hero p { font-size: 13px; color: rgba(255,255,255,0.6); margin-bottom: 18px; }
.header-tabs { display: flex; gap: 2px; }
.htab { padding: 9px 18px; font-size: 13px; font-weight: 500; color: rgba(255,255,255,0.55); cursor: pointer; border-radius: 8px 8px 0 0; border: none; background: transparent; transition: all 0.15s; font-family: var(--font); }
.htab:hover { color: rgba(255,255,255,0.85); background: rgba(255,255,255,0.07); }
.htab.active { color: var(--text); background: var(--gray-0); }

/* LAYOUT */
.main { max-width: 1000px; margin: 0 auto; padding: 20px 24px 40px; display: grid; grid-template-columns: 330px 1fr; gap: 20px; align-items: start; }
.panel { display: none; }
.panel.active { display: block; }

/* CARDS */
.card { background: white; border-radius: var(--radius); box-shadow: var(--shadow); border: 1px solid var(--gray-2); }
.card-head { padding: 14px 18px 12px; border-bottom: 1px solid var(--gray-1); display: flex; align-items: center; gap: 8px; }
.card-head h3 { font-size: 12px; font-weight: 700; color: var(--gray-5); text-transform: uppercase; letter-spacing: 0.5px; }
.card-icon { width: 22px; height: 22px; background: var(--green-light); border-radius: 6px; display: flex; align-items: center; justify-content: center; font-size: 11px; }
.card-body { padding: 16px 18px; }

/* INPUTS */
.input-group { margin-bottom: 16px; }
.input-group:last-child { margin-bottom: 0; }
.input-label { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 7px; }
.input-label .lbl { font-size: 11px; font-weight: 700; color: var(--gray-5); text-transform: uppercase; letter-spacing: 0.5px; }
.input-label .val { font-family: var(--mono); font-size: 12px; color: var(--green); font-weight: 500; }
input[type=range] { width: 100%; height: 4px; -webkit-appearance: none; appearance: none; background: var(--gray-2); border-radius: 2px; cursor: pointer; }
input[type=range]::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 16px; height: 16px; border-radius: 50%; background: var(--green); border: 3px solid white; box-shadow: 0 0 0 1.5px var(--green); cursor: grab; }
.range-hints { display: flex; justify-content: space-between; margin-top: 3px; }
.range-hints span { font-size: 9px; color: var(--gray-3); font-family: var(--mono); }
select { width: 100%; padding: 8px 10px; border: 1.5px solid var(--gray-2); border-radius: var(--radius-sm); font-size: 12px; font-family: var(--font); color: var(--text); background: white; cursor: pointer; appearance: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%236B7585' stroke-width='2'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 10px center; }
select:focus { outline: none; border-color: var(--green-mid); }

/* METRICS */
.metric-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-bottom: 14px; }
.mc { background: white; border-radius: var(--radius); padding: 12px 14px; box-shadow: var(--shadow); border: 1px solid var(--gray-2); }
.mc.accent { background: var(--green); border-color: var(--green); grid-column: span 2; }
.mc-label { font-size: 10px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px; color: var(--gray-3); margin-bottom: 5px; }
.mc.accent .mc-label { color: rgba(255,255,255,0.55); }
.mc-val { font-size: 20px; font-weight: 700; color: var(--text); font-family: var(--mono); letter-spacing: -0.5px; }
.mc.accent .mc-val { color: white; font-size: 26px; }
.mc-sub { font-size: 10px; color: var(--gray-3); margin-top: 2px; }
.mc.accent .mc-sub { color: rgba(255,255,255,0.5); }

/* HEALTH */
.health-card { background: white; border-radius: var(--radius); padding: 14px; box-shadow: var(--shadow); border: 1px solid var(--gray-2); margin-bottom: 14px; }
.health-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; }
.health-title { font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.5px; color: var(--gray-5); }
.health-pct { font-family: var(--mono); font-size: 15px; font-weight: 700; }
.health-track { height: 8px; background: var(--gray-1); border-radius: 4px; overflow: hidden; margin-bottom: 6px; }
.health-fill { height: 100%; border-radius: 4px; transition: width 0.4s, background 0.3s; }
.health-zones { display: flex; margin-bottom: 6px; }
.zone { flex: 1; font-size: 9px; text-align: center; color: var(--gray-3); line-height: 1.3; }
.health-msg { font-size: 11px; line-height: 1.5; padding: 8px 10px; border-radius: var(--radius-sm); font-weight: 600; }

/* RESULT TABS */
.result-tabs { display: flex; gap: 4px; margin-bottom: 14px; flex-wrap: wrap; }
.rtab { padding: 6px 13px; font-size: 11px; font-weight: 700; border-radius: 20px; cursor: pointer; border: 1.5px solid var(--gray-2); background: white; color: var(--gray-4); transition: all 0.15s; font-family: var(--font); }
.rtab:hover { border-color: var(--green-mid); color: var(--green); }
.rtab.active { background: var(--green); color: white; border-color: var(--green); }
.rp { display: none; }
.rp.active { display: block; }

/* TABLE */
.amort-wrap { overflow-x: auto; }
table { width: 100%; border-collapse: collapse; font-size: 11px; table-layout: fixed; }
thead th { text-align: left; padding: 7px 8px; background: var(--gray-0); border-bottom: 1px solid var(--gray-2); font-size: 9px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.5px; color: var(--gray-4); }
tbody td { padding: 8px 8px; border-bottom: 1px solid var(--gray-1); color: var(--gray-5); font-family: var(--mono); font-size: 11px; }
tbody tr:hover td { background: var(--gray-0); }
tbody tr.hl td { background: var(--green-light); color: var(--green); font-weight: 700; }
.td-lbl { font-family: var(--font) !important; font-weight: 600 !important; color: var(--text) !important; }

/* BARS */
.bar-chart { }
.bc-row { display: flex; align-items: center; gap: 8px; margin-bottom: 7px; }
.bc-lbl { font-size: 10px; color: var(--gray-4); width: 65px; text-align: right; flex-shrink: 0; }
.bc-track { flex: 1; height: 16px; background: var(--gray-1); border-radius: 3px; overflow: hidden; display: flex; }
.bc-fill { height: 100%; border-radius: 3px; transition: width 0.5s ease; }
.bc-val { font-family: var(--mono); font-size: 10px; color: var(--text); width: 75px; font-weight: 600; flex-shrink: 0; }

/* BANK GRID */
.bank-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 8px; }
.bank-card { border: 1.5px solid var(--gray-2); border-radius: var(--radius); padding: 12px; background: white; }
.bank-card.best { border-color: var(--green-mid); background: #F0FBF6; }
.bank-name { font-size: 12px; font-weight: 700; color: var(--text); margin-bottom: 2px; }
.bank-rate { font-size: 10px; color: var(--gray-4); margin-bottom: 7px; font-family: var(--mono); }
.bank-cicilan { font-family: var(--mono); font-size: 15px; font-weight: 700; color: var(--green); }
.bank-sub { font-size: 9px; color: var(--gray-3); margin-top: 2px; }
.best-badge { display: inline-block; font-size: 8px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.5px; background: var(--green); color: white; padding: 2px 6px; border-radius: 20px; margin-bottom: 5px; }

/* BIAYA */
.biaya-row { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; padding: 10px 0; border-bottom: 1px solid var(--gray-1); }
.biaya-row:last-child { border-bottom: none; }
.biaya-name { font-size: 12px; font-weight: 600; color: var(--text); margin-bottom: 2px; }
.biaya-note { font-size: 10px; color: var(--gray-3); }
.biaya-amount { font-family: var(--mono); font-size: 12px; font-weight: 700; color: var(--text); white-space: nowrap; flex-shrink: 0; }
.biaya-total { display: flex; justify-content: space-between; align-items: center; padding: 12px 14px; border-radius: var(--radius-sm); background: var(--green-light); margin-top: 10px; }
.biaya-total span { font-size: 12px; font-weight: 700; color: var(--green); }
.biaya-total .amount { font-family: var(--mono); font-size: 15px; }

/* PELUNASAN */
.pl-card { background: var(--gray-0); border-radius: var(--radius-sm); padding: 12px; margin-bottom: 8px; border: 1px solid var(--gray-1); }
.pl-card.best { background: var(--green-light); border-color: var(--green-mid); }
.pl-head { font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.5px; color: var(--gray-4); margin-bottom: 7px; }
.pl-card.best .pl-head { color: var(--green); }
.pl-row { display: flex; justify-content: space-between; margin-bottom: 3px; font-size: 11px; }
.pl-key { color: var(--gray-4); }
.pl-val { font-family: var(--mono); font-weight: 600; color: var(--text); }
.pl-save { color: var(--green); }

/* TOOLTIP */
.tip { position: relative; display: inline-block; cursor: help; }
.tip-icon { width: 13px; height: 13px; border-radius: 50%; background: var(--gray-2); color: var(--gray-4); font-size: 8px; font-weight: 700; display: inline-flex; align-items: center; justify-content: center; margin-left: 3px; vertical-align: middle; }
.tip-txt { display: none; position: absolute; left: 0; top: 18px; background: var(--gray-6); color: white; padding: 6px 10px; border-radius: var(--radius-sm); font-size: 10px; font-weight: 400; width: 190px; line-height: 1.4; z-index: 10; }
.tip:hover .tip-txt { display: block; }

/* INFO BOX */
.info-box { padding: 9px 12px; border-radius: var(--radius-sm); font-size: 11px; line-height: 1.55; margin-top: 10px; }
.info-green { background: var(--green-light); color: var(--green); border-left: 3px solid var(--green-mid); border-radius: 0 var(--radius-sm) var(--radius-sm) 0; }
.info-amber { background: var(--amber-light); color: var(--amber); border-left: 3px solid var(--amber); border-radius: 0 var(--radius-sm) var(--radius-sm) 0; }
.info-red { background: var(--red-light); color: var(--red); border-left: 3px solid var(--red); border-radius: 0 var(--radius-sm) var(--radius-sm) 0; }
.info-blue { background: var(--blue-light); color: var(--blue); border-left: 3px solid var(--blue); border-radius: 0 var(--radius-sm) var(--radius-sm) 0; }

/* SECTION TITLE */
.sec-title { font-size: 12px; font-weight: 700; color: var(--text); margin-bottom: 12px; display: flex; align-items: center; gap: 6px; }
.dot { width: 7px; height: 7px; border-radius: 50%; background: var(--green-mid); flex-shrink: 0; }

/* UNGGULAN */
.unggulan-bar { background: white; border: 1.5px solid var(--green-light); border-radius: var(--radius); padding: 10px 14px; margin-bottom: 16px; display: flex; gap: 14px; flex-wrap: wrap; }
.u-item { display: flex; align-items: center; gap: 5px; font-size: 10px; font-weight: 700; color: var(--green); }

/* BUTTONS */
.btn { padding: 7px 14px; border-radius: var(--radius-sm); font-size: 11px; font-weight: 700; cursor: pointer; border: 1.5px solid var(--gray-2); background: white; color: var(--gray-5); font-family: var(--font); transition: all 0.15s; }
.btn:hover { border-color: var(--green-mid); color: var(--green); }
.btn-primary { background: var(--green); color: white; border-color: var(--green); }
.btn-primary:hover { background: var(--green-mid); border-color: var(--green-mid); color: white; }
.export-bar { display: flex; gap: 8px; margin-top: 14px; justify-content: flex-end; }

/* TO GRID */
.to-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-bottom: 20px; }
.to-section-lbl { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.5px; color: var(--gray-4); margin-bottom: 12px; padding-bottom: 8px; border-bottom: 1px solid var(--gray-2); }

@media (max-width: 720px) {
  .main { grid-template-columns: 1fr; }
  .to-grid { grid-template-columns: 1fr; }
}
@media print {
  header { background: white !important; }
  .header-tabs, .htab, .export-bar, .result-tabs, .rtab { display: none !important; }
  .main { display: block; }
  .panel, .rp { display: block !important; }
}
</style>
</head>
<body>

<header>
  <div class="header-inner">
    <div class="logo">
      <div class="logo-mark">CC</div>
      <div>
        <div class="logo-text">Cicil Cerdas</div>
        <div class="logo-sub">Kalkulator KPR Terlengkap Indonesia</div>
      </div>
    </div>
    <div class="header-hero">
      <h1>Simulasi KPR Lengkap &amp; Akurat</h1>
      <p>Hitung cicilan, bandingkan 6 bank, lihat biaya lengkap, dan simulasi percepat lunas — semua dalam satu halaman.</p>
    </div>
    <div class="header-tabs">
      <button class="htab active" onclick="switchMain('kpr',this)">Kalkulator KPR</button>
      <button class="htab" onclick="switchMain('subsidi',this)">KPR Subsidi</button>
      <button class="htab" onclick="switchMain('takeover',this)">Take Over / Refinancing</button>
    </div>
  </div>
</header>

<!-- ===================== PANEL KPR ===================== -->
<div id="panel-kpr" class="panel active">
<div class="main">

  <!-- KIRI: INPUT -->
  <div>
    <div class="unggulan-bar">
      <div class="u-item">&#9889; Real-time</div>
      <div class="u-item">&#127970; 6 bank dibandingkan</div>
      <div class="u-item">&#128203; Skor kelayakan DSR</div>
      <div class="u-item">&#127919; Biaya awal lengkap</div>
    </div>

    <!-- DATA PROPERTI -->
    <div class="card" style="margin-bottom:14px">
      <div class="card-head"><div class="card-icon">&#127968;</div><h3>Data Properti</h3></div>
      <div class="card-body">
        <div class="input-group">
          <div class="input-label">
            <span class="lbl">Harga Properti</span>
            <span class="val" id="v-harga">Rp 500 jt</span>
          </div>
          <input type="range" id="harga" min="100" max="5000" step="50" value="500">
          <div class="range-hints"><span>100 jt</span><span>5 M</span></div>
        </div>
        <div class="input-group">
          <div class="input-label">
            <span class="lbl">Uang Muka (DP)
              <span class="tip"><span class="tip-icon">?</span><span class="tip-txt">Minimal DP KPR konvensional adalah 15–20%. Makin besar DP, cicilan makin ringan dan total bunga makin kecil.</span></span>
            </span>
            <span class="val" id="v-dp">20% = Rp 100 jt</span>
          </div>
          <input type="range" id="dp" min="10" max="50" step="1" value="20">
          <div class="range-hints"><span>10%</span><span>50%</span></div>
        </div>
        <div class="input-group" style="margin-bottom:0">
          <div class="input-label"><span class="lbl">Jenis KPR</span></div>
          <select id="jenis">
            <option value="konvensional">Konvensional (bunga anuitas)</option>
            <option value="syariah">Syariah (margin murabahah tetap)</option>
          </select>
        </div>
      </div>
    </div>

    <!-- KREDIT & BUNGA -->
    <div class="card" style="margin-bottom:14px">
      <div class="card-head"><div class="card-icon">&#128200;</div><h3>Kredit &amp; Suku Bunga</h3></div>
      <div class="card-body">
        <div class="input-group">
          <div class="input-label">
            <span class="lbl">Tenor Pinjaman</span>
            <span class="val" id="v-tenor">20 tahun</span>
          </div>
          <input type="range" id="tenor" min="5" max="30" step="5" value="20">
          <div class="range-hints"><span>5 thn</span><span>30 thn</span></div>
        </div>
        <div class="input-group">
          <div class="input-label">
            <span class="lbl">Bunga Fixed
              <span class="tip"><span class="tip-icon">?</span><span class="tip-txt">Bunga tetap berlaku 1–5 tahun pertama. Setelahnya beralih ke bunga floating mengikuti BI Rate + spread bank.</span></span>
            </span>
            <span class="val" id="v-bunga">8.00% / tahun</span>
          </div>
          <input type="range" id="bunga" min="4" max="15" step="0.25" value="8">
          <div class="range-hints"><span>4%</span><span>15%</span></div>
        </div>
        <div class="input-group" style="margin-bottom:0">
          <div class="input-label">
            <span class="lbl">Estimasi Bunga Floating
              <span class="tip"><span class="tip-icon">?</span><span class="tip-txt">Bunga floating berlaku setelah periode fixed. Estimasi: BI Rate (5.75%) + spread bank (6–8%). Bisa berubah sewaktu-waktu.</span></span>
            </span>
            <span class="val" id="v-floating">12.00% / tahun</span>
          </div>
          <input type="range" id="floating" min="6" max="18" step="0.25" value="12">
          <div class="range-hints"><span>6%</span><span>18%</span></div>
        </div>
      </div>
    </div>

    <!-- DATA PEMOHON -->
    <div class="card">
      <div class="card-head"><div class="card-icon">&#128100;</div><h3>Data Pemohon</h3></div>
      <div class="card-body">
        <div class="input-group">
          <div class="input-label">
            <span class="lbl">Penghasilan Bulanan (bruto)</span>
            <span class="val" id="v-gaji">Rp 15 jt</span>
          </div>
          <input type="range" id="gaji" min="3" max="150" step="1" value="15">
          <div class="range-hints"><span>3 jt</span><span>150 jt</span></div>
        </div>
        <div class="input-group" style="margin-bottom:0">
          <div class="input-label">
            <span class="lbl">Cicilan Lain / Bulan
              <span class="tip"><span class="tip-icon">?</span><span class="tip-txt">Semua cicilan yang sedang berjalan: kartu kredit, cicilan kendaraan, pinjaman online dll. Bank akan menghitung total DSR.</span></span>
            </span>
            <span class="val" id="v-lain">Rp 0</span>
          </div>
          <input type="range" id="cicilan-lain" min="0" max="20" step="0.5" value="0">
          <div class="range-hints"><span>0</span><span>20 jt/bln</span></div>
        </div>
      </div>
    </div>
  </div>

  <!-- KANAN: OUTPUT -->
  <div>
    <!-- METRICS UTAMA -->
    <div class="metric-grid">
      <div class="mc accent">
        <div class="mc-label">Cicilan per bulan (periode fixed)</div>
        <div class="mc-val" id="m-cicilan">—</div>
        <div class="mc-sub" id="m-cicilan-sub">—</div>
      </div>
      <div class="mc">
        <div class="mc-label">Total pokok pinjaman</div>
        <div class="mc-val" id="m-pokok" style="font-size:15px">—</div>
      </div>
      <div class="mc">
        <div class="mc-label">Total bunga / margin</div>
        <div class="mc-val" id="m-bunga" style="font-size:15px;color:var(--amber)">—</div>
      </div>
      <div class="mc">
        <div class="mc-label">Total keseluruhan bayar</div>
        <div class="mc-val" id="m-total" style="font-size:15px">—</div>
      </div>
      <div class="mc">
        <div class="mc-label">Estimasi cicilan floating</div>
        <div class="mc-val" id="m-floating" style="font-size:15px;color:var(--red)">—</div>
        <div class="mc-sub">Setelah periode fixed berakhir</div>
      </div>
    </div>

    <!-- HEALTH METER -->
    <div class="health-card">
      <div class="health-header">
        <span class="health-title">Skor Kelayakan KPR (DSR)</span>
        <span class="health-pct" id="h-pct">—</span>
      </div>
      <div class="health-track"><div class="health-fill" id="h-fill" style="width:0%"></div></div>
      <div class="health-zones">
        <div class="zone">Sangat aman<br>&lt;25%</div>
        <div class="zone">Aman<br>25–33%</div>
        <div class="zone">Hati-hati<br>33–40%</div>
        <div class="zone">Berisiko<br>&gt;40%</div>
      </div>
      <div class="health-msg" id="h-msg">—</div>
      <div id="dsr-box" style="margin-top:7px;font-size:10px;color:var(--gray-4)"></div>
    </div>

    <!-- RESULT TABS -->
    <div class="result-tabs">
      <button class="rtab active" onclick="switchResult('ringkasan',this)">Ringkasan</button>
      <button class="rtab" onclick="switchResult('amort',this)">Amortisasi</button>
      <button class="rtab" onclick="switchResult('grafik',this)">Grafik</button>
      <button class="rtab" onclick="switchResult('bank',this)">6 Bank</button>
      <button class="rtab" onclick="switchResult('percepat',this)">Percepat Lunas</button>
      <button class="rtab" onclick="switchResult('biaya',this)">Biaya Awal</button>
    </div>

    <!-- RINGKASAN -->
    <div id="rp-ringkasan" class="rp active card">
      <div class="card-body">
        <div class="sec-title"><div class="dot"></div>Breakdown Total Pembayaran</div>
        <div id="breakdown-bars" class="bar-chart"></div>
        <div id="rasio-box" style="margin-top:14px"></div>
        <div class="export-bar">
          <button class="btn" onclick="window.print()">&#128424; Cetak / PDF</button>
          <button class="btn btn-primary" onclick="copyResult()">&#128203; Salin Ringkasan</button>
        </div>
      </div>
    </div>

    <!-- AMORTISASI -->
    <div id="rp-amort" class="rp card">
      <div class="card-body">
        <div class="sec-title"><div class="dot"></div>Tabel Amortisasi Tahunan</div>
        <div class="amort-wrap">
          <table>
            <thead>
              <tr>
                <th style="width:60px">Tahun</th>
                <th>Cicilan/bln</th>
                <th>Pokok (thn)</th>
                <th>Bunga (thn)</th>
                <th>Sisa Hutang</th>
                <th style="width:50px">% Lunas</th>
              </tr>
            </thead>
            <tbody id="amort-body"></tbody>
          </table>
        </div>
        <div class="info-box info-green" style="margin-top:10px;font-size:10px">
          &#128161; Baris <strong>hijau</strong> = tahun di mana porsi pokok sudah lebih besar dari bunga (titik balik efisiensi KPR Anda).
        </div>
      </div>
    </div>

    <!-- GRAFIK -->
    <div id="rp-grafik" class="rp card">
      <div class="card-body">
        <div class="sec-title"><div class="dot"></div>Komposisi Cicilan per Tahun</div>
        <div style="display:flex;gap:14px;margin-bottom:12px;font-size:10px">
          <span><span style="display:inline-block;width:10px;height:10px;background:#0B6E4F;border-radius:2px;margin-right:3px"></span>Pokok</span>
          <span><span style="display:inline-block;width:10px;height:10px;background:#C87B00;border-radius:2px;margin-right:3px"></span>Bunga</span>
        </div>
        <div id="grafik-bars" class="bar-chart"></div>
        <div class="info-box info-amber" style="margin-top:10px;font-size:10px">
          &#9888;&#65039; Di awal KPR, sebagian besar cicilan adalah bunga bukan pokok. Itulah mengapa melunasi lebih cepat menghemat biaya sangat signifikan.
        </div>
      </div>
    </div>

    <!-- 6 BANK -->
    <div id="rp-bank" class="rp card">
      <div class="card-body">
        <div class="sec-title"><div class="dot"></div>Perbandingan Cicilan 6 Bank Utama Indonesia</div>
        <div id="bank-grid" class="bank-grid"></div>
        <div class="info-box info-amber" style="margin-top:10px;font-size:10px">
          &#128204; Data bunga adalah estimasi berdasarkan rate promo umum 2025. Konfirmasi langsung ke bank untuk rate terkini dan promo khusus nasabah.
        </div>
      </div>
    </div>

    <!-- PERCEPAT LUNAS -->
    <div id="rp-percepat" class="rp card">
      <div class="card-body">
        <div class="sec-title"><div class="dot"></div>Simulasi Percepat Pelunasan</div>
        <div class="input-group" style="margin-bottom:14px">
          <div class="input-label">
            <span class="lbl">Tambahan bayar pokok / bulan</span>
            <span class="val" id="v-extra">Rp 0</span>
          </div>
          <input type="range" id="extra-bayar" min="0" max="10" step="0.5" value="0">
          <div class="range-hints"><span>0</span><span>10 jt/bln</span></div>
        </div>
        <div id="percepat-result"></div>
        <div class="info-box info-green" style="margin-top:10px;font-size:10px">
          &#128161; Strategi terbaik: bayarkan THR, bonus tahunan, atau rezeki lebih langsung ke pokok KPR. Efeknya luar biasa dalam jangka panjang.
        </div>
      </div>
    </div>

    <!-- BIAYA AWAL -->
    <div id="rp-biaya" class="rp card">
      <div class="card-body">
        <div class="sec-title"><div class="dot"></div>Estimasi Biaya-Biaya Awal KPR</div>
        <div id="biaya-list"></div>
        <div class="info-box info-red" style="margin-top:10px;font-size:10px">
          &#9888;&#65039; Siapkan dana biaya awal secara <strong>terpisah</strong> dari DP. Total bisa mencapai 8–12% dari harga properti. Jangan sampai menguras tabungan darurat Anda.
        </div>
      </div>
    </div>

  </div>
</div>
</div>

<!-- ===================== PANEL SUBSIDI ===================== -->
<div id="panel-subsidi" class="panel">
<div class="main" style="grid-template-columns:1fr;max-width:680px">
  <div class="card">
    <div class="card-head"><div class="card-icon">&#127968;</div><h3>Kalkulator KPR Subsidi FLPP 2025</h3></div>
    <div class="card-body">
      <div class="input-group">
        <div class="input-label">
          <span class="lbl">Penghasilan Bulanan</span>
          <span class="val" id="s-gaji-val">Rp 5 jt</span>
        </div>
        <input type="range" id="s-gaji" min="1" max="16" step="0.5" value="5" oninput="calcSubsidi()">
        <div class="range-hints"><span>1 jt</span><span>16 jt</span></div>
      </div>
      <div id="subsidi-result"></div>
      <div class="info-box info-blue" style="margin-top:14px;font-size:10px">
        &#8505;&#65039; Data berdasarkan Peraturan Menteri PKP No. 5 Tahun 2025. Batas penghasilan dan harga rumah bervariasi per zona/wilayah.
      </div>
    </div>
  </div>
</div>
</div>

<!-- ===================== PANEL TAKE OVER ===================== -->
<div id="panel-takeover" class="panel">
<div class="main" style="grid-template-columns:1fr;max-width:720px">
  <div class="card">
    <div class="card-head"><div class="card-icon">&#128260;</div><h3>Simulasi Take Over / Refinancing KPR</h3></div>
    <div class="card-body">
      <div class="to-grid">
        <div>
          <div class="to-section-lbl">&#128308; KPR Lama (saat ini)</div>
          <div class="input-group">
            <div class="input-label"><span class="lbl">Sisa Hutang</span><span class="val" id="to-sisa-val">Rp 300 jt</span></div>
            <input type="range" id="to-sisa" min="50" max="3000" step="25" value="300" oninput="calcTO()">
            <div class="range-hints"><span>50 jt</span><span>3 M</span></div>
          </div>
          <div class="input-group">
            <div class="input-label"><span class="lbl">Bunga Saat Ini</span><span class="val" id="to-bunga-lama-val">13%</span></div>
            <input type="range" id="to-bunga-lama" min="8" max="18" step="0.25" value="13" oninput="calcTO()">
            <div class="range-hints"><span>8%</span><span>18%</span></div>
          </div>
          <div class="input-group" style="margin-bottom:0">
            <div class="input-label"><span class="lbl">Sisa Tenor</span><span class="val" id="to-tenor-lama-val">15 tahun</span></div>
            <input type="range" id="to-tenor-lama" min="1" max="25" step="1" value="15" oninput="calcTO()">
            <div class="range-hints"><span>1 thn</span><span>25 thn</span></div>
          </div>
        </div>
        <div>
          <div class="to-section-lbl">&#128994; KPR Baru (take over)</div>
          <div class="input-group">
            <div class="input-label"><span class="lbl">Bunga Baru</span><span class="val" id="to-bunga-baru-val">9%</span></div>
            <input type="range" id="to-bunga-baru" min="4" max="15" step="0.25" value="9" oninput="calcTO()">
            <div class="range-hints"><span>4%</span><span>15%</span></div>
          </div>
          <div class="input-group" style="margin-bottom:0">
            <div class="input-label"><span class="lbl">Tenor Baru</span><span class="val" id="to-tenor-baru-val">15 tahun</span></div>
            <input type="range" id="to-tenor-baru" min="1" max="25" step="1" value="15" oninput="calcTO()">
            <div class="range-hints"><span>1 thn</span><span>25 thn</span></div>
          </div>
        </div>
      </div>
      <div id="to-result"></div>
    </div>
  </div>
</div>
</div>

<script>
function fmtM(v) {
  const n = Math.round(v * 10) / 10;
  if (n >= 1000) return 'Rp ' + (n/1000).toFixed(2).replace(/\.?0+$/, '') + ' M';
  return 'Rp ' + n.toFixed(0) + ' jt';
}
function calcCicilan(pokok, bungaTahunan, nBulan) {
  const r = bungaTahunan / 100 / 12;
  if (r === 0) return pokok / nBulan;
  return pokok * (r * Math.pow(1+r, nBulan)) / (Math.pow(1+r, nBulan) - 1);
}

function calc() {
  const harga = +document.getElementById('harga').value;
  const dpPct = +document.getElementById('dp').value;
  const tenor = +document.getElementById('tenor').value;
  const bunga = +document.getElementById('bunga').value;
  const floatRate = +document.getElementById('floating').value;
  const gaji = +document.getElementById('gaji').value;
  const cicilanLain = +document.getElementById('cicilan-lain').value;
  const jenis = document.getElementById('jenis').value;

  const dp = harga * dpPct / 100;
  const pokok = harga - dp;
  const nBulan = tenor * 12;

  let cicilan;
  if (jenis === 'syariah') {
    const totalMargin = pokok * bunga / 100 * tenor;
    cicilan = (pokok + totalMargin) / nBulan;
  } else {
    cicilan = calcCicilan(pokok, bunga, nBulan);
  }

  const cicilanFloat = calcCicilan(pokok, floatRate, nBulan);
  const totalCicilan = cicilan * nBulan;
  const totalBunga = totalCicilan - pokok;
  const rasio = (cicilan / gaji) * 100;
  const dsr = ((cicilan + cicilanLain) / gaji) * 100;

  // Labels
  document.getElementById('v-harga').textContent = fmtM(harga);
  document.getElementById('v-dp').textContent = dpPct + '% = ' + fmtM(dp);
  document.getElementById('v-tenor').textContent = tenor + ' tahun';
  document.getElementById('v-bunga').textContent = bunga.toFixed(2) + '% / tahun';
  document.getElementById('v-floating').textContent = floatRate.toFixed(2) + '% / tahun';
  document.getElementById('v-gaji').textContent = fmtM(gaji);
  document.getElementById('v-lain').textContent = cicilanLain === 0 ? 'Rp 0' : fmtM(cicilanLain);

  // Metrics
  document.getElementById('m-cicilan').textContent = fmtM(cicilan);
  document.getElementById('m-cicilan-sub').textContent = tenor + ' thn × 12 × ' + fmtM(cicilan) + ' (bunga ' + bunga.toFixed(2) + '%)';
  document.getElementById('m-pokok').textContent = fmtM(pokok);
  document.getElementById('m-bunga').textContent = fmtM(totalBunga);
  document.getElementById('m-total').textContent = fmtM(totalCicilan + dp);
  document.getElementById('m-floating').textContent = fmtM(cicilanFloat);

  // Health
  const pct = Math.min(rasio, 100);
  let col, msg, msgBg, msgCol;
  if (rasio <= 25) {
    col='#0B6E4F'; msg='✅ Sangat sehat — peluang disetujui bank sangat tinggi.';
    msgBg='#D6F5EB'; msgCol='#0B6E4F';
  } else if (rasio <= 33) {
    col='#1A9E75'; msg='✅ Aman — masih dalam batas standar bank (maks 30–35% penghasilan).';
    msgBg='#D6F5EB'; msgCol='#0B6E4F';
  } else if (rasio <= 40) {
    col='#C87B00'; msg='⚠️ Hati-hati — bank mungkin minta co-debtor atau jaminan tambahan.';
    msgBg='#FFF3D6'; msgCol='#C87B00';
  } else {
    col='#C0392B'; msg='❌ Berisiko ditolak — naikkan DP, perpanjang tenor, atau kurangi pinjaman.';
    msgBg='#FDECEA'; msgCol='#C0392B';
  }
  document.getElementById('h-fill').style.width = pct + '%';
  document.getElementById('h-fill').style.background = col;
  document.getElementById('h-pct').textContent = rasio.toFixed(1) + '% dari gaji';
  document.getElementById('h-pct').style.color = col;
  const hMsg = document.getElementById('h-msg');
  hMsg.textContent = msg;
  hMsg.style.background = msgBg;
  hMsg.style.color = msgCol;
  hMsg.style.padding = '7px 10px';
  hMsg.style.borderRadius = '7px';
  hMsg.style.fontWeight = '600';

  const dsrBox = document.getElementById('dsr-box');
  if (cicilanLain > 0) {
    const dsrPct = dsr.toFixed(1);
    dsrBox.textContent = 'DSR total (termasuk cicilan lain ' + fmtM(cicilanLain) + '): ' + dsrPct + '% — ' + (dsr > 40 ? '⚠️ Melewati batas aman.' : '✓ Masih aman.');
    dsrBox.style.color = dsr > 40 ? '#C0392B' : '#0B6E4F';
  } else {
    dsrBox.textContent = '';
  }

  // Breakdown bars
  const maxV = Math.max(totalCicilan + dp, harga);
  const bItems = [
    { label: 'Harga rumah', val: harga, color: '#0B6E4F' },
    { label: 'DP dibayar', val: dp, color: '#1A9E75' },
    { label: 'Total cicilan', val: totalCicilan, color: '#378ADD' },
    { label: 'Total bunga', val: totalBunga, color: '#C87B00' },
  ];
  document.getElementById('breakdown-bars').innerHTML = bItems.map(b =>
    `<div class="bc-row">
      <span class="bc-lbl">${b.label}</span>
      <div class="bc-track"><div class="bc-fill" style="width:${(b.val/maxV*100).toFixed(1)}%;background:${b.color}"></div></div>
      <span class="bc-val">${fmtM(b.val)}</span>
    </div>`).join('');

  const rasioB = Math.round(totalBunga / totalCicilan * 100);
  const cls = rasioB > 50 ? 'info-amber' : 'info-green';
  document.getElementById('rasio-box').innerHTML =
    `<div class="info-box ${cls}">Dari total cicilan <strong>${fmtM(totalCicilan)}</strong>, sebesar <strong>${rasioB}%</strong> adalah bunga (${fmtM(totalBunga)}) dan <strong>${100-rasioB}%</strong> adalah pokok (${fmtM(pokok)}).</div>`;

  // Amortisasi
  let sisa = pokok;
  let rows = '', breakEven = null;
  for (let yr = 1; yr <= tenor; yr++) {
    let tb = 0, tp = 0;
    for (let b = 1; b <= 12; b++) {
      let bBln, pBln;
      if (jenis === 'syariah') {
        const totalMarginY = pokok * bunga / 100 * tenor;
        bBln = totalMarginY / nBulan;
        pBln = pokok / nBulan;
      } else {
        bBln = sisa * (bunga / 100 / 12);
        pBln = cicilan - bBln;
      }
      tb += bBln; tp += pBln;
      sisa = Math.max(0, sisa - pBln);
    }
    const lunas = Math.round((pokok - sisa) / pokok * 100);
    if (breakEven === null && tp >= tb) breakEven = yr;
    const isBreak = yr === breakEven;
    rows += `<tr${isBreak ? ' class="hl"' : ''}>
      <td class="td-lbl">Thn ${yr}${isBreak ? ' ★' : ''}</td>
      <td>${fmtM(cicilan)}</td>
      <td>${fmtM(tp)}</td>
      <td>${fmtM(tb)}</td>
      <td>${fmtM(sisa)}</td>
      <td>${lunas}%</td>
    </tr>`;
  }
  document.getElementById('amort-body').innerHTML = rows;

  // Grafik
  let sisa2 = pokok;
  let grafHtml = '';
  for (let yr = 1; yr <= Math.min(tenor, 20); yr++) {
    let tb2 = 0, tp2 = 0;
    for (let b = 1; b <= 12; b++) {
      let bBln, pBln;
      if (jenis === 'syariah') {
        const tm = pokok * bunga / 100 * tenor;
        bBln = tm / nBulan; pBln = pokok / nBulan;
      } else {
        bBln = sisa2 * (bunga / 100 / 12);
        pBln = cicilan - bBln;
      }
      tb2 += bBln; tp2 += pBln;
      sisa2 = Math.max(0, sisa2 - pBln);
    }
    const total = tb2 + tp2;
    const pPct = Math.round(tp2 / total * 100);
    const bPct = 100 - pPct;
    grafHtml += `<div class="bc-row" style="align-items:center">
      <span class="bc-lbl" style="font-size:9px">Thn ${yr}</span>
      <div class="bc-track" style="display:flex;border-radius:3px">
        <div style="width:${pPct}%;background:#0B6E4F;height:16px;border-radius:${bPct>0?'3px 0 0 3px':'3px'}"></div>
        <div style="width:${bPct}%;background:#C87B00;height:16px;border-radius:${pPct>0?'0 3px 3px 0':'3px'}"></div>
      </div>
      <span class="bc-val" style="font-size:9px">${pPct}% pokok</span>
    </div>`;
  }
  document.getElementById('grafik-bars').innerHTML = grafHtml;

  // Bank comparison
  const banks = [
    { name: 'BTN', rate: 7.25, note: 'KPR BTN fixed 2 thn' },
    { name: 'BRI', rate: 7.50, note: 'BRI Griya Utama' },
    { name: 'BNI', rate: 7.75, note: 'BNI Griya' },
    { name: 'Mandiri', rate: 8.00, note: 'KPR Mandiri' },
    { name: 'BCA', rate: 8.25, note: 'KPR BCA fixed' },
    { name: 'CIMB', rate: 8.50, note: 'CIMB KPR Xtra' },
  ];
  const minRate = Math.min(...banks.map(b => b.rate));
  let bankHtml = '';
  banks.forEach(b => {
    const c = (jenis === 'syariah')
      ? (pokok + pokok * b.rate / 100 * tenor) / nBulan
      : calcCicilan(pokok, b.rate, nBulan);
    const isBest = b.rate === minRate;
    bankHtml += `<div class="bank-card${isBest ? ' best' : ''}">
      ${isBest ? '<div class="best-badge">&#10003; Bunga terendah</div>' : ''}
      <div class="bank-name">${b.name}</div>
      <div class="bank-rate">${b.rate.toFixed(2)}%/thn — ${b.note}</div>
      <div class="bank-cicilan">${fmtM(c)}</div>
      <div class="bank-sub">/ bulan | tenor ${tenor} thn</div>
    </div>`;
  });
  document.getElementById('bank-grid').innerHTML = bankHtml;

  // Percepat lunas
  calcPercepat(pokok, bunga, nBulan, cicilan, jenis, tenor);

  // Biaya awal
  const provisi = pokok * 0.01;
  const notaris = harga * 0.015;
  const bphtb = harga > 60 ? (harga - 60) * 0.05 : 0;
  const ppn = harga * 0.11;
  const aJiwa = pokok * 0.005;
  const aApi = harga * 0.001;
  const appraisal = 0.5;
  const admin = 0.35;
  const totalB = provisi + notaris + bphtb + aJiwa + aApi + appraisal + admin;
  const biItems = [
    { name: 'Biaya provisi bank', note: '~1% dari pokok pinjaman', val: provisi, opt: false },
    { name: 'Biaya notaris &amp; PPAT', note: '~1.5% dari harga properti', val: notaris, opt: false },
    { name: 'BPHTB (bea perolehan hak)', note: '5% dari (NJOP &minus; Rp 60 jt)', val: bphtb, opt: false },
    { name: 'PPN rumah baru', note: '11% dari harga (kondisional)', val: ppn, opt: true },
    { name: 'Asuransi jiwa kredit', note: '~0.5% dari pokok (premi awal)', val: aJiwa, opt: false },
    { name: 'Asuransi kebakaran', note: '~0.1% dari harga/tahun', val: aApi, opt: false },
    { name: 'Biaya appraisal properti', note: 'estimasi rata-rata', val: appraisal, opt: false },
    { name: 'Biaya administrasi bank', note: 'estimasi rata-rata', val: admin, opt: false },
  ];
  let biHtml = biItems.map(bi =>
    `<div class="biaya-row">
      <div><div class="biaya-name">${bi.name}${bi.opt ? ' <span style="font-size:9px;color:var(--gray-3)">(kondisional)</span>' : ''}</div><div class="biaya-note">${bi.note}</div></div>
      <div class="biaya-amount" style="${bi.opt ? 'color:var(--gray-3)' : ''}">${fmtM(bi.val)}</div>
    </div>`).join('');
  biHtml += `<div class="biaya-total"><span>Total estimasi biaya awal (tanpa PPN)</span><span class="amount">${fmtM(totalB)}</span></div>`;
  document.getElementById('biaya-list').innerHTML = biHtml;

  window._data = { harga, dp, dpPct, pokok, tenor, bunga, cicilan, totalBunga, totalCicilan, gaji, rasio };
}

function calcPercepat(pokok, bunga, nBulan, cicilan, jenis, tenor) {
  const extra = +document.getElementById('extra-bayar').value;
  document.getElementById('v-extra').textContent = extra === 0 ? 'Rp 0' : fmtM(extra);

  const scenarios = extra === 0
    ? [0, 0.5, 2]
    : [0, extra, extra * 2];

  let html = '';
  scenarios.forEach((ekstra, i) => {
    let sisa = pokok, bulan = 0, totalBayarBaru = 0;
    while (sisa > 0.01 && bulan < nBulan * 2) {
      bulan++;
      let bBln, pBln;
      if (jenis === 'syariah') {
        const tm = pokok * bunga / 100 * tenor;
        bBln = tm / nBulan;
        pBln = pokok / nBulan;
      } else {
        bBln = sisa * (bunga / 100 / 12);
        pBln = (cicilan + ekstra) - bBln;
      }
      if (pBln <= 0) pBln = 0.001;
      totalBayarBaru += cicilan + ekstra;
      sisa = Math.max(0, sisa - pBln);
      if (ekstra > 0 && bulan > nBulan) break;
    }
    const tahunEfektif = Math.ceil(bulan / 12);
    const hematWaktu = tenor - tahunEfektif;
    const totalNormal = cicilan * nBulan;
    const hematBunga = Math.max(0, totalNormal - (cicilan * bulan));
    const label = i === 0 ? 'Tanpa tambahan bayar' : `Tambah ${fmtM(ekstra)}/bulan`;
    const isBest = i > 0 && hematBunga > 0;
    html += `<div class="pl-card${isBest ? ' best' : ''}">
      <div class="pl-head">${label}</div>
      <div class="pl-row"><span class="pl-key">Tenor efektif</span><span class="pl-val">${tahunEfektif} tahun (${bulan} bulan)</span></div>
      <div class="pl-row"><span class="pl-key">Hemat waktu</span><span class="pl-val ${hematWaktu > 0 ? 'pl-save' : ''}">${hematWaktu > 0 ? hematWaktu + ' tahun lebih cepat' : '—'}</span></div>
      <div class="pl-row"><span class="pl-key">Hemat bunga</span><span class="pl-val ${hematBunga > 0 ? 'pl-save' : ''}">${hematBunga > 0 ? fmtM(hematBunga) : '—'}</span></div>
      <div class="pl-row"><span class="pl-key">Cicilan total/bln</span><span class="pl-val">${ekstra > 0 ? fmtM(cicilan + ekstra) : fmtM(cicilan)}</span></div>
    </div>`;
  });
  document.getElementById('percepat-result').innerHTML = html;
}

function switchMain(id, btn) {
  document.querySelectorAll('.panel').forEach(p => p.classList.remove('active'));
  document.querySelectorAll('.htab').forEach(b => b.classList.remove('active'));
  document.getElementById('panel-' + id).classList.add('active');
  btn.classList.add('active');
}
function switchResult(id, btn) {
  document.querySelectorAll('.rp').forEach(p => p.classList.remove('active'));
  document.querySelectorAll('.rtab').forEach(b => b.classList.remove('active'));
  document.getElementById('rp-' + id).classList.add('active');
  btn.classList.add('active');
}

function calcSubsidi() {
  const gaji = +document.getElementById('s-gaji').value;
  document.getElementById('s-gaji-val').textContent = fmtM(gaji);
  const eligible = gaji <= 14;
  const maxHarga = gaji <= 4 ? 166 : gaji <= 7 ? 166 : gaji <= 8 ? 185 : gaji <= 10 ? 185 : 200;
  const dp = maxHarga * 0.01;
  const pokok = maxHarga - dp;
  const cicilan = calcCicilan(pokok, 5, 240);
  let html;
  if (eligible) {
    html = `<div class="metric-grid" style="margin-top:14px">
      <div class="mc accent">
        <div class="mc-label">Estimasi cicilan KPR subsidi</div>
        <div class="mc-val">${fmtM(cicilan)}</div>
        <div class="mc-sub">Bunga 5% tetap | tenor 20 tahun | harga maks ${fmtM(maxHarga)}</div>
      </div>
      <div class="mc"><div class="mc-label">DP minimal (1%)</div><div class="mc-val" style="font-size:15px">${fmtM(dp)}</div></div>
      <div class="mc"><div class="mc-label">Pokok pinjaman</div><div class="mc-val" style="font-size:15px">${fmtM(pokok)}</div></div>
      <div class="mc"><div class="mc-label">Suku bunga subsidi</div><div class="mc-val" style="font-size:15px">5% / thn</div></div>
      <div class="mc"><div class="mc-label">Tenor maksimal</div><div class="mc-val" style="font-size:15px">20 tahun</div></div>
    </div>
    <div class="info-box info-green" style="margin-top:12px">&#10003; Penghasilan ${fmtM(gaji)}/bln memenuhi syarat KPR Subsidi FLPP 2025. Harga rumah subsidi maks ${fmtM(maxHarga)} jt untuk zona ini.</div>`;
  } else {
    html = `<div class="info-box info-red" style="margin-top:14px">&#10007; Penghasilan ${fmtM(gaji)}/bln melebihi batas KPR Subsidi (maks Rp 14 jt/bln). Gunakan kalkulator KPR komersial di tab pertama.</div>`;
  }
  document.getElementById('subsidi-result').innerHTML = html;
}

function calcTO() {
  const sisa = +document.getElementById('to-sisa').value;
  const bungaLama = +document.getElementById('to-bunga-lama').value;
  const tenorLama = +document.getElementById('to-tenor-lama').value;
  const bungaBaru = +document.getElementById('to-bunga-baru').value;
  const tenorBaru = +document.getElementById('to-tenor-baru').value;
  document.getElementById('to-sisa-val').textContent = fmtM(sisa);
  document.getElementById('to-bunga-lama-val').textContent = bungaLama + '%';
  document.getElementById('to-tenor-lama-val').textContent = tenorLama + ' tahun';
  document.getElementById('to-bunga-baru-val').textContent = bungaBaru + '%';
  document.getElementById('to-tenor-baru-val').textContent = tenorBaru + ' tahun';
  const cLama = calcCicilan(sisa, bungaLama, tenorLama * 12);
  const cBaru = calcCicilan(sisa, bungaBaru, tenorBaru * 12);
  const hematBulan = cLama - cBaru;
  const totalLama = cLama * tenorLama * 12;
  const totalBaru = cBaru * tenorBaru * 12;
  const hematTotal = totalLama - totalBaru;
  const biayaTO = sisa * 0.02;
  const worthIt = hematTotal > biayaTO;
  document.getElementById('to-result').innerHTML = `
    <div class="metric-grid" style="margin-top:4px">
      <div class="mc"><div class="mc-label">Cicilan lama / bulan</div><div class="mc-val" style="font-size:15px;color:var(--red)">${fmtM(cLama)}</div></div>
      <div class="mc accent"><div class="mc-label">Cicilan baru / bulan</div><div class="mc-val" style="font-size:18px">${fmtM(cBaru)}</div></div>
      <div class="mc"><div class="mc-label">Hemat per bulan</div><div class="mc-val" style="font-size:15px;color:var(--green)">${hematBulan > 0 ? fmtM(hematBulan) : '—'}</div></div>
      <div class="mc"><div class="mc-label">Hemat total</div><div class="mc-val" style="font-size:15px;color:var(--green)">${hematTotal > 0 ? fmtM(hematTotal) : '—'}</div></div>
    </div>
    <div class="biaya-row" style="margin-top:10px">
      <div><div class="biaya-name">Estimasi biaya take over</div><div class="biaya-note">Provisi + notaris + administrasi (~2% dari sisa hutang)</div></div>
      <div class="biaya-amount">${fmtM(biayaTO)}</div>
    </div>
    <div class="info-box ${worthIt ? 'info-green' : 'info-amber'}" style="margin-top:10px">
      ${worthIt
        ? '&#10003; Take over menguntungkan. Penghematan total ' + fmtM(hematTotal) + ' jauh melampaui biaya TO ' + fmtM(biayaTO) + '. Disarankan untuk dilanjutkan.'
        : '&#9888;&#65039; Perlu pertimbangan. Biaya take over (' + fmtM(biayaTO) + ') mendekati atau melebihi penghematan yang didapat.'}
    </div>`;
}

function copyResult() {
  const d = window._data;
  if (!d) return;
  const text = [
    'SIMULASI KPR — CICIL CERDAS',
    '================================',
    'Harga properti : ' + fmtM(d.harga),
    'Uang muka (DP) : ' + d.dpPct + '% = ' + fmtM(d.dp),
    'Pokok pinjaman : ' + fmtM(d.pokok),
    'Tenor          : ' + d.tenor + ' tahun',
    'Suku bunga     : ' + d.bunga + '%/tahun',
    '',
    'Cicilan/bulan  : ' + fmtM(d.cicilan),
    'Total bunga    : ' + fmtM(d.totalBunga),
    'Total bayar    : ' + fmtM(d.totalCicilan + d.dp),
    'Rasio gaji     : ' + d.rasio.toFixed(1) + '%',
    '',
    'Simulasi dari cicilcerdas.com',
  ].join('\n');
  navigator.clipboard.writeText(text).then(() => alert('Ringkasan berhasil disalin!')).catch(() => alert('Gagal menyalin. Coba lagi.'));
}

['harga','dp','tenor','bunga','floating','gaji','cicilan-lain','jenis'].forEach(id => {
  const el = document.getElementById(id);
  if (el) { el.addEventListener('input', calc); el.addEventListener('change', calc); }
});
document.getElementById('extra-bayar').addEventListener('input', function() {
  const d = window._data;
  if (d) calcPercepat(d.pokok, d.bunga, d.tenor*12, d.cicilan, document.getElementById('jenis').value, d.tenor);
  document.getElementById('v-extra').textContent = +this.value === 0 ? 'Rp 0' : fmtM(+this.value);
});

calc();
calcSubsidi();
calcTO();
</script>
</body>
</html>
Scroll to Top