# Diagram-Design Animation Modes and Static-First Contract: Complete Guide

> Explore diagram-design animation modes (none, reveal, step, loop) and the static-first contract. Ensure accessibility and deterministic timing for your diagrams.

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

---

**Diagram-design supports four optional animation modes (`none`, `reveal`, `step`, `loop`) that can be added without changing a diagram's underlying static meaning, enforced by a static-first contract guaranteeing complete static frames, deterministic timing, and reduced-motion accessibility.**

The **diagram-design** repository implements a disciplined approach to animation in technical diagrams. Every motion feature is optional, opt-in, and strictly subordinate to a fully-rendered static baseline. This architecture ensures diagrams remain accessible, printable, and semantically stable regardless of animation state.

## Supported Animation Modes in Diagram-Design

The [`animation.md`](https://github.com/cathrynlavery/diagram-design/blob/main/animation.md) reference file defines four sanctioned animation modes. These are loaded only when a request explicitly asks for motion, keeping static diagrams lightweight by default.

### `none` (Default)

The default state applies **no animation whatsoever**. The diagram contains no JavaScript, no CSS animation keyframes, and no motion-related markup. This is the baseline that all other modes must preserve as a fallback.

### `reveal`

Elements appear **sequentially on load**—the only sanctioned autoplay style. The reveal animation respects the static-first contract: the full static frame renders completely before any element begins its entrance animation. Timing is controlled through CSS variables such as `--motion-step`.

### `step`

The diagram advances through **discrete, deterministic steps** triggered by user interaction (e.g., "next" clicks). Each step shows a calculated change while maintaining the static baseline underneath. This mode is ideal for progressive disclosure in presentations or documentation.

### `loop`

Infinite looping is permitted **only when the container explicitly declares `data-motion-mode="loop"`**. Critically, the loop never alters the static frame—it repeats motion that was already defined by the static picture. No new semantic content appears during loops.

## The Static-First Contract

The **static-first contract** is the architectural guarantee that makes diagram-design animation safe and accessible. It is enforced by the [`verify-semantic-motion.py`](https://github.com/cathrynlavery/diagram-design/blob/main/verify-semantic-motion.py) script and implemented in [`template-motion.html`](https://github.com/cathrynlavery/diagram-design/blob/main/template-motion.html).

### Complete Static Frame

Every diagram must contain a **fully-rendered static version** that exists independently of animation state. This frame can be captured, printed, exported to PDF, or embedded in static documentation without loss of information.

### Deterministic Timing

All animation timing follows **predictable CSS variables** (`--motion-step`, etc.) rather than arbitrary JavaScript. The timing system never modifies element positions in the static layout—motion is purely presentational.

### Reduced-Motion Fallback

When users request reduced motion via `prefers-reduced-motion`, animation suppresses entirely:

```css
@media (prefers-reduced-motion: reduce) {
  .motion-ready [data-motion-item] {
    animation: none !important;
  }
}

```

The static frame remains fully functional and complete.

### No Arbitrary Scripts

Only the **canonical controller from [`template-motion.html`](https://github.com/cathrynlavery/diagram-design/blob/main/template-motion.html)** may execute. Arbitrary JavaScript, external CSS imports, or unsanctioned "autoplay on load" behaviors are rejected by the verification pipeline.

## Implementation Examples

### Markdown Declaration

```markdown

```diagram
type: flowchart
animation: reveal   # options: none | reveal | step | loop

---
A --> B
B --> C

```

```

### HTML Embedding with Canonical Controller

```html
<div class="motion-ready" data-motion-mode="reveal">
  <!-- SVG content generated by diagram-design -->
</div>
<script src="skills/diagram-design/assets/template-motion.html"></script>

```

### Verification Pipeline

The [`scripts/verify-semantic-motion.py`](https://github.com/cathrynlavery/diagram-design/blob/main/scripts/verify-semantic-motion.py) script enforces contract compliance:

1. Validates that declared modes exist in [`skills/diagram-design/references/animation.md`](https://github.com/cathrynlavery/diagram-design/blob/main/skills/diagram-design/references/animation.md)
2. Confirms static fallback presence for all animated elements
3. Rejects unauthorized animation primitives or external dependencies

## Key Source Files

| File | Purpose |
|------|---------|
| [`skills/diagram-design/references/animation.md`](https://github.com/cathrynlavery/diagram-design/blob/main/skills/diagram-design/references/animation.md) | Canonical list of supported modes and contract specifications |
| [`skills/diagram-design/assets/template-motion.html`](https://github.com/cathrynlavery/diagram-design/blob/main/skills/diagram-design/assets/template-motion.html) | Reference HTML/CSS controller implementing all modes |
| [`skills/diagram-design/SKILL.md`](https://github.com/cathrynlavery/diagram-design/blob/main/skills/diagram-design/SKILL.md) | Documents when animation references load and motion layer architecture |
| [`scripts/verify-semantic-motion.py`](https://github.com/cathrynlavery/diagram-design/blob/main/scripts/verify-semantic-motion.py) | Automated contract enforcement and validation |

## Summary

- **Four animation modes** (`none`, `reveal`, `step`, `loop`) provide opt-in motion without static compromise
- **Static-first contract** guarantees complete baseline frames, deterministic CSS-based timing, and `prefers-reduced-motion` support
- **Canonical controller** in [`template-motion.html`](https://github.com/cathrynlavery/diagram-design/blob/main/template-motion.html) is the sole permitted animation runtime
- **Verification script** [`verify-semantic-motion.py`](https://github.com/cathrynlavery/diagram-design/blob/main/verify-semantic-motion.py) automatically enforces all contract requirements

## Frequently Asked Questions

### What happens if I don't specify an animation mode?

Diagram-design defaults to `none`—a completely static output with zero JavaScript or CSS animation overhead. The diagram renders immediately and is fully accessible to screen readers, print workflows, and static export tools.

### Can I use custom JavaScript animations with diagram-design?

No. The static-first contract explicitly prohibits arbitrary JavaScript. Only the canonical controller from [`template-motion.html`](https://github.com/cathrynlavery/diagram-design/blob/main/template-motion.html) may execute. This restriction preserves accessibility guarantees and prevents motion from altering semantic meaning.

### How does the reveal mode differ from step mode?

**Reveal** runs automatically on load, showing elements sequentially without user interaction—useful for entry animations. **Step** requires explicit user advancement (clicks or keypresses), making it ideal for presenter-controlled progressive disclosure. Both preserve the complete static frame underneath.

### What is `data-motion-mode="loop"` and when should I use it?

This attribute explicitly opts a container into **infinite looping animation**—the only context where loops are permitted. Use it for ambient, non-semantic motion (e.g., gentle pulsing indicators) where the static frame already contains all meaningful information and repetition adds no new content.