Diagram-Design Animation Modes: A Complete Guide to None, Reveal, Step, and Loop

Diagram-Design implements four mutually exclusive animation modes—none, reveal, step, and loop—each governed by a strict static-first accessibility contract that guarantees full diagram availability for screen readers and reduced-motion users before any motion is applied.

The cathrynlavery/diagram-design repository treats animation as optional progressive enhancement, not a required feature. This philosophy is codified in skills/diagram-design/references/animation.md, where every mode adheres to a contract ensuring assistive technologies always encounter complete, navigable diagrams regardless of JavaScript or CSS availability.

The Four Animation Modes Explained

Each mode is declared via data-motion-mode="…" on a container with data-motion-root. The modes are exclusive—a diagram cannot combine, for example, reveal and step behaviors.

none: Static-First Default

The none mode produces a fully stable figure with zero JavaScript dependency.

  • Behavior: The diagram renders exactly as authored, with no motion, no controls, and no timing considerations.
  • Implementation: Pure HTML/SVG; no template-motion.html controller loads.
  • Use cases: Print workflows, screenshot capture, email embeds, and environments where motion is explicitly unwanted.
<div data-motion-root data-motion-mode="none">
  <!-- Complete SVG content visible immediately -->
  <svg aria-labelledby="diagram-title">
    <title id="diagram-title">System Architecture Overview</title>
    <!-- All nodes, edges, and labels fully rendered -->
  </svg>
</div>

According to the animation contract in animation.md, none is the implicit default when no data-motion-mode is specified.

reveal: Deterministic Autoplay

The reveal mode executes a single deterministic animation sequence that stops at the final frame.

  • Behavior: Content appears progressively on load, then stabilizes permanently.
  • Implementation: CSS-only for sequences ≤5 seconds; longer sequences trigger the scoped controller from skills/diagram-design/assets/template-motion.html.
  • Use cases: Ordered explanations like request flows, where one automated walkthrough suffices.
<div data-motion-root data-motion-mode="reveal">
  <path data-motion-item data-step="1" class="motion-reveal" d="..."/>
  <path data-motion-item data-step="2" class="motion-reveal" d="..."/>
  <path data-motion-item data-step="3" class="motion-reveal" d="..."/>
</div>

The reveal timing follows fixed CSS variables: --motion-fast: 160ms, --motion-step: 480ms, --motion-hold: 720ms. Total sequence budget: 8 seconds maximum.

step: User-Controlled Progressive Disclosure

The step mode presents paused semantic states that users advance manually via explicit controls.

  • Behavior: Diagram begins at step 0 (static preview or blank canvas); user controls pacing.
  • Implementation: Inline JavaScript from template-motion.html binds Play, Pause, Replay, Previous, and Next buttons to the nearest data-motion-root.
  • Use cases: Teaching scenarios, policy trace diagrams, comparative analysis—any context where audience control improves comprehension.
<div data-motion-root data-motion-mode="step">
  <g data-motion-item data-step="1" aria-label="Initial request">
    <rect .../>
  </g>
  <g data-motion-item data-step="2" aria-label="Validation layer">
    <rect .../>
  </g>
  <g data-motion-item data-step="3" aria-label="Response construction">
    <rect .../>
  </g>
</div>

<!-- Control panel injected by controller -->
<div data-motion-controls>
  <button data-motion-action="prev">Previous</button>
  <button data-motion-action="play">Play</button>
  <button data-motion-action="pause">Pause</button>
  <button data-motion-action="next">Next</button>
  <button data-motion-action="replay">Replay</button>
</div>

The DOM order of data-motion-item elements must match narrative order; at most two items appear per step to prevent cognitive overload.

loop: Decorative Repetition

The loop mode enables endless decorative motion that adds no semantic meaning.

  • Behavior: Pure CSS animation repeats indefinitely (minimum 3-second cycle).
  • Implementation: No JavaScript required; data-motion-decorative marks non-essential elements.
  • Use cases: Subtle visual indicators like "live data" tokens or attention-directing pulses.
<div data-motion-root data-motion-mode="loop">
  <!-- Diagnostic: this element loops but conveys no information -->
  <circle data-motion-decorative 
          class="motion-pulse" 
          cx="50" cy="50" r="5"/>
</div>

The loop mode is strictly decorative per the contract. No diagram may rely on loop animation to communicate essential relationships.

The Accessibility Contract: Static-First Enhancement

The animation.md specification mandates seven guarantees that protect users regardless of their technology stack or motion preferences.

1. Source Completeness

