B2C Buzz

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>EMI Calculator</title>
<link href="https://fonts.googleapis.com/css2?family=Playfair+Display:wght@400;700&family=DM+Sans:wght@300;400;500;600&display=swap" rel="stylesheet">
<style>
  :root {
    --bg: #0d0f14;
    --surface: #161922;
    --surface2: #1e2330;
    --border: #2a3045;
    --gold: #c9a84c;
    --gold-light: #e8c97a;
    --gold-dim: rgba(201,168,76,0.12);
    --text: #f0ede6;
    --text-muted: #8891a8;
    --green: #4caf82;
    --red: #e05a5a;
    --radius: 16px;
  }

  * { box-sizing: border-box; margin: 0; padding: 0; }

  body {
    background: var(--bg);
    font-family: 'DM Sans', sans-serif;
    color: var(--text);
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px 16px;
  }

  .calculator {
    width: 100%;
    max-width: 860px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 24px;
    overflow: hidden;
    box-shadow: 0 40px 80px rgba(0,0,0,0.5), 0 0 0 1px rgba(201,168,76,0.08);
  }

  .header {
    background: linear-gradient(135deg, #1a1d28 0%, #111420 100%);
    padding: 36px 40px 28px;
    border-bottom: 1px solid var(--border);
    position: relative;
    overflow: hidden;
  }

  .header::before {
    content: '';
    position: absolute;
    top: -40px; right: -40px;
    width: 200px; height: 200px;
    background: radial-gradient(circle, rgba(201,168,76,0.15) 0%, transparent 70%);
    pointer-events: none;
  }

  .header-label {
    font-size: 11px;
    letter-spacing: 3px;
    text-transform: uppercase;
    color: var(--gold);
    font-weight: 600;
    margin-bottom: 8px;
  }

  .header h1 {
    font-family: 'Playfair Display', serif;
    font-size: 32px;
    font-weight: 700;
    color: var(--text);
    line-height: 1.1;
  }

  .header p {
    color: var(--text-muted);
    font-size: 14px;
    margin-top: 8px;
    font-weight: 300;
  }

  .body {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0;
  }

  @media (max-width: 650px) {
    .body { grid-template-columns: 1fr; }
    .header { padding: 28px 24px 20px; }
    .header h1 { font-size: 26px; }
    .inputs { padding: 28px 24px; }
    .results { padding: 28px 24px; }
  }

  .inputs {
    padding: 36px 40px;
    border-right: 1px solid var(--border);
    display: flex;
    flex-direction: column;
    gap: 28px;
  }

  @media (max-width: 650px) {
    .inputs { border-right: none; border-bottom: 1px solid var(--border); }
  }

  .field label {
    display: flex;
    justify-content: space-between;
    align-items: center;
    font-size: 12px;
    letter-spacing: 1.5px;
    text-transform: uppercase;
    color: var(--text-muted);
    font-weight: 600;
    margin-bottom: 10px;
  }

  .field label span {
    font-family: 'Playfair Display', serif;
    font-size: 18px;
    letter-spacing: 0;
    text-transform: none;
    color: var(--gold);
    font-weight: 400;
  }

  .input-row {
    display: flex;
    align-items: center;
    background: var(--surface2);
    border: 1px solid var(--border);
    border-radius: 10px;
    overflow: hidden;
    transition: border-color 0.2s;
  }

  .input-row:focus-within {
    border-color: var(--gold);
  }

  .input-prefix {
    padding: 12px 14px;
    background: var(--gold-dim);
    color: var(--gold);
    font-size: 14px;
    font-weight: 600;
    border-right: 1px solid var(--border);
    white-space: nowrap;
  }

  .input-row input {
    flex: 1;
    background: transparent;
    border: none;
    outline: none;
    color: var(--text);
    font-family: 'DM Sans', sans-serif;
    font-size: 16px;
    font-weight: 500;
    padding: 12px 14px;
    width: 100%;
  }

  input[type=range] {
    -webkit-appearance: none;
    width: 100%;
    height: 4px;
    background: var(--border);
    border-radius: 2px;
    outline: none;
    margin-top: 12px;
    cursor: pointer;
  }

  input[type=range]::-webkit-slider-thumb {
    -webkit-appearance: none;
    width: 18px;
    height: 18px;
    background: var(--gold);
    border-radius: 50%;
    cursor: pointer;
    box-shadow: 0 0 0 4px rgba(201,168,76,0.2);
    transition: box-shadow 0.2s;
  }

  input[type=range]::-webkit-slider-thumb:hover {
    box-shadow: 0 0 0 6px rgba(201,168,76,0.3);
  }

  .results {
    padding: 36px 40px;
    display: flex;
    flex-direction: column;
    gap: 0;
  }

  .emi-hero {
    text-align: center;
    padding-bottom: 28px;
    border-bottom: 1px solid var(--border);
    margin-bottom: 28px;
  }

  .emi-label {
    font-size: 11px;
    letter-spacing: 3px;
    text-transform: uppercase;
    color: var(--text-muted);
    font-weight: 600;
    margin-bottom: 8px;
  }

  .emi-amount {
    font-family: 'Playfair Display', serif;
    font-size: 46px;
    font-weight: 700;
    color: var(--gold);
    line-height: 1;
    transition: all 0.3s ease;
  }

  .emi-sub {
    font-size: 13px;
    color: var(--text-muted);
    margin-top: 6px;
  }

  .stat-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 16px;
    margin-bottom: 28px;
  }

  .stat {
    background: var(--surface2);
    border: 1px solid var(--border);
    border-radius: 12px;
    padding: 16px;
  }

  .stat-label {
    font-size: 11px;
    letter-spacing: 1.5px;
    text-transform: uppercase;
    color: var(--text-muted);
    font-weight: 600;
    margin-bottom: 6px;
  }

  .stat-value {
    font-family: 'Playfair Display', serif;
    font-size: 22px;
    font-weight: 700;
  }

  .stat-value.principal { color: var(--green); }
  .stat-value.interest { color: var(--red); }
  .stat-value.total { color: var(--text); }

  .donut-section {
    display: flex;
    align-items: center;
    gap: 20px;
  }

  .donut-wrap {
    position: relative;
    flex-shrink: 0;
  }

  .donut-wrap svg { display: block; }

  .donut-center {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    pointer-events: none;
  }

  .donut-pct {
    font-family: 'Playfair Display', serif;
    font-size: 20px;
    font-weight: 700;
    color: var(--gold);
  }

  .donut-pct-label {
    font-size: 9px;
    letter-spacing: 1px;
    text-transform: uppercase;
    color: var(--text-muted);
  }

  .legend {
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 10px;
  }

  .legend-item {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 13px;
  }

  .legend-dot {
    width: 10px; height: 10px;
    border-radius: 50%;
    flex-shrink: 0;
  }

  .legend-text {
    color: var(--text-muted);
    flex: 1;
  }

  .legend-val {
    font-weight: 600;
    color: var(--text);
  }

  .amort-toggle {
    margin-top: 24px;
    background: none;
    border: 1px solid var(--border);
    color: var(--gold);
    padding: 10px 20px;
    border-radius: 8px;
    font-family: 'DM Sans', sans-serif;
    font-size: 13px;
    font-weight: 500;
    cursor: pointer;
    width: 100%;
    letter-spacing: 0.5px;
    transition: background 0.2s, border-color 0.2s;
  }

  .amort-toggle:hover {
    background: var(--gold-dim);
    border-color: var(--gold);
  }

  .amort-table-wrap {
    display: none;
    margin-top: 0;
    overflow: hidden;
  }

  .amort-table-wrap.open {
    display: block;
  }

  .amort-table-inner {
    max-height: 300px;
    overflow-y: auto;
    margin-top: 16px;
    border: 1px solid var(--border);
    border-radius: 12px;
    scrollbar-width: thin;
    scrollbar-color: var(--border) transparent;
  }

  table {
    width: 100%;
    border-collapse: collapse;
    font-size: 12px;
  }

  thead th {
    background: var(--surface2);
    padding: 10px 12px;
    text-align: right;
    font-size: 10px;
    letter-spacing: 1px;
    text-transform: uppercase;
    color: var(--text-muted);
    font-weight: 600;
    position: sticky;
    top: 0;
    z-index: 1;
  }

  thead th:first-child { text-align: left; }

  tbody tr { border-top: 1px solid var(--border); }
  tbody tr:hover { background: var(--surface2); }

  tbody td {
    padding: 9px 12px;
    text-align: right;
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
  }

  tbody td:first-child { text-align: left; color: var(--text); font-weight: 500; }
