Accessibility
Statement last updated: September 4, 2026
Calcinum targets WCAG 2.2 Level AA. Naming a target is not the same as meeting it everywhere, so this page also records what we have actually checked, what we have not, and what we know is still wrong.
What we have verified
- Colour contrast computed against the actual rendered backgrounds by axe-core in a browser, not by eye over a palette. An earlier version of this list claimed every text colour met 4.5:1; that was wrong. Five did not — the three action-bar buttons at 3.07 to 3.99:1, the homepage category counts at 4.01:1 and the embed footer at 2.56:1 — and all five are fixed. Hover states were checked too, which axe does not do, and the share button's hover was also failing at 4.24:1.
- Every form control across all 478 built pages verified to have an accessible name, by label association, wrapping label, or aria-label. Enforced on every build by .scripts/verify-a11y.mjs.
- axe-core 4.10 run against the WCAG 2.0/2.1/2.2 A and AA rule sets in a real browser at 1280px and 375px, on the home page, a calculator, a state page, a city page, a blog post, the contact form, the corrections log, the calculator index and an embed fragment. All clean. It found two real faults that the static sweep could not: fifty unnamed links in the interactive US map, which also declared itself a single image while holding fifty focusable children, and a horizontally scrolling table that no keyboard could reach.
- Result announcement. The calculators rewrote their result in place with no live region, so a screen-reader user was never told the answer had changed; the only live region on the page was the copy-to-clipboard toast. A debounced polite region now announces a short summary on 262 calculator pages.
- The embed code handed to other sites, which had no iframe title and so exported a WCAG 4.1.2 failure into every page that used it.
- Every button verified to expose an accessible name, including icon-only controls.
- All images verified to carry alt text.
- Page language declared, and a skip link to the main landmark present on every full page.
- Heading order verified on all 478 built pages: each starts at h1, carries exactly one h1, and skips no level. Enforced after every build by .scripts/verify-headings.mjs, which fails the build on a regression.
- Duplicate element ids checked on all 478 built pages, and none remain. This was not cosmetic: a duplicated id made the extra-payment field on the loan calculator do nothing at all.
- Keyboard traversal of a representative calculator: all 45 tab stops reachable in a sensible order, each with a visible focus indicator. The site-wide search button had none and now does.
- Reflow at 400% zoom, tested at a 320px viewport on the home page, a paycheck calculator, the sales tax index and the military pay chart: no two-dimensional scrolling, and wide tables scroll inside their own container rather than the page.
- Dialog focus management on all three modals (embed, review, save calculation): focus moves into the dialog on open, Tab and Shift+Tab wrap inside it rather than escaping to the page behind, and focus returns to the control that opened it on close. Verified with real keypresses through every close path — Escape, the close button and the overlay.
What we have not tested
Automated checks catch structural problems. They do not tell you whether a page is usable. The following have not been done, and we would rather say so than imply a level of assurance we do not have:
- Whether the touch-target sizes hold in every layout. They were measured at 320, 375 and 1280 pixels and pass at all three; an axe run inside an unusually narrow preview pane reported a failure that turned out to be an artefact of that pane rather than a real one.
- Screen-reader testing with NVDA, JAWS, or VoiceOver.
- Keyboard traversal of every one of the 160-odd calculators individually; one representative page was tested in full.
- Reflow on every page at 400%; four representative pages were tested.
- Comprehension testing with people who use assistive technology.
Known issues
- Embedded widgets have no h1 or skip link. That is intentional — they are iframe fragments and the host page supplies both — but it means an embed viewed directly is not a well-formed document.
Telling us about a problem
If something on this site is difficult or impossible to use, please get in touch and say what you were trying to do and what got in the way. Accessibility problems are treated as defects, not suggestions, and go through the same route as a wrong number: fixed at source, with a check added so it does not come back. Our correction log records what we have fixed.