{
 "version": 1,
 "categories": [
  {
   "id": "images",
   "title": "Images"
  },
  {
   "id": "structure",
   "title": "Structure"
  },
  {
   "id": "links",
   "title": "Links and buttons"
  },
  {
   "id": "forms",
   "title": "Forms"
  },
  {
   "id": "aria",
   "title": "ARIA"
  },
  {
   "id": "media",
   "title": "Media and motion"
  },
  {
   "id": "colour",
   "title": "Colour"
  },
  {
   "id": "typography",
   "title": "Typography"
  },
  {
   "id": "interaction",
   "title": "Interaction"
  },
  {
   "id": "content",
   "title": "Content"
  }
 ],
 "rules": [
  {
   "id": "img-alt-missing",
   "title": "Image has no alt attribute",
   "wcag": {
    "sc": "1.1.1",
    "name": "Non-text Content",
    "level": "A"
   },
   "severity": "critical",
   "category": "images",
   "pass": "server",
   "mode": "automated",
   "why": "Screen reader users hear the file name or nothing at all, so they miss whatever the picture was telling everyone else. Search engines miss it too.",
   "fix": "Add an alt attribute. Describe what the image shows or says, in a short sentence. If the image is purely decorative, use an empty alt (alt=\"\") so screen readers skip it.",
   "example": "<!-- Before -->\n<img src=\"team.jpg\">\n\n<!-- After: informative -->\n<img src=\"team.jpg\" alt=\"The four of us outside the studio, laughing at a whiteboard\">\n\n<!-- After: decorative -->\n<img src=\"swirl.svg\" alt=\"\">",
   "helpUrl": "https://www.w3.org/WAI/WCAG22/Understanding/non-text-content.html"
  },
  {
   "id": "img-alt-filename",
   "title": "Alt text looks like a file name",
   "wcag": {
    "sc": "1.1.1",
    "name": "Non-text Content",
    "level": "A"
   },
   "severity": "serious",
   "category": "images",
   "pass": "server",
   "mode": "automated",
   "why": "Alt text such as \"IMG_4032.jpg\" tells a screen reader user nothing about the picture. It is read out letter by letter, which is worse than silence.",
   "fix": "Replace it with a short description of what the image shows. If it is decorative, use an empty alt instead.",
   "example": "<!-- Before -->\n<img src=\"p.jpg\" alt=\"IMG_4032.jpg\">\n\n<!-- After -->\n<img src=\"p.jpg\" alt=\"A baker dusting flour over a tray of loaves\">",
   "helpUrl": "https://www.w3.org/WAI/WCAG22/Understanding/non-text-content.html"
  },
  {
   "id": "img-alt-redundant",
   "title": "Alt text starts with \"image of\" or similar",
   "wcag": {
    "sc": "1.1.1",
    "name": "Non-text Content",
    "level": "A"
   },
   "severity": "minor",
   "category": "images",
   "pass": "server",
   "mode": "automated",
   "why": "Screen readers already announce \"image\" or \"graphic\" before the alt text, so saying it again makes people hear \"image, image of a dog\".",
   "fix": "Drop the opening \"image of\", \"picture of\" or \"photo of\" and describe the content directly.",
   "example": "<!-- Before -->\n<img src=\"dog.jpg\" alt=\"Image of a dog on a beach\">\n\n<!-- After -->\n<img src=\"dog.jpg\" alt=\"A spaniel shaking off water on a beach\">",
   "helpUrl": "https://www.w3.org/WAI/WCAG22/Understanding/non-text-content.html"
  },
  {
   "id": "img-alt-long",
   "title": "Alt text is very long",
   "wcag": {
    "sc": "1.1.1",
    "name": "Non-text Content",
    "level": "A"
   },
   "severity": "minor",
   "category": "images",
   "pass": "server",
   "mode": "automated",
   "why": "Alt text over about 150 characters is tiring to listen to and cannot be skipped part-way through. Long descriptions belong in the page itself.",
   "fix": "Keep the alt text to the point. Put any longer explanation (for a chart or infographic, say) in visible text next to the image and refer to it.",
   "example": "<!-- Before -->\n<img src=\"chart.png\" alt=\"A bar chart showing sales by month ... (200 more words)\">\n\n<!-- After -->\n<figure>\n  <img src=\"chart.png\" alt=\"Sales by month, rising from March to a peak in November\">\n  <figcaption>Full figures are in the table below.</figcaption>\n</figure>",
   "helpUrl": "https://www.w3.org/WAI/WCAG22/Understanding/non-text-content.html"
  },
  {
   "id": "img-link-no-name",
   "title": "Linked image has no accessible name",
   "wcag": {
    "sc": "2.4.4",
    "name": "Link Purpose (In Context)",
    "level": "A"
   },
   "severity": "critical",
   "category": "images",
   "pass": "server",
   "mode": "automated",
   "why": "When an image is the only content of a link and has no alt text, a screen reader announces just \"link\" or reads out the web address. Nobody knows where it goes.",
   "fix": "Give the image alt text that says where the link goes, not what the picture looks like.",
   "example": "<!-- Before -->\n<a href=\"/shop/\"><img src=\"basket.svg\"></a>\n\n<!-- After -->\n<a href=\"/shop/\"><img src=\"basket.svg\" alt=\"Visit the shop\"></a>",
   "helpUrl": "https://www.w3.org/WAI/WCAG22/Understanding/link-purpose-in-context.html"
  },
  {
   "id": "svg-role-img-no-name",
   "title": "SVG marked as an image has no name",
   "wcag": {
    "sc": "1.1.1",
    "name": "Non-text Content",
    "level": "A"
   },
   "severity": "serious",
   "category": "images",
   "pass": "server",
   "mode": "automated",
   "why": "An SVG with role=\"img\" is announced as an image. Without a name, people hear \"image\" and nothing else.",
   "fix": "Add an aria-label, or a <title> inside the SVG referenced by aria-labelledby. If it is decorative, use aria-hidden=\"true\" and drop the role.",
   "example": "<!-- Before -->\n<svg role=\"img\" viewBox=\"0 0 24 24\">...</svg>\n\n<!-- After -->\n<svg role=\"img\" aria-label=\"Warning\" viewBox=\"0 0 24 24\">...</svg>",
   "helpUrl": "https://www.w3.org/WAI/WCAG22/Understanding/non-text-content.html"
  },
  {
   "id": "input-image-alt",
   "title": "Image button has no alt text",
   "wcag": {
    "sc": "1.1.1",
    "name": "Non-text Content",
    "level": "A"
   },
   "severity": "critical",
   "category": "images",
   "pass": "server",
   "mode": "automated",
   "why": "An <input type=\"image\"> is a button made from a picture. Without alt text a screen reader cannot say what the button does.",
   "fix": "Add an alt attribute that names the action, such as \"Search\" or \"Send message\".",
   "example": "<!-- Before -->\n<input type=\"image\" src=\"go.png\">\n\n<!-- After -->\n<input type=\"image\" src=\"go.png\" alt=\"Search\">",
   "helpUrl": "https://www.w3.org/WAI/WCAG22/Understanding/non-text-content.html"
  },
  {
   "id": "area-alt",
   "title": "Image map area has no alt text",
   "wcag": {
    "sc": "1.1.1",
    "name": "Non-text Content",
    "level": "A"
   },
   "severity": "critical",
   "category": "images",
   "pass": "server",
   "mode": "automated",
   "why": "Each clickable region in an image map is a link. Without alt text, keyboard and screen reader users cannot tell the regions apart.",
   "fix": "Add alt text to every <area> that has an href, describing where it goes.",
   "example": "<!-- Before -->\n<area shape=\"rect\" coords=\"0,0,80,40\" href=\"/north/\">\n\n<!-- After -->\n<area shape=\"rect\" coords=\"0,0,80,40\" href=\"/north/\" alt=\"North office\">",
   "helpUrl": "https://www.w3.org/WAI/WCAG22/Understanding/non-text-content.html"
  },
  {
   "id": "html-lang-missing",
   "title": "Page has no language set",
   "wcag": {
    "sc": "3.1.1",
    "name": "Language of Page",
    "level": "A"
   },
   "severity": "serious",
   "category": "structure",
   "pass": "server",
   "mode": "automated",
   "why": "Screen readers choose a voice and pronunciation from the page language. Without it, an English page can be read with the wrong accent, or garbled.",
   "fix": "Set the lang attribute on the <html> element. WordPress does this from the Site Language setting, so check the theme is calling language_attributes().",
   "example": "<!-- Before -->\n<html>\n\n<!-- After -->\n<html lang=\"en-GB\">",
   "helpUrl": "https://www.w3.org/WAI/WCAG22/Understanding/language-of-page.html"
  },
  {
   "id": "html-lang-invalid",
   "title": "Page language code is not valid",
   "wcag": {
    "sc": "3.1.1",
    "name": "Language of Page",
    "level": "A"
   },
   "severity": "serious",
   "category": "structure",
   "pass": "server",
   "mode": "automated",
   "why": "A language code that does not exist is ignored, so assistive technology falls back to guessing.",
   "fix": "Use a valid BCP 47 code such as en, en-GB or fr-CA.",
   "example": "<!-- Before -->\n<html lang=\"english\">\n\n<!-- After -->\n<html lang=\"en-GB\">",
   "helpUrl": "https://www.w3.org/WAI/WCAG22/Understanding/language-of-page.html"
  },
  {
   "id": "title-missing",
   "title": "Page has no title",
   "wcag": {
    "sc": "2.4.2",
    "name": "Page Titled",
    "level": "A"
   },
   "severity": "serious",
   "category": "structure",
   "pass": "server",
   "mode": "automated",
   "why": "The page title is the first thing a screen reader announces and the label on every browser tab. Without one people cannot tell pages apart.",
   "fix": "Add a <title> that describes this page. WordPress themes should declare title-tag support so core writes it for you.",
   "example": "<!-- Before -->\n<title></title>\n\n<!-- After -->\n<title>Contact us - Acme Bakery</title>",
   "helpUrl": "https://www.w3.org/WAI/WCAG22/Understanding/page-titled.html"
  },
  {
   "id": "title-duplicate",
   "title": "Several pages share the same title",
   "wcag": {
    "sc": "2.4.2",
    "name": "Page Titled",
    "level": "A"
   },
   "severity": "moderate",
   "category": "structure",
   "pass": "server",
   "mode": "automated",
   "why": "If many pages have an identical title, people using tabs, history or a screen reader cannot tell where they are.",
   "fix": "Make each title say what is unique about the page, with the site name last.",
   "example": "<!-- Before -->\n<title>Acme Bakery</title>   <!-- on every page -->\n\n<!-- After -->\n<title>Sourdough classes - Acme Bakery</title>",
   "helpUrl": "https://www.w3.org/WAI/WCAG22/Understanding/page-titled.html"
  },
  {
   "id": "h1-missing",
   "title": "Page has no main heading (h1)",
   "wcag": {
    "sc": "2.4.6",
    "name": "Headings and Labels",
    "level": "AA"
   },
   "severity": "moderate",
   "category": "structure",
   "pass": "server",
   "mode": "automated",
   "why": "The h1 tells everyone what the page is about, and screen reader users often jump straight to it.",
   "fix": "Add one h1 that names the page. Usually this is the post or page title.",
   "example": "<!-- Before -->\n<div class=\"big-title\">Opening times</div>\n\n<!-- After -->\n<h1>Opening times</h1>",
   "helpUrl": "https://www.w3.org/WAI/WCAG22/Understanding/headings-and-labels.html"
  },
  {
   "id": "heading-skipped",
   "title": "Heading levels are skipped",
   "wcag": {
    "sc": "1.3.1",
    "name": "Info and Relationships",
    "level": "A"
   },
   "severity": "moderate",
   "category": "structure",
   "pass": "server",
   "mode": "automated",
   "why": "Headings are a table of contents for people who navigate by them. Jumping from h2 to h4 suggests something is missing, and makes the outline confusing.",
   "fix": "Use heading levels in order, without gaps. Choose the level for the structure, then style it with CSS to get the size you want.",
   "example": "<!-- Before -->\n<h2>Services</h2>\n<h4>Web design</h4>\n\n<!-- After -->\n<h2>Services</h2>\n<h3>Web design</h3>",
   "helpUrl": "https://www.w3.org/WAI/WCAG22/Understanding/info-and-relationships.html"
  },
  {
   "id": "heading-empty",
   "title": "Heading is empty",
   "wcag": {
    "sc": "1.3.1",
    "name": "Info and Relationships",
    "level": "A"
   },
   "severity": "serious",
   "category": "structure",
   "pass": "server",
   "mode": "automated",
   "why": "An empty heading is announced as \"heading\" with nothing after it, and shows up as a blank entry in the heading list.",
   "fix": "Add text, or remove the heading. If it was only there for spacing, use CSS margin instead.",
   "example": "<!-- Before -->\n<h3></h3>\n\n<!-- After -->\n<h3>Opening times</h3>",
   "helpUrl": "https://www.w3.org/WAI/WCAG22/Understanding/info-and-relationships.html"
  },
  {
   "id": "landmark-main-missing",
   "title": "Page has no main landmark",
   "wcag": {
    "sc": "2.4.1",
    "name": "Bypass Blocks",
    "level": "A"
   },
   "severity": "moderate",
   "category": "structure",
   "pass": "server",
   "mode": "automated",
   "why": "The main landmark lets keyboard and screen reader users jump straight past the header and menu to the content.",
   "fix": "Wrap the page's primary content in a single <main> element.",
   "example": "<!-- After -->\n<header>...</header>\n<main id=\"content\">\n  ...page content...\n</main>\n<footer>...</footer>",
   "helpUrl": "https://www.w3.org/WAI/WCAG22/Understanding/bypass-blocks.html"
  },
  {
   "id": "landmark-nav-unlabelled",
   "title": "Several navigation areas share no labels",
   "wcag": {
    "sc": "1.3.1",
    "name": "Info and Relationships",
    "level": "A"
   },
   "severity": "minor",
   "category": "structure",
   "pass": "server",
   "mode": "automated",
   "why": "When a page has more than one <nav>, screen reader users hear \"navigation\" repeatedly with no way to tell them apart.",
   "fix": "Give each extra <nav> an aria-label that says what it is, such as \"Primary\", \"Footer\" or \"Breadcrumb\".",
   "example": "<nav aria-label=\"Primary\">...</nav>\n<nav aria-label=\"Footer\">...</nav>",
   "helpUrl": "https://www.w3.org/WAI/WCAG22/Understanding/info-and-relationships.html"
  },
  {
   "id": "skip-link-missing",
   "title": "No skip link",
   "wcag": {
    "sc": "2.4.1",
    "name": "Bypass Blocks",
    "level": "A"
   },
   "severity": "moderate",
   "category": "structure",
   "pass": "server",
   "mode": "automated",
   "why": "Keyboard users have to tab through the whole header and menu on every page before they reach the content. A skip link removes that effort.",
   "fix": "Add a link as the first focusable thing on the page that jumps to the main content. It can be hidden until it gets focus. The Safe Fixes module can add one for you.",
   "example": "<a class=\"skip-link\" href=\"#content\">Skip to content</a>\n...\n<main id=\"content\">",
   "helpUrl": "https://www.w3.org/WAI/WCAG22/Understanding/bypass-blocks.html"
  },
  {
   "id": "list-orphan-li",
   "title": "List item is outside a list",
   "wcag": {
    "sc": "1.3.1",
    "name": "Info and Relationships",
    "level": "A"
   },
   "severity": "moderate",
   "category": "structure",
   "pass": "server",
   "mode": "automated",
   "why": "A <li> that is not inside a <ul> or <ol> is not announced as part of a list, so the grouping is lost.",
   "fix": "Wrap list items in <ul> or <ol>. If you only want the look, use a different element.",
   "example": "<!-- Before -->\n<li>Tea</li><li>Coffee</li>\n\n<!-- After -->\n<ul><li>Tea</li><li>Coffee</li></ul>",
   "helpUrl": "https://www.w3.org/WAI/WCAG22/Understanding/info-and-relationships.html"
  },
  {
   "id": "table-no-headers",
   "title": "Data table has no header cells",
   "wcag": {
    "sc": "1.3.1",
    "name": "Info and Relationships",
    "level": "A"
   },
   "severity": "serious",
   "category": "structure",
   "pass": "server",
   "mode": "automated",
   "why": "Screen readers announce the column and row heading as you move around a table. Without header cells, every number is read out with no context.",
   "fix": "Mark the header cells with <th>, and add scope=\"col\" or scope=\"row\". Use tables for data only, not layout.",
   "example": "<table>\n  <tr><th scope=\"col\">Plan</th><th scope=\"col\">Price</th></tr>\n  <tr><td>Pro</td><td>£59</td></tr>\n</table>",
   "helpUrl": "https://www.w3.org/WAI/WCAG22/Understanding/info-and-relationships.html"
  },
  {
   "id": "iframe-title-missing",
   "title": "Frame has no title",
   "wcag": {
    "sc": "4.1.2",
    "name": "Name, Role, Value",
    "level": "A"
   },
   "severity": "serious",
   "category": "structure",
   "pass": "server",
   "mode": "automated",
   "why": "Screen readers list frames by title. An untitled embed is announced as just \"frame\", so people cannot tell a map from an advert.",
   "fix": "Add a title attribute that says what the embed is.",
   "example": "<iframe src=\"https://www.youtube.com/embed/abc\" title=\"Video: how we bake sourdough\"></iframe>",
   "helpUrl": "https://www.w3.org/WAI/WCAG22/Understanding/name-role-value.html"
  },
  {
   "id": "viewport-zoom-disabled",
   "title": "Pinch zoom is switched off",
   "wcag": {
    "sc": "1.4.4",
    "name": "Resize Text",
    "level": "AA"
   },
   "severity": "serious",
   "category": "structure",
   "pass": "server",
   "mode": "automated",
   "why": "Setting user-scalable=no or a low maximum-scale stops people with low vision from zooming in on a phone.",
   "fix": "Remove user-scalable=no and maximum-scale from the viewport meta tag. The Safe Fixes module can do this for you.",
   "example": "<!-- Before -->\n<meta name=\"viewport\" content=\"width=device-width, user-scalable=no\">\n\n<!-- After -->\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">",
   "helpUrl": "https://www.w3.org/WAI/WCAG22/Understanding/resize-text.html"
  },
  {
   "id": "meta-refresh",
   "title": "Page refreshes or redirects on a timer",
   "wcag": {
    "sc": "2.2.1",
    "name": "Timing Adjustable",
    "level": "A"
   },
   "severity": "serious",
   "category": "structure",
   "pass": "server",
   "mode": "automated",
   "why": "A timed refresh can move people away before they have finished reading, which is especially hard for screen reader and switch users.",
   "fix": "Remove the meta refresh. Use a server-side redirect, or let the user choose when to move on.",
   "example": "<!-- Remove -->\n<meta http-equiv=\"refresh\" content=\"5; url=/next/\">",
   "helpUrl": "https://www.w3.org/WAI/WCAG22/Understanding/timing-adjustable.html"
  },
  {
   "id": "aria-ref-missing-id",
   "title": "Label points at an element that does not exist",
   "wcag": {
    "sc": "4.1.2",
    "name": "Name, Role, Value",
    "level": "A"
   },
   "severity": "serious",
   "category": "structure",
   "pass": "server",
   "mode": "automated",
   "why": "aria-labelledby, aria-describedby and for can only work if the id they mention exists. A broken reference silently leaves the control without a name.",
   "fix": "Fix the id so it matches an element on the page, or remove the attribute.",
   "example": "<!-- Before -->\n<input aria-labelledby=\"nme\">\n<label id=\"name-label\">Name</label>\n\n<!-- After -->\n<input aria-labelledby=\"name-label\">\n<label id=\"name-label\">Name</label>",
   "helpUrl": "https://www.w3.org/WAI/WCAG22/Understanding/name-role-value.html"
  },
  {
   "id": "id-duplicate-referenced",
   "title": "Duplicate id is used by a label or ARIA attribute",
   "wcag": {
    "sc": "4.1.2",
    "name": "Name, Role, Value",
    "level": "A"
   },
   "severity": "moderate",
   "category": "structure",
   "pass": "server",
   "mode": "automated",
   "why": "Browsers pick the first element with a given id, so a label or aria-describedby can end up attached to the wrong thing. (WCAG 2.2 dropped the old parsing rule, so duplicates only matter when something refers to them.)",
   "fix": "Make every id that is referenced unique on the page.",
   "example": "<!-- Before -->\n<input id=\"email\"> ... <input id=\"email\">\n\n<!-- After -->\n<input id=\"header-email\"> ... <input id=\"footer-email\">",
   "helpUrl": "https://www.w3.org/WAI/WCAG22/Understanding/name-role-value.html"
  },
  {
   "id": "link-empty",
   "title": "Link has no text",
   "wcag": {
    "sc": "2.4.4",
    "name": "Link Purpose (In Context)",
    "level": "A"
   },
   "severity": "critical",
   "category": "links",
   "pass": "server",
   "mode": "automated",
   "why": "A link with no readable content is announced as \"link\" and nothing else, or as its web address. People cannot tell where it goes.",
   "fix": "Add visible text, or an aria-label that says where it goes. Icon-only links need a name too.",
   "example": "<!-- Before -->\n<a href=\"https://x.com/acme\"><i class=\"icon-x\"></i></a>\n\n<!-- After -->\n<a href=\"https://x.com/acme\" aria-label=\"Acme on X\"><i class=\"icon-x\" aria-hidden=\"true\"></i></a>",
   "helpUrl": "https://www.w3.org/WAI/WCAG22/Understanding/link-purpose-in-context.html"
  },
  {
   "id": "button-empty",
   "title": "Button has no name",
   "wcag": {
    "sc": "4.1.2",
    "name": "Name, Role, Value",
    "level": "A"
   },
   "severity": "critical",
   "category": "links",
   "pass": "server",
   "mode": "automated",
   "why": "A button without a name is announced as just \"button\". Screen reader and voice control users cannot find or use it.",
   "fix": "Add visible text, or an aria-label for icon buttons.",
   "example": "<!-- Before -->\n<button class=\"menu-toggle\"><svg>...</svg></button>\n\n<!-- After -->\n<button class=\"menu-toggle\" aria-label=\"Open menu\"><svg aria-hidden=\"true\">...</svg></button>",
   "helpUrl": "https://www.w3.org/WAI/WCAG22/Understanding/name-role-value.html"
  },
  {
   "id": "link-vague",
   "title": "Link text is vague",
   "wcag": {
    "sc": "2.4.4",
    "name": "Link Purpose (In Context)",
    "level": "A"
   },
   "severity": "moderate",
   "category": "links",
   "pass": "server",
   "mode": "automated",
   "why": "Screen reader users often pull up a list of all links on a page. A list of ten \"Read more\" entries is useless.",
   "fix": "Make the link say where it goes. If the design needs a short visible label, add the context for screen readers with an aria-label that starts with the visible text.",
   "example": "<!-- Before -->\n<a href=\"/blog/a11y/\">Read more</a>\n\n<!-- After -->\n<a href=\"/blog/a11y/\">Read more<span class=\"screen-reader-text\"> about accessibility basics</span></a>",
   "helpUrl": "https://www.w3.org/WAI/WCAG22/Understanding/link-purpose-in-context.html"
  },
  {
   "id": "link-new-window",
   "title": "Link opens a new tab without saying so",
   "wcag": {
    "sc": "3.2.5",
    "name": "Change on Request",
    "level": "AAA"
   },
   "severity": "minor",
   "category": "links",
   "pass": "server",
   "mode": "needs-review",
   "why": "Opening a new window without warning can disorient people, especially if they use a screen reader or magnifier and do not notice the change.",
   "fix": "Say so in the link text, or add screen reader text. Safe Fixes can add \"(opens in a new tab)\" automatically. Also add rel=\"noopener\".",
   "example": "<a href=\"https://example.com\" target=\"_blank\" rel=\"noopener\">Example <span class=\"screen-reader-text\">(opens in a new tab)</span></a>",
   "helpUrl": "https://www.w3.org/WAI/WCAG22/Understanding/change-on-request.html"
  },
  {
   "id": "link-same-text-different-dest",
   "title": "Same link text goes to different places",
   "wcag": {
    "sc": "2.4.4",
    "name": "Link Purpose (In Context)",
    "level": "A"
   },
   "severity": "moderate",
   "category": "links",
   "pass": "server",
   "mode": "needs-review",
   "why": "If two links say \"Details\" but go to different pages, people who navigate by link list cannot tell which is which.",
   "fix": "Make the text unique, or add hidden context that differs. If they genuinely go to the same place, use the same address.",
   "example": "<a href=\"/rooms/single/\">Single room details</a>\n<a href=\"/rooms/double/\">Double room details</a>",
   "helpUrl": "https://www.w3.org/WAI/WCAG22/Understanding/link-purpose-in-context.html"
  },
  {
   "id": "link-file-no-type",
   "title": "Link to a file does not say what it is",
   "wcag": {
    "sc": "2.4.4",
    "name": "Link Purpose (In Context)",
    "level": "A"
   },
   "severity": "minor",
   "category": "links",
   "pass": "server",
   "mode": "needs-review",
   "why": "People should know before they click that a link downloads a PDF or opens a spreadsheet, and roughly how large it is.",
   "fix": "Include the type and size in the link text.",
   "example": "<a href=\"/brochure.pdf\">Brochure (PDF, 2.4 MB)</a>",
   "helpUrl": "https://www.w3.org/WAI/WCAG22/Understanding/link-purpose-in-context.html"
  },
  {
   "id": "input-no-label",
   "title": "Form field has no label",
   "wcag": {
    "sc": "1.3.1",
    "name": "Info and Relationships",
    "level": "A"
   },
   "severity": "critical",
   "category": "forms",
   "pass": "server",
   "mode": "automated",
   "why": "Without a label, a screen reader says \"edit text\" and the person has to guess what to type. Voice control users cannot name the field. A label also makes the click target larger.",
   "fix": "Connect a visible <label> to the field using for and id. If the design truly has no room for a visible label, use aria-label as a last resort.",
   "example": "<!-- Before -->\n<input type=\"email\" name=\"email\">\n\n<!-- After -->\n<label for=\"email\">Email address</label>\n<input type=\"email\" id=\"email\" name=\"email\">",
   "helpUrl": "https://www.w3.org/WAI/WCAG22/Understanding/info-and-relationships.html"
  },
  {
   "id": "input-placeholder-only",
   "title": "Placeholder is the only label",
   "wcag": {
    "sc": "3.3.2",
    "name": "Labels or Instructions",
    "level": "A"
   },
   "severity": "serious",
   "category": "forms",
   "pass": "server",
   "mode": "automated",
   "why": "Placeholder text disappears as soon as you start typing, is often pale grey, and is not reliably announced. People forget what the field was for.",
   "fix": "Add a real label. Keep the placeholder only for an example format, if at all.",
   "example": "<label for=\"tel\">Phone number</label>\n<input id=\"tel\" type=\"tel\" placeholder=\"e.g. 07700 900123\">",
   "helpUrl": "https://www.w3.org/WAI/WCAG22/Understanding/labels-or-instructions.html"
  },
  {
   "id": "input-autocomplete-missing",
   "title": "Personal details field has no autocomplete",
   "wcag": {
    "sc": "1.3.5",
    "name": "Identify Input Purpose",
    "level": "AA"
   },
   "severity": "moderate",
   "category": "forms",
   "pass": "server",
   "mode": "automated",
   "why": "Autocomplete lets browsers and assistive tools fill in names, emails and addresses. It helps people with memory, motor or cognitive difficulties.",
   "fix": "Add the right autocomplete token (name, email, tel, street-address, postal-code and so on).",
   "example": "<input type=\"email\" id=\"email\" name=\"email\" autocomplete=\"email\">",
   "helpUrl": "https://www.w3.org/WAI/WCAG22/Understanding/identify-input-purpose.html"
  },
  {
   "id": "group-no-fieldset",
   "title": "Radio or checkbox group has no group label",
   "wcag": {
    "sc": "1.3.1",
    "name": "Info and Relationships",
    "level": "A"
   },
   "severity": "moderate",
   "category": "forms",
   "pass": "server",
   "mode": "automated",
   "why": "Each radio button has its own label, but people also need the question. Without a group name a screen reader just says \"Yes, radio button\".",
   "fix": "Wrap the group in a <fieldset> with a <legend> that holds the question.",
   "example": "<fieldset>\n  <legend>How should we contact you?</legend>\n  <label><input type=\"radio\" name=\"c\" value=\"email\"> Email</label>\n  <label><input type=\"radio\" name=\"c\" value=\"phone\"> Phone</label>\n</fieldset>",
   "helpUrl": "https://www.w3.org/WAI/WCAG22/Understanding/info-and-relationships.html"
  },
  {
   "id": "required-not-programmatic",
   "title": "Required field is only marked visually",
   "wcag": {
    "sc": "3.3.2",
    "name": "Labels or Instructions",
    "level": "A"
   },
   "severity": "moderate",
   "category": "forms",
   "pass": "server",
   "mode": "automated",
   "why": "A red asterisk is invisible to a screen reader. People submit the form, hit an error and have to start again.",
   "fix": "Add the required attribute (or aria-required=\"true\") as well as the visible marker.",
   "example": "<label for=\"name\">Name <span aria-hidden=\"true\">*</span></label>\n<input id=\"name\" required>",
   "helpUrl": "https://www.w3.org/WAI/WCAG22/Understanding/labels-or-instructions.html"
  },
  {
   "id": "aria-role-invalid",
   "title": "ARIA role is not valid",
   "wcag": {
    "sc": "4.1.2",
    "name": "Name, Role, Value",
    "level": "A"
   },
   "severity": "serious",
   "category": "aria",
   "pass": "server",
   "mode": "automated",
   "why": "An unknown role is ignored, so the element loses the meaning you meant to give it.",
   "fix": "Use a role from the WAI-ARIA list, or better, use the matching native HTML element.",
   "example": "<!-- Before -->\n<div role=\"buton\">Save</div>\n\n<!-- After -->\n<button type=\"button\">Save</button>",
   "helpUrl": "https://www.w3.org/WAI/WCAG22/Understanding/name-role-value.html"
  },
  {
   "id": "aria-attr-invalid",
   "title": "ARIA attribute is not valid",
   "wcag": {
    "sc": "4.1.2",
    "name": "Name, Role, Value",
    "level": "A"
   },
   "severity": "serious",
   "category": "aria",
   "pass": "server",
   "mode": "automated",
   "why": "A misspelt or made-up aria- attribute does nothing, so the information never reaches assistive technology.",
   "fix": "Check the spelling against the WAI-ARIA attribute list, or remove the attribute.",
   "example": "<!-- Before -->\n<button aria-expand=\"false\">\n\n<!-- After -->\n<button aria-expanded=\"false\">",
   "helpUrl": "https://www.w3.org/WAI/WCAG22/Understanding/name-role-value.html"
  },
  {
   "id": "aria-hidden-focusable",
   "title": "Hidden element can still be focused",
   "wcag": {
    "sc": "4.1.2",
    "name": "Name, Role, Value",
    "level": "A"
   },
   "severity": "serious",
   "category": "aria",
   "pass": "server",
   "mode": "automated",
   "why": "aria-hidden=\"true\" hides an element from screen readers but not from the keyboard. Focus lands on something that is not announced.",
   "fix": "Remove aria-hidden, or make the element unfocusable (tabindex=\"-1\", the inert attribute, or hide it with display:none).",
   "example": "<!-- Before -->\n<a href=\"/x/\" aria-hidden=\"true\">Hidden link</a>\n\n<!-- After -->\n<a href=\"/x/\">Visible link</a>",
   "helpUrl": "https://www.w3.org/WAI/WCAG22/Understanding/name-role-value.html"
  },
  {
   "id": "tabindex-positive",
   "title": "Positive tabindex changes the tab order",
   "wcag": {
    "sc": "2.4.3",
    "name": "Focus Order",
    "level": "A"
   },
   "severity": "moderate",
   "category": "aria",
   "pass": "server",
   "mode": "automated",
   "why": "A tabindex above 0 pulls an element to the front of the tab order and creates a confusing jump around the page.",
   "fix": "Use tabindex=\"0\" or no tabindex, and put things in the DOM in the order you want them focused.",
   "example": "<!-- Before -->\n<input tabindex=\"5\">\n\n<!-- After -->\n<input>",
   "helpUrl": "https://www.w3.org/WAI/WCAG22/Understanding/focus-order.html"
  },
  {
   "id": "presentation-focusable",
   "title": "Focusable element is marked as presentational",
   "wcag": {
    "sc": "4.1.2",
    "name": "Name, Role, Value",
    "level": "A"
   },
   "severity": "serious",
   "category": "aria",
   "pass": "server",
   "mode": "automated",
   "why": "role=\"presentation\" or \"none\" strips an element's meaning, but a link or button still takes focus, and the browser ignores the role to avoid hiding it.",
   "fix": "Remove the role from interactive elements.",
   "example": "<!-- Before -->\n<button role=\"presentation\">Buy</button>\n\n<!-- After -->\n<button>Buy</button>",
   "helpUrl": "https://www.w3.org/WAI/WCAG22/Understanding/name-role-value.html"
  },
  {
   "id": "video-no-captions",
   "title": "Video has no captions",
   "wcag": {
    "sc": "1.2.2",
    "name": "Captions (Prerecorded)",
    "level": "A"
   },
   "severity": "critical",
   "category": "media",
   "pass": "server",
   "mode": "automated",
   "why": "Deaf and hard-of-hearing people, and anyone watching without sound, cannot follow speech in a video without captions.",
   "fix": "Add a <track kind=\"captions\"> file. For YouTube or Vimeo embeds, turn on captions in the player settings and check them. (If the captions are burned into the video, ignore this issue.)",
   "example": "<video controls>\n  <source src=\"intro.mp4\">\n  <track kind=\"captions\" src=\"intro.en.vtt\" srclang=\"en\" label=\"English\" default>\n</video>",
   "helpUrl": "https://www.w3.org/WAI/WCAG22/Understanding/captions-prerecorded.html"
  },
  {
   "id": "media-autoplay",
   "title": "Media plays automatically",
   "wcag": {
    "sc": "1.4.2",
    "name": "Audio Control",
    "level": "A"
   },
   "severity": "serious",
   "category": "media",
   "pass": "server",
   "mode": "automated",
   "why": "Sound that starts by itself fights with screen readers and can be impossible to stop. Moving video is also distracting for people with attention or vestibular difficulties.",
   "fix": "Remove autoplay, or make sure the video is muted, short and has a visible pause button.",
   "example": "<!-- Before -->\n<video autoplay loop src=\"hero.mp4\"></video>\n\n<!-- After -->\n<video controls muted src=\"hero.mp4\"></video>",
   "helpUrl": "https://www.w3.org/WAI/WCAG22/Understanding/audio-control.html"
  },
  {
   "id": "marquee-blink",
   "title": "Page uses marquee or blink",
   "wcag": {
    "sc": "2.2.2",
    "name": "Pause, Stop, Hide",
    "level": "A"
   },
   "severity": "serious",
   "category": "media",
   "pass": "server",
   "mode": "automated",
   "why": "Scrolling or flashing text cannot be paused and is almost impossible to read for many people. The elements are also obsolete.",
   "fix": "Replace with static text.",
   "example": "<!-- Before -->\n<marquee>Sale now on</marquee>\n\n<!-- After -->\n<p>Sale now on</p>",
   "helpUrl": "https://www.w3.org/WAI/WCAG22/Understanding/pause-stop-hide.html"
  },
  {
   "id": "motion-reduced-ignored",
   "title": "Animations ignore the reduced motion setting",
   "wcag": {
    "sc": "2.3.3",
    "name": "Animation from Interactions",
    "level": "AAA"
   },
   "severity": "minor",
   "category": "media",
   "pass": "rendered",
   "mode": "needs-review",
   "why": "Some people feel ill from parallax, zooms and large movement. Their device has a \"reduce motion\" setting, and sites are expected to respect it.",
   "fix": "Wrap non-essential animation in a prefers-reduced-motion query, or switch it off inside one. The Safe Fixes module has a toggle for this.",
   "example": "@media (prefers-reduced-motion: reduce) {\n  *, *::before, *::after {\n    animation-duration: 0.01ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: 0.01ms !important;\n    scroll-behavior: auto !important;\n  }\n}",
   "helpUrl": "https://www.w3.org/WAI/WCAG22/Understanding/animation-from-interactions.html"
  },
  {
   "id": "moving-content",
   "title": "Content moves on its own for more than 5 seconds",
   "wcag": {
    "sc": "2.2.2",
    "name": "Pause, Stop, Hide",
    "level": "A"
   },
   "severity": "serious",
   "category": "media",
   "pass": "rendered",
   "mode": "needs-review",
   "why": "Carousels, tickers and looping animations are hard to read and distracting. People need a way to pause, stop or hide them.",
   "fix": "Add a visible pause control, or stop the motion after five seconds.",
   "example": "<button type=\"button\" aria-pressed=\"false\" id=\"pause-slider\">Pause slideshow</button>",
   "helpUrl": "https://www.w3.org/WAI/WCAG22/Understanding/pause-stop-hide.html"
  },
  {
   "id": "contrast-text",
   "title": "Text does not have enough contrast",
   "wcag": {
    "sc": "1.4.3",
    "name": "Contrast (Minimum)",
    "level": "AA"
   },
   "severity": "serious",
   "category": "colour",
   "pass": "rendered",
   "mode": "automated",
   "why": "Low-contrast text is hard to read for people with low vision, in sunlight, or on a worn-out screen. AA needs 4.5:1 for normal text and 3:1 for large text (24px, or 19px bold).",
   "fix": "Darken the text or lighten the background until the ratio passes. A11yMate suggests the nearest colour that keeps your hue.",
   "example": "/* Before: 2.8:1 */\ncolor: #999999; background: #ffffff;\n\n/* After: 7:1 */\ncolor: #595959; background: #ffffff;",
   "helpUrl": "https://www.w3.org/WAI/WCAG22/Understanding/contrast-minimum.html"
  },
  {
   "id": "contrast-text-enhanced",
   "title": "Text misses the enhanced (AAA) contrast level",
   "wcag": {
    "sc": "1.4.6",
    "name": "Contrast (Enhanced)",
    "level": "AAA"
   },
   "severity": "minor",
   "category": "colour",
   "pass": "rendered",
   "mode": "automated",
   "why": "AAA asks for 7:1 for normal text and 4.5:1 for large text. It is not required for AA, but it helps many people with low vision.",
   "fix": "Darken the text a little further if you are aiming for AAA.",
   "example": "color: #3b3b3b; background: #ffffff; /* 11.6:1 */",
   "helpUrl": "https://www.w3.org/WAI/WCAG22/Understanding/contrast-enhanced.html"
  },
  {
   "id": "contrast-nontext",
   "title": "Interface component or border has low contrast",
   "wcag": {
    "sc": "1.4.11",
    "name": "Non-text Contrast",
    "level": "AA"
   },
   "severity": "serious",
   "category": "colour",
   "pass": "rendered",
   "mode": "automated",
   "why": "Form field borders, icons and other parts you need to see to use the page need at least 3:1 against what is behind them.",
   "fix": "Darken the border or icon colour to at least 3:1 against its background.",
   "example": "input { border: 1px solid #767676; } /* 4.5:1 on white */",
   "helpUrl": "https://www.w3.org/WAI/WCAG22/Understanding/non-text-contrast.html"
  },
  {
   "id": "link-colour-only",
   "title": "Link is only distinguished by colour",
   "wcag": {
    "sc": "1.4.1",
    "name": "Use of Colour",
    "level": "A"
   },
   "severity": "serious",
   "category": "colour",
   "pass": "rendered",
   "mode": "automated",
   "why": "People who cannot tell colours apart cannot see links that differ only by hue. If the link colour is the only clue, it needs 3:1 against the surrounding text.",
   "fix": "Underline links in body text (Safe Fixes can do that), or make the link colour at least 3:1 against the text around it, and give it another cue on hover and focus.",
   "example": "p a { text-decoration: underline; }",
   "helpUrl": "https://www.w3.org/WAI/WCAG22/Understanding/use-of-color.html"
  },
  {
   "id": "contrast-needs-review",
   "title": "Text sits over an image or gradient",
   "wcag": {
    "sc": "1.4.3",
    "name": "Contrast (Minimum)",
    "level": "AA"
   },
   "severity": "moderate",
   "category": "colour",
   "pass": "rendered",
   "mode": "needs-review",
   "why": "A tool cannot know how much contrast text has when the background is a photo or gradient. It might be fine in one spot and unreadable in another.",
   "fix": "Check the text against the lightest and darkest parts it covers. Add a solid or semi-transparent overlay behind the text if in doubt.",
   "example": ".hero__text { background: rgb(14 17 22 / 0.7); color: #fff; }",
   "helpUrl": "https://www.w3.org/WAI/WCAG22/Understanding/contrast-minimum.html"
  },
  {
   "id": "text-too-small",
   "title": "Text is smaller than 12px",
   "wcag": {
    "sc": "1.4.4",
    "name": "Resize Text",
    "level": "AA"
   },
   "severity": "serious",
   "category": "typography",
   "pass": "rendered",
   "mode": "automated",
   "why": "Very small text is hard to read for everyone, and people zooming in may hit layout limits sooner.",
   "fix": "Make readable text at least 12px, and body text at least 16px.",
   "example": "small, .meta { font-size: 0.875rem; } /* 14px */",
   "helpUrl": "https://www.w3.org/WAI/WCAG22/Understanding/resize-text.html"
  },
  {
   "id": "text-small-body",
   "title": "Body text is smaller than 16px",
   "wcag": {
    "sc": "1.4.4",
    "name": "Resize Text",
    "level": "AA"
   },
   "severity": "minor",
   "category": "typography",
   "pass": "rendered",
   "mode": "needs-review",
   "why": "16px is the usual comfortable minimum for body copy. Smaller type works for some readers but not for many.",
   "fix": "Set the base font size to 1rem (16px) or more and scale up from there.",
   "example": "html { font-size: 100%; }\nbody { font-size: 1rem; }",
   "helpUrl": "https://www.w3.org/WAI/WCAG22/Understanding/resize-text.html"
  },
  {
   "id": "line-height-low",
   "title": "Line spacing is tight",
   "wcag": {
    "sc": "1.4.12",
    "name": "Text Spacing",
    "level": "AA"
   },
   "severity": "minor",
   "category": "typography",
   "pass": "rendered",
   "mode": "needs-review",
   "why": "Tight lines are hard to track, especially for readers with dyslexia or low vision. WCAG asks that content survives line height of 1.5, and 1.5 is a good default.",
   "fix": "Set body text line-height to 1.5 or more.",
   "example": "p { line-height: 1.6; }",
   "helpUrl": "https://www.w3.org/WAI/WCAG22/Understanding/text-spacing.html"
  },
  {
   "id": "line-length-long",
   "title": "Lines of text are very long",
   "wcag": {
    "sc": "1.4.8",
    "name": "Visual Presentation",
    "level": "AAA"
   },
   "severity": "minor",
   "category": "typography",
   "pass": "rendered",
   "mode": "needs-review",
   "why": "Lines over about 80 characters make it hard to find the start of the next line. This is an AAA suggestion.",
   "fix": "Limit the text column width to around 45 to 75 characters, for example with max-width: 65ch.",
   "example": ".entry-content { max-width: 65ch; }",
   "helpUrl": "https://www.w3.org/WAI/WCAG22/Understanding/visual-presentation.html"
  },
  {
   "id": "text-justified",
   "title": "Text is justified",
   "wcag": {
    "sc": "1.4.8",
    "name": "Visual Presentation",
    "level": "AAA"
   },
   "severity": "minor",
   "category": "typography",
   "pass": "rendered",
   "mode": "needs-review",
   "why": "Justified text creates uneven gaps between words, which are hard for readers with dyslexia.",
   "fix": "Use left-aligned text (or right-aligned for right-to-left languages).",
   "example": "p { text-align: left; }",
   "helpUrl": "https://www.w3.org/WAI/WCAG22/Understanding/visual-presentation.html"
  },
  {
   "id": "text-all-caps-long",
   "title": "Long passage in capitals",
   "wcag": {
    "sc": "1.4.8",
    "name": "Visual Presentation",
    "level": "AAA"
   },
   "severity": "minor",
   "category": "typography",
   "pass": "rendered",
   "mode": "needs-review",
   "why": "Long runs of capitals are slower to read, and screen readers can spell out some acronyms or shout.",
   "fix": "Use sentence case for passages, and keep capitals for short labels.",
   "example": "h3 { text-transform: none; }",
   "helpUrl": "https://www.w3.org/WAI/WCAG22/Understanding/visual-presentation.html"
  },
  {
   "id": "text-italic-long",
   "title": "Long passage in italics",
   "wcag": {
    "sc": "1.4.8",
    "name": "Visual Presentation",
    "level": "AAA"
   },
   "severity": "minor",
   "category": "typography",
   "pass": "rendered",
   "mode": "needs-review",
   "why": "Long stretches of italic text are harder to read, particularly for people with dyslexia.",
   "fix": "Use italics for emphasis only, not for whole paragraphs.",
   "example": "blockquote { font-style: normal; border-left: 4px solid currentColor; }",
   "helpUrl": "https://www.w3.org/WAI/WCAG22/Understanding/visual-presentation.html"
  },
  {
   "id": "font-weight-thin",
   "title": "Very thin text at small sizes",
   "wcag": {
    "sc": "1.4.8",
    "name": "Visual Presentation",
    "level": "AAA"
   },
   "severity": "minor",
   "category": "typography",
   "pass": "rendered",
   "mode": "needs-review",
   "why": "Hairline weights vanish on low-resolution screens and in bright light, especially at small sizes.",
   "fix": "Use a weight of 300 or heavier for text below 24px.",
   "example": "body { font-weight: 400; }",
   "helpUrl": "https://www.w3.org/WAI/WCAG22/Understanding/visual-presentation.html"
  },
  {
   "id": "letter-spacing-negative",
   "title": "Tight letter spacing on body text",
   "wcag": {
    "sc": "1.4.12",
    "name": "Text Spacing",
    "level": "AA"
   },
   "severity": "moderate",
   "category": "typography",
   "pass": "rendered",
   "mode": "automated",
   "why": "Negative letter spacing makes letters touch, which blurs words for many readers.",
   "fix": "Remove negative letter-spacing on body text (small amounts on large headings are fine).",
   "example": "p { letter-spacing: normal; }",
   "helpUrl": "https://www.w3.org/WAI/WCAG22/Understanding/text-spacing.html"
  },
  {
   "id": "target-size-min",
   "title": "Click target is smaller than 24 by 24 pixels",
   "wcag": {
    "sc": "2.5.8",
    "name": "Target Size (Minimum)",
    "level": "AA"
   },
   "severity": "serious",
   "category": "interaction",
   "pass": "rendered",
   "mode": "automated",
   "why": "Tiny buttons and links are hard to hit with a finger, a tremor, or a mouse. WCAG 2.2 AA asks for at least 24 by 24 CSS pixels, unless there is spacing around them.",
   "fix": "Increase the size or padding of the target, or leave 24px of space around it.",
   "example": ".icon-button { min-width: 24px; min-height: 24px; padding: 8px; }",
   "helpUrl": "https://www.w3.org/WAI/WCAG22/Understanding/target-size-minimum.html"
  },
  {
   "id": "target-size-enhanced",
   "title": "Click target is smaller than 44 by 44 pixels",
   "wcag": {
    "sc": "2.5.5",
    "name": "Target Size (Enhanced)",
    "level": "AAA"
   },
   "severity": "minor",
   "category": "interaction",
   "pass": "rendered",
   "mode": "automated",
   "why": "44 by 44 is the comfortable size for touch. It is an AAA recommendation.",
   "fix": "Increase padding on touch controls to reach about 44px.",
   "example": ".nav a { display: inline-block; min-height: 44px; padding: 12px; }",
   "helpUrl": "https://www.w3.org/WAI/WCAG22/Understanding/target-size-enhanced.html"
  },
  {
   "id": "focus-not-visible",
   "title": "No visible focus indicator",
   "wcag": {
    "sc": "2.4.7",
    "name": "Focus Visible",
    "level": "AA"
   },
   "severity": "serious",
   "category": "interaction",
   "pass": "rendered",
   "mode": "automated",
   "why": "Keyboard users need to see where they are. If focusing a control changes nothing on screen, they are lost.",
   "fix": "Never remove the outline without replacing it. Add a clear :focus-visible style. Safe Fixes can add a contrast-checked ring for you.",
   "example": ":focus-visible { outline: 3px solid #1F5C8B; outline-offset: 2px; }",
   "helpUrl": "https://www.w3.org/WAI/WCAG22/Understanding/focus-visible.html"
  },
  {
   "id": "focus-obscured",
   "title": "Focused element is hidden behind a sticky header",
   "wcag": {
    "sc": "2.4.11",
    "name": "Focus Not Obscured (Minimum)",
    "level": "AA"
   },
   "severity": "serious",
   "category": "interaction",
   "pass": "rendered",
   "mode": "automated",
   "why": "When a fixed header or banner covers an element as you tab to it, you cannot see what is focused.",
   "fix": "Add scroll-padding-top equal to the height of the sticky element, so focused items scroll into clear view.",
   "example": "html { scroll-padding-top: 5rem; }",
   "helpUrl": "https://www.w3.org/WAI/WCAG22/Understanding/focus-not-obscured-minimum.html"
  },
  {
   "id": "reflow-horizontal-scroll",
   "title": "Page scrolls sideways at 320px wide",
   "wcag": {
    "sc": "1.4.10",
    "name": "Reflow",
    "level": "AA"
   },
   "severity": "serious",
   "category": "interaction",
   "pass": "rendered",
   "mode": "automated",
   "why": "People who zoom to 400% on a desktop get the equivalent of a 320px-wide screen. If the page scrolls in two directions, reading is a chore.",
   "fix": "Find the element that is wider than the screen (often a fixed width, table, image or code block) and let it shrink or scroll on its own.",
   "example": "img, video, iframe { max-width: 100%; height: auto; }\npre, table { overflow-x: auto; }",
   "helpUrl": "https://www.w3.org/WAI/WCAG22/Understanding/reflow.html"
  },
  {
   "id": "text-spacing-clipped",
   "title": "Text is cut off when spacing is increased",
   "wcag": {
    "sc": "1.4.12",
    "name": "Text Spacing",
    "level": "AA"
   },
   "severity": "moderate",
   "category": "interaction",
   "pass": "rendered",
   "mode": "automated",
   "why": "Some people need wider letter, word and line spacing. If your layout has fixed heights, their text is clipped or overlaps.",
   "fix": "Avoid fixed heights on text containers. Use min-height and let the box grow.",
   "example": ".card { min-height: 12rem; } /* not height */",
   "helpUrl": "https://www.w3.org/WAI/WCAG22/Understanding/text-spacing.html"
  },
  {
   "id": "reading-level",
   "title": "Text is hard to read",
   "wcag": {
    "sc": "3.1.5",
    "name": "Reading Level",
    "level": "AAA"
   },
   "severity": "minor",
   "category": "content",
   "pass": "server",
   "mode": "needs-review",
   "why": "Plain writing helps everyone, and is essential for many people with cognitive or learning disabilities. The Flesch reading ease score for this page is low (English only).",
   "fix": "Use shorter sentences and everyday words, and explain jargon. Aim for a score of 60 or more.",
   "example": "<!-- Before -->\n<p>Utilisation of the facility is contingent upon prior authorisation.</p>\n\n<!-- After -->\n<p>You need to book before you use the room.</p>",
   "helpUrl": "https://www.w3.org/WAI/WCAG22/Understanding/reading-level.html"
  },
  {
   "id": "paragraph-long",
   "title": "Paragraph is very long",
   "wcag": {
    "sc": "3.1.5",
    "name": "Reading Level",
    "level": "AAA"
   },
   "severity": "minor",
   "category": "content",
   "pass": "server",
   "mode": "needs-review",
   "why": "Walls of text are daunting. Short paragraphs and clear headings make a page easier to scan and to follow.",
   "fix": "Break long paragraphs into shorter ones, and add subheadings.",
   "example": "<p>One idea per paragraph.</p>\n<p>The next idea starts a new one.</p>",
   "helpUrl": "https://www.w3.org/WAI/WCAG22/Understanding/reading-level.html"
  },
  {
   "id": "pdf-heavy",
   "title": "Page relies on PDF documents",
   "wcag": {
    "sc": "1.3.1",
    "name": "Info and Relationships",
    "level": "A"
   },
   "severity": "minor",
   "category": "content",
   "pass": "server",
   "mode": "needs-review",
   "why": "PDFs are often not accessible: missing tags, reading order, alt text. They are also harder to read on phones.",
   "fix": "Publish the same content as a web page, and make sure any PDF you keep is tagged and tested.",
   "example": "<a href=\"/prices/\">Our prices</a> (also available as a <a href=\"/prices.pdf\">PDF</a>)",
   "helpUrl": "https://www.w3.org/WAI/WCAG22/Understanding/info-and-relationships.html"
  }
 ]
}