All semantic content—nodes, labels, connectors, outcomes—must be present in the raw HTML/SVG before motion enhancement. Only elements within .motion-ready containers may be hidden or transformed.

2. Stable Capture Frame

Every animated diagram must expose a data-frame="static" (or ?motion=static query) view that:

  • Displays the complete diagram
  • Hides all playback controls
  • Serves print, screen-reader narration, and SVG/PNG export workflows

3. CSS-Driven Presentation

Visual changes use CSS transitions and keyframes exclusively. JavaScript scope is limited to:

  • Control binding
  • Step attribute updates
  • Single deterministic timer management

Prohibited: network fetches, DOM injection, geometry measurement, requestAnimationFrame loops for layout.

4. Deterministic Timing

All timing derives from fixed CSS custom properties:

  • --motion-fast: 160ms
  • --motion-step: 480ms
  • --motion-hold: 720ms

Hard limit: 8 seconds total motion budget. Randomness, spring physics, and setInterval polling are forbidden.

5. Explicit Step Ordering

Animated items declare narrative position:

  • data-motion-item marks animatable elements
  • data-step="N" where N ∈ [1, 8]
  • Maximum two items per step

6. Scoped State

Controls affect only the nearest data-motion-root. IDs, timers, and ARIA live regions never cross figure boundaries, enabling multiple animated diagrams per page without collision.

7. Failure-Safe Startup

The .motion-ready class attaches only after successful control binding. Any script error leaves the complete static source visible—no broken half-animations.

Reduced-Motion and Print Support

The contract enforces automatic degradation for users who need it.

The prefers-reduced-motion: reduce media query triggers:

  • Forced static frame display
  • Control hiding
  • Decorative motion suppression ([data-motion-decorative])

Print styles replicate this behavior, ensuring physical and digital accessibility parity.

@media (prefers-reduced-motion: reduce), print {
  [data-motion-root] {
    --motion-enabled: 0;
  }
  
  [data-motion-controls] {
    display: none !important;
  }
  
  [data-motion-item] {
    opacity: 1 !important;
    transform: none !important;
  }
  
  [data-motion-decorative] {
    display: none;
  }
}

Verification and Compliance

The repository includes automated enforcement of the animation contract:

Tool Path Purpose
verify-motion.py scripts/verify-motion.py CI script validating mode declarations, step counts, timing limits, and ARIA compliance
self_check.py skills/diagram-design/scripts/self_check.py Runtime diagnostic agents invoke to verify generated diagrams
template-motion.html skills/diagram-design/assets/template-motion.html Canonical controller implementation for reveal and step modes
example-policy-trace-animated.html skills/diagram-design/assets/example-policy-trace-animated.html Reference implementation demonstrating full contract compliance

Running python scripts/verify-motion.py --strict fails the build if any diagram violates timing budgets, misses required attributes, or lacks static frame exposure.

Summary

  • Four exclusive modes—none, reveal, step, loop—cover static, autoplay, interactive, and decorative motion needs.
  • Static-first architecture guarantees complete diagram availability before any JavaScript or CSS enhancement.
  • Strict timing and scope limits (8s budget, scoped controllers, CSS-only presentation) ensure predictable, performant behavior.
  • Automatic reduced-motion support via prefers-reduced-motion and print styles provides accessible fallbacks without author intervention.
  • Automated verification through verify-motion.py enforces contract compliance in CI pipelines.

Frequently Asked Questions

What happens if JavaScript fails to load in a step or reveal diagram?

The diagram remains fully visible and functional. The .motion-ready class—required to hide or transform any content—is only added after successful controller initialization from template-motion.html. A script error leaves all data-motion-item elements in their default visible state, satisfying the source completeness guarantee.

Can I combine multiple animation modes in one diagram?

No. The data-motion-mode attribute accepts exactly one value: none, reveal, step, or loop. These modes are mutually exclusive by design. If you need both autoplay and manual control, create two diagram variants or use step mode with an auto-advance option (not part of the core contract).

How does prefers-reduced-motion interact with the loop mode?

Decorative loops cease entirely. The media query forces display: none on [data-motion-decorative] elements and disables all CSS animations. The loop mode is intentionally non-semantic, so its suppression never removes information—only visual polish.

What's the maximum number of steps allowed in step mode?

Eight steps maximum, with at most two data-motion-item elements appearing per step. This constraint—enforced by verify-motion.py—prevents cognitive overload and maintains the 8-second total motion budget even at maximum step duration (--motion-step: 480ms × 8 = 3.84s active animation plus hold time).

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 →