{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "retro-grid",
  "type": "registry:component",
  "title": "Retro grid",
  "description": "A retro perspective grid floor that recedes to a glowing horizon and scrolls slowly toward you.",
  "dependencies": [
    "lucide-react",
    "motion"
  ],
  "registryDependencies": [
    "https://ui.minidev.pro/r/button.json",
    "utils"
  ],
  "files": [
    {
      "path": "registry/premium/retro-grid.tsx",
      "type": "registry:ui",
      "target": "components/ui/retro-grid.tsx",
      "content": "\"use client\"\nimport * as React from \"react\"\nimport { useInView, useReducedMotion } from \"motion/react\"\nimport { ArrowRight } from \"lucide-react\"\nimport { cn } from \"@/lib/utils\"\nimport { Button } from \"@/components/ui/button\"\n\n/**\n * A retro perspective grid floor that recedes to a glowing horizon and scrolls slowly toward you.\n * Lines are tinted with the accent and fade out before they reach the\n * horizon, so they never shimmer. The floor sits behind the content, ignores\n * the pointer, pauses off screen and holds still for reduced motion.\n */\ntype RetroGridProps = {\n  /** Tilt of the floor in degrees. Higher is flatter and longer. */\n  angle?: number\n  /** Size of one grid cell in pixels, at the front of the floor. */\n  cellSize?: number\n  /** Cells per second travelled toward the viewer. */\n  speed?: number\n  /** Where the floor meets the sky, as a percent of the height from the top. */\n  horizon?: number\n  className?: string\n  children?: React.ReactNode\n}\n\n/** Camera distance in pixels. Short enough for a strong vanishing point. */\nconst DEPTH = 320\n/** Length of the floor in pixels. Far enough that its end sits on the horizon. */\nconst FLOOR = 3200\n\nfunction RetroGrid({ angle = 68, cellSize = 48, speed = 0.7, horizon = 56, className, children }: RetroGridProps) {\n  const reduce = useReducedMotion()\n  const ref = React.useRef<HTMLDivElement>(null)\n  const inView = useInView(ref, { margin: \"80px\" })\n  const tilt = Math.min(85, Math.max(30, angle))\n  // A floor tilted by `tilt` vanishes DEPTH * cot(tilt) above the perspective origin,\n  // so the origin is pushed down by that much to land the horizon where asked.\n  const lift = DEPTH / Math.tan((tilt * Math.PI) / 180)\n  const fade = `linear-gradient(to bottom, transparent ${horizon}%, black ${Math.min(100, horizon + 26)}%)`\n  const lines = \"linear-gradient(to right, var(--accent-line) 2px, transparent 2px), linear-gradient(to bottom, var(--accent-line) 2px, transparent 2px)\"\n\n  return (\n    <div\n      ref={ref}\n      data-slot=\"retro-grid\"\n      className={cn(\"relative isolate h-[360px] w-full overflow-hidden rounded-2xl border border-border bg-bg\", className)}\n    >\n      <div aria-hidden className=\"pointer-events-none absolute inset-0 z-0\">\n        <div\n          className=\"absolute inset-0\"\n          style={{ background: `radial-gradient(60% 34% at 50% ${horizon}%, var(--accent-soft), transparent 75%)` }}\n        />\n        <div\n          className=\"absolute inset-x-0 h-px\"\n          style={{ top: `${horizon}%`, background: \"linear-gradient(to right, transparent, var(--accent-line) 30%, var(--accent-line) 70%, transparent)\" }}\n        />\n        <div\n          className=\"absolute inset-0 overflow-hidden\"\n          style={{\n            perspective: DEPTH,\n            perspectiveOrigin: `50% calc(${horizon}% + ${lift.toFixed(1)}px)`,\n            maskImage: fade,\n            WebkitMaskImage: fade,\n          }}\n        >\n          <div\n            className=\"absolute bottom-0 left-[-250%] w-[600%]\"\n            style={{ height: FLOOR, transformOrigin: \"50% 100%\", transform: `rotateX(${tilt}deg)` }}\n          >\n            <div\n              data-slot=\"retro-grid-lines\"\n              className=\"absolute inset-x-0 bottom-0 will-change-transform\"\n              style={{\n                top: -cellSize,\n                backgroundImage: lines,\n                backgroundSize: `${cellSize}px ${cellSize}px`,\n                backgroundPosition: \"50% 0\",\n                [\"--retro-cell\" as string]: `${cellSize}px`,\n                animation: reduce || speed <= 0 ? undefined : `retro-grid-scroll ${(1 / speed).toFixed(3)}s linear infinite`,\n                animationPlayState: inView ? \"running\" : \"paused\",\n              }}\n            />\n          </div>\n        </div>\n      </div>\n      <div className=\"relative z-10 h-full\">\n        {children ?? (\n          <div className=\"flex h-full flex-col items-center gap-4 px-6 pt-10 text-center\">\n            <span className=\"rounded-full border border-accent-line bg-accent-soft px-2.5 py-0.5 text-xs font-medium text-accent-fg\">\n              Northwind deploys\n            </span>\n            <p className=\"max-w-[18ch] text-3xl font-medium tracking-[-0.035em] text-balance text-fg\">\n              Every release, right on schedule\n            </p>\n            <Button>\n              View pipeline\n              <ArrowRight />\n            </Button>\n          </div>\n        )}\n      </div>\n      <style>{`@keyframes retro-grid-scroll{to{transform:translateY(var(--retro-cell))}}`}</style>\n    </div>\n  )\n}\n\nexport { RetroGrid }\nexport type { RetroGridProps }\n"
    }
  ]
}
