# Logo 3

> logo

A shadcn/ui block from the [@cnippet-blocks](https://blocks.cnippet.dev/?utm_source=shadcn.exchange) registry, listed on [shadcn.exchange](https://shadcn.exchange/r/cnippet-blocks/logo-3).

- Page, with a live preview: https://shadcn.exchange/r/cnippet-blocks/logo-3
- Screenshot: https://shadcn.exchange/shot/cnippet-blocks/logo-3/light.png
- Registry item: https://blocks.cnippet.dev/r/logo-3.json
- Categories: logo
- Listed: 2026-11-01, source last changed 2026-11-01

## Install

```bash
npx shadcn@latest add https://shadcn.exchange/r/cnippet-blocks/logo-3.json
```

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

## Dependencies

- Registry items: `@cnippet/utils`

## Files

### `registry/default/sections/logo-3.tsx`

```tsx
"use client";

import Image from "next/image";
import { Marquee } from "@/components/ui/marquee";

const testimonialBadges = [
  {
    avatar:
      "https://res.cloudinary.com/dvwtcsh5v/image/upload/v1770279333/a1.jpg",
    text: "Provided the tools to optimise conversions effortlessly.",
  },
  {
    avatar:
      "https://res.cloudinary.com/dvwtcsh5v/image/upload/v1770279333/a4.jpg",
    text: "Boost in productivity directly translates into happier customers",
  },
  {
    avatar:
      "https://res.cloudinary.com/dvwtcsh5v/image/upload/v1770279333/a3.jpg",
    text: "Streamlined project workflows with automated dashboards",
  },
];

const stats = [
  { label: "Users migrated to premium accounts", value: "+35k" },
  { label: "Increase in customer satisfaction", value: "88%" },
  { label: "Saved in deployment costs", value: "24.5m" },
];

export default function Component() {
  return (
    <section className="relative w-full overflow-hidden bg-white px-4 dark:bg-background">
      <div>
        <svg
          className="absolute top-0 left-20 text-neutral-100 dark:text-neutral-800"
          fill="none"
          height="149"
          viewBox="0 0 259 149"
          width="259"
          xmlns="http://www.w3.org/2000/svg"
        >
          <g clipPath="url(#clip0_450_3432)">
            <path
              d="M-302.316 -438C-345.03 -335.213 -349.374 -223.272 -302.316 -158.312C-247.534 -82.6905 -123.092 -70.7382 91.5694 -211.017C-164.578 460.946 374.375 -176.105 204.032 128"
              stroke="currentColor"
              strokeLinecap="round"
              strokeLinejoin="round"
              strokeWidth="40"
            />
          </g>
          <defs>
            <clipPath id="clip0_450_3432">
              <rect fill="white" height="149" width="259" />
            </clipPath>
          </defs>
        </svg>
      </div>

      <div className="relative z-10 mx-auto max-w-5xl px-6 py-28 lg:px-0">
        <div className="grid grid-cols-1 gap-8 md:grid-cols-3">
          {testimonialBadges.map((badge, _index) => (
            <div
              className="flex items-center gap-5 rounded-xl bg-gray-100 px-4 py-3 shadow-sm dark:bg-neutral-800"
              key={badge.text}
            >
              <Image
                alt="Avatar"
                className="size-14 rounded-lg object-cover"
                height={40}
                src={badge.avatar}
                width={40}
              />
              <p className="text-neutral-700 tracking-tight dark:text-neutral-300">
                {badge.text}
              </p>
            </div>
          ))}
        </div>

        <div className="mt-16 grid grid-cols-1 gap-12 md:grid-cols-3">
          {stats.map((stat) => (
            <div key={stat.value}>
              <h3 className="font-semibold text-5xl! text-neutral-900 tracking-tight md:text-6xl! dark:text-neutral-100">
                {stat.value}
              </h3>
              <p className="mt-2 w-1/2 text-neutral-700 dark:text-neutral-400">
                {stat.label}
              </p>
            </div>
          ))}
        </div>
      </div>

      <div className="w-full rounded-t-[3rem] bg-gray-50 py-16 dark:bg-neutral-700">
        <div className="mx-auto max-w-5xl px-6 lg:px-0">
          <p className="mb-10 text-center text-neutral-600 text-sm dark:text-neutral-400">
            Making the cloud effortless for{" "}
            <span className="font-semibold text-neutral-900 dark:text-neutral-100">
              2,500+ companies
            </span>
          </p>

          <div className="relative -mx-4 mt-8 sm:-mx-6 lg:-mx-8">
            <div className="absolute left-0 z-40 h-full w-20 bg-linear-to-r from-white dark:from-neutral-700" />
            <div className="absolute right-0 z-40 h-full w-20 bg-linear-to-l from-white dark:from-neutral-700" />

            <Marquee className="[--duration:25s]" pauseOnHover repeat={2}>
              {Array.from({ length: 6 }).map((_, index) => {
                const k = `cmp_sno_${index}`;

                return (
                  <div
                    className="flex items-center justify-center px-3 md:px-5"
                    key={k}
                  >
                    <Image
                      alt="Logo"
                      className="h-5 w-auto md:h-8"
                      height={24}
                      src={`https://res.cloudinary.com/dvwtcsh5v/image/upload/v1770296407/icon_0${index + 1}.svg`}
                      width={100}
                    />
                  </div>
                );
              })}
            </Marquee>
          </div>

          <div className="mt-12 text-center">
            <h2 className="mx-auto max-w-3xl font-medium text-3xl text-neutral-900 tracking-tight sm:text-4xl dark:text-neutral-100">
              Unified Excellence, Boundless Possibilities.
            </h2>
            <p className="mx-auto mt-4 max-w-2xl text-neutral-600 dark:text-neutral-400">
              Why settle for less when your team deserves it all? Empower them
              with tools to craft experiences that inspire, engage, and convert
              every time.
            </p>
          </div>
        </div>
      </div>
    </section>
  );
}
```

### `components/ui/marquee.tsx`

```tsx
//biome-ignore-all lint/suspicious/noArrayIndexKey:<>

import type { ComponentPropsWithoutRef } from "react";
import { cn } from "@/lib/utils";

interface MarqueeProps extends ComponentPropsWithoutRef<"div"> {
  className?: string;
  reverse?: boolean;
  pauseOnHover?: boolean;
  children: React.ReactNode;
  vertical?: boolean;
  repeat?: number;
}

export function Marquee({
  className,
  reverse = false,
  pauseOnHover = false,
  children,
  vertical = false,
  repeat = 4,
  ...props
}: MarqueeProps) {
  return (
    <div
      {...props}
      className={cn(
        "group flex gap-(--gap) overflow-hidden p-2 [--duration:40s] [--gap:1rem]",
        {
          "flex-col": vertical,
          "flex-row": !vertical,
        },
        className,
      )}
    >
      {Array(repeat)
        .fill(0)
        .map((_, i) => (
          <div
            className={cn("flex shrink-0 justify-around gap-(--gap)", {
              "animate-marquee flex-row": !vertical,
              "animate-marquee-vertical flex-col": vertical,
              "direction-[reverse]": reverse,
              "group-hover:paused": pauseOnHover,
            })}
            key={i}
          >
            {children}
          </div>
        ))}
    </div>
  );
}
```
