Code & Engineering

WCAG Color Contrast Check: AA and AAA Ratios

Computes the real contrast ratio of every text and background pair in pasted CSS, design tokens or a palette, says whether each pair passes WCAG AA and AAA, and gives every failing pair a replacement color that passes on its real background. It carries a table of 256 channel values so the ratio is added and divided instead of guessed, and it reads the cases a glance gets wrong: a rgba color or opacity is blended with its background first, a placeholder is text, 18px bold is not large text, a border or an icon is a 3:1 component, a disabled control and a logo are exempt, short hex and color names are expanded, and 4.48 is never rounded up to 4.5. One line per pair, then a Verdict line. Use when asked for a WCAG color contrast check of a stylesheet, theme or palette, whether colors pass AA or AAA, or to fix text colors that are too pale.

WCAG Color Contrast Check: AA and AAA Ratios is a SKILL.md that computes the real contrast ratio of every text and background pair in pasted CSS, design tokens or a palette, says whether each pair passes WCAG AA and AAA, and gives every failing pair a replacement color that passes on its real background; an agent buys it once for $0.05 over x402.

Tested 2026-11-12No code, no hidden instructionsv1.0.1 · 10.3 KB · perpetual license

Not for

Reading markup for missing alt text, labels or keyboard access, and judging text on images, gradients or colors set by a script: you must say which color is behind the text. It reads the colors you paste and does not open your site. Color blindness simulation and APCA scores are not covered; the formula is WCAG 2.2.

Tested, honestly

Tested 2026-11-12 with a strong and a weak model.

With and without the skill

Results with and without the skill, for Sonnet and Haiku
SonnetHaiku
withwithoutwithwithout
Color pairs judged right (31 pairs)31/3112/3131/3129/31
Cases that ended with a pair-by-pair answer (5 cases)5/52/55/55/5

Read by hand. Without the file Sonnet gave a right answer on the two cases where it answered (the light stylesheet and the dark tokens, all 12 pairs right), but on the other three, with no tools in the test, it wrote out calls to a shell to compute the ratios and never produced an answer, in both of two runs on the form and the brand palette and in the final run on the clean theme as well; the run on the form cost about $1.30 in tokens and the clean theme $1.66. Those pairs count as not answered. So what the file gives Sonnet is mostly the table that lets it finish the arithmetic itself, not new rules. Haiku without the file answered every case with the right verdicts and good fixes, but called the logo wordmark and the disabled button failures (2 pairs); it also computed a few ratios to 4.62 where the true one is 4.54 on a tinted footer, which stayed inside the pass verdict.

Same cases and the same checks with and without the skill. The cases are ours, written around what the skill is for; with a handful of cases, a difference of one or two is within noise.

SonnetStrong model, claude-sonnet-5-5
Right on all 31 pairs in the 5 cases, read by hand against the formula. On the light CSS it put the fix for grey text on the tinted panel against the panel itself and gave the white-on-blue button a dark text colour; on the dark tokens it blended the transparent text and the opacity with the surface before taking the ratio; on the form it treated the placeholder as text, 18px bold as normal text, the border and the icon as 3 to 1 components and the disabled button as exempt; on the brand palette it expanded #abc-style short hex and the name gray, called the logo exempt and passed 24px regular text at 3.78. On the clean theme it answered that all pairs pass, including the two pairs just above 4.5. The ratio on the line was within 0.1 of the true one in all 31 pairs, and the closing Verdict line was exact in four of the five answers (in the fifth, the dark tokens, it added a remark after the line).
HaikuWeak model, claude-haiku-5-5
Right on all 31 pairs, with the true ratio within 0.1 on every line and, for every pair marked failing AA, a fix that passes on the real background; the logo and the disabled button were written as exempt. Its closing line was less tidy than Sonnet's: in four of five answers it added a remark after the Verdict line.

Full test summary

Example

Our own test text, before and after the skill ran. Excerpts only.

English · claude-sonnet-5-5

Before

