The 390 that was 1440
Eighty accessibility checks reported clean at 390 pixels. They had run at 1440: the resize did nothing to a tab in the background, and nothing said so.
Date: 2026-11-10. Context: DS-6, overlays and disclosure (feat/ds-overlays, journal ch. 46).
What happened
Each new story was checked with axe in both themes, at 1280 and at 390 pixels, through the
browser tool: open a tab, resize it, load the story, run axe. Eighty checks, no problems. Then the
same loop went to the app, to open the new mobile menu at 390 pixels, and could not find its
button. The header still showed the desktop links. window.innerWidth said 1440.
The tab had been opened in the background. Resizing a background tab does nothing, and returns no
error. Every "390" check had run at the desktop width. Rerun with the viewport emulated
(390x844x2,mobile), and with the width read back inside the check: 46 checks, at 390 for real,
still clean.
The next block did it again, another way. The axe loop for DS-7 built story ids from the file
names (date-picker--default); Storybook names them from the title (datepicker--default). Four
of the six components were never drawn: axe checked Storybook's "Couldn't find story" page and
found it fine. The loop now reads the ids from Storybook's index.json and checks that the story
rendered before it trusts axe.
What we learned
- A check must assert its own precondition. "At 390 pixels" was a label on the loop, not a
fact the check verified. One line reading
innerWidthwould have caught it at the first story. - A clean result is the one to doubt. A wrong width cannot make axe fail more; it can only hide what a narrow screen breaks. Silence looked like success.
- A check of nothing passes. A missing story, like a wrong width, cannot fail axe.
- The tool's success message is not the effect. "Resized" described the call, not the page.
What it means for Vektos
The benchmark asks the same of the agents it measures: a run that says "done" is checked by rendering the page, not believed. Its own browser check sets the viewport on the Playwright context, which does apply, and screenshots it. The checks an agent runs by hand while building need the same discipline.
Follow-ups
- Every hand-run axe loop returns
innerWidthwith its results. - APP-5 puts the app's pages, at both widths, into
check:page, so this stops being by hand.
The view written as a string
Asked for a view as a tool argument, the model wrote it as JSON inside a string, a third of the time, and sometimes with a brace missing. The shape of the schema decided it.
Zero rules, no error
The benchmark asked axe for the tag "best-practices". axe has "best-practice". It ran no rule for that tag, for weeks, and said nothing.