Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
225 changes: 225 additions & 0 deletions docs/skill-optimizer/web-design-guidelines/01-functionality.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,225 @@
---
skill_source: https://github.com/vercel-labs/agent-skills/blob/main/skills/web-design-guidelines/SKILL.md
pr_submission_intent: true
classification: ui-code-review-checklist
optimization_target: command.md
optimization_target_source: https://raw.githubusercontent.com/vercel-labs/web-interface-guidelines/main/command.md
optimization_target_candidates:
- path: SKILL.md
source: https://raw.githubusercontent.com/vercel-labs/agent-skills/main/skills/web-design-guidelines/SKILL.md
rationale: 39-line wrapper that only orchestrates a WebFetch; no substantive rules to test or improve.
- path: command.md
source: https://raw.githubusercontent.com/vercel-labs/web-interface-guidelines/main/command.md
rationale: The actual rule corpus (~80 checklist items across 15 categories) that every review applies; this is where behavior lives.
likely_wrapper: true
wrapper_points_to: https://raw.githubusercontent.com/vercel-labs/web-interface-guidelines/main/command.md
---

# web-design-guidelines — functionality briefing

## 1. What the skill does

`web-design-guidelines` is a UI code review checklist skill. When an agent is asked to review front-end source files (JSX/TSX/HTML/CSS), the skill fetches a curated set of Vercel "Web Interface Guidelines" rules and applies them to the provided files, emitting a terse `file:line - issue` report grouped by file. It is fundamentally a static review pass — read the files, match each rule against the source, and report violations in a compact format optimized for IDE clickthrough. The substantive content (the rules themselves and the output format) is not embedded in the published SKILL.md; the SKILL.md is a thin wrapper that WebFetches `command.md` from a separate `vercel-labs/web-interface-guidelines` repo on every invocation.

## 2. Who uses it

End-user agents (Claude Code, Cursor, Codex, etc.) running on a developer's machine while that developer is iterating on a web UI. The consumer is the agent; the human audience is a front-end engineer who wants a fast lint-like sanity pass over component code before opening a PR or shipping.

## 3. When it should fire

Per the wrapper SKILL.md description, the skill should trigger on user phrasing like:

- "review my UI"
- "check accessibility"
- "audit design"
- "review UX"
- "check my site against best practices"

Implicit triggers: any request to review/audit/inspect front-end files (`.tsx`, `.jsx`, `.html`, `.css`, component code) against design-system / accessibility / performance heuristics.

## 4. Responsibilities

Every rule in `command.md` is a candidate testable behavior. They group naturally into the categories `command.md` itself uses:

### Accessibility (10 rules)

- Icon-only buttons need `aria-label`
- Form controls need `<label>` or `aria-label`
- Interactive elements need keyboard handlers (`onKeyDown`/`onKeyUp`)
- `<button>` for actions, `<a>`/`<Link>` for navigation (not `<div onClick>`)
- Images need `alt` (or `alt=""` if decorative)
- Decorative icons need `aria-hidden="true"`
- Async updates (toasts, validation) need `aria-live="polite"`
- Prefer semantic HTML over ARIA
- Hierarchical heading order `<h1>`–`<h6>` plus skip link
- `scroll-margin-top` on heading anchors

### Focus States (4 rules)

- Interactive elements need visible focus (`focus-visible:ring-*`)
- Never `outline-none` / `outline: none` without replacement
- Prefer `:focus-visible` over `:focus`
- Use `:focus-within` for compound controls

### Forms (11 rules)

- `autocomplete` and meaningful `name` on inputs
- Correct `type` and `inputmode`
- Never block paste (`onPaste` + `preventDefault`)
- Labels must be clickable (`htmlFor` or wrap)
- Disable spellcheck on emails/codes/usernames
- Checkbox/radio single hit target
- Submit stays enabled until request starts; spinner during request
- Inline errors next to fields; focus first error on submit
- Placeholders end with `…` and show example
- `autocomplete="off"` on non-auth fields
- Warn before navigation with unsaved changes

### Animation (6 rules)

- Honor `prefers-reduced-motion`
- Animate `transform` / `opacity` only
- Never `transition: all` — list properties
- Correct `transform-origin`
- SVG transforms on `<g>` wrapper with `transform-box: fill-box`
- Animations must be interruptible

### Typography (6 rules)

- Ellipsis `…` not `...`
- Curly quotes not straight
- Non-breaking spaces in `10&nbsp;MB`, `⌘&nbsp;K`, brand names
- Loading states end with `…`
- `font-variant-numeric: tabular-nums` for number columns
- `text-wrap: balance` / `text-pretty` on headings

### Content Handling (4 rules)

- `truncate` / `line-clamp-*` / `break-words` on text containers
- Flex children need `min-w-0`
- Handle empty states
- Anticipate short/average/long user-generated content

### Images (3 rules)

- Explicit `width` and `height` (prevents CLS)
- `loading="lazy"` below the fold
- `priority` / `fetchpriority="high"` above the fold

### Performance (6 rules)

- Virtualize lists >50 items
- No layout reads in render
- Batch DOM reads/writes
- Prefer uncontrolled inputs
- `<link rel="preconnect">` for CDN domains
- Critical fonts: `<link rel="preload" as="font">` + `font-display: swap`

### Navigation & State (4 rules)

- URL reflects filters/tabs/pagination/expanded panels
- Links use `<a>` / `<Link>` (preserve Cmd/Ctrl+click and middle-click)
- Deep-link stateful UI (consider URL sync via nuqs)
- Destructive actions need confirmation or undo

### Touch & Interaction (5 rules)

- `touch-action: manipulation`
- Intentional `-webkit-tap-highlight-color`
- `overscroll-behavior: contain` in modals/drawers/sheets
- During drag: disable text selection, `inert` on dragged elements
- `autoFocus` sparingly — desktop only

