# Depth Carousel Hero

> Build a playful 3D-style carousel hero where 3–4 subjects (product shots, character figurines, app screens) sit at depth positions — one big in the center, others smaller to the sides and behind — and rotate through those roles with a smooth crossfade when you click arrows. The whole background color changes per active item, a giant "ghost" display word sits behind the subjects, and a film-grain overlay adds texture. Use this skill whenever the user wants a carousel, a rotating showcase, a "coverflow"-style gallery, cycling product/character cards, or a colorful, toy-like hero that swaps subjects. Prefer this when the content is a small set of hero objects meant to be flipped through.

- Skill: `brcapitalusa/depth-carousel-hero` (Agent Skill)
- Install (CLI): `npx skillmds@latest add brcapitalusa/depth-carousel-hero`
- Raw SKILL.md: https://api.skillmd.com/api/skills/brcapitalusa/depth-carousel-hero/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Docs & Writing
- Author: BRCapitalUSA (https://skillmd.com/u/brcapitalusa)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/brcapitalusa/depth-carousel-hero

---


# Depth Carousel Hero

A tactile carousel with real depth. Four subjects occupy four roles — center
(large, sharp), left, right (small, blurred, to the sides), and back (tiny,
behind). Clicking an arrow rotates every subject to the next role while the
background color, scales, blurs, and opacities all crossfade together.

## Before building
Read `/mnt/skills/public/frontend-design/SKILL.md`. Collect: 3–4 `ITEMS`, each
with an image `src`, a `bg` color, and (optional) a `panel` color; a `BRAND`
label; a giant `GHOST_TEXT` (e.g. "3D SHAPE"); a bottom-left blurb; and a
bottom-right CTA word. Fonts: a heavy display face (Anton) for the ghost text +
CTA; Inter for body.

## Stack
React + Vite + TypeScript, Tailwind, `lucide-react` (`ArrowLeft`, `ArrowRight`).
Single `App.tsx`. Preload all images on mount via `new Image()`.

## State & role logic
```tsx
const [active, setActive] = React.useState(0);
const [locked, setLocked] = React.useState(false);
const n = ITEMS.length; // 4
const navigate = (dir: "next" | "prev") => {
  if (locked) return;
  setLocked(true);
  setActive(p => dir === "next" ? (p + 1) % n : (p + n - 1) % n);
  setTimeout(() => setLocked(false), 650);
};
const roles = {
  center: active,
  left:  (active + n - 1) % n,
  right: (active + 1) % n,
  back:  (active + 2) % n,
};
```

## Per-role styling (the depth illusion)
Each item is `position: absolute`, `aspectRatio: "0.6 / 1"`, image
`objectFit: contain; objectPosition: bottom center`. Transition every property
over `650ms cubic-bezier(0.4,0,0.2,1)` with `willChange: transform,filter,opacity,left`.

| Role | transform | blur | opacity | z | left | height (desktop / mobile) | bottom |
|------|-----------|------|---------|---|------|---------------------------|--------|
| center | `translateX(-50%) scale(1.68 / 1.25)` | 0 | 1 | 20 | 50% | 92% / 60% | 0 / 22% |
| left | `translateX(-50%) scale(1)` | 2px | 0.85 | 10 | 30% / 20% | 28% / 16% | 12% / 32% |
| right | same as left | 2px | 0.85 | 10 | 70% / 80% | 28% / 16% | 12% / 32% |
| back | `translateX(-50%) scale(1)` | 4px | 1 | 5 | 50% | 22% / 13% | 12% / 32% |

Root wrapper: `backgroundColor: ITEMS[active].bg`, transition
`background-color 650ms cubic-bezier(0.4,0,0.2,1)`, `relative w-full
overflow-hidden`, inner `height: 100vh`.

## The scenery
- **Ghost text** (`z-2`, `absolute inset-x-0 flex justify-center`, `top: 18%`,
  `pointer-events-none select-none`): Anton, `fontSize: clamp(90px,28vw,380px)`,
  white, `lineHeight:1`, uppercase, `letterSpacing:-0.02em`, `whiteSpace:nowrap`.
  The subjects (`z-3`) overlap it.
- **Grain overlay** (`z-50`, `pointer-events-none`): an inline SVG `feTurbulence`
  fractal-noise data URI, `baseFrequency 0.9 numOctaves 4`, container
  `opacity 0.4`, `backgroundSize:200px 200px`, repeat.
- **Brand label** top-left; **blurb + two round arrow buttons** bottom-left
  (`w-12 h-12 sm:w-16 sm:h-16`, transparent, 2px white border, hover `scale 1.08`
  + `bg-white/12`); **CTA link** bottom-right in Anton + `ArrowRight`.

## Responsive
Track `isMobile = window.innerWidth < 640` on resize and switch the scale/
height/bottom values per the table. Ghost text and CTA scale via `clamp()`.

## Quality checklist
- [ ] Clicking arrows rotates all subjects through center→right→back→left.
- [ ] Background color, scales, blurs, opacities crossfade together (650ms).
- [ ] Input is locked during the 650ms transition (no double-fire).
- [ ] Ghost display word sits behind; grain overlay on top.
- [ ] Images preloaded; subjects anchored to the bottom.
- [ ] Mobile uses the smaller scale/position set.

