{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "customer-experience",
  "dependencies": [
    "motion"
  ],
  "devDependencies": [],
  "registryDependencies": [],
  "files": [
    {
      "path": "../../packages/blocks/src/experience-section/customer-experience.tsx",
      "content": "'use client'\r\n\r\nimport { motion, useSpring } from 'motion/react'\r\nimport React, { useState, MouseEvent, useRef } from 'react'\r\n\r\ninterface ImageItem {\r\n  img: string\r\n  label: string\r\n  title: string\r\n  description: string\r\n}\r\nconst list: ImageItem[] = [\r\n  {\r\n    img: 'https://images.unsplash.com/photo-1682806816936-c3ac11f65112?q=80&w=1274&auto=format&fit=crop',\r\n    label: 'Urban Landscapes',\r\n    title: 'City Photography',\r\n    description:\r\n      'A visual exploration of modern architectural wonders, iconic city skylines, and the rhythm of urban life captured through bold compositions.',\r\n  },\r\n  {\r\n    img: 'https://images.unsplash.com/photo-1681063762354-d542c03bbfc5?q=80&w=1274&auto=format&fit=crop',\r\n    label: 'Nature Portraits',\r\n    title: 'Outdoor Photography',\r\n    description:\r\n      'Intimate moments of wildlife in their natural habitat, showcasing raw beauty, movement, and the quiet balance of the outdoors.',\r\n  },\r\n  {\r\n    img: 'https://images.unsplash.com/photo-1679640034489-a6db1f096b70?q=80&w=1274&auto=format&fit=crop',\r\n    label: 'Abstract Art',\r\n    title: 'Creative Photography',\r\n    description:\r\n      'Contemporary artistic expressions that blend color, texture, and form to create visually striking and thought-provoking compositions.',\r\n  },\r\n  {\r\n    img: 'https://images.unsplash.com/photo-1679482451632-b2e126da7142?q=80&w=1274&auto=format&fit=crop',\r\n    label: 'Fashion Editorial',\r\n    title: 'Style Photography',\r\n    description:\r\n      'High-fashion editorials highlighting runway trends, expressive styling, and editorial storytelling through bold visuals.',\r\n  },\r\n\r\n  {\r\n    img: 'https://images.unsplash.com/photo-1682686580024-580519d4b2d2?q=80&w=1274&auto=format&fit=crop',\r\n    label: 'Minimal Spaces',\r\n    title: 'Interior Photography',\r\n    description:\r\n      'Calm and intentional interior scenes that focus on light, texture, and spatial balance, capturing the beauty of simplicity.',\r\n  },\r\n  {\r\n    img: 'https://images.unsplash.com/photo-1683009427042-e094996f9780?q=80&w=1274&auto=format&fit=crop',\r\n    label: 'Portrait Studies',\r\n    title: 'Human Expression',\r\n    description:\r\n      'Expressive portraits that highlight emotion, personality, and subtle storytelling through light, framing, and composition.',\r\n  },\r\n  {\r\n    img: 'https://images.unsplash.com/photo-1768248855015-36e55c07ae98?q=80&w=687&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',\r\n    label: 'Motion & Speed',\r\n    title: 'Action Photography',\r\n    description:\r\n      'Dynamic captures of movement and energy, freezing fast-paced moments while preserving a strong sense of momentum.',\r\n  },\r\n  {\r\n    img: 'https://images.unsplash.com/photo-1769251845951-c271e703f047?q=80&w=687&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',\r\n    label: 'Aerial Perspectives',\r\n    title: 'Drone Photography',\r\n    description:\r\n      'Unique top-down viewpoints revealing patterns, scale, and geometry that are often hidden from ground level.',\r\n  },\r\n]\r\n\r\nexport function CustomerExperience() {\r\n  const [img, setImg] = useState<{ src: string; alt: string; opacity: number }>(\r\n    {\r\n      src: '',\r\n      alt: '',\r\n      opacity: 0,\r\n    }\r\n  )\r\n\r\n  const imageRef = useRef<HTMLImageElement>(null)\r\n  const containerRef = useRef<HTMLDivElement>(null)\r\n\r\n  const spring = {\r\n    stiffness: 150,\r\n    damping: 15,\r\n    mass: 0.1,\r\n  }\r\n\r\n  const imagePos = {\r\n    x: useSpring(0, spring),\r\n    y: useSpring(0, spring),\r\n  }\r\n\r\n  const handleMove = (e: MouseEvent<HTMLDivElement>) => {\r\n    if (!imageRef.current || !containerRef.current) return\r\n\r\n    const containerRect = containerRef.current.getBoundingClientRect()\r\n    const { clientX, clientY } = e\r\n    const relativeX = clientX - containerRect.left\r\n    const relativeY = clientY - containerRect.top\r\n\r\n    imagePos.x.set(relativeX - imageRef.current.offsetWidth / 2)\r\n    imagePos.y.set(relativeY - imageRef.current.offsetHeight / 2)\r\n  }\r\n\r\n  const handleImageInteraction = (item: ImageItem, opacity: number) => {\r\n    setImg({ src: item.img, alt: item.label, opacity })\r\n  }\r\n\r\n  return (\r\n    <section className=\"bg-orange-200 font-manrope overflow-x-hidden\">\r\n      <div\r\n        ref={containerRef}\r\n        onMouseMove={handleMove}\r\n        className=\"relative max-w-6xl mx-auto border-x border-orange-500\"\r\n      >\r\n        <h1 className=\"lg:text-9xl sm:text-8xl px-5 text-7xl border-b border-orange-500 font-bold py-10 text-orange-500 font-spaceGrotesk\">\r\n          EXPERIENCE\r\n        </h1>\r\n        {list.map((item) => (\r\n          <div\r\n            key={item.label}\r\n            onMouseEnter={() => handleImageInteraction(item, 1)}\r\n            onMouseMove={() => handleImageInteraction(item, 1)}\r\n            onMouseLeave={() => handleImageInteraction(item, 0)}\r\n            className=\"w-full py-5 px-5 cursor-pointer relative text-center md:flex justify-between items-center text-primary border-b border-orange-500 last:border-none\"\r\n          >\r\n            <div className=\"flex gap-2 items-center\">\r\n              <svg\r\n                xmlns=\"http://www.w3.org/2000/svg\"\r\n                viewBox=\"0 0 24 24\"\r\n                className=\"w-14 h-14 text-orange-500\"\r\n                fill=\"none\"\r\n                stroke=\"currentColor\"\r\n                stroke-width=\"2\"\r\n              >\r\n                <path d=\"M9 17.3497C9 17.3497 15.9383 17.8924 16.9154 16.9154C17.8924 15.9383 17.3496 9 17.3496 9M16.5 16.5L6.5 6.5\" />\r\n              </svg>\r\n              <div className=\"flex flex-col items-start\">\r\n                <h2 className=\"lg:text-4xl text-xl font-bold\">{item.label}</h2>\r\n                <span>{item?.title}</span>\r\n              </div>\r\n            </div>\r\n            <p className=\"xl:max-w-xl md:max-w-96 ml-auto text-right md:pt-0 pt-5\">\r\n              {item.description}{' '}\r\n            </p>\r\n          </div>\r\n        ))}\r\n\r\n        <motion.img\r\n          ref={imageRef}\r\n          src={img.src}\r\n          alt={img.alt}\r\n          className=\"w-[300px] h-[220px] rounded-lg object-cover absolute top-0 left-0 transition-opacity duration-200 ease-in-out pointer-events-none\"\r\n          style={{\r\n            x: imagePos.x,\r\n            y: imagePos.y,\r\n            opacity: img.opacity,\r\n          }}\r\n        />\r\n      </div>\r\n    </section>\r\n  )\r\n}\r\n",
      "type": "registry:block"
    },
    {
      "path": "./components/ui/timeline-animation.tsx",
      "content": "import type { Variants } from 'motion/react';\nimport { type HTMLMotionProps, motion, useInView } from 'motion/react';\nimport type React from 'react';\n\ntype TimelineContentProps<T extends keyof HTMLElementTagNameMap> = {\n  children?: React.ReactNode;\n  animationNum: number;\n  className?: string;\n  timelineRef: React.RefObject<HTMLElement | null>;\n  as?: T;\n  customVariants?: Variants;\n  once?: boolean;\n} & HTMLMotionProps<T>;\n\nexport const TimelineAnimation = <T extends keyof HTMLElementTagNameMap = 'div'>({\n  children,\n  animationNum,\n  timelineRef,\n  className,\n  as,\n  customVariants,\n  once = true,\n  ...props\n}: TimelineContentProps<T>) => {\n  const defaultSequenceVariants = {\n    visible: (i: number) => ({\n      filter: 'blur(0px)',\n      y: 0,\n      opacity: 1,\n      transition: {\n        delay: i * 0.5,\n        duration: 0.5,\n      },\n    }),\n    hidden: {\n      filter: 'blur(20px)',\n      y: 0,\n      opacity: 0,\n    },\n  };\n\n  const sequenceVariants = customVariants || defaultSequenceVariants;\n\n  const isInView = useInView(timelineRef, {\n    once,\n  });\n\n  const MotionComponent = motion[as || 'div'] as React.ElementType;\n\n  return (\n    <MotionComponent\n      initial='hidden'\n      animate={isInView ? 'visible' : 'hidden'}\n      custom={animationNum}\n      variants={sequenceVariants}\n      className={className}\n      {...props}\n    >\n      {children}\n    </MotionComponent>\n  );\n};\n",
      "type": "registry:component"
    }
  ],
  "type": "registry:block"
}