lerpa
ver1.0.0
node20.11
branch⎇ main
uptime14d 03:42:17
cpu3.2%
mem14 MB
teams4,213
utc00:00:00
LIVE
$lerpa --motion

Animations

Motion is part of the Lerpa UI house style — but it always degrades gracefully. Components use Framer Motionand gate every animation behind the user's reduced-motion preference.

The pattern

Read the preference with usePrefersReducedMotion and branch your variants and transitions. When motion is reduced, the element snaps to its final state with duration: 0 instead of animating.

reveal.tsx
"use client";

import { motion } from "framer-motion";
import { usePrefersReducedMotion } from "@lerpa/ui";

export function Reveal({ children }: { children: React.ReactNode }) {
  const reduced = usePrefersReducedMotion();
  return (
    <motion.div
      initial={reduced ? { opacity: 1 } : { opacity: 0, y: 24 }}
      whileInView={{ opacity: 1, y: 0 }}
      viewport={{ once: true, margin: "0px 0px -12% 0px" }}
      transition={reduced ? { duration: 0 } : { duration: 0.5, ease: [0.22, 1, 0.36, 1] }}
    >
      {children}
    </motion.div>
  );
}

Staggered reveals

For lists, drive children off the parent with a small per-item delay — and clamp the total so long lists don't lag. The same reduced-motion branch zeroes the delay.

stagger
const variants = {
  hidden: reduced ? { opacity: 1 } : { opacity: 0, y: 20 },
  visible: (i: number) => ({
    opacity: 1,
    y: 0,
    transition: reduced
      ? { duration: 0 }
      : { duration: 0.45, delay: Math.min(i * 0.04, 0.2) },
  }),
};

App-wide reduced motion

At the app level you can wrap your tree in Framer Motion's MotionConfig so animations respect the system setting globally — the docs site does exactly this:

layout.tsx
import { MotionConfig } from "framer-motion";

export default function Layout({ children }) {
  return <MotionConfig reducedMotion="user">{children}</MotionConfig>;
}

Guidelines

  • Never animate without a fallback. Every animated component branches on reduced motion.
  • Keep durations short. Entrances are typically 0.3–0.6s with an ease-out curve.
  • Animate transforms and opacity rather than layout properties, to stay on the compositor and avoid jank.

Motion accessibility is covered further in the accessibility guide.

lerpa · running
turbopack142ms
a11yAAA
tokens14
network14kb