Skip to main content

mobile-motion-patterns

Motion design rules for the Agenta mobile app (web/mobile) — the shared presets in src/lib/motion, when to animate, and reduced-motion requirements. Use when adding any animation or transition under web/mobile, animating navigation, sheets, skeletons, or list/chat surfaces.

Source facts

Repository
Agenta-AI/agenta
Last source activity
September 26, 2026 at 16:50
Detected SKILL.md language
English
Stars
4,887
Forks
726

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
mobile-motion-patterns
description
Motion design rules for the Agenta mobile app (web/mobile) — the shared presets in src/lib/motion, when to animate, and reduced-motion requirements. Use when adding any animation or transition under web/mobile, animating navigation, sheets, skeletons, or list/chat surfaces.
# Mobile motion patterns JS-driven animation in `web/mobile` uses the `motion` package through the shared presets module `src/lib/motion/presets.ts`. Components never define their own durations, easings, or springs. ## The presets Consume via the hook (reduced-motion aware — this is mandatory): ```tsx import {AnimatePresence, motion} from "motion/react" import {useMotionPresets} from "@/lib/motion/presets" const presets = useMotionPresets() <AnimatePresence initial={false}> {open ? ( <motion.div key="panel" variants={presets.crossfade} initial="initial" animate="animate" exit="exit" /> ) : null} </AnimatePresence> ``` In use today: - **`crossfade`** — the only preset components consume. Used for the reply reveal (`features/chat/AnswerReveal.tsx`) and the composer's picker and recording overlays (`features/chat/Composer.tsx`). For skeleton → content swaps, skeleton and content must occupy identical geometry so the fade causes zero layout shift. Defined but not used by any screen yet: - **`sharedAxisPush`** — horizontal parent → child push. `custom={1}` forward, `custom={-1}` back, inside `<AnimatePresence custom={direction} initial={false}>`. - **`sheetSlideUp`** — spring-based slide-up for a custom bottom sheet. - The raw `pushTransition` / `sheetTransition` / `crossfadeTransition` values and the `reduced` flag. Reach for these before adding a new preset. Screen navigation has no transition today, and sheets and drawers (`Sheet` from `@agenta/ui/ui` or the local `src/components/ui/sheet.tsx`) animate with their own Tailwind `animate-in`/`slide-in-*` classes, not with `motion`. ## Rules - **Animate navigation, containment, and state swaps — not decoration.** No attention-seeking motion, no animating properties that trigger layout (animate `transform`/`opacity` only). - **Reduced motion is not optional.** `useMotionPresets()` returns instant variants and zero-duration transitions when `prefers-reduced-motion` is set. Any animation built outside the presets module must justify itself in review AND handle reduced motion itself. CSS keyframe animations need a `@media (prefers-reduced-motion: reduce)` override in `globals.css` (see `.animate-composer-ring`). Prefer extending the presets module. - **Message entrance/streaming**: subtle — the reply fades in on `crossfade`; text streaming is never per-character animated. - New shared patterns go INTO `presets.ts` (one exported preset + doc comment, plus its reduced variant in `useMotionPresets`), not into a component file.
View on GitHub