ProductBrand
Join us
Foundations
  • Introduction
  • Guidelines
  • Colors
  • Typography
  • Breakpoints
  • Elevation
  • Patterns
Identity
  • Logos
  • Mr Rogo
  • Assets
Components
  • Button
  • Carousel
  • CTA Headline
  • Navigation Menu
  • Popover
  • Separator Dot
  • Sheet
  • Skeleton
  • Video Player

Carousel

Paged content on the marketing surfaces: one engine, composable parts.

The brand weaves

houndstooth
twill
chequer
wordmark

Overview

Built on Embla, because a marketing carousel has to feel like a gesture and not a slideshow: real drag physics on touch, momentum, and slides that settle rather than snap. Embla supplies the engine; everything it looks like comes from here.

tsx
import {
  Carousel,
  CarouselContent,
  CarouselItem,
  CarouselNext,
  CarouselPrevious,
} from "@rogo-technologies/brand/carousel";

<Carousel opts={{ loop: true }}>
  <CarouselContent>
    {slides.map((slide) => (
      <CarouselItem key={slide.id}>{slide.content}</CarouselItem>
    ))}
  </CarouselContent>
  <CarouselPrevious />
  <CarouselNext />
</Carousel>;

The provider carries the engine and the parts read it from context, so a surface composes exactly the frame and controls it needs: controls beside a headline, under the track, or wherever the band puts them. Never inside a CarouselItem: a control that rides a slide travels with it and is gone mid-press.

PartWhat it is
CarouselThe provider. opts passes to Embla; setApi hands the engine out.
CarouselContentThe scrolling track inside its clipping viewport.
CarouselItemOne slide. Size it with a basis-* class; basis-full is the default.
CarouselPreviousThe back disc. Disabled at the start unless loop is on.
CarouselNextThe forward disc. Disabled at the end unless loop is on.
useCarouselThe context, for custom controls or progress indicators.

Slide rhythm

Embla expects the gap to live on the slides: give each CarouselItem a pl-* and mirror it as a negative margin on CarouselContent, so the first slide sits flush while every pair keeps the gap.

tsx
<CarouselContent className="-ml-5">
  <CarouselItem className="basis-[62%] pl-5">…</CarouselItem>
</CarouselContent>

Bleeding off the page

A track that runs to the screen's edge says there is more to page through. Keep the viewport at full width and walk the first slide in with padding that matches the page shell, the way the landing page's case-study wall does:

tsx
<CarouselContent
  viewportClassName="w-full"
  className="pl-5 tablet:pl-10 wide:pl-[max(40px,calc((100vw-1280px)/2))]"
>

Keyboard and announcement

The region is announced as a carousel, each item as a slide, and the arrow keys page it. That comes with the provider, not from the controls, so it holds even when a surface draws its own.

PreviousButton
NextCTA Headline
Made in NYC© 2026 Rogo Technologies Inc.

Design at Rogo

We’re redesigning an entire industry. Come design it with us.

See open roles

Design at Rogo

  • How we workThe mission of design at Rogo, and the open roles
  • About RogoThe company and the product