# Reviewing Animation Code Against High Craft Standards: The Ten Non-Negotiable Rules Explained

> Master animation code with ten non-negotiable rules. Learn how to review animations for high craft standards using deterministic checks and GPU-only constraints.

- Repository: [Emil Kowalski/skills](https://github.com/emilkowalski/skills)
- Tags: best-practices
- Published: 2026-08-02

---

**The *review-animations* skill enforces ten non-negotiable animation standards through deterministic rule checking, reference-driven precision, and mandatory GPU-only constraints.**

Reviewing animation code against high craft standards requires more than subjective taste—it demands a codified, repeatable framework. Emil Kowalski's `review-animations` skill in the `emilkowalski/skills` repository provides exactly that: an opinionated, rule-based reviewer that treats motion quality as a measurable engineering requirement. This guide breaks down the ten non-negotiable rules, the architecture that enforces them, and how to apply them in practice.

## How the Animation Reviewer Works

The skill operates through a deliberately simple architecture defined in [[`skills/review-animations/SKILL.md`](https://github.com/emilkowalski/skills/blob/main/skills/review-animations/SKILL.md)](https://github.com/emilkowalski/skills/blob/main/skills/review-animations/SKILL.md). It disables AI model generation via `disable-model-invocation: true` in its YAML frontmatter, ensuring deterministic, auditable behavior on every run.

The reviewer adopts the **mindset of a senior design engineer** whose bias is *motion that feels right*, not merely motion that runs. It defaults to flagging issues and only approves when every rule is satisfied.

## The Ten Non-Negotiable Rules

All findings are measured against the ten non-negotiable standards. When violated, the reviewer emits a markdown table row with the issue, a concrete fix, and rationale drawn from [[`skills/review-animations/STANDARDS.md`](https://github.com/emilkowalski/skills/blob/main/skills/review-animations/STANDARDS.md)](https://github.com/emilkowalski/skills/blob/main/skills/review-animations/STANDARDS.md).

### Rule 1: GPU-Only Properties

- Only `transform` and `opacity` may be animated
- **Violating**: `transition: all` or animating `width`, `height`, `top`, `left`
- **Fix**: Explicitly list `transform` and `opacity` only

```css
/* Before */
transition: all 300ms;

/* After */
transition: transform 200ms ease-out, opacity 200ms ease-out;

```

### Rule 2: Duration Ceiling

- UI animations must stay under **300ms** unless explicitly justified
- Reference values are pulled from [[`STANDARDS.md`](https://github.com/emilkowalski/skills/blob/main/STANDARDS.md)](https://github.com/emilkowalski/skills/blob/main/skills/review-animations/STANDARDS.md)
- Button press feedback: **100–160ms** (suggested: 120ms)

```css
.button {
  transition: transform 120ms var(--ease-out);
  transform: scale(0.97);
}

```

### Rule 3: Mandatory Ease-Out

- `ease-out` (or a strong custom cubic-bezier) is required for enter/exit motions
- `ease-in` delays the moment the user watches, making UI feel sluggish

| Before | After | Why |
| --- | --- | --- |
| `ease-in` on dropdown | `ease-out` + custom cubic-bezier | `ease-in` delays visual feedback, violating perceived responsiveness. |

### Rule 4: No "From Nothing" Scales

- Animations must start from a visible state
- **Violating**: `transform: scale(0)`
- **Fix**: `transform: scale(0.95)` paired with `opacity: 0`

| Before | After | Why |
| --- | --- | --- |
| `transform: scale(0)` | `transform: scale(0.95); opacity: 0` | `scale(0)` creates a disorienting "from-nothing" effect. |

### Rule 5: Prefers-Reduced-Motion Support

- All animations must respect `prefers-reduced-motion`
- Gated behind hover/pointer media queries where appropriate

| Before | After | Why |
| --- | --- | --- |
| Missing `prefers-reduced-motion` | `@media (prefers-reduced-motion: reduce) { … }` | Ensures accessibility for users who request reduced motion. |

### Rule 6: Origin-Aware Scaling

- Popovers require `transform-origin` based on trigger position
- Modals are exempt from this rule

### Rule 7: Escalation Triggers

The skill enumerates aggressive escalation triggers that immediately flag for blocking:

- `transition: all`
- `ease-in` on UI elements
- Missing `prefers-reduced-motion` support

### Rule 8: Reference-Driven Precision

Precise values (easing curves, duration tables, spring configs) live in [[`STANDARDS.md`](https://github.com/emilkowalski/skills/blob/main/STANDARDS.md)](https://github.com/emilkowalski/skills/blob/main/skills/review-animations/STANDARDS.md). The reviewer loads this file on demand to cite exact numbers instead of approximations.

### Rule 9: Remedial Hierarchy

The skill defines a clear escalation path:

1. **Deletion** — remove the animation entirely
2. **Replacement** — substitute with compliant motion
3. **Polishing** — refine existing compliant animation

### Rule 10: Mandatory Output Format

Every response must contain two sections:

- **Findings table**: markdown table with "Before", "After", "Why" columns
- **Verdict**: tiered commentary ending with explicit **Block** or **Approve**

## Practical Implementation

### Installation

```bash
npx skills@latest add emilkowalski/skills

```

### Detecting Violations in Code

The reviewer implements detection logic similar to:

```js
if (css.includes('transition: all')) {
  findings.push({
    before: 'transition: all 300ms',
    after: 'transition: transform 200ms ease-out',
    why: 'Unbounded property animation; forces layout/paint.'
  });
  // Block the change immediately
}

```

### Standard Reference Values

| Animation Type | Duration | Easing |
| --- | --- | --- |
| Button press | 100–160ms | ease-out |
| Popover enter | 200–250ms | ease-out, origin-aware |
| Modal enter | 200–300ms | ease-out |
| Exit animations | 150–200ms | ease-in (exceptions only) |

## Key Files and Their Roles

| File | Role |
| --- | --- |
| [[`skills/review-animations/SKILL.md`](https://github.com/emilkowalski/skills/blob/main/skills/review-animations/SKILL.md)](https://github.com/emilkowalski/skills/blob/main/skills/review-animations/SKILL.md) | Defines metadata, operating posture, escalation triggers, remedial hierarchy, and output format |
| [[`skills/review-animations/STANDARDS.md`](https://github.com/emilkowalski/skills/blob/main/skills/review-animations/STANDARDS.md)](https://github.com/emilkowalski/skills/blob/main/skills/review-animations/STANDARDS.md) | Canonical source of precise animation standards |
| [`README.md`](https://github.com/emilkowalski/skills/blob/main/README.md) (root) | High-level context for the skills framework |

## Summary

- The *review-animations* skill enforces **ten non-negotiable standards** through deterministic, reference-driven checking
- **GPU-only properties** (`transform`, `opacity`) and **300ms duration ceiling** are hard constraints
- **Ease-out is mandatory** for enter/exit motions; `ease-in` is treated as a regression
- **Accessibility** via `prefers-reduced-motion` is required, not optional
- **Origin-aware scaling** applies to popovers but not modals
- All precision values live in **version-controlled** [[`STANDARDS.md`](https://github.com/emilkowalski/skills/blob/main/STANDARDS.md)](https://github.com/emilkowalski/skills/blob/main/skills/review-animations/STANDARDS.md), enabling extension without code changes

## Frequently Asked Questions

### What makes these animation standards "non-negotiable"?

The standards are designed to protect **perceived performance** and **accessibility** without exception. According to the `emilkowalski/skills` source code, the reviewer defaults to flagging and only approves when every rule passes—there is no partial credit for "good enough" motion.

### Can I customize the duration limits or easing curves?

Yes, but only by modifying [[`STANDARDS.md`](https://github.com/emilkowalski/skills/blob/main/STANDARDS.md)](https://github.com/emilkowalski/skills/blob/main/skills/review-animations/STANDARDS.md). The reviewer loads reference values from this file at runtime, so changes propagate without touching the skill's core logic. This keeps the system auditable and version-controlled.

### Why does the reviewer block `transition: all` specifically?

`transition: all` forces the browser to track layout and paint properties for animation, defeating GPU acceleration. The skill treats this as an immediate escalation because it silently degrades performance in ways developers often don't detect during development.