The Motion Envelope: 30 Years After Flash, Figma Motion Still Cannot Say Why Anything Moves
Keyframes record how pixels move and nothing else. The Motion Envelope makes every animation declare its purpose, and a verifier proves the…
The Motion Envelope: 30 Years After Flash, Figma Motion Still Cannot Say Why Anything Moves

Keyframes record how pixels move and nothing else. The Motion Envelope makes every animation declare its purpose, and a verifier proves the compiled keyframes stay inside the envelope that purpose earns.
The keyframe is older than most people using it. Burtnyk and Wein published computer-generated key-frame animation in 1971, borrowing the concept from traditional animation studios older still. Macromedia Flash mainstreamed it for interface work in the late 1990s, and every motion tool since (After Effects, Principle, ProtoPie, Figma’s Smart Animate, Lottie, Rive’s timelines) has refined the same abstraction: define states, interpolate between them, tune the curve. Thirty years of better ergonomics on an unchanged unit.
In 2026 that unit got an industrial supply chain. Adobe shipped what it calls semantic motion in After Effects on January 20, with an Auto-Keyframer that predicts object paths. At Config on June 24, Figma rolled out its Weave generation tools in open beta and introduced Figma Motion: a keyframe timeline inside Figma Design, motion attachable to design-system components so it travels the way fills and typography do, and a Dev Mode where, in Figma’s words, “every timing value, every easing curve, every keyframe is readable” and exportable as CSS, JSON, or React. Read that carefully: the largest design platform just made the complete HOW of motion inspectable at the component level, and the WHY appears nowhere in the artifact. All of these tools are remarkable, and all of them automate or expose the same thing: keyframe production. An agent that generates keyframes at scale is automating 1996, and the volume is now hitting design systems that have no way to evaluate what arrives.
Because here is what a keyframe records: how pixels move. Position, scale, opacity, over normalized time. Here is what it does not record, anywhere, in any format: why. Whether the motion is feedback confirming a tap, orientation explaining a layout change, or decoration that exists to be pretty. That missing fact is not a nice-to-have. It is the fact every meaningful judgment about motion depends on, including, as we will see, the one judgment the accessibility standards already require and no tool can make.
This article proposes the Motion Envelope: a governance model where every animation in a design system declares its purpose as a machine-read field, the purpose determines a machine-checkable constraint envelope, and a verifier proves the compiled artifact (the actual keyframes, not the design intention) stays inside it. The named gaming move it catches is lenient-envelope shopping. The named aggregate hazard is the surface overdraft.
Motion governance exists. All of it is input-side.
Let me be precise about the incumbents, because motion governance is no longer an empty field and pretending otherwise would be false.
Design systems ship motion tokens today. Material 3 publishes duration and easing token specs. IBM’s Carbon defines productive and expressive motion styles with tokenized curves. The W3C Design Tokens Community Group format defines first-class duration and cubicBezier types, while springs, keyframes, and composite motion still have no first-class types in the specification. Semantic naming (motion.duration.fast, not 200ms) is established practice.
Purpose taxonomies exist too, as guidance. The academic Taxonomy of Functional Animation classifies interface motion into functions like identifying, structural, guide, feedback, didactic, esthetic, and emotive, validated by expert survey. Material distinguishes functional from expressive motion. These taxonomies tell designers how to think. None of them is a field a machine reads.
And motion governance is now a product category. LottieFiles’ Motion System ships approved animation libraries, presets, and distribution workflows for teams, marketed on the argument that color has tokens and type has a scale while motion lacks an owner. It is a real product solving a real problem, and it defines the incumbent model: govern the inputs. Approve a library, bless the presets, control who can add to it. Their own FAQ states the philosophy plainly: once presets are baked into components, “there’s nothing left to check.”
That sentence is where this article begins. For the brand consistency of library-sourced assets, the scope the FAQ is actually about, it is fair. As a governance philosophy for what ships, it is exactly wrong. There is everything left to check. What ships is not the preset; it is the compiled output, produced by hand-tuned CSS, by a spring config someone tweaked, or increasingly by a generative tool that never consulted the library. Input-side governance approves what teams may reach for. Nothing verifies what actually moves. Governance by library and governance by verification are different capabilities, and the second one does not exist for motion, in any tool, at any layer of the stack.
The exemption no checker can grant
The sharpest proof that output-side motion governance is missing sits inside the accessibility standards everyone already claims to follow.
WCAG 2.3.3 (Animation from Interactions, Level AAA) requires that motion animation triggered by interaction can be disabled, “unless the animation is essential to the functionality or the information being conveyed.” WCAG 2.2.2 (Pause, Stop, Hide, Level A) makes the parallel carve-out for moving, auto-updating content, and because it sits at Level A it binds every conformance target, not just the ambitious ones. Both criteria hinge on the word essential, and essential is a purpose judgment.
Now look at the tooling. Automated accessibility checkers have gotten genuinely good at motion detection. LottieFiles ships a Lottie Accessibility Analyzer that inspects Lottie JSON before render and flags motion sensitivity risks, flashing, and contrast issues. TestParty detects WCAG 2.2.2 violations from source, catching CSS animations over five seconds and auto-advancing carousels. axe and friends check rendered pages. These tools are real, artifact-level in some cases, and they all share one structural limit: they enforce universal rules. Animation longer than five seconds, flag it. Flashing over threshold, flag it.
What none of them can do from the artifact alone is apply the standard’s own exemption, because the deciding fact (is this motion essential?) is not present in anything they read. A Lottie file does not say whether it is decoration or feedback. A CSS keyframe block does not say whether the motion conveys state or vibes. The most important clause in motion accessibility is undecidable by every checker on the market, not because the checkers are weak but because the input is missing the load-bearing field.
The Motion Envelope’s first claim is simply: put the fact in the artifact. Everything else follows from that.
The Motion Envelope, in four parts
One: purpose is a required, machine-read field. Every animation in the system declares one purpose from a small governed set. The reference implementation uses five: feedback, orientation, spatial_continuity, attention, and decoration, adapted from the Taxonomy of Functional Animation and Material’s functional/expressive split. The taxonomy is not the contribution; taxonomies are twenty years old. The contribution is the field: purpose moves from design guidance to declared, reviewable, machine-consumed metadata, the same shift design tokens made when color moved from a style guide PDF into JSON.
Two: the envelope is a function of the purpose. Each purpose earns a constraint envelope: duration ceiling, iteration limit, displacement bound, allowed trigger classes, and a required reduced-motion behavior. Feedback motion is brief, runs once, moves little, is user-triggered, and survives prefers-reduced-motion in simplified form, because feedback is essential in exactly the WCAG sense. Decoration may be long and looping, but it must drop to nothing under reduced motion, because decoration is the definition of nonessential. The binding is strict on purpose: an envelope is not a per-animation negotiation, it is what the declared purpose earns. The metaphor is the flight envelope: operate inside it and you are certified, exit it and you are not, and the envelope you get depends on what kind of aircraft you claimed to be.
Three, and this is the heart: a verifier checks the compiled artifact, not the intention. A small trusted checker ingests the actual output (CSS keyframes, Lottie JSON, spring parameters, normalized into one fact format), derives measured motion facts (total path displacement, duration, iteration count, trigger class, presence and kind of reduced-motion variant), and checks the facts against the declared purpose’s envelope. Tool-independence is the point: the same check governs hand-written CSS, a designer’s Lottie export, and whatever a generative canvas emits, because it reads what ships rather than what was intended. Reduced motion stops being a hand-authored afterthought and becomes a compile target derived from purpose: essential purposes degrade, decoration drops, and the absence of the required variant is a build failure, not an audit finding six months later.
The verifier also runs the mismatch detector, which catches the gaming move this design invites. If purposes earn envelopes, authors (human or agent) will shop for the lenient envelope: declare the infinitely pulsing notification badge as “feedback” to dodge decoration’s drop requirement. Some of that shopping is machine-detectable, because the compiled facts betray the declaration: feedback that loops forever and fires autonomously is decoration wearing a feedback badge, and the verifier flags it as a config error, not a style nit. Lenient-envelope shopping that survives the detector routes to human review, which is what Intent Diffs are for. Declared-intent systems always carry this residual; the difference here is the detectable cases are actually detected.
Four: the surface budget. Envelope conformance is per-animation, and per-animation checks have a known blind spot, one I have written about before as the Conformance Trap: individually conformant changes that aggregate into a degraded system. Motion has the sharpest version of it. Peripheral motion captures human attention involuntarily; that is what it is for, evolutionarily. For users with ADHD the capture cost is higher and recovery slower, and vestibular dysfunction, which more than 35 percent of adults have experienced by age 40, makes sustained ambient motion physically hostile. web.dev’s accessibility guidance and practitioner writing (Pope Tech, December 2025) both name ADHD distraction and vestibular harm as the core motion risks. Three tasteful ambient animations, each inside its decoration envelope, are still three things moving at once next to a checkout form.
So the Motion Envelope adds Surface Motion Load: each declared surface (a named composition unit listing its member animations) carries a budget for concurrent autonomous motion, and the verifier counts. The budget number is a governed default in the tradition of performance budgets, chosen and owned by the team, not an empirically derived perception threshold, and I will not pretend otherwise. Honest scope note: true concurrency depends on runtime layout and viewport composition, which compiled artifacts do not carry; the declared-surface approximation is checkable today, runtime verification is future work.
The replay: keyframes pass, envelopes fail
The reference implementation (motions.json plus motion_check.py) carries seven compiled animations across two surfaces and runs two worlds on identical inputs.
In envelope mode: M-01, a 180ms user-triggered button ripple declared as feedback, is inside its envelope and allowed. M-02, an ambient hero gradient drift declared as decoration with a proper reduced-motion drop, is allowed. M-03, a promo banner shimmer declared as decoration but compiled with no reduced-motion variant, is blocked: nonessential motion must drop, and the Level A failure (the 2.2.2 and 2.3.3 essential-motion exemptions) is caught at the artifact, before any page exists for an auditor to scan. M-04 is the shopping case: a notification badge pulse declared as feedback whose compiled facts loop infinitely and fire autonomously; the mismatch detector flags it as a config error, decoration wearing a feedback badge. M-05, a 420ms page transition declared spatial continuity, is allowed at 320px displacement, which would bury any universal displacement rule but is exactly what its purpose earns. Then the aggregate pass runs: checkout-form holds two autonomous motions against a budget of one, and home-hero holds three individually allowed decorations against a budget of two. Both surfaces are in overdraft. Note the deliberate rule in checkout-form’s count: both of its autonomous motions were already blocked per-animation, and they still count against the surface until they are removed, because blocking a merge does not un-ship what is currently live. Home-hero is the purer case: three animations that each pass their envelope, aggregating into a surface that fails its budget. The run exits 1 with four problems.
In keyframe-only mode, the status quo, the same seven animations are validated for well-formed, monotonic keyframes, which is the only check the artifact supports when purpose is not read. Everything passes. Exit 0. The purpose violations, the WCAG drop failure, the envelope shopping, and both overdrafts are invisible, and the summary line states the reason: the deciding fact is not in the keyframes.
The delta between those two exit codes, on byte-identical inputs, is the entire argument of this article in executable form.
What this asks of teams, honestly
Adoption cost lives in two places. The declaration burden: every animation needs a purpose field, which is one enum value, reviewable in the same pull request as the motion itself, and exactly the kind of field an agent can be required to emit with its output. And the decompiler tier list: Lottie JSON and spring configs normalize cleanly and should be the first supported tier; CSS keyframes are the hard tier (relative units, composed transforms, values resolvable only at runtime), and a team should scope the first deployment to the formats its motion actually ships in rather than promising universal coverage on day one.
For the ecosystem this slots into, three connections and one refusal. Motion changes are Trapdoor-prone in Blast Radius Mapping terms: tiny structural fan-out, enormous perceptual reach, exactly the quadrant a dependency-sized gate auto-merges. Envelope results are natural components of a Proof-Carrying Design receipt, so an agent’s motion change arrives with its envelope check attached. Purpose declarations are precisely the kind of settled intent Intent Diffs surface for human review. And the refusal: this is not a fourth contract. The Three Contracts already cover it; purpose is the meaning contract for a motion primitive, the envelope is its method contract, and who may add motion to which surface is its permission contract. The Motion Envelope is the three contracts instantiated for the one token class that never got them.
Failure modes
Envelope shopping beyond the detector. The mismatch detector catches fact-contradicted declarations; a plausible false purpose on a borderline animation survives it. Residual for human review, same as every declared-intent system, including mine.
Agent-emitted purposes. The adoption story asks agents to emit the purpose field with their output, and when the same agent emits both the keyframes and the declaration, the declaration is not an independent signal; it is the fox filing its own flight plan. In that deployment the mismatch detector stops being auxiliary and becomes load-bearing, and its current coverage is narrow. Expanding fact-contradiction rules per purpose, and routing every agent-declared purpose through Intent Diffs, is the honest price of agent-generated motion.
Taxonomy wars. Teams will dispute whether five purposes suffice. They will not suffice for everyone; the governed set is extensible per system. The invariant that matters is not the list, it is that every purpose in the list carries an envelope and every animation carries a purpose.
Invented thresholds. 300ms feedback ceilings and budget-of-two surfaces are defensible defaults, not perception science. Publishing them as science would be the pseudo-quantification mistake; they are governed values a team tunes, like performance budgets, and the verifier’s job is consistency, not truth.
Reduced-motion theater. A team can compile a “simplified” variant that is barely simpler. The envelope checks presence and kind, not aesthetic sufficiency. Sufficiency stays with human review; the envelope guarantees the variant exists and the drop actually drops.
The takeaway
Motion is the token class where design systems still accept the 1971 abstraction as the artifact of record, and generative tools are now filling that artifact at industrial rates. The incumbent answer governs the library. The missing answer governs the output, and it becomes possible the moment the artifact carries one more field. A keyframe says how. A purpose says why. An envelope makes the why checkable, and a design system that can check the why of motion can finally extend to its most perceptually powerful primitive the same discipline it learned to apply to a hex value.

