@hegemonart/get-design-done 1.15.0 → 1.18.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 (70) hide show
  1. package/.claude-plugin/marketplace.json +9 -5
  2. package/.claude-plugin/plugin.json +19 -5
  3. package/CHANGELOG.md +122 -0
  4. package/README.md +41 -0
  5. package/SKILL.md +4 -1
  6. package/agents/component-benchmark-harvester.md +112 -0
  7. package/agents/component-benchmark-synthesizer.md +88 -0
  8. package/agents/design-auditor.md +60 -1
  9. package/agents/design-doc-writer.md +21 -0
  10. package/agents/design-executor.md +22 -4
  11. package/agents/design-pattern-mapper.md +61 -0
  12. package/agents/motion-mapper.md +74 -9
  13. package/agents/token-mapper.md +8 -0
  14. package/connections/design-corpora.md +158 -0
  15. package/package.json +13 -3
  16. package/reference/components/README.md +94 -0
  17. package/reference/components/TEMPLATE.md +184 -0
  18. package/reference/components/accordion.md +217 -0
  19. package/reference/components/alert.md +198 -0
  20. package/reference/components/badge.md +202 -0
  21. package/reference/components/breadcrumbs.md +198 -0
  22. package/reference/components/button.md +195 -0
  23. package/reference/components/card.md +200 -0
  24. package/reference/components/checkbox.md +207 -0
  25. package/reference/components/chip.md +209 -0
  26. package/reference/components/command-palette.md +228 -0
  27. package/reference/components/date-picker.md +227 -0
  28. package/reference/components/drawer.md +201 -0
  29. package/reference/components/file-upload.md +219 -0
  30. package/reference/components/input.md +208 -0
  31. package/reference/components/label.md +200 -0
  32. package/reference/components/link.md +193 -0
  33. package/reference/components/list.md +217 -0
  34. package/reference/components/menu.md +212 -0
  35. package/reference/components/modal-dialog.md +210 -0
  36. package/reference/components/navbar.md +211 -0
  37. package/reference/components/pagination.md +205 -0
  38. package/reference/components/popover.md +197 -0
  39. package/reference/components/progress.md +210 -0
  40. package/reference/components/radio.md +203 -0
  41. package/reference/components/rich-text-editor.md +226 -0
  42. package/reference/components/select-combobox.md +219 -0
  43. package/reference/components/sidebar.md +211 -0
  44. package/reference/components/skeleton.md +197 -0
  45. package/reference/components/slider.md +208 -0
  46. package/reference/components/stepper.md +220 -0
  47. package/reference/components/switch.md +194 -0
  48. package/reference/components/table.md +229 -0
  49. package/reference/components/tabs.md +213 -0
  50. package/reference/components/toast.md +200 -0
  51. package/reference/components/tooltip.md +201 -0
  52. package/reference/components/tree.md +225 -0
  53. package/reference/css-grid-layout.md +835 -0
  54. package/reference/external/NOTICE.hyperframes +28 -0
  55. package/reference/image-optimization.md +582 -0
  56. package/reference/motion-advanced.md +754 -0
  57. package/reference/motion-easings.md +381 -0
  58. package/reference/motion-interpolate.md +282 -0
  59. package/reference/motion-spring.md +234 -0
  60. package/reference/motion-transition-taxonomy.md +155 -0
  61. package/reference/motion.md +20 -0
  62. package/reference/output-contracts/motion-map.schema.json +135 -0
  63. package/reference/registry.json +285 -0
  64. package/reference/registry.schema.json +6 -1
  65. package/reference/variable-fonts-loading.md +532 -0
  66. package/scripts/lib/easings.cjs +280 -0
  67. package/scripts/lib/parse-contract.cjs +220 -0
  68. package/scripts/lib/spring.cjs +160 -0
  69. package/scripts/tests/test-motion-provenance.sh +64 -0
  70. package/skills/benchmark/SKILL.md +105 -0
