Design languageAccessibility

Design language Accessibility

Accessibility

We build zeronesecurity.com to WCAG 2.2 level AA, in English and Turkish, and we check it on every change. This page sets out the rules the site follows, the test that holds each one and the places no test reaches yet.

WCAG 2.2 AA, on every change.

#

WCAG 2.2 level AA is the floor for every page in both languages, and a change that fails an accessibility check does not reach the site.

  • 0 axe violations allowed on a page, of any impact
  • 63 axe rules run on each scanned page, from 5 WCAG tag sets
  • 320 CSS pixels wide, and no page may scroll sideways
  • 100 desktop Lighthouse accessibility score required on 21 pages

axe-core judges what a machine can judge. Several criteria it cannot judge have scripted browser tests of their own, among them reflow, focus hidden under the sticky header and a pause control for moving content. The checks run on every merge request and every push, and the next section lists each one with the exact name its test has in the code.

  • Every built page is scanned, the 404 page included.

    WhyThe test takes its list of pages from the built site itself: every HTML file the build writes, in English and in Turkish, including the 404 page that a visitor sees at any address that does not exist. A new page is checked without anyone adding it.

    TestEnforced by a test on every change.

  • A change that fails a check does not reach the site.

    WhyDeployment of the site waits for the build gates, the browser tests and the desktop Lighthouse run. If one fails, the site is not deployed. In CI a browser test that fails is run once more, and it stops the deployment only if it fails again.

    BuildEnforced by the build pipeline on every change.

What is tested and how.

#

Each row is a check that runs on every change. When this page is built, every row is matched to the test that runs it, so a renamed, deleted or skipped test breaks the build of this page instead of leaving a stale claim behind.

