ui-system skill is no longer a placeholder. Full design-system and interaction-design interviews with branching, defaults, batched question clusters, and an 'accept default / skip' protocol so users move through fast when they have taste and patient when they don't. Design system interview covers: visual posture, color (with WCAG contrast verification before writing), typography, spacing, radii, shadows, density, visual motion, components, theming, and accessibility tokens (focus ring, hit targets). Interaction design interview covers: input model, state-surface declarations per action class, motion posture and triggers, breakpoints, i18n, four state postures (empty/loading/error/offline), time formatting, keyboard policy, optimistic-update strategy with rollback and conflict resolution, gestures, focus management, notification patterns, selection, and drag-and-drop. Reference banks for "make it look like Linear/Notion/Stripe/etc." translate well-known products into starting tokens — user still confirms each value, no silent invention. Templates expanded to hold the full output: - design-system/SKILL.md grew sections for accessibility tokens, density, dark-mode mapping, contrast verification, theming variants - design-system/tokens.ts now exports color (light + dark), typography (family/size/weight/line-height/letter-spacing), spacing + density- aware padding tokens, radii, shadows, motion (durations + easings), z-index scale, breakpoints, hit-target minimums - design-system/components.md gained anatomy/state/a11y coverage for 10 primitives plus an "adding a new component" workflow and a "patterns to avoid" list (nested cards, color-only meaning, etc.) - interaction-design/SKILL.md gained sections for optimistic updates, conflict resolution, gestures, focus management, notification patterns, selection/multi-select, and drag-and-drop Hard rules: never invent on the user's behalf; <TBD> instead. Verify contrast before writing color tokens. Always declare prefers-reduced- motion as honored. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
7.6 KiB
7.6 KiB
Component vocabulary
The named components for . Component names match
ia.md where applicable. Do not introduce new components without
proposing them here first.
This file is a sidecar of the design-system skill — agents generating UI should be aware of every component in this list and prefer them to ad-hoc one-offs. New patterns belong here, not in mock files.
How to read this
For each component:
- Variants — distinct visual flavors with different semantic meaning
- Sizes — usually
sm / md / lg; pick the same scale across components - States — every visible state the component must handle
- Anatomy — the named slots / regions the component is composed of
- Tokens used — which design-system tokens this component reads
- A11y notes — load-bearing accessibility rules for this component
Primitives
Button
- Variants:
primary|secondary|ghost|destructive|link - Sizes:
sm|md|lg - States: default | hover | active | focus | focus-visible | disabled | loading
- Anatomy: optional leading icon · label · optional trailing icon · optional loading spinner
- Tokens used:
color.brand.primary,color.semantic.error(destructive),color.focus,padding.default,radius.md,motion.duration.fast,fontSize.sm/base/lg,fontWeight.medium - A11y:
- Hit target ≥
hitTarget.mobileformd+sizes aria-busywhile loading; preserve labelaria-disabledrather thandisabledif the action is permission-gated rather than form-invalidlinkvariant uses<a>, not<button>
- Hit target ≥
Input
- Variants:
text|textarea|select|checkbox|radio|toggle|password|number|date - Sizes:
sm|md|lg - States: default | focus | filled | disabled | readonly | error | success (rare)
- Anatomy: label · (optional) description · field · (optional) helper text · (error or hint) message
- Tokens used:
color.neutral.*,color.semantic.error,color.focus,padding.default,radius.sm,fontSize.base - A11y:
- Label is always present (visible or
aria-label) - Error message is
aria-describedby-linked to the field aria-invalid="true"while error- Required fields marked in two ways (asterisk +
requiredattribute) aria-describedbyfor helper text
- Label is always present (visible or
Card / Surface
- Variants:
flat|bordered|elevated(per design-system shadow posture) - States: default | hover (if interactive) | focus (if interactive) | disabled
- Anatomy: optional header · body · optional footer · optional media region
- Tokens used:
color.neutral.*,radius.lg,shadow.sm(elevated),padding.loose - A11y:
- If clickable, the entire card is one
<button>or<a>— not nested interactives - If contains interactives, card itself is not clickable
- If clickable, the entire card is one
Badge / Tag
- Variants:
neutral|success|warning|error|info|brand - Sizes:
sm|md - States: default | (removable) with close button
- Anatomy: optional dot · label · optional close button
- Tokens used:
color.semantic.*,radius.pill,fontSize.xs,fontWeight.medium
Avatar
- Variants:
image|initials|placeholder - Sizes:
xs|sm|md|lg|xl - States: default | with status indicator
- Anatomy: image / initials · (optional) status dot
- Tokens used:
radius.full,color.neutral.*(fallback bg),fontSize.*(initials sizing) - A11y:
alttext required for image variant; meaningful or emptyalt=""for purely decorative
Tooltip
- Variants:
default|error|info - States: hidden | shown
- Anatomy: trigger · floating panel · optional arrow
- Tokens used:
color.neutral.900bg,color.neutral.50text,radius.sm,shadow.md,motion.duration.fast - A11y:
role="tooltip",aria-describedbyon trigger- Show on hover AND focus (keyboard parity)
- Dismissible with
Esc - Never the only conveyance of critical information
Modal / Drawer / Popover
These are behavioral patterns — see the interaction-design skill for when to use which. The visual styling is here.
- Modal:
- Anatomy: backdrop · panel · optional header · body · optional footer · close button
- Tokens:
shadow.xl,radius.lg,motion.duration.default,zIndex.modal - Always traps focus; restores on close
- Drawer:
- Anatomy: backdrop · panel (side-anchored) · header · body · footer · close button
- Tokens:
shadow.xl,motion.duration.default,zIndex.drawer
- Popover:
- Anatomy: trigger · floating panel · optional arrow
- Tokens:
shadow.md,radius.md,zIndex.popover
Tabs
- Variants:
underline|pills|enclosed - States: active | inactive | hover | focus | disabled
- Anatomy: tab list · tab · panel
- A11y:
role="tablist",role="tab",role="tabpanel"- Arrow-key navigation between tabs (per WAI-ARIA Authoring Practices)
- Tab
aria-selectedandtabindexmanaged appropriately
Menu / Dropdown
- Variants:
default|with-icons|with-shortcuts|submenu - States: closed | open
- Anatomy: trigger · floating panel · menu items · separators
- Tokens used:
shadow.md,radius.md,padding.tight,zIndex.dropdown - A11y:
role="menu",role="menuitem"- Arrow-key navigation;
Esccloses - Type-ahead is encouraged
- Focus returns to trigger on close
Toast / Notification
- Variants:
default|success|warning|error|info - Anatomy: optional icon · title · optional description · optional action button · close button
- Tokens used:
color.semantic.*,radius.md,shadow.lg,motion.duration.default,zIndex.toast - A11y:
role="status"for non-critical,role="alert"for critical- Dismissible by user; don't auto-dismiss critical errors
- Stack region is
aria-live="polite"(orassertivefor errors)
Project-specific components
- Variants:
- Sizes:
- States:
- Anatomy: <slots / regions>
- Tokens used:
- A11y:
- Notes:
Patterns to avoid
Things that come up often and should be vetoed by default. Saves the agent from re-inventing them.
- Nested cards — flatten or use sections; visual hierarchy comes from spacing and dividers, not stacking surfaces
- Inline icons in body text — icons in body text rarely scale or align well; use them in headers, buttons, badges
- Modal-from-modal — if a modal needs to launch another modal, the first modal is doing too much
- Tooltip as the only conveyance — tooltips are supplementary; the primary information must be available without hover
- Color-only meaning — every color-coded distinction needs a redundant signal (icon, label, position)
- Custom focus rings that don't meet contrast — use the system focus-ring token
- Animation that violates
prefers-reduced-motion— always honor the user preference - Click targets below 44px on touch devices
Adding a new component
- Propose it here first with the same shape as the others (variants, states, anatomy, tokens, a11y).
- Add it to
tokens.tsif it needs new tokens. - Add a mock that uses it before writing real-code implementation.
- Council review (Maya for a11y, Marge for end-user) before locking in.