Components
3D perspective card that rotates to follow your cursor with a traveling spotlight glare and a colored border glow that tracks mouse position. When idle, each card auto-animates on a figure-8 path with configurable phase offsets so multiple cards move independently. Wrap any content — images, features, pricing, profiles. Configurable tilt angle, glare intensity, glow color, perspective depth, and animation speed. Zero dependencies.
Loading preview...
import { Component as TiltCard } from "@/components/ui/interactive-tilt-card";
import { Zap, Shield, Globe } from "lucide-react";
export default function Demo() {
return (
<div className="flex min-h-screen items-center justify-center bg-background p-8">
<div className="w-full max-w-5xl">
<div className="text-center mb-16">
<h2 className="text-2xl font-bold tracking-tight text-foreground mb-2">
Interactive Tilt Card
</h2>
<p className="text-sm text-muted-foreground max-w-md mx-auto">
3D perspective rotation with spotlight glare and border glow. Hover to control — or watch the auto-animation.
</p>
</div>
<div className="grid grid-cols-1 md:grid-cols-3 gap-8">
{/* Card 1 — Image showcase */}
<TiltCard
className="overflow-hidden"
maxTilt={18}
borderGlowColor="rgba(139, 92, 246, 0.4)"
autoPhase={0}
>
<div className="aspect-[4/5]">
<img
src="https://images.unsplash.com/photo-1618005182384-a83a8bd57fbe?w=400&q=80"
alt="Abstract art"
className="w-full h-full object-cover"
/>
<div className="absolute bottom-0 inset-x-0 bg-gradient-to-t from-black/80 to-transparent p-6">
<p className="text-xs text-white/60 uppercase tracking-wider mb-1">Collection</p>
<h3 className="text-lg font-bold text-white">Abstract Series</h3>
</div>
</div>
</TiltCard>
{/* Card 2 — Feature card */}
<TiltCard
maxTilt={14}
borderGlowColor="rgba(59, 130, 246, 0.4)"
autoPhase={2}
>
<div className="p-8 flex flex-col items-center text-center aspect-[4/5] justify-center">
<div className="size-14 rounded-2xl bg-blue-500/10 border border-blue-500/20 flex items-center justify-center mb-5">
<Globe className="size-7 text-blue-400" />
</div>
<h3 className="text-lg font-bold text-foreground mb-2">
Edge Network
</h3>
<p className="text-sm text-muted-foreground leading-relaxed">
Deploy to 150+ global edge locations. Sub-50ms latency anywhere on earth.
</p>
<div className="mt-6 grid grid-cols-3 gap-4 w-full">
{[
{ n: "150+", l: "Nodes" },
{ n: "50ms", l: "Latency" },
{ n: "100%", l: "Uptime" },
].map((s) => (
<div key={s.l}>
<p className="text-base font-bold text-foreground">{s.n}</p>
<p className="text-[10px] text-muted-foreground">{s.l}</p>
</div>
))}
</div>
</div>
</TiltCard>
{/* Card 3 — Dark premium */}
<TiltCard
maxTilt={16}
glareOpacity={0.2}
borderGlowColor="rgba(16, 185, 129, 0.4)"
autoPhase={4}
>
<div className="p-8 flex flex-col aspect-[4/5] justify-between">
<div>
<div className="flex items-center gap-3 mb-6">
<div className="size-10 rounded-full bg-emerald-500/10 border border-emerald-500/20 flex items-center justify-center">
<Shield className="size-5 text-emerald-400" />
</div>
<div>
<p className="text-sm font-semibold text-foreground">Enterprise</p>
<p className="text-xs text-muted-foreground">Security suite</p>
</div>
</div>
<div className="space-y-3">
{[
"SOC 2 Type II certified",
"End-to-end encryption",
"SSO with SAML & OIDC",
"Role-based access control",
"Audit logging",
].map((item) => (
<div key={item} className="flex items-center gap-2.5">
<Zap className="size-3.5 text-emerald-400 shrink-0" />
<span className="text-sm text-muted-foreground">{item}</span>
</div>
))}
</div>
</div>
<button className="mt-6 w-full rounded-lg bg-emerald-500/10 border border-emerald-500/20 py-2.5 text-sm font-semibold text-emerald-400 hover:bg-emerald-500/20 transition-colors">
Contact Sales
</button>
</div>
</TiltCard>
</div>
</div>
</div>
);
}