</style>
</head>
<body>

<div class="calculator">
  <div class="header">
    <div class="header-label">Financial Tool</div>
    <h1>EMI Calculator</h1>
    <p>Calculate your Equated Monthly Installment instantly</p>
  </div>

  <div class="body">
    <!-- INPUTS -->
    <div class="inputs">

      <div class="field">
        <label>Loan Amount <span id="lbl-principal">₹10,00,000</span></label>
        <div class="input-row">
          <span class="input-prefix">₹</span>
          <input type="number" id="principal" value="1000000" min="10000" max="100000000" step="10000">
        </div>
        <input type="range" id="principal-range" min="10000" max="10000000" step="10000" value="1000000">
      </div>

      <div class="field">
        <label>Annual Interest Rate <span id="lbl-rate">8.5%</span></label>
        <div class="input-row">
          <span class="input-prefix">%</span>
          <input type="number" id="rate" value="8.5" min="0.1" max="36" step="0.1">
        </div>
        <input type="range" id="rate-range" min="0.1" max="36" step="0.1" value="8.5">
      </div>

      <div class="field">
        <label>Loan Tenure <span id="lbl-tenure">60 mo</span></label>
        <div class="input-row">
          <span class="input-prefix">Months</span>
          <input type="number" id="tenure" value="60" min="1" max="360" step="1">
        </div>
        <input type="range" id="tenure-range" min="1" max="360" step="1" value="60">
      </div>

    </div>

    <!-- RESULTS -->
    <div class="results">
      <div class="emi-hero">
        <div class="emi-label">Monthly EMI</div>
        <div class="emi-amount" id="emi-display">₹0</div>
        <div class="emi-sub">per month</div>
      </div>

      <div class="stat-grid">
        <div class="stat">
          <div class="stat-label">Principal</div>
          <div class="stat-value principal" id="stat-principal">₹0</div>
        </div>
        <div class="stat">
          <div class="stat-label">Total Interest</div>
          <div class="stat-value interest" id="stat-interest">₹0</div>
        </div>
        <div class="stat" style="grid-column: span 2;">
          <div class="stat-label">Total Payment</div>
          <div class="stat-value total" id="stat-total">₹0</div>
        </div>
      </div>

      <div class="donut-section">
        <div class="donut-wrap">
          <svg width="100" height="100" viewBox="0 0 100 100">
            <circle cx="50" cy="50" r="38" fill="none" stroke="#2a3045" stroke-width="14"/>
            <circle cx="50" cy="50" r="38" fill="none" stroke="#4caf82" stroke-width="14"
              stroke-dasharray="0 239" stroke-linecap="round"
              transform="rotate(-90 50 50)" id="donut-principal" style="transition: stroke-dasharray 0.5s ease;"/>
            <circle cx="50" cy="50" r="38" fill="none" stroke="#e05a5a" stroke-width="14"
              stroke-dasharray="0 239" stroke-linecap="round"
              transform="rotate(-90 50 50)" id="donut-interest" style="transition: stroke-dasharray 0.5s ease, stroke-dashoffset 0.5s ease;"/>
          </svg>
          <div class="donut-center">
            <div class="donut-pct" id="donut-pct">0%</div>
            <div class="donut-pct-label">Interest</div>
          </div>
        </div>
        <div class="legend">
          <div class="legend-item">
            <div class="legend-dot" style="background:#4caf82"></div>
            <span class="legend-text">Principal</span>
            <span class="legend-val" id="legend-principal">0%</span>
          </div>
          <div class="legend-item">
            <div class="legend-dot" style="background:#e05a5a"></div>
            <span class="legend-text">Interest</span>
            <span class="legend-val" id="legend-interest">0%</span>
          </div>
        </div>
      </div>

      <button class="amort-toggle" id="amort-btn">▼ View Amortization Schedule</button>
      <div class="amort-table-wrap" id="amort-wrap">
        <div class="amort-table-inner">
          <table>
            <thead>
              <tr>
                <th>Month</th>
                <th>Principal</th>
                <th>Interest</th>
                <th>Balance</th>
              </tr>
            </thead>
            <tbody id="amort-body"></tbody>
          </table>
        </div>
      </div>
    </div>
  </div>
