Getting Started
Templates
Blocks
Components
For solo developers, indie hackers, and freelancers shipping their own products. Pay once, keep everything forever.
Instant download · No subscription · Lifetime access
For small teams, agencies, and freelancers shipping multiple client products. Lifetime access for everyone on your team.
Instant CLI token for 5 seats · Onboarding included · Invoice on request
pnpm dlx shadcn@latest add @ruixenui-pro/logo-cloud-underlineWhen a category becomes active, a single absolutely-positioned <span> mounts behind the text — bg-foreground/10 rounded-md extending past the word so it reads as a tight chip.
-inset-x-1.5 -inset-y-0.5The pill animates in with starting:scale-95 starting:opacity-0 → scale-100 opacity-100 over 500ms, compiled from Tailwind v4's starting: variant (CSS @starting-style). Because the pill only mounts while its category is active, every cycle replays the entry: the outgoing pill unmounts (snaps away cleanly with no exit animation), and the incoming pill mounts fresh, triggering @starting-style again.
The text color transition lives on the outer persistent span (text-muted-foreground/70 → text-foreground over 300ms), so the word color shifts smoothly while the pill pops in behind it.
IntersectionObserver while the section is offscreen.AnimatePresence).brightness-0 dark:invert keeps logos consistent across themes.sm upward.CATEGORIES at the top of the file declares the four category groups. Each entry holds a key (used internally for React keys), a label rendered in the description sentence, and an array of six logo descriptors with explicit file extensions so SVG and PNG can be mixed freely.
const CATEGORIES = [
{
key: "saas",
label: "SaaS founders",
logos: [
{ name: "your-logo", ext: "svg", alt: "Your Logo" },
// ...
],
},
// ...
]Place asset files under /public/logos/ and reference them by name and ext — the component constructs the URL as /logos/${name}.${ext}.