SuperAPI AI Directory

motion-review

Design & creation

View repository

Updated 10-15 19:52

About this skill

Reviewing Motion in a Diff

Default to flagging. Approval is earned, not assumed: motion that runs is not motion that passes, and a transition that merely works while landing from the wrong origin, firing on a keyboard shortcut, or holding the user for 450ms is a regression this diff introduced. Read every motion hunk before judging any line of it, measure each animation against a fixed bar rather than against your mood, and close with one word — Block or Approve. A review that ends in a paragraph of impressions has not been done.

This skill reviews the motion in a diff and nothing else. ui-review owns non-motion UI code; on a mixed diff ui-review runs first and hands its motion hunks here, so never re-report its spacing, type, or contrast findings. Two further boundaries: a whole-codebase sweep that ends in a prioritized fix plan is motion-audit, not this skill, and a rendered screen or screen recording rather than source text is design-critique.

Read the project's own motion vocabulary before writing the first finding. Grep for --ease-, --duration-, the Tailwind theme block, and whichever of motion/framer-motion, React Spring, GSAP, or plain CSS the package manifest actually carries. Review the diff against that system: if the repo defines --ease-drawer, a hand-typed cubic-bezier(0.32, 0.72, 0, 1) in the diff is a finding even though the number is correct, and every fix you propose must be written in the repo's existing tokens. A review that bolts on a parallel easing vocabulary has added the exact debt it was called to prevent.

Quick Reference

Topic Where
Exact curves, durations, spring configs, velocity and stagger numbers standards.md — open it the moment a finding needs a number, before you type one from memory
Documented exemptions and known false positives standards.md — open it before reporting anything that looks like a violation but sits on a modal, a marketing page, or a reduced-motion block

Core Principles

  1. Ask the frequency question before the easing question. A perfectly eased 200ms animation on a command-palette toggle is still a Block, and re-easing it is wasted work: the fix is deletion. The gate is 100+/day → no animation, ever, and any keyboard-initiated action is disqualified regardless of count. Exception: marketing and explanatory surfaces, where a given visitor sees the motion roughly once and the frequency gate does not bind.
  1. Flag the five prohibitions on sight and do not deliberate. transition: all, entering from scale(0), ease-in on product UI, transform-origin: center on a trigger-anchored popover, and any animation on a keyboard-initiated action are lint-checkable, so deliberating over them only makes the review slower. Exception: modals legitimately keep transform-origin: center because they are anchored to the viewport rather than to a trigger — reporting that costs you the reader's trust for every later row.

  2. Cite file:line and the exact replacement value, never an adjective. "Too slow" cannot be executed, and the author will guess wrong; a reviewable finding reads Drawer.tsx:41 — 500ms ease-in-out → 250ms var(--ease-drawer). Pull the number from standards.md rather than approximating. Exception: when the repo already owns a token for that role, cite the token name and not the literal behind it.

  3. Treat any product-UI duration over 300ms as a finding unless the diff says why. Perceived responsiveness is dominated by the first 100ms of movement, so a 180ms dropdown reads as faster than a 400ms one that covers the same distance. Exception: modals and drawers may run to 500ms, and marketing or explanatory motion is out of budget by design.

  4. Prefer deletion to correction, in that order. The remedial hierarchy is delete → reduce → re-ease → fix the origin → make it interruptible → move it to the GPU → make the timing asymmetric → polish → accessibility and cohesion, and an animation that is removed can never regress again. Exception: motion carrying spatial information — where a panel came from, which edge a toast leaves by — where deletion trades one regression for another.

  5. Judge interruptibility by how often the element is retriggered, not by which API it uses. @keyframes is not itself a defect; @keyframes on a toast stack, a toggle, or a drag is, because keyframes restart from zero while transitions and springs retarget from the current value. Exception: a one-shot entrance or a loader that always runs to completion, where restarting is unreachable.

  6. Do not flag a curve for being unfamiliar — flag a diff for carrying two curve families. Two published families exist and they genuinely disagree: one overshoots past 1 (cubic-bezier(0.175, 0.885, 0.32, 1.1)), one settles into it (cubic-bezier(0.23, 1, 0.32, 1)). Either is defensible; mixing them inside one product is the finding. standards.md carries both families and their attribution. Exception: a deliberately playful surface inside an otherwise crisp app, when the diff or a design doc states the intent — note it, do not report it.

  7. Do not re-litigate a decision the code already documents. A comment or design note explaining why a drawer runs long is evidence the tradeoff was made deliberately, and reopening it burns the review's credibility. Exception: the accessibility floor — a missing prefers-reduced-motion path or ungated :hover motion is never settled by a comment.

  8. "I cannot tell whether it feels right" is not a finding. Guessing at feel from source text produces noise that buries the rows that are real. Name the exact interaction to watch and hand it to design-critique; if the diff also needs it, say so in the verdict. Exception: when the source makes feel deterministic — a 2s ease-in on a dropdown needs no screen to judge.

Smell / Fix

Smell Fix
transition: all 300ms Name the properties: transition: transform 200ms var(--ease-out)
transform: scale(0) on enter transform: scale(0.95); opacity: 0
ease-in on a dropdown, sheet, or menu ease-out or the repo's strong custom curve
transform-origin: center on a popover, dropdown, or tooltip var(--transform-origin); leave modals alone
Animation on a shortcut, palette toggle, or arrow-key move Delete the animation
@keyframes on a toast, toggle, or drag A transition or spring so it retargets mid-flight
Animated width, height, margin, top, or left transform and opacity only
Framer Motion x / y / scale shorthands on a busy page The full transform string
Enter and exit share one duration on a press-and-hold Slow the deliberate phase, snap the release
A fourth hand-typed cubic-bezier in a repo that has tokens The existing token
No prefers-reduced-motion path on anything that moves Gentler, not zero — keep opacity, drop movement
A verdict of "looks good overall" Block or Approve, one word

Output Format

Two parts, in this order. The table form is mandatory — Emil Kowalski's review format explicitly forbids the Before: / After: list, because a list hides how many issues there are and cannot be scanned.

Part 1 — Findings table. One markdown table, one row per issue, columns | Before | After | Why |. Before carries the code as written plus file:line; After carries the exact replacement including the token name; Why is one clause on what it costs the user. No prose between rows.

Part 2 — Verdict. Group any remaining commentary by impact, highest first, omitting empty tiers: feel-breaking regressions · motion that should be deleted · performance · interruptibility and timing · origin, physicality, and cohesion · accessibility. Then state the decision on its own line.

  • Block — any feel-breaking regression, any animation on a keyboard-initiated or 100+/day action, any of the five prohibitions, or a non-GPU animation with a one-line GPU fix.
  • Approve — no feel-breaking regressions, nothing that should be deleted, durations and curves inside budget and inside one family, interruptibility handled where the element is retriggered, and a reduced-motion path present.

An empty findings table with a fast Approve is a real outcome. Manufacturing rows to look thorough costs more than it buys.

Checklist

  • Read every motion hunk in the diff before writing a row
  • Checked the repo's existing easing and duration tokens and written all fixes in them
  • Frequency question answered for each animation before any easing judgment
  • The five prohibitions scanned, with modals exempted from the origin rule
  • Every row cites file:line and an exact value pulled from standards.md
  • Durations checked against the per-element budget and the 300ms product ceiling
  • Interruptibility judged by retrigger rate, not by API
  • Curve family checked for mixing, not for unfamiliarity
  • Reduced-motion and hover gating checked on everything that moves
  • Anything unjudgeable from source handed to design-critique by name, not guessed
  • Output is one | Before | After | Why | table plus a one-word verdict