Split from #2915 (checks 1-4, the head/headers/well-known/error-page gate, landed in src/release/webspec.ts, test/webspec.test.ts and bun scripts/smoke.ts <url> --standards). Extend that module and its test; every finding cites its specification.website section.
Done: webspec.ts checks each look's body: headings never skip a level and there is one h1, every img has alt, every input/select/textarea has a label (for=, wrapping label, or aria-label), no link or button without an accessible name, a skip link is the first focusable element, exactly one <main>, no inline on* handlers, every external <script> is defer/async/module, no http:// subresource on an https page. Fix what it finds on the forge's pages; a test proves each check goes red on a fixture.
Split from #2915 (checks 1-4, the head/headers/well-known/error-page gate, landed in src/release/webspec.ts, test/webspec.test.ts and
bun scripts/smoke.ts <url> --standards). Extend that module and its test; every finding cites its specification.website section.Done: webspec.ts checks each look's body: headings never skip a level and there is one h1, every img has alt, every input/select/textarea has a label (for=, wrapping label, or aria-label), no link or button without an accessible name, a skip link is the first focusable element, exactly one <main>, no inline on* handlers, every external <script> is defer/async/module, no http:// subresource on an https page. Fix what it finds on the forge's pages; a test proves each check goes red on a fixture.