mirror of
https://github.com/NoFxAiOS/nofx.git
synced 2026-07-16 09:11:03 +08:00
feat: redesign landing page with new brand components
- Add brand components: BrandHero, BrandFeatures, BrandStats, Marquee - Add core components: TerminalHero, AgentGrid, LiveFeed - Add mascot images - Update LandingPage with new component structure - Update CSS and Tailwind config for new design - Add market data enhancements
This commit is contained in:
82
web/src/components/landing/brand/BrandFeatures.tsx
Normal file
82
web/src/components/landing/brand/BrandFeatures.tsx
Normal file
@@ -0,0 +1,82 @@
|
||||
import { motion } from 'framer-motion'
|
||||
import { Terminal, Cpu, Share2, Shield, Activity, Code } from 'lucide-react'
|
||||
|
||||
const features = [
|
||||
{
|
||||
icon: Terminal,
|
||||
title: "AI DRIVEN",
|
||||
description: "Powered by advanced LLMs (Claude, GPT-4, DeepSeek) to analyze market sentiment and technicals in real-time."
|
||||
},
|
||||
{
|
||||
icon: Cpu,
|
||||
title: "AUTONOMOUS",
|
||||
description: "Fully automated trading loops. From data ingestion to order execution without human intervention."
|
||||
},
|
||||
{
|
||||
icon: Share2,
|
||||
title: "PUNK SOCIAL",
|
||||
description: "Follow, copy, and debate with AI traders. A social layer built for the post-human economy."
|
||||
},
|
||||
{
|
||||
icon: Shield,
|
||||
title: "NON-CUSTODIAL",
|
||||
description: "Your funds, your keys. Connect via API keys or decentralized wallets. We never touch your assets."
|
||||
},
|
||||
{
|
||||
icon: Activity,
|
||||
title: "HIGH FREQUENCY",
|
||||
description: "Event-driven architecture capable of processing thousands of market signals per second."
|
||||
},
|
||||
{
|
||||
icon: Code,
|
||||
title: "OPEN SOURCE",
|
||||
description: "Auditable codebase. Community driven strategies. Build your own trader upon our core."
|
||||
}
|
||||
]
|
||||
|
||||
export default function BrandFeatures() {
|
||||
return (
|
||||
<section id="features" className="py-24 bg-zinc-950 relative">
|
||||
<div className="max-w-[1920px] mx-auto px-6 lg:px-16">
|
||||
|
||||
<div className="mb-16 border-l-4 border-nofx-gold pl-6">
|
||||
<h2 className="text-4xl md:text-5xl font-black text-white uppercase tracking-tighter mb-4">
|
||||
Core Protocol <span className="text-zinc-600">Specs</span>
|
||||
</h2>
|
||||
<p className="text-xl text-zinc-400 font-mono">
|
||||
Next generation infrastructure for algorithmic dominance.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-1">
|
||||
{features.map((f, i) => (
|
||||
<motion.div
|
||||
key={i}
|
||||
className="group relative bg-zinc-900 border border-zinc-800 p-8 hover:bg-zinc-800 transition-colors cursor-default overflow-hidden"
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ delay: i * 0.1 }}
|
||||
>
|
||||
<div className="absolute top-0 right-0 p-4 opacity-10 group-hover:opacity-20 transition-opacity">
|
||||
<f.icon size={100} />
|
||||
</div>
|
||||
|
||||
<f.icon className="w-10 h-10 text-nofx-gold mb-6" />
|
||||
|
||||
<h3 className="text-xl font-bold text-white mb-3 uppercase flex items-center gap-2">
|
||||
{f.title}
|
||||
</h3>
|
||||
|
||||
<p className="text-zinc-400 leading-relaxed text-sm md:text-base">
|
||||
{f.description}
|
||||
</p>
|
||||
|
||||
<div className="absolute bottom-0 left-0 w-full h-1 bg-nofx-gold transform scale-x-0 group-hover:scale-x-100 transition-transform origin-left duration-300" />
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
108
web/src/components/landing/brand/BrandHero.tsx
Normal file
108
web/src/components/landing/brand/BrandHero.tsx
Normal file
@@ -0,0 +1,108 @@
|
||||
import { motion } from 'framer-motion'
|
||||
import { ArrowRight, Github } from 'lucide-react'
|
||||
import { Marquee } from './Marquee'
|
||||
import { OFFICIAL_LINKS } from '../../../constants/branding'
|
||||
|
||||
export default function BrandHero() {
|
||||
const handleScroll = () => {
|
||||
const element = document.getElementById('features')
|
||||
if (element) {
|
||||
element.scrollIntoView({ behavior: 'smooth' })
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<section className="relative w-full min-h-screen bg-nofx-bg text-nofx-text overflow-hidden flex flex-col pt-16">
|
||||
|
||||
{/* Top Marquee */}
|
||||
<div className="w-full bg-nofx-gold text-black font-bold py-2 border-y border-black z-20">
|
||||
<Marquee speed={40}>
|
||||
<span className="mx-8 text-sm md:text-base uppercase tracking-widest">NOFX AI TRADING • AUTOMATED WEALTH • DECENTRALIZED INTELLIGENCE • PUNK ETHOS •</span>
|
||||
<span className="mx-8 text-sm md:text-base uppercase tracking-widest">NOFX AI TRADING • AUTOMATED WEALTH • DECENTRALIZED INTELLIGENCE • PUNK ETHOS •</span>
|
||||
</Marquee>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col lg:flex-row flex-1 relative z-10">
|
||||
|
||||
{/* Left Content */}
|
||||
<div className="flex-1 flex flex-col justify-center px-6 lg:px-16 pt-12 lg:pt-0 relative z-20">
|
||||
<motion.div
|
||||
initial={{ opacity: 0, x: -50 }}
|
||||
animate={{ opacity: 1, x: 0 }}
|
||||
transition={{ duration: 0.8, ease: "circOut" }}
|
||||
>
|
||||
<h1 className="text-6xl md:text-8xl lg:text-[7rem] font-black leading-[0.9] tracking-tighter mb-6">
|
||||
AI TRADING<br />
|
||||
<span className="text-nofx-gold">EVOLVED</span>
|
||||
</h1>
|
||||
|
||||
<p className="text-xl md:text-2xl text-zinc-400 max-w-xl mb-10 font-mono leading-relaxed">
|
||||
Autonomous trading agents. High-frequency execution.
|
||||
<br />
|
||||
Institutional-grade strategies for the
|
||||
<span className="text-white font-bold ml-2 bg-nofx-accent px-2 py-0.5">DEGENERATES</span>.
|
||||
</p>
|
||||
|
||||
<div className="flex flex-wrap gap-4">
|
||||
<button
|
||||
onClick={handleScroll}
|
||||
className="bg-nofx-gold text-black text-lg font-black px-8 py-4 uppercase tracking-wider hover:bg-white hover:scale-105 transition-all flex items-center gap-2 clip-path-slant"
|
||||
style={{ clipPath: 'polygon(0 0, 100% 0, 95% 100%, 0% 100%)' }}
|
||||
>
|
||||
Start Trading <ArrowRight className="w-6 h-6" />
|
||||
</button>
|
||||
|
||||
<a
|
||||
href={OFFICIAL_LINKS.github}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className="border-2 border-white/20 text-white text-lg font-bold px-8 py-4 uppercase tracking-wider hover:bg-white/10 hover:border-white transition-all flex items-center gap-2"
|
||||
>
|
||||
<Github className="w-5 h-5" /> Source
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="mt-12 flex items-center gap-8 text-zinc-500 font-mono text-xs md:text-sm">
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="w-2 h-2 bg-green-500 rounded-full animate-pulse" />
|
||||
SYSTEM ONLINE
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="w-2 h-2 bg-nofx-accent rounded-full" />
|
||||
VP v2.4.0
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
|
||||
{/* Right Visual - Mascot */}
|
||||
<div className="flex-1 relative flex items-end justify-center lg:justify-end overflow-hidden">
|
||||
{/* Abstract background elements */}
|
||||
<div className="absolute top-1/4 right-0 w-[600px] h-[600px] bg-nofx-accent/20 rounded-full blur-[100px] pointer-events-none" />
|
||||
<div className="absolute bottom-0 left-10 w-[400px] h-[400px] bg-nofx-gold/10 rounded-full blur-[80px] pointer-events-none" />
|
||||
|
||||
{/* Grid Pattern */}
|
||||
<div className="absolute inset-0 opacity-20"
|
||||
style={{
|
||||
backgroundImage: 'linear-gradient(#333 1px, transparent 1px), linear-gradient(90deg, #333 1px, transparent 1px)',
|
||||
backgroundSize: '40px 40px'
|
||||
}}
|
||||
/>
|
||||
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 100 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 1, delay: 0.2 }}
|
||||
className="relative z-10 w-full h-full flex items-end justify-center lg:justify-end lg:pr-10"
|
||||
>
|
||||
<img
|
||||
src="/images/nofx_mascot.png"
|
||||
alt="Cyberpunk Mascot"
|
||||
className="h-[80vh] object-contain drop-shadow-[0_0_50px_rgba(0,0,0,0.5)]"
|
||||
/>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
43
web/src/components/landing/brand/BrandStats.tsx
Normal file
43
web/src/components/landing/brand/BrandStats.tsx
Normal file
@@ -0,0 +1,43 @@
|
||||
import { motion } from 'framer-motion'
|
||||
|
||||
const stats = [
|
||||
{ label: "TRADING VOL", value: "$4.2B+" },
|
||||
{ label: "AI AGENTS", value: "850+" },
|
||||
{ label: "STRATEGIES", value: "Infinite" },
|
||||
{ label: "UPTIME", value: "99.9%" },
|
||||
]
|
||||
|
||||
export default function BrandStats() {
|
||||
return (
|
||||
<section className="bg-nofx-accent py-20 relative overflow-hidden">
|
||||
{/* Halftone Pattern */}
|
||||
<div
|
||||
className="absolute inset-0 opacity-10 pointer-events-none"
|
||||
style={{
|
||||
backgroundImage: 'radial-gradient(circle, #000 2px, transparent 2.5px)',
|
||||
backgroundSize: '20px 20px'
|
||||
}}
|
||||
/>
|
||||
|
||||
<div className="max-w-[1920px] mx-auto px-6 lg:px-16 relative z-10">
|
||||
<div className="grid grid-cols-2 md:grid-cols-4 gap-12 text-center md:text-left">
|
||||
{stats.map((stat, i) => (
|
||||
<motion.div
|
||||
key={i}
|
||||
initial={{ opacity: 0 }}
|
||||
whileInView={{ opacity: 1 }}
|
||||
transition={{ delay: i * 0.1 }}
|
||||
>
|
||||
<div className="text-5xl md:text-6xl font-black text-white tracking-tighter mb-2">
|
||||
{stat.value}
|
||||
</div>
|
||||
<div className="text-sm md:text-base font-bold text-black/60 uppercase tracking-widest bg-white/20 inline-block px-2 py-1">
|
||||
{stat.label}
|
||||
</div>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
35
web/src/components/landing/brand/Marquee.tsx
Normal file
35
web/src/components/landing/brand/Marquee.tsx
Normal file
@@ -0,0 +1,35 @@
|
||||
import { useRef } from 'react'
|
||||
|
||||
export function Marquee({
|
||||
children,
|
||||
direction = 'left',
|
||||
speed = 30,
|
||||
className = '',
|
||||
}: {
|
||||
children: React.ReactNode
|
||||
direction?: 'left' | 'right'
|
||||
speed?: number
|
||||
className?: string
|
||||
}) {
|
||||
const scrollerRef = useRef<HTMLDivElement>(null)
|
||||
|
||||
// Clone children to create seamless loop
|
||||
return (
|
||||
<div className={`overflow-hidden whitespace-nowrap ${className}`}>
|
||||
<div
|
||||
ref={scrollerRef}
|
||||
className="inline-flex w-max"
|
||||
style={{
|
||||
animation: `marquee ${speed}s linear infinite ${direction === 'right' ? 'reverse' : 'normal'}`
|
||||
}}
|
||||
>
|
||||
<div className="flex shrink-0 min-w-full justify-around items-center">
|
||||
{children}
|
||||
</div>
|
||||
<div className="flex shrink-0 min-w-full justify-around items-center" aria-hidden="true">
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user