# 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.

- Skill: `agenta-ai/mobile-motion-patterns` (Agent Skill)
- Install (CLI): `npx skillmds@latest add agenta-ai/mobile-motion-patterns`
- Raw SKILL.md: https://api.skillmd.com/api/skills/agenta-ai/mobile-motion-patterns/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: Agenta-AI (https://skillmd.com/u/agenta-ai)
- Updated: 2026-09-10
- Page: https://skillmd.com/skills/agenta-ai/mobile-motion-patterns

---


# Mobile motion patterns

All 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 {useMotionPresets} from "@/lib/motion/presets"

const {sharedAxisPush, sheetSlideUp, crossfade, reduced} = useMotionPresets()
```

- **`sharedAxisPush`** — list → chat navigation (and any parent → child screen
  push). Forward uses `custom={1}`, back uses `custom={-1}`; the back
  gesture/button reverses the same preset. Wrap sibling screens in
  `<AnimatePresence custom={direction} initial={false}>`.
- **`sheetSlideUp`** — spring-based bottom sheets (project drawer). Pair with a
  `crossfade` scrim.
- **`crossfade`** — skeleton → content swaps. Skeleton and content must occupy
  identical geometry so the fade causes zero layout shift.

## 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 when `prefers-reduced-motion` is set; any animation built outside
  the presets module must justify itself in review AND handle reduced motion
  itself (prefer extending the presets module instead).
- **Message entrance/streaming** (WP3b+): subtle and consistent with the
  playground's feel — entrance is a small fade/rise on the preset tokens; text
  streaming is never per-character animated.
- New shared patterns go INTO `presets.ts` (one exported preset + doc comment),
  not into a component file.

