Fieldwork Animation Testing

Fieldwork should detect, drive, scrub, and prove the animations running in the live product it inspects, so motion becomes an editable, verifiable design object instead of an effect that only exists at real-time speed.

Why This Exists

Fieldwork already inspects live product state, selects DOM nodes, annotates on typed layers, and drives bounded agent changes with before/after proof. Motion was the gap: a designer could annotate a static frame but could not see, pause, or replay the animation that actually plays in the running app. Kevin's signal is direct—"if there are animations in a website my design IDE is being used in, be able to test animations and show them," with joshpuckett/DialKit named as the interaction reference (visual timeline editing for loops, groups, staggers, compound animations, scrubbing, and springs). Source: private Discord message, 2026-07-20 05:00 PT; raw/discord/straight-fats/tasks-signals-2026-07-21.md item A2

This page is the feature spec for that capability. It extends Fieldwork — Visual Design IDE; it does not fork it. Fieldwork owns the surface, the layer model, the agent loop, and the proof contract. Animation testing is a new layer and a new panel inside that surface, subject to the same quality and safety rules.

Product Boundary

Concern Owner
Live preview session, low-latency capture, terminals, artifacts Agent Machines
The inspection surface, layer model, annotations, versioned proposals, proof Fieldwork — Visual Design IDE
Motion detection, timeline UI, scrubbing, replay, motion proof This spec (Animation Testing layer)
Motion tokens (--ret-duration-*, --ret-ease-*) and named motion vocabulary Sigil Token Architecture, Reticle Design System
Motion taste rules (budget, reduced-motion, interruptibility) AI-Native Web Design Pattern Library

Animation testing reads and drives motion; it does not become a general-purpose animation authoring tool that competes with the product's own code. Authored changes still route through the Fieldwork agent loop and land as reversible code diffs plus token writeback.

Detection

Fieldwork must discover what is animating before it can show it. Detection is layered because no single API sees every animation source.

Source Detection method What it yields
CSS transitions getComputedStyle transition props plus transitionrun/transitionstart/transitionend events on selected and descendant nodes property, duration, delay, easing, trigger element
CSS keyframe animations Element.getAnimations() / document.getAnimations() (Web Animations API), @keyframes rule inspection keyframe timeline, iteration count, direction, fill
Web Animations API (WAAPI) document.getAnimations() returns live Animation objects with currentTime, playbackRate, effect, timeline fully controllable native handles
GSAP Detect window.gsap; read the global timeline and gsap.globalTimeline.getChildren(); hook ScrollTrigger instances tween/timeline tree, labels, scroll bindings
Motion for React (Framer Motion) Detect the runtime; inspect via WAAPI (Motion drives WAAPI/animate() under the hood) and component-level AnimatePresence mounts entrance/exit, layout animations, gestures
Lenis / scroll-driven Detect window.lenis or Lenis instance; read scroll progress; detect CSS scroll-timeline/view-timeline and animation-timeline scroll-linked progress, not wall-clock time
Spring / physics GSAP elastic, Motion type: "spring", or custom rAF loops sampled over time stiffness/damping approximation, settle time
Uncontrollable / opaque Canvas/WebGL rAF loops, third-party embeds flag as "observed, not controllable"; fall back to record-only

Detection produces an animation inventory: a list of discovered animations, each tagged with source engine, target node(s), trigger (load, hover, focus, scroll, click, in-view, state change), duration/easing, and a controllability class of native-controllable, library-controllable, scroll-linked, or record-only. The inventory attaches to DOM nodes and the current UI version so it survives refresh and can be marked stale when the element or its code changes, exactly like Fieldwork annotations.

Timeline And Scrubbing UI (DialKit-like)

The animation panel is a visual timeline editor modeled on DialKit's interaction grammar. It renders discovered animations as tracks against time (or against scroll progress for scroll-linked motion).

