Commit: fd8fe83b
Scope: products/sandbox/web/src/layouts/DashboardLayout.tsx
codex — ❌ FAILED
OpenAI Codex v0.116.0 (research preview)
workdir: /home/drew/tools/pr-reviewer/.webhook-state/checkouts/tangle-network-agent-dev-container-pr-457 model: gpt-5.4 provider: openai approval: never sandbox: workspace-write [workdir, /tmp, $TMPDIR, /home/drew/.codex/memories] reasoning effort: high reasoning summaries: none session id: 019d210d-dc6b-7301-b4db-a8a48aeda5e5
user You are a senior engineer reviewing one assigned track of a code change. You are thorough but you respect the reader's time — every finding you report should be worth someone stopping to look at.
You own only your assigned track. Stay in scope. Do not report on files or concerns outside your track's scope unless you find something genuinely dangerous.
Read the evidence in your track scope. Think about what could go wrong in production, what would break silently, what a test wouldn't catch. Look at error paths, edge cases, and implicit assumptions.
Use sub-agents when it helps — for example, to check test coverage while you're reviewing implementation logic. But don't use them just because you can.
A good finding names a specific file and line, explains what's wrong, and shows evidence. "This nil check on line 47 of auth.go doesn't cover the case where the token is expired but structurally valid — the downstream handler will panic" is a finding. "Consider adding error handling" is not.
Ask yourself: would a staff engineer read this finding and say "good catch" or "obvious filler"? Only report the former.
- Findings about style, naming, or formatting unless they create actual confusion
- "Consider adding tests for X" without explaining what specific behavior is untested and why it matters
- Speculative findings without code evidence — if you can't point to the line, don't report it
- Duplicating findings that clearly belong to another track
Be honest about what you're sure about versus what you suspect. Flag uncertainty in confidence_notes rather than inflating finding confidence.
Return JSON only, no markdown fences.
{
"status": "ok|error",
"track_id": "from the assigned track",
"summary": "what you found, in one paragraph",
"findings": [
{
"severity": "high|medium|low",
"confidence": "high|medium|low",
"category": "correctness|security|regression|testing|operational",
"title": "short, specific title",
"body": "what's wrong, why it matters, what evidence you found",
"file": "path/to/file",
"line": 0,
"evidence": "the actual code or behavior that demonstrates the issue"
}
],
"questions": ["things you want to ask the author — genuine questions, not passive-aggressive suggestions"],
"confidence_notes": ["where you're uncertain and why"]
}
Based on 175 reviews with 1002 findings:
- sidecar: 89 findings historically
- container: 79 findings historically
- no test: 35 findings historically
- auth: 33 findings historically
- config: 33 findings historically
- timeout: 28 findings historically
- token: 25 findings historically
- leak: 23 findings historically
- lock: 20 findings historically
- test coverage: 17 findings historically
- [high] security: Docker runtime missing reserved env var blocking (SIDECAR_AUTH_DISABLED bypass)
- [high] correctness: removeContainerFromDriver swallows errors, leaks running containers
- [high] regression: AgentExecutionInput.message changed from required to optional -- breaks adapters
- [high] regression: TraceEventInput removes tool_call, tool_result, llm_request, llm_response event types
- [high] security: Docker runtime accepts arbitrary host bind mounts from request body
Prioritize findings in these known-weak areas. Do not waste review cycles on patterns outside these categories unless you find a genuine critical/high issue.
{ "changed_files": [ "products/sandbox/web/src/layouts/DashboardLayout.tsx", "products/sandbox/web/src/pages/Landing.tsx", "products/sandbox/web/src/pages/Login.tsx", "products/sandbox/web/src/pages/Pricing.tsx" ], "pr": 457, "repo": "tangle-network/agent-dev-container", "track": { "evidence_targets": [ "products/sandbox/web/src/layouts/DashboardLayout.tsx" ], "goal": "Audit changed files for correctness, security, tests, and maintainability.", "scope": [ "products/sandbox/web/src/layouts/DashboardLayout.tsx" ], "should_use_subagents": false, "suggested_provider": "", "track_id": "track-01" } }
diff --git a/products/sandbox/web/src/layouts/DashboardLayout.tsx b/products/sandbox/web/src/layouts/DashboardLayout.tsx index 58f627e..e4bbf12 100644 --- a/products/sandbox/web/src/layouts/DashboardLayout.tsx +++ b/products/sandbox/web/src/layouts/DashboardLayout.tsx @@ -68,9 +68,7 @@ export function DashboardLayout() {
{/* Logo */}-
<div className="flex h-10 w-10 items-center justify-center rounded-lg bg-gradient-to-br from-[#ada3ff] to-[#705bf5]"> -
<MaterialIcon name="cloud" fill className="text-lg text-white" /> -
</div>
-
<img src="/tangle-logo-light.svg" alt="Tangle" className="h-8 w-8" /> <div> <h1 className="font-bold font-headline text-lg text-white leading-tight"> Tangle Sandbox
diff --git a/products/sandbox/web/src/pages/Landing.tsx b/products/sandbox/web/src/pages/Landing.tsx index 524a1f5..7c11998 100644 --- a/products/sandbox/web/src/pages/Landing.tsx +++ b/products/sandbox/web/src/pages/Landing.tsx @@ -1,26 +1,6 @@ -import {
- Badge,
- Button,
- Card,
- Logo, -} from "@tangle-network/sandbox-ui/primitives"; -import {
- ArrowRight,
- Bot,
- Code2,
- Copy,
- Github,
- Layers,
- Lock,
- Menu,
- Play,
- Server,
- Terminal as TerminalIcon,
- X,
- Zap, -} from "lucide-react"; import { useState } from "react"; import { Link } from "react-router-dom"; +import { MaterialIcon } from "../components/MaterialIcon"; import { useAuth } from "../hooks/useAuth";
// Syntax highlighting helpers @@ -31,7 +11,7 @@ const S = ({ children }: { children: React.ReactNode }) => ( {children} ); const C = ({ children }: { children: React.ReactNode }) => (
- {children}
- {children} ); const F = ({ children }: { children: React.ReactNode }) => ( {children} @@ -40,7 +20,7 @@ const N = ({ children }: { children: React.ReactNode }) => ( {children} ); const V = ({ children }: { children: React.ReactNode }) => (
- {children}
- {children} ); const SH = ({ children }: { children: React.ReactNode }) => ( {children} @@ -178,52 +158,47 @@ const TAB_COMPONENTS: Record<TabKey, () => React.ReactNode> = {
function CodeTabs() { const [active, setActive] = useState("create");
- const tabs: { key: TabKey; label: string; icon: React.ReactNode }[] = [
- { key: "create", label: "Create", icon: },
- {
-
key: "agent", -
label: "AI Agent", -
icon: <Bot className="h-3.5 w-3.5" />, - },
- {
-
key: "stream", -
label: "Stream", -
icon: <Zap className="h-3.5 w-3.5" />, - },
- {
-
key: "cli", -
label: "CLI", -
icon: <TerminalIcon className="h-3.5 w-3.5" />, - },
- const tabs: { key: TabKey; label: string; icon: string }[] = [
- { key: "create", label: "Create", icon: "play_arrow" },
- { key: "agent", label: "AI Agent", icon: "smart_toy" },
- { key: "stream", label: "Stream", icon: "bolt" },
- { key: "cli", label: "CLI", icon: "terminal" }, ];
const ActiveCode = TAB_COMPONENTS[active];
return (
-
-
<div className="flex items-center gap-1 border-border/50 border-b bg-card/30 px-3 py-2"> -
<div className="mr-3 flex gap-1.5"> -
<div className="h-3 w-3 rounded-full bg-red-500/80" /> -
<div className="h-3 w-3 rounded-full bg-yellow-500/80" /> -
<div className="h-3 w-3 rounded-full bg-purple-500/80" />
-
-
<div className="flex items-center justify-between border-white/5 border-b bg-[#1d2020] px-4 py-3"> -
<div className="flex items-center gap-2"> -
<div className="flex gap-1.5"> -
<div className="h-3 w-3 rounded-full bg-red-500/50" /> -
<div className="h-3 w-3 rounded-full bg-yellow-500/50" /> -
<div className="h-3 w-3 rounded-full bg-green-500/50" /> -
</div> -
<div className="ml-4 flex items-center gap-1"> -
{tabs.map((tab) => ( -
<button -
key={tab.key} -
type="button" -
onClick={() => setActive(tab.key)} -
className={`flex items-center gap-1.5 rounded-lg px-3 py-1.5 font-label text-xs transition-all ${ -
active === tab.key -
? "bg-[#ada3ff]/10 text-[#ada3ff]" -
: "text-[#747676] hover:text-[#aaabab]" -
}`} -
> -
<MaterialIcon name={tab.icon} size="sm" /> -
{tab.label} -
</button> -
))} -
</div> </div>
-
{tabs.map((tab) => ( -
<button -
key={tab.key} -
type="button" -
onClick={() => setActive(tab.key)} -
className={`flex items-center gap-1.5 rounded-md px-3 py-1.5 font-mono text-xs transition-colors ${ -
active === tab.key -
? "bg-purple-500/15 text-purple-400" -
: "text-muted-foreground hover:text-foreground" -
}`} -
> -
{tab.icon} -
{tab.label} -
</button> -
))}
-
<span className="font-label text-[#747676] text-[10px]"> -
TypeScript -
</span> </div>
-
<pre className="overflow-x-auto p-5 font-mono text-[13px] text-foreground/80 leading-relaxed">
-
<pre className="overflow-x-auto bg-[#0d0e0f]/60 p-8 font-label text-sm leading-relaxed"> <code> <ActiveCode /> </code>
@@ -232,507 +207,574 @@ function CodeTabs() { ); }
+const FAQ_ITEMS = [
- {
- question: "How is Tangle Sandbox different from standard Docker?",
- answer:
-
"While Docker provides containerization, Tangle Sandbox provides an agent-specific orchestration layer with sub-second cold starts, automated life-cycle management, and secure network isolation specifically designed for large-scale AI agent deployments.", - },
- {
- question: "Can agents access the internet?",
- answer:
-
"Yes. Sandboxes have outbound internet access by default. You can configure network egress rules to restrict access to specific domains or disable it entirely for maximum isolation.", - },
- {
- question: "What is the pricing model?",
- answer:
-
"Pay-per-second billing based on compute time. No monthly minimums, no idle charges. Sandboxes auto-hibernate when not in use. See our pricing page for full details.", - },
- {
- question: "Is there a free tier for developers?",
- answer:
-
"Yes. Every account includes a generous free tier with enough compute hours to build and test your agent workflows. No credit card required to get started.", - }, +];
+function FaqItem({ question, answer }: { question: string; answer: string }) {
- const [open, setOpen] = useState(false);
- return (
-
-
<button -
type="button" -
className="group flex w-full items-center justify-between text-left" -
onClick={() => setOpen(!open)} -
> -
<span className="font-bold text-lg text-white">{question}</span> -
<MaterialIcon -
name={open ? "expand_less" : "expand_more"} -
className={ -
"text-[#747676] transition-colors group-hover:text-[#ada3ff]" -
} -
/> -
</button> -
{open && ( -
<p className="mt-4 text-[#aaabab] text-sm leading-relaxed">{answer}</p> -
)}
export function LandingPage() { const { user } = useAuth(); const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
return (
-
-
{/* Layered background effects */}
-
-
{/* Background effects */} <div className="pointer-events-none fixed inset-0">
-
{/* Neural mesh pattern */} <div className="neural-mesh absolute inset-0" /> -
{/* Radial glow */} <div className="absolute inset-0 bg-[radial-gradient(ellipse_at_top,rgba(173,163,255,0.08),transparent_50%)]" /> -
{/* Secondary glow bottom-right */} <div className="absolute inset-0 bg-[radial-gradient(ellipse_at_80%_100%,rgba(112,91,245,0.05),transparent_50%)]" /> </div> -
{/* Header */} -
<header className="relative sticky top-0 z-50 border-border/40 border-b bg-background/80 backdrop-blur-lg"> -
<div className="mx-auto flex max-w-6xl items-center justify-between px-6 py-4"> -
<Logo variant="sandbox" size="md" /> -
<nav className="hidden items-center gap-1 md:flex"> -
<a -
href="https://docs.tangle.tools" -
target="_blank" -
rel="noopener noreferrer" -
className="rounded-md px-3 py-2 text-muted-foreground text-sm transition-colors hover:bg-accent hover:text-foreground" -
> -
Docs -
</a>
-
{/* Top Nav */} -
<nav className="fixed top-0 z-50 w-full border-white/5 border-b bg-[#0d0e0f]/80 shadow-[0_8px_32px_0_rgba(0,0,0,0.36)] backdrop-blur-xl"> -
<div className="mx-auto flex h-16 max-w-7xl items-center justify-between px-8"> -
<div className="flex items-center gap-8"> <Link
-
to="/pricing" -
className="rounded-md px-3 py-2 text-muted-foreground text-sm transition-colors hover:bg-accent hover:text-foreground"
-
to="/" -
className="flex items-center gap-2 font-bold font-headline text-2xl text-white tracking-tighter" >
-
Pricing
-
<img src="/tangle-logo-light.svg" alt="" className="h-7 w-7" /> -
Tangle Sandbox </Link>
-
<a -
href="https://github.com/tangle-network" -
target="_blank" -
rel="noopener noreferrer" -
className="flex items-center gap-1.5 rounded-md px-3 py-2 text-muted-foreground text-sm transition-colors hover:bg-accent hover:text-foreground" -
> -
<Github className="h-4 w-4" /> -
GitHub -
</a> -
</nav>
-
<div className="hidden items-center gap-6 md:flex"> -
<Link -
to="/dashboard" -
className="font-bold text-gray-400 text-sm transition-colors hover:text-white" -
> -
Sandbox -
</Link> -
<Link -
to="/pricing" -
className="font-bold text-gray-400 text-sm transition-colors hover:text-white" -
> -
Pricing -
</Link> -
<a -
href="https://docs.tangle.tools" -
target="_blank" -
rel="noopener noreferrer" -
className="font-bold text-gray-400 text-sm transition-colors hover:text-white" -
> -
Docs -
</a> -
<a -
href="https://github.com/tangle-network" -
target="_blank" -
rel="noopener noreferrer" -
className="font-bold text-gray-400 text-sm transition-colors hover:text-white" -
> -
GitHub -
</a> -
</div> -
</div> <div className="flex items-center gap-3"> {user ? ( <Link to="/dashboard">
-
<Button -
variant="sandbox" -
size="sm" -
className="hidden md:inline-flex"
-
<button -
type="button" -
className="hidden rounded-full bg-gradient-to-br from-[#ada3ff] to-[#705bf5] px-5 py-2 font-bold text-black text-sm shadow-[#ada3ff]/20 shadow-lg transition-all active:scale-95 md:inline-flex" > Dashboard
-
<ArrowRight className="ml-1.5 h-3.5 w-3.5" /> -
</Button>
-
</button> </Link> ) : (
-
<> -
<Link to="/login"> -
<Button -
variant="ghost" -
size="sm" -
className="hidden md:inline-flex" -
> -
Sign In -
</Button> -
</Link> -
<Link to="/login"> -
<Button -
variant="sandbox" -
size="sm" -
className="hidden md:inline-flex" -
> -
Get Started -
</Button> -
</Link> -
</>
-
<Link to="/login"> -
<button -
type="button" -
className="hidden rounded-full bg-gradient-to-br from-[#ada3ff] to-[#705bf5] px-5 py-2 font-bold text-black text-sm shadow-[#ada3ff]/20 shadow-lg transition-all active:scale-95 md:inline-flex" -
> -
Get Started -
</button> -
</Link> )}
-
<Button -
variant="ghost" -
size="icon" -
className="md:hidden"
-
<button -
type="button" -
className="text-gray-400 transition-colors hover:text-white md:hidden" onClick={() => setMobileMenuOpen(!mobileMenuOpen)} aria-label="Toggle menu" >
-
{mobileMenuOpen ? ( -
<X className="h-5 w-5" /> -
) : ( -
<Menu className="h-5 w-5" /> -
)} -
</Button>
-
<MaterialIcon name={mobileMenuOpen ? "close" : "menu"} /> -
</button> </div> </div> {mobileMenuOpen && (
-
<div className="border-border/40 border-t bg-background px-6 py-4 md:hidden"> -
<nav className="flex flex-col gap-3">
-
<div className="border-white/5 border-t bg-[#0d0e0f] px-8 py-6 md:hidden"> -
<nav className="flex flex-col gap-4"> -
<Link -
to="/dashboard" -
className="font-bold text-gray-400 text-sm transition-colors hover:text-white" -
> -
Sandbox -
</Link> -
<Link -
to="/pricing" -
className="font-bold text-gray-400 text-sm transition-colors hover:text-white" -
> -
Pricing -
</Link> <a href="https://docs.tangle.tools" target="_blank" rel="noopener noreferrer"
-
className="text-muted-foreground transition-colors hover:text-foreground"
-
className="font-bold text-gray-400 text-sm transition-colors hover:text-white" > Docs </a>
-
<Link -
to="/pricing" -
className="text-muted-foreground transition-colors hover:text-foreground" -
> -
Pricing -
</Link> <a href="https://github.com/tangle-network" target="_blank" rel="noopener noreferrer" -
className="flex items-center gap-2 text-muted-foreground transition-colors hover:text-foreground"
-
className="font-bold text-gray-400 text-sm transition-colors hover:text-white" >
-
<Github className="h-4 w-4" /> GitHub </a> -
<div className="border-border/40 border-t pt-3">
-
<div className="border-white/5 border-t pt-4"> <Link to={user ? "/dashboard" : "/login"}>
-
<Button variant="sandbox" size="sm" className="w-full"> -
{user ? "Dashboard" : "Sign In"} -
</Button>
-
<button -
type="button" -
className="w-full rounded-full bg-gradient-to-br from-[#ada3ff] to-[#705bf5] px-5 py-2 font-bold text-black text-sm" -
> -
{user ? "Dashboard" : "Get Started"} -
</button> </Link> </div> </nav> </div> )}
-
</header>
-
</nav>
-
<main className="relative">
-
<main className="relative pt-16"> {/* Hero */}
-
<section className="relative mx-auto max-w-6xl px-6 pt-24 pb-24 md:pt-32"> -
{/* Floating orbs */} -
<div className="pointer-events-none absolute -top-20 left-1/4 h-72 w-72 animate-pulse rounded-full bg-purple-500/10 blur-[100px]" /> -
<div className="pointer-events-none absolute top-40 -right-20 h-56 w-56 animate-pulse rounded-full bg-violet-500/8 blur-[80px] [animation-delay:1s]" />
-
<section className="relative flex min-h-[870px] items-center overflow-hidden px-8 lg:px-24"> -
<div className="pointer-events-none absolute top-1/4 -left-20 h-[500px] w-[500px] rounded-full bg-[#ada3ff]/10 blur-[120px]" /> -
<div className="pointer-events-none absolute -right-20 bottom-1/4 h-[600px] w-[600px] rounded-full bg-[#484073]/20 blur-[150px]" /> -
<div className="z-10 mx-auto grid w-full max-w-7xl items-center gap-16 lg:grid-cols-2"> -
<div className="space-y-8"> -
<div className="inline-flex items-center gap-2 rounded-full border border-white/10 bg-white/5 px-3 py-1 font-label text-[#9f93ff] text-xs uppercase tracking-widest"> -
<span className="h-1.5 w-1.5 animate-pulse rounded-full bg-[#ada3ff]" /> -
Next-Gen Agent Infrastructure -
</div>
-
<div className="grid gap-16 lg:grid-cols-2 lg:items-center"> -
<div> -
<Badge variant="sandbox" className="mb-6"> -
Now in Public Beta -
</Badge> -
<h1 className="mb-6 font-bold text-5xl leading-[1.05] tracking-tight md:text-7xl"> -
Sandboxed -
<br /> -
cloud{" "} -
<span className="text-gradient-sandbox"> -
for AI -
<br /> -
agents -
</span>
-
<h1 className="font-bold font-headline text-6xl text-white leading-[1.05] tracking-tight md:text-7xl"> -
Give your agents the{" "} -
<span className="gradient-text">real world</span>, safely. </h1>
-
<p className="mb-10 max-w-md text-lg text-muted-foreground leading-relaxed"> -
Isolated dev containers with built-in LLM access. Run any AI -
agent — Claude Code, Codex, your own — and pay per second. -
</p> -
{/* Install snippet */} -
<div className="group mb-8 inline-flex items-center gap-3 rounded-lg border border-purple-500/20 bg-card/50 px-5 py-3 font-mono text-sm transition-colors hover:border-purple-500/40"> -
<span className="text-purple-400">$</span> -
<span className="text-muted-foreground"> -
npm install @tangle-network/sandbox -
</span> -
<Copy -
className="h-3.5 w-3.5 cursor-pointer text-muted-foreground/50 transition-colors group-hover:text-purple-400" -
onClick={() => -
navigator.clipboard.writeText( -
"npm install @tangle-network/sandbox", -
) -
} -
/> -
</div>
-
<p className="max-w-lg text-[#aaabab] text-lg leading-relaxed"> -
Deploy AI agents in ephemeral, isolated sandboxes. Full root -
access, complete network isolation, and sub-second cold starts. -
</p>
-
<div className="flex flex-wrap items-center gap-4">
-
<div className="flex flex-wrap gap-4 pt-4"> <Link to={user ? "/dashboard" : "/login"}>
-
<Button variant="sandbox" size="lg"> -
{user ? "Go to Dashboard" : "Get Started Free"} -
<ArrowRight className="h-4 w-4" /> -
</Button>
-
<button -
type="button" -
className="glow-primary rounded-full bg-gradient-to-br from-[#ada3ff] to-[#705bf5] px-8 py-4 font-bold text-black text-lg transition-all hover:scale-105" -
> -
Get Started Free -
</button> </Link> <a
-
href="https://github.com/tangle-network"
-
href="https://docs.tangle.tools" target="_blank" rel="noopener noreferrer" >
-
<Button variant="outline" size="lg"> -
<Github className="h-4 w-4" /> -
View Source -
</Button>
-
<button -
type="button" -
className="rounded-full border border-[#474848]/30 bg-white/5 px-8 py-4 font-bold text-lg text-white transition-all hover:bg-white/10" -
> -
Documentation -
</button> </a> </div> </div>
-
{/* Code preview with glow effect */} -
<div className="hidden lg:block"> -
<div className="relative"> -
<div className="absolute -inset-1 rounded-xl bg-gradient-to-r from-purple-500/20 to-violet-500/20 blur-lg" /> -
<div className="relative overflow-hidden rounded-xl border border-purple-500/20 bg-card"> -
<div className="flex items-center gap-2 border-border/50 border-b bg-card/30 px-4 py-3"> -
<div className="flex gap-1.5"> -
<div className="h-3 w-3 rounded-full bg-red-500/80" /> -
<div className="h-3 w-3 rounded-full bg-yellow-500/80" /> -
<div className="h-3 w-3 rounded-full bg-purple-500/80" />
-
{/* Sandbox environment visual */} -
<div className="relative hidden lg:block"> -
<div className="glass-panel relative flex aspect-square items-center justify-center overflow-hidden rounded-3xl p-4 shadow-2xl"> -
<div className="absolute inset-0 bg-gradient-to-tr from-[#121414] to-transparent opacity-50" /> -
<div className="relative flex h-full w-full items-center justify-center rounded-2xl border border-white/5 bg-black/50"> -
<div -
className="pointer-events-none absolute inset-0 opacity-20" -
style={{ -
backgroundImage: -
"radial-gradient(#ada3ff 1px, transparent 1px)", -
backgroundSize: "20px 20px", -
}} -
/> -
<div className="z-10 text-center"> -
<div className="relative mx-auto mb-6 flex h-32 w-32 items-center justify-center rounded-full bg-[#ada3ff]/20"> -
<div className="absolute inset-0 rounded-full bg-[#ada3ff] opacity-30 blur-3xl" /> -
<MaterialIcon -
name="security" -
fill -
className="text-6xl text-[#ada3ff]" -
/> -
</div> -
<div className="mb-2 font-label text-[#ada3ff] text-sm"> -
SANDBOX_ENVIRONMENT_01 </div>
-
<span className="ml-2 font-mono text-muted-foreground text-xs"> -
quickstart.ts -
</span>
-
<div className="flex justify-center gap-2"> -
<span className="rounded border border-green-500/30 bg-green-500/20 px-2 py-0.5 font-label text-[10px] text-green-400"> -
ACTIVE -
</span> -
<span className="rounded border border-blue-500/30 bg-blue-500/20 px-2 py-0.5 font-label text-[10px] text-blue-400"> -
ROOT_ACCESS -
</span> -
</div> -
</div> -
</div> -
{/* Floating data points */} -
<div className="glass-panel absolute top-8 right-8 rounded-lg px-3 py-2 font-label text-[#aaabab] text-[10px]"> -
CPU: 1.2% | MEM: 45MB -
</div> -
<div className="glass-panel absolute bottom-12 left-8 rounded-lg px-3 py-2 font-label text-[#aaabab] text-[10px]"> -
TCP_PORT_8080: OPEN -
</div> -
</div> -
</div> -
</div> -
</section> -
{/* Bento Grid Features */} -
<section className="bg-[#121414] px-8 py-24 lg:px-24"> -
<div className="mx-auto max-w-7xl"> -
<div className="mb-16"> -
<h2 className="mb-4 font-bold font-headline text-4xl"> -
Uncompromising Infrastructure -
</h2> -
<p className="max-w-xl text-[#aaabab]"> -
Everything you need to run autonomous agents that can actually -
do work, without the security nightmares. -
</p> -
</div> -
<div className="grid grid-cols-1 gap-6 md:grid-cols-3"> -
{/* Full Root Access — 2 col */} -
<div className="group glass-panel flex flex-col justify-between rounded-3xl p-8 transition-all duration-500 hover:border-[#ada3ff]/30 md:col-span-2"> -
<div> -
<div className="mb-6 flex h-12 w-12 items-center justify-center rounded-xl bg-[#ada3ff]/10 transition-all group-hover:bg-[#ada3ff]/20"> -
<MaterialIcon name="terminal" className="text-[#ada3ff]" /> </div>
-
<pre className="p-5 font-mono text-[13px] text-foreground/80 leading-relaxed">
-
<h3 className="mb-3 font-bold text-2xl">Full Root Access</h3> -
<p className="max-w-md text-[#aaabab]"> -
Give agents a real Linux environment. Install packages, run -
complex scripts, and manage files just like a human -
developer would. -
</p> -
</div> -
<div className="mt-12 overflow-hidden rounded-xl border border-white/5 bg-[#050505]"> -
<pre className="p-6 font-label text-[#aaabab] text-xs leading-relaxed"> <code>
-
<K>import</K> {"{ Sandbox }"} <K>from</K>{" "} -
<S>"@tangle-network/sandbox"</S> -
{"\n\n"} -
<K>const</K> <V>box</V> = <K>await</K> sandbox. -
<F>create</F>({"{"}
-
<SH>$</SH> apt-get install -y build-essential{"\n"} -
<SH>$</SH> git clone https://github.com/my-org/api.git {"\n"}
-
{" "}image: <S>"node:20"</S>,{"\n"} -
{"}"});{"\n\n"} -
<K>await</K> box.<F>task</F>( -
<S>"Build an API with auth"</S>);
-
<SH>$</SH> cd api && npm install && npm test{"\n"} -
<span className="text-green-400"> -
All 47 tests passed. -
</span> </code> </pre> </div> </div> -
{/* Any Image */} -
<div className="glass-panel flex flex-col rounded-3xl p-8 transition-all duration-500 hover:border-[#ada3ff]/30"> -
<div className="mb-6 flex h-12 w-12 items-center justify-center rounded-xl bg-[#484073]/30"> -
<MaterialIcon name="image" className="text-[#ada3ff]" /> -
</div> -
<h3 className="mb-3 font-bold text-2xl">Any Image</h3> -
<p className="mb-8 text-[#aaabab]"> -
Bring your own Docker images or use our optimized agent-ready -
environments. -
</p> -
<div className="mt-auto flex -space-x-4"> -
<div className="flex h-12 w-12 items-center justify-center rounded-full border-2 border-[#0d0e0f] bg-blue-600 shadow-xl"> -
<MaterialIcon -
name="deployed_code" -
className="text-lg text-white" -
/> -
</div> -
<div className="flex h-12 w-12 items-center justify-center rounded-full border-2 border-[#0d0e0f] bg-orange-600 shadow-xl"> -
<MaterialIcon name="dns" className="text-lg text-white" /> -
</div> -
<div className="flex h-12 w-12 items-center justify-center rounded-full border-2 border-[#0d0e0f] bg-slate-800 shadow-xl"> -
<MaterialIcon name="build" className="text-lg text-white" /> -
</div> -
</div> -
</div> -
{/* Locked Security */} -
<div className="glass-panel flex flex-col rounded-3xl p-8 transition-all duration-500 hover:border-[#ada3ff]/30"> -
<div className="mb-6 flex h-12 w-12 items-center justify-center rounded-xl bg-[#ff6e84]/10"> -
<MaterialIcon name="lock" className="text-[#ff6e84]" /> -
</div> -
<h3 className="mb-3 font-bold text-2xl">Locked Security</h3> -
<p className="text-[#aaabab]"> -
Network egress rules, dropped capabilities, and sub-second -
cleanup. Your infrastructure stays safe from unintended agent -
actions. -
</p> -
</div> -
{/* Ephemeral & Instant — 2 col */} -
<div className="glass-panel flex items-center gap-12 rounded-3xl p-8 transition-all duration-500 hover:border-[#ada3ff]/30 md:col-span-2"> -
<div className="flex-1"> -
<h3 className="mb-3 font-bold text-2xl"> -
Ephemeral & Instant -
</h3> -
<p className="text-[#aaabab]"> -
Sandboxes start in <150ms. High density means you can -
scale to thousands of simultaneous agents without breaking -
the bank. -
</p> -
</div> -
<div className="hidden flex-1 md:block"> -
<div className="relative flex h-24 w-full items-center justify-center overflow-hidden rounded-lg bg-[#181a1a]"> -
<div className="absolute inset-0 animate-pulse bg-gradient-to-r from-transparent via-[#ada3ff]/10 to-transparent" /> -
<div className="font-bold font-label text-4xl text-[#ada3ff]"> -
150ms -
</div> -
</div> -
</div> -
</div> </div> </div> </section>
-
{/* SDK Examples — tabbed code blocks */} -
<section className="relative mx-auto max-w-6xl px-6 pb-28"> -
<div className="pointer-events-none absolute top-1/2 left-1/2 h-96 w-96 -translate-x-1/2 -translate-y-1/2 rounded-full bg-purple-500/5 blur-[120px]" /> -
<div className="mb-10 text-center"> -
<p className="mb-2 font-mono text-purple-400 text-sm uppercase tracking-wide"> -
Developer Experience -
</p> -
<h2 className="mb-4 font-bold text-3xl tracking-tight md:text-4xl"> -
Everything you need in the SDK -
</h2> -
<p className="mx-auto max-w-lg text-lg text-muted-foreground"> -
Create sandboxes, execute commands, run AI agents, stream -
responses — all from TypeScript or the CLI. -
</p> -
</div> -
<div className="relative"> -
<div className="absolute -inset-2 rounded-2xl bg-gradient-to-br from-purple-500/10 via-transparent to-violet-500/10 blur-xl" /> -
<div className="relative">
-
{/* SDK Section — Built for Builders */} -
<section className="px-8 py-24 lg:px-24"> -
<div className="mx-auto grid max-w-7xl items-center gap-16 lg:grid-cols-5"> -
<div className="space-y-6 lg:col-span-2"> -
<h2 className="font-bold font-headline text-4xl leading-tight"> -
Built for Builders. -
</h2> -
<p className="text-[#aaabab] leading-relaxed"> -
The Tangle SDK is lightweight and fits right into your existing -
agentic workflows. Whether you use LangChain, AutoGPT, or custom -
loops, managing environments is just a function call away. -
</p> -
<ul className="space-y-4"> -
<li className="flex items-center gap-3 text-sm"> -
<MaterialIcon -
name="check_circle" -
className="text-[#ada3ff] text-lg" -
/> -
TypeScript & Python Native -
</li> -
<li className="flex items-center gap-3 text-sm"> -
<MaterialIcon -
name="check_circle" -
className="text-[#ada3ff] text-lg" -
/> -
Direct WebSocket access to shell -
</li> -
<li className="flex items-center gap-3 text-sm"> -
<MaterialIcon -
name="check_circle" -
className="text-[#ada3ff] text-lg" -
/> -
Auto-cleanup after task completion -
</li> -
</ul> -
</div> -
<div className="lg:col-span-3"> <CodeTabs /> </div> </div> </section>
-
{/* Features grid */} -
<section className="mx-auto max-w-6xl px-6 pb-28"> -
<div className="mb-10 text-center"> -
<p className="mb-2 font-mono text-purple-400 text-sm uppercase tracking-wide"> -
Platform -
</p> -
<h2 className="mb-4 font-bold text-3xl tracking-tight md:text-4xl"> -
Built for AI-native workflows -
</h2> -
</div> -
<div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3"> -
{[ -
{ -
icon: <Server className="h-5 w-5" />, -
title: "Any Docker Image", -
desc: "Node, Python, Ubuntu, or your own custom image. Full root access inside each sandbox.", -
}, -
{ -
icon: <Bot className="h-5 w-5" />, -
title: "AI Agent Runtime", -
desc: "Run Claude Code, Codex, or any agent inside sandboxes with built-in LLM proxy access.", -
}, -
{ -
icon: <TerminalIcon className="h-5 w-5" />, -
title: "SSH & Web Terminal", -
desc: "SSH directly into any sandbox or connect through the browser-based terminal.", -
}, -
{ -
icon: <Layers className="h-5 w-5" />, -
title: "Snapshots & Restore", -
desc: "Checkpoint sandbox state, restore from snapshots. Bring your own S3 storage.", -
}, -
{ -
icon: <Lock className="h-5 w-5" />, -
title: "Isolated & Secure", -
desc: "Dropped capabilities, no privilege escalation, gVisor/Firecracker isolation options.", -
}, -
{ -
icon: <Zap className="h-5 w-5" />, -
title: "Pay Per Second", -
desc: "Billed by compute time. No monthly minimums. Idle sandboxes auto-hibernate.", -
}, -
].map((feature) => ( -
<Card -
key={feature.title} -
variant="glass" -
className="group relative p-6 transition-all duration-300 hover:border-purple-500/30 hover:shadow-lg hover:shadow-purple-500/5" -
> -
<div className="mb-4 flex h-10 w-10 items-center justify-center rounded-xl bg-purple-500/10 text-purple-400 transition-colors group-hover:bg-purple-500/15"> -
{feature.icon} -
</div> -
<h3 className="mb-2 font-semibold text-base"> -
{feature.title} -
</h3> -
<p className="text-muted-foreground text-sm leading-relaxed"> -
{feature.desc} -
</p> -
</Card> -
))}
-
{/* FAQ */} -
<section className="bg-[#121414]/50 px-8 py-24 lg:px-24"> -
<div className="mx-auto max-w-3xl"> -
<div className="mb-16 text-center"> -
<h2 className="mb-4 font-bold font-headline text-4xl"> -
Common Questions -
</h2> -
<p className="text-[#aaabab]"> -
Everything you need to know about secure agent hosting. -
</p> -
</div> -
<div className="space-y-4"> -
{FAQ_ITEMS.map((item) => ( -
<FaqItem -
key={item.question} -
question={item.question} -
answer={item.answer} -
/> -
))} -
</div> </div> </section>
-
{/* CTA — Tangle gradient card */} -
<section className="mx-auto max-w-6xl px-6 pb-28"> -
<div className="relative overflow-hidden rounded-2xl bg-gradient-to-br from-purple-600 via-purple-500 to-violet-500 p-10 text-center md:p-16"> -
<div className="pointer-events-none absolute inset-0 bg-[radial-gradient(circle_at_30%_50%,rgba(255,255,255,0.1),transparent_60%)]" /> -
<div className="pointer-events-none absolute -top-24 -right-24 h-48 w-48 rounded-full bg-white/10 blur-2xl" /> -
<div className="pointer-events-none absolute -bottom-16 -left-16 h-40 w-40 rounded-full bg-violet-400/20 blur-2xl" /> -
<h2 className="relative mb-3 font-bold text-2xl text-white md:text-3xl"> -
Start building in minutes
-
{/* Final CTA */} -
<section className="relative overflow-hidden px-8 py-32 lg:px-24"> -
<div className="absolute inset-0 -z-10 bg-[#ada3ff]/5" /> -
<div className="absolute top-0 left-1/2 h-px w-full -translate-x-1/2 bg-gradient-to-r from-transparent via-[#ada3ff]/30 to-transparent" /> -
<div className="mx-auto max-w-4xl space-y-8 text-center"> -
<h2 className="font-bold font-headline text-5xl tracking-tight md:text-6xl"> -
Ready to let your agents <br /> -
loose in the wild? </h2>
-
<p className="relative mx-auto mb-8 max-w-md text-white/70"> -
Create your first sandbox, run an AI agent, ship faster. Free tier -
included.
-
<p className="mx-auto max-w-2xl text-[#aaabab] text-xl"> -
Join teams building the next generation of autonomous AI systems -
with Tangle's secure sandboxes. </p>
-
<div className="relative flex flex-wrap items-center justify-center gap-3"> -
<Link to="/dashboard"> -
<Button -
size="lg" -
className="bg-white text-gray-900 shadow-lg hover:bg-white/90"
-
<div className="pt-8"> -
<Link to={user ? "/dashboard" : "/login"}> -
<button -
type="button" -
className="glow-primary rounded-full bg-gradient-to-br from-[#ada3ff] to-[#705bf5] px-10 py-5 font-bold text-black text-xl transition-all hover:scale-105" >
-
Get Started Free -
<ArrowRight className="h-4 w-4" /> -
</Button>
-
Get Started Now -
</button> </Link>
-
<a -
href="https://github.com/tangle-network" -
target="_blank" -
rel="noopener noreferrer" -
> -
<Button -
variant="outline" -
size="lg" -
className="border-white/30 text-white hover:bg-white/10" -
> -
<Code2 className="h-4 w-4" /> -
View on GitHub -
</Button> -
</a>
-
<p className="mt-4 font-label text-[#747676] text-xs uppercase tracking-widest"> -
No Credit Card Required -
</p> </div> </div> </section> </main> {/* Footer */}
-
<footer className="relative border-border/40 border-t bg-card/30"> -
<div className="mx-auto max-w-6xl px-6 py-12"> -
<div className="grid gap-8 md:grid-cols-4"> -
<div className="md:col-span-2"> -
<Logo variant="sandbox" size="md" /> -
<p className="mt-3 max-w-sm text-muted-foreground text-sm"> -
Isolated dev containers with built-in LLM access. Create -
sandboxes, run AI agents, pay per second. -
</p> -
</div> -
<div> -
<h4 className="mb-3 font-medium text-sm">Product</h4> -
<div className="flex flex-col gap-2 text-muted-foreground text-sm"> -
<Link -
to="/dashboard" -
className="transition-colors hover:text-foreground" -
> -
Dashboard -
</Link> -
<Link -
to="/pricing" -
className="transition-colors hover:text-foreground" -
> -
Pricing -
</Link> -
<a -
href="https://docs.tangle.tools" -
target="_blank" -
rel="noopener noreferrer" -
className="transition-colors hover:text-foreground" -
> -
Docs -
</a> -
</div> -
</div> -
<div> -
<h4 className="mb-3 font-medium text-sm">Tangle Network</h4> -
<div className="flex flex-col gap-2 text-muted-foreground text-sm"> -
<a -
href="https://tangle.tools" -
target="_blank" -
rel="noopener noreferrer" -
className="transition-colors hover:text-foreground" -
> -
tangle.tools -
</a> -
<a -
href="https://github.com/tangle-network" -
target="_blank" -
rel="noopener noreferrer" -
className="transition-colors hover:text-foreground" -
> -
GitHub -
</a> -
<a -
href="https://twitter.com/tangle_network" -
target="_blank" -
rel="noopener noreferrer" -
className="transition-colors hover:text-foreground" -
> -
X / Twitter -
</a> -
<a -
href="https://discord.com/invite/cv8EfJu3Tn" -
target="_blank" -
rel="noopener noreferrer" -
className="transition-colors hover:text-foreground" -
> -
Discord -
</a> -
</div> -
</div> -
</div> -
<div className="mt-8 flex items-center justify-between border-border/40 border-t pt-6"> -
<p className="text-muted-foreground text-xs">
-
<footer className="w-full border-white/5 border-t bg-[#0d0e0f] px-8 py-12"> -
<div className="mx-auto flex max-w-7xl flex-col items-center justify-between gap-8 md:flex-row"> -
<div className="flex flex-col items-center gap-4 md:items-start"> -
<span className="flex items-center gap-2 font-bold text-lg text-white"> -
<img src="/tangle-logo-light.svg" alt="" className="h-6 w-6" /> -
Tangle Sandbox -
</span> -
<p className="text-center text-gray-500 text-sm md:text-left"> © {new Date().getFullYear()} Tangle Foundation. All rights reserved. </p>
-
<div className="flex items-center gap-4 text-muted-foreground"> -
<a -
href="https://github.com/tangle-network" -
target="_blank" -
rel="noopener noreferrer" -
className="transition-colors hover:text-foreground" -
aria-label="GitHub" -
> -
<Github className="h-4 w-4" /> -
</a> -
<a -
href="https://twitter.com/tangle_network" -
target="_blank" -
rel="noopener noreferrer" -
className="transition-colors hover:text-foreground" -
aria-label="X / Twitter"
-
</div> -
<div className="flex flex-wrap justify-center gap-8"> -
<Link -
to="/pricing" -
className="text-gray-500 text-sm transition-colors hover:text-gray-300" -
> -
Pricing -
</Link> -
<a -
href="https://docs.tangle.tools" -
target="_blank" -
rel="noopener noreferrer" -
className="text-gray-500 text-sm transition-colors hover:text-gray-300" -
> -
Docs -
</a> -
<a -
href="https://tangle.tools" -
target="_blank" -
rel="noopener noreferrer" -
className="text-gray-500 text-sm transition-colors hover:text-gray-300" -
> -
Status -
</a> -
<a -
href="https://github.com/tangle-network" -
target="_blank" -
rel="noopener noreferrer" -
className="text-gray-500 text-sm transition-colors hover:text-gray-300" -
> -
GitHub -
</a> -
</div> -
<div className="flex gap-4"> -
<a -
href="https://github.com/tangle-network" -
target="_blank" -
rel="noopener noreferrer" -
className="flex h-10 w-10 items-center justify-center rounded-full bg-white/5 transition-all hover:bg-white/10" -
aria-label="GitHub" -
> -
<svg -
className="h-5 w-5 text-gray-400" -
viewBox="0 0 24 24" -
fill="currentColor" >
-
<svg -
className="h-4 w-4" -
viewBox="0 0 24 24" -
fill="currentColor" -
role="img" -
aria-label="X" -
> -
<title>X</title> -
<path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z" /> -
</svg> -
</a> -
<a -
href="https://discord.com/invite/cv8EfJu3Tn" -
target="_blank" -
rel="noopener noreferrer" -
className="transition-colors hover:text-foreground" -
aria-label="Discord"
-
<title>GitHub</title> -
<path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z" /> -
</svg> -
</a> -
<a -
href="https://twitter.com/tangle_network" -
target="_blank" -
rel="noopener noreferrer" -
className="flex h-10 w-10 items-center justify-center rounded-full bg-white/5 transition-all hover:bg-white/10" -
aria-label="X / Twitter" -
> -
<svg -
className="h-5 w-5 text-gray-400" -
viewBox="0 0 24 24" -
fill="currentColor" >
-
<svg -
className="h-4 w-4" -
viewBox="0 0 24 24" -
fill="currentColor" -
role="img" -
aria-label="Discord" -
> -
<title>Discord</title> -
<path d="M20.317 4.3698a19.7913 19.7913 0 00-4.8851-1.5152.0741.0741 0 00-.0785.0371c-.211.3753-.4447.8648-.6083 1.2495-1.8447-.2762-3.68-.2762-5.4868 0-.1636-.3933-.4058-.8742-.6177-1.2495a.077.077 0 00-.0785-.037 19.7363 19.7363 0 00-4.8852 1.515.0699.0699 0 00-.0321.0277C.5334 9.0458-.319 13.5799.0992 18.0578a.0824.0824 0 00.0312.0561c2.0528 1.5076 4.0413 2.4228 5.9929 3.0294a.0777.0777 0 00.0842-.0276c.4616-.6304.8731-1.2952 1.226-1.9942a.076.076 0 00-.0416-.1057c-.6528-.2476-1.2743-.5495-1.8722-.8923a.077.077 0 01-.0076-.1277c.1258-.0943.2517-.1923.3718-.2914a.0743.0743 0 01.0776-.0105c3.9278 1.7933 8.18 1.7933 12.0614 0a.0739.0739 0 01.0785.0095c.1202.099.246.1981.3728.2924a.077.077 0 01-.0066.1276 12.2986 12.2986 0 01-1.873.8914.0766.0766 0 00-.0407.1067c.3604.698.7719 1.3628 1.225 1.9932a.076.076 0 00.0842.0286c1.961-.6067 3.9495-1.5219 6.0023-3.0294a.077.077 0 00.0313-.0552c.5004-5.177-.8382-9.6739-3.5485-13.6604a.061.061 0 00-.0312-.0286z" /> -
</svg> -
</a> -
<a -
href="https://t.me/tanglenet" -
target="_blank" -
rel="noopener noreferrer" -
className="transition-colors hover:text-foreground" -
aria-label="Telegram"
-
<title>X</title> -
<path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z" /> -
</svg> -
</a> -
<a -
href="https://discord.com/invite/cv8EfJu3Tn" -
target="_blank" -
rel="noopener noreferrer" -
className="flex h-10 w-10 items-center justify-center rounded-full bg-white/5 transition-all hover:bg-white/10" -
aria-label="Discord" -
> -
<svg -
className="h-5 w-5 text-gray-400" -
viewBox="0 0 24 24" -
fill="currentColor" >
-
<svg -
className="h-4 w-4" -
viewBox="0 0 24 24" -
fill="currentColor" -
role="img" -
aria-label="Telegram" -
> -
<title>Telegram</title> -
<path d="M11.944 0A12 12 0 000 12a12 12 0 0012 12 12 12 0 0012-12A12 12 0 0012 0a12 12 0 00-.056 0zm4.962 7.224c.1-.002.321.023.465.14a.506.506 0 01.171.325c.016.093.036.306.02.472-.18 1.898-.962 6.502-1.36 8.627-.168.9-.499 1.201-.82 1.23-.696.065-1.225-.46-1.9-.902-1.056-.693-1.653-1.124-2.678-1.8-1.185-.78-.417-1.21.258-1.91.177-.184 3.247-2.977 3.307-3.23.007-.032.014-.15-.056-.212s-.174-.041-.249-.024c-.106.024-1.793 1.14-5.061 3.345-.479.33-.913.49-1.302.48-.428-.008-1.252-.241-1.865-.44-.752-.245-1.349-.374-1.297-.789.027-.216.325-.437.893-.663 3.498-1.524 5.83-2.529 6.998-3.014 3.332-1.386 4.025-1.627 4.476-1.635z" /> -
</svg> -
</a> -
</div>
-
<title>Discord</title> -
<path d="M20.317 4.3698a19.7913 19.7913 0 00-4.8851-1.5152.0741.0741 0 00-.0785.0371c-.211.3753-.4447.8648-.6083 1.2495-1.8447-.2762-3.68-.2762-5.4868 0-.1636-.3933-.4058-.8742-.6177-1.2495a.077.077 0 00-.0785-.037 19.7363 19.7363 0 00-4.8852 1.515.0699.0699 0 00-.0321.0277C.5334 9.0458-.319 13.5799.0992 18.0578a.0824.0824 0 00.0312.0561c2.0528 1.5076 4.0413 2.4228 5.9929 3.0294a.0777.0777 0 00.0842-.0276c.4616-.6304.8731-1.2952 1.226-1.9942a.076.076 0 00-.0416-.1057c-.6528-.2476-1.2743-.5495-1.8722-.8923a.077.077 0 01-.0076-.1277c.1258-.0943.2517-.1923.3718-.2914a.0743.0743 0 01.0776-.0105c3.9278 1.7933 8.18 1.7933 12.0614 0a.0739.0739 0 01.0785.0095c.1202.099.246.1981.3728.2924a.077.077 0 01-.0066.1276 12.2986 12.2986 0 01-1.873.8914.0766.0766 0 00-.0407.1067c.3604.698.7719 1.3628 1.225 1.9932a.076.076 0 00.0842.0286c1.961-.6067 3.9495-1.5219 6.0023-3.0294a.077.077 0 00.0313-.0552c.5004-5.177-.8382-9.6739-3.5485-13.6604a.061.061 0 00-.0312-.0286z" /> -
</svg> -
</a> </div> </div> </footer>
diff --git a/products/sandbox/web/src/pages/Login.tsx b/products/sandbox/web/src/pages/Login.tsx index 8df03b6..e533cf2 100644 --- a/products/sandbox/web/src/pages/Login.tsx +++ b/products/sandbox/web/src/pages/Login.tsx @@ -81,11 +81,13 @@ export function LoginPage() {
-
<div className="mb-4 flex h-14 w-14 items-center justify-center rounded-2xl bg-gradient-to-br from-[#ada3ff] to-[#705bf5] shadow-[#ada3ff]/20 shadow-lg"> -
<MaterialIcon name="cloud" fill className="text-2xl text-white" /> -
</div>
-
<img -
src="/tangle-logo-light.svg" -
alt="Tangle Sandbox" -
className="mb-2 h-12" -
/> <h1 className="font-bold font-headline text-2xl text-white">
-
Tangle
-
Tangle Sandbox </h1> <p className="mt-1 font-label text-gray-500 text-xs uppercase tracking-widest"> Production Cluster Auth
diff --git a/products/sandbox/web/src/pages/Pricing.tsx b/products/sandbox/web/src/pages/Pricing.tsx index b056a71..36791d5 100644 --- a/products/sandbox/web/src/pages/Pricing.tsx +++ b/products/sandbox/web/src/pages/Pricing.tsx @@ -1,314 +1,441 @@ -import {
- Button,
- Card,
- CardContent,
- CardHeader,
- CardTitle,
- Logo, -} from "@tangle-network/sandbox-ui/primitives"; -import { Check, Menu, X } from "lucide-react"; import { useState } from "react"; import { Link } from "react-router-dom"; -import { API_BASE_URL } from "../hooks/useAuth"; +import { MaterialIcon } from "../components/MaterialIcon"; +import { useAuth } from "../hooks/useAuth";
-const tiers = [ +const TIERS = [ {
- tier: "Individual", name: "Free", price: "$0",
- period: "forever",
- description: "Starter tier for evaluation", features: [
-
"2 hrs compute/month", -
"1 GB storage", -
"1 concurrent sandbox", -
"2 vCPU, 1 GB RAM per sandbox", -
"1 hr max session", -
"5 sessions/day", -
"Community support",
-
{ text: "1 sandbox", included: true }, -
{ text: "2 cores", included: true }, -
{ text: "1GB RAM", included: true }, -
],{ text: "Team collaboration", included: false },
- cta: "Get Started",
- ctaHref: "/dashboard",
- external: false,
- cta: "Start Coding",
- ctaLink: "/dashboard", highlighted: false, }, {
- name: "Builder",
- price: "$29.99",
- period: "per month",
- description: "Production usage for individuals and small teams",
- tier: "Professional",
- name: "Pro",
- price: "$29", features: [
-
"200 hrs compute/month", -
"100 GB storage", -
"5 concurrent sandboxes", -
"4 vCPU, 8 GB RAM per sandbox", -
"4 hr max session", -
"Unlimited sessions/day", -
"$0.05/hr overage", -
"Priority scheduling",
-
{ text: "Unlimited sandboxes", included: true }, -
{ text: "8 cores", included: true }, -
{ text: "16GB RAM", included: true }, -
],{ text: "Team collab", included: true },
- cta: "Upgrade to Builder",
- ctaHref: "/dashboard/billing",
- external: false,
- cta: "Level Up",
- ctaLink: "/dashboard/billing", highlighted: true, }, {
- name: "Team",
- price: "$99",
- period: "per month",
- description: "High-scale workloads and dedicated support",
- tier: "Corporate",
- name: "Enterprise",
- price: "Custom",
- priceIsLabel: true, features: [
-
"1,000 hrs compute/month", -
"1 TB storage", -
"20 concurrent sandboxes", -
"8 vCPU, 16 GB RAM per sandbox", -
"24 hr max session", -
"Unlimited sessions/day", -
"$0.04/hr overage", -
"Dedicated support",
-
{ text: "Dedicated infra", included: true }, -
{ text: "SSO / SAML Auth", included: true }, -
{ text: "Custom SLA", included: true }, -
],{ text: "24/7 Priority support", included: true },
- cta: "Upgrade to Team",
- ctaHref: "/dashboard/billing",
- external: false,
- cta: "Contact Sales",
- ctaLink: "mailto:sales@tangle.tools",
- ctaExternal: true, highlighted: false, }, -]; +] as const;
+const COMPARISON_ROWS = [
- {
- feature: "Parallel Sandboxes",
- free: "1",
- pro: "Unlimited",
- enterprise: "Unlimited",
- },
- {
- feature: "CPU Power",
- free: "2 Cores (Shared)",
- pro: "8 Cores (Dedicated)",
- enterprise: "Custom allocation",
- },
- {
- feature: "Max RAM",
- free: "1 GB",
- pro: "16 GB",
- enterprise: "No upper limit",
- },
- {
- feature: "Network Speed",
- free: "1 Gbps",
- pro: "10 Gbps",
- enterprise: "100 Gbps Burst",
- },
- {
- feature: "Snapshot Backups",
- free: "Manual only",
- pro: "Auto hourly",
- enterprise: "Custom retention",
- },
- {
- feature: "Security",
- free: "Standard",
- pro: "VPC Peering",
- enterprise: "Air-gapped option",
- }, +] as const;
export function PricingPage() {
- const { user } = useAuth(); const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
- const handleSignIn = () => {
- const redirectTo =
${window.location.origin}/dashboard; - const base = API_BASE_URL || window.location.origin;
- const loginUrl = new URL(
${base}/auth/login); - loginUrl.searchParams.set("redirect_to", redirectTo);
- window.location.href = loginUrl.toString();
- };
- return (
-
-
{/* Gradient background */} -
<div className="pointer-events-none fixed inset-0 bg-gradient-to-br from-purple-500/5 via-transparent to-violet-500/5" />
-
-
{/* Background effects */} -
<div className="pointer-events-none fixed inset-0"> -
<div className="neural-mesh absolute inset-0" /> -
<div className="absolute inset-0 bg-[radial-gradient(ellipse_at_top,rgba(173,163,255,0.08),transparent_50%)]" /> -
<div className="absolute inset-0 bg-[radial-gradient(ellipse_at_80%_100%,rgba(112,91,245,0.05),transparent_50%)]" /> -
</div>
-
{/* Header */} -
<header className="relative sticky top-0 z-50 border-border/50 border-b bg-background/80 backdrop-blur-xl"> -
<div className="mx-auto flex max-w-6xl items-center justify-between px-6 py-4"> -
<Link to="/"> -
<Logo variant="sandbox" size="md" /> -
</Link> -
<nav className="hidden items-center gap-8 md:flex"> -
<a -
href="https://docs.tangle.network" -
target="_blank" -
rel="noopener noreferrer" -
className="text-muted-foreground transition-colors hover:text-foreground" -
> -
Documentation -
</a> -
<Link to="/pricing" className="text-foreground"> -
Pricing -
</Link>
-
{/* Top Nav */} -
<nav className="fixed top-0 z-50 w-full border-white/5 border-b bg-[#0d0e0f]/80 shadow-[0_8px_32px_0_rgba(0,0,0,0.36)] backdrop-blur-xl"> -
<div className="mx-auto flex h-16 max-w-7xl items-center justify-between px-8"> -
<div className="flex items-center gap-8"> <Link
-
to="/dashboard" -
className="text-muted-foreground transition-colors hover:text-foreground"
-
to="/" -
className="flex items-center gap-2 font-bold font-headline text-2xl text-white tracking-tighter" >
-
Dashboard
-
<img src="/tangle-logo-light.svg" alt="" className="h-7 w-7" /> -
Tangle Sandbox </Link>
-
</nav>
-
<div className="hidden items-center gap-6 md:flex"> -
<Link -
to="/dashboard" -
className="font-bold text-gray-400 text-sm transition-colors hover:text-white" -
> -
Sandbox -
</Link> -
<Link -
to="/pricing" -
className="font-bold text-[#ada3ff] text-sm transition-all duration-300" -
> -
Pricing -
</Link> -
<a -
href="https://docs.tangle.tools" -
target="_blank" -
rel="noopener noreferrer" -
className="font-bold text-gray-400 text-sm transition-colors hover:text-white" -
> -
Docs -
</a> -
</div> -
</div> <div className="flex items-center gap-3">
-
<Button -
variant="ghost" -
size="sm" -
className="hidden md:inline-flex" -
onClick={handleSignIn} -
> -
Sign In -
</Button> -
<Button -
variant="ghost" -
size="icon" -
className="md:hidden"
-
{user ? ( -
<Link to="/dashboard"> -
<button -
type="button" -
className="hidden rounded-full bg-gradient-to-br from-[#ada3ff] to-[#705bf5] px-5 py-2 font-bold text-black text-sm shadow-[#ada3ff]/20 shadow-lg transition-all active:scale-95 md:inline-flex" -
> -
Dashboard -
</button> -
</Link> -
) : ( -
<Link to="/login"> -
<button -
type="button" -
className="hidden rounded-full bg-gradient-to-br from-[#ada3ff] to-[#705bf5] px-5 py-2 font-bold text-black text-sm shadow-[#ada3ff]/20 shadow-lg transition-all active:scale-95 md:inline-flex" -
> -
Get Started -
</button> -
</Link> -
)} -
<button -
type="button" -
className="text-gray-400 transition-colors hover:text-white md:hidden" onClick={() => setMobileMenuOpen(!mobileMenuOpen)} aria-label="Toggle menu" >
-
{mobileMenuOpen ? ( -
<X className="h-5 w-5" /> -
) : ( -
<Menu className="h-5 w-5" /> -
)} -
</Button>
-
<MaterialIcon name={mobileMenuOpen ? "close" : "menu"} /> -
</button> </div> </div> {mobileMenuOpen && (
-
<div className="border-border/50 border-t bg-background px-6 py-4 md:hidden"> -
<nav className="flex flex-col gap-3">
-
<div className="border-white/5 border-t bg-[#0d0e0f] px-8 py-6 md:hidden"> -
<nav className="flex flex-col gap-4"> -
<Link -
to="/dashboard" -
className="font-bold text-gray-400 text-sm transition-colors hover:text-white" -
> -
Sandbox -
</Link> -
<Link to="/pricing" className="font-bold text-[#ada3ff] text-sm"> -
Pricing -
</Link> <a
-
href="https://docs.tangle.network"
-
href="https://docs.tangle.tools" target="_blank" rel="noopener noreferrer"
-
className="text-muted-foreground transition-colors hover:text-foreground"
-
className="font-bold text-gray-400 text-sm transition-colors hover:text-white" >
-
Documentation
-
Docs </a>
-
<Link to="/pricing" className="text-foreground"> -
Pricing -
</Link> -
<Link -
to="/dashboard" -
className="text-muted-foreground transition-colors hover:text-foreground" -
> -
Dashboard -
</Link> -
<Button variant="ghost" size="sm" onClick={handleSignIn}> -
Sign In -
</Button>
-
<div className="border-white/5 border-t pt-4"> -
<Link to={user ? "/dashboard" : "/login"}> -
<button -
type="button" -
className="w-full rounded-full bg-gradient-to-br from-[#ada3ff] to-[#705bf5] px-5 py-2 font-bold text-black text-sm" -
> -
{user ? "Dashboard" : "Get Started"} -
</button> -
</Link> -
</div> </nav> </div> )}
-
</header>
-
</nav> -
<main className="relative mx-auto max-w-7xl px-6 pt-32 pb-24 md:px-12"> -
{/* Ambient glows */} -
<div className="pointer-events-none absolute top-0 left-1/4 -z-10 h-96 w-96 rounded-full bg-[#ada3ff]/10 blur-[120px]" /> -
<div className="pointer-events-none absolute right-0 bottom-1/4 -z-10 h-80 w-80 rounded-full bg-[#705bf5]/10 blur-[100px]" />
-
{/* Pricing Content */} -
<main className="relative mx-auto max-w-6xl px-6 py-16"> {/* Hero */} -
<div className="mb-16 text-center"> -
<h1 className="font-bold text-4xl tracking-tight md:text-5xl"> -
Simple, transparent pricing
-
<div className="mb-20 text-center"> -
<h1 className="mb-6 font-extrabold font-headline text-5xl tracking-tight md:text-7xl"> -
Simple <span className="gradient-text">Scalable</span> Pricing </h1>
-
<p className="mx-auto mt-4 max-w-2xl text-muted-foreground text-xl"> -
Start free, scale as you grow. No hidden fees or surprises.
-
<p className="mx-auto max-w-2xl text-[#aaabab] text-lg leading-relaxed"> -
Choose the sandbox environment that fits your workflow. From solo -
developers to global engineering teams. </p> </div>
-
{/* Pricing Grid */} -
<div className="grid gap-8 lg:grid-cols-3"> -
{tiers.map((tier) => ( -
<Card
-
{/* Pricing Cards */} -
<div className="mb-32 grid grid-cols-1 gap-8 md:grid-cols-3"> -
{TIERS.map((tier) => ( -
<div key={tier.name}
-
className={`relative flex flex-col ${
-
className={`glass-panel flex flex-col rounded-xl p-8 transition-all duration-500 ${ tier.highlighted
-
? "border-purple-500/50 ring-1 ring-purple-500/20" -
: ""
-
? "relative z-10 scale-105 border border-[#ada3ff]/30 shadow-[0_0_40px_rgba(173,163,255,0.1)]" -
: "outline outline-1 outline-[#474848]/20 hover:outline-[#ada3ff]/40" }`} > {tier.highlighted && (
-
<div className="absolute -top-3 left-1/2 -translate-x-1/2"> -
<span className="rounded-full bg-gradient-to-r from-purple-500 to-violet-500 px-4 py-1 font-medium text-sm text-white">
-
<div className="absolute -top-4 left-1/2 -translate-x-1/2 rounded-full bg-gradient-to-r from-[#ada3ff] to-[#705bf5] px-4 py-1"> -
<span className="font-bold text-[10px] text-black uppercase tracking-tighter"> Most Popular </span> </div> )}
-
<CardHeader className="pb-2"> -
<CardTitle className="text-lg">{tier.name}</CardTitle> -
<div className="mt-4"> -
<span className="font-bold text-4xl">{tier.price}</span> -
<span className="ml-2 text-muted-foreground"> -
{tier.period} -
</span>
-
<div className="mb-8"> -
<span className="mb-4 block font-label text-[#ada3ff] text-xs uppercase tracking-widest"> -
{tier.tier} -
</span> -
<h3 className="mb-2 font-bold font-headline text-3xl"> -
{tier.name} -
</h3> -
<div className="flex items-baseline gap-1"> -
<span className="font-extrabold text-4xl">{tier.price}</span> -
{!("priceIsLabel" in tier && tier.priceIsLabel) && ( -
<span className="text-[#aaabab]">/mo</span> -
)} </div>
-
<p className="mt-2 text-muted-foreground text-sm"> -
{tier.description} -
</p> -
</CardHeader> -
<CardContent className="flex flex-1 flex-col"> -
<ul className="mb-8 flex-1 space-y-3"> -
{tier.features.map((feature) => ( -
<li key={feature} className="flex items-start gap-3"> -
<Check className="mt-0.5 h-5 w-5 shrink-0 text-purple-400" /> -
<span className="text-muted-foreground text-sm"> -
{feature} -
</span> -
</li> -
))} -
</ul> -
{tier.external ? ( -
<Button -
variant={tier.highlighted ? "sandbox" : "outline"} -
className="w-full" -
asChild
-
</div> -
<ul className="mb-10 flex-grow space-y-4"> -
{tier.features.map((feature) => ( -
<li -
key={feature.text} -
className={`flex items-center gap-3 ${!feature.included ? "opacity-40" : ""}`} >
-
<a href={tier.ctaHref}>{tier.cta}</a> -
</Button> -
) : ( -
<Button -
variant={tier.highlighted ? "sandbox" : "outline"} -
className="w-full" -
asChild -
> -
<Link to={tier.ctaHref}>{tier.cta}</Link> -
</Button> -
)} -
</CardContent> -
</Card>
-
<MaterialIcon -
name={feature.included ? "check_circle" : "block"} -
size="sm" -
fill={tier.highlighted && feature.included} -
className={feature.included ? "text-[#ada3ff]" : ""} -
/> -
<span -
className={`text-sm ${ -
tier.highlighted && feature.included -
? "font-semibold text-[#f4f3f3]" -
: feature.included -
? "text-[#aaabab]" -
: "text-[#aaabab] line-through" -
}`} -
> -
{feature.text} -
</span> -
</li> -
))} -
</ul> -
{"ctaExternal" in tier && tier.ctaExternal ? ( -
<a -
href={tier.ctaLink} -
className="block w-full rounded-full border border-[#ada3ff] py-4 text-center font-bold text-[#ada3ff] transition-all hover:bg-[#ada3ff]/5" -
> -
{tier.cta} -
</a> -
) : tier.highlighted ? ( -
<Link -
to={tier.ctaLink} -
className="block w-full rounded-full bg-gradient-to-br from-[#ada3ff] to-[#705bf5] py-4 text-center font-bold text-black shadow-[0_10px_30px_rgba(112,91,245,0.4)] transition-all hover:shadow-[0_15px_40px_rgba(112,91,245,0.6)] active:scale-[0.98]" -
> -
{tier.cta} -
</Link> -
) : ( -
<Link -
to={tier.ctaLink} -
className="block w-full rounded-full border border-[#474848] py-4 text-center font-bold transition-all hover:bg-white/5" -
> -
{tier.cta} -
</Link> -
)} -
</div> ))} </div>
-
{/* FAQ */} -
<div className="mt-20 text-center"> -
<h2 className="font-bold text-2xl">Frequently Asked Questions</h2> -
<div className="mx-auto mt-8 grid max-w-3xl gap-6 text-left"> -
<div className="rounded-lg border border-border p-6"> -
<h3 className="font-semibold">What counts as a compute hour?</h3> -
<p className="mt-2 text-muted-foreground text-sm"> -
A compute hour is counted for each hour your sandbox is in a -
running state. Stopped sandboxes do not consume compute hours. -
</p> -
</div> -
<div className="rounded-lg border border-border p-6"> -
<h3 className="font-semibold"> -
Can I upgrade or downgrade anytime? -
</h3> -
<p className="mt-2 text-muted-foreground text-sm"> -
Yes, you can change your plan at any time. When upgrading, you -
will be charged the prorated difference. When downgrading, the -
remaining credit will be applied to future bills. -
</p>
-
{/* Comparison Table */} -
<div className="mx-auto max-w-5xl"> -
<h2 className="mb-12 text-center font-bold font-headline text-3xl"> -
Feature Breakdown -
</h2> -
<div className="glass-panel overflow-hidden rounded-xl border border-[#474848]/10"> -
<table className="w-full border-collapse text-left"> -
<thead> -
<tr className="bg-[#1d2020]/50"> -
<th className="p-6 font-label text-[#aaabab] text-xs uppercase tracking-widest"> -
Feature -
</th> -
<th className="p-6 font-bold font-headline">Free</th> -
<th className="p-6 font-bold font-headline text-[#ada3ff]"> -
Pro -
</th> -
<th className="p-6 font-bold font-headline">Enterprise</th> -
</tr> -
</thead> -
<tbody className="divide-y divide-[#474848]/10"> -
{COMPARISON_ROWS.map((row, i) => ( -
<tr -
key={row.feature} -
className={i % 2 === 1 ? "bg-[#121414]/30" : ""} -
> -
<td className="p-6 text-sm">{row.feature}</td> -
<td className="p-6 text-[#aaabab] text-sm">{row.free}</td> -
<td className="p-6 font-bold text-[#f4f3f3] text-sm"> -
{row.pro} -
</td> -
<td className="p-6 text-[#aaabab] text-sm"> -
{row.enterprise} -
</td> -
</tr> -
))} -
</tbody> -
</table> -
</div> -
</div> -
{/* Build in the Future */} -
<section className="mt-40 grid items-center gap-16 md:grid-cols-2"> -
<div> -
<h2 className="mb-6 font-bold font-headline text-4xl"> -
Build in the <span className="gradient-text">Future</span> -
</h2> -
<p className="mb-8 text-[#aaabab] text-lg"> -
Our infra is built on next-gen hardware, ensuring your development -
cycle is limited by your imagination, not your hardware. -
</p> -
<div className="grid grid-cols-2 gap-4"> -
<div className="rounded-xl border border-[#474848]/10 bg-[#181a1a] p-6"> -
<div className="mb-1 font-bold font-headline text-2xl text-[#ada3ff]"> -
99.99% -
</div> -
<div className="font-label text-[#aaabab] text-xs uppercase"> -
Uptime SLA -
</div> -
</div> -
<div className="rounded-xl border border-[#474848]/10 bg-[#181a1a] p-6"> -
<div className="mb-1 font-bold font-headline text-2xl text-[#ada3ff]"> -
< 10ms -
</div> -
<div className="font-label text-[#aaabab] text-xs uppercase"> -
Global Latency -
</div> -
</div> </div>
-
<div className="rounded-lg border border-border p-6"> -
<h3 className="font-semibold"> -
What happens if I exceed my limits? -
</h3> -
<p className="mt-2 text-muted-foreground text-sm"> -
On the Free plan, sandboxes will be paused when you reach your -
monthly compute limit. Builder and Team plans allow overage at -
$0.05/hr and $0.04/hr respectively. -
</p>
-
</div> -
<div className="group relative"> -
<div className="absolute inset-0 rounded-full bg-[#ada3ff]/20 blur-3xl transition-all duration-700 group-hover:scale-110" /> -
<div className="glass-panel relative overflow-hidden rounded-xl border border-[#474848]/20 p-2"> -
<div className="flex h-80 items-center justify-center rounded-lg bg-[#121414]"> -
<div className="text-center"> -
<MaterialIcon -
name="developer_board" -
className="mx-auto mb-4 block text-6xl text-[#ada3ff]" -
/> -
<div className="font-bold font-headline text-2xl text-[#ada3ff]"> -
Next-Gen Infra -
</div> -
<div className="mt-2 font-label text-[#747676] text-xs uppercase"> -
Firecracker MicroVMs -
</div> -
</div> -
</div> </div> </div>
-
</div>
-
</section> </main> {/* Footer */}
-
<footer className="relative mt-16 border-border/50 border-t"> -
<div className="mx-auto max-w-6xl px-6 py-12"> -
<div className="flex flex-col items-center justify-between gap-4 md:flex-row"> -
<Logo variant="sandbox" size="sm" /> -
<div className="flex items-center gap-6 text-muted-foreground text-sm"> -
<a -
href="https://docs.tangle.network" -
target="_blank" -
rel="noopener noreferrer" -
className="transition-colors hover:text-foreground" -
> -
Docs -
</a> -
<Link -
to="/pricing" -
className="transition-colors hover:text-foreground" -
> -
Pricing -
</Link> -
<span -
title="Coming soon" -
className="cursor-default transition-colors hover:text-foreground" -
> -
Terms -
</span> -
<span -
title="Coming soon" -
className="cursor-default transition-colors hover:text-foreground" -
> -
Privacy -
</span> -
</div>
-
<footer className="w-full border-white/5 border-t bg-[#0d0e0f] px-8 py-12"> -
<div className="mx-auto flex max-w-7xl flex-col items-center justify-between gap-8 md:flex-row"> -
<div className="flex flex-col items-center gap-4 md:items-start"> -
<span className="flex items-center gap-2 font-bold text-lg text-white"> -
<img src="/tangle-logo-light.svg" alt="" className="h-6 w-6" /> -
Tangle Sandbox -
</span> -
<p className="text-center text-gray-500 text-sm md:text-left"> -
© {new Date().getFullYear()} Tangle Foundation. All rights -
reserved. -
</p> -
</div> -
<div className="flex flex-wrap justify-center gap-8"> -
<Link -
to="/pricing" -
className="text-gray-500 text-sm transition-colors hover:text-gray-300" -
> -
Pricing -
</Link> -
<a -
href="https://docs.tangle.tools" -
target="_blank" -
rel="noopener noreferrer" -
className="text-gray-500 text-sm transition-colors hover:text-gray-300" -
> -
Docs -
</a> -
<a -
href="https://tangle.tools" -
target="_blank" -
rel="noopener noreferrer" -
className="text-gray-500 text-sm transition-colors hover:text-gray-300" -
> -
Status -
</a> -
<a -
href="https://github.com/tangle-network" -
target="_blank" -
rel="noopener noreferrer" -
className="text-gray-500 text-sm transition-colors hover:text-gray-300" -
> -
GitHub -
</a> </div> </div> </footer>
mcp startup: no servers ERROR: You've hit your usage limit. Visit https://chatgpt.com/codex/settings/usage to purchase more credits or try again at Mar 25th, 2026 1:29 PM.