Accessibility checks and how each one runs
Criterion or checkHow it is checked
WCAG 2.2 A and AA, automatedaxe-core 4.13.0 runs on every built page, the 404 page included, with the tags wcag2a, wcag2aa, wcag21a, wcag21aa, wcag22aa. axe leaves out its experimental and deprecated rules, so 63 rules run. The page is first scrolled from top to bottom so that visuals are judged in their final state, and the test expects an empty list of violations.
1.4.10 ReflowOne browser window 320 × 640 CSS px opens every built page, the 404 page included. No page may be wider than the window, not even by one pixel.
2.4.11 Focus not obscured60 presses of Tab, then 40 of Shift+Tab, on /, /zero-door and /tr/contact: once in a desktop window 1280 × 800 and once in a narrow window 390 × 844. After each press the test waits for scrolling to stop and fails if the sticky header covers the centre and all four corners of the focused element.
2.2.2 Pause, stop, hideOn every scanned page: if a loop has started, a visible pause control must be on the page as well, or the page fails. Every loop sets the mark data-ambient when it starts. The shared motion lifecycle sets it for the loops it runs; the noise canvas, the hold motion of the two scroll scenes and the scroll cue in the home page hero set it themselves. The build of this page stops if a component loops without setting it.
2.2.2 The decision persistsPausing on the home page pauses the site. On the Zero Door page the control still reads paused, and back on the home page the noise canvas reports itself paused.
2.2.2 and 2.5.8 on the Zero Door pageEvery looping visual has its own control; the first is at least 24 × 24 px and labelled as a pause. One click pauses every control and the moving rows stop, and the decision survives a reload.
2.5.8 Target size (minimum)The axe rule target-size, part of the wcag22aa tag set, runs on every scanned page.
1.4.13 Content on hover or focusOn a wide screen a rule on the home page opens when keyboard focus reaches its title. Escape closes it while focus stays, focus on its proof link opens it again and focus moving on to the next rule closes it. On a narrow screen the rules are an accordion: opening one closes the one that was open, and a closed rule keeps its link hidden.
2.1.1 KeyboardIn the evidence scene on the home page the arrow keys move between steps, take focus with them and stop at the first and the last step.
1.1.1 and 4.1.2 The label follows the stepChoosing a step changes the role=img label of the scene to the sentence for that step, taken from the dictionary.
1.3.1 Info and relationships: heading orderIn every built HTML file, heading levels inside <main> never skip. axe treats heading order as good practice rather than a WCAG rule, so a build gate holds it.
3.1.2 Language of partsIn the hero of the Turkish home page, the framework names in the trust line and the kicker carry lang=en. On the Turkish sector pages, a proof line quoted from the product’s English output carries lang=en, and a proof line written in Turkish carries none.
Reduced motion, site-wideEvery built page except the 404 page opens with reduced motion requested. No revealed element is left with a transform, every labelled visual in the main content is drawn, not hidden or clipped away, the motion class is not set and no loop starts.
Reduced motion, home pageOn the home page, with reduced motion requested, every revealed element stands in its final place with no transform, fully opaque and not hidden, and the motion class is never set.
Without JavaScript, site-wideEvery built page except the 404 page opens with scripts off. Every revealed element stands in its final place with no transform, and every labelled visual in the main content is drawn, not hidden or clipped away.
Without JavaScript, home pageWith scripts off, the evidence scene on the home page stacks its four cards, the stage stands still and the pause control stays hidden.
1.4.3 Contrast (minimum): text colour tokensink, ink-muted, ink-subtle and accent-deep are computed against paper and paper-2 and must reach 4.5:1 on both.
1.4.11 Non-text contrast: focus ring and field borderFrom the colour tokens, the accent focus ring is computed against paper, paper-2, accent-tint and ink, and the ink-subtle border of form fields against paper, paper-2 and accent-tint; each must reach 3:1. The test also checks that the contact form, the call-to-action band and the glossary filter draw their fields with that border, and that the global focus rule is a 2px solid accent outline.
Lighthouse accessibilityDesktop Lighthouse opens 21 pages, 2 runs each, and every run on each page must score 100 for accessibility.
  1. WCAG 2.2 A and AA, automated

    How it is checkedaxe-core 4.13.0 runs on every built page, the 404 page included, with the tags wcag2a, wcag2aa, wcag21a, wcag21aa, wcag22aa. axe leaves out its experimental and deprecated rules, so 63 rules run. The page is first scrolled from top to bottom so that visuals are judged in their final state, and the test expects an empty list of violations.

  2. 1.4.10 Reflow

    How it is checkedOne browser window 320 × 640 CSS px opens every built page, the 404 page included. No page may be wider than the window, not even by one pixel.

  3. 2.4.11 Focus not obscured

    How it is checked60 presses of Tab, then 40 of Shift+Tab, on /, /zero-door and /tr/contact: once in a desktop window 1280 × 800 and once in a narrow window 390 × 844. After each press the test waits for scrolling to stop and fails if the sticky header covers the centre and all four corners of the focused element.

  4. 2.2.2 Pause, stop, hide

    How it is checkedOn every scanned page: if a loop has started, a visible pause control must be on the page as well, or the page fails. Every loop sets the mark data-ambient when it starts. The shared motion lifecycle sets it for the loops it runs; the noise canvas, the hold motion of the two scroll scenes and the scroll cue in the home page hero set it themselves. The build of this page stops if a component loops without setting it.

  5. 2.2.2 The decision persists

    How it is checkedPausing on the home page pauses the site. On the Zero Door page the control still reads paused, and back on the home page the noise canvas reports itself paused.

  6. 2.2.2 and 2.5.8 on the Zero Door page

    How it is checkedEvery looping visual has its own control; the first is at least 24 × 24 px and labelled as a pause. One click pauses every control and the moving rows stop, and the decision survives a reload.

  7. 2.5.8 Target size (minimum)

    How it is checkedThe axe rule target-size, part of the wcag22aa tag set, runs on every scanned page.

  8. 1.4.13 Content on hover or focus

    How it is checkedOn a wide screen a rule on the home page opens when keyboard focus reaches its title. Escape closes it while focus stays, focus on its proof link opens it again and focus moving on to the next rule closes it. On a narrow screen the rules are an accordion: opening one closes the one that was open, and a closed rule keeps its link hidden.

  9. 2.1.1 Keyboard

    How it is checkedIn the evidence scene on the home page the arrow keys move between steps, take focus with them and stop at the first and the last step.

  10. 1.1.1 and 4.1.2 The label follows the step

    How it is checkedChoosing a step changes the role=img label of the scene to the sentence for that step, taken from the dictionary.

  11. 1.3.1 Info and relationships: heading order

    How it is checkedIn every built HTML file, heading levels inside <main> never skip. axe treats heading order as good practice rather than a WCAG rule, so a build gate holds it.

  12. 3.1.2 Language of parts

    How it is checkedIn the hero of the Turkish home page, the framework names in the trust line and the kicker carry lang=en. On the Turkish sector pages, a proof line quoted from the product’s English output carries lang=en, and a proof line written in Turkish carries none.

  13. Reduced motion, site-wide

    How it is checkedEvery built page except the 404 page opens with reduced motion requested. No revealed element is left with a transform, every labelled visual in the main content is drawn, not hidden or clipped away, the motion class is not set and no loop starts.

  14. Reduced motion, home page

    How it is checkedOn the home page, with reduced motion requested, every revealed element stands in its final place with no transform, fully opaque and not hidden, and the motion class is never set.

  15. Without JavaScript, site-wide

    How it is checkedEvery built page except the 404 page opens with scripts off. Every revealed element stands in its final place with no transform, and every labelled visual in the main content is drawn, not hidden or clipped away.

  16. Without JavaScript, home page

    How it is checkedWith scripts off, the evidence scene on the home page stacks its four cards, the stage stands still and the pause control stays hidden.

  17. 1.4.3 Contrast (minimum): text colour tokens

    How it is checkedink, ink-muted, ink-subtle and accent-deep are computed against paper and paper-2 and must reach 4.5:1 on both.

  18. 1.4.11 Non-text contrast: focus ring and field border

    How it is checkedFrom the colour tokens, the accent focus ring is computed against paper, paper-2, accent-tint and ink, and the ink-subtle border of form fields against paper, paper-2 and accent-tint; each must reach 3:1. The test also checks that the contact form, the call-to-action band and the glossary filter draw their fields with that border, and that the global focus rule is a 2px solid accent outline.

  19. Lighthouse accessibility

    How it is checkedDesktop Lighthouse opens 21 pages, 2 runs each, and every run on each page must score 100 for accessibility.

