@verndale/accessibility-standards 1.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 (148) hide show
  1. package/OPERATING.md +5 -0
  2. package/README.md +22 -0
  3. package/bin/accessibility-standards.mjs +32 -0
  4. package/dist/manifest.json +202 -0
  5. package/dist/profiles/ai-orchestration/coverage-manifest.json +202 -0
  6. package/dist/profiles/ai-orchestration/implementation/accessibility.md +329 -0
  7. package/dist/profiles/ai-orchestration/pattern-contracts.json +697 -0
  8. package/dist/profiles/ai-orchestration/patterns/accordion.md +12 -0
  9. package/dist/profiles/ai-orchestration/patterns/alert.md +11 -0
  10. package/dist/profiles/ai-orchestration/patterns/carousel.md +12 -0
  11. package/dist/profiles/ai-orchestration/patterns/combobox.md +11 -0
  12. package/dist/profiles/ai-orchestration/patterns/consequential-submission.md +11 -0
  13. package/dist/profiles/ai-orchestration/patterns/dialog.md +12 -0
  14. package/dist/profiles/ai-orchestration/patterns/disclosure.md +11 -0
  15. package/dist/profiles/ai-orchestration/patterns/dynamic-status.md +11 -0
  16. package/dist/profiles/ai-orchestration/patterns/field.md +11 -0
  17. package/dist/profiles/ai-orchestration/patterns/image.md +11 -0
  18. package/dist/profiles/ai-orchestration/patterns/listbox.md +12 -0
  19. package/dist/profiles/ai-orchestration/patterns/media-player.md +11 -0
  20. package/dist/profiles/ai-orchestration/patterns/menu-button.md +11 -0
  21. package/dist/profiles/ai-orchestration/patterns/pagination.md +11 -0
  22. package/dist/profiles/ai-orchestration/patterns/popover.md +11 -0
  23. package/dist/profiles/ai-orchestration/patterns/progress.md +11 -0
  24. package/dist/profiles/ai-orchestration/patterns/tabs.md +12 -0
  25. package/dist/profiles/ai-orchestration/patterns/tooltip.md +12 -0
  26. package/dist/profiles/ai-orchestration/patterns/validation.md +11 -0
  27. package/dist/profiles/ai-orchestration/review/accessibility.md +67 -0
  28. package/dist/profiles/ai-orchestration/semantics/accessible-name.md +8 -0
  29. package/dist/profiles/ai-orchestration/semantics/alert.md +8 -0
  30. package/dist/profiles/ai-orchestration/semantics/consequential-action.md +8 -0
  31. package/dist/profiles/ai-orchestration/semantics/data-table.md +8 -0
  32. package/dist/profiles/ai-orchestration/semantics/expanded-state.md +8 -0
  33. package/dist/profiles/ai-orchestration/semantics/focus.initial.md +8 -0
  34. package/dist/profiles/ai-orchestration/semantics/focus.return.md +8 -0
  35. package/dist/profiles/ai-orchestration/semantics/focus.visible.md +8 -0
  36. package/dist/profiles/ai-orchestration/semantics/form-error.md +8 -0
  37. package/dist/profiles/ai-orchestration/semantics/form-label.md +8 -0
  38. package/dist/profiles/ai-orchestration/semantics/form-required.md +8 -0
  39. package/dist/profiles/ai-orchestration/semantics/headings.md +8 -0
  40. package/dist/profiles/ai-orchestration/semantics/keyboard.escape.md +8 -0
  41. package/dist/profiles/ai-orchestration/semantics/keyboard.md +8 -0
  42. package/dist/profiles/ai-orchestration/semantics/landmarks.md +8 -0
  43. package/dist/profiles/ai-orchestration/semantics/live-status.md +8 -0
  44. package/dist/profiles/ai-orchestration/semantics/media-alternatives.md +8 -0
  45. package/dist/profiles/ai-orchestration/semantics/motion-control.md +8 -0
  46. package/dist/profiles/ai-orchestration/semantics/name-role-value.md +8 -0
  47. package/dist/profiles/ai-orchestration/semantics/native-dialog.md +8 -0
  48. package/dist/profiles/ai-orchestration/semantics/native-elements.md +8 -0
  49. package/dist/profiles/ai-orchestration/semantics/non-text-alternative.md +8 -0
  50. package/dist/profiles/ai-orchestration/semantics/roles-states-properties.md +8 -0
  51. package/dist/profiles/ai-orchestration/semantics/selected-state.md +8 -0
  52. package/dist/profiles/ai-orchestration/semantics/target-size.md +8 -0
  53. package/dist/profiles/ai-orchestration/semantics.json +289 -0
  54. package/dist/profiles/ai-orchestration/testing/accessibility.md +138 -0
  55. package/dist/profiles/conductor/a11y-semantics.md +152 -0
  56. package/dist/profiles/conductor/accessibility-quality.md +179 -0
  57. package/dist/profiles/conductor/applicability-matrix.json +428 -0
  58. package/dist/profiles/conductor/coverage-manifest.json +202 -0
  59. package/dist/profiles/conductor/pattern-contracts.json +697 -0
  60. package/dist/profiles/conductor/patterns/accordion.json +44 -0
  61. package/dist/profiles/conductor/patterns/alert.json +34 -0
  62. package/dist/profiles/conductor/patterns/carousel.json +45 -0
  63. package/dist/profiles/conductor/patterns/combobox.json +44 -0
  64. package/dist/profiles/conductor/patterns/consequential-submission.json +38 -0
  65. package/dist/profiles/conductor/patterns/dialog.json +47 -0
  66. package/dist/profiles/conductor/patterns/disclosure.json +39 -0
  67. package/dist/profiles/conductor/patterns/dynamic-status.json +36 -0
  68. package/dist/profiles/conductor/patterns/field.json +39 -0
  69. package/dist/profiles/conductor/patterns/image.json +35 -0
  70. package/dist/profiles/conductor/patterns/listbox.json +43 -0
  71. package/dist/profiles/conductor/patterns/media-player.json +45 -0
  72. package/dist/profiles/conductor/patterns/menu-button.json +41 -0
  73. package/dist/profiles/conductor/patterns/pagination.json +39 -0
  74. package/dist/profiles/conductor/patterns/popover.json +40 -0
  75. package/dist/profiles/conductor/patterns/progress.json +37 -0
  76. package/dist/profiles/conductor/patterns/tabs.json +42 -0
  77. package/dist/profiles/conductor/patterns/tooltip.json +37 -0
  78. package/dist/profiles/conductor/patterns/validation.json +42 -0
  79. package/dist/profiles/conductor/semantics.json +289 -0
  80. package/dist/projection-manifest.json +90 -0
  81. package/dist/requirements-to-implementation.md +21 -0
  82. package/lib/build-manifest.mjs +20 -0
  83. package/lib/build.mjs +31 -0
  84. package/lib/compile-applicability.mjs +56 -0
  85. package/lib/digest.mjs +11 -0
  86. package/lib/index.mjs +4 -0
  87. package/lib/load.mjs +40 -0
  88. package/lib/render.mjs +71 -0
  89. package/lib/sync.mjs +94 -0
  90. package/lib/validate.mjs +31 -0
  91. package/package.json +46 -0
  92. package/profiles/ai-orchestration/profile.json +1 -0
  93. package/profiles/ai-orchestration/templates/implementation/README.md +3 -0
  94. package/profiles/ai-orchestration/templates/patterns/README.md +3 -0
  95. package/profiles/ai-orchestration/templates/review/README.md +3 -0
  96. package/profiles/ai-orchestration/templates/semantics/README.md +3 -0
  97. package/profiles/ai-orchestration/templates/testing/README.md +3 -0
  98. package/profiles/conductor/profile.json +1 -0
  99. package/profiles/conductor/templates/applicability/README.md +3 -0
  100. package/profiles/conductor/templates/evidence/README.md +3 -0
  101. package/profiles/conductor/templates/patterns/README.md +3 -0
  102. package/profiles/conductor/templates/semantics/README.md +3 -0
  103. package/schemas/applicability-matrix.schema.json +1 -0
  104. package/schemas/consumer-config.schema.json +1 -0
  105. package/schemas/consumer-routes.schema.json +1 -0
  106. package/schemas/manifest.schema.json +1 -0
  107. package/schemas/pattern.schema.json +1 -0
  108. package/schemas/profile.schema.json +1 -0
  109. package/schemas/projection-manifest.schema.json +1 -0
  110. package/schemas/record.schema.json +1 -0
  111. package/schemas/semantic.schema.json +1 -0
  112. package/src/applicability/facts.yml +1 -0
  113. package/src/applicability/matrix.yml +20 -0
  114. package/src/evidence/proof-routing.yml +1 -0
  115. package/src/foundations/conformance-boundary.yml +1 -0
  116. package/src/foundations/standards-hierarchy.yml +1 -0
  117. package/src/foundations/wcag-2.2.yml +1 -0
  118. package/src/patterns/disclosure/accordion.yml +1 -0
  119. package/src/patterns/disclosure/disclosure.yml +1 -0
  120. package/src/patterns/feedback/alert.yml +1 -0
  121. package/src/patterns/feedback/dynamic-status.yml +1 -0
  122. package/src/patterns/feedback/progress.yml +1 -0
  123. package/src/patterns/forms/consequential-submission.yml +1 -0
  124. package/src/patterns/forms/field.yml +1 -0
  125. package/src/patterns/forms/validation.yml +1 -0
  126. package/src/patterns/media/carousel.yml +1 -0
  127. package/src/patterns/media/image.yml +1 -0
  128. package/src/patterns/media/media-player.yml +1 -0
  129. package/src/patterns/navigation/menu-button.yml +1 -0
  130. package/src/patterns/navigation/pagination.yml +1 -0
  131. package/src/patterns/navigation/tabs.yml +1 -0
  132. package/src/patterns/overlays/dialog.yml +1 -0
  133. package/src/patterns/overlays/popover.yml +1 -0
  134. package/src/patterns/overlays/tooltip.yml +1 -0
  135. package/src/patterns/selection/combobox.yml +1 -0
  136. package/src/patterns/selection/listbox.yml +1 -0
  137. package/src/policies/enhanced-quality.yml +1 -0
  138. package/src/policies/target-size.yml +1 -0
  139. package/src/semantics/accessible-names.yml +1 -0
  140. package/src/semantics/forms.yml +1 -0
  141. package/src/semantics/headings-landmarks.yml +1 -0
  142. package/src/semantics/keyboard-focus.yml +1 -0
  143. package/src/semantics/live-regions.yml +1 -0
  144. package/src/semantics/media.yml +1 -0
  145. package/src/semantics/native-elements.yml +1 -0
  146. package/src/semantics/roles-states-properties.yml +1 -0
  147. package/src/semantics/tables.yml +1 -0
  148. package/src/sources.yml +1 -0
