{"id":1015,"date":"2025-09-15T22:32:00","date_gmt":"2025-09-15T22:32:00","guid":{"rendered":"https:\/\/millionpathapp.com\/?page_id=1015"},"modified":"2025-09-15T22:32:01","modified_gmt":"2025-09-15T22:32:01","slug":"monthly-budget-planner","status":"publish","type":"page","link":"https:\/\/millionpathapp.com\/de\/monthly-budget-planner\/","title":{"rendered":"Monthly Budget Planner"},"content":{"rendered":"\n<p><\/p>\n\n\n\n<!doctype html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\" \/>\n<meta name=\"viewport\" content=\"width=device-width,initial-scale=1\" \/>\n<title>Monthly Budget Planner \u2014 MillionPath<\/title>\n<style>\n  :root{--bg:#fff;--ink:#111;--muted:#6b7280;--brand:#f59e0b;--ok:#10b981;--bad:#ef4444;--card:#fff;--ring:#fde68a}\n  *{box-sizing:border-box} body{margin:0;background:#f8fafc;color:var(--ink);font:16px\/1.5 ui-sans-serif,system-ui,Segoe UI,Roboto}\n  .wrap{max-width:980px;margin:24px auto;padding:16px}\n  .title{display:flex;align-items:center;gap:10px}\n  .badge{background:var(--brand);color:#111;padding:2px 10px;border-radius:999px;font-weight:700}\n  .grid{display:grid;gap:14px}\n  @media(min-width:800px){.grid{grid-template-columns:1fr 1fr}}\n  .card{background:var(--card);border:1px solid #e5e7eb;border-radius:14px;padding:14px;box-shadow:0 2px 10px rgba(0,0,0,.04)}\n  h2,h3{margin:0 0 8px}\n  .row{display:grid;grid-template-columns:1fr 130px;gap:8px;margin-bottom:8px}\n  label{font-size:13px;color:var(--muted)}\n  input[type=number],input[type=text]{width:100%;padding:10px 12px;border:1px solid #e5e7eb;border-radius:10px;background:#fff}\n  input:focus{outline:none;border-color:var(--brand);box-shadow:0 0 0 4px var(--ring)}\n  .btn{cursor:pointer;border:0;border-radius:10px;padding:10px 14px;font-weight:600}\n  .btn.primary{background:var(--brand)}\n  .btn.light{background:#111;color:#fff}\n  .btn.ghost{background:#f1f5f9}\n  .flex{display:flex;gap:10px;flex-wrap:wrap}\n  .kpis{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:10px}\n  .kpi{background:#fff;border:1px solid #e5e7eb;border-radius:12px;padding:10px}\n  .kpi small{color:var(--muted)}\n  .kpi b{font-size:18px}\n  .bar{height:10px;background:#e5e7eb;border-radius:999px;overflow:hidden}\n  .bar>span{display:block;height:100%;background:linear-gradient(90deg,var(--ok),#34d399);width:0}\n  table{width:100%;border-collapse:separate;border-spacing:0 6px}\n  th,td{padding:8px 10px;text-align:left}\n  th{font-size:12px;color:var(--muted)}\n  tbody tr{background:#fff;border:1px solid #e5e7eb}\n  tbody td:first-child, thead th:first-child{border-radius:10px 0 0 10px}\n  tbody td:last-child, thead th:last-child{border-radius:0 10px 10px 0}\n  .sumpos{color:var(--ok);font-weight:700}\n  .sumneg{color:var(--bad);font-weight:700}\n  .foot{display:flex;justify-content:space-between;align-items:center;margin-top:10px}\n<\/style>\n<\/head>\n<body>\n<div class=\"wrap\">\n  <div class=\"title\">\n    <span class=\"badge\">Budget<\/span>\n    <h1>Monthly Budget Planner<\/h1>\n  <\/div>\n\n  <div class=\"kpis\" id=\"kpis\">\n    <div class=\"kpi\"><small>Total Income<\/small><br><b id=\"kpiIncome\">\u20ac0<\/b><\/div>\n    <div class=\"kpi\"><small>Total Expenses<\/small><br><b id=\"kpiExp\">\u20ac0<\/b><\/div>\n    <div class=\"kpi\"><small>Savings \/ Net<\/small><br><b id=\"kpiNet\">\u20ac0<\/b><\/div>\n    <div class=\"kpi\">\n      <small>Progress to Goal<\/small>\n      <div class=\"bar\" style=\"margin-top:8px\"><span id=\"progBar\"><\/span><\/div>\n      <small id=\"progTxt\">0%<\/small>\n    <\/div>\n  <\/div>\n\n  <div class=\"grid\" style=\"margin-top:14px\">\n    <div class=\"card\">\n      <h2>Income<\/h2>\n      <div id=\"incomeRows\"><\/div>\n      <div class=\"flex\">\n        <button class=\"btn primary\" onclick=\"addRow('income')\">+ Add income<\/button>\n        <button class=\"btn ghost\" onclick=\"fillSamples('income')\">Demo<\/button>\n      <\/div>\n    <\/div>\n    <div class=\"card\">\n      <h2>Expenses<\/h2>\n      <div id=\"expenseRows\"><\/div>\n      <div class=\"flex\">\n        <button class=\"btn primary\" onclick=\"addRow('expense')\">+ Add expense<\/button>\n        <button class=\"btn ghost\" onclick=\"fillSamples('expense')\">Demo<\/button>\n      <\/div>\n    <\/div>\n  <\/div>\n\n  <div class=\"card\" style=\"margin-top:14px\">\n    <h3>Summary<\/h3>\n    <table>\n      <thead>\n        <tr>\n          <th>Type<\/th><th>Items<\/th><th>Amount<\/th><th>Notes<\/th>\n        <\/tr>\n      <\/thead>\n      <tbody>\n        <tr>\n          <td>Income<\/td>\n          <td id=\"sumIncomeItems\">0<\/td>\n          <td class=\"sumpos\" id=\"sumIncome\">\u20ac0<\/td>\n          <td>After taxes (if any)<\/td>\n        <\/tr>\n        <tr>\n          <td>Expenses<\/td>\n          <td id=\"sumExpItems\">0<\/td>\n          <td class=\"sumneg\" id=\"sumExp\">\u20ac0<\/td>\n          <td>Fixed + Variable<\/td>\n        <\/tr>\n        <tr>\n          <td><b>Net (Income \u2212 Expenses)<\/b><\/td>\n          <td>\u2014<\/td>\n          <td id=\"sumNet\"><b>\u20ac0<\/b><\/td>\n          <td id=\"netMsg\">Stay in the green \u2705<\/td>\n        <\/tr>\n      <\/tbody>\n    <\/table>\n    <div class=\"foot\">\n      <div class=\"flex\">\n        <label>Monthly savings goal:<\/label>\n        <input id=\"goal\" type=\"number\" min=\"0\" step=\"1\" value=\"1000\" oninput=\"recalc()\"\/>\n      <\/div>\n      <div class=\"flex\">\n        <button class=\"btn light\" onclick=\"exportCSV()\">Export CSV<\/button>\n        <button class=\"btn ghost\" onclick=\"clearAll()\">Clear<\/button>\n      <\/div>\n    <\/div>\n  <\/div>\n<\/div>\n\n<script>\n  const currency = \"\u20ac\";\n  const incomeWrap = document.getElementById('incomeRows');\n  const expenseWrap = document.getElementById('expenseRows');\n\n  function addRow(type, name=\"\", amount=\"\"){\n    const wrap = type==='income' ? incomeWrap : expenseWrap;\n    const row = document.createElement('div');\n    row.className = 'row';\n    row.innerHTML = `\n      <div>\n        <label>${type==='income'?'Source':'Category'}<\/label>\n        <input type=\"text\" placeholder=\"${type==='income'?'e.g., Salary':'e.g., Rent'}\" value=\"${name}\" oninput=\"recalc()\">\n      <\/div>\n      <div>\n        <label>Amount<\/label>\n        <input type=\"number\" min=\"0\" step=\"1\" value=\"${amount}\" oninput=\"recalc()\">\n      <\/div>`;\n    wrap.appendChild(row);\n    recalc();\n  }\n\n  function euros(n){ return currency + (Number(n).toLocaleString('de-DE',{maximumFractionDigits:0})); }\n\n  function recalc(){\n    const g = Number(document.getElementById('goal').value||0);\n    \/\/ income\n    let inc = 0, incItems = 0;\n    incomeWrap.querySelectorAll('input[type=number]').forEach(i=>{ inc += Number(i.value||0); incItems++; });\n    \/\/ expenses\n    let exp = 0, expItems = 0;\n    expenseWrap.querySelectorAll('input[type=number]').forEach(i=>{ exp += Number(i.value||0); expItems++; });\n    \/\/ KPIs\n    document.getElementById('kpiIncome').textContent = euros(inc);\n    document.getElementById('kpiExp').textContent = euros(exp);\n    const net = inc - exp;\n    document.getElementById('kpiNet').textContent = euros(net);\n    \/\/ Summary\n    document.getElementById('sumIncome').textContent = euros(inc);\n    document.getElementById('sumIncomeItems').textContent = incItems;\n    document.getElementById('sumExp').textContent = euros(exp);\n    document.getElementById('sumExpItems').textContent = expItems;\n    document.getElementById('sumNet').innerHTML = `<b>${euros(net)}<\/b>`;\n    const msg = net>=g ? `Goal met \ud83c\udf89 (+${euros(net-g)})` : `Need ${euros(g-net)} to reach goal`;\n    document.getElementById('netMsg').textContent = msg;\n    \/\/ progress\n    const p = g>0 ? Math.max(0, Math.min(100, Math.round((net\/g)*100))) : 0;\n    document.getElementById('progBar').style.width = p + '%';\n    document.getElementById('progTxt').textContent = p + '%';\n  }\n\n  function fillSamples(type){\n    if(type==='income'){\n      addRow('income','Salary',2200);\n      addRow('income','Side Hustle',400);\n    } else {\n      addRow('expense','Rent',980);\n      addRow('expense','Groceries',280);\n      addRow('expense','Transport',89);\n      addRow('expense','Phone\/Internet',55);\n      addRow('expense','Leisure',120);\n    }\n  }\n\n  function clearAll(){\n    incomeWrap.innerHTML = '';\n    expenseWrap.innerHTML = '';\n    recalc();\n  }\n\n  function exportCSV(){\n    \/\/ Build rows\n    const rows = [[\"Type\",\"Name\",\"Amount\"]];\n    incomeWrap.querySelectorAll('.row').forEach(r=>{\n      const name = r.querySelector('input[type=text]').value.replaceAll(',',' ');\n      const val = r.querySelector('input[type=number]').value||0;\n      rows.push([\"Income\",name,val]);\n    });\n    expenseWrap.querySelectorAll('.row').forEach(r=>{\n      const name = r.querySelector('input[type=text]').value.replaceAll(',',' ');\n      const val = r.querySelector('input[type=number]').value||0;\n      rows.push([\"Expense\",name,val]);\n    });\n    rows.push([]);\n    rows.push([\"Summary\",\"Income\",document.getElementById('kpiIncome').textContent.replace(currency,'')]);\n    rows.push([\"Summary\",\"Expenses\",document.getElementById('kpiExp').textContent.replace(currency,'')]);\n    rows.push([\"Summary\",\"Net\",document.getElementById('kpiNet').textContent.replace(currency,'')]);\n    \/\/ CSV\n    const csv = rows.map(r=>r.join(',')).join('\\n');\n    const blob = new Blob([csv],{type:'text\/csv;charset=utf-8;'});\n    const a = document.createElement('a');\n    a.href = URL.createObjectURL(blob);\n    a.download = 'monthly-budget.csv';\n    a.click();\n  }\n\n  \/\/ start with one empty row on each side\n  addRow('income'); addRow('expense');\n<\/script>\n<\/body>\n<\/html>\n","protected":false},"excerpt":{"rendered":"<p>Monthly Budget Planner \u2014 MillionPath Budget Monthly Budget Planner Total Income\u20ac0 Total Expenses\u20ac0 Savings \/ Net\u20ac0 Progress to Goal 0% [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-1015","page","type-page","status-publish","hentry"],"_hostinger_reach_plugin_has_subscription_block":false,"_hostinger_reach_plugin_is_elementor":false,"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/millionpathapp.com\/de\/wp-json\/wp\/v2\/pages\/1015","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/millionpathapp.com\/de\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/millionpathapp.com\/de\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/millionpathapp.com\/de\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/millionpathapp.com\/de\/wp-json\/wp\/v2\/comments?post=1015"}],"version-history":[{"count":1,"href":"https:\/\/millionpathapp.com\/de\/wp-json\/wp\/v2\/pages\/1015\/revisions"}],"predecessor-version":[{"id":1016,"href":"https:\/\/millionpathapp.com\/de\/wp-json\/wp\/v2\/pages\/1015\/revisions\/1016"}],"wp:attachment":[{"href":"https:\/\/millionpathapp.com\/de\/wp-json\/wp\/v2\/media?parent=1015"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}