{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "blinds-mask-reveal",
  "description": "A venetian-blinds mask reveal — the image is hidden behind N slats cut from a repeating-linear-gradient CSS mask, then every slat opens at once to uncover the whole frame.",
  "dependencies": [
    "gsap"
  ],
  "files": [
    {
      "path": "registry/new-york/mask/blinds-mask-reveal.tsx",
      "content": "\"use client\";\n\n/**\n * A venetian-blinds mask reveal — the image is hidden behind N slats cut from a repeating-linear-gradient CSS mask, then every slat opens at once to uncover the whole frame.\n */\n\nimport { useEffect, useRef } from \"react\";\nimport gsap from \"gsap\";\n\nconst SRC = \"/bend-image-reveal.gif\";\nconst SLATS = 8;\n\nexport type SlatOrientation = \"vertical\" | \"horizontal\";\n\nconst BlindsMaskReveal = ({\n  orientation = \"vertical\",\n}: {\n  orientation?: SlatOrientation;\n}) => {\n  const imgRef = useRef<HTMLImageElement>(null);\n\n  const reveal = () => {\n    const img = imgRef.current;\n    if (!img) return;\n    const horizontal = orientation === \"horizontal\";\n    const deg = horizontal ? \"0deg\" : \"90deg\";\n\n    const state = { p: 0 };\n    const apply = () => {\n      const size = horizontal ? img.clientHeight : img.clientWidth;\n      const band = size / SLATS;\n      const open = band * state.p;\n      const mask = `repeating-linear-gradient(${deg}, #000 0 ${open}px, transparent ${open}px ${band}px)`;\n      img.style.maskImage = mask;\n      img.style.webkitMaskImage = mask;\n    };\n    apply();\n\n    const tl = gsap.timeline();\n    tl.to(state, { p: 1, duration: 1.1, ease: \"power3.inOut\", onUpdate: apply });\n    tl.fromTo(\n      img,\n      { scale: 1.4, filter: \"blur(16px)\" },\n      { scale: 1, filter: \"blur(0px)\", duration: 1.1, ease: \"power3.inOut\" },\n      \"<\",\n    );\n  };\n\n  useEffect(() => {\n    reveal();\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [orientation]);\n\n  return (\n    <button\n      onClick={reveal}\n      className=\"relative aspect-video w-[40rem] max-w-[92%] cursor-pointer overflow-hidden rounded-xl\"\n      aria-label=\"Replay reveal\"\n    >\n      <img\n        ref={imgRef}\n        src={SRC}\n        alt=\"reveal\"\n        className=\"size-full object-cover\"\n        style={{\n          maskImage:\n            \"repeating-linear-gradient(90deg, #000 0 0px, transparent 0px 1px)\",\n          WebkitMaskImage:\n            \"repeating-linear-gradient(90deg, #000 0 0px, transparent 0px 1px)\",\n          transform: \"scale(1.4)\",\n          filter: \"blur(16px)\",\n        }}\n      />\n    </button>\n  );\n};\n\nexport default BlindsMaskReveal;\n",
      "type": "registry:component",
      "target": "components/pixel-perfect/blinds-mask-reveal.tsx"
    }
  ],
  "type": "registry:block"
}