@@ -0,0 +1,697 @@
1
+ {
2
+ "_generated": "GENERATED by @verndale/accessibility-standards; DO NOT EDIT",
3
+ "schema_version": 1,
4
+ "patterns": [
5
+ {
6
+ "id": "pattern.accordion",
7
+ "version": "1.0.0",
8
+ "title": "Accordion",
9
+ "kind": "pattern",
10
+ "requires": [
11
+ "semantics.native-elements",
12
+ "semantics.accessible-name",
13
+ "semantics.expanded-state",
14
+ "semantics.keyboard",
15
+ "semantics.focus.visible"
16
+ ],
17
+ "activation": {
18
+ "fact": "component.pattern",
19
+ "equals": "accordion"
20
+ },
21
+ "scope": "Grouped disclosure sections",
22
+ "behavior": [
23
+ "Toggle only the controlled panel",
24
+ "Preserve DOM and focus order"
25
+ ],
26
+ "product_decisions": [
27
+ "single_or_multiple_open"
28
+ ],
29
+ "functional_spec_bindings": [
30
+ "behavior",
31
+ "states",
32
+ "keyboard"
33
+ ],
34
+ "implementation_outcomes": [
35
+ "accordion-control",
36
+ "accordion-panel"
37
+ ],
38
+ "evidence_routes": [
39
+ "unit",
40
+ "axe",
41
+ "e2e",
42
+ "human"
43
+ ]
44
+ },
45
+ {
46
+ "id": "pattern.alert",
47
+ "version": "1.0.0",
48
+ "title": "Alert",
49
+ "kind": "pattern",
50
+ "requires": [
51
+ "semantics.alert"
52
+ ],
53
+ "activation": {
54
+ "fact": "component.pattern",
55
+ "equals": "alert"
56
+ },
57
+ "scope": "Urgent message",
58
+ "behavior": [
59
+ "Announce once without moving focus"
60
+ ],
61
+ "product_decisions": [
62
+ "urgency"
63
+ ],
64
+ "functional_spec_bindings": [
65
+ "messaging"
66
+ ],
67
+ "implementation_outcomes": [
68
+ "alert-announcement"
69
+ ],
70
+ "evidence_routes": [
71
+ "unit",
72
+ "human"
73
+ ]
74
+ },
75
+ {
76
+ "id": "pattern.carousel",
77
+ "version": "1.0.0",
78
+ "title": "Carousel",
79
+ "kind": "pattern",
80
+ "requires": [
81
+ "semantics.accessible-name",
82
+ "semantics.keyboard",
83
+ "semantics.focus.visible",
84
+ "semantics.motion-control",
85
+ "semantics.live-status"
86
+ ],
87
+ "activation": {
88
+ "fact": "component.pattern",
89
+ "equals": "carousel"
90
+ },
91
+ "scope": "Rotating content set",
92
+ "behavior": [
93
+ "Pause rotation on interaction",
94
+ "Provide named controls and current position"
95
+ ],
96
+ "product_decisions": [
97
+ "auto_rotation",
98
+ "looping"
99
+ ],
100
+ "functional_spec_bindings": [
101
+ "behavior",
102
+ "states",
103
+ "controls"
104
+ ],
105
+ "implementation_outcomes": [
106
+ "carousel-controls",
107
+ "carousel-rotation"
108
+ ],
109
+ "evidence_routes": [
110
+ "unit",
111
+ "axe",
112
+ "e2e",
113
+ "human"
114
+ ]
115
+ },
116
+ {
117
+ "id": "pattern.combobox",
118
+ "version": "1.0.0",
119
+ "title": "Combobox",
120
+ "kind": "pattern",
121
+ "requires": [
122
+ "semantics.accessible-name",
123
+ "semantics.expanded-state",
124
+ "semantics.selected-state",
125
+ "semantics.keyboard",
126
+ "semantics.live-status"
127
+ ],
128
+ "activation": {
129
+ "fact": "component.pattern",
130
+ "equals": "combobox"
131
+ },
132
+ "scope": "Input with selectable popup",
133
+ "behavior": [
134
+ "Keyboard controls popup, option, and input independently"
135
+ ],
136
+ "product_decisions": [
137
+ "editable",
138
+ "autocomplete",
139
+ "selection_commit"
140
+ ],
141
+ "functional_spec_bindings": [
142
+ "behavior",
143
+ "states",
144
+ "keyboard"
145
+ ],
146
+ "implementation_outcomes": [
147
+ "combobox-state-machine"
148
+ ],
149
+ "evidence_routes": [
150
+ "unit",
151
+ "axe",
152
+ "e2e",
153
+ "human"
154
+ ]
155
+ },
156
+ {
157
+ "id": "pattern.consequential-submission",
158
+ "version": "1.0.0",
159
+ "title": "Consequential submission",
160
+ "kind": "pattern",
161
+ "requires": [
162
+ "semantics.consequential-action",
163
+ "semantics.form-error",
164
+ "semantics.keyboard"
165
+ ],
166
+ "activation": {
167
+ "fact": "component.submission_consequence",
168
+ "contains": "consequential"
169
+ },
170
+ "scope": "Legal, financial, destructive, or irreversible submission",
171
+ "behavior": [
172
+ "Support review, correction, confirmation, or reversal"
173
+ ],
174
+ "product_decisions": [
175
+ "safeguard",
176
+ "reversal_window"
177
+ ],
178
+ "functional_spec_bindings": [
179
+ "submission",
180
+ "confirmation"
181
+ ],
182
+ "implementation_outcomes": [
183
+ "submission-safeguard"
184
+ ],
185
+ "evidence_routes": [
186
+ "e2e",
187
+ "human"
188
+ ]
189
+ },
190
+ {
191
+ "id": "pattern.dialog",
192
+ "version": "1.0.0",
193
+ "title": "Dialog",
194
+ "kind": "pattern",
195
+ "requires": [
196
+ "semantics.native-dialog",
197
+ "semantics.accessible-name",
198
+ "semantics.keyboard.escape",
199
+ "semantics.focus.initial",
200
+ "semantics.focus.return"
201
+ ],
202
+ "activation": {
203
+ "fact": "component.pattern",
204
+ "equals": "dialog"
205
+ },
206
+ "scope": "Modal and non-modal dialogs",
207
+ "behavior": [
208
+ "Manage initial, contained, and return focus",
209
+ "Dismiss topmost dialog with Escape"
210
+ ],
211
+ "product_decisions": [
212
+ "modal",
213
+ "initial_focus",
214
+ "dismissal"
215
+ ],
216
+ "functional_spec_bindings": [
217
+ "behavior",
218
+ "states",
219
+ "focus",
220
+ "keyboard"
221
+ ],
222
+ "implementation_outcomes": [
223
+ "dialog-semantics",
224
+ "dialog-focus-lifecycle"
225
+ ],
226
+ "evidence_routes": [
227
+ "unit",
228
+ "axe",
229
+ "e2e",
230
+ "human"
231
+ ]
232
+ },
233
+ {
234
+ "id": "pattern.disclosure",
235
+ "version": "1.0.0",
236
+ "title": "Disclosure",
237
+ "kind": "pattern",
238
+ "requires": [
239
+ "semantics.native-elements",
240
+ "semantics.accessible-name",
241
+ "semantics.expanded-state",
242
+ "semantics.keyboard"
243
+ ],
244
+ "activation": {
245
+ "fact": "component.pattern",
246
+ "equals": "disclosure"
247
+ },
248
+ "scope": "Show and hide supplementary content",
249
+ "behavior": [
250
+ "Control toggles one region"
251
+ ],
252
+ "product_decisions": [
253
+ "initial_state"
254
+ ],
255
+ "functional_spec_bindings": [
256
+ "behavior",
257
+ "states"
258
+ ],
259
+ "implementation_outcomes": [
260
+ "disclosure-control"
261
+ ],
262
+ "evidence_routes": [
263
+ "unit",
264
+ "axe",
265
+ "e2e"
266
+ ]
267
+ },
268
+ {
269
+ "id": "pattern.dynamic-status",
270
+ "version": "1.0.0",
271
+ "title": "Dynamic status",
272
+ "kind": "pattern",
273
+ "requires": [
274
+ "semantics.live-status"
275
+ ],
276
+ "activation": {
277
+ "fact": "component.has_dynamic_status",
278
+ "equals": true
279
+ },
280
+ "scope": "Asynchronous status message",
281
+ "behavior": [
282
+ "Announce meaningful changes once"
283
+ ],
284
+ "product_decisions": [
285
+ "announcement_copy"
286
+ ],
287
+ "functional_spec_bindings": [
288
+ "messaging",
289
+ "states"
290
+ ],
291
+ "implementation_outcomes": [
292
+ "status-live-region"
293
+ ],
294
+ "evidence_routes": [
295
+ "unit",
296
+ "e2e",
297
+ "human"
298
+ ]
299
+ },
300
+ {
301
+ "id": "pattern.field",
302
+ "version": "1.0.0",
303
+ "title": "Form field",
304
+ "kind": "pattern",
305
+ "requires": [
306
+ "semantics.form-label",
307
+ "semantics.form-required",
308
+ "semantics.focus.visible"
309
+ ],
310
+ "activation": {
311
+ "fact": "component.has_form_fields",
312
+ "equals": true
313
+ },
314
+ "scope": "Labeled form input",
315
+ "behavior": [
316
+ "Expose label, instructions, and requiredness before interaction"
317
+ ],
318
+ "product_decisions": [
319
+ "required",
320
+ "instructions"
321
+ ],
322
+ "functional_spec_bindings": [
323
+ "fields",
324
+ "requiredness"
325
+ ],
326
+ "implementation_outcomes": [
327
+ "field-associations"
328
+ ],
329
+ "evidence_routes": [
330
+ "unit",
331
+ "axe",
332
+ "human"
333
+ ]
334
+ },
335
+ {
336
+ "id": "pattern.image",
337
+ "version": "1.0.0",
338
+ "title": "Image",
339
+ "kind": "pattern",
340
+ "requires": [
341
+ "semantics.non-text-alternative"
342
+ ],
343
+ "activation": {
344
+ "fact": "content.has_non_text",
345
+ "equals": true
346
+ },
347
+ "scope": "Informative, functional, complex, or decorative image",
348
+ "behavior": [
349
+ "Alternative follows image purpose"
350
+ ],
351
+ "product_decisions": [
352
+ "purpose",
353
+ "long_description"
354
+ ],
355
+ "functional_spec_bindings": [
356
+ "content"
357
+ ],
358
+ "implementation_outcomes": [
359
+ "image-alternative"
360
+ ],
361
+ "evidence_routes": [
362
+ "axe",
363
+ "human"
364
+ ]
365
+ },
366
+ {
367
+ "id": "pattern.listbox",
368
+ "version": "1.0.0",
369
+ "title": "Listbox",
370
+ "kind": "pattern",
371
+ "requires": [
372
+ "semantics.accessible-name",
373
+ "semantics.selected-state",
374
+ "semantics.keyboard",
375
+ "semantics.focus.visible"
376
+ ],
377
+ "activation": {
378
+ "fact": "component.pattern",
379
+ "equals": "listbox"
380
+ },
381
+ "scope": "Single or multi-select option list",
382
+ "behavior": [
383
+ "Arrow keys move active option",
384
+ "Selection follows declared model"
385
+ ],
386
+ "product_decisions": [
387
+ "single_or_multi",
388
+ "selection_follows_focus"
389
+ ],
390
+ "functional_spec_bindings": [
391
+ "behavior",
392
+ "states",
393
+ "keyboard"
394
+ ],
395
+ "implementation_outcomes": [
396
+ "listbox-keyboard-model"
397
+ ],
398
+ "evidence_routes": [
399
+ "unit",
400
+ "axe",
401
+ "e2e",
402
+ "human"
403
+ ]
404
+ },
405
+ {
406
+ "id": "pattern.media-player",
407
+ "version": "1.0.0",
408
+ "title": "Media player",
409
+ "kind": "pattern",
410
+ "requires": [
411
+ "semantics.media-alternatives",
412
+ "semantics.accessible-name",
413
+ "semantics.keyboard",
414
+ "semantics.focus.visible",
415
+ "semantics.motion-control"
416
+ ],
417
+ "activation": {
418
+ "fact": "content.has_media",
419
+ "equals": true
420
+ },
421
+ "scope": "Audio or video playback",
422
+ "behavior": [
423
+ "Provide keyboard-operable named controls and required alternatives"
424
+ ],
425
+ "product_decisions": [
426
+ "captions",
427
+ "transcript",
428
+ "audio_description",
429
+ "autoplay"
430
+ ],
431
+ "functional_spec_bindings": [
432
+ "content",
433
+ "controls",
434
+ "behavior"
435
+ ],
436
+ "implementation_outcomes": [
437
+ "media-alternatives",
438
+ "media-controls"
439
+ ],
440
+ "evidence_routes": [
441
+ "axe",
442
+ "e2e",
443
+ "human"
444
+ ]
445
+ },
446
+ {
447
+ "id": "pattern.menu-button",
448
+ "version": "1.0.0",
449
+ "title": "Menu button",
450
+ "kind": "pattern",
451
+ "requires": [
452
+ "semantics.accessible-name",
453
+ "semantics.expanded-state",
454
+ "semantics.keyboard",
455
+ "semantics.focus.initial",
456
+ "semantics.focus.return"
457
+ ],
458
+ "activation": {
459
+ "fact": "component.pattern",
460
+ "equals": "menu-button"
461
+ },
462
+ "scope": "Button opening a command menu",
463
+ "behavior": [
464
+ "Open and navigate menu by keyboard"
465
+ ],
466
+ "product_decisions": [
467
+ "focus_strategy"
468
+ ],
469
+ "functional_spec_bindings": [
470
+ "behavior",
471
+ "keyboard",
472
+ "focus"
473
+ ],
474
+ "implementation_outcomes": [
475
+ "menu-button-keyboard"
476
+ ],
477
+ "evidence_routes": [
478
+ "unit",
479
+ "e2e",
480
+ "human"
481
+ ]
482
+ },
483
+ {
484
+ "id": "pattern.pagination",
485
+ "version": "1.0.0",
486
+ "title": "Pagination",
487
+ "kind": "pattern",
488
+ "requires": [
489
+ "semantics.native-elements",
490
+ "semantics.accessible-name",
491
+ "semantics.landmarks",
492
+ "semantics.focus.visible"
493
+ ],
494
+ "activation": {
495
+ "fact": "component.pattern",
496
+ "equals": "pagination"
497
+ },
498
+ "scope": "Paged result navigation",
499
+ "behavior": [
500
+ "Expose current page and named navigation"
501
+ ],
502
+ "product_decisions": [
503
+ "url_behavior"
504
+ ],
505
+ "functional_spec_bindings": [
506
+ "states",
507
+ "navigation"
508
+ ],
509
+ "implementation_outcomes": [
510
+ "pagination-current-page"
511
+ ],
512
+ "evidence_routes": [
513
+ "unit",
514
+ "axe",
515
+ "human"
516
+ ]
517
+ },
518
+ {
519
+ "id": "pattern.popover",
520
+ "version": "1.0.0",
521
+ "title": "Popover",
522
+ "kind": "pattern",
523
+ "requires": [
524
+ "semantics.native-elements",
525
+ "semantics.accessible-name",
526
+ "semantics.keyboard.escape",
527
+ "semantics.focus.return"
528
+ ],
529
+ "activation": {
530
+ "fact": "component.pattern",
531
+ "equals": "popover"
532
+ },
533
+ "scope": "Non-modal transient surface",
534
+ "behavior": [
535
+ "Dismiss without trapping focus"
536
+ ],
537
+ "product_decisions": [
538
+ "dismissal",
539
+ "focus_entry"
540
+ ],
541
+ "functional_spec_bindings": [
542
+ "behavior",
543
+ "focus"
544
+ ],
545
+ "implementation_outcomes": [
546
+ "popover-dismissal"
547
+ ],
548
+ "evidence_routes": [
549
+ "unit",
550
+ "e2e",
551
+ "human"
552
+ ]
553
+ },
554
+ {
555
+ "id": "pattern.progress",
556
+ "version": "1.0.0",
557
+ "title": "Progress",
558
+ "kind": "pattern",
559
+ "requires": [
560
+ "semantics.name-role-value",
561
+ "semantics.live-status"
562
+ ],
563
+ "activation": {
564
+ "fact": "component.pattern",
565
+ "equals": "progress"
566
+ },
567
+ "scope": "Determinate or indeterminate progress",
568
+ "behavior": [
569
+ "Expose value and completion changes without announcement noise"
570
+ ],
571
+ "product_decisions": [
572
+ "determinate"
573
+ ],
574
+ "functional_spec_bindings": [
575
+ "states",
576
+ "messaging"
577
+ ],
578
+ "implementation_outcomes": [
579
+ "progress-value"
580
+ ],
581
+ "evidence_routes": [
582
+ "unit",
583
+ "axe",
584
+ "human"
585
+ ]
586
+ },
587
+ {
588
+ "id": "pattern.tabs",
589
+ "version": "1.0.0",
590
+ "title": "Tabs",
591
+ "kind": "pattern",
592
+ "requires": [
593
+ "semantics.accessible-name",
594
+ "semantics.selected-state",
595
+ "semantics.keyboard",
596
+ "semantics.focus.visible"
597
+ ],
598
+ "activation": {
599
+ "fact": "component.pattern",
600
+ "equals": "tabs"
601
+ },
602
+ "scope": "Tabbed interfaces",
603
+ "behavior": [
604
+ "Arrow keys move between tabs",
605
+ "Selection and activation follow the documented model"
606
+ ],
607
+ "product_decisions": [
608
+ "automatic_or_manual_activation"
609
+ ],
610
+ "functional_spec_bindings": [
611
+ "behavior",
612
+ "states",
613
+ "keyboard"
614
+ ],
615
+ "implementation_outcomes": [
616
+ "tabs-keyboard-model"
617
+ ],
618
+ "evidence_routes": [
619
+ "unit",
620
+ "axe",
621
+ "e2e",
622
+ "human"
623
+ ]
624
+ },
625
+ {
626
+ "id": "pattern.tooltip",
627
+ "version": "1.0.0",
628
+ "title": "Tooltip",
629
+ "kind": "pattern",
630
+ "requires": [
631
+ "semantics.accessible-name",
632
+ "semantics.keyboard.escape"
633
+ ],
634
+ "activation": {
635
+ "fact": "component.pattern",
636
+ "equals": "tooltip"
637
+ },
638
+ "scope": "Supplementary description",
639
+ "behavior": [
640
+ "Available on hover and focus",
641
+ "Never contains interactive content"
642
+ ],
643
+ "product_decisions": [
644
+ "delay"
645
+ ],
646
+ "functional_spec_bindings": [
647
+ "behavior"
648
+ ],
649
+ "implementation_outcomes": [
650
+ "tooltip-description"
651
+ ],
652
+ "evidence_routes": [
653
+ "unit",
654
+ "e2e",
655
+ "human"
656
+ ]
657
+ },
658
+ {
659
+ "id": "pattern.validation",
660
+ "version": "1.0.0",
661
+ "title": "Form validation",
662
+ "kind": "pattern",
663
+ "requires": [
664
+ "semantics.form-error",
665
+ "semantics.live-status",
666
+ "semantics.focus.initial"
667
+ ],
668
+ "activation": {
669
+ "fact": "component.has_validation",
670
+ "equals": true
671
+ },
672
+ "scope": "Client or server validation",
673
+ "behavior": [
674
+ "Identify, associate, summarize, and focus errors deterministically"
675
+ ],
676
+ "product_decisions": [
677
+ "validation_timing",
678
+ "error_summary"
679
+ ],
680
+ "functional_spec_bindings": [
681
+ "validation",
682
+ "messaging",
683
+ "focus"
684
+ ],
685
+ "implementation_outcomes": [
686
+ "validation-associations",
687
+ "error-summary"
688
+ ],
689
+ "evidence_routes": [
690
+ "unit",
691
+ "axe",
692
+ "e2e",
693
+ "human"
694
+ ]
695
+ }
696
+ ]
697
+ }
@@ -0,0 +1,12 @@
1
+ <!-- GENERATED by @verndale/accessibility-standards; DO NOT EDIT -->
2
+ # pattern.accordion
3
+
4
+ ## pattern.accordion
5
+
6
+ Requires: semantics.native-elements, semantics.accessible-name, semantics.expanded-state, semantics.keyboard, semantics.focus.visible.
7
+
8
+ Behavior:
9
+ - Toggle only the controlled panel
10
+ - Preserve DOM and focus order
11
+
12
+ Evidence: unit, axe, e2e, human.