ux-ui-agent-skills 1.1.0 → 1.2.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.
- package/CLAUDE.md +40 -7
- package/README.md +27 -12
- package/accessibility/aria-patterns.md +44 -0
- package/accessibility/cognitive.md +51 -0
- package/accessibility/i18n-rtl.md +47 -0
- package/accessibility/vision.md +43 -0
- package/accessibility/wcag-aaa.md +45 -0
- package/components/data-display.md +71 -0
- package/components/data-viz.md +55 -0
- package/components/icon-system.md +51 -0
- package/design-systems/crosswalk.md +34 -4
- package/frameworks/adapters/astro.md +44 -0
- package/frameworks/adapters/bootstrap.md +36 -0
- package/frameworks/adapters/chakra.md +47 -0
- package/frameworks/adapters/mantine.md +44 -0
- package/frameworks/adapters/mui.md +44 -0
- package/frameworks/adapters/qwik.md +48 -0
- package/package.json +2 -2
- package/tokens/data-viz.json +60 -0
- package/workflows/design-qa.md +51 -0
- package/workflows/figma-integration.md +42 -0
- package/workflows/governance.md +48 -0
- package/workflows/performance.md +43 -0
- package/workflows/token-build.md +53 -0
package/CLAUDE.md
CHANGED
|
@@ -108,6 +108,7 @@ All tokens use **DTCG format** (Design Tokens Community Group) with `$type`/`$va
|
|
|
108
108
|
- `tokens/sizing.json` — Control size scale + icon sizes + aspect ratios
|
|
109
109
|
- `tokens/states.json` — Semantic interaction-state tokens for the 8 component states
|
|
110
110
|
- `tokens/theming.json` — Multi-brand theme override map + density modes (compact/default/spacious)
|
|
111
|
+
- `tokens/data-viz.json` — Color-blind-aware chart palette (categorical/sequential/diverging) + axis/grid/tooltip tokens
|
|
111
112
|
|
|
112
113
|
### Naming Convention
|
|
113
114
|
```
|
|
@@ -240,7 +241,11 @@ All interactive components must define these states:
|
|
|
240
241
|
|
|
241
242
|
### Implementation Reference
|
|
242
243
|
- Full checklist: `accessibility/wcag-checklist.md`
|
|
243
|
-
- ARIA patterns for
|
|
244
|
+
- ARIA patterns for 19 components: `accessibility/aria-patterns.md`
|
|
245
|
+
- Cognitive accessibility (load, plain language, memory, dyslexia, reduced-data): `accessibility/cognitive.md`
|
|
246
|
+
- Internationalization & RTL (logical properties, mirroring, text expansion): `accessibility/i18n-rtl.md`
|
|
247
|
+
- Vision (color blindness, low vision, high-contrast / forced-colors): `accessibility/vision.md`
|
|
248
|
+
- AAA upgrade delta (when targeting the highest support level): `accessibility/wcag-aaa.md`
|
|
244
249
|
|
|
245
250
|
---
|
|
246
251
|
|
|
@@ -382,6 +387,19 @@ Full workflow: `workflows/design-to-code.md`
|
|
|
382
387
|
|
|
383
388
|
---
|
|
384
389
|
|
|
390
|
+
## Operations & Pipeline
|
|
391
|
+
|
|
392
|
+
Keeping the system healthy at scale — governance, build, sync, QA, and performance:
|
|
393
|
+
|
|
394
|
+
- **Governance** — versioning (SemVer for tokens/components), contribution path, deprecation policy, change communication: `workflows/governance.md`.
|
|
395
|
+
- **Token build pipeline** — transform `tokens/*.json` (source of truth) → CSS vars / Tailwind `@theme` / iOS Asset Catalog / Android / Compose via Style Dictionary or Tokens Studio (DTCG): `workflows/token-build.md`.
|
|
396
|
+
- **Figma integration** — token ↔ Figma Variable sync (3-tier collections + modes), Figma MCP usage, component parity: `workflows/figma-integration.md`.
|
|
397
|
+
- **Design QA** — automated gates (token validation, axe a11y, visual regression across variants/states/themes/RTL) + manual a11y per release: `workflows/design-qa.md`.
|
|
398
|
+
- **Performance** — Core Web Vitals (LCP/INP/CLS) budgets, loading/code-split strategy, layout-shift and animation-perf rules: `workflows/performance.md`.
|
|
399
|
+
- **Icon system** — grid/stroke/sizing tokens, delivery, and a11y for icons as a governed subsystem: `components/icon-system.md`.
|
|
400
|
+
|
|
401
|
+
---
|
|
402
|
+
|
|
385
403
|
## Output Format Instructions
|
|
386
404
|
|
|
387
405
|
When responding to user requests, match the output format to the request type:
|
|
@@ -414,7 +432,8 @@ tokens/ ← Design tokens (DTCG $type/$value)
|
|
|
414
432
|
├── blur.json ← Backdrop / frosted-glass blur scale
|
|
415
433
|
├── sizing.json ← Control sizes + icon sizes + aspect ratios
|
|
416
434
|
├── states.json ← Semantic interaction-state tokens (the 8 states)
|
|
417
|
-
|
|
435
|
+
├── theming.json ← Multi-brand theme overrides + density modes
|
|
436
|
+
└── data-viz.json ← Chart palette (categorical/sequential/diverging) + axis/grid
|
|
418
437
|
|
|
419
438
|
taste/ ← Aesthetic judgment layer (serves the Aesthetics tier)
|
|
420
439
|
├── design-taste.md ← Anti-slop doctrine, banned defaults, pre-flight aesthetic check
|
|
@@ -423,7 +442,8 @@ taste/ ← Aesthetic judgment layer (serves the Aesthetics ti
|
|
|
423
442
|
|
|
424
443
|
design-systems/ ← Interop + brand library
|
|
425
444
|
├── interop-protocol.md ← Map to/from ANY design system (crosswalk method)
|
|
426
|
-
├── crosswalk.md ← Curated tables: Material 3, Apple HIG, Fluent, Carbon, shadcn, Radix
|
|
445
|
+
├── crosswalk.md ← Curated tables: Material 3, Apple HIG, Fluent, Carbon, shadcn, Radix,
|
|
446
|
+
│ Ant, Polaris, Primer, Atlassian, Bootstrap
|
|
427
447
|
└── library/<name>/DESIGN.md ← 138 brand-grade design-system specs
|
|
428
448
|
|
|
429
449
|
content/
|
|
@@ -437,24 +457,37 @@ components/
|
|
|
437
457
|
├── navigation.md ← Tabs, Breadcrumb, Pagination, Stepper, Menu
|
|
438
458
|
├── feedback.md ← Toast, Banner, Skeleton, Progress, Empty State
|
|
439
459
|
├── forms-advanced.md ← Combobox, Select, Slider, Date Picker, File Upload
|
|
440
|
-
|
|
460
|
+
├── overlays.md ← Popover, Command Palette, Divider
|
|
461
|
+
├── data-display.md ← Calendar, Carousel, Tree
|
|
462
|
+
├── data-viz.md ← Charts: Bar, Line/Area, Pie/Donut, Sparkline, Scatter
|
|
463
|
+
└── icon-system.md ← Icon grid/stroke/sizing tokens + delivery + a11y
|
|
441
464
|
|
|
442
465
|
accessibility/
|
|
443
466
|
├── wcag-checklist.md ← WCAG 2.2 AA/AAA checklist by POUR principle
|
|
444
|
-
|
|
467
|
+
├── aria-patterns.md ← WAI-ARIA patterns for 19 components
|
|
468
|
+
├── cognitive.md ← Cognitive load, plain language, memory/attention, dyslexia, reduced-data
|
|
469
|
+
├── i18n-rtl.md ← Logical properties, RTL mirroring, text expansion, locale formatting
|
|
470
|
+
├── vision.md ← Color blindness, low vision, high-contrast / forced-colors
|
|
471
|
+
└── wcag-aaa.md ← AAA upgrade delta (7:1 contrast, 44px targets, no-timing…)
|
|
445
472
|
|
|
446
473
|
workflows/
|
|
447
474
|
├── design-review.md ← Review rubric, Nielsen heuristics, audit process
|
|
448
475
|
├── design-to-code.md ← Handoff workflow, state docs, edge cases, definition of done
|
|
449
476
|
├── prototyping.md ← 5-level fidelity ladder, user journey mapping, usability testing
|
|
450
|
-
|
|
477
|
+
├── redesign-audit.md ← Audit-first redesign + output completeness
|
|
478
|
+
├── governance.md ← Versioning (SemVer), contribution, deprecation, change comms
|
|
479
|
+
├── token-build.md ← Token pipeline → CSS/Tailwind/iOS/Android (Style Dictionary, DTCG)
|
|
480
|
+
├── figma-integration.md ← Token↔Variable sync, Figma MCP, component parity
|
|
481
|
+
├── design-qa.md ← Visual regression + a11y CI gates (axe, snapshots)
|
|
482
|
+
└── performance.md ← Core Web Vitals, loading, CLS, animation perf
|
|
451
483
|
|
|
452
484
|
frameworks/
|
|
453
485
|
├── adapter-protocol.md ← Universal contract to target ANY framework
|
|
454
486
|
├── react-tailwind.md ← React 19 + Tailwind v4 + TypeScript + cva patterns
|
|
455
487
|
├── nextjs.md ← Next.js 15 App Router patterns
|
|
456
488
|
├── swiftui.md ← SwiftUI 6 + Dynamic Type + platform adaptation
|
|
457
|
-
└── adapters/ ← vue, svelte, angular, solid, web-components-lit,
|
|
489
|
+
└── adapters/ ← vue, svelte, angular, solid, web-components-lit, qwik, astro,
|
|
490
|
+
mui, mantine, chakra, bootstrap,
|
|
458
491
|
react-native, flutter, jetpack-compose, vanilla-css, css-in-js
|
|
459
492
|
|
|
460
493
|
.claude/skills/ ← Runnable skills (invoke via /name): design-tokens, design-component,
|
package/README.md
CHANGED
|
@@ -8,17 +8,19 @@ A comprehensive kit of structured instructions, design tokens, runnable skills,
|
|
|
8
8
|
|
|
9
9
|
<br>
|
|
10
10
|
|
|
11
|
-
[](https://github.com/plugin87/ux-ui-agent-skills/releases)
|
|
12
12
|
[](#-license)
|
|
13
|
-
[](#-accessibility-standards)
|
|
13
|
+
[](#-accessibility-standards)
|
|
14
14
|
|
|
15
15
|
<br>
|
|
16
16
|
|
|
17
|
-
](https://www.npmjs.com/package/ux-ui-agent-skills)
|
|
18
|
+
[](https://www.npmjs.com/package/ux-ui-agent-skills)
|
|
18
19
|

|
|
19
20
|

|
|
20
21
|

|
|
21
22
|

|
|
23
|
+

|
|
22
24
|

|
|
23
25
|

|
|
24
26
|

|
|
@@ -30,7 +32,7 @@ A comprehensive kit of structured instructions, design tokens, runnable skills,
|
|
|
30
32
|
|
|
31
33
|
## 📌 Version
|
|
32
34
|
|
|
33
|
-
**Current release: `v1.
|
|
35
|
+
**Current release: `v1.2.0`** · See the [Changelog](#-changelog) · [All releases](https://github.com/plugin87/ux-ui-agent-skills/releases)
|
|
34
36
|
|
|
35
37
|
> No build tools, dependencies, or runtime required — this is a pure instruction & knowledge layer for AI agents.
|
|
36
38
|
|
|
@@ -188,27 +190,32 @@ python3 scripts/scaffold_component.py "Date Picker" # emit a component spec stub
|
|
|
188
190
|
├── design-systems/ # 🔌 Interop + brand library
|
|
189
191
|
│ ├── interop-protocol.md # Map to/from ANY design system
|
|
190
192
|
│ ├── crosswalk.md # Material 3 · Apple HIG · Fluent · Carbon · shadcn · Radix
|
|
193
|
+
│ │ # · Ant · Polaris · Primer · Atlassian · Bootstrap
|
|
191
194
|
│ └── library/<name>/ # 138 brand-grade DESIGN.md specs
|
|
192
195
|
│
|
|
193
196
|
├── content/ # UX writing & content design
|
|
194
197
|
│ └── voice-tone.md # Voice & tone, error/empty-state copy, microcopy, inclusive language
|
|
195
198
|
│
|
|
196
|
-
├── components/ # Component specs (Atomic Design) —
|
|
199
|
+
├── components/ # Component specs (Atomic Design) — 50 components
|
|
197
200
|
│ ├── atoms · molecules · organisms · templates
|
|
198
|
-
│
|
|
201
|
+
│ ├── navigation · feedback · forms-advanced · overlays
|
|
202
|
+
│ └── data-display · data-viz · icon-system
|
|
199
203
|
│
|
|
200
|
-
├── accessibility/ # WCAG & ARIA references
|
|
204
|
+
├── accessibility/ # WCAG & ARIA references + inclusive design
|
|
201
205
|
│ ├── wcag-checklist.md # WCAG 2.2 checklist (POUR, P0/P1/P2)
|
|
202
|
-
│
|
|
206
|
+
│ ├── aria-patterns.md # WAI-ARIA patterns for 19 components
|
|
207
|
+
│ ├── cognitive.md · vision.md · i18n-rtl.md # cognitive · low-vision/CVD/forced-colors · RTL
|
|
208
|
+
│ └── wcag-aaa.md # AAA upgrade delta
|
|
203
209
|
│
|
|
204
|
-
├── workflows/ # Design process guides
|
|
205
|
-
│ ├── design-review.md · design-to-code.md · prototyping.md
|
|
206
|
-
│ └──
|
|
210
|
+
├── workflows/ # Design process + ops/pipeline guides
|
|
211
|
+
│ ├── design-review.md · design-to-code.md · prototyping.md · redesign-audit.md
|
|
212
|
+
│ └── governance.md · token-build.md · figma-integration.md · design-qa.md · performance.md
|
|
207
213
|
│
|
|
208
214
|
└── frameworks/ # Implementation patterns — ANY framework
|
|
209
215
|
├── adapter-protocol.md # Universal translation contract
|
|
210
216
|
├── react-tailwind.md · nextjs.md · swiftui.md # full references
|
|
211
|
-
└── adapters/ # vue · svelte · angular · solid · web-components-lit
|
|
217
|
+
└── adapters/ # vue · svelte · angular · solid · web-components-lit · qwik · astro
|
|
218
|
+
# mui · mantine · chakra · bootstrap
|
|
212
219
|
# react-native · flutter · jetpack-compose · vanilla-css · css-in-js
|
|
213
220
|
```
|
|
214
221
|
|
|
@@ -308,6 +315,14 @@ This is a **starter kit** — make it yours:
|
|
|
308
315
|
|
|
309
316
|
## 📝 Changelog
|
|
310
317
|
|
|
318
|
+
### `v1.2.0`
|
|
319
|
+
- 🧩 **8 new component specs** — `data-display.md` (Calendar, Carousel, Tree) + `data-viz.md` (Bar, Line/Area, Pie/Donut, Sparkline, Scatter) → **50 components**; plus `components/icon-system.md`
|
|
320
|
+
- 📊 **Data-viz tokens** — `tokens/data-viz.json`: color-blind-aware (Okabe–Ito) categorical/sequential/diverging palettes + axis/grid/tooltip → **14 token files**
|
|
321
|
+
- ⟨⟩ **6 new framework adapters** — Qwik, Astro, **MUI**, Mantine, Chakra, Bootstrap → **16 adapters**
|
|
322
|
+
- 🔌 **Extended interop crosswalks** — Ant Design 5, Shopify Polaris, GitHub Primer, Atlassian, Bootstrap (color-role tables + per-system notes)
|
|
323
|
+
- ♿ **Accessibility depth** — `cognitive.md` (load, plain language, dyslexia, reduced-data), `i18n-rtl.md` (logical properties, RTL mirroring, text expansion), `vision.md` (color blindness, low vision, forced-colors), `wcag-aaa.md` (AAA upgrade delta); +4 ARIA patterns (Carousel, Grid, Toolbar, Feed)
|
|
324
|
+
- ⚙️ **Ops & pipeline workflows** — `governance.md` (SemVer, contribution, deprecation), `token-build.md` (Style Dictionary / DTCG → multi-platform), `figma-integration.md` (token↔Variable sync, Figma MCP), `design-qa.md` (visual regression + a11y CI), `performance.md` (Core Web Vitals)
|
|
325
|
+
|
|
311
326
|
### `v1.1.0`
|
|
312
327
|
- 📦 **npm package** — install into any project with `npx ux-ui-agent-skills init` (zero-dependency CLI: `init` / `add` / `list`, `--force`/`--dry`)
|
|
313
328
|
- ⚡ **Runnable skills** — 10 invocable `/skills` under `.claude/skills/` + real helper scripts (`validate_tokens.py`, `contrast.py`, `design_systems.py`, `scaffold_component.py`)
|
|
@@ -485,6 +485,50 @@ A text input with a popup listbox for suggestions.
|
|
|
485
485
|
|
|
486
486
|
---
|
|
487
487
|
|
|
488
|
+
## 16. Carousel
|
|
489
|
+
|
|
490
|
+
Browsable slide set (`components/data-display.md`).
|
|
491
|
+
|
|
492
|
+
**Roles:** container `role="group"` (or `region`) + `aria-roledescription="carousel"` + `aria-label`. Each slide `role="group"` + `aria-roledescription="slide"` + `aria-label="N of M"`.
|
|
493
|
+
|
|
494
|
+
**Keyboard:** Prev/Next/dots are real `<button>`s, reachable by Tab and activated by Enter/Space. Off-screen slides `inert`/`aria-hidden`.
|
|
495
|
+
|
|
496
|
+
**Auto-rotation (WCAG 2.2.2):** visible Pause/Play control; pause on hover and on keyboard focus within. Rotating region `aria-live="off"` while auto-advancing, switch to `"polite"` after the user takes manual control. Disable autoplay under `prefers-reduced-motion`.
|
|
497
|
+
|
|
498
|
+
---
|
|
499
|
+
|
|
500
|
+
## 17. Grid (Calendar / Data Grid)
|
|
501
|
+
|
|
502
|
+
Two-dimensional navigable cells — date pickers (`components/data-display.md`) and interactive tables.
|
|
503
|
+
|
|
504
|
+
**Roles:** `role="grid"` → `role="row"` → `role="gridcell"` (or `columnheader`/`rowheader`). For a date grid, column headers carry weekday names (`abbr`).
|
|
505
|
+
|
|
506
|
+
**Keyboard (roving tabindex — one cell tabbable):** Arrow keys move between cells; Home/End to row edges; Ctrl+Home/End to grid corners; PageUp/Down for month (calendar); Enter/Space selects/activates. Selected cell `aria-selected="true"`; today `aria-current="date"`.
|
|
507
|
+
|
|
508
|
+
**Announce:** month/year changes via a polite live region; for data grids, expose sort state with `aria-sort` on the header.
|
|
509
|
+
|
|
510
|
+
---
|
|
511
|
+
|
|
512
|
+
## 18. Toolbar
|
|
513
|
+
|
|
514
|
+
Grouped set of controls (formatting bars, chart actions).
|
|
515
|
+
|
|
516
|
+
**Roles:** `role="toolbar"` + `aria-label` (or `aria-orientation` if vertical).
|
|
517
|
+
|
|
518
|
+
**Keyboard (roving tabindex):** Toolbar is a single tab stop; Left/Right (or Up/Down when vertical) move between controls; Home/End jump to first/last. Tab moves *out* of the toolbar. Nested controls keep their own activation keys.
|
|
519
|
+
|
|
520
|
+
---
|
|
521
|
+
|
|
522
|
+
## 19. Feed
|
|
523
|
+
|
|
524
|
+
Scrollable stream of comparable articles (timelines, infinite lists).
|
|
525
|
+
|
|
526
|
+
**Roles:** container `role="feed"` (+ `aria-busy` while loading more); each item `role="article"` with `aria-labelledby`, `aria-posinset`, and `aria-setsize` (use a large/estimated value for infinite feeds).
|
|
527
|
+
|
|
528
|
+
**Keyboard:** PageDown/PageUp move between articles; Home/End to first/last loaded; focus moves *into* article content with Tab. Load more before the user reaches the end to avoid focus loss.
|
|
529
|
+
|
|
530
|
+
---
|
|
531
|
+
|
|
488
532
|
## General Patterns
|
|
489
533
|
|
|
490
534
|
### Focus Indicator Spec
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Cognitive Accessibility
|
|
2
|
+
|
|
3
|
+
Designing for memory, attention, language processing, and executive function. Covers WCAG 2.2's cognitive-focused criteria (3.2.6, 3.3.7, 3.3.8) and goes beyond them. Cognitive load is the most common, least-tested barrier — these rules help everyone, not just users with cognitive disabilities.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Core principles
|
|
8
|
+
|
|
9
|
+
1. **Reduce load, don't add it.** Every field, choice, and step has a cost. Remove before you explain.
|
|
10
|
+
2. **Don't make people remember.** Recognition over recall — show options, keep entered data visible, persist context across steps.
|
|
11
|
+
3. **One primary action per view.** Progressive disclosure (CLAUDE.md) hides secondary/advanced paths until needed.
|
|
12
|
+
4. **Be predictable.** Consistent navigation/identification (WCAG 3.2.3/3.2.4); no context changes on focus or input (3.2.1/3.2.2).
|
|
13
|
+
5. **Forgive errors.** Confirm destructive actions, allow undo, autosave, and let users review before submit (3.3.4 / 3.3.6).
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Plain language
|
|
18
|
+
|
|
19
|
+
- Target a lower-secondary reading level for general UI; frontload the point (`content/voice-tone.md`).
|
|
20
|
+
- Short sentences, common words, active voice. Expand or avoid jargon, idioms, and acronyms (define on first use).
|
|
21
|
+
- One idea per paragraph; use lists and headings to chunk.
|
|
22
|
+
|
|
23
|
+
## Memory & attention
|
|
24
|
+
|
|
25
|
+
- **Accessible Authentication (3.3.8 AA / 3.3.7 AA):** never require recalling/transcribing codes, solving puzzles, or re-entering info already provided. Allow password managers (don't block paste), support passkeys/email-link, and offer "Show password".
|
|
26
|
+
- Keep instructions visible *while* the task is performed — don't put them only in a dismissed dialog.
|
|
27
|
+
- Avoid timeouts; if unavoidable, warn and allow extension (WCAG 2.2.1). Persist progress so a lapse doesn't lose work.
|
|
28
|
+
- Minimize concurrent decisions; default sensible values; remember preferences.
|
|
29
|
+
|
|
30
|
+
## Executive function & task flow
|
|
31
|
+
|
|
32
|
+
- Break long flows into clear steps with a Stepper (`components/navigation.md`) showing where the user is and what remains.
|
|
33
|
+
- Show progress and expected effort ("Step 2 of 4 · ~2 min").
|
|
34
|
+
- Make the next action obvious; never hide the only way forward behind a gesture or hover.
|
|
35
|
+
|
|
36
|
+
## Dyslexia & reading
|
|
37
|
+
|
|
38
|
+
- Body text ≥ 16px; generous line height (1.5) and paragraph spacing; line length 45–75ch (CLAUDE.md typography).
|
|
39
|
+
- Left-align body text — **never justify** (uneven "rivers" of space hurt tracking). Avoid all-caps for running text.
|
|
40
|
+
- Use a clean sans (Inter/system-ui) or an OpenDyslexic option; never convey meaning by italics alone.
|
|
41
|
+
- Strong heading hierarchy and whitespace so structure is scannable.
|
|
42
|
+
|
|
43
|
+
## Reduced-data / low-bandwidth
|
|
44
|
+
|
|
45
|
+
- Respect `prefers-reduced-data` (Save-Data): skip autoplay media, heavy fonts, and large hero images; serve text-first.
|
|
46
|
+
- Don't block core tasks behind large downloads; show lightweight skeletons (`components/feedback.md`) over spinners-then-jank.
|
|
47
|
+
|
|
48
|
+
## Verification
|
|
49
|
+
- Read every label/error aloud — does a tired, distracted first-time user understand it?
|
|
50
|
+
- Can the task complete without remembering anything from a previous screen?
|
|
51
|
+
- Does any timeout, puzzle, or transcription step exist? If so, remove or provide an exemption path.
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Internationalization & RTL
|
|
2
|
+
|
|
3
|
+
Design and build so the UI works in any language and writing direction. The cheapest time to internationalize is before launch; retrofitting bidi and text-expansion is expensive. Bake logical properties and externalized strings in from the start.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Logical properties (the foundation)
|
|
8
|
+
|
|
9
|
+
Use **flow-relative** CSS, never physical, so layout mirrors automatically for RTL:
|
|
10
|
+
|
|
11
|
+
| Physical (avoid) | Logical (use) |
|
|
12
|
+
|------------------|---------------|
|
|
13
|
+
| `margin-left` / `padding-right` | `margin-inline-start` / `padding-inline-end` |
|
|
14
|
+
| `left` / `right` | `inset-inline-start` / `inset-inline-end` |
|
|
15
|
+
| `text-align: left` | `text-align: start` |
|
|
16
|
+
| `border-left` | `border-inline-start` |
|
|
17
|
+
| `width` / `height` | `inline-size` / `block-size` |
|
|
18
|
+
|
|
19
|
+
Our token CSS already uses `block-size`/`padding-inline` (see `frameworks/adapters/*`). Set direction once: `<html dir="rtl" lang="ar">` — children inherit. In SwiftUI/Compose/Flutter use the native start/end leading/trailing equivalents (`leadingMargin`, `MaterialLocalizations`, `Directionality`).
|
|
20
|
+
|
|
21
|
+
## RTL mirroring rules
|
|
22
|
+
|
|
23
|
+
- **Mirror:** layout flow, alignment, icons that imply direction (arrows, back/forward, send, progress, chevrons), sliders, breadcrumbs, carousels.
|
|
24
|
+
- **Do NOT mirror:** time-independent media, logos, phone numbers, code, checkmarks, most pictographic icons (clock, search rarely), media playback controls (play stays ▶ in many locales — verify per market).
|
|
25
|
+
- Numbers and embedded LTR runs (URLs, emails, code) inside RTL text need bidi isolation: `<bdi>` / `unicode-bidi: isolate` to prevent reordering glitches.
|
|
26
|
+
|
|
27
|
+
## Text expansion
|
|
28
|
+
|
|
29
|
+
- Translations run **+30–40% longer** than English (German/Finnish more); CJK can be shorter but taller.
|
|
30
|
+
- Never fix widths to English text. Let buttons/labels grow; allow wrapping; avoid truncation on essential labels (or provide full text on hover/focus + `title`).
|
|
31
|
+
- Test layouts with a pseudo-locale (e.g. `[!!! Ŝȧṽḗ ƈħȧńɠḗŝ !!!]`) to catch clipping, overlap, and concatenation bugs early.
|
|
32
|
+
- Don't build sentences by concatenating fragments — word order differs per language. Use full strings with named placeholders (`{count} items`), and use ICU plural/select for grammatical number/gender.
|
|
33
|
+
|
|
34
|
+
## Locale-aware formatting
|
|
35
|
+
|
|
36
|
+
- Format dates, times, numbers, currency, and units with `Intl.*` (or platform equivalents) — never hand-format. Respect locale decimal/thousands separators and first-day-of-week (affects the Calendar in `components/data-display.md`).
|
|
37
|
+
- Names, addresses, and phone formats vary — don't assume first/last name or US address shape.
|
|
38
|
+
|
|
39
|
+
## Fonts & typography
|
|
40
|
+
|
|
41
|
+
- Choose a font (or stack) with the required script coverage (Arabic, Hebrew, Devanagari, Thai, CJK). Verify line-height accommodates tall scripts (Thai/Arabic diacritics clip at tight leading).
|
|
42
|
+
- `font-feature-settings`/optical sizing differ per script; don't letter-space non-Latin text.
|
|
43
|
+
|
|
44
|
+
## Verification
|
|
45
|
+
- Flip `dir="rtl"` — does the whole layout mirror, with directional icons flipped and no hard-coded left/right?
|
|
46
|
+
- Run the pseudo-locale — any clipped, overlapped, or concatenated strings?
|
|
47
|
+
- Are all user-facing strings externalized (zero hard-coded copy) and formatted via `Intl`?
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Vision Accessibility — Low Vision, Color Blindness, High Contrast
|
|
2
|
+
|
|
3
|
+
Beyond the baseline contrast ratios (CLAUDE.md Color Guidelines), this covers users with low vision, color vision deficiency (CVD), light sensitivity, and OS-level high-contrast/forced-colors modes.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Color vision deficiency (CVD)
|
|
8
|
+
|
|
9
|
+
~8% of men, ~0.5% of women. Red–green (deutan/protan) is most common; blue–yellow (tritan) rarer; full achromatopsia rarest.
|
|
10
|
+
|
|
11
|
+
- **Never encode meaning in hue alone** (WCAG 1.4.1) — pair every color signal with icon, text, shape, or pattern. Red/green status, chart series, required-field marks, map regions: all need a second channel.
|
|
12
|
+
- Don't rely on red-vs-green to distinguish success/error — add ✓/✕ icons and labels.
|
|
13
|
+
- Charts: distinguish series by **marker shape + dash pattern + direct labels**, and use the CVD-safe palette in `tokens/data-viz.json` (Okabe–Ito-derived). Cap categorical series.
|
|
14
|
+
- Test with a simulator (deuteranopia, protanopia, tritanopia, grayscale) — if information disappears in grayscale, it failed.
|
|
15
|
+
|
|
16
|
+
## Low vision
|
|
17
|
+
|
|
18
|
+
- Support **200% zoom with no loss of content/function** (WCAG 1.4.4) and **400% reflow** to a single column at 320px width (1.4.10) — this is why we use logical properties + relative units, not fixed px layouts.
|
|
19
|
+
- Respect the user's **base font size** — size type in `rem`, never lock `html { font-size }` to px. Honor browser/OS text scaling (SwiftUI Dynamic Type via `@ScaledMetric`; Android `sp`).
|
|
20
|
+
- **Text spacing override (1.4.12):** content must survive user-applied line-height 1.5, paragraph 2×, letter 0.12em, word 0.16em — don't clip with fixed heights.
|
|
21
|
+
- Keep a visible, high-contrast focus indicator (≥ 3:1, `shadow.focus-ring`) and don't let sticky headers obscure it (WCAG 2.4.11).
|
|
22
|
+
- Maintain a clear visual hierarchy and generous spacing so magnifier users keep context.
|
|
23
|
+
|
|
24
|
+
## Light sensitivity & dark mode
|
|
25
|
+
|
|
26
|
+
- Offer both light and dark themes (semantic tokens auto-swap — CLAUDE.md Dark Mode). Honor `prefers-color-scheme`.
|
|
27
|
+
- Avoid pure-black-on-pure-white for large text blocks if it causes halation; our `surface.page`/`text.primary` are tuned for comfort.
|
|
28
|
+
- No flashing > 3×/sec (WCAG 2.3.1) — seizure safety.
|
|
29
|
+
|
|
30
|
+
## High-contrast / forced-colors mode
|
|
31
|
+
|
|
32
|
+
Windows High Contrast / `forced-colors: active` overrides author colors with a system palette.
|
|
33
|
+
|
|
34
|
+
- Use `@media (forced-colors: active)` to adapt; rely on **system color keywords** (`CanvasText`, `Canvas`, `ButtonText`, `LinkText`, `Highlight`) rather than hard-coded hex.
|
|
35
|
+
- Don't convey state with background-color alone — it gets flattened. Add borders/outlines/icons that survive.
|
|
36
|
+
- Set `forced-color-adjust: auto` (default) for most UI; use `none` only for things that must keep brand color (e.g. a chart swatch) — and verify a non-color cue remains.
|
|
37
|
+
- Test: icons drawn with CSS background-images can vanish — use real `<svg>` with `currentColor` so they pick up the forced color.
|
|
38
|
+
|
|
39
|
+
## Verification
|
|
40
|
+
- Grayscale the screen — is any status/required/series still distinguishable?
|
|
41
|
+
- Zoom to 400% — does content reflow to one column with nothing lost or overlapping?
|
|
42
|
+
- Toggle Windows High Contrast / emulate `forced-colors` — do borders, focus, and icons survive?
|
|
43
|
+
- Apply the 1.4.12 text-spacing bookmarklet — any clipping?
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# WCAG 2.2 AAA — Upgrade Guide
|
|
2
|
+
|
|
3
|
+
AA is our minimum (CLAUDE.md). This is the **AAA delta** — the additional success criteria to target when a product serves users who need the highest support (government, healthcare, education, accessibility-first brands). AAA is rarely required wholesale; adopt the criteria that fit the audience.
|
|
4
|
+
|
|
5
|
+
> Conformance note: W3C states AAA conformance is not achievable for all content. Treat this as a prioritized enhancement list, not a pass/fail gate.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Perceivable
|
|
10
|
+
|
|
11
|
+
| Criterion | AAA bar (vs. AA) | How |
|
|
12
|
+
|-----------|------------------|-----|
|
|
13
|
+
| 1.4.6 Contrast (Enhanced) | **7:1** normal / **4.5:1** large (AA was 4.5/3) | Verify `text.primary` (already ~15:1 ✓); bump `text.secondary` pairings; check `scripts/contrast.py` |
|
|
14
|
+
| 1.4.8 Visual Presentation | line ≤ 80ch, line-height ≥ 1.5, no justification, user color/width control | Our typography defaults comply; add a width/theme control |
|
|
15
|
+
| 1.4.9 Images of Text (No Exception) | no text-in-images at all | Use real text + web fonts; SVG with live `<text>` only if styleable |
|
|
16
|
+
| 1.2.6–1.2.9 | sign language for audio, extended descriptions, live captions/audio-only alt | Media-heavy products only |
|
|
17
|
+
|
|
18
|
+
## Operable
|
|
19
|
+
|
|
20
|
+
| Criterion | AAA bar | How |
|
|
21
|
+
|-----------|---------|-----|
|
|
22
|
+
| 2.1.3 Keyboard (No Exception) | **all** functionality keyboard-operable, no exceptions | Audit every interaction incl. drag (provide non-drag alt — also 2.5.7 AA) |
|
|
23
|
+
| 2.2.3 No Timing | no time limits on tasks | Remove timeouts entirely where feasible |
|
|
24
|
+
| 2.2.4 Interruptions | user can postpone/suppress non-emergency interruptions | Quiet-mode for toasts/banners |
|
|
25
|
+
| 2.3.2 Three Flashes | **no** flashing > nothing (stricter than 2.3.1) | Ban flashing outright |
|
|
26
|
+
| 2.4.8 Location | show where the user is (breadcrumb + current nav state) | `components/navigation.md` |
|
|
27
|
+
| 2.4.9 Link Purpose (Link Only) | link text alone is unambiguous | No bare "click here"/"read more" |
|
|
28
|
+
| 2.4.12/2.4.13 Focus | focus never obscured (Enhanced) + thick, high-contrast focus appearance | Strong `shadow.focus-ring`; offset; no sticky-header overlap |
|
|
29
|
+
| 2.5.5 Target Size (Enhanced) | **44×44px** targets (AA 2.5.8 is 24px) | Use `sizing.control.lg`; we already recommend 44px for primary |
|
|
30
|
+
|
|
31
|
+
## Understandable
|
|
32
|
+
|
|
33
|
+
| Criterion | AAA bar | How |
|
|
34
|
+
|-----------|---------|-----|
|
|
35
|
+
| 3.1.3–3.1.6 | define unusual words, expand abbreviations, lower-secondary reading level, pronunciation | See `accessibility/cognitive.md` plain-language rules |
|
|
36
|
+
| 3.2.5 Change on Request | no automatic context changes; user initiates all | No auto-redirects/refresh; explicit confirm |
|
|
37
|
+
| 3.3.5 Help | context-sensitive help available | Inline help, tooltips (`components/atoms.md`) |
|
|
38
|
+
| 3.3.6 Error Prevention (All) | reversible / checked / confirmed for **all** submissions (AA limits to legal/financial/data) | Review-before-submit + undo everywhere |
|
|
39
|
+
| 3.3.9 Accessible Authentication (Enhanced) | no cognitive function test, **no exceptions** (object-recognition exception of 3.3.8 removed) | Passkeys/email-link; never image puzzles |
|
|
40
|
+
|
|
41
|
+
## Verification
|
|
42
|
+
- Run `scripts/contrast.py` against 7:1 for all body-text pairings.
|
|
43
|
+
- Confirm zero timeouts, zero flashing, zero drag-only or keyboard-excluded interactions.
|
|
44
|
+
- Every link and button label makes sense read out of context.
|
|
45
|
+
- Primary targets ≥ 44×44px; focus indicator thick, offset, never obscured.
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# Data-Display Components
|
|
2
|
+
|
|
3
|
+
Components that present structured or browsable data: Calendar, Carousel, and Tree. Each uses a documented WAI-ARIA pattern (`accessibility/aria-patterns.md`) and renders via the [Framework Adapter Protocol](../frameworks/adapter-protocol.md). For tabular data see `components/organisms.md` (Data Table); for charts see `components/data-viz.md`.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. Calendar / Date Grid
|
|
8
|
+
|
|
9
|
+
Standalone month grid for picking or displaying dates. The popover-wrapped picker variant lives in `components/forms-advanced.md` (Date Picker) — this is the grid itself.
|
|
10
|
+
|
|
11
|
+
**Anatomy:** `[header: ‹ prev | month year | next ›] [weekday row] [day grid 6×7] [footer: Today / Clear?]`
|
|
12
|
+
|
|
13
|
+
**Variants:**
|
|
14
|
+
| Variant | Use |
|
|
15
|
+
|---------|-----|
|
|
16
|
+
| Single date | Pick one day |
|
|
17
|
+
| Range | Start→end selection with in-range fill (`semantic.interactive.selected-bg` at reduced opacity) |
|
|
18
|
+
| Multi-month | 2–3 grids side-by-side for range picking |
|
|
19
|
+
| With time | Grid + time selector below |
|
|
20
|
+
| Display-only | Read-only schedule/availability heatmap |
|
|
21
|
+
|
|
22
|
+
**Sizes:** cell hit area ≥ `sizing.control.xs` (24px); md grid uses `sizing.control.md` cells. Gap from `spacing` scale.
|
|
23
|
+
|
|
24
|
+
**States (8):** default, hover (cell `interactive.hover-bg`), focus (roving `shadow.focus-ring`), selected (`interactive.selected-bg`), today (ringed via `border.strong` / `aria-current`), disabled (out-of-range, `opacity.disabled`), range-endpoint, in-range (subtle fill).
|
|
25
|
+
|
|
26
|
+
**Accessibility:**
|
|
27
|
+
- `role="grid"` (or `role="application"` for rich range UX); column headers `role="columnheader"` with `abbr` for weekday.
|
|
28
|
+
- **Roving tabindex** — one cell tabbable; Arrow keys move day/week, PageUp/Down month, Shift+PageUp/Down year, Home/End week edges, Enter/Space select.
|
|
29
|
+
- Selected cell `aria-selected="true"`; today `aria-current="date"`. Announce month/year change on navigation (live region).
|
|
30
|
+
- Never convey availability by color alone — pair with icon/label/`aria-disabled`.
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## 2. Carousel / Slideshow
|
|
35
|
+
|
|
36
|
+
Sequentially browsable set of slides (media, cards, testimonials).
|
|
37
|
+
|
|
38
|
+
**Anatomy:** `[viewport (overflow clip)] → [slide track] [prev ‹] [next ›] [pagination dots] [play/pause?]`
|
|
39
|
+
|
|
40
|
+
**Variants:** single-slide, multi-item (n visible), peek (partial next), fade vs. slide transition, auto-advancing vs. manual, looping vs. bounded.
|
|
41
|
+
|
|
42
|
+
**Sizes:** slide width via `sizing.aspectRatio` or container fraction; control hit area ≥ 44px recommended.
|
|
43
|
+
|
|
44
|
+
**Behavior:** transition uses `tokens/motion.json` (`transition.standard`, `ease-out`). Snap to slide boundaries. On multi-item, advance by page or by item (document which).
|
|
45
|
+
|
|
46
|
+
**States:** default, hover (reveal/enlarge controls), focus (control `shadow.focus-ring`), active slide (dot filled), transitioning, auto-playing (timer), paused, disabled control (at non-looping bound).
|
|
47
|
+
|
|
48
|
+
**Accessibility:**
|
|
49
|
+
- Container `role="region"` (or `group`) with `aria-roledescription="carousel"` + `aria-label`. Slide group `aria-roledescription="slide"` + `aria-label="N of M"`.
|
|
50
|
+
- **WCAG 2.2.2** — any auto-advance must be pausable/stoppable; show a visible Pause control and **pause on hover/focus**. Respect `prefers-reduced-motion` (disable autoplay + use fade/instant).
|
|
51
|
+
- Prev/Next/dots are real `<button>`s with labels; rotation region `aria-live="off"` while auto, `"polite"` after user interaction.
|
|
52
|
+
- Off-screen slides `aria-hidden`/`inert` so they're skipped by Tab and SR.
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## 3. Tree View
|
|
57
|
+
|
|
58
|
+
Hierarchical, expandable list (file explorers, nav, nested categories).
|
|
59
|
+
|
|
60
|
+
**Anatomy:** `[node: ▸ twisty | icon? | label | badge/count?] [indent guides] [nested group]`
|
|
61
|
+
|
|
62
|
+
**Variants:** single-select, multi-select (tri-state checkboxes), with icons, draggable-reorder, lazy-loaded branches.
|
|
63
|
+
|
|
64
|
+
**Sizes:** row height `sizing.control.sm`/`md`; indent step from `spacing` scale (consistent per level).
|
|
65
|
+
|
|
66
|
+
**States (8):** default, hover (`interactive.hover-bg`), focus (roving `shadow.focus-ring`), selected (`interactive.selected-bg`), expanded, collapsed, loading (branch spinner + `aria-busy`), disabled.
|
|
67
|
+
|
|
68
|
+
**Accessibility:**
|
|
69
|
+
- `role="tree"` → `role="treeitem"` → nested `role="group"`. Each item: `aria-expanded` (parents only), `aria-level`, `aria-setsize`, `aria-posinset`; selection via `aria-selected`. Multi-select checkboxes use `aria-checked="mixed"` for partial.
|
|
70
|
+
- **Roving tabindex** — Up/Down move visible items, Right expands/enters, Left collapses/exits to parent, Home/End to first/last, type-ahead to label, Enter/Space activate/select, `*` expands siblings.
|
|
71
|
+
- Twisty is decorative if the row is the control; expose state through `aria-expanded`, never the glyph alone.
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Data-Visualization Components
|
|
2
|
+
|
|
3
|
+
Charts and graphs. Color comes from `tokens/data-viz.json` (color-blind-aware categorical + sequential/diverging scales), never the brand palette directly. Charts are **graphical objects** — UI/contrast rules apply (3:1 for meaningful strokes) and **information must never depend on color alone**. Render via the [Framework Adapter Protocol](../frameworks/adapter-protocol.md).
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Universal chart rules
|
|
8
|
+
|
|
9
|
+
1. **Token-driven series color** — map series to `dataviz.categorical.*`; sequences to `dataviz.sequential.*`; +/− to `dataviz.diverging.*` / `dataviz.semantic.*`. Limit to ≤ 8 categorical series; beyond that, group "Other" or switch encoding.
|
|
10
|
+
2. **Never color-alone** — pair series with **direct labels**, distinct markers/dash patterns, or texture. Provide a legend *and* on-hover labels.
|
|
11
|
+
3. **Axes & grid** — use `dataviz.axis.*` / `dataviz.grid.*` (low-contrast gridlines `~1.4:1` are acceptable as they are non-essential; axis text meets 4.5:1).
|
|
12
|
+
4. **Motion** — entrance/transition from `tokens/motion.json` (`ease-out`, ≤ 300ms); animate value changes, not on every re-render. Honor `prefers-reduced-motion` (render final frame).
|
|
13
|
+
5. **Accessible alternative** — every chart ships a text/table equivalent (visually-hidden `<table>` or `<figcaption>` summary) and a descriptive `aria-label`/`aria-labelledby`.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## 1. Bar / Column
|
|
18
|
+
|
|
19
|
+
Compare discrete categories.
|
|
20
|
+
|
|
21
|
+
**Variants:** vertical (column), horizontal (bar), grouped, stacked, 100%-stacked.
|
|
22
|
+
**States:** default, hover (bar emphasis + tooltip), focus (keyboardable bar `shadow.focus-ring`), selected/filtered, empty, loading (skeleton bars).
|
|
23
|
+
**Accessibility:** bars in a `role="list"`/`figure` with per-bar `aria-label="Category: value"`; or expose the backing table. Order bars meaningfully (value or category), label axes.
|
|
24
|
+
|
|
25
|
+
## 2. Line / Area
|
|
26
|
+
|
|
27
|
+
Trends over a continuous dimension (usually time).
|
|
28
|
+
|
|
29
|
+
**Variants:** single line, multi-series, area, stacked area, stepped, with threshold band.
|
|
30
|
+
**States:** default, hover (crosshair + nearest-point tooltip), focus (point navigation), zoomed/brushed, empty, loading.
|
|
31
|
+
**Accessibility:** distinguish series by **dash pattern + marker shape**, not only hue. Provide point-by-point keyboard traversal or the table fallback. Label units on the axis.
|
|
32
|
+
|
|
33
|
+
## 3. Pie / Donut
|
|
34
|
+
|
|
35
|
+
Part-to-whole for **few** segments (≤ 5–6).
|
|
36
|
+
|
|
37
|
+
**Variants:** pie, donut (with center metric), with leader-line labels.
|
|
38
|
+
**States:** default, hover (segment lift + value), focus, selected, empty.
|
|
39
|
+
**Accessibility:** **direct-label each segment with name + %** — legends alone fail. Prefer a bar chart when segments are many or similar in size. Order by magnitude.
|
|
40
|
+
|
|
41
|
+
## 4. Sparkline
|
|
42
|
+
|
|
43
|
+
Inline micro-trend (in a table cell or KPI card). No axes.
|
|
44
|
+
|
|
45
|
+
**Variants:** line, bar, win/loss; with end-dot or min/max markers.
|
|
46
|
+
**States:** default, hover (reveal value), positive/negative tint (`dataviz.semantic.positive`/`negative`).
|
|
47
|
+
**Accessibility:** decorative if the numeric value is adjacent (`aria-hidden`); otherwise give an `aria-label` with the trend summary ("Up 12% over 7 days").
|
|
48
|
+
|
|
49
|
+
## 5. Scatter / Bubble
|
|
50
|
+
|
|
51
|
+
Correlation across two (or three, via size) measures.
|
|
52
|
+
|
|
53
|
+
**Variants:** scatter, bubble (size = 3rd measure), with trend line, categorized by color+shape.
|
|
54
|
+
**States:** default, hover (point tooltip), focus, selected/lassoed, empty.
|
|
55
|
+
**Accessibility:** encode category by **shape and** color; label axes with units; provide the data table. Don't rely on size alone for the third measure — include it in the tooltip.
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Icon System
|
|
2
|
+
|
|
3
|
+
Icons are a token-governed subsystem, not loose SVGs. Consistency in grid, stroke, and metaphor is what makes an icon set feel like one system. Sizing comes from `tokens/sizing.json` (`icon.*`); color from `currentColor` so icons inherit text/state tokens.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Foundations
|
|
8
|
+
|
|
9
|
+
- **Grid:** design on a single pixel grid (commonly 24×24) with a consistent live area + padding. Every icon shares the grid so optical weight matches.
|
|
10
|
+
- **Stroke:** one stroke width across the set (e.g. 1.5–2px at 24px). Keep stroke constant across sizes — scale the canvas, not the stroke, or the set looks inconsistent (CLAUDE.md: "keep stroke weight consistent across sizes").
|
|
11
|
+
- **Style:** pick one — outline OR solid OR duotone — as the primary; use the alternate only for a deliberate signal (e.g. solid = selected/active). Don't mix styles arbitrarily.
|
|
12
|
+
- **Optical alignment:** align to optical center, not geometric; balance visual mass.
|
|
13
|
+
|
|
14
|
+
## Sizing & color (tokens)
|
|
15
|
+
|
|
16
|
+
| Token | Size | Use |
|
|
17
|
+
|-------|------|-----|
|
|
18
|
+
| `sizing.icon.xs` | 12px | Dense inline / badge |
|
|
19
|
+
| `sizing.icon.sm` | 16px | Default inline icon (with body text) |
|
|
20
|
+
| `sizing.icon.md` | 20px | Buttons, inputs |
|
|
21
|
+
| `sizing.icon.lg` | 24px | Standalone / nav |
|
|
22
|
+
| `sizing.icon.xl` | 32px | Feature / empty-state accent |
|
|
23
|
+
|
|
24
|
+
- Color via `currentColor` — the icon inherits `text.*` / state tokens automatically (incl. forced-colors mode, `accessibility/vision.md`). Never hard-code icon hex.
|
|
25
|
+
- Pair icon size with text size for optical balance; keep stroke legible at the smallest used size.
|
|
26
|
+
|
|
27
|
+
## Delivery
|
|
28
|
+
|
|
29
|
+
| Method | When |
|
|
30
|
+
|--------|------|
|
|
31
|
+
| **Inline `<svg>`** | Default — stylable (`currentColor`), no extra request, supports `aria-*`. Best for forced-colors and theming. |
|
|
32
|
+
| **SVG sprite** (`<use href="#id">`) | Large sets, cache one file, reference by id. |
|
|
33
|
+
| **Icon font** | Legacy only — avoid (a11y + rendering issues; can't do duotone/forced-colors well). |
|
|
34
|
+
| Component wrapper | An `<Icon name size>` component enforces size tokens + a11y props across frameworks (`frameworks/adapter-protocol.md`). |
|
|
35
|
+
|
|
36
|
+
## Accessibility
|
|
37
|
+
|
|
38
|
+
- **Decorative icon** (next to a text label): `aria-hidden="true"` and no `title` — the label carries meaning. Most UI icons are decorative.
|
|
39
|
+
- **Meaningful icon** (icon-only button/status): give an accessible name — `aria-label` on the button, or `role="img"` + `aria-label`/`<title>` on the SVG. Icon-only controls still need a ≥ 24×24px (44px recommended) hit target (CLAUDE.md).
|
|
40
|
+
- **Never icon-alone for status** — pair with text/color-plus-shape (`accessibility/vision.md`); an icon's meaning isn't universal.
|
|
41
|
+
- Use `currentColor` so icons meet contrast with their text context and adapt to high-contrast mode.
|
|
42
|
+
|
|
43
|
+
## States
|
|
44
|
+
|
|
45
|
+
Icons participate in component states via inherited color: default (`text.secondary`), hover/active (inherit control state), selected (`action.primary` or solid variant), disabled (`opacity.disabled`), loading (animated spinner icon + `aria-busy`).
|
|
46
|
+
|
|
47
|
+
## Verification
|
|
48
|
+
- Single grid + single stroke weight across the whole set?
|
|
49
|
+
- All icons use `currentColor` and `sizing.icon.*` (zero hard-coded hex/px)?
|
|
50
|
+
- Every icon-only control has an accessible name and a ≥ 24px target?
|
|
51
|
+
- No status conveyed by icon (or color) alone?
|