{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "hero-surge",
  "title": "Hero · Surge",
  "description": "Hero · Surge section.",
  "dependencies": [
    "lucide-react",
    "three"
  ],
  "files": [
    {
      "path": "registry/talizen/hero/hero-surge/hero-surge.tsx",
      "content": "import { Menu, X } from \"lucide-react\"\nimport { useState } from \"react\"\n\nimport { MeshGradient } from \"./MeshGradient\"\n\nexport type HeroSurgeProps = {\n  className?: string\n}\n\nfunction SurgeMark({ className }: { className?: string }) {\n  return (\n    <svg viewBox=\"0 0 32 32\" fill=\"none\" aria-hidden=\"true\" className={className}>\n      <path d=\"M17.8 2.7 5 17.1l9.6 2.1-1.8 10.1L27 12.7l-9.9-2.1.7-7.9Z\" fill=\"currentColor\" opacity=\"0.95\" />\n      <path d=\"m13.3 7.9-5.8 6.6 7.1 1.6 2.5-5.5-3.8-2.7Z\" fill=\"white\" opacity=\"0.72\" />\n    </svg>\n  )\n}\n\nexport function HeroSurge({ className = \"\" }: HeroSurgeProps) {\n  const navItems = [\"Platform\", \"Workflows\", \"Signals\", \"Docs\", \"Pricing\"]\n  const [menuOpen, setMenuOpen] = useState(false)\n  const MenuIcon = menuOpen ? X : Menu\n\n  return (\n    <section className={`relative min-h-[100svh] w-full overflow-hidden bg-[#7068ff] text-white ${className}`}>\n      <MeshGradient />\n      <div className=\"absolute inset-x-0 bottom-0 h-48 bg-gradient-to-t from-[#554dff]/55 to-transparent\" aria-hidden=\"true\" />\n\n      <div className=\"relative z-10 flex min-h-[100svh] flex-col px-4 py-4 sm:px-8 sm:py-5 lg:px-14 xl:px-20\">\n        <header className=\"relative grid min-h-12 grid-cols-[minmax(0,1fr)_auto] items-center gap-3 sm:min-h-14 lg:grid-cols-[auto_minmax(0,1fr)_auto] lg:gap-4\">\n          <a href=\"#\" className=\"inline-flex items-center gap-3 text-white\">\n            <SurgeMark className=\"h-7 w-7 shrink-0 sm:h-8 sm:w-8\" />\n            <span className=\"text-[22px] font-semibold uppercase leading-none sm:text-[26px]\">SURGE</span>\n          </a>\n\n          <nav className=\"hidden items-center gap-9 text-[18px] font-medium text-white/60 lg:flex xl:gap-12\">\n            {navItems.map((item) => (\n              <a key={item} href=\"#\" className=\"transition hover:text-white\">\n                {item}\n              </a>\n            ))}\n          </nav>\n\n          <a\n            href=\"#\"\n            className=\"hidden min-h-14 items-center justify-center rounded-full border border-white/18 bg-white/5 px-7 text-[17px] font-semibold text-white/72 shadow-[inset_0_1px_0_rgba(255,255,255,0.16)] backdrop-blur transition hover:border-white/34 hover:bg-white/10 hover:text-white lg:inline-flex\"\n          >\n            Start building\n          </a>\n\n          <button\n            type=\"button\"\n            onClick={() => setMenuOpen((open) => !open)}\n            aria-label={menuOpen ? \"Close menu\" : \"Open menu\"}\n            aria-expanded={menuOpen}\n            aria-controls=\"hero-surge-mobile-menu\"\n            className=\"inline-grid size-11 place-items-center rounded-full border border-white/18 bg-white/8 text-white shadow-[inset_0_1px_0_rgba(255,255,255,0.12)] backdrop-blur transition hover:bg-white/14 lg:hidden\"\n          >\n            <MenuIcon className=\"size-5\" aria-hidden=\"true\" />\n          </button>\n\n          <div\n            id=\"hero-surge-mobile-menu\"\n            className={`absolute left-0 right-0 top-[calc(100%+12px)] z-30 overflow-hidden rounded-[18px] border border-white/16 bg-[#5f57f5]/88 p-2 shadow-[0_24px_80px_rgba(45,40,124,0.38)] backdrop-blur-xl transition duration-200 lg:hidden ${\n              menuOpen\n                ? \"translate-y-0 opacity-100\"\n                : \"pointer-events-none -translate-y-2 opacity-0\"\n            }`}\n          >\n            <nav className=\"grid text-sm font-semibold text-white/78\">\n              {navItems.map((item) => (\n                <a\n                  key={item}\n                  href=\"#\"\n                  onClick={() => setMenuOpen(false)}\n                  className=\"rounded-[14px] px-4 py-3 transition hover:bg-white/12 hover:text-white\"\n                >\n                  {item}\n                </a>\n              ))}\n            </nav>\n            <a\n              href=\"#\"\n              onClick={() => setMenuOpen(false)}\n              className=\"mt-2 flex min-h-11 items-center justify-center rounded-full bg-white px-5 text-sm font-semibold text-zinc-950 transition hover:bg-white/90\"\n            >\n              Start building\n            </a>\n          </div>\n        </header>\n\n        <div className=\"flex flex-1 items-center justify-center pb-10 pt-14 text-center sm:pb-[8vh] sm:pt-24\">\n          <div className=\"mx-auto flex w-full max-w-[1120px] flex-col items-center\">\n            <h1 className=\"max-w-[340px] text-[42px] font-light leading-[1.04] text-white sm:max-w-[760px] sm:text-[76px] sm:leading-[0.98] md:max-w-[980px] md:text-[96px] lg:max-w-[1080px] lg:text-[112px]\">\n              Build AI products\n              <br />\n              that surge ahead\n            </h1>\n\n            <p className=\"mt-7 max-w-[330px] text-[18px] font-medium leading-7 text-white/74 sm:mt-10 sm:max-w-[720px] sm:text-[24px] sm:leading-10\">\n              Orchestrate models, data, and release workflows in one responsive layer{\" \"}\n              <br className=\"hidden sm:block\" />\n              built for teams shipping reliable AI at production speed.\n            </p>\n\n            <a\n              href=\"#\"\n              className=\"mt-10 inline-flex min-h-[58px] w-full max-w-[246px] items-center justify-center rounded-full bg-white px-7 text-[18px] font-semibold text-zinc-950 shadow-[0_24px_70px_rgba(47,44,135,0.28)] transition hover:-translate-y-0.5 hover:bg-white/90 sm:mt-14 sm:min-h-[70px] sm:min-w-[258px] sm:text-[21px]\"\n            >\n              Start building\n            </a>\n          </div>\n        </div>\n      </div>\n    </section>\n  )\n}\n\nexport default HeroSurge\n",
      "type": "registry:component"
    },
    {
      "path": "registry/talizen/hero/hero-surge/MeshGradient.tsx",
      "content": "import { useEffect, useRef, type CSSProperties } from \"react\"\nimport * as THREE from \"three\"\n\nexport type MeshGradientProps = {\n  className?: string\n  style?: CSSProperties\n}\n\nconst vertexShader = `\n  varying vec2 vUv;\n  varying float vDistortion;\n  uniform float uTime;\n  uniform float uSpeed;\n  uniform float uAmplitude;\n  uniform float uFrequency;\n\n  vec3 mod289(vec3 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }\n  vec4 mod289(vec4 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }\n  vec4 permute(vec4 x) { return mod289(((x*34.0)+1.0)*x); }\n  vec4 taylorInvSqrt(vec4 r) { return 1.79284291400159 - 0.85373472095314 * r; }\n\n  float snoise(vec3 v) {\n    const vec2 C = vec2(1.0 / 6.0, 1.0 / 3.0);\n    const vec4 D = vec4(0.0, 0.5, 1.0, 2.0);\n    vec3 i = floor(v + dot(v, C.yyy));\n    vec3 x0 = v - i + dot(i, C.xxx);\n    vec3 g = step(x0.yzx, x0.xyz);\n    vec3 l = 1.0 - g;\n    vec3 i1 = min(g.xyz, l.zxy);\n    vec3 i2 = max(g.xyz, l.zxy);\n    vec3 x1 = x0 - i1 + C.xxx;\n    vec3 x2 = x0 - i2 + C.yyy;\n    vec3 x3 = x0 - D.yyy;\n    i = mod289(i);\n    vec4 p = permute(permute(permute(\n      i.z + vec4(0.0, i1.z, i2.z, 1.0))\n      + i.y + vec4(0.0, i1.y, i2.y, 1.0))\n      + i.x + vec4(0.0, i1.x, i2.x, 1.0));\n    float n_ = 0.142857142857;\n    vec3 ns = n_ * D.wyz - D.xzx;\n    vec4 j = p - 49.0 * floor(p * ns.z * ns.z);\n    vec4 x_ = floor(j * ns.z);\n    vec4 y_ = floor(j - 7.0 * x_);\n    vec4 x = x_ * ns.x + ns.yyyy;\n    vec4 y = y_ * ns.x + ns.yyyy;\n    vec4 h = 1.0 - abs(x) - abs(y);\n    vec4 b0 = vec4(x.xy, y.xy);\n    vec4 b1 = vec4(x.zw, y.zw);\n    vec4 s0 = floor(b0) * 2.0 + 1.0;\n    vec4 s1 = floor(b1) * 2.0 + 1.0;\n    vec4 sh = -step(h, vec4(0.0));\n    vec4 a0 = b0.xzyw + s0.xzyw * sh.xxyy;\n    vec4 a1 = b1.xzyw + s1.xzyw * sh.zzww;\n    vec3 p0 = vec3(a0.xy, h.x);\n    vec3 p1 = vec3(a0.zw, h.y);\n    vec3 p2 = vec3(a1.xy, h.z);\n    vec3 p3 = vec3(a1.zw, h.w);\n    vec4 norm = taylorInvSqrt(vec4(dot(p0, p0), dot(p1, p1), dot(p2, p2), dot(p3, p3)));\n    p0 *= norm.x;\n    p1 *= norm.y;\n    p2 *= norm.z;\n    p3 *= norm.w;\n    vec4 m = max(0.6 - vec4(dot(x0, x0), dot(x1, x1), dot(x2, x2), dot(x3, x3)), 0.0);\n    m = m * m;\n    return 42.0 * dot(m * m, vec4(dot(p0, x0), dot(p1, x1), dot(p2, x2), dot(p3, x3)));\n  }\n\n  void main() {\n    vUv = uv;\n    float noise = snoise(vec3(position.xy * uFrequency, uTime * uSpeed));\n    vDistortion = noise;\n    vec3 newPosition = position + normal * noise * uAmplitude;\n    gl_Position = projectionMatrix * modelViewMatrix * vec4(newPosition, 1.0);\n  }\n`\n\nconst fragmentShader = `\n  varying vec2 vUv;\n  varying float vDistortion;\n  uniform vec3 uColor1;\n  uniform vec3 uColor2;\n  uniform vec3 uColor3;\n  uniform vec3 uColor4;\n  uniform float uBrightness;\n  uniform float uReflection;\n  uniform bool uGrain;\n  uniform float uTime;\n\n  float random(vec2 p) {\n    return fract(sin(dot(p, vec2(12.9898, 78.233))) * 43758.5453);\n  }\n\n  void main() {\n    float noise = (vDistortion + 1.0) * 0.5;\n    vec3 colTop = mix(uColor1, uColor2, smoothstep(0.0, 1.0, vUv.x + noise * 0.3));\n    vec3 colBottom = mix(uColor3, uColor4, smoothstep(0.0, 1.0, vUv.y - noise * 0.3));\n    float blend = smoothstep(0.1, 0.9, noise);\n    vec3 finalColor = mix(colTop, colBottom, blend);\n    finalColor += pow(noise, 6.0) * uReflection;\n    finalColor *= uBrightness;\n    if (uGrain) {\n      float grain = (random(vUv * 1024.0 + fract(uTime)) - 0.5) * 0.04;\n      finalColor += grain;\n    }\n    gl_FragColor = vec4(finalColor, 1.0);\n  }\n`\n\nexport function MeshGradient({ className = \"\", style }: MeshGradientProps) {\n  const containerRef = useRef<HTMLDivElement | null>(null)\n  const frameRef = useRef<number | null>(null)\n\n  useEffect(() => {\n    const container = containerRef.current\n    if (!container) return\n\n    const scene = new THREE.Scene()\n    const camera = new THREE.PerspectiveCamera(40, 1, 0.1, 100)\n    camera.position.set(0, 0, 5 / 1.2)\n\n    let renderer: THREE.WebGLRenderer\n    try {\n      renderer = new THREE.WebGLRenderer({\n        antialias: true,\n        alpha: false,\n        powerPreference: \"high-performance\",\n      })\n    } catch {\n      return\n    }\n\n    renderer.setClearColor(\"#000\", 1)\n    renderer.setPixelRatio(Math.min(window.devicePixelRatio || 1, 2))\n    renderer.domElement.style.display = \"block\"\n    renderer.domElement.style.height = \"100%\"\n    renderer.domElement.style.width = \"100%\"\n    container.appendChild(renderer.domElement)\n\n    const geometry = new THREE.PlaneGeometry(20, 20, 180, 180)\n    const material = new THREE.ShaderMaterial({\n      vertexShader,\n      fragmentShader,\n      uniforms: {\n        uTime: { value: 0 },\n        uSpeed: { value: 0.15 },\n        uAmplitude: { value: 1.2 },\n        uFrequency: { value: 0.4 },\n        uBrightness: { value: 1.1 },\n        uReflection: { value: 0.3 },\n        uColor1: { value: new THREE.Color(\"#ffffff\") },\n        uColor2: { value: new THREE.Color(\"#0e4ee1\") },\n        uColor3: { value: new THREE.Color(\"#ffffff\") },\n        uColor4: { value: new THREE.Color(\"#0011ff\") },\n        uGrain: { value: true },\n      },\n      side: THREE.DoubleSide,\n    })\n    const mesh = new THREE.Mesh(geometry, material)\n    mesh.rotation.set(-0.6, 0, 0.1)\n    scene.add(mesh)\n\n    const resize = () => {\n      const width = Math.max(container.clientWidth, 1)\n      const height = Math.max(container.clientHeight, 1)\n      camera.aspect = width / height\n      camera.updateProjectionMatrix()\n      renderer.setSize(width, height, false)\n    }\n\n    const resizeObserver = new ResizeObserver(resize)\n    resizeObserver.observe(container)\n    resize()\n\n    const startTime = performance.now()\n    const render = () => {\n      material.uniforms.uTime.value = (performance.now() - startTime) / 1000\n      renderer.render(scene, camera)\n      frameRef.current = requestAnimationFrame(render)\n    }\n    frameRef.current = requestAnimationFrame(render)\n\n    return () => {\n      resizeObserver.disconnect()\n      if (frameRef.current !== null) {\n        cancelAnimationFrame(frameRef.current)\n      }\n      scene.remove(mesh)\n      geometry.dispose()\n      material.dispose()\n      renderer.dispose()\n      if (container.contains(renderer.domElement)) {\n        container.removeChild(renderer.domElement)\n      }\n    }\n  }, [])\n\n  return (\n    <div\n      ref={containerRef}\n      aria-hidden=\"true\"\n      className={`absolute inset-0 bg-black ${className}`}\n      style={style}\n    />\n  )\n}\n\nexport default MeshGradient\n",
      "type": "registry:component"
    }
  ],
  "categories": [
    "hero"
  ],
  "type": "registry:block"
}