{"$schema":"https://ui.shadcn.com/schema/registry-item.json","author":"Eduardo Calvo <educlopez93@gmail.com>","css":{},"dependencies":["motion"],"description":"Animated logo cloud block with infinite scroll","devDependencies":[],"files":[{"content":"\"use client\";\n\nimport { motion, useReducedMotion } from \"motion/react\";\nimport type React from \"react\";\nimport {\n  Canpoy,\n  Canva,\n  Casetext,\n  Clearbit,\n  Descript,\n  Duolingo,\n  Faire,\n  Strava,\n} from \"@/components/smoothui/shared\";\n\nconst ANIMATION_DURATION = 25;\nconst STAGGER_DELAY = 0.1;\nconst HOVER_SCALE = 1.2;\nconst HOVER_ROTATE = 5;\nconst SPRING_STIFFNESS = 300;\nconst SCROLL_DISTANCE_FACTOR = 33.333;\n\ninterface LogoCloudAnimatedProps {\n  description?: string;\n  logos?: Array<{\n    name: string;\n    logo: React.ComponentType;\n    url?: string;\n  }>;\n  title?: string;\n}\n\nexport function LogoCloudAnimated({\n  title = \"Trusted by the world's most innovative teams\",\n  description = \"Join thousands of developers and designers who are already building with Smoothui\",\n  logos = [\n    { logo: Canpoy, name: \"Canpoy\", url: \"https://canpoy.com\" },\n    { logo: Canva, name: \"Canva\", url: \"https://canva.com\" },\n    { logo: Casetext, name: \"Casetext\", url: \"https://casetext.com\" },\n    { logo: Strava, name: \"Strava\", url: \"https://strava.com\" },\n    { logo: Descript, name: \"Descript\", url: \"https://descript.com\" },\n    { logo: Duolingo, name: \"Duolingo\", url: \"https://duolingo.com\" },\n    { logo: Faire, name: \"Faire\", url: \"https://faire.com\" },\n    { logo: Clearbit, name: \"Clearbit\", url: \"https://clearbit.com\" },\n  ],\n}: LogoCloudAnimatedProps) {\n  const shouldReduceMotion = useReducedMotion();\n  return (\n    <section className=\"overflow-hidden py-20\">\n      <div className=\"mx-auto max-w-7xl px-6\">\n        <motion.div\n          animate={shouldReduceMotion ? { opacity: 1 } : { opacity: 1, y: 0 }}\n          className=\"mb-16 text-center\"\n          initial={shouldReduceMotion ? { opacity: 1 } : { opacity: 0, y: 20 }}\n          transition={shouldReduceMotion ? { duration: 0 } : { duration: 0.6 }}\n        >\n          <h2 className=\"mb-4 font-bold text-2xl text-foreground lg:text-3xl\">\n            {title}\n          </h2>\n          <p className=\"text-foreground/70 text-lg\">{description}</p>\n        </motion.div>\n        {/* Infinite scrolling logos */}\n        <div\n          className=\"relative overflow-hidden\"\n          style={{\n            maskImage:\n              \"linear-gradient(to right, hsl(0 0% 0% / 0), hsl(0 0% 0% / 1) 20%, hsl(0 0% 0% / 1) 80%, hsl(0 0% 0% / 0))\",\n            WebkitMaskImage:\n              \"linear-gradient(to right, hsl(0 0% 0% / 0), hsl(0 0% 0% / 1) 20%, hsl(0 0% 0% / 1) 80%, hsl(0 0% 0% / 0))\",\n          }}\n        >\n          <motion.div\n            animate={\n              shouldReduceMotion\n                ? { x: 0 }\n                : { x: [0, -SCROLL_DISTANCE_FACTOR * logos.length] }\n            }\n            className=\"flex min-w-full shrink-0 items-center justify-around gap-8\"\n            transition={\n              shouldReduceMotion\n                ? { duration: 0 }\n                : {\n                    x: {\n                      duration: ANIMATION_DURATION,\n                      ease: \"linear\",\n                      repeat: Number.POSITIVE_INFINITY,\n                      repeatType: \"loop\",\n                    },\n                  }\n            }\n          >\n            {/* First set */}\n            {logos.map((logo, index) => (\n              <motion.a\n                animate={\n                  shouldReduceMotion ? { opacity: 1 } : { opacity: 1, scale: 1 }\n                }\n                aria-label={`Visit ${logo.name}`}\n                className=\"group flex shrink-0 flex-col items-center justify-center p-6 transition-all hover:scale-105\"\n                href={logo.url}\n                initial={\n                  shouldReduceMotion\n                    ? { opacity: 1 }\n                    : { opacity: 0, scale: 0.8 }\n                }\n                key={`first-${logo.name}`}\n                rel=\"noopener noreferrer\"\n                target=\"_blank\"\n                transition={\n                  shouldReduceMotion\n                    ? { duration: 0 }\n                    : {\n                        delay: index * STAGGER_DELAY,\n                        duration: 0.4,\n                      }\n                }\n              >\n                <motion.div\n                  className=\"mb-2 text-4xl *:fill-foreground\"\n                  transition={\n                    shouldReduceMotion\n                      ? { duration: 0 }\n                      : { stiffness: SPRING_STIFFNESS, type: \"spring\" as const }\n                  }\n                  whileHover={\n                    shouldReduceMotion\n                      ? {}\n                      : { rotate: HOVER_ROTATE, scale: HOVER_SCALE }\n                  }\n                >\n                  <logo.logo />\n                </motion.div>\n              </motion.a>\n            ))}\n            {/* Second set for seamless loop */}\n            {logos.map((logo, index) => (\n              <motion.a\n                animate={\n                  shouldReduceMotion ? { opacity: 1 } : { opacity: 1, scale: 1 }\n                }\n                aria-label={`Visit ${logo.name}`}\n                className=\"group flex shrink-0 flex-col items-center justify-center p-6 transition-all hover:scale-105\"\n                href={logo.url}\n                initial={\n                  shouldReduceMotion\n                    ? { opacity: 1 }\n                    : { opacity: 0, scale: 0.8 }\n                }\n                key={`second-${logo.name}`}\n                rel=\"noopener noreferrer\"\n                target=\"_blank\"\n                transition={\n                  shouldReduceMotion\n                    ? { duration: 0 }\n                    : { delay: index * STAGGER_DELAY, duration: 0.4 }\n                }\n              >\n                <motion.div\n                  className=\"mb-2 text-4xl *:fill-foreground\"\n                  transition={\n                    shouldReduceMotion\n                      ? { duration: 0 }\n                      : { stiffness: SPRING_STIFFNESS, type: \"spring\" as const }\n                  }\n                  whileHover={\n                    shouldReduceMotion\n                      ? {}\n                      : { rotate: HOVER_ROTATE, scale: HOVER_SCALE }\n                  }\n                >\n                  <logo.logo />\n                </motion.div>\n              </motion.a>\n            ))}\n            {/* Third set for even smoother loop */}\n            {logos.map((logo, index) => (\n              <motion.a\n                animate={\n                  shouldReduceMotion ? { opacity: 1 } : { opacity: 1, scale: 1 }\n                }\n                aria-label={`Visit ${logo.name}`}\n                className=\"group flex shrink-0 flex-col items-center justify-center p-6 transition-all hover:scale-105\"\n                href={logo.url}\n                initial={\n                  shouldReduceMotion\n                    ? { opacity: 1 }\n                    : { opacity: 0, scale: 0.8 }\n                }\n                key={`third-${logo.name}`}\n                rel=\"noopener noreferrer\"\n                target=\"_blank\"\n                transition={\n                  shouldReduceMotion\n                    ? { duration: 0 }\n                    : { delay: index * STAGGER_DELAY, duration: 0.4 }\n                }\n              >\n                <motion.div\n                  className=\"mb-2 text-4xl *:fill-foreground\"\n                  transition={\n                    shouldReduceMotion\n                      ? { duration: 0 }\n                      : { stiffness: SPRING_STIFFNESS, type: \"spring\" as const }\n                  }\n                  whileHover={\n                    shouldReduceMotion\n                      ? {}\n                      : { rotate: HOVER_ROTATE, scale: HOVER_SCALE }\n                  }\n                >\n                  <logo.logo />\n                </motion.div>\n              </motion.a>\n            ))}\n          </motion.div>\n        </div>\n      </div>\n    </section>\n  );\n}\n\nexport default LogoCloudAnimated;\n","path":"index.tsx","target":"components/smoothui/logo-cloud-2/index.tsx","type":"registry:block"}],"name":"logo-cloud-2","registryDependencies":["https://smoothui.dev/r/shared.json"],"title":"Logo Cloud 2","type":"registry:block"}