📦 deps(thirdparty): update snapshots

This commit is contained in:
ci[bot]
2026-07-01 16:02:41 +00:00
parent 8301f01888
commit c824ba9d7b
2449 changed files with 555104 additions and 9259 deletions
@@ -0,0 +1,111 @@
# Motion choreography — a generalizable animation guideline
When to animate, which transitions earn their keep, how long, and the craft that
separates intentional motion from jitter. **Framework-agnostic** — the rules hold for
plain CSS, the Web Animations API, the browser View Transition API, a JS motion library,
or React's `<ViewTransition>`. Load from design-system's Motion section when a UI has
state changes, navigation, list changes, or reveals worth animating.
> Adapted & generalized from the Web Interface Guidelines (`vercel-labs/web-interface-guidelines` @ `4e799d4`, 2026-04-06) and the React View Transitions skill (`vercel-labs/agent-skills` @ `f8a72b9`, 2026-06-10). Their API specifics are React/Next-bound; the *choreography* below is portable.
## 1. When to animate — earn every transition
Animate only when the motion **communicates** one of: a spatial relationship, continuity
("same thing, new place"), cause→effect, that data arrived, or deliberate delight.
**If you can't articulate in one sentence what a transition communicates, cut it.** Motion
with no message is noise that costs performance and attention.
- **Input-driven, never autoplay.** Animate in response to a user action or a state change
they caused — not on a timer that plays at them.
- This is the motion-specific case of restraint-rule: the default is *no* animation; a clear
communicative purpose is what forces a yes.
## 2. Which transitions earn their keep — priority order
When several kinds of change happen, implement every one that *applies* (not "pick one"),
in roughly this order of value:
1. **Shared element** — the same object persists across views (thumbnail → hero). Says "this
is the same thing, going deeper." Highest value; most worth the effort.
2. **Reveal** — skeleton/loading → real content. Says "data loaded."
3. **List identity** — items keep identity as the set reorders/filters. Says "same items,
new arrangement" (animate position, not a wholesale fade).
4. **State change** — something enters/exits (panel, toast, row). Says "this appeared/left."
5. **Route/section change** — moving to a new place.
Skip a level only when the UI has no such change. A background refresh / silent
revalidation should animate **nothing**.
## 3. Style by the *kind* of navigation — direction must be honest
The animation style must not imply a spatial relationship that isn't there:
| Navigation kind | Animation | Why |
|---|---|---|
| **Hierarchical** (list → detail, parent → child) | directional slide (in from the side, out the other) | direction encodes depth |
| **Ordered sequence** (prev/next photo, carousel, paginated) | directional slide; "next" from the right, "prev" from the left | direction encodes position |
| **Lateral / sibling** (tab ↔ tab, unordered) | **fade / cross-fade** — NOT a slide | there's no depth; a slide lies about it |
| **Reveal** (skeleton → content) | fade or short slide-up | content arriving |
| **Background refresh / revalidation** | none | nothing happened the user must track |
The single most common motion mistake is a directional slide on lateral navigation — it
falsely implies forward/back depth between peers.
## 4. Timing & easing (starting points, not law)
| Interaction | Duration |
|---|---|
| Direct toggle (expand/collapse, switch) | 100200 ms |
| Route / section transition (slide) | 150250 ms |
| Reveal (skeleton → content) | 200400 ms |
| Shared-element morph | 300500 ms |
- **Easing matches the change:** entrances `ease-out` (decelerate in), exits `ease-in`
(accelerate away), positional moves `ease-in-out`. Choose by what's changing (size,
distance, trigger) — bigger/further → a touch longer.
- A playful/toy direction (design-thinking) may stretch these and add spring/bounce; a
restrained/professional one keeps them tight. Match the feel to the chosen direction
rather than defaulting to the numbers.
## 5. Mechanics — what to animate, and how (any stack)
- **Compositor-friendly only:** animate `transform` and `opacity`. **Never** animate layout
properties (`width`, `height`, `top`, `left`) — they trigger reflow and jank.
- **Never `transition: all`** — list the exact properties; `all` silently animates
layout-affecting props and janks.
- **Correct `transform-origin`** — anchor motion where it "physically" starts (a menu from
its trigger, not screen-center).
- **Interruptible** — a new user input cancels/redirects the in-flight animation; motion is
never a modal wait.
- **SVG transforms** — apply to a `<g>` wrapper with `transform-box: fill-box;
transform-origin: center;` (avoids Safari origin bugs).
- **Stack preference:** CSS > Web Animations API > JS library. Prefer the platform; reach for
a library only when the platform can't express it.
## 6. Craft details that separate polished from amateur
- **Motion blur on morphs.** A shared-element morph reads as fast and physical with a brief
blur at mid-transition (e.g. `filter: blur(3px)` around the 30% mark), clearing to sharp.
- **Don't raster-scale text.** A shared-element morph between different text sizes (`h3 → h1`)
scales a *bitmap* of the small text up → a blurry ghost. Instead hold/cross-fade the text
(show the new text at full resolution, hide the old snapshot) rather than scaling it.
- **Isolate persistent chrome.** Headers, navs, sidebars, sticky toolbars that stay on screen
across a transition must NOT slide with the page content — give them their own transition
identity (or exclude them) so they stay put while content moves beneath.
- **Reveal anti-flicker.** If you show a spinner/skeleton, add a short show-delay (~150300 ms)
and a minimum visible time (~300500 ms) so a fast response doesn't flash the loader. (See
design-ux interaction add-ons.)
## 7. Accessibility — reduced motion
Honor `prefers-reduced-motion` for **public / multi-user** builds: drop the tweens (keep the
end state / a 0s cross-fade), don't remove the information the motion conveyed. For
**personal/single-user** projects this repo deliberately overrides that flag — see
`motion-preference-rule`. Either way, avoid parallax, large viewport-spanning transforms, and
strobing regardless of the flag.
## The one-line test
Before adding a transition: *what does this communicate, and is the style honest about it?*
If you can't answer the first, cut it; if the style implies depth/position that isn't there
(a slide between peers), change the style.