import type { Transition, Variants } from "framer-motion";

/** Premium ease-out curve shared by all motion. */
export const EASE_OUT = [0.22, 1, 0.36, 1] as const;

/** Base transition for reveal-style animations. */
export const baseTransition: Transition = {
  duration: 0.25,
  ease: EASE_OUT,
};

/**
 * Fade + lift in. `visible` is a function variant so callers can pass a
 * per-item delay via `custom` (defaults to 0, e.g. when driven by a
 * stagger container).
 */
export const fadeInUp: Variants = {
  hidden: { opacity: 0, y: 16 },
  visible: (delay: number = 0) => ({
    opacity: 1,
    y: 0,
    transition: { ...baseTransition, delay },
  }),
};

/** Fade + subtle scale in (cards, popovers). */
export const scaleIn: Variants = {
  hidden: { opacity: 0, scale: 0.96 },
  visible: (delay: number = 0) => ({
    opacity: 1,
    scale: 1,
    transition: { ...baseTransition, delay },
  }),
};

/** Parent container that staggers its children's `visible` state. */
export const staggerContainer: Variants = {
  hidden: {},
  visible: {
    transition: { staggerChildren: 0.06, delayChildren: 0.02 },
  },
};

/**
 * Route enter/exit transition used with AnimatePresence (mode="wait"). The old
 * page is removed instantly (exit duration 0) so it never lingers as a ghost
 * frame behind the incoming page; only the new page animates, fading in. This
 * keeps a visible transition without any cross-fade overlap.
 */
export const pageTransition: Variants = {
  initial: { opacity: 0 },
  enter: { opacity: 1, transition: { duration: 0.22, ease: EASE_OUT } },
  exit: { opacity: 0, transition: { duration: 0 } },
};

/** Springy hover lift for cards. Use rest/hover states on an `m` element. */
export const cardHover: Variants = {
  rest: { y: 0 },
  hover: {
    y: -4,
    transition: { type: "spring", stiffness: 380, damping: 26 },
  },
};
