1+ ---
2+ description:
3+ globs:
4+ alwaysApply: true
5+ ---
6+ Concise rules for building accessible, fast, delightful UIs Use MUST/SHOULD/NEVER to guide decisions
7+
8+ ## Interactions
9+
10+ - Keyboard
11+ - MUST: Full keyboard support per [WAI-ARIA APG](https://wwww3org/WAI/ARIA/apg/patterns/)
12+ - MUST: Visible focus rings (`:focus-visible`; group with `:focus-within`)
13+ - MUST: Manage focus (trap, move, and return) per APG patterns
14+ - Targets & input
15+ - MUST: Hit target ≥24px (mobile ≥44px) If visual <24px, expand hit area
16+ - MUST: Mobile `<input>` font-size ≥16px or set:
17+ ```html
18+ <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, viewport-fit=cover">
19+ ```
20+ - NEVER: Disable browser zoom
21+ - MUST: `touch-action: manipulation` to prevent double-tap zoom; set `-webkit-tap-highlight-color` to match design
22+ - Inputs & forms (behavior)
23+ - MUST: Hydration-safe inputs (no lost focus/value)
24+ - NEVER: Block paste in `<input>/<textarea>`
25+ - MUST: Loading buttons show spinner and keep original label
26+ - MUST: Enter submits focused text input In `<textarea>`, ⌘/Ctrl+Enter submits; Enter adds newline
27+ - MUST: Keep submit enabled until request starts; then disable, show spinner, use idempotency key
28+ - MUST: Don’t block typing; accept free text and validate after
29+ - MUST: Allow submitting incomplete forms to surface validation
30+ - MUST: Errors inline next to fields; on submit, focus first error
31+ - MUST: `autocomplete` + meaningful `name`; correct `type` and `inputmode`
32+ - SHOULD: Disable spellcheck for emails/codes/usernames
33+ - SHOULD: Placeholders end with ellipsis and show example pattern (eg, `+1 (123) 456-7890`, `sk-012345…`)
34+ - MUST: Warn on unsaved changes before navigation
35+ - MUST: Compatible with password managers & 2FA; allow pasting one-time codes
36+ - MUST: Trim values to handle text expansion trailing spaces
37+ - MUST: No dead zones on checkboxes/radios; label+control share one generous hit target
38+ - State & navigation
39+ - MUST: URL reflects state (deep-link filters/tabs/pagination/expanded panels) Prefer libs like [nuqs](https://nuqs47ngcom/)
40+ - MUST: Back/Forward restores scroll
41+ - MUST: Links are links—use `<a>/<Link>` for navigation (support Cmd/Ctrl/middle-click)
42+ - Feedback
43+ - SHOULD: Optimistic UI; reconcile on response; on failure show error and rollback or offer Undo
44+ - MUST: Confirm destructive actions or provide Undo window
45+ - MUST: Use polite `aria-live` for toasts/inline validation
46+ - SHOULD: Ellipsis (`…`) for options that open follow-ups (eg, “Rename…”)
47+ - Touch/drag/scroll
48+ - MUST: Design forgiving interactions (generous targets, clear affordances; avoid finickiness)
49+ - MUST: Delay first tooltip in a group; subsequent peers no delay
50+ - MUST: Intentional `overscroll-behavior: contain` in modals/drawers
51+ - MUST: During drag, disable text selection and set `inert` on dragged element/containers
52+ - MUST: No “dead-looking” interactive zones—if it looks clickable, it is
53+ - Autofocus
54+ - SHOULD: Autofocus on desktop when there’s a single primary input; rarely on mobile (to avoid layout shift)
55+
56+ ## Animation
57+
58+ - MUST: Honor `prefers-reduced-motion` (provide reduced variant)
59+ - SHOULD: Prefer CSS > Web Animations API > JS libraries
60+ - MUST: Animate compositor-friendly props (`transform`, `opacity`); avoid layout/repaint props (`top/left/width/height`)
61+ - SHOULD: Animate only to clarify cause/effect or add deliberate delight
62+ - SHOULD: Choose easing to match the change (size/distance/trigger)
63+ - MUST: Animations are interruptible and input-driven (avoid autoplay)
64+ - MUST: Correct `transform-origin` (motion starts where it “physically” should)
65+
66+ ## Layout
67+
68+ - SHOULD: Optical alignment; adjust by ±1px when perception beats geometry
69+ - MUST: Deliberate alignment to grid/baseline/edges/optical centers—no accidental placement
70+ - SHOULD: Balance icon/text lockups (stroke/weight/size/spacing/color)
71+ - MUST: Verify mobile, laptop, ultra-wide (simulate ultra-wide at 50% zoom)
72+ - MUST: Respect safe areas (use env(safe-area-inset-*))
73+ - MUST: Avoid unwanted scrollbars; fix overflows
74+
75+ ## Content & Accessibility
76+
77+ - SHOULD: Inline help first; tooltips last resort
78+ - MUST: Skeletons mirror final content to avoid layout shift
79+ - MUST: `<title>` matches current context
80+ - MUST: No dead ends; always offer next step/recovery
81+ - MUST: Design empty/sparse/dense/error states
82+ - SHOULD: Curly quotes (“ ”); avoid widows/orphans
83+ - MUST: Tabular numbers for comparisons (`font-variant-numeric: tabular-nums` or a mono like Geist Mono)
84+ - MUST: Redundant status cues (not color-only); icons have text labels
85+ - MUST: Don’t ship the schema—visuals may omit labels but accessible names still exist
86+ - MUST: Use the ellipsis character `…` (not ``)
87+ - MUST: `scroll-margin-top` on headings for anchored links; include a “Skip to content” link; hierarchical `<h1–h6>`
88+ - MUST: Resilient to user-generated content (short/avg/very long)
89+ - MUST: Locale-aware dates/times/numbers/currency
90+ - MUST: Accurate names (`aria-label`), decorative elements `aria-hidden`, verify in the Accessibility Tree
91+ - MUST: Icon-only buttons have descriptive `aria-label`
92+ - MUST: Prefer native semantics (`button`, `a`, `label`, `table`) before ARIA
93+ - SHOULD: Right-clicking the nav logo surfaces brand assets
94+ - MUST: Use non-breaking spaces to glue terms: `10 MB`, `⌘ + K`, `Vercel SDK`
95+
96+ ## Performance
97+
98+ - SHOULD: Test iOS Low Power Mode and macOS Safari
99+ - MUST: Measure reliably (disable extensions that skew runtime)
100+ - MUST: Track and minimize re-renders (React DevTools/React Scan)
101+ - MUST: Profile with CPU/network throttling
102+ - MUST: Batch layout reads/writes; avoid unnecessary reflows/repaints
103+ - MUST: Mutations (`POST/PATCH/DELETE`) target <500 ms
104+ - SHOULD: Prefer uncontrolled inputs; make controlled loops cheap (keystroke cost)
105+ - MUST: Virtualize large lists (eg, `virtua`)
106+ - MUST: Preload only above-the-fold images; lazy-load the rest
107+ - MUST: Prevent CLS from images (explicit dimensions or reserved space)
108+
109+ ## Design
110+
111+ - SHOULD: Layered shadows (ambient + direct)
112+ - SHOULD: Crisp edges via semi-transparent borders + shadows
113+ - SHOULD: Nested radii: child ≤ parent; concentric
114+ - SHOULD: Hue consistency: tint borders/shadows/text toward bg hue
115+ - MUST: Accessible charts (color-blind-friendly palettes)
116+ - MUST: Meet contrast—prefer [APCA](https://apcacontrastcom/) over WCAG 2
117+ - MUST: Increase contrast on `:hover/:active/:focus`
118+ - SHOULD: Match browser UI to bg
119+ - SHOULD: Avoid gradient banding (use masks when needed)
0 commit comments