Components
A physics-based card deck gallery featuring 3D mouse parallax, glowing accents, and smooth shuffle animations.
Loading preview...
'use client';
import React, { useState } from 'react';
import { motion } from 'framer-motion';
import { ArrowRight, Hexagon } from 'lucide-react';
import CardStack, { Feature } from '@/components/ui/cinematic-shuffle-stack'; // Ensure path is correct
/* ---------- Data ---------- */
const FEATURES: Feature[] = [
{
id: '01',
title: 'Quantum Core',
subtitle: 'Processing Unit',
description: 'Next-generation processing architecture designed to handle probabilistic computing states with zero latency.',
tags: ['Hardware', 'R&D'],
image: 'https://images.unsplash.com/photo-1635070041078-e363dbe005cb?q=80&w=1000&auto=format&fit=crop',
color: '#3b82f6',
},
{
id: '02',
title: 'Neural Mesh',
subtitle: 'Network Layer',
description: 'A self-healing decentralized network that mimics biological synaptic plasticity for unbreakable connectivity.',
tags: ['Network', 'AI'],
image: 'https://images.pexels.com/photos/17484899/pexels-photo-17484899.png',
color: '#ec4899',
},
{
id: '03',
title: 'Obsidian Vault',
subtitle: 'Security Protocol',
description: 'Military-grade encryption utilizing distinct light-refraction keys stored in synthetic crystal structures.',
tags: ['Security', 'Crypto'],
image: 'https://images.unsplash.com/photo-1550751827-4bd374c3f58b?q=80&w=1000&auto=format&fit=crop',
color: '#10b981',
},
{
id: '04',
title: 'Aero Dynamics',
subtitle: 'Propulsion System',
description: 'Silent propulsion systems derived from ionic wind technology, allowing for frictionless atmospheric travel.',
tags: ['Aero', 'Physics'],
image: 'https://images.pexels.com/photos/33534366/pexels-photo-33534366.jpeg',
color: '#f59e0b',
},
];
/* ---------- Main Component ---------- */
function ShuffleStack() {
const [activeId, setActiveId] = useState<string>(FEATURES[0].id);
return (
<div className="relative min-h-screen w-full bg-[#050505] text-neutral-200 overflow-hidden flex flex-col justify-center py-12 px-6 md:px-12 md:py-20">
{/* Background Atmosphere */}
<div className="pointer-events-none absolute inset-0 bg-[radial-gradient(circle_at_80%_20%,rgba(255,255,255,0.05),transparent_40%)]" />
<div className="pointer-events-none absolute inset-0 bg-[url('https://grainy-gradients.vercel.app/noise.svg')] opacity-[0.03]" />
<div className="mx-auto w-full max-w-7xl grid grid-cols-1 lg:grid-cols-2 gap-8 lg:gap-24 items-center">
{/* RIGHT COLUMN (Stack) - Order Logic:
Mobile: order-1 (Top)
Desktop: order-2 (Right)
*/}
<div className="relative h-[400px] lg:h-[600px] w-full flex items-center justify-center order-2 lg:order-1 perspective-1000">
<CardStack activeId={activeId} features={FEATURES} />
</div>
{/* LEFT COLUMN (Text Content) - Order Logic:
Mobile: order-2 (Bottom)
Desktop: order-1 (Left)
*/}
<div className="relative z-10 flex flex-col gap-2 order-1 lg:order-2">
<div className="mb-8 md:mb-12">
<motion.div
initial={{ opacity: 0, x: -20 }}
animate={{ opacity: 1, x: 0 }}
className="flex items-center gap-2 text-xs font-mono text-neutral-500 uppercase tracking-widest mb-4"
>
<Hexagon size={14} className="text-white" />
<span>System Architecture</span>
</motion.div>
<h1 className="text-4xl md:text-5xl font-medium text-white tracking-tight">
Core <span className="text-neutral-600">Modules</span>
</h1>
</div>
<div className="flex flex-col gap-6">
{FEATURES.map((feature) => (
<ListItem
key={feature.id}
feature={feature}
isActive={activeId === feature.id}
onClick={() => setActiveId(feature.id)}
/>
))}
</div>
</div>
</div>
</div>
);
}
/* ---------- Sub-Component: List Item ---------- */
function ListItem({
feature,
isActive,
onClick,
}: {
feature: Feature;
isActive: boolean;
onClick: () => void;
}) {
return (
<div
className={`group relative flex flex-col gap-4 border-l-2 transition-all duration-500 ${
isActive ? 'border-white pl-8' : 'border-neutral-800 pl-6 hover:pl-8 hover:border-neutral-700'
} cursor-pointer`}
onClick={onClick}
>
{/* Active Indicator Glow (Left Border) */}
{isActive && (
<motion.div
layoutId="activeGlow"
className="absolute left-[-2px] top-0 bottom-0 w-[2px] shadow-[0_0_20px_2px_rgba(255,255,255,0.5)] bg-white"
/>
)}
{/* Header Section */}
<div className="flex justify-between items-center">
<div>
<h3 className={`text-xl md:text-2xl font-medium transition-colors duration-300 ${isActive ? 'text-white' : 'text-neutral-500 group-hover:text-neutral-300'}`}>
{feature.title}
</h3>
<p className="text-[10px] md:text-xs font-mono uppercase tracking-wider text-neutral-600 mt-1">
{feature.subtitle}
</p>
</div>
{/* Arrow Icon */}
<motion.div
animate={{
x: isActive ? 0 : -10,
opacity: isActive ? 1 : 0
}}
>
<ArrowRight className="text-white" size={20} />
</motion.div>
</div>
{/* Expanded Details */}
<motion.div
initial={false}
animate={{
height: isActive ? 'auto' : 0,
opacity: isActive ? 1 : 0
}}
className="overflow-hidden"
>
<p className="text-neutral-400 text-sm md:text-base leading-relaxed max-w-md pb-4 pt-2">
{feature.description}
</p>
<div className="flex gap-2 pb-4">
{feature.tags.map(tag => (
<span key={tag} className="text-[10px] uppercase font-bold px-2 py-1 bg-neutral-900 border border-neutral-800 rounded text-neutral-400">
{tag}
</span>
))}
</div>
</motion.div>
</div>
);
}
export default function DemoOne() {
return <ShuffleStack />;
}