DocsOrbit Card Stack

Orbit Card Stack

A premium interactive card stack that collapses into a tight deck, fans out on hover, and lifts the active card above the rest without changing its color or angle.

Installation

pnpm dlx shadcn@latest add @componentry/orbit-card-stack

Dependencies: framer-motion lucide-react clsx tailwind-merge

Usage

API Reference

PropTypeDefault
itemsOrbitStackItem[]

Cards shown in the stack. Each item can include an `image` path.

—
defaultActiveIndexnumber

Card that sits at the front when the stack is collapsed.

2
spreadnumber

Horizontal fan distance in pixels.

168
liftnumber

Vertical lift for hovered cards in pixels.

34
onActiveChange(item: OrbitStackItem, index: number) => void

Callback fired when the active card changes.

—
classNamestring

Additional CSS classes for the outer stage.

—
cardClassNamestring

Additional CSS classes for each card.

—

Keep in mind

This component is inspired by various open-source projects and patterns. Please verify licenses and implementation details before using in production.

Need a custom component?

I build bespoke UI components & websites tailored to your brand.

DM me on X
PreviousNewsletter BookshelfNextScroll Choreography
Mira ValeMV

Creative Lead

Mira Vale

Shapes visual systems with enough restraint to feel expensive and enough edge to be remembered.

Identity
Noor KadeNK

Product Strategy

Noor Kade

Turns loose ideas into sharp product moves, crisp priorities, and launchable experiences.

Roadmap
Ari ChenAC

Founder

Ari Chen

Sets the taste bar, protects the details, and keeps the whole team pointed at the same high signal.

Vision
Sana HoltSH

Frontend Engineer

Sana Holt

Builds the motion, polish, and interface texture that make the product feel calm under pressure.

Motion
Ezra MoonEM

Operations

Ezra Moon

Keeps the machine quiet, the handoffs clean, and the team moving without pointless friction.

Systems
"use client";
 
import { useState } from "react";
import {
  OrbitCardStack,
  type OrbitStackItem,
} from "@/components/ui/orbit-card-stack";
 
const team: OrbitStackItem[] = [
  {
    name: "Mira Vale",
    role: "Creative Lead",
    description: "Shapes visual systems with restraint and edge.",
    initials: "MV",
    stat: "Identity",
    accent: "#f8d66d",
    image: "/team/mira-vale.png",
  },
  {
    name: "Noor Kade",
    role: "Product Strategy",
    description: "Turns loose ideas into crisp product moves.",
    initials: "NK",
    stat: "Roadmap",
    accent: "#78dcca",
    image: "/team/noor-kade.png",
  },
  {
    name: "Ari Chen",
    role: "Founder",
    description: "Keeps the team pointed at the same signal.",
    initials: "AC",
    stat: "Vision",
    accent: "#f3f1ea",
    image: "/team/ari-chen.png",
  },
];
 
export default function TeamPreview() {
  const [activeMember, setActiveMember] = useState(team[2]!);
 
  return (
    <section className="space-y-6">
      <div>
        <p className="text-sm font-medium text-muted-foreground">
          Currently viewing
        </p>
        <h2 className="text-2xl font-semibold">{activeMember.name}</h2>
      </div>
 
      <div className="h-[620px] w-full">
        <OrbitCardStack
          items={team}
          defaultActiveIndex={2}
          spread={150}
          lift={40}
          onActiveChange={(item) => setActiveMember(item)}
        />
      </div>
    </section>
  );
}