# Animation Modes in Diagram-Design: A Complete Guide to Accessible Motion

> Explore four animation modes in diagram-design: none, reveal, step, and loop. Ensure accessibility and comprehension with reduced-motion preferences and keyboard navigation.

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

---

**Diagram-design supports four optional animation modes—`none`, `reveal`, `step`, and `loop`—that operate as presentation-layer enhancements without altering the underlying semantic meaning of diagrams, enforced by a strict accessibility contract that ensures full comprehension under reduced-motion preferences and keyboard-only navigation.**

The cathrynlavery/diagram-design repository implements a static-first animation system where motion never compromises accessibility. Every animated diagram maintains a complete semantic structure in the source HTML/SVG, with JavaScript and CSS merely transforming visibility states within scoped containers. This architecture ensures that animation modes in diagram-design remain optional enhancements that degrade gracefully to static figures when motion is disabled or unavailable.

## The Four Animation Modes in Diagram-Design

Diagram-design declares animation behavior through the `data-motion-mode` attribute on the diagram root element. Each mode follows deterministic rules defined in [`skills/diagram-design/references/animation.md`](https://github.com/cathrynlavery/diagram-design/blob/main/skills/diagram-design/references/animation.md) and implements specific accessibility safeguards.

### Mode: `none` (Static Default)

The default state renders complete, static figures without JavaScript execution. This mode serves as the foundation for print media, screenshots, and reduced-motion fallbacks. Because the SVG content remains fully exposed in the DOM, screen readers access the complete diagram structure immediately without playback controls or temporal barriers.

### Mode: `reveal` (Single Autoplay)

This mode executes one deterministic autoplay sequence that concludes on a complete static frame. Short sequences under five seconds use CSS-only implementation, while longer durations import the scoped controller from [`assets/template-motion.html`](https://github.com/cathrynlavery/diagram-design/blob/main/assets/template-motion.html). The animation runs exactly once on initial load if explicitly requested, never restarting on viewport re-entry. Under reduced-motion preferences, playback controls hide automatically and the diagram presents only the final frame.

### Mode: `step` (Interactive Navigation)

Designed for educational sequences, `step` provides paused semantic states navigable through native Play, Pause, Replay, Previous, and Next controls. The controller in [`template-motion.html`](https://github.com/cathrynlavery/diagram-design/blob/main/template-motion.html) manages state transitions while maintaining focus management. Keyboard support includes Arrow Right/Left for step advancement, Home/End for first/last step navigation, Space for Play/Pause toggling, and R for replay. Interactive controls maintain minimum touch targets of 44×44 pixels with `aria-pressed` states and a dedicated `role="status"` live region announcing step context (e.g., "Step 3 of 5: first divergence").

### Mode: `loop` (Decorative Only)

Reserved for non-essential visual flourishes, `loop` repeats decorative tokens without conveying semantic information. The implementation defaults to CSS-only animations with cycles exceeding three seconds. Because this motion adds no meaning, the container carries `aria-hidden="true"`, rendering it invisible to assistive technologies. Reduced-motion media queries disable the animation entirely, presenting only the static base diagram.

## Accessibility Contract and Technical Implementation

The repository enforces a strict accessibility contract through [`verify-motion.py`](https://github.com/cathrynlavery/diagram-design/blob/main/verify-motion.py), a linter that validates animation compliance before deployment.

### Static-First Guarantee

All diagram markup in `diagram-design` contains the complete semantic structure regardless of animation mode. Motion controllers only manipulate visibility within `.motion-ready` containers, ensuring the underlying meaning persists if JavaScript fails or CSS loads incorrectly.

### Reduced-Motion Handling

The system respects `prefers-reduced-motion` through media queries that force diagrams to their final static frames, hide all playback controls, and disable decorative movement. The `role="status"` region communicates playback unavailability to screen reader users when controls suppress.

### Keyboard Navigation Standards

Interactive `step` diagrams expose native button elements with visible focus indicators. The controller traps keyboard events within the diagram context, allowing Arrow keys, Home, End, Space, and R to operate playback without displacing user focus. Each control maintains explicit `aria-pressed` states for toggle buttons.

### ARIA Semantics and Print Compliance

Meaningful text appears exactly once in the accessibility tree, with decorative overlays excluded via `aria-hidden`. The root `<svg>` or container includes `<title>` and `<desc>` elements describing the complete diagram rather than the animation sequence. Print media queries (`@media print`) hide controls and decorative layers, ensuring exported PNG/SVG files contain full static content.

## Source Files and Validation Tools

Implementing accessible animation in diagram-design requires these core resources:

- **[`skills/diagram-design/references/animation.md`](https://github.com/cathrynlavery/diagram-design/blob/main/skills/diagram-design/references/animation.md)** — Defines mode specifications, motion budgets, and accessibility requirements.
- **[`assets/template-motion.html`](https://github.com/cathrynlavery/diagram-design/blob/main/assets/template-motion.html)** — Canonical controller implementing `step` and `reveal` behaviors; must be copied verbatim for animated diagrams.
- **[`scripts/verify-motion.py`](https://github.com/cathrynlavery/diagram-design/blob/main/scripts/verify-motion.py)** — Linter validating animation declarations, state management, and ARIA compliance.
- **[`scripts/test-verify-motion.py`](https://github.com/cathrynlavery/diagram-design/blob/main/scripts/test-verify-motion.py)** — Test suite ensuring the verifier rejects non-compliant markup patterns.

## Implementation Examples

The following examples demonstrate proper markup for each animation mode using the `data-motion-mode` and `data-motion-root` attributes.

Static diagram using mode `none`:

```html
<div data-motion-mode="none" data-motion-root>
  <!-- SVG content here – complete static diagram -->
</div>

```

Autoplay reveal sequence:

```html
<div data-motion-mode="reveal" data-motion-root>
  <!-- SVG content -->
</div>
<script src="assets/template-motion.html"></script>

```

Interactive step diagram with accessibility controls:

```html
<div data-motion-mode="step" data-motion-root>
  <!-- SVG content -->
</div>

<div data-motion-controls>
  <button data-motion-action="play" aria-pressed="false">Play</button>
  <button data-motion-action="pause" aria-pressed="true">Pause</button>
  <button data-motion-action="prev">Previous</button>
  <button data-motion-action="next">Next</button>
  <button data-motion-action="replay">Replay</button>
</div>

<div role="status" aria-live="polite" aria-atomic="true" data-motion-status>
  <!-- Live announcements inserted by the controller -->
</div>

<script src="assets/template-motion.html"></script>

```

Decorative loop animation:

```html
<div data-motion-mode="loop" data-motion-root>
  <!-- SVG content with a decorative token -->
</div>
<script src="assets/template-motion.html"></script>

```

## Summary

- **Diagram-design provides four deterministic animation modes**—`none`, `reveal`, `step`, and `loop`—declared via `data-motion-mode` attributes that never alter underlying semantic meaning.
- **A static-first architecture** ensures complete diagram content exists in the source HTML/SVG, with motion merely transforming visibility within controlled containers.
- **Strict accessibility compliance** includes `prefers-reduced-motion` support, 44×44 pixel touch targets, comprehensive keyboard navigation (Arrow keys, Home, End, Space, R), and ARIA live regions for step announcements.
- **Validation through [`verify-motion.py`](https://github.com/cathrynlavery/diagram-design/blob/main/verify-motion.py)** ensures all animated diagrams meet the repository's accessibility contract before deployment.
- **Print and export compatibility** guarantees that static representations contain full diagram content regardless of animation configuration.

## Frequently Asked Questions

### What happens if a user has reduced-motion preferences enabled?

When `prefers-reduced-motion: reduce` is active, diagram-design forces all animations to their final static frames, hides playback controls, and disables decorative loops. The `role="status"` live region announces that playback is unavailable, while the full semantic diagram remains accessible in the DOM.

### Can I use multiple animation modes in a single diagram?

No, each diagram root element accepts only one `data-motion-mode` value. The architecture enforces deterministic behavior where `none`, `reveal`, `step`, or `loop` operate exclusively. For complex presentations, create separate diagram instances or use the `step` mode to sequence multiple states without changing the underlying mode declaration.

### How does keyboard navigation work for step-by-step diagrams?

The [`template-motion.html`](https://github.com/cathrynlavery/diagram-design/blob/main/template-motion.html) controller implements full keyboard accessibility using Arrow Right/Left for step advancement, Home/End for jumping to first/last steps, Space for Play/Pause toggling, and R for replay. Focus remains within the diagram context during operation, and all interactive controls expose `aria-pressed` states and visible focus indicators.

### What validation is required before deploying an animated diagram?

All animated diagrams must pass [`scripts/verify-motion.py`](https://github.com/cathrynlavery/diagram-design/blob/main/scripts/verify-motion.py), which checks for proper `data-motion-mode` declarations, valid accessibility attributes (including `aria-hidden` for decorative elements), motion budget compliance, and correct controller inclusion. The accompanying [`test-verify-motion.py`](https://github.com/cathrynlavery/diagram-design/blob/main/test-verify-motion.py) suite ensures the linter correctly identifies non-compliant patterns like missing live regions or insufficient touch targets.