Focus is always visible.

#

Keyboard focus looks the same everywhere: a solid 2px outline in the accent colour. It is drawn when the browser decides focus should show, so a mouse click on a button or link leaves no ring behind. Components may change the offset. They never change the width or the colour.

Try it with the keyboard.

Press Tab to move through these controls. They use the site’s own button and link classes and a plain text field, under the one global focus rule. The buttons are samples and do nothing.

Text link
Live: .btn, .btn-ghost, .btn-ink, .link and a text field. Every ring here comes from the global rule: 2px, offset 3px.

The ring on four surfaces

The ring is not text, so it needs 3:1 against the colour behind it. The accent meets that on each of the four surfaces below: the two page surfaces, the accent tint and the ink of the code panels.

  • paper4.38:1 meets 3:1
  • paper-24.12:1 meets 3:1
  • accent-tint3.97:1 meets 3:1
  • ink3.78:1 meets 3:1
Ratios are computed from the colour tokens when this page is built and rounded down, never up.

Offsets in use

Offsets in use run from 3px to -2px. The default ring stands clear of the element, the pause control and fields sit closer, step buttons are hugged by their ring and code panels draw it inside.

  • Default3px
  • Pause control2px
  • Glossary field1px
  • Step button0px
  • Code panel-2px
Drawn with the offsets read from each component’s CSS. The default sample is the site’s own .btn.
Every focus rule that sets an outline, in the site’s components, layouts, pages and global CSS
SelectorOffset
:focus-visible3px
.fd:focus-visible2px
li:focus-within-2px
.v:focus-visiblenone, see :focus-within
.tw:focus-visible2px
pre:focus-visible-2px
.tw:focus-visible2px
.t:focus-visiblenone, see :focus-within
.row:focus-within-2px
.tw:focus-visible2px
.tw:focus-visible2px
.tw:focus-visible2px
.tw:focus-visible2px
.tw:focus-visible2px
.b:focus-visible2px
.tg:focus-visible2px
.chip:focus-visible, .play:focus-visible2px
.b:focus-visible, .card:focus-visible2px
.in:focus-visible1px
.tw:focus-visible2px
.dots button:focus-visible0
.mb:focus-visible2px
.integ summary:focus-visible3px
.errs .err:focus-visible2px
input:focus-visible, select:focus-visible, textarea:focus-visible2px
input:focus-visible1px
.card:focus-within2px
.title a:focus-visiblenone, see :focus-within
.file pre:focus-visible-2px
.dots button:focus-visible0

