# How to Enable and Configure the Optional Animation Layer in Diagram-Design

> Easily enable and configure the optional animation layer in Diagram-Design. Learn how to set data-motion-mode and import the template-motion.html controller for dynamic diagrams.

- Repository: [Cathryn Lavery/diagram-design](https://github.com/cathrynlavery/diagram-design)
- Tags: how-to-guide
- Published: 2026-08-14

---

**Enable animation in Diagram-Design by setting `data-motion-mode="reveal|step|loop"` on your root element and importing the canonical [`template-motion.html`](https://github.com/cathrynlavery/diagram-design/blob/main/template-motion.html) controller.**

The Diagram-Design repository by cathrynlavery/cathrynlavery-diagram-design ships with a **static-first rendering pipeline**. Animation is treated as an optional presentation layer that you must explicitly opt into. This guide walks through the exact steps, configuration options, and verification流程 required to add motion to your diagrams without breaking accessibility or performance budgets.

## Understanding the Animation Architecture

Diagram-Design follows a strict **animation contract** defined in [`references/animation.md`](https://github.com/cathrynlavery/diagram-design/blob/main/references/animation.md). The system loads animation capabilities only when requested, keeping static diagrams lightweight and print-friendly.

Three conditions must be met to enable animation:

- **Load the animation reference** — The SKILL system loads [`references/animation.md`](https://github.com/cathrynlavery/diagram-design/blob/main/references/animation.md) when motion is explicitly requested (see [`SKILL.md`](https://github.com/cathrynlavery/diagram-design/blob/main/SKILL.md) for routing logic)
- **Import the canonical controller** — Every animated diagram must use [`assets/template-motion.html`](https://github.com/cathrynlavery/diagram-design/blob/main/assets/template-motion.html) verbatim
- **Declare a motion mode** — Set `data-motion-mode` on your root element to activate the rendering pipeline

## Choosing a Motion Mode

The animation contract supports four distinct modes. Select based on your narrative needs and accessibility requirements.

| Mode | Behavior | Best For |
|------|----------|----------|
| **none** | Static rendering only; no JavaScript loaded | Print, screenshots, reduced-motion preferences |
| **reveal** | Single deterministic autoplay ending on complete frame | Short ordered explanations (< 5 seconds) |
| **step** | Paused semantic states with full playback controls | Teaching, detailed comparisons, user-paced exploration |
| **loop** | Continuous decorative motion that never changes meaning | Quiet flow hints, ambient indicators (≥ 3 seconds) |

## Enabling Animation: Step-by-Step Configuration

### Step 1: Add the Root Attribute

Set `data-motion-mode` on your outermost container element:

```html
<!DOCTYPE html>
<html data-motion-mode="reveal">
<!-- or data-motion-mode="step" or data-motion-mode="loop" -->

```

For **step mode**, also declare the total step count:

```html
<html data-motion-mode="step" data-step-count="4">

```

### Step 2: Import the Canonical Controller

Include [`template-motion.html`](https://github.com/cathrynlavery/diagram-design/blob/main/template-motion.html) exactly as provided in the repository. Per the animation contract, this file must be used **unchanged** — do not modify the inline JavaScript or CSS.

```html
<head>
  <link rel="stylesheet" href="your-local-style.css">
</head>
<body>
  <!-- Canonical controller from assets/template-motion.html -->
  <script src="template-motion.html"></script>
  ...
</body>

```

The controller in [`template-motion.html`](https://github.com/cathrynlavery/diagram-design/blob/main/template-motion.html) handles:

- Mode-specific initialization
- Keyboard shortcuts (Space to play/pause, arrow keys for stepping)
- Reduced-motion preference detection
- Control button wiring for step mode

### Step 3: Configure CSS Timing Variables

Override these custom properties in your stylesheet to adjust pacing:

```css
:root {
  --motion-fast: 160ms;      /* Micro-transitions */
  --motion-step: 480ms;      /* Between-state transitions */
  --motion-hold: 720ms;      /* Pause duration per step */
  --motion-total: 3600ms;    /* Maximum: step-count × --motion-hold, capped at 8s */
  --motion-ease: cubic-bezier(0.2, 0.8, 0.2, 1);
}

```

## Marking Animated Elements

### Semantic Items with Step Attribution

Tag each animated element with `data-motion-item` and a numeric `data-step`:

```html
<svg viewBox="0 0 200 100">
  <g data-motion-item data-step="1">
    <rect x="10" y="10" width="180" height="20" fill="var(--accent)"/>
  </g>
  <g data-motion-item data-step="2">
    <path d="M10,50 L190,50" stroke="var(--ink)"/>
  </g>
</svg>

```

**Constraints from the animation contract:**

- DOM order must match narrative order
- Maximum **two items per step**
- Step numbering must be continuous (no gaps)

### Decorative Loop Elements

For **loop mode**, use `data-motion-decorative` instead of step attribution:

```html
<circle cx="100" cy="50" r="30"
        data-motion-decorative
        style="animation: token-flow var(--motion-total) linear infinite"/>

```

## Adding Playback Controls (Step Mode)

Include control buttons outside your SVG with `data-motion-action` attributes:

```html
<div data-motion-controls>
  <button data-motion-action="play">▶︎</button>
  <button data-motion-action="pause">⏸︎</button>
  <button data-motion-action="prev">←</button>
  <button data-motion-action="next">→</button>
  <button data-motion-action="replay">↺</button>
  <span role="status" aria-live="polite"></span>
</div>

```

The canonical controller automatically wires these buttons and manages state synchronization.

## Complete Code Examples

### Reveal Mode: Minimal Animated Diagram

```html
<!DOCTYPE html>
<html data-motion-mode="reveal">
<head>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <script src="template-motion.html"></script>

  <svg viewBox="0 0 200 100">
    <rect x="10" y="10" width="180" height="80" 
          fill="var(--paper)" stroke="var(--ink)"/>
    <path data-motion-item data-step="1"
          d="M20,20 L180,20"
          stroke="var(--accent)" stroke-width="2" fill="none"
          pathLength="1"
          style="stroke-dasharray:1;stroke-dashoffset:1"/>
  </svg>
</body>
</html>

```

The `pathLength` and `stroke-dasharray` technique enables CSS-only drawing animation for reveal mode under 5 seconds.

### Step Mode: Full Control Interface

```html
<!DOCTYPE html>
<html data-motion-mode="step" data-step-count="3">
<head>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <script src="template-motion.html"></script>

  <div data-motion-controls>
    <button data-motion-action="play">Play</button>
    <button data-motion-action="pause">Pause</button>
    <button data-motion-action="prev">Previous</button>
    <button data-motion-action="next">Next</button>
    <button data-motion-action="replay">Replay</button>
    <span role="status" aria-live="polite"></span>
  </div>

  <svg viewBox="0 0 200 100">
    <g data-motion-item data-step="1">
      <rect x="10" y="10" width="180" height="20" fill="var(--accent)"/>
    </g>
    <g data-motion-item data-step="2">
      <rect x="10" y="40" width="180" height="20" fill="var(--accent)"/>
    </g>
    <g data-motion-item data-step="3">
      <rect x="10" y="70" width="180" height="20" fill="var(--accent)"/>
    </g>
  </svg>
</body>
</html>

```

### Loop Mode: Decorative Flow Token

```html
<!DOCTYPE html>
<html data-motion-mode="loop">
<head>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <script src="template-motion.html"></script>

  <svg viewBox="0 0 200 100">
    <circle cx="100" cy="50" r="30" 
            fill="none" stroke="var(--accent)" stroke-width="4"
            data-motion-decorative
            style="animation: pulse var(--motion-total) ease-in-out infinite"/>
  </svg>
</body>
</html>

```

## Accessibility and Reduced Motion

The animation contract mandates automatic fallback. The CSS in [`references/animation.md`](https://github.com/cathrynlavery/diagram-design/blob/main/references/animation.md) (lines 68-78) enforces:

```css
@media (prefers-reduced-motion: reduce) {
  /* Forces complete static frame */
  /* Hides all motion controls */
  /* Disables all transitions and animations */
}

```

No additional configuration required — the canonical controller handles detection and fallback.

## Verifying Your Animated Diagram

Run the verification suite to ensure compliance with the animation contract:

```bash

# Validate single diagram

python3 scripts/verify-motion.py path/to/your-diagram.html

# Run adversarial tests against verifier

python3 scripts/test-verify-motion.py

# Lint skin compliance

python3 scripts/lint-skin.py path/to/your-diagram.html

```

These scripts check:

- Mode declaration validity
- Step continuity and count matching
- Motion budget adherence (≤ 8 seconds total)
- Accessibility markup completeness
- Unmodified canonical controller usage

## Key Reference Files

| File | Purpose |
|------|---------|
| [`skills/diagram-design/references/animation.md`](https://github.com/cathrynlavery/diagram-design/blob/main/skills/diagram-design/references/animation.md) | Complete animation contract with primitives, timing, accessibility rules, and anti-patterns |
| [`skills/diagram-design/assets/template-motion.html`](https://github.com/cathrynlavery/diagram-design/blob/main/skills/diagram-design/assets/template-motion.html) | Canonical controller — must be used verbatim |
| [`skills/diagram-design/assets/example-policy-trace-animated.html`](https://github.com/cathrynlavery/diagram-design/blob/main/skills/diagram-design/assets/example-policy-trace-animated.html) | Self-contained step-mode example |
| [`skills/diagram-design/SKILL.md`](https://github.com/cathrynlavery/diagram-design/blob/main/skills/diagram-design/SKILL.md) | System overview and routing logic |
| [`scripts/verify-motion.py`](https://github.com/cathrynlavery/diagram-design/blob/main/scripts/verify-motion.py) | Contract compliance verifier |

## Summary

- **Enable animation** by setting `data-motion-mode="reveal|step|loop"` on your root element
- **Import [`template-motion.html`](https://github.com/cathrynlavery/diagram-design/blob/main/template-motion.html)** exactly as provided — no modifications permitted
- **Choose mode by narrative need**: reveal for quick autoplay, step for controlled exploration, loop for ambient decoration
- **Mark elements** with `data-motion-item` and `data-step` (or `data-motion-decorative` for loops)
- **Respect constraints**: continuous steps, max two items per step, 8-second total budget
- **Verify compliance** with [`scripts/verify-motion.py`](https://github.com/cathrynlavery/diagram-design/blob/main/scripts/verify-motion.py) before distribution

## Frequently Asked Questions

### What happens if I don't set `data-motion-mode`?

The diagram renders completely static with no JavaScript loaded. This is the default behavior and recommended for print, screenshots, or any context where motion adds no value.

### Can I modify the controller in [`template-motion.html`](https://github.com/cathrynlavery/diagram-design/blob/main/template-motion.html)?

No. The animation contract explicitly requires using the canonical controller unchanged. The verification scripts detect any modifications and will reject your diagram. If you need different behavior, use a different mode or file an issue against the repository.

### How does reduced motion accessibility work?

The controller automatically detects `prefers-reduced-motion: reduce` via media query. When active, all animations disable immediately, controls hide, and the diagram snaps to its complete static state. No manual intervention required — this is enforced by the CSS in [`references/animation.md`](https://github.com/cathrynlavery/diagram-design/blob/main/references/animation.md) at lines 68-78.

### Why does step mode require controls outside the SVG?

Separating controls from the graphic maintains semantic clarity and ensures keyboard accessibility. The `data-motion-controls` container can be styled and positioned independently, while the controller script handles all state synchronization between buttons and the visualization.