{"$schema":"https://ui.shadcn.com/schema/registry-item.json","author":"Eduardo Calvo <educlopez93@gmail.com>","css":{},"dependencies":["lucide-react","motion"],"description":"Modern header block with navigation and mobile menu","devDependencies":[],"files":[{"content":"\"use client\";\n\nimport { ExternalLink } from \"lucide-react\";\nimport { useEffect, useRef, useState } from \"react\";\nimport { AnimatedGroup, AnimatedText, Button, HeroHeader } from \"@/components/smoothui/shared\";\nimport styles from \"./hero-grid.module.css\";\n\nconst CELL_SIZE = 120; // px\nconst COLORS = [\n  \"oklch(0.72 0.2 352.53)\", // blue\n  \"#A764FF\",\n  \"#4B94FD\",\n  \"#FD4B4E\",\n  \"#FF8743\",\n];\n\nfunction getRandomColor() {\n  return COLORS[Math.floor(Math.random() * COLORS.length)];\n}\n\nfunction SubGrid() {\n  const [cellColors, setCellColors] = useState<(string | null)[]>([\n    null,\n    null,\n    null,\n    null,\n  ]);\n  // Add refs for leave timeouts\n  const leaveTimeouts = useRef<(NodeJS.Timeout | null)[]>([\n    null,\n    null,\n    null,\n    null,\n  ]);\n\n  function handleHover(cellIdx: number) {\n    // Clear any pending timeout for this cell\n    const timeout = leaveTimeouts.current[cellIdx];\n    if (timeout) {\n      clearTimeout(timeout);\n      leaveTimeouts.current[cellIdx] = null;\n    }\n    setCellColors((prev) =>\n      prev.map((c, i) => (i === cellIdx ? getRandomColor() : c))\n    );\n  }\n  function handleLeave(cellIdx: number) {\n    // Add a small delay before removing the color\n    leaveTimeouts.current[cellIdx] = setTimeout(() => {\n      setCellColors((prev) => prev.map((c, i) => (i === cellIdx ? null : c)));\n      leaveTimeouts.current[cellIdx] = null;\n    }, 120);\n  }\n  // Cleanup on unmount\n  useEffect(\n    () => () => {\n      for (const t of leaveTimeouts.current) {\n        if (t) {\n          clearTimeout(t);\n        }\n      }\n    },\n    []\n  );\n\n  return (\n    <div className={styles.subgrid} style={{ pointerEvents: \"none\" }}>\n      {[0, 1, 2, 3].map((cellIdx) => (\n        <button\n          className={styles.cell}\n          key={cellIdx}\n          onMouseEnter={() => handleHover(cellIdx)}\n          onMouseLeave={() => handleLeave(cellIdx)}\n          style={{\n            background: cellColors[cellIdx] || \"transparent\",\n            pointerEvents: \"auto\",\n          }}\n          type=\"button\"\n        />\n      ))}\n    </div>\n  );\n}\n\nfunction InteractiveGrid() {\n  const containerRef = useRef<HTMLDivElement>(null);\n  const [grid, setGrid] = useState({ columns: 0, rows: 0 });\n\n  useEffect(() => {\n    function updateGrid() {\n      if (containerRef.current) {\n        const { width, height } = containerRef.current.getBoundingClientRect();\n        setGrid({\n          columns: Math.ceil(width / CELL_SIZE),\n          rows: Math.ceil(height / CELL_SIZE),\n        });\n      }\n    }\n    updateGrid();\n    window.addEventListener(\"resize\", updateGrid);\n    return () => window.removeEventListener(\"resize\", updateGrid);\n  }, []);\n\n  const total = grid.columns * grid.rows;\n\n  return (\n    <div\n      aria-hidden=\"true\"\n      className=\"pointer-events-none absolute inset-0 z-0\"\n      ref={containerRef}\n      style={{ height: \"100%\", width: \"100%\" }}\n    >\n      <div\n        className={styles.mainGrid}\n        style={\n          {\n            \"--grid-cell-size\": `${CELL_SIZE}px`,\n            gridTemplateColumns: `repeat(${grid.columns}, 1fr)`,\n            gridTemplateRows: `repeat(${grid.rows}, 1fr)`,\n            height: \"100%\",\n            width: \"100%\",\n          } as React.CSSProperties\n        }\n      >\n        {Array.from({ length: total }, (_, idx) => (\n          <SubGrid key={`subgrid-${grid.columns}-${grid.rows}-${idx}`} />\n        ))}\n      </div>\n    </div>\n  );\n}\n\nexport function HeroGrid() {\n  return (\n    <div className=\"relative\">\n      <HeroHeader />\n      <main>\n        <section className=\"relative overflow-hidden py-36\">\n          {/* Interactive animated grid background */}\n          <InteractiveGrid />\n          <AnimatedGroup\n            className=\"pointer-events-none flex flex-col items-center gap-6 text-center\"\n            preset=\"blur-slide\"\n          >\n            <div>\n              <AnimatedText\n                as=\"h1\"\n                className=\"mb-6 text-pretty font-bold text-2xl tracking-tight lg:text-5xl\"\n              >\n                Build your next project with{\" \"}\n                <span className=\"text-brand\">Smoothui</span>\n              </AnimatedText>\n              <AnimatedText\n                as=\"p\"\n                className=\"mx-auto max-w-3xl text-muted-foreground lg:text-xl\"\n                delay={0.15}\n              >\n                Smoothui gives you the building blocks to create stunning,\n                animated interfaces in minutes.\n              </AnimatedText>\n            </div>\n            <AnimatedGroup\n              className=\"pointer-events-auto mt-6 flex justify-center gap-3\"\n              preset=\"slide\"\n            >\n              <Button\n                className=\"shadow-sm transition-shadow hover:shadow\"\n                variant=\"outline\"\n              >\n                Get Started\n              </Button>\n              <Button className=\"group\" variant=\"candy\">\n                Learn more{\" \"}\n                <ExternalLink className=\"ml-2 h-4 transition-transform group-hover:translate-x-0.5\" />\n              </Button>\n            </AnimatedGroup>\n          </AnimatedGroup>\n        </section>\n      </main>\n    </div>\n  );\n}\n\nexport default HeroGrid;\n","path":"index.tsx","target":"components/smoothui/header-1/index.tsx","type":"registry:block"},{"content":"/* @reference \"../../../../app/styles/smoothui.css\"; */\n\n.mainGrid {\n  position: absolute;\n  top: 0;\n  left: 0;\n  display: grid;\n  width: 100%;\n  height: 100%;\n  pointer-events: auto;\n  border-top: 1px solid var(--color-smooth-200);\n  border-right: 1px solid var(--color-smooth-200);\n  opacity: 1;\n  transition: opacity 300ms;\n  will-change: transform;\n}\n\n.subgrid {\n  position: relative;\n  display: grid;\n  grid-template-rows: repeat(2, 1fr);\n  grid-template-columns: repeat(2, 1fr);\n  width: var(--grid-cell-size);\n  height: var(--grid-cell-size);\n  pointer-events: auto;\n  user-select: none;\n  border-top: 1px solid var(--color-smooth-200);\n  border-right: 1px solid var(--color-smooth-200);\n}\n\n.cell {\n  width: 100%;\n  height: 100%;\n  pointer-events: auto;\n  transition: background 3000ms cubic-bezier(0.23, 1, 0.32, 1);\n}\n\n.cell:nth-child(1) {\n  border-right: 1px solid var(--color-smooth-200);\n}\n.cell:nth-child(3) {\n  border-top: 1px solid var(--color-smooth-200);\n  border-right: 1px solid var(--color-smooth-200);\n}\n.cell:nth-child(4) {\n  border-top: 1px solid var(--color-smooth-200);\n}\n\n/* Reduce overlay size of hero text/button containers */\n.heroContent {\n  display: flex;\n  flex-direction: column;\n  align-items: flex-start;\n  max-width: 600px;\n  padding: 0;\n  margin: 0 auto;\n  background: none;\n  box-shadow: none;\n}\n\n.heroButtons {\n  display: flex;\n  gap: 1rem;\n  width: auto;\n  padding: 0;\n  margin-top: 1.5rem;\n  background: none;\n  box-shadow: none;\n}\n","path":"hero-grid.module.css","target":"components/smoothui/header-1/hero-grid.module.css","type":"registry:block"}],"name":"header-1","registryDependencies":["https://smoothui.dev/r/shared.json","https://smoothui.dev/r/tokens.json"],"title":"Header 1","type":"registry:block"}