Page transitions
Subtle opacity + 6px translateY on every page mount. Just enough to acknowledge the navigation without slowing it.
Setup
// src/app/template.tsx — wraps every page
"use client";
import { motion } from "framer-motion";
export default function Template({ children }: { children: React.ReactNode }) {
return (
<motion.div
initial={{ opacity: 0, y: 6 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: -6 }}
transition={{ duration: 0.25, ease: [0, 0, 0.2, 1] }}
>
{children}
</motion.div>
);
}Why template.tsx (not layout.tsx)
Layouts persist across navigation; templates remount. The template.tsx file ensures the animation re-runs every time the user navigates, giving the lift-on-arrival feel.
Reduced motion
Framer Motion respects prefers-reduced-motion automatically when wrapped in a MotionConfig with reducedMotion="user" .