107 lines
3.7 KiB
TypeScript
107 lines
3.7 KiB
TypeScript
import { useState, useEffect, useRef } from 'react';
|
|
import GadgetGrid from './GadgetGrid';
|
|
import { isWebGLAvailable } from '../lib/webgl-detect';
|
|
|
|
export default function Hero() {
|
|
const [webgl, setWebgl] = useState(true);
|
|
const [visible, setVisible] = useState(false);
|
|
const containerRef = useRef<HTMLDivElement>(null);
|
|
|
|
useEffect(() => {
|
|
setWebgl(isWebGLAvailable());
|
|
// Trigger entrance animation after mount
|
|
requestAnimationFrame(() => setVisible(true));
|
|
}, []);
|
|
|
|
return (
|
|
<section
|
|
ref={containerRef}
|
|
id="hero"
|
|
className="relative min-h-screen flex items-center justify-center overflow-hidden"
|
|
>
|
|
{/* ThreeJS Background */}
|
|
{webgl ? (
|
|
<GadgetGrid />
|
|
) : (
|
|
<div
|
|
className="absolute inset-0"
|
|
style={{
|
|
background: `radial-gradient(ellipse at 50% 50%, #1a0500 0%, #0a0a0a 70%)`,
|
|
}}
|
|
/>
|
|
)}
|
|
|
|
{/* Scan line overlay for fallback and subtle depth */}
|
|
{!webgl && (
|
|
<div
|
|
className="absolute inset-0 opacity-5 pointer-events-none"
|
|
style={{
|
|
backgroundImage:
|
|
'repeating-linear-gradient(0deg, transparent, transparent 2px, rgba(0,255,68,0.03) 2px, rgba(0,255,68,0.03) 4px)',
|
|
}}
|
|
/>
|
|
)}
|
|
|
|
{/* Dark overlay for text readability */}
|
|
<div className="absolute inset-0 bg-bg-primary/50 pointer-events-none" />
|
|
|
|
{/* Content */}
|
|
<div
|
|
className={`relative z-10 text-center px-6 max-w-4xl mx-auto transition-all duration-1000 ${
|
|
visible ? 'opacity-100 translate-y-0' : 'opacity-0 translate-y-8'
|
|
}`}
|
|
>
|
|
{/* Status indicator */}
|
|
<div className="flex items-center justify-center gap-2 mb-6">
|
|
<div className="w-1.5 h-1.5 rounded-full bg-green-glow status-indicator" />
|
|
<span className="text-xs font-mono tracking-widest text-green-glow/80">
|
|
SYSTEMS ONLINE
|
|
</span>
|
|
</div>
|
|
|
|
{/* App icon */}
|
|
<img
|
|
src="/web-app.png"
|
|
alt="Gadget Code"
|
|
className="w-16 h-16 mx-auto mb-6 rounded-lg shadow-lg shadow-brand/20"
|
|
/>
|
|
|
|
{/* Tagline */}
|
|
<h1 className="text-5xl md:text-6xl font-mono font-bold tracking-tight text-text-primary mb-4">
|
|
<span className="text-brand">Self-Hosted</span> Agentic Engineering
|
|
</h1>
|
|
|
|
{/* Subtext */}
|
|
<p className="text-lg md:text-xl text-text-secondary max-w-2xl mx-auto mb-10 leading-relaxed">
|
|
The platform where AI agents and humans build software together —
|
|
on your infrastructure, under your control.
|
|
</p>
|
|
|
|
{/* CTAs */}
|
|
<div className="flex flex-col sm:flex-row items-center justify-center gap-4">
|
|
<a
|
|
href="#gadget-code"
|
|
className="px-8 py-3 text-sm font-mono tracking-wider border border-brand bg-brand hover:bg-brand-light text-white rounded transition-all shadow-lg shadow-brand/20"
|
|
>
|
|
GET GADGET CODE
|
|
</a>
|
|
<a
|
|
href="#gadget"
|
|
className="px-8 py-3 text-sm font-mono tracking-wider border border-border-default hover:border-border-highlight text-text-secondary hover:text-text-primary rounded transition-all"
|
|
>
|
|
GET GADGET
|
|
</a>
|
|
</div>
|
|
|
|
{/* Scroll indicator */}
|
|
<div className="absolute bottom-8 left-1/2 -translate-x-1/2 flex flex-col items-center gap-1 opacity-40">
|
|
<span className="text-xs font-mono tracking-widest text-text-muted">SCROLL</span>
|
|
<svg width="12" height="20" viewBox="0 0 12 20" fill="none">
|
|
<path d="M6 2v16M1 13l5 5 5-5" stroke="currentColor" strokeWidth="1.5" />
|
|
</svg>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
);
|
|
}
|