# Logo marquee

A looping row, or a still wall, of logos in one dithered treatment, with soft or dithered edges.

> For the complete documentation index, see [llms.txt](/llms.txt). Markdown variants are available by appending `.md` to any URL or sending an `Accept: text/markdown` header. The dithercn agent skill, for building any dither on the engine, is at [/.well-known/agent-skills/dithercn/SKILL.md](/.well-known/agent-skills/dithercn/SKILL.md).

<ComponentPreview src="examples/logo-marquee-demo.tsx" controls="logoMarqueeControls">
  <LogoMarqueeDemo />
</ComponentPreview>

## Installation [#installation]

<InstallBlock name="logo-marquee" />

## Usage [#usage]

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

const logos = [
  { src: "/logos/acme.svg", alt: "Acme", ratio: 4 },
  {
    src: "/logos/globex.svg",
    alt: "Globex",
    ratio: 3.5,
    href: "/customers/globex",
  },
];

export function Customers() {
  return <LogoMarquee logos={logos} label="Customers" />;
}
```

Every logo is a [Dithered logo](/docs/images/dithered-logo) with the same fill, cell and colour, so logos from different brands read as one set. The row repeats as many times as it needs to fill the width and loops without a seam.

Hover or focus the row and it coasts to a stop instead of halting; let go and it picks up speed again. A small pause button appears at the right end on hover and keyboard focus. The ends fade out through a mask, so the fade works on any background: `soft` is a smooth ramp, `dither` steps through Bayer levels.

`ratio` on each logo reserves its width before it loads, so the row does not shift. Give a logo an `href` to make it a link.

## Examples [#examples]

### Wall [#wall]

`variant="wall"` lays the logos out in a still grid with hairline dividers, two columns, or four once its container is 672px wide. Each logo links to a case study, and the shimmer passes through them in turn.

<ComponentPreview src="examples/logo-marquee-wall.tsx" size="lg">
  <LogoMarqueeWall />
</ComponentPreview>

### Two rows [#two-rows]

Two marquees moving in opposite directions with dithered edges, the second hatched in grey.

<ComponentPreview src="examples/logo-marquee-rows.tsx" size="lg">
  <LogoMarqueeRows />
</ComponentPreview>

## Props [#props]

Also takes the drawing props of [Dithered logo](/docs/images/dithered-logo): `color`, `tone`, `fill`, `outline`, `floor`, `matrix`, `cell`, `effect` and `period`.

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `logos` (required) | `{ src: string; alt: string; ratio?: number; href?: string; color?: DitherColor }[]` |  | The logos, in order. |
| `label` | `string` | `"Logos"` | Names the list for screen readers. |
| `variant` | `"marquee" \| "wall"` | `"marquee"` | A scrolling row or a still grid. |
| `speed` | `number` | `32` | Marquee only: scroll speed in CSS pixels per second. |
| `direction` | `"left" \| "right"` | `"left"` | Marquee only: which way the row moves. |
| `fade` | `"soft" \| "dither" \| "none"` | `"soft"` | Marquee only: how the ends fade out. |
| `fadeWidth` | `number` | `96` | Marquee only: width of each end's fade in CSS pixels. |
| `pauseButton` | `boolean` | `true` | Marquee only: show a pause button on hover and focus. |
| `logoHeight` | `number` | `28` | Logo height in CSS pixels. |
| `gap` | `number` | `64` | Space between logos in the row, in CSS pixels. |

## Notes [#notes]

* The first copy of the row is a list labelled by `label`; the copies that fill the loop are hidden from assistive technology and their links are out of the tab order.
* The row stops while it is offscreen. Under reduced motion it becomes a still, centred row that wraps.
* The motion is a single Web Animation on a transform, so it runs off the main thread.