mirror of
https://github.com/NoFxAiOS/nofx.git
synced 2026-07-16 17:12:25 +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:
@@ -1183,3 +1183,30 @@ func isStaleData(klines []Kline, symbol string) bool {
|
|||||||
logger.Infof("⚠️ %s detected extreme price stability (no fluctuation for %d consecutive periods), but volume is normal", symbol, stalePriceThreshold)
|
logger.Infof("⚠️ %s detected extreme price stability (no fluctuation for %d consecutive periods), but volume is normal", symbol, stalePriceThreshold)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ========== 导出的指标计算函数(供测试使用) ==========
|
||||||
|
|
||||||
|
// ExportCalculateEMA exports calculateEMA for testing
|
||||||
|
func ExportCalculateEMA(klines []Kline, period int) float64 {
|
||||||
|
return calculateEMA(klines, period)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExportCalculateMACD exports calculateMACD for testing
|
||||||
|
func ExportCalculateMACD(klines []Kline) float64 {
|
||||||
|
return calculateMACD(klines)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExportCalculateRSI exports calculateRSI for testing
|
||||||
|
func ExportCalculateRSI(klines []Kline, period int) float64 {
|
||||||
|
return calculateRSI(klines, period)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExportCalculateATR exports calculateATR for testing
|
||||||
|
func ExportCalculateATR(klines []Kline, period int) float64 {
|
||||||
|
return calculateATR(klines, period)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExportCalculateBOLL exports calculateBOLL for testing
|
||||||
|
func ExportCalculateBOLL(klines []Kline, period int, multiplier float64) (upper, middle, lower float64) {
|
||||||
|
return calculateBOLL(klines, period, multiplier)
|
||||||
|
}
|
||||||
|
|||||||
BIN
web/public/images/nofx_mascot.b.png
Normal file
BIN
web/public/images/nofx_mascot.b.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 565 KiB |
BIN
web/public/images/nofx_mascot.png
Normal file
BIN
web/public/images/nofx_mascot.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 310 KiB |
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>
|
||||||
|
)
|
||||||
|
}
|
||||||
89
web/src/components/landing/core/AgentGrid.tsx
Normal file
89
web/src/components/landing/core/AgentGrid.tsx
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
import { motion } from 'framer-motion'
|
||||||
|
import { Bot, TrendingUp, Layers } from 'lucide-react'
|
||||||
|
|
||||||
|
const agents = [
|
||||||
|
{ name: "Alpha-1", type: "Scalper", apy: "142%", winRate: "68%", exposure: "Low", avatar: "/images/nofx_mascot.png", color: "text-nofx-gold" },
|
||||||
|
{ name: "Beta-X", type: "Swing", apy: "89%", winRate: "55%", exposure: "Med", icon: TrendingUp, color: "text-blue-400" },
|
||||||
|
{ name: "Gamma-Ray", type: "Arbitrage", apy: "24%", winRate: "99%", exposure: "Zero", icon: Layers, color: "text-purple-400" },
|
||||||
|
]
|
||||||
|
|
||||||
|
export default function AgentGrid() {
|
||||||
|
return (
|
||||||
|
<section id="market-scanner" className="py-24 bg-nofx-bg relative">
|
||||||
|
<div className="max-w-7xl mx-auto px-6">
|
||||||
|
|
||||||
|
<div className="flex items-center gap-4 mb-12">
|
||||||
|
<div className="w-2 h-8 bg-nofx-gold" />
|
||||||
|
<h2 className="text-3xl font-black text-white uppercase tracking-tighter">
|
||||||
|
Deployable <span className="text-nofx-gold">Agents</span>
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
|
||||||
|
{agents.map((agent, i) => {
|
||||||
|
const Icon = agent.icon
|
||||||
|
return (
|
||||||
|
<motion.div
|
||||||
|
key={i}
|
||||||
|
initial={{ opacity: 0, scale: 0.95 }}
|
||||||
|
whileInView={{ opacity: 1, scale: 1 }}
|
||||||
|
transition={{ delay: i * 0.1 }}
|
||||||
|
className={`relative bg-zinc-900/50 border border-zinc-800 p-6 overflow-hidden hover:border-zinc-600 transition-colors group ${i === 0 ? 'border-nofx-gold/50 shadow-[0_0_30px_rgba(240,185,11,0.1)]' : ''}`}
|
||||||
|
>
|
||||||
|
{/* Header */}
|
||||||
|
<div className="flex justify-between items-start mb-6">
|
||||||
|
<div>
|
||||||
|
<div className="text-zinc-400 text-xs font-mono uppercase mb-1">{agent.type} CLASS</div>
|
||||||
|
<div className="text-2xl font-bold text-white flex items-center gap-2">
|
||||||
|
{agent.name}
|
||||||
|
{i === 0 && <span className="text-[10px] bg-nofx-gold text-black px-1.5 py-0.5 rounded font-bold">TOP RATED</span>}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<Bot className={`w-8 h-8 ${agent.color}`} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Stats Grid */}
|
||||||
|
<div className="grid grid-cols-3 gap-2 mb-6 font-mono text-sm">
|
||||||
|
<div className="bg-black/40 p-2 rounded border border-zinc-800 group-hover:border-zinc-700 transition-colors">
|
||||||
|
<div className="text-zinc-500 text-[10px] uppercase">APY</div>
|
||||||
|
<div className="text-green-400 font-bold">{agent.apy}</div>
|
||||||
|
</div>
|
||||||
|
<div className="bg-black/40 p-2 rounded border border-zinc-800 group-hover:border-zinc-700 transition-colors">
|
||||||
|
<div className="text-zinc-500 text-[10px] uppercase">Win Rate</div>
|
||||||
|
<div className={`font-bold ${agent.color}`}>{agent.winRate}</div>
|
||||||
|
</div>
|
||||||
|
<div className="bg-black/40 p-2 rounded border border-zinc-800 group-hover:border-zinc-700 transition-colors">
|
||||||
|
<div className="text-zinc-500 text-[10px] uppercase">Risk</div>
|
||||||
|
<div className="text-white font-bold">{agent.exposure}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Visual Asset (Avatar or Abstract Icon) */}
|
||||||
|
<div className="absolute right-[-20px] bottom-[-20px] opacity-10 group-hover:opacity-20 transition-all duration-500 group-hover:scale-110 pointer-events-none">
|
||||||
|
{agent.avatar ? (
|
||||||
|
<img
|
||||||
|
src={agent.avatar}
|
||||||
|
alt="Agent"
|
||||||
|
className="w-40 h-40 object-cover grayscale mix-blend-screen"
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
Icon && <Icon strokeWidth={1} className={`w-40 h-40 ${agent.color}`} />
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Action */}
|
||||||
|
<button className={`w-full py-3 font-bold uppercase tracking-wider text-sm transition-colors ${i === 0
|
||||||
|
? 'bg-nofx-gold text-black hover:bg-white'
|
||||||
|
: 'bg-zinc-800 text-zinc-400 hover:bg-zinc-700'
|
||||||
|
}`}>
|
||||||
|
Initialize Agent
|
||||||
|
</button>
|
||||||
|
|
||||||
|
</motion.div>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
)
|
||||||
|
}
|
||||||
66
web/src/components/landing/core/LiveFeed.tsx
Normal file
66
web/src/components/landing/core/LiveFeed.tsx
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
import { motion } from 'framer-motion'
|
||||||
|
import { Activity, BarChart3, Globe } from 'lucide-react'
|
||||||
|
|
||||||
|
// Mock Data for "Live" Feed
|
||||||
|
const logs = [
|
||||||
|
{ time: "14:02:23", type: "EXE", msg: "Bot-Alpha executed BUY BTC-USDT @ 64230.50", color: "text-green-500" },
|
||||||
|
{ time: "14:02:24", type: "SIG", msg: "High vol detected in ETH-PERP. Signal strength: 0.89", color: "text-nofx-gold" },
|
||||||
|
{ time: "14:02:25", type: "NET", msg: "Block propagation delay < 2ms", color: "text-zinc-500" },
|
||||||
|
{ time: "14:02:27", type: "EXE", msg: "Bot-Beta executed SELL SOL-USDT @ 145.20", color: "text-red-500" },
|
||||||
|
{ time: "14:02:28", type: "SYS", msg: "Memory pool optimization complete.", color: "text-nofx-accent" },
|
||||||
|
{ time: "14:02:30", type: "ARB", msg: "Arbitrage opportunity found: BINANCE vs BYBIT (0.4%)", color: "text-blue-400" },
|
||||||
|
]
|
||||||
|
|
||||||
|
export default function LiveFeed() {
|
||||||
|
return (
|
||||||
|
<section className="w-full bg-black border-y border-zinc-800 py-4 overflow-hidden">
|
||||||
|
<div className="max-w-[1920px] mx-auto px-6 flex flex-col md:flex-row gap-6">
|
||||||
|
|
||||||
|
{/* Left Status Panel */}
|
||||||
|
<div className="w-full md:w-1/3 flex items-center justify-between md:justify-start gap-8 text-xs font-mono text-zinc-500 border-b md:border-b-0 md:border-r border-zinc-900 pb-4 md:pb-0">
|
||||||
|
<div className="flex items-center gap-3">
|
||||||
|
<Activity className="w-4 h-4 text-nofx-gold" />
|
||||||
|
<div>
|
||||||
|
<div className="text-zinc-300 font-bold">SYSTEM LOAD</div>
|
||||||
|
<div className="text-nofx-gold">42%</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center gap-3">
|
||||||
|
<Globe className="w-4 h-4 text-nofx-accent" />
|
||||||
|
<div>
|
||||||
|
<div className="text-zinc-300 font-bold">ACTIVE NODES</div>
|
||||||
|
<div className="text-nofx-accent">8,249</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center gap-3">
|
||||||
|
<BarChart3 className="w-4 h-4 text-green-500" />
|
||||||
|
<div>
|
||||||
|
<div className="text-zinc-300 font-bold">24H VOL</div>
|
||||||
|
<div className="text-green-500">$4.2B</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Right Scrolling Log */}
|
||||||
|
<div className="flex-1 font-mono text-xs md:text-sm h-32 md:h-12 overflow-hidden relative mask-image-b">
|
||||||
|
<div className="absolute inset-0 flex flex-col gap-1 animate-slide-up">
|
||||||
|
{logs.map((log, i) => (
|
||||||
|
<motion.div
|
||||||
|
key={i}
|
||||||
|
initial={{ opacity: 0, x: -10 }}
|
||||||
|
animate={{ opacity: 1, x: 0 }}
|
||||||
|
transition={{ delay: i * 0.2 }}
|
||||||
|
className="flex gap-4"
|
||||||
|
>
|
||||||
|
<span className="text-zinc-600">[{log.time}]</span>
|
||||||
|
<span className="text-zinc-400 font-bold w-8">{log.type}</span>
|
||||||
|
<span className={log.color}>{log.msg}</span>
|
||||||
|
</motion.div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
)
|
||||||
|
}
|
||||||
224
web/src/components/landing/core/TerminalHero.tsx
Normal file
224
web/src/components/landing/core/TerminalHero.tsx
Normal file
@@ -0,0 +1,224 @@
|
|||||||
|
import { motion } from 'framer-motion'
|
||||||
|
import { ArrowRight, Terminal as TerminalIcon, Star, GitFork, Users, Activity, Layers, Cpu, Network } from 'lucide-react'
|
||||||
|
import { useState, useEffect } from 'react'
|
||||||
|
import { OFFICIAL_LINKS } from '../../../constants/branding'
|
||||||
|
|
||||||
|
export default function TerminalHero() {
|
||||||
|
const [text, setText] = useState('')
|
||||||
|
const [githubData, setGithubData] = useState({ stars: '9.4k', forks: '2.4k', subscribers: '74' })
|
||||||
|
const fullText = "INITIALIZING NOFX KERNEL... CRYPTO | STOCKS | FOREX | METALS... SYSTEM READY."
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
// Typing effect
|
||||||
|
let i = 0
|
||||||
|
const timer = setInterval(() => {
|
||||||
|
setText(fullText.slice(0, i))
|
||||||
|
i++
|
||||||
|
if (i > fullText.length) clearInterval(timer)
|
||||||
|
}, 30)
|
||||||
|
|
||||||
|
// Fetch GitHub Data
|
||||||
|
fetch('https://api.github.com/repos/NoFxAiOS/nofx')
|
||||||
|
.then(res => res.json())
|
||||||
|
.then(data => {
|
||||||
|
if (data.stargazers_count) {
|
||||||
|
setGithubData({
|
||||||
|
stars: (data.stargazers_count / 1000).toFixed(1) + 'k',
|
||||||
|
forks: (data.forks_count / 1000).toFixed(1) + 'k',
|
||||||
|
subscribers: data.subscribers_count?.toString() || '74'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(err => console.error("Failed to fetch GitHub stats", err))
|
||||||
|
|
||||||
|
return () => clearInterval(timer)
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<section className="relative w-full min-h-screen bg-nofx-bg text-nofx-text overflow-hidden flex flex-col items-center justify-center pt-20">
|
||||||
|
|
||||||
|
{/* 1. ARCHITECTURAL BACKGROUND / HOLOGRAPHIC CONSTRUCT */}
|
||||||
|
<div className="absolute inset-0 z-0 overflow-hidden pointer-events-none select-none">
|
||||||
|
|
||||||
|
{/* The Mascot "Ghost" in the Machine - PREMIUM & CLEAN */}
|
||||||
|
<div className="absolute right-0 bottom-0 w-[80vw] lg:w-[45vw] h-[85vh] opacity-90 mix-blend-normal flex items-end justify-end">
|
||||||
|
<div className="relative w-full h-full">
|
||||||
|
<img
|
||||||
|
src="/images/nofx_mascot.png"
|
||||||
|
alt=""
|
||||||
|
className="w-full h-full object-contain object-bottom drop-shadow-[0_0_50px_rgba(240,185,11,0.2)]"
|
||||||
|
style={{
|
||||||
|
maskImage: 'linear-gradient(to top, black 60%, transparent 100%)',
|
||||||
|
filter: 'grayscale(100%) contrast(110%) brightness(110%) sepia(20%) hue-rotate(320deg)'
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* Clean Horizontal Scanline Overlay */}
|
||||||
|
<div className="absolute inset-0 bg-[url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0IiBoZWlnaHQ9IjQiPgo8cmVjdCB3aWR0aD0iNCIgaGVpZ2h0PSIxIiBmaWxsPSJyZ2JhKDAsIDAsIDAsIDAuMykiIC8+Cjwvc3ZnPg==')] opacity-50 mix-blend-overlay pointer-events-none" />
|
||||||
|
|
||||||
|
{/* Subtle Glow Behind */}
|
||||||
|
<div className="absolute right-10 bottom-10 w-64 h-64 bg-nofx-gold/20 rounded-full blur-[100px] -z-10" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Clean Geometric Grid */}
|
||||||
|
<svg className="absolute inset-0 w-full h-full opacity-10" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<defs>
|
||||||
|
<pattern id="grid" width="40" height="40" patternUnits="userSpaceOnUse">
|
||||||
|
<path d="M 40 0 L 0 0 0 40" fill="none" stroke="currentColor" strokeWidth="0.5" className="text-zinc-500" />
|
||||||
|
</pattern>
|
||||||
|
</defs>
|
||||||
|
<rect width="100%" height="100%" fill="url(#grid)" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="relative z-10 flex flex-col items-center text-center max-w-[1400px] px-6 w-full h-full justify-center">
|
||||||
|
|
||||||
|
<div className="grid grid-cols-1 lg:grid-cols-12 gap-8 w-full items-center">
|
||||||
|
|
||||||
|
{/* LEFT COLUMN: Main System Interface */}
|
||||||
|
<div className="col-span-1 lg:col-span-8 text-left z-30 flex flex-col justify-center h-full">
|
||||||
|
|
||||||
|
{/* System Status Tag */}
|
||||||
|
<motion.div
|
||||||
|
initial={{ opacity: 0, y: -10 }}
|
||||||
|
animate={{ opacity: 1, y: 0 }}
|
||||||
|
className="flex flex-wrap items-center gap-3 mb-8"
|
||||||
|
>
|
||||||
|
<div className="px-3 py-1 border border-nofx-gold/30 bg-nofx-gold/5 rounded-sm text-nofx-gold text-xs font-mono flex items-center gap-2 shadow-[0_0_15px_rgba(240,185,11,0.2)]">
|
||||||
|
<div className="w-1.5 h-1.5 bg-nofx-gold rounded-full animate-pulse" />
|
||||||
|
SYSTEM ONLINE
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
|
||||||
|
{/* Main Headline with Project Specifics */}
|
||||||
|
<motion.div
|
||||||
|
initial={{ opacity: 0, x: -20 }}
|
||||||
|
animate={{ opacity: 1, x: 0 }}
|
||||||
|
transition={{ delay: 0.2 }}
|
||||||
|
className="relative"
|
||||||
|
>
|
||||||
|
<h1 className="text-6xl md:text-8xl xl:text-9xl font-black tracking-tighter leading-[0.85] mb-8 text-white">
|
||||||
|
AGENTIC <br />
|
||||||
|
<span className="text-transparent bg-clip-text bg-gradient-to-r from-nofx-gold via-white to-nofx-gold animate-shimmer bg-[length:200%_100%]">TRADING OS</span>
|
||||||
|
</h1>
|
||||||
|
|
||||||
|
{/* SVG Connector Line */}
|
||||||
|
<div className="absolute -left-10 top-2 bottom-2 w-px bg-zinc-800 hidden lg:block">
|
||||||
|
<div className="absolute top-0 left-[-1px] w-[3px] h-8 bg-nofx-gold" />
|
||||||
|
<div className="absolute bottom-0 left-[-1px] w-[3px] h-8 bg-zinc-600" />
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
|
||||||
|
{/* Typing Terminal Output */}
|
||||||
|
<div className="h-24 mb-10 font-mono text-zinc-400 text-sm flex flex-col justify-start gap-3 max-w-2xl border-l-2 border-zinc-800 pl-6">
|
||||||
|
<div className="flex items-center gap-2 text-nofx-gold">
|
||||||
|
<span>></span> {text}<span className="animate-pulse bg-nofx-gold w-2 h-4 block"></span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Clean Markets Row */}
|
||||||
|
<div className="flex gap-6 text-[10px] md:text-xs text-zinc-500 font-bold tracking-widest uppercase">
|
||||||
|
<span className="flex items-center gap-2 hover:text-white transition-colors"><Network className="w-3 h-3" /> CRYPTO</span>
|
||||||
|
<span className="flex items-center gap-2 hover:text-white transition-colors"><Activity className="w-3 h-3" /> STOCKS</span>
|
||||||
|
<span className="flex items-center gap-2 hover:text-white transition-colors"><Layers className="w-3 h-3" /> FOREX</span>
|
||||||
|
<span className="flex items-center gap-2 hover:text-white transition-colors"><Cpu className="w-3 h-3" /> METALS</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Primary Actions */}
|
||||||
|
<div className="flex flex-col sm:flex-row gap-4 w-full max-w-lg">
|
||||||
|
<button
|
||||||
|
onClick={() => document.getElementById('market-scanner')?.scrollIntoView({ behavior: 'smooth' })}
|
||||||
|
className="group relative px-8 py-4 bg-nofx-gold text-black font-bold font-mono hover:bg-white transition-all flex items-center justify-between min-w-[200px] hover:shadow-[0_0_20px_rgba(240,185,11,0.4)]"
|
||||||
|
style={{ clipPath: 'polygon(0 0, 100% 0, 100% 80%, 90% 100%, 0% 100%)' }}
|
||||||
|
>
|
||||||
|
<span>DEPLOY TRADERS</span>
|
||||||
|
<ArrowRight className="w-5 h-5 group-hover:translate-x-1 transition-transform" />
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<a
|
||||||
|
href={OFFICIAL_LINKS.github}
|
||||||
|
target="_blank"
|
||||||
|
rel="noreferrer"
|
||||||
|
className="px-8 py-4 border border-zinc-700 bg-black/50 backdrop-blur-sm text-zinc-300 font-mono hover:border-nofx-accent hover:text-nofx-accent transition-all flex items-center justify-between min-w-[200px]"
|
||||||
|
style={{ clipPath: 'polygon(0 0, 100% 0, 100% 100%, 10% 100%, 0% 80%)' }}
|
||||||
|
>
|
||||||
|
<span>SOURCE CODE</span>
|
||||||
|
<TerminalIcon className="w-4 h-4" />
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* RIGHT COLUMN: Modules & Data HUD */}
|
||||||
|
<div className="col-span-1 lg:col-span-4 flex flex-col gap-6 mt-12 lg:mt-0 z-20">
|
||||||
|
|
||||||
|
{/* Module 1: GitHub Intelligence */}
|
||||||
|
<div className="border border-zinc-800 bg-black/80 backdrop-blur-md p-6 relative group overflow-hidden">
|
||||||
|
<div className="absolute top-0 right-0 w-20 h-20 bg-nofx-gold/5 rounded-bl-full -mr-10 -mt-10 transition-transform group-hover:scale-150" />
|
||||||
|
|
||||||
|
<div className="flex justify-between items-start mb-4">
|
||||||
|
<div className="text-xs font-mono text-zinc-500 flex items-center gap-2">
|
||||||
|
<Users className="w-4 h-4 text-nofx-gold" /> COMMUNITY UPLINK
|
||||||
|
</div>
|
||||||
|
<div className="flex gap-1">
|
||||||
|
<div className="w-1.5 h-1.5 bg-green-500 rounded-full animate-pulse" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="grid grid-cols-2 gap-4">
|
||||||
|
<div>
|
||||||
|
<div className="text-2xl font-bold text-white flex items-center gap-1">
|
||||||
|
{githubData.stars} <Star className="w-3 h-3 text-nofx-gold fill-nofx-gold" />
|
||||||
|
</div>
|
||||||
|
<div className="text-[10px] text-zinc-500 uppercase tracking-wider">Active Star-gazers</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div className="text-2xl font-bold text-white flex items-center gap-1">
|
||||||
|
{githubData.forks} <GitFork className="w-3 h-3 text-zinc-500" />
|
||||||
|
</div>
|
||||||
|
<div className="text-[10px] text-zinc-500 uppercase tracking-wider">Protocol Forks</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Module 2: System Capabilities (Specific to NoFX) */}
|
||||||
|
<div className="border border-zinc-800 bg-black/60 backdrop-blur-sm p-6 space-y-3 hidden md:block">
|
||||||
|
<div className="text-xs font-mono text-zinc-500 mb-2">ACTIVE MODULES</div>
|
||||||
|
|
||||||
|
<div className="flex justify-between items-center text-sm font-mono border-b border-zinc-900 pb-2">
|
||||||
|
<span className="text-zinc-300">STRATEGY STUDIO</span>
|
||||||
|
<span className="text-green-500 text-xs">READY</span>
|
||||||
|
</div>
|
||||||
|
<div className="flex justify-between items-center text-sm font-mono border-b border-zinc-900 pb-2">
|
||||||
|
<span className="text-zinc-300">DEBATE ARENA</span>
|
||||||
|
<span className="text-green-500 text-xs text-nofx-accent animate-pulse">Running</span>
|
||||||
|
</div>
|
||||||
|
<div className="flex justify-between items-center text-sm font-mono pb-2">
|
||||||
|
<span className="text-zinc-300">BACKTEST LAB</span>
|
||||||
|
<span className="text-zinc-500 text-xs">Idle</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Decorative Footer */}
|
||||||
|
<div className="absolute bottom-0 w-full border-t border-zinc-800 bg-black/90 backdrop-blur-md p-3 flex flex-wrap justify-between items-center text-[10px] md:text-xs text-zinc-500 font-mono z-20">
|
||||||
|
<div className="flex gap-6 px-4">
|
||||||
|
<span className="flex items-center gap-2">
|
||||||
|
<div className="w-2 h-2 bg-nofx-gold/50 rounded-full" />
|
||||||
|
NOFX-OS
|
||||||
|
</span>
|
||||||
|
<span className="hidden sm:inline">24H VOL: $42.8M</span>
|
||||||
|
<span className="hidden sm:inline">ACTIVE AGENTS: 1,024</span>
|
||||||
|
</div>
|
||||||
|
<div className="px-4 flex gap-4">
|
||||||
|
<span className="text-nofx-gold">ENCRYPTED CONNECTION</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -11,29 +11,23 @@ html {
|
|||||||
}
|
}
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
/* Binance Brand Colors */
|
/* NoFX Neo-Gold Design System */
|
||||||
--brand-yellow: #FCD535;
|
--nofx-gold: #F0B90B;
|
||||||
--brand-black: #0B0E11;
|
--nofx-bg: #0B0E11;
|
||||||
--brand-dark-gray: #1E2329;
|
--nofx-accent: #00F0FF;
|
||||||
--brand-light-gray: #EAECEF;
|
--nofx-glass: rgba(30, 35, 41, 0.6);
|
||||||
--brand-white: #FFFFFF;
|
--nofx-border: rgba(240, 185, 11, 0.2);
|
||||||
|
|
||||||
/* Premium Theme Colors */
|
|
||||||
--binance-yellow: #FCD535;
|
|
||||||
--binance-yellow-dark: #F0B90B;
|
|
||||||
--binance-yellow-light: #FDE059;
|
|
||||||
--binance-yellow-glow: rgba(252, 213, 53, 0.15);
|
|
||||||
|
|
||||||
--background: #0B0E11;
|
--background: #0B0E11;
|
||||||
--header-bg: rgba(11, 14, 17, 0.85);
|
--header-bg: rgba(11, 14, 17, 0.9);
|
||||||
/* Glass header */
|
/* Glass header */
|
||||||
--glass-bg: rgba(30, 35, 41, 0.4);
|
--glass-bg: rgba(11, 14, 17, 0.6);
|
||||||
--glass-border: rgba(255, 255, 255, 0.08);
|
--glass-border: rgba(240, 185, 11, 0.1);
|
||||||
|
|
||||||
--panel-bg: #1E2329;
|
--panel-bg: #15181D;
|
||||||
--panel-bg-hover: #2B3139;
|
--panel-bg-hover: #1E2329;
|
||||||
--panel-border: #2B3139;
|
--panel-border: rgba(255, 255, 255, 0.08);
|
||||||
--panel-border-hover: #474D57;
|
--panel-border-hover: rgba(240, 185, 11, 0.4);
|
||||||
|
|
||||||
--foreground: #EAECEF;
|
--foreground: #EAECEF;
|
||||||
--text-primary: #EAECEF;
|
--text-primary: #EAECEF;
|
||||||
@@ -53,7 +47,7 @@ html {
|
|||||||
--shadow-sm: 0 2px 4px rgba(0, 0, 0, 0.2);
|
--shadow-sm: 0 2px 4px rgba(0, 0, 0, 0.2);
|
||||||
--shadow-md: 0 4px 12px rgba(0, 0, 0, 0.3);
|
--shadow-md: 0 4px 12px rgba(0, 0, 0, 0.3);
|
||||||
--shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.4);
|
--shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.4);
|
||||||
--shadow-glow: 0 0 20px rgba(252, 213, 53, 0.1);
|
--shadow-glow: 0 0 20px rgba(240, 185, 11, 0.2);
|
||||||
|
|
||||||
font-family:
|
font-family:
|
||||||
'Inter',
|
'Inter',
|
||||||
@@ -79,15 +73,13 @@ body {
|
|||||||
min-width: 320px;
|
min-width: 320px;
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
background-color: var(--background);
|
background-color: var(--background);
|
||||||
background-image:
|
background-image: none;
|
||||||
radial-gradient(circle at 15% 50%, rgba(252, 213, 53, 0.08), transparent 25%),
|
|
||||||
radial-gradient(circle at 85% 30%, rgba(14, 203, 129, 0.05), transparent 25%);
|
|
||||||
background-attachment: fixed;
|
background-attachment: fixed;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Premium Selection Styles */
|
/* Premium Selection Styles */
|
||||||
::selection {
|
::selection {
|
||||||
background: rgba(252, 213, 53, 0.3);
|
background: rgba(255, 88, 0, 0.3);
|
||||||
color: #FFFFFF;
|
color: #FFFFFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,7 +105,7 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
::-webkit-scrollbar-thumb:hover {
|
::-webkit-scrollbar-thumb:hover {
|
||||||
background: var(--panel-border-hover);
|
background: var(--nofx-gold);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Animations */
|
/* Animations */
|
||||||
@@ -189,6 +181,21 @@ body {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Marquee Animation */
|
||||||
|
@keyframes marquee {
|
||||||
|
0% {
|
||||||
|
transform: translateX(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
transform: translateX(-50%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-marquee {
|
||||||
|
animation: marquee 30s linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
.animate-fade-in {
|
.animate-fade-in {
|
||||||
animation: fadeIn 0.3s ease-out;
|
animation: fadeIn 0.3s ease-out;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,12 @@
|
|||||||
import { useState } from 'react'
|
import { useState } from 'react'
|
||||||
import { motion } from 'framer-motion'
|
|
||||||
import { ArrowRight, Github } from 'lucide-react'
|
|
||||||
import HeaderBar from '../components/HeaderBar'
|
import HeaderBar from '../components/HeaderBar'
|
||||||
import HeroSection from '../components/landing/HeroSection'
|
|
||||||
import AboutSection from '../components/landing/AboutSection'
|
|
||||||
import FeaturesSection from '../components/landing/FeaturesSection'
|
|
||||||
import HowItWorksSection from '../components/landing/HowItWorksSection'
|
|
||||||
import CommunitySection from '../components/landing/CommunitySection'
|
|
||||||
import LoginModal from '../components/landing/LoginModal'
|
import LoginModal from '../components/landing/LoginModal'
|
||||||
import FooterSection from '../components/landing/FooterSection'
|
import FooterSection from '../components/landing/FooterSection'
|
||||||
|
import TerminalHero from '../components/landing/core/TerminalHero'
|
||||||
|
import LiveFeed from '../components/landing/core/LiveFeed'
|
||||||
|
import AgentGrid from '../components/landing/core/AgentGrid'
|
||||||
import { useAuth } from '../contexts/AuthContext'
|
import { useAuth } from '../contexts/AuthContext'
|
||||||
import { useLanguage } from '../contexts/LanguageContext'
|
import { useLanguage } from '../contexts/LanguageContext'
|
||||||
import { t } from '../i18n/translations'
|
|
||||||
import { OFFICIAL_LINKS } from '../constants/branding'
|
|
||||||
|
|
||||||
export function LandingPage() {
|
export function LandingPage() {
|
||||||
const [showLoginModal, setShowLoginModal] = useState(false)
|
const [showLoginModal, setShowLoginModal] = useState(false)
|
||||||
@@ -40,96 +34,15 @@ export function LandingPage() {
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<div
|
<div className="min-h-screen bg-nofx-bg text-nofx-text font-sans selection:bg-nofx-gold selection:text-black">
|
||||||
className="min-h-screen"
|
|
||||||
style={{
|
|
||||||
background: '#0B0E11',
|
|
||||||
color: '#EAECEF',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<HeroSection language={language} />
|
|
||||||
<AboutSection language={language} />
|
|
||||||
<FeaturesSection language={language} />
|
|
||||||
<HowItWorksSection language={language} />
|
|
||||||
<CommunitySection language={language} />
|
|
||||||
|
|
||||||
{/* Final CTA Section */}
|
<TerminalHero />
|
||||||
<section className="py-24 relative overflow-hidden" style={{ background: '#0D1117' }}>
|
|
||||||
{/* Background Glow */}
|
|
||||||
<div
|
|
||||||
className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[600px] h-[600px] rounded-full blur-3xl opacity-30"
|
|
||||||
style={{ background: 'radial-gradient(circle, rgba(240, 185, 11, 0.15) 0%, transparent 70%)' }}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div className="max-w-4xl mx-auto px-4 text-center relative z-10">
|
<LiveFeed />
|
||||||
<motion.h2
|
|
||||||
className="text-4xl lg:text-5xl font-bold mb-6"
|
|
||||||
style={{ color: '#EAECEF' }}
|
|
||||||
initial={{ opacity: 0, y: 30 }}
|
|
||||||
whileInView={{ opacity: 1, y: 0 }}
|
|
||||||
viewport={{ once: true }}
|
|
||||||
>
|
|
||||||
{t('readyToDefine', language)}
|
|
||||||
</motion.h2>
|
|
||||||
<motion.p
|
|
||||||
className="text-lg mb-10 max-w-2xl mx-auto"
|
|
||||||
style={{ color: '#848E9C' }}
|
|
||||||
initial={{ opacity: 0, y: 30 }}
|
|
||||||
whileInView={{ opacity: 1, y: 0 }}
|
|
||||||
viewport={{ once: true }}
|
|
||||||
transition={{ delay: 0.1 }}
|
|
||||||
>
|
|
||||||
{t('startWithCrypto', language)}
|
|
||||||
</motion.p>
|
|
||||||
|
|
||||||
<motion.div
|
<AgentGrid />
|
||||||
className="flex flex-col sm:flex-row items-center justify-center gap-4"
|
|
||||||
initial={{ opacity: 0, y: 30 }}
|
|
||||||
whileInView={{ opacity: 1, y: 0 }}
|
|
||||||
viewport={{ once: true }}
|
|
||||||
transition={{ delay: 0.2 }}
|
|
||||||
>
|
|
||||||
<motion.button
|
|
||||||
onClick={() => setShowLoginModal(true)}
|
|
||||||
className="group flex items-center gap-3 px-8 py-4 rounded-xl font-bold text-lg"
|
|
||||||
style={{
|
|
||||||
background: 'linear-gradient(135deg, #F0B90B 0%, #FCD535 100%)',
|
|
||||||
color: '#0B0E11',
|
|
||||||
boxShadow: '0 4px 24px rgba(240, 185, 11, 0.3)',
|
|
||||||
}}
|
|
||||||
whileHover={{
|
|
||||||
scale: 1.02,
|
|
||||||
boxShadow: '0 8px 32px rgba(240, 185, 11, 0.4)',
|
|
||||||
}}
|
|
||||||
whileTap={{ scale: 0.98 }}
|
|
||||||
>
|
|
||||||
{t('getStartedNow', language)}
|
|
||||||
<ArrowRight className="w-5 h-5 transition-transform group-hover:translate-x-1" />
|
|
||||||
</motion.button>
|
|
||||||
|
|
||||||
<motion.a
|
<FooterSection language={language} />
|
||||||
href={OFFICIAL_LINKS.github}
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
className="group flex items-center gap-3 px-8 py-4 rounded-xl font-bold text-lg"
|
|
||||||
style={{
|
|
||||||
background: 'rgba(255, 255, 255, 0.05)',
|
|
||||||
color: '#EAECEF',
|
|
||||||
border: '1px solid rgba(255, 255, 255, 0.1)',
|
|
||||||
}}
|
|
||||||
whileHover={{
|
|
||||||
scale: 1.02,
|
|
||||||
background: 'rgba(255, 255, 255, 0.08)',
|
|
||||||
borderColor: 'rgba(240, 185, 11, 0.3)',
|
|
||||||
}}
|
|
||||||
whileTap={{ scale: 0.98 }}
|
|
||||||
>
|
|
||||||
<Github className="w-5 h-5" />
|
|
||||||
{t('viewSourceCode', language)}
|
|
||||||
</motion.a>
|
|
||||||
</motion.div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
{showLoginModal && (
|
{showLoginModal && (
|
||||||
<LoginModal
|
<LoginModal
|
||||||
@@ -137,7 +50,6 @@ export function LandingPage() {
|
|||||||
language={language}
|
language={language}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<FooterSection language={language} />
|
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -5,7 +5,15 @@ export default {
|
|||||||
"./src/**/*.{js,ts,jsx,tsx}",
|
"./src/**/*.{js,ts,jsx,tsx}",
|
||||||
],
|
],
|
||||||
theme: {
|
theme: {
|
||||||
extend: {},
|
extend: {
|
||||||
|
colors: {
|
||||||
|
'nofx-gold': '#F0B90B',
|
||||||
|
'nofx-gold-dim': 'rgba(240, 185, 11, 0.15)',
|
||||||
|
'nofx-bg': '#0B0E11',
|
||||||
|
'nofx-accent': '#00F0FF',
|
||||||
|
'nofx-text': '#EAECEF',
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
plugins: [],
|
plugins: [],
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user