Colours are tokens, and contrast is a calculated number
The palette sits in a block of 14 variables, and the secondary text uses a single token: `--muted: #666b65`. The ratios, recalculated with the relative luminance formula from WCAG on the site’s seven backgrounds: 5.45:1 on white, 5.15, 5.11, 5.03, 5.02, 4.79 and 4.72. The main text, `--ink: #181a19`, achieves 17.49:1 on white; the green accent `#355c46`, 7.58:1. When a colour does not reach the threshold, the token changes, not the argument in the meeting.
The components have keyboard patterns, not just appearance
The tabs group on the home page uses a roving tab index: only the active tab is reachable with Tab, the others are taken out of the order, and the left/right, Home and End arrows move focus, with the default key behaviour cancelled. It is the pattern from the recommended practices for accessible components, implemented, not quoted. In the site’s base components there are 21 accessible labels, 7 pressed/unpressed states, 3 links between a heading and a region, 2 selection states, 2 regions that announce changes and 2 links between a command and the panel it controls.
Motion has a stop button and turns off at the system preference
On the home page there are 38 automatically started infinite animations lasting more than five seconds — exactly the situation covered by the “Pause, Stop, Hide” criterion. All 38 are covered by pause buttons: when pressed, the animations switch to the stopped state and the button state changes. Separately, at `prefers-reduced-motion: reduce` a global rule cancels any animation and transition, stops smooth scrolling, removes hover movement and hides the pause button. In the main stylesheet there are seven such blocks, plus one in the base stylesheet.
Visible focus indicator, only where needed
A 2 px solid outline, in the accent green, with 5 px offset, applied via `:focus-visible` — so it appears during keyboard navigation and not on mouse click. Checked in the browser, element by element, on the header and on the first content controls: four different elements, the same outline. Nowhere in the stylesheet is there a removed outline without a replacement.
Forms that announce their states
In the site’s contact form, labels are implicit on fields, the error is marked as an alert and the confirmation as a status — so screen readers announce them without the user having to search. The bot trap is correctly hidden: parent without display, marked as hidden for assistive technologies and removed from the tab order. Our own audit confirms that the labelling rules, the name rules for selectors and the autocomplete rules all pass.
The check is done with a tool, on real pages
We run axe-core 4.10.2 on the live page, not in a test environment, on a sample of ten pages covering different patterns: the home page, the catalogue, a product page, the services index, a service page, the solutions matrix, a combination from the matrix, contact, pricing, an article and a legal document. The raw result is written on the page, with the number of nodes, not summarised as “compliant”.
What fails is published, not rounded away
From the same audit: at 320 px width, the command in the header and the menu button overflow the screen by 22 px and the page scrolls horizontally — the arithmetic is 362 px of content in a 280 px container. In the legal documents, links in the text are distinguishable from the surrounding text only by colour, and the ratio between the accent and body text is 1.01:1, so underlining is mandatory. Both are open, with a written fix. We publish them because a buyer who asks for accessibility deserves to see what a real defect list looks like.
No dark theme — stated, not simulated
The site does not have a dark theme. The token block is declared for three selectors that receive identical values, and in the code there is no rule for the system colour-scheme preference. Checked in the browser with a simulated dark scheme: the page stays white. The useful consequence: all measured contrast ratios are valid in both schemes. The unpleasant consequence: the theme switch is dead code from the colour point of view. A real dark theme means fully re-measuring contrast, not copying values.
Typography with rules, not preferences
One family for headings and text, with letter-spacing adjusted by level — tighter on the large headings, `-0.055em` at levels one and two, `-0.035em` at level three — and weight 500 on headings. Paragraphs use line balancing, so one word is not left on the last line. The container has a maximum width of 1240 px with 48 px margins, and buttons have the same line height throughout. These are rules written in the stylesheet, so they apply after we leave.