{
  "spec": "quick-html/v0",
  "id": "household-budget",
  "version": "0.1.0",
  "name": "Household Budget",
  "description": "Monthly household budget on one A4 page: income and expense tables with planned vs actual, per-category progress bars with a 100% tick, savings summary tiles and goals. Pick it when a family or household plans or reviews a month of money.",
  "useWhen": [
    "household budget",
    "monthly budget",
    "family budget",
    "budget review",
    "track spending",
    "huishoudboekje",
    "maandbudget",
    "haushaltsbudget",
    "budget familial"
  ],
  "format": "printable",
  "theme": "personal-finance",
  "tags": [
    "budget",
    "monthly",
    "money",
    "household",
    "tracker"
  ],
  "language": "en",
  "page": {
    "size": "A4",
    "orientation": "portrait"
  },
  "modules": [
    "edit-overlay",
    "print-helper"
  ],
  "slots": [
    {
      "name": "doc-title",
      "type": "text",
      "required": true,
      "example": "Household budget — Familie Jansen · September 2026",
      "notes": "Browser tab title; used as the download filename."
    },
    {
      "name": "title",
      "type": "text",
      "required": true,
      "example": "Household budget",
      "notes": "Masthead kicker above the household name; keep under ~30 chars."
    },
    {
      "name": "household-name",
      "type": "text",
      "required": true,
      "example": "Familie Jansen",
      "notes": "Family or household name, e.g. 'Familie Jansen' or 'Sam & Noor'."
    },
    {
      "name": "month-label",
      "type": "text",
      "required": true,
      "example": "September 2026",
      "notes": "Month chip top right."
    },
    {
      "name": "sum-income",
      "type": "text",
      "required": true,
      "example": "€ 5.461,45",
      "notes": "Actual income total — must equal income-actual-total."
    },
    {
      "name": "sum-expenses",
      "type": "text",
      "required": true,
      "example": "€ 4.239,70",
      "notes": "Actual expense total — must equal expense-actual-total."
    },
    {
      "name": "sum-saved",
      "type": "text",
      "required": true,
      "example": "€ 1.221,75",
      "notes": "sum-income minus sum-expenses (may be negative)."
    },
    {
      "name": "sum-rate",
      "type": "text",
      "required": true,
      "example": "22,4%",
      "notes": "sum-saved ÷ sum-income, one decimal."
    },
    {
      "name": "income-planned-total",
      "type": "text",
      "required": true,
      "example": "€ 5.400,00",
      "notes": "Sum of the income Planned column."
    },
    {
      "name": "income-actual-total",
      "type": "text",
      "required": true,
      "example": "€ 5.461,45",
      "notes": "Sum of the income Actual column."
    },
    {
      "name": "expense-planned-total",
      "type": "text",
      "required": true,
      "example": "€ 4.200,00",
      "notes": "Sum of the expense Planned column."
    },
    {
      "name": "expense-actual-total",
      "type": "text",
      "required": true,
      "example": "€ 4.239,70",
      "notes": "Sum of the expense Actual column."
    },
    {
      "name": "expense-diff-total",
      "type": "text",
      "required": true,
      "example": "− € 39,70",
      "notes": "expense-planned-total minus expense-actual-total, signed; must equal the sum of the row diffs."
    },
    {
      "name": "goals-content",
      "type": "html",
      "required": false,
      "example": "<ul><li><strong>Emergency fund</strong> — €&nbsp;4.200 / €&nbsp;6.000</li><li><strong>Summer holiday 2027</strong> — €&nbsp;850 / €&nbsp;2.500</li></ul>",
      "notes": "Inside the goals optional block: one <ul> with 1–3 <li>, each '<strong>Goal</strong> — saved so far / target'. Use &nbsp; between € and the amount."
    },
    {
      "name": "notes-content",
      "type": "html",
      "required": false,
      "example": "<p>New energy contract from October — the advance drops to €&nbsp;195.</p>",
      "notes": "Inside the notes optional block: 1–2 short <p> lines explaining outliers or next month's changes. Use &nbsp; between € and the amount."
    },
    {
      "name": "footer-line",
      "type": "text",
      "required": false,
      "example": "Reviewed together on 2 Oct 2026 · next check-in 1 Nov 2026",
      "notes": "Keep under ~80 chars."
    }
  ],
  "repeats": [
    {
      "name": "income-row",
      "description": "One row per income source (salaries, benefits, side income).",
      "min": 1,
      "max": 8,
      "slots": [
        {
          "name": "income-source",
          "type": "text",
          "required": true,
          "example": "Salary — Mark (net)",
          "notes": "Keep under ~45 chars."
        },
        {
          "name": "income-planned",
          "type": "text",
          "required": true,
          "example": "€ 3.180,00"
        },
        {
          "name": "income-actual",
          "type": "text",
          "required": true,
          "example": "€ 3.180,00"
        }
      ]
    },
    {
      "name": "expense-row",
      "description": "One row per spending category, with planned vs actual, a signed diff and a progress bar.",
      "min": 3,
      "max": 24,
      "slots": [
        {
          "name": "expense-group",
          "type": "text",
          "required": true,
          "example": "Housing",
          "notes": "Tiny group label above the category name: Housing, Food, Utilities, Insurance, Transport, Kids, Leisure, Other…"
        },
        {
          "name": "expense-category",
          "type": "text",
          "required": true,
          "example": "Mortgage & service costs",
          "notes": "Keep under ~40 chars."
        },
        {
          "name": "expense-planned",
          "type": "text",
          "required": true,
          "example": "€ 1.485,00"
        },
        {
          "name": "expense-actual",
          "type": "text",
          "required": true,
          "example": "€ 1.485,00"
        },
        {
          "name": "expense-diff",
          "type": "text",
          "required": true,
          "example": "− € 53,45",
          "notes": "planned − actual, signed: '+ € 23,20' money left, '− € 53,45' overspent, '€ 0,00' on plan."
        },
        {
          "name": "expense-diff-class",
          "type": "text",
          "required": true,
          "example": "delta",
          "notes": "class attribute of the diff span. EXACTLY 'delta' (zero or money left) or 'delta delta-neg' (overspent, renders red)."
        },
        {
          "name": "expense-bar-style",
          "type": "text",
          "required": true,
          "example": "width:76%",
          "notes": "style attribute of the bar fill. EXACTLY 'width:NN%' with NN = round(actual ÷ planned × 100), capped at 120."
        },
        {
          "name": "expense-bar-class",
          "type": "text",
          "required": true,
          "example": "fill fill-ok",
          "notes": "class attribute of the bar fill. EXACTLY 'fill fill-ok' (≤100% of planned) or 'fill fill-over' (>100%)."
        }
      ]
    }
  ],
  "optionals": [
    {
      "name": "goals",
      "description": "Compact savings-goals list (goals-content) — remove when the household tracks no goals."
    },
    {
      "name": "notes",
      "description": "Short free-form notes on outliers or next month's changes — remove when empty."
    }
  ],
  "changelog": [
    {
      "version": "0.1.0",
      "date": "2026-08-14",
      "notes": "Initial release: one-page monthly budget with income/expense tables, per-category progress bars, summary tiles and savings goals."
    }
  ],
  "agentInstructions": "Fill one income-row per income source and one expense-row per spending category; DELETE every data-example row — they are preview filler. Compute all numbers yourself, then re-check the arithmetic: totals are column sums; expense-diff = planned − actual (negative = overspent); sum-income and sum-expenses mirror the actual totals; sum-saved = sum-income − sum-expenses; sum-rate = sum-saved ÷ sum-income with one decimal ('22,4%'). Format money exactly like the placeholders — '€ 1.234,56' (adapt symbol and separators to the user's locale, but never mix formats in one document). Bars: expense-bar-style must be EXACTLY 'width:NN%' with NN = round(actual ÷ planned × 100), capped at 120 even when spending runs higher (the track ends at 120%; the tick marks 100%). expense-bar-class must be EXACTLY 'fill fill-ok' (≤100%) or 'fill fill-over' (>100%). expense-diff-class must be EXACTLY 'delta' (zero or money left) or 'delta delta-neg' (overspent — renders red; red is reserved for overspend). Sign diffs like the placeholders: '+ € 23,20', '− € 53,45', '€ 0,00'. Keep it to ONE page: beyond ~24 categories merge the smallest into a single 'Other' row. Remove the goals and notes optional blocks when there is nothing real to put in them. Unknown amounts: leave a recognizable placeholder like [MORTGAGE PER MONTH] and tell the user to fill it via the built-in Edit button.",
  "license": "MIT",
  "authors": [
    {
      "github": "bvrln"
    }
  ]
}
