Our published checklist
Every check we run, what it costs you when it fails, and exactly how the score is calculated. Nothing here is proprietary.
Version ssc-1.0 · 34 checks · effective August 2026
We publish this for a simple reason: a score we could quietly adjust would not be worth selling. If you disagree with a finding, you can check our arithmetic against the rules below and tell us we got it wrong. Some clients have.
How the score is calculated
Each category starts at 100 and loses points for every check that fails:
penalty = base × (1 + log₁₀(occurrences)) capped per severity
| Severity | Base penalty | Maximum |
|---|---|---|
| critical | 12 | 26 |
| serious | 7 | 16 |
| moderate | 3 | 8 |
| minor | 1 | 3 |
The overall score is the weighted average of the four categories:
| Category | Weight | Why |
|---|---|---|
| Accessibility | 70% | It is what we are primarily assessing. |
| Security | 12% | Cheap to get right, expensive to get wrong. |
| Site health | 10% | Broken links and missing policies cost enquiries. |
| Performance | 8% | Real, but the most visible and most often already known. |
What this version can actually test
10 of the 34 checks below are published and carry weight, but are not yet automated — 24 are in use today. We would rather say so here than let you assume otherwise. Where a check is marked not yet tested, no site loses points for it — including yours, and including your competitors’.
| Category | Tested today | Not yet tested | Weight |
|---|---|---|---|
| Accessibility | 14 of 20 | 6 | 70% |
| Security | 6 of 6 | — | 12% |
| Site health | 4 of 5 | 1 | 10% |
| Performance | 0 of 3 | 3 | 8% |
The consequence worth stating plainly: no site is currently assessed on performance, so every site scores 8 out of 8 there. Every composite score we publish is that much higher than it would be if we tested it. That is the same for everyone, and it is in your favour rather than ours — but you should know it before you read your number. When those checks are automated we will publish a new version rather than quietly changing what your score means.
Two things this score is not
It is not a certification. It is an assessment against this checklist, observed on one date. It says nothing about whether your site complies with the Americans with Disabilities Act or any other law, and we are not qualified to say.
It is not complete. Automated testing catches roughly a third of possible accessibility problems. The checks marked Human review below are the ones a machine cannot settle — which is why a person reads every paid audit before it goes out.
Accessibility 20 checks · 70% of the score
| Reference | Check | Severity | How tested |
|---|---|---|---|
| A-1.1.1 WCAG 1.1.1 | Images have meaningful alternative text Every image that carries information needs a text description. Someone using a screen reader hears "image" instead of what you are showing them. Search engines are equally blind to it. How we test this
Fails when: Any node failing any listed rule. Evidence we record: the exact element, a screenshot of it on your page Where this check can be wrong:
| serious | Automated |
| A-1.1.1-M WCAG 1.1.1 | Alternative text is actually useful The description says what the image shows, not "DSC_0421.jpg". Alt text that exists but says nothing passes every automated tool and helps nobody. A machine cannot tell the difference; a person can. How we test this
The question our reviewer answers: “For each image with alt text: does the text tell someone who cannot see it what the image is doing here — or is it a filename, a keyword list, or a repeat of the words next to it?” Evidence we record: the exact element, a screenshot of it on your page, the reviewer's own note, signed Where this check can be wrong:
| serious | Human review |
| A-1.3.1 WCAG 1.3.1 | Page structure is marked up correctly Headings, lists and tables are built as headings, lists and tables — not text styled to look like them. Screen reader users navigate by structure. Without it they read the whole page top to bottom or leave. How we test this
Fails when: Any node failing any listed rule. Evidence we record: the exact element, a screenshot of it on your page Where this check can be wrong:
| serious | Automated |
| A-1.3.1-H WCAG 1.3.1 | Heading levels are in order Headings go h1, h2, h3 without skipping levels. Skipped levels break the outline people use to jump around your page. How we test this
Fails when: A skipped level, a missing h1, or a heading with no text. Evidence we record: the exact element, a screenshot of it on your page Where this check can be wrong:
| moderate | Automated |
| A-1.4.3 WCAG 1.4.3 | Text has enough contrast against its background Normal text needs a 4.5:1 contrast ratio; large text needs 3:1. Low contrast is the single most common failure on the web. It affects anyone with reduced vision, and everyone on a phone in sunlight. How we test this
Fails when: 4.5:1 for normal text; 3:1 for text at 18pt, or 14pt bold, and larger. Evidence we record: the exact element, the number we measured, a screenshot of it on your page Where this check can be wrong:
| critical | Automated |
| A-1.4.1 WCAG 1.4.1 | Colour is not the only way information is conveyed Errors, required fields and status are marked with more than just red or green. Roughly one in twelve men has some colour vision deficiency. If red is your only signal, they miss it. How we test this
The question our reviewer answers: “If this page were printed in greyscale, which pieces of information would disappear entirely?” Evidence we record: the exact element, a screenshot of it on your page, the reviewer's own note, signed Where this check can be wrong:
| moderate | Human review |
| A-1.4.4 WCAG 1.4.4 | Text survives being zoomed to 200% Zooming to twice the size does not cut off or overlap content. Many people browse zoomed in permanently. If your layout breaks, your site is unusable for them. How we test this
Fails when: Any content lost, clipped or overlapping at 200%. Evidence we record: the exact element, a screenshot of it on your page Where this check can be wrong:
| moderate | not yet tested |
| A-1.4.10 WCAG 1.4.10 | No horizontal scrolling at phone width At 320 pixels wide the page reflows instead of forcing sideways scrolling. Most of your visitors are on a phone. Sideways scrolling reads as broken and they leave. How we test this
Fails when: scrollWidth > innerWidth + 2px at a 320px viewport. Evidence we record: the exact element, the number we measured, a screenshot of it on your page Where this check can be wrong:
| serious | Automated (keyboard) |
| A-2.1.1 WCAG 2.1.1 | Everything works with a keyboard alone Every button, link, menu and gallery can be reached and operated without a mouse. People with motor impairments, and anyone using assistive tech, navigate by keyboard. A lightbox that only closes on click traps them on the page. How we test this
Fails when: Any interactive element unreachable or inoperable by keyboard alone. Evidence we record: the exact element, a screenshot while it has keyboard focus Where this check can be wrong:
| critical | not yet tested |
| A-2.1.2 WCAG 2.1.2 | No keyboard traps Focus can always move forward and back out of any component. A trap means the only way out is closing the tab. It is the most hostile failure on this list. How we test this
Fails when: Any component keyboard focus cannot exit by Tab, Shift+Tab or Escape. Evidence we record: the exact element, a screenshot while it has keyboard focus Where this check can be wrong:
| critical | not yet tested |
| A-2.4.1 WCAG 2.4.1 | A skip link lets people jump past the navigation Keyboard users can skip repeated menus and get to the content. Without it, every page starts with twenty tab presses through the same menu. How we test this
Fails when: No skip link, no landmark structure, and no heading structure to navigate by. Evidence we record: the exact element, a screenshot while it has keyboard focus Where this check can be wrong:
| moderate | Automated |
| A-2.4.3 WCAG 2.4.3 | Focus order follows the visual order Tabbing moves through the page in the order things appear, and focus moves into and out of menus and dialogs correctly. When an open menu leaves focus behind it, keyboard users are typing into a page they cannot see. How we test this
Fails when: Focus order that does not preserve meaning and operability. Evidence we record: the exact element, a screenshot while it has keyboard focus, the number we measured Where this check can be wrong:
| serious | not yet tested |
| A-2.4.4 WCAG 2.4.4 | Link text says where the link goes No bare "click here" or "read more" without context. Screen reader users often pull up a list of links alone. Twelve identical "read more" entries are useless. How we test this
Fails when: A link with no accessible name, or a generic name reused for different destinations. Evidence we record: the exact element, a screenshot of it on your page Where this check can be wrong:
| moderate | Automated |
| A-2.4.7 WCAG 2.4.7 | The focused element is visibly marked Whatever the keyboard is on has a clear outline. Nobody has removed it in the stylesheet. Removing the focus ring for looks makes keyboard navigation impossible — you cannot see where you are. How we test this
Fails when: No visible change on focus; or an indicator below 3:1 against adjacent colour. Evidence we record: the exact element, a screenshot while it has keyboard focus, the number we measured Where this check can be wrong:
| critical | not yet tested |
| A-2.5.8 WCAG 2.5.8 | Tap targets are large enough Buttons and links are at least 24 by 24 pixels. Small targets are missed by anyone with a tremor, and by everyone on a bumpy bus. How we test this
Fails when: 24x24 CSS pixels, or a 24px spacing offset. WCAG 2.2 SC 2.5.8 Level AA. Evidence we record: the exact element, the number we measured, a screenshot of it on your page Where this check can be wrong:
| moderate | not yet tested |
| A-3.1.1 WCAG 3.1.1 | The page declares its language A lang attribute tells assistive tech which language to pronounce. Without it, a screen reader may read English with the wrong accent and rules — sometimes unintelligibly. How we test this
Fails when: Missing lang, or a value that is not a valid BCP 47 tag. Evidence we record: the number we measured | minor | Automated |
| A-3.3.2 WCAG 3.3.2 | Every form field has a label Each input has a real label element, not just placeholder text. This is the one that costs you money directly. An unlabelled quote form cannot be completed by a screen reader user — they wanted to hire you and could not. How we test this
Fails when: Any input, select or textarea with no programmatically associated label. Evidence we record: the exact element, a screenshot of it on your page Where this check can be wrong:
| critical | Automated |
| A-3.3.1 WCAG 3.3.1 | Errors are identified in text and explain the fix A rejected form says what was wrong and how to correct it. A red border with no message leaves people guessing. Most of them just give up on the form. How we test this
The question our reviewer answers: “When this form rejects something, does it say in words which field was wrong and what would be accepted instead?” Evidence we record: the exact element, a screenshot of it on your page, the reviewer's own note, signed Where this check can be wrong:
| moderate | Human review |
| A-4.1.2 WCAG 4.1.2 | Controls have accessible names Buttons, links and widgets announce what they do — including icon-only carousel arrows. An unnamed button is announced as just "button". Carousel and lightbox controls are the usual offenders. How we test this
Fails when: Any interactive control whose computed accessible name is empty. Evidence we record: the exact element, a screenshot of it on your page Where this check can be wrong:
| critical | Automated |
| A-4.1.2-ARIA WCAG 4.1.2 | ARIA is used correctly, or not at all ARIA roles and attributes are valid and point at elements that exist. Broken ARIA is worse than none. Pages using ARIA average more errors than pages without it, because it is usually applied by a plugin that got it wrong. How we test this
Fails when: Any invalid role, invalid attribute, invalid value, missing required attribute or child, or aria-hidden on a focusable element. Evidence we record: the exact element, a screenshot of it on your page Where this check can be wrong:
| serious | Automated |
Security 6 checks · 12% of the score
| Reference | Check | Severity | How tested |
|---|---|---|---|
| S-TLS | The site is served over HTTPS The connection is encrypted and the certificate is valid and current. Browsers now label plain HTTP as "Not secure" in the address bar. Visitors see that before they see you. How we test this
Fails when: Not served over HTTPS, or a certificate that is invalid, expired or does not match the host. Evidence we record: the number we measured, your response headers as we received them | critical | Automated (headers) |
| S-HSTS | HTTPS is enforced (HSTS) The server tells browsers to refuse the unencrypted version. Without it, the first visit can be intercepted before the redirect happens. How we test this
Fails when: Header absent. Presence is a pass in ssc-1.0; max-age is recorded but not scored. Evidence we record: your response headers as we received them | moderate | Automated (headers) |
| S-CSP | A content security policy is set The site declares which scripts it trusts. This is the main defence against an injected script skimming your contact form. How we test this
Fails when: Header absent. ssc-1.0 scores presence only and does not grade policy strength. Evidence we record: your response headers as we received them Where this check can be wrong:
| serious | Automated (headers) |
| S-FRAME | The site cannot be framed by others X-Frame-Options or frame-ancestors stops someone embedding your site inside theirs. Framing is used to trick visitors into clicking things they cannot see. How we test this
Fails when: Neither x-frame-options nor a CSP frame-ancestors directive. Evidence we record: your response headers as we received them | moderate | Automated (headers) |
| S-SNIFF | MIME type sniffing is disabled X-Content-Type-Options: nosniff is present. Stops a browser from guessing that an uploaded file is a script. How we test this
Fails when: x-content-type-options is not exactly `nosniff`. Evidence we record: your response headers as we received them | minor | Automated (headers) |
| S-STACK | No outdated software is publicly advertised The site does not announce an old CMS or plugin version in its headers or markup. Automated bots scan for exactly these version strings. Advertising one is an invitation. How we test this
Fails when: A version number publicly advertised in a response header. Evidence we record: your response headers as we received them, the number we measured Where this check can be wrong:
| serious | Automated (headers) |
Site health 5 checks · 10% of the score
| Reference | Check | Severity | How tested |
|---|---|---|---|
| H-LINKS | No broken links Every link on the page resolves. A dead link on a services page is a lost enquiry and a bad signal to search engines. How we test this
Fails when: Any link returning 4xx or 5xx. Evidence we record: the exact element, the number we measured Where this check can be wrong:
| moderate | not yet tested |
| H-MIXED | No insecure content on a secure page An HTTPS page does not load images or scripts over plain HTTP. Mixed content breaks the padlock and can be blocked outright by the browser. How we test this
Fails when: Any subresource loaded over http:// on an https:// page. Evidence we record: the exact element, the number we measured Where this check can be wrong:
| serious | Automated |
| H-PRIVACY | A privacy policy exists and is reachable If the site collects anything through a form, it says what happens to it. Expected by visitors, required by most analytics and advertising terms of service. How we test this
Fails when: No link whose URL contains "privacy". Evidence we record: the number we measured Where this check can be wrong:
| moderate | Automated |
| H-TITLE | Pages have unique, descriptive titles The browser tab and search result say what the page is. The title is the first line of every search result. "Home | Home" wastes it. How we test this
Fails when: Empty, or fewer than 5 characters. Uniqueness is only assessed across a paid multi-page audit. Evidence we record: the number we measured Where this check can be wrong:
| moderate | Automated |
| H-VIEWPORT | Mobile viewport is configured and zoom is not blocked A viewport meta tag exists and does not disable pinch-to-zoom. Blocking zoom is a direct accessibility failure and still common on older templates. How we test this
Fails when: No viewport meta, or a zoom cap below 200%. The 2x boundary is where WCAG 1.4.4 puts it. Evidence we record: the number we measured Where this check can be wrong:
| serious | Automated |
Performance 3 checks · 8% of the score
| Reference | Check | Severity | How tested |
|---|---|---|---|
| P-LCP | The main content appears quickly Largest Contentful Paint under 2.5 seconds. Every extra second past three loses visitors. On a phone on mobile data it is worse. How we test this
Fails when: LCP above 2.5s at the median of three throttled mobile runs. Evidence we record: the number we measured, a screenshot of it on your page Where this check can be wrong:
| serious | not yet tested |
| P-CLS | The layout does not jump while loading Cumulative Layout Shift under 0.1. Content moving under a finger causes mistaps, and reads as cheap. How we test this
Fails when: CLS above 0.1 at the median of three throttled mobile runs. Evidence we record: the number we measured, a screenshot of it on your page Where this check can be wrong:
| moderate | not yet tested |
| P-WEIGHT | The page is not unnecessarily heavy Total page weight under about 3 MB, images sized for the web. Uncompressed photographs straight from a camera are the usual cause, and the easiest thing to fix. How we test this
Fails when: Total transferred weight above 3 MB. Evidence we record: the number we measured Where this check can be wrong:
| moderate | not yet tested |
Changes to this checklist
Weights and checks change as the standard does. When they change we publish a new version number rather than editing this page, because scores produced under different versions are not comparable. Every report we issue records the version it was scored against — this one is ssc-1.0.