{
  "name": "glare-card",
  "type": "registry:ui",
  "files": [
    {
      "path": "components/ui/glare-card.tsx",
      "content": "\"use client\";\nimport { cn } from \"@/lib/utils\";\nimport { useRef } from \"react\";\n\nexport const GlareCard = ({\n  children,\n  className,\n}: {\n  children: React.ReactNode;\n  className?: string;\n}) => {\n  const isPointerInside = useRef(false);\n  const refElement = useRef<HTMLDivElement>(null);\n  const state = useRef({\n    glare: {\n      x: 50,\n      y: 50,\n    },\n    background: {\n      x: 50,\n      y: 50,\n    },\n    rotate: {\n      x: 0,\n      y: 0,\n    },\n  });\n  const containerStyle = {\n    \"--m-x\": \"50%\",\n    \"--m-y\": \"50%\",\n    \"--r-x\": \"0deg\",\n    \"--r-y\": \"0deg\",\n    \"--bg-x\": \"50%\",\n    \"--bg-y\": \"50%\",\n    \"--duration\": \"300ms\",\n    \"--foil-size\": \"100%\",\n    \"--opacity\": \"0\",\n    \"--radius\": \"48px\",\n    \"--easing\": \"ease\",\n    \"--transition\": \"var(--duration) var(--easing)\",\n  } as any;\n\n  const backgroundStyle = {\n    \"--step\": \"5%\",\n    \"--foil-svg\": `url(\"data:image/svg+xml,%3Csvg width='26' height='26' viewBox='0 0 26 26' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M2.99994 3.419C2.99994 3.419 21.6142 7.43646 22.7921 12.153C23.97 16.8695 3.41838 23.0306 3.41838 23.0306' stroke='white' stroke-width='5' stroke-miterlimit='3.86874' stroke-linecap='round' style='mix-blend-mode:darken'/%3E%3C/svg%3E\")`,\n    \"--pattern\": \"var(--foil-svg) center/100% no-repeat\",\n    \"--rainbow\":\n      \"repeating-linear-gradient( 0deg,rgb(255,119,115) calc(var(--step) * 1),rgba(255,237,95,1) calc(var(--step) * 2),rgba(168,255,95,1) calc(var(--step) * 3),rgba(131,255,247,1) calc(var(--step) * 4),rgba(120,148,255,1) calc(var(--step) * 5),rgb(216,117,255) calc(var(--step) * 6),rgb(255,119,115) calc(var(--step) * 7) ) 0% var(--bg-y)/200% 700% no-repeat\",\n    \"--diagonal\":\n      \"repeating-linear-gradient( 128deg,#0e152e 0%,hsl(180,10%,60%) 3.8%,hsl(180,10%,60%) 4.5%,hsl(180,10%,60%) 5.2%,#0e152e 10%,#0e152e 12% ) var(--bg-x) var(--bg-y)/300% no-repeat\",\n    \"--shade\":\n      \"radial-gradient( farthest-corner circle at var(--m-x) var(--m-y),rgba(255,255,255,0.1) 12%,rgba(255,255,255,0.15) 20%,rgba(255,255,255,0.25) 120% ) var(--bg-x) var(--bg-y)/300% no-repeat\",\n    backgroundBlendMode: \"hue, hue, hue, overlay\",\n  };\n\n  const updateStyles = () => {\n    if (refElement.current) {\n      console.log(state.current);\n      const { background, rotate, glare } = state.current;\n      refElement.current?.style.setProperty(\"--m-x\", `${glare.x}%`);\n      refElement.current?.style.setProperty(\"--m-y\", `${glare.y}%`);\n      refElement.current?.style.setProperty(\"--r-x\", `${rotate.x}deg`);\n      refElement.current?.style.setProperty(\"--r-y\", `${rotate.y}deg`);\n      refElement.current?.style.setProperty(\"--bg-x\", `${background.x}%`);\n      refElement.current?.style.setProperty(\"--bg-y\", `${background.y}%`);\n    }\n  };\n  return (\n    <div\n      style={containerStyle}\n      className=\"relative isolate [aspect-ratio:17/21] w-[320px] transition-transform delay-[var(--delay)] duration-[var(--duration)] ease-[var(--easing)] will-change-transform [contain:layout_style] [perspective:600px]\"\n      ref={refElement}\n      onPointerMove={(event) => {\n        const rotateFactor = 0.4;\n        const rect = event.currentTarget.getBoundingClientRect();\n        const position = {\n          x: event.clientX - rect.left,\n          y: event.clientY - rect.top,\n        };\n        const percentage = {\n          x: (100 / rect.width) * position.x,\n          y: (100 / rect.height) * position.y,\n        };\n        const delta = {\n          x: percentage.x - 50,\n          y: percentage.y - 50,\n        };\n\n        const { background, rotate, glare } = state.current;\n        background.x = 50 + percentage.x / 4 - 12.5;\n        background.y = 50 + percentage.y / 3 - 16.67;\n        rotate.x = -(delta.x / 3.5);\n        rotate.y = delta.y / 2;\n        rotate.x *= rotateFactor;\n        rotate.y *= rotateFactor;\n        glare.x = percentage.x;\n        glare.y = percentage.y;\n\n        updateStyles();\n      }}\n      onPointerEnter={() => {\n        isPointerInside.current = true;\n        if (refElement.current) {\n          setTimeout(() => {\n            if (isPointerInside.current) {\n              refElement.current?.style.setProperty(\"--duration\", \"0s\");\n            }\n          }, 300);\n        }\n      }}\n      onPointerLeave={() => {\n        isPointerInside.current = false;\n        if (refElement.current) {\n          refElement.current.style.removeProperty(\"--duration\");\n          refElement.current?.style.setProperty(\"--r-x\", `0deg`);\n          refElement.current?.style.setProperty(\"--r-y\", `0deg`);\n        }\n      }}\n    >\n      <div className=\"grid h-full origin-center [transform:rotateY(var(--r-x))_rotateX(var(--r-y))] overflow-hidden rounded-[var(--radius)] border border-slate-800 transition-transform delay-[var(--delay)] duration-[var(--duration)] ease-[var(--easing)] will-change-transform hover:filter-none hover:[--duration:200ms] hover:[--easing:linear] hover:[--opacity:0.6]\">\n        <div className=\"grid h-full w-full mix-blend-soft-light [clip-path:inset(0_0_0_0_round_var(--radius))] [grid-area:1/1]\">\n          <div className={cn(\"h-full w-full bg-slate-950\", className)}>\n            {children}\n          </div>\n        </div>\n        <div className=\"transition-background will-change-background grid h-full w-full opacity-[var(--opacity)] mix-blend-soft-light transition-opacity delay-[var(--delay)] duration-[var(--duration)] ease-[var(--easing)] [background:radial-gradient(farthest-corner_circle_at_var(--m-x)_var(--m-y),_rgba(255,255,255,0.8)_10%,_rgba(255,255,255,0.65)_20%,_rgba(255,255,255,0)_90%)] [clip-path:inset(0_0_1px_0_round_var(--radius))] [grid-area:1/1]\" />\n        <div\n          className=\"will-change-background after:grid-area-[inherit] after:bg-repeat-[inherit] after:bg-attachment-[inherit] after:bg-origin-[inherit] after:bg-clip-[inherit] relative grid h-full w-full opacity-[var(--opacity)] [background-blend-mode:hue_hue_hue_overlay] mix-blend-color-dodge transition-opacity [background:var(--pattern),_var(--rainbow),_var(--diagonal),_var(--shade)] [clip-path:inset(0_0_1px_0_round_var(--radius))] [grid-area:1/1] after:bg-[inherit] after:[background-size:var(--foil-size),_200%_400%,_800%,_200%] after:[background-position:center,_0%_var(--bg-y),_calc(var(--bg-x)*_-1)_calc(var(--bg-y)*_-1),_var(--bg-x)_var(--bg-y)] after:[background-blend-mode:soft-light,_hue,_hard-light] after:mix-blend-exclusion after:content-['']\"\n          style={{ ...backgroundStyle }}\n        />\n      </div>\n    </div>\n  );\n};\n",
      "type": "registry:ui",
      "target": "components/ui/glare-card.tsx"
    }
  ],
  "author": "Manu Arora <hi@manuarora.in>",
  "title": "Glare Card"
}