Skip to content

Commit e4abc98

Browse files
committed
vercel's web interface guidelines as AGENTS.md
1 parent 4787282 commit e4abc98

File tree

1 file changed

+167
-0
lines changed

1 file changed

+167
-0
lines changed

AGENTS.md

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
Concise rules for building accessible, fast, delightful UIs Use MUST/SHOULD/NEVER to guide decisions
2+
3+
## Interactions
4+
5+
- Keyboard
6+
- MUST: Full keyboard support per [WAI-ARIA APG](https://wwww3org/WAI/ARIA/apg/patterns/)
7+
- MUST: Visible focus rings (`:focus-visible`; group with `:focus-within`)
8+
- MUST: Manage focus (trap, move, and return) per APG patterns
9+
- Targets & input
10+
- MUST: Hit target ≥24px (mobile ≥44px) If visual <24px, expand hit area
11+
- MUST: Mobile `<input>` font-size ≥16px or set:
12+
```html
13+
<meta
14+
name="viewport"
15+
content="width=device-width, initial-scale=1, maximum-scale=1, viewport-fit=cover"
16+
/>
17+
```
18+
- NEVER: Disable browser zoom
19+
- MUST: `touch-action: manipulation` to prevent double-tap zoom; set `-webkit-tap-highlight-color` to match design
20+
- Inputs & forms (behavior)
21+
- MUST: Hydration-safe inputs (no lost focus/value)
22+
- NEVER: Block paste in `<input>/<textarea>`
23+
- MUST: Loading buttons show spinner and keep original label
24+
- MUST: Enter submits focused text input In `<textarea>`, ⌘/Ctrl+Enter submits; Enter adds newline
25+
- MUST: Keep submit enabled until request starts; then disable, show spinner, use idempotency key
26+
- MUST: Don’t block typing; accept free text and validate after
27+
- MUST: Allow submitting incomplete forms to surface validation
28+
- MUST: Errors inline next to fields; on submit, focus first error
29+
- MUST: `autocomplete` + meaningful `name`; correct `type` and `inputmode`
30+
- SHOULD: Disable spellcheck for emails/codes/usernames
31+
- SHOULD: Placeholders end with ellipsis and show example pattern (eg, `+1 (123) 456-7890`, `sk-012345…`)
32+
- MUST: Warn on unsaved changes before navigation
33+
- MUST: Compatible with password managers & 2FA; allow pasting one-time codes
34+
- MUST: Trim values to handle text expansion trailing spaces
35+
- MUST: No dead zones on checkboxes/radios; label+control share one generous hit target
36+
- State & navigation
37+
- MUST: URL reflects state (deep-link filters/tabs/pagination/expanded panels) Prefer libs like [nuqs](https://nuqs.dev)
38+
- MUST: Back/Forward restores scroll
39+
- MUST: Links are links—use `<a>/<Link>` for navigation (support Cmd/Ctrl/middle-click)
40+
- Feedback
41+
- SHOULD: Optimistic UI; reconcile on response; on failure show error and rollback or offer Undo
42+
- MUST: Confirm destructive actions or provide Undo window
43+
- MUST: Use polite `aria-live` for toasts/inline validation
44+
- SHOULD: Ellipsis (`…`) for options that open follow-ups (eg, “Rename…”)
45+
- Touch/drag/scroll
46+
- MUST: Design forgiving interactions (generous targets, clear affordances; avoid finickiness)
47+
- MUST: Delay first tooltip in a group; subsequent peers no delay
48+
- MUST: Intentional `overscroll-behavior: contain` in modals/drawers
49+
- MUST: During drag, disable text selection and set `inert` on dragged element/containers
50+
- MUST: No “dead-looking” interactive zones—if it looks clickable, it is
51+
- Autofocus
52+
- SHOULD: Autofocus on desktop when there’s a single primary input; rarely on mobile (to avoid layout shift)
53+
54+
## Animation
55+
56+
- MUST: Honor `prefers-reduced-motion` (provide reduced variant)
57+
- SHOULD: Prefer CSS > Web Animations API > JS libraries
58+
- MUST: Animate compositor-friendly props (`transform`, `opacity`); avoid layout/repaint props (`top/left/width/height`)
59+
- SHOULD: Animate only to clarify cause/effect or add deliberate delight
60+
- SHOULD: Choose easing to match the change (size/distance/trigger)
61+
- MUST: Animations are interruptible and input-driven (avoid autoplay)
62+
- MUST: Correct `transform-origin` (motion starts where it “physically” should)
63+
64+
## Layout
65+
66+
- SHOULD: Optical alignment; adjust by ±1px when perception beats geometry
67+
- MUST: Deliberate alignment to grid/baseline/edges/optical centers—no accidental placement
68+
- SHOULD: Balance icon/text lockups (stroke/weight/size/spacing/color)
69+
- MUST: Verify mobile, laptop, ultra-wide (simulate ultra-wide at 50% zoom)
70+
- MUST: Respect safe areas (use env(safe-area-inset-\*))
71+
- MUST: Avoid unwanted scrollbars; fix overflows
72+
73+
## Content & Accessibility
74+
75+
- SHOULD: Inline help first; tooltips last resort
76+
- MUST: Skeletons mirror final content to avoid layout shift
77+
- MUST: `<title>` matches current context
78+
- MUST: No dead ends; always offer next step/recovery
79+
- MUST: Design empty/sparse/dense/error states
80+
- SHOULD: Curly quotes (“ ”); avoid widows/orphans
81+
- MUST: Tabular numbers for comparisons (`font-variant-numeric: tabular-nums` or a mono like Geist Mono)
82+
- MUST: Redundant status cues (not color-only); icons have text labels
83+
- MUST: Don’t ship the schema—visuals may omit labels but accessible names still exist
84+
- MUST: Use the ellipsis character `…` (not ``)
85+
- MUST: `scroll-margin-top` on headings for anchored links; include a “Skip to content” link; hierarchical `<h1–h6>`
86+
- MUST: Resilient to user-generated content (short/avg/very long)
87+
- MUST: Locale-aware dates/times/numbers/currency
88+
- MUST: Accurate names (`aria-label`), decorative elements `aria-hidden`, verify in the Accessibility Tree
89+
- MUST: Icon-only buttons have descriptive `aria-label`
90+
- MUST: Prefer native semantics (`button`, `a`, `label`, `table`) before ARIA
91+
- SHOULD: Right-clicking the nav logo surfaces brand assets
92+
- MUST: Use non-breaking spaces to glue terms: `10&nbsp;MB`, `⌘&nbsp;+&nbsp;K`, `Vercel&nbsp;SDK`
93+
94+
## Performance
95+
96+
- SHOULD: Test iOS Low Power Mode and macOS Safari
97+
- MUST: Measure reliably (disable extensions that skew runtime)
98+
- MUST: Track and minimize re-renders (React DevTools/React Scan)
99+
- MUST: Profile with CPU/network throttling
100+
- MUST: Batch layout reads/writes; avoid unnecessary reflows/repaints
101+
- MUST: Mutations (`POST/PATCH/DELETE`) target <500 ms
102+
- SHOULD: Prefer uncontrolled inputs; make controlled loops cheap (keystroke cost)
103+
- MUST: Virtualize large lists (eg, `virtua`)
104+
- MUST: Preload only above-the-fold images; lazy-load the rest
105+
- MUST: Prevent CLS from images (explicit dimensions or reserved space)
106+
107+
## Design
108+
109+
- SHOULD: Layered shadows (ambient + direct)
110+
- SHOULD: Crisp edges via semi-transparent borders + shadows
111+
- SHOULD: Nested radii: child parent; concentric
112+
- SHOULD: Hue consistency: tint borders/shadows/text toward bg hue
113+
- MUST: Accessible charts (color-blind-friendly palettes)
114+
- MUST: Meet contrast—prefer [APCA](https://apcacontrastcom/) over WCAG 2
115+
- MUST: Increase contrast on `:hover/:active/:focus`
116+
- SHOULD: Match browser UI to bg
117+
- SHOULD: Avoid gradient banding (use masks when needed)
118+
119+
## Code Style and Structure:
120+
121+
- Write concise, technical TypeScript code with accurate examples
122+
- Use functional and declarative programming patterns; avoid classes
123+
- Prefer iteration and modularization over code duplication
124+
- Use descriptive variable names with auxiliary verbs (e.g., isLoading, hasError)
125+
- Structure files: exported component, subcomponents, helpers, static content, types
126+
127+
## Naming Conventions:
128+
129+
- Use lowercase with dashes for directories (e.g., components/auth-wizard)
130+
- Favor named exports for components
131+
132+
## TypeScript Usage:
133+
134+
- Use TypeScript for all code; prefer types over interfaces UNLESS specificially for intersections (Typescript Performance)
135+
- Avoid enums; use maps instead
136+
- Use functional components with types
137+
138+
## Syntax and Formatting:
139+
140+
- Use the "function" keyword for pure functions
141+
- Avoid unnecessary curly braces in conditionals; use concise syntax for simple statements
142+
- Use declarative JSX
143+
144+
## Error Handling and Validation:
145+
146+
- Prioritize error handling: handle errors and edge cases early
147+
- Use early returns and guard clauses
148+
- Implement proper error logging and user-friendly messages
149+
- Use Zod for form validation
150+
- Model expected errors as return values in Server Actions
151+
- Use error boundaries for unexpected errors
152+
153+
## Performance Optimization:
154+
155+
- Minimize 'use client', 'useEffect', and 'setState'; favor React Server Components (RSC)
156+
- Wrap client components in Suspense with fallback
157+
- Use dynamic loading for non-critical components
158+
- Optimize images: use WebP format, include size data, implement lazy loading
159+
160+
## Key Conventions:
161+
162+
- Use 'nuqs' for URL search parameter state management
163+
- Optimize Web Vitals (LCP, CLS, FID)
164+
- Limit 'use client':
165+
- Favor server components and Next.js SSR
166+
- Use only for Web API access in small components
167+
- Avoid for data fetching or state management

0 commit comments

Comments
 (0)