Initial commit
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
"use client";
|
||||
|
||||
export default function AnimatedBackground() {
|
||||
return (
|
||||
<>
|
||||
{/* Animated Background */}
|
||||
<div className="fixed inset-0 -z-10 overflow-hidden pointer-events-none">
|
||||
{/* Grid pattern */}
|
||||
<div
|
||||
className="absolute inset-0 opacity-[0.08]"
|
||||
style={{
|
||||
backgroundImage: `linear-gradient(to right, #f97815 1px, transparent 1px), linear-gradient(to bottom, #f97815 1px, transparent 1px)`,
|
||||
backgroundSize: '50px 50px'
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* Animated gradient orbs */}
|
||||
<div className="absolute -top-20 left-1/4 w-[600px] h-[600px] bg-[#f97815]/20 rounded-full blur-[120px] animate-blob" />
|
||||
<div className="absolute top-1/3 -right-20 w-[500px] h-[500px] bg-purple-500/15 rounded-full blur-[120px] animate-blob-delayed-1" />
|
||||
<div className="absolute -bottom-20 left-1/2 w-[550px] h-[550px] bg-blue-500/12 rounded-full blur-[120px] animate-blob-delayed-2" />
|
||||
|
||||
{/* Vignette effect */}
|
||||
<div
|
||||
className="absolute inset-0"
|
||||
style={{
|
||||
background: 'radial-gradient(circle at center, transparent 0%, rgba(24, 20, 17, 0.4) 100%)'
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* CSS Animations */}
|
||||
<style jsx global>{`
|
||||
@keyframes blob {
|
||||
0%, 100% {
|
||||
transform: translate(0, 0) scale(1);
|
||||
}
|
||||
33% {
|
||||
transform: translate(30px, -50px) scale(1.1);
|
||||
}
|
||||
66% {
|
||||
transform: translate(-20px, 20px) scale(0.9);
|
||||
}
|
||||
}
|
||||
.animate-blob {
|
||||
animation: blob 20s ease-in-out infinite;
|
||||
}
|
||||
.animate-blob-delayed-1 {
|
||||
animation: blob 22s ease-in-out 2s infinite;
|
||||
}
|
||||
.animate-blob-delayed-2 {
|
||||
animation: blob 25s ease-in-out 4s infinite;
|
||||
}
|
||||
`}</style>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,133 @@
|
||||
"use client";
|
||||
|
||||
const FEATURES = [
|
||||
{
|
||||
icon: "link",
|
||||
title: "Unified Endpoint",
|
||||
desc: "Access all providers via a single standard API URL.",
|
||||
colors: {
|
||||
border: "hover:border-blue-500/50",
|
||||
bg: "hover:bg-blue-500/5",
|
||||
iconBg: "bg-blue-500/10",
|
||||
iconText: "text-blue-500",
|
||||
titleHover: "group-hover:text-blue-400"
|
||||
}
|
||||
},
|
||||
{
|
||||
icon: "bolt",
|
||||
title: "Easy Setup",
|
||||
desc: "Get up and running in minutes with npx command.",
|
||||
colors: {
|
||||
border: "hover:border-orange-500/50",
|
||||
bg: "hover:bg-orange-500/5",
|
||||
iconBg: "bg-orange-500/10",
|
||||
iconText: "text-orange-500",
|
||||
titleHover: "group-hover:text-orange-400"
|
||||
}
|
||||
},
|
||||
{
|
||||
icon: "shield_with_heart",
|
||||
title: "Model Fallback",
|
||||
desc: "Automatically switch providers on failure or high latency.",
|
||||
colors: {
|
||||
border: "hover:border-rose-500/50",
|
||||
bg: "hover:bg-rose-500/5",
|
||||
iconBg: "bg-rose-500/10",
|
||||
iconText: "text-rose-500",
|
||||
titleHover: "group-hover:text-rose-400"
|
||||
}
|
||||
},
|
||||
{
|
||||
icon: "monitoring",
|
||||
title: "Usage Tracking",
|
||||
desc: "Detailed analytics and cost monitoring across all models.",
|
||||
colors: {
|
||||
border: "hover:border-purple-500/50",
|
||||
bg: "hover:bg-purple-500/5",
|
||||
iconBg: "bg-purple-500/10",
|
||||
iconText: "text-purple-500",
|
||||
titleHover: "group-hover:text-purple-400"
|
||||
}
|
||||
},
|
||||
{
|
||||
icon: "key",
|
||||
title: "OAuth & API Keys",
|
||||
desc: "Securely manage credentials in one vault.",
|
||||
colors: {
|
||||
border: "hover:border-amber-500/50",
|
||||
bg: "hover:bg-amber-500/5",
|
||||
iconBg: "bg-amber-500/10",
|
||||
iconText: "text-amber-500",
|
||||
titleHover: "group-hover:text-amber-400"
|
||||
}
|
||||
},
|
||||
{
|
||||
icon: "cloud_sync",
|
||||
title: "Cloud Sync",
|
||||
desc: "Sync your configurations across devices instantly.",
|
||||
colors: {
|
||||
border: "hover:border-sky-500/50",
|
||||
bg: "hover:bg-sky-500/5",
|
||||
iconBg: "bg-sky-500/10",
|
||||
iconText: "text-sky-500",
|
||||
titleHover: "group-hover:text-sky-400"
|
||||
}
|
||||
},
|
||||
{
|
||||
icon: "terminal",
|
||||
title: "CLI Support",
|
||||
desc: "Works with Claude Code, Codex, Cline, Cursor, and more.",
|
||||
colors: {
|
||||
border: "hover:border-emerald-500/50",
|
||||
bg: "hover:bg-emerald-500/5",
|
||||
iconBg: "bg-emerald-500/10",
|
||||
iconText: "text-emerald-500",
|
||||
titleHover: "group-hover:text-emerald-400"
|
||||
}
|
||||
},
|
||||
{
|
||||
icon: "dashboard",
|
||||
title: "Dashboard",
|
||||
desc: "Visual dashboard for real-time traffic analysis.",
|
||||
colors: {
|
||||
border: "hover:border-fuchsia-500/50",
|
||||
bg: "hover:bg-fuchsia-500/5",
|
||||
iconBg: "bg-fuchsia-500/10",
|
||||
iconText: "text-fuchsia-500",
|
||||
titleHover: "group-hover:text-fuchsia-400"
|
||||
}
|
||||
},
|
||||
];
|
||||
|
||||
export default function Features() {
|
||||
return (
|
||||
<section className="py-24 px-6" id="features">
|
||||
<div className="max-w-7xl mx-auto">
|
||||
<div className="mb-16">
|
||||
<h2 className="text-3xl md:text-4xl font-bold mb-4">Powerful Features</h2>
|
||||
<p className="text-gray-400 max-w-xl text-lg">
|
||||
Everything you need to manage your AI infrastructure in one place, built for scale.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
|
||||
{FEATURES.map((feature) => (
|
||||
<div
|
||||
key={feature.title}
|
||||
className={`p-6 rounded-xl bg-[#23180f] border border-[#3a2f27] ${feature.colors.border} ${feature.colors.bg} transition-all duration-300 group`}
|
||||
>
|
||||
<div className={`w-10 h-10 rounded-lg ${feature.colors.iconBg} flex items-center justify-center mb-4 ${feature.colors.iconText} group-hover:scale-110 transition-transform duration-300`}>
|
||||
<span className="material-symbols-outlined">{feature.icon}</span>
|
||||
</div>
|
||||
<h3 className={`text-lg font-bold mb-2 ${feature.colors.titleHover} transition-colors`}>
|
||||
{feature.title}
|
||||
</h3>
|
||||
<p className="text-sm text-gray-400 leading-relaxed">{feature.desc}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
"use client";
|
||||
import { useEffect, useState } from "react";
|
||||
import Image from "next/image";
|
||||
|
||||
const CLI_TOOLS = [
|
||||
{ id: "claude", name: "Claude Code", image: "/providers/claude.png" },
|
||||
{ id: "codex", name: "OpenAI Codex", image: "/providers/codex.png" },
|
||||
{ id: "cline", name: "Cline", image: "/providers/cline.png" },
|
||||
{ id: "cursor", name: "Cursor", image: "/providers/cursor.png" },
|
||||
];
|
||||
|
||||
const PROVIDERS = [
|
||||
{ id: "openai", name: "OpenAI", color: "bg-emerald-500", textColor: "text-white" },
|
||||
{ id: "anthropic", name: "Anthropic", color: "bg-orange-400", textColor: "text-white" },
|
||||
{ id: "gemini", name: "Gemini", color: "bg-blue-500", textColor: "text-white" },
|
||||
{ id: "github", name: "GitHub Copilot", color: "bg-gray-700", textColor: "text-white" },
|
||||
];
|
||||
|
||||
export default function FlowAnimation() {
|
||||
const [activeFlow, setActiveFlow] = useState(0);
|
||||
|
||||
useEffect(() => {
|
||||
const interval = setInterval(() => {
|
||||
setActiveFlow((prev) => (prev + 1) % PROVIDERS.length);
|
||||
}, 2000);
|
||||
return () => clearInterval(interval);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="mt-16 w-full max-w-4xl relative h-[360px] hidden md:flex items-center justify-center animate-[float_6s_ease-in-out_infinite]">
|
||||
{/* 9Router Hub - Center */}
|
||||
<div className="relative z-20 w-32 h-32 rounded-full bg-[#23180f] border-2 border-[#f97815] shadow-[0_0_40px_rgba(249,120,21,0.3)] flex flex-col items-center justify-center gap-1 group cursor-pointer hover:scale-105 transition-transform duration-500">
|
||||
<span className="material-symbols-outlined text-4xl text-[#f97815]">hub</span>
|
||||
<span className="text-xs font-bold text-white tracking-widest uppercase">9Router</span>
|
||||
<div className="absolute inset-0 rounded-full border border-[#f97815]/30 animate-ping opacity-20"></div>
|
||||
</div>
|
||||
|
||||
{/* CLI Tools - Left side */}
|
||||
<div className="absolute left-0 top-1/2 -translate-y-1/2 flex flex-col gap-7">
|
||||
{CLI_TOOLS.map((tool) => (
|
||||
<div
|
||||
key={tool.id}
|
||||
className="flex items-center gap-3 opacity-70 hover:opacity-100 transition-opacity group"
|
||||
>
|
||||
<div className="w-16 h-16 rounded-2xl bg-[#23180f] border border-[#3a2f27] flex items-center justify-center overflow-hidden p-2 hover:border-[#f97815]/50 transition-all hover:scale-105">
|
||||
<Image
|
||||
src={tool.image}
|
||||
alt={tool.name}
|
||||
width={48}
|
||||
height={48}
|
||||
className="object-contain rounded-xl"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* SVG Lines from CLI to 9Router */}
|
||||
<svg className="absolute inset-0 w-full h-full z-10 pointer-events-none stroke-yellow-700" xmlns="http://www.w3.org/2000/svg">
|
||||
<path className="animate-[dash_2s_linear_infinite]" d="M 60 50 C 250 70, 250 180, 360 180" fill="none" strokeDasharray="5,5" strokeWidth="2"></path>
|
||||
<path className="animate-[dash_2s_linear_infinite]" d="M 60 140 C 250 140, 250 180, 360 180" fill="none" strokeDasharray="5,5" strokeWidth="2"></path>
|
||||
<path className="animate-[dash_2s_linear_infinite]" d="M 60 210 C 250 210, 250 180, 360 180" fill="none" strokeDasharray="5,5" strokeWidth="2"></path>
|
||||
<path className="animate-[dash_2s_linear_infinite]" d="M 60 300 C 250 280, 250 180, 360 180" fill="none" strokeDasharray="5,5" strokeWidth="2"></path>
|
||||
</svg>
|
||||
|
||||
{/* SVG Lines from 9Router to Providers */}
|
||||
<svg className="absolute inset-0 w-full h-full z-10 pointer-events-none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M 440 180 C 550 180, 550 50, 740 50"
|
||||
fill="none"
|
||||
stroke={activeFlow === 0 ? "#f97815" : "rgb(75, 85, 99)"}
|
||||
strokeWidth={activeFlow === 0 ? "3" : "2"}
|
||||
className={activeFlow === 0 ? "animate-pulse" : ""}
|
||||
></path>
|
||||
<path
|
||||
d="M 440 180 C 550 180, 550 130, 740 130"
|
||||
fill="none"
|
||||
stroke={activeFlow === 1 ? "#f97815" : "rgb(75, 85, 99)"}
|
||||
strokeWidth={activeFlow === 1 ? "3" : "2"}
|
||||
className={activeFlow === 1 ? "animate-pulse" : ""}
|
||||
></path>
|
||||
<path
|
||||
d="M 440 180 C 550 180, 550 230, 740 230"
|
||||
fill="none"
|
||||
stroke={activeFlow === 2 ? "#f97815" : "rgb(75, 85, 99)"}
|
||||
strokeWidth={activeFlow === 2 ? "3" : "2"}
|
||||
className={activeFlow === 2 ? "animate-pulse" : ""}
|
||||
></path>
|
||||
<path
|
||||
d="M 440 180 C 550 180, 550 310, 740 310"
|
||||
fill="none"
|
||||
stroke={activeFlow === 3 ? "#f97815" : "rgb(75, 85, 99)"}
|
||||
strokeWidth={activeFlow === 3 ? "3" : "2"}
|
||||
className={activeFlow === 3 ? "animate-pulse" : ""}
|
||||
></path>
|
||||
</svg>
|
||||
|
||||
{/* AI Providers - Right side */}
|
||||
<div className="absolute right-0 top-0 bottom-0 flex flex-col justify-between py-6">
|
||||
{PROVIDERS.map((provider, idx) => (
|
||||
<div
|
||||
key={provider.id}
|
||||
className={`px-4 py-2 rounded-lg ${provider.color} ${provider.textColor} flex items-center justify-center font-bold text-xs shadow-lg hover:scale-110 transition-all cursor-help min-w-[140px] ${
|
||||
activeFlow === idx ? "ring-4 ring-[#f97815]/50 scale-110" : ""
|
||||
}`}
|
||||
title={provider.name}
|
||||
>
|
||||
{provider.name}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Mobile fallback */}
|
||||
<div className="md:hidden mt-8 w-full p-4 rounded-lg bg-[#23180f] border border-[#3a2f27]">
|
||||
<p className="text-sm text-center text-gray-400">Interactive diagram visible on desktop</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
"use client";
|
||||
|
||||
export default function Footer() {
|
||||
return (
|
||||
<footer className="border-t border-[#3a2f27] bg-[#120f0d] pt-16 pb-8 px-6">
|
||||
<div className="max-w-7xl mx-auto">
|
||||
<div className="grid grid-cols-2 md:grid-cols-4 lg:grid-cols-5 gap-8 mb-16">
|
||||
{/* Brand */}
|
||||
<div className="col-span-2 lg:col-span-2">
|
||||
<div className="flex items-center gap-3 mb-6">
|
||||
<div className="size-6 rounded bg-[#f97815] flex items-center justify-center text-white">
|
||||
<span className="material-symbols-outlined text-[16px]">hub</span>
|
||||
</div>
|
||||
<h3 className="text-white text-lg font-bold">9Router</h3>
|
||||
</div>
|
||||
<p className="text-gray-500 text-sm max-w-xs mb-6">
|
||||
The unified endpoint for AI generation. Connect, route, and manage your AI providers with ease.
|
||||
</p>
|
||||
<div className="flex gap-4">
|
||||
<a className="text-gray-400 hover:text-white transition-colors" href="https://github.com/decolua/9router" target="_blank" rel="noopener noreferrer">
|
||||
<span className="material-symbols-outlined">code</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Product */}
|
||||
<div className="flex flex-col gap-4">
|
||||
<h4 className="font-bold text-white">Product</h4>
|
||||
<a className="text-gray-400 hover:text-[#f97815] text-sm transition-colors" href="#features">Features</a>
|
||||
<a className="text-gray-400 hover:text-[#f97815] text-sm transition-colors" href="/dashboard">Dashboard</a>
|
||||
<a className="text-gray-400 hover:text-[#f97815] text-sm transition-colors" href="https://github.com/decolua/9router" target="_blank" rel="noopener noreferrer">Changelog</a>
|
||||
</div>
|
||||
|
||||
{/* Resources */}
|
||||
<div className="flex flex-col gap-4">
|
||||
<h4 className="font-bold text-white">Resources</h4>
|
||||
<a className="text-gray-400 hover:text-[#f97815] text-sm transition-colors" href="https://github.com/decolua/9router#readme" target="_blank" rel="noopener noreferrer">Documentation</a>
|
||||
<a className="text-gray-400 hover:text-[#f97815] text-sm transition-colors" href="https://github.com/decolua/9router" target="_blank" rel="noopener noreferrer">GitHub</a>
|
||||
<a className="text-gray-400 hover:text-[#f97815] text-sm transition-colors" href="https://www.npmjs.com/package/9router" target="_blank" rel="noopener noreferrer">NPM</a>
|
||||
</div>
|
||||
|
||||
{/* Legal */}
|
||||
<div className="flex flex-col gap-4">
|
||||
<h4 className="font-bold text-white">Legal</h4>
|
||||
<a className="text-gray-400 hover:text-[#f97815] text-sm transition-colors" href="https://github.com/decolua/9router/blob/main/LICENSE" target="_blank" rel="noopener noreferrer">MIT License</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Bottom */}
|
||||
<div className="border-t border-[#3a2f27] pt-8 flex flex-col md:flex-row justify-between items-center gap-4">
|
||||
<p className="text-gray-600 text-sm">© 2025 9Router. All rights reserved.</p>
|
||||
<div className="flex gap-6">
|
||||
<a className="text-gray-600 hover:text-white text-sm transition-colors" href="https://github.com/decolua/9router" target="_blank" rel="noopener noreferrer">GitHub</a>
|
||||
<a className="text-gray-600 hover:text-white text-sm transition-colors" href="https://www.npmjs.com/package/9router" target="_blank" rel="noopener noreferrer">NPM</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
"use client";
|
||||
import { useState } from "react";
|
||||
|
||||
export default function GetStarted() {
|
||||
const [copied, setCopied] = useState(false);
|
||||
|
||||
const handleCopy = (text) => {
|
||||
navigator.clipboard.writeText(text);
|
||||
setCopied(true);
|
||||
setTimeout(() => setCopied(false), 2000);
|
||||
};
|
||||
|
||||
return (
|
||||
<section className="py-24 px-6 bg-[#120f0d]">
|
||||
<div className="max-w-7xl mx-auto">
|
||||
<div className="flex flex-col lg:flex-row gap-16 items-start">
|
||||
{/* Left: Steps */}
|
||||
<div className="flex-1">
|
||||
<h2 className="text-3xl md:text-4xl font-bold mb-6">Get Started in 30 Seconds</h2>
|
||||
<p className="text-gray-400 text-lg mb-8">
|
||||
Install 9Router, configure your providers via web dashboard, and start routing AI requests.
|
||||
</p>
|
||||
|
||||
<div className="flex flex-col gap-6">
|
||||
<div className="flex gap-4">
|
||||
<div className="flex-none w-8 h-8 rounded-full bg-[#f97815]/20 text-[#f97815] flex items-center justify-center font-bold">1</div>
|
||||
<div>
|
||||
<h4 className="font-bold text-lg">Install 9Router</h4>
|
||||
<p className="text-sm text-gray-500 mt-1">Run npx command to start the server instantly</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex gap-4">
|
||||
<div className="flex-none w-8 h-8 rounded-full bg-[#f97815]/20 text-[#f97815] flex items-center justify-center font-bold">2</div>
|
||||
<div>
|
||||
<h4 className="font-bold text-lg">Open Dashboard</h4>
|
||||
<p className="text-sm text-gray-500 mt-1">Configure providers and API keys via web interface</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex gap-4">
|
||||
<div className="flex-none w-8 h-8 rounded-full bg-[#f97815]/20 text-[#f97815] flex items-center justify-center font-bold">3</div>
|
||||
<div>
|
||||
<h4 className="font-bold text-lg">Route Requests</h4>
|
||||
<p className="text-sm text-gray-500 mt-1">Point your CLI tools to http://localhost:20128</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Right: Code block */}
|
||||
<div className="flex-1 w-full">
|
||||
<div className="rounded-xl overflow-hidden bg-[#1e1e1e] border border-[#3a2f27] shadow-2xl">
|
||||
{/* Terminal header */}
|
||||
<div className="flex items-center gap-2 px-4 py-3 bg-[#252526] border-b border-gray-700">
|
||||
<div className="w-3 h-3 rounded-full bg-red-500"></div>
|
||||
<div className="w-3 h-3 rounded-full bg-yellow-500"></div>
|
||||
<div className="w-3 h-3 rounded-full bg-green-500"></div>
|
||||
<div className="ml-2 text-xs text-gray-500 font-mono">terminal</div>
|
||||
</div>
|
||||
|
||||
{/* Terminal content */}
|
||||
<div className="p-6 font-mono text-sm leading-relaxed overflow-x-auto">
|
||||
<div
|
||||
className="flex items-center gap-2 mb-4 group cursor-pointer"
|
||||
onClick={() => handleCopy("npx 9router")}
|
||||
>
|
||||
<span className="text-green-400">$</span>
|
||||
<span className="text-white">npx 9router</span>
|
||||
<span className="ml-auto text-gray-500 text-xs opacity-0 group-hover:opacity-100">
|
||||
{copied ? "✓ Copied" : "Copy"}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="text-gray-400 mb-6">
|
||||
<span className="text-[#f97815]">></span> Starting 9Router...<br/>
|
||||
<span className="text-[#f97815]">></span> Server running on <span className="text-blue-400">http://localhost:20128</span><br/>
|
||||
<span className="text-[#f97815]">></span> Dashboard: <span className="text-blue-400">http://localhost:20128/dashboard</span><br/>
|
||||
<span className="text-green-400">></span> Ready to route! ✓
|
||||
</div>
|
||||
|
||||
<div className="text-xs text-gray-500 mb-2 border-t border-gray-700 pt-4">
|
||||
📝 Configure providers in dashboard or use environment variables
|
||||
</div>
|
||||
|
||||
<div className="text-gray-400 text-xs">
|
||||
<span className="text-purple-400">Data Location:</span><br/>
|
||||
<span className="text-gray-500"> macOS/Linux:</span> ~/.9router/db.json<br/>
|
||||
<span className="text-gray-500"> Windows:</span> %APPDATA%/9router/db.json
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
"use client";
|
||||
|
||||
export default function HeroSection() {
|
||||
return (
|
||||
<section className="relative pt-32 pb-20 px-6 min-h-[90vh] flex flex-col items-center justify-center overflow-hidden">
|
||||
{/* Glow effect */}
|
||||
<div className="absolute top-0 left-1/2 -translate-x-1/2 w-[1000px] h-[500px] bg-[#f97815]/10 rounded-full blur-[120px] pointer-events-none"></div>
|
||||
|
||||
<div className="relative z-10 max-w-4xl w-full text-center flex flex-col items-center gap-8">
|
||||
{/* Version badge */}
|
||||
<div className="inline-flex items-center gap-2 rounded-full border border-[#3a2f27] bg-[#23180f]/50 px-3 py-1 text-xs font-medium text-[#f97815]">
|
||||
<span className="flex h-2 w-2 rounded-full bg-[#f97815] animate-pulse"></span>
|
||||
v1.0 is now live
|
||||
</div>
|
||||
|
||||
{/* Main heading */}
|
||||
<h1 className="text-5xl md:text-7xl font-black leading-[1.1] tracking-tight">
|
||||
One Endpoint for <br/>
|
||||
<span className="text-[#f97815]">All AI Providers</span>
|
||||
</h1>
|
||||
|
||||
{/* Description */}
|
||||
<p className="text-lg md:text-xl text-gray-400 max-w-2xl mx-auto font-light">
|
||||
AI endpoint proxy with web dashboard - A JavaScript port of CLIProxyAPI. Works seamlessly with Claude Code, OpenAI Codex, Cline, RooCode, and other CLI tools.
|
||||
</p>
|
||||
|
||||
{/* CTA Buttons */}
|
||||
<div className="flex flex-wrap items-center justify-center gap-4 w-full">
|
||||
<button className="h-12 px-8 rounded-lg bg-[#f97815] hover:bg-[#e0650a] text-[#181411] text-base font-bold transition-all shadow-[0_0_15px_rgba(249,120,21,0.4)] flex items-center gap-2">
|
||||
<span className="material-symbols-outlined">rocket_launch</span>
|
||||
Get Started
|
||||
</button>
|
||||
<a
|
||||
href="https://github.com/decolua/9router"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="h-12 px-8 rounded-lg border border-[#3a2f27] bg-[#23180f] hover:bg-[#3a2f27] text-white text-base font-bold transition-all flex items-center gap-2"
|
||||
>
|
||||
<span className="material-symbols-outlined">code</span>
|
||||
View on GitHub
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
"use client";
|
||||
|
||||
export default function HowItWorks() {
|
||||
return (
|
||||
<section className="py-24 border-y border-[#3a2f27] bg-[#23180f]/30" id="how-it-works">
|
||||
<div className="max-w-7xl mx-auto px-6">
|
||||
<div className="mb-16">
|
||||
<h2 className="text-3xl md:text-4xl font-bold mb-4">How 9Router Works</h2>
|
||||
<p className="text-gray-400 max-w-xl text-lg">
|
||||
Data flows seamlessly from your application through our intelligent routing layer to the best provider for the job.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-8 relative">
|
||||
{/* Connection line */}
|
||||
<div className="hidden md:block absolute top-12 left-[16%] right-[16%] h-[2px] bg-gradient-to-r from-gray-700 via-[#f97815] to-gray-700 -z-10"></div>
|
||||
|
||||
{/* Step 1: CLI & SDKs */}
|
||||
<div className="flex flex-col gap-6 relative group">
|
||||
<div className="w-24 h-24 rounded-2xl bg-[#181411] border border-[#3a2f27] flex items-center justify-center shadow-xl group-hover:border-gray-500 transition-colors z-10 mx-auto md:mx-0">
|
||||
<span className="material-symbols-outlined text-4xl text-gray-300">terminal</span>
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-xl font-bold mb-2">1. CLI & SDKs</h3>
|
||||
<p className="text-sm text-gray-400">
|
||||
Your requests start from your favorite tools or our unified SDK. Just change the base URL.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Step 2: 9Router Hub */}
|
||||
<div className="flex flex-col gap-6 relative group md:items-center md:text-center">
|
||||
<div className="w-24 h-24 rounded-2xl bg-[#181411] border-2 border-[#f97815] flex items-center justify-center shadow-[0_0_30px_rgba(249,120,21,0.2)] z-10 mx-auto">
|
||||
<span className="material-symbols-outlined text-4xl text-[#f97815] animate-pulse">hub</span>
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-xl font-bold mb-2 text-[#f97815]">2. 9Router Hub</h3>
|
||||
<p className="text-sm text-gray-400">
|
||||
Our engine analyzes the prompt, checks provider health, and routes for lowest latency or cost.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Step 3: AI Providers */}
|
||||
<div className="flex flex-col gap-6 relative group md:items-end md:text-right">
|
||||
<div className="w-24 h-24 rounded-2xl bg-[#181411] border border-[#3a2f27] flex items-center justify-center shadow-xl group-hover:border-gray-500 transition-colors z-10 mx-auto md:mx-0">
|
||||
<div className="grid grid-cols-2 gap-2">
|
||||
<div className="w-6 h-6 rounded bg-white/10"></div>
|
||||
<div className="w-6 h-6 rounded bg-white/10"></div>
|
||||
<div className="w-6 h-6 rounded bg-white/10"></div>
|
||||
<div className="w-6 h-6 rounded bg-white/10"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-xl font-bold mb-2">3. AI Providers</h3>
|
||||
<p className="text-sm text-gray-400">
|
||||
The request is fulfilled by OpenAI, Anthropic, Gemini, or others instantly.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
"use client";
|
||||
import { useState } from "react";
|
||||
import { useRouter } from "next/navigation";
|
||||
|
||||
export default function Navigation() {
|
||||
const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
|
||||
const router = useRouter();
|
||||
|
||||
return (
|
||||
<nav className="fixed top-0 z-50 w-full bg-[#181411]/80 backdrop-blur-md border-b border-[#3a2f27]">
|
||||
<div className="max-w-7xl mx-auto px-6 h-16 flex items-center justify-between">
|
||||
{/* Logo */}
|
||||
<div className="flex items-center gap-3 cursor-pointer" onClick={() => router.push("/")}>
|
||||
<div className="size-8 rounded bg-gradient-to-br from-[#f97815] to-orange-700 flex items-center justify-center text-white">
|
||||
<span className="material-symbols-outlined text-[20px]">hub</span>
|
||||
</div>
|
||||
<h2 className="text-white text-xl font-bold tracking-tight">9Router</h2>
|
||||
</div>
|
||||
|
||||
{/* Desktop menu */}
|
||||
<div className="hidden md:flex items-center gap-8">
|
||||
<a className="text-gray-300 hover:text-white text-sm font-medium transition-colors" href="#features">Features</a>
|
||||
<a className="text-gray-300 hover:text-white text-sm font-medium transition-colors" href="#how-it-works">How it Works</a>
|
||||
<a className="text-gray-300 hover:text-white text-sm font-medium transition-colors" href="https://github.com/decolua/9router#readme" target="_blank" rel="noopener noreferrer">Docs</a>
|
||||
<a className="text-gray-300 hover:text-white text-sm font-medium transition-colors flex items-center gap-1" href="https://github.com/decolua/9router" target="_blank" rel="noopener noreferrer">
|
||||
GitHub <span className="material-symbols-outlined text-[14px]">open_in_new</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{/* CTA + Mobile menu */}
|
||||
<div className="flex items-center gap-4">
|
||||
<button
|
||||
onClick={() => router.push("/dashboard")}
|
||||
className="hidden sm:flex h-9 items-center justify-center rounded-lg px-4 bg-[#f97815] hover:bg-[#e0650a] transition-all text-[#181411] text-sm font-bold shadow-[0_0_15px_rgba(249,120,21,0.4)] hover:shadow-[0_0_20px_rgba(249,120,21,0.6)]"
|
||||
>
|
||||
Get Started
|
||||
</button>
|
||||
<button
|
||||
className="md:hidden text-white"
|
||||
onClick={() => setMobileMenuOpen(!mobileMenuOpen)}
|
||||
>
|
||||
<span className="material-symbols-outlined">{mobileMenuOpen ? "close" : "menu"}</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Mobile menu dropdown */}
|
||||
{mobileMenuOpen && (
|
||||
<div className="md:hidden border-t border-[#3a2f27] bg-[#181411]/95 backdrop-blur-md">
|
||||
<div className="flex flex-col gap-4 p-6">
|
||||
<a className="text-gray-300 hover:text-white text-sm font-medium transition-colors" href="#features" onClick={() => setMobileMenuOpen(false)}>Features</a>
|
||||
<a className="text-gray-300 hover:text-white text-sm font-medium transition-colors" href="#how-it-works" onClick={() => setMobileMenuOpen(false)}>How it Works</a>
|
||||
<a className="text-gray-300 hover:text-white text-sm font-medium transition-colors" href="https://github.com/decolua/9router#readme" target="_blank" rel="noopener noreferrer">Docs</a>
|
||||
<a className="text-gray-300 hover:text-white text-sm font-medium transition-colors" href="https://github.com/decolua/9router" target="_blank" rel="noopener noreferrer">GitHub</a>
|
||||
<button
|
||||
onClick={() => router.push("/dashboard")}
|
||||
className="h-9 rounded-lg bg-[#f97815] hover:bg-[#e0650a] text-[#181411] text-sm font-bold"
|
||||
>
|
||||
Get Started
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</nav>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user