{
	"$schema": "https://ui.shadcn.com/schema/registry-item.json",
	"name": "Lightning-JS-CSS",
	"title": "Lightning",
	"description": "Procedural lightning bolts with branching and glow flicker.",
	"type": "registry:component",
	"files": [
		{
			"type": "registry:file",
			"path": "Lightning.css",
			"target": "@components/Lightning.css",
			"content": ".lightning-container {\n  width: 100%;\n  height: 100%;\n  position: relative;\n}\n"
		},
		{
			"type": "registry:component",
			"path": "Lightning.jsx",
			"content": "import { useRef, useEffect } from 'react';\nimport './Lightning.css';\n\nconst Lightning = ({ hue = 230, xOffset = 0, speed = 1, intensity = 1, size = 1 }) => {\n  const canvasRef = useRef(null);\n\n  useEffect(() => {\n    const canvas = canvasRef.current;\n    if (!canvas) return;\n\n    const resizeCanvas = () => {\n      canvas.width = canvas.clientWidth;\n      canvas.height = canvas.clientHeight;\n    };\n    resizeCanvas();\n    window.addEventListener('resize', resizeCanvas);\n\n    const gl = canvas.getContext('webgl', { alpha: true, premultipliedAlpha: false });\n    if (!gl) {\n      console.error('WebGL not supported');\n      return;\n    }\n\n    const vertexShaderSource = `\n      attribute vec2 aPosition;\n      void main() {\n        gl_Position = vec4(aPosition, 0.0, 1.0);\n      }\n    `;\n\n    const fragmentShaderSource = `\n      precision mediump float;\n      uniform vec2 iResolution;\n      uniform float iTime;\n      uniform float uHue;\n      uniform float uXOffset;\n      uniform float uSpeed;\n      uniform float uIntensity;\n      uniform float uSize;\n      \n      #define OCTAVE_COUNT 10\n\n      vec3 hsv2rgb(vec3 c) {\n          vec3 rgb = clamp(abs(mod(c.x * 6.0 + vec3(0.0,4.0,2.0), 6.0) - 3.0) - 1.0, 0.0, 1.0);\n          return c.z * mix(vec3(1.0), rgb, c.y);\n      }\n\n      float hash11(float p) {\n          p = fract(p * .1031);\n          p *= p + 33.33;\n          p *= p + p;\n          return fract(p);\n      }\n\n      float hash12(vec2 p) {\n          vec3 p3 = fract(vec3(p.xyx) * .1031);\n          p3 += dot(p3, p3.yzx + 33.33);\n          return fract((p3.x + p3.y) * p3.z);\n      }\n\n      mat2 rotate2d(float theta) {\n          float c = cos(theta);\n          float s = sin(theta);\n          return mat2(c, -s, s, c);\n      }\n\n      float noise(vec2 p) {\n          vec2 ip = floor(p);\n          vec2 fp = fract(p);\n          float a = hash12(ip);\n          float b = hash12(ip + vec2(1.0, 0.0));\n          float c = hash12(ip + vec2(0.0, 1.0));\n          float d = hash12(ip + vec2(1.0, 1.0));\n          \n          vec2 t = smoothstep(0.0, 1.0, fp);\n          return mix(mix(a, b, t.x), mix(c, d, t.x), t.y);\n      }\n\n      float fbm(vec2 p) {\n          float value = 0.0;\n          float amplitude = 0.5;\n          for (int i = 0; i < OCTAVE_COUNT; ++i) {\n              value += amplitude * noise(p);\n              p *= rotate2d(0.45);\n              p *= 2.0;\n              amplitude *= 0.5;\n          }\n          return value;\n      }\n\n      void mainImage( out vec4 fragColor, in vec2 fragCoord ) {\n          vec2 uv = fragCoord / iResolution.xy;\n          uv = 2.0 * uv - 1.0;\n          uv.x *= iResolution.x / iResolution.y;\n          uv.x += uXOffset;\n          \n          uv += 2.0 * fbm(uv * uSize + 0.8 * iTime * uSpeed) - 1.0;\n          \n          float dist = abs(uv.x);\n          vec3 baseColor = hsv2rgb(vec3(uHue / 360.0, 0.7, 0.8));\n          vec3 col = baseColor * pow(mix(0.0, 0.07, hash11(iTime * uSpeed)) / dist, 1.0) * uIntensity;\n          col = pow(col, vec3(1.0));\n          float a = clamp(max(col.r, max(col.g, col.b)), 0.0, 1.0);\n          fragColor = vec4(col, a);\n      }\n\n      void main() {\n          mainImage(gl_FragColor, gl_FragCoord.xy);\n      }\n    `;\n\n    const compileShader = (source, type) => {\n      const shader = gl.createShader(type);\n      if (!shader) return null;\n      gl.shaderSource(shader, source);\n      gl.compileShader(shader);\n      if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n        console.error('Shader compile error:', gl.getShaderInfoLog(shader));\n        gl.deleteShader(shader);\n        return null;\n      }\n      return shader;\n    };\n\n    const vertexShader = compileShader(vertexShaderSource, gl.VERTEX_SHADER);\n    const fragmentShader = compileShader(fragmentShaderSource, gl.FRAGMENT_SHADER);\n    if (!vertexShader || !fragmentShader) return;\n\n    const program = gl.createProgram();\n    if (!program) return;\n    gl.attachShader(program, vertexShader);\n    gl.attachShader(program, fragmentShader);\n    gl.linkProgram(program);\n    if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n      console.error('Program linking error:', gl.getProgramInfoLog(program));\n      return;\n    }\n    gl.useProgram(program);\n\n    const vertices = new Float32Array([-1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1]);\n    const vertexBuffer = gl.createBuffer();\n    gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);\n    gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);\n\n    const aPosition = gl.getAttribLocation(program, 'aPosition');\n    gl.enableVertexAttribArray(aPosition);\n    gl.vertexAttribPointer(aPosition, 2, gl.FLOAT, false, 0, 0);\n\n    const iResolutionLocation = gl.getUniformLocation(program, 'iResolution');\n    const iTimeLocation = gl.getUniformLocation(program, 'iTime');\n    const uHueLocation = gl.getUniformLocation(program, 'uHue');\n    const uXOffsetLocation = gl.getUniformLocation(program, 'uXOffset');\n    const uSpeedLocation = gl.getUniformLocation(program, 'uSpeed');\n    const uIntensityLocation = gl.getUniformLocation(program, 'uIntensity');\n    const uSizeLocation = gl.getUniformLocation(program, 'uSize');\n\n    let animationFrameId;\n    const startTime = performance.now();\n    const render = () => {\n      resizeCanvas();\n      gl.viewport(0, 0, canvas.width, canvas.height);\n      gl.uniform2f(iResolutionLocation, canvas.width, canvas.height);\n      const currentTime = performance.now();\n      gl.uniform1f(iTimeLocation, (currentTime - startTime) / 1000.0);\n      gl.uniform1f(uHueLocation, hue);\n      gl.uniform1f(uXOffsetLocation, xOffset);\n      gl.uniform1f(uSpeedLocation, speed);\n      gl.uniform1f(uIntensityLocation, intensity);\n      gl.uniform1f(uSizeLocation, size);\n      gl.drawArrays(gl.TRIANGLES, 0, 6);\n      animationFrameId = requestAnimationFrame(render);\n    };\n    animationFrameId = requestAnimationFrame(render);\n\n    return () => {\n      cancelAnimationFrame(animationFrameId);\n      window.removeEventListener('resize', resizeCanvas);\n    };\n  }, [hue, xOffset, speed, intensity, size]);\n\n  return <canvas ref={canvasRef} className=\"lightning-container\" />;\n};\n\nexport default Lightning;\n"
		}
	],
	"registryDependencies": [],
	"dependencies": []
}