# Logo cloud 4

> Split layout — stat copy left, blur-to-sharp logo marks with wordmarks on the right.

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

- Page, with a live preview: https://shadcn.exchange/r/nusaiba/logo-cloud-4
- Screenshot: https://abzjhwgwpdpz7ua5.public.blob.vercel-storage.com/shots/nusaiba/logo-cloud-4-light-5eb312bd4d5779bb.png
- Registry item: https://nusaiba.dev/r/base-nova/logo-cloud-4.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-4.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/4/logo-cloud-section.tsx`

```tsx
"use client";

import { motion, 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 logos: Brand[] = [
	{ name: "Atlassian", domain: "atlassian.com" },
	{ name: "HubSpot", domain: "hubspot.com" },
	{ name: "Salesforce", domain: "salesforce.com" },
	{ name: "Zendesk", domain: "zendesk.com" },
	{ name: "Dropbox", domain: "dropbox.com" },
	{ name: "Asana", domain: "asana.com" },
	{ name: "Intercom", domain: "intercom.com" },
	{ name: "Airtable", domain: "airtable.com" },
	{ name: "Monday", domain: "monday.com" },
	{ name: "Miro", domain: "miro.com" },
];

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

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

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

	return (
		<div className="flex h-7 items-center gap-2 md:h-8">
			{src ? (
				<img
					alt=""
					aria-hidden
					className={logoIconClass}
					height={26}
					loading="lazy"
					referrerPolicy="origin"
					src={src}
				/>
			) : null}
			<BrandWordmark
				className={cn(logoWordmarkClass, "text-foreground/85", !src && "opacity-80")}
				domain={brand.domain}
				name={brand.name}
			/>
		</div>
	);
}

export function LogoCloudSplitSection() {
	const reduceMotion = useReducedMotion();

	return (
		<SectionShell spacingMode="compact" className="bg-background">
			<BrandFonts id="logo-cloud-4-brand-fonts" />
			<ContentRail maxWidth="max-w-5xl" className="grid gap-10 md:grid-cols-[minmax(0,0.9fr)_minmax(0,1.1fr)] md:items-center md:gap-14">
				<div className="mx-auto max-w-sm space-y-0 text-center md:mx-0 md:max-w-none md:text-left">
					<motion.p
						className="font-medium text-primary text-xs uppercase tracking-[0.22em]"
						initial={reduceMotion ? false : { opacity: 0, y: 8, filter: "blur(4px)" }}
						transition={defaultSpring}
						viewport={motionViewport}
						whileInView={reduceMotion ? undefined : { opacity: 1, y: 0, filter: "blur(0px)" }}
					>
						Adopted globally
					</motion.p>
					<motion.p
						className="mt-4 font-medium text-5xl tracking-tight tabular-nums md:text-6xl"
						initial={reduceMotion ? false : { opacity: 0, y: 10, filter: "blur(4px)" }}
						transition={{ ...defaultSpring, delay: motionStagger.item }}
						viewport={motionViewport}
						whileInView={reduceMotion ? undefined : { opacity: 1, y: 0, filter: "blur(0px)" }}
					>
						2,000+
					</motion.p>
					<motion.p
						className="mt-2 text-balance font-medium text-lg tracking-tight md:text-xl"
						initial={reduceMotion ? false : { opacity: 0, y: 10, filter: "blur(4px)" }}
						transition={{ ...defaultSpring, delay: motionStagger.item * 2 }}
						viewport={motionViewport}
						whileInView={reduceMotion ? undefined : { opacity: 1, y: 0, filter: "blur(0px)" }}
					>
						teams ship with us
					</motion.p>
					<motion.p
						className="mt-4 max-w-xs text-pretty text-muted-foreground text-sm leading-relaxed md:max-w-sm md:text-base"
						initial={reduceMotion ? false : { opacity: 0, y: 10, filter: "blur(4px)" }}
						transition={{ ...defaultSpring, delay: motionStagger.item * 3 }}
						viewport={motionViewport}
						whileInView={reduceMotion ? undefined : { opacity: 1, y: 0, filter: "blur(0px)" }}
					>
						From startups to public companies — product and engineering teams rely on
						the platform every day.
					</motion.p>
				</div>

				<div className="relative">
					<div
						aria-hidden="true"
						className="pointer-events-none absolute inset-0 z-10 bg-linear-to-r from-background via-transparent to-background md:hidden"
					/>
					<div className="flex flex-wrap items-center justify-center gap-x-6 gap-y-5 sm:gap-x-8 sm:gap-y-6 md:justify-end md:gap-x-8 md:gap-y-7">
						{logos.map((brand, index) => (
							<motion.div
								initial={reduceMotion ? false : { opacity: 0, filter: "blur(8px)" }}
								key={brand.domain}
								transition={{
									...defaultSpring,
									delay: motionStagger.item * 2 + index * motionStagger.item,
								}}
								viewport={motionViewport}
								whileInView={reduceMotion ? undefined : { opacity: 1, filter: "blur(0px)" }}
							>
								<LogoMark brand={brand} />
							</motion.div>
						))}
					</div>
				</div>
			</ContentRail>
		</SectionShell>
	);
}
```
