{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "location-map",
  "title": "Location Map",
  "description": "An interactive 3D-tilting location card with expandable animated map, live indicator, and motion-based hover effects.",
  "dependencies": [
    "react",
    "motion"
  ],
  "files": [
    {
      "path": "registry/gammaui/location-map.tsx",
      "content": "\"use client\"\n\nimport type React from \"react\"\nimport { useRef, useState } from \"react\"\nimport {\n  AnimatePresence,\n  motion,\n  useMotionValue,\n  useSpring,\n  useTransform,\n} from \"motion/react\"\n\ninterface LocationMapProps {\n  location?: string\n  coordinates?: string\n  className?: string\n}\n\nexport function LocationMap({\n  location = \"San Francisco, CA\",\n  coordinates = \"37.7749° N, 122.4194° W\",\n  className,\n}: LocationMapProps) {\n  const [isHovered, setIsHovered] = useState(false)\n  const [isExpanded, setIsExpanded] = useState(false)\n  const containerRef = useRef<HTMLDivElement>(null)\n\n  const mouseX = useMotionValue(0)\n  const mouseY = useMotionValue(0)\n\n  const rotateX = useTransform(mouseY, [-50, 50], [8, -8])\n  const rotateY = useTransform(mouseX, [-50, 50], [-8, 8])\n\n  const springRotateX = useSpring(rotateX, { stiffness: 300, damping: 30 })\n  const springRotateY = useSpring(rotateY, { stiffness: 300, damping: 30 })\n\n  const handleMouseMove = (e: React.MouseEvent) => {\n    if (!containerRef.current) return\n    const rect = containerRef.current.getBoundingClientRect()\n    const centerX = rect.left + rect.width / 2\n    const centerY = rect.top + rect.height / 2\n    mouseX.set(e.clientX - centerX)\n    mouseY.set(e.clientY - centerY)\n  }\n\n  const handleMouseLeave = () => {\n    mouseX.set(0)\n    mouseY.set(0)\n    setIsHovered(false)\n  }\n\n  const handleClick = () => {\n    setIsExpanded(!isExpanded)\n  }\n\n  return (\n    <motion.div\n      ref={containerRef}\n      className={`relative cursor-pointer select-none ${className}`}\n      style={{\n        perspective: 1000,\n      }}\n      onMouseMove={handleMouseMove}\n      onMouseEnter={() => setIsHovered(true)}\n      onMouseLeave={handleMouseLeave}\n      onClick={handleClick}\n    >\n      <motion.div\n        className=\"bg-background border-border relative overflow-hidden rounded-2xl border\"\n        style={{\n          rotateX: springRotateX,\n          rotateY: springRotateY,\n          transformStyle: \"preserve-3d\",\n        }}\n        animate={{\n          width: isExpanded ? 360 : 240,\n          height: isExpanded ? 280 : 140,\n        }}\n        transition={{\n          type: \"spring\",\n          stiffness: 400,\n          damping: 35,\n        }}\n      >\n        {/* Subtle gradient overlay */}\n        <div className=\"from-muted/20 to-muted/40 absolute inset-0 bg-linear-to-br via-transparent\" />\n\n        <AnimatePresence>\n          {isExpanded && (\n            <motion.div\n              className=\"pointer-events-none absolute inset-0\"\n              initial={{ opacity: 0 }}\n              animate={{ opacity: 1 }}\n              exit={{ opacity: 0 }}\n              transition={{ duration: 0.4, delay: 0.1 }}\n            >\n              <div className=\"bg-muted absolute inset-0 rounded-2xl\" />\n\n              <svg\n                className=\"absolute inset-0 h-full w-full\"\n                preserveAspectRatio=\"none\"\n              >\n                {/* Main roads - using foreground with opacity */}\n                <motion.line\n                  x1=\"0%\"\n                  y1=\"35%\"\n                  x2=\"100%\"\n                  y2=\"35%\"\n                  className=\"stroke-foreground/25\"\n                  strokeWidth=\"4\"\n                  initial={{ pathLength: 0 }}\n                  animate={{ pathLength: 1 }}\n                  transition={{ duration: 0.8, delay: 0.2 }}\n                />\n                <motion.line\n                  x1=\"0%\"\n                  y1=\"65%\"\n                  x2=\"100%\"\n                  y2=\"65%\"\n                  className=\"stroke-foreground/25\"\n                  strokeWidth=\"4\"\n                  initial={{ pathLength: 0 }}\n                  animate={{ pathLength: 1 }}\n                  transition={{ duration: 0.8, delay: 0.3 }}\n                />\n\n                {/* Vertical main roads */}\n                <motion.line\n                  x1=\"30%\"\n                  y1=\"0%\"\n                  x2=\"30%\"\n                  y2=\"100%\"\n                  className=\"stroke-foreground/20\"\n                  strokeWidth=\"3\"\n                  initial={{ pathLength: 0 }}\n                  animate={{ pathLength: 1 }}\n                  transition={{ duration: 0.6, delay: 0.4 }}\n                />\n                <motion.line\n                  x1=\"70%\"\n                  y1=\"0%\"\n                  x2=\"70%\"\n                  y2=\"100%\"\n                  className=\"stroke-foreground/20\"\n                  strokeWidth=\"3\"\n                  initial={{ pathLength: 0 }}\n                  animate={{ pathLength: 1 }}\n                  transition={{ duration: 0.6, delay: 0.5 }}\n                />\n\n                {/* Secondary streets */}\n                {[20, 50, 80].map((y, i) => (\n                  <motion.line\n                    key={`h-${i}`}\n                    x1=\"0%\"\n                    y1={`${y}%`}\n                    x2=\"100%\"\n                    y2={`${y}%`}\n                    className=\"stroke-foreground/10\"\n                    strokeWidth=\"1.5\"\n                    initial={{ pathLength: 0 }}\n                    animate={{ pathLength: 1 }}\n                    transition={{ duration: 0.5, delay: 0.6 + i * 0.1 }}\n                  />\n                ))}\n                {[15, 45, 55, 85].map((x, i) => (\n                  <motion.line\n                    key={`v-${i}`}\n                    x1={`${x}%`}\n                    y1=\"0%\"\n                    x2={`${x}%`}\n                    y2=\"100%\"\n                    className=\"stroke-foreground/10\"\n                    strokeWidth=\"1.5\"\n                    initial={{ pathLength: 0 }}\n                    animate={{ pathLength: 1 }}\n                    transition={{ duration: 0.5, delay: 0.7 + i * 0.1 }}\n                  />\n                ))}\n              </svg>\n\n              {/* Buildings - using muted-foreground */}\n              <motion.div\n                className=\"bg-muted-foreground/30 border-muted-foreground/20 absolute top-[40%] left-[10%] h-[20%] w-[15%] rounded-sm border\"\n                initial={{ opacity: 0, scale: 0.8 }}\n                animate={{ opacity: 1, scale: 1 }}\n                transition={{ duration: 0.4, delay: 0.5 }}\n              />\n              <motion.div\n                className=\"bg-muted-foreground/25 border-muted-foreground/15 absolute top-[15%] left-[35%] h-[15%] w-[12%] rounded-sm border\"\n                initial={{ opacity: 0, scale: 0.8 }}\n                animate={{ opacity: 1, scale: 1 }}\n                transition={{ duration: 0.4, delay: 0.6 }}\n              />\n              <motion.div\n                className=\"bg-muted-foreground/28 border-muted-foreground/18 absolute top-[70%] left-[75%] h-[18%] w-[18%] rounded-sm border\"\n                initial={{ opacity: 0, scale: 0.8 }}\n                animate={{ opacity: 1, scale: 1 }}\n                transition={{ duration: 0.4, delay: 0.7 }}\n              />\n              <motion.div\n                className=\"bg-muted-foreground/22 border-muted-foreground/15 absolute top-[20%] right-[10%] h-[25%] w-[10%] rounded-sm border\"\n                initial={{ opacity: 0, scale: 0.8 }}\n                animate={{ opacity: 1, scale: 1 }}\n                transition={{ duration: 0.4, delay: 0.55 }}\n              />\n              <motion.div\n                className=\"bg-muted-foreground/20 border-muted-foreground/12 absolute top-[55%] left-[5%] h-[12%] w-[8%] rounded-sm border\"\n                initial={{ opacity: 0, scale: 0.8 }}\n                animate={{ opacity: 1, scale: 1 }}\n                transition={{ duration: 0.4, delay: 0.65 }}\n              />\n              <motion.div\n                className=\"bg-muted-foreground/22 border-muted-foreground/15 absolute top-[8%] left-[75%] h-[10%] w-[14%] rounded-sm border\"\n                initial={{ opacity: 0, scale: 0.8 }}\n                animate={{ opacity: 1, scale: 1 }}\n                transition={{ duration: 0.4, delay: 0.75 }}\n              />\n\n              <motion.div\n                className=\"absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2\"\n                initial={{ scale: 0, y: -20 }}\n                animate={{ scale: 1, y: 0 }}\n                transition={{\n                  type: \"spring\",\n                  stiffness: 400,\n                  damping: 20,\n                  delay: 0.3,\n                }}\n              >\n                <svg\n                  width=\"32\"\n                  height=\"32\"\n                  viewBox=\"0 0 24 24\"\n                  fill=\"none\"\n                  className=\"drop-shadow-lg\"\n                  style={{\n                    filter: \"drop-shadow(0 0 10px rgba(52, 211, 153, 0.5))\",\n                  }}\n                >\n                  <path\n                    d=\"M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7z\"\n                    fill=\"#34D399\"\n                  />\n                  <circle cx=\"12\" cy=\"9\" r=\"2.5\" className=\"fill-background\" />\n                </svg>\n              </motion.div>\n\n              <div className=\"from-background absolute inset-0 bg-linear-to-t via-transparent to-transparent opacity-60\" />\n            </motion.div>\n          )}\n        </AnimatePresence>\n\n        {/* Grid pattern - only show when collapsed */}\n        <motion.div\n          className=\"absolute inset-0 opacity-[0.03]\"\n          animate={{ opacity: isExpanded ? 0 : 0.03 }}\n          transition={{ duration: 0.3 }}\n        >\n          <svg width=\"100%\" height=\"100%\" className=\"absolute inset-0\">\n            <defs>\n              <pattern\n                id=\"grid\"\n                width=\"20\"\n                height=\"20\"\n                patternUnits=\"userSpaceOnUse\"\n              >\n                <path\n                  d=\"M 20 0 L 0 0 0 20\"\n                  fill=\"none\"\n                  className=\"stroke-foreground\"\n                  strokeWidth=\"0.5\"\n                />\n              </pattern>\n            </defs>\n            <rect width=\"100%\" height=\"100%\" fill=\"url(#grid)\" />\n          </svg>\n        </motion.div>\n\n        {/* Content */}\n        <div className=\"relative z-10 flex h-full flex-col justify-between p-5\">\n          {/* Top section */}\n          <div className=\"flex items-start justify-between\">\n            <div className=\"relative\">\n              <motion.div\n                className=\"relative\"\n                animate={{\n                  opacity: isExpanded ? 0 : 1,\n                }}\n                transition={{ duration: 0.3 }}\n              >\n                {/* Map Icon SVG */}\n                <motion.svg\n                  width=\"18\"\n                  height=\"18\"\n                  viewBox=\"0 0 24 24\"\n                  fill=\"none\"\n                  stroke=\"currentColor\"\n                  strokeWidth=\"2\"\n                  strokeLinecap=\"round\"\n                  strokeLinejoin=\"round\"\n                  className=\"text-emerald-400\"\n                  animate={{\n                    filter: isHovered\n                      ? \"drop-shadow(0 0 8px rgba(52, 211, 153, 0.6))\"\n                      : \"drop-shadow(0 0 4px rgba(52, 211, 153, 0.3))\",\n                  }}\n                  transition={{ duration: 0.3 }}\n                >\n                  <polygon points=\"3 6 9 3 15 6 21 3 21 18 15 21 9 18 3 21\" />\n                  <line x1=\"9\" x2=\"9\" y1=\"3\" y2=\"18\" />\n                  <line x1=\"15\" x2=\"15\" y1=\"6\" y2=\"21\" />\n                </motion.svg>\n              </motion.div>\n            </div>\n\n            {/* Status indicator */}\n            <motion.div\n              className=\"bg-foreground/5 flex items-center gap-1.5 rounded-full px-2 py-1 backdrop-blur-sm\"\n              animate={{\n                scale: isHovered ? 1.05 : 1,\n                backgroundColor: isHovered\n                  ? \"hsl(var(--foreground) / 0.08)\"\n                  : \"hsl(var(--foreground) / 0.05)\",\n              }}\n              transition={{ duration: 0.2 }}\n            >\n              <div className=\"h-1.5 w-1.5 rounded-full bg-emerald-400\" />\n              <span className=\"text-muted-foreground text-[10px] font-medium tracking-wide uppercase\">\n                Live\n              </span>\n            </motion.div>\n          </div>\n\n          {/* Bottom section */}\n          <div className=\"space-y-1\">\n            <motion.h3\n              className=\"text-foreground text-sm font-medium tracking-tight\"\n              animate={{\n                x: isHovered ? 4 : 0,\n              }}\n              transition={{ type: \"spring\", stiffness: 400, damping: 25 }}\n            >\n              {location}\n            </motion.h3>\n\n            <AnimatePresence>\n              {isExpanded && (\n                <motion.p\n                  className=\"text-muted-foreground font-mono text-xs\"\n                  initial={{ opacity: 0, y: -10, height: 0 }}\n                  animate={{ opacity: 1, y: 0, height: \"auto\" }}\n                  exit={{ opacity: 0, y: -10, height: 0 }}\n                  transition={{ duration: 0.25 }}\n                >\n                  {coordinates}\n                </motion.p>\n              )}\n            </AnimatePresence>\n\n            {/* Animated underline */}\n            <motion.div\n              className=\"h-px bg-linear-to-r from-emerald-500/50 via-emerald-400/30 to-transparent\"\n              initial={{ scaleX: 0, originX: 0 }}\n              animate={{\n                scaleX: isHovered || isExpanded ? 1 : 0.3,\n              }}\n              transition={{ duration: 0.4, ease: \"easeOut\" }}\n            />\n          </div>\n        </div>\n      </motion.div>\n\n      {/* Click hint */}\n      <motion.p\n        className=\"text-muted-foreground absolute -bottom-6 left-1/2 text-[10px] whitespace-nowrap\"\n        style={{ x: \"-50%\" }}\n        initial={{ opacity: 0 }}\n        animate={{\n          opacity: isHovered && !isExpanded ? 1 : 0,\n          y: isHovered ? 0 : 4,\n        }}\n        transition={{ duration: 0.2 }}\n      >\n        Click to expand\n      </motion.p>\n    </motion.div>\n  )\n}\n",
      "type": "registry:ui"
    }
  ],
  "type": "registry:ui"
}