### Safe Areas & Layout (3 rules)

- `env(safe-area-inset-*)` for full-bleed
- Avoid unwanted scrollbars (`overflow-x-hidden`)
- Flex/grid over JS measurement

### Dark Mode & Theming (3 rules)

- `color-scheme: dark` on `<html>` for dark themes
- `<meta name="theme-color">` matches background
- Native `<select>`: explicit `background-color` and `color`

### Locale & i18n (4 rules)

- `Intl.DateTimeFormat` for dates/times
- `Intl.NumberFormat` for numbers/currency
- Detect language via `Accept-Language` / `navigator.languages`
- Wrap brand names / code tokens with `translate="no"`

### Hydration Safety (3 rules)

- Inputs with `value` need `onChange` (or use `defaultValue`)
- Guard date/time rendering against hydration mismatch
- `suppressHydrationWarning` only where needed

### Hover & Interactive States (2 rules)

- Buttons/links need a `hover:` state
- Interactive states increase contrast

### Content & Copy (7 rules)

- Active voice
- Title Case for headings/buttons (Chicago style)
- Numerals for counts
- Specific button labels (not "Continue")
- Error messages include fix / next step
- Second person; avoid first person
- `&` over "and" where space-constrained

### Anti-patterns (explicit flag list, 12 items)

`user-scalable=no`, `onPaste` + `preventDefault`, `transition: all`, `outline-none` without replacement, inline `onClick` navigation, `<div>`/`<span>` with click handlers, images without dimensions, large `.map()` without virtualization, inputs without labels, icon buttons without `aria-label`, hardcoded date/number formats, unjustified `autoFocus`.

### Output format contract

- Group findings by file (`## src/Foo.tsx`)
- One finding per line in `path:line - issue` (VS Code-clickable)
- Terse: "icon button missing aria-label" not full sentences
- Files with no issues get `✓ pass`
- No preamble, no closing summary

## 5. Tools / dependencies

- **WebFetch** — the wrapper SKILL.md requires it to pull `command.md` on each run. (Substantive — without network, the skill is empty.)
- **File Read** — to load the user-specified files/patterns being reviewed.
- **Glob / file pattern matching** — implicit from the `<file-or-pattern>` argument-hint.
- No code execution, no editing, no build step. The skill is a pure read-and-report static analyzer driven by the agent's LLM.

## 6. Key terminology

- **CLS** — Cumulative Layout Shift (Core Web Vital; explicit `width`/`height` prevents it)
- **`prefers-reduced-motion`** — CSS media query / accessibility preference for users sensitive to motion
- **`focus-visible`** — pseudo-class that shows focus ring only for keyboard navigation, not mouse clicks
- **Tabular numerals** — fixed-width digits via `font-variant-numeric: tabular-nums` for aligned columns
- **Hydration** — React/Next.js step where server-rendered HTML is matched up with client-side JS; mismatch causes warnings/re-render
- **Virtualization** — rendering only visible rows of long lists (e.g. `virtua`)
- **`content-visibility: auto`** — CSS hint that lets the browser skip rendering off-screen content
- **`inert`** — HTML attribute that makes an element non-interactive and removes it from accessibility tree
- **`nuqs`** — popular React library for syncing component state to URL query params
- **Safe-area insets** — `env(safe-area-inset-*)` for iPhone notch / Android cutout

## 7. Underlying technology

The rules are a distillation of consensus web-platform best practices circa 2024-2025, leaning on:

- **WCAG 2.x / ARIA Authoring Practices** for the accessibility and focus categories (semantic HTML, keyboard support, visible focus, alt text, live regions).
- **Core Web Vitals** (LCP, CLS, INP) for the performance and image categories (preload, preconnect, explicit dimensions, no layout thrash).
- **Tailwind utility class names** (`focus-visible:ring-*`, `truncate`, `line-clamp-*`, `min-w-0`, `text-wrap: balance`) — the checklist is written assuming a Tailwind-style design system, though the underlying CSS properties apply universally.
- **React / Next.js idioms** for the hydration, navigation, and forms categories (`onChange`/`defaultValue`, `<Link>`, `useState` vs URL state).
- **Vercel platform conventions** — `nuqs` for URL state, `fetchpriority`, Title Case in copy.
- **Mobile-web platform** for touch/safe-area/dark-mode (`touch-action`, `env(safe-area-inset-*)`, `color-scheme`).
- **Typography & i18n** standards (`Intl.*` APIs, non-breaking spaces, ellipsis character, curly quotes, `translate="no"`).

## 8. Wrapper observation

**Confidence: very high.** This is unambiguously a wrapper skill.

- The published SKILL.md at `vercel-labs/agent-skills/skills/web-design-guidelines/SKILL.md` is 39 lines and contains no rules — only a description of when to fire and an instruction to WebFetch `https://raw.githubusercontent.com/vercel-labs/web-interface-guidelines/main/command.md` on every invocation.
- The substantive rule corpus and the output-format contract both live in `command.md` (~180 lines, ~80 rules across 15 categories) in a separate repo `vercel-labs/web-interface-guidelines`.
- Every invocation re-fetches from the raw URL, so improvements to the agent's behavior must land in `command.md`, not in the wrapper SKILL.md.
- **`wrapper_points_to`**: `https://raw.githubusercontent.com/vercel-labs/web-interface-guidelines/main/command.md`
- Rationale: the wrapper exists so that the rule corpus can be iterated on a separate cadence (no agent-skill release needed) and so the same rules can be shared across multiple skill / slash-command surfaces. Optimization target for the skill-optimizer chain is therefore `command.md`.
Loading
Loading