{"$schema":"https://ui.shadcn.com/schema/registry-item.json","author":"Eduardo Calvo <educlopez93@gmail.com>","css":{},"dependencies":["motion"],"description":"Feature grid block with animated cards","devDependencies":[],"files":[{"content":"\"use client\";\n\nimport { cn } from \"@/lib/utils\";\nimport { motion, useReducedMotion } from \"motion/react\";\nimport { useEffect, useState } from \"react\";\n\nconst SPRING = {\n  bounce: 0.1,\n  duration: 0.25,\n  type: \"spring\" as const,\n};\n\nconst features = [\n  {\n    description:\n      \"Optimized for performance with minimal bundle size and efficient rendering.\",\n    icon: (\n      <svg\n        aria-hidden=\"true\"\n        className=\"h-6 w-6\"\n        fill=\"none\"\n        stroke=\"currentColor\"\n        strokeWidth={1.5}\n        viewBox=\"0 0 24 24\"\n      >\n        <path\n          d=\"m3.75 13.5 10.5-11.25L12 10.5h8.25L9.75 21.75 12 13.5H3.75z\"\n          strokeLinecap=\"round\"\n          strokeLinejoin=\"round\"\n        />\n      </svg>\n    ),\n    title: \"Lightning Fast\",\n  },\n  {\n    description:\n      \"Built with ARIA attributes, keyboard navigation, and reduced motion support.\",\n    icon: (\n      <svg\n        aria-hidden=\"true\"\n        className=\"h-6 w-6\"\n        fill=\"none\"\n        stroke=\"currentColor\"\n        strokeWidth={1.5}\n        viewBox=\"0 0 24 24\"\n      >\n        <path\n          d=\"M12 18v-5.25m0 0a6.01 6.01 0 001.5-.189m-1.5.189a6.01 6.01 0 01-1.5-.189m3.75 7.478a12.06 12.06 0 01-4.5 0m3.75 2.383a14.406 14.406 0 01-3 0M14.25 18v-.192c0-.983.658-1.823 1.508-2.316a7.5 7.5 0 10-7.517 0c.85.493 1.509 1.333 1.509 2.316V18\"\n          strokeLinecap=\"round\"\n          strokeLinejoin=\"round\"\n        />\n      </svg>\n    ),\n    title: \"Accessible\",\n  },\n  {\n    description:\n      \"Fully customizable with Tailwind CSS classes and design tokens.\",\n    icon: (\n      <svg\n        aria-hidden=\"true\"\n        className=\"h-6 w-6\"\n        fill=\"none\"\n        stroke=\"currentColor\"\n        strokeWidth={1.5}\n        viewBox=\"0 0 24 24\"\n      >\n        <path\n          d=\"M9.53 16.122a3 3 0 00-5.78 1.128 2.25 2.25 0 01-2.4 2.245 4.5 4.5 0 008.4-2.245c0-.399-.078-.78-.22-1.128zm0 0a15.998 15.998 0 003.388-1.62m-5.043-.025a15.994 15.994 0 011.622-3.395m3.42 3.42a15.995 15.995 0 004.764-4.648l3.876-5.814a1.151 1.151 0 00-1.597-1.597L14.146 6.32a15.996 15.996 0 00-4.649 4.763m3.42 3.42a6.776 6.776 0 00-3.42-3.42\"\n          strokeLinecap=\"round\"\n          strokeLinejoin=\"round\"\n        />\n      </svg>\n    ),\n    title: \"Customizable\",\n  },\n  {\n    description:\n      \"Full TypeScript support with exported types for all component props.\",\n    icon: (\n      <svg\n        aria-hidden=\"true\"\n        className=\"h-6 w-6\"\n        fill=\"none\"\n        stroke=\"currentColor\"\n        strokeWidth={1.5}\n        viewBox=\"0 0 24 24\"\n      >\n        <path\n          d=\"M17.25 6.75L22.5 12l-5.25 5.25m-10.5 0L1.5 12l5.25-5.25m7.5-3l-4.5 16.5\"\n          strokeLinecap=\"round\"\n          strokeLinejoin=\"round\"\n        />\n      </svg>\n    ),\n    title: \"TypeScript First\",\n  },\n  {\n    description:\n      \"Smooth spring animations powered by Motion with configurable easing.\",\n    icon: (\n      <svg\n        aria-hidden=\"true\"\n        className=\"h-6 w-6\"\n        fill=\"none\"\n        stroke=\"currentColor\"\n        strokeWidth={1.5}\n        viewBox=\"0 0 24 24\"\n      >\n        <path\n          d=\"M9.813 15.904L9 18.75l-.813-2.846a4.5 4.5 0 00-3.09-3.09L2.25 12l2.846-.813a4.5 4.5 0 003.09-3.09L9 5.25l.813 2.846a4.5 4.5 0 003.09 3.09L15.75 12l-2.846.813a4.5 4.5 0 00-3.09 3.09zM18.259 8.715L18 9.75l-.259-1.035a3.375 3.375 0 00-2.455-2.456L14.25 6l1.036-.259a3.375 3.375 0 002.455-2.456L18 2.25l.259 1.035a3.375 3.375 0 002.456 2.456L21.75 6l-1.035.259a3.375 3.375 0 00-2.456 2.456zM16.894 20.567L16.5 21.75l-.394-1.183a2.25 2.25 0 00-1.423-1.423L13.5 18.75l1.183-.394a2.25 2.25 0 001.423-1.423l.394-1.183.394 1.183a2.25 2.25 0 001.423 1.423l1.183.394-1.183.394a2.25 2.25 0 00-1.423 1.423z\"\n          strokeLinecap=\"round\"\n          strokeLinejoin=\"round\"\n        />\n      </svg>\n    ),\n    title: \"Animated\",\n  },\n  {\n    description:\n      \"Free and open source. Install via the shadcn registry with one command.\",\n    icon: (\n      <svg\n        aria-hidden=\"true\"\n        className=\"h-6 w-6\"\n        fill=\"none\"\n        stroke=\"currentColor\"\n        strokeWidth={1.5}\n        viewBox=\"0 0 24 24\"\n      >\n        <path\n          d=\"M21 8.25c0-2.485-2.099-4.5-4.688-4.5-1.935 0-3.597 1.126-4.312 2.733-.715-1.607-2.377-2.733-4.313-2.733C5.1 3.75 3 5.765 3 8.25c0 7.22 9 12 9 12s9-4.78 9-12z\"\n          strokeLinecap=\"round\"\n          strokeLinejoin=\"round\"\n        />\n      </svg>\n    ),\n    title: \"Open Source\",\n  },\n];\n\nexport function FeaturesGrid() {\n  const shouldReduceMotion = useReducedMotion();\n  const [isHoverDevice, setIsHoverDevice] = useState(false);\n\n  useEffect(() => {\n    const mq = window.matchMedia(\"(hover: hover) and (pointer: fine)\");\n    setIsHoverDevice(mq.matches);\n    const handler = (e: MediaQueryListEvent) => setIsHoverDevice(e.matches);\n    mq.addEventListener(\"change\", handler);\n    return () => mq.removeEventListener(\"change\", handler);\n  }, []);\n\n  return (\n    <section aria-labelledby=\"features-grid-heading\">\n      <div className=\"py-24 md:py-32\">\n        <div className=\"mx-auto max-w-6xl px-6\">\n          <div className=\"mx-auto mb-16 max-w-2xl text-center\">\n            <h2\n              className=\"text-balance font-bold text-3xl tracking-tight md:text-4xl\"\n              id=\"features-grid-heading\"\n            >\n              Everything you need to build\n            </h2>\n            <p className=\"mt-4 text-foreground/70 text-lg\">\n              Production-ready components with animations, accessibility, and\n              TypeScript built in.\n            </p>\n          </div>\n          <ul className=\"grid gap-6 sm:grid-cols-2 lg:grid-cols-3\">\n            {features.map((feature, index) => (\n              <motion.li\n                className={cn(\n                  \"rounded-xl border bg-background p-6 transition-shadow\",\n                  isHoverDevice && !shouldReduceMotion && \"hover:shadow-md\"\n                )}\n                initial={\n                  shouldReduceMotion ? { opacity: 1 } : { opacity: 0, y: 20 }\n                }\n                key={feature.title}\n                transition={\n                  shouldReduceMotion\n                    ? { duration: 0 }\n                    : { ...SPRING, delay: index * 0.05 }\n                }\n                viewport={{ margin: \"-100px\", once: true }}\n                whileHover={\n                  isHoverDevice && !shouldReduceMotion ? { y: -4 } : undefined\n                }\n                whileInView={\n                  shouldReduceMotion ? { opacity: 1 } : { opacity: 1, y: 0 }\n                }\n              >\n                <div className=\"mb-4 inline-flex rounded-lg bg-foreground/5 p-2.5 text-foreground\">\n                  {feature.icon}\n                </div>\n                <h3 className=\"mb-2 font-semibold text-foreground\">\n                  {feature.title}\n                </h3>\n                <p className=\"text-foreground/70 text-sm leading-relaxed\">\n                  {feature.description}\n                </p>\n              </motion.li>\n            ))}\n          </ul>\n        </div>\n      </div>\n    </section>\n  );\n}\n\nexport default FeaturesGrid;\n","path":"index.tsx","target":"components/smoothui/features-1/index.tsx","type":"registry:block"}],"name":"features-1","registryDependencies":[],"title":"Features 1","type":"registry:block"}