</div>

<script>
const fmt = v => '₹' + Math.round(v).toLocaleString('en-IN');
const fmtShort = v => {
  if (v >= 10000000) return '₹' + (v/10000000).toFixed(2) + ' Cr';
  if (v >= 100000) return '₹' + (v/100000).toFixed(2) + ' L';
  return fmt(v);
};

function sync(inputId, rangeId, lblId, fmtFn) {
  const input = document.getElementById(inputId);
  const range = document.getElementById(rangeId);
  const lbl = document.getElementById(lblId);
  input.addEventListener('input', () => {
    range.value = input.value;
    lbl.textContent = fmtFn(+input.value);
    calculate();
  });
  range.addEventListener('input', () => {
    input.value = range.value;
    lbl.textContent = fmtFn(+range.value);
    calculate();
  });
}

sync('principal', 'principal-range', 'lbl-principal', v => '₹' + Number(v).toLocaleString('en-IN'));
sync('rate', 'rate-range', 'lbl-rate', v => v + '%');
sync('tenure', 'tenure-range', 'lbl-tenure', v => v + ' mo');

function calculate() {
  const P = parseFloat(document.getElementById('principal').value) || 0;
  const annualRate = parseFloat(document.getElementById('rate').value) || 0;
  const N = parseInt(document.getElementById('tenure').value) || 0;
  const r = annualRate / 12 / 100;

  let emi = 0;
  if (r === 0) {
    emi = N > 0 ? P / N : 0;
  } else {
    emi = P * r * Math.pow(1+r, N) / (Math.pow(1+r, N) - 1);
  }

  const totalPayment = emi * N;
  const totalInterest = totalPayment - P;
  const interestPct = totalPayment > 0 ? (totalInterest / totalPayment * 100) : 0;
  const principalPct = 100 - interestPct;

  document.getElementById('emi-display').textContent = fmt(emi);
  document.getElementById('stat-principal').textContent = fmtShort(P);
  document.getElementById('stat-interest').textContent = fmtShort(totalInterest);
  document.getElementById('stat-total').textContent = fmtShort(totalPayment);
  document.getElementById('donut-pct').textContent = Math.round(interestPct) + '%';
  document.getElementById('legend-principal').textContent = Math.round(principalPct) + '%';
  document.getElementById('legend-interest').textContent = Math.round(interestPct) + '%';

  // Donut chart (circumference ~238.76 for r=38)
  const C = 2 * Math.PI * 38;
  const pDash = (principalPct / 100) * C;
  const iDash = (interestPct / 100) * C;
  const pCircle = document.getElementById('donut-principal');
  const iCircle = document.getElementById('donut-interest');
  pCircle.setAttribute('stroke-dasharray', pDash + ' ' + C);
  iCircle.setAttribute('stroke-dasharray', iDash + ' ' + C);
  iCircle.setAttribute('stroke-dashoffset', -pDash);

  // Amortization
  buildAmort(P, r, N, emi);
}

function buildAmort(P, r, N, emi) {
  const tbody = document.getElementById('amort-body');
  tbody.innerHTML = '';
  let balance = P;
  for (let m = 1; m <= N; m++) {
    const interest = balance * r;
    const principal = emi - interest;
    balance -= principal;
    const tr = document.createElement('tr');
    tr.innerHTML = `<td>${m}</td><td>${fmt(principal)}</td><td>${fmt(interest)}</td><td>${fmt(Math.max(0, balance))}</td>`;
    tbody.appendChild(tr);
  }
}

document.getElementById('amort-btn').addEventListener('click', () => {
  const wrap = document.getElementById('amort-wrap');
  const btn = document.getElementById('amort-btn');
  const open = wrap.classList.toggle('open');
  btn.textContent = open ? '▲ Hide Amortization Schedule' : '▼ View Amortization Schedule';
});

calculate();
</script>
</body>
</html>