@@ -0,0 +1,184 @@
1
+ # [Component Name] — Benchmark Spec
2
+
3
+ > **Template version**: 1.0 (Phase 16)
4
+ > Replace every placeholder in `[brackets]`. Delete this block before committing.
5
+ > Max 350 lines. Every section must be present even if brief.
6
+ > See `agents/component-benchmark-synthesizer.md` for authoring rules.
7
+
8
+ ---
9
+
10
+ **Harvested from**: [N] design systems · [date]
11
+ **Wave**: [1 | 2 | 3 | 4 | 5] · **Category**: [Inputs | Containers | Feedback | Navigation | Advanced]
12
+ **Spec file**: `reference/components/[name].md`
13
+
14
+ ---
15
+
16
+ ## Purpose
17
+
18
+ [One paragraph: what this component is, its core job, and when to use it vs. alternatives.
19
+ Cite convergence: "(Material 3, Carbon, Polaris agree: …)"]
20
+
21
+ ---
22
+
23
+ ## Anatomy
24
+
25
+ [Describe the structural parts. Use a numbered or bulleted list of named elements.
26
+ Mark each as optional or required.]
27
+
28
+ ```
29
+ [ASCII diagram or bulleted tree showing component structure]
30
+ ```
31
+
32
+ | Part | Required | Notes |
33
+ |------|----------|-------|
34
+ | [part] | Yes/No | [brief description] |
35
+
36
+ ---
37
+
38
+ ## Variants
39
+
40
+ [List the canonical variant set. For each, note which systems define it and what
41
+ distinguishes it visually/behaviorally.]
42
+
43
+ | Variant | Description | Systems |
44
+ |---------|-------------|---------|
45
+ | [variant] | [what it is] | [Material 3, Carbon, …] |
46
+
47
+ **Norm** (≥4/18 systems agree): [what the majority agrees on for variant naming/behavior]
48
+ **Diverge**: [where systems meaningfully differ and why]
49
+
50
+ ---
51
+
52
+ ## States
53
+
54
+ [All interaction states the component must handle. Include visual and semantic description.]
55
+
56
+ | State | Trigger | Visual | ARIA |
57
+ |-------|---------|--------|------|
58
+ | default | — | [description] | — |
59
+ | hover | pointer over | [description] | — |
60
+ | focus | keyboard focus | focus-visible ring | — |
61
+ | active / pressed | mousedown / Space/Enter | [description] | — |
62
+ | disabled | `disabled` attr | [description] | `aria-disabled="true"` |
63
+ | loading | [if applicable] | [description] | `aria-busy="true"` |
64
+ | error | [if applicable] | [description] | `aria-invalid="true"` |
65
+
66
+ ---
67
+
68
+ ## Sizing & Spacing
69
+
70
+ [Token-based sizing guidance. Reference `reference/typography.md` and `reference/surfaces.md`
71
+ for typographic and radius rules.]
72
+
73
+ | Size | Height | Padding H | Font | Notes |
74
+ |------|--------|-----------|------|-------|
75
+ | sm | [value] | [value] | [value] | |
76
+ | md (default) | [value] | [value] | [value] | |
77
+ | lg | [value] | [value] | [value] | |
78
+
79
+ **Norm**: [what most systems agree on for sizing ratios]
80
+
81
+ ---
82
+
83
+ ## Typography
84
+
85
+ [Any typographic constraints: weight, size relative to body, line-height cap, truncation rules.]
86
+
87
+ Cross-link: `reference/typography.md` — [relevant section]
88
+
89
+ ---
90
+
91
+ ## Keyboard & Accessibility
92
+
93
+ > **WAI-ARIA role**: `[role]`
94
+ > **Required attributes**: `[aria-* attrs]`
95
+
96
+ ### Keyboard Contract
97
+
98
+ *Quoted verbatim from WAI-ARIA APG — [pattern URL] — W3C — [access date]*
99
+
100
+ | Key | Action |
101
+ |-----|--------|
102
+ | [key] | [action] |
103
+
104
+ ### Accessibility Rules
105
+
106
+ - [Rule 1 — e.g., must have visible label or `aria-label`]
107
+ - [Rule 2 — e.g., focus-visible ring must not be suppressed]
108
+ - [Rule 3 — e.g., disabled state uses `aria-disabled`, not `disabled` attr, if interactive]
109
+
110
+ Cross-link: `reference/accessibility.md` — [relevant section]
111
+
112
+ ---
113
+
114
+ ## Motion
115
+
116
+ [Animation guidance for entry, exit, state transitions. Reference `reference/motion.md`.]
117
+
118
+ | Transition | Duration | Easing | Notes |
119
+ |------------|----------|--------|-------|
120
+ | [transition] | [ms] | [easing] | |
121
+
122
+ **BAN**: [any motion anti-patterns specific to this component]
123
+
124
+ Cross-link: `reference/motion.md` — [relevant section]
125
+
126
+ ---
127
+
128
+ ## Do / Don't
129
+
130
+ ### Do
131
+ - [Positive practice 1] *([System])*
132
+ - [Positive practice 2] *([System])*
133
+ - [Positive practice 3] *([System])*
134
+
135
+ ### Don't
136
+ - [Anti-practice 1] *(diverges from [N] systems)*
137
+ - [Anti-practice 2]
138
+ - [Anti-practice 3]
139
+
140
+ ---
141
+
142
+ ## Anti-patterns Cross-links
143
+
144
+ | Anti-pattern | Entry |
145
+ |--------------|-------|
146
+ | [BAN-XX] | [brief name] — `reference/anti-patterns.md#ban-xx` |
147
+
148
+ ---
149
+
150
+ ## Benchmark Citations
151
+
152
+ | Claim | Sources |
153
+ |-------|---------|
154
+ | [claim] | [System1, System2, System3] |
155
+
156
+ Full system URLs: `connections/design-corpora.md`
157
+
158
+ ---
159
+
160
+ ## Grep Signatures
161
+
162
+ Patterns to detect common implementation failures (used by `design-auditor`):
163
+
164
+ ```bash
165
+ # Missing accessible label on icon-only variant
166
+ grep -rn 'aria-label\|aria-labelledby' src/ | grep -v '[Component]'
167
+
168
+ # [Additional grep pattern with comment explaining what it detects]
169
+ ```
170
+
171
+ ---
172
+
173
+ ## Failing Example
174
+
175
+ What a broken implementation of this component looks like, and how to detect it:
176
+
177
+ ```[html|jsx|tsx]
178
+ <!-- BAD: [describe the failure] -->
179
+ [broken code snippet]
180
+ ```
181
+
182
+ **Why it fails**: [explanation]
183
+ **Grep detection**: `grep -rn '[pattern]' src/`
184
+ **Fix**: [one-line fix or cross-link to reference]
@@ -0,0 +1,217 @@
1
+ # Accordion — Benchmark Spec
2
+
3
+ **Harvested from**: WAI-ARIA APG, Radix UI, Carbon, Chakra UI, Material 3, Mantine, shadcn/ui, Atlassian
4
+ **Wave**: 2 · **Category**: Containers
5
+
6
+ ---
7
+
8
+ ## Purpose
9
+
10
+ An accordion is a vertically stacked set of headers that each reveal or conceal an associated section of content when activated. It reduces visual clutter by hiding content that is not immediately relevant. The header MUST be a button (or have `role="button"`) — users must be able to activate sections by keyboard. *(WAI-ARIA APG, Radix, Carbon all agree)*
11
+
12
+ ---
13
+
14
+ ## Anatomy
15
+
16
+ ```
17
+ ┌──────────────────────────────┬──┐
18
+ │ Section 1 header (button) │ ▾│ ← aria-expanded="true"
19
+ └──────────────────────────────┴──┘
20
+ ┌────────────────────────────┐
21
+ │ Section 1 content │ ← aria-hidden="false"
22
+ └────────────────────────────┘
23
+ ┌──────────────────────────────┬──┐
24
+ │ Section 2 header (button) │ ▾│ ← aria-expanded="false"
25
+ └──────────────────────────────┴──┘
26
+ (Section 2 content hidden)
27
+ ```
28
+
29
+ | Part | Required | Notes |
30
+ |------|----------|-------|
31
+ | Header (h2–h6) | Yes | Wraps the trigger button; maintains document outline |
32
+ | Trigger button | Yes | `<button>` with `aria-expanded` + `aria-controls` |
33
+ | Panel | Yes | `id` referenced by `aria-controls`; `role="region"` + `aria-labelledby` |
34
+ | Chevron / icon | No | Rotates 180° on open; `aria-hidden="true"` |
35
+ | Divider | No | Border between items |
36
+
37
+ ---
38
+
39
+ ## Variants
40
+
41
+ | Variant | Description | Systems |
42
+ |---------|-------------|---------|
43
+ | Single-open | Only one panel open at a time | Material 3, Mantine (default) |
44
+ | Multi-open | Multiple panels can be open simultaneously | Radix (default), Carbon, shadcn |
45
+ | Bordered | Each item has a border/card appearance | All |
46
+ | Flush / ghost | No border; full-width dividers only | shadcn, Material 3 |
47
+ | With icon | Leading icon per header | Carbon, Atlassian |
48
+
49
+ **Norm** (≥5/18): chevron icon rotates on open (180°); panel animates height.
50
+ **Diverge**: single-open vs. multi-open — Radix defaults to multi-open (more flexible); Material 3 defaults to single-open (simpler UX). Multi-open is safer for long FAQ pages where users may want to compare sections.
51
+
52
+ ---
53
+
54
+ ## States
55
+
56
+ | State | Trigger | Visual | ARIA |
57
+ |-------|---------|--------|------|
58
+ | collapsed | default | Panel hidden | `aria-expanded="false"` on button |
59
+ | expanded | button activated | Panel visible | `aria-expanded="true"` on button |
60
+ | hover | pointer over header | Header background tint | — |
61
+ | focus | keyboard | 2px focus ring on button | — |
62
+ | disabled | programmatic | 38% opacity; non-interactive | `aria-disabled="true"` on button |
63
+
64
+ ---
65
+
66
+ ## Sizing & Spacing
67
+
68
+ | Property | Value | Notes |
69
+ |----------|-------|-------|
70
+ | Header height | 48px (md default) | Touch-friendly |
71
+ | Padding H (header) | 16px | |
72
+ | Padding (panel) | 16px | |
73
+ | Icon size | 16–20px | Chevron; gap from label: 8px |
74
+ | Item border | 1px `border-bottom` | Flush style |
75
+
76
+ ---
77
+
78
+ ## Typography
79
+
80
+ - Header: 14–16px/500 — slightly heavier than panel body
81
+ - Panel body: 14px/400
82
+ - Disabled header: same size, 38% opacity
83
+
84
+ ---
85
+
86
+ ## Keyboard & Accessibility
87
+
88
+ > **WAI-ARIA role**: `button` on header trigger (implicit if `<button>`); `region` on panel
89
+ > **Header trigger attributes**: `aria-expanded`, `aria-controls` (panel id)
90
+ > **Panel attributes**: `id`, `role="region"`, `aria-labelledby` (header button id)
91
+
92
+ ### Keyboard Contract
93
+
94
+ *Quoted verbatim from WAI-ARIA APG — https://www.w3.org/WAI/ARIA/apg/patterns/accordion/ — W3C — 2024*
95
+
96
+ | Key | Action |
97
+ |-----|--------|
98
+ | Enter / Space | When focus is on the accordion header, toggles the associated panel |
99
+ | Tab | Moves focus to the next focusable element |
100
+ | Shift+Tab | Moves focus to the previous focusable element |
101
+ | Arrow Down | (Optional) Moves focus to the next accordion header |
102
+ | Arrow Up | (Optional) Moves focus to the previous accordion header |
103
+ | Home | (Optional) Moves focus to the first accordion header |
104
+ | End | (Optional) Moves focus to the last accordion header |
105
+
106
+ Arrow/Home/End navigation is optional; Tab navigation between headers is always required.
107
+
108
+ ### Accessibility Rules
109
+
110
+ - Header MUST be wrapped in an `<h2>`–`<h6>` tag to maintain document outline — the heading level should match the surrounding page hierarchy
111
+ - The trigger MUST be a `<button>` (or `role="button"`) — `<div>` headers are inaccessible by keyboard
112
+ - `aria-expanded` MUST be on the trigger button, not the panel
113
+ - Panel SHOULD have `role="region"` + `aria-labelledby` referencing the trigger button id — this creates a named region for landmark navigation
114
+ - `role="region"` should be omitted if there are more than 6 accordions (too many regions = noisy landmark nav)
115
+ - Avoid `display:none` for the panel in open state — use `hidden` or height animation
116
+
117
+ ---
118
+
119
+ ## Motion
120
+
121
+ | Transition | Duration | Easing | Notes |
122
+ |------------|----------|--------|-------|
123
+ | Panel expand | 200ms | ease-out | Height 0→auto via `grid-template-rows` trick |
124
+ | Panel collapse | 150ms | ease-in | |
125
+ | Chevron rotate | 200ms | ease | 0→180deg |
126
+
127
+ **Height animation trick** (CSS-only, no JS measurement):
128
+ ```css
129
+ .panel { display: grid; grid-template-rows: 0fr; transition: grid-template-rows 200ms ease; }
130
+ .panel.open { grid-template-rows: 1fr; }
131
+ .panel > div { overflow: hidden; }
132
+ ```
133
+
134
+ Cross-link: `reference/motion.md` — `prefers-reduced-motion`: skip height animation, instant toggle
135
+
136
+ ---
137
+
138
+ ## Do / Don't
139
+
140
+ ### Do
141
+ - Wrap header triggers in proper heading tags (`<h2>`–`<h6>`) *(WAI-ARIA APG, Carbon)*
142
+ - Use `aria-expanded` on the trigger button, not on the panel *(WAI-ARIA APG)*
143
+ - Animate height with `grid-template-rows` trick — no JS height measurement needed *(CSS-only pattern)*
144
+ - Support Tab navigation between accordion headers at minimum *(WAI-ARIA APG)*
145
+
146
+ ### Don't
147
+ - Don't use `<div>` as the accordion header without `role="button"` *(WAI-ARIA APG)*
148
+ - Don't use `display:none` to hide the panel in collapsed state if you want animation — use CSS grid trick *(CSS pattern)*
149
+ - Don't use `role="region"` for more than 6 accordions — excessive landmarks harm screen reader navigation *(WAI-ARIA APG note)*
150
+ - Don't auto-close other panels in a "single-open" accordion without announcing the change *(Atlassian)*
151
+
152
+ ---
153
+
154
+ ## Anti-patterns Cross-links
155
+
156
+ | Anti-pattern | Entry |
157
+ |--------------|-------|
158
+ | div header without role="button" | `reference/anti-patterns.md` |
159
+ | aria-expanded on panel instead of button | `reference/anti-patterns.md` |
160
+
161
+ ---
162
+
163
+ ## Benchmark Citations
164
+
165
+ | Claim | Sources |
166
+ |-------|---------|
167
+ | Header in h2–h6 required | WAI-ARIA APG, Carbon |
168
+ | aria-expanded on trigger (not panel) | WAI-ARIA APG §3.1 |
169
+ | role="region" + aria-labelledby on panel | WAI-ARIA APG |
170
+ | Enter/Space to toggle | WAI-ARIA APG §3.1 |
171
+ | grid-template-rows for height animation | CSS-only pattern (no system-specific) |
172
+
173
+ Full system URLs: `connections/design-corpora.md`
174
+
175
+ ---
176
+
177
+ ## Grep Signatures
178
+
179
+ ```bash
180
+ # Accordion header not a button
181
+ grep -rn 'accordion\|Accordion' src/ | grep 'header\|trigger' | grep -v '<button\|role="button"'
182
+
183
+ # aria-expanded on wrong element (panel instead of trigger)
184
+ grep -rn 'aria-expanded' src/ | grep 'panel\|content\|body'
185
+
186
+ # display:none used on accordion panel (breaks animation)
187
+ grep -rn 'accordion.*panel\|panel.*accordion' src/ | grep 'display.*none'
188
+ ```
189
+
190
+ ---
191
+
192
+ ## Failing Example
193
+
194
+ ```html
195
+ <!-- BAD: div header — no keyboard access, no aria-expanded -->
196
+ <div class="accordion-header" onclick="toggle(1)">
197
+ What is the return policy?
198
+ </div>
199
+ <div id="panel-1" class="accordion-panel" style="display:none">
200
+ Our return policy is 30 days…
201
+ </div>
202
+ ```
203
+
204
+ **Why it fails**: `<div>` is not keyboard-operable (no Tab stop). No `aria-expanded`. Screen reader cannot determine expanded state. `display:none` prevents CSS animation.
205
+ **Grep detection**: `grep -rn 'class.*accordion.*header\|accordion-header' src/ | grep -v '<button\|role="button"'`
206
+ **Fix**:
207
+ ```html
208
+ <h3>
209
+ <button aria-expanded="false" aria-controls="panel-1" id="header-1">
210
+ What is the return policy?
211
+ <svg aria-hidden="true"><!-- chevron --></svg>
212
+ </button>
213
+ </h3>
214
+ <div id="panel-1" role="region" aria-labelledby="header-1" class="panel">
215
+ <div>Our return policy is 30 days…</div>
216
+ </div>
217
+ ```
@@ -0,0 +1,198 @@
1
+ # Alert / Banner — Benchmark Spec
2
+
3
+ **Harvested from**: Material 3 (Banner), Carbon (InlineNotification), Polaris (Banner), Atlassian (SectionMessage)
4
+ **Wave**: 3 · **Category**: Feedback
5
+
6
+ ---
7
+
8
+ ## Purpose
9
+
10
+ An alert (inline notification or banner) is a persistent in-page message that communicates status, warnings, or errors relevant to the current context. Unlike Toast, it does not auto-dismiss — it remains visible until the user dismisses it or the underlying condition resolves. Use alert for messages that require acknowledgement or that must remain visible for reference. *(Material 3, Carbon, Polaris, Atlassian agree: alert = persistent inline feedback)*
11
+
12
+ ---
13
+
14
+ ## Anatomy
15
+
16
+ ```
17
+ ┌─────────────────────────────────────────────────────────┐
18
+ │ [icon] [Title (optional)] [✕ dismiss?]│
19
+ │ Message text │
20
+ │ [Primary action?] [Secondary action?] │
21
+ └─────────────────────────────────────────────────────────┘
22
+ ↑ role="alert" (error/warning) or role="status" (info/success)
23
+ ```
24
+
25
+ | Part | Required | Notes |
26
+ |------|----------|-------|
27
+ | Container | Yes | `role="alert"` or `role="status"` per severity |
28
+ | Severity icon | Yes | Visual + semantic variant indicator; never color alone |
29
+ | Message text | Yes | Concise description of status or error |
30
+ | Title | No | Recommended for error/warning; provides quick scanning |
31
+ | Primary action | No | One CTA linking to resolution (e.g. "Retry", "Review") |
32
+ | Secondary action | No | Supplemental link; lower emphasis |
33
+ | Dismiss button | No | Required when alert can be resolved by user |
34
+
35
+ ---
36
+
37
+ ## Variants
38
+
39
+ | Variant | Description | Systems |
40
+ |---------|-------------|---------|
41
+ | Info | Blue; neutral informational message; `role="status"` polite | All |
42
+ | Success | Green; completed action confirmation; `role="status"` polite | All |
43
+ | Warning | Amber; potentially harmful condition; `role="alert"` assertive | All |
44
+ | Error | Red; failure or blocking condition; `role="alert"` assertive | All |
45
+
46
+ **Norm** (≥4/18 systems agree): four-variant semantic model (info/success/warning/error) with matching color, icon, and role. Icon is REQUIRED — color alone violates WCAG 1.4.1.
47
+ **Diverge**: Atlassian names this "SectionMessage" and omits dismiss; Carbon always includes an X; Polaris supports titled and untitled variants; Material 3 "Banner" supports one CTA only.
48
+
49
+ ---
50
+
51
+ ## States
52
+
53
+ | State | Trigger | Visual | ARIA |
54
+ |-------|---------|--------|------|
55
+ | visible | render | Full opacity, inline position | `role="alert"` or `role="status"` |
56
+ | hover | pointer over action | Action underline / background change | — |
57
+ | focus | keyboard on action/dismiss | focus-visible ring on button | — |
58
+ | dismissed | click dismiss button | Collapsed / removed | Removed from DOM |
59
+
60
+ ---
61
+
62
+ ## Sizing & Spacing
63
+
64
+ | Placement | Width | Radius | Padding |
65
+ |-----------|-------|--------|---------|
66
+ | Full-width (page/section) | 100% of container | 0px | 16px 20px |
67
+ | Inline / card-contained | fit-to-container | 6–8px | 12px 16px |
68
+
69
+ | Property | Value | Notes |
70
+ |----------|-------|-------|
71
+ | Icon size | 20px | Aligned to first line of text |
72
+ | Gap (icon → text) | 12px | |
73
+ | Min height | 48px single-line | Grows with content |
74
+
75
+ **Norm**: Full-width placement in page-level contexts; rounded corners for component-level inline placement *(Material 3, Carbon, Atlassian)*.
76
+
77
+ ---
78
+
79
+ ## Typography
80
+
81
+ - Title: label-md (14px/600) — gives quick scannable context for complex errors
82
+ - Message: body-sm (14px/400) — readable at inline scale
83
+ - Action: label-sm (13px/500) — matches action button label weight
84
+
85
+ Cross-link: `reference/typography.md` — body-sm, label-md definitions
86
+
87
+ ---
88
+
89
+ ## Keyboard & Accessibility
90
+
91
+ > **WAI-ARIA role**: `alert` (error/warning) or `status` (info/success)
92
+ > **Required attributes**: `role` on container; icon must have `aria-hidden="true"` + text-based variant reinforcement
93
+
94
+ ### Keyboard Contract
95
+
96
+ *Quoted verbatim from WAI-ARIA APG — https://www.w3.org/WAI/ARIA/apg/patterns/alert/ — W3C — 2024*
97
+
98
+ | Key | Action |
99
+ |-----|--------|
100
+ | Tab | Moves focus to action buttons or dismiss button in document order |
101
+ | Enter / Space | Activates focused action or dismiss button |
102
+ | Escape | No special behavior (unlike modal); alert stays visible |
103
+
104
+ The alert container itself is not focusable. Child buttons follow standard button keyboard contract.
105
+
106
+ ### Accessibility Rules
107
+
108
+ - Icon MUST be `aria-hidden="true"` — the icon is decorative reinforcement; the `role` and text carry the semantic meaning *(WCAG 1.4.1)*
109
+ - Color MUST NOT be the sole differentiator between variants — icon shape and text label must also differ *(WCAG 1.4.1)*
110
+ - `role="alert"` causes immediate assertion by screen readers — only use for error and warning severity
111
+ - `role="status"` uses a polite live region — appropriate for info and success
112
+ - Dismiss button MUST have `aria-label` (e.g. `aria-label="Dismiss warning"`) *(WAI-ARIA APG)*
113
+ - Do NOT auto-dismiss alerts — that is Toast's job; alert stays until explicitly dismissed *(Carbon, Polaris)*
114
+
115
+ Cross-link: `reference/accessibility.md` — live-regions, color-contrast sections
116
+
117
+ ---
118
+
119
+ ## Motion
120
+
121
+ | Transition | Duration | Easing | Notes |
122
+ |------------|----------|--------|-------|
123
+ | Enter (height expand + fade) | 200ms | ease-out | Pushes content down; avoids position:fixed |
124
+ | Exit (height collapse + fade) | 150ms | ease-in | Content reflows up as alert closes |
125
+ | Icon entrance | 0ms | — | No animation on icon; immediate |
126
+
127
+ **BAN**: Slide-in from edge (reserve for Toast). Alert is inline — it should feel like content appearing, not a notification arriving.
128
+
129
+ Cross-link: `reference/motion.md` — `prefers-reduced-motion`: skip height animation, instant show/hide
130
+
131
+ ---
132
+
133
+ ## Do / Don't
134
+
135
+ ### Do
136
+ - Always include an icon matching the semantic variant *(WCAG 1.4.1 — color not sole differentiator)*
137
+ - Use `role="alert"` for warning/error (assertive) and `role="status"` for info/success (polite) *(WAI-ARIA APG)*
138
+ - Keep alert visible until the condition is resolved or user dismisses *(Carbon, Polaris)*
139
+ - Use full-width for page-level alerts; rounded inline for component-level *(Material 3, Carbon)*
140
+
141
+ ### Don't
142
+ - Don't auto-dismiss alerts — use Toast for transient messages *(Material 3, Carbon)*
143
+ - Don't use color alone to distinguish severity — always include an icon and text label *(WCAG 1.4.1)*
144
+ - Don't stack more than 2 alerts in the same section — consolidate into a single summary *(Polaris)*
145
+ - Don't use `role="alert"` for info/success — overly assertive announcements desensitize users *(WAI-ARIA APG)*
146
+
147
+ ---
148
+
149
+ ## Anti-patterns Cross-links
150
+
151
+ | Anti-pattern | Entry |
152
+ |--------------|-------|
153
+ | Color as sole variant differentiator | `reference/anti-patterns.md#ban-color-only` |
154
+ | role="alert" on info/success (over-announcing) | `reference/anti-patterns.md#ban-live-region` |
155
+
156
+ ---
157
+
158
+ ## Benchmark Citations
159
+
160
+ | Claim | Sources |
161
+ |-------|---------|
162
+ | Icon required; color not sole differentiator | WCAG 1.4.1; Material 3, Carbon, Polaris, Atlassian |
163
+ | role="alert" for error/warning; role="status" for info/success | WAI-ARIA APG, Carbon, Polaris |
164
+ | No auto-dismiss | Material 3, Carbon, Polaris, Atlassian |
165
+ | Full-width vs. rounded inline placement | Material 3, Carbon, Atlassian |
166
+ | Dismiss button requires aria-label | WAI-ARIA APG |
167
+
168
+ Full system URLs: `connections/design-corpora.md`
169
+
170
+ ---
171
+
172
+ ## Grep Signatures
173
+
174
+ ```bash
175
+ # Alert missing role attribute entirely
176
+ grep -rn 'alert\|Alert\|banner\|Banner\|notification' src/ | grep 'class=\|className=' | grep -v 'role='
177
+
178
+ # Error/warning alert using role="status" instead of role="alert"
179
+ grep -rn 'role="status"' src/ | grep -i 'error\|warning\|danger'
180
+
181
+ # Color-only differentiation — severity class with no icon reference
182
+ grep -rn 'alert--error\|alert--warning\|alert-error\|alert-warning' src/ | grep -v 'icon\|Icon\|svg\|SVG'
183
+ ```
184
+
185
+ ---
186
+
187
+ ## Failing Example
188
+
189
+ ```html
190
+ <!-- BAD: alert using only color class — no icon, no role, no text variant label -->
191
+ <div class="alert alert--error">
192
+ Your session has expired. Please log in again.
193
+ </div>
194
+ ```
195
+
196
+ **Why it fails**: No `role="alert"` so screen readers do not announce the error message. Color class alone distinguishes severity — users with color blindness or high-contrast themes cannot distinguish this from a neutral message. No icon provides a shape-based cue.
197
+ **Grep detection**: `grep -rn 'class.*alert--error\|class.*alert-error' src/ | grep -v 'role='`
198
+ **Fix**: Add `role="alert"`, include an error icon with `aria-hidden="true"`, and ensure the variant is communicated through text or visually-hidden label in addition to color.