Kaushik

Card Fan

Cards

About

3D deck of frosted-glass cards with immersive interaction. Scroll, drag, or use arrow keys to navigate a curved 3D carousel featuring frosted-glass styling, animated mesh gradients, smooth spring physics, and premium micro-interactions.

Built with React and Tailwind. Copy the prompt and paste it into Claude Code, Cursor or Lovable: your agent adds Card Fan to your project and fits it to your theme.

Code

How Card Fan is used: the demo's code. The component's own source comes with a free account.

Usage.tsx

"use client";

import CardFan, { type FanCardData } from "@/components/ui/card-fan";

/* ------------------------------------------------------------------ *
 * Demo 1 — project portfolio (default accent)
 * ------------------------------------------------------------------ */

const PROJECTS: FanCardData[] = [
  {
    id: "p1", code: "Northwind", kicker: "IN BUILD",
    title: "Rebuilding the checkout flow on the new payments core",
    value: 42, total: 60, progress: 72,
    stats: [
      { label: "Tasks done", value: "42 / 60" },
      { label: "Squad", value: 6 },
      { label: "Blockers", value: 4, alert: true },
    ],
  },
  {
    id: "p2", code: "Halcyon", kicker: "IN BUILD",
    title: "Realtime collaboration layer for the shared workspace",
    value: 36, total: 50, progress: 64,
    stats: [
      { label: "Tasks done", value: "36 / 50" },
      { label: "Squad", value: 4 },
      { label: "Blockers", value: 7, alert: true },
    ],
  },
  {
    id: "p3", code: "Meridian", kicker: "DISCOVERY",
    title: "Usage-based pricing engine and metering pipeline",
    value: 24, total: 80, progress: 41,
    stats: [
      { label: "Tasks done", value: "24 / 80" },
      { label: "Squad", value: 8 },
      { label: "Blockers", value: 1, alert: true },
    ],
  },
  {
    id: "p4", code: "Fathom", kicker: "IN REVIEW",
    title: "Search relevance rewrite with vector re-ranking",
    value: 26, total: 26, progress: 88,
    stats: [
      { label: "Tasks done", value: "26 / 26" },
      { label: "Squad", value: 3 },
      { label: "Blockers", value: 0 },
    ],
  },
  {
    id: "p5", code: "Lantern", kicker: "SHIPPED",
    title: "Onboarding redesign and first-run checklist",
    value: 58, total: 58, progress: 100, muted: true,
    stats: [
      { label: "Tasks done", value: "58 / 58" },
      { label: "Squad", value: 5 },
      { label: "Blockers", value: 0 },
    ],
  },
  {
    id: "p6", code: "Kestrel", kicker: "SHIPPED",
    title: "Mobile offline sync and conflict resolution",
    value: 31, total: 31, progress: 100, muted: true,
    stats: [
      { label: "Tasks done", value: "31 / 31" },
      { label: "Squad", value: 4 },
      { label: "Blockers", value: 0 },
    ],
  },
  {
    id: "p7", code: "Solstice", kicker: "ARCHIVED",
    title: "Legacy reporting module, superseded by Meridian",
    value: 44, total: 44, progress: 100, muted: true,
    stats: [
      { label: "Tasks done", value: "44 / 44" },
      { label: "Squad", value: 2 },
      { label: "Blockers", value: 0 },
    ],
  },
];

/* ------------------------------------------------------------------ *
 * Demo 2 — release pipeline, violet accent
 * ------------------------------------------------------------------ */

const RELEASES: FanCardData[] = [
  {
    id: "r1", code: "v4.2.0", kicker: "IN QA",
    title: "Multi-region failover and the new query planner",
    value: 18, total: 24, progress: 74,
    stats: [
      { label: "Tickets", value: "18 / 24" },
      { label: "Owner", value: "Platform" },
      { label: "Blockers", value: 2, alert: true },
    ],
  },
  {
    id: "r2", code: "v4.1.3", kicker: "STAGING",
    title: "Batch export, signed URLs and audit streaming",
    value: 31, total: 33, progress: 92,
    stats: [
      { label: "Tickets", value: "31 / 33" },
      { label: "Owner", value: "Core" },
      { label: "Blockers", value: 0 },
    ],
  },
  {
    id: "r3", code: "v4.1.2", kicker: "SHIPPED",
    title: "Form builder validation rules and regex guard",
    value: 27, total: 27, progress: 100, muted: true,
    stats: [
      { label: "Tickets", value: "27 / 27" },
      { label: "Owner", value: "Core" },
      { label: "Blockers", value: 0 },
    ],
  },
  {
    id: "r4", code: "v4.1.1", kicker: "SHIPPED",
    title: "Scheduler atomicity fixes and retry semantics",
    value: 12, total: 12, progress: 100, muted: true,
    stats: [
      { label: "Tickets", value: "12 / 12" },
      { label: "Owner", value: "Platform" },
      { label: "Blockers", value: 0 },
    ],
  },
  {
    id: "r5", code: "v4.1.0", kicker: "SHIPPED",
    title: "Dark theme, glass surfaces and the new app shell",
    value: 46, total: 46, progress: 100, muted: true,
    stats: [
      { label: "Tickets", value: "46 / 46" },
      { label: "Owner", value: "Design Eng" },
      { label: "Blockers", value: 0 },
    ],
  },
];

export default function CardFanDemo() {
  return (
    <div className="flex w-full flex-col gap-10 bg-[#0a0a0b] p-6">
      <section>
        <div className="mb-4 px-2">
          <h3 className="text-[26px] font-normal tracking-[-.8px] text-white">
            Project <b className="font-semibold">portfolio</b>
          </h3>
          <p className="mt-2 text-[11.5px] text-white/45">
            Scroll, drag or use ← → to browse. Click the focused card to open it.
          </p>
        </div>
        <CardFan
          cards={PROJECTS}
          unitLabel="PROJECTS"
          actionLabel="Open project"
          height={560}
          onOpen={(c) => console.log("open", c.code)}
        />
      </section>

      <section>
        <div className="mb-4 px-2">
          <h3 className="text-[26px] font-normal tracking-[-.8px] text-white">
            Release <b className="font-semibold">pipeline</b>
          </h3>
          <p className="mt-2 text-[11.5px] text-white/45">
            Same component with a violet accent and a different record shape.
          </p>
        </div>
        <CardFan
          cards={RELEASES}
          unitLabel="RELEASES"
          actionLabel="Open release"
          defaultIndex={1}
          height={560}
          accent={{ soft: "#b39bff", deep: "#5b34d6", glow: "150,120,255" }}
          onOpen={(c) => console.log("open", c.code)}
        />
      </section>
    </div>
  );
}

More in Cards

View all
  • Stats cards with links

    Stats cards with links

    33
  • Course Design Cards

    Course Design Cards

    1.1K
  • Card

    Card

    70
  • Statistics Card 10

    Statistics Card 10

    263
  • Statistics Card 2

    Statistics Card 2

    264
  • Card

    Card

    17
  • Card Studio

    Card Studio

    9
  • The Item one

    The Item one

    3