Required capabilities:

  • Scrubbing — a playhead the user drags to set currentTime on every controllable animation simultaneously; scrubbing is bidirectional and frame-accurate for WAAPI/Motion/GSAP-controllable tracks.
  • Loops — set and preview iteration count and direction (normal, reverse, alternate); loop a single track or a selected range for repeated inspection.
  • Groups — collapse related tracks (for example, all children of one component) into a named group that can be soloed, muted, or scrubbed as a unit.
  • Staggers — visualize and edit per-child offset so a list/grid reveal reads as a ramp; show the stagger delta numerically and as track offsets.
  • Compound — nest timelines (a group that itself contains groups) so a page-level choreography shows sub-timelines aligned to one master playhead, matching GSAP timeline nesting.
  • Springs — for physics-based motion, plot the sampled position curve and expose approximate stiffness/damping/mass so a designer sees settle time and overshoot rather than a fake linear duration.
  • Playback controls — play, pause, step-frame, set playbackRate (slow-motion 0.1x–1x, and fast 2x–4x), jump to labels/markers, and set in/out loop points.
  • Track metadata — each track shows target node, trigger, engine, duration/easing, and controllability class; a record-only track shows a camera badge instead of a scrub handle.

The panel consumes the same Reticle grammar as the rest of Fieldwork: square controls, mono labels, tabular time readouts, one shared hairline per seam, and Lucide icons for transport controls. Timeline rails and track separators follow the per-side edge ownership rule so the timeline does not draw double-dark seams (see Reticle/Sigil Per-Side Edge Ownership).

Trigger And Replay

Many product animations only fire on an event. Fieldwork must be able to synthesize those triggers so the designer never has to manually reproduce a fragile interaction.

  • Trigger replay — re-fire load, in-view (via IntersectionObserver reset), hover, focus, click, and state-change triggers on the selected node without a full page reload where possible.
  • Isolated replay — pause the rest of the page and replay one animation in place so it can be inspected without competing motion.
  • Scroll driving — for Lenis/scroll-timeline motion, the playhead drives synthetic scroll progress instead of time, so scroll-linked reveals can be scrubbed deterministically.
  • State injection — where an animation depends on component state (open/closed, loading/loaded), coordinate with the Fieldwork agent to toggle that state, then replay; never fabricate a visual that cannot be mapped back to real product state (a generated motion clip that does not correspond to editable state is inspiration, not completion, per the Fieldwork agent-loop rule).
  • Deterministic seeding — pin Date.now/performance.now offsets and RNG seeds during replay when the animation reads them, so repeated captures are comparable.

Capture And Proof

Motion proof is the motion-native extension of Fieldwork's before/after proof requirement. A motion change is only "done" when its proof artifacts exist and can be compared.

Required proof artifacts per tested animation:

  • Before/after keyframe strip — a filmstrip of sampled frames (for example at 0%, 25%, 50%, 75%, 100% of the timeline) at desktop and mobile widths, in light and dark themes.
  • Recorded clip — a captured video/GIF of the replayed animation at real-time and at slow-motion, produced from deterministic replay so it is reproducible, not a lucky screen grab.
  • Timing manifest — the resolved duration, delay, easing, iteration, stagger deltas, and (for springs) sampled settle time, stored as structured data next to the clip.
  • Diff summary — when the agent changes motion, record the token/code diff (which --ret-duration-*/--ret-ease-* or keyframe changed) alongside the before/after strips.
  • Provenance — which agent, model, source fixture, and design tokens produced the version, matching Fieldwork's existing provenance requirement.

Proof artifacts attach to the animation inventory entry and the UI version, and go stale when the underlying element or motion code changes.

Accessibility

Accessibility is a hard requirement, not a later pass, and it mirrors the motion rules in AI-Native Web Design Pattern Library and the Reticle motion standards.

  • Reduced-motion fallback — Fieldwork must render the surface under prefers-reduced-motion: reduce and prove the reduced state is complete: the reduced path should preserve final layout and communicate the same state change (usually via opacity/instant transition), never leave a dead or empty region. Both the full and reduced renderings are captured as proof.
  • Keyboard navigation — every timeline control (play, pause, step, scrub, set loop points, select/solo/mute track, jump to marker) is reachable and operable by keyboard with visible focus, using Reticle --ret-focus. Scrubbing supports arrow-key frame stepping and Home/End for start/finish.
  • Interruptibility check — Fieldwork tests rapid reversal (fire the trigger, then reverse before completion) and flags motion that snaps, double-fires, or leaves an inconsistent state, per the "interactions must be interruptible" rule.
  • Vestibular safety — large-distance, parallax, and continuous scroll-film motion are flagged for review; the panel surfaces distance and duration so a designer can catch motion likely to cause discomfort.
  • Non-visual confirmation parity — if the product pairs motion with sound/haptics (see the multimodal-feedback rule), the fallback must not make motion the only channel; the reduced path still confirms the state change.

Fit With Fieldwork's Near-Term Slice

Fieldwork's near-term slice ends at Sigil token writeback and project design-contract integration. Animation testing slots in as an increment on that slice rather than a parallel product:

  1. Reuse the reliable Agent Machines session and low-latency preview (slice step 1) as the substrate detection reads from.
  2. Add the Animation layer to the existing layer panel (slice step 3) as a typed layer with visibility, lock, opacity, author, and version provenance—the same contract every Fieldwork layer already satisfies.
  3. Add the timeline/transport panel alongside the existing pen/measure toolset (slice step 4).
  4. Extend versioned proposals and before/after proof (slice step 5) with motion proof artifacts (filmstrips, clips, timing manifest).
  5. Route motion edits through Sigil token writeback (slice step 6): motion changes should prefer editing --ret-duration-*/--ret-ease-*/named keyframes over inlining magic numbers.

Sequencing recommendation: land detection + inventory first (read-only value immediately), then scrubbing/replay of native-controllable and library-controllable animations, then capture/proof, then agent-driven motion edits with token writeback. Scroll-linked and record-only classes can ship as observe-and-record before they become fully controllable.

Contract-Token Integration

Animation testing is bound to the same token contract as the rest of Reticle/Sigil so it never invents ad hoc motion values:

  • Read and display motion through the Reticle motion tokens: --ret-ease-out, --ret-ease-in-out, --ret-duration-fast, --ret-duration-base, --ret-duration-enter, --ret-duration-page.
  • When the agent proposes a motion change, prefer a token edit (surfaced in Sigil Token Architecture's DESIGN.md motion block: press, hover, page) so the change cascades system-wide instead of hardcoding one component.
  • Name the motion's job before adding or changing it, following the Emil/animations.dev vocabulary Reticle already adopts (stagger, direction-aware entrance, crossfade, layout animation).
  • Respect the engine-routing decision tree: CSS for hover/focus/press/opacity, Motion for React for component/layout/gesture state, GSAP for timeline-heavy scroll choreography, and Three/Lottie only when the surface truly needs them. The timeline panel should label each track with its engine so an audit can catch a full GSAP timeline used where a CSS transition would do.

Failure Modes

Failure Fix
Detection misses library motion Probe for gsap, Motion runtime, and lenis; fall back to document.getAnimations() and rAF sampling; mark opaque motion record-only.
Scrubbing desyncs multiple engines Drive one master playhead; map it to WAAPI currentTime, GSAP timeline time, and synthetic scroll progress; never let each track free-run during scrub.
Spring shown as fake linear duration Sample the physics curve and plot overshoot/settle time; expose approximate stiffness/damping instead of a made-up duration.
Proof is a non-reproducible screen grab Capture from deterministic seeded replay so clips and filmstrips are reproducible and comparable.
Reduced-motion path untested Render under prefers-reduced-motion, prove final layout/state is preserved, and capture the reduced rendering as required proof.
Timeline controls mouse-only Make every transport and track control keyboard-operable with visible --ret-focus; support arrow-key frame stepping.
Motion edit hardcodes numbers Route the change through --ret-duration-*/--ret-ease-* token writeback via Sigil.
Timeline draws double-dark seams Apply per-side edge ownership from Reticle/Sigil Per-Side Edge Ownership to timeline rails and track separators.
Generated motion clip with no state mapping Reject as inspiration; a motion result must map back to editable product state and code.

Timeline

  • 2026-07-21 | Created the Fieldwork animation-testing spec after Kevin asked that the design IDE be able to test and show animations in the site it inspects, citing joshpuckett/DialKit for timeline scrubbing, loops, groups, staggers, compound timelines, and springs. Covers layered detection (CSS/WAAPI/GSAP/Motion/Lenis/spring), a DialKit-like timeline/scrubbing panel, trigger replay, motion proof (filmstrips, seeded clips, timing manifest), reduced-motion and keyboard accessibility, fit with the existing near-term slice, and Reticle/Sigil motion-token integration. Source: private Discord message, 2026-07-20 05:00 PT; raw/discord/straight-fats/tasks-signals-2026-07-21.md item A2