27 checks

How scoring works

Every score comes from these rules, not from a language model. The same page always produces the same number.

The formula

Each rule declares a maximum penalty and whether it applies to the page being audited. A category’s score is:

100 × (1 − penalties incurred / penalties possible on this page)

Normalising over applicable rules is what stops a nearly empty page scoring well for the checks it never triggered — a page with no images gets no credit for “all images have alt text”. The overall score is the mean of the active category scores.

5 of the 27 rules need the page to be rendered in a real browser. Where no browser is available they are skipped entirely — they neither pass nor fail, and the report says so.

15Accessibility

Whether the page can be used by someone relying on a screen reader, a keyboard, or zoom.

critical−14 maxlow effortWCAG 3.1.1

The <html> element carries a lang attribute.

a11y-html-lang
Applies
Every page.
Does not detect
Does not verify the declared language matches the content.
critical−12 maxlow effortWCAG 2.4.2

A non-empty <title> exists.

a11y-page-title
Applies
Every page.
Does not detect
Quality of the title is scored separately by clarity-title-quality.
critical−12 maxlow effortWCAG 1.4.4

A responsive viewport is declared and does not block zoom.

a11y-viewport
Applies
Every page.
Does not detect
Cannot detect zoom blocked by CSS or JavaScript.
high−14 maxmedium effortWCAG 1.1.1

Every image has an alt attribute; alt="" counts as correct for decorative images.

a11y-image-alt
Applies
Only when the page has at least one image not hidden from assistive tech.
Does not detect
Cannot judge whether the alt text is actually descriptive.
high−10 maxlow effortWCAG 1.3.1

A <main> or role="main" region exists.

a11y-main-landmark
Applies
Every page.
Does not detect
Does not verify the main region wraps the right content.
high−10 maxlow effortWCAG 1.3.1

Exactly one visible H1, ignoring aria-hidden duplicates.

a11y-h1
Applies
Every page.
Does not detect
Does not judge whether the H1 describes the page well.
high−14 maxmedium effortWCAG 3.3.2

Every form field has a label, aria-label or aria-labelledby.

a11y-form-labels
Applies
Only when the page has form fields that are not hidden or control types.
Does not detect
A placeholder is deliberately not accepted as a label.
high−10 maxlow effortWCAG 4.1.2

Every button has an accessible name, including via SVG aria-label.

a11y-button-name
Applies
Only when the page has visible buttons.
Does not detect
Does not resolve aria-labelledby references to their target text.
medium−8 maxmedium effortWCAG 2.4.4

Links do not rely on generic text like "click here" or "read more".

a11y-link-text
Applies
Only when the page has keyboard-reachable links.
Does not detect
The generic-phrase list is finite and English/Spanish only.
medium−6 maxlow effortWCAG 2.4.1

A skip-to-content link exists as an in-page anchor.

a11y-skip-link
Applies
Only on pages with repeated navigation: 3+ nav links or 15+ links total.
Does not detect
Does not verify the link becomes visible on focus.
medium−6 maxmedium effortWCAG 2.4.3

No element uses a tabindex greater than zero.

a11y-positive-tabindex
Applies
Every page.
Does not detect
Does not evaluate the overall focus order.
medium−5 maxlow effortWCAG 4.1.2

Every iframe has a title describing the embedded content.

a11y-iframe-title
Applies
Only when the page has iframes.
Does not detect
Does not judge whether the title is meaningful.
critical−18 maxlow effortWCAG 1.4.3needs rendering

Text meets WCAG contrast — 4.5:1, or 3:1 for large text — measured against the composited background.

visual-contrast
Applies
Only when the page is rendered and at least one background is determinable.
Does not detect
Text over gradients or images is reported as indeterminate rather than guessed.
medium−10 maxlow effortneeds rendering

Running text is at least 12px as rendered.

visual-font-size
Applies
Only for text blocks longer than 40 characters, so captions are exempt.
Does not detect
Measured at a 1280px desktop viewport only.
high−12 maxmedium effortWCAG 2.5.8needs rendering

Interactive controls are at least 24x24 CSS pixels (WCAG 2.5.8).

visual-touch-targets
Applies
Measured in a 390px mobile viewport; visually hidden and in-text links are excluded.
Does not detect
Does not measure spacing between adjacent targets.
5Visual hierarchy

Whether the page's structure lets someone scan it and find what they came for.

medium−12 maxmedium effortWCAG 1.3.1

Heading levels do not skip, e.g. H2 straight to H4.

hier-heading-order
Applies
Only when the page has two or more headings.
Does not detect
Uses document order, which can differ from visual order.
medium−12 maxhigh effort

Long content is broken up by headings — under 300 words per heading.

hier-heading-density
Applies
Only when the page has 250+ words of visible text.
Does not detect
Word count is a proxy; some content is legitimately dense.
medium−12 maxlow effortWCAG 1.3.1

The page uses <header>, <nav> and <footer> rather than generic divs.

hier-landmarks
Applies
Skipped on very short pages missing only one or two regions.
Does not detect
A single-purpose page may legitimately have no nav.
low−8 maxhigh effort

Spacing and type come from a system rather than per-element inline styles.

hier-inline-styles
Applies
Only when 25+ elements carry inline styles and they exceed 15% of all elements.
Does not detect
Some frameworks emit inline styles legitimately; this is a smell, not a defect.
high−12 maxmedium effortWCAG 1.4.10needs rendering

Page content is not wider than a phone screen.

visual-horizontal-scroll
Applies
Only when the page is rendered; a 4px tolerance absorbs browser rounding.
Does not detect
Does not identify which element overflows.
7UX clarity

Whether the page says what it is, and whether a visitor can tell what to do next.

medium−12 maxlow effort

A meta description exists and is 70-165 characters.

clarity-meta-description
Applies
Every page.
Does not detect
Does not judge whether the description is compelling.
medium−10 maxlow effort

The title is 15-60 characters, so it is informative and not truncated.

clarity-title-quality
Applies
Only when a title exists; absence is covered by a11y-page-title.
Does not detect
Character limits are search-engine conventions, not hard rules.
medium−12 maxhigh effort

The page offers at least one button, form or submit control.

clarity-call-to-action
Applies
Only when the page has 80+ words of content.
Does not detect
A link can be a valid call to action and is not counted here.
low−8 maxlow effort

og:title, og:description and og:image are present for link previews.

clarity-social-preview
Applies
Every page.
Does not detect
Does not fetch the image to verify it exists or its dimensions.
low−10 maxhigh effort

The served HTML contains at least 60 words of visible copy.

clarity-content-depth
Applies
Every page.
Does not detect
Flags client-rendered pages; rendering the page resolves the ambiguity.
low−5 maxlow effort

A favicon is declared via a link[rel~=icon].

clarity-favicon
Applies
Every page.
Does not detect
Does not check the icon file actually loads.
medium−12 maxhigh effortneeds rendering

The first screen contains enough copy to orient the visitor and a visible action.

visual-above-fold
Applies
Only when the page is rendered; measured at 1280x800.
Does not detect
One viewport size cannot represent every device.
What the AI layer does — and does not

A separate, optional layer sends the rendered screenshot and the page copy to Claude. It writes the summary and adds observations a rule engine cannot make — whether a headline says anything, whether the primary action looks primary. Every AI observation must quote the page or it is discarded before reaching the report.

It never touches the score. The number is produced by the rules above before the model is called, and an audit run with the AI layer disabled returns exactly the same score.

← Run an audit