# Logos Orbit Ring — React Logo Cloud

> Logo chips ride two counter-rotating rings that rise over the horizon behind the headline; each chip counter-spins so its wordmark stays upright.

- Category: [Logo Clouds](https://pixelpapa.com/components/logo-clouds.md)
- Tags: logos, orbit, ring, rotation, social-proof
- Dependencies: none (plus React and Tailwind CSS v4)
- Last updated: 2026-11-13
- Live preview: https://pixelpapa.com/components/logo-clouds/logos-orbit-ring

## Install

```bash
npx shadcn@latest add "https://pixelpapa.com/r/logos-orbit-ring.json"
```

The file is written to `components/pixelpapa/logos-orbit-ring.tsx`. To install manually, copy the source below into your project. It imports `cn` from `@/lib/utils`, which every shadcn project has.

## Source

```tsx
"use client";

import { cn } from "@/lib/utils";

type Logo = { name: string; d: string; cls: string };

// Fictional wordmarks: one 24px glyph path plus a type treatment each.
const logos: Logo[] = [
  { name: "Alderwood", d: "M12 3 22 21H2Z", cls: "font-semibold tracking-tight" },
  { name: "Kestrel", d: "M12 2a10 10 0 1 0 0 20 10 10 0 0 0 0-20Zm0 5a5 5 0 1 1 0 10 5 5 0 0 1 0-10Z", cls: "font-serif text-[1.15em] italic" },
  { name: "TIDELINE", d: "M3 3h12v12H3Zm6 6h12v12H9Z", cls: "text-[0.82em] font-bold tracking-[0.18em]" },
  { name: "basalt", d: "M12 2 22 12 12 22 2 12Z M12 7 7 12l5 5 5-5Z", cls: "font-mono font-medium" },
  { name: "Halden", d: "M3 14h4v7H3Zm7-6h4v13h-4Zm7-5h4v18h-4Z", cls: "font-bold tracking-tighter" },
  { name: "Larkspur", d: "M12 12V2a10 10 0 0 1 10 10Zm0 0v10A10 10 0 0 1 2 12Z", cls: "font-serif text-[1.1em]" },
  { name: "ARCLIGHT", d: "M2 17a10 10 0 0 1 20 0h-5a5 5 0 0 0-10 0Z", cls: "text-[0.82em] font-medium tracking-[0.3em]" },
  { name: "Fieldstone", d: "M12 2l8.66 5v10L12 22l-8.66-5V7Z", cls: "font-medium" },
  { name: "wexford", d: "M9 2h6v7h7v6h-7v7H9v-7H2V9h7Z", cls: "font-semibold tracking-tight" },
  { name: "Marlowe", d: "M8 5a7 7 0 1 0 0 14A7 7 0 0 0 8 5Zm8 0a7 7 0 1 1 0 14 7 7 0 0 1 0-14Z", cls: "font-serif text-[1.15em] italic" },
];

function Wordmark({ logo, className }: { logo: Logo; className?: string }) {
  return (
    <span className={cn("inline-flex items-center gap-2.5 text-xl whitespace-nowrap", className)}>
      <svg viewBox="0 0 24 24" fill="currentColor" fillRule="evenodd" aria-hidden className="size-[1.2em] shrink-0">
        <path d={logo.d} />
      </svg>
      <span className={logo.cls}>{logo.name}</span>
    </span>
  );
}

function Ring({ items, radius, duration, reverse }: { items: Logo[]; radius: number; duration: number; reverse?: boolean }) {
  const spin = (dir: "normal" | "reverse") => `pp-logos-orbit-ring-spin ${duration}s linear infinite ${dir}`;
  return (
    <div
      className="absolute top-full left-1/2 rounded-full border border-border motion-reduce:[animation-play-state:paused]"
      style={{ width: radius * 2, height: radius * 2, marginLeft: -radius, marginTop: -radius + 40, animation: spin(reverse ? "reverse" : "normal") }}
    >
      {items.map((logo, i) => {
        const angle = (360 / items.length) * i;
        return (
          // arm rotates the chip to its slot; the two inner layers undo the slot angle and the ring's spin.
          <div key={logo.name} className="absolute inset-0" style={{ transform: `rotate(${angle}deg)` }}>
            <div className="absolute top-0 left-1/2 size-0" style={{ transform: `rotate(${-angle}deg)` }}>
              <div className="absolute motion-reduce:[animation-play-state:paused]" style={{ animation: spin(reverse ? "normal" : "reverse") }}>
                <span className="absolute flex h-11 -translate-x-1/2 -translate-y-1/2 items-center rounded-full border border-border bg-card px-4 shadow-md shadow-primary/5">
                  <Wordmark logo={logo} className="text-sm text-foreground/80 sm:text-base" />
                </span>
              </div>
            </div>
          </div>
        );
      })}
    </div>
  );
}

export default function LogosOrbitRing() {
  return (
    <section className="w-full overflow-hidden bg-background pt-16">
      <style>{`@keyframes pp-logos-orbit-ring-spin { to { transform: rotate(360deg); } }`}</style>
      <div className="relative mx-auto h-[540px] max-w-[1400px]">
        {/* Only the orbit layer is masked, so the headline stays fully opaque. */}
        <div aria-hidden className="absolute inset-0 overflow-hidden [mask-image:linear-gradient(to_bottom,black_55%,transparent_92%)]">
          <Ring items={logos} radius={560} duration={110} />
          <Ring items={[...logos.slice(5), ...logos.slice(0, 3)]} radius={380} duration={80} reverse />
        </div>
        <div aria-hidden className="absolute inset-x-0 bottom-0 h-56 [background:radial-gradient(50%_100%_at_50%_100%,color-mix(in_oklch,var(--primary)_16%,transparent),transparent)]" />
        <div aria-hidden className="absolute inset-x-0 bottom-0 h-px bg-gradient-to-r from-transparent via-primary/50 to-transparent" />
        <div className="absolute inset-x-0 bottom-0 flex justify-center px-6 pb-14">
          <div className="max-w-sm text-center">
            <p className="text-xs font-medium tracking-[0.2em] text-primary uppercase">In orbit</p>
            <h2 className="mt-3 text-3xl font-semibold tracking-tight text-balance text-foreground sm:text-4xl">
              2,600 teams revolve around Tessel
            </h2>
            <p className="mt-3 text-sm text-muted-foreground">From two-person studios to public companies, shipping UI on the same primitives.</p>
            <a href="#" className="mt-5 inline-flex h-10 items-center rounded-full border border-border bg-card px-5 text-sm font-medium text-foreground transition-colors hover:bg-muted">
              Read their stories
            </a>
          </div>
        </div>
      </div>
    </section>
  );
}
```

## AI prompt

```text
Add the "Logos Orbit Ring" component from PixelPapa UI to this project.

What it is: Logo chips ride two counter-rotating rings that rise over the horizon behind the headline; each chip counter-spins so its wordmark stays upright.
Category: Logo Clouds. Depends on: no extra packages.

1. Install it with the shadcn CLI:
   npx shadcn@latest add "https://pixelpapa.com/r/logos-orbit-ring.json"
   (If the CLI is unavailable, fetch that URL, write files[0].content to components/pixelpapa/logos-orbit-ring.tsx and install the listed dependencies.)
2. Import it from "@/components/pixelpapa/logos-orbit-ring" and place it where I describe below.
3. Keep its animation timings and accessibility attributes. Replace the demo copy and data with content that fits my product, and use my existing theme tokens (bg-background, text-foreground, bg-primary, border-border) rather than hard-coded colours.

Where to use it: <describe the page and position here>
```

## More logo clouds

- [Logos Grid Hover Reveal](https://pixelpapa.com/components/logo-clouds/logos-grid-hover-reveal.md) (Pro): A bordered logo grid where each cell rolls its wordmark up and away on hover or focus to reveal that customer's headline result and a case-study link.
- [Logos Marquee Fade](https://pixelpapa.com/components/logo-clouds/logos-marquee-fade.md): A single row of wordmarks drifting left forever, masked to fade at both edges; hovering slows the belt and lifts the logo under the cursor.
- [Logos Spotlight Swap](https://pixelpapa.com/components/logo-clouds/logos-spotlight-swap.md) (Pro): Six fixed cells that take turns swapping their wordmark: every couple of seconds one cell blurs out its logo and focuses a new one from the pool.
- [Logos Two Row Opposing Marquee](https://pixelpapa.com/components/logo-clouds/logos-two-row-opposing-marquee.md): Two rows of logo chips glide in opposite directions; page scroll pushes them further apart in each direction, so the rows shear as you move.
- [Logos With Stat Header](https://pixelpapa.com/components/logo-clouds/logos-with-stat-header.md) (Pro): A logo strip led by a counting headline figure; the stat counts up on view, then the wordmarks rise in one by one along a hairline rule.
