The audit room
A page broken on purpose. Below sits the release page for a band's debut EP — and hidden in it are twelve accessibility barriers, planted deliberately. Your job is the hunt: the heading list, the tab key, the accessibility pane, the emulations — everything the proof chapter and the reference sheets taught. A scanner finds two of the twelve — this site's own suite measured it. The other ten need you.
The contract: every barrier lives inside the framed page below, nothing outside the frame is broken, none of its links or buttons do anything real, and the answers wait at the end. The broken page is a page of its own — deliberately outside this site's styles and safety nets, so what you catch behaves the way it would in the wild. What sits below is only a half-scale preview; the hunt happens at full scale in its own tab. One warning: a barrier in there is a small badge that bounces and ignores your reduced-motion preference. If that's harmful for you, skip past the broken page, straight to the answers.
Broken on purpose · barriers 1–12 · preview at 1:2
Full-page DevTools, your own Lighthouse run — the hunt happens at full scale.
End of the broken page. Everything from here on is compliant again.
Answers
Each barrier below opens to a hint first; the answer hides one level deeper. Honest scoring is your own business — that's why there is no counter.
Barrier 1: try to press the most important thing on the page
Reveal the answer
"Listen now" is a styled div. It looks like the primary button, but it is not focusable, not pressable by keyboard, and announces as nothing — the tree shows role generic, no name that matters.
A native button element brings focus, keyboard behaviour, role, and name for free — the agent skill’s first swap.
Barrier 2: one image says nothing at all
Reveal the answer
The EP cover has no alt attribute. A screen reader announces the filename or skips it; either way the most important image on the page is silence.
alt="Cover of Alles auf Anfang: the band walks through darkness in a long-exposure blur" — describe what it shows, not that it is an image.
Barrier 3: one of the photos is lying
Reveal the answer
The band photo has alt="IMG_2047.jpg". An alt exists, so scanners pass it — but hearing a camera filename is as useless as hearing nothing.
Useful alt text, or alt="" if the image is decoration. The judgment is exactly what automation cannot make.
Barrier 4: pull the heading list — where did the page go?
Reveal the answer
Tracklist, Tour, Listen, Mailing list all look like headings and are all styled paragraphs. The rotor’s heading list is empty; a screen reader user has no outline to jump by.
Real h2 elements. Style is free; structure is what the shortcuts land on — the fifteen-minute plan, step two.
Barrier 5: read the band’s self-description in bad light
Reveal the answer
The tagline is #a7a7a7 on white — roughly 2.4:1, far under the 4.5:1 minimum for body text.
Pick a passing gray in DevTools — the picker draws the AA line for you — sheet A·04 shows where.
Barrier 6: what is the email field actually called?
Reveal the answer
The signup field’s only label is its placeholder. The name vanishes the moment you type, low-contrast by design, and never a real label — the tree shows the field named by a hint that is about to disappear.
A visible label element, wired with for — and an autocomplete token while you are there (1.3.5).
Barrier 7: which shows can you still get into?
Reveal the answer
Sold-out dates differ from open ones by red text alone. With deuteranopia — or a monochrome display, or forced colors — the distinction evaporates.
Say it in text — the word "ausverkauft" is actually already doing the work here; the barrier is that only its color distinguishes it from the ticket link next to it. Add an explicit "Tickets" link text and the color becomes reinforcement, not the message.
Barrier 8: Tab into the signup form and watch your position vanish
Reveal the answer
The form controls set outline: none, and inside its own little page there is no preferences layer to overrule it. Tab into the form and your position simply vanishes — exactly where the page asks you to type.
Never remove an outline without replacing it. :focus-visible styling costs one declaration.
Barrier 9: pull the links list and try to tell them apart
Reveal the answer
Three links in a row read "click here". In the rotor’s links list — which strips their surroundings — they are indistinguishable.
Name the destination: "Listen on Spotify". The sentence around the link is not what a links list reads.
Barrier 10: ask the tracklist which column is which
Reveal the answer
The tracklist is a table of td cells only — no th, no headers. The tree shows a grid of anonymous cells; a screen reader can’t answer "which column am I in?"
th elements with scope="col" — number, title, length — and the table starts answering questions.
Barrier 11: something on this page never stops moving
Reveal the answer
The "OUT NOW" badge bounces forever, and its CSS never asks permission — no reduced-motion guard anywhere. Because the broken page is a document of its own, no site-wide kill rescues it either: set your OS preference or flip the Rendering-panel emulation and it keeps bouncing. That indifference is the barrier.
Wrap it in @media (prefers-reduced-motion: no-preference) — motion is the enhancement, stillness the default.
Barrier 12: ask the mailing-list button its name, then read its label
Reveal the answer
The button shows "Join the mailing list" but carries aria-label="subscribe". Voice-control users say what they see — "click join the mailing list" — and nothing happens, because the visible words are not in the accessible name.
Let the content name it — or if ARIA must add context, start with the visible words, as the tree section showed.
About this page
The band is real; this page is not its website. Fitis exists, the EP exists, and the actual site — which is not broken on purpose — lives at fitis-band.de. Everything else here is fiction in service of the exercise.
Found barriers like these on a page you work on? The proof chapter ends with how to file what you find — impact first, one barrier per ticket, and the fix is usually a swap.