{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "orbit",
  "title": "Orbit",
  "description": "Icons orbiting a center on dashed tracks.",
  "dependencies": [],
  "registryDependencies": [
    "utils",
    "https://ui.cuelark.com/r/theme.json",
    "https://ui.cuelark.com/r/motion.json"
  ],
  "files": [
    {
      "path": "src/registry/cuelark/ui/orbit.tsx",
      "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport { gsap, motionScale, useGSAP } from \"@/lib/motion\";\nimport { cn } from \"@/lib/utils\";\n\ntype OrbitProps = React.ComponentProps<\"div\"> & {\n  /** Orbit radius in px. */\n  radius?: number;\n  /** Seconds per revolution. */\n  duration?: number;\n  reverse?: boolean;\n  /** Draw the dashed track. */\n  path?: boolean;\n};\n\n/**\n * Children orbit the center at even spacing on a dashed track (integrations, avatars, logos). Items stay upright\n * while the ring turns; hover slows the whole system down. Nest several Orbits for multiple rings.\n * The radius shrinks to fit narrow containers (a size container query), so rings never spill off a phone screen.\n */\nfunction Orbit({ className, radius = 110, duration = 24, reverse = false, path = true, children, ...props }: OrbitProps) {\n  const ref = React.useRef<HTMLDivElement>(null);\n  const items = React.Children.toArray(children);\n  const tween = React.useRef<gsap.core.Tween | null>(null);\n\n  useGSAP(\n    () => {\n      const el = ref.current;\n      const ring = el?.querySelector<HTMLElement>('[data-slot=\"orbit-ring\"]');\n      if (!el || !ring || !motionScale(el)) return;\n      const dir = reverse ? -1 : 1;\n      tween.current = gsap.to(ring, {\n        rotate: 360 * dir,\n        duration,\n        ease: \"none\",\n        repeat: -1,\n        onUpdate: () => {\n          const angle = Number(gsap.getProperty(ring, \"rotate\"));\n          ring.querySelectorAll<HTMLElement>('[data-slot=\"orbit-item\"]').forEach((i) => gsap.set(i, { rotate: -angle }));\n        },\n      });\n    },\n    { scope: ref, dependencies: [duration, reverse] },\n  );\n\n  return (\n    <div\n      ref={ref}\n      data-slot=\"orbit\"\n      className={cn(\"pointer-events-none absolute inset-0 [container-type:size]\", className)}\n      // Requested radius, capped at half the container's short side minus room for the items.\n      style={{ \"--orbit-r\": `min(${radius}px, 50cqmin - 1.5rem)` } as React.CSSProperties}\n      onPointerEnter={() => tween.current && gsap.to(tween.current, { timeScale: 0.25, duration: 0.6 })}\n      onPointerLeave={() => tween.current && gsap.to(tween.current, { timeScale: 1, duration: 0.6 })}\n      {...props}\n    >\n      {path && <div aria-hidden=\"true\" className=\"absolute top-1/2 left-1/2 size-[calc(var(--orbit-r)*2)] -m-(--orbit-r) rounded-full border border-dashed border-border\" />}\n      {/* Centered with negative margins, not translate: GSAP owns this element's transform for the rotation. */}\n      <div data-slot=\"orbit-ring\" className=\"absolute top-1/2 left-1/2 size-[calc(var(--orbit-r)*2)] -m-(--orbit-r)\">\n        {items.map((child, i) => {\n          const a = (i / items.length) * Math.PI * 2;\n          return (\n            <div key={i} className=\"pointer-events-auto absolute\" style={{ left: `calc(var(--orbit-r) * ${1 + Math.cos(a)})`, top: `calc(var(--orbit-r) * ${1 + Math.sin(a)})`, transform: \"translate(-50%, -50%)\" }}>\n              <div data-slot=\"orbit-item\">{child}</div>\n            </div>\n          );\n        })}\n      </div>\n    </div>\n  );\n}\n\nexport { Orbit };\nexport type { OrbitProps };\n",
      "type": "registry:ui"
    }
  ],
  "docs": "Docs and examples: https://ui.cuelark.com/components/orbit",
  "categories": [
    "effects"
  ],
  "type": "registry:ui"
}