/** * Shared motion personality — Emil Kowalski craft methodology. * * One cohesive easing/spring vocabulary used across the whole page so every * interaction feels like it belongs to the same product. Springs (not raw * mouse-tracking) drive ALL decorative/pointer motion so it has momentum and * feels alive; bezier curves drive everything choreographed. */ import type { Transition } from "motion/react"; /* Custom bezier curves (mirror globals.css tokens). */ export const EASE_OUT = [0.23, 1, 0.32, 1] as const; // entrances / settle export const EASE_IN_OUT = [0.77, 0, 0.175, 1] as const; // on-screen movement export const EASE_DRAWER = [0.32, 0.72, 0, 1] as const; // panels / accordions /* Springs — soft & momentum-rich so motion has life, never mechanical. */ export const SPRING = { /* magnetic buttons / pointer pull — loose, lively, slight overshoot */ magnetic: { stiffness: 150, damping: 13, mass: 0.7 } satisfies Transition, /* 3D card tilt — heavier so it floats and settles, never snaps */ tilt: { stiffness: 110, damping: 14, mass: 0.9 } satisfies Transition, /* cursor ring — trails the pointer with visible lag (the "alive" feel) */ cursorRing: { stiffness: 220, damping: 24, mass: 0.7 } satisfies Transition, /* cursor dot — tighter so it leads, ring chases it */ cursorDot: { stiffness: 600, damping: 34, mass: 0.5 } satisfies Transition, /* generic decorative drift */ soft: { stiffness: 120, damping: 18, mass: 0.8 } satisfies Transition, } as const; /* Asymmetric enter/exit: deliberate in (ease-out), snappy out. */ export const ENTER = (duration = 0.9): Transition => ({ duration, ease: EASE_OUT, }); export const EXIT = (duration = 0.22): Transition => ({ duration, ease: EASE_OUT, });