# Logo cloud 16

> Compact footer logo strip — icons on mobile, wordmarks on desktop.

A shadcn/ui block from the [@nusaiba](https://nusaiba.dev) registry, listed on [shadcn.exchange](https://shadcn.exchange/r/nusaiba/logo-cloud-16).

- Page, with a live preview: https://shadcn.exchange/r/nusaiba/logo-cloud-16
- Screenshot: https://abzjhwgwpdpz7ua5.public.blob.vercel-storage.com/shots/nusaiba/logo-cloud-16-light-f2c5545aab4e9f1b.png
- Registry item: https://nusaiba.dev/r/base-nova/logo-cloud-16.json
- Categories: logo-cloud
- Listed: 2026-10-13, source last changed 2026-10-13

## Install

```bash
npx shadcn@latest add https://nusaiba.dev/r/base-nova/logo-cloud-16.json
```

Run it in a project that has shadcn/ui set up. It adds the files below and installs what they depend on.

## Dependencies

- npm packages: `motion`
- Registry items: `@nusaiba/foundation`, `@nusaiba/brand-typography`

## Files

### `registry/blocks/logo-cloud/16/logo-cloud-section.tsx`

```tsx
"use client";

import { useRef } from "react";
import { motion, useInView, useReducedMotion } from "motion/react";
import { BrandFonts, BrandWordmark } from "@/lib/brand-typography";
import { defaultSpring, motionStagger, motionViewport } from "@/lib/motion-tokens";
import { cn } from "@/lib/utils";
import { SectionShell, ContentRail } from "@/components/layout-contract";

type Brand = { name: string; domain: string };

const brands: Brand[] = [
	{ name: "Stripe", domain: "stripe.com" },
	{ name: "Notion", domain: "notion.so" },
	{ name: "Vercel", domain: "vercel.com" },
	{ name: "Linear", domain: "linear.app" },
	{ name: "Figma", domain: "figma.com" },
	{ name: "Slack", domain: "slack.com" },
];

const logoIconClass =
	"size-6 shrink-0 object-contain md:size-[1.375rem] outline outline-1 -outline-offset-1 outline-black/10 dark:outline-white/10";
const logoWordmarkClass = "text-[0.8125rem] leading-none md:text-[0.875rem]";

function getLogoDevUrl(domain: string) {
	const token = process.env.NEXT_PUBLIC_LOGO_DEV_PUBLISHABLE_KEY;
	if (!token) return null;
	const params = new URLSearchParams({
		token,
		size: "88",
		format: "png",
		retina: "true",
		fallback: "monogram",
	});
	return `https://img.logo.dev/${domain}?${params}`;
}

function FooterLogoMark({ brand }: { brand: Brand }) {
	const src = getLogoDevUrl(brand.domain);

	return (
		<div className="flex h-6 items-center gap-2 md:h-7 md:gap-2.5">
			{src ? (
				<img
					alt=""
					aria-hidden
					className={logoIconClass}
					height={24}
					loading="lazy"
					referrerPolicy="origin"
					src={src}
				/>
			) : (
				<span className="font-medium text-foreground/45 text-xs">{brand.name}</span>
			)}
			<BrandWordmark
				className={cn(
					logoWordmarkClass,
					"hidden text-foreground/80 md:block",
					!src && "block",
				)}
				domain={brand.domain}
				name={brand.name}
			/>
		</div>
	);
}

export function LogoCloudFooterStripSection() {
	const reduceMotion = useReducedMotion();
	const rowRef = useRef<HTMLUListElement>(null);
	const inView = useInView(rowRef, motionViewport);

	const itemVariants = reduceMotion
		? { hidden: { opacity: 1 }, visible: { opacity: 1 } }
		: {
				hidden: { opacity: 0, filter: "blur(4px)", y: 4 },
				visible: { opacity: 1, filter: "blur(0px)", y: 0 },
			};

	return (
		<SectionShell spacingMode="compact" dividerMode="top">
			<BrandFonts id="logo-cloud-16-brand-fonts" />
			<ContentRail maxWidth="max-w-4xl">
				<motion.p
					className="mb-4 text-pretty text-center text-muted-foreground text-xs lowercase tracking-wide md:mb-5"
					initial={reduceMotion ? false : { opacity: 0, y: 6, filter: "blur(4px)" }}
					transition={defaultSpring}
					viewport={motionViewport}
					whileInView={reduceMotion ? undefined : { opacity: 1, y: 0, filter: "blur(0px)" }}
				>
					Also integrates with
				</motion.p>

				<motion.ul
					animate={inView ? "visible" : "hidden"}
					className="flex flex-wrap items-center justify-center gap-x-5 gap-y-3.5 sm:gap-x-7 md:gap-x-9 md:gap-y-4"
					initial="hidden"
					ref={rowRef}
					variants={{
						hidden: {},
						visible: {
							transition: {
								staggerChildren: motionStagger.item,
								delayChildren: 0.02,
							},
						},
					}}
				>
					{brands.map((brand) => (
						<motion.li key={brand.domain} variants={itemVariants}>
							<FooterLogoMark brand={brand} />
						</motion.li>
					))}
				</motion.ul>
			</ContentRail>
		</SectionShell>
	);
}
```
