{"$schema":"https://ui.shadcn.com/schema/registry-item.json","name":"scroll-reveal","type":"registry:component","title":"Scroll Animation Scroll Reveal","description":"Reveals its children with a spring slide and blur as they enter the viewport, once or every time. Reduced-motion keeps a fade.","author":"Saurabh <saurabh10102@gmail.com>","dependencies":["clsx","motion","tailwind-merge"],"registryDependencies":[],"files":[{"path":"components/motion/scroll-reveal.tsx","type":"registry:component","target":"@components/motion/scroll-reveal.tsx","content":"\"use client\";\n// beui.dev/components/motion/scroll-animation\n\nimport { motion, useInView, useReducedMotion } from \"motion/react\";\nimport { type ReactNode, type RefObject, useRef } from \"react\";\n\nimport { EASE_OUT } from \"@/lib/ease\";\nimport { cn } from \"@/lib/utils\";\n\nexport interface ScrollRevealProps {\n  children: ReactNode;\n  /** Slide distance in px before reveal. */\n  y?: number;\n  /** Enter blur in px (kept ≤ 10 per motion conventions). */\n  blur?: number;\n  /** Reveal duration in seconds. */\n  duration?: number;\n  delay?: number;\n  /** Reveal only once (default) or every time it enters view. */\n  once?: boolean;\n  /** Portion of the element that must be visible to trigger. */\n  amount?: \"some\" | \"all\" | number;\n  /** Scroll root for contained scroll areas. Defaults to the viewport. */\n  root?: RefObject<Element | null>;\n  className?: string;\n}\n\nexport function ScrollReveal({\n  children,\n  y = 16,\n  blur = 8,\n  duration = 0.6,\n  delay = 0,\n  once = true,\n  amount = 0.3,\n  root,\n  className,\n}: ScrollRevealProps) {\n  const reduce = useReducedMotion();\n  const ref = useRef<HTMLDivElement>(null);\n  const inView = useInView(ref, { root, once, amount });\n\n  const hidden = reduce\n    ? { opacity: 0 }\n    : { opacity: 0, y, filter: `blur(${blur}px)` };\n  const shown = reduce\n    ? { opacity: 1 }\n    : { opacity: 1, y: 0, filter: \"blur(0px)\" };\n\n  return (\n    <motion.div\n      ref={ref}\n      initial={hidden}\n      animate={inView ? shown : hidden}\n      transition={{ duration, ease: EASE_OUT, delay }}\n      className={cn(className)}\n    >\n      {children}\n    </motion.div>\n  );\n}\n"},{"path":"lib/ease.ts","type":"registry:lib","target":"@lib/ease.ts","content":"// Shared motion tokens. Easing curves mirror the CSS custom properties in\n// globals.css; springs are the canonical physics used across components.\n// Strong custom variants — defaults like `ease-in`/`ease-out` feel weak.\n\nexport const EASE_OUT = [0.16, 1, 0.3, 1] as const;\n/** Accelerating curve for things that fall (a dropped ball, a toppled block). Not for UI entrances. */\nexport const EASE_IN = [0.55, 0, 1, 0.45] as const;\nexport const EASE_IN_OUT = [0.77, 0, 0.175, 1] as const;\nexport const EASE_DRAWER = [0.32, 0.72, 0, 1] as const;\n\n/** CSS string form of EASE_OUT for inline style transitions. */\nexport const EASE_OUT_CSS = \"cubic-bezier(0.16, 1, 0.3, 1)\";\n\n/** Press feedback on buttons and other tappable surfaces. */\nexport const SPRING_PRESS = {\n  type: \"spring\",\n  stiffness: 500,\n  damping: 30,\n  mass: 0.6,\n} as const;\n\n/** Content swaps — label/icon slots trading places inside a control. */\nexport const SPRING_SWAP = {\n  type: \"spring\",\n  stiffness: 460,\n  damping: 30,\n  mass: 0.55,\n} as const;\n\n/** Overlay panel entrances — modals and sheets summoned by pointer. */\nexport const SPRING_PANEL = {\n  type: \"spring\",\n  stiffness: 420,\n  damping: 40,\n  mass: 0.5,\n} as const;\n\n/** Shared-layout glides — pills, indicators and panels morphing between positions. */\nexport const SPRING_LAYOUT = {\n  type: \"spring\",\n  stiffness: 360,\n  damping: 32,\n  mass: 0.6,\n} as const;\n\n/** Cursor-follow physics for decorative mouse tracking (magnetic, tilt, dock). */\nexport const SPRING_MOUSE = {\n  stiffness: 200,\n  damping: 15,\n  mass: 0.3,\n} as const;\n\n/** Dragged handles and fills (sliders) — critically damped `useSpring` config,\n * so the value follows the pointer butterily and never rebounds off an end. */\nexport const SPRING_GLIDE = {\n  stiffness: 700,\n  damping: 50,\n  mass: 0.5,\n} as const;\n"},{"path":"lib/utils.ts","type":"registry:lib","target":"@lib/utils.ts","content":"import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n"}]}