Adopt design comps: dark system, new landing/auth, dashboard shell + canvas

Re-skins the whole app to the dark design comps and wires the new surfaces to
the backend (the /api proxy + auth + schemas are unchanged).

Design system:
- globals.css: remapped @theme tokens to the comp palette (#08080a base, coral
  #ff6f61, status cyan/green/amber/purple/teal); token names preserved
- MeshMark: triangle + 3-node brand glyph; cm-flow/cm-blink/cm-halo keyframes
- marketing flipped light → dark

Backend (migration 0012):
- agents.model_binding (persisted on team deploy) + GET /api/claws/{id}/runtime-config
- routine_runs table + scheduler journaling + GET /api/routines/runs
- GET /api/claws/{id}/compartments (anatomy aggregate)
- GET /api/structure/stats (workspace counts)

Frontend:
- Landing: full dark marketing page (hero constellation, deploy ladder,
  12-topology taxonomy, recursive execution, compare/Pareto, safety, self-host)
- Auth: dark split-panel AuthShell + comp LoginForm + Clerk SignIn themed dark
- Dashboard shell: TopBar (breadcrumb + live stats + deploy + user) + StatusBar
  (runner/sandbox/doors); rail slimmed to 60px + 252px context column
- ConstellationCanvas (radial recursive) replaces the graph view in StructureCanvas;
  selecting a claw opens ComputerPanel (apps/now-running/dock); RoutinesPanel
- Claw anatomy view (/claws/[id]/anatomy) from compartments + runtime-config

Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
Omar Sobh
2026-06-19 04:12:16 -07:00
co-authored by Claude Opus 4.8
parent 3eca4ed70c
commit 540c74f42e
41 changed files with 2253 additions and 406 deletions
@@ -0,0 +1,554 @@
import Link from "next/link";
import { MeshMark } from "@/components/brand/MeshMark";
// ── Topology taxonomy (12 kinds × mini node-graphs), from the design comp. ──
const C = {
coral: "#ff6f61",
cyan: "#5ec8d8",
green: "#5fd08a",
amber: "#e8b465",
purple: "#c98af0",
teal: "#6fd0c0",
};
interface Topo {
name: string;
kind: string;
color: string;
pts: [number, number][];
edges: [number, number][];
big?: number;
dash?: boolean;
}
const TOPOLOGIES: Topo[] = [
{ name: "Hierarchical", kind: "tree command", color: C.coral, pts: [[50, 15], [28, 50], [72, 50], [16, 85], [40, 85], [84, 85]], edges: [[0, 1], [0, 2], [1, 3], [1, 4], [2, 5]] },
{ name: "Pipeline", kind: "sequential", color: C.amber, pts: [[12, 50], [37, 50], [63, 50], [88, 50]], edges: [[0, 1], [1, 2], [2, 3]] },
{ name: "Swarm", kind: "parallel", color: C.cyan, pts: [[26, 30], [60, 22], [82, 52], [54, 80], [22, 64], [48, 48]], edges: [[0, 1], [1, 2], [3, 4], [5, 0], [5, 2], [5, 3]] },
{ name: "Mesh", kind: "all-to-all", color: C.green, pts: [[50, 14], [86, 42], [70, 84], [30, 84], [14, 42]], edges: [[0, 1], [0, 2], [0, 3], [0, 4], [1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4]] },
{ name: "Debate", kind: "adversarial", color: C.purple, pts: [[50, 12], [26, 46], [26, 82], [74, 46], [74, 82]], edges: [[1, 3], [1, 4], [2, 3], [2, 4], [0, 1], [0, 3]] },
{ name: "Hub-spoke", kind: "one coordinator", color: C.coral, pts: [[50, 50], [50, 16], [82, 38], [70, 82], [30, 82], [18, 38]], edges: [[0, 1], [0, 2], [0, 3], [0, 4], [0, 5]], big: 0 },
{ name: "Star-MoE", kind: "router + experts", color: C.teal, pts: [[50, 50], [24, 24], [76, 24], [24, 76], [76, 76]], edges: [[0, 1], [0, 2], [0, 3], [0, 4]], big: 0 },
{ name: "Market", kind: "bid / auction", color: C.amber, pts: [[50, 50], [20, 30], [80, 30], [20, 72], [80, 72]], edges: [[0, 1], [0, 2], [0, 3], [0, 4]], big: 0, dash: true },
{ name: "Ring", kind: "cyclic hand-off", color: C.cyan, pts: [[50, 14], [81, 32], [81, 68], [50, 86], [19, 68], [19, 32]], edges: [[0, 1], [1, 2], [2, 3], [3, 4], [4, 5], [5, 0]] },
{ name: "Flat", kind: "peers", color: C.purple, pts: [[30, 32], [70, 32], [30, 68], [70, 68]], edges: [] },
{ name: "Holacratic", kind: "nested circles", color: C.teal, pts: [[50, 50], [50, 22], [74, 64], [26, 64]], edges: [[0, 1], [0, 2], [0, 3]], big: 0 },
{ name: "Blackboard", kind: "shared memory", color: C.cyan, pts: [[50, 50], [24, 26], [76, 26], [24, 74], [76, 74]], edges: [[0, 1], [0, 2], [0, 3], [0, 4]], big: 0 },
];
const mono = "font-mono tracking-[0.14em]";
const coralBtn =
"inline-flex items-center gap-2 rounded-[10px] bg-gradient-to-br from-coral-light to-coral-dark font-bold text-[#2a0d0a] transition-[filter] hover:brightness-110";
const ghostBtn =
"inline-flex items-center gap-2 rounded-[10px] border border-white/[0.14] font-semibold text-[#e6e6ea] transition-colors hover:bg-white/[0.04]";
function TopoCard({ t }: { t: Topo }) {
return (
<div className="rounded-[13px] border border-white/[0.07] bg-[#0d0d10] p-4 transition-colors hover:border-white/20">
<div className="mb-3 flex h-[88px] items-center justify-center">
<svg viewBox="0 0 100 100" className="h-[88px] w-[100px]">
{t.edges.map(([a, b], i) => (
<line
key={i}
x1={t.pts[a][0]}
y1={t.pts[a][1]}
x2={t.pts[b][0]}
y2={t.pts[b][1]}
stroke={t.color}
strokeWidth={1.3}
strokeOpacity={0.4}
strokeDasharray={t.dash ? "3 3" : undefined}
/>
))}
{t.pts.map(([x, y], i) => (
<circle key={i} cx={x} cy={y} r={t.big === i ? 7 : 5} fill={t.color} />
))}
</svg>
</div>
<div className="mb-0.5 text-[15px] font-bold">{t.name}</div>
<div className={`${mono} text-[10px] text-[#6a6a72]`}>{t.kind}</div>
</div>
);
}
// One labelled avatar node for the constellation panels.
function Node({
letter,
from,
to,
ink,
size = 38,
left,
top,
label,
labelColor,
ring,
halo,
dim,
}: {
letter: string;
from: string;
to: string;
ink: string;
size?: number;
left: string;
top: string;
label?: string;
labelColor?: string;
ring?: boolean;
halo?: string;
dim?: boolean;
}) {
return (
<div
className="absolute flex -translate-x-1/2 -translate-y-1/2 flex-col items-center gap-1.5"
style={{ left, top, opacity: dim ? 0.7 : 1 }}
>
<div className="relative" style={{ width: size, height: size }}>
{halo ? (
<span
className="cm-halo absolute inset-0 rounded-full"
style={{ background: halo }}
/>
) : null}
{ring ? (
<span className="absolute -inset-[5px] rounded-full border-2 border-coral" />
) : null}
<div
className="relative flex items-center justify-center rounded-full font-bold"
style={{
width: size,
height: size,
background: `linear-gradient(135deg, ${from}, ${to})`,
color: ink,
fontSize: size > 50 ? 21 : 13,
}}
>
{letter}
</div>
</div>
{label ? (
<span
className={label.length > 4 ? `${mono} text-[9px]` : "text-[11px] font-semibold"}
style={{ color: labelColor }}
>
{label}
</span>
) : null}
</div>
);
}
export function Landing() {
return (
<div className="bg-background text-foreground">
{/* NAV */}
<header className="sticky top-0 z-50 flex items-center gap-3.5 border-b border-white/[0.06] bg-[#08080acc] px-8 py-4 backdrop-blur-md">
<Link href="/" className="flex items-center gap-2.5 text-coral">
<MeshMark size={24} title="" />
<span className="text-[17px] font-bold tracking-[-0.01em] text-foreground">
Clawmates
</span>
</Link>
<div className="flex-1" />
<nav className="hidden items-center gap-7 text-sm text-[#b5b5bd] md:flex">
<span className="cursor-pointer hover:text-foreground">Platform</span>
<span className="cursor-pointer hover:text-foreground">Topologies</span>
<span className="cursor-pointer hover:text-foreground">Safety</span>
<span className="cursor-pointer hover:text-foreground">Docs</span>
</nav>
<span className="mx-5 hidden h-[22px] w-px bg-white/10 md:block" />
<Link href="/login" className="text-sm text-[#b5b5bd] hover:text-foreground">
Sign in
</Link>
<Link href="/login" className={`${coralBtn} px-4 py-[9px] text-sm`}>
Get started
</Link>
</header>
{/* HERO */}
<section className="relative mx-auto grid max-w-[1240px] grid-cols-1 items-center gap-12 px-8 pb-20 pt-[88px] lg:grid-cols-[1.05fr_0.95fr]">
<div
className="pointer-events-none absolute left-[30%] top-[-40px] h-[420px] w-[520px]"
style={{ background: "radial-gradient(circle, rgba(255,111,97,.13), transparent 68%)" }}
/>
<div className="relative">
<div
className={`${mono} mb-6 inline-flex items-center gap-2 rounded-[7px] border px-[11px] py-1.5 text-[11px] text-coral-light`}
style={{ borderColor: "rgba(255,111,97,.25)", background: "rgba(255,111,97,.06)" }}
>
<span className="cm-blink size-1.5 rounded-full bg-coral" />
MULTI-AGENT PLATFORM
</div>
<h1 className="mb-[22px] text-5xl font-bold leading-[1.02] tracking-[-0.035em] text-balance lg:text-[62px]">
Deploy agents at any scale.
</h1>
<p className="mb-8 max-w-[480px] text-[18px] leading-relaxed text-[#a8a8b0]">
Every unit of work is a{" "}
<span className="font-semibold text-foreground">topology</span> a graph of role-slots
bound to real AI agents. Compose and run agentic systems from a single claw up to a
whole org, on a durable, crash-resumable runner.
</p>
<div className="mb-[30px] flex flex-wrap gap-3">
<Link href="/login" className={`${coralBtn} px-[22px] py-[13px] text-[15px]`}>
Start deploying
</Link>
<span className={`${ghostBtn} px-[22px] py-[13px] text-[15px]`}>Read the paper</span>
</div>
<div className={`${mono} flex flex-wrap gap-x-[18px] gap-y-2 text-[11px] text-[#6a6a72]`}>
<span className="text-running">12 topologies</span>
<span>·</span>
<span>durable runner</span>
<span>·</span>
<span className="text-online">§15-safe</span>
<span>·</span>
<span>self-hostable</span>
</div>
</div>
{/* hero constellation */}
<div
className="relative h-[420px] overflow-hidden rounded-2xl border border-white/[0.07]"
style={{
background: "radial-gradient(120% 100% at 60% 30%, #0f0f14, #0a0a0c)",
boxShadow: "0 30px 80px rgba(0,0,0,.4)",
}}
>
<div className={`${mono} absolute left-4 top-3.5 text-[10px] tracking-[0.1em] text-[#5a5a62]`}>
GROWTH TEAM · hub-spoke · running
</div>
<svg viewBox="0 0 100 100" preserveAspectRatio="none" className="absolute inset-0 size-full">
<path d="M50,52 C40,38 34,32 24,26" fill="none" stroke="rgba(94,200,216,.5)" strokeWidth={1.4} strokeDasharray="3 4" vectorEffect="non-scaling-stroke" className="cm-flow" />
<path d="M50,52 C40,64 34,70 26,76" fill="none" stroke="rgba(94,200,216,.5)" strokeWidth={1.4} strokeDasharray="3 4" vectorEffect="non-scaling-stroke" className="cm-flow" />
<path d="M50,52 C52,38 53,28 54,18" fill="none" stroke="rgba(255,255,255,.12)" strokeWidth={1.3} vectorEffect="non-scaling-stroke" />
<path d="M50,52 C64,46 72,40 80,32" fill="none" stroke="rgba(255,255,255,.12)" strokeWidth={1.3} vectorEffect="non-scaling-stroke" />
<path d="M50,52 C64,58 72,66 80,74" fill="none" stroke="rgba(255,111,97,.6)" strokeWidth={1.6} strokeDasharray="3 4" vectorEffect="non-scaling-stroke" className="cm-flow" />
</svg>
<Node letter="A" from="#ff9a6a" to="#ff6f4a" ink="#2a0d05" size={58} left="50%" top="52%" label="Atlas" />
<Node letter="I" from="#6fd0c0" to="#4aa3b8" ink="#06201f" size={40} left="24%" top="26%" label="research…" labelColor="#5ec8d8" halo="rgba(94,200,216,.4)" />
<Node letter="N" from="#e8c46a" to="#d89a3a" ink="#2a1d05" left="54%" top="18%" />
<Node letter="S" from="#c98af0" to="#9a5ad8" ink="#1a0a2a" left="80%" top="32%" dim />
<Node letter="E" from="#8a9af0" to="#5a6ad8" ink="#0a0e2a" left="26%" top="76%" />
<Node letter="M" from="#ff8a7a" to="#ff5f57" ink="#2a0d0a" size={44} left="80%" top="74%" label="Morpheus" labelColor="#ff8a7a" ring />
</div>
</section>
{/* DEPLOY LADDER */}
<section className="mx-auto max-w-[1240px] px-8 py-16">
<div className="mb-12 text-center">
<div className={`${mono} mb-3.5 text-[11px] tracking-[0.16em] text-running`}>
THE DEPLOY LADDER
</div>
<h2 className="mb-3.5 text-[40px] font-bold tracking-[-0.03em]">One model, four scales.</h2>
<p className="mx-auto max-w-[580px] text-[17px] leading-relaxed text-[#a8a8b0]">
Each rung composes the one below a company is staffed with teams, an org with companies.
Pick a scale; we instantiate the topology and bind it to real, chattable claws.
</p>
</div>
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4">
{[
{ n: "01 · SINGLE", t: "A claw", d: "One agent in a §15 sandbox. Chat with it, give it skills, point it at a task." },
{ n: "02 · TEAM", t: "A team", d: "A topology of claws — lead, researchers, writer, critic — running one of 12 patterns." },
{ n: "03 · COMPANY", t: "A company", d: "Teams composed into a coordinating topology. Run the parent, run every child." },
{ n: "04 · ORG", t: "A whole org", d: "Companies under one roof. Recursive execution all the way down to the leaf claws.", hot: true },
].map((c) => (
<div
key={c.n}
className={`rounded-[14px] border p-[22px] transition-colors ${
c.hot
? "border-coral/30 bg-gradient-to-b from-[#150f12] to-[#0d0d10]"
: "border-white/[0.08] bg-[#0d0d10] hover:border-coral/35"
}`}
>
<div className={`${mono} mb-[18px] text-[10px] ${c.hot ? "text-coral-light" : "text-[#5a5a62]"}`}>
{c.n}
</div>
<div className="mb-2 text-coral">
<MeshMark size={32} variant={c.t === "A claw" ? "team" : c.t === "A team" ? "team" : c.t === "A company" ? "company" : "org"} title="" />
</div>
<div className="mb-1.5 text-[18px] font-bold">{c.t}</div>
<div className="text-[13px] leading-relaxed text-[#8a8a92]">{c.d}</div>
</div>
))}
</div>
</section>
{/* TOPOLOGIES */}
<section className="border-t border-white/[0.06] bg-gradient-to-b from-[#0a0a0c] to-[#08080a]">
<div className="mx-auto max-w-[1240px] px-8 py-[72px]">
<div className="mb-10">
<div className={`${mono} mb-3.5 text-[11px] tracking-[0.16em] text-running`}>
THE TAXONOMY
</div>
<h2 className="mb-3 max-w-[620px] text-[40px] font-bold leading-tight tracking-[-0.03em] text-balance">
Twelve topologies. Five execution patterns.
</h2>
<p className="max-w-[520px] text-[17px] leading-relaxed text-[#a8a8b0]">
Classify a task, build the structure that fits it, and switch patterns without rewriting
a thing authority stays invariant across every one.
</p>
</div>
<div className="grid grid-cols-2 gap-3.5 sm:grid-cols-3 lg:grid-cols-4">
{TOPOLOGIES.map((t) => (
<TopoCard key={t.name} t={t} />
))}
</div>
</div>
</section>
{/* RECURSIVE EXECUTION */}
<section className="mx-auto max-w-[1240px] px-8 py-[72px]">
<div className="grid grid-cols-1 items-center gap-12 lg:grid-cols-2">
<div>
<div className={`${mono} mb-3.5 text-[11px] tracking-[0.16em] text-running`}>
RECURSIVE EXECUTION
</div>
<h2 className="mb-4 text-[38px] font-bold tracking-[-0.03em] text-balance">
Run the parent, run everything beneath it.
</h2>
<p className="mb-[26px] text-[17px] leading-relaxed text-[#a8a8b0]">
Executing a node runs its entire sub-topology, all the way down to the leaf claws on a
durable runner that checkpoints every step.
</p>
<div className="flex flex-col gap-3.5">
{[
{ c: "#5fd08a", t: "Crash-resumable", d: "Checkpointed per step. A crash resumes where it left off — not from zero." },
{ c: "#5ec8d8", t: "Live + cancellable", d: "Stream every turn over SSE; cancel a run mid-flight at any tier." },
{ c: "#ff6f61", t: "Recursive zoom canvas", d: "One view for every tier — click a node to drill down, breadcrumb to climb back up." },
].map((f) => (
<div key={f.t} className="flex items-start gap-3">
<span className="mt-1.5 size-2 flex-none rounded-[2px]" style={{ background: f.c }} />
<div>
<div className="text-[15px] font-semibold">{f.t}</div>
<div className="text-[13px] leading-relaxed text-[#8a8a92]">{f.d}</div>
</div>
</div>
))}
</div>
</div>
<div
className="relative h-[340px] overflow-hidden rounded-2xl border border-white/[0.07] bg-[#0c0c0f]"
style={{ boxShadow: "0 24px 60px rgba(0,0,0,.4)" }}
>
<div className={`${mono} flex items-center gap-1.5 border-b border-white/[0.06] px-4 py-3.5 text-[11px]`}>
<span className="text-[#6a6a72]">Org</span>
<span className="text-[#3a3a40]">/</span>
<span className="text-[#9a9aa2]">Acme Corp</span>
<span className="text-[#3a3a40]">/</span>
<span className="text-coral-light">Growth Team</span>
</div>
<div className="absolute inset-x-0 bottom-0 top-12">
<svg viewBox="0 0 100 100" preserveAspectRatio="none" className="absolute inset-0 size-full">
<path d="M50,46 L24,26 M50,46 L76,26 M50,46 L28,74 M50,46 L74,74" stroke="rgba(255,255,255,.12)" strokeWidth={1.2} vectorEffect="non-scaling-stroke" />
<path d="M50,46 L24,26" stroke="rgba(94,200,216,.55)" strokeWidth={1.5} strokeDasharray="3 4" vectorEffect="non-scaling-stroke" className="cm-flow" />
</svg>
<Node letter="A" from="#ff9a6a" to="#ff6f4a" ink="#2a0d05" size={46} left="50%" top="46%" />
<Node letter="I" from="#6fd0c0" to="#4aa3b8" ink="#06201f" size={30} left="24%" top="26%" />
<Node letter="N" from="#e8c46a" to="#d89a3a" ink="#2a1d05" size={30} left="76%" top="26%" />
<Node letter="E" from="#8a9af0" to="#5a6ad8" ink="#0a0e2a" size={30} left="28%" top="74%" />
<Node letter="S" from="#c98af0" to="#9a5ad8" ink="#1a0a2a" size={30} left="74%" top="74%" />
</div>
<div className={`${mono} absolute bottom-3 left-4 text-[10px] text-online`}>
step 142 · checkpoint 3s ago
</div>
</div>
</div>
</section>
{/* COMPARE + MODELS */}
<section className="mx-auto max-w-[1240px] px-8 pb-[72px]">
<div className="grid grid-cols-1 gap-4 lg:grid-cols-[1.2fr_1fr]">
<div className="flex items-center gap-7 rounded-2xl border border-white/[0.08] bg-[#0d0d10] p-7">
<div className="flex-1">
<div className={`${mono} mb-3 text-[11px] text-amber`}>COMPARE &amp; EVOLVE</div>
<h3 className="mb-2.5 text-2xl font-bold tracking-[-0.02em]">
Run one task across many topologies.
</h3>
<p className="text-sm leading-relaxed text-[#9a9aa2]">
Get a quality/cost Pareto front, then let a MAP-Elites search evolve better team
configurations using the comparison harness as fitness.
</p>
</div>
<svg width="180" height="150" viewBox="0 0 180 150" className="flex-none">
<line x1="24" y1="126" x2="168" y2="126" stroke="rgba(255,255,255,.12)" />
<line x1="24" y1="14" x2="24" y2="126" stroke="rgba(255,255,255,.12)" />
<path d="M34,104 C70,96 108,52 156,30" fill="none" stroke="rgba(255,111,97,.5)" strokeWidth={1.4} strokeDasharray="3 3" />
{[[34, 104], [68, 88], [104, 58], [156, 30]].map(([x, y], i) => (
<circle key={i} cx={x} cy={y} r={4} fill="#ff6f61" />
))}
{[[58, 112], [92, 96], [120, 92], [138, 64]].map(([x, y], i) => (
<circle key={i} cx={x} cy={y} r={3} fill="#4a4a52" />
))}
<text x="92" y="144" fill="#5a5a62" fontSize="9" textAnchor="middle" className="font-mono">cost </text>
</svg>
</div>
<div className="rounded-2xl border border-white/[0.08] bg-[#0d0d10] p-7">
<div className={`${mono} mb-3 text-[11px] text-running`}>HETEROGENEOUS</div>
<h3 className="mb-4 text-2xl font-bold tracking-[-0.02em]">Bind any node to any model.</h3>
<div className="flex flex-wrap gap-2">
{["Claude", "Gemini", "Groq", "GLM", "Kimi"].map((m, i) => (
<span
key={m}
className={`${mono} rounded-lg px-3 py-[7px] text-xs ${
i === 0 ? "text-[#e6e6ea]" : "text-[#cfcfd5]"
}`}
style={
i === 0
? { border: "1px solid rgba(255,111,97,.3)", background: "rgba(255,111,97,.07)" }
: { border: "1px solid rgba(255,255,255,.1)", background: "rgba(255,255,255,.03)" }
}
>
{m}
</span>
))}
</div>
<p className="mt-[18px] text-sm leading-relaxed text-[#9a9aa2]">
Mix backends across a single topology a cheap model for fan-out, a strong one for the
judge.
</p>
</div>
</div>
</section>
{/* SAFETY */}
<section className="border-t border-white/[0.06] bg-gradient-to-b from-[#0a0a0c] to-[#08080a]">
<div className="mx-auto max-w-[1240px] px-8 py-[72px]">
<div className="grid grid-cols-1 items-center gap-12 lg:grid-cols-[1fr_1.1fr]">
<div>
<div className={`${mono} mb-3.5 text-[11px] tracking-[0.16em] text-online`}>
§15 · SAFE BY CONSTRUCTION
</div>
<h2 className="mb-4 text-[38px] font-bold tracking-[-0.03em] text-balance">
Authority is topology-invariant.
</h2>
<p className="mb-[22px] text-[17px] leading-relaxed text-[#a8a8b0]">
No choice of structure and no switch between structures can let an agent exceed its
sandbox. The network segmentation{" "}
<span className="font-semibold text-foreground">is</span> the security model.
</p>
<div className="flex flex-col gap-3 text-sm text-[#b5b5bd]">
{[
"Agents run tool-free in network-isolated sandboxes",
'Every sandbox-leaving action is a gated, human-approvable "door"',
"A secret broker holds credentials that never reach agent code",
].map((s) => (
<div key={s} className="flex items-center gap-2.5">
<span className="text-online"></span> {s}
</div>
))}
</div>
</div>
<div
className="rounded-2xl border border-white/[0.08] bg-[#0c0c0f] p-6"
style={{ boxShadow: "0 24px 60px rgba(0,0,0,.4)" }}
>
<div className="flex flex-col gap-2.5">
<div className="flex items-center gap-3 rounded-[11px] border border-dashed border-white/[0.14] bg-[#0f0f13] px-4 py-3.5">
<span className="flex size-[34px] items-center justify-center rounded-[9px]" style={{ background: "rgba(255,111,97,.14)" }}>
<svg width="18" height="18" viewBox="0 0 20 20"><rect x="4" y="4" width="12" height="12" rx="3" stroke="#ff6f61" strokeWidth="1.5" fill="none" /><circle cx="10" cy="10" r="2" fill="#ff6f61" /></svg>
</span>
<div className="flex-1">
<div className="text-[13px] font-semibold">Agent sandbox</div>
<div className={`${mono} text-[10px] text-[#6a6a72]`}>tool-free · no network</div>
</div>
<span className={`${mono} rounded-[5px] px-2 py-[3px] text-[9px] text-coral-light`} style={{ background: "rgba(255,111,97,.1)" }}>isolated</span>
</div>
<div className={`${mono} flex justify-center text-[11px] text-[#3a3a40]`}> gated door · human approval</div>
<div className="flex items-center gap-3 rounded-[11px] border bg-[#0f0f13] px-4 py-3.5" style={{ borderColor: "rgba(94,200,216,.22)" }}>
<span className="flex size-[34px] items-center justify-center rounded-[9px]" style={{ background: "rgba(94,200,216,.14)" }}>
<svg width="18" height="18" viewBox="0 0 20 20"><path d="M10 2v6m0 0l3-3m-3 3L7 5M3 12v4a2 2 0 002 2h10a2 2 0 002-2v-4" stroke="#5ec8d8" strokeWidth="1.5" fill="none" strokeLinecap="round" /></svg>
</span>
<div className="flex-1">
<div className="text-[13px] font-semibold">Door tool egress</div>
<div className={`${mono} text-[10px] text-[#6a6a72]`}>email · slack · browser</div>
</div>
<span className={`${mono} rounded-[5px] px-2 py-[3px] text-[9px] text-online`} style={{ background: "rgba(95,208,138,.1)" }}>approved</span>
</div>
<div className="flex items-center gap-3 rounded-[11px] border border-white/[0.08] bg-[#0f0f13] px-4 py-3.5">
<span className="flex size-[34px] items-center justify-center rounded-[9px]" style={{ background: "rgba(232,196,106,.14)" }}>
<svg width="18" height="18" viewBox="0 0 20 20"><rect x="4" y="9" width="12" height="8" rx="2" stroke="#e8b465" strokeWidth="1.5" fill="none" /><path d="M7 9V6.5a3 3 0 016 0V9" stroke="#e8b465" strokeWidth="1.5" fill="none" /></svg>
</span>
<div className="flex-1">
<div className="text-[13px] font-semibold">Secret broker</div>
<div className={`${mono} text-[10px] text-[#6a6a72]`}>private socket · creds never leave</div>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
{/* SELF-HOST */}
<section className="mx-auto max-w-[1240px] px-8 py-[72px]">
<div className="grid grid-cols-1 items-center gap-10 rounded-2xl border border-white/[0.08] bg-gradient-to-b from-[#0e0e12] to-[#0a0a0c] p-10 lg:grid-cols-2">
<div>
<div className={`${mono} mb-3.5 text-[11px] tracking-[0.16em] text-purple`}>
SELF-HOSTABLE
</div>
<h2 className="mb-3.5 text-[32px] font-bold tracking-[-0.03em]">
The whole platform, one node.
</h2>
<p className="text-base leading-relaxed text-[#a8a8b0]">
A single-node Docker Compose deployment runs everything with the same network-segmented
security model as the Kubernetes path. The server self-migrates on boot.
</p>
</div>
<div className={`${mono} rounded-xl border border-white/[0.08] bg-[#070708] p-5 text-[13px] leading-[1.9]`}>
<div className="text-[#5a5a62]"># bring up the stack</div>
<div><span className="text-online">$</span> <span className="text-[#cfcfd5]">cd deploy/compose</span></div>
<div><span className="text-online">$</span> <span className="text-[#cfcfd5]">docker compose up -d</span></div>
<div className="mt-2 text-[#5a5a62]"># app localhost:3000</div>
<div className="text-running"> server self-migrated · owner provisioned</div>
</div>
</div>
</section>
{/* CTA */}
<section className="mx-auto max-w-[1240px] px-8 pb-24 pt-10">
<div
className="relative overflow-hidden rounded-[20px] border px-8 py-[72px] text-center"
style={{
borderColor: "rgba(255,111,97,.25)",
background: "radial-gradient(120% 140% at 50% 0%, rgba(255,111,97,.12), #0c0c0f 60%)",
}}
>
<h2 className="mb-4 text-[46px] font-bold tracking-[-0.035em] text-balance">
Deploy your first claw.
</h2>
<p className="mb-[30px] text-[18px] text-[#a8a8b0]">
From one agent to a whole org same model, same guarantees.
</p>
<div className="flex flex-wrap justify-center gap-3">
<Link href="/login" className={`${coralBtn} px-[26px] py-3.5 text-base`}>
Get started free
</Link>
<span className={`${ghostBtn} px-[26px] py-3.5 text-base`}>clawmates.work</span>
</div>
</div>
</section>
{/* FOOTER */}
<footer className="border-t border-white/[0.06] bg-[#0a0a0c]">
<div className="mx-auto flex max-w-[1240px] flex-wrap items-center gap-4 px-8 py-10">
<div className="flex items-center gap-2.5 text-coral">
<MeshMark size={20} title="" />
<span className="text-sm font-bold text-foreground">Clawmates</span>
</div>
<div className="flex-1" />
<div className="flex gap-6 text-[13px] text-[#8a8a92]">
<span className="cursor-pointer hover:text-foreground">Platform</span>
<span className="cursor-pointer hover:text-foreground">Topologies</span>
<span className="cursor-pointer hover:text-foreground">Safety</span>
<span className="cursor-pointer hover:text-foreground">Docs</span>
<span className="cursor-pointer hover:text-foreground">Paper</span>
</div>
<div className={`${mono} mt-6 w-full border-t border-white/[0.05] pt-5 text-[11px] text-[#5a5a62]`}>
© 2026 Clawmates · authority is topology-invariant
</div>
</div>
</footer>
</div>
);
}