Patterns

Logo carousel

Two-column proof section — a text tile beside an infinite LogoLoop strip. Both sides are flat data (a TextTile record and LogoLoop props), so the pairing spreads straight from a query while the pattern owns the layout.

Install

npx shadcn@latest add @alix/logoCarousel

Preview

Teams working across complex sectors

The copy and the logo strip stay separate records so each side can evolve.
  • Northline
  • Harbor
  • Axis
  • Stonebridge
  • Cobalt
  • Summit

Usage

<LogoCarousel
  textTile={{
    bgColor: "primary",
    sectionTitle: {
      title: "Teams working across complex sectors",
      description: "The copy and the logo strip stay separate records.",
      align: "start",
    },
    buttonGroup: {},
  }}
  logos={{ logos: clientLogos, speed: 36, logoHeight: 28 }}
/>

Examples

01

On a quiet surface

Pick the tile's bgColor per page rhythm — the pattern maps the right button variant to the surface for you.

Trusted across urgent operating moments

The text tile stays simple while the strip owns the brand composition.
  • Northline
  • Harbor
  • Axis
  • Stonebridge
  • Cobalt
  • Summit
<LogoCarousel
  textTile={{
    bgColor: "greyGradient",
    sectionTitle: {
      title: "Trusted across urgent operating moments",
      description: "The text tile stays simple while the strip owns the brand composition.",
      align: "start",
    },
    buttonGroup: {},
  }}
  logos={{ logos: clientLogos, speed: 36, logoHeight: 28 }}
/>
02

Tuning the strip

The logos prop is the full LogoLoop contract — speed, logo height, gap, hover-pause, and the edge fade are all data.

Client teams that move under pressure

  • Northline
  • Harbor
  • Axis
  • Stonebridge
  • Cobalt
  • Summit
<LogoCarousel
  textTile={{
    bgColor: "sand",
    sectionTitle: { title: "Client teams that move under pressure", align: "start" },
    buttonGroup: {},
  }}
  logos={{ logos: clientLogos, speed: 60, logoHeight: 24, gap: "lg", fade: false }}
/>
03

With an action

The tile's buttonGroup carries the follow-on path — the button variant is the pattern's opinion, keyed to the surface.

Proof should sit beside the proposition.

  • Northline
  • Harbor
  • Axis
  • Stonebridge
  • Cobalt
  • Summit
<LogoCarousel
  textTile={{
    bgColor: "primary",
    sectionTitle: { title: "Proof should sit beside the proposition.", align: "start" },
    buttonGroup: {
      primaryAction: { children: "Our clients", render: <a href="/clients" /> },
    },
  }}
  logos={{ logos: clientLogos, speed: 36, logoHeight: 28 }}
/>

When to use it

Use it for

  • Proof sections that pair section copy with a moving wall of client or partner logos.
  • CMS-fed credibility bands — both the tile record and the logo list are flat, serializable data.
  • Professional-services pages that need credibility signals without turning logos into content cards.

Reach for something else

  • A standalone moving strip with no copy column — use LogoLoop instead.
  • One official brand mark or wordmark — use Logo instead.
  • A static logo grid or a bespoke text column — compose Grid, TextTileDefault, and your own logo treatment directly.

Props

PropTypeDefaultDescription
textTileTextTileDefaultPropsThe copy column as one record — surface (bgColor), a SectionTitle's content, and a buttonGroup. The pattern locks the tile's layout and the button variant per surface.
logosLogoLoopPropsThe full LogoLoop contract for the strip — logos ({ src, alt, href? }[]), speed, logoHeight, gap, pauseOnHover, fade.

See also