{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "hero-06",
  "title": "Hero 06",
  "description": "A simple hero block",
  "dependencies": [
    "lucide-react",
    "next-themes"
  ],
  "registryDependencies": [
    "badge",
    "button",
    "https://www.shadcnui-blocks.com/r/dot-pattern.json",
    "https://www.shadcnui-blocks.com/r/particles.json"
  ],
  "files": [
    {
      "path": "src/registry/blocks/radix/hero-06/components/hero.tsx",
      "content": "import { ArrowUpRight, CirclePlay } from \"lucide-react\";\nimport Link from \"next/link\";\nimport { BackgroundPattern } from \"@/registry/blocks/radix/hero-06/components/background-pattern\";\nimport { Badge } from \"@/registry/bases/radix/ui/badge\";\nimport { Button } from \"@/registry/bases/radix/ui/button\";\n\nexport default function Hero() {\n  return (\n    <div className=\"flex min-h-screen items-center justify-center px-6\">\n      <BackgroundPattern />\n\n      <div className=\"relative z-10 max-w-3xl text-center\">\n        <Badge\n          asChild\n          className=\"rounded-full border-border py-1\"\n          variant=\"secondary\"\n        >\n          <Link href=\"#\">\n            Just released v1.0.0 <ArrowUpRight className=\"ml-1 size-4\" />\n          </Link>\n        </Badge>\n\n        <h1 className=\"mx-auto mt-6 max-w-xl font-medium text-4xl tracking-[-0.04em] sm:text-[2.75rem] md:text-6xl/[1.2]\">\n          Ship better UI without&nbsp;the&nbsp;hassle\n        </h1>\n        <p className=\"mx-auto mt-6 max-w-2xl text-muted-foreground text-xl md:text-2xl/normal\">\n          Instead of starting from scratch every time, use thoughtfully designed\n          blocks that give you a solid foundation for any UI.\n        </p>\n        <div className=\"mt-12 flex items-center justify-center gap-4\">\n          <Button className=\"rounded-full\" size=\"lg\">\n            Get Started <ArrowUpRight className=\"h-5! w-5!\" />\n          </Button>\n          <Button\n            className=\"rounded-full shadow-none\"\n            size=\"lg\"\n            variant=\"outline\"\n          >\n            <CirclePlay className=\"h-5! w-5!\" /> Watch Demo\n          </Button>\n        </div>\n      </div>\n    </div>\n  );\n}\n",
      "type": "registry:component"
    },
    {
      "path": "src/registry/blocks/radix/hero-06/components/background-pattern.tsx",
      "content": "\"use client\";\n\nimport { useTheme } from \"next-themes\";\nimport DotPattern from \"@/registry/bases/radix/ui/dot-pattern\";\nimport Particles from \"@/registry/bases/radix/ui/particles\";\nimport { cn } from \"@/lib/utils\";\n\nexport const BackgroundPattern = () => {\n  const { resolvedTheme } = useTheme();\n  const isLightTheme = resolvedTheme === \"light\";\n\n  return (\n    <>\n      <DotPattern\n        className={cn(\n          \"mask-[radial-gradient(ellipse,rgba(0,0,0,0.3)_30%,black_50%)]\",\n          \"dark:fill-slate-700\"\n        )}\n        cr={1}\n        cx={1}\n        cy={1}\n        height={20}\n        width={20}\n      />\n      <Particles\n        className=\"absolute inset-0\"\n        color={isLightTheme ? \"#000\" : \"#fff\"}\n        ease={80}\n        quantity={100}\n        refresh\n      />\n    </>\n  );\n};\n",
      "type": "registry:component"
    },
    {
      "path": "src/registry/blocks/radix/hero-06/components/ui/dot-pattern.tsx",
      "content": "import { type ComponentProps, useId } from \"react\";\n\nimport { cn } from \"@/lib/utils\";\n\ninterface DotPatternProps extends ComponentProps<\"svg\"> {\n  width?: number;\n  height?: number;\n  x?: number;\n  y?: number;\n  cx?: number;\n  cy?: number;\n  cr?: number;\n  className?: string;\n}\nexport function DotPattern({\n  width = 16,\n  height = 16,\n  x = 0,\n  y = 0,\n  cx = 1,\n  cy = 1,\n  cr = 1,\n  className,\n  ...props\n}: DotPatternProps) {\n  const id = useId();\n\n  return (\n    <svg\n      aria-hidden=\"true\"\n      className={cn(\n        \"pointer-events-none absolute inset-0 h-full w-full fill-neutral-400/80\",\n        className\n      )}\n      {...props}\n    >\n      <defs>\n        <pattern\n          height={height}\n          id={id}\n          patternContentUnits=\"userSpaceOnUse\"\n          patternUnits=\"userSpaceOnUse\"\n          width={width}\n          x={x}\n          y={y}\n        >\n          <circle cx={cx} cy={cy} id=\"pattern-circle\" r={cr} />\n        </pattern>\n      </defs>\n      <rect fill={`url(#${id})`} height=\"100%\" strokeWidth={0} width=\"100%\" />\n    </svg>\n  );\n}\n\nexport default DotPattern;\n",
      "type": "registry:component"
    },
    {
      "path": "src/registry/blocks/radix/hero-06/components/ui/particles.tsx",
      "content": "\"use client\";\n\nimport type React from \"react\";\nimport { useEffect, useRef, useState } from \"react\";\nimport { cn } from \"@/lib/utils\";\n\ninterface MousePosition {\n  x: number;\n  y: number;\n}\n\nfunction MousePosition(): MousePosition {\n  const [mousePosition, setMousePosition] = useState<MousePosition>({\n    x: 0,\n    y: 0,\n  });\n\n  useEffect(() => {\n    const handleMouseMove = (event: MouseEvent) => {\n      setMousePosition({ x: event.clientX, y: event.clientY });\n    };\n\n    window.addEventListener(\"mousemove\", handleMouseMove);\n\n    return () => {\n      window.removeEventListener(\"mousemove\", handleMouseMove);\n    };\n  }, []);\n\n  return mousePosition;\n}\n\ninterface ParticlesProps {\n  className?: string;\n  quantity?: number;\n  staticity?: number;\n  ease?: number;\n  size?: number;\n  refresh?: boolean;\n  color?: string;\n  vx?: number;\n  vy?: number;\n}\nfunction hexToRgb(hex: string): number[] {\n  hex = hex.replace(\"#\", \"\");\n\n  if (hex.length === 3) {\n    hex = hex\n      .split(\"\")\n      .map((char) => char + char)\n      .join(\"\");\n  }\n\n  const hexInt = Number.parseInt(hex, 16);\n  const red = (hexInt >> 16) & 255;\n  const green = (hexInt >> 8) & 255;\n  const blue = hexInt & 255;\n  return [red, green, blue];\n}\n\nconst Particles: React.FC<ParticlesProps> = ({\n  className = \"\",\n  quantity = 100,\n  staticity = 50,\n  ease = 50,\n  size = 0.4,\n  refresh = false,\n  color = \"#ffffff\",\n  vx = 0,\n  vy = 0,\n}) => {\n  const canvasRef = useRef<HTMLCanvasElement>(null);\n  const canvasContainerRef = useRef<HTMLDivElement>(null);\n  const context = useRef<CanvasRenderingContext2D | null>(null);\n  const circles = useRef<Circle[]>([]);\n  const mousePosition = MousePosition();\n  const mouse = useRef<{ x: number; y: number }>({ x: 0, y: 0 });\n  const canvasSize = useRef<{ w: number; h: number }>({ w: 0, h: 0 });\n  const dpr = typeof window !== \"undefined\" ? window.devicePixelRatio : 1;\n\n  useEffect(() => {\n    if (canvasRef.current) {\n      context.current = canvasRef.current.getContext(\"2d\");\n    }\n    initCanvas();\n    animate();\n    window.addEventListener(\"resize\", initCanvas);\n\n    return () => {\n      window.removeEventListener(\"resize\", initCanvas);\n    };\n  }, [color]);\n\n  useEffect(() => {\n    onMouseMove();\n  }, [mousePosition.x, mousePosition.y]);\n\n  useEffect(() => {\n    initCanvas();\n  }, [refresh]);\n\n  const initCanvas = () => {\n    resizeCanvas();\n    drawParticles();\n  };\n\n  const onMouseMove = () => {\n    if (canvasRef.current) {\n      const rect = canvasRef.current.getBoundingClientRect();\n      const { w, h } = canvasSize.current;\n      const x = mousePosition.x - rect.left - w / 2;\n      const y = mousePosition.y - rect.top - h / 2;\n      const inside = x < w / 2 && x > -w / 2 && y < h / 2 && y > -h / 2;\n      if (inside) {\n        mouse.current.x = x;\n        mouse.current.y = y;\n      }\n    }\n  };\n\n  type Circle = {\n    x: number;\n    y: number;\n    translateX: number;\n    translateY: number;\n    size: number;\n    alpha: number;\n    targetAlpha: number;\n    dx: number;\n    dy: number;\n    magnetism: number;\n  };\n\n  const resizeCanvas = () => {\n    if (canvasContainerRef.current && canvasRef.current && context.current) {\n      circles.current.length = 0;\n      canvasSize.current.w = canvasContainerRef.current.offsetWidth;\n      canvasSize.current.h = canvasContainerRef.current.offsetHeight;\n      canvasRef.current.width = canvasSize.current.w * dpr;\n      canvasRef.current.height = canvasSize.current.h * dpr;\n      canvasRef.current.style.width = `${canvasSize.current.w}px`;\n      canvasRef.current.style.height = `${canvasSize.current.h}px`;\n      context.current.scale(dpr, dpr);\n    }\n  };\n\n  const circleParams = (): Circle => {\n    const x = Math.floor(Math.random() * canvasSize.current.w);\n    const y = Math.floor(Math.random() * canvasSize.current.h);\n    const translateX = 0;\n    const translateY = 0;\n    const pSize = Math.floor(Math.random() * 2) + size;\n    const alpha = 0;\n    const targetAlpha = Number.parseFloat(\n      (Math.random() * 0.6 + 0.1).toFixed(1)\n    );\n    const dx = (Math.random() - 0.5) * 0.1;\n    const dy = (Math.random() - 0.5) * 0.1;\n    const magnetism = 0.1 + Math.random() * 4;\n    return {\n      x,\n      y,\n      translateX,\n      translateY,\n      size: pSize,\n      alpha,\n      targetAlpha,\n      dx,\n      dy,\n      magnetism,\n    };\n  };\n\n  const rgb = hexToRgb(color);\n\n  const drawCircle = (circle: Circle, update = false) => {\n    if (context.current) {\n      const { x, y, translateX, translateY, size, alpha } = circle;\n      context.current.translate(translateX, translateY);\n      context.current.beginPath();\n      context.current.arc(x, y, size, 0, 2 * Math.PI);\n      context.current.fillStyle = `rgba(${rgb.join(\", \")}, ${alpha})`;\n      context.current.fill();\n      context.current.setTransform(dpr, 0, 0, dpr, 0, 0);\n\n      if (!update) {\n        circles.current.push(circle);\n      }\n    }\n  };\n\n  const clearContext = () => {\n    if (context.current) {\n      context.current.clearRect(\n        0,\n        0,\n        canvasSize.current.w,\n        canvasSize.current.h\n      );\n    }\n  };\n\n  const drawParticles = () => {\n    clearContext();\n    const particleCount = quantity;\n    for (let i = 0; i < particleCount; i++) {\n      const circle = circleParams();\n      drawCircle(circle);\n    }\n  };\n\n  const remapValue = (\n    value: number,\n    start1: number,\n    end1: number,\n    start2: number,\n    end2: number\n  ): number => {\n    const remapped =\n      ((value - start1) * (end2 - start2)) / (end1 - start1) + start2;\n    return remapped > 0 ? remapped : 0;\n  };\n\n  const animate = () => {\n    clearContext();\n    circles.current.forEach((circle: Circle, i: number) => {\n      // Handle the alpha value\n      const edge = [\n        circle.x + circle.translateX - circle.size, // distance from left edge\n        canvasSize.current.w - circle.x - circle.translateX - circle.size, // distance from right edge\n        circle.y + circle.translateY - circle.size, // distance from top edge\n        canvasSize.current.h - circle.y - circle.translateY - circle.size, // distance from bottom edge\n      ];\n      const closestEdge = edge.reduce((a, b) => Math.min(a, b));\n      const remapClosestEdge = Number.parseFloat(\n        remapValue(closestEdge, 0, 20, 0, 1).toFixed(2)\n      );\n      if (remapClosestEdge > 1) {\n        circle.alpha += 0.02;\n        if (circle.alpha > circle.targetAlpha) {\n          circle.alpha = circle.targetAlpha;\n        }\n      } else {\n        circle.alpha = circle.targetAlpha * remapClosestEdge;\n      }\n      circle.x += circle.dx + vx;\n      circle.y += circle.dy + vy;\n      circle.translateX +=\n        (mouse.current.x / (staticity / circle.magnetism) - circle.translateX) /\n        ease;\n      circle.translateY +=\n        (mouse.current.y / (staticity / circle.magnetism) - circle.translateY) /\n        ease;\n\n      drawCircle(circle, true);\n\n      // circle gets out of the canvas\n      if (\n        circle.x < -circle.size ||\n        circle.x > canvasSize.current.w + circle.size ||\n        circle.y < -circle.size ||\n        circle.y > canvasSize.current.h + circle.size\n      ) {\n        // remove the circle from the array\n        circles.current.splice(i, 1);\n        // create a new circle\n        const newCircle = circleParams();\n        drawCircle(newCircle);\n        // update the circle position\n      }\n    });\n    window.requestAnimationFrame(animate);\n  };\n\n  return (\n    <div\n      aria-hidden=\"true\"\n      className={cn(\"pointer-events-none\", className)}\n      ref={canvasContainerRef}\n    >\n      <canvas className=\"size-full\" ref={canvasRef} />\n    </div>\n  );\n};\n\nexport default Particles;\n",
      "type": "registry:component"
    }
  ],
  "type": "registry:block"
}