{
  "schemaVersion": 1,
  "slug": "rent-affordability-calculator",
  "category": "finance",
  "kind": "implementation",
  "independentValidation": false,
  "implementationHash": "36ba22dec0914310f1b2f7040d3c9d416927a9ad5fe6201e76ecdbcbff56727f",
  "provenance": "Generated from the calculation contract used by the published page. Publication is not external validation.",
  "sourceFiles": [
    "data/calculators/rent-affordability-calculator.json",
    "src/engine.js"
  ],
  "runtimeSource": "/sources/engine.txt",
  "runtimeHash": "5c888d8898afbdee36267bb9977829e1e2ac568f6677c8ee87469c139864645c",
  "scope": "The compute function records implemented equations, constants, lookup tables and custom rules. Inputs record defaults and allowed values; outputs record precision and units. Defaults are examples, not recommendations. General background references are not evidence for this specific algorithm.",
  "publishedFormula": {
    "formula": "Rₜ = max(0, (I+O)×p÷100 − U); R_d = max(0, (I+O)×0.45 − D − U); R = min(Rₜ, R_d); L = 40×R",
    "vars": [
      [
        "I",
        "Monthly gross income"
      ],
      [
        "O",
        "Other monthly income"
      ],
      [
        "D",
        "Existing monthly debt payments"
      ],
      [
        "p",
        "Target rent-to-income ratio (%)"
      ],
      [
        "U",
        "Estimated utilities per month"
      ],
      [
        "Rₜ",
        "Target-ratio rent limit after utilities"
      ],
      [
        "R_d",
        "R_d is the 45% gross-income ceiling after debts and utilities."
      ],
      [
        "R",
        "Recommended rent ceiling"
      ],
      [
        "L",
        "Annual income at 40× monthly rent (illustration)"
      ]
    ],
    "note": "Utilities are deducted from both rent limits. The 30% target and 45% gross-income cap are planning assumptions, not universal affordability rules. The 40× output is an optional screening comparison; landlord requirements vary. Move-in funds are displayed as entered."
  },
  "externalEvidence": null,
  "contract": {
    "compute": "const totalIncome = monthlyIncome+otherIncome; const maxRent = Math.max(0, totalIncome*targetRatio/100-utilitiesEstimate); const maxRentAfterDebts = Math.max(0, totalIncome*0.45-existingDebts-utilitiesEstimate); const recommendedRent = Math.min(maxRent, maxRentAfterDebts); return { totalIncome, maxRent, maxRentAfterDebts, recommendedRent, landlordIncome: recommendedRent*40 };",
    "inputs": [
      {
        "name": "monthlyIncome",
        "type": "number",
        "default": 6000,
        "min": 0,
        "max": 1000000,
        "step": 100
      },
      {
        "name": "otherIncome",
        "type": "number",
        "default": 0,
        "min": 0,
        "max": 1000000,
        "step": 100
      },
      {
        "name": "existingDebts",
        "type": "number",
        "default": 400,
        "min": 0,
        "max": 500000,
        "step": 25
      },
      {
        "name": "targetRatio",
        "type": "number",
        "default": 30,
        "min": 10,
        "max": 60,
        "step": 1,
        "slider": true
      },
      {
        "name": "utilitiesEstimate",
        "type": "number",
        "default": 150,
        "min": 0,
        "max": 5000,
        "step": 10,
        "slider": true
      }
    ],
    "outputs": [
      {
        "name": "totalIncome",
        "precision": 0,
        "unit": "$"
      },
      {
        "name": "maxRent",
        "precision": 0,
        "unit": "$"
      },
      {
        "name": "maxRentAfterDebts",
        "precision": 0,
        "unit": "$"
      },
      {
        "name": "recommendedRent",
        "precision": 0,
        "unit": "$"
      },
      {
        "name": "landlordIncome",
        "precision": 0,
        "unit": "$"
      }
    ],
    "interpret": null
  }
}
