agentleFS
dafaalzdafaalz/agent-skills/skills/ui-motion/SKILL.md

ui-motion

Skill2 starsChanged 52 days agoMITView on GitHub

Use when designing, implementing, or polishing CSS transitions, FLIP animations, gesture feedback, spring physics, or delight choreography. Don't use for layout styling (use frontend-design), accessibility audits (use ui-ux-review), interactive mockups (use prototype), React render optimization (use react), or multi-task execution plans (use agent-planning).

9 other projects use a version of this.

Adopted by

Most recently taken up by

The file

Show its rules and text

We split this skill into the rules it gives an agent

22 rules. 0 are common, 13 are distinctive, and 9 are very specific to this project.

  • 0

    Common

    Most of the 8 edited versions we read keep these.

  • 13

    Distinctive

    This author's own choices. Worth a look.

  • 9

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Authoring animations from scratch: Follow the build sequence below to gate necessity, select tools, and pick exact tokens.

    line 28
  2. Distinctive:

    Refining tactile micro-interactions: Add active press feedback, anchor popovers to trigger coordinates, eliminate secondary tooltip delays, …

    line 30
  3. Distinctive:

    Codebase audits and refactor planning: When called with an audit request (e.g.

    line 32
  4. Distinctive:

    Avoid these core failure modes:

    line 60
  5. Very specific:

    Animating keyboard-initiated actions: Never animate actions triggered by keyboard shortcuts (Cmd+Space, Esc, Tab).

    line 63
  6. Distinctive:

    Preserve state feedback when motion is disabled: Never eliminate state registration when animations are turned off.

    line 64
  7. Very specific:

    Using incorrect motion properties: Avoid ease-in on interactive entrances, scale(0) on mounting elements, keyframes on rapidly triggered …

    line 67
  8. Very specific:

    Altering source code during audits: When auditing repositories, generate structured plans under docs/superpowers/plans/ without mutating …

    line 69
  9. Distinctive:

    Animating bulk historical data during initial load: Never bind entrance animations to message histories or bulk collection renders.

    line 70
  10. Very specific:

    Tearing down ephemeral elements without exit choreography: Never call element.remove() synchronously on live activity indicators.

    line 71
  11. Distinctive:

    If the request fails this gate, state the decision directly and do not write animation code.

    line 87
  12. Distinctive:

    If no purpose applies, halt and do not write animation code.

    line 103
  13. Distinctive:

    Never run two animation engines on the exact same property simultaneously.

    line 121
  14. Very specific:

    Mount and exit orchestration: Use @starting-style for mount frames.

    line 131
  15. Very specific:

    Use ease-out for entering elements.

    line 148
  16. Very specific:

    Use ease-in-out for elements already on screen changing position or morphing.

    line 149
  17. Very specific:

    Use linear for scroll timelines (animation-timeline: view()) and hold-to-confirm progress indicators.

    line 150
  18. Distinctive:

    Follow this duration budget reference:

    line 156
  19. Distinctive:

    Keep functional UI animations under 300ms.

    line 167
  20. Very specific:

    Never branch conditionally on useReducedMotion() in JSX before initial hydration.

    line 187
  21. Distinctive:

    When reviewing or proposing UI micro-interaction changes, format findings using an exact table with Before, After, and Why columns:

    line 203
  22. Distinctive:

    Verify code against this checklist before delivering.

    line 217

“Common” is measured: kept by at least 6 in 10 of the 8 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

UI motion engineering

Design, build, audit, and optimize hardware-accelerated user interface motion.

Overview

UI motion engineering delivers hardware-accelerated, physically grounded interface motion that preserves utility, improves spatial orientation, and avoids decorative bloat. Motion copies nature to establish spatial consistency (an internal map of where intangible things live in software). Because physical nature is slow, high-frequency actions demand restraint: keyboard shortcuts execute in 0ms, ease-out curves front-load velocity, gestures remain interruptible mid-flight, and state feedback persists even when motion is disabled. Consult deep reference documents in references/ for recipes, gesture physics, platform standards, and audit playbooks.

<HARD-GATE> Write-Target Boundary. In Author mode, write only to component files containing motion, transition, or animation styling. In Audit mode, write only to `docs/superpowers/plans/` for audit plans and `.agents/state/ui-motion/` for findings. Never modify application state logic, backend calls, or accessibility roles. Any change to `prefers-reduced-motion` handlers requires explicit user approval. </HARD-GATE>

Modes

Select an execution mode before Step 1:

  • Author mode (default). Implement choreographies, transitions, and gesture physics.
  • Audit mode. Inspect animation performance, check frame drops, and verify reduced-motion compliance without editing styles.

Workflow router

Identify user intent and route execution immediately:

  1. Authoring animations from scratch. Follow the build sequence below to gate necessity, select tools, and pick exact tokens. Consult references/recipes.md for pre-built component patterns.
  2. Mental models, time perception, and personality. Consult references/mental-models-and-perception.md for spatial continuity, the Wise artificial delay paradox, Android touch prediction, personality calibration, and the Pokémon state feedback invariant.
  3. Refining tactile micro-interactions. Add active press feedback, anchor popovers to trigger coordinates, eliminate secondary tooltip delays, apply context menu blink exits, and format reviews using the Before, After, Why table.
  4. Fluid gestures and spring physics. Consult references/physics-and-gestures.md for Apple momentum decay projection, rubber band boundaries, pointer capture, mid-flight retargeting, and velocity handoffs.
  5. Codebase audits and refactor planning. When called with an audit request (e.g. /ui-motion audit <target>), follow references/audit-and-plans.md to inspect the repository against motion failure modes and generate structured refactor plans under docs/superpowers/plans/ without mutating source files.
  6. Mobile web and native platform motion. Consult references/mobile-web-and-native.md for mobile Safari viewport sizing (100dvh), 300ms tap delay elimination, 16px input auto-zoom prevention, touch overscroll boundaries, and React Native Reanimated worklet UI thread isolation.
  7. Translating informal animation vocabulary. Consult references/vocabulary.md when the user describes an animation informally or by sensation rather than technical names.
  8. Browser compositor and Google rendering standards. Consult references/google-standards.md when diagnosing Chromium layer explosion, auditing Core Web Vitals (INP and CLS) frame budgets, adopting Material Design 3 motion tokens, or implementing Android physics-based fling and spring animations.
  9. Desktop native and platform motion. Consult references/desktop-and-platform.md for Windows 11 DWM compositor tokens, Mica backdrop rules, macOS AppKit NSAnimationContext atomic batching, Electron and Tauri non-client title bar dragging without IPC loop latency, and Linux Wayland buffer sync.
  10. Kinetic typography and shimmer. Consult references/kinetic-typography-and-shimmer.md for character stagger sequences, blur filter boundaries, text-clip gradient shimmer, webfont loading synchronization, and CDP visual test capture timing.
  11. Creative and editorial storytelling. Consult references/creative-and-editorial.md for RAF LERP pointer inertia, dynamic spotlight cards, windowed parallax, clip-path curtain wipes, dimensional multi-plane hero layering, and SVG grain.
  12. Canvas scrubbing and smooth scroll. Consult references/canvas-and-scroll-scrubbing.md for Lenis synchronization, 2D canvas frame sequences, dense GOP video scrub encoding, DPR capping, predictive caching, and sliding pill tabs.

Reference quick routing

Motion domainReference moduleScope
Animation & delightreferences/animation-and-delight.mdMicro-interactions, spring physics, & delight choreography
Component recipesreferences/recipes.mdPre-built component animations & transitions
Physics & gesturesreferences/physics-and-gestures.mdApple momentum decay, rubber-banding, & gestures
Mobile & nativereferences/mobile-web-and-native.mdMobile Safari viewport, 100dvh, & touch latency
Desktop & platformreferences/desktop-and-platform.mdWindows Mica, macOS AppKit, & Electron frame timing
Google standardsreferences/google-standards.mdMaterial 3 motion tokens & Core Web Vitals INP/CLS
Kinetic typographyreferences/kinetic-typography-and-shimmer.mdCharacter stagger sequences & gradient shimmer
Canvas & scrollreferences/canvas-and-scroll-scrubbing.mdSmooth scroll sync & canvas frame scrubbing
Creative & editorialreferences/creative-and-editorial.mdRAF LERP pointer inertia, spotlight cards, & wipes
Mental modelsreferences/mental-models-and-perception.mdSpatial continuity & time perception calibration
Vocabularyreferences/vocabulary.mdInformal motion descriptions to technical tokens
Audit playbooksreferences/audit-and-plans.mdPerformance inspection & non-destructive audit plans

Execution invariants

Avoid these core failure modes:

  1. Animating elements that must stay static. The frequency gate below intentionally produces zero lines of code when motion degrades utility. Deliver an instant state toggle instead.
  2. Animating keyboard-initiated actions. Never animate actions triggered by keyboard shortcuts (Cmd+Space, Esc, Tab). Users know the outcome; animation forces waiting. Deliver an instant 0ms state change.
  3. Preserve state feedback when motion is disabled. Never eliminate state registration when animations are turned off. Preserve instant tactile or visual cues such as selection blinks or high-contrast flashes; never use shake as shake is a vestibular trigger.
  4. Locking user input during animation. Transitions must remain interruptible and retargetable mid-flight. Never apply pointer-events: none to transforming elements.
  5. Using instant transitions on high-stakes operations (The Wise paradox). Completing financial or irreversible actions in 0ms induces user distrust. Use an artificial 350ms to 450ms confirmation animation to close the perception delta.
  6. Using incorrect motion properties. Avoid ease-in on interactive entrances, scale(0) on mounting elements, keyframes on rapidly triggered elements, or sluggish durations above 300ms.
  7. Approximating motion values. Take every curve, duration, and spring parameter from the reference tables. Never invent arbitrary cubic-bezier coordinates.
  8. Altering source code during audits. When auditing repositories, generate structured plans under docs/superpowers/plans/ without mutating source files.
  9. Animating bulk historical data during initial load. Never bind entrance animations to message histories or bulk collection renders. Render historical logs instantly without motion, and gate animations behind reactive flags (isNew: boolean) for live events.
  10. Tearing down ephemeral elements without exit choreography. Never call element.remove() synchronously on live activity indicators. Apply an exit transition (opacity: 0, scale(0.95)) over 120ms before removing nodes from the DOM.

The build sequence

Step 1. Frequency gate

Evaluate interaction frequency before writing motion code:

FrequencyDecision
100+ times per day (keyboard shortcuts, command palette, core navigation)Disqualify motion immediately. Use an instant 0ms state toggle.
Context menus and right-click actionsOpen instantly in 0ms; animate selection blink and 120ms fade-out on exit only.
Tens of times per day (hover effects, list navigation, frequent toggles)Limit to subtle transitions under 160ms or disqualify.
Occasional (modals, drawers, toasts, settings dialogs)Eligible for standard transitions (150ms to 250ms).
Rare or high-stakes (onboarding, task completion, financial settlement)Permitted for expressive feedback or artificial trust confirmation (up to 450ms).

If the request fails this gate, state the decision directly and do not write animation code. Deliver the non-motion alternative instead.

Completion criterion. The interaction frequency is classified and confirmed eligible for motion, or disqualified in favor of an instant 0ms state toggle.

Step 2. Sanctioned purpose selection

Name exactly one sanctioned purpose before writing code:

  • Feedback. Confirm that the interface registered user interaction.
  • Spatial consistency. Show element origin and departure points to build an internal map of where controls live.
  • State indication. Make a state transition legible.
  • Preventing a jarring change. Bridge content that would otherwise jump instantaneously.
  • Explanation. Demonstrate how an onboarding or marketing flow operates.
  • Trust calibration. Bridge the perception delta during instantaneous high-stakes operations (such as payments or deletions).
  • Delight. Permitted only at the rare or first-time tier.

If no purpose applies, halt and do not write animation code. Data tables, financial graphs, and reading content must remain stationary.

Completion criterion. Exactly one sanctioned purpose declared before writing animation code.

Step 3. Tool selection

Walk down this table in order and select the first matching tool:

NeedTool
Hover, press, color, class toggleCSS transition
Mount/exit animation without JS runtimeCSS @starting-style + transition-behavior: allow-discrete
Shared-element & DOM state morphsdocument.startViewTransition(() => flushSync(fn)) with dynamic view-transition-name cleanup
Scroll-tied reveal or progressCSS Scroll-driven animations (animation-timeline: view())
Predetermined motion off main threadCSS animation
Programmatic interrupts with CSS performanceWAAPI (element.animate()) with composite: "add" (commitStyles + cancel on finish; cap at 8 instances)
Springs, layout transitions, exit animations, gesturesMotion (motion.dev)

Never run two animation engines on the exact same property simultaneously.

Completion criterion. The cheapest capable tool is selected with compositor CSS transitions prioritized over JavaScript animation libraries.

Step 4. Hardware acceleration and property scoping

  • Animate transform and opacity exclusively; never animate width, height, margin, padding, top, or left. Transforms and opacity run directly on the compositor thread without layout recalculation. Accordions use grid-template-rows: 0fr -> 1fr or interpolate-size: allow-keywords. Allow clip-path: inset() on creative editorial curtain reveals.
  • Start entry transitions from scale(0.95) with zero opacity; never use scale(0).
  • Set transform-origin with fallback at the trigger. Anchor popovers, dropdowns, and tooltips using var(--transform-origin, center) with trigger coordinates. Modals remain exempt and stay centered via margin: auto.
  • Provide tactile press feedback on all touch and pointer surfaces. Gate :hover strictly by @media (hover: hover) and (pointer: fine). Apply :active transform: scale(0.97) with touch-action: manipulation directly to pressable targets.
  • Mount and exit orchestration: Use @starting-style for mount frames. Gate exit unmounting on transitionend (verifying e.target === e.currentTarget), transitioncancel, and a deterministic (duration + 34ms) fallback watchdog timer.
  • View Transitions pseudo-elements: Set pointer-events: none on ::view-transition-group(*). Lock height: 100% and object-fit: none on ::view-transition-old/new during container aspect-ratio morphs. Scope unique view-transition-name tokens dynamically to active elements only and remove on completion.

Completion criterion. Motion styles animate transform and opacity exclusively with valid trigger-anchored transform origins and orchestrated exit transitions.

Step 5. Easing curves, spring physics, and ProMotion synchronization

--ease-out: cubic-bezier(0.23, 1, 0.32, 1); /* strong ease-out front-loading velocity for UI entries */
--ease-in: cubic-bezier(0.32, 0, 0.67, 0); /* fast acceleration for UI exits */
--ease-in-out: cubic-bezier(0.77, 0, 0.175, 1); /* on-screen repositioning and curtain wipes */
--ease-drawer: cubic-bezier(0.32, 0.72, 0, 1); /* iOS drawer curve */
--ease-quintic: cubic-bezier(0.22, 1, 0.36, 1); /* weighted editorial presentations, hero entries */
--ease-expo: cubic-bezier(0.16, 1, 0.3, 1); /* kinetic text stagger, high-velocity reveals */

Apply these easing and personality selection rules:

  • Use ease-out for entering elements. Exits may use ease-in to accelerate off-screen. Never use ease-in on interactive entrances or press feedback.
  • Use ease-in-out for elements already on screen changing position or morphing.
  • Use linear for scroll timelines (animation-timeline: view()) and hold-to-confirm progress indicators.
  • Calibrate springs: UI uses { stiffness: 300, damping: 30 } (critically damped, zero bounce); active press uses { stiffness: 400, damping: 17 }.
  • Mid-flight retargeting mutates the target coordinate on a single stateful solver inheriting live instantaneous velocity v(t) and position x(t) without resetting state.
  • Gesture flick velocity filtering computes release velocity across samples in a rolling 40ms ring buffer, zeros velocity if idle over 45ms, and clamps release velocity to [-3500, 3500] px/s.
  • ProMotion RAF loops integrate physics via timestamp deltas clamped to dt <= 0.032s with 4ms (240Hz) internal sub-stepping to prevent tunneling or explosion after tab throttling.

Follow this duration budget reference:

ElementTarget duration
Button press feedback100 to 160ms
Tooltips and small popovers125 to 200ms
Dropdowns and selects150 to 250ms
Modals and sheet drawers200 to 400ms
High-stakes trust confirmation350 to 450ms
Creative editorial storytelling600 to 1400ms

Keep functional UI animations under 300ms. Reserve 600 to 1400ms for creative editorial entrances.

Completion criterion. Custom cubic bezier tokens and duration budgets assigned without using ease-in on entrances.

Step 6. Accessibility, fallback feedback, and SSR hydration

@media (prefers-reduced-motion: reduce) {
  *, ::before, ::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
@media (hover: hover) and (pointer: fine) {
  .element:hover { transform: scale(1.04); }
}

Never branch conditionally on useReducedMotion() in JSX before initial hydration. Tag swapping triggers React 19 hydration mismatches and traps server-rendered opacity: 0 in permanent invisibility. Use identical DOM trees with [data-motion-enter] attribute contracts and CSS !important overrides.

Disable spatial motion deltas without overriding structural layout transforms (translate3d(x,y,0) and translate(-50%, -50%)). Never apply transform: none !important globally under reduced motion because it breaks positioning transforms. Collapse animation durations and replace spatial entrances with opacity fades.

Preserve state feedback under reduced motion (The Pokémon principle). Replace spatial motion with an instant border flash, selection blink, or background tint pulse so users register state changes without motion sickness. Never preserve shake; shake is a vestibular trigger.

Defer mobile focus past transition completion. Delay .focus({ preventScroll: true }) until the entry transition completes (duration + 10ms). Never auto-focus text inputs on touch viewports (pointer: coarse or < 640px) to prevent virtual keyboard layout jumps. Focus the container or close button instead.

Completion criterion. Styles include @media (prefers-reduced-motion: reduce) overrides with preserved non-motion feedback and zero conditional JSX tag branching.

Boundary isolation

Confine animation rules strictly to motion timing, CSS transforms, and gesture hooks. Never alter core application state logic, backend API calls, or accessibility roles in the name of animation.

Review format

When reviewing or proposing UI micro-interaction changes, format findings using an exact table with Before, After, and Why columns:

BeforeAfterWhy
transition: all 300mstransition: transform 200ms ease-outSpecify exact properties to avoid expensive style recalculations
transform: scale(0)transform: scale(0.95); opacity: 0Physical objects never emerge from absolute zero
ease-in on dropdown entranceease-out with custom curveease-in on entrance delays initial motion and feels sluggish
Missing active press feedbacktransform: scale(0.97) on active pressPressable targets must provide immediate tactile feedback
transform-origin: center on popovervar(--transform-origin, center)Popovers scale from trigger origin, while dialog modals remain centered
400ms enter on keyboard shortcutInstant 0ms toggleKeyboard actions reflect deliberate user intent and require zero waiting
Removing state feedback on reduced motionInstant border flash or selection blinkRetain state impact proof when motion is disabled via instant border flash or selection blink

Quick audit checklist

Verify code against this checklist before delivering. Every item represents an automatic rejection:

TitlePattern descriptionWhy it failsConcrete fix
Transition alltransition: all shorthand in stylesheetAnimates expensive layout and paint properties causing jankName the exact properties (transform, opacity)
Scale-zero entrancetransform: scale(0) used as entrance mount stateObjects cannot physically emerge from a dimensionless pointUse scale(0.95) paired with zero opacity
Ease-in entranceease-in applied to interactive entrancesSlow initial acceleration feels unresponsive and sluggishUse ease-out token (reserve ease-in strictly for exits)
Generic ease-outBrowser default ease-out on deliberate UILacks distinct personality and natural decelerationUse custom curve cubic-bezier(0.23, 1, 0.32, 1)
Keyboard animationAnimation on keyboard actions or shortcutsUser already anticipates outcome; motion forces idle waitingApply instant 0ms state toggle
Context menu animationSliding or expanding context menu entrance animationBlocks instant command executionUse instant 0ms entry, selection blink, and 120ms exit fade
Motionless feedback dropEliminating state feedback when motion is disabledLeaves user uncertain whether action registeredRetain instant blink, border pulse, or color flash; never shake
Input lock during motionNon-interruptible animation or blocked pointer eventsTraps user interaction mid-flightRetarget live presentation transforms mid-flight
Instant high-stakes action0ms transition on irreversible or high-stakes operationsInduces user distrust from lack of perceptible processingUse 350ms to 450ms confirmation to close perception delta
Excessive durationFunctional UI animation duration over 300msDrags interactive rhythm and wastes user timeBound duration strictly between 150ms and 250ms
Unguarded transform-origintransform-origin declared without dynamic fallbackScales popovers from arbitrary viewport locationsDeclare var(--transform-origin, center)
Rapid element keyframesCSS keyframes on rapidly triggered elementsKeyframe animations cannot be interrupted cleanlyUse CSS transitions or spring physics
Layout property animationAnimating width, height, margin, padding, top, or leftTriggers expensive layout recalculations on main threadAnimate transform and opacity (accordions use grid rows)
Main-thread script loopsNon-accelerated JS transform loopsStalls main thread during concurrent script executionUse WAAPI compositor execution or CSS transitions
Ungated hover motionHover animation triggered on touch devicesCreates sticky persistent hover states on mobileWrap in @media (hover: hover) and (pointer: fine)
Destructive reduced-motionGlobal transform: none !important under reduced motionBreaks layout positioning transforms like centeringCollapse durations to 0.01ms; preserve structural transforms
Unguarded unmountUnmounting without transitionend guard or fallbackLeaves orphaned DOM nodes when transitions cancelFilter e.target === e.currentTarget, listen to transitioncancel
Unclamped physics stepUnclamped delta-time in RAF physics loopsCauses spring physics explosion on background tab wakeClamp dt <= 0.032s with 4ms internal sub-stepping
Duplicate view-transitionDuplicate view-transition-name tokens in DOMInvalidates entire document view transitionScope tokens dynamically during active transition

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.