{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "aurora-blur",
  "title": "Aurora Blur",
  "description": "Aurora blur shader layer used by Aurora Card.",
  "dependencies": [
    "@react-three/fiber",
    "three"
  ],
  "files": [
    {
      "path": "registry/components/ui/blob-card/aurora-blur.tsx",
      "content": "\"use client\";\n/* eslint-disable react/no-unknown-property */\n\nimport * as React from \"react\";\nimport { Canvas, useFrame, useThree } from \"@react-three/fiber\";\nimport * as THREE from \"three\";\n\nimport { cn } from \"@/lib/utils\";\n\nexport interface AuroraLayer {\n  color: string;\n  speed: number;\n  intensity: number;\n}\n\nexport interface SkyLayer {\n  color: string;\n  blend: number;\n}\n\nexport interface AuroraBlurProps extends React.ComponentProps<\"div\"> {\n  width?: number | string;\n  height?: number | string;\n  speed?: number;\n  layers?: AuroraLayer[];\n  noiseScale?: number;\n  movementX?: number;\n  movementY?: number;\n  verticalFade?: number;\n  bloomIntensity?: number;\n  skyLayers?: SkyLayer[];\n  brightness?: number;\n  saturation?: number;\n  opacity?: number;\n}\n\nconst DEFAULT_LAYERS: AuroraLayer[] = [\n  { color: \"#22d3ee\", speed: 0.35, intensity: 0.7 },\n  { color: \"#3b82f6\", speed: 0.18, intensity: 0.65 },\n  { color: \"#60a5fa\", speed: 0.12, intensity: 0.4 },\n  { color: \"#1d4ed8\", speed: 0.08, intensity: 0.22 },\n];\n\nconst DEFAULT_SKY_LAYERS: SkyLayer[] = [\n  { color: \"#020617\", blend: 0.52 },\n  { color: \"#0f172a\", blend: 0.78 },\n];\n\nconst vertexShader = `\nvarying vec2 vUv;\nvoid main() {\n  vUv = uv;\n  gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n}\n`;\n\nconst fragmentShader = `\nprecision highp float;\nvarying vec2 vUv;\nuniform float u_time;\nuniform vec2 u_resolution;\nuniform float u_speed;\nuniform vec3 u_layer1Color;\nuniform float u_layer1Speed;\nuniform float u_layer1Intensity;\nuniform vec3 u_layer2Color;\nuniform float u_layer2Speed;\nuniform float u_layer2Intensity;\nuniform vec3 u_layer3Color;\nuniform float u_layer3Speed;\nuniform float u_layer3Intensity;\nuniform vec3 u_layer4Color;\nuniform float u_layer4Speed;\nuniform float u_layer4Intensity;\nuniform float u_noiseScale;\nuniform float u_movementX;\nuniform float u_movementY;\nuniform float u_verticalFade;\nuniform float u_bloomIntensity;\nuniform vec3 u_skyColor1;\nuniform vec3 u_skyColor2;\nuniform float u_skyBlend1;\nuniform float u_skyBlend2;\nuniform float u_brightness;\nuniform float u_saturation;\nuniform float u_opacity;\n\nfloat hashNoise(float n) { return fract(sin(n) * 43758.5453123); }\n\nfloat noise2d(vec2 p) {\n  vec2 i = floor(p);\n  vec2 f = fract(p);\n  vec2 u = f * f * (3.0 - 2.0 * f);\n\n  return mix(\n    mix(hashNoise(i.x + hashNoise(i.y)), hashNoise(i.x + 1.0 + hashNoise(i.y)), u.x),\n    mix(hashNoise(i.x + hashNoise(i.y + 1.0)), hashNoise(i.x + 1.0 + hashNoise(i.y + 1.0)), u.x),\n    u.y\n  );\n}\n\nvec3 aurora(vec2 uv, float layerSpeed, float intensity, vec3 color, float aspect) {\n  float time = u_time * u_speed * layerSpeed;\n  vec2 scaled = vec2(uv.x * aspect, uv.y) * u_noiseScale;\n  vec2 point = scaled + time * vec2(u_movementX, u_movementY);\n  float n = noise2d(point + noise2d(color.xy + point + time));\n  float alpha = n - uv.y * u_verticalFade;\n  return color * alpha * intensity * u_bloomIntensity;\n}\n\nvec3 saturateColor(vec3 color, float saturation) {\n  float gray = dot(color, vec3(0.299, 0.587, 0.114));\n  return mix(vec3(gray), color, saturation);\n}\n\nvoid main() {\n  vec2 uv = vUv;\n  float aspect = u_resolution.x / u_resolution.y;\n\n  vec3 color = vec3(0.0);\n  color += aurora(uv, u_layer1Speed, u_layer1Intensity, u_layer1Color, aspect);\n  color += aurora(uv, u_layer2Speed, u_layer2Intensity, u_layer2Color, aspect);\n  color += aurora(uv, u_layer3Speed, u_layer3Intensity, u_layer3Color, aspect);\n  color += aurora(uv, u_layer4Speed, u_layer4Intensity, u_layer4Color, aspect);\n\n  color += u_skyColor2 * (1.0 - smoothstep(u_skyBlend1, 1.0, uv.y));\n  color += u_skyColor1 * (1.0 - smoothstep(0.0, u_skyBlend2, uv.y));\n\n  color = saturateColor(color, u_saturation) * u_brightness;\n\n  gl_FragColor = vec4(color, u_opacity);\n}\n`;\n\nfunction hexToVec3(hex: string): [number, number, number] {\n  const parsed = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\n\n  if (!parsed) return [1, 1, 1];\n\n  return [\n    parseInt(parsed[1], 16) / 255,\n    parseInt(parsed[2], 16) / 255,\n    parseInt(parsed[3], 16) / 255,\n  ];\n}\n\nfunction colorToVec3(color: string): [number, number, number] {\n  if (color.startsWith(\"#\")) return hexToVec3(color);\n  if (typeof document === \"undefined\") return [1, 1, 1];\n\n  const probe = document.createElement(\"span\");\n  probe.style.color = color;\n  document.body.appendChild(probe);\n  const resolved = getComputedStyle(probe).color;\n  probe.remove();\n\n  const parsed = resolved.match(/\\d+(\\.\\d+)?/g);\n  if (!parsed || parsed.length < 3) return [1, 1, 1];\n\n  return [\n    Number(parsed[0]) / 255,\n    Number(parsed[1]) / 255,\n    Number(parsed[2]) / 255,\n  ];\n}\n\ninterface SceneProps {\n  speed: number;\n  layers: AuroraLayer[];\n  noiseScale: number;\n  movementX: number;\n  movementY: number;\n  verticalFade: number;\n  bloomIntensity: number;\n  skyLayers: SkyLayer[];\n  brightness: number;\n  saturation: number;\n  opacity: number;\n}\n\nfunction Scene({\n  speed,\n  layers,\n  noiseScale,\n  movementX,\n  movementY,\n  verticalFade,\n  bloomIntensity,\n  skyLayers,\n  brightness,\n  saturation,\n  opacity,\n}: SceneProps) {\n  const meshRef = React.useRef<THREE.Mesh>(null);\n  const { size } = useThree();\n\n  const uniforms = React.useMemo(\n    () => ({\n      u_time: { value: 0 },\n      u_resolution: { value: new THREE.Vector2(1, 1) },\n      u_speed: { value: 1 },\n      u_layer1Color: { value: new THREE.Vector3(0.13, 0.83, 0.93) },\n      u_layer1Speed: { value: 0.35 },\n      u_layer1Intensity: { value: 0.7 },\n      u_layer2Color: { value: new THREE.Vector3(0.23, 0.51, 0.96) },\n      u_layer2Speed: { value: 0.18 },\n      u_layer2Intensity: { value: 0.65 },\n      u_layer3Color: { value: new THREE.Vector3(0.38, 0.65, 0.98) },\n      u_layer3Speed: { value: 0.12 },\n      u_layer3Intensity: { value: 0.4 },\n      u_layer4Color: { value: new THREE.Vector3(0.11, 0.31, 0.85) },\n      u_layer4Speed: { value: 0.08 },\n      u_layer4Intensity: { value: 0.22 },\n      u_noiseScale: { value: 3.2 },\n      u_movementX: { value: -1.4 },\n      u_movementY: { value: -2.6 },\n      u_verticalFade: { value: 0.5 },\n      u_bloomIntensity: { value: 1.9 },\n      u_skyColor1: { value: new THREE.Vector3(0.01, 0.02, 0.09) },\n      u_skyColor2: { value: new THREE.Vector3(0.06, 0.09, 0.16) },\n      u_skyBlend1: { value: 0.78 },\n      u_skyBlend2: { value: 0.52 },\n      u_brightness: { value: 0.92 },\n      u_saturation: { value: 1.12 },\n      u_opacity: { value: 1 },\n    }),\n    [],\n  );\n\n  useFrame((state) => {\n    if (!meshRef.current) return;\n\n    const material = meshRef.current.material as THREE.ShaderMaterial;\n    const resolvedLayers = layers.length ? layers : DEFAULT_LAYERS;\n    const resolvedSkyLayers = skyLayers.length ? skyLayers : DEFAULT_SKY_LAYERS;\n\n    material.uniforms.u_time.value = state.clock.elapsedTime;\n    material.uniforms.u_resolution.value.set(size.width, size.height);\n    material.uniforms.u_speed.value = speed;\n\n    material.uniforms.u_layer1Color.value.set(\n      ...colorToVec3(resolvedLayers[0]?.color ?? DEFAULT_LAYERS[0].color),\n    );\n    material.uniforms.u_layer1Speed.value =\n      resolvedLayers[0]?.speed ?? DEFAULT_LAYERS[0].speed;\n    material.uniforms.u_layer1Intensity.value =\n      resolvedLayers[0]?.intensity ?? DEFAULT_LAYERS[0].intensity;\n\n    material.uniforms.u_layer2Color.value.set(\n      ...colorToVec3(resolvedLayers[1]?.color ?? DEFAULT_LAYERS[1].color),\n    );\n    material.uniforms.u_layer2Speed.value =\n      resolvedLayers[1]?.speed ?? DEFAULT_LAYERS[1].speed;\n    material.uniforms.u_layer2Intensity.value =\n      resolvedLayers[1]?.intensity ?? DEFAULT_LAYERS[1].intensity;\n\n    material.uniforms.u_layer3Color.value.set(\n      ...colorToVec3(resolvedLayers[2]?.color ?? DEFAULT_LAYERS[2].color),\n    );\n    material.uniforms.u_layer3Speed.value =\n      resolvedLayers[2]?.speed ?? DEFAULT_LAYERS[2].speed;\n    material.uniforms.u_layer3Intensity.value =\n      resolvedLayers[2]?.intensity ?? DEFAULT_LAYERS[2].intensity;\n\n    material.uniforms.u_layer4Color.value.set(\n      ...colorToVec3(resolvedLayers[3]?.color ?? DEFAULT_LAYERS[3].color),\n    );\n    material.uniforms.u_layer4Speed.value =\n      resolvedLayers[3]?.speed ?? DEFAULT_LAYERS[3].speed;\n    material.uniforms.u_layer4Intensity.value =\n      resolvedLayers[3]?.intensity ?? DEFAULT_LAYERS[3].intensity;\n\n    material.uniforms.u_noiseScale.value = noiseScale;\n    material.uniforms.u_movementX.value = movementX;\n    material.uniforms.u_movementY.value = movementY;\n    material.uniforms.u_verticalFade.value = verticalFade;\n    material.uniforms.u_bloomIntensity.value = bloomIntensity;\n    material.uniforms.u_skyColor1.value.set(\n      ...colorToVec3(\n        resolvedSkyLayers[0]?.color ?? DEFAULT_SKY_LAYERS[0].color,\n      ),\n    );\n    material.uniforms.u_skyColor2.value.set(\n      ...colorToVec3(\n        resolvedSkyLayers[1]?.color ?? DEFAULT_SKY_LAYERS[1].color,\n      ),\n    );\n    material.uniforms.u_skyBlend1.value =\n      resolvedSkyLayers[1]?.blend ?? DEFAULT_SKY_LAYERS[1].blend;\n    material.uniforms.u_skyBlend2.value =\n      resolvedSkyLayers[0]?.blend ?? DEFAULT_SKY_LAYERS[0].blend;\n    material.uniforms.u_brightness.value = brightness;\n    material.uniforms.u_saturation.value = saturation;\n    material.uniforms.u_opacity.value = opacity;\n  });\n\n  return (\n    <mesh ref={meshRef}>\n      <planeGeometry args={[2, 2]} />\n      <shaderMaterial\n        fragmentShader={fragmentShader}\n        transparent\n        uniforms={uniforms}\n        vertexShader={vertexShader}\n      />\n    </mesh>\n  );\n}\n\nexport function AuroraBlur({\n  width = \"100%\",\n  height = \"100%\",\n  className,\n  children,\n  speed = 1.1,\n  layers = DEFAULT_LAYERS,\n  noiseScale = 3.2,\n  movementX = -1.4,\n  movementY = -2.6,\n  verticalFade = 0.5,\n  bloomIntensity = 1.9,\n  skyLayers = DEFAULT_SKY_LAYERS,\n  brightness = 0.92,\n  saturation = 1.12,\n  opacity = 1,\n  style,\n  ...props\n}: AuroraBlurProps) {\n  const resolvedWidth = typeof width === \"number\" ? `${width}px` : width;\n  const resolvedHeight = typeof height === \"number\" ? `${height}px` : height;\n\n  return (\n    <div\n      className={cn(\"relative overflow-hidden\", className)}\n      style={{ ...style, width: resolvedWidth, height: resolvedHeight }}\n      {...props}\n    >\n      <Canvas\n        camera={{\n          bottom: -1,\n          left: -1,\n          position: [0, 0, 1],\n          right: 1,\n          top: 1,\n          zoom: 1,\n        }}\n        className=\"pointer-events-none absolute inset-0 h-full w-full\"\n        dpr={[1, 1.5]}\n        gl={{\n          alpha: true,\n          antialias: true,\n          powerPreference: \"high-performance\",\n        }}\n        orthographic\n      >\n        <Scene\n          bloomIntensity={bloomIntensity}\n          brightness={brightness}\n          layers={layers}\n          movementX={movementX}\n          movementY={movementY}\n          noiseScale={noiseScale}\n          opacity={opacity}\n          saturation={saturation}\n          skyLayers={skyLayers}\n          speed={speed}\n          verticalFade={verticalFade}\n        />\n      </Canvas>\n\n      {children ? (\n        <div className=\"relative z-10 h-full w-full\">{children}</div>\n      ) : null}\n    </div>\n  );\n}\n",
      "type": "registry:ui",
      "target": "components/unlumen-ui/aurora-blur.tsx"
    }
  ],
  "type": "registry:ui"
}