@verndale/accessibility-standards 1.0.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (171) hide show
  1. package/OPERATING.md +3 -1
  2. package/README.md +4 -0
  3. package/bin/accessibility-standards.mjs +1 -1
  4. package/dist/manifest.json +159 -101
  5. package/dist/profiles/ai-orchestration/coverage-manifest.json +724 -68
  6. package/dist/profiles/ai-orchestration/implementation/accessibility.md +825 -10
  7. package/dist/profiles/ai-orchestration/pattern-contracts.json +1015 -343
  8. package/dist/profiles/ai-orchestration/patterns/accordion.md +14 -0
  9. package/dist/profiles/ai-orchestration/patterns/alert.md +14 -0
  10. package/dist/profiles/ai-orchestration/patterns/carousel.md +14 -0
  11. package/dist/profiles/ai-orchestration/patterns/checkbox.md +27 -0
  12. package/dist/profiles/ai-orchestration/patterns/combobox.md +14 -0
  13. package/dist/profiles/ai-orchestration/patterns/consequential-submission.md +15 -1
  14. package/dist/profiles/ai-orchestration/patterns/dialog.md +14 -0
  15. package/dist/profiles/ai-orchestration/patterns/disclosure.md +14 -0
  16. package/dist/profiles/ai-orchestration/patterns/dynamic-status.md +14 -0
  17. package/dist/profiles/ai-orchestration/patterns/field.md +15 -0
  18. package/dist/profiles/ai-orchestration/patterns/image.md +14 -0
  19. package/dist/profiles/ai-orchestration/patterns/listbox.md +14 -0
  20. package/dist/profiles/ai-orchestration/patterns/media-player.md +17 -0
  21. package/dist/profiles/ai-orchestration/patterns/menu-button.md +14 -0
  22. package/dist/profiles/ai-orchestration/patterns/menu.md +30 -0
  23. package/dist/profiles/ai-orchestration/patterns/pagination.md +14 -0
  24. package/dist/profiles/ai-orchestration/patterns/popover.md +15 -0
  25. package/dist/profiles/ai-orchestration/patterns/progress.md +15 -0
  26. package/dist/profiles/ai-orchestration/patterns/radio-group.md +27 -0
  27. package/dist/profiles/ai-orchestration/patterns/slider.md +31 -0
  28. package/dist/profiles/ai-orchestration/patterns/spinbutton.md +28 -0
  29. package/dist/profiles/ai-orchestration/patterns/tabs.md +14 -0
  30. package/dist/profiles/ai-orchestration/patterns/tooltip.md +14 -0
  31. package/dist/profiles/ai-orchestration/patterns/tree-view.md +31 -0
  32. package/dist/profiles/ai-orchestration/patterns/validation.md +15 -0
  33. package/dist/profiles/ai-orchestration/review/accessibility.md +21 -6
  34. package/dist/profiles/ai-orchestration/semantics/accessible-authentication.md +13 -0
  35. package/dist/profiles/ai-orchestration/semantics/accessible-name.md +8 -1
  36. package/dist/profiles/ai-orchestration/semantics/alert.md +7 -0
  37. package/dist/profiles/ai-orchestration/semantics/consequential-action.md +6 -1
  38. package/dist/profiles/ai-orchestration/semantics/consistent-help.md +13 -0
  39. package/dist/profiles/ai-orchestration/semantics/data-table.md +7 -1
  40. package/dist/profiles/ai-orchestration/semantics/dragging-alternative.md +13 -0
  41. package/dist/profiles/ai-orchestration/semantics/expanded-state.md +6 -0
  42. package/dist/profiles/ai-orchestration/semantics/focus.initial.md +4 -0
  43. package/dist/profiles/ai-orchestration/semantics/focus.return.md +4 -0
  44. package/dist/profiles/ai-orchestration/semantics/focus.visible.md +8 -1
  45. package/dist/profiles/ai-orchestration/semantics/form-error.md +8 -1
  46. package/dist/profiles/ai-orchestration/semantics/form-label.md +7 -0
  47. package/dist/profiles/ai-orchestration/semantics/form-required.md +7 -0
  48. package/dist/profiles/ai-orchestration/semantics/headings.md +7 -0
  49. package/dist/profiles/ai-orchestration/semantics/keyboard.escape.md +4 -0
  50. package/dist/profiles/ai-orchestration/semantics/keyboard.md +7 -0
  51. package/dist/profiles/ai-orchestration/semantics/landmarks.md +6 -0
  52. package/dist/profiles/ai-orchestration/semantics/live-status.md +7 -1
  53. package/dist/profiles/ai-orchestration/semantics/media-alternatives.md +11 -0
  54. package/dist/profiles/ai-orchestration/semantics/motion-control.md +8 -1
  55. package/dist/profiles/ai-orchestration/semantics/name-role-value.md +6 -1
  56. package/dist/profiles/ai-orchestration/semantics/native-dialog.md +7 -0
  57. package/dist/profiles/ai-orchestration/semantics/native-elements.md +5 -0
  58. package/dist/profiles/ai-orchestration/semantics/non-text-alternative.md +5 -0
  59. package/dist/profiles/ai-orchestration/semantics/redundant-entry.md +13 -0
  60. package/dist/profiles/ai-orchestration/semantics/roles-states-properties.md +6 -0
  61. package/dist/profiles/ai-orchestration/semantics/selected-state.md +6 -0
  62. package/dist/profiles/ai-orchestration/semantics/target-size.md +6 -1
  63. package/dist/profiles/ai-orchestration/semantics.json +843 -100
  64. package/dist/profiles/ai-orchestration/testing/accessibility.md +33 -3
  65. package/dist/profiles/ai-orchestration/ui-design-brain-bindings.json +836 -0
  66. package/dist/profiles/conductor/a11y-semantics.md +270 -10
  67. package/dist/profiles/conductor/accessibility-quality.md +557 -1
  68. package/dist/profiles/conductor/applicability-matrix.json +270 -230
  69. package/dist/profiles/conductor/coverage-manifest.json +724 -68
  70. package/dist/profiles/conductor/pattern-contracts.json +1015 -343
  71. package/dist/profiles/conductor/patterns/accordion.json +42 -24
  72. package/dist/profiles/conductor/patterns/alert.json +36 -18
  73. package/dist/profiles/conductor/patterns/carousel.json +43 -25
  74. package/dist/profiles/conductor/patterns/checkbox.json +67 -0
  75. package/dist/profiles/conductor/patterns/combobox.json +44 -26
  76. package/dist/profiles/conductor/patterns/consequential-submission.json +41 -22
  77. package/dist/profiles/conductor/patterns/dialog.json +44 -26
  78. package/dist/profiles/conductor/patterns/disclosure.json +40 -22
  79. package/dist/profiles/conductor/patterns/dynamic-status.json +38 -19
  80. package/dist/profiles/conductor/patterns/field.json +58 -22
  81. package/dist/profiles/conductor/patterns/image.json +48 -19
  82. package/dist/profiles/conductor/patterns/listbox.json +42 -24
  83. package/dist/profiles/conductor/patterns/media-player.json +76 -26
  84. package/dist/profiles/conductor/patterns/menu-button.json +41 -23
  85. package/dist/profiles/conductor/patterns/menu.json +78 -0
  86. package/dist/profiles/conductor/patterns/pagination.json +41 -22
  87. package/dist/profiles/conductor/patterns/popover.json +49 -23
  88. package/dist/profiles/conductor/patterns/progress.json +45 -20
  89. package/dist/profiles/conductor/patterns/radio-group.json +69 -0
  90. package/dist/profiles/conductor/patterns/slider.json +84 -0
  91. package/dist/profiles/conductor/patterns/spinbutton.json +74 -0
  92. package/dist/profiles/conductor/patterns/tabs.json +41 -23
  93. package/dist/profiles/conductor/patterns/tooltip.json +38 -20
  94. package/dist/profiles/conductor/patterns/tree-view.json +77 -0
  95. package/dist/profiles/conductor/patterns/validation.json +59 -23
  96. package/dist/profiles/conductor/semantics.json +843 -100
  97. package/dist/profiles/conductor/ui-design-brain-bindings.json +836 -0
  98. package/dist/projection-manifest.json +123 -82
  99. package/dist/requirements-to-implementation.md +8 -0
  100. package/lib/build-manifest.mjs +12 -6
  101. package/lib/build.mjs +21 -7
  102. package/lib/compile-applicability.mjs +131 -10
  103. package/lib/coverage.mjs +20 -0
  104. package/lib/digest.mjs +8 -0
  105. package/lib/index.mjs +1 -1
  106. package/lib/load.mjs +44 -1
  107. package/lib/provenance.mjs +51 -0
  108. package/lib/render.mjs +115 -31
  109. package/lib/sync.mjs +242 -28
  110. package/lib/validate.mjs +557 -24
  111. package/package.json +27 -10
  112. package/profiles/ai-orchestration/profile.json +1 -1
  113. package/profiles/ai-orchestration/templates/patterns/README.md +1 -1
  114. package/profiles/ai-orchestration/templates/review/README.md +1 -1
  115. package/profiles/ai-orchestration/templates/semantics/README.md +1 -1
  116. package/profiles/ai-orchestration/templates/testing/README.md +1 -1
  117. package/profiles/conductor/profile.json +1 -1
  118. package/profiles/conductor/templates/evidence/README.md +1 -1
  119. package/profiles/conductor/templates/patterns/README.md +1 -1
  120. package/profiles/conductor/templates/semantics/README.md +1 -1
  121. package/schemas/consumer-config.schema.json +1 -1
  122. package/schemas/contract.schema.json +1 -0
  123. package/schemas/manifest.schema.json +1 -1
  124. package/schemas/pattern.schema.json +98 -1
  125. package/schemas/profile.schema.json +1 -1
  126. package/schemas/projection-manifest.schema.json +84 -1
  127. package/schemas/semantic.schema.json +26 -1
  128. package/schemas/standards-reference.schema.json +105 -0
  129. package/schemas/ui-design-brain-bindings.schema.json +86 -0
  130. package/schemas/wcag-coverage.schema.json +93 -0
  131. package/src/applicability/facts.yml +27 -1
  132. package/src/applicability/matrix.yml +8 -9
  133. package/src/applicability/ui-design-brain-bindings.yml +196 -0
  134. package/src/contract.yml +1 -0
  135. package/src/coverage/wcag-2.2.yml +68 -0
  136. package/src/patterns/disclosure/accordion.yml +1 -1
  137. package/src/patterns/disclosure/disclosure.yml +1 -1
  138. package/src/patterns/feedback/alert.yml +1 -1
  139. package/src/patterns/feedback/dynamic-status.yml +1 -1
  140. package/src/patterns/feedback/progress.yml +1 -1
  141. package/src/patterns/forms/consequential-submission.yml +1 -1
  142. package/src/patterns/forms/field.yml +1 -1
  143. package/src/patterns/forms/spinbutton.yml +1 -0
  144. package/src/patterns/forms/validation.yml +1 -1
  145. package/src/patterns/media/carousel.yml +1 -1
  146. package/src/patterns/media/image.yml +1 -1
  147. package/src/patterns/media/media-player.yml +1 -1
  148. package/src/patterns/navigation/menu-button.yml +1 -1
  149. package/src/patterns/navigation/menu.yml +1 -0
  150. package/src/patterns/navigation/pagination.yml +1 -1
  151. package/src/patterns/navigation/tabs.yml +1 -1
  152. package/src/patterns/navigation/tree-view.yml +1 -0
  153. package/src/patterns/overlays/dialog.yml +1 -1
  154. package/src/patterns/overlays/popover.yml +1 -1
  155. package/src/patterns/overlays/tooltip.yml +1 -1
  156. package/src/patterns/selection/checkbox.yml +1 -0
  157. package/src/patterns/selection/combobox.yml +1 -1
  158. package/src/patterns/selection/listbox.yml +1 -1
  159. package/src/patterns/selection/radio-group.yml +1 -0
  160. package/src/patterns/selection/slider.yml +1 -0
  161. package/src/semantics/accessible-names.yml +1 -1
  162. package/src/semantics/forms.yml +1 -1
  163. package/src/semantics/headings-landmarks.yml +1 -1
  164. package/src/semantics/keyboard-focus.yml +1 -1
  165. package/src/semantics/live-regions.yml +1 -1
  166. package/src/semantics/media.yml +1 -1
  167. package/src/semantics/native-elements.yml +1 -1
  168. package/src/semantics/roles-states-properties.yml +1 -1
  169. package/src/semantics/tables.yml +1 -1
  170. package/src/semantics/wcag-2.2.yml +1 -0
  171. package/src/sources.yml +1 -1