Sticky header and scroll margin

The header stays at the top of the window and is 67px tall. Links, buttons, form fields, summaries and anything with a tabindex carry a scroll margin of 84px at the top and 16px at the bottom, so when focus scrolls one of them into view it stops below the header with 17px to spare. Section anchors carry margins of their own.

Actual size. The header height comes from the navigation component, the margins from the global rule below.
CSSThe global focus and scroll-margin rules, as the stylesheet writes them
:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 3px; }
:where(a[href], button, input, select, textarea, summary, [tabindex]) { scroll-margin-top: 84px; scroll-margin-bottom: 16px; }
  • Focus is a solid 2px accent outline. Only the offset changes.

    WhyOne sign for focus everywhere, so nobody has to learn a second one. When this page is built it reads every focus rule in the components, layouts, pages and global CSS, and stops the build if one draws a different width or colour, or sets the ring through outline longhands or box-shadow.

    BuildEnforced by the build pipeline on every change.

  • Focus is never hidden entirely under the sticky header.

    WhyWCAG 2.4.11. Keyboard users move through the page with focus, and a header that covers the focused element hides where they are. The test walks 3 pages at desktop width, and a second test walks them again in a window 390 px wide.

    TestEnforced by a test on every change.

  • An outline is removed only where the ring moves to the container.

    WhyOn a whole-card link the ring goes to the card through :focus-within, so it still outlines the whole target. The build of this page stops if a component removes an outline in a file with no :focus-within rule.

    BuildEnforced by the build pipeline on every change.

DoMove the ring to the card when the whole card is the link.
Do notRemove the outline and leave nothing in its place.

Colour is never the only signal.

#

Text reaches 4.5:1 on both page surfaces, and meaning never rests on colour alone. Links are underlined, the pause control changes shape and the do and do not marks on these pages carry a word as well as a symbol.

The full palette and the computed text contrast of every token are on the Colour page. This section keeps what accessibility adds to it.

Contrast for what is not text

Focus rings, icons and the borders that mark out a control need 3:1 against the colour behind them (WCAG 1.4.11). The accent, ink-muted and ink-subtle tokens meet it, and form fields draw their border in ink-subtle. The two hair tokens do not: the site draws separators and frames with them, and also the borders of the pause control, the ghost button and the menu button.

Non-text colours against the two page surfaces
TokenOn paperOn paper-2
accent4.38:1 · meets 3:14.12:1 · meets 3:1
ink-muted6.85:1 · meets 3:16.44:1 · meets 3:1
ink-subtle4.89:1 · meets 3:14.60:1 · meets 3:1
hair-21.56:1 · below 3:11.47:1 · below 3:1
hair1.27:1 · below 3:11.19:1 · below 3:1

Computed from the tokens in tokens.css with the WCAG 2.x formula when this page is built, and rounded down. Whether the pause control, the ghost button or the menu button needs its border to be recognised has not been audited; it is listed under the gaps below.

Links in running text

In running text a link is marked by its underline. The colour supports the underline; it never replaces it.

Check the contrast table before you pick a colour pair.

DoUnderline links in running text.

Check the contrast table before you pick a colour pair.

Do notSet a link apart by colour alone.

Shape and words carry state.

The pause control shows two bars while things move and a triangle once they stop, and its label switches between “Pause animations” and “Play animations”. The do and do not marks on these pages pair a tick or a cross with a word.

  • Pause animations
  • Play animations
The two states of the pause control, drawn with its own shapes, beside the label a screen reader hears.
  • Small text never falls below 4.5:1.

    WhyWCAG 1.4.3. axe measures the text on every scanned page, and a unit test pins the text tokens against both surfaces.

    TestEnforced by a test on every change.

  • Plain accent is for non-text: rings, underlines, rules and dots.

    WhyOn paper it measures 4.38:1, under the 4.5:1 that small text needs. Filled buttons use accent-deep instead; paper text on it measures 6.65:1.

    ReviewKept by review, not by a test.

  • A link in running text never stands out by colour alone.

    WhyWCAG 1.4.1. axe fails a link in running text whose colour differs from the text around it by less than 3:1 and that has no other mark, such as an underline.

    TestEnforced by a test on every change.

