On any mistyped URL under a theme route — /heirloom/anything, /warm-print/anything — the not-found page renders two main landmarks: the theme shell always draws one around its content, and the root not-found view inside draws its own. Screen-reader users navigating by landmark get two competing "main content" targets on every broken link. The accessibility gate cannot see it because the suite only visits the listed routes. Whichever theme wins the design pick carries its shell — and this defect — into the real design system, so it should be fixed in the winner right after the pick.
Where it lives
The theme shells (apps/web/src/features/design-comparison/ui/heirloom/shell.tsx, .../warm-print/shell.tsx) wrap their children in main unconditionally. When the router matches no child route, the fallback not-found view renders inside that wrapper and brings its own main. Fix in the winning theme only: let exactly one layer own the landmark, and add one unmatched-URL scan per surviving theme route to the accessibility suite so the case stays covered.
Two smaller residuals in the same tree, also winner-only
- Heirloom's binding strip decides color inside the component (
dark:bg-primary/70 on the stitch dots and hairline in ui/heirloom/binding-strip.tsx). The painted result is 4.54:1 (dots) and 2.02:1 (hairline) in dark mode while the token audit, which only sees full-strength tokens, believes 7.57:1. The strip is decorative, so nothing is illegible today — but it is the one place a component's opacity modifier makes the audited numbers untrue, and the pattern would spread.
- The heatmap legend places the "no entry" swatch inside the Less-to-More ramp, which misstates the encoding: an empty day is absence drawn as an outline, not "less than the lightest band".
On any mistyped URL under a theme route —
/heirloom/anything,/warm-print/anything— the not-found page renders twomainlandmarks: the theme shell always draws one around its content, and the root not-found view inside draws its own. Screen-reader users navigating by landmark get two competing "main content" targets on every broken link. The accessibility gate cannot see it because the suite only visits the listed routes. Whichever theme wins the design pick carries its shell — and this defect — into the real design system, so it should be fixed in the winner right after the pick.Where it lives
The theme shells (
apps/web/src/features/design-comparison/ui/heirloom/shell.tsx,.../warm-print/shell.tsx) wrap their children inmainunconditionally. When the router matches no child route, the fallback not-found view renders inside that wrapper and brings its ownmain. Fix in the winning theme only: let exactly one layer own the landmark, and add one unmatched-URL scan per surviving theme route to the accessibility suite so the case stays covered.Two smaller residuals in the same tree, also winner-only
dark:bg-primary/70on the stitch dots and hairline inui/heirloom/binding-strip.tsx). The painted result is 4.54:1 (dots) and 2.02:1 (hairline) in dark mode while the token audit, which only sees full-strength tokens, believes 7.57:1. The strip is decorative, so nothing is illegible today — but it is the one place a component's opacity modifier makes the audited numbers untrue, and the pattern would spread.