claude/skills-external/design-motion-principles/workflows/audit.md
Bastien Chanot 469c807c10 feat(skills): add design-motion-principles from kylezantos
Motion/animation design skill with 3-designer lens (Emil Kowalski,
Jakub Krehel, Jhey Tompkins). Two modes: Create and Audit.
Complements frontend-design (broad) with deep motion expertise.

Integration points:
- skills-external/design-motion-principles/ — skill files + references
- link.sh EXTERNAL_SKILLS — symlink to ~/.claude/skills/
- install-plugins.sh step 8c — presence check
- update-all.sh step 7.2 — sync from GitHub
- profiles: design, full, web, web-full — listed as external
- plugin-advisor — decision table, recommended sets, conditional rules
- design-gate — symlink check + non-blocking warning if missing

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-25 22:40:23 +02:00

12 KiB

Workflow: Audit Mode

Review existing motion design and produce a per-designer report. Reconnaissance first, then a full audit, then a structured report. Never apply rules blindly.

Required Reading

Read as you reach each step (not all upfront):

  1. references/audit-checklist.md — your systematic guide (STEP 2)
  2. The weighted designer file(s) — emil-kowalski.md, jakub-krehel.md, jhey-tompkins.md (STEP 2)
  3. references/accessibility.md — mandatory every audit (STEP 2)
  4. references/anti-checklist.md — the quality gate: AI-slop motion categories + anti-patterns to flag (STEP 2)
  5. references/output-format.md — the report template, HTML mode + terminal mode (STEP 3)
  6. references/demo-shell.html — the demo-card template for HTML-mode per-finding demos (STEP 3)

STEP 1: Context Reconnaissance (DO THIS FIRST)

Before auditing any code, understand the project context.

Gather Context

Check these sources:

  1. CLAUDE.md — Any explicit context about the project's purpose or design intent
  2. package.json — What type of app? (Next.js marketing site vs Electron productivity app vs mobile PWA)
  3. Existing animations — Grep for motion, animate, transition, @keyframes. What durations are used? What patterns exist?
  4. Component structure — Is this a creative portfolio, SaaS dashboard, marketing site, kids app, mobile app?