Every loop can be stopped.

#

Motion is added on top of content that is already there. One control stops every loop, loops rest when nobody can see them and nothing moves for people who ask their system for less motion.

How motion is built, from the curve to the scroll scenes, is on the Motion page. This section keeps what accessibility asks of it.

Live state of the diagram

Lifecycle data-state
not set
Loop data-ambient
not set
Paused site-wide html.paused
no

Live: the diagram from the architecture page with its real pause control. Pausing here pauses every loop on the site and is remembered on the next page you open.

The pause control

A round 28px icon button labelled “Pause animations” or “Play animations”: one click stops every loop on the page, and the choice is stored in the browser under the key zs-motion, so the next page opens paused as well.

Loops rest when nobody is watching.

A loop pauses when its visual leaves the screen or the tab is hidden, and it obeys the site-wide pause.

Reduced motion

When the system asks for reduced motion, the block below turns off smooth scrolling, cuts transitions to almost nothing and removes CSS animations, and visuals go straight to their final state.

CSSThe reduced-motion block, as the stylesheet writes it
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { transition-duration: 0.01ms !important; animation: none !important; }
}
  • No loop runs without a visible pause control on the page.

    WhyWCAG 2.2.2. A browser cannot tell whether a page moves, so every loop sets data-ambient when it starts, and the 2.2.2 check in the axe test then looks for a visible control. The shared lifecycle sets the mark for the loops it runs; the noise canvas, the hold motion of the two scroll scenes and the hero scroll cue set it themselves. The build of this page stops if a component loops without the mark.

    TestEnforced by a test on every change.

  • One decision pauses every loop on every page.

    WhyStopping motion should not be a task to repeat on each page. The test pauses on the home page and finds the next page paused.

    TestEnforced by a test on every change.

  • A loop stops when its visual leaves the screen.

    WhyMotion that nobody sees still costs battery and processing. The test scrolls the dam illustration on the Zero Door page away and checks that its cards stand still.

    TestEnforced by a test on every change.

  • With reduced motion, visuals rest in their final state and the control is hidden.

    WhyWhat was asked for is less motion, not a button to press. The test checks the visuals of the Zero Door page.

    TestEnforced by a test on every change.

  • A one-time animation shorter than five seconds needs no control.

    WhyWCAG 2.2.2 asks for a control only when motion lasts longer than five seconds. A block that rises into place as it scrolls into view moves once, for 0.8 seconds, and stops.

    ReviewKept by review, not by a test.

  • Motion never animates opacity.

    WhyText that fades through half transparency fails contrast on the way, and the automated contrast checks once failed for that reason. Elements enter by transform, clip-path or stroke drawing instead.

    ReviewKept by review, not by a test.

Content arrives before scripts.

#

The server sends every page in its final, readable state. Scripts add motion on top; only the second block of the home hero waits for a script, and a CSS rescue opens it if the script is late.

Each page starts with the class no-js on its root element. A script removes it and, unless reduced motion is requested, adds the class motion. Every state that hides something before it animates is written under that motion class, except the second block of the home hero, which a CSS rescue opens if the hero script is late; without the script no content is hidden.

If the script runs but the observer never sees an element, a safety net reveals every reveal element after 3 seconds.

Without JavaScript the scroll scenes stack their cards, the pause controls stay hidden, the glossary shows its full list and the contact form posts as a plain HTML form.

DoDraw the final state first and animate from it.
Do notStart content invisible and wait for a script to show it.
  • Content is complete without JavaScript.

    WhyA script can fail to load, be blocked or break. What a page says must not depend on it. A browser test opens every built page except the 404 page with scripts off: every revealed element must stand in its final place, and every labelled visual in the main content must be drawn, not hidden or clipped away. A second test checks the evidence scene on the home page in detail.

    TestEnforced by a test on every change.

  • The contact form works without JavaScript.

    WhyIt is a real HTML form with native validation, and it posts to the same address with or without a script.

    TestEnforced by a test on every change.

  • Reduced motion never leaves an element half revealed.

    WhySomeone who asks for less motion still sees all of the content, whatever the scripts do. A browser test opens every built page except the 404 page with reduced motion requested: no revealed element is left out of place, every labelled visual in the main content is drawn, the motion class is not set and no loop starts. A second test checks on the home page that every revealed element is also fully opaque and not hidden.

    TestEnforced by a test on every change.

