{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "cyberpunk-button",
  "title": "Cyberpunk Button",
  "description": "Futuristic, minimalistic button with smooth animations.",
  "dependencies": [
    "motion"
  ],
  "files": [
    {
      "path": "packages/cyberpunk-button/cyberpunk-button.tsx",
      "content": "\"use client\";\r\n\r\nimport { useState, useEffect } from \"react\";\r\n\r\ntype PixelColor = \"lime\" | \"bloodred\" | \"sky\";\r\ntype PixelShade = \"white\" | \"black\";\r\n\r\ninterface CyberpunkButtonProps {\r\n  buttonColor?: PixelColor;\r\n  pixelColor?: PixelShade;\r\n  buttonText?: string;\r\n}\r\n\r\nconst colorMap: Record<PixelColor, string> = {\r\n  lime: \"#ccff00\",\r\n  bloodred: \"#f03030\",\r\n  sky: \"#007bff\",\r\n};\r\n\r\nconst gradientMap: Record<PixelColor, string> = {\r\n  lime: \"linear-gradient(to bottom, #ccff00, #b3e600)\",\r\n  bloodred: \"linear-gradient(to bottom, #f03030, #e11d2e)\",\r\n  sky: \"linear-gradient(to bottom, #007bff, #0056b3)\",\r\n};\r\n\r\nconst pixelShadeMap: Record<PixelShade, { active: string; inactive: string }> =\r\n  {\r\n    white: {\r\n      active: \"rgba(255,255,255,1)\",\r\n      inactive: \"rgba(255,255,255,0.55)\",\r\n    },\r\n    black: {\r\n      active: \"rgba(15,15,15,1)\",\r\n      inactive: \"rgba(15,15,15,0.55)\",\r\n    },\r\n  };\r\n\r\nconst CyberpunkButton = ({\r\n  buttonColor = \"lime\",\r\n  pixelColor = \"black\",\r\n  buttonText = \"Book a demo\",\r\n}: CyberpunkButtonProps) => {\r\n  const [isHovered, setIsHovered] = useState(false);\r\n  const [shimmerPhase, setShimmerPhase] = useState(0);\r\n  const [activeArrow, setActiveArrow] = useState(0);\r\n\r\n  const rows = 5;\r\n  const pixelSize = 3;\r\n  const gap = 2;\r\n  const spacing = 5;\r\n  const centerRow = 2;\r\n  const colsHovered = 30;\r\n  const arrowCols = spacing;\r\n\r\n  useEffect(() => {\r\n    if (isHovered) return;\r\n    const timer = setInterval(() => {\r\n      setShimmerPhase((prev) => (prev + 1) % (spacing + 3));\r\n    }, 110);\r\n    return () => clearInterval(timer);\r\n  }, [isHovered]);\r\n\r\n  useEffect(() => {\r\n    if (!isHovered) return;\r\n    const totalArrows = Math.floor(colsHovered / spacing);\r\n    const timer = setInterval(() => {\r\n      setActiveArrow((prev) => (prev + 1) % totalArrows);\r\n    }, 120);\r\n    return () => clearInterval(timer);\r\n  }, [isHovered]);\r\n\r\n  const isPixelActiveHovered = (r: number, c: number) => {\r\n    const rowOffset = r - centerRow;\r\n    const diagonalShift = Math.abs(rowOffset);\r\n    const arrowIndex = Math.floor(c / spacing);\r\n    const phase = c % spacing;\r\n\r\n    const isHead =\r\n      r === centerRow && (phase === spacing - 1 || phase === spacing - 2);\r\n\r\n    const isDiagonal =\r\n      r !== centerRow &&\r\n      (phase === spacing - 1 - diagonalShift ||\r\n        phase === spacing - 2 - diagonalShift);\r\n\r\n    return { active: isHead || isDiagonal, arrowIndex };\r\n  };\r\n\r\n  const pixelColors = pixelShadeMap[pixelColor];\r\n\r\n  return (\r\n    <button\r\n      style={{\r\n        position: \"relative\",\r\n        display: \"flex\",\r\n        alignItems: \"center\",\r\n        backgroundColor: \"#0a0a0a\",\r\n        borderRadius: \"12px\",\r\n        padding: \"4px\",\r\n        border: \"1px solid #262626\",\r\n        height: \"64px\",\r\n        cursor: \"pointer\",\r\n        transition: \"border-color 0.3s\",\r\n        outline: \"none\",\r\n        overflow: \"hidden\",\r\n      }}\r\n      onMouseEnter={() => setIsHovered(true)}\r\n      onMouseLeave={() => setIsHovered(false)}\r\n    >\r\n      {/* TEXT (now flexible) */}\r\n      <div\r\n        style={{\r\n          paddingLeft: \"72px\",\r\n          paddingRight: \"24px\",\r\n          whiteSpace: \"nowrap\",\r\n          transition: \"opacity 0.3s, transform 0.3s\",\r\n          opacity: isHovered ? 0 : 1,\r\n          transform: isHovered ? \"translateX(-8px)\" : \"translateX(0)\",\r\n        }}\r\n      >\r\n        <span\r\n          style={{\r\n            color: \"white\",\r\n            fontSize: \"18px\",\r\n            fontWeight: 500,\r\n            letterSpacing: \"-0.02em\",\r\n            fontFamily: \"system-ui\",\r\n          }}\r\n        >\r\n          {buttonText}\r\n        </span>\r\n      </div>\r\n\r\n      {/* COLORED BOX */}\r\n      <div\r\n        style={{\r\n          position: \"absolute\",\r\n          left: \"4px\",\r\n          top: \"4px\",\r\n          bottom: \"4px\",\r\n          width: isHovered ? \"calc(100% - 8px)\" : \"56px\",\r\n          transition: \"width 0.5s cubic-bezier(0.2,0,0,1)\",\r\n          borderRadius: \"8px\",\r\n          display: \"flex\",\r\n          alignItems: \"center\",\r\n          justifyContent: \"center\",\r\n          overflow: \"hidden\",\r\n          backgroundColor: colorMap[buttonColor],\r\n          backgroundImage: isHovered ? gradientMap[buttonColor] : \"none\",\r\n        }}\r\n      >\r\n        {isHovered ? (\r\n          <div style={{ display: \"grid\", gap: `${gap}px` }}>\r\n            {Array.from({ length: rows }).map((_, r) => (\r\n              <div key={r} style={{ display: \"flex\", gap: `${gap}px` }}>\r\n                {Array.from({ length: colsHovered }).map((_, c) => {\r\n                  const { active, arrowIndex } = isPixelActiveHovered(r, c);\r\n                  const isHighlighted = arrowIndex === activeArrow;\r\n                  return (\r\n                    <div\r\n                      key={`${r}-${c}`}\r\n                      style={{\r\n                        width: `${pixelSize}px`,\r\n                        height: `${pixelSize}px`,\r\n                        borderRadius: \"1px\",\r\n                        backgroundColor: active\r\n                          ? isHighlighted\r\n                            ? pixelColors.active\r\n                            : pixelColors.inactive\r\n                          : \"transparent\",\r\n                      }}\r\n                    />\r\n                  );\r\n                })}\r\n              </div>\r\n            ))}\r\n          </div>\r\n        ) : (\r\n          <div style={{ display: \"grid\", gap: `${gap}px` }}>\r\n            {Array.from({ length: rows }).map((_, r) => (\r\n              <div key={r} style={{ display: \"flex\", gap: `${gap}px` }}>\r\n                {Array.from({ length: arrowCols }).map((_, c) => {\r\n                  const { active } = isPixelActiveHovered(r, c);\r\n                  const shimCol = shimmerPhase % spacing;\r\n                  const phase = c % spacing;\r\n                  const isShimmering = active && phase === shimCol;\r\n\r\n                  return (\r\n                    <div\r\n                      key={`${r}-${c}`}\r\n                      style={{\r\n                        width: `${pixelSize}px`,\r\n                        height: `${pixelSize}px`,\r\n                        borderRadius: \"1px\",\r\n                        backgroundColor: active\r\n                          ? isShimmering\r\n                            ? pixelColors.active\r\n                            : pixelColors.inactive\r\n                          : \"transparent\",\r\n                      }}\r\n                    />\r\n                  );\r\n                })}\r\n              </div>\r\n            ))}\r\n          </div>\r\n        )}\r\n      </div>\r\n    </button>\r\n  );\r\n};\r\n\r\nexport default CyberpunkButton;\r\n",
      "type": "registry:component",
      "target": "components/satori-ui/cyberpunk-button.tsx"
    }
  ],
  "type": "registry:component"
}