{"id":195,"date":"2026-05-20T07:19:57","date_gmt":"2026-05-20T07:19:57","guid":{"rendered":"https:\/\/nordbalance.dk\/?page_id=195"},"modified":"2026-06-04T17:08:05","modified_gmt":"2026-06-04T17:08:05","slug":"automatisk-budget","status":"publish","type":"page","link":"https:\/\/nordbalance.dk\/?page_id=195","title":{"rendered":"Smart Budget Planner"},"content":{"rendered":"\n<script src=\"https:\/\/cdn.jsdelivr.net\/npm\/@supabase\/supabase-js@2\"><\/script>\n\n<script>\nconst SUPABASE_URL=\"https:\/\/vmcpmdcbzatavfkwdcuz.supabase.co\";\nconst SUPABASE_KEY=\"sb_publishable_ODGTPniESClcPb8E2alCQQ_3tadLNmM\";\nconst STRIPE_LINK=\"https:\/\/buy.stripe.com\/test_28EaEY4Dj4TZfXyglE7AI00\";\nconst SMART_TABLE=\"smart_planner\";\n\nconst supabaseClient=window.supabase.createClient(SUPABASE_URL,SUPABASE_KEY);\n\nlet currentUser=null;\nlet latestBudget=null;\nlet recommendedPlan=null;\nlet existingPlannerId=null;\n\nasync function logoutUser(){\n  await supabaseClient.auth.signOut();\n  window.location.href=\"https:\/\/nordbalance.dk\/?page_id=40\";\n}\n\nfunction kr(value){\n  return new Intl.NumberFormat(\"da-DK\",{style:\"currency\",currency:\"DKK\",maximumFractionDigits:0}).format(Number(value)||0);\n}\n\nfunction setText(id,text){\n  const el=document.getElementById(id);\n  if(el) el.textContent=text;\n}\n\nfunction num(row,key){\n  return Number(row?.[key])||0;\n}\n\nfunction setMessage(text,isError=false){\n  const el=document.getElementById(\"saveMessage\");\n  if(!el) return;\n  el.textContent=text;\n  el.style.color=isError ? \"#dc2626\" : \"#16a34a\";\n}\n\nfunction setStatus(title,text,type=\"info\"){\n  const box=document.getElementById(\"plannerStatus\");\n  if(!box) return;\n  box.className=\"status-box \"+type;\n  box.innerHTML=`<strong>${title}<\/strong><span>${text}<\/span>`;\n}\n\nasync function checkUser(){\n  const {data,error}=await supabaseClient.auth.getUser();\n  if(error || !data?.user){\n    window.location.href=\"https:\/\/nordbalance.dk\/?page_id=40\";\n    return null;\n  }\n  currentUser=data.user;\n  setText(\"loggedUser\",\"Logget ind som: \"+currentUser.email);\n  return currentUser;\n}\n\nasync function checkSubscription(){\n  if(!currentUser) return false;\n\n  const {data,error}=await supabaseClient\n    .from(\"abonnementer\")\n    .select(\"*\")\n    .eq(\"e-mail\",currentUser.email)\n    .order(\"oprettet_p\u00e5\",{ascending:false})\n    .limit(1)\n    .maybeSingle();\n\n  if(error){\n    console.warn(\"Kunne ikke tjekke abonnement:\",error);\n    return true;\n  }\n\n  if(!data){\n    console.warn(\"Ingen abonnement-r\u00e6kke fundet. Adgang tilladt midlertidigt.\");\n    return true;\n  }\n\n  const status=String(data.status||\"\").toLowerCase();\n  const blockedStatuses=[\"canceled\",\"cancelled\",\"unpaid\",\"past_due\",\"incomplete\",\"incomplete_expired\",\"paused\",\"blocked\"];\n  const isBlocked=data.adgang_blokeret===true || data.blokeret===true || data.aflyst===true || blockedStatuses.includes(status);\n\n  if(isBlocked){\n    document.querySelector(\".nb-planner\").innerHTML=`\n      <div class=\"premium-box\">\n        <h2>\ud83d\udd12 NordBalance Premium<\/h2>\n        <p>Din adgang er sat p\u00e5 pause, fordi betalingen ikke er aktiv. Opdater dit kort eller start abonnementet igen.<\/p>\n        <a href=\"${STRIPE_LINK}\">Opdater betaling<\/a>\n      <\/div>`;\n    return false;\n  }\n\n  return true;\n}\n\nfunction parseBudget(row){\n  const income=(num(row,\"samlet_indkomst\") || (num(row,\"income\")+num(row,\"indkomst2\")) || num(row,\"income\"));\n  const housing=num(row,\"housing\");\n  const food=num(row,\"food\");\n  const transport=num(row,\"transport\");\n  const subs=num(row,\"subs\");\n  const insurance=num(row,\"insurance\");\n  const utilities=num(row,\"utilities\");\n  const phone=num(row,\"phone\");\n  const debt=num(row,\"debt\");\n  const leisure=num(row,\"leisure\");\n  const other=num(row,\"other\");\n  const savings=num(row,\"savings\");\n  const fixed=subs+insurance+utilities+phone;\n  const expenses=housing+food+transport+fixed+debt+leisure+other;\n  const disposable=(num(row,\"r\u00e5dighedsbel\u00f8b\") || income-expenses-savings);\n  const adults=Number(row.voksne||1);\n  const children=Number(row.born||0);\n  const budgettype=String(row.budgettype||\"privat\").toLowerCase();\n\n  return {\n    raw:row,\n    month:row.month||row.m\u00e5ned||\"Seneste budget\",\n    budgettype,\n    adults,\n    children,\n    income,\n    income1:num(row,\"income\"),\n    income2:num(row,\"indkomst2\"),\n    housing,\n    food,\n    transport,\n    fixed,\n    subs,\n    insurance,\n    utilities,\n    phone,\n    debt,\n    leisure,\n    other,\n    savings,\n    expenses,\n    disposable\n  };\n}\n\nasync function fetchLatestBudget(){\n  if(!currentUser) return null;\n\n  let {data,error}=await supabaseClient\n    .from(\"budgets\")\n    .select(\"*\")\n    .eq(\"user_id\",currentUser.id)\n    .order(\"created_at\",{ascending:false})\n    .limit(1)\n    .maybeSingle();\n\n  if(error){\n    console.warn(\"Budget user_id fejl:\",error);\n  }\n\n  if(!data && currentUser.email){\n    const fallback=await supabaseClient\n      .from(\"budgets\")\n      .select(\"*\")\n      .eq(\"user_email\",currentUser.email)\n      .order(\"created_at\",{ascending:false})\n      .limit(1)\n      .maybeSingle();\n\n    data=fallback.data;\n    error=fallback.error;\n\n    if(error){\n      console.warn(\"Budget user_email fejl:\",error);\n    }\n  }\n\n  if(!data) return null;\n  return parseBudget(data);\n}\n\nasync function fetchExistingPlanner(){\n  if(!currentUser) return null;\n\n  const {data,error}=await supabaseClient\n    .from(SMART_TABLE)\n    .select(\"*\")\n    .eq(\"user_id\",currentUser.id)\n    .order(\"created_at\",{ascending:false})\n    .limit(1)\n    .maybeSingle();\n\n  if(error){\n    console.warn(\"Smart planner kunne ikke hentes:\",error);\n    return null;\n  }\n\n  if(data?.id) existingPlannerId=data.id;\n  return data;\n}\n\nfunction cap(value,min,max){\n  value=Number(value)||0;\n  if(value<min) return min;\n  if(value>max) return max;\n  return value;\n}\n\nfunction makeRecommendedPlan(b){\n  const isFamily=b.budgettype===\"familie\" || b.children>0 || b.adults>1;\n  const income=b.income;\n\n  const targets={\n    housing: income*0.35,\n    food: income*(isFamily ? 0.17 : 0.14),\n    transport: income*(isFamily ? 0.10 : 0.08),\n    subs: income*0.04,\n    insurance: income*0.04,\n    utilities: income*0.04,\n    phone: income*0.02,\n    debt: income*0.10,\n    leisure: income*(isFamily ? 0.09 : 0.12),\n    other: income*0.05,\n    savings: income*(isFamily ? 0.08 : 0.10),\n    buffer: income*(b.children>0 ? 0.08 : 0.06)\n  };\n\n  const actualRows=[\n    {key:\"housing\",name:\"Bolig\",actual:b.housing,target:targets.housing,type:\"fixed\",description:\"Fast udgift. Bruges som overblik, ikke som automatisk spareforslag.\",action:\"Hold \u00f8je med husleje\/l\u00e5n, men \u00e6ndr kun hvis det giver mening p\u00e5 l\u00e6ngere sigt.\"},\n    {key:\"food\",name:\"Mad\",actual:b.food,target:targets.food,type:\"save\",description:\"Madbudget kan ofte forbedres uden at livskvaliteten falder.\",action:\"Lav madplan, k\u00f8b ind 1 gang om ugen og sk\u00e6r ned p\u00e5 takeaway\/impulsk\u00f8b.\"},\n    {key:\"transport\",name:\"Transport\",actual:b.transport,target:targets.transport,type:\"review\",description:\"Transport kan v\u00e6re b\u00e5de fast og variabel.\",action:\"Tjek om abonnement, br\u00e6ndstof, parkering eller rejser kan optimeres.\"},\n    {key:\"subs\",name:\"Abonnementer\",actual:b.subs,target:targets.subs,type:\"save\",description:\"Abonnementer er ofte et godt sted at finde hurtige besparelser.\",action:\"Opsig streaming, apps, fitness eller medlemskaber du ikke bruger fast.\"},\n    {key:\"insurance\",name:\"Forsikringer\",actual:b.insurance,target:targets.insurance,type:\"review\",description:\"Forsikringer skal ikke bare fjernes, men priser kan sammenlignes.\",action:\"Indhent 2-3 tilbud og tjek om du er dobbeltforsikret.\"},\n    {key:\"utilities\",name:\"El \/ vand \/ varme\",actual:b.utilities,target:targets.utilities,type:\"fixed\",description:\"Fast regning. Den b\u00f8r prim\u00e6rt bruges som overblik.\",action:\"Tjek forbrug og aftale, men s\u00e6nk ikke automatisk posten i budgettet.\"},\n    {key:\"phone\",name:\"Telefon \/ internet\",actual:b.phone,target:targets.phone,type:\"review\",description:\"Kan ofte forhandles eller skiftes til billigere udbyder.\",action:\"Sammenlign abonnement og dataforbrug. Skift hvis du betaler for meget.\"},\n    {key:\"debt\",name:\"G\u00e6ld \/ l\u00e5n\",actual:b.debt,target:targets.debt,type:\"debt\",description:\"G\u00e6ld skal h\u00e5ndteres stabilt og ikke bare sk\u00e6res v\u00e6k.\",action:\"Priorit\u00e9r dyr g\u00e6ld f\u00f8rst, betal til tiden og overvej ekstra afdrag hvis der er overskud.\"},\n    {key:\"leisure\",name:\"Fritid \/ fri forbrug\",actual:b.leisure,target:targets.leisure,type:\"save\",description:\"Fri forbrug er ofte nemmest at justere m\u00e5ned for m\u00e5ned.\",action:\"S\u00e6t et fast m\u00e5nedsbel\u00f8b og brug 24-timers-reglen f\u00f8r impulsk\u00f8b.\"},\n    {key:\"other\",name:\"Andre udgifter\",actual:b.other,target:targets.other,type:\"save\",description:\"Andre udgifter b\u00f8r opdeles, hvis de fylder meget.\",action:\"Gennemg\u00e5 posten og find ud af hvad pengene konkret g\u00e5r til.\"}\n  ];\n\n  let savingPotential=0;\n  const rows=actualRows.map(function(item){\n    let recommended=Math.round(item.actual);\n    let diff=item.actual-item.target;\n    let status=\"green\";\n    let headline=\"Ser fint ud\";\n    let advice=item.action;\n    let saving=0;\n\n    if(item.actual===0){\n      status=\"neutral\";\n      headline=\"Ingen registreret udgift\";\n      advice=\"Der er ikke gemt noget bel\u00f8b p\u00e5 denne post.\";\n    }else if(item.type===\"fixed\"){\n      status=diff>1500 ? \"yellow\" : \"green\";\n      headline=\"Fast udgift\";\n      recommended=Math.round(item.actual);\n      advice=item.description+\" \"+item.action;\n    }else if(item.type===\"debt\"){\n      status=diff>1500 ? \"yellow\" : \"green\";\n      headline=\"G\u00e6ld skal planl\u00e6gges\";\n      recommended=Math.round(item.actual);\n      advice=\"S\u00e6nk ikke betalingen automatisk. \"+item.action;\n    }else if(diff>0){\n      saving=Math.round(diff);\n      savingPotential+=saving;\n      recommended=Math.max(0,Math.round(item.target));\n      status=diff>1000 ? \"red\" : \"yellow\";\n      headline=\"Mulig besparelse: \"+kr(saving);\n      advice=item.action+\" Forslag: pr\u00f8v at n\u00e6rme posten mod ca. \"+kr(recommended)+\".\";\n    }else{\n      recommended=Math.round(item.actual);\n      headline=\"Godt niveau\";\n      advice=\"Posten ligger fornuftigt i forhold til indkomsten. \"+item.action;\n    }\n\n    return Object.assign({},item,{target:Math.round(item.target),recommended:Math.round(recommended),diff:Math.round(diff),status,headline,advice,saving});\n  });\n\n  const recommendedExpenses=rows.reduce((sum,r)=>sum+Number(r.recommended||0),0);\n  let recommendedSavings=Math.round(targets.savings);\n  let recommendedBuffer=Math.round(targets.buffer);\n  let leftoverAfterRecommended=income-recommendedExpenses-recommendedSavings-recommendedBuffer;\n\n  if(leftoverAfterRecommended<0){\n    const missing=Math.abs(leftoverAfterRecommended);\n    const reduceSavings=Math.min(recommendedSavings,missing);\n    recommendedSavings-=reduceSavings;\n    leftoverAfterRecommended=income-recommendedExpenses-recommendedSavings-recommendedBuffer;\n  }\n\n  if(leftoverAfterRecommended<0){\n    const missing=Math.abs(leftoverAfterRecommended);\n    const reduceBuffer=Math.min(recommendedBuffer,missing);\n    recommendedBuffer-=reduceBuffer;\n    leftoverAfterRecommended=income-recommendedExpenses-recommendedSavings-recommendedBuffer;\n  }\n\n  const actualAfterAll=income-b.expenses-b.savings;\n  const actualExpenseRate=income>0 ? b.expenses\/income : 0;\n  const actualSavingRate=income>0 ? b.savings\/income : 0;\n\n  let score=55;\n  if(income>0){\n    if(actualAfterAll>=0) score+=10;\n    if(actualExpenseRate<0.85) score+=10;\n    if(actualExpenseRate<0.70) score+=10;\n    if(actualSavingRate>=0.05) score+=10;\n    if(actualSavingRate>=0.10) score+=10;\n    if(savingPotential<1000) score+=5;\n  }\n  if(actualAfterAll<0) score-=25;\n  if(savingPotential>2000) score-=10;\n  score=Math.max(0,Math.min(100,Math.round(score)));\n\n  return {rows,recommendedExpenses,recommendedSavings,recommendedBuffer,leftoverAfterRecommended,savingPotential,score};\n}\n\nfunction renderOverview(){\n  const b=latestBudget;\n  const p=recommendedPlan;\n\n  if(!b || !p){\n    setStatus(\"Intet budget fundet\",\"G\u00e5 til Mit Budget og gem dit budget f\u00f8rst.\",\"warning\");\n    return;\n  }\n\n  setText(\"monthText\",b.month);\n  setText(\"budgetTypeText\",b.budgettype===\"familie\" ? \"Familie\" : \"Privat\");\n  setText(\"householdText\",b.adults+\" voksen\/voksne \u00b7 \"+b.children+\" barn\/b\u00f8rn\");\n\n  setText(\"incomeText\",kr(b.income));\n  setText(\"actualExpensesText\",kr(b.expenses));\n  setText(\"actualSavingsText\",kr(b.savings));\n  setText(\"actualLeftText\",kr(b.disposable));\n\n  setText(\"recommendedExpensesText\",kr(p.recommendedExpenses));\n  setText(\"recommendedSavingsText\",kr(p.recommendedSavings));\n  setText(\"recommendedBufferText\",kr(p.recommendedBuffer));\n  setText(\"recommendedLeftText\",kr(p.leftoverAfterRecommended));\n  setText(\"savingPotentialText\",kr(p.savingPotential));\n\n  setText(\"plannerScore\",p.score);\n\n  let scoreText=\"Din budget-score er \"+p.score+\"\/100.\";\n  if(p.score>=75) scoreText+=\" Dit budget ser st\u00e6rkt ud.\";\n  else if(p.score>=55) scoreText+=\" Dit budget er brugbart, men der er tydelige forbedringsmuligheder.\";\n  else scoreText+=\" Dit budget er presset og b\u00f8r justeres.\";\n  setText(\"scoreText\",scoreText);\n\n  let planHtml=\"\";\n  p.rows.forEach(function(r){\n    const diffText = r.saving>0 ? \"Kan muligvis frig\u00f8re: \"+kr(r.saving) : (r.type===\"fixed\" ? \"Fast post\" : \"Ingen spareforslag\");\n    planHtml+=`\n      <div class=\"budget-card ${r.status} smart-plan-card\">\n        <span>${r.name}<\/span>\n        <strong>${kr(r.actual)}<\/strong>\n        <div class=\"value-row\"><small>Nuv\u00e6rende<\/small><b>${kr(r.actual)}<\/b><\/div>\n        <div class=\"value-row\"><small>Plan<\/small><b>${kr(r.recommended)}<\/b><\/div>\n        <div class=\"value-row\"><small>Status<\/small><b>${diffText}<\/b><\/div>\n        <p><b>${r.headline}<\/b><br>${r.advice}<\/p>\n      <\/div>`;\n  });\n\n  planHtml+=`\n    <div class=\"budget-card green smart-plan-card\">\n      <span>Opsparing<\/span>\n      <strong>${kr(p.recommendedSavings)}<\/strong>\n      <div class=\"value-row\"><small>Nuv\u00e6rende<\/small><b>${kr(b.savings)}<\/b><\/div>\n      <div class=\"value-row\"><small>Plan<\/small><b>${kr(p.recommendedSavings)}<\/b><\/div>\n      <p><b>Fast opsparing<\/b><br>Forslag til realistisk m\u00e5nedlig opsparing ud fra din indkomst og dine nuv\u00e6rende udgifter.<\/p>\n    <\/div>\n    <div class=\"budget-card green smart-plan-card\">\n      <span>Buffer<\/span>\n      <strong>${kr(p.recommendedBuffer)}<\/strong>\n      <div class=\"value-row\"><small>Plan<\/small><b>${kr(p.recommendedBuffer)}<\/b><\/div>\n      <div class=\"value-row\"><small>Tilbage efter plan<\/small><b>${kr(p.leftoverAfterRecommended)}<\/b><\/div>\n      <p><b>Sikkerhed<\/b><br>Buffer giver plads til uforudsete regninger uden at budgettet v\u00e6lter.<\/p>\n    <\/div>`;\n\n  document.getElementById(\"budgetPlanRows\").innerHTML=planHtml;\n\n  const focusRows=p.rows.filter(r=>r.saving>0).sort((a,b)=>b.saving-a.saving).slice(0,4);\n  let insightHtml=\"\";\n\n  if(focusRows.length===0){\n    insightHtml='<div class=\"insight-card green\"><strong>\u2705 God balance<\/strong><p>Der er ikke tydelige poster, der b\u00f8r s\u00e6nkes automatisk. Fokus\u00e9r p\u00e5 fast opsparing og buffer.<\/p><\/div>';\n  }else{\n    focusRows.forEach(function(r,index){\n      insightHtml+=`\n        <div class=\"insight-card ${r.status}\">\n          <strong>${index+1}. ${r.name}<\/strong>\n          <p>${r.headline}. ${r.action}<\/p>\n        <\/div>`;\n    });\n  }\n\n  if(b.debt>0){\n    insightHtml+=`\n      <div class=\"insight-card yellow\">\n        <strong>G\u00e6ldsr\u00e5d<\/strong>\n        <p>Du har ${kr(b.debt)} i g\u00e6ldsbetaling. S\u00e6nk ikke betalingen uden plan. Betal dyr g\u00e6ld f\u00f8rst, og brug ekstra overskud til ekstra afdrag.<\/p>\n      <\/div>`;\n  }\n\n  document.getElementById(\"insightRows\").innerHTML=insightHtml;\n\n  let aiAdvice=\"\";\n  if(b.income<=0){\n    aiAdvice=\"Gem f\u00f8rst din indkomst p\u00e5 Mit Budget, s\u00e5 Smart Planner kan lave en automatisk budgetplan.\";\n  }else if(b.disposable<0){\n    aiAdvice=\"Dit budget ender i minus. Start med mad, abonnementer, fritid og andre udgifter. Faste regninger og g\u00e6ld skal ikke bare s\u00e6nkes automatisk.\";\n  }else if(focusRows.length>0){\n    aiAdvice=\"Start med \"+focusRows[0].name+\". Det er den mest oplagte post at gennemg\u00e5 f\u00f8rst. Samlet mulig forbedring er ca. \"+kr(p.savingPotential)+\". Faste regninger bruges kun som overblik.\";\n  }else{\n    aiAdvice=\"Dit budget ser sundt ud. Brug overskuddet til buffer, opsparing eller hurtigere afbetaling af dyr g\u00e6ld.\";\n  }\n\n  setText(\"aiAdvice\",aiAdvice);\n\n  if(b.income>0){\n    setStatus(\"Budget indl\u00e6st\",\"Smart Planner viser nu \u00e9t samlet budgetoverblik ud fra dine faktiske udgifter.\",\"success\");\n  }\n}\n\nasync function savePlanner(){\n  if(!currentUser || !latestBudget || !recommendedPlan){\n    setMessage(\"\u26a0\ufe0f Der mangler budgetdata fra Mit Budget.\",true);\n    return;\n  }\n\n  const getRow=(key)=>recommendedPlan.rows.find(r=>r.key===key)?.recommended || 0;\n\n  const row={\n    user_id:currentUser.id,\n    income:latestBudget.income,\n    housing:getRow(\"housing\"),\n    food:getRow(\"food\"),\n    transport:getRow(\"transport\"),\n    subscriptions:getRow(\"subs\") + getRow(\"insurance\") + getRow(\"utilities\") + getRow(\"phone\"),\n    debt:getRow(\"debt\"),\n    savings:recommendedPlan.recommendedSavings,\n    spending:getRow(\"leisure\"),\n    buffer:recommendedPlan.recommendedBuffer,\n    created_at:new Date().toISOString()\n  };\n\n  setMessage(\"Gemmer budgetplan...\");\n\n  try{\n    if(existingPlannerId){\n      const {error}=await supabaseClient\n        .from(SMART_TABLE)\n        .update(row)\n        .eq(\"id\",existingPlannerId)\n        .eq(\"user_id\",currentUser.id);\n      if(error) throw error;\n    }else{\n      const {data,error}=await supabaseClient\n        .from(SMART_TABLE)\n        .insert(row)\n        .select(\"id\")\n        .single();\n      if(error) throw error;\n      existingPlannerId=data.id;\n    }\n\n    setMessage(\"\u2705 Din anbefalede budgetplan er gemt.\");\n  }catch(error){\n    console.error(error);\n    setMessage(\"\u274c Kunne ikke gemme budgetplanen. Tjek smart_planner-tabellen i Supabase.\",true);\n  }\n}\n\nasync function initSmartPlanner(){\n  const user=await checkUser();\n  if(!user) return;\n\n  const access=await checkSubscription();\n  if(!access) return;\n\n  setStatus(\"Henter budget\",\"Vi henter dit seneste budget fra Mit Budget...\",\"info\");\n\n  await fetchExistingPlanner();\n  latestBudget=await fetchLatestBudget();\n\n  if(!latestBudget){\n    setStatus(\"Intet budget fundet\",\"G\u00e5 til Mit Budget og tryk Gem budget f\u00f8rst. Derefter kan Smart Planner lave et automatisk budget.\",\"warning\");\n    setText(\"scoreText\",\"Der mangler budgetdata fra Mit Budget.\");\n    document.getElementById(\"budgetPlanRows\").innerHTML=\"<p>Ingen budgetdata fundet.<\/p>\";\n    document.getElementById(\"insightRows\").innerHTML=\"<p>Gem f\u00f8rst et budget p\u00e5 Mit Budget.<\/p>\";\n    return;\n  }\n\n  recommendedPlan=makeRecommendedPlan(latestBudget);\n  renderOverview();\n\n  document.getElementById(\"savePlanBtn\").addEventListener(\"click\",savePlanner);\n}\n\nwindow.addEventListener(\"load\",initSmartPlanner);\n<\/script>\n\n<div class=\"nb-planner\">\n\n  <div class=\"nb-top\">\n    <div>\n      <h1>\ud83e\udde0 Smart Budget Planner<\/h1>\n      <p>Planneren henter automatisk dine tal fra Mit Budget og laver et bedre budget ud fra de udgifter, du allerede har.<\/p>\n      <div id=\"loggedUser\" class=\"logged-user\">Tjekker login&#8230;<\/div>\n    <\/div>\n    <button class=\"logout-btn\" type=\"button\" onclick=\"logoutUser()\">Log ud<\/button>\n  <\/div>\n\n <div class=\"nb-menu\">\n<a href=\"https:\/\/nordbalance.dk\/?page_id=63\">\ud83d\udcca Mit Budget<\/a>\n<a href=\"https:\/\/nordbalance.dk\/?page_id=126\">\ud83d\udcb0 Opsparing<\/a>\n<a href=\"https:\/\/nordbalance.dk\/?page_id=130\">\ud83d\udcc8 \u00d8konomi-score<\/a>\n<a href=\"https:\/\/nordbalance.dk\/?page_id=493\">\ud83d\udcc5 M\u00e5nedsoverblik<\/a>\n<a href=\"https:\/\/nordbalance.dk\/?page_id=195\">\ud83e\udde0 Smart Budget Planner<\/a>\n<a class=\"active\" href=\"https:\/\/nordbalance.dk\/?page_id=14\">\ud83e\udd16 AI Hj\u00e6lp<\/a>\n<a href=\"https:\/\/nordbalance.dk\/?page_id=76\">\u2699\ufe0f Min Profil<\/a>\n<\/div>\n\n  <section class=\"planner-hero\">\n    <span>Automatisk budget ud fra dine rigtige udgifter<\/span>\n    <h2>Automatisk budget med Smart Budget Planner<\/h2>\n    <p>NordBalance laver et automatisk budget ud fra dine gemte tal fra Mit Budget. Du f\u00e5r \u00e9t samlet overblik over indkomst, udgifter, opsparing, buffer, g\u00e6ld og de vigtigste steder, hvor du kan spare penge.<\/p>\n    <img decoding=\"async\" class=\"seo-img\" src=\"https:\/\/nordbalance.dk\/wp-content\/uploads\/2026\/05\/ChatGPT-Image-23.-maj-2026-12.20.05.png\" alt=\"Automatisk budget med Smart Budget Planner\">\n  <\/section>\n\n  <div id=\"plannerStatus\" class=\"status-box info\">\n    <strong>Henter data&#8230;<\/strong>\n    <span>Vi henter dit seneste budget fra Supabase.<\/span>\n  <\/div>\n\n  <div class=\"top-grid\">\n    <div class=\"planner-result\">\n      <h2>\ud83d\udcca Budget-score<\/h2>\n      <div class=\"score-circle\">\n        <strong id=\"plannerScore\">0<\/strong>\n        <span>\/100<\/span>\n      <\/div>\n      <p id=\"scoreText\">Henter budgetdata&#8230;<\/p>\n    <\/div>\n\n    <div class=\"overview-card big\">\n      <h2>Dit budget-overblik<\/h2>\n      <div class=\"mini-row\"><span>M\u00e5ned<\/span><strong id=\"monthText\">&#8211;<\/strong><\/div>\n      <div class=\"mini-row\"><span>Budgettype<\/span><strong id=\"budgetTypeText\">&#8211;<\/strong><\/div>\n      <div class=\"mini-row\"><span>Husstand<\/span><strong id=\"householdText\">&#8211;<\/strong><\/div>\n      <div class=\"mini-row\"><span>Indkomst<\/span><strong id=\"incomeText\">0 kr.<\/strong><\/div>\n    <\/div>\n  <\/div>\n\n  <h2 class=\"section-title\">\ud83d\udccc Dit samlede budgetoverblik<\/h2>\n  <div class=\"summary-grid\">\n    <div class=\"summary-card\"><span>Samlede udgifter nu<\/span><strong id=\"actualExpensesText\">0 kr.<\/strong><\/div>\n    <div class=\"summary-card\"><span>Nuv\u00e6rende opsparing<\/span><strong id=\"actualSavingsText\">0 kr.<\/strong><\/div>\n    <div class=\"summary-card\"><span>R\u00e5dighedsbel\u00f8b<\/span><strong id=\"actualLeftText\">0 kr.<\/strong><\/div>\n    <div class=\"summary-card green\"><span>Mulig forbedring<\/span><strong id=\"savingPotentialText\">0 kr.<\/strong><\/div>\n  <\/div>\n\n  <div class=\"summary-grid\">\n    <div class=\"summary-card\"><span>Planlagte udgifter<\/span><strong id=\"recommendedExpensesText\">0 kr.<\/strong><\/div>\n    <div class=\"summary-card green\"><span>Anbefalet opsparing<\/span><strong id=\"recommendedSavingsText\">0 kr.<\/strong><\/div>\n    <div class=\"summary-card green\"><span>Anbefalet buffer<\/span><strong id=\"recommendedBufferText\">0 kr.<\/strong><\/div>\n    <div class=\"summary-card\"><span>Tilbage efter planen<\/span><strong id=\"recommendedLeftText\">0 kr.<\/strong><\/div>\n  <\/div>\n\n  <div class=\"budget-results\" id=\"budgetPlanRows\"><\/div>\n\n  <h2 class=\"section-title\">\ud83d\udca1 Smarte fokuspunkter<\/h2>\n  <div class=\"insight-grid\" id=\"insightRows\"><\/div>\n\n  <div class=\"ai-box\">\n    <h2>\ud83e\udd16 AI budget-r\u00e5d<\/h2>\n    <p id=\"aiAdvice\">N\u00e5r dit budget er hentet, f\u00e5r du konkrete r\u00e5d her.<\/p>\n  <\/div>\n\n  <div class=\"save-area\">\n    <button id=\"savePlanBtn\" type=\"button\" class=\"save-btn\">Gem anbefalet budgetplan<\/button>\n    <p id=\"saveMessage\" class=\"save-message\"><\/p>\n  <\/div>\n\n  <div class=\"seo-box\">\n    <h2>Hvordan virker automatisk budget?<\/h2>\n    <p>Et automatisk budget hj\u00e6lper dig med at f\u00e5 et klart og roligt overblik over din privat\u00f8konomi. I stedet for at du selv skal taste de samme tal flere steder, henter NordBalance dine gemte oplysninger fra Mit Budget og bruger dem til at lave en samlet budgetanalyse. Det betyder, at Smart Budget Planner kan vise dine faktiske udgifter, dit r\u00e5dighedsbel\u00f8b, din opsparing og dine vigtigste fokuspunkter p\u00e5 \u00e9n side.<\/p>\n    <p>Med automatisk budget kan du se, hvordan dine penge fordeler sig mellem bolig, mad, transport, abonnementer, forsikringer, faste regninger, g\u00e6ld, fritid og andre udgifter. Systemet s\u00e6nker ikke bare faste regninger automatisk, fordi faste udgifter ofte er sv\u00e6re at \u00e6ndre fra den ene m\u00e5ned til den anden. I stedet viser NordBalance dem som overblik og giver forslag til de poster, hvor der realistisk kan v\u00e6re noget at hente.<\/p>\n\n    <h2>Fordele ved automatisk budget<\/h2>\n    <p>Den st\u00f8rste fordel ved automatisk budget er, at brugeren hurtigt kan forst\u00e5 sin \u00f8konomi uden at bygge et budget fra bunden. N\u00e5r tallene allerede er gemt i Mit Budget, kan Smart Budget Planner analysere dem og give konkrete anbefalinger. Det kan v\u00e6re forslag til at reducere madbudgettet, gennemg\u00e5 abonnementer, sammenligne forsikringer eller finde mere luft til opsparing og buffer.<\/p>\n    <p>Et automatisk budget g\u00f8r det ogs\u00e5 lettere at se, om \u00f8konomien er sund eller presset. Hvis udgifterne fylder for meget i forhold til indkomsten, viser systemet tydelige fokuspunkter. Hvis \u00f8konomien ser st\u00e6rk ud, kan brugeren i stedet fokusere p\u00e5 st\u00f8rre opsparing, buffer eller hurtigere afbetaling af dyr g\u00e6ld. P\u00e5 den m\u00e5de bliver automatisk budget ikke bare et skema, men et aktivt beslutningsv\u00e6rkt\u00f8j.<\/p>\n\n    <h3>Automatisk budget for familier<\/h3>\n    <p>Et automatisk budget for familier skal tage h\u00f8jde for, at mad, transport, forsikringer og uforudsete udgifter ofte er h\u00f8jere end hos en enkeltperson. Derfor bruger NordBalance oplysninger om budgettype, voksne og b\u00f8rn, n\u00e5r budgettet vurderes. Familier kan bruge automatisk budget til at finde en realistisk balance mellem faste udgifter, hverdagens forbrug, opsparing og buffer.<\/p>\n\n    <h3>Automatisk budget til privat\u00f8konomi<\/h3>\n    <p>Automatisk budget til privat\u00f8konomi er s\u00e6rligt nyttigt, hvis du vil vide, hvor pengene forsvinder hen hver m\u00e5ned. Mange har styr p\u00e5 indkomsten, men mister overblikket over sm\u00e5 betalinger, abonnementer, madindk\u00f8b og impulsk\u00f8b. Smart Budget Planner samler tallene og viser, hvor der er mulighed for forbedring uden at g\u00f8re budgettet urealistisk.<\/p>\n\n    <h3>Automatisk budget og g\u00e6ld<\/h3>\n    <p>Hvis der er g\u00e6ld i budgettet, viser NordBalance g\u00e6lden som et s\u00e6rskilt fokuspunkt. Et automatisk budget b\u00f8r ikke bare s\u00e6nke g\u00e6ldsbetalingen, fordi det kan g\u00f8re \u00f8konomien dyrere p\u00e5 l\u00e6ngere sigt. I stedet anbefaler systemet at betale til tiden, prioritere dyr g\u00e6ld f\u00f8rst og bruge eventuelt overskud til ekstra afdrag. Det giver et bedre overblik og kan hj\u00e6lpe brugeren med at blive hurtigere g\u00e6ldfri.<\/p>\n\n    <h3>Automatisk budget med spareforslag<\/h3>\n    <p>Smart Budget Planner kan give spareforslag p\u00e5 de poster, hvor det giver mening. Det kan for eksempel v\u00e6re mad, abonnementer, forsikringer, telefon, internet, fritid og andre variable udgifter. Faste regninger vises som overblik, mens forsikringer og abonnementer markeres som poster, der kan gennemg\u00e5s. P\u00e5 den m\u00e5de f\u00e5r brugeren realistiske r\u00e5d i stedet for urealistiske nedsk\u00e6ringer.<\/p>\n\n    <p>L\u00e6s ogs\u00e5 generelle r\u00e5d om budget og privat\u00f8konomi hos <a href=\"https:\/\/www.raadtilpenge.dk\/\" target=\"_blank\" rel=\"noopener\">R\u00e5d til Penge<\/a>.<\/p>\n  <\/div>\n\n<\/div>\n\n<style>\n.entry-content,\n.wp-block-post-content,\n.wp-site-blocks,\n.is-layout-constrained > *,\n.wp-block-group,\n.wp-block-html{max-width:100%!important;width:100%!important}\n\n.nb-planner{max-width:1500px!important;width:100%!important;margin:auto;padding:30px;font-family:Inter,Arial,sans-serif;background:#f5f7fb;border-radius:24px;color:#111827;box-sizing:border-box}\n.nb-top{display:flex;justify-content:space-between;align-items:flex-start;gap:20px;margin-bottom:20px}\n.nb-top h1{font-size:42px;margin:0;font-weight:900}\n.nb-top p{color:#64748b;font-size:18px;margin:8px 0 0;line-height:1.6;max-width:900px}\n.logged-user{margin-top:10px;font-weight:900;color:#2563eb}\n.logout-btn{background:#0f172a;color:white;text-decoration:none;padding:14px 22px;border-radius:14px;font-weight:900;border:none;cursor:pointer}\n.nb-menu{display:flex;gap:12px;flex-wrap:wrap;background:white;padding:15px;border-radius:18px;margin-bottom:25px;box-shadow:0 4px 18px rgba(0,0,0,.05)}\n.nb-menu a{text-decoration:none;color:#0f172a;font-weight:900;background:#f1f5f9;padding:14px 18px;border-radius:12px}\n.nb-menu a.active,.nb-menu a:hover{background:#dbeafe;color:#1d4ed8}\n.planner-hero{background:linear-gradient(135deg,#0f172a,#2563eb);color:white;padding:38px;border-radius:28px;margin-bottom:25px}\n.planner-hero span{display:inline-block;background:rgba(255,255,255,.15);padding:9px 14px;border-radius:999px;font-weight:900;margin-bottom:15px}\n.planner-hero h2{font-size:40px;margin:0 0 10px;font-weight:900}\n.planner-hero p{font-size:18px;color:#dbeafe;line-height:1.6;margin:0;max-width:900px}\n.seo-img{display:block;max-width:210px;width:100%;height:auto;border-radius:18px;margin:22px auto 0;background:white;padding:8px}\n.status-box{display:flex;justify-content:space-between;gap:12px;align-items:center;background:white;padding:18px 22px;border-radius:18px;margin-bottom:25px;border-left:7px solid #2563eb;box-shadow:0 4px 18px rgba(0,0,0,.05)}\n.status-box strong{font-size:20px}.status-box span{color:#475569;font-weight:800}.status-box.success{border-left-color:#22c55e;background:#f0fdf4}.status-box.warning{border-left-color:#f97316;background:#fff7ed}.status-box.info{border-left-color:#2563eb;background:white}\n.top-grid{display:grid;grid-template-columns:360px 1fr;gap:25px;margin-bottom:25px}\n.planner-result,.overview-card,.ai-box,.seo-box{background:white;padding:28px;border-radius:22px;box-shadow:0 4px 20px rgba(0,0,0,.05)}\n.planner-result h2,.overview-card h2,.ai-box h2,.seo-box h2{margin-top:0;font-size:28px}\n.score-circle{width:170px;height:170px;border-radius:50%;background:#dbeafe;display:flex;align-items:center;justify-content:center;margin:20px auto;gap:4px}\n.score-circle strong{font-size:56px}.score-circle span{font-size:22px;font-weight:900;color:#64748b}\n.planner-result p,.ai-box p,.seo-box p{font-size:18px;line-height:1.7;color:#475569}\n.mini-row{display:flex;justify-content:space-between;gap:16px;background:#f8fafc;padding:16px;border-radius:14px;margin-bottom:12px}\n.mini-row span{color:#64748b;font-weight:900}.mini-row strong{font-weight:900;text-align:right}\n.summary-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:18px;margin-bottom:25px}\n.summary-card{background:white;padding:22px;border-radius:18px;border:1px solid #e2e8f0;box-shadow:0 4px 18px rgba(0,0,0,.05)}\n.summary-card span{display:block;color:#64748b;font-weight:900;margin-bottom:8px}.summary-card strong{font-size:28px}.summary-card.green strong{color:#16a34a}\n.section-title{font-size:30px;margin:30px 0 18px}\n.budget-results,.compare-results{display:grid;grid-template-columns:repeat(auto-fit,minmax(250px,1fr));gap:18px;margin-bottom:25px}\n.budget-card,.compare-card{background:white;padding:22px;border-radius:20px;box-shadow:0 4px 18px rgba(0,0,0,.05);border-left:7px solid #22c55e}\n.budget-card.yellow,.compare-card.yellow{border-left-color:#facc15}.budget-card.red,.compare-card.red{border-left-color:#ef4444}.budget-card.neutral,.compare-card.neutral{border-left-color:#94a3b8}.budget-card.green,.compare-card.green{border-left-color:#22c55e}\n.budget-card span,.compare-card span{display:block;color:#64748b;font-weight:900;margin-bottom:8px}.budget-card strong,.compare-card strong{font-size:28px}.budget-card p,.compare-card p{color:#475569;line-height:1.5}.budget-card small,.compare-card small{display:block;margin-top:10px;color:#64748b;font-weight:900}\n.ai-box{background:#ecfeff;border-left:7px solid #06b6d4;margin-bottom:25px}\n.save-area{background:white;padding:24px;border-radius:22px;box-shadow:0 4px 18px rgba(0,0,0,.05);margin-bottom:25px;text-align:center}\n.save-btn{background:#2563eb;color:white;border:none;padding:16px 24px;border-radius:14px;font-size:18px;font-weight:900;cursor:pointer}.save-message{font-weight:900;margin:14px 0 0}\n.seo-box{line-height:1.75}.seo-box p{margin:0 0 14px}\n.premium-box{max-width:650px;margin:60px auto;text-align:center;background:white;padding:35px;border-radius:24px;box-shadow:0 4px 20px rgba(0,0,0,.06)}\n.premium-box h2{font-size:32px;margin-bottom:16px}.premium-box p{color:#64748b;line-height:1.6;font-size:17px;margin-bottom:24px}.premium-box a{display:inline-block;background:#2563eb;color:white;padding:15px 22px;border-radius:14px;font-weight:900;text-decoration:none}\n\n.smart-plan-card .value-row{display:flex;justify-content:space-between;gap:12px;background:#f8fafc;border-radius:12px;padding:10px 12px;margin:10px 0}\n.smart-plan-card .value-row small{margin:0;color:#64748b;font-weight:900}.smart-plan-card .value-row b{font-weight:900;text-align:right}\n.insight-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:18px;margin-bottom:25px}\n.insight-card{background:white;padding:22px;border-radius:20px;box-shadow:0 4px 18px rgba(0,0,0,.05);border-left:7px solid #22c55e}\n.insight-card.yellow{border-left-color:#facc15}.insight-card.red{border-left-color:#ef4444}.insight-card.green{border-left-color:#22c55e}.insight-card strong{font-size:20px}.insight-card p{color:#475569;line-height:1.6;font-size:17px}\n\n@media(max-width:900px){.nb-planner{padding:18px;border-radius:16px}.nb-top{flex-direction:column}.nb-top h1{font-size:32px}.planner-hero h2{font-size:30px}.top-grid{grid-template-columns:1fr}.score-circle{width:145px;height:145px}.score-circle strong{font-size:46px}.nb-menu{display:grid;grid-template-columns:1fr}.nb-menu a{text-align:center}.logout-btn{width:100%;text-align:center}.status-box{flex-direction:column;align-items:flex-start}.overview-card,.planner-result,.ai-box,.seo-box{padding:22px}}\n<\/style>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\ud83e\udde0 Smart Budget Planner Planneren henter automatisk dine tal fra Mit Budget og laver et bedre budget ud fra de udgifter, du allerede har. Tjekker login&#8230; Log ud \ud83d\udcca Mit Budget \ud83d\udcb0 Opsparing \ud83d\udcc8 \u00d8konomi-score \ud83d\udcc5 M\u00e5nedsoverblik \ud83e\udde0 Smart Budget Planner \ud83e\udd16 AI Hj\u00e6lp \u2699\ufe0f Min Profil Automatisk budget ud fra dine rigtige udgifter Automatisk [&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-195","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/nordbalance.dk\/index.php?rest_route=\/wp\/v2\/pages\/195","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/nordbalance.dk\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/nordbalance.dk\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/nordbalance.dk\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/nordbalance.dk\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=195"}],"version-history":[{"count":23,"href":"https:\/\/nordbalance.dk\/index.php?rest_route=\/wp\/v2\/pages\/195\/revisions"}],"predecessor-version":[{"id":503,"href":"https:\/\/nordbalance.dk\/index.php?rest_route=\/wp\/v2\/pages\/195\/revisions\/503"}],"wp:attachment":[{"href":"https:\/\/nordbalance.dk\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=195"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}