{"id":134,"date":"2026-05-17T15:39:48","date_gmt":"2026-05-17T15:39:48","guid":{"rendered":"https:\/\/nordbalance.dk\/?page_id=134"},"modified":"2026-06-05T13:34:21","modified_gmt":"2026-06-05T13:34:21","slug":"oekonomi-score","status":"publish","type":"page","link":"https:\/\/nordbalance.dk\/?page_id=134","title":{"rendered":"\u00d8konomi-score"},"content":{"rendered":"\n<style>\n.nb-score-wrap{max-width:1250px;margin:auto;padding:25px 15px;font-family:Inter,Arial,sans-serif;background:#f5f7fb;color:#0f172a}\n.nb-score-top{display:flex;justify-content:space-between;align-items:center;gap:20px;margin-bottom:20px;flex-wrap:wrap}\n.nb-score-top h1{font-size:38px;margin:0;font-weight:900}\n.nb-score-top p{color:#64748b;font-size:17px;margin-top:6px}\n.nb-logout{background:#0f172a;color:white;text-decoration:none;padding:14px 22px;border-radius:14px;font-weight:800}\n.nb-menu{display:flex;flex-wrap:wrap;gap:12px;background:#fff;padding:18px;border-radius:24px;margin-bottom:25px;box-shadow:0 10px 30px rgba(0,0,0,.05)}\n.nb-menu a{padding:14px 18px;border-radius:14px;background:#eef2ff;font-size:16px;font-weight:800;text-decoration:none;color:#0f172a;text-align:center}\n.nb-menu a.active{background:#2563eb!important;color:white!important}\n.nb-hero{background:linear-gradient(135deg,#0f172a,#2563eb);padding:40px;border-radius:30px;color:white;margin-bottom:25px}\n.nb-hero-title{font-size:50px;font-weight:900;margin-bottom:16px;line-height:1.1}\n.nb-hero-text{font-size:20px;line-height:1.7;max-width:850px;opacity:.95}\n.nb-status{background:#fff7ed;border:2px solid #fdba74;padding:24px;border-radius:24px;margin-bottom:25px}\n.nb-status.success{background:#ecfdf5;border-color:#86efac}\n.nb-status.error{background:#fef2f2;border-color:#fca5a5}\n.nb-status-title{font-size:24px;font-weight:900;margin-bottom:8px;color:#9a3412}\n.nb-status.success .nb-status-title{color:#166534}\n.nb-status.error .nb-status-title{color:#991b1b}\n.nb-status-text{font-size:17px;line-height:1.6;color:#7c2d12}\n.nb-status.success .nb-status-text{color:#166534}\n.nb-status.error .nb-status-text{color:#991b1b}\n.nb-main-grid{display:grid;grid-template-columns:2fr 1fr;gap:22px;margin-bottom:25px}\n.nb-score-card,.nb-side-card{background:white;padding:28px;border-radius:28px;box-shadow:0 10px 30px rgba(0,0,0,.05)}\n.nb-score-circle{width:230px;height:230px;border-radius:50%;background:#94a3b8;margin:10px auto 25px;display:flex;justify-content:center;align-items:center;color:white;font-size:54px;font-weight:900}\n.nb-score-card h2,.nb-side-card h2{font-size:30px;margin:0 0 12px;font-weight:900}\n.nb-score-card p,.nb-side-card p{font-size:18px;line-height:1.7;color:#475569}\n.nb-side-grid{display:grid;gap:18px}\n.nb-side-card strong{display:block;font-size:28px;margin-top:10px;font-weight:900}\n.nb-kpi-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:18px;margin-bottom:25px}\n.nb-kpi{background:white;padding:24px;border-radius:24px;box-shadow:0 10px 30px rgba(0,0,0,.05)}\n.nb-kpi span{display:block;color:#64748b;font-weight:900;margin-bottom:10px}\n.nb-kpi strong{font-size:28px;font-weight:900}\n.nb-rating{padding:24px;border-radius:24px;background:#e5e7eb;margin-bottom:25px}\n.nb-rating.good{background:#dcfce7}\n.nb-rating.medium{background:#fef9c3}\n.nb-rating.bad{background:#fee2e2}\n.nb-rating h2{margin:0 0 8px;font-size:30px}\n.nb-rating p{margin:0;font-size:18px;line-height:1.6}\n.nb-actions{margin-top:25px;display:flex;gap:12px;flex-wrap:wrap;justify-content:center}\n.nb-action{display:inline-block;background:#22c55e;color:white;padding:16px 24px;border-radius:14px;font-size:17px;font-weight:900;text-decoration:none}\n.nb-blue{background:#2563eb}.nb-dark{background:#0f172a}.nb-purple{background:#7c3aed}\n@media(max-width:900px){.nb-main-grid{grid-template-columns:1fr}.nb-hero-title{font-size:38px}.nb-menu{flex-direction:column}.nb-menu a{width:100%}.nb-logout{width:100%;text-align:center}}\n@media(max-width:600px){.nb-score-top h1{font-size:30px}.nb-hero-title{font-size:30px}.nb-score-circle{width:180px;height:180px;font-size:42px}}\n<\/style>\n\n<div id=\"nbEconomyScorePage\" class=\"nb-score-wrap\">\n\n  <div class=\"nb-score-top\">\n    <div>\n      <h1>\u00d8konomi-score<\/h1>\n      <p>Se din \u00f8konomiske sundhed baseret p\u00e5 dit seneste budget.<\/p>\n    <\/div>\n    <a href=\"https:\/\/nordbalance.dk\/?page_id=43\" class=\"nb-logout\">Log ud<\/a>\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 class=\"active\" href=\"https:\/\/nordbalance.dk\/?page_id=134\">\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 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  <div class=\"nb-hero\">\n    <div class=\"nb-hero-title\">Din \u00f8konomi-score<\/div>\n    <div class=\"nb-hero-text\">\n      NordBalance henter automatisk dine tal fra Mit Budget og beregner din \u00f8konomi-score.\n    <\/div>\n  <\/div>\n\n  <div id=\"scoreStatus\" class=\"nb-status\">\n    <div class=\"nb-status-title\">Henter data&#8230;<\/div>\n    <div class=\"nb-status-text\">Vi henter dit seneste budget fra Supabase.<\/div>\n  <\/div>\n\n  <div class=\"nb-main-grid\">\n    <div class=\"nb-score-card\">\n      <div id=\"scoreCircle\" class=\"nb-score-circle\">0\/100<\/div>\n      <h2>Din \u00f8konomi-score<\/h2>\n      <p id=\"scoreText\">Indl\u00e6ser \u00f8konomi-score&#8230;<\/p>\n    <\/div>\n\n    <div class=\"nb-side-grid\">\n      <div class=\"nb-side-card\">\n        <h2>\ud83d\udcc5 Seneste m\u00e5ned<\/h2>\n        <strong id=\"monthBox\">Ingen data<\/strong>\n      <\/div>\n\n      <div class=\"nb-side-card\">\n        <h2>\ud83d\udcb0 R\u00e5dighedsbel\u00f8b<\/h2>\n        <strong id=\"disposableBox\">0 kr.<\/strong>\n      <\/div>\n\n      <div class=\"nb-side-card\">\n        <h2>\ud83e\udd16 AI anbefaling<\/h2>\n        <p id=\"aiAdvice\">Indl\u00e6ser AI analyse&#8230;<\/p>\n      <\/div>\n    <\/div>\n  <\/div>\n\n  <div class=\"nb-kpi-grid\">\n    <div class=\"nb-kpi\">\n      <span>Samlet indkomst<\/span>\n      <strong id=\"incomeBox\">0 kr.<\/strong>\n    <\/div>\n    <div class=\"nb-kpi\">\n      <span>Samlede udgifter<\/span>\n      <strong id=\"expenseBox\">0 kr.<\/strong>\n    <\/div>\n    <div class=\"nb-kpi\">\n      <span>Opsparing<\/span>\n      <strong id=\"savingBox\">0 kr.<\/strong>\n    <\/div>\n  <\/div>\n\n  <div id=\"ratingBox\" class=\"nb-rating\">\n    <h2 id=\"ratingTitle\">Din status<\/h2>\n    <p id=\"ratingText\">N\u00e5r data er hentet, vises din vurdering her.<\/p>\n  <\/div>\n\n  <div class=\"nb-actions\">\n    <a href=\"https:\/\/nordbalance.dk\/?page_id=63\" class=\"nb-action\">Mit Budget<\/a>\n    <a href=\"https:\/\/nordbalance.dk\/?page_id=493\" class=\"nb-action nb-blue\">M\u00e5nedsoverblik<\/a>\n    <a href=\"https:\/\/nordbalance.dk\/?page_id=195\" class=\"nb-action nb-purple\">Smart Budget Planner<\/a>\n    <a href=\"https:\/\/nordbalance.dk\/?page_id=14\" class=\"nb-action nb-dark\">AI Hj\u00e6lp<\/a>\n  <\/div>\n\n<\/div>\n\n<script src=\"https:\/\/cdn.jsdelivr.net\/npm\/@supabase\/supabase-js@2\"><\/script>\n\n<script>\nwindow.addEventListener(\"load\", async function () {\n\n  function waitForSupabase() {\n    return new Promise((resolve, reject) => {\n      let tries = 0;\n      const timer = setInterval(() => {\n        tries++;\n        if (window.supabase) {\n          clearInterval(timer);\n          resolve();\n        }\n        if (tries > 30) {\n          clearInterval(timer);\n          reject(new Error(\"Supabase blev ikke indl\u00e6st\"));\n        }\n      }, 100);\n    });\n  }\n\n  await waitForSupabase();\n\n  const supabaseClient = window.supabase.createClient(\n    \"https:\/\/vmcpmdcbzatavfkwdcuz.supabase.co\",\n    \"sb_publishable_ODGTPniESClcPb8E2alCQQ_3tadLNmM\"\n  );\n\n  const kr = (tal) =>\n    new Intl.NumberFormat(\"da-DK\", {\n      style: \"currency\",\n      currency: \"DKK\",\n      maximumFractionDigits: 0\n    }).format(Number(tal) || 0);\n\n  function setText(id, value) {\n    const el = document.getElementById(id);\n    if (el) el.textContent = value;\n  }\n\n  function setStatus(type, title, text) {\n    const box = document.getElementById(\"scoreStatus\");\n    if (!box) return;\n    box.className = \"nb-status \" + type;\n    box.innerHTML = `\n      <div class=\"nb-status-title\">${title}<\/div>\n      <div class=\"nb-status-text\">${text}<\/div>\n    `;\n  }\n\n  function n(row, keys) {\n    for (const key of keys) {\n      if (row[key] !== null && row[key] !== undefined && row[key] !== \"\") {\n        return Number(String(row[key]).replace(\",\", \".\")) || 0;\n      }\n    }\n    return 0;\n  }\n\n  function v(row, keys, fallback = \"\u2013\") {\n    for (const key of keys) {\n      if (row[key] !== null && row[key] !== undefined && row[key] !== \"\") {\n        return row[key];\n      }\n    }\n    return fallback;\n  }\n\n  try {\n    const { data: userData } = await supabaseClient.auth.getUser();\n\n    if (!userData || !userData.user) {\n      setStatus(\"error\", \"Ikke logget ind\", \"Log ind igen.\");\n      return;\n    }\n\n    const user = userData.user;\n\n    const { data, error } = await supabaseClient\n      .from(\"budgets\")\n      .select(\"*\")\n      .or(`user_id.eq.${user.id},user_email.eq.${user.email}`)\n      .order(\"created_at\", { ascending: false })\n      .limit(1);\n\n    if (error) {\n      console.error(error);\n      setStatus(\"error\", \"Kunne ikke hente data\", error.message);\n      return;\n    }\n\n    if (!data || data.length === 0) {\n      setStatus(\"error\", \"Intet budget fundet\", \"Gem f\u00f8rst et budget.\");\n      return;\n    }\n\n    const row = data[0];\n\n    const income = n(row, [\"samlet_indkomst\"]) || n(row, [\"income\"]) + n(row, [\"indkomst2\"]);\n    const savings = n(row, [\"savings\", \"opsparing\"]);\n    const debt = n(row, [\"debt\"]);\n    const expenses =\n      n(row, [\"housing\"]) +\n      n(row, [\"food\"]) +\n      n(row, [\"transport\"]) +\n      n(row, [\"subs\"]) +\n      n(row, [\"insurance\"]) +\n      n(row, [\"utilities\"]) +\n      n(row, [\"phone\"]) +\n      n(row, [\"debt\"]) +\n      n(row, [\"leisure\"]) +\n      n(row, [\"other\"]);\n\n    const disposable = n(row, [\"r\u00e5dighedsbel\u00f8b\"]) || income - expenses - savings;\n    const score = n(row, [\"score\"]);\n\n    setText(\"scoreCircle\", score + \"\/100\");\n    setText(\"scoreText\", \"Din \u00f8konomi-score er hentet fra dit seneste budget.\");\n    setText(\"monthBox\", v(row, [\"month\"], \"Ingen data\"));\n    setText(\"incomeBox\", kr(income));\n    setText(\"expenseBox\", kr(expenses));\n    setText(\"savingBox\", kr(savings));\n    setText(\"disposableBox\", kr(disposable));\n    setText(\"aiAdvice\", \"Dine tal er hentet. Brug budgettet til at holde \u00f8je med faste udgifter, g\u00e6ld og opsparing.\");\n\n    const circle = document.getElementById(\"scoreCircle\");\n    const ratingBox = document.getElementById(\"ratingBox\");\n\n    if (score >= 75) {\n      if (circle) circle.style.background = \"#22c55e\";\n      if (ratingBox) ratingBox.className = \"nb-rating good\";\n      setText(\"ratingTitle\", \"St\u00e6rk \u00f8konomi\");\n      setText(\"ratingText\", \"Du har en god balance mellem indkomst, udgifter og opsparing.\");\n    } else if (score >= 50) {\n      if (circle) circle.style.background = \"#f59e0b\";\n      if (ratingBox) ratingBox.className = \"nb-rating medium\";\n      setText(\"ratingTitle\", \"Middel \u00f8konomi\");\n      setText(\"ratingText\", \"Der er plads til forbedring, is\u00e6r hvis udgifter eller g\u00e6ld fylder meget.\");\n    } else {\n      if (circle) circle.style.background = \"#ef4444\";\n      if (ratingBox) ratingBox.className = \"nb-rating bad\";\n      setText(\"ratingTitle\", \"Presset \u00f8konomi\");\n      setText(\"ratingText\", \"Dine udgifter fylder meget i forhold til din indkomst.\");\n    }\n\n    setStatus(\"success\", \"Data hentet\", \"\u00d8konomi-score er opdateret fra Mit Budget.\");\n\n  } catch (err) {\n    console.error(err);\n    setStatus(\"error\", \"Fejl\", err.message);\n  }\n});\n<\/script>\n<style>\n.nb-section{\n  display:none!important;\n}\n<\/style>\n\n\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{\nmax-width:100% !important;\nwidth:100% !important;\n}\n\n.os-wrap{\nmax-width:1500px !important;\nwidth:100% !important;\nmargin:auto;\npadding:28px 14px;\nfont-family:Inter,Arial,sans-serif;\nbackground:#f5f7fb;\ncolor:#0f172a;\nbox-sizing:border-box;\n}\n\n.os-top{\ndisplay:flex;\njustify-content:space-between;\nalign-items:center;\ngap:18px;\nflex-wrap:wrap;\nmargin-bottom:20px;\n}\n\n.os-top h1{\nfont-size:40px;\nfont-weight:900;\nmargin:0;\n}\n\n.os-top p{\ncolor:#64748b;\nmargin-top:8px;\nfont-size:17px;\n}\n\n.os-dark{\ndisplay:inline-block;\nbackground:#0f172a;\ncolor:white;\npadding:14px 20px;\nborder-radius:14px;\nfont-weight:800;\ntext-decoration:none;\n}\n\n.os-menu{\ndisplay:flex;\nflex-wrap:wrap;\ngap:12px;\nbackground:white;\npadding:18px;\nborder-radius:22px;\nmargin-bottom:25px;\nbox-shadow:0 10px 30px rgba(0,0,0,.05);\n}\n\n.os-link{\npadding:14px 18px;\nbackground:#eef2ff;\nborder-radius:14px;\ntext-decoration:none;\nfont-weight:800;\ncolor:#0f172a;\ntext-align:center;\n}\n\n.os-link.active{\nbackground:#2563eb;\ncolor:white;\n}\n\n.os-grid{\ndisplay:grid;\ngrid-template-columns:2fr 1fr;\ngap:24px;\n}\n\n.os-card,.os-box,.os-stat{\nbackground:white;\nborder-radius:28px;\npadding:28px;\nbox-shadow:0 10px 30px rgba(0,0,0,.05);\n}\n\n.os-score{\nwidth:220px;\nheight:220px;\nborder-radius:50%;\nbackground:linear-gradient(135deg,#94a3b8,#64748b);\ndisplay:flex;\nalign-items:center;\njustify-content:center;\nfont-size:58px;\nfont-weight:900;\ncolor:white;\nmargin:auto auto 25px;\n}\n\n.os-premium{\nmax-width:650px;\nmargin:50px auto;\ntext-align:center;\n}\n\n.os-premium h2{\nfont-size:32px;\nmargin-bottom:15px;\n}\n\n.os-premium p{\nline-height:1.6;\ncolor:#64748b;\nmargin-bottom:25px;\n}\n\n.os-seo{\nbackground:white;\nborder-radius:28px;\npadding:28px;\nmargin-top:25px;\nbox-shadow:0 10px 30px rgba(0,0,0,.05);\n}\n\n.os-seo h2,.os-seo h3{color:#0f172a}\n.os-seo p,.os-seo li{line-height:1.8;color:#475569}\n.os-seo img{\nwidth:100%;\nmax-height:300px;\nobject-fit:contain;\nborder-radius:18px;\nbackground:#f8fafc;\npadding:12px;\nmargin-top:15px;\n}\n\n.os-household-grid{\ndisplay:grid;\ngrid-template-columns:repeat(auto-fit,minmax(190px,1fr));\ngap:14px;\nmargin-top:18px;\n}\n\n.os-household-box{\nbackground:#f8fafc;\nborder:1px solid #e2e8f0;\nborder-radius:18px;\npadding:16px;\n}\n\n.os-household-box span{\ndisplay:block;\nfont-size:13px;\nfont-weight:900;\ncolor:#64748b;\nmargin-bottom:7px;\n}\n\n.os-household-box strong{\nfont-size:22px;\nfont-weight:900;\ncolor:#0f172a;\n}\n\n.os-history-table-wrap{\noverflow-x:auto;\nwidth:100%;\n}\n\n@media(max-width:900px){\n.os-grid{grid-template-columns:1fr}\n.os-menu{display:grid;grid-template-columns:1fr}\n.os-link{text-align:center}\n.os-top h1{font-size:32px}\n.os-score{width:175px;height:175px;font-size:44px}\n.os-card,.os-box,.os-stat,.os-seo{padding:20px;border-radius:22px}\n}\n<\/style>\n\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_ANON_KEY=\"sb_publishable_ODGTPniESClcPb8E2alCQQ_3tadLNmM\";\nconst STRIPE_LINK=\"https:\/\/buy.stripe.com\/test_28EaEY4Dj4TZfXyglE7AI00\";\n\nconst client=supabase.createClient(SUPABASE_URL,SUPABASE_ANON_KEY);\n\nlet currentUser=null;\n\nasync function checkLogin(){\n  const {data:{user},error}=await client.auth.getUser();\n\n  if(error || !user){\n    window.location.href=\"https:\/\/nordbalance.dk\/?page_id=40\";\n    return false;\n  }\n\n  currentUser=user;\n  return true;\n}\n\nasync function checkSubscription(){\n  if(!currentUser){\n    return false;\n  }\n\n  const {data,error}=await client\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\n  const blockedStatuses=[\n    \"canceled\",\n    \"cancelled\",\n    \"unpaid\",\n    \"past_due\",\n    \"incomplete\",\n    \"incomplete_expired\",\n    \"paused\",\n    \"blocked\"\n  ];\n\n  const isBlocked =\n    data.adgang_blokeret === true ||\n    data.blokeret === true ||\n    data.aflyst === true ||\n    blockedStatuses.includes(status);\n\n  if(isBlocked){\n    document.body.innerHTML=`\n      <div class=\"os-premium os-card\">\n        <h2>\ud83d\udd12 NordBalance Premium<\/h2>\n        <p>\n          Din adgang er sat p\u00e5 pause, fordi betalingen ikke er aktiv.\n          Opdater dit kort eller start abonnementet igen for at bruge \u00d8konomi-score.\n        <\/p>\n        <a href=\"${STRIPE_LINK}\" class=\"os-dark\">Opdater betaling<\/a>\n      <\/div>\n    `;\n    return false;\n  }\n\n  return true;\n}\n\nasync function initPage(){\n  const loggedIn=await checkLogin();\n  if(!loggedIn)return;\n\n  const access=await checkSubscription();\n  if(!access)return;\n\n  loadEconomyScore();\n}\n<\/script>\n\n<div class=\"os-wrap\">\n\n<div class=\"os-top\">\n<div>\n<h1>\ud83d\udcc8 \u00d8konomi-score<\/h1>\n<p>Din \u00f8konomiske udvikling, score og AI-analyse<\/p>\n<\/div>\n\n<a href=\"https:\/\/nordbalance.dk\/?page_id=63\" class=\"os-dark\">\n\u2190 Tilbage til budget\n<\/a>\n<\/div>\n\n<div class=\"os-menu\">\n<a href=\"https:\/\/nordbalance.dk\/?page_id=63\" class=\"os-link\">\ud83d\udcca Mit Budget<\/a>\n<a href=\"https:\/\/nordbalance.dk\/?page_id=126\" class=\"os-link\">\ud83d\udcb0 Opsparing<\/a>\n<a href=\"https:\/\/nordbalance.dk\/?page_id=14\" class=\"os-link\">\ud83e\udd16 AI Hj\u00e6lp<\/a>\n<a href=\"https:\/\/nordbalance.dk\/?page_id=195\" class=\"os-link\">\ud83e\udde0 Smart Budget Planner<\/a>\n<a href=\"https:\/\/nordbalance.dk\/?page_id=134\" class=\"os-link active\">\ud83d\udcc8 \u00d8konomi-score<\/a>\n<a href=\"https:\/\/nordbalance.dk\/?page_id=76\" class=\"os-link\">\u2699\ufe0f Min Profil<\/a>\n<\/div>\n\n<div class=\"os-seo\">\n<h2>\u00d8konomi-score NordBalance og \u00f8konomisk udvikling<\/h2>\n\n<p>\u00d8konomi-score NordBalance hj\u00e6lper dig med at forst\u00e5 din \u00f8konomiske udvikling m\u00e5ned for m\u00e5ned. Systemet analyserer indkomst, udgifter, opsparing og \u00f8konomiske m\u00f8nstre for at skabe et simpelt \u00f8konomisk overblik.<\/p>\n\n<p>\u00d8konomi-score NordBalance er udviklet til private brugere, som \u00f8nsker et hurtigt indblik i deres \u00f8konomiske situation uden komplicerede regneark eller avancerede budgetv\u00e6rkt\u00f8jer.<\/p>\n\n<h3>Hvad kan \u00d8konomi-score NordBalance bruges til?<\/h3>\n<ul>\n<li>F\u00f8lge \u00f8konomisk udvikling m\u00e5ned for m\u00e5ned.<\/li>\n<li>Se \u00f8konomi-score og \u00f8konomisk sundhed.<\/li>\n<li>Modtage AI \u00f8konomianalyse.<\/li>\n<li>Forst\u00e5 \u00f8konomiske m\u00f8nstre.<\/li>\n<li>Forbedre opsparing og budget.<\/li>\n<\/ul>\n\n<p>Systemet beregner \u00f8konomiske data ud fra indkomst, udgifter og opsparing. Det g\u00f8r det lettere at se, om \u00f8konomien bev\u00e6ger sig i den rigtige retning.<\/p>\n\n<p>\u00d8konomi-score NordBalance hj\u00e6lper ogs\u00e5 med at identificere omr\u00e5der hvor \u00f8konomien kan forbedres. Hvis udgifter bliver h\u00f8je eller opsparing er lav, kan systemet vise anbefalinger.<\/p>\n\n<p>Over tid kan du sammenligne m\u00e5neder og se udviklingen i din \u00f8konomiske sundhed. Det giver et bedre beslutningsgrundlag og mere \u00f8konomisk ro.<\/p>\n\n<p>NordBalance samler budget, opsparing, Smart Budget Planner, AI \u00f8konomihj\u00e6lp og \u00f8konomi-score \u00e9t sted. Form\u00e5let er at g\u00f8re privat\u00f8konomi nemmere og mere overskueligt.<\/p>\n\n<h3>S\u00e5dan hj\u00e6lper \u00d8konomi-score NordBalance dig<\/h3>\n\n<p>\n\u00d8konomi-score NordBalance giver dig en enkel vurdering af din \u00f8konomiske sundhed.\nScoren g\u00f8r det nemmere at forst\u00e5, om dit budget h\u00e6nger sammen, om dine udgifter fylder for meget,\nog om din opsparing udvikler sig i den rigtige retning.\n<\/p>\n\n<p>\nN\u00e5r du gemmer flere m\u00e5neder i NordBalance, kan \u00d8konomi-score NordBalance vise om din \u00f8konomi bliver\nst\u00e6rkere, mere stabil eller mere presset.\n<\/p>\n\n<p>\n\u00d8konomi-score NordBalance kan bruges sammen med Mit Budget, Opsparing, Smart Budget Planner og\nAI \u00f8konomihj\u00e6lp.\n<\/p>\n\n<p>\nL\u00e6s mere hos <a href=\"https:\/\/www.forbrug.dk\" target=\"_blank\" rel=\"noopener\">Forbrugerr\u00e5det T\u00e6nk<\/a>.\n<\/p>\n\n<img decoding=\"async\" src=\"https:\/\/nordbalance.dk\/wp-content\/uploads\/2026\/05\/ChatGPT-Image-21.-maj-2026-09.19.52-1.png\" alt=\"\u00d8konomi-score NordBalance \u00f8konomisk udvikling AI analyse\">\n<\/div>\n\n<div class=\"os-grid\">\n\n<div class=\"os-card\">\n\n<div class=\"os-score\" id=\"scoreCircle\">\n0\/100\n<\/div>\n\n<div class=\"os-center\">\n\n<div class=\"os-title\">\nDin \u00f8konomi-score\n<\/div>\n\n<div class=\"os-text\" id=\"scoreText\">\nHenter \u00f8konomi-score&#8230;\n<\/div>\n\n<div class=\"os-level\" id=\"scoreLevel\">\nIndl\u00e6ser&#8230;\n<\/div>\n\n<\/div>\n\n<\/div>\n\n<div class=\"os-side\">\n\n<div class=\"os-box\">\n<h3>\ud83d\udcc5 Seneste m\u00e5ned<\/h3>\n<p id=\"latestMonth\">\nIngen data\n<\/p>\n<\/div>\n\n<div class=\"os-box\">\n<h3>\ud83d\udcb0 R\u00e5dighedsbel\u00f8b<\/h3>\n<p id=\"afterSavings\">\n0 kr.\n<\/p>\n<\/div>\n\n<div class=\"os-box os-ai\">\n<h3>\ud83e\udd16 AI anbefaling<\/h3>\n<p id=\"aiAdvice\">\nIndl\u00e6ser AI analyse&#8230;\n<\/p>\n<\/div>\n\n<\/div>\n\n<\/div>\n\n<div class=\"os-card os-history\">\n\n<h2>\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc67 Husstand og budgetgrundlag<\/h2>\n<div class=\"os-household-grid\">\n  <div class=\"os-household-box\"><span>Budgettype<\/span><strong id=\"householdType\">&#8211;<\/strong><\/div>\n  <div class=\"os-household-box\"><span>Voksne<\/span><strong id=\"householdAdults\">0<\/strong><\/div>\n  <div class=\"os-household-box\"><span>B\u00f8rn<\/span><strong id=\"householdChildren\">0<\/strong><\/div>\n  <div class=\"os-household-box\"><span>Samlet indkomst<\/span><strong id=\"householdIncome\">0 kr.<\/strong><\/div>\n  <div class=\"os-household-box\"><span>Indkomst 2<\/span><strong id=\"householdIncome2\">0 kr.<\/strong><\/div>\n  <div class=\"os-household-box\"><span>R\u00e5dighedsbel\u00f8b<\/span><strong id=\"householdDisposable\">0 kr.<\/strong><\/div>\n<\/div>\n\n<\/div>\n\n<div class=\"os-card os-history\">\n\n<h2>\ud83d\udcca Score historik<\/h2>\n\n<div id=\"historyTable\">\nIndl\u00e6ser&#8230;\n<\/div>\n\n<\/div>\n\n<\/div>\n\n<script>\nfunction money(value){\nreturn Number(value||0).toLocaleString(\"da-DK\")+\" kr.\";\n}\n\nfunction getField(row, names, fallback=0){\nfor(const name of names){\nif(row[name] !== undefined && row[name] !== null && row[name] !== \"\"){\nreturn row[name];\n}\n}\nreturn fallback;\n}\n\nfunction getNumberField(row, names){\nreturn Number(getField(row,names,0)) || 0;\n}\n\nfunction getExpense(row){\nreturn getNumberField(row,[\"bolig\",\"housing\"])+\ngetNumberField(row,[\"mad\",\"food\"])+\ngetNumberField(row,[\"transport\"])+\ngetNumberField(row,[\"subs\",\"subscriptions\",\"abonnementer\"])+\ngetNumberField(row,[\"forsikring\",\"insurance\"])+\ngetNumberField(row,[\"telefon\",\"phone\"])+\ngetNumberField(row,[\"g\u00e6ld\",\"gaeld\",\"debt\"])+\ngetNumberField(row,[\"fritid\",\"leisure\"])+\ngetNumberField(row,[\"andre\",\"other\"]);\n}\n\nfunction calculateScore(income,expenses,savings,disposable,debt,children,adults){\nlet expensePercent=income>0?(expenses\/income)*100:0;\nlet savingPercent=income>0?(savings\/income)*100:0;\nlet debtPercent=income>0?(debt\/income)*100:0;\nlet disposablePercent=income>0?(disposable\/income)*100:0;\n\nlet score=50;\n\nif(income>0){score+=10;}\nif(expensePercent<70){score+=18;}\nelse if(expensePercent<85){score+=8;}\nelse if(expensePercent>95){score-=20;}\nelse if(expensePercent>85){score-=10;}\n\nif(savingPercent>=20){score+=18;}\nelse if(savingPercent>=10){score+=12;}\nelse if(savingPercent>0){score+=5;}\nelse{score-=8;}\n\nif(disposable>0){score+=10;}\nif(disposablePercent>=10){score+=6;}\nif(disposable<0){score-=25;}\n\nif(debtPercent>25){score-=12;}\nelse if(debtPercent>15){score-=6;}\nelse if(debtPercent>0){score+=3;}\n\nif(children>0 && disposable>0){score+=3;}\nif(adults>=2 && income>0){score+=2;}\n\nif(score>100)score=100;\nif(score<0)score=0;\n\nreturn Math.round(score);\n}\n\nfunction normalizeBudget(row){\nconst income1=getNumberField(row,[\"indkomst\",\"income\"]);\nconst income2=getNumberField(row,[\"indkomst2\",\"income2\"]);\nconst income=getNumberField(row,[\"samlet_indkomst\",\"income\"] ) || (income1+income2);\nconst savings=getNumberField(row,[\"opsparing\",\"savings\"]);\nconst debt=getNumberField(row,[\"g\u00e6ld\",\"gaeld\",\"debt\"]);\nconst expenses=getExpense(row);\nconst disposable=getNumberField(row,[\"r\u00e5dighedsbel\u00f8b\",\"raadighedsbeloeb\",\"disposable\"]) || (income-expenses);\nconst adults=getNumberField(row,[\"voksen\",\"voksne\",\"adults\"]);\nconst children=getNumberField(row,[\"f\u00f8dt\",\"born\",\"b\u00f8rn\",\"children\"]);\nconst budgettype=String(getField(row,[\"budgettype\",\"account_type\"],\"Privat\"));\nconst month=String(getField(row,[\"m\u00e5ned\",\"month\"],\"Ingen\"));\nconst storedScore=getNumberField(row,[\"score\"]);\nconst score=storedScore>0?storedScore:calculateScore(income,expenses,savings,disposable,debt,children,adults);\n\nreturn {income1,income2,income,savings,debt,expenses,disposable,adults,children,budgettype,month,score};\n}\n\nfunction renderAdvice(data){\nif(data.income<=0){return \"Gem dit f\u00f8rste budget for at f\u00e5 en \u00f8konomi-score.\";}\nif(data.disposable<0){return \"Din \u00f8konomi er presset, fordi budgettet g\u00e5r i minus. Start med at reducere de st\u00f8rste udgifter.\";}\nif(data.score>=80){return \"Din \u00f8konomi ser st\u00e6rk ud. Fokus\u00e9r p\u00e5 st\u00f8rre opsparing, buffer og langsigtede m\u00e5l.\";}\nif(data.score>=60){return \"Din \u00f8konomi er stabil. Du kan forbedre scoren ved at \u00f8ge opsparing eller s\u00e6nke faste udgifter.\";}\nif(data.savings<=0){return \"Din opsparing er lav. Pr\u00f8v at s\u00e6tte et fast m\u00e5nedligt bel\u00f8b af, ogs\u00e5 selvom det starter sm\u00e5t.\";}\nreturn \"Reducer udgifter, gennemg\u00e5 abonnementer og skab mere luft i r\u00e5dighedsbel\u00f8bet.\";\n}\n\nasync function loadEconomyScore(){\nconst {data,error}=await client\n.from(\"budgetter\")\n.select(\"*\")\n.eq(\"bruger_id\",currentUser.id)\n.order(\"oprettet_dato\",{ascending:false});\n\nif(error){\nconsole.warn(\"Budgetter fejl:\",error);\ndocument.getElementById(\"scoreText\").innerText=\"Kunne ikke hente budgetdata.\";\nreturn;\n}\n\nif(!data || data.length===0){\ndocument.getElementById(\"scoreText\").innerText=\"Gem dit f\u00f8rste budget.\";\ndocument.getElementById(\"historyTable\").innerHTML=\"<p>Ingen scorehistorik endnu.<\/p>\";\nreturn;\n}\n\nconst normalized=data.map(normalizeBudget);\nlet latest=normalized[0];\nlet score=calculateScore(latest.income,latest.expenses,latest.savings,latest.disposable,latest.debt,latest.children,latest.adults);\n\nif(latest.score>0){score=latest.score;}\n\ndocument.getElementById(\"scoreCircle\").innerText=score+\"\/100\";\ndocument.getElementById(\"latestMonth\").innerText=latest.month || \"Ingen\";\ndocument.getElementById(\"afterSavings\").innerText=money(latest.disposable);\ndocument.getElementById(\"householdType\").innerText=latest.budgettype || \"Privat\";\ndocument.getElementById(\"householdAdults\").innerText=latest.adults || 0;\ndocument.getElementById(\"householdChildren\").innerText=latest.children || 0;\ndocument.getElementById(\"householdIncome\").innerText=money(latest.income);\ndocument.getElementById(\"householdIncome2\").innerText=money(latest.income2);\ndocument.getElementById(\"householdDisposable\").innerText=money(latest.disposable);\n\nif(score>=80){\ndocument.getElementById(\"scoreLevel\").innerText=\"St\u00e6rk \u00f8konomi\";\ndocument.getElementById(\"aiAdvice\").innerText=renderAdvice({...latest,score});\n}\nelse if(score>=60){\ndocument.getElementById(\"scoreLevel\").innerText=\"Stabil \u00f8konomi\";\ndocument.getElementById(\"aiAdvice\").innerText=renderAdvice({...latest,score});\n}\nelse if(score>=40){\ndocument.getElementById(\"scoreLevel\").innerText=\"Kr\u00e6ver opm\u00e6rksomhed\";\ndocument.getElementById(\"aiAdvice\").innerText=renderAdvice({...latest,score});\n}\nelse{\ndocument.getElementById(\"scoreLevel\").innerText=\"Presset \u00f8konomi\";\ndocument.getElementById(\"aiAdvice\").innerText=renderAdvice({...latest,score});\n}\n\nlet html=`\n<div class=\"os-history-table-wrap\">\n<table style=\"width:100%;border-collapse:collapse;min-width:760px;\">\n<tr>\n<th style=\"text-align:left;padding:10px;border-bottom:1px solid #e5e7eb;\">M\u00e5ned<\/th>\n<th style=\"text-align:left;padding:10px;border-bottom:1px solid #e5e7eb;\">Type<\/th>\n<th style=\"text-align:left;padding:10px;border-bottom:1px solid #e5e7eb;\">Voksne\/b\u00f8rn<\/th>\n<th style=\"text-align:left;padding:10px;border-bottom:1px solid #e5e7eb;\">Indkomst<\/th>\n<th style=\"text-align:left;padding:10px;border-bottom:1px solid #e5e7eb;\">Udgifter<\/th>\n<th style=\"text-align:left;padding:10px;border-bottom:1px solid #e5e7eb;\">Opsparing<\/th>\n<th style=\"text-align:left;padding:10px;border-bottom:1px solid #e5e7eb;\">R\u00e5dighedsbel\u00f8b<\/th>\n<th style=\"text-align:left;padding:10px;border-bottom:1px solid #e5e7eb;\">Score<\/th>\n<\/tr>\n`;\n\nnormalized.forEach(function(row){\nlet rowScore=row.score>0?row.score:calculateScore(row.income,row.expenses,row.savings,row.disposable,row.debt,row.children,row.adults);\n\nhtml+=`\n<tr>\n<td style=\"padding:10px;border-bottom:1px solid #e5e7eb;\">${row.month||\"-\"}<\/td>\n<td style=\"padding:10px;border-bottom:1px solid #e5e7eb;\">${row.budgettype||\"Privat\"}<\/td>\n<td style=\"padding:10px;border-bottom:1px solid #e5e7eb;\">${row.adults||0}\/${row.children||0}<\/td>\n<td style=\"padding:10px;border-bottom:1px solid #e5e7eb;\">${money(row.income)}<\/td>\n<td style=\"padding:10px;border-bottom:1px solid #e5e7eb;\">${money(row.expenses)}<\/td>\n<td style=\"padding:10px;border-bottom:1px solid #e5e7eb;\">${money(row.savings)}<\/td>\n<td style=\"padding:10px;border-bottom:1px solid #e5e7eb;\">${money(row.disposable)}<\/td>\n<td style=\"padding:10px;border-bottom:1px solid #e5e7eb;\">${rowScore}\/100<\/td>\n<\/tr>\n`;\n});\n\nhtml+=`<\/table><\/div>`;\n\ndocument.getElementById(\"historyTable\").innerHTML=html;\n}\n\ninitPage();\n<\/script>\n","protected":false},"excerpt":{"rendered":"<p>\u00d8konomi-score Se din \u00f8konomiske sundhed baseret p\u00e5 dit seneste budget. 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 Din \u00f8konomi-score NordBalance henter automatisk dine tal fra Mit Budget og beregner din \u00f8konomi-score. Henter data&#8230; Vi henter dit seneste budget fra Supabase. 0\/100 [&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-134","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/nordbalance.dk\/index.php?rest_route=\/wp\/v2\/pages\/134","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=134"}],"version-history":[{"count":33,"href":"https:\/\/nordbalance.dk\/index.php?rest_route=\/wp\/v2\/pages\/134\/revisions"}],"predecessor-version":[{"id":535,"href":"https:\/\/nordbalance.dk\/index.php?rest_route=\/wp\/v2\/pages\/134\/revisions\/535"}],"wp:attachment":[{"href":"https:\/\/nordbalance.dk\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=134"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}