How the Animation Decision Framework Works in emilkowalski/skills

The Animation Decision Framework is a non-negotiable, four-step checklist defined in skills/emil-design-eng/SKILL.md that every animation must pass before implementation, ensuring motion is purposeful, performant, and accessible.

Emil Kowalski's skills repository encodes a disciplined approach to UI animation through the Animation Decision Framework. This systematic methodology lives in the emil-design-eng skill and serves as the foundation for all animation-related reviews and improvements across the codebase.

The Four-Step Animation Decision Framework

The framework operates as a strict gatekeeping system. Any skill that reviews or creates animations—including review-animations, improve-animations, and find-animation-opportunities—runs this checklist and automatically rejects motion that fails any step.

Step 1: Should This Animate at All? (Frequency-Based Guard)

The first decision uses a frequency table to determine motion eligibility. In skills/emil-design-eng/SKILL.md (lines 62-76), the framework asks: How often will users see this motion?

  • High frequency (100+ times/day): No animation ever. Keyboard-driven actions like command palettes must feel instant.
  • Medium frequency: Drastically reduce or eliminate motion.
  • Low/Occasional frequency: Standard animation permitted.
  • Rare/First-time: Delight animations allowed.

This guard guarantees that high-frequency interactions remain snappy and never break the mental model of instant feedback.

Step 2: Define the Purpose

If motion passes the frequency gate, you must identify a concrete purpose. According to lines 81-93 of the central skill file, valid reasons include spatial consistency, state indication, explanation, feedback, or preventing jarring changes.

If the only justification is "it looks cool," the animation is rejected. This step prevents decorative motion that adds latency without improving usability.

Step 3: Choose the Right Easing

The framework mandates specific easing curves based on animation type. As documented in lines 95-100 of skills/emil-design-eng/SKILL.md:

  • Entrances: Use ease-out (fast start, quick feedback).
  • Static UI interactions (hover, toggle): Use custom curves with fast initial velocity and gentle settle.
  • Never use ease-in: This makes the UI feel sluggish.

The improve-animations skill reinforces this with an explicit "never use ease-in" rule.

Step 4: Set Duration and Respect Accessibility

Final constraints govern timing and user preferences. Lines 101-108 specify:

  • Duration budget: UI animations must stay under 300 ms.
  • Reduced motion: Respect prefers-reduced-motion by reducing or stripping movement, while keeping opacity and color changes that aid comprehension.

This keeps interactions feeling fast, avoids motion sickness, and maintains performance budgets.

How the Framework Enforces Motion Quality Across the Repository

The framework is non-negotiable and centralized to ensure consistency. The review-animations/STANDARDS.md file (lines 9-14) enforces the same frequency-based rules and 300 ms budget during code reviews.

When improve-animations/SKILL.md audits a codebase, it embeds the checklist (lines 23-31) to generate remediation plans. Similarly, find-animation-opportunities/SKILL.md uses the framework to evaluate new motion proposals before surfacing them.

By centralizing logic in skills/emil-design-eng/SKILL.md, the repository guarantees that every motion decision—whether in review, audit, or opportunity detection—is justified, performant, and accessible.

Implementing the Framework in Code

These TypeScript and CSS examples demonstrate how to encode the framework's rules in actual implementations.

Frequency-Based Guard

// helpers/animationDecisions.ts
export const shouldAnimate = (freq: 'high' | 'medium' | 'low' | 'rare'): boolean => {
  // high = 100+ times/day (keyboard shortcuts, command palette)
  // medium = tens times/day (hover, list navigation)
  // low = occasional (modals, drawers)
  // rare = first-time or celebratory
  switch (freq) {
    case 'high':   return false;               // no animation ever
    case 'medium': return false;               // drastically reduce
    case 'low':    return true;                // standard animation
    case 'rare':   return true;                // may add delight
  }
};

Purpose-Driven CSS

/* Example: toast entrance – spatial consistency */
.toast {
  animation: slideIn 250ms ease-out forwards; /* purpose: maintain direction */
}

/* If purpose were only "looks cool" → remove animation */

Easing and Duration Enforcement

// utils/animation.ts
export const uiTransition = (property: string) => ({
  transition: `${property} 200ms cubic-bezier(0.25, 0.8, 0.25, 1)`, // custom ease-out
});

Reduced Motion Detection

// hooks/useReducedMotion.ts
import { useEffect, useState } from 'react';

export const useReducedMotion = () => {
  const [prefersReduced, setPrefersReduced] = useState(false);
  useEffect(() => {
    const mql = window.matchMedia('(prefers-reduced-motion: reduce)');
    setPrefersReduced(mql.matches);
    const handler = (e: MediaQueryListEvent) => setPrefersReduced(e.matches);
    mql.addEventListener('change', handler);
    return () => mql.removeEventListener('change', handler);
  }, []);
  return prefersReduced;
};

Use this hook to swap heavy transforms for simple opacity or color changes when prefersReduced returns true.

Summary

  • The Animation Decision Framework lives in skills/emil-design-eng/SKILL.md and consists of a mandatory four-step checklist.
  • Frequency analysis blocks animation on high-frequency interactions (100+ times/day) to maintain perceived performance.
  • Purpose validation rejects decorative motion that lacks concrete UX justification.
  • Easing rules mandate ease-out for entrances and ban ease-in curves that create sluggishness.
  • Accessibility requirements cap duration at 300 ms and enforce prefers-reduced-motion support.
  • The framework is cross-referenced by review-animations, improve-animations, and find-animation-opportunities skills to maintain consistent quality.

Frequently Asked Questions

What happens if an animation fails one step of the framework?

Any code that fails a step of the Animation Decision Framework is automatically rejected. According to the repository structure, the review-animations skill consults skills/emil-design-eng/SKILL.md before raising findings and will block motion that lacks proper frequency justification, concrete purpose, correct easing, or accessibility compliance.

Why are keyboard-driven actions specifically banned from animating?

Keyboard shortcuts and command palette interactions often occur 100+ times per day. As defined in the frequency table at lines 62-76 of skills/emil-design-eng/SKILL.md, these high-frequency actions must never animate because motion introduces perceived latency and breaks the user's mental model of instant feedback, making the application feel slower than it is.

How does the framework handle users who prefer reduced motion?

The framework mandates respect for the prefers-reduced-motion media query. While heavy transform animations should be reduced or stripped for these users, the skills/emil-design-eng/SKILL.md file (lines 101-108) specifies that opacity and color changes can be preserved since they aid comprehension without causing motion sickness.

Where can I find the source files for the Animation Decision Framework?

The central definition resides in skills/emil-design-eng/SKILL.md. Supporting enforcement files include skills/review-animations/STANDARDS.md for code review standards, skills/improve-animations/SKILL.md for audit remediation, and skills/find-animation-opportunities/SKILL.md for evaluating new motion proposals.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →