diff --git a/.circleci/config.yml b/.circleci/config.yml
index f34b506694e520..35fd3a987a213a 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -95,6 +95,12 @@ jobs:
- code-infra/check-static-changes
- code-infra/check-generated:
command: pnpm proptypes
+ - run:
+ # Fails when a conformance report changes without its rollup being
+ # regenerated, and when a report rates a criterion ⚙️ Automated
+ # without citing the test or axe rule that proves it.
+ name: Accessibility scorecard up to date?
+ command: pnpm a11y:scorecard:check
- code-infra/check-generated:
command: pnpm docs:api
- code-infra/extract-error-codes
diff --git a/docs/data/material/getting-started/accessibility/accessibility.md b/docs/data/material/getting-started/accessibility/accessibility.md
new file mode 100644
index 00000000000000..3c7f51e1a5ece9
--- /dev/null
+++ b/docs/data/material/getting-started/accessibility/accessibility.md
@@ -0,0 +1,121 @@
+# Accessibility conformance report
+
+
How Material UI components conform to WCAG 2.2 Level A and AA, reported in VPAT terms for procurement and accessibility review.
+
+:::warning
+**Draft — partial coverage.** This report covers the 12 components assessed so far, not the whole library. It has not been reviewed by an external auditor, and no assistive-technology testing has been performed yet. See [Scope and limitations](#scope-and-limitations) before relying on it for a procurement decision.
+:::
+
+## About this report
+
+This is a Voluntary Product Accessibility Template (VPAT®) style report: it states how far Material UI meets the [Web Content Accessibility Guidelines 2.2](https://www.w3.org/TR/WCAG22/) at Levels A and AA, using the conformance vocabulary defined by the [Information Technology Industry Council](https://www.itic.org/policy/accessibility/vpat).
+
+Each component is rated criterion by criterion in its own report, kept next to the source code at `packages/mui-material/src//accessibility.md`. Those reports carry the reasoning, the responsibility split, and reproducible manual test steps for every criterion. **The table below summarizes them; follow a component link for the detail.**
+
+| Field | Value |
+| :---------------- | :--------------------------------------------------------------------------------------------- |
+| Product | Material UI (`@mui/material`) |
+| Product type | React component library (software) |
+| Version assessed | Results track the `master` branch; see [releases](https://github.com/mui/material-ui/releases) |
+| Vendor | MUI |
+| Standards applied | WCAG 2.2 Level A and AA |
+| Report type | Self-assessment, published as source-controlled documentation |
+
+## Conformance by component
+
+Each row counts only the criteria that **apply** to that component; criteria that are Not Applicable are excluded. Levels are [cumulative](https://www.w3.org/WAI/WCAG2AA-Conformance) — AA includes all of A.
+
+- **Rated** — applicable Level A and AA criteria.
+- **Verified** — criteria confirmed by a test or a recorded review. The remainder are assessed from the source but not yet re-verified; they are flagged 🚩 in the component report. The flag concerns evidence, not conformance.
+- **Automated** — criteria a deterministic test proves on its own, so they cannot silently regress.
+
+
+
+| Component | Level A | Level AA | Rated | ✅ Supports | ⚠️ Partially Supports | Verified | Automated |
+| :------------------------------------------------------------------------------------------------------------------------------- | ------: | -------: | ------: | ----------: | --------------------: | ----------: | --------: |
+| [Accordion](https://github.com/mui/material-ui/blob/master/packages/mui-material/src/Accordion/accessibility.md) | 11 | 8 | 19 | 19 | 0 | 16/19 | 9 |
+| [AccordionSummary](https://github.com/mui/material-ui/blob/master/packages/mui-material/src/AccordionSummary/accessibility.md) | 13 | 11 | 24 | 23 | 1 | 21/24 | 11 |
+| [Avatar](https://github.com/mui/material-ui/blob/master/packages/mui-material/src/Avatar/accessibility.md) | 5 | 6 | 11 | 9 | 2 | 6/11 | 2 |
+| [Button](https://github.com/mui/material-ui/blob/master/packages/mui-material/src/Button/accessibility.md) | 15 | 12 | 27 | 23 | 4 | 20/27 | 11 |
+| [Checkbox](https://github.com/mui/material-ui/blob/master/packages/mui-material/src/Checkbox/accessibility.md) | 14 | 11 | 25 | 23 | 2 | 22/25 | 11 |
+| [LinearProgress](https://github.com/mui/material-ui/blob/master/packages/mui-material/src/LinearProgress/accessibility.md) | 6 | 5 | 11 | 8 | 3 | 6/11 | 1 |
+| [Radio](https://github.com/mui/material-ui/blob/master/packages/mui-material/src/Radio/accessibility.md) | 14 | 11 | 25 | 23 | 2 | 23/25 | 11 |
+| [RadioGroup](https://github.com/mui/material-ui/blob/master/packages/mui-material/src/RadioGroup/accessibility.md) | 6 | 1 | 7 | 7 | 0 | 4/7 | 2 |
+| [Switch](https://github.com/mui/material-ui/blob/master/packages/mui-material/src/Switch/accessibility.md) | 14 | 11 | 25 | 23 | 2 | 23/25 | 11 |
+| [TextField](https://github.com/mui/material-ui/blob/master/packages/mui-material/src/TextField/accessibility.md) | 14 | 14 | 28 | 25 | 3 | 24/28 | 12 |
+| [ToggleButton](https://github.com/mui/material-ui/blob/master/packages/mui-material/src/ToggleButton/accessibility.md) | 13 | 11 | 24 | 20 | 4 | 22/24 | 11 |
+| [ToggleButtonGroup](https://github.com/mui/material-ui/blob/master/packages/mui-material/src/ToggleButtonGroup/accessibility.md) | 2 | 2 | 4 | 4 | 0 | 3/4 | 1 |
+| **12 components** | **127** | **103** | **230** | **207** | **23** | **190/230** | **93** |
+
+
+
+**No component records a ❌ Does Not Support rating for any Level A or AA criterion.**
+
+Rolled up to the library level, where each criterion takes the worst rating any assessed component receives, 32 success criteria are exercised: **25 Supports, 7 Partially Supports, 0 Does Not Support.**
+
+The Level A and AA criteria absent from every row apply at the page or application level — [2.4.1 Bypass Blocks](https://www.w3.org/WAI/WCAG22/Understanding/bypass-blocks), [3.1.1 Language of Page](https://www.w3.org/WAI/WCAG22/Understanding/language-of-page), the [1.2.x Time-based Media](https://www.w3.org/TR/WCAG22/#time-based-media) set — and are the responsibility of the application.
+
+## How to read the ratings
+
+| Symbol | Term | Meaning |
+| :----- | :----------------- | :---------------------------------------------- |
+| ✅ | Supports | Met, with no known defects. |
+| ⚠️ | Partially Supports | Some functionality does not meet the criterion. |
+| ❌ | Does Not Support | Most functionality does not meet the criterion. |
+| ➖ | Not Applicable | The criterion does not apply to this component. |
+
+Each criterion in a component report also records **who is responsible** for meeting it — ● the component, ◐ shared when used as documented, or ○ you, depending on your implementation and surrounding content. This distinction matters more for a component library than for an application, and the reports state it per criterion.
+
+:::info
+An application built with Material UI is not automatically accessible. Material UI supplies accessible building blocks; meeting WCAG for a finished product remains the responsibility of the team building it.
+:::
+
+## Known gaps
+
+Four issues account for almost every ⚠️ rating. Three are properties of the **default theme** rather than of the components' structure, so a theme resolves them today.
+
+| Gap | Criteria | Affected | Workaround |
+| :--------------------------------------------------------------------------------------------- | :------------ | :---------------------------------------------------- | :-------------------------------------------------- |
+| The keyboard focus indicator is the ripple, so `disableRipple`/`disableFocusRipple` removes it | 1.4.11, 2.4.7 | Button, Checkbox, Radio, Switch, Toggle Button | Style `.Mui-focusVisible` in your theme — see below |
+| Some default palette colors fall short of contrast minimums | 1.4.3, 1.4.11 | Avatar, Button, TextField, Toggle Button, and others | Override the affected palette entries |
+| Dynamic state changes are not announced | 4.1.3 | Button (`loading`), LinearProgress, TextField (error) | Render your own `aria-live` region alongside |
+| Indefinite animation cannot be paused | 2.2.2 | LinearProgress (`indeterminate`, `query`, `buffer`) | Show it only while an operation is in flight |
+
+If you disable the ripple, restore a focus indicator in your theme:
+
+```js
+const theme = createTheme({
+ components: {
+ MuiButtonBase: {
+ styleOverrides: {
+ root: {
+ '&.Mui-focusVisible': {
+ outline: '2px solid currentColor',
+ outlineOffset: 2,
+ },
+ },
+ },
+ },
+ },
+});
+```
+
+One genuine defect sits outside those four: Checkbox's `indeterminate` state sets `aria-checked="mixed"` on a native checkbox whose `checked` property is `false` (4.1.2), which ARIA in HTML disallows. It is tracked for a fix.
+
+## Scope and limitations
+
+:::warning
+Read this section before citing the report.
+:::
+
+- **Component coverage is partial.** 12 components are assessed. Widely used components including Select, Autocomplete, Dialog, Menu, Table, Tabs, Slider, Tooltip, Snackbar, and Drawer are **not yet assessed**, and this report says nothing about them.
+- **No assistive-technology testing.** No screen-reader passes have been performed. Criteria that depend on how a specific assistive technology behaves are assessed from the exposed accessibility tree, not from observed behavior.
+- **Level AAA is out of scope**, as it is for a standard VPAT.
+- **Components are rated in isolation**, as rendered with default props and the default theme. Customization, composition, and your surrounding page can change the result.
+- **Evidence strength varies.** See the Verified column above; the shortfall is assessed from the source but not yet re-verified.
+- **This is a self-assessment**, not audited by an independent third party.
+- **Section 508 and EN 301 549 chapters are not yet included.** The WCAG results above supply the substance those chapters incorporate by reference, but the chapter-by-chapter mapping has not been written.
+
+## Feedback
+
+Accessibility defects are treated as bugs. Report them on [GitHub](https://github.com/mui/material-ui/issues/new/choose) with the component, the success criterion, and steps to reproduce.
diff --git a/docs/data/material/getting-started/accessibility/scorecard.json b/docs/data/material/getting-started/accessibility/scorecard.json
new file mode 100644
index 00000000000000..96311d3898fc46
--- /dev/null
+++ b/docs/data/material/getting-started/accessibility/scorecard.json
@@ -0,0 +1,2665 @@
+{
+ "standard": "WCAG 2.2 Level A and AA",
+ "componentCount": 12,
+ "totals": {
+ "supports": 207,
+ "partiallySupports": 23,
+ "doesNotSupport": 0,
+ "notApplicable": 387,
+ "inherited": 43,
+ "flagged": 40
+ },
+ "criteria": [
+ {
+ "number": "1.1.1",
+ "name": "Non-text Content",
+ "level": "A",
+ "conformance": "Supports",
+ "flagged": false,
+ "affected": []
+ },
+ {
+ "number": "1.3.1",
+ "name": "Info and Relationships",
+ "level": "A",
+ "conformance": "Supports",
+ "flagged": false,
+ "affected": []
+ },
+ {
+ "number": "1.3.2",
+ "name": "Meaningful Sequence",
+ "level": "A",
+ "conformance": "Supports",
+ "flagged": true,
+ "affected": []
+ },
+ {
+ "number": "1.3.3",
+ "name": "Sensory Characteristics",
+ "level": "A",
+ "conformance": "Supports",
+ "flagged": true,
+ "affected": []
+ },
+ {
+ "number": "1.3.5",
+ "name": "Identify Input Purpose",
+ "level": "AA",
+ "conformance": "Supports",
+ "flagged": false,
+ "affected": []
+ },
+ {
+ "number": "1.4.1",
+ "name": "Use of Color",
+ "level": "A",
+ "conformance": "Partially Supports",
+ "flagged": true,
+ "affected": ["ToggleButton"]
+ },
+ {
+ "number": "1.4.3",
+ "name": "Contrast (Minimum)",
+ "level": "AA",
+ "conformance": "Partially Supports",
+ "flagged": true,
+ "affected": ["Avatar", "Button", "TextField", "ToggleButton"]
+ },
+ {
+ "number": "1.4.4",
+ "name": "Resize Text",
+ "level": "AA",
+ "conformance": "Supports",
+ "flagged": true,
+ "affected": []
+ },
+ {
+ "number": "1.4.5",
+ "name": "Images of Text",
+ "level": "AA",
+ "conformance": "Supports",
+ "flagged": false,
+ "affected": []
+ },
+ {
+ "number": "1.4.10",
+ "name": "Reflow",
+ "level": "AA",
+ "conformance": "Supports",
+ "flagged": false,
+ "affected": []
+ },
+ {
+ "number": "1.4.11",
+ "name": "Non-text Contrast",
+ "level": "AA",
+ "conformance": "Partially Supports",
+ "flagged": true,
+ "affected": [
+ "AccordionSummary",
+ "Avatar",
+ "Button",
+ "Checkbox",
+ "LinearProgress",
+ "Radio",
+ "Switch",
+ "TextField",
+ "ToggleButton"
+ ]
+ },
+ {
+ "number": "1.4.12",
+ "name": "Text Spacing",
+ "level": "AA",
+ "conformance": "Supports",
+ "flagged": false,
+ "affected": []
+ },
+ {
+ "number": "2.1.1",
+ "name": "Keyboard",
+ "level": "A",
+ "conformance": "Supports",
+ "flagged": false,
+ "affected": []
+ },
+ {
+ "number": "2.1.2",
+ "name": "No Keyboard Trap",
+ "level": "A",
+ "conformance": "Supports",
+ "flagged": false,
+ "affected": []
+ },
+ {
+ "number": "2.2.2",
+ "name": "Pause, Stop, Hide",
+ "level": "A",
+ "conformance": "Partially Supports",
+ "flagged": true,
+ "affected": ["LinearProgress"]
+ },
+ {
+ "number": "2.3.1",
+ "name": "Three Flashes or Below Threshold",
+ "level": "A",
+ "conformance": "Supports",
+ "flagged": true,
+ "affected": []
+ },
+ {
+ "number": "2.4.3",
+ "name": "Focus Order",
+ "level": "A",
+ "conformance": "Supports",
+ "flagged": false,
+ "affected": []
+ },
+ {
+ "number": "2.4.4",
+ "name": "Link Purpose (In Context)",
+ "level": "A",
+ "conformance": "Supports",
+ "flagged": false,
+ "affected": []
+ },
+ {
+ "number": "2.4.6",
+ "name": "Headings and Labels",
+ "level": "AA",
+ "conformance": "Supports",
+ "flagged": true,
+ "affected": []
+ },
+ {
+ "number": "2.4.7",
+ "name": "Focus Visible",
+ "level": "AA",
+ "conformance": "Partially Supports",
+ "flagged": false,
+ "affected": ["Button", "Checkbox", "Radio", "Switch", "ToggleButton"]
+ },
+ {
+ "number": "2.4.11",
+ "name": "Focus Not Obscured (Minimum)",
+ "level": "AA",
+ "conformance": "Supports",
+ "flagged": true,
+ "affected": []
+ },
+ {
+ "number": "2.5.2",
+ "name": "Pointer Cancellation",
+ "level": "A",
+ "conformance": "Supports",
+ "flagged": false,
+ "affected": []
+ },
+ {
+ "number": "2.5.3",
+ "name": "Label in Name",
+ "level": "A",
+ "conformance": "Supports",
+ "flagged": false,
+ "affected": []
+ },
+ {
+ "number": "2.5.8",
+ "name": "Target Size (Minimum)",
+ "level": "AA",
+ "conformance": "Supports",
+ "flagged": false,
+ "affected": []
+ },
+ {
+ "number": "3.2.1",
+ "name": "On Focus",
+ "level": "A",
+ "conformance": "Supports",
+ "flagged": false,
+ "affected": []
+ },
+ {
+ "number": "3.2.2",
+ "name": "On Input",
+ "level": "A",
+ "conformance": "Supports",
+ "flagged": false,
+ "affected": []
+ },
+ {
+ "number": "3.2.4",
+ "name": "Consistent Identification",
+ "level": "AA",
+ "conformance": "Supports",
+ "flagged": true,
+ "affected": []
+ },
+ {
+ "number": "3.3.1",
+ "name": "Error Identification",
+ "level": "A",
+ "conformance": "Supports",
+ "flagged": false,
+ "affected": []
+ },
+ {
+ "number": "3.3.2",
+ "name": "Labels or Instructions",
+ "level": "A",
+ "conformance": "Supports",
+ "flagged": true,
+ "affected": []
+ },
+ {
+ "number": "3.3.3",
+ "name": "Error Suggestion",
+ "level": "AA",
+ "conformance": "Supports",
+ "flagged": false,
+ "affected": []
+ },
+ {
+ "number": "4.1.2",
+ "name": "Name, Role, Value",
+ "level": "A",
+ "conformance": "Supports",
+ "flagged": false,
+ "affected": []
+ },
+ {
+ "number": "4.1.3",
+ "name": "Status Messages",
+ "level": "AA",
+ "conformance": "Partially Supports",
+ "flagged": true,
+ "affected": ["Button", "LinearProgress", "TextField"]
+ }
+ ],
+ "components": [
+ {
+ "component": "Accordion",
+ "counts": {
+ "supports": "19",
+ "partiallySupports": "0",
+ "doesNotSupport": "0",
+ "notApplicable": "31",
+ "inherited": "5",
+ "flagged": "3/19"
+ },
+ "gaps": [
+ "Inherits: ⚠️ **1.4.11 Non-text Contrast** (the summary focus indicator) from [AccordionSummary](../AccordionSummary/accessibility.md)."
+ ],
+ "criteria": [
+ {
+ "number": "1.3.2",
+ "name": "Meaningful Sequence",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Manual",
+ "flagged": true
+ },
+ {
+ "number": "1.3.3",
+ "name": "Sensory Characteristics",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Author",
+ "group": "Manual",
+ "flagged": false
+ },
+ {
+ "number": "1.4.1",
+ "name": "Use of Color",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Manual",
+ "flagged": true
+ },
+ {
+ "number": "1.4.5",
+ "name": "Images of Text",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Author",
+ "group": "Manual",
+ "flagged": false
+ },
+ {
+ "number": "2.4.11",
+ "name": "Focus Not Obscured (Minimum)",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Author",
+ "group": "Manual",
+ "flagged": false
+ },
+ {
+ "number": "3.2.4",
+ "name": "Consistent Identification",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Author",
+ "group": "Manual",
+ "flagged": false
+ },
+ {
+ "number": "1.3.1",
+ "name": "Info and Relationships",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Hybrid",
+ "flagged": false
+ },
+ {
+ "number": "1.4.3",
+ "name": "Contrast (Minimum)",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Hybrid",
+ "flagged": true
+ },
+ {
+ "number": "2.4.6",
+ "name": "Headings and Labels",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Hybrid",
+ "flagged": false
+ },
+ {
+ "number": "4.1.2",
+ "name": "Name, Role, Value",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Hybrid",
+ "flagged": false
+ },
+ {
+ "number": "1.4.4",
+ "name": "Resize Text",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "1.4.10",
+ "name": "Reflow",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "1.4.12",
+ "name": "Text Spacing",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "2.1.1",
+ "name": "Keyboard",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Component",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "2.1.2",
+ "name": "No Keyboard Trap",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Component",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "2.4.3",
+ "name": "Focus Order",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "2.5.2",
+ "name": "Pointer Cancellation",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Component",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "3.2.1",
+ "name": "On Focus",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Component",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "3.2.2",
+ "name": "On Input",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Automated",
+ "flagged": false
+ }
+ ],
+ "summary": {
+ "rated": 19,
+ "levelA": 11,
+ "levelAA": 8,
+ "supports": 19,
+ "partiallySupports": 0,
+ "doesNotSupport": 0,
+ "verified": 16,
+ "automated": 9
+ }
+ },
+ {
+ "component": "AccordionSummary",
+ "counts": {
+ "supports": "23",
+ "partiallySupports": "1",
+ "doesNotSupport": "0",
+ "notApplicable": "31",
+ "flagged": "3/24"
+ },
+ "gaps": [
+ "⚠️ **1.4.11 Non-text Contrast.** The keyboard-focus indicator is only a background tint (`action.focus`), about 1.3:1 against the adjacent `paper` surface, below the 3:1 minimum."
+ ],
+ "criteria": [
+ {
+ "number": "1.3.2",
+ "name": "Meaningful Sequence",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Author",
+ "group": "Manual",
+ "flagged": false
+ },
+ {
+ "number": "1.3.3",
+ "name": "Sensory Characteristics",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Author",
+ "group": "Manual",
+ "flagged": false
+ },
+ {
+ "number": "1.4.1",
+ "name": "Use of Color",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Manual",
+ "flagged": true
+ },
+ {
+ "number": "1.4.5",
+ "name": "Images of Text",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Author",
+ "group": "Manual",
+ "flagged": false
+ },
+ {
+ "number": "1.4.11",
+ "name": "Non-text Contrast",
+ "level": "AA",
+ "conformance": "Partially Supports",
+ "responsibility": "Component",
+ "group": "Manual",
+ "flagged": true
+ },
+ {
+ "number": "2.4.11",
+ "name": "Focus Not Obscured (Minimum)",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Author",
+ "group": "Manual",
+ "flagged": false
+ },
+ {
+ "number": "3.2.4",
+ "name": "Consistent Identification",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Author",
+ "group": "Manual",
+ "flagged": false
+ },
+ {
+ "number": "1.1.1",
+ "name": "Non-text Content",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Hybrid",
+ "flagged": false
+ },
+ {
+ "number": "1.3.1",
+ "name": "Info and Relationships",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Hybrid",
+ "flagged": false
+ },
+ {
+ "number": "1.4.3",
+ "name": "Contrast (Minimum)",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Component",
+ "group": "Hybrid",
+ "flagged": true
+ },
+ {
+ "number": "2.4.6",
+ "name": "Headings and Labels",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Hybrid",
+ "flagged": false
+ },
+ {
+ "number": "2.4.7",
+ "name": "Focus Visible",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Component",
+ "group": "Hybrid",
+ "flagged": false
+ },
+ {
+ "number": "4.1.2",
+ "name": "Name, Role, Value",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Hybrid",
+ "flagged": false
+ },
+ {
+ "number": "1.4.4",
+ "name": "Resize Text",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "1.4.10",
+ "name": "Reflow",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "1.4.12",
+ "name": "Text Spacing",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "2.1.1",
+ "name": "Keyboard",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Component",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "2.1.2",
+ "name": "No Keyboard Trap",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Component",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "2.4.3",
+ "name": "Focus Order",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "2.5.2",
+ "name": "Pointer Cancellation",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Component",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "2.5.3",
+ "name": "Label in Name",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "2.5.8",
+ "name": "Target Size (Minimum)",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Component",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "3.2.1",
+ "name": "On Focus",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Component",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "3.2.2",
+ "name": "On Input",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Automated",
+ "flagged": false
+ }
+ ],
+ "summary": {
+ "rated": 24,
+ "levelA": 13,
+ "levelAA": 11,
+ "supports": 23,
+ "partiallySupports": 1,
+ "doesNotSupport": 0,
+ "verified": 21,
+ "automated": 11
+ }
+ },
+ {
+ "component": "Avatar",
+ "counts": {
+ "supports": "9",
+ "partiallySupports": "2",
+ "doesNotSupport": "0",
+ "notApplicable": "44",
+ "flagged": "5/11"
+ },
+ "gaps": [
+ "⚠️ **1.4.3 Contrast (Minimum).** Default letter and fallback avatars render white text on `grey[400]` (about 1.9:1), and the `deepOrange[500]` example is 3.16:1, both below 4.5:1; arbitrary `stringToColor` backgrounds are unguaranteed.",
+ "⚠️ **1.4.11 Non-text Contrast.** Meaningful icon-child avatars use the default white-on-`grey[400]` (1.9:1) or low-contrast author backgrounds (for example `green[500]` 2.78:1), below the 3:1 minimum for graphical objects."
+ ],
+ "criteria": [
+ {
+ "number": "1.3.2",
+ "name": "Meaningful Sequence",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Author",
+ "group": "Manual",
+ "flagged": true
+ },
+ {
+ "number": "1.3.3",
+ "name": "Sensory Characteristics",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Author",
+ "group": "Manual",
+ "flagged": true
+ },
+ {
+ "number": "1.4.4",
+ "name": "Resize Text",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Component",
+ "group": "Manual",
+ "flagged": true
+ },
+ {
+ "number": "1.4.5",
+ "name": "Images of Text",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Manual",
+ "flagged": false
+ },
+ {
+ "number": "1.1.1",
+ "name": "Non-text Content",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Manual",
+ "flagged": false
+ },
+ {
+ "number": "1.3.1",
+ "name": "Info and Relationships",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Manual",
+ "flagged": false
+ },
+ {
+ "number": "1.4.1",
+ "name": "Use of Color",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Manual",
+ "flagged": true
+ },
+ {
+ "number": "1.4.3",
+ "name": "Contrast (Minimum)",
+ "level": "AA",
+ "conformance": "Partially Supports",
+ "responsibility": "Shared",
+ "group": "Manual",
+ "flagged": false
+ },
+ {
+ "number": "1.4.11",
+ "name": "Non-text Contrast",
+ "level": "AA",
+ "conformance": "Partially Supports",
+ "responsibility": "Shared",
+ "group": "Manual",
+ "flagged": true
+ },
+ {
+ "number": "1.4.10",
+ "name": "Reflow",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Component",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "1.4.12",
+ "name": "Text Spacing",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Component",
+ "group": "Automated",
+ "flagged": false
+ }
+ ],
+ "summary": {
+ "rated": 11,
+ "levelA": 5,
+ "levelAA": 6,
+ "supports": 9,
+ "partiallySupports": 2,
+ "doesNotSupport": 0,
+ "verified": 6,
+ "automated": 2
+ }
+ },
+ {
+ "component": "Button",
+ "counts": {
+ "supports": "23",
+ "partiallySupports": "4",
+ "doesNotSupport": "0",
+ "notApplicable": "28",
+ "flagged": "7/27"
+ },
+ "gaps": [
+ "⚠️ **1.4.3 Contrast (Minimum).** `info` and `warning` buttons fall short of 4.5:1 in every variant.",
+ "⚠️ **1.4.11 Non-text Contrast.** Focus-indicator, border, and icon contrast are untested; `disableRipple`/`disableFocusRipple` remove the `text`/`outlined` focus indicator, and `disableElevation` removes the `contained` one.",
+ "⚠️ **2.4.7 Focus Visible.** `disableRipple`/`disableFocusRipple` remove the `text`/`outlined` focus indicator; `contained` loses its indicator only when `disableElevation` is combined with them.",
+ "⚠️ **4.1.3 Status Messages.** The `loading` state adds no live region, so the change may go unannounced."
+ ],
+ "criteria": [
+ {
+ "number": "1.3.2",
+ "name": "Meaningful Sequence",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Author",
+ "group": "Manual",
+ "flagged": true
+ },
+ {
+ "number": "1.3.3",
+ "name": "Sensory Characteristics",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Author",
+ "group": "Manual",
+ "flagged": true
+ },
+ {
+ "number": "1.4.5",
+ "name": "Images of Text",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Author",
+ "group": "Manual",
+ "flagged": false
+ },
+ {
+ "number": "2.4.11",
+ "name": "Focus Not Obscured (Minimum)",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Author",
+ "group": "Manual",
+ "flagged": true
+ },
+ {
+ "number": "3.2.4",
+ "name": "Consistent Identification",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Author",
+ "group": "Manual",
+ "flagged": true
+ },
+ {
+ "number": "4.1.3",
+ "name": "Status Messages",
+ "level": "AA",
+ "conformance": "Partially Supports",
+ "responsibility": "Shared",
+ "group": "Manual",
+ "flagged": true
+ },
+ {
+ "number": "1.1.1",
+ "name": "Non-text Content",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Hybrid",
+ "flagged": false
+ },
+ {
+ "number": "1.3.1",
+ "name": "Info and Relationships",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Hybrid",
+ "flagged": false
+ },
+ {
+ "number": "1.4.1",
+ "name": "Use of Color",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Hybrid",
+ "flagged": true
+ },
+ {
+ "number": "1.4.3",
+ "name": "Contrast (Minimum)",
+ "level": "AA",
+ "conformance": "Partially Supports",
+ "responsibility": "Component",
+ "group": "Hybrid",
+ "flagged": false
+ },
+ {
+ "number": "1.4.11",
+ "name": "Non-text Contrast",
+ "level": "AA",
+ "conformance": "Partially Supports",
+ "responsibility": "Component",
+ "group": "Hybrid",
+ "flagged": true
+ },
+ {
+ "number": "2.4.4",
+ "name": "Link Purpose (In Context)",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Hybrid",
+ "flagged": false
+ },
+ {
+ "number": "2.4.6",
+ "name": "Headings and Labels",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Hybrid",
+ "flagged": false
+ },
+ {
+ "number": "2.4.7",
+ "name": "Focus Visible",
+ "level": "AA",
+ "conformance": "Partially Supports",
+ "responsibility": "Component",
+ "group": "Hybrid",
+ "flagged": false
+ },
+ {
+ "number": "3.3.2",
+ "name": "Labels or Instructions",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Hybrid",
+ "flagged": false
+ },
+ {
+ "number": "4.1.2",
+ "name": "Name, Role, Value",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Hybrid",
+ "flagged": false
+ },
+ {
+ "number": "1.4.4",
+ "name": "Resize Text",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "1.4.10",
+ "name": "Reflow",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "1.4.12",
+ "name": "Text Spacing",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "2.1.1",
+ "name": "Keyboard",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Component",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "2.1.2",
+ "name": "No Keyboard Trap",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Component",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "2.4.3",
+ "name": "Focus Order",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "2.5.2",
+ "name": "Pointer Cancellation",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Component",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "2.5.3",
+ "name": "Label in Name",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "2.5.8",
+ "name": "Target Size (Minimum)",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Component",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "3.2.1",
+ "name": "On Focus",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Component",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "3.2.2",
+ "name": "On Input",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Automated",
+ "flagged": false
+ }
+ ],
+ "summary": {
+ "rated": 27,
+ "levelA": 15,
+ "levelAA": 12,
+ "supports": 23,
+ "partiallySupports": 4,
+ "doesNotSupport": 0,
+ "verified": 20,
+ "automated": 11
+ }
+ },
+ {
+ "component": "Checkbox",
+ "counts": {
+ "supports": "23",
+ "partiallySupports": "2",
+ "doesNotSupport": "0",
+ "notApplicable": "30",
+ "flagged": "3/25"
+ },
+ "gaps": [
+ "⚠️ **1.4.11 Non-text Contrast.** The default checkmark icons clear 3:1 (`warning` is the tightest at 3.11:1). The keyboard focus indicator is untested. `disableRipple`/`disableFocusRipple` or custom icons can drop below 3:1 — a faint custom unchecked box can be about 1.1:1 against the page.",
+ "⚠️ **2.4.7 Focus Visible.** `disableRipple`/`disableFocusRipple` removes the default focus indicator (the focus ripple). None remains unless the author adds `.Mui-focusVisible` styling or enables the `theme.focusVisible` ring, which draws on the icon and does not depend on the ripple."
+ ],
+ "criteria": [
+ {
+ "number": "1.3.2",
+ "name": "Meaningful Sequence",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Author",
+ "group": "Manual",
+ "flagged": false
+ },
+ {
+ "number": "1.3.3",
+ "name": "Sensory Characteristics",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Author",
+ "group": "Manual",
+ "flagged": false
+ },
+ {
+ "number": "1.4.5",
+ "name": "Images of Text",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Author",
+ "group": "Manual",
+ "flagged": false
+ },
+ {
+ "number": "2.4.11",
+ "name": "Focus Not Obscured (Minimum)",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Author",
+ "group": "Manual",
+ "flagged": false
+ },
+ {
+ "number": "3.2.4",
+ "name": "Consistent Identification",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Author",
+ "group": "Manual",
+ "flagged": false
+ },
+ {
+ "number": "1.1.1",
+ "name": "Non-text Content",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Hybrid",
+ "flagged": false
+ },
+ {
+ "number": "1.3.1",
+ "name": "Info and Relationships",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Hybrid",
+ "flagged": false
+ },
+ {
+ "number": "1.4.1",
+ "name": "Use of Color",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Hybrid",
+ "flagged": true
+ },
+ {
+ "number": "1.4.3",
+ "name": "Contrast (Minimum)",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Hybrid",
+ "flagged": false
+ },
+ {
+ "number": "1.4.11",
+ "name": "Non-text Contrast",
+ "level": "AA",
+ "conformance": "Partially Supports",
+ "responsibility": "Component",
+ "group": "Hybrid",
+ "flagged": true
+ },
+ {
+ "number": "2.4.6",
+ "name": "Headings and Labels",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Hybrid",
+ "flagged": false
+ },
+ {
+ "number": "2.4.7",
+ "name": "Focus Visible",
+ "level": "AA",
+ "conformance": "Partially Supports",
+ "responsibility": "Component",
+ "group": "Hybrid",
+ "flagged": false
+ },
+ {
+ "number": "3.3.2",
+ "name": "Labels or Instructions",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Hybrid",
+ "flagged": true
+ },
+ {
+ "number": "4.1.2",
+ "name": "Name, Role, Value",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Hybrid",
+ "flagged": false
+ },
+ {
+ "number": "1.4.4",
+ "name": "Resize Text",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "1.4.10",
+ "name": "Reflow",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "1.4.12",
+ "name": "Text Spacing",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "2.1.1",
+ "name": "Keyboard",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Component",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "2.1.2",
+ "name": "No Keyboard Trap",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Component",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "2.4.3",
+ "name": "Focus Order",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "2.5.2",
+ "name": "Pointer Cancellation",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Component",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "2.5.3",
+ "name": "Label in Name",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "2.5.8",
+ "name": "Target Size (Minimum)",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "3.2.1",
+ "name": "On Focus",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Component",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "3.2.2",
+ "name": "On Input",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Automated",
+ "flagged": false
+ }
+ ],
+ "summary": {
+ "rated": 25,
+ "levelA": 14,
+ "levelAA": 11,
+ "supports": 23,
+ "partiallySupports": 2,
+ "doesNotSupport": 0,
+ "verified": 22,
+ "automated": 11
+ }
+ },
+ {
+ "component": "LinearProgress",
+ "counts": {
+ "supports": "8",
+ "partiallySupports": "3",
+ "doesNotSupport": "0",
+ "notApplicable": "44",
+ "flagged": "5/11"
+ },
+ "gaps": [
+ "⚠️ **1.4.11 Non-text Contrast.** The fill-vs-track boundary falls below `3:1` for most palette colors in light mode, including the default `primary` (about `2.7:1`); in dark mode only `error` (`2.77:1`) falls short.",
+ "⚠️ **2.2.2 Pause, Stop, Hide.** The `indeterminate`, `query`, and `buffer` variants animate indefinitely with no built-in pause, stop, or hide control.",
+ "⚠️ **4.1.3 Status Messages.** The `progressbar` role is not a live region, so `value` changes are not announced unless the surrounding application adds one."
+ ],
+ "criteria": [
+ {
+ "number": "1.4.1",
+ "name": "Use of Color",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Component",
+ "group": "Manual",
+ "flagged": true
+ },
+ {
+ "number": "1.3.3",
+ "name": "Sensory Characteristics",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Author",
+ "group": "Manual",
+ "flagged": false
+ },
+ {
+ "number": "1.4.11",
+ "name": "Non-text Contrast",
+ "level": "AA",
+ "conformance": "Partially Supports",
+ "responsibility": "Component",
+ "group": "Manual",
+ "flagged": true
+ },
+ {
+ "number": "2.2.2",
+ "name": "Pause, Stop, Hide",
+ "level": "A",
+ "conformance": "Partially Supports",
+ "responsibility": "Shared",
+ "group": "Manual",
+ "flagged": true
+ },
+ {
+ "number": "2.3.1",
+ "name": "Three Flashes or Below Threshold",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Component",
+ "group": "Manual",
+ "flagged": true
+ },
+ {
+ "number": "3.2.4",
+ "name": "Consistent Identification",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Author",
+ "group": "Manual",
+ "flagged": false
+ },
+ {
+ "number": "4.1.3",
+ "name": "Status Messages",
+ "level": "AA",
+ "conformance": "Partially Supports",
+ "responsibility": "Shared",
+ "group": "Manual",
+ "flagged": true
+ },
+ {
+ "number": "1.3.1",
+ "name": "Info and Relationships",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Component",
+ "group": "Hybrid",
+ "flagged": false
+ },
+ {
+ "number": "2.4.6",
+ "name": "Headings and Labels",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Hybrid",
+ "flagged": false
+ },
+ {
+ "number": "4.1.2",
+ "name": "Name, Role, Value",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Hybrid",
+ "flagged": false
+ },
+ {
+ "number": "1.4.10",
+ "name": "Reflow",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Automated",
+ "flagged": false
+ }
+ ],
+ "summary": {
+ "rated": 11,
+ "levelA": 6,
+ "levelAA": 5,
+ "supports": 8,
+ "partiallySupports": 3,
+ "doesNotSupport": 0,
+ "verified": 6,
+ "automated": 1
+ }
+ },
+ {
+ "component": "Radio",
+ "counts": {
+ "supports": "23",
+ "partiallySupports": "2",
+ "doesNotSupport": "0",
+ "notApplicable": "30",
+ "flagged": "2/25"
+ },
+ "gaps": [
+ "⚠️ **1.4.11 Non-text Contrast.** The default dot and circle clear 3:1 (`warning` is the tightest at 3.11:1), but the keyboard focus indicator is untested and `disableRipple`/`disableFocusRipple` or custom icons can drop below 3:1 (the `CustomizedRadios` unchecked circle is about 1.1:1 against the page).",
+ "⚠️ **2.4.7 Focus Visible.** `disableRipple`/`disableFocusRipple` removes the focus ripple, leaving none unless the author adds `.Mui-focusVisible` styling."
+ ],
+ "criteria": [
+ {
+ "number": "1.3.2",
+ "name": "Meaningful Sequence",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Author",
+ "group": "Manual",
+ "flagged": false
+ },
+ {
+ "number": "1.3.3",
+ "name": "Sensory Characteristics",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Author",
+ "group": "Manual",
+ "flagged": false
+ },
+ {
+ "number": "1.4.5",
+ "name": "Images of Text",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Author",
+ "group": "Manual",
+ "flagged": false
+ },
+ {
+ "number": "2.4.11",
+ "name": "Focus Not Obscured (Minimum)",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Author",
+ "group": "Manual",
+ "flagged": false
+ },
+ {
+ "number": "3.2.4",
+ "name": "Consistent Identification",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Author",
+ "group": "Manual",
+ "flagged": false
+ },
+ {
+ "number": "3.3.2",
+ "name": "Labels or Instructions",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Author",
+ "group": "Manual",
+ "flagged": false
+ },
+ {
+ "number": "1.1.1",
+ "name": "Non-text Content",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Hybrid",
+ "flagged": false
+ },
+ {
+ "number": "1.3.1",
+ "name": "Info and Relationships",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Hybrid",
+ "flagged": false
+ },
+ {
+ "number": "1.4.1",
+ "name": "Use of Color",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Hybrid",
+ "flagged": true
+ },
+ {
+ "number": "1.4.3",
+ "name": "Contrast (Minimum)",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Hybrid",
+ "flagged": false
+ },
+ {
+ "number": "1.4.11",
+ "name": "Non-text Contrast",
+ "level": "AA",
+ "conformance": "Partially Supports",
+ "responsibility": "Component",
+ "group": "Hybrid",
+ "flagged": true
+ },
+ {
+ "number": "2.4.6",
+ "name": "Headings and Labels",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Hybrid",
+ "flagged": false
+ },
+ {
+ "number": "2.4.7",
+ "name": "Focus Visible",
+ "level": "AA",
+ "conformance": "Partially Supports",
+ "responsibility": "Component",
+ "group": "Hybrid",
+ "flagged": false
+ },
+ {
+ "number": "4.1.2",
+ "name": "Name, Role, Value",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Hybrid",
+ "flagged": false
+ },
+ {
+ "number": "1.4.4",
+ "name": "Resize Text",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "1.4.10",
+ "name": "Reflow",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "1.4.12",
+ "name": "Text Spacing",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "2.1.1",
+ "name": "Keyboard",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Component",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "2.1.2",
+ "name": "No Keyboard Trap",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Component",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "2.4.3",
+ "name": "Focus Order",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "2.5.2",
+ "name": "Pointer Cancellation",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Component",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "2.5.3",
+ "name": "Label in Name",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "2.5.8",
+ "name": "Target Size (Minimum)",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "3.2.1",
+ "name": "On Focus",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Component",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "3.2.2",
+ "name": "On Input",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Automated",
+ "flagged": false
+ }
+ ],
+ "summary": {
+ "rated": 25,
+ "levelA": 14,
+ "levelAA": 11,
+ "supports": 23,
+ "partiallySupports": 2,
+ "doesNotSupport": 0,
+ "verified": 23,
+ "automated": 11
+ }
+ },
+ {
+ "component": "RadioGroup",
+ "counts": {
+ "supports": "7",
+ "partiallySupports": "0",
+ "doesNotSupport": "0",
+ "notApplicable": "30",
+ "inherited": "18",
+ "flagged": "3/7"
+ },
+ "gaps": [],
+ "criteria": [
+ {
+ "number": "1.4.1",
+ "name": "Use of Color",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Manual",
+ "flagged": true
+ },
+ {
+ "number": "1.3.1",
+ "name": "Info and Relationships",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Hybrid",
+ "flagged": false
+ },
+ {
+ "number": "2.4.6",
+ "name": "Headings and Labels",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Hybrid",
+ "flagged": true
+ },
+ {
+ "number": "3.3.2",
+ "name": "Labels or Instructions",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Hybrid",
+ "flagged": true
+ },
+ {
+ "number": "4.1.2",
+ "name": "Name, Role, Value",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Hybrid",
+ "flagged": false
+ },
+ {
+ "number": "2.1.1",
+ "name": "Keyboard",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Component",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "2.4.3",
+ "name": "Focus Order",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Component",
+ "group": "Automated",
+ "flagged": false
+ }
+ ],
+ "summary": {
+ "rated": 7,
+ "levelA": 6,
+ "levelAA": 1,
+ "supports": 7,
+ "partiallySupports": 0,
+ "doesNotSupport": 0,
+ "verified": 4,
+ "automated": 2
+ }
+ },
+ {
+ "component": "Switch",
+ "counts": {
+ "supports": "23",
+ "partiallySupports": "2",
+ "doesNotSupport": "0",
+ "notApplicable": "30",
+ "flagged": "2/25"
+ },
+ "gaps": [
+ "⚠️ **1.4.11 Non-text Contrast.** In light mode the thumb and track stay under 3:1. The off-state white thumb is about 2.7:1 on the gray track, and the track is about 2.7:1 on the page. Each checked color measures 1.8:1 to 2.6:1 thumb-on-track. The focus indicator is untested, and `disableRipple` removes it.",
+ "⚠️ **2.4.7 Focus Visible.** `disableRipple`/`disableFocusRipple` removes the default focus indicator (the focus ripple), leaving none unless the author adds `.Mui-focusVisible` styling."
+ ],
+ "criteria": [
+ {
+ "number": "1.3.2",
+ "name": "Meaningful Sequence",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Author",
+ "group": "Manual",
+ "flagged": false
+ },
+ {
+ "number": "1.3.3",
+ "name": "Sensory Characteristics",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Author",
+ "group": "Manual",
+ "flagged": false
+ },
+ {
+ "number": "1.4.5",
+ "name": "Images of Text",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Author",
+ "group": "Manual",
+ "flagged": false
+ },
+ {
+ "number": "2.4.11",
+ "name": "Focus Not Obscured (Minimum)",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Author",
+ "group": "Manual",
+ "flagged": false
+ },
+ {
+ "number": "3.2.4",
+ "name": "Consistent Identification",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Author",
+ "group": "Manual",
+ "flagged": false
+ },
+ {
+ "number": "3.3.2",
+ "name": "Labels or Instructions",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Author",
+ "group": "Manual",
+ "flagged": false
+ },
+ {
+ "number": "1.1.1",
+ "name": "Non-text Content",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Hybrid",
+ "flagged": false
+ },
+ {
+ "number": "1.3.1",
+ "name": "Info and Relationships",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Hybrid",
+ "flagged": false
+ },
+ {
+ "number": "1.4.1",
+ "name": "Use of Color",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Hybrid",
+ "flagged": true
+ },
+ {
+ "number": "1.4.3",
+ "name": "Contrast (Minimum)",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Hybrid",
+ "flagged": false
+ },
+ {
+ "number": "1.4.11",
+ "name": "Non-text Contrast",
+ "level": "AA",
+ "conformance": "Partially Supports",
+ "responsibility": "Component",
+ "group": "Hybrid",
+ "flagged": true
+ },
+ {
+ "number": "2.4.6",
+ "name": "Headings and Labels",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Hybrid",
+ "flagged": false
+ },
+ {
+ "number": "2.4.7",
+ "name": "Focus Visible",
+ "level": "AA",
+ "conformance": "Partially Supports",
+ "responsibility": "Component",
+ "group": "Hybrid",
+ "flagged": false
+ },
+ {
+ "number": "4.1.2",
+ "name": "Name, Role, Value",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Hybrid",
+ "flagged": false
+ },
+ {
+ "number": "1.4.4",
+ "name": "Resize Text",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "1.4.10",
+ "name": "Reflow",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "1.4.12",
+ "name": "Text Spacing",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "2.1.1",
+ "name": "Keyboard",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Component",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "2.1.2",
+ "name": "No Keyboard Trap",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Component",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "2.4.3",
+ "name": "Focus Order",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "2.5.2",
+ "name": "Pointer Cancellation",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Component",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "2.5.3",
+ "name": "Label in Name",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "2.5.8",
+ "name": "Target Size (Minimum)",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "3.2.1",
+ "name": "On Focus",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Component",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "3.2.2",
+ "name": "On Input",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Automated",
+ "flagged": false
+ }
+ ],
+ "summary": {
+ "rated": 25,
+ "levelA": 14,
+ "levelAA": 11,
+ "supports": 23,
+ "partiallySupports": 2,
+ "doesNotSupport": 0,
+ "verified": 23,
+ "automated": 11
+ }
+ },
+ {
+ "component": "TextField",
+ "counts": {
+ "supports": "25",
+ "partiallySupports": "3",
+ "doesNotSupport": "0",
+ "notApplicable": "27",
+ "flagged": "4/28"
+ },
+ "gaps": [
+ "⚠️ **1.4.3 Contrast (Minimum).** The placeholder (about 2.55:1), the focused `warning` label (3.11:1), and the focused color labels on the filled surface (`primary` 4.04:1) fall short of 4.5:1.",
+ "⚠️ **1.4.11 Non-text Contrast.** The default `outlined` resting border (`rgba(0, 0, 0, 0.23)`, about 1.74:1) is below 3:1; the `filled` underline (about 3.03:1) clears it only marginally.",
+ "⚠️ **4.1.3 Status Messages.** A dynamically shown error is associated to the input but is not a live region, so it may go unannounced when focus is elsewhere."
+ ],
+ "criteria": [
+ {
+ "number": "1.3.2",
+ "name": "Meaningful Sequence",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Author",
+ "group": "Manual",
+ "flagged": false
+ },
+ {
+ "number": "1.3.3",
+ "name": "Sensory Characteristics",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Author",
+ "group": "Manual",
+ "flagged": false
+ },
+ {
+ "number": "1.4.5",
+ "name": "Images of Text",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Author",
+ "group": "Manual",
+ "flagged": false
+ },
+ {
+ "number": "1.4.11",
+ "name": "Non-text Contrast",
+ "level": "AA",
+ "conformance": "Partially Supports",
+ "responsibility": "Component",
+ "group": "Manual",
+ "flagged": true
+ },
+ {
+ "number": "2.4.7",
+ "name": "Focus Visible",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Component",
+ "group": "Manual",
+ "flagged": false
+ },
+ {
+ "number": "2.4.11",
+ "name": "Focus Not Obscured (Minimum)",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Author",
+ "group": "Manual",
+ "flagged": false
+ },
+ {
+ "number": "3.2.4",
+ "name": "Consistent Identification",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Author",
+ "group": "Manual",
+ "flagged": false
+ },
+ {
+ "number": "3.3.3",
+ "name": "Error Suggestion",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Author",
+ "group": "Manual",
+ "flagged": false
+ },
+ {
+ "number": "4.1.3",
+ "name": "Status Messages",
+ "level": "AA",
+ "conformance": "Partially Supports",
+ "responsibility": "Shared",
+ "group": "Manual",
+ "flagged": true
+ },
+ {
+ "number": "1.3.1",
+ "name": "Info and Relationships",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Hybrid",
+ "flagged": false
+ },
+ {
+ "number": "1.3.5",
+ "name": "Identify Input Purpose",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Author",
+ "group": "Hybrid",
+ "flagged": false
+ },
+ {
+ "number": "1.4.1",
+ "name": "Use of Color",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Hybrid",
+ "flagged": true
+ },
+ {
+ "number": "1.4.3",
+ "name": "Contrast (Minimum)",
+ "level": "AA",
+ "conformance": "Partially Supports",
+ "responsibility": "Component",
+ "group": "Hybrid",
+ "flagged": false
+ },
+ {
+ "number": "2.4.6",
+ "name": "Headings and Labels",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Hybrid",
+ "flagged": false
+ },
+ {
+ "number": "3.3.2",
+ "name": "Labels or Instructions",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Hybrid",
+ "flagged": true
+ },
+ {
+ "number": "4.1.2",
+ "name": "Name, Role, Value",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Hybrid",
+ "flagged": false
+ },
+ {
+ "number": "1.4.4",
+ "name": "Resize Text",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "1.4.10",
+ "name": "Reflow",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "1.4.12",
+ "name": "Text Spacing",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "2.1.1",
+ "name": "Keyboard",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Component",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "2.1.2",
+ "name": "No Keyboard Trap",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Component",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "2.4.3",
+ "name": "Focus Order",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "2.5.2",
+ "name": "Pointer Cancellation",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Component",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "2.5.3",
+ "name": "Label in Name",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "2.5.8",
+ "name": "Target Size (Minimum)",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Component",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "3.2.1",
+ "name": "On Focus",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Component",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "3.2.2",
+ "name": "On Input",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "3.3.1",
+ "name": "Error Identification",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Automated",
+ "flagged": false
+ }
+ ],
+ "summary": {
+ "rated": 28,
+ "levelA": 14,
+ "levelAA": 14,
+ "supports": 25,
+ "partiallySupports": 3,
+ "doesNotSupport": 0,
+ "verified": 24,
+ "automated": 12
+ }
+ },
+ {
+ "component": "ToggleButton",
+ "counts": {
+ "supports": "20",
+ "partiallySupports": "4",
+ "doesNotSupport": "0",
+ "notApplicable": "31",
+ "flagged": "2/24"
+ },
+ "gaps": [
+ "⚠️ **1.4.1 Use of Color.** For the color variants (`primary`, `error`, `info`, `success`), the selected and unselected labels are near-identical in grayscale lightness, so the pressed state is conveyed almost entirely by hue.",
+ "⚠️ **1.4.3 Contrast (Minimum).** When selected, the `primary`, `error`, `info`, and `warning` labels (their `color.main` text over the tinted selected background) fall short of 4.5:1.",
+ "⚠️ **1.4.11 Non-text Contrast.** The focus indicator is the ripple; `disableRipple`/`disableFocusRipple` remove it, leaving no focus indicator. The selected-state fill is untested for 3:1.",
+ "⚠️ **2.4.7 Focus Visible.** `disableRipple`/`disableFocusRipple` remove the only keyboard focus indicator; the Toggle Button has no box-shadow fallback."
+ ],
+ "criteria": [
+ {
+ "number": "1.3.2",
+ "name": "Meaningful Sequence",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Author",
+ "group": "Manual",
+ "flagged": false
+ },
+ {
+ "number": "1.3.3",
+ "name": "Sensory Characteristics",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Author",
+ "group": "Manual",
+ "flagged": false
+ },
+ {
+ "number": "1.4.5",
+ "name": "Images of Text",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Author",
+ "group": "Manual",
+ "flagged": false
+ },
+ {
+ "number": "2.4.11",
+ "name": "Focus Not Obscured (Minimum)",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Author",
+ "group": "Manual",
+ "flagged": false
+ },
+ {
+ "number": "3.2.4",
+ "name": "Consistent Identification",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Author",
+ "group": "Manual",
+ "flagged": false
+ },
+ {
+ "number": "1.1.1",
+ "name": "Non-text Content",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Hybrid",
+ "flagged": false
+ },
+ {
+ "number": "1.3.1",
+ "name": "Info and Relationships",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Hybrid",
+ "flagged": false
+ },
+ {
+ "number": "1.4.1",
+ "name": "Use of Color",
+ "level": "A",
+ "conformance": "Partially Supports",
+ "responsibility": "Component",
+ "group": "Hybrid",
+ "flagged": true
+ },
+ {
+ "number": "1.4.3",
+ "name": "Contrast (Minimum)",
+ "level": "AA",
+ "conformance": "Partially Supports",
+ "responsibility": "Component",
+ "group": "Hybrid",
+ "flagged": false
+ },
+ {
+ "number": "1.4.11",
+ "name": "Non-text Contrast",
+ "level": "AA",
+ "conformance": "Partially Supports",
+ "responsibility": "Component",
+ "group": "Hybrid",
+ "flagged": true
+ },
+ {
+ "number": "2.4.6",
+ "name": "Headings and Labels",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Hybrid",
+ "flagged": false
+ },
+ {
+ "number": "2.4.7",
+ "name": "Focus Visible",
+ "level": "AA",
+ "conformance": "Partially Supports",
+ "responsibility": "Component",
+ "group": "Hybrid",
+ "flagged": false
+ },
+ {
+ "number": "4.1.2",
+ "name": "Name, Role, Value",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Hybrid",
+ "flagged": false
+ },
+ {
+ "number": "1.4.4",
+ "name": "Resize Text",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "1.4.10",
+ "name": "Reflow",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "1.4.12",
+ "name": "Text Spacing",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "2.1.1",
+ "name": "Keyboard",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Component",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "2.1.2",
+ "name": "No Keyboard Trap",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Component",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "2.4.3",
+ "name": "Focus Order",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "2.5.2",
+ "name": "Pointer Cancellation",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Component",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "2.5.3",
+ "name": "Label in Name",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "2.5.8",
+ "name": "Target Size (Minimum)",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Component",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "3.2.1",
+ "name": "On Focus",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Component",
+ "group": "Automated",
+ "flagged": false
+ },
+ {
+ "number": "3.2.2",
+ "name": "On Input",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Automated",
+ "flagged": false
+ }
+ ],
+ "summary": {
+ "rated": 24,
+ "levelA": 13,
+ "levelAA": 11,
+ "supports": 20,
+ "partiallySupports": 4,
+ "doesNotSupport": 0,
+ "verified": 22,
+ "automated": 11
+ }
+ },
+ {
+ "component": "ToggleButtonGroup",
+ "counts": {
+ "supports": "4",
+ "partiallySupports": "0",
+ "doesNotSupport": "0",
+ "notApplicable": "31",
+ "inherited": "20",
+ "flagged": "1/4"
+ },
+ "gaps": [],
+ "criteria": [
+ {
+ "number": "1.3.1",
+ "name": "Info and Relationships",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Manual",
+ "flagged": false
+ },
+ {
+ "number": "2.4.6",
+ "name": "Headings and Labels",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Manual",
+ "flagged": true
+ },
+ {
+ "number": "4.1.2",
+ "name": "Name, Role, Value",
+ "level": "A",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Manual",
+ "flagged": false
+ },
+ {
+ "number": "1.4.10",
+ "name": "Reflow",
+ "level": "AA",
+ "conformance": "Supports",
+ "responsibility": "Shared",
+ "group": "Automated",
+ "flagged": false
+ }
+ ],
+ "summary": {
+ "rated": 4,
+ "levelA": 2,
+ "levelAA": 2,
+ "supports": 4,
+ "partiallySupports": 0,
+ "doesNotSupport": 0,
+ "verified": 3,
+ "automated": 1
+ }
+ }
+ ]
+}
diff --git a/docs/data/material/pages.ts b/docs/data/material/pages.ts
index f98fc7ea8c8a92..74d3b61f8c65a8 100644
--- a/docs/data/material/pages.ts
+++ b/docs/data/material/pages.ts
@@ -17,6 +17,7 @@ const pages: MuiPage[] = [
{ pathname: '/material-ui/getting-started/learn' },
{ pathname: '/material-ui/getting-started/design-resources' },
{ pathname: '/material-ui/getting-started/faq', title: 'FAQs' },
+ { pathname: '/material-ui/getting-started/accessibility' },
{ pathname: '/material-ui/getting-started/supported-components' },
{ pathname: '/material-ui/getting-started/supported-platforms' },
{ pathname: '/material-ui/getting-started/support' },
diff --git a/docs/pages/material-ui/getting-started/accessibility.js b/docs/pages/material-ui/getting-started/accessibility.js
new file mode 100644
index 00000000000000..a13a6b59e091dc
--- /dev/null
+++ b/docs/pages/material-ui/getting-started/accessibility.js
@@ -0,0 +1,6 @@
+import { MarkdownDocs } from '@mui/internal-core-docs/MarkdownDocs';
+import * as pageProps from 'docs/data/material/getting-started/accessibility/accessibility.md?muiMarkdown';
+
+export default function Page() {
+ return ;
+}
diff --git a/package.json b/package.json
index d48cc8c9bba8a6..00e0609d2a29ff 100644
--- a/package.json
+++ b/package.json
@@ -17,6 +17,8 @@
"release:build": "lerna run --concurrency 8 --no-private build --skip-nx-cache",
"release:changelog": "node scripts/releaseChangelog.mjs",
"release:pack": "tsx scripts/releasePack.mts",
+ "a11y:scorecard": "node scripts/a11yScorecard.mjs",
+ "a11y:scorecard:check": "node scripts/a11yScorecard.mjs --check",
"docs:api": "rimraf --glob ./docs/pages/**/api-docs ./docs/pages/**/api && pnpm docs:api:build",
"docs:api:build": "tsx ./scripts/buildApiDocs/index.ts",
"docs:llms:build": "rimraf --glob ./docs/public/material-ui/ && tsx ./scripts/buildLlmsDocs/index.ts --projectSettings ./packages-internal/api-docs-builder-core/materialUi/projectSettings.ts",
diff --git a/packages/mui-material/src/AccordionSummary/accessibility.md b/packages/mui-material/src/AccordionSummary/accessibility.md
index df4cf6c6628e95..aab74a88a720f8 100644
--- a/packages/mui-material/src/AccordionSummary/accessibility.md
+++ b/packages/mui-material/src/AccordionSummary/accessibility.md
@@ -10,7 +10,7 @@ This is the item-level report for the accordion header button. The root `/accessibility.md` rates every applicable success criterion, and records how it is tested and who is responsible. That file is written by hand — it cannot be generated, because most criteria need human judgment.
+
+### The proof
+
+Three kinds of test, none of which writes anything into a report:
+
+| Kind | Where | Covers |
+| :---------------------- | :------------------------------------------------------- | :----------------------------------------------------------------------------------------- |
+| Unit tests | `/.test.js`, named `it('2.1.1 …')` | Behavior: keyboard operation, focus order, pointer cancellation, accessible naming |
+| axe-core | The docs demos, inside the Playwright loop | The mechanical layer: ARIA, labels, text contrast, target size |
+| Playwright layout suite | `test/regressions/index.test.js` | What axe has no rule for: reflow at 320px, 200% text size, the WCAG text-spacing overrides |
+
+axe results are written to `docs/data/material/components/{slug}/{slug}.a11y.json` and committed, so a change that alters them fails CI. **Those files are a tripwire, not a data source** — nothing downstream reads them.
+
+### The rollup
+
+`pnpm a11y:scorecard` reads every `/accessibility.md` and regenerates three things:
+
+- the [Reports](#reports) table below
+- the summary table on the public [accessibility conformance page](../../../docs/data/material/getting-started/accessibility/accessibility.md), between its `scorecard` markers
+- `docs/data/material/getting-started/accessibility/scorecard.json`, the machine-readable rollup
+
+None of those numbers are typed by hand. Edit the reports and re-run the command.
+
+### What CI enforces
+
+| Job | Check |
+| :----------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `test_unit` | The unit tests pass. |
+| `test_regressions` | axe and the layout suite pass, and the committed `*.a11y.json` still match. |
+| `test_static` | `pnpm a11y:scorecard:check` — the generated tables are current, and no criterion is rated ⚙️ Automated while still flagged `🚩` or without citing the test or axe rule that proves it. |
+
+That last check is the link between claim and proof. It is a **citation** check, not a mechanical trace: it verifies the entry names its evidence, not that the named test genuinely proves the criterion. That judgment stays with the reviewer.
+
## Reports
-| Component | ✅ Supports | ⚠️ Partially Supports | ❌ Does Not Support | ➖ Not Applicable |
-| :-------------------------------------------------------- | :---------- | :-------------------- | :------------------ | :---------------- |
-| [Accordion](./Accordion/accessibility.md) | 19 | 0 | 0 | 31 |
-| [AccordionSummary](./AccordionSummary/accessibility.md) | 23 | 1 | 0 | 31 |
-| [Avatar](./Avatar/accessibility.md) | 9 | 2 | 0 | 44 |
-| [Button](./Button/accessibility.md) | 23 | 4 | 0 | 28 |
-| [Checkbox](./Checkbox/accessibility.md) | 23 | 2 | 0 | 30 |
-| [LinearProgress](./LinearProgress/accessibility.md) | 8 | 3 | 0 | 44 |
-| [Radio](./Radio/accessibility.md) | 23 | 2 | 0 | 30 |
-| [RadioGroup](./RadioGroup/accessibility.md) | 7 | 0 | 0 | 30 |
-| [Switch](./Switch/accessibility.md) | 23 | 2 | 0 | 30 |
-| [TextField](./TextField/accessibility.md) | 25 | 3 | 0 | 27 |
-| [ToggleButton](./ToggleButton/accessibility.md) | 20 | 4 | 0 | 31 |
-| [ToggleButtonGroup](./ToggleButtonGroup/accessibility.md) | 4 | 0 | 0 | 31 |
+Generated by `pnpm a11y:scorecard` from the count table at the top of each
+component report. Edit the reports, not this table.
+
+
+
+| Component | ✅ Supports | ⚠️ Partially Supports | ❌ Does Not Support | ➖ Not Applicable | 🚩 Flagged |
+| :-------------------------------------------------------- | :---------- | :-------------------- | :------------------ | :---------------- | :--------- |
+| [Accordion](./Accordion/accessibility.md) | 19 | 0 | 0 | 31 | 3/19 |
+| [AccordionSummary](./AccordionSummary/accessibility.md) | 23 | 1 | 0 | 31 | 3/24 |
+| [Avatar](./Avatar/accessibility.md) | 9 | 2 | 0 | 44 | 5/11 |
+| [Button](./Button/accessibility.md) | 23 | 4 | 0 | 28 | 7/27 |
+| [Checkbox](./Checkbox/accessibility.md) | 23 | 2 | 0 | 30 | 3/25 |
+| [LinearProgress](./LinearProgress/accessibility.md) | 8 | 3 | 0 | 44 | 5/11 |
+| [Radio](./Radio/accessibility.md) | 23 | 2 | 0 | 30 | 2/25 |
+| [RadioGroup](./RadioGroup/accessibility.md) | 7 | 0 | 0 | 30 | 3/7 |
+| [Switch](./Switch/accessibility.md) | 23 | 2 | 0 | 30 | 2/25 |
+| [TextField](./TextField/accessibility.md) | 25 | 3 | 0 | 27 | 4/28 |
+| [ToggleButton](./ToggleButton/accessibility.md) | 20 | 4 | 0 | 31 | 2/24 |
+| [ToggleButtonGroup](./ToggleButtonGroup/accessibility.md) | 4 | 0 | 0 | 31 | 1/4 |
+| **12 components** | **207** | **23** | **0** | **387** | **40** |
+
+
+
+The same rollup feeds the public [accessibility conformance page](../../../docs/data/material/getting-started/accessibility/accessibility.md), which restates these results for procurement in VPAT form.
diff --git a/packages/mui-material/src/manual-testing.md b/packages/mui-material/src/manual-testing.md
new file mode 100644
index 00000000000000..ab6488449a9550
--- /dev/null
+++ b/packages/mui-material/src/manual-testing.md
@@ -0,0 +1,178 @@
+# Manual accessibility checks
+
+Generated by `pnpm a11y:scorecard`. Edit the component reports, not this file.
+
+The accessibility checks a person still has to make by eye when changing a component.
+Anything not listed here is covered by a test — see [How it works](./accessibility.md#how-it-works).
+
+Two things are deliberately left out: criteria a deterministic test already proves
+(⚙️ Automated in the reports), and criteria that depend on the application rather than
+the component (○ Author).
+
+| Marker | Meaning |
+| :----- | :---------------------------------------------------------------- |
+| 🔍 | No automation. Check it by hand. |
+| 🔁 | Automation catches regressions; confirm the judgment still holds. |
+
+## What to re-check, by kind of change
+
+Run the rows matching what you touched, for the component you touched.
+
+| If your change touches… | Re-check |
+| :----------------------------------- | :------------------------------------------------------------------------------------------------------------------------------ |
+| Styling, theme, or palette | 1.4.1 Use of Color; 1.4.3 Contrast (Minimum); 1.4.4 Resize Text; 1.4.5 Images of Text; 1.4.11 Non-text Contrast |
+| DOM structure, roles, or ARIA | 1.1.1 Non-text Content; 1.3.1 Info and Relationships; 1.3.2 Meaningful Sequence; 4.1.2 Name, Role, Value; 4.1.3 Status Messages |
+| Keyboard, focus, or pointer handling | 2.4.4 Link Purpose (In Context); 2.4.6 Headings and Labels; 2.4.7 Focus Visible |
+| Labels, errors, or validation | 3.3.2 Labels or Instructions |
+| Motion or timing | 2.2.2 Pause, Stop, Hide |
+| Other | 2.3.1 Three Flashes or Below Threshold |
+
+## Accordion
+
+6 checks · full procedures in [`Accordion/accessibility.md`](./Accordion/accessibility.md)
+
+- [ ] 🔍 **1.3.2 Meaningful Sequence** — the header is announced before its panel content.
+- [ ] 🔍 **1.4.1 Use of Color** — the state stays distinguishable without color.
+- [ ] 🔁 **1.3.1 Info and Relationships** — the header is exposed as a heading and the panel as a region named by it.
+- [ ] 🔁 **1.4.3 Contrast (Minimum)** — at least 4.5:1 for the summary label and panel text. Disabled summaries are exempt.
+- [ ] 🔁 **2.4.6 Headings and Labels** — every heading describes its section.
+- [ ] 🔁 **4.1.2 Name, Role, Value** — state, role, and the header-to-region name are all exposed.
+
+## AccordionSummary
+
+8 checks · full procedures in [`AccordionSummary/accessibility.md`](./AccordionSummary/accessibility.md)
+
+- [ ] 🔍 **1.4.1 Use of Color** — the open and closed states stay distinguishable without color.
+- [ ] 🔍 **1.4.11 Non-text Contrast** — the focus indicator and the icon are each at least 3:1. The focus indicator is the known shortfall.
+- [ ] 🔁 **1.1.1 Non-text Content** — every summary's announced name matches its section, and the chevron is silent.
+- [ ] 🔁 **1.3.1 Info and Relationships** — role and state match the visual presentation.
+- [ ] 🔁 **1.4.3 Contrast (Minimum)** — at least 4.5:1 for the label text. Disabled summaries are exempt.
+- [ ] 🔁 **2.4.6 Headings and Labels** — every label describes its section, not a vague "Details".
+- [ ] 🔁 **2.4.7 Focus Visible** — every keyboard-focused summary shows a visible indicator.
+- [ ] 🔁 **4.1.2 Name, Role, Value** — name, role, and state are correct for the native and non-native summaries.
+
+## Avatar
+
+7 checks · full procedures in [`Avatar/accessibility.md`](./Avatar/accessibility.md)
+
+- [ ] 🔍 **1.4.4 Resize Text** — initials and fallback text stay fully visible at 200% page zoom. The container scales with the page.
+- [ ] 🔍 **1.4.5 Images of Text** — avatar initials and fallback are real text; the component renders no image of text.
+- [ ] 🔍 **1.1.1 Non-text Content** — every informative avatar exposes a text alternative (`img` `alt` or an author-provided label); decorative and no-image avatars are silent. The component does its part; an informative avatar with no `alt` is an authoring failure.
+- [ ] 🔍 **1.3.1 Info and Relationships** — the image-to-name relationship is programmatically available via native `img` and `alt`.
+- [ ] 🔍 **1.4.1 Use of Color** — no information conveyed by the avatar is lost in grayscale; any color-coded meaning an author adds is paired with a non-color cue.
+- [ ] 🔍 **1.4.3 Contrast (Minimum)** — all letter and fallback text meets `4.5:1` (or `3:1` if it's sized to qualify as large text). The default gray letter avatar, the `deepOrange[500]` example, and arbitrary `stringToColor` backgrounds do not meet this without author color overrides.
+- [ ] 🔍 **1.4.11 Non-text Contrast** — any icon that conveys meaning meets `3:1` against its background; the decorative container shape and `Person` placeholder are exempt, and the boundary stays visible in forced-colors mode.
+
+## Button
+
+11 checks · full procedures in [`Button/accessibility.md`](./Button/accessibility.md)
+
+- [ ] 🔍 **4.1.3 Status Messages** — the change is announced without the user moving focus to it. It is not, because the component adds no live region; wrap the status in `role="status"` to fix it.
+- [ ] 🔁 **1.1.1 Non-text Content** — every button's announced name matches its purpose, and decorative icons are silent.
+- [ ] 🔁 **1.3.1 Info and Relationships** — role and state match the visual presentation for every variant.
+- [ ] 🔁 **1.4.1 Use of Color** — meaning/purpose of the Button can be understood without color.
+- [ ] 🔁 **1.4.3 Contrast (Minimum)** — at least `4.5:1`, or `3:1` for large text, in the resting, hover, and active states. Disabled is exempt; `info` and `warning` are the known failures.
+- [ ] 🔁 **1.4.11 Non-text Contrast** — border, focus indicator, and any meaningful icon are each at least `3:1`. Disabled and purely decorative parts are exempt.
+- [ ] 🔁 **2.4.4 Link Purpose (In Context)** — a user can tell where the link goes. Replace vague labels like "Learn more" or "click here".
+- [ ] 🔁 **2.4.6 Headings and Labels** — every label describes its action ("Submit order", not "OK").
+- [ ] 🔁 **2.4.7 Focus Visible** — every keyboard-focused button shows a visible indicator, including under `disableRipple`, `disableFocusRipple`, and `disableElevation`.
+- [ ] 🔁 **3.3.2 Labels or Instructions** — the label clearly tells the user what to upload, not just "Upload".
+- [ ] 🔁 **4.1.2 Name, Role, Value** — name, role, and state are correct for every variant, and state changes are announced.
+
+## Checkbox
+
+9 checks · full procedures in [`Checkbox/accessibility.md`](./Checkbox/accessibility.md)
+
+- [ ] 🔁 **1.1.1 Non-text Content** — every checkbox exposes a non-empty accessible name and the checkmark icon stays `aria-hidden`.
+- [ ] 🔁 **1.3.1 Info and Relationships** — role, states, label association, and group name are programmatically determinable, and any helper/error text is tied to the control via author-supplied `aria-describedby`.
+- [ ] 🔁 **1.4.1 Use of Color** — the three states are distinguishable by shape, and any error state is conveyed by more than color.
+- [ ] 🔁 **1.4.3 Contrast (Minimum)** — label and helper/error text meet `4.5:1` (`3:1` for large text) against the actual background.
+- [ ] 🔁 **1.4.11 Non-text Contrast** — the indicator in every active state (unchecked outline, checked fill, indeterminate dash) and the focus indicator are `3:1` against adjacent colors; disabled is exempt.
+- [ ] 🔁 **2.4.6 Headings and Labels** — every provided label and legend describes its purpose.
+- [ ] 🔁 **2.4.7 Focus Visible** — every keyboard-focused checkbox shows a visible indicator, including `disableRipple` via author-supplied styles. Today a bare `disableRipple` checkbox shows none.
+- [ ] 🔁 **3.3.2 Labels or Instructions** — every checkbox has a label or instruction presented to all users, via `FormControlLabel`, adjacent text, or clear context.
+- [ ] 🔁 **4.1.2 Name, Role, Value** — the role, the checked/unchecked/mixed/disabled state with change notification, and an author-supplied accessible name are all programmatically determinable.
+
+## LinearProgress
+
+8 checks · full procedures in [`LinearProgress/accessibility.md`](./LinearProgress/accessibility.md)
+
+- [ ] 🔍 **1.4.1 Use of Color**
+- [ ] 🔍 **1.4.11 Non-text Contrast** — the fill-vs-track contrast is at least `3:1`. In light mode `primary`, `error`, `warning`, `info`, and `success` fail (only `secondary` passes); in dark mode only `error` fails.
+- [ ] 🔍 **2.2.2 Pause, Stop, Hide** — the user can pause, stop, or hide the motion, or it stops within five seconds. The component supplies no such control; a full-viewport (essential) loader, or a bar removed once loading finishes, is what keeps it conformant.
+- [ ] 🔍 **2.3.1 Three Flashes or Below Threshold** — no part flashes more than three times per second.
+- [ ] 🔍 **4.1.3 Status Messages** — the change is announced without the user moving focus to it. It is not by default; add a polite live region in the application to convey it.
+- [ ] 🔁 **1.3.1 Info and Relationships** — role and value match the variant.
+- [ ] 🔁 **2.4.6 Headings and Labels** — every name describes its operation.
+- [ ] 🔁 **4.1.2 Name, Role, Value** — name, role, and value are correct for every variant.
+
+## Radio
+
+8 checks · full procedures in [`Radio/accessibility.md`](./Radio/accessibility.md)
+
+- [ ] 🔁 **1.1.1 Non-text Content** — every radio exposes a non-empty accessible name and the dot and circle stay `aria-hidden`.
+- [ ] 🔁 **1.3.1 Info and Relationships** — role, state, and label association are programmatically determinable, and any helper or error text is tied to the control via author-supplied `aria-describedby`.
+- [ ] 🔁 **1.4.1 Use of Color** — checked and unchecked are distinguishable by the dot, and any error state is conveyed by more than color.
+- [ ] 🔁 **1.4.3 Contrast (Minimum)** — label and helper or error text meet `4.5:1` (`3:1` for large text) against the actual background.
+- [ ] 🔁 **1.4.11 Non-text Contrast** — the dot and circle in every active state and the focus indicator are `3:1` against adjacent colors; disabled is exempt.
+- [ ] 🔁 **2.4.6 Headings and Labels** — every provided label describes its purpose.
+- [ ] 🔁 **2.4.7 Focus Visible** — every keyboard-focused radio shows a visible indicator, including `disableRipple` via author-supplied styles.
+- [ ] 🔁 **4.1.2 Name, Role, Value** — the role, the checked or unchecked and disabled state with change notification, and an author-supplied accessible name are all programmatically determinable.
+
+## RadioGroup
+
+5 checks · full procedures in [`RadioGroup/accessibility.md`](./RadioGroup/accessibility.md)
+
+- [ ] 🔍 **1.4.1 Use of Color** — the selected option is distinguishable by the dot, and any error state is conveyed by more than color.
+- [ ] 🔁 **1.3.1 Info and Relationships** — the radios are exposed as one `radiogroup`, and the name and any description are set by the author.
+- [ ] 🔁 **2.4.6 Headings and Labels** — every group label describes the question it asks.
+- [ ] 🔁 **3.3.2 Labels or Instructions** — every group has a visible label or instruction. A group with no visible label fails.
+- [ ] 🔁 **4.1.2 Name, Role, Value** — the group exposes its `radiogroup` role, an author-supplied name, and the current selected value with change notification.
+
+## Switch
+
+8 checks · full procedures in [`Switch/accessibility.md`](./Switch/accessibility.md)
+
+- [ ] 🔁 **1.1.1 Non-text Content** — every switch exposes a non-empty accessible name.
+- [ ] 🔁 **1.3.1 Info and Relationships** — role, state, label association, and group name are programmatically determinable, and any helper text is tied to the control via author-supplied `aria-describedby`.
+- [ ] 🔁 **1.4.1 Use of Color** — on and off are distinguishable by thumb position, and any error state is conveyed by more than color.
+- [ ] 🔁 **1.4.3 Contrast (Minimum)** — label and helper text meet `4.5:1` (`3:1` for large text) against the actual background.
+- [ ] 🔁 **1.4.11 Non-text Contrast** — the thumb against the track, the track against the page, and the focus indicator are each at least `3:1`; disabled is exempt. Today the default thumb and track are the known failures.
+- [ ] 🔁 **2.4.6 Headings and Labels** — every provided label and legend describes its purpose.
+- [ ] 🔁 **2.4.7 Focus Visible** — every keyboard-focused switch shows a visible indicator, including `disableRipple` via author-supplied styles. Today a bare `disableRipple` switch shows none.
+- [ ] 🔁 **4.1.2 Name, Role, Value** — the role, the on/off state with change notification, and an author-supplied accessible name are all programmatically determinable.
+
+## TextField
+
+9 checks · full procedures in [`TextField/accessibility.md`](./TextField/accessibility.md)
+
+- [ ] 🔍 **1.4.11 Non-text Contrast** — the resting boundary and the focus indicator are each `3:1` against adjacent colors. Today the resting `outlined` border is the known failure.
+- [ ] 🔍 **2.4.7 Focus Visible** — every keyboard-focused field shows a visible indicator.
+- [ ] 🔍 **4.1.3 Status Messages** — the error is announced without the user moving focus to it.
+- [ ] 🔁 **1.3.1 Info and Relationships** — label, description, required, and invalid relationships are programmatically determinable.
+- [ ] 🔁 **1.4.1 Use of Color** — the error state is conveyed by more than color (the `helperText` message), not the red alone.
+- [ ] 🔁 **1.4.3 Contrast (Minimum)** — label, value, placeholder, and error text meet `4.5:1` (`3:1` for large text) against the actual background. The placeholder, focused `warning`, and filled-surface error text are the known failures.
+- [ ] 🔁 **2.4.6 Headings and Labels** — every provided label describes its field.
+- [ ] 🔁 **3.3.2 Labels or Instructions** — each field has a visible label or instruction. A placeholder-only or `aria-label`-only field fails.
+- [ ] 🔁 **4.1.2 Name, Role, Value** — name, role, value, and the required and invalid states are programmatically determinable.
+
+## ToggleButton
+
+8 checks · full procedures in [`ToggleButton/accessibility.md`](./ToggleButton/accessibility.md)
+
+- [ ] 🔁 **1.1.1 Non-text Content** — every toggle's announced name matches its purpose, and decorative icons are silent.
+- [ ] 🔁 **1.3.1 Info and Relationships** — role and state match the visual presentation for every variant.
+- [ ] 🔁 **1.4.1 Use of Color** — the control's meaning survives without color. The `standard` selected state stays distinguishable; the color variants do not, since their pressed cue is hue-dominant.
+- [ ] 🔁 **1.4.3 Contrast (Minimum)** — at least 4.5:1, or 3:1 for large text, in the resting and hover states. Disabled is exempt; selected `primary`, `error`, `info`, and `warning` are the known failures.
+- [ ] 🔁 **1.4.11 Non-text Contrast** — the focus indicator and any meaningful icon are each at least 3:1, and the pressed state stays identifiable. Disabled parts are exempt.
+- [ ] 🔁 **2.4.6 Headings and Labels** — every label describes its action ("Bold", not "B").
+- [ ] 🔁 **2.4.7 Focus Visible** — every keyboard-focused toggle shows a visible indicator, including under `disableRipple` and `disableFocusRipple`.
+- [ ] 🔁 **4.1.2 Name, Role, Value** — name, role, and state are correct for every variant, and state changes are announced.
+
+## ToggleButtonGroup
+
+3 checks · full procedures in [`ToggleButtonGroup/accessibility.md`](./ToggleButtonGroup/accessibility.md)
+
+- [ ] 🔍 **1.3.1 Info and Relationships** — the toggles are exposed as one group, named when the author supplies a label.
+- [ ] 🔍 **2.4.6 Headings and Labels** — every group label describes the set of toggles it contains.
+- [ ] 🔍 **4.1.2 Name, Role, Value** — the group exposes its role and author-supplied name, and each toggle's pressed state and its changes are announced.
diff --git a/scripts/a11yScorecard.mjs b/scripts/a11yScorecard.mjs
new file mode 100644
index 00000000000000..87ccc0577f78ba
--- /dev/null
+++ b/scripts/a11yScorecard.mjs
@@ -0,0 +1,550 @@
+/* eslint-disable no-console */
+/**
+ * Aggregates the per-component conformance reports into a library-level scorecard.
+ *
+ * Each `packages/mui-material/src//accessibility.md` opens with a
+ * count table rating the component against WCAG 2.2 Level A and AA. This script
+ * parses those reports and rewrites three generated outputs:
+ *
+ * - the `Reports` table in `packages/mui-material/src/accessibility.md`
+ * - the summary table on the public conformance page
+ * - `docs/data/material/getting-started/accessibility/scorecard.json`, the
+ * machine-readable rollup behind both.
+ *
+ * Run with `pnpm a11y:scorecard`; `--check` exits non-zero when either output is
+ * stale, so CI can guard against a report landing without its rollup.
+ */
+import fs from 'fs/promises';
+import path from 'path';
+import { fileURLToPath } from 'url';
+import * as prettier from 'prettier';
+
+const currentDirectory = path.dirname(fileURLToPath(import.meta.url));
+const rootDirectory = path.resolve(currentDirectory, '..');
+const componentsDirectory = path.join(rootDirectory, 'packages/mui-material/src');
+const indexPath = path.join(componentsDirectory, 'accessibility.md');
+const scorecardPath = path.join(
+ rootDirectory,
+ 'docs/data/material/getting-started/accessibility/scorecard.json',
+);
+const docsPagePath = path.join(
+ rootDirectory,
+ 'docs/data/material/getting-started/accessibility/accessibility.md',
+);
+const checklistPath = path.join(componentsDirectory, 'manual-testing.md');
+
+const START_MARKER = '';
+const END_MARKER = '';
+
+/**
+ * Rows are `|