Hard Rules for the animate Skill: 5 Non-Negotiable Constraints in emilkowalski/skills

The animate skill enforces five hard rules: sequential gating, preset-only values, token reuse, built-in accessibility guards, and minimal tooling—any violation aborts the animation.

The animate skill in the emilkowalski/skills repository transforms design requests into production-ready motion code. Its hard rules are guardrails that ensure every animation passes the automated review-animations check and complies with team motion-design standards. This guide explains each rule with references to skills/animate/SKILL.md and practical examples.


Rule 1: Run the Sequence in Order

The first two gating steps—"should it animate?" and "what's the purpose?"—must be resolved before selecting any curve or duration.

As defined in SKILL.md at line 23, this prevents premature decisions that produce unnecessary or incorrect motion. If the interaction occurs 100+ times daily (like a button press), the gate typically returns no animation, favoring instant feedback instead.


Rule 2: No Approximated Values

Every easing curve, duration, and spring configuration must come from preset tables. Do not invent ad-hoc cubic-beziers like cubic-bezier(0.4,0,0.2,1).

This rule at SKILL.md line 24 guarantees visual consistency and maintains the motion token system as the single source of truth. Custom curves break the design system's cohesion and will fail automated review.


Rule 3: Extend Tokens, Don't Fork Them

Reuse existing design tokens such as --ease-out or duration scales. Adding a parallel motion system counts as a defect.

Line 25 of SKILL.md emphasizes this for maintainability. Token duplication creates technical debt and undermines the centralized system that designers and engineers share.


Rule 4: Reduced-Motion and Hover Gating Ship Built-In

Media-query guards—prefers-reduced-motion and @media (hover: hover)—must be embedded in the animation code itself, never patched later.

Specified at SKILL.md line 26, this ensures accessibility and platform-appropriate behavior from the first render. Post-hoc patches are unreliable and often overlooked.


Rule 5: Cheapest Tool That Works

Never pull in a heavyweight motion library for simple fades or transitions. Prefer CSS transitions, @starting-style, or WAAPI when they suffice.

This performance constraint from line 27 reduces bundle size and improves runtime metrics. The skill explicitly rejects library imports when native browser APIs can achieve the same effect.


Hard Rules in Practice: Code Examples

Example 1: Button Press (Gate Blocks Animation)

<button class="btn">Save</button>

<style>
  .btn {
    background: var(--color-primary);
    color: white;
    padding: .5rem 1rem;
    border: none;
    border-radius: .25rem;
    transition: background .12s var(--ease-out);
  }
  .btn:active {
    background: var(--color-primary-dark);
  }
</style>

Rule 1 stops motion for high-frequency interactions. A CSS transition on background satisfies Rule 5 (minimal tool) while using the --ease-out token per Rules 2 and 3.


Example 2: Modal Entrance (Full Animation)

<div class="modal" role="dialog" aria-modal="true">
  <h2>Settings</h2>
</div>

<style>
  .modal {
    --duration: 250ms;
    animation: slide-down var(--duration) var(--ease-out) forwards;
  }

  @keyframes slide-down {
    from { transform: translateY(-10%); opacity: 0; }
    to   { transform: translateY(0); opacity: 1; }
  }

  @media (prefers-reduced-motion: reduce) {
    .modal { animation: fade-in .15s ease forwards; }
  }
</style>

The gate passes (Rule 1). Values come from preset tables (Rule 2), tokens are reused (Rule 3), and reduced-motion is built-in (Rule 4).


Example 3: Tooltip with Hover Guard

<span class="tooltip" data-tip="Info">Hover me</span>

<style>
  .tooltip {
    position: relative;
    cursor: help;
  }
  .tooltip::after {
    content: attr(data-tip);
    position: absolute;
    bottom: 100%;
    left: 50%;
    transform: translateX(-50%) translateY(4px);
    opacity: 0;
    transition: opacity .14s var(--ease);
    pointer-events: none;
    background: var(--color-bg-tooltip);
    padding: .25rem .5rem;
  }
  @media (hover: hover) and (pointer: fine) {
    .tooltip:hover::after { opacity: 1; }
  }
</style>

Pure CSS transition (Rule 5), token reuse (Rule 3), and embedded hover guard (Rule 4).


Source Files and Automated Enforcement

File Purpose
skills/animate/SKILL.md Complete specification, lines 23-27 define hard rules
skills/animate/RECIPES.md Copy-paste implementations for common patterns
skills/review-animations/SKILL.md Automated reviewer that blocks PRs on rule violations

The review-animations skill parses output from this skill and enforces all five rules programmatically. Any violation aborts the animation and returns either a static fallback or an explanatory note.


Summary

  • Sequential gating—resolve purpose before picking motion parameters
  • Preset values only—no invented curves or durations
  • Token extension—reuse existing design tokens exclusively
  • Built-in accessibility—embed prefers-reduced-motion and hover guards
  • Minimal tooling—CSS transitions and WAAPI over libraries

Frequently Asked Questions

What happens if a hard rule is violated?

The skill aborts and returns a static fallback or explanation. The review-animations automation will block the PR with a specific rule violation message referencing SKILL.md.

Where are the preset values defined?

The token tables (easing curves, duration scales, spring configurations) are specified in skills/animate/SKILL.md and cross-referenced in RECIPES.md for common UI patterns.

Can I use Framer Motion or GSAP with this skill?

Only when the animation complexity genuinely requires it. Rule 5 mandates the cheapest tool that works—most UI feedback, entrances, and transitions should use CSS or WAAPI instead.

How does the skill handle reduced motion preferences?

Rule 4 requires prefers-reduced-motion guards in the animation code itself, not as external patches. The skill generates alternative animations or disables motion entirely based on the preset tables.

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 →