Spaces:
Build error
Build error
| import { useEffect, useRef } from 'react'; | |
| import { gsap } from 'gsap'; | |
| import { ArrowDown, Play, Sparkles, Terminal } from 'lucide-react'; | |
| export default function Hero() { | |
| const heroRef = useRef(null); | |
| const titleRef = useRef(null); | |
| const subtitleRef = useRef(null); | |
| const ctaRef = useRef(null); | |
| const canvasRef = useRef(null); | |
| useEffect(() => { | |
| // Binary rain animation | |
| const canvas = canvasRef.current; | |
| const ctx = canvas.getContext('2d'); | |
| let animationId; | |
| const resize = () => { | |
| canvas.width = window.innerWidth; | |
| canvas.height = window.innerHeight; | |
| }; | |
| resize(); | |
| window.addEventListener('resize', resize); | |
| const chars = '01アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワヲン'; | |
| const fontSize = 14; | |
| const columns = canvas.width / fontSize; | |
| const drops = Array(Math.floor(columns)).fill(1); | |
| const draw = () => { | |
| ctx.fillStyle = 'rgba(10, 10, 15, 0.05)'; | |
| ctx.fillRect(0, 0, canvas.width, canvas.height); | |
| ctx.fillStyle = '#00f0ff'; | |
| ctx.font = `${fontSize}px JetBrains Mono`; | |
| drops.forEach((drop, i) => { | |
| const char = chars[Math.floor(Math.random() * chars.length)]; | |
| ctx.fillText(char, i * fontSize, drop * fontSize); | |
| drops[i] = drop * fontSize > canvas.height && Math.random() > 0.975 ? 0 : drop + 1; | |
| }); | |
| }; | |
| const animate = () => { | |
| draw(); | |
| animationId = requestAnimationFrame(animate); | |
| }; | |
| animate(); | |
| // GSAP Animations | |
| const tl = gsap.timeline({ defaults: { ease: 'power4.out' } }); | |
| tl.from('.hero-badge', { | |
| y: 30, | |
| opacity: 0, | |
| duration: 0.8, | |
| }) | |
| .from(titleRef.current, { | |
| y: 100, | |
| opacity: 0, | |
| duration: 1, | |
| skewY: 7, | |
| }, '-=0.4') | |
| .from(subtitleRef.current, { | |
| y: 50, | |
| opacity: 0, | |
| duration: 0.8, | |
| }, '-=0.6') | |
| .from('.hero-stats', { | |
| y: 30, | |
| opacity: 0, | |
| duration: 0.6, | |
| stagger: 0.1, | |
| }, '-=0.4') | |
| .from(ctaRef.current, { | |
| y: 30, | |
| opacity: 0, | |
| duration: 0.6, | |
| }, '-=0.3'); | |
| // Floating elements animation | |
| gsap.to('.float-element', { | |
| y: -20, | |
| rotation: 5, | |
| duration: 3, | |
| ease: 'sine.inOut', | |
| yoyo: true, | |
| repeat: -1, | |
| stagger: 0.5, | |
| }); | |
| return () => { | |
| cancelAnimationFrame(animationId); | |
| window.removeEventListener('resize', resize); | |
| }; | |
| }, []); | |
| const scrollToWorkbench = () => { | |
| document.getElementById('workbench').scrollIntoView({ behavior: 'smooth' }); | |
| }; | |
| return ( | |
| <section ref={heroRef} className="relative min-h-screen flex items-center justify-center overflow-hidden pt-20"> | |
| {/* Binary Rain Canvas */} | |
| <canvas ref={canvasRef} className="absolute inset-0 pointer-events-none opacity-30" /> | |
| {/* Gradient Orbs */} | |
| <div className="absolute top-1/4 left-1/4 w-96 h-96 bg-electric-500/20 rounded-full blur-3xl animate-pulse-slow" /> | |
| <div className="absolute bottom-1/4 right-1/4 w-96 h-96 bg-magma-500/20 rounded-full blur-3xl animate-pulse-slow" style={{ animationDelay: '1s' }} /> | |
| <div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[600px] h-[600px] bg-gold-500/10 rounded-full blur-3xl animate-pulse-slow" style={{ animationDelay: '2s' }} /> | |
| {/* Grid Pattern */} | |
| <div className="absolute inset-0 grid-pattern opacity-50" /> | |
| {/* Floating Code Elements */} | |
| <div className="absolute left-10 top-1/3 float-element hidden lg:block"> | |
| <div className="bg-iron-800/80 backdrop-blur-sm border border-iron-600/50 rounded-lg p-4 font-mono text-xs text-electric-400"> | |
| <div className="flex items-center gap-2 mb-2 text-iron-400"> | |
| <Terminal className="w-4 h-4" /> | |
| <span>bash</span> | |
| </div> | |
| <p className="terminal-cursor">npm run optimize</p> | |
| </div> | |
| </div> | |
| <div className="absolute right-10 top-1/2 float-element hidden lg:block" style={{ animationDelay: '0.5s' }}> | |
| <div className="bg-iron-800/80 backdrop-blur-sm border border-iron-600/50 rounded-lg p-4 font-mono text-xs text-magma-400"> | |
| <p>{`{`}</p> | |
| <p className="pl-2">"performance": "99.9%",</p> | |
| <p className="pl-2">"optimization": "complete"</p> | |
| <p>{`}`}</p> | |
| </div> | |
| </div> | |
| <div className="absolute left-20 bottom-1/3 float-element hidden lg:block" style={{ animationDelay: '1s' }}> | |
| <div className="bg-iron-800/80 backdrop-blur-sm border border-iron-600/50 rounded-lg p-3 font-mono text-xs text-gold-400"> | |
| <Sparkles className="w-4 h-4 mb-1" /> | |
| <p>AI Enhanced</p> | |
| </div> | |
| </div> | |
| {/* Main Content */} | |
| <div className="relative z-10 max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 text-center"> | |
| {/* Badge */} | |
| <div className="hero-badge inline-flex items-center gap-2 px-4 py-2 rounded-full bg-iron-800/80 border border-electric-500/30 mb-8"> | |
| <span className="w-2 h-2 bg-electric-500 rounded-full animate-pulse" /> | |
| <span className="font-mono text-sm text-electric-400">SYSTEM ONLINE v2.024</span> | |
| </div> | |
| {/* Title */} | |
| <h1 ref={titleRef} className="text-5xl sm:text-7xl lg:text-8xl font-bold mb-6 tracking-tight"> | |
| <span className="block text-iron-100 glitch" data-text="FORGE YOUR">FORGE YOUR</span> | |
| <span className="block text-gradient">DIGITAL EDGE</span> | |
| </h1> | |
| {/* Subtitle */} | |
| <p ref={subtitleRef} className="max-w-2xl mx-auto text-lg sm:text-xl text-iron-300 mb-12 font-mono leading-relaxed"> | |
| Advanced protocols for developers who refuse to settle. | |
| Master the arcane arts of performance, automation, and system architecture. | |
| </p> | |
| {/* Stats */} | |
| <div className="flex flex-wrap justify-center gap-8 mb-12"> | |
| {[ | |
| { value: '500+', label: 'Pro Tips' }, | |
| { value: '50K+', label: 'Developers' }, | |
| { value: '99.9%', label: 'Uptime' }, | |
| ].map((stat, i) => ( | |
| <div key={i} className="hero-stats text-center"> | |
| <div className="text-3xl sm:text-4xl font-bold text-electric-500 font-mono">{stat.value}</div> | |
| <div className="text-sm text-iron-400 font-mono uppercase tracking-wider">{stat.label}</div> | |
| </div> | |
| ))} | |
| </div> | |
| {/* CTA Buttons */} | |
| <div ref={ctaRef} className="flex flex-col sm:flex-row gap-4 justify-center"> | |
| <button | |
| onClick={scrollToWorkbench} | |
| className="group relative px-8 py-4 bg-gradient-to-r from-electric-500 to-electric-400 text-iron-900 font-mono font-semibold rounded-lg overflow-hidden transition-all hover:scale-105" | |
| > | |
| <span className="relative z-10 flex items-center justify-center gap-2"> | |
| <Play className="w-5 h-5" /> | |
| ENTER THE LAB | |
| </span> | |
| <div className="absolute inset-0 bg-gradient-to-r from-magma-500 to-electric-500 opacity-0 group-hover:opacity-100 transition-opacity duration-500" /> | |
| </button> | |
| <button className="group px-8 py-4 border border-iron-600 text-iron-200 font-mono font-semibold rounded-lg hover:border-electric-500 hover:text-electric-500 transition-all flex items-center justify-center gap-2"> | |
| <ArrowDown className="w-5 h-5 group-hover:translate-y-1 transition-transform" /> | |
| EXPLORE ARCHIVE | |
| </button> | |
| </div> | |
| </div> | |
| {/* Scroll Indicator */} | |
| <div className="absolute bottom-8 left-1/2 -translate-x-1/2"> | |
| <div className="w-6 h-10 border-2 border-iron-600 rounded-full flex justify-center pt-2"> | |
| <div className="w-1.5 h-3 bg-electric-500 rounded-full animate-bounce" /> | |
| </div> | |
| </div> | |
| </section> | |
| ); | |
| } |