Showcase Section

A scroll-scrubbed showcase where cards fly in from offscreen, gather into a stack behind a title, then drift upward and fade away as you scroll.

A cinematic scroll section that pins for ~3.6 viewport heights. Cards scatter from the edges of the viewport, gather into a layered stack, and then rise and fade out while the title scales and lifts.

Behavior

  • Scroll-scrubbed — the whole section is tied to scroll progress.
  • Pinned stage — scene stays fixed while the animation plays.
  • Title motion — scales down and nudges upward across the timeline.
  • Card scatter→gather — each card starts far offscreen, flies in, and rests with a unique offset/rotation.
  • Stack exit — the entire stack drifts upward and fades away near the end.
  • Hover affordance — hovering scales a card up slightly and raises its z-index above neighbors.
  • Optional links — cards can be clickable if href is provided.

Props

  • title?: string — text behind the cards (default: Are you watching closely?).
  • cards?: { src: string; href?: string; alt?: string }[] — array of images with optional links and alt text (default: first 5 demo images).
  • className?: string — custom wrapper classes for layout/sizing.
  • scrollContainerRef?: RefObject<HTMLElement> — pass if using a custom scroll container.

Scroll down to view the component

Are you watching closely?

Scroll up


This component use a subtle noise texture for depth and realism.
To make it render correctly, you need to download and place the following image into your project’s public/ folder with the exact filename noise.webp.

💡 Why?
This texture is layered via CSS (backgroundImage: url(/noise.webp)) in this component to create a film-grain style background. Without it, you’ll see missing backgrounds or fallback colors instead.