/* app.css - Cashly dashboard, light theme */ :root { --bg: #ffffff; --panel: #eef2f7; --ink: #1e293b; --brand: #2b75ee; --link: #3c6fdd; --ok-bg: #e3f6e8; --ok-ink: #1f7c46; --soft: #677383; --faint: #6a7482; } body { background: var(--bg); color: var(--ink); font: 16px/1.5 system-ui, sans-serif; } a { color: var(--link); }…

After

The ratios below were computed from the table in the skill. Only `btn-primary` needed a different kind of fix: white text can't reach 4.5:1 on `#2b75ee`, so the replacement text colour is a near-black. Darkening `--brand` would also work if you'd rather keep the white text. body: #1e293b on #ffffff — L 0.0218 / 1.0000 — 14.62:1 — normal text needs 4.5 — AA pass — AAA pass…

What is in the file

  • The pairs
  • The ratio
  • What the pair needs
  • The fix
  • The answer
  • Worked example (an analogue, not your input)
  • Limits

Languages

Any language. Tried in: English.

License

Perpetual, non-exclusive; use and modify for yourself incl. paid work; no resale or republishing. Holder: Georgi Kalchev, aiskills402.com. Full terms.

Versions

Current version 1.0.1, updated 2026-11-13. Whoever bought an earlier version gets new ones free through the same re-download token.

  1. v1.0.1 · 2026-11-13

    One sentence in the input rules reworded (no rule changed, not re-tested): the end of the line on a pair with an unknown background shared five words with three free articles on our blog, and paid wording must not appear there.

  2. v1.0.0 · 2026-11-12

    First release. The idea is ours (the owner's pick list of 12 November 2026); no foreign skill or repository was opened. The file carries a table of 256 channel values (generated by a script, checked against 4.542, 4.478, 2.849 and 21), the WCAG 2.2 formula as a short procedure, the thresholds by text size and component, the rules for transparency, placeholders, 18px bold, borders and icons, disabled controls and logos, and a fix rule computed against the real background. Output: one line per pair and a Verdict line.

    Measured on 12 November 2026, five cases and 31 pairs, scored by a script that applies the formula (not by patterns): Sonnet 31 of 31 with the file, 12 of 31 without it (on three of five cases it tried to call a shell and gave no answer; where it answered, it was right); Haiku 31 of 31 with the file, 29 of 31 without it (a logo and a disabled button called failures). An earlier run of Sonnet alone without the file, before the file was written, gave 18 of 31 with the same two cases right and two without an answer. The side with the file was run twice (the worked example in the file was reworded after the first run to avoid shared wording with the answers; both runs gave 31 of 31 for both models, the second is the final file). No check was widened after the runs.

    Public sources: see notes/ideas.md. The two public themes this idea came from have no rule for contrast, so only with and without the file was compared.

    Price 50000 ($0.05), by the measured gain for Sonnet (19 pairs, but mostly through the missing arithmetic, not through new rules, and not owner-measured, so the lower of the two tiers).

FAQ

How is each pair reported?

One line per pair with the two luminances, the ratio, the size class and the AA and AAA verdicts, and for a pair that fails AA a replacement color with its own ratio on the same background. The last line is the verdict with the number of failing pairs, or all pairs passing. A fix is a neutral grey or near-black, so keep your own hue by checking a tint of it against the same background.

Which cases does it read that a glance gets wrong?

Transparent colors and opacity are blended with the background before the ratio is taken. A placeholder counts as text, 18px bold does not count as large text, and an input border or a meaningful icon needs 3 to 1 against its neighbour. A disabled control and a logo have no requirement and get an exempt line. Short hex such as #abc and color names such as gray are expanded first, and a ratio of 4.499 is a fail, never rounded up.

Does Claude Sonnet do better with this file?

It does, mainly by letting it finish the sums. Across 31 text and background pairs in five setups, Sonnet with the file judged all 31 right, each fix colour passing on the real background. Without it, Sonnet was right on the 12 pairs of the two setups it answered; on the other three it tried to call a shell for the arithmetic, which this test does not give, and returned no answer. Haiku went from 29 right to 31: alone it called a logo and a disabled button failures.

How accurate is the table inside it?

It holds the 256 channel values with four decimals, generated by a script and checked against four known results: 4.54 for #767676 on white, 4.48 for #777777, 2.85 for #999999 and 21 for black on white. On 300000 random pairs the ratio from the table is off by at most 0.007, so a pair within 0.02 of a threshold is recomputed with more digits.

Share

Read this page as Markdown: /skills/wcag-color-contrast-check.md.

  • Accessibility Review: WCAG Defects in Markup

    Code & Engineering

    SKILL.md · v1.0.0 · 6.8 KB

    Reviews pasted HTML or JSX for the accessibility defects a screen reader or keyboard user hits first, and names the WCAG 2.2 success criterion for each. It flags images without a text alternative, form fields without a label, buttons and links with no accessible name, clickable elements that a keyboard cannot reach, focusable content hidden from assistive technology, personal-data fields without autocomplete, data tables without header cells and pages without a language, and it marks heading levels that skip and positive tabindex values as best-practice findings, not WCAG failures. Each finding has a fixed code, the element, the criterion and a fix, then one verdict. Use to review HTML for accessibility, audit a component or page markup for WCAG issues, or check a form or template before release.

    $0.03once

    • x402
    • USDC
    • Base
    Get skill

    Tested with Sonnet and Haiku, 8 Oct 2026

More in Code & Engineering

  • Recommended

    Safe Refactoring: Refactor Without Changing Behavior

    Code & Engineering

    SKILL.md · v1.0.1 · 9.7 KB

    Refactors, cleans up and modernizes Python, JavaScript, TypeScript and React code without changing what it does. It guards the change that cleanups make most often without saying so - how the code treats missing and empty values - and ends each answer with a short Behavior section that names what was checked and anything that changed. Use when asked to refactor, clean up, tidy, simplify or modernize a function, class, component or file.

    $0.05once

    • x402
    • USDC
    • Base
    Get skill

    Tested with Sonnet and Haiku, 13 Nov 2026

  • API Key Leaks in Code: Secret Handling Review

    Code & Engineering

    SKILL.md · v1.0.0 · 7.8 KB

    Reviews pasted application code, scripts and config for the four ways a secret leaks from the code that uses it, and lists only those, one line each with a fixed code, the place, who can then read the secret and the fix - or exactly No findings. It catches a secret value written to a log or printed (the key itself, an object or environment dump that contains it), a secret placed in a URL query string, a secret typed into source or a committed file, and a server secret sent to the browser through a public environment prefix or a prop of a client component. It leaves out the safe look-alikes: printing only that a key is present, its length or its last four characters, a publishable key that is public by design, and a secret read from the environment on the server. Use to review code that calls an API with a key, to check a Next.js or Vite project before release, or to gate a pull request that touches credentials.

    $0.01once

    • x402
    • USDC
    • Base
    Get skill

    Tested with Sonnet and Haiku, 29 Oct 2026

  • Convert a Cron Expression: Linux, Quartz, GitHub Actions

    Code & Engineering

    SKILL.md · v1.0.0 · 11.4 KB

    Converts an existing schedule between cron dialects so that the target runs at exactly the times the source runs - classic crontab, GitHub Actions schedule, a Quartz-style six-field expression, a small numbers-only HTTP scheduler (Cron Hub) and Cloudflare Workers Cron Triggers - answered as JSON with the crons and a note. Knows what changes between them - day-of-week 1 is Monday in crontab and GitHub but Sunday in Cloudflare, 0 is refused by Cloudflare, 7 means Sunday in crontab and Saturday in Cloudflare, names are refused by the small scheduler; a day of the month plus a day of the week means either in crontab but both in the small scheduler; the at-sign macros, reboot, seconds other than zero and sub-5-minute GitHub intervals have no equivalent; a time zone becomes a timezone key, a CRON_TZ line or two UTC hours. Refuses what cannot be run at the same times. Use when asked to move a job from one scheduler to another, to port a crontab or a workflow schedule to wrangler, or to check that an expression in one dialect means the same in another. For a schedule given in words, use cron-schedule instead.

    $0.02once

    • x402
    • USDC
    • Base
    Get skill

    Tested with Sonnet and Haiku, 9 Oct 2026

  • UI Edge-Case Test Data: Long Names, Empty and Huge Values

    Code & Engineering

    SKILL.md · v1.0.0 · 6.8 KB

    Turns the props of a UI component (a TypeScript type or a list of props) into strict JSON test data that stresses how it displays, and nothing else. Per prop it picks the worst values for the type, a string that is empty, one word of eighty characters with no space, on two lines, an emoji joined with a zero-width joiner, right-to-left letters or HTML-looking text, numbers at zero and at the large and decimal ends, lists that are empty, hold one item or hold a hundred, optional props left out, and dates at the far ends and across a time-zone edge. Every fixture still fits the declared type: a required prop is never missing, an enum gets only its values, a documented range is never broken, and callbacks are named apart from the data. Use to build fixtures for a component story, a visual test or a layout check, or to find what breaks a card, a list row or a badge.

    $0.01once

    • x402
    • USDC
    • Base
    Get skill

    Tested with Sonnet and Haiku, 29 Oct 2026