# Logo marquee (goodtabs UI)

A slow looping row of logos that pauses on hover and focus and stops under reduced motion.

## Install

```bash
npx shadcn@latest add https://ui.goodtabs.co/r/logo-marquee.json
```

Or, with the @goodtabs namespace configured in components.json: `npx shadcn@latest add @goodtabs/logo-marquee`

## Usage

```tsx
import { LogoMarquee } from "@/components/logo-marquee"

<LogoMarquee label="Trusted by small teams" logos={[{ name: "Halden" }, { name: "Fernwick" }]} />
```

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| logos | `{ name: string; mark?: ReactNode; href?: string }[]` |  | The logos. A name alone renders a text wordmark; mark replaces it with your own element. |
| label | `string` |  | Small uppercase line above the track. |
| duration | `number` | `40` | Seconds for one full loop. Slower reads calmer. |

## When to use

- A strip of customer or partner logos under a hero
- When there are more logos than fit in one row
- Quiet social proof that should not compete with the headline

## When not to use

- Fewer than four logos, where a static row is calmer
- As the only evidence of trust, which needs numbers or quotes
- Inside dense app screens

## Notes for agents

- Server component with no state; the motion is a CSS keyframe injected through a precedence style tag
- The list renders twice for a seamless loop; the second copy is aria-hidden and inert
- Hover and focus-within pause it; under prefers-reduced-motion it stops and wraps into a centered still row
- Pass real logos as mark; the demos use made-up wordmarks only

## The maths

- Loop distance is the width of one copy, so the track moves by -50% of its own width: 2 copies × w, shift = w.
- Edge fade is a mask from 0 to 12% and 88% to 100%, so a logo is fully visible across the middle 76%.
- Gap and trailing padding are both 3rem, so the seam equals the gap: no jump at the loop point.

Docs: https://ui.goodtabs.co/components/logo-marquee