Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Start - Interactive Onboarding</title> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet"> | |
| <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;600;800&display=swap" rel="stylesheet"> | |
| <style> | |
| body { | |
| font-family: 'Inter', sans-serif; | |
| overflow: hidden; | |
| background-color: #0f172a; | |
| } | |
| /* Custom Animations */ | |
| @keyframes float { | |
| 0%, 100% { transform: translateY(0px); } | |
| 50% { transform: translateY(-20px); } | |
| } | |
| @keyframes pulse-glow { | |
| 0%, 100% { box-shadow: 0 0 20px rgba(56, 189, 248, 0.5); } | |
| 50% { box-shadow: 0 0 40px rgba(56, 189, 248, 0.8); } | |
| } | |
| @keyframes slide-up-fade { | |
| from { opacity: 0; transform: translateY(20px); } | |
| to { opacity: 1; transform: translateY(0); } | |
| } | |
| @keyframes gradient-shift { | |
| 0% { background-position: 0% 50%; } | |
| 50% { background-position: 100% 50%; } | |
| 100% { background-position: 0% 50%; } | |
| } | |
| .animate-float { animation: float 6s ease-in-out infinite; } | |
| .animate-float-delayed { animation: float 6s ease-in-out 3s infinite; } | |
| .glass-panel { | |
| background: rgba(255, 255, 255, 0.05); | |
| backdrop-filter: blur(16px); | |
| -webkit-backdrop-filter: blur(16px); | |
| border: 1px solid rgba(255, 255, 255, 0.1); | |
| box-shadow: 0 4px 30px rgba(0, 0, 0, 0.1); | |
| } | |
| .gradient-text { | |
| background: linear-gradient(135deg, #60a5fa 0%, #c084fc 50%, #f472b6 100%); | |
| background-size: 200% auto; | |
| -webkit-background-clip: text; | |
| -webkit-text-fill-color: transparent; | |
| animation: gradient-shift 5s ease infinite; | |
| } | |
| .step-transition { | |
| transition: all 0.6s cubic-bezier(0.22, 1, 0.36, 1); | |
| } | |
| /* Custom Scrollbar for content areas if needed */ | |
| ::-webkit-scrollbar { width: 6px; } | |
| ::-webkit-scrollbar-track { background: transparent; } | |
| ::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.2); border-radius: 3px; } | |
| .selection-card { | |
| transition: all 0.3s ease; | |
| } | |
| .selection-card:hover { | |
| transform: translateY(-4px); | |
| background: rgba(255, 255, 255, 0.1); | |
| border-color: rgba(255, 255, 255, 0.3); | |
| } | |
| .selection-card.selected { | |
| background: rgba(56, 189, 248, 0.15); | |
| border-color: #38bdf8; | |
| box-shadow: 0 0 20px rgba(56, 189, 248, 0.2); | |
| } | |
| .loader-bar { | |
| transition: width 1s ease-in-out; | |
| } | |
| </style> | |
| </head> | |
| <body class="text-white h-screen w-screen relative"> | |
| <!-- Background Canvas for Particles --> | |
| <canvas id="bgCanvas" class="absolute inset-0 z-0"></canvas> | |
| <!-- Overlay Gradient --> | |
| <div class="absolute inset-0 z-0 bg-gradient-to-b from-slate-900/80 via-slate-900/50 to-slate-900/90 pointer-events-none"></div> | |
| <!-- Main Application Container --> | |
| <main class="relative z-10 h-full w-full flex flex-col items-center justify-center p-6"> | |
| <!-- Header / Logo Area --> | |
| <header class="absolute top-8 left-0 w-full flex justify-between items-center px-8 md:px-16"> | |
| <div class="flex items-center gap-3 group cursor-pointer"> | |
| <div class="w-10 h-10 rounded-xl bg-gradient-to-br from-blue-500 to-purple-600 flex items-center justify-center shadow-lg group-hover:scale-110 transition-transform"> | |
| <i class="fa-solid fa-rocket text-white text-lg"></i> | |
| </div> | |
| <span class="text-xl font-bold tracking-tight">Nexus<span class="text-blue-400">Start</span></span> | |
| </div> | |
| <div class="hidden md:flex items-center gap-4 text-sm text-slate-400"> | |
| <span>v2.4.0</span> | |
| <div class="h-4 w-px bg-slate-700"></div> | |
| <span class="hover:text-white cursor-pointer transition-colors">Help</span> | |
| </div> | |
| <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" class="text-xs text-slate-500 hover:text-blue-400 transition-colors flex items-center gap-2"> | |
| <i class="fa-solid fa-code"></i> Built with anycoder | |
| </a> | |
| </header> | |
| <!-- Progress Bar (Top Center) --> | |
| <div class="absolute top-8 left-1/2 -translate-x-1/2 w-64 h-1 bg-slate-800 rounded-full overflow-hidden hidden md:block"> | |
| <div id="progressBar" class="h-full bg-gradient-to-r from-blue-500 to-purple-500 w-0 loader-bar"></div> | |
| </div> | |
| <!-- Content Area --> | |
| <div id="app-container" class="w-full max-w-4xl h-[600px] relative perspective-1000"> | |
| <!-- STEP 1: Hero / Welcome --> | |
| <section id="step-1" class="step-section absolute inset-0 flex flex-col items-center justify-center text-center step-transition opacity-100 translate-y-0"> | |
| <div class="relative mb-8 animate-float"> | |
| <div class="absolute inset-0 bg-blue-500 blur-3xl opacity-20 rounded-full"></div> | |
| <img src="https://images.unsplash.com/photo-1618005182384-a83a8bd57fbe?q=80&w=1000&auto=format&fit=crop" | |
| alt="Abstract 3D" | |
| class="w-48 h-48 object-cover rounded-full border-4 border-white/10 shadow-2xl relative z-10 mask-image-gradient"> | |
| </div> | |
| <h1 class="text-5xl md:text-7xl font-extrabold mb-6 tracking-tight"> | |
| Ready to <span class="gradient-text">Start?</span> | |
| </h1> | |
| <p class="text-slate-400 text-lg md:text-xl max-w-lg mb-10 leading-relaxed"> | |
| Experience the next generation of digital workflow. Seamless, powerful, and designed for creators. | |
| </p> | |
| <button onclick="app.nextStep()" class="group relative px-8 py-4 bg-white text-slate-900 rounded-full font-bold text-lg overflow-hidden transition-all hover:scale-105 hover:shadow-[0_0_40px_rgba(255,255,255,0.3)]"> | |
| <span class="relative z-10 flex items-center gap-2"> | |
| Get Started <i class="fa-solid fa-arrow-right group-hover:translate-x-1 transition-transform"></i> | |
| </span> | |
| <div class="absolute inset-0 bg-gradient-to-r from-blue-200 to-purple-200 opacity-0 group-hover:opacity-100 transition-opacity"></div> | |
| </button> | |
| </section> | |
| <!-- STEP 2: Role Selection --> | |
| <section id="step-2" class="step-section absolute inset-0 flex flex-col items-center justify-center step-transition opacity-0 translate-y-10 pointer-events-none"> | |
| <h2 class="text-3xl md:text-4xl font-bold mb-2">What describes you best?</h2> | |
| <p class="text-slate-400 mb-10">We'll customize your dashboard based on your role.</p> | |
| <div class="grid grid-cols-1 md:grid-cols-3 gap-6 w-full px-4"> | |
| <!-- Card 1 --> | |
| <div class="selection-card glass-panel p-6 rounded-2xl cursor-pointer border border-white/5" onclick="app.selectRole('developer', this)"> | |
| <div class="w-12 h-12 rounded-lg bg-blue-500/20 text-blue-400 flex items-center justify-center mb-4 text-xl"> | |
| <i class="fa-solid fa-code"></i> | |
| </div> | |
| <h3 class="text-xl font-bold mb-2">Developer</h3> | |
| <p class="text-sm text-slate-400">Building the future with code, APIs, and logic.</p> | |
| </div> | |
| <!-- Card 2 --> | |
| <div class="selection-card glass-panel p-6 rounded-2xl cursor-pointer border border-white/5" onclick="app.selectRole('designer', this)"> | |
| <div class="w-12 h-12 rounded-lg bg-purple-500/20 text-purple-400 flex items-center justify-center mb-4 text-xl"> | |
| <i class="fa-solid fa-pen-nib"></i> | |
| </div> | |
| <h3 class="text-xl font-bold mb-2">Designer</h3> | |
| <p class="text-sm text-slate-400">Crafting visual experiences and user interfaces.</p> | |
| </div> | |
| <!-- Card 3 --> | |
| <div class="selection-card glass-panel p-6 rounded-2xl cursor-pointer border border-white/5" onclick="app.selectRole('manager', this)"> | |
| <div class="w-12 h-12 rounded-lg bg-pink-500/20 text-pink-400 flex items-center justify-center mb-4 text-xl"> | |
| <i class="fa-solid fa-chart-line"></i> | |
| </div> | |
| <h3 class="text-xl font-bold mb-2">Manager</h3> | |
| <p class="text-sm text-slate-400">Leading teams, tracking progress, and strategy.</p> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- STEP 3: Interests / Features --> | |
| <section id="step-3" class="step-section absolute inset-0 flex flex-col items-center justify-center step-transition opacity-0 translate-y-10 pointer-events-none"> | |
| <h2 class="text-3xl md:text-4xl font-bold mb-2">Select your interests</h2> | |
| <p class="text-slate-400 mb-8">Pick at least 2 topics to personalize your feed.</p> | |
| <div class="flex flex-wrap justify-center gap-3 max-w-2xl mb-10" id="tags-container"> | |
| <!-- Tags generated by JS --> | |
| </div> | |
| <button id="btn-step-3" onclick="app.nextStep()" class="px-8 py-3 bg-slate-700 text-slate-400 rounded-full font-semibold transition-all cursor-not-allowed" disabled> | |
| Continue | |
| </button> | |
| </section> | |
| <!-- STEP 4: Processing / Loading --> | |
| <section id="step-4" class="step-section absolute inset-0 flex flex-col items-center justify-center step-transition opacity-0 translate-y-10 pointer-events-none"> | |
| <div class="relative w-32 h-32 mb-8"> | |
| <div class="absolute inset-0 border-4 border-slate-700 rounded-full"></div> | |
| <div class="absolute inset-0 border-4 border-t-blue-500 border-r-transparent border-b-purple-500 border-l-transparent rounded-full animate-spin"></div> | |
| <div class="absolute inset-0 flex items-center justify-center text-2xl font-bold" id="loading-percentage">0%</div> | |
| </div> | |
| <h2 class="text-2xl font-bold mb-2 animate-pulse">Setting up your workspace...</h2> | |
| <p class="text-slate-400 text-sm" id="loading-text">Initializing core modules...</p> | |
| </section> | |
| <!-- STEP 5: Success / Dashboard Preview --> | |
| <section id="step-5" class="step-section absolute inset-0 flex flex-col items-center justify-center step-transition opacity-0 translate-y-10 pointer-events-none scale-95"> | |
| <div class="glass-panel p-8 rounded-3xl border border-white/10 shadow-2xl max-w-md w-full text-center relative overflow-hidden"> | |
| <!-- Confetti Canvas Layer inside card --> | |
| <canvas id="confettiCanvas" class="absolute inset-0 pointer-events-none z-0"></canvas> | |
| <div class="relative z-10"> | |
| <div class="w-20 h-20 bg-green-500 rounded-full flex items-center justify-center mx-auto mb-6 shadow-[0_0_30px_rgba(34,197,94,0.5)] animate-[bounce_1s_infinite]"> | |
| <i class="fa-solid fa-check text-3xl text-white"></i> | |
| </div> | |
| <h2 class="text-3xl font-bold mb-2">You're all set!</h2> | |
| <p class="text-slate-300 mb-8">Welcome aboard, <span id="user-role-display" class="text-blue-400 font-semibold">Creator</span>.</p> | |
| <div class="space-y-3"> | |
| <button onclick="location.reload()" class="w-full py-3 bg-gradient-to-r from-blue-600 to-purple-600 rounded-xl font-bold hover:shadow-lg hover:scale-[1.02] transition-all"> | |
| Launch Dashboard | |
| </button> | |
| <button onclick="location.reload()" class="w-full py-3 bg-transparent border border-white/10 rounded-xl font-medium hover:bg-white/5 transition-all text-slate-400 hover:text-white"> | |
| Restart Demo | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| </div> | |
| <!-- Navigation Controls --> | |
| <div class="absolute bottom-8 flex gap-4"> | |
| <button id="btn-prev" onclick="app.prevStep()" class="w-12 h-12 rounded-full glass-panel flex items-center justify-center hover:bg-white/10 transition-all opacity-0 pointer-events-none"> | |
| <i class="fa-solid fa-arrow-left"></i> | |
| </button> | |
| <div class="flex gap-2 items-center" id="dots-container"> | |
| <div class="w-2 h-2 rounded-full bg-white transition-all duration-300"></div> | |
| <div class="w-2 h-2 rounded-full bg-slate-600 transition-all duration-300"></div> | |
| <div class="w-2 h-2 rounded-full bg-slate-600 transition-all duration-300"></div> | |
| <div class="w-2 h-2 rounded-full bg-slate-600 transition-all duration-300"></div> | |
| <div class="w-2 h-2 rounded-full bg-slate-600 transition-all duration-300"></div> | |
| </div> | |
| </div> | |
| </main> | |
| <script> | |
| /** | |
| * Application Logic | |
| */ | |
| const app = { | |
| currentStep: 1, | |
| totalSteps: 5, | |
| selectedRole: null, | |
| selectedTags: new Set(), | |
| // Data for Step 3 | |
| tags: [ | |
| "UI/UX Design", "Machine Learning", "Web3", "Mobile Dev", | |
| "DevOps", "Marketing", "SaaS", "E-commerce", "Open Source", | |
| "Cloud Computing", "Data Science", "Cybersecurity" | |
| ], | |
| init() { | |
| this.renderTags(); | |
| this.initCanvas(); | |
| this.updateUI(); | |
| }, | |
| nextStep() { | |
| if (this.currentStep < this.totalSteps) { | |
| this.transition(this.currentStep, this.currentStep + 1); | |
| this.currentStep++; | |
| this.updateUI(); | |
| if (this.currentStep === 4) this.simulateLoading(); | |
| if (this.currentStep === 5) this.triggerConfetti(); | |
| } | |
| }, | |
| prevStep() { | |
| if (this.currentStep > 1) { | |
| this.transition(this.currentStep, this.currentStep - 1); | |
| this.currentStep--; | |
| this.updateUI(); | |
| } | |
| }, | |
| transition(from, to) { | |
| const fromEl = document.getElementById(`step-${from}`); | |
| const toEl = document.getElementById(`step-${to}`); | |
| // Animate Out | |
| fromEl.style.opacity = '0'; | |
| fromEl.style.transform = 'translateY(-20px) scale(0.95)'; | |
| fromEl.style.pointerEvents = 'none'; | |
| // Animate In | |
| setTimeout(() => { | |
| toEl.style.opacity = '1'; | |
| toEl.style.transform = 'translateY(0) scale(1)'; | |
| toEl.style.pointerEvents = 'auto'; | |
| }, 300); | |
| }, | |
| updateUI() { | |
| // Progress Bar | |
| const progress = ((this.currentStep - 1) / (this.totalSteps - 1)) * 100; | |
| document.getElementById('progressBar').style.width = `${progress}%`; | |
| // Prev Button | |
| const prevBtn = document.getElementById('btn-prev'); | |
| if (this.currentStep > 1 && this.currentStep < 5) { | |
| prevBtn.style.opacity = '1'; | |
| prevBtn.style.pointerEvents = 'auto'; | |
| } else { | |
| prevBtn.style.opacity = '0'; | |
| prevBtn.style.pointerEvents = 'none'; | |
| } | |
| // Dots | |
| const dots = document.getElementById('dots-container').children; | |
| Array.from(dots).forEach((dot, index) => { | |
| if (index + 1 === this.currentStep) { | |
| dot.classList.remove('bg-slate-600'); | |
| dot.classList.add('bg-white', 'scale-125'); | |
| } else { | |
| dot.classList.add('bg-slate-600'); | |
| dot.classList.remove('bg-white', 'scale-125'); | |
| } | |
| }); | |
| }, | |
| selectRole(role, element) { | |
| this.selectedRole = role; | |
| // Visual selection | |
| document.querySelectorAll('.selection-card').forEach(el => el.classList.remove('selected')); | |
| element.classList.add('selected'); | |
| // Auto advance after short delay | |
| setTimeout(() => this.nextStep(), 600); | |
| }, | |
| renderTags() { | |
| const container = document.getElementById('tags-container'); | |
| container.innerHTML = this.tags.map(tag => ` | |
| <button class="px-4 py-2 rounded-full border border-slate-600 text-slate-300 text-sm hover:border-blue-400 hover:text-blue-400 transition-all select-none" | |
| onclick="app.toggleTag(this, '${tag}')"> | |
| ${tag} | |
| </button> | |
| `).join(''); | |
| }, | |
| toggleTag(btn, tag) { | |
| if (this.selectedTags.has(tag)) { | |
| this.selectedTags.delete(tag); | |
| btn.classList.remove('bg-blue-500', 'border-blue-500', 'text-white'); | |
| btn.classList.add('border-slate-600', 'text-slate-300'); | |
| } else { | |
| this.selectedTags.add(tag); | |
| btn.classList.add('bg-blue-500', 'border-blue-500', 'text-white'); | |
| btn.classList.remove('border-slate-600', 'text-slate-300'); | |
| } | |
| this.validateStep3(); | |
| }, | |
| validateStep3() { | |
| const btn = document.getElementById('btn-step-3'); | |
| if (this.selectedTags.size >= 2) { | |
| btn.removeAttribute('disabled'); | |
| btn.classList.remove('bg-slate-700', 'text-slate-400', 'cursor-not-allowed'); | |
| btn.classList.add('bg-white', 'text-slate-900', 'hover:scale-105', 'shadow-lg'); | |
| } else { | |
| btn.setAttribute('disabled', 'true'); | |
| btn.classList.add('bg-slate-700', 'text-slate-400', 'cursor-not-allowed'); | |
| btn.classList.remove('bg-white', 'text-slate-900', 'hover:scale-105', 'shadow-lg'); | |
| } | |
| }, | |
| simulateLoading() { | |
| const percentageEl = document.getElementById('loading-percentage'); | |
| const textEl = document.getElementById('loading-text'); | |
| let progress = 0; | |
| const texts = [ | |
| "Initializing core modules...", | |
| "Loading user preferences...", | |
| "Compiling assets...", | |
| "Connecting to server...", | |
| "Finalizing setup..." | |
| ]; | |
| const interval = setInterval(() => { | |
| progress += Math.floor(Math.random() * 5) + 1; | |
| if (progress > 100) progress = 100; | |
| percentageEl.innerText = `${progress}%`; | |
| // Update text based on progress | |
| const textIndex = Math.floor((progress / 100) * texts.length); | |
| if (texts[textIndex]) textEl.innerText = texts[textIndex]; | |
| if (progress === 100) { | |
| clearInterval(interval); | |
| setTimeout(() => this.nextStep(), 500); | |
| } | |
| }, 50); | |
| }, | |
| triggerConfetti() { | |
| const canvas = document.getElementById('confettiCanvas'); | |
| const ctx = canvas.getContext('2d'); | |
| canvas.width = canvas.parentElement.offsetWidth; | |
| canvas.height = canvas.parentElement.offsetHeight; | |
| const particles = []; | |
| const colors = ['#60a5fa', '#c084fc', '#f472b6', '#ffffff']; | |
| for (let i = 0; i < 100; i++) { | |
| particles.push({ | |
| x: canvas.width / 2, | |
| y: canvas.height / 2, | |
| vx: (Math.random() - 0.5) * 10, | |
| vy: (Math.random() - 0.5) * 10 - 5, | |
| size: Math.random() * 5 + 2, | |
| color: colors[Math.floor(Math.random() * colors.length)], | |
| life: 100 | |
| }); | |
| } | |
| const animate = () => { | |
| ctx.clearRect(0, 0, canvas.width, canvas.height); | |
| let active = false; | |
| particles.forEach(p => { | |
| if (p.life > 0) { | |
| active = true; | |
| p.x += p.vx; | |
| p.y += p.vy; | |
| p.vy += 0.2; // gravity | |
| p.life--; | |
| p.size *= 0.96; | |
| ctx.fillStyle = p.color; | |
| ctx.beginPath(); | |
| ctx.arc(p.x, p.y, p.size, 0, Math.PI * 2); | |
| ctx.fill(); | |
| } | |
| }); | |
| if (active) requestAnimationFrame(animate); | |
| }; | |
| animate(); | |
| // Update role text | |
| const roleText = this.selectedRole ? this.selectedRole.charAt(0).toUpperCase() + this.selectedRole.slice(1) : "Creator"; | |
| document.getElementById('user-role-display').innerText = roleText; | |
| }, | |
| initCanvas() { | |
| // Background Particle Network | |
| const canvas = document.getElementById('bgCanvas'); | |
| const ctx = canvas.getContext('2d'); | |
| let width, height; | |
| let particles = []; | |
| const resize = () => { | |
| width = window.innerWidth; | |
| height = window.innerHeight; | |
| canvas.width = width; | |
| canvas.height = height; | |
| createParticles(); | |
| }; | |
| const createParticles = () => { | |
| particles = []; | |
| const count = Math.floor((width * height) / 15000); | |
| for (let i = 0; i < count; i++) { | |
| particles.push({ | |
| x: Math.random() * width, | |
| y: Math.random() * height, | |
| vx: (Math.random() - 0.5) * 0.5, | |
| vy: (Math.random() - 0.5) * 0.5, | |
| size: Math.random() * 2 | |
| }); | |
| } | |
| }; | |
| const animate = () => { | |
| ctx.clearRect(0, 0, width, height); | |
| ctx.fillStyle = 'rgba(255, 255, 255, 0.5)'; | |
| particles.forEach((p, i) => { | |
| p.x += p.vx; | |
| p.y += p.vy; | |
| if (p.x < 0 || p.x > width) p.vx *= -1; | |
| if (p.y < 0 || p.y > height) p.vy *= -1; | |
| ctx.beginPath(); | |
| ctx.arc(p.x, p.y, p.size, 0, Math.PI * 2); | |
| ctx.fill(); | |
| // Connections | |
| for (let j = i + 1; j < particles.length; j++) { | |
| const p2 = particles[j]; | |
| const dx = p.x - p2.x; | |
| const dy = p.y - p2.y; | |
| const dist = Math.sqrt(dx*dx + dy*dy); | |
| if (dist < 100) { | |
| ctx.strokeStyle = `rgba(255, 255, 255, ${0.1 - dist/1000})`; | |
| ctx.lineWidth = 1; | |
| ctx.beginPath(); | |
| ctx.moveTo(p.x, p.y); | |
| ctx.lineTo(p2.x, p2.y); | |
| ctx.stroke(); | |
| } | |
| } | |
| }); | |
| requestAnimationFrame(animate); | |
| }; | |
| window.addEventListener('resize', resize); | |
| resize(); | |
| animate(); | |
| } | |
| }; | |
| // Initialize on load | |
| document.addEventListener('DOMContentLoaded', () => { | |
| app.init(); | |
| }); | |
| </script> | |
| </body> | |
| </html> |