{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "components-logoclouds-logocloud-4",
  "title": "Logo Cloud 4",
  "description": "CSS-animated logo carousel that cycles groups with blur and slide transitions.",
  "files": [
    {
      "path": "registry/components/logoclouds/logocloud-4/index.tsx",
      "content": "'use client';\n\nimport { cn } from '@/lib/utils';\nimport * as React from 'react';\n\nconst KEYFRAMES = `\n  @keyframes logos-enter {\n    from { transform: translateY(32px); filter: blur(4px); opacity: 0; }\n    to   { transform: translateY(0);    filter: blur(0px); opacity: 1; }\n  }\n  @keyframes logos-exit {\n    from { transform: translateY(0);     filter: blur(0px); opacity: 1; }\n    to   { transform: translateY(-32px); filter: blur(4px); opacity: 0; }\n  }\n`;\n\ntype LogoItem = {\n  name: string;\n  svg: React.ReactNode;\n};\n\ntype LogosCarouselProps = {\n  logos: LogoItem[];\n  count?: number;\n  stagger?: number;\n  duration?: number;\n  interval?: number;\n  initialDelay?: number;\n  className?: string;\n  label?: string;\n};\n\nexport default function LogosCarousel({\n  logos,\n  count = 4,\n  stagger = 0.1,\n  duration = 500,\n  interval = 2500,\n  initialDelay = 800,\n  className,\n  label,\n}: LogosCarouselProps) {\n  const [groupIndex, setGroupIndex] = React.useState(0);\n  const [active, setActive] = React.useState(false);\n\n  const groups = React.useMemo<LogoItem[][]>(() => {\n    const result: LogoItem[][] = [];\n    for (let i = 0; i < logos.length; i += count) {\n      result.push(logos.slice(i, i + count));\n    }\n    return result;\n  }, [logos, count]);\n\n  const groupCount = groups.length;\n  const nextIndex = (groupIndex + 1) % groupCount;\n\n  React.useEffect(() => {\n    const t = setTimeout(() => setActive(true), initialDelay);\n    return () => clearTimeout(t);\n  }, [initialDelay]);\n\n  React.useEffect(() => {\n    if (!active || groupCount < 2) return;\n    const id = setInterval(\n      () => setGroupIndex((prev) => (prev + 1) % groupCount),\n      interval,\n    );\n    return () => clearInterval(id);\n  }, [active, interval, groupCount]);\n\n  if (groupCount === 0) return null;\n\n  return (\n    <section className=\"bg-background py-16\">\n      <div className=\"m-auto max-w-7xl px-6\">\n        {label && (\n          <p className=\"mb-8 text-center text-sm text-muted-foreground\">\n            {label}\n          </p>\n        )}\n        <style>{KEYFRAMES}</style>\n        <div className={cn('grid w-full place-items-center', className)}>\n          {groups.map((group, gi) => {\n            const isCurrent = gi === groupIndex;\n            const isNext = active && gi === nextIndex;\n            const visible = isCurrent || isNext;\n\n            return (\n              <div\n                key={gi}\n                className=\"flex w-full justify-center gap-10\"\n                style={{\n                  gridArea: '1 / 1',\n                  pointerEvents: visible ? 'auto' : 'none',\n                }}\n              >\n                {group.map((logo, li) => (\n                  <AnimatedLogo\n                    key={logo.name}\n                    animate={active && visible}\n                    state={isCurrent ? 'exit' : 'enter'}\n                    index={li}\n                    stagger={stagger}\n                    duration={duration}\n                  >\n                    <span aria-label={logo.name} className=\"flex items-center\">\n                      {logo.svg}\n                    </span>\n                  </AnimatedLogo>\n                ))}\n              </div>\n            );\n          })}\n        </div>\n      </div>\n    </section>\n  );\n}\n\ntype AnimatedLogoProps = {\n  children: React.ReactNode;\n  animate: boolean;\n  state: 'enter' | 'exit';\n  index: number;\n  stagger: number;\n  duration: number;\n};\n\nfunction AnimatedLogo({\n  children,\n  animate,\n  state,\n  index,\n  stagger,\n  duration,\n}: AnimatedLogoProps) {\n  const style: React.CSSProperties = animate\n    ? {\n        animationName: state === 'enter' ? 'logos-enter' : 'logos-exit',\n        animationDelay: `${index * stagger}s`,\n        animationDuration: `${duration}ms`,\n        animationFillMode: 'both',\n        animationTimingFunction: 'ease',\n      }\n    : { opacity: state === 'exit' ? 1 : 0 };\n\n  return <div style={style}>{children}</div>;\n}\n",
      "type": "registry:ui",
      "target": "components/odysseyui/logocloud-4.tsx"
    }
  ],
  "type": "registry:ui"
}