Live Preview
Apple Card
•••• •••• •••• 1234
Chase Sapphire
•••• •••• •••• 2345
Amex Cash Magnet
•••• •••• •••• 3456
Click stack to expand
"use client";
import { useState } from "react";
import { motion } from "framer-motion";
const cards = [
{ id: 1, color: "bg-zinc-800", title: "Apple Card" },
{ id: 2, color: "bg-blue-600", title: "Chase Sapphire" },
{ id: 3, color: "bg-emerald-600", title: "Amex Cash Magnet" },
];
export function AppleWalletStack() {
const [isExpanded, setIsExpanded] = useState(false);
return (
<div className="flex items-center justify-center w-full h-96 bg-[#0a0a0a] rounded-xl border border-border overflow-hidden relative">
<div
className="relative w-64 h-80 flex items-end justify-center pb-8 cursor-pointer"
onClick={() => setIsExpanded(!isExpanded)}
>
{cards.map((card, i) => (
<motion.div
key={card.id}
initial={false}
animate={{
y: isExpanded ? -i * 80 : -i * 15,
scale: isExpanded ? 1 : 1 - (cards.length - 1 - i) * 0.05,
zIndex: i,
}}
transition={{ type: "spring", stiffness: 300, damping: 25 }}
className={`absolute w-full h-40 rounded-2xl ${card.color} shadow-2xl border border-white/10 p-5 flex flex-col justify-between`}
style={{ transformOrigin: "bottom center" }}
>
<div className="flex justify-between items-start">
<span className="text-white font-semibold tracking-tight">{card.title}</span>
<svg className="h-6 w-8 text-white/50" viewBox="0 0 32 32" fill="none"><circle cx="11.5" cy="16" r="6.5" fill="currentColor"/><circle cx="20.5" cy="16" r="6.5" fill="currentColor" className="opacity-50"/></svg>
</div>
<div className="text-white/80 font-mono text-sm tracking-widest">
•••• •••• •••• {1234 + i * 1111}
</div>
</motion.div>
))}
</div>
<p className="text-sm text-zinc-500 absolute bottom-4">Click stack to expand</p>
</div>
);
}