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

Enable animation in Diagram-Design by setting data-motion-mode="reveal|step|loop" on your root element and importing the canonical 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. 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 when motion is explicitly requested (see SKILL.md for routing logic)
  • Import the canonical controller — Every animated diagram must use 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:

<!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 data-motion-mode="step" data-step-count="4">

Step 2: Import the Canonical Controller

Include 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.

<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 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:

: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:

<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:

<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:

<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

<!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

<!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

<!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 (lines 68-78) enforces:

@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:


# 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 Complete animation contract with primitives, timing, accessibility rules, and anti-patterns
skills/diagram-design/assets/template-motion.html Canonical controller — must be used verbatim
skills/diagram-design/assets/example-policy-trace-animated.html Self-contained step-mode example
skills/diagram-design/SKILL.md System overview and routing logic
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 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 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?

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 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.

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 →