Gsd-2 userinterface-wiki
UI/UX best practices for web interfaces. Use when reviewing animations, CSS, audio, typography, UX patterns, prefetching, or icon implementations. Covers 11 categories from animation principles to typography. Outputs file:line findings.
install
source · Clone the upstream repo
git clone https://github.com/gsd-build/gsd-2
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/gsd-build/gsd-2 "$T" && mkdir -p ~/.claude/skills && cp -r "$T/src/resources/skills/userinterface-wiki" ~/.claude/skills/gsd-build-gsd-2-userinterface-wiki && rm -rf "$T"
manifest:
src/resources/skills/userinterface-wiki/SKILL.mdsource content
User Interface Wiki
Comprehensive UI/UX best practices guide for web interfaces. Contains 152 rules across 12 categories, prioritized by impact to guide automated code review and generation.
When to Apply
Reference these guidelines when:
- Implementing or reviewing animations (CSS transitions, Motion/Framer Motion)
- Choosing between springs, easing curves, or no animation
- Working with AnimatePresence and exit animations
- Writing CSS with pseudo-elements or View Transitions API
- Adding audio feedback or procedural sound to UI
- Building morphing icon components
- Animating container width/height with dynamic content
- Designing UI that respects cognitive psychology (Fitts's, Hick's, Miller's laws)
- Implementing predictive prefetching for perceived performance
- Setting up typography, OpenType features, or numeric formatting
Rule Categories by Priority
| Priority | Category | Impact | Prefixes |
|---|---|---|---|
| 1 | Animation Principles | CRITICAL | , , |
| 2 | Timing Functions | HIGH | , , , |
| 3 | Exit Animations | HIGH | , , , |
| 4 | CSS Pseudo Elements | MEDIUM | , , |
| 5 | Audio Feedback | MEDIUM | , , , |
| 6 | Sound Synthesis | MEDIUM | , , , |
| 7 | Morphing Icons | LOW | |
| 8 | Container Animation | MEDIUM | |
| 9 | Laws of UX | HIGH | |
| 10 | Predictive Prefetching | MEDIUM | |
| 11 | Typography | MEDIUM | |
| 12 | Visual Design | HIGH | |
Quick Reference
1. Animation Principles (CRITICAL)
- User animations must complete within 300mstiming-under-300ms
- Similar elements use identical timing valuestiming-consistent
- Context menus: no entrance animation, exit onlytiming-no-entrance-context-menu
- Use exponential ramps for natural decay, not lineareasing-natural-decay
- Linear easing only for progress indicatorseasing-no-linear-motion
- Interactive elements need :active scale transformphysics-active-state
- Squash/stretch in 0.95-1.05 rangephysics-subtle-deformation
- Springs for overshoot-and-settle, not easingphysics-spring-for-overshoot
- Stagger delays under 50ms per itemphysics-no-excessive-stagger
- One prominent animation at a timestaging-one-focal-point
- Dim modal/dialog backgroundsstaging-dim-background
- Animated elements respect z-index layersstaging-z-index-hierarchy
2. Timing Functions (HIGH)
- Gesture-driven motion (drag, flick) must use springsspring-for-gestures
- Interruptible motion must use springsspring-for-interruptible
- Springs preserve input energy on releasespring-preserves-velocity
- Avoid excessive oscillation in spring paramsspring-params-balanced
- System state changes use easing curveseasing-for-state-change
- Entrances use ease-outeasing-entrance-ease-out
- Exits use ease-ineasing-exit-ease-in
- View transitions use ease-in-outeasing-transition-ease-in-out
- Linear only for progress/time representationeasing-linear-only-progress
- Press/hover: 120-180msduration-press-hover
- Small state changes: 180-260msduration-small-state
- User-initiated max 300msduration-max-300ms
- Fix slow feel with shorter duration, not curveduration-shorten-before-curve
- No animation for high-frequency interactionsnone-high-frequency
- Keyboard navigation instant, no animationnone-keyboard-navigation
- Context menus: no entrance, exit onlynone-context-menu-entrance
3. Exit Animations (HIGH)
- Conditional motion elements need AnimatePresence wrapperexit-requires-wrapper
- Elements in AnimatePresence need exit propexit-prop-required
- Dynamic lists need unique keys, not indexexit-key-required
- Exit mirrors initial for symmetryexit-matches-initial
- useIsPresent in child, not parentpresence-hook-in-child
- Call safeToRemove after async cleanuppresence-safe-to-remove
- Disable interactions on exiting elementspresence-disable-interactions
- Mode "wait" doubles duration; halve timingmode-wait-doubles-duration
- Mode "sync" causes layout conflictsmode-sync-layout-conflict
- Use popLayout for list reorderingmode-pop-layout-for-lists
- Nested AnimatePresence needs propagate propnested-propagate-required
- Coordinate parent-child exit durationsnested-consistent-timing
4. CSS Pseudo Elements (MEDIUM)
- ::before/::after need content propertypseudo-content-required
- Pseudo-elements over extra DOM nodes for decorationpseudo-over-dom-node
- Parent needs position: relativepseudo-position-relative-parent
- Z-index for correct pseudo-element layeringpseudo-z-index-layering
- Negative inset for larger hit targetspseudo-hit-target-expansion
- Use ::marker for custom list bullet stylespseudo-marker-styling
- Use ::first-line for typographic treatmentspseudo-first-line-styling
- View transitions need view-transition-nametransition-name-required
- Each transition name unique during transitiontransition-name-unique
- Remove transition name after completiontransition-name-cleanup
- Prefer View Transitions API over JS librariestransition-over-js-library
- Style ::view-transition-group for custom animationstransition-style-pseudo-elements
- Use ::backdrop for dialog backgroundsnative-backdrop-styling
- Use ::placeholder for input stylingnative-placeholder-styling
- Use ::selection for text selection stylingnative-selection-styling
5. Audio Feedback (MEDIUM)
- Every sound must have a visual equivalenta11y-visual-equivalent
- Provide toggle to disable soundsa11y-toggle-setting
- Respect prefers-reduced-motion for sounda11y-reduced-motion-check
- Allow independent volume adjustmenta11y-volume-control
- No sound on typing or keyboard navappropriate-no-high-frequency
- Sound for payments, uploads, submissionsappropriate-confirmations-only
- Sound for errors that can't be overlookedappropriate-errors-warnings
- No sound on hover or decorative momentsappropriate-no-decorative
- Inform, don't punish with harsh soundsappropriate-no-punishing
- Preload audio files to avoid delayimpl-preload-audio
- Default volume subtle (0.3), not loudimpl-default-subtle
- Reset currentTime before replayimpl-reset-current-time
- Sound weight matches action importanceweight-match-action
- Sound duration matches action durationweight-duration-matches-action
6. Sound Synthesis (MEDIUM)
- Reuse single AudioContext, don't create per soundcontext-reuse-single
- Resume suspended AudioContext before playingcontext-resume-suspended
- Disconnect audio nodes after playbackcontext-cleanup-nodes
- Exponential ramps for natural decayenvelope-exponential-decay
- Exponential ramps target 0.001, not 0envelope-no-zero-target
- Set initial value before rampingenvelope-set-initial-value
- Filtered noise for clicks/tapsdesign-noise-for-percussion
- Oscillators with pitch sweep for tonal soundsdesign-oscillator-for-tonal
- Bandpass filter to shape percussive soundsdesign-filter-for-character
- Click sounds: 5-15ms durationparam-click-duration
- Click filter: 3000-6000Hzparam-filter-frequency-range
- Gain under 1.0 to prevent clippingparam-reasonable-gain
- Filter Q: 2-5 for focused but naturalparam-q-value-range
7. Morphing Icons (LOW)
- Every icon uses exactly 3 SVG linesmorphing-three-lines
- Unused lines use collapsed constantmorphing-use-collapsed
- All icons share same viewBox (14x14)morphing-consistent-viewbox
- Rotational variants share group and base linesmorphing-group-variants
- Spring physics for grouped icon rotationmorphing-spring-rotation
- Respect prefers-reduced-motionmorphing-reduced-motion
- Instant rotation jump between non-grouped iconsmorphing-jump-non-grouped
- Round stroke line capsmorphing-strokelinecap-round
- Icon SVGs are aria-hiddenmorphing-aria-hidden
8. Container Animation (MEDIUM)
- Outer animated div, inner measured div; never same elementcontainer-two-div-pattern
- Guard bounds === 0 on initial render, fall back to "auto"container-guard-initial-zero
- Use ResizeObserver for measurement, not getBoundingClientRectcontainer-use-resize-observer
- Set overflow: hidden on animated container during transitionscontainer-overflow-hidden
- Use sparingly: buttons, accordions, interactive elementscontainer-no-excessive-use
- Use callback ref (not useRef) for measurement hookscontainer-callback-ref
- Add small delay for natural catching-up feelcontainer-transition-delay
9. Laws of UX (HIGH)
- Size interactive targets for easy clicking (min 32px)ux-fitts-target-size
- Expand hit areas with invisible padding or pseudo-elementsux-fitts-hit-area
- Minimize choices to reduce decision timeux-hicks-minimize-choices
- Chunk data into groups of 5-9 for scannabilityux-millers-chunking
- Respond within 400ms to feel instantux-doherty-under-400ms
- Fake speed with skeletons, optimistic UI, progress indicatorsux-doherty-perceived-speed
- Accept messy input, output clean dataux-postels-accept-messy-input
- Show what matters now, reveal complexity laterux-progressive-disclosure
- Use familiar UI patterns users know from other sitesux-jakobs-familiar-patterns
- Visual polish increases perceived usabilityux-aesthetic-usability
- Group related elements spatially with tighter spacingux-proximity-grouping
- Similar elements should look alikeux-similarity-consistency
- Use boundaries to group related contentux-common-region-boundaries
- Make important elements visually distinctux-von-restorff-emphasis
- Place key items first or last in sequencesux-serial-position
- End experiences with clear success statesux-peak-end-finish-strong
- Move complexity to the system, not the userux-teslers-complexity
- Show progress toward completionux-goal-gradient-progress
- Show incomplete state to drive completionux-zeigarnik-show-incomplete
- Simplify complex visuals into clear formsux-pragnanz-simplify
- Prioritize the critical 20% of featuresux-pareto-prioritize-features
- Minimize extraneous cognitive loadux-cognitive-load-reduce
- Visually connect related elements with lines or framesux-uniform-connectedness
10. Predictive Prefetching (MEDIUM)
- Trajectory prediction over hover; reclaims 100-200msprefetch-trajectory-over-hover
- Prefetch by intent, not viewport; avoid wasted bandwidthprefetch-not-everything
- Use hitSlop to trigger predictions earlierprefetch-hit-slop
- Fall back gracefully on touch devices (no cursor)prefetch-touch-fallback
- Prefetch on keyboard navigation when focus approachesprefetch-keyboard-tab
- Use predictive prefetching where latency is noticeableprefetch-use-selectively
11. Typography (MEDIUM)
- Tabular numbers for columns, dashboards, pricingtype-tabular-nums-for-data
- Oldstyle numbers blend into body texttype-oldstyle-nums-for-prose
- Slashed zero in code-adjacent UIstype-slashed-zero
- Keep calt enabled for contextual glyph adjustmenttype-opentype-contextual-alternates
- Enable ss02 to distinguish I/l/1 and 0/Otype-disambiguation-stylistic-set
- Leave font-optical-sizing auto for size-adaptive glyphstype-optical-sizing-auto
- Antialiased font smoothing on retina displaystype-antialiased-on-retina
- text-wrap: balance on headings for even linestype-text-wrap-balance-headings
- Offset underlines below descenderstype-underline-offset
- Disable font-synthesis to prevent faux bold/italictype-no-font-synthesis
- Use font-display: swap to avoid invisible text during loadtype-font-display-swap
- Use continuous weight values (100-900) with variable fontstype-variable-weight-continuous
- text-wrap: pretty for body text to reduce orphanstype-text-wrap-pretty
- Pair text-align: justify with hyphens: autotype-justify-with-hyphens
- Add letter-spacing to uppercase and small-caps texttype-letter-spacing-uppercase
- Use diagonal-fractions for proper typographic fractionstype-proper-fractions
12. Visual Design (HIGH)
- Inner radius = outer radius minus padding for nested elementsvisual-concentric-radius
- Layer multiple shadows for realistic depthvisual-layered-shadows
- All shadows share same offset direction (single light source)visual-shadow-direction
- Use neutral colors, not pure black, for shadowsvisual-no-pure-black-shadow
- Shadow size indicates elevation in consistent scalevisual-shadow-matches-elevation
- Animate shadow via pseudo-element opacity for performancevisual-animate-shadow-pseudo
- Use a consistent spacing scale, not arbitrary valuesvisual-consistent-spacing-scale
- Semi-transparent borders adapt to any backgroundvisual-border-alpha-colors
- Six-layer shadow anatomy for polished buttonsvisual-button-shadow-anatomy
How to Use
Read individual rule files for detailed explanations and code examples:
rules/timing-under-300ms.md rules/spring-for-gestures.md rules/ux-doherty-under-400ms.md rules/type-tabular-nums-for-data.md
Each rule file contains:
- Brief explanation of why it matters
- Incorrect code example with explanation
- Correct code example with explanation
Full Compiled Document
For the complete guide with all rules expanded:
AGENTS.md