A visual that makes a point has a sentence.

#

A visual that makes a point is an image with a sentence: role=img and a label from the dictionary, written in both languages. A visual that only decorates is hidden from assistive technology.

What a screen reader reads for the architecture diagram in the Motion section

A host runs the agent; the agent opens the connection outwards to the platform, which holds the stores. Nothing dials in to your hosts.

AstroThe opening tags of that diagram, as the component writes them. {d.label} is the sentence above, read from the dictionary.
<figure class="fd" data-flow role="img" aria-label={d.label} tabindex="0">
  <svg viewBox="0 0 760 260" preserveAspectRatio="xMidYMid meet">
AstroThe tick of a do mark, as the component writes it. It only decorates, so it is aria-hidden.
<span class="lbl"><svg viewBox="0 0 16 16" aria-hidden="true"><path d="M3.5 8.5 6.5 11.5 12.5 4.5"></path></svg>{c.do}</span>

The label follows the scene.

The scroll scenes on the home page and the Zero Door page are one image whose meaning changes step by step, and the label changes with it. These are the four sentences of the home page scene in this language.

  1. Scene 1: two curves cross. Thousands of raw changes on one server narrow to a single alert.
  2. Scene 2: a calendar grid. An illustrative fourteen days of evidence hunting, with a two day target scenario over the first two.
  3. Scene 3: signal pills merging into one verdict pill.
  4. Scene 4: a row of memory regions with one gap, the region with no file behind it.

How labels are written

Many labels in use begin with “Illustration:” or “Scene N:” and then say what is drawn and what it shows. Icons, glyphs, canvases, separators and arrows that only decorate carry aria-hidden=true. Numbers that count up on screen do so inside such an image, so a screen reader hears its sentence and not the count.

  • A role=img visual never ships without a label.

    WhyWCAG 1.1.1. axe fails an image role that has no name. The labels come from the dictionary, so the English and Turkish sentences sit side by side.

    TestEnforced by a test on every change.

  • When a scene changes step, its label changes with it.

    WhyA screen reader user hears what a sighted reader sees at that step.

    TestEnforced by a test on every change.

  • Counting numbers are not read out on their way up.

    WhyReading every value is noise. The counters in the Zero Door illustrations climb inside an image with a sentence, so a screen reader hears that sentence instead. The commitment figures in the Trust centre do not count at all: on its way up a counter showed values that were never promised.

    ReviewKept by review, not by a test.

  • Decoration is aria-hidden.

    WhyA shape that carries no meaning only takes up time in a screen reader.

    ReviewKept by review, not by a test.

Wide content scrolls in its own box.

#

The reflow test opens every built page, the 404 page included, at 320 CSS px, and none scrolls sideways. Tables, code and diagrams that cannot shrink scroll inside their own box, and the box takes keyboard focus so it can be scrolled without a mouse.

Pages in the desktop Lighthouse run
PageRunsAccessibility score required
/solutions/banking-and-finance2100
/research/inside-symbiote-malware-deep-dive2100
/legal/terms-of-use2100
/tr/legal/terms-of-use2100
/design/motion2100

16 more pages in the run

A 320px frame. The table scrolls inside its own box while the page around it stays still. Its rows are the 5 longest of the 21 page paths in the desktop Lighthouse run, read from its configuration.

Boxes that scroll on their own

  • Markdown tables, wrapped in a focusable box when the site is built
  • Markdown code blocks, made focusable when the site is built
  • The tables and code panels on these pages
  • The architecture diagram below 760px wide, which keeps its drawing 620px wide and scrolls instead of shrinking
  • Nothing scrolls the page sideways at 320 CSS px.

    WhyWCAG 1.4.10. On a narrow screen or at high zoom, nobody should have to scroll in two directions to read a line.

    TestEnforced by a test on every change.

  • A box that scrolls can take keyboard focus.

    WhyWCAG 2.1.1. A keyboard user can only scroll a box that takes focus, and axe fails one that cannot.

    TestEnforced by a test on every change.

Targets are large enough to hit.

#

