How to Configure Optional Motion Animations with the Accessibility Contract in Diagram Design
Diagram Design enforces a strict accessibility contract that requires all motion to start from a complete static diagram, preserve semantic content for assistive technology, and provide a reduced-motion fallback via prefers-reduced-motion: reduce.
To configure optional motion animations with the accessibility contract in diagram design, developers implement a static-first enhancement pattern that validates against the motion verifier scripts in the cathrynlavery/diagram-design repository. This approach guarantees that every animated diagram remains fully accessible while supporting progressive disclosure, teaching sequences, and decorative flow hints.
Understanding the Accessibility Contract
The accessibility contract is a binding specification that governs how motion may be added to diagrams. It is enforced by the motion verifier (scripts/verify‑motion.py and scripts/verify‑semantic‑motion.py), which checks for compliance before deployment.
Static-First Requirement
Every animation must start from a complete static diagram. All semantic content—including labels, connectors, and statuses—must be present in the source HTML/SVG before any motion is applied. This ensures that if JavaScript fails or motion is disabled, the diagram remains fully readable.
Semantic Preservation
Decorative elements must be hidden from assistive technology using aria‑hidden="true" and focusable="false", while semantic text appears exactly once in the accessibility tree. The SVG <title> and <desc> elements must describe the full meaning of the diagram without requiring animation to understand the content.
Reduced-Motion Guarantee
The contract mandates that prefers‑reduced‑motion: reduce forces the diagram into its final static frame, hides playback controls, and disables decorative motion. This media query also triggers for print media (@media print) and static exports (?motion=static).
Motion Modes and Constraints
Diagram Design supports four distinct motion modes defined by the data‑motion‑mode attribute. Only the reveal mode may autoplay, and it must run once on load when motion is explicitly requested.
| Mode | Behavior | Implementation | Typical Use |
|---|---|---|---|
none |
Fully static, no JavaScript | No controller, plain HTML | Default, print, screenshots |
reveal |
One deterministic autoplay run ending in final state | CSS-only (≤ 5 s) or scoped controller | Short ordered explanations |
step |
Paused semantic states with interactive controls | Minimal inline JS for Play/Pause | Teaching, policy traces |
loop |
Decorative token repeats without changing meaning | CSS-only default | Quiet flow hints (≥ 3 s cycle) |
The reveal mode never restarts on viewport re-entry and can be replayed only via the explicit Replay control. The loop mode is restricted to purely decorative tokens that do not convey semantic information.
Required Markup Structure
To configure optional motion animations with the accessibility contract in diagram design, apply the following data attributes exactly as specified in [skills/diagram-design/references/animation.md](https://github.com/cathrynlavery/diagram-design/blob/main/skills/diagram-design/references/animation.md):
- Single root container: One element with
data‑motion‑rootand a validdata‑motion‑mode(none|reveal|step|loop). - Motion items: Each animated element requires
data‑motion‑itemand an integerdata‑stepattribute defining its sequence. - Decorative markers: Purely visual items must include
data‑motion‑decorative. - Live region: A container with
role="status"andaria‑live="polite"must exist outside the controls to announce step changes (e.g., “Step 3 of 5: first divergence”).
Accessibility Implementation
Semantic motion requires specific ARIA markup and keyboard interaction patterns defined in the contract.
Decorative Overlays
Decorative elements carry aria‑hidden="true" and focusable="false" (see lines 95‑99 of the reference documentation). The verifier automatically checks for these attributes on items marked with data‑motion‑decorative.
Keyboard Controls
Interactive diagrams must use native <button> elements with data‑motion‑action attributes (play, pause, prev, next, replay). These buttons must expose focus, aria‑pressed, and disabled states. Arrow keys, Home/End, Space, and R (replay) operate on the motion root without stealing focus.
Live Status Region
The status container announces meaningful step changes but not every frame. Place this element outside the control block to prevent interference with assistive technology navigation.
Reduced-Motion and Print Fallbacks
The contract requires CSS that responds to user preferences and output media:
- Reduced motion:
@media (prefers-reduced-motion: reduce)forces all items toopacity: 1andtransform: none, hides decorative elements withdisplay: none, and removes playback controls. - Print:
@media printapplies the same static presentation as reduced motion. - Export: Static exports use the query parameter
?motion=staticto trigger the final frame view.
Verification Workflow
Before deploying an animated diagram, run the verification scripts to confirm compliance with the accessibility contract.
Basic motion verification:
python3 scripts/verify-motion.py path/to/diagram.html
Semantic and accessibility verification:
python3 scripts/verify-semantic-motion.py path/to/diagram.html
These scripts validate:
- Single
data‑motion‑rootelement and validdata‑motion‑mode. - Correctly scoped
data‑motion‑itemelements with integerdata‑stepattributes. - Proper ARIA markup for decorative items.
- Presence of live status region.
- Reduced-motion CSS that makes every item fully visible.
Code Examples
The canonical controller implementation lives in assets/template‑motion.html and must be used verbatim for any animated diagram.
Step Animation Implementation
This example demonstrates a minimal step mode animation with semantic items and accessible controls:
<div data-motion-root data-motion-mode="step" data-frame="static">
<!-- Semantic items -->
<g data-motion-item data-step="1" class="is-visible">
<text>Step 1 Label</text>
</g>
<g data-motion-item data-step="2">
<text>Step 2 Label</text>
</g>
<!-- Controls (copied from template-motion.html) -->
<div data-motion-controls>
<button data-motion-action="play" aria-pressed="false">▶︎</button>
<button data-motion-action="pause" disabled>‖</button>
<button data-motion-action="prev" disabled>←</button>
<button data-motion-action="next" disabled>→</button>
<button data-motion-action="replay" disabled>↺</button>
</div>
<!-- Live status region -->
<div role="status" aria-live="polite" aria-atomic="true"></div>
</div>
All attributes are defined exactly as required by the contract; the diagram starts static, then steps through the two items when the user clicks Play.
Reveal Animation with CSS Timing
For deterministic autoplay that ends in a static state, use reveal mode with CSS-only timing:
<div data-motion-root data-motion-mode="reveal">
<g data-motion-item data-step="1" class="is-visible">
<text>First item</text>
</g>
<g data-motion-item data-step="2">
<text>Second item</text>
</g>
<style>
.motion-ready [data-motion-item] {
transition: opacity var(--motion-step) var(--motion-ease),
transform var(--motion-step) var(--motion-ease);
}
.motion-ready [data-motion-item].is-visible {
opacity: 1;
transform: none;
}
</style>
</div>
Because the mode is reveal, the CSS automatically animates the two items once on load and then remains at the final static frame.
Decorative Tokens
Mark purely visual animations with data‑motion‑decorative to ensure they are hidden from assistive technology when reduced motion is preferred:
<g data-motion-decorative data-motion-item data-step="1">
<path d="M10 10 L90 90" stroke="orange" pathLength="1"
stroke-dasharray="1" stroke-dashoffset="1"></path>
</g>
The token is hidden from assistive tech (aria‑hidden added by the verifier) and will be removed when the user’s system prefers reduced motion.
Key Files in the Repository
skills/diagram-design/references/animation.md: Full specification of the optional animation contract, modes, CSS variables (--motion-fast,--motion-step), and accessibility rules.skills/diagram-design/assets/template-motion.html: Canonical controller containing the JavaScript that wires up controls, live regions, and state handling. Must be used verbatim.scripts/verify-motion.py: Linter checking the static-first enhancement contract (single root, mode validity, step ordering).scripts/verify-semantic-motion.py: Extended verifier validating ARIA markup, reduced-motion CSS, and keyboard interaction requirements.commands/doctor.md: Documentation for running the motion verifier via thediagram-design doctorcommand.
Summary
- Configure optional motion animations with the accessibility contract in diagram design by applying the static-first enhancement pattern and validating with
verify-motion.py. - Always include a single
data-motion-rootwith a valid mode (none,reveal,step, orloop) and sequentialdata-stepattributes on items. - Preserve accessibility by hiding decorative elements with
aria-hidden, maintaining semantic text in the SVG title/desc, and implementing a live status region. - Enforce reduced-motion compliance through
@media (prefers-reduced-motion: reduce)that forces final-frame visibility and hides controls. - Use the canonical controller from
template-motion.htmlverbatim to ensure consistent keyboard navigation and ARIA behavior.
Frequently Asked Questions
What is the accessibility contract in Diagram Design?
The accessibility contract is a binding specification that guarantees all motion starts from a complete static diagram, preserves semantic content for assistive technology, and provides a reduced-motion fallback. It is enforced by the motion verifier scripts (verify-motion.py and verify-semantic-motion.py) which validate markup structure, ARIA attributes, and CSS fallbacks before deployment.
How do I verify that my diagram meets the motion accessibility requirements?
Run python3 scripts/verify-motion.py path/to/diagram.html to check for structural compliance (single root, valid modes, step ordering). For comprehensive accessibility validation including ARIA markup and reduced-motion CSS, run python3 scripts/verify-semantic-motion.py. Both scripts exit with error codes if the accessibility contract is violated.
Which motion mode should I use for teaching materials?
Use step mode for teaching and policy traces. This mode presents paused semantic states with interactive Play/Pause/Previous/Next controls, allowing learners to navigate through complex diagrams at their own pace while maintaining full keyboard accessibility and screen reader compatibility via the live status region.
How does the reduced-motion fallback work?
When a user has prefers-reduced-motion: reduce enabled, the diagram immediately renders in its final static state with all items fully visible (opacity: 1, transform: none), decorative elements hidden (display: none), and playback controls removed. The same presentation applies to print media and static exports (?motion=static), ensuring no information is lost when motion cannot be perceived.
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 →