@@ -1,179 +1,735 @@
1
1
  <!-- GENERATED by @verndale/accessibility-standards; DO NOT EDIT -->
2
+ <!-- package: @verndale/accessibility-standards@3.0.0; profile: conductor@3.0.0; schema: 3; source-digest: 708ac82783bfb5ebcce31e4dada15d8580863f5e37b32d1807adf61e415ed5af; profile-digest: beadcb5fe8151303b3e3241de4fee0ece3be9ff2f4dbdb3a6f93a363b0a2d491 -->
2
3
  # Accessibility quality contract
3
4
 
4
5
  ## pattern.accordion
5
6
 
7
+ Standards:
8
+ - [aria-apg accordion](<https://www.w3.org/WAI/ARIA/apg/patterns/accordion/>) — informative
9
+
6
10
  Requires: semantics.native-elements, semantics.accessible-name, semantics.expanded-state, semantics.keyboard, semantics.focus.visible.
7
11
 
12
+ Activation: `{"contains":{"fact":"component.accessibility_pattern_ids","value":"pattern.accordion"}}`
13
+
14
+ Scope: Grouped disclosure sections.
15
+
8
16
  Behavior:
9
17
  - Toggle only the controlled panel
10
18
  - Preserve DOM and focus order
11
19
 
20
+ Product decisions: single_or_multiple_open.
21
+
22
+ Functional Spec bindings: behavior, states, keyboard.
23
+
24
+ Implementation outcomes: accordion-control, accordion-panel.
25
+
12
26
  Evidence: unit, axe, e2e, human.
13
27
 
14
28
  ## pattern.alert
15
29
 
30
+ Standards:
31
+ - [aria-apg alert](<https://www.w3.org/WAI/ARIA/apg/patterns/alert/>) — informative
32
+
16
33
  Requires: semantics.alert.
17
34
 
35
+ Activation: `{"contains":{"fact":"component.accessibility_pattern_ids","value":"pattern.alert"}}`
36
+
37
+ Scope: Urgent message.
38
+
18
39
  Behavior:
19
40
  - Announce once without moving focus
20
41
 
42
+ Product decisions: urgency.
43
+
44
+ Functional Spec bindings: messaging.
45
+
46
+ Implementation outcomes: alert-announcement.
47
+
21
48
  Evidence: unit, human.
22
49
 
23
50
  ## pattern.carousel
24
51
 
52
+ Standards:
53
+ - [aria-apg carousel](<https://www.w3.org/WAI/ARIA/apg/patterns/carousel/>) — informative
54
+
25
55
  Requires: semantics.accessible-name, semantics.keyboard, semantics.focus.visible, semantics.motion-control, semantics.live-status.
26
56
 
57
+ Activation: `{"contains":{"fact":"component.accessibility_pattern_ids","value":"pattern.carousel"}}`
58
+
59
+ Scope: Rotating content set.
60
+
27
61
  Behavior:
28
62
  - Pause rotation on interaction
29
63
  - Provide named controls and current position
30
64
 
65
+ Product decisions: auto_rotation, looping.
66
+
67
+ Functional Spec bindings: behavior, states, controls.
68
+
69
+ Implementation outcomes: carousel-controls, carousel-rotation.
70
+
71
+ Evidence: unit, axe, e2e, human.
72
+
73
+ ## pattern.checkbox
74
+
75
+ Standards:
76
+ - [aria-apg checkbox](<https://www.w3.org/WAI/ARIA/apg/patterns/checkbox/>) — informative
77
+
78
+ Requires: semantics.accessible-name, semantics.focus.visible, semantics.form-label, semantics.keyboard, semantics.name-role-value, semantics.native-elements, semantics.roles-states-properties.
79
+
80
+ Activation: `{"contains":{"fact":"component.accessibility_pattern_ids","value":"pattern.checkbox"}}`
81
+
82
+ Scope: Standalone, grouped, dual-state, or tri-state checkboxes.
83
+
84
+ Behavior:
85
+ - Use a native checkbox when it provides the required behavior; otherwise expose checkbox semantics and synchronize checked, unchecked, or mixed state
86
+ - Space toggles the focused checkbox without changing unrelated controls
87
+ - Associate logical groups and any relevant descriptions with programmatic group labels
88
+
89
+ Product decisions: dual_or_tri_state, group_labeling, mixed_state_cycle.
90
+
91
+ Functional Spec bindings: fields, states, keyboard.
92
+
93
+ Implementation outcomes: checkbox-group-semantics, checkbox-state-machine.
94
+
31
95
  Evidence: unit, axe, e2e, human.
32
96
 
33
97
  ## pattern.combobox
34
98
 
99
+ Standards:
100
+ - [aria-apg combobox](<https://www.w3.org/WAI/ARIA/apg/patterns/combobox/>) — informative
101
+
35
102
  Requires: semantics.accessible-name, semantics.expanded-state, semantics.selected-state, semantics.keyboard, semantics.live-status.
36
103
 
104
+ Activation: `{"contains":{"fact":"component.accessibility_pattern_ids","value":"pattern.combobox"}}`
105
+
106
+ Scope: Input with selectable popup.
107
+
37
108
  Behavior:
38
109
  - Keyboard controls popup, option, and input independently
39
110
 
111
+ Product decisions: editable, autocomplete, selection_commit.
112
+
113
+ Functional Spec bindings: behavior, states, keyboard.
114
+
115
+ Implementation outcomes: combobox-state-machine.
116
+
40
117
  Evidence: unit, axe, e2e, human.
41
118
 
42
119
  ## pattern.consequential-submission
43
120
 
121
+ Standards:
122
+ - [wcag-2.2 3.3.4](<https://www.w3.org/TR/WCAG22/#error-prevention-legal-financial-data>) (Level AA) — normative
123
+
44
124
  Requires: semantics.consequential-action, semantics.form-error, semantics.keyboard.
45
125
 
126
+ Activation: `{"contains":{"fact":"component.submission_consequence","value":"consequential"}}`
127
+
128
+ Scope: Legal commitments, financial transactions, stored user-controllable data changes, or user test-response submissions.
129
+
46
130
  Behavior:
47
- - Support review, correction, confirmation, or reversal
131
+ - Provide at least one declared safeguard: make the submission reversible; check user-entered data for errors and let the user correct them; or let the user review, confirm, and correct information before finalizing
132
+
133
+ Product decisions: safeguard, reversal_window.
134
+
135
+ Functional Spec bindings: submission, confirmation.
136
+
137
+ Implementation outcomes: submission-safeguard.
48
138
 
49
139
  Evidence: e2e, human.
50
140
 
51
141
  ## pattern.dialog
52
142
 
143
+ Standards:
144
+ - [aria-apg dialog-modal](<https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/>) — informative
145
+
53
146
  Requires: semantics.native-dialog, semantics.accessible-name, semantics.keyboard.escape, semantics.focus.initial, semantics.focus.return.
54
147
 
148
+ Activation: `{"contains":{"fact":"component.accessibility_pattern_ids","value":"pattern.dialog"}}`
149
+
150
+ Scope: Modal and non-modal dialogs.
151
+
55
152
  Behavior:
56
153
  - Manage initial, contained, and return focus
57
154
  - Dismiss topmost dialog with Escape
58
155
 
156
+ Product decisions: modal, initial_focus, dismissal.
157
+
158
+ Functional Spec bindings: behavior, states, focus, keyboard.
159
+
160
+ Implementation outcomes: dialog-semantics, dialog-focus-lifecycle.
161
+
59
162
  Evidence: unit, axe, e2e, human.
60
163
 
61
164
  ## pattern.disclosure
62
165
 
166
+ Standards:
167
+ - [aria-apg disclosure](<https://www.w3.org/WAI/ARIA/apg/patterns/disclosure/>) — informative
168
+
63
169
  Requires: semantics.native-elements, semantics.accessible-name, semantics.expanded-state, semantics.keyboard.
64
170
 
171
+ Activation: `{"contains":{"fact":"component.accessibility_pattern_ids","value":"pattern.disclosure"}}`
172
+
173
+ Scope: Show and hide supplementary content.
174
+
65
175
  Behavior:
66
176
  - Control toggles one region
67
177
 
178
+ Product decisions: initial_state.
179
+
180
+ Functional Spec bindings: behavior, states.
181
+
182
+ Implementation outcomes: disclosure-control.
183
+
68
184
  Evidence: unit, axe, e2e.
69
185
 
70
186
  ## pattern.dynamic-status
71
187
 
188
+ Standards:
189
+ - [wcag-2.2 4.1.3](<https://www.w3.org/TR/WCAG22/#status-messages>) (Level AA) — normative
190
+
72
191
  Requires: semantics.live-status.
73
192
 
193
+ Activation: `{"equals":{"fact":"component.has_dynamic_status","value":true}}`
194
+
195
+ Scope: Asynchronous status message.
196
+
74
197
  Behavior:
75
198
  - Announce meaningful changes once
76
199
 
200
+ Product decisions: announcement_copy.
201
+
202
+ Functional Spec bindings: messaging, states.
203
+
204
+ Implementation outcomes: status-live-region.
205
+
77
206
  Evidence: unit, e2e, human.
78
207
 
79
208
  ## pattern.field
80
209
 
210
+ Standards:
211
+ - [wcag-2.2 3.3.2](<https://www.w3.org/TR/WCAG22/#labels-or-instructions>) (Level A) — normative
212
+ - [wcag-2.2 4.1.2](<https://www.w3.org/TR/WCAG22/#name-role-value>) (Level A) — normative
213
+
81
214
  Requires: semantics.form-label, semantics.form-required, semantics.focus.visible.
82
215
 
216
+ Activation: `{"any":[{"contains":{"fact":"component.accessibility_pattern_ids","value":"pattern.field"}},{"equals":{"fact":"component.has_form_fields","value":true}}]}`
217
+
218
+ Scope: Labeled form input.
219
+
83
220
  Behavior:
84
221
  - Expose label, instructions, and requiredness before interaction
85
222
 
223
+ Product decisions: required, instructions.
224
+
225
+ Functional Spec bindings: fields, requiredness.
226
+
227
+ Implementation outcomes: field-associations.
228
+
86
229
  Evidence: unit, axe, human.
87
230
 
88
231
  ## pattern.image
89
232
 
233
+ Standards:
234
+ - [wcag-2.2 1.1.1](<https://www.w3.org/TR/WCAG22/#non-text-content>) (Level A) — normative
235
+
90
236
  Requires: semantics.non-text-alternative.
91
237
 
238
+ Activation: `{"any":[{"contains":{"fact":"component.accessibility_pattern_ids","value":"pattern.image"}},{"equals":{"fact":"content.has_non_text","value":true}}]}`
239
+
240
+ Scope: Informative, functional, complex, or decorative image.
241
+
92
242
  Behavior:
93
243
  - Alternative follows image purpose
94
244
 
245
+ Product decisions: purpose, long_description.
246
+
247
+ Functional Spec bindings: content.
248
+
249
+ Implementation outcomes: image-alternative.
250
+
95
251
  Evidence: axe, human.
96
252
 
97
253
  ## pattern.listbox
98
254
 
255
+ Standards:
256
+ - [aria-apg listbox](<https://www.w3.org/WAI/ARIA/apg/patterns/listbox/>) — informative
257
+
99
258
  Requires: semantics.accessible-name, semantics.selected-state, semantics.keyboard, semantics.focus.visible.
100
259
 
260
+ Activation: `{"contains":{"fact":"component.accessibility_pattern_ids","value":"pattern.listbox"}}`
261
+
262
+ Scope: Single or multi-select option list.
263
+
101
264
  Behavior:
102
265
  - Arrow keys move active option
103
266
  - Selection follows declared model
104
267
 
268
+ Product decisions: single_or_multi, selection_follows_focus.
269
+
270
+ Functional Spec bindings: behavior, states, keyboard.
271
+
272
+ Implementation outcomes: listbox-keyboard-model.
273
+
105
274
  Evidence: unit, axe, e2e, human.
106
275
 
107
276
  ## pattern.media-player
108
277
 
278
+ Standards:
279
+ - [wcag-2.2 1.2.1](<https://www.w3.org/TR/WCAG22/#audio-only-and-video-only-prerecorded>) (Level A) — normative
280
+ - [wcag-2.2 1.2.2](<https://www.w3.org/TR/WCAG22/#captions-prerecorded>) (Level A) — normative
281
+ - [wcag-2.2 1.2.3](<https://www.w3.org/TR/WCAG22/#audio-description-or-media-alternative-prerecorded>) (Level A) — normative
282
+ - [wcag-2.2 1.2.5](<https://www.w3.org/TR/WCAG22/#audio-description-prerecorded>) (Level AA) — normative
283
+
109
284
  Requires: semantics.media-alternatives, semantics.accessible-name, semantics.keyboard, semantics.focus.visible, semantics.motion-control.
110
285
 
286
+ Activation: `{"any":[{"contains":{"fact":"component.accessibility_pattern_ids","value":"pattern.media-player"}},{"equals":{"fact":"content.has_media","value":true}}]}`
287
+
288
+ Scope: Audio or video playback.
289
+
111
290
  Behavior:
112
291
  - Provide keyboard-operable named controls and required alternatives
113
292
 
293
+ Product decisions: captions, transcript, audio_description, autoplay.
294
+
295
+ Functional Spec bindings: content, controls, behavior.
296
+
297
+ Implementation outcomes: media-alternatives, media-controls.
298
+
114
299
  Evidence: axe, e2e, human.
115
300
 
301
+ ## pattern.menu
302
+
303
+ Standards:
304
+ - [aria-apg menubar](<https://www.w3.org/WAI/ARIA/apg/patterns/menubar/>) — informative
305
+
306
+ Requires: semantics.accessible-name, semantics.expanded-state, semantics.focus.initial, semantics.focus.return, semantics.focus.visible, semantics.keyboard, semantics.keyboard.escape, semantics.roles-states-properties.
307
+
308
+ Activation: `{"contains":{"fact":"component.accessibility_pattern_ids","value":"pattern.menu"}}`
309
+
310
+ Scope: Command menus, submenus, and persistent menubars.
311
+
312
+ Behavior:
313
+ - Expose menu or menubar containers with menuitem, menuitemcheckbox, or menuitemradio children; synchronize submenu expanded state, checkable-item checked state, orientation, and disabled state
314
+ - When a popup menu opens, move focus to its first item; when a persistent menubar receives focus through Tab or Shift+Tab, restore its declared last-focused item or use its first enabled item; Tab and Shift+Tab do not move among items and, from an item, exit the composite and close all open menus
315
+ - For the default horizontal menubar with vertical popup menus, Right and Left move among menubar items, Down opens a submenu and focuses its first item, Up may open it and focus its last item, Down and Up move among popup items, Right opens a child submenu, and Left closes a child submenu and returns focus to its parent item; reverse the declared axes for alternate orientations
316
+ - Enter opens an item's submenu and focuses its first item, or otherwise activates the item and closes the menu; declare whether Space mirrors Enter on plain items, toggles menuitemcheckbox without closing, and checks a menuitemradio while unchecking its group peers without closing
317
+ - Keep disabled menu items focusable but non-activatable, keep separators non-focusable, and apply Home, End, optional type-ahead, and the declared wrapping policy within the current menu or menubar
318
+ - Escape closes the menu containing focus and restores focus to its parent item, menu button, or invoking context
319
+
320
+ Product decisions: entry_focus, focus_strategy, menu_or_menubar, orientation, space_behavior, submenu_model, typeahead, wrap_navigation.
321
+
322
+ Functional Spec bindings: behavior, states, keyboard, focus.
323
+
324
+ Implementation outcomes: menu-composite-focus, menu-keyboard-model, menu-state-model.
325
+
326
+ Evidence: unit, axe, e2e, human.
327
+
116
328
  ## pattern.menu-button
117
329
 
330
+ Standards:
331
+ - [aria-apg menu-button](<https://www.w3.org/WAI/ARIA/apg/patterns/menu-button/>) — informative
332
+
118
333
  Requires: semantics.accessible-name, semantics.expanded-state, semantics.keyboard, semantics.focus.initial, semantics.focus.return.
119
334
 
335
+ Activation: `{"contains":{"fact":"component.accessibility_pattern_ids","value":"pattern.menu-button"}}`
336
+
337
+ Scope: Button opening a command menu.
338
+
120
339
  Behavior:
121
340
  - Open and navigate menu by keyboard
122
341
 
342
+ Product decisions: focus_strategy.
343
+
344
+ Functional Spec bindings: behavior, keyboard, focus.
345
+
346
+ Implementation outcomes: menu-button-keyboard.
347
+
123
348
  Evidence: unit, e2e, human.
124
349
 
125
350
  ## pattern.pagination
126
351
 
352
+ Standards:
353
+ - [wcag-2.2 2.4.4](<https://www.w3.org/TR/WCAG22/#link-purpose-in-context>) (Level A) — normative
354
+
127
355
  Requires: semantics.native-elements, semantics.accessible-name, semantics.landmarks, semantics.focus.visible.
128
356
 
357
+ Activation: `{"contains":{"fact":"component.accessibility_pattern_ids","value":"pattern.pagination"}}`
358
+
359
+ Scope: Paged result navigation.
360
+
129
361
  Behavior:
130
362
  - Expose current page and named navigation
131
363
 
364
+ Product decisions: url_behavior.
365
+
366
+ Functional Spec bindings: states, navigation.
367
+
368
+ Implementation outcomes: pagination-current-page.
369
+
132
370
  Evidence: unit, axe, human.
133
371
 
134
372
  ## pattern.popover
135
373
 
374
+ Standards:
375
+ - [wcag-2.2 2.1.1](<https://www.w3.org/TR/WCAG22/#keyboard>) (Level A) — normative
376
+ - [wcag-2.2 2.4.3](<https://www.w3.org/TR/WCAG22/#focus-order>) (Level A) — normative
377
+
136
378
  Requires: semantics.native-elements, semantics.accessible-name, semantics.keyboard.escape, semantics.focus.return.
137
379
 
380
+ Activation: `{"contains":{"fact":"component.accessibility_pattern_ids","value":"pattern.popover"}}`
381
+
382
+ Scope: Non-modal transient surface.
383
+
138
384
  Behavior:
139
385
  - Dismiss without trapping focus
140
386
 
387
+ Product decisions: dismissal, focus_entry.
388
+
389
+ Functional Spec bindings: behavior, focus.
390
+
391
+ Implementation outcomes: popover-dismissal.
392
+
141
393
  Evidence: unit, e2e, human.
142
394
 
143
395
  ## pattern.progress
144
396
 
397
+ Standards:
398
+ - [wai-aria-1.2 progressbar](<https://www.w3.org/TR/wai-aria-1.2/#progressbar>) — normative
399
+ - [wcag-2.2 4.1.2](<https://www.w3.org/TR/WCAG22/#name-role-value>) (Level A) — normative
400
+
145
401
  Requires: semantics.name-role-value, semantics.live-status.
146
402
 
403
+ Activation: `{"contains":{"fact":"component.accessibility_pattern_ids","value":"pattern.progress"}}`
404
+
405
+ Scope: Determinate or indeterminate progress.
406
+
147
407
  Behavior:
148
408
  - Expose value and completion changes without announcement noise
149
409
 
410
+ Product decisions: determinate.
411
+
412
+ Functional Spec bindings: states, messaging.
413
+
414
+ Implementation outcomes: progress-value.
415
+
150
416
  Evidence: unit, axe, human.
151
417
 
418
+ ## pattern.radio-group
419
+
420
+ Standards:
421
+ - [aria-apg radio](<https://www.w3.org/WAI/ARIA/apg/patterns/radio/>) — informative
422
+
423
+ Requires: semantics.accessible-name, semantics.focus.visible, semantics.form-label, semantics.keyboard, semantics.native-elements, semantics.roles-states-properties.
424
+
425
+ Activation: `{"contains":{"fact":"component.accessibility_pattern_ids","value":"pattern.radio-group"}}`
426
+
427
+ Scope: Mutually exclusive choices presented as a radio group.
428
+
429
+ Behavior:
430
+ - Use native grouped radio inputs when they provide the required behavior; otherwise expose a named radiogroup containing named radio controls with exactly one checked item when selected
431
+ - Use one tab stop for group entry, focusing the checked radio or the first radio when none is checked
432
+ - Outside a toolbar, Space selects the focused radio and arrow keys move focus and selection with wrapping; inside a toolbar, toolbar navigation moves focus without changing selection, while Space or optionally Enter checks the focused radio
433
+
434
+ Product decisions: initial_selection, native_or_custom, toolbar_context, wrap_navigation.
435
+
436
+ Functional Spec bindings: fields, states, keyboard, focus.
437
+
438
+ Implementation outcomes: radio-group-keyboard-model, radio-group-labeling, radio-group-selection-model.
439
+
440
+ Evidence: unit, axe, e2e, human.
441
+
442
+ ## pattern.slider
443
+
444
+ Standards:
445
+ - [aria-apg slider](<https://www.w3.org/WAI/ARIA/apg/patterns/slider/>) — informative
446
+ - [aria-apg slider-multithumb](<https://www.w3.org/WAI/ARIA/apg/patterns/slider-multithumb/>) — informative
447
+
448
+ Requires: semantics.accessible-name, semantics.dragging-alternative, semantics.focus.visible, semantics.keyboard, semantics.name-role-value, semantics.native-elements, semantics.roles-states-properties.
449
+
450
+ Activation: `{"contains":{"fact":"component.accessibility_pattern_ids","value":"pattern.slider"}}`
451
+
452
+ Scope: Single-thumb or multi-thumb bounded range input.
453
+
454
+ Behavior:
455
+ - Use a native input[type=range] for a single-thumb slider when it supplies the required range, step, orientation, labeling, and value presentation; use a custom slider only when native behavior cannot satisfy the declared interaction
456
+ - Expose every focusable thumb as a distinct named slider with synchronized current, minimum, maximum, orientation, and user-friendly value text when the numeric value is insufficient
457
+ - Right and Up increase by one step while Left and Down decrease by one step unless a documented orientation and value presentation makes reversal more intuitive; Home and End move to range bounds, and optional Page Up and Page Down apply the declared larger step
458
+ - Provide an equivalent single-pointer method for every drag operation that does not require dragging, such as track activation or an adjacent value input
459
+ - Keep every thumb in a constant tab order for multi-thumb sliders and update dependent thumb bounds whenever another thumb changes them
460
+ - Verify operation with touch-based assistive technology on target devices before production use
461
+
462
+ Product decisions: direction_mapping, large_step, native_or_custom, orientation, single_or_multi_thumb, step, thumb_constraints, value_text.
463
+
464
+ Functional Spec bindings: fields, states, keyboard, controls.
465
+
466
+ Implementation outcomes: slider-keyboard-model, slider-native-control-selection, slider-range-state, slider-touch-at-compatibility.
467
+
468
+ Evidence: unit, axe, e2e, human.
469
+
470
+ ## pattern.spinbutton
471
+
472
+ Standards:
473
+ - [aria-apg spinbutton](<https://www.w3.org/WAI/ARIA/apg/patterns/spinbutton/>) — informative
474
+
475
+ Requires: semantics.accessible-name, semantics.focus.visible, semantics.form-label, semantics.keyboard, semantics.name-role-value, semantics.native-elements, semantics.roles-states-properties.
476
+
477
+ Activation: `{"contains":{"fact":"component.accessibility_pattern_ids","value":"pattern.spinbutton"}}`
478
+
479
+ Scope: Value input constrained to a discrete set or range, with optional direct text editing.
480
+
481
+ Behavior:
482
+ - Use a native number input when it supplies the required range, step, editing, labeling, and validation behavior; otherwise expose a named spinbutton with synchronized current, minimum, maximum, user-friendly value text, and invalid state when a value is outside the allowed range
483
+ - Keep focus on the spinbutton while Up and Down change its value, Home and End apply known bounds, and optional Page Up and Page Down apply the declared larger step
484
+ - Treat the editable decision as permission for direct text entry, not as whether the spinbutton is adjustable; when direct editing is disabled, the declared increment and decrement controls still change the value and the spinbutton is not exposed as read-only
485
+ - When direct editing is allowed, preserve platform text editing commands and do not intercept keys needed to enter, navigate, select, or modify text
486
+
487
+ Product decisions: editable, large_step, native_or_custom, range_bounds, step, value_text.
488
+
489
+ Functional Spec bindings: fields, states, keyboard, validation.
490
+
491
+ Implementation outcomes: spinbutton-keyboard-model, spinbutton-native-control-selection, spinbutton-range-state, spinbutton-validation.
492
+
493
+ Evidence: unit, axe, e2e, human.
494
+
152
495
  ## pattern.tabs
153
496
 
497
+ Standards:
498
+ - [aria-apg tabs](<https://www.w3.org/WAI/ARIA/apg/patterns/tabs/>) — informative
499
+
154
500
  Requires: semantics.accessible-name, semantics.selected-state, semantics.keyboard, semantics.focus.visible.
155
501
 
502
+ Activation: `{"contains":{"fact":"component.accessibility_pattern_ids","value":"pattern.tabs"}}`
503
+
504
+ Scope: Tabbed interfaces.
505
+
156
506
  Behavior:
157
507
  - Arrow keys move between tabs
158
508
  - Selection and activation follow the documented model
159
509
 
510
+ Product decisions: automatic_or_manual_activation.
511
+
512
+ Functional Spec bindings: behavior, states, keyboard.
513
+
514
+ Implementation outcomes: tabs-keyboard-model.
515
+
160
516
  Evidence: unit, axe, e2e, human.
161
517
 
162
518
  ## pattern.tooltip
163
519
 
520
+ Standards:
521
+ - [aria-apg tooltip](<https://www.w3.org/WAI/ARIA/apg/patterns/tooltip/>) — informative
522
+
164
523
  Requires: semantics.accessible-name, semantics.keyboard.escape.
165
524
 
525
+ Activation: `{"contains":{"fact":"component.accessibility_pattern_ids","value":"pattern.tooltip"}}`
526
+
527
+ Scope: Supplementary description.
528
+
166
529
  Behavior:
167
530
  - Available on hover and focus
168
531
  - Never contains interactive content
169
532
 
533
+ Product decisions: delay.
534
+
535
+ Functional Spec bindings: behavior.
536
+
537
+ Implementation outcomes: tooltip-description.
538
+
170
539
  Evidence: unit, e2e, human.
171
540
 
541
+ ## pattern.tree-view
542
+
543
+ Standards:
544
+ - [aria-apg treeview](<https://www.w3.org/WAI/ARIA/apg/patterns/treeview/>) — informative
545
+
546
+ Requires: semantics.accessible-name, semantics.expanded-state, semantics.focus.visible, semantics.keyboard, semantics.roles-states-properties, semantics.selected-state.
547
+
548
+ Activation: `{"contains":{"fact":"component.accessibility_pattern_ids","value":"pattern.tree-view"}}`
549
+
550
+ Scope: Hierarchical single-select or multi-select tree widgets.
551
+
552
+ Behavior:
553
+ - Expose tree, treeitem, and group relationships, set aria-multiselectable for a multi-select tree, and provide level, position, and set-size metadata when the complete hierarchy is not represented in the DOM
554
+ - On tree entry, focus the selected node or first selected node when one exists and otherwise focus the first node; keep one composite tab stop and keep focus visually distinct from selection
555
+ - In a vertical tree, Right Arrow opens a closed parent without moving focus, moves from an open parent to its first child, and does nothing on an end node; Left Arrow closes an open parent, moves from a closed parent or end node to its parent, and does nothing on a root node that cannot close
556
+ - In a vertical tree, Down Arrow moves to the next visible focusable node and Up Arrow moves to the previous visible focusable node without changing expansion; Home and End move to the first and last visible focusable nodes, Enter performs the node's declared default action, and type-ahead moves to the next matching node
557
+ - For a horizontal tree, remap Down Arrow to the vertical Right Arrow behavior, Right Arrow to vertical Down Arrow, Up Arrow to vertical Left Arrow, and Left Arrow to vertical Up Arrow
558
+ - Keep focus distinct from selection and synchronize expansion and the declared aria-selected or aria-checked state model without exposing both states for the same selection purpose
559
+ - For a multi-select tree using the recommended modifier-free model, navigation does not clear selection, Space toggles selection of the focused node, and declared Shift combinations extend contiguous selection; for the alternative modifier-required model, unmodified navigation selects only the focused node while Control plus an arrow moves focus without changing selection and Control plus Space toggles the focused node
560
+
561
+ Product decisions: focus_strategy, multi_select_keyboard_model, orientation, selection_follows_focus, selection_state, single_or_multi_select, typeahead, virtualization.
562
+
563
+ Functional Spec bindings: behavior, states, keyboard, focus.
564
+
565
+ Implementation outcomes: tree-hierarchy-semantics, tree-keyboard-model, tree-selection-model.
566
+
567
+ Evidence: unit, axe, e2e, human.
568
+
172
569
  ## pattern.validation
173
570
 
571
+ Standards:
572
+ - [wcag-2.2 3.3.1](<https://www.w3.org/TR/WCAG22/#error-identification>) (Level A) — normative
573
+ - [wcag-2.2 3.3.3](<https://www.w3.org/TR/WCAG22/#error-suggestion>) (Level AA) — normative
574
+
174
575
  Requires: semantics.form-error, semantics.live-status, semantics.focus.initial.
175
576
 
577
+ Activation: `{"any":[{"contains":{"fact":"component.accessibility_pattern_ids","value":"pattern.validation"}},{"equals":{"fact":"component.has_validation","value":true}}]}`
578
+
579
+ Scope: Client or server validation.
580
+
176
581
  Behavior:
177
582
  - Identify, associate, summarize, and focus errors deterministically
178
583
 
584
+ Product decisions: validation_timing, error_summary.
585
+
586
+ Functional Spec bindings: validation, messaging, focus.
587
+
588
+ Implementation outcomes: validation-associations, error-summary.
589
+
590
+ Evidence: unit, axe, e2e, human.
591
+
592
+ ## applicability.page-context
593
+
594
+ When: `{"equals":{"fact":"artifact.page_context","value":true}}`
595
+
596
+ Outcomes: semantics.headings, semantics.landmarks.
597
+
598
+ Evidence: axe, human.
599
+
600
+ ## applicability.non-text-content
601
+
602
+ When: `{"equals":{"fact":"content.has_non_text","value":true}}`
603
+
604
+ Outcomes: pattern.image.
605
+
606
+ Evidence: axe, human.
607
+
608
+ ## applicability.media
609
+
610
+ When: `{"equals":{"fact":"content.has_media","value":true}}`
611
+
612
+ Outcomes: pattern.media-player.
613
+
614
+ Evidence: e2e, human.
615
+
616
+ ## applicability.forms
617
+
618
+ When: `{"equals":{"fact":"component.has_form_fields","value":true}}`
619
+
620
+ Outcomes: pattern.field.
621
+
622
+ Evidence: unit, axe.
623
+
624
+ ## applicability.validation
625
+
626
+ When: `{"equals":{"fact":"component.has_validation","value":true}}`
627
+
628
+ Outcomes: pattern.validation.
629
+
179
630
  Evidence: unit, axe, e2e, human.
631
+
632
+ ## applicability.consequential-submission
633
+
634
+ When: `{"contains":{"fact":"component.submission_consequence","value":"consequential"}}`
635
+
636
+ Outcomes: pattern.consequential-submission.
637
+
638
+ Evidence: e2e, human.
639
+
640
+ ## applicability.dynamic-status
641
+
642
+ When: `{"equals":{"fact":"component.has_dynamic_status","value":true}}`
643
+
644
+ Outcomes: pattern.dynamic-status.
645
+
646
+ Evidence: unit, e2e, human.
647
+
648
+ ## applicability.overlays
649
+
650
+ When: `{"any":[{"contains":{"fact":"component.ui_pattern_ids","value":"modal"}},{"contains":{"fact":"component.ui_pattern_ids","value":"popover"}},{"contains":{"fact":"component.ui_pattern_ids","value":"tooltip"}}]}`
651
+
652
+ Outcomes: semantics.keyboard.escape, semantics.focus.return.
653
+
654
+ Evidence: e2e.
655
+
656
+ ## applicability.motion-timing
657
+
658
+ When: `{"equals":{"fact":"interaction.has_motion_or_timing","value":true}}`
659
+
660
+ Outcomes: semantics.motion-control.
661
+
662
+ Evidence: e2e, human.
663
+
664
+ ## applicability.complex-pointer
665
+
666
+ When: `{"equals":{"fact":"interaction.has_complex_pointer","value":true}}`
667
+
668
+ Outcomes: semantics.keyboard.
669
+
670
+ Evidence: e2e, human.
671
+
672
+ ## applicability.dragging-alternative
673
+
674
+ When: `{"equals":{"fact":"interaction.has_dragging","value":true}}`
675
+
676
+ Outcomes: semantics.dragging-alternative.
677
+
678
+ Evidence: e2e, human.
679
+
680
+ ## applicability.target-size
681
+
682
+ When: `{"equals":{"fact":"interaction.has_pointer_targets","value":true}}`
683
+
684
+ Outcomes: semantics.target-size.
685
+
686
+ Evidence: e2e, human.
687
+
688
+ ## applicability.focus-obstruction
689
+
690
+ When: `{"equals":{"fact":"interaction.can_obscure_focus","value":true}}`
691
+
692
+ Outcomes: semantics.focus.visible.
693
+
694
+ Evidence: e2e, human.
695
+
696
+ ## applicability.accessible-authentication
697
+
698
+ When: `{"equals":{"fact":"flow.has_authentication","value":true}}`
699
+
700
+ Outcomes: semantics.accessible-authentication.
701
+
702
+ Evidence: e2e, human.
703
+
704
+ ## applicability.redundant-entry
705
+
706
+ When: `{"equals":{"fact":"flow.repeats_entry","value":true}}`
707
+
708
+ Outcomes: semantics.form-label, semantics.redundant-entry.
709
+
710
+ Evidence: e2e, human.
711
+
712
+ ## applicability.consistent-help
713
+
714
+ When: `{"equals":{"fact":"artifact.has_repeated_help_across_page_set","value":true}}`
715
+
716
+ Outcomes: semantics.consistent-help.
717
+
718
+ Evidence: e2e, human.
719
+
720
+ ## applicability.data-table
721
+
722
+ When: `{"equals":{"fact":"component.has_data_table","value":true}}`
723
+
724
+ Outcomes: semantics.data-table.
725
+
726
+ Evidence: axe, e2e, human.
727
+
728
+ ## Evidence routing
729
+
730
+ Tool availability changes the evidence route, never requirement applicability. A missing required capability is a blocker.
731
+
732
+ - axe: automated rule evidence; capability: axe
733
+ - e2e: keyboard, focus, and integrated behavior; capability: e2e
734
+ - human: judgment, assistive technology, content, and visual evidence; capability: human
735
+ - unit: semantic state and deterministic resolver behavior; capability: unit