Motion Gap Analysis (CRITICAL - Don't Skip)

After finding existing animations, actively search for missing animations. These are UI changes that happen without any transition:

Search for conditional renders without AnimatePresence:

# Find conditional renders: {condition && <Component />}
grep -n "&&\s*(" --include="*.tsx" --include="*.jsx" -r .

# Find ternary UI swaps: {condition ? <A /> : <B />}
grep -n "?\s*<" --include="*.tsx" --include="*.jsx" -r .

For each conditional render found, check:

  • Is it wrapped in <AnimatePresence>?
  • Does the component inside have enter/exit animations?
  • If NO to both → this is a motion gap that needs fixing

Common motion gap patterns:

  • {isOpen && <Modal />} — Modal appears/disappears instantly
  • {mode === "a" && <ControlsA />} — Controls swap without transition
  • {isLoading ? <Spinner /> : <Content />} — Loading state snaps
  • style={{ height: isExpanded ? 200 : 0 }} — Height changes without CSS transition
  • Inline styles with dynamic values but no transition property

Where to look for motion gaps:

  • Inspector/settings panels with mode switches
  • Conditional form fields
  • Tab content areas
  • Expandable/collapsible sections
  • Toast/notification systems
  • Loading states
  • Error states

State Your Inference

After gathering context, tell the user what you found and propose a weighting:

## Reconnaissance Complete

**Project type**: [What you inferred — e.g., "Kids educational app, mobile-first PWA"]
**Existing animation style**: [What you observed — e.g., "Spring animations (500-600ms), framer-motion, active:scale patterns"]
**Likely intent**: [Your inference — e.g., "Delight and engagement for young children"]

**Motion gaps found**: [Number] conditional renders without AnimatePresence
- [List the files/areas with gaps, e.g., "Settings panel mode switches", "Loading states"]

**Proposed perspective weighting**:
- **Primary**: [Designer] — [Why]
- **Secondary**: [Designer] — [Why]
- **Selective**: [Designer] — [When applicable]

Does this approach sound right? Should I adjust the weighting before proceeding with the full audit?

Use the Context-to-Perspective Mapping table in SKILL.md to propose the weighting.

Wait for User Confirmation

STOP and wait for the user to confirm or adjust. Do not proceed to the full audit until they respond.

If AskUserQuestion is available, present the decision as tappable options:

  • Confirm weighting — Proceed with the proposed primary/secondary/selective designers
  • Adjust primary — Swap which designer is primary (e.g., prioritize delight over restraint)
  • Adjust secondary — Change the secondary lens while keeping primary
  • Rebuild weighting — The project type inference was wrong; start over

Otherwise ask in plain text: "Does this weighting sound right, or should I adjust?"

If they adjust (e.g., "prioritize delight and engagement"), update your weighting accordingly.


STEP 2: Full Audit (After User Confirms)

Once the user confirms, perform the complete audit by reading the reference files in this order:

2a. Read the Audit Checklist First

Read references/audit-checklist.md — Use this as your systematic guide. It provides the structured checklist of what to evaluate.

2b. Read Designer Files for Your Weighted Perspectives

Based on your context weighting, read the relevant designer files:

  • Read references/emil-kowalski.md if Emil is primary/secondary — Restraint philosophy, frequency rules, decision frameworks
  • Read references/jakub-krehel.md if Jakub is primary/secondary — Production polish philosophy, what to check
  • Read references/jhey-tompkins.md if Jhey is primary/secondary — Playful experimentation philosophy, opportunities to surface

2c. Read Topical References as Needed

  • Read references/accessibility.md — MANDATORY. Always check for prefers-reduced-motion. No exceptions.
  • Read references/anti-checklist.md — Apply this as the audit's quality gate. AI-slop categories at the top (pulsing indicators, hover-scale-on-everything, stagger-spam, etc.) trigger findings; perspective-specific and general anti-patterns sit below. Each category includes a frequency heuristic so single intentional uses don't trip the gate.
  • Read references/performance.md — If you see complex animations, check for GPU optimization issues
  • Read references/motion-cookbook.md — Reference when making specific implementation recommendations (the recommended fix code, including the per-finding demo motion in HTML mode)

STEP 3: Output Format (HTML by default)

The audit produces a self-contained HTML report with auto-looping CSS demos beside Critical and Important findings. Read references/output-format.md for the full template (both HTML mode and terminal mode).

Default behavior — write and open the HTML report

  1. Resolve the write location. The file is written to motion-audits/{project-name}-{ISO-date}.html in the audited project's root.

    • Audited project root: run git rev-parse --show-toplevel from the agent's cwd. If it succeeds, use that path. If it fails (no .git ancestor), use cwd.
    • {project-name}: the name field from package.json at the project root if it exists; else the name field from pyproject.toml; else the basename of the project root. Strip any scoping prefix (@scope/pkgpkg) and sanitize to lowercase kebab-case ([a-z0-9-], replace others with -).
    • {ISO-date}: today's date as YYYY-MM-DD.
    • Example: <project-root>/motion-audits/my-app-2026-05-20.html.
    • Do not modify .gitignore. The user sees motion-audits/ in git status and decides whether to ignore it.
  2. Read references/demo-shell.html and use it as the template for each demo card. Embed one card per Critical + Important finding (Opportunities do not get demo cards). Use the suffixed-naming contract — @keyframes motion-{n}-... and .demo-card-{n}__motion-target, {n} = the finding's 1-indexed position across the whole report — so multiple findings don't collide on CSS names.

  3. Generate per-finding motion code by reading the audited code, the relevant lens reference, and references/motion-cookbook.md for the recipe. Use the shell's 0% / 66% / 100% cadence at animation-duration: 3s (~2s motion, ~1s hold, loop). The @keyframes 100% state must match the motion-target's default static rendering so the shell's prefers-reduced-motion guard shows the correct final visual.

  4. Write the file. Create motion-audits/ if it doesn't exist. Write the complete self-contained HTML document.

  5. Open in the default browser via OS-detected Bash dispatch:

    path="<absolute path to the HTML file>"
    if [ -n "$WSL_DISTRO_NAME" ] || grep -qi microsoft /proc/version 2>/dev/null; then
      win_path=$(wslpath -w "$path")
      cmd.exe /c start "" "$win_path" 2>/dev/null
    else
      case "$(uname -s)" in
        Darwin)               open "$path" ;;
        Linux)                xdg-open "$path" ;;
        MINGW*|MSYS*|CYGWIN*) start "" "$path" ;;
        *)                    echo "Unknown platform — open this file manually: $path" ;;
      esac
    fi
    

    If the open command returns non-zero or the platform is unrecognized, print Open this file in your browser: {absolute path} and continue. Never abort the audit because of a failed browser-open.

  6. Print the 3-line terminal summary:

    🎬 Motion audit complete — 🔴 {N} Critical · 🟡 {N} Important · 🟢 {N} Opportunities
    📄 Report: {absolute path}
    💡 Want the full report inline instead? Re-run with --terminal or say "show inline".
    

