Motion
Animation.
SKILL.md.agents/skills/thorbis-motion/
Follow the skill selection policy and shared Linear baseline. For mobile-app work, the Native contract (D-025) is required.
Scope and required context
Linear baseline: This skill specializes one part of Thorbis; it does not introduce another product grammar. Preserve quiet chrome, one dominant work region, structured density, stable action neighborhoods, contextual surfaces, visible keyboard paths, durable state, and role-adaptive mobile. Use the Thorbis × Linear pattern matrix only when the owning pattern is ambiguous.
Mobile platform gate (D-025): Every mobile-app task requires the Native contract, HIG-001–HIG-022, and relevant live Apple Human Interface Guidelines (opens in a new tab). Apple HIG governs iOS/iPadOS behavior over conflicting web/Linear rules. Cite rule IDs and topic URLs in specifications, component contracts, PRs, and release evidence. Android retains host conventions. Normative requirements and exceptions have one owner: Native.
Two failures. The first is worse.
- Animating something that should not move.
- Moving the right thing the wrong way.
This is its own skill. Drop it at .agents/skills/motion.md. Pick this file. Do not average it with the others.
Live: https://design.thorbis.com/skills/motion
Rules is what we ship. Research is the homework. `DESIGN.md` is the constitution. `AGENTS.md` is the contract.
This skill holds: frequency-first motion, --motion-fast and --ease-out, D-021 (overlay is a mix, a popover grows from its trigger, a menu fades), and the motion half of D-022 (a Film sequence may follow scroll; the browser still owns the wheel).
Homework: Emil Kowalski. Most UI does not need to move. 100dvh. Hover only if they can hover. Rauno Freiberg: a sheet grows from the row that opened it. High-frequency menus stay still. Grammar, not a spring showcase.
Do not offer a menu of motions. Make the call.
thorbis-motion-SKILL.md
First
- How often does this happen? A hundred times a day does not animate.
- Who is holding it? Keyboard is instant. A thumb may drive a sheet. A visitor on Film may own a sequence.
- What is the purpose? Feedback, space, state, or continuity. If you cannot name it, do not build it.
- Which token?
--motion-fast,--motion-overlay,--ease-out. No private curve.
A dispatcher with vestibular issues still has to run the morning board. Instant is the respectful default.
Gate
| Frequency | Decision | Examples |
|---|---|---|
| 100+ / day | No animation. | ⌘K, shortcuts, row focus, J K |
| Tens / day | Near nothing. Color only. | Hover, selected row |
| Occasional | 120–200ms. | Dialog, sheet, toast |
| Rare / Showcase | The only delight budget. | First-run, marketing cut |
On a Film page, scroll may drive a sequence. The visitor owns speed and reverse. The browser still owns the wheel. Do not pin the page. Motion must explain a join. Headings that drift: refuse. D-022. Cinematic.
Keyboard is instant. Destructive commits on release, not on press. Swipe-to-cancel a job commits when the thumb lifts, so they can abort mid-swipe with muddy gloves.
If the animation does not help them see what changed on a job, cut it.
| Purpose | Allowed |
|---|---|
| Feedback | Press dim, success tick |
| Space | Sheet from an edge |
| State | Dialog in, toast in |
| Continuity | Shared element on Showcase |
Tool
| Need | Tool |
|---|---|
| Hover, press, color | CSS transition |
| Mount, no JS | @starting-style |
| Known sequence | CSS animation |
| Programmatic | WAAPI |
| Spring or gesture | Motion |
Do not install a library for a fade. Don’t ship a spring library so a toast can fade. CSS is enough for almost every shop-floor motion.
Ingredients
transformandopacityonly.clip-pathallowed.heightonly for accordions. Jank on the board loses the 7 a.m. window.- Never
scale(0). Start at0.95plus fade, or do not scale. A bounce looks like a game, not a job. --ease-out: cubic-bezier(0.23, 1, 0.32, 1). Neverease-inon UI. A sheet that eases in late feels broken. First frame already moving.- Press 80–120ms. Hover 100–120ms. Dialog and sheet 160–200ms. Ordinary web UI transitions take at most 200ms. Popovers and menus use the event recipes below. A slow drawer on a job they open 80 times a day is stolen time.
- Exit the way it entered. Exit quieter than enter. Interrupt with transitions, not keyframes. They will tap another job before the first inspector finishes. The next one has to win.
- Overlay is a mix, not a blur. A popover grows from the control that opened it. A menu fades; it does not fly off the screen. D-021.
- Reduced motion: keep opacity, drop movement.
- Hover motion gated to
(hover: hover) and (pointer: fine). will-changeonly ontransformoropacity, and only if the first frame stutters. Take it off when the motion ends. Neverwill-change: all.
--ease-out: cubic-bezier(0.23, 1, 0.32, 1);
--motion-fast: 120ms;
--motion-overlay: 180ms;Copy the token. Do not invent a curve.
Recipes
| Event | Recipe |
|---|---|
| Press | opacity or brightness, 80–120ms, ease-out |
| Hover color | color, 120ms, gated to a real mouse |
| Dialog | opacity + translate 8px, 160–200ms; --motion-overlay is 180ms |
| Sheet | translate from its edge, 200ms, reduced-motion = opacity |
| Popover | scale from the trigger, 120–160ms. Origin is the control. |
| Menu close | opacity, 80–120ms. Do not fly off screen. |
| Toast | opacity, 120ms |
| Sidebar | transform + negative margin. Never width. |
⌘K | Instant. No scale. No fade. |
| Showcase enter | Stagger ~100ms on first load only. Title, then copy, then the shot. Never on a board. |
If two things move, they are one event, not two shows. A first-run empty state can arrive in pieces. The morning board cannot.
A status icon that pops in next to On site can fade. The whole toolbar cannot.
Closing a job sheet should get out of the way. The row they picked may flash as the inspector closes, so they know which job they just edited. The next job is the show.
The finger drives the sheet. A canned animation that ignores the swipe fights them.
A popover from a job row grows from that row. From the center it feels like a different product.
Showcase
Delight lives here only. Do not export this motion into Admin.
On Film, a sequence may be tied to scroll: it moves when they move, pauses when they stop, reverses when they go back. Do not pin the page and fake a reel. Do not hijack or artificially slow the scroll.
Motion must explain a join, a before/after, a config, a dimension, a workflow. Headings that drift, cards that float, objects that spin for atmosphere: refuse.
Preserve one subject. Change one or two properties. Many objects moving at once is a template, not a film.
Reduced-motion stills of the same crop. A usable page before cinematic assets load. Cinematic.
Never
transition: all- Animation on
⌘K - Ungated
:hover - Everything at once
- A bounce on a workbench control
- Animating
widthon the sidebar. Use transform plus negative margin. backdrop-filteras an overlaywill-change: all- A private cubic-bezier
- A spring library for a fade
- Cinematic stagger on a board
- Motion that only resembles Apple
Audit
- Frequency named. 100+/day is instant
- Purpose named, or motion refused
- Token curve and duration. No private easing
transformandopacityonly (or a named accordion)- Overlay is a mix. Popover grows from its trigger. Menu fades. D-021
- Reduced motion: opacity only
- Hover gated to a real mouse
- Keyboard path is instant
- If Showcase: the motion explains a join. D-022
Two failures: do not ship.
Done
State the gate, the tool, the curve, the duration. If you refused motion, say so. That is success.
Applied bookmark research
Reviewed 2026-09-06. These are Thorbis applications and review exercises, not replacements for DESIGN.md, COMPONENTS.md, or the owning skill. Linear remains the operational baseline. External advice that conflicts with the constitution stays out.
These worked examples are not a claim that the product behaviors have been implemented or verified.
Frequent work stays immediate; allowed motion can be interrupted
Owning skill: motion.
A small delay repeated through a working day becomes friction, and a transition that restarts from the wrong position disconnects feedback from input.
Apply the existing profile first: Workbench is press-only, Evidence has no motion, and other profiles remain constrained by their owner. Where a transition is already permitted, preserve continuity and the state footprint when input interrupts it.
Thorbis example: Command-menu selection follows the key immediately. A permitted popover opens from its trigger and survives open-close-open without snapping, losing focus, or changing the action label.
Verify: Repeat the interaction rapidly, switch between input methods, and test reduced motion. Compare with the nonanimated version at ordinary task speed. Use existing tokens rather than copying durations or curves from an article.
Do not import: No row stagger in routine work, delayed keyboard highlights, ornamental blur, minimum success delay, or automatic spring-library adoption.
Evidence: You Don't Need Animations (opens in a new tab); 7 Practical Animation Tips (opens in a new tab); Train Your Judgement (opens in a new tab); Details that make interfaces feel better (opens in a new tab). Source access limits.
All skills
The bundle includes every skill. Use Resources to choose the smallest context for a task.