frontend
A motion system, and the components built but never mounted
A motion system, and the components built but never mounted
A motion system isn't a pile of animations — it's tokens plus a component vocabulary, mirrored per platform. My platform runs the same conceptual system on two different stacks:
| Concept | Web (framer-motion) | Mobile (reanimated) |
|---|---|---|
| Ambient background | Drifting gradient blobs + scattered geometry | Same, plus the geometry reacts to device tilt via gyroscope |
| Interactive accent | An octagram that follows the cursor on spring physics | Same shape, pressable with spring scale + spin, plus tilt offset |
| Success feedback | Geometric particles on polar trajectories | Same, plus haptics |
| Entrance | Scroll-triggered reveal / cascade primitives | FadeInDown entrances plus a stagger hook |
| Sensor input | Mouse position | useAnimatedSensor, one shared context for the whole app |
What makes it a system rather than a pile of effects: a shared duration scale (fast ~150ms, base ~200–220ms, slow ~400ms), one signature ease-out curve, named stagger intervals and travel distances every component draws from. Reduced-motion is a first-class branch, not an afterthought — every decorative component checks the accessibility preference and degrades to static. Decorative motion that can't turn itself off is a defect. And motion attaches to meaning — a status change pulses, a number counts up — not to page-load spectacle.
The trap this project actually hit
The mobile celebration burst was finished and physics-tuned, mounted on zero screens. The interactive geometry accent was used once, at 22px. Nothing in a build, lint or review flags a component that exists and is never rendered — in a solo codebase this quietly accumulates until the system's capability races ahead of what users ever see.
The countermeasure that works: when auditing design, explicitly diff what the component library can do against what each screen actually mounts. That diff was most of my redesign backlog.
A few practical notes: tokens don't cross the CSS/native boundary automatically, so the native side hand-mirrors the web token file — accept the duplication but treat the mirror as a named drift risk and re-audit it (my mobile dark-mode debt came exactly from that seam). Gyro-driven motion is the cheapest way to make a mobile app feel alive, and it's ambient — no user education needed — but wrap the sensor in one context provider, since per-component polling wastes battery. And keep the signature geometry recurring across pins, particles, patterns and accents — a repeated shape is a brand, varied clipart is a template.