| import React, { useState, useEffect } from 'react'; |
| import { motion, AnimatePresence } from 'motion/react'; |
| import { Terminal, CheckCircle2, CircleDashed, Cpu, Play, Zap, BookOpen, ChevronRight } from 'lucide-react'; |
|
|
| |
|
|
| const TYPING_LINES = [ |
| { text: 'function twoSum(nums, target) {', color: '#c084fc' }, |
| { text: ' const map = new Map();', color: '#93c5fd' }, |
| { text: ' for (let i = 0; i < nums.length; i++) {', color: '#93c5fd' }, |
| { text: ' const diff = target - nums[i];', color: '#93c5fd' }, |
| { text: ' if (map.has(diff)) {', color: '#c084fc' }, |
| { text: ' return [map.get(diff), i];', color: '#f87171' }, |
| { text: ' }', color: '#93c5fd' }, |
| { text: ' map.set(nums[i], i);', color: '#fbbf24' }, |
| { text: ' }', color: '#93c5fd' }, |
| { text: ' return [];', color: '#f87171' }, |
| { text: '}', color: '#c084fc' }, |
| ]; |
|
|
| export function HeroCodeEditor() { |
| const [currentLine, setCurrentLine] = useState(0); |
| const [currentChar, setCurrentChar] = useState(0); |
| const [showToast, setShowToast] = useState(false); |
|
|
| useEffect(() => { |
| let interval: ReturnType<typeof setInterval>; |
| const start = setTimeout(() => { |
| interval = setInterval(() => { |
| setCurrentChar(prev => { |
| if (currentLine >= TYPING_LINES.length) { |
| clearInterval(interval); |
| setTimeout(() => setShowToast(true), 600); |
| return prev; |
| } |
| const len = TYPING_LINES[currentLine].text.length; |
| if (prev < len) return prev + 1; |
| setCurrentLine(l => l + 1); |
| return 0; |
| }); |
| }, 28); |
| }, 800); |
| return () => { clearTimeout(start); clearInterval(interval); }; |
| }, [currentLine]); |
|
|
| return ( |
| <div className="relative w-full max-w-[500px] mx-auto"> |
| <div className="absolute -inset-4 bg-gradient-to-r from-blue-500/20 via-violet-500/20 to-amber-500/20 blur-2xl rounded-3xl" /> |
| <motion.div |
| initial={{ opacity: 0, y: 20 }} |
| animate={{ opacity: 1, y: 0 }} |
| transition={{ duration: 0.8, ease: 'easeOut' }} |
| className="relative rounded-2xl border border-white/10 bg-[#0d0d18]/90 backdrop-blur-xl shadow-2xl overflow-hidden flex flex-col" |
| style={{ height: 300 }} |
| > |
| {/* Title bar */} |
| <div className="flex items-center justify-between px-4 py-3 border-b border-white/5 bg-black/40"> |
| <div className="flex gap-2"> |
| <div className="w-3 h-3 rounded-full bg-rose-500/80" /> |
| <div className="w-3 h-3 rounded-full bg-amber-500/80" /> |
| <div className="w-3 h-3 rounded-full bg-emerald-500/80" /> |
| </div> |
| <span className="text-[11px] font-bold text-slate-400 flex items-center gap-1.5"> |
| <span className="text-violet-400">JS</span> twoSum.js |
| </span> |
| <div className="w-8" /> |
| </div> |
| {/* Editor body */} |
| <div className="flex flex-1 overflow-hidden"> |
| <div className="w-10 bg-black/20 border-r border-white/5 py-4 flex flex-col items-end pr-2 text-[11px] text-slate-600 font-mono select-none"> |
| {TYPING_LINES.map((_, i) => <div key={i}>{i + 1}</div>)} |
| </div> |
| <div className="flex-1 p-4 font-mono text-[12px] leading-relaxed overflow-hidden"> |
| {TYPING_LINES.map((line, idx) => { |
| if (idx > currentLine) return null; |
| const isActive = idx === currentLine; |
| const text = isActive ? line.text.slice(0, currentChar) : line.text; |
| return ( |
| <div key={idx} className="whitespace-pre flex"> |
| <span style={{ color: line.color }}>{text}</span> |
| {isActive && ( |
| <motion.span |
| animate={{ opacity: [1, 0] }} |
| transition={{ duration: 0.7, repeat: Infinity, repeatType: 'reverse' }} |
| className="w-2 h-4 bg-white/70 self-center ml-0.5" |
| /> |
| )} |
| </div> |
| ); |
| })} |
| </div> |
| </div> |
| {/* Toast */} |
| <AnimatePresence> |
| {showToast && ( |
| <motion.div |
| initial={{ opacity: 0, y: 20, scale: 0.9 }} |
| animate={{ opacity: 1, y: 0, scale: 1 }} |
| className="absolute bottom-4 left-1/2 -translate-x-1/2 flex items-center gap-3 rounded-full border border-emerald-500/30 bg-emerald-500/20 px-5 py-2.5 backdrop-blur-md z-20 shadow-lg" |
| > |
| <CheckCircle2 size={16} className="text-emerald-400" /> |
| <span className="text-sm font-bold text-white">Accepted! 48ms</span> |
| </motion.div> |
| )} |
| </AnimatePresence> |
| </motion.div> |
| <motion.div |
| animate={{ y: [-8, 8, -8] }} |
| transition={{ duration: 3.5, repeat: Infinity, ease: 'easeInOut' }} |
| className="absolute -right-5 -top-5 flex h-12 w-12 items-center justify-center rounded-2xl border border-violet-500/30 bg-violet-500/20 backdrop-blur-md z-10" |
| > |
| <Zap size={18} className="text-violet-300" /> |
| </motion.div> |
| </div> |
| ); |
| } |
|
|
| |
|
|
| export function FeatureGlowCard({ icon: Icon, title, desc, color, accent, image }: { |
| icon: React.ElementType; title: string; desc: string; color: string; accent: string; image: string | null; |
| }) { |
| return ( |
| <div className="group relative flex flex-col rounded-[2rem] overflow-hidden border border-white/5 bg-[#09090f] shadow-2xl transition-all duration-300 hover:-translate-y-2"> |
| <div className="relative h-48 w-full overflow-hidden"> |
| {image ? ( |
| <img src={image} alt={title} className="w-full h-full object-cover group-hover:scale-110 transition-transform duration-700" /> |
| ) : ( |
| <div className={`w-full h-full opacity-20 bg-gradient-to-br ${color}`} /> |
| )} |
| <div className="absolute inset-0 bg-gradient-to-t from-[#09090f] to-transparent opacity-90" /> |
| </div> |
| <div className="p-8 pt-0 -mt-8 relative z-10"> |
| <div className={`w-14 h-14 rounded-2xl flex items-center justify-center mb-6 shadow-lg ring-4 ring-[#09090f] bg-gradient-to-br ${color}`}> |
| <Icon size={24} className="text-white" /> |
| </div> |
| <h3 className="text-xl font-bold mb-3 text-white">{title}</h3> |
| <p className="text-slate-400 text-sm leading-relaxed">{desc}</p> |
| </div> |
| </div> |
| ); |
| } |
|
|
| |
|
|
| export function AnimatedTerminal() { |
| const [step, setStep] = useState(0); |
|
|
| useEffect(() => { |
| const seq = async () => { |
| setStep(1); |
| await new Promise(r => setTimeout(r, 600)); |
| setStep(2); |
| await new Promise(r => setTimeout(r, 1200)); |
| setStep(3); |
| await new Promise(r => setTimeout(r, 1500)); |
| setStep(4); |
| }; |
| const interval = setInterval(() => { setStep(0); setTimeout(seq, 500); }, 7000); |
| seq(); |
| return () => clearInterval(interval); |
| }, []); |
|
|
| return ( |
| <div className="w-full max-w-[500px] rounded-2xl border border-white/10 bg-[#0c0c16]/90 backdrop-blur-xl shadow-2xl overflow-hidden font-mono flex flex-col"> |
| <div className="flex items-center justify-between border-b border-white/5 bg-black/40 px-4 py-3"> |
| <div className="flex gap-2 text-xs font-bold text-slate-400"> |
| <Terminal size={14} className="text-emerald-400" /> Test Results |
| </div> |
| <div className={`text-[10px] font-black uppercase tracking-wider px-3 py-1.5 rounded flex items-center gap-1.5 ${step >= 2 ? 'bg-slate-800/50 text-slate-400 border border-white/5' : 'bg-emerald-500/20 text-emerald-400 border border-emerald-500/30'}`}> |
| {step >= 2 ? <CircleDashed size={12} className="animate-spin" /> : <Play size={12} />} |
| {step >= 2 ? 'Evaluating...' : 'Submit Code'} |
| </div> |
| </div> |
| <div className="p-5 min-h-[220px] flex flex-col gap-4 text-sm relative"> |
| <AnimatePresence> |
| {step === 0 && ( |
| <motion.div initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }} |
| className="absolute inset-0 flex items-center justify-center text-slate-500 text-xs"> |
| Waiting for submission... |
| </motion.div> |
| )} |
| </AnimatePresence> |
| <AnimatePresence> |
| {step >= 2 && ( |
| <motion.div initial={{ opacity: 0, x: -10 }} animate={{ opacity: 1, x: 0 }} className="flex flex-col gap-3"> |
| {['Testcase 1', 'Testcase 2', 'Testcase 3'].map((tc, i) => ( |
| <div key={tc} className="flex justify-between items-center bg-white/5 px-3 py-2.5 rounded"> |
| <span className="text-slate-300 font-semibold text-xs">{tc}</span> |
| {step >= 3 |
| ? <span className="text-emerald-400 text-[11px] font-bold flex items-center gap-1.5"><CheckCircle2 size={14} /> Passed</span> |
| : <span className={`text-[11px] font-bold flex items-center gap-1.5 ${i === 0 ? 'text-amber-400' : 'text-slate-600'}`}> |
| {i === 0 ? <><CircleDashed size={14} className="animate-spin" /> Running</> : 'Pending'} |
| </span> |
| } |
| </div> |
| ))} |
| </motion.div> |
| )} |
| </AnimatePresence> |
| <AnimatePresence> |
| {step >= 4 && ( |
| <motion.div |
| initial={{ opacity: 0, y: 10, scale: 0.95 }} |
| animate={{ opacity: 1, y: 0, scale: 1 }} |
| className="absolute bottom-4 left-4 right-4 flex flex-col gap-2 rounded-xl border border-emerald-500/30 bg-emerald-900/40 backdrop-blur-md p-4 shadow-lg z-10" |
| > |
| <div className="flex items-center justify-between"> |
| <div className="font-black text-emerald-400 text-sm uppercase tracking-widest flex items-center gap-2"> |
| <CheckCircle2 size={16} /> Accepted |
| </div> |
| <div className="text-[10px] text-emerald-400/80 font-bold tracking-wider">RUNTIME: 48MS</div> |
| </div> |
| <div className="w-full bg-black/50 h-1.5 rounded-full overflow-hidden mt-1 relative"> |
| <motion.div |
| initial={{ width: 0 }} animate={{ width: '98%' }} transition={{ duration: 0.8, ease: 'easeOut' }} |
| className="absolute inset-y-0 left-0 bg-gradient-to-r from-emerald-500 to-emerald-300" |
| /> |
| </div> |
| <div className="text-[10px] text-emerald-100/70 mt-1 font-semibold">Beats 98.4% of users with JavaScript</div> |
| </motion.div> |
| )} |
| </AnimatePresence> |
| </div> |
| </div> |
| ); |
| } |
|
|
| |
|
|
| export function AnimatedNotesPreview() { |
| const [step, setStep] = useState(0); |
|
|
| useEffect(() => { |
| const seq = async () => { |
| setStep(1); |
| await new Promise(r => setTimeout(r, 800)); |
| setStep(2); |
| await new Promise(r => setTimeout(r, 600)); |
| setStep(3); |
| await new Promise(r => setTimeout(r, 1200)); |
| setStep(4); |
| await new Promise(r => setTimeout(r, 1000)); |
| setStep(5); |
| }; |
| const interval = setInterval(() => { setStep(0); setTimeout(seq, 500); }, 8000); |
| seq(); |
| return () => clearInterval(interval); |
| }, []); |
|
|
| return ( |
| <div className="w-full max-w-[500px] rounded-2xl border border-white/10 bg-[#0c0c16]/90 backdrop-blur-xl shadow-2xl overflow-hidden flex flex-col"> |
| <div className="flex items-center justify-between border-b border-white/5 bg-black/40 px-4 py-3"> |
| <div className="flex gap-2"> |
| <div className="h-3 w-3 rounded-full bg-rose-500/80" /> |
| <div className="h-3 w-3 rounded-full bg-amber-500/80" /> |
| <div className="h-3 w-3 rounded-full bg-emerald-500/80" /> |
| </div> |
| <div className="flex items-center gap-2 text-[10px] font-bold uppercase tracking-widest text-slate-500"> |
| <BookOpen size={12} className="text-amber-400" /> OS_Notes.md |
| </div> |
| <div className="w-10" /> |
| </div> |
| <div className="flex min-h-[260px] relative"> |
| {/* Sidebar */} |
| <div className="w-[130px] border-r border-white/5 bg-white/[0.01] p-3 flex flex-col gap-2"> |
| <div className="text-[10px] font-black uppercase text-slate-500 mb-2 tracking-widest">Chapters</div> |
| {['Virtual Memory', 'Scheduling', 'Deadlocks'].map((ch, i) => ( |
| <div key={ch} className={`px-3 py-2 rounded text-xs font-semibold transition-colors ${step >= 1 && i === 0 ? 'bg-amber-500/10 text-amber-400 border border-amber-500/20' : 'text-slate-500'}`}> |
| {ch} |
| </div> |
| ))} |
| </div> |
| {/* Content */} |
| <div className="flex-1 p-5 text-sm text-slate-300 leading-relaxed relative"> |
| <AnimatePresence> |
| {step === 0 && ( |
| <motion.div initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }} |
| className="absolute inset-0 flex items-center justify-center text-slate-600 font-mono text-xs"> |
| <CircleDashed size={14} className="animate-spin mr-2" /> Loading... |
| </motion.div> |
| )} |
| </AnimatePresence> |
| <AnimatePresence> |
| {step >= 2 && ( |
| <motion.h3 initial={{ opacity: 0, y: 8 }} animate={{ opacity: 1, y: 0 }} |
| className="text-xl font-black text-white mb-3 border-b border-white/10 pb-2"> |
| Virtual Memory |
| </motion.h3> |
| )} |
| </AnimatePresence> |
| <AnimatePresence> |
| {step >= 3 && ( |
| <motion.div initial={{ opacity: 0 }} animate={{ opacity: 1 }} className="space-y-3"> |
| <p className="text-[13px]">A technique that provides an <span className="text-white font-bold">idealized abstraction of storage</span>.</p> |
| <div className="relative inline-block mt-1"> |
| <span className="relative z-10 font-bold text-amber-100 text-[13px]">Creates the illusion of a very large memory.</span> |
| {step >= 4 && ( |
| <motion.div initial={{ width: 0 }} animate={{ width: '100%' }} transition={{ duration: 0.5 }} |
| className="absolute bottom-0 left-0 h-2 bg-amber-500/40 rounded-sm -z-10" /> |
| )} |
| </div> |
| </motion.div> |
| )} |
| </AnimatePresence> |
| <AnimatePresence> |
| {step >= 5 && ( |
| <motion.div initial={{ opacity: 0, scale: 0.95 }} animate={{ opacity: 1, scale: 1 }} |
| className="mt-5 p-3 rounded-xl border border-white/10 bg-white/5 flex gap-2 items-center justify-center"> |
| <div className="flex flex-col gap-1 w-16 text-center"> |
| <div className="h-5 rounded bg-blue-500/20 border border-blue-500/30 text-[9px] text-blue-400 font-bold flex items-center justify-center">Logical</div> |
| <div className="h-5 rounded bg-blue-500/20 border border-blue-500/30 text-[9px] text-blue-400 font-bold flex items-center justify-center">Memory</div> |
| </div> |
| <ChevronRight size={12} className="text-slate-500" /> |
| <div className="h-12 w-14 rounded-lg bg-amber-500/20 border border-amber-500/30 text-[9px] text-amber-400 font-bold flex items-center justify-center flex-col leading-tight"> |
| Page<br />Table |
| </div> |
| <ChevronRight size={12} className="text-slate-500" /> |
| <div className="flex flex-col gap-1 w-16 text-center"> |
| <div className="h-5 rounded bg-emerald-500/20 border border-emerald-500/30 text-[9px] text-emerald-400 font-bold flex items-center justify-center">Physical</div> |
| <div className="h-5 rounded bg-emerald-500/20 border border-emerald-500/30 text-[9px] text-emerald-400 font-bold flex items-center justify-center">RAM</div> |
| </div> |
| </motion.div> |
| )} |
| </AnimatePresence> |
| </div> |
| </div> |
| </div> |
| ); |
| } |
|
|
| |
|
|
| const ORB_TOPICS = [ |
| { label: 'DSA', color: '#3b82f6', glow: '#3b82f640', angle: 0 }, |
| { label: 'OS', color: '#a78bfa', glow: '#a78bfa40', angle: 72 }, |
| { label: 'DBMS', color: '#f59e0b', glow: '#f59e0b40', angle: 144 }, |
| { label: 'CN', color: '#34d399', glow: '#34d39940', angle: 216 }, |
| { label: 'Aptitude', color: '#f87171', glow: '#f8717140', angle: 288 }, |
| ]; |
|
|
| const INNER_TOPICS = [ |
| { label: 'DP', color: '#60a5fa', angle: 36 }, |
| { label: 'Trees', color: '#c084fc', angle: 108 }, |
| { label: 'Heap', color: '#fbbf24', angle: 180 }, |
| { label: 'Graph', color: '#4ade80', angle: 252 }, |
| { label: 'Tries', color: '#fb7185', angle: 324 }, |
| ]; |
|
|
| export function AnimatedStudyOrb() { |
| const cx = 200; |
| const cy = 200; |
| const outerR = 140; |
| const innerR = 82; |
|
|
| return ( |
| <div className="relative w-full max-w-[400px] mx-auto select-none"> |
| <div className="absolute inset-0 rounded-full blur-3xl opacity-20" |
| style={{ background: 'radial-gradient(circle, #3b82f6 0%, #a78bfa 50%, transparent 80%)' }} /> |
| <svg viewBox="0 0 400 400" className="w-full h-auto" style={{ overflow: 'visible' }}> |
| <defs> |
| <radialGradient id="coreGrad" cx="50%" cy="50%" r="50%"> |
| <stop offset="0%" stopColor="#e0f2fe" stopOpacity="1" /> |
| <stop offset="40%" stopColor="#818cf8" stopOpacity="0.9" /> |
| <stop offset="100%" stopColor="#1e1b4b" stopOpacity="0" /> |
| </radialGradient> |
| <filter id="glow"> |
| <feGaussianBlur stdDeviation="4" result="blur" /> |
| <feMerge><feMergeNode in="blur" /><feMergeNode in="SourceGraphic" /></feMerge> |
| </filter> |
| </defs> |
| <motion.circle cx={cx} cy={cy} r={outerR} |
| fill="none" stroke="rgba(99,102,241,0.15)" strokeWidth="1.5" strokeDasharray="6 10" |
| animate={{ rotate: 360 }} transition={{ duration: 40, repeat: Infinity, ease: 'linear' }} |
| style={{ originX: `${cx}px`, originY: `${cy}px` }} /> |
| <motion.circle cx={cx} cy={cy} r={innerR} |
| fill="none" stroke="rgba(167,139,250,0.15)" strokeWidth="1" strokeDasharray="3 8" |
| animate={{ rotate: -360 }} transition={{ duration: 28, repeat: Infinity, ease: 'linear' }} |
| style={{ originX: `${cx}px`, originY: `${cy}px` }} /> |
| <circle cx={cx} cy={cy} r={outerR + 30} fill="none" stroke="rgba(99,102,241,0.05)" strokeWidth="1" /> |
| <motion.circle cx={cx} cy={cy} r={44} fill="url(#coreGrad)" |
| animate={{ r: [42, 48, 42] }} transition={{ duration: 3, repeat: Infinity, ease: 'easeInOut' }} |
| filter="url(#glow)" /> |
| <motion.circle cx={cx} cy={cy} r={30} |
| fill="none" stroke="rgba(224,242,254,0.25)" strokeWidth="2" |
| animate={{ r: [28, 34, 28], opacity: [0.3, 0.7, 0.3] }} |
| transition={{ duration: 2.5, repeat: Infinity, ease: 'easeInOut' }} /> |
| <text x={cx} y={cy + 8} textAnchor="middle" fontSize="28" fill="white" opacity="0.9">📖</text> |
| {ORB_TOPICS.map((t, i) => { |
| const rad = (t.angle * Math.PI) / 180; |
| const nx = cx + outerR * Math.cos(rad); |
| const ny = cy + outerR * Math.sin(rad); |
| return ( |
| <motion.g key={t.label} animate={{ rotate: 360 }} |
| transition={{ duration: 40, repeat: Infinity, ease: 'linear' }} |
| style={{ originX: `${cx}px`, originY: `${cy}px` }}> |
| <motion.g animate={{ rotate: -360 }} |
| transition={{ duration: 40, repeat: Infinity, ease: 'linear' }} |
| style={{ originX: `${nx}px`, originY: `${ny}px` }}> |
| <circle cx={nx} cy={ny} r={22} fill={t.glow} /> |
| <motion.circle cx={nx} cy={ny} r={18} fill="#0f0f1f" stroke={t.color} strokeWidth="2" |
| animate={{ r: [17, 20, 17] }} |
| transition={{ duration: 2.5, delay: i * 0.4, repeat: Infinity, ease: 'easeInOut' }} /> |
| <text x={nx} y={ny + 4.5} textAnchor="middle" |
| fontSize={t.label.length > 3 ? '7' : '9'} fontWeight="700" fill={t.color} fontFamily="monospace"> |
| {t.label} |
| </text> |
| </motion.g> |
| </motion.g> |
| ); |
| })} |
| {INNER_TOPICS.map((t, i) => { |
| const rad = (t.angle * Math.PI) / 180; |
| const nx = cx + innerR * Math.cos(rad); |
| const ny = cy + innerR * Math.sin(rad); |
| return ( |
| <motion.g key={t.label} animate={{ rotate: -360 }} |
| transition={{ duration: 28, repeat: Infinity, ease: 'linear' }} |
| style={{ originX: `${cx}px`, originY: `${cy}px` }}> |
| <motion.g animate={{ rotate: 360 }} |
| transition={{ duration: 28, repeat: Infinity, ease: 'linear' }} |
| style={{ originX: `${nx}px`, originY: `${ny}px` }}> |
| <circle cx={nx} cy={ny} r={14} fill={`${t.color}22`} /> |
| <motion.circle cx={nx} cy={ny} r={12} fill="#0a0a18" stroke={t.color} strokeWidth="1.5" |
| animate={{ r: [11, 13.5, 11] }} |
| transition={{ duration: 2, delay: i * 0.3, repeat: Infinity, ease: 'easeInOut' }} /> |
| <text x={nx} y={ny + 4} textAnchor="middle" |
| fontSize="7" fontWeight="700" fill={t.color} fontFamily="monospace"> |
| {t.label} |
| </text> |
| </motion.g> |
| </motion.g> |
| ); |
| })} |
| </svg> |
| <motion.div |
| className="absolute top-2 right-4 px-2.5 py-1 rounded-full text-[10px] font-black text-emerald-400 border border-emerald-500/30" |
| style={{ background: 'rgba(10,20,15,0.85)', backdropFilter: 'blur(8px)' }} |
| animate={{ y: [0, -6, 0] }} transition={{ duration: 3.2, repeat: Infinity, ease: 'easeInOut' }}> |
| 500+ problems |
| </motion.div> |
| <motion.div |
| className="absolute bottom-8 left-2 px-2.5 py-1 rounded-full text-[10px] font-black text-amber-400 border border-amber-500/30" |
| style={{ background: 'rgba(15,12,5,0.85)', backdropFilter: 'blur(8px)' }} |
| animate={{ y: [0, 6, 0] }} transition={{ duration: 2.8, repeat: Infinity, ease: 'easeInOut', delay: 1 }}> |
| FAANG mapped |
| </motion.div> |
| <motion.div |
| className="absolute top-1/2 right-0 -translate-y-1/2 px-2.5 py-1 rounded-full text-[10px] font-black text-blue-400 border border-blue-500/30" |
| style={{ background: 'rgba(5,10,20,0.85)', backdropFilter: 'blur(8px)' }} |
| animate={{ y: [0, -4, 0] }} transition={{ duration: 3.6, repeat: Infinity, ease: 'easeInOut', delay: 0.5 }}> |
| AI guided |
| </motion.div> |
| </div> |
| ); |
| } |
|
|