Terminal mode (flag-triggered)

When the user signals terminal mode (--terminal / --inline / --no-html flag, or "show the full report inline" / "skip the HTML" / "terminal only"), skip the HTML write and the browser-open and render the decorated-markdown report inline per references/output-format.md terminal mode. Do not print the 3-line summary in this case.

Do not summarize the audit content in either mode — users want full per-lens perspectives.


Agent Gotchas (Self-Check Before Writing the Report)

Common failure modes during HTML report generation. Most break silently or only manifest when a second finding lands in the same report.

  • Don't reuse keyframe or class names across findings. Each demo uses @keyframes motion-{n}-... and .demo-card-{n}__motion-target where {n} is the 1-indexed position across the WHOLE report. Duplicate names mean the second finding shadows the first and the first demo breaks silently.
  • Don't redefine the shell's CSS variables. Per-finding code uses var(--bg), var(--fg), var(--border), var(--accent), var(--loop-dim), var(--sans), var(--mono). Hard-coding colors or fonts breaks dark mode and typography consistency.
  • Don't write per-finding overrides inside the prefers-reduced-motion block. The shell's guard collapses all [class*="__motion-target"] animations. Make the @keyframes 100% state match the motion-target's default static rendering instead.
  • Don't include demo cards for Opportunities. Demos are reserved for Critical and Important. Surface Opportunities in text only.
  • Don't animate the report itself. No entrance, scroll, or mount animations on the report chrome — only the demo cards animate. Animating the report reproduces the AI-slop patterns the audit exists to catch.
  • Don't write to cwd if git rev-parse --show-toplevel succeeds. The report goes to {project-root}/motion-audits/. Only fall back to cwd when git returns nonzero.
  • Don't abort the audit if browser-open fails. A non-zero exit code is a "no default handler" condition, not an error. Print the path and continue.
  • Don't modify .gitignore. The skill never touches it. The user adds motion-audits/ themselves if they want.
  • Don't summarize per-lens findings. Each section needs its own findings + working-well items + the Through {Designer}'s lens: summary.

Success Criteria

  • Context gathered (CLAUDE.md, package.json, existing animations, structure)
  • Motion gap analysis run — conditional renders checked for missing animation
  • Weighting proposed and confirmed by the user
  • Audit checklist worked through systematically
  • Anti-checklist applied — AI-slop categories checked against the codebase
  • Accessibility checked — prefers-reduced-motion verified (mandatory)
  • HTML report written to motion-audits/, opened in browser, 3-line summary printed (or terminal-mode report rendered inline when flagged)
  • Report follows output-format.md with full per-lens sections; Critical + Important findings have looping demo cards