{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "eye-tracking",
  "type": "registry:ui",
  "title": "Eye Tracking",
  "dependencies": [],
  "devDependencies": [],
  "registryDependencies": [],
  "description": "Component for eye-tracking",
  "files": [
    {
      "path": "components/ui/eye-tracking.tsx",
      "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { motion, useMotionValue, useSpring, useTransform } from \"framer-motion\"\nimport { cn } from \"@/lib/utils\"\n\ninterface EyeTrackingProps {\n  /** Additional CSS classes */\n  className?: string\n  /** Size of each eye in pixels */\n  eyeSize?: number\n  /** Gap between eyes in pixels */\n  gap?: number\n  /** Color of the iris */\n  irisColor?: string\n  /** Secondary iris color for gradient */\n  irisColorSecondary?: string\n  /** Pupil color */\n  pupilColor?: string\n  /** Sclera (white) color */\n  scleraColor?: string\n  /** How far the pupil can travel (0-1) */\n  pupilRange?: number\n  /** Enable the reflection/glint effect */\n  showReflection?: boolean\n  /** Enable iris detail pattern */\n  showIrisDetail?: boolean\n  /** Enable subtle idle animation when cursor is away */\n  idleAnimation?: boolean\n  /** Blink interval in milliseconds (0 to disable) */\n  blinkInterval?: number\n  /** Number of eyes */\n  eyeCount?: number\n  /** Variant style */\n  variant?: \"realistic\" | \"cartoon\" | \"minimal\" | \"cyber\"\n  /** Enable reactive pupil dilation */\n  reactivePupil?: boolean\n  /** Eyelid visibility */\n  showEyelids?: boolean\n}\n\ninterface EyeProps {\n  eyeSize: number\n  irisColor: string\n  irisColorSecondary: string\n  pupilColor: string\n  scleraColor: string\n  pupilRange: number\n  showReflection: boolean\n  showIrisDetail: boolean\n  blinkInterval: number\n  variant: \"realistic\" | \"cartoon\" | \"minimal\" | \"cyber\"\n  reactivePupil: boolean\n  showEyelids: boolean\n  mouseX: React.MutableRefObject<number>\n  mouseY: React.MutableRefObject<number>\n  index: number\n}\n\nfunction Eye({\n  eyeSize,\n  irisColor,\n  irisColorSecondary,\n  pupilColor,\n  scleraColor,\n  pupilRange,\n  showReflection,\n  showIrisDetail,\n  blinkInterval,\n  variant,\n  reactivePupil,\n  showEyelids,\n  mouseX,\n  mouseY,\n  index,\n}: EyeProps) {\n  const eyeRef = React.useRef<HTMLDivElement>(null)\n  const [isBlinking, setIsBlinking] = React.useState(false)\n  const [pupilScale, setPupilScale] = React.useState(1)\n\n  const x = useMotionValue(0)\n  const y = useMotionValue(0)\n  const springX = useSpring(x, { stiffness: 300, damping: 25, mass: 0.5 })\n  const springY = useSpring(y, { stiffness: 300, damping: 25, mass: 0.5 })\n\n  const irisSize = eyeSize * 0.45\n  const pupilSize = irisSize * 0.5\n  const maxOffset = (eyeSize / 2 - irisSize / 2) * pupilRange\n\n  // Blink animation\n  React.useEffect(() => {\n    if (blinkInterval <= 0) return\n\n    const blink = () => {\n      setIsBlinking(true)\n      setTimeout(() => setIsBlinking(false), 150)\n    }\n\n    // Random offset per eye so they don't all blink at the exact same time\n    const randomOffset = Math.random() * 200\n    const timeout = setTimeout(() => {\n      blink()\n      const interval = setInterval(blink, blinkInterval + Math.random() * 1000)\n      return () => clearInterval(interval)\n    }, randomOffset)\n\n    const interval = setInterval(blink, blinkInterval + Math.random() * 1000)\n    return () => {\n      clearTimeout(timeout)\n      clearInterval(interval)\n    }\n  }, [blinkInterval])\n\n  // Track mouse position and update pupil\n  React.useEffect(() => {\n    let animFrame: number\n\n    const update = () => {\n      if (!eyeRef.current) {\n        animFrame = requestAnimationFrame(update)\n        return\n      }\n\n      const rect = eyeRef.current.getBoundingClientRect()\n      const eyeCenterX = rect.left + rect.width / 2\n      const eyeCenterY = rect.top + rect.height / 2\n\n      const dx = mouseX.current - eyeCenterX\n      const dy = mouseY.current - eyeCenterY\n      const distance = Math.sqrt(dx * dx + dy * dy)\n      const angle = Math.atan2(dy, dx)\n\n      const clampedDistance = Math.min(distance, maxOffset * 3)\n      const normalizedDistance = clampedDistance / (maxOffset * 3)\n      const offset = normalizedDistance * maxOffset\n\n      x.set(Math.cos(angle) * offset)\n      y.set(Math.sin(angle) * offset)\n\n      // Reactive pupil dilation based on distance\n      if (reactivePupil) {\n        const proximityScale = distance < 200 ? 1.3 - (distance / 200) * 0.3 : 0.85 + (Math.min(distance, 800) / 800) * 0.15\n        setPupilScale(proximityScale)\n      }\n\n      animFrame = requestAnimationFrame(update)\n    }\n\n    animFrame = requestAnimationFrame(update)\n    return () => cancelAnimationFrame(animFrame)\n  }, [x, y, maxOffset, reactivePupil, mouseX, mouseY])\n\n  // Rotation transform for iris detail\n  const irisRotation = useTransform(springX, [-maxOffset, maxOffset], [-15, 15])\n\n  const eyeAspect = variant === \"cartoon\" ? 1 : 0.85\n  const borderRadius = variant === \"minimal\" ? \"50%\" : variant === \"cartoon\" ? \"50%\" : \"50%\"\n\n  const scleraGradient =\n    variant === \"realistic\"\n      ? `radial-gradient(circle at 35% 35%, ${scleraColor} 0%, ${scleraColor}ee 60%, ${scleraColor}cc 100%)`\n      : variant === \"cyber\"\n        ? `radial-gradient(circle at 50% 50%, #0a0a1a 0%, #111128 100%)`\n        : scleraColor\n\n  const eyeWidth = eyeSize\n  const eyeHeight = eyeSize * eyeAspect\n\n  return (\n    <motion.div\n      ref={eyeRef}\n      className={cn(\n        \"relative overflow-hidden\",\n        variant === \"cyber\" && \"border border-cyan-500/30\"\n      )}\n      style={{\n        width: eyeWidth,\n        height: eyeHeight,\n        borderRadius,\n        background: scleraGradient,\n        boxShadow:\n          variant === \"realistic\"\n            ? \"inset 0 2px 8px rgba(0,0,0,0.15), inset 0 -1px 4px rgba(0,0,0,0.05), 0 4px 20px rgba(0,0,0,0.1)\"\n            : variant === \"cyber\"\n              ? \"inset 0 0 30px rgba(0,200,255,0.1), 0 0 20px rgba(0,200,255,0.15)\"\n              : variant === \"cartoon\"\n                ? \"inset 0 4px 12px rgba(0,0,0,0.1), 0 6px 24px rgba(0,0,0,0.15)\"\n                : \"0 2px 10px rgba(0,0,0,0.1)\",\n      }}\n      animate={{\n        scaleY: isBlinking ? 0.05 : 1,\n      }}\n      transition={{\n        scaleY: { duration: 0.1, ease: \"easeInOut\" },\n      }}\n    >\n      {/* Blood vessel details for realistic variant */}\n      {variant === \"realistic\" && (\n        <div className=\"absolute inset-0 overflow-hidden rounded-full opacity-[0.07]\">\n          {[...Array(6)].map((_, i) => (\n            <div\n              key={i}\n              className=\"absolute bg-red-500\"\n              style={{\n                width: \"1px\",\n                height: eyeSize * 0.4,\n                left: `${20 + i * 12}%`,\n                top: `${10 + (i % 3) * 15}%`,\n                transform: `rotate(${-30 + i * 20}deg)`,\n                opacity: 0.3 + Math.random() * 0.4,\n              }}\n            />\n          ))}\n        </div>\n      )}\n\n      {/* Iris */}\n      <motion.div\n        className=\"absolute\"\n        style={{\n          width: irisSize,\n          height: irisSize,\n          borderRadius: \"50%\",\n          left: eyeWidth / 2 - irisSize / 2,\n          top: eyeHeight / 2 - irisSize / 2,\n          x: springX,\n          y: springY,\n          background:\n            variant === \"cyber\"\n              ? `conic-gradient(from 0deg, ${irisColor}, ${irisColorSecondary}, ${irisColor})`\n              : `radial-gradient(circle at 40% 40%, ${irisColorSecondary}, ${irisColor} 60%, ${irisColor}dd 100%)`,\n          boxShadow:\n            variant === \"realistic\"\n              ? `inset 0 2px 6px rgba(0,0,0,0.3), 0 0 0 1px rgba(0,0,0,0.1)`\n              : variant === \"cyber\"\n                ? `0 0 15px ${irisColor}66, inset 0 0 10px ${irisColor}33`\n                : `inset 0 1px 4px rgba(0,0,0,0.2)`,\n        }}\n      >\n        {/* Iris detail pattern */}\n        {showIrisDetail && (\n          <motion.div\n            className=\"absolute inset-0 rounded-full overflow-hidden\"\n            style={{ rotate: irisRotation }}\n          >\n            {variant === \"cyber\" ? (\n              // Cyber circuit pattern\n              <>\n                <div\n                  className=\"absolute inset-[15%] rounded-full border border-dashed opacity-40\"\n                  style={{ borderColor: irisColor }}\n                />\n                <div\n                  className=\"absolute inset-[30%] rounded-full border opacity-30\"\n                  style={{ borderColor: irisColorSecondary }}\n                />\n                {[...Array(8)].map((_, i) => (\n                  <div\n                    key={i}\n                    className=\"absolute left-1/2 top-1/2 origin-left opacity-25\"\n                    style={{\n                      width: irisSize * 0.45,\n                      height: \"1px\",\n                      background: irisColor,\n                      transform: `rotate(${i * 45}deg)`,\n                    }}\n                  />\n                ))}\n              </>\n            ) : (\n              // Realistic iris fibers\n              <>\n                {[...Array(24)].map((_, i) => (\n                  <div\n                    key={i}\n                    className=\"absolute left-1/2 top-1/2 origin-left\"\n                    style={{\n                      width: irisSize * 0.45,\n                      height: \"1px\",\n                      background: `linear-gradient(to right, transparent 20%, ${irisColor}44 50%, transparent 80%)`,\n                      transform: `rotate(${i * 15}deg)`,\n                      opacity: 0.3 + (i % 3) * 0.15,\n                    }}\n                  />\n                ))}\n                <div\n                  className=\"absolute inset-[20%] rounded-full\"\n                  style={{\n                    border: `1px solid ${irisColor}33`,\n                  }}\n                />\n              </>\n            )}\n          </motion.div>\n        )}\n\n        {/* Pupil */}\n        <motion.div\n          className=\"absolute rounded-full\"\n          style={{\n            width: pupilSize,\n            height: pupilSize,\n            left: irisSize / 2 - pupilSize / 2,\n            top: irisSize / 2 - pupilSize / 2,\n            background:\n              variant === \"cyber\"\n                ? `radial-gradient(circle, ${pupilColor} 40%, transparent 100%)`\n                : pupilColor,\n            boxShadow:\n              variant === \"cyber\"\n                ? `0 0 10px ${irisColor}88`\n                : undefined,\n          }}\n          animate={{\n            scale: reactivePupil ? pupilScale : 1,\n          }}\n          transition={{ duration: 0.3, ease: \"easeOut\" }}\n        />\n\n        {/* Primary light reflection */}\n        {showReflection && (\n          <>\n            <div\n              className=\"absolute rounded-full\"\n              style={{\n                width: pupilSize * 0.35,\n                height: pupilSize * 0.35,\n                left: irisSize * 0.3,\n                top: irisSize * 0.25,\n                background:\n                  variant === \"cyber\"\n                    ? `radial-gradient(circle, rgba(0,255,255,0.9), transparent)`\n                    : \"radial-gradient(circle, rgba(255,255,255,0.95), rgba(255,255,255,0.6))\",\n                filter: \"blur(0.5px)\",\n              }}\n            />\n            {/* Secondary smaller reflection */}\n            <div\n              className=\"absolute rounded-full\"\n              style={{\n                width: pupilSize * 0.15,\n                height: pupilSize * 0.15,\n                left: irisSize * 0.58,\n                top: irisSize * 0.6,\n                background:\n                  variant === \"cyber\"\n                    ? \"rgba(0,255,255,0.5)\"\n                    : \"rgba(255,255,255,0.7)\",\n              }}\n            />\n          </>\n        )}\n      </motion.div>\n\n      {/* Top eyelid shadow */}\n      {showEyelids && variant !== \"minimal\" && (\n        <>\n          <div\n            className=\"pointer-events-none absolute inset-x-0 top-0\"\n            style={{\n              height: eyeHeight * 0.35,\n              background:\n                variant === \"cyber\"\n                  ? \"linear-gradient(to bottom, rgba(0,10,30,0.6) 0%, transparent 100%)\"\n                  : \"linear-gradient(to bottom, rgba(0,0,0,0.08) 0%, transparent 100%)\",\n              borderRadius: \"50% 50% 0 0\",\n            }}\n          />\n          <div\n            className=\"pointer-events-none absolute inset-x-0 bottom-0\"\n            style={{\n              height: eyeHeight * 0.2,\n              background:\n                variant === \"cyber\"\n                  ? \"linear-gradient(to top, rgba(0,10,30,0.4) 0%, transparent 100%)\"\n                  : \"linear-gradient(to top, rgba(0,0,0,0.04) 0%, transparent 100%)\",\n              borderRadius: \"0 0 50% 50%\",\n            }}\n          />\n        </>\n      )}\n\n      {/* Cyber scan line */}\n      {variant === \"cyber\" && (\n        <motion.div\n          className=\"pointer-events-none absolute inset-x-0 h-[2px]\"\n          style={{\n            background: `linear-gradient(to right, transparent, ${irisColor}44, transparent)`,\n          }}\n          animate={{\n            top: [0, eyeHeight, 0],\n          }}\n          transition={{\n            duration: 3,\n            repeat: Infinity,\n            ease: \"linear\",\n          }}\n        />\n      )}\n    </motion.div>\n  )\n}\n\nexport function EyeTracking({\n  className,\n  eyeSize = 120,\n  gap = 40,\n  irisColor = \"#4A6741\",\n  irisColorSecondary = \"#6B8F62\",\n  pupilColor = \"#0a0a0a\",\n  scleraColor = \"#F5F0EB\",\n  pupilRange = 0.7,\n  showReflection = true,\n  showIrisDetail = true,\n  idleAnimation = true,\n  blinkInterval = 4000,\n  eyeCount = 2,\n  variant = \"realistic\",\n  reactivePupil = true,\n  showEyelids = true,\n}: EyeTrackingProps) {\n  const mouseX = React.useRef(typeof window !== \"undefined\" ? window.innerWidth / 2 : 0)\n  const mouseY = React.useRef(typeof window !== \"undefined\" ? window.innerHeight / 2 : 0)\n  const [isMounted, setIsMounted] = React.useState(false)\n\n  // Default colors per variant\n  const resolvedIrisColor =\n    variant === \"cyber\" ? (irisColor === \"#4A6741\" ? \"#00d4ff\" : irisColor) : irisColor\n  const resolvedIrisSecondary =\n    variant === \"cyber\"\n      ? irisColorSecondary === \"#6B8F62\"\n        ? \"#0088ff\"\n        : irisColorSecondary\n      : irisColorSecondary\n  const resolvedPupilColor =\n    variant === \"cyber\" ? (pupilColor === \"#0a0a0a\" ? \"#001122\" : pupilColor) : pupilColor\n  const resolvedScleraColor =\n    variant === \"cyber\" ? (scleraColor === \"#F5F0EB\" ? \"#0a0a1a\" : scleraColor) : scleraColor\n\n  React.useEffect(() => {\n    setIsMounted(true)\n  }, [])\n\n  // Global mouse tracker\n  React.useEffect(() => {\n    const handleMouseMove = (e: MouseEvent) => {\n      mouseX.current = e.clientX\n      mouseY.current = e.clientY\n    }\n\n    const handleTouchMove = (e: TouchEvent) => {\n      if (e.touches[0]) {\n        mouseX.current = e.touches[0].clientX\n        mouseY.current = e.touches[0].clientY\n      }\n    }\n\n    window.addEventListener(\"mousemove\", handleMouseMove, { passive: true })\n    window.addEventListener(\"touchmove\", handleTouchMove, { passive: true })\n    return () => {\n      window.removeEventListener(\"mousemove\", handleMouseMove)\n      window.removeEventListener(\"touchmove\", handleTouchMove)\n    }\n  }, [])\n\n  // Idle animation - subtle random eye movement when no cursor activity\n  React.useEffect(() => {\n    if (!idleAnimation) return\n\n    let idleTimeout: ReturnType<typeof setTimeout>\n    let idleInterval: ReturnType<typeof setInterval>\n    let lastX = mouseX.current\n    let lastY = mouseY.current\n\n    const checkIdle = () => {\n      if (mouseX.current === lastX && mouseY.current === lastY) {\n        // Start idle micro-movements\n        idleInterval = setInterval(() => {\n          const currentX = mouseX.current\n          const currentY = mouseY.current\n          mouseX.current = currentX + (Math.random() - 0.5) * 30\n          mouseY.current = currentY + (Math.random() - 0.5) * 30\n          // Restore after brief moment\n          setTimeout(() => {\n            mouseX.current = currentX\n            mouseY.current = currentY\n          }, 500)\n        }, 2000)\n      }\n      lastX = mouseX.current\n      lastY = mouseY.current\n    }\n\n    idleTimeout = setInterval(checkIdle, 3000)\n\n    return () => {\n      clearInterval(idleTimeout)\n      clearInterval(idleInterval)\n    }\n  }, [idleAnimation])\n\n  if (!isMounted) {\n    return (\n      <div\n        className={cn(\"flex items-center justify-center\", className)}\n        style={{ gap }}\n      >\n        {[...Array(eyeCount)].map((_, i) => (\n          <div\n            key={i}\n            className=\"rounded-full bg-neutral-200 dark:bg-neutral-800\"\n            style={{ width: eyeSize, height: eyeSize * 0.85 }}\n          />\n        ))}\n      </div>\n    )\n  }\n\n  return (\n    <div\n      className={cn(\"flex items-center justify-center\", className)}\n      style={{ gap }}\n    >\n      {[...Array(eyeCount)].map((_, i) => (\n        <Eye\n          key={i}\n          index={i}\n          eyeSize={eyeSize}\n          irisColor={resolvedIrisColor}\n          irisColorSecondary={resolvedIrisSecondary}\n          pupilColor={resolvedPupilColor}\n          scleraColor={resolvedScleraColor}\n          pupilRange={pupilRange}\n          showReflection={showReflection}\n          showIrisDetail={showIrisDetail}\n          blinkInterval={blinkInterval}\n          variant={variant}\n          reactivePupil={reactivePupil}\n          showEyelids={showEyelids}\n          mouseX={mouseX}\n          mouseY={mouseY}\n        />\n      ))}\n    </div>\n  )\n}\n",
      "type": "registry:ui"
    }
  ]
}