WCAG 2.2 asks for targets of at least 24 by 24 CSS px, or enough space around a smaller one. The custom controls on the site meet that size or go beyond it.

  • 24 × 24Step buttons, home page scene
  • 24 × 24Step buttons, Zero Door scene
  • 28 × 28Pause control
  • 28 × 28Icon link in the footer
  • 40 × 40Menu button on narrow screens
  • 24 × 24The # link beside each section heading on these pages
Actual size. Each size is read from the component’s own CSS; the dashed square is the 24 × 24 px minimum, read from the axe rule target-size.

Smaller targets that rely on an exception

Links in running text fall under the inline exception: the line of text sets their size. axe target-size does not measure them.

  • Custom controls meet the target size of WCAG 2.5.8.

    WhyWCAG 2.5.8. axe runs its target-size rule on every scanned page, and the Zero Door test measures the first pause control as well.

    TestEnforced by a test on every change.

What is not tested yet.

#

Automated checks do not cover everything. These are the gaps we know of, listed so that this page is never read as a larger claim than the tests behind it.

Not tested

  • Non-text contrast of icons and controls (1.4.11)axe does not measure it. A unit test computes, from the tokens, the focus ring against the four surfaces it lands on and the form-field border against the surfaces it sits on, and checks that the site’s three forms draw that border; no test checks icons or rendered controls. hair-2, which draws the borders of the pause control, the ghost button and the menu button, measures 1.56:1 against paper; whether those controls need the border to be recognised has not been audited. Form fields draw theirs in ink-subtle, at 4.89:1.
  • A second cue beside colourIn diagrams, accent and raw differ by 1.30:1 in luminance and read as different mainly by hue. The rule that a direction, a mark shape or a word says the same thing is a convention held by review; no test checks that every scene keeps that second cue.
  • Visible focus (2.4.7)The ring is defined in one global rule that components restate with an offset of their own. Only the live controls on this page are checked for a drawn ring; no test checks it across the site. The header test for 2.4.11 runs on 3 pages, not on all of them.
  • Text spacing, resize and orientationaxe checks only that zoom is not disabled (1.4.4) and that inline styles do not lock text spacing (1.4.12). No test renders a page at 200 percent or with wider spacing, and orientation (1.3.4) is not checked: the axe rule for it is experimental and does not run.
  • Forced coloursThe site has no styles for forced colours or high contrast modes, and none are tested.
  • Skip linkIt is the first element on every page, and no test uses it.
  • Assistive technologyNobody has recorded a test with a screen reader or other assistive technology. Of the criteria a scanner cannot judge, three have scripted browser tests that walk many pages: reflow (1.4.10) on every built page, focus under the sticky header (2.4.11) on 3 pages and the pause control (2.2.2) on every scanned page. Others, such as keyboard use (2.1.1), are tested on a single component or not at all, and no person checks them.
  • PhonesOn the phone profile, axe skips every page under /legal/ and /research/ but still scans the index page of each, and the mobile Lighthouse run is advisory. The reflow test runs in a desktop browser narrowed to 320 px, and the header test for 2.4.11 in a desktop browser at 1280 × 800 and narrowed to 390 × 844; neither runs in the phone profile.
  • Where the pause control sitsThe 2.2.2 check looks for a visible control on the page while a loop runs, not for one beside each loop.
  • Text inside illustrationsThe smallest size set in the site’s components is 5.4px, in Plate. SVG text also shrinks with its drawing on narrow screens. No rule sets a minimum and no test measures it.
  • Changing the motion setting mid-visitScripts read the setting when a page loads, so loops and reveals follow a change on the next page; the CSS rules follow it at once.
  • Lighthouse coverageLighthouse runs on a fixed list of 21 pages.

Not defined yet

  • Allowed colour pairsNo rule forbids ink-subtle text on accent-tint, which measures 4.44:1, under 4.5:1. axe would flag it on any page that used it.
  • A conformance reportNo accessibility conformance report for the site has been published.
  • A contrast preferenceThe site does not respond to a request for more contrast (prefers-contrast).

Statement and reports

#

The short public statement is in the Trust centre, and this page is the working detail behind it: it lists the tests in full.

If something on the site does not work with your keyboard, your browser settings or your assistive technology, tell us through the contact form. Name the page and what you were trying to do, and we will reply.

Report a problemAccessibility statement in the Trust centre