Described diagram: a three-lane horizontal flow. Lane one, authoring: three sources (hand-written CSS, a Lottie export, a generative canvas node graph) all emitting keyframe documents into a funnel. Lane two, the checkpoint: each document paired with a small purpose tag (feedback, decoration, spatial continuity) entering a gate shaped like a flight envelope chart, with an inset magnifier showing measured facts (duration, displacement, loop, reduced-motion variant) being compared against the envelope curve for its declared purpose; one document bounces off the curve marked SHOPPING. Lane three, the surface: allowed animations landing on two labeled viewport rectangles, one calm and within budget, one glowing amber with a counter reading 3 of 2 and the label SURFACE OVERDRAFT.
메타데이터
- post_id
- 8d87c19c997a
- slug
- the-motion-envelope-30-years-after-flash-figma-motion-still-cannot-say-why-anything-moves-8d87c19c997a
- url
- https://medium.com/design-bootcamp/the-motion-envelope-30-years-after-flash-figma-motion-still-cannot-say-why-anything-moves-8d87c19c997a
- canonical_url
- https://medium.com/design-bootcamp/the-motion-envelope-30-years-after-flash-figma-motion-still-cannot-say-why-anything-moves-8d87c19c997a
- author_url
- https://medium.com/@surendarselvaraj
- status
- ok
- fetched_at
- 2026-07-13 22:03:30