Diagram-Design Optional Animation Modes and Accessibility Contracts: A Complete Technical Guide
The Diagram-Design skill defines four optional animation modes—none, reveal, step, and loop—controlled via the data-motion-mode attribute, all bound by a strict static-first accessibility contract that mandates complete source diagrams, deterministic CSS timing, and full ARIA keyboard support.
The cathrynlavery/diagram-design repository implements a lightweight, optional animation layer for technical diagrams that adds motion without altering static semantic meaning. This system is built around optional animation modes and accessibility contracts defined in the animation reference file, ensuring diagrams remain fully usable across print media, screen readers, and reduced-motion preferences.
Optional Animation Modes and Their Behaviors
The animation system allows exactly one mode per diagram, selected via the data-motion-mode attribute. As specified in skills/diagram-design/references/animation.md (lines 9-15), each mode determines playback behavior, control requirements, and JavaScript dependencies.
Mode: None (Static Default)
data-motion-mode="none" produces a complete, stable figure with no animation. This mode requires no JavaScript and serves as the default for static output, print media, screenshots, and reduced-motion fallbacks.
Mode: Reveal (Autoplay Once)
data-motion-mode="reveal" executes one deterministic autoplay run that ends on the complete static frame. Animations under five seconds use CSS-only implementation; longer sequences require the scoped controller. This mode suits short ordered explanations such as single flows or timelines, and the animation never restarts automatically.
Mode: Step (Interactive)
data-motion-mode="step" presents paused semantic states that users navigate via playback controls. This mode requires minimal inline JavaScript providing Play, Pause, Replay, Prev, and Next buttons, designed for teaching scenarios and policy-trace walkthroughs. Each step displays at most two items marked with data-motion-item and data-step="N" attributes.
Mode: Loop (Decorative)
data-motion-mode="loop" repeats a decorative token without altering semantic meaning, using CSS-only implementation by default. Loop cycles must run at least three seconds to avoid distraction. Unlike other modes, this is the only animation that repeats indefinitely rather than finishing on a static frame.
Accessibility Contracts and Static-First Requirements
The accessibility contract defined in skills/diagram-design/references/animation.md (lines 20-30) mandates that animated diagrams remain complete and usable regardless of playback state. This static-first enhancement contract contains seven binding requirements:
- Source completeness: Every semantic node, label, connector, status, and outcome must be present in the raw HTML/SVG before any animation runs.
- Stable capture: The static frame (
data-frame="static"or?motion=static) is what printers, screenshots, and export tools receive; playback controls are hidden in these contexts. - CSS-only presentation: Visual changes are driven by CSS transitions and keyframes; JavaScript may only bind controls and update step/state attributes.
- Deterministic timing: Fixed timing variables (
--motion-fast,--motion-step,--motion-hold,--motion-total) guarantee no randomness in animation sequences. - Explicit ordering: Items are marked with
data-motion-itemanddata-step="N"attributes; at most two items may appear per step. - Scoped state: Each diagram maintains its own
[data-motion-root]container; IDs, timers, and live regions never cross figure boundaries. - Failure-safe startup: The script adds the
.motion-readyclass only after successful control binding; a script error before that point leaves the full static diagram visible.
Reduced-Motion and Assistive Technology Support
The contract specifies strict behavior for reduced-motion preferences, print media, and screen readers, as documented in skills/diagram-design/references/animation.md (lines 85-92 and 95-99).
When prefers-reduced-motion: reduce is active, the system automatically shows the complete static frame, hides all playback controls, and disables decorative motion. Print media queries remove controls and decorative overlays, leaving only static content.
For screen reader accessibility, diagrams must include an ARIA live region (role="status" aria-live="polite" aria-atomic="true") that announces user actions (e.g., "Step 3 of 5: first divergence") but does not announce every autoplay frame. Keyboard interaction requires native buttons (minimum 44×44 px) for Play, Pause, Replay, Prev, and Next. Arrow keys step forward and backward, Home and End reset or complete the sequence, Space toggles Play/Pause, and the R key replays (unless a modifier key is held).
Implementation Examples
The following HTML snippets demonstrate how to enable each animation mode while satisfying the accessibility contract. Every animated diagram must include the canonical controller script from skills/diagram-design/assets/template-motion.html verbatim; the verification suite rejects any modifications.
Static diagram with no animation:
<!-- Base diagram (static SVG) -->
<svg id="my-diagram" ...>...</svg>
<!-- 1. No animation (default) -->
<div data-motion-mode="none">
<!-- No controls, no JS -->
</div>
Reveal animation with autoplay:
<!-- 2. Reveal animation (autoplay once) -->
<div data-motion-mode="reveal" data-motion-root>
<button data-motion-action="replay" hidden>Replay</button>
</div>
Step animation with full controls:
<!-- 3. Step animation (interactive) -->
<div data-motion-mode="step" data-motion-root>
<div data-motion-controls>
<button data-motion-action="play">Play</button>
<button data-motion-action="pause">Pause</button>
<button data-motion-action="prev">Prev</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"></div>
</div>
Loop animation (decorative):
<!-- 4. Loop animation (decorative token) -->
<div data-motion-mode="loop" data-motion-root>
<!-- No controls; pure CSS -->
</div>
Verification and Enforcement
The repository enforces optional animation modes and accessibility contracts through automated verification scripts. The scripts/verify-motion.py and scripts/test-verify-motion.py files validate mode declarations, step continuity, timing budgets, accessibility attributes, and proper usage of the canonical controller.
These verifiers check that:
- Each diagram declares exactly one valid
data-motion-mode - Step sequences are continuous and properly numbered
- Timing variables remain within budget constraints
- All required ARIA attributes and keyboard handlers are present
- The controller script matches
assets/template-motion.htmlexactly
Summary
- The cathrynlavery/diagram-design repository supports four optional animation modes—
none,reveal,step, andloop—selected via thedata-motion-modeattribute. - The static-first accessibility contract requires complete source diagrams, deterministic CSS timing, scoped state management, and failure-safe startup procedures.
- Reduced-motion preferences automatically disable animations and display static frames, while print media receives only static content without controls.
- Screen reader support requires ARIA live regions for step announcements and comprehensive keyboard navigation using arrows, Home/End, Space, and R keys.
- Implementation requires the canonical controller from
skills/diagram-design/assets/template-motion.htmland passes verification viascripts/verify-motion.py.
Frequently Asked Questions
What are the four optional animation modes in Diagram-Design?
The four modes are none (static default), reveal (autoplay once ending on static frame), step (interactive paused states with controls), and loop (repeating decorative motion). Only loop repeats indefinitely; all others finish on a complete static frame and never restart automatically. Each mode is selected via the data-motion-mode attribute on the diagram container.
How does the static-first accessibility contract protect diagram accessibility?
The contract mandates that every animated diagram must have a complete static version present in the source HTML/SVG before any animation runs. It requires deterministic CSS timing via custom properties, scoped state isolation per diagram, and failure-safe startup where script errors leave the full static diagram visible. This ensures printers, screenshots, and users with disabled JavaScript always receive usable content.
What happens when a user has prefers-reduced-motion enabled?
When prefers-reduced-motion: reduce is detected, the system automatically displays the complete static frame, hides all playback controls, and disables decorative motion. This behavior is enforced by the accessibility contract defined in skills/diagram-design/references/animation.md (lines 85-92), ensuring users with vestibular disorders or motion sensitivity receive an equivalent experience without animation.
How are animation contracts verified in the repository?
The repository uses scripts/verify-motion.py and scripts/test-verify-motion.py to enforce contracts automatically. These scripts validate that diagrams use valid mode declarations, maintain step continuity, respect timing budgets, include required ARIA attributes, and implement the canonical controller from skills/diagram-design/assets/template-motion.html without modifications.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →