feat(marketing): redesign landing as "trusted infrastructure"
ci / gates (push) Has been cancelled
ci / rust (push) Has been cancelled
ci / sandbox-k8s (push) Has been cancelled
ci / frontend (push) Has been cancelled
ci / e2e (push) Has been cancelled

Re-skins the playful/consumer feel into disciplined agent-infrastructure,
keeping the animated hero canvas (re-themed) and adding the hierarchy story.

- Palette: re-point coral→ember (#E0584A); add ink/surface/mist/slate-light/
  azure/teal tokens. One accent per viewport; retire the black/coral split-
  headline pattern across all 8 headings (single ink color).
- Typography: hero/section weights 800→~650-675, tighter tracking, smaller
  hero size; uppercase eyebrow label.
- Hero: dark ink base with glowing azure/indigo + faint ember canvas blooms;
  light copy; new positioning ("Build safe, scalable agentic systems" + the
  single-agent-to-company subhead); ember primary CTA + ghost "Read the docs".
- Imagery overhaul (code-built, no mascots): AgentToken chips (CrewStrip,
  OneClick card, footer), AlwaysOn rebuilt as a terminal/log with an approval
  line, SkillsShowcase as duotone lucide cards on Mist, Security as a shield/
  lock motif.
- New HierarchyDiagram section ("One agent, or a whole org chart"): SVG org
  chart with an azure active path and teal human-approval checkpoints on
  sandbox-leaving actions.
- Tests: dark-hero/terminal/eyebrow contrast fixed to AA; refreshed the
  marketing @visual baseline (hero masked).

Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
Omar Sobh
2026-06-15 15:56:58 -07:00
co-authored by Claude Opus 4.8
parent 4b55c4d81e
commit 44512a744f
8 changed files with 436 additions and 150 deletions
@@ -1,6 +1,7 @@
import type { Metadata } from "next"; import type { Metadata } from "next";
import { Faq } from "@/components/marketing/Faq"; import { Faq } from "@/components/marketing/Faq";
import { HierarchyDiagram } from "@/components/marketing/HierarchyDiagram";
import { MarketingNav } from "@/components/marketing/Nav"; import { MarketingNav } from "@/components/marketing/Nav";
import { import {
AlwaysOn, AlwaysOn,
@@ -34,6 +35,7 @@ export default function MarketingPage() {
<Works /> <Works />
<AlwaysOn /> <AlwaysOn />
<SkillsShowcase /> <SkillsShowcase />
<HierarchyDiagram />
<Security /> <Security />
<Faq /> <Faq />
</main> </main>
+10 -5
View File
@@ -184,15 +184,20 @@
--shadow-dock-capsule: inset 0 1px 0 #ffffff0f, 0 10px 30px -6px #00000059; --shadow-dock-capsule: inset 0 1px 0 #ffffff0f, 0 10px 30px -6px #00000059;
--nav-logo-shadow: inset 0 0 0 1px #ffffff26; --nav-logo-shadow: inset 0 0 0 1px #ffffff26;
/* ---- Marketing (light) palette ---- */ /* ---- Marketing palette (trusted-infrastructure theme) ---- */
--color-marketing-ink: #161d27; --color-marketing-ink: #0b1220; /* headings on light; hero/dark base */
--color-marketing-coral: #e95656; --color-marketing-surface: #161d27; /* dark cards / footer / dark sections */
--color-marketing-slate: #475569; --color-marketing-mist: #f5f8fc; /* light section backgrounds */
--color-marketing-coral: #e0584a; /* ember — primary accent / CTA fill */
--color-marketing-coral-strong: #c7463a; /* AA-safe ember accent on light */
--color-marketing-slate: #475569; /* body/secondary text on light */
--color-marketing-slate-light: #94a3b8; /* secondary text on dark */
--color-marketing-slate-dark: #1e293b; --color-marketing-slate-dark: #1e293b;
--color-marketing-border: #e2e8f0; --color-marketing-border: #e2e8f0;
--color-marketing-periwinkle: #e7eafc; --color-marketing-periwinkle: #e7eafc;
--color-marketing-blue: #3286d8; /* FAQ field (AA-safe for white text) */ --color-marketing-blue: #3286d8; /* FAQ field (AA-safe for white text) */
--color-marketing-coral-strong: #d23a3a; /* AA-safe coral: button fills + small text on light */ --color-marketing-azure: #3b82f6; /* links, diagram nodes, interactive */
--color-marketing-teal: #14b8a6; /* "secure / approved" status only */
} }
body { body {
@@ -0,0 +1,51 @@
/** Abstract agent token — a slate squircle with a monogram and a small glowing
* node glyph. Replaces the mascot avatars so the roster reads as infrastructure
* (nodes in a system), not characters. One consistent visual system for every
* named agent ("Marketing Claw", "Support Claw", …). */
export function AgentToken({
name,
size = 48,
accent = "#3b82f6", // azure
}: {
name: string;
size?: number;
accent?: string;
}) {
const initials =
name
.split(/\s+/)
.filter(Boolean)
.slice(0, 2)
.map((w) => w[0]!.toUpperCase())
.join("") || "C";
const dot = Math.max(5, Math.round(size * 0.14));
return (
<span
aria-hidden
className="relative inline-flex shrink-0 items-center justify-center font-semibold text-white"
style={{
width: size,
height: size,
borderRadius: Math.round(size * 0.28),
background: "linear-gradient(160deg, #1e293b, #0f172a)",
boxShadow: "inset 0 0 0 1px rgba(148,163,184,0.18)",
fontSize: Math.round(size * 0.34),
letterSpacing: "-0.02em",
}}
>
{initials}
<span
className="absolute"
style={{
right: Math.round(size * 0.12),
top: Math.round(size * 0.12),
width: dot,
height: dot,
borderRadius: 9999,
background: accent,
boxShadow: `0 0 ${dot}px ${accent}`,
}}
/>
</span>
);
}
@@ -6,8 +6,8 @@ import { useEffect, useRef } from "react";
* (js/shift.js): a few dozen large circles drift at random, their hue driven by * (js/shift.js): a few dozen large circles drift at random, their hue driven by
* 3D simplex noise at their position + time; everything is drawn to an offscreen * 3D simplex noise at their position + time; everything is drawn to an offscreen
* buffer, then blurred and composited onto the visible canvas over a flat base. * buffer, then blurred and composited onto the visible canvas over a flat base.
* Re-tuned to a light, brand palette (pale periwinkle base; soft blue→violet→coral * Re-themed to a dark, infrastructure palette (deep-ink base; glowing azure/indigo
* blooms) so the dark hero copy stays readable. Scoped to its container, not the * blooms with a faint ember). Light hero copy sits on top. Scoped to its container, not the
* window. Respects prefers-reduced-motion and pauses when scrolled out of view. */ * window. Respects prefers-reduced-motion and pauses when scrolled out of view. */
// --- tunables (all easy to tweak) --------------------------------------- // --- tunables (all easy to tweak) ---------------------------------------
@@ -16,16 +16,19 @@ const BASE_SPEED = 0.06;
const RANGE_SPEED = 0.7; const RANGE_SPEED = 0.7;
const BASE_TTL = 180; const BASE_TTL = 180;
const RANGE_TTL = 260; const RANGE_TTL = 260;
const BASE_RADIUS = 120; const BASE_RADIUS = 140;
const RANGE_RADIUS = 240; const RANGE_RADIUS = 260;
const NOISE_OFF = 0.0015; // x/y/z noise sampling step const NOISE_OFF = 0.0015; // x/y/z noise sampling step
const BLUR_PX = 50; const BLUR_PX = 55;
const BASE_COLOR = "#edf3fc"; // pale periwinkle base (matches the hero fill) const BASE_COLOR = "#0b1220"; // deep ink — blooms read as glowing light sources
const HUE_MIN = 205; // blue const ALPHA = 1; // global multiplier on each blob's peak alpha
const HUE_MAX = 360; // → indigo / violet / magenta / coral // Cool glow palette on dark [r, g, b, peakAlpha]. Azure + indigo dominate; a
const SAT = 70; // faint ember adds warmth (re-themed from the original hue-band approach).
const LIGHT = 74; const PALETTE: [number, number, number, number][] = [
const ALPHA = 0.5; // peak blob opacity (scaled by fade-in/out) [59, 130, 246, 0.22], // azure #3B82F6
[79, 70, 229, 0.18], // indigo #4F46E5
[224, 88, 74, 0.12], // ember #E0584A (faint, rare)
];
const TAU = Math.PI * 2; const TAU = Math.PI * 2;
const rand = (n: number) => n * Math.random(); const rand = (n: number) => n * Math.random();
@@ -152,17 +155,18 @@ export function HeroAmbient() {
const simplex = new SimplexNoise(); const simplex = new SimplexNoise();
const circles = new Float32Array(CIRCLE_COUNT * PROPS); const circles = new Float32Array(CIRCLE_COUNT * PROPS);
let baseHue = HUE_MIN; let tick = 0;
let raf = 0; let raf = 0;
let running = true; let running = true;
function initCircle(i: number) { function initCircle(i: number) {
const x = rand(a.width); const x = rand(a.width);
const y = rand(a.height); const y = rand(a.height);
const n = simplex.noise3D(x * NOISE_OFF, y * NOISE_OFF, baseHue * NOISE_OFF); const n = simplex.noise3D(x * NOISE_OFF, y * NOISE_OFF, tick * NOISE_OFF);
const ang = rand(TAU); const ang = rand(TAU);
const speed = BASE_SPEED + rand(RANGE_SPEED); const speed = BASE_SPEED + rand(RANGE_SPEED);
const hue = HUE_MIN + ((n + 1) / 2) * (HUE_MAX - HUE_MIN); // Noise picks the glow color: azure dominant, indigo next, ember rare.
const colorIndex = n > 0.05 ? 0 : n > -0.4 ? 1 : 2;
circles.set( circles.set(
[ [
x, x,
@@ -172,7 +176,7 @@ export function HeroAmbient() {
0, 0,
BASE_TTL + rand(RANGE_TTL), BASE_TTL + rand(RANGE_TTL),
BASE_RADIUS + rand(RANGE_RADIUS), BASE_RADIUS + rand(RANGE_RADIUS),
hue, colorIndex,
], ],
i, i,
); );
@@ -184,10 +188,11 @@ export function HeroAmbient() {
life: number, life: number,
ttl: number, ttl: number,
radius: number, radius: number,
hue: number, colorIndex: number,
) { ) {
const [r, g, b, peak] = PALETTE[colorIndex] ?? PALETTE[0];
actx.save(); actx.save();
actx.fillStyle = `hsla(${hue},${SAT}%,${LIGHT}%,${fadeInOut(life, ttl) * ALPHA})`; actx.fillStyle = `rgba(${r},${g},${b},${fadeInOut(life, ttl) * peak * ALPHA})`;
actx.beginPath(); actx.beginPath();
actx.arc(x, y, radius, 0, TAU); actx.arc(x, y, radius, 0, TAU);
actx.fill(); actx.fill();
@@ -216,8 +221,7 @@ export function HeroAmbient() {
actx.clearRect(0, 0, a.width, a.height); actx.clearRect(0, 0, a.width, a.height);
bctx.fillStyle = BASE_COLOR; bctx.fillStyle = BASE_COLOR;
bctx.fillRect(0, 0, b.width, b.height); bctx.fillRect(0, 0, b.width, b.height);
baseHue += 0.05; // slow drift keeps the band gently shifting tick++; // advances the noise field used when respawning circles
if (baseHue > HUE_MAX) baseHue = HUE_MIN;
for (let i = 0; i < circles.length; i += PROPS) updateCircle(i); for (let i = 0; i < circles.length; i += PROPS) updateCircle(i);
bctx.save(); bctx.save();
bctx.filter = `blur(${BLUR_PX}px)`; bctx.filter = `blur(${BLUR_PX}px)`;
@@ -0,0 +1,168 @@
/* "One agent, or a whole org chart" — the differentiator visual. A code-built
* SVG org chart: an orchestrator delegates to mid-level agents, each to
* specialists; the active delegation path is azure, and any action that leaves
* the sandbox (email, refund, …) carries a teal human-approval checkpoint —
* tying the hierarchy story to the safety story in one image. */
const NODE_W = 184;
const NODE_H = 56;
function Node({
x,
y,
title,
sub,
active = false,
}: {
x: number;
y: number;
title: string;
sub?: string;
active?: boolean;
}) {
return (
<g>
<rect
x={x}
y={y}
width={NODE_W}
height={NODE_H}
rx={14}
fill="#161d27"
stroke={active ? "#3b82f6" : "rgba(148,163,184,0.22)"}
strokeWidth={active ? 2 : 1}
/>
<circle cx={x + 18} cy={y + NODE_H / 2} r={4} fill={active ? "#3b82f6" : "#94a3b8"} />
<text
x={x + 34}
y={sub ? y + 24 : y + NODE_H / 2 + 5}
fill="#f5f8fc"
fontSize={15}
fontWeight={600}
letterSpacing="-0.01em"
>
{title}
</text>
{sub ? (
<text x={x + 34} y={y + 41} fill="#94a3b8" fontSize={12}>
{sub}
</text>
) : null}
</g>
);
}
function ApprovalBadge({ cx, cy }: { cx: number; cy: number }) {
const w = 132;
const h = 26;
return (
<g>
<rect x={cx - w / 2} y={cy - h / 2} width={w} height={h} rx={13} fill="#14b8a6" />
<text
x={cx}
y={cy + 4}
fill="#ffffff"
fontSize={12}
fontWeight={600}
textAnchor="middle"
>
✓ human approval
</text>
</g>
);
}
export function HierarchyDiagram() {
// node top-centers
const orch = { x: 318, y: 16 };
const tier1 = [
{ x: 38, y: 168, title: "Marketing Claw", sub: "mid-level agent" },
{ x: 318, y: 168, title: "Engineering Claw", sub: "mid-level agent", active: true },
{ x: 598, y: 168, title: "Operations Claw", sub: "mid-level agent" },
];
const tier2 = [
{ x: 38, y: 326, title: "Send email", sub: "leaves sandbox", gated: true },
{ x: 318, y: 326, title: "Code review", sub: "specialist", active: true },
{ x: 598, y: 326, title: "Process refund", sub: "leaves sandbox", gated: true },
];
const cx = (n: { x: number }) => n.x + NODE_W / 2;
const orchBottom = orch.y + NODE_H;
return (
<section className="flex w-full flex-col items-center bg-white px-6 py-[104px] sm:py-[128px]">
<div className="flex w-full max-w-[900px] flex-col items-center gap-4 text-center">
<span
className="font-[500] uppercase"
style={{ color: "#475569", fontSize: 13, letterSpacing: "0.16em" }}
>
Hierarchy &amp; control
</span>
<h2 className="text-[32px] leading-none font-[650] tracking-[-1.6px] text-marketing-ink sm:text-[48px] lg:text-[56px]">
One agent, or a whole org chart
</h2>
<p className="max-w-[560px] text-[18px] leading-[1.6] text-marketing-slate sm:text-[20px]">
Agents delegate to sub-agents the way a team delegates to people. Every
action that leaves the sandbox stops for a human approval first.
</p>
</div>
<div className="mt-12 w-full max-w-[820px]">
<svg
viewBox="0 0 820 410"
className="h-auto w-full"
role="img"
aria-label="Org chart: an orchestrator delegates to Marketing, Engineering, and Operations agents, which delegate to specialists; actions that leave the sandbox require human approval."
>
{/* connectors (drawn first, under nodes) */}
{tier1.map((n) => (
<line
key={`o-${n.x}`}
x1={cx(orch)}
y1={orchBottom}
x2={cx(n)}
y2={n.y}
stroke={n.active ? "#3b82f6" : "#cbd5e1"}
strokeWidth={n.active ? 2 : 1.5}
/>
))}
{tier1.map((p, i) => {
const c = tier2[i];
return (
<line
key={`c-${c.x}`}
x1={cx(p)}
y1={p.y + NODE_H}
x2={cx(c)}
y2={c.y}
stroke={c.active ? "#3b82f6" : "#cbd5e1"}
strokeWidth={c.active ? 2 : 1.5}
/>
);
})}
{/* nodes */}
<Node x={orch.x} y={orch.y} title="Orchestrator" sub="top-level agent" />
{tier1.map((n) => (
<Node key={n.title} {...n} />
))}
{tier2.map((n) => (
<Node key={n.title} {...n} />
))}
{/* approval checkpoints on sandbox-leaving connectors */}
{tier1.map((p, i) => {
const c = tier2[i];
if (!c.gated) return null;
return (
<ApprovalBadge
key={`a-${c.x}`}
cx={cx(c)}
cy={(p.y + NODE_H + c.y) / 2}
/>
);
})}
</svg>
</div>
</section>
);
}
+1 -1
View File
@@ -72,7 +72,7 @@ export function MarketingNav() {
key={l.label} key={l.label}
href={l.href} href={l.href}
onClick={() => setOpen(false)} onClick={() => setOpen(false)}
className="flex w-full items-center gap-4 rounded-2xl py-2 pr-6 pl-2 text-marketing-ink transition-colors hover:bg-[rgba(233,86,86,0.08)]" className="flex w-full items-center gap-4 rounded-2xl py-2 pr-6 pl-2 text-marketing-ink transition-colors hover:bg-[rgba(224,88,74,0.08)]"
> >
<span className="text-[18px] font-bold tracking-[-0.25px]"> <span className="text-[18px] font-bold tracking-[-0.25px]">
{l.label} {l.label}
+181 -125
View File
@@ -1,24 +1,24 @@
import { Lock, Package, Share2, ShieldCheck, Wand2 } from "lucide-react";
import Image from "next/image"; import Image from "next/image";
import Link from "next/link"; import Link from "next/link";
import { AgentToken } from "./AgentToken";
import { HeroAmbient } from "./HeroAmbient"; import { HeroAmbient } from "./HeroAmbient";
/* Marketing landing — WorkClaw's full section layout/styling reproduced 1:1, /* Marketing landing — WorkClaw's full section layout/styling reproduced 1:1,
Clawmates-branded with honest claims (no borrowed customer logos, no Clawmates-branded with honest claims (no borrowed customer logos, no
unverified SOC 2). Measurements/colours lifted from the live source. unverified SOC 2). Measurements/colours lifted from the live source.
Coral text on light fills uses the AA-safe `coral-strong`; #e95656 stays on Coral text on light fills uses the AA-safe `coral-strong`; #e0584a stays on
dark fills and solid buttons. */ dark fills and solid buttons. */
const ctaCoral = const ctaCoral =
"inline-flex items-center justify-center rounded-full bg-marketing-coral-strong font-semibold text-white transition-colors hover:bg-[#bd2d2d]"; "inline-flex items-center justify-center rounded-full bg-marketing-coral-strong font-semibold text-white transition-colors hover:bg-[#a63a2f]";
const ctaGhost =
"inline-flex items-center justify-center rounded-full bg-white font-semibold text-[#0f172a] transition-colors hover:bg-[#f1f3f7]";
/* ---------- Hero ---------- */ /* ---------- Hero ---------- */
export function Hero() { export function Hero() {
return ( return (
<section <section
className="relative -mt-[98px] h-[760px] w-full overflow-hidden bg-[#ebf4fd] sm:h-[720px] md:h-[760px] lg:h-[820px] xl:h-[900px] 2xl:h-[963px]" className="relative -mt-[98px] h-[760px] w-full overflow-hidden bg-[#0b1220] sm:h-[720px] md:h-[760px] lg:h-[820px] xl:h-[900px] 2xl:h-[963px]"
style={{ zIndex: 2 }} style={{ zIndex: 2 }}
> >
{/* Animated ambient backdrop (replaces the hero illustration). */} {/* Animated ambient backdrop (replaces the hero illustration). */}
@@ -27,44 +27,56 @@ export function Hero() {
className="absolute left-1/2 flex w-full max-w-[720px] -translate-x-1/2 flex-col items-center px-6 text-center" className="absolute left-1/2 flex w-full max-w-[720px] -translate-x-1/2 flex-col items-center px-6 text-center"
style={{ top: "clamp(160px, 12.0139vw, 173px)", gap: 48, zIndex: 2 }} style={{ top: "clamp(160px, 12.0139vw, 173px)", gap: 48, zIndex: 2 }}
> >
<div className="flex flex-col items-center" style={{ gap: 13 }}> <div className="flex flex-col items-center" style={{ gap: 16 }}>
<span
className="font-[500] uppercase"
style={{ color: "#94a3b8", fontSize: 13, letterSpacing: "0.16em" }}
>
Agentic infrastructure
</span>
<h1 <h1
className="m-0 font-extrabold" className="m-0 font-[675]"
style={{ style={{
color: "#161d27", color: "#f5f8fc",
fontSize: "clamp(49px, 6.667vw, 96px)", fontSize: "clamp(40px, 5vw, 64px)",
lineHeight: 0.9, lineHeight: 1.02,
letterSpacing: "-0.04em", letterSpacing: "-0.02em",
}} }}
> >
Scale your Build safe, scalable
<br /> <br className="hidden sm:inline" /> agentic systems
<span className="text-marketing-coral-strong">Large World</span>
</h1> </h1>
<p <p
className="m-0 font-medium" className="m-0 font-medium"
style={{ style={{
color: "#475569", color: "#cbd5e1",
fontSize: "clamp(16px, 1.944vw, 28px)", fontSize: "clamp(16px, 1.6vw, 22px)",
lineHeight: 1.3, lineHeight: 1.45,
letterSpacing: "-0.04em", letterSpacing: "-0.01em",
maxWidth: 659, maxWidth: 620,
}} }}
> >
Building safe and scalable systems of claws for any domain of work. From a single agent to an entire company of them — with the
hierarchy, controls, and human approvals to run them safely in
production.
</p> </p>
</div> </div>
<div <div
className="flex w-full flex-col items-stretch justify-center px-4 sm:flex-row sm:items-start sm:px-0" className="flex w-full flex-col items-stretch justify-center px-4 sm:flex-row sm:items-center sm:px-0"
style={{ gap: 16, maxWidth: 538 }} style={{ gap: 16, maxWidth: 460 }}
> >
<a <a
href="mailto:[email protected]" href="mailto:[email protected]"
className={`${ctaGhost} h-14 border border-[#e2e8f0] px-10 text-base sm:h-16`} className={`${ctaCoral} h-14 px-10 text-base sm:h-16`}
style={{ filter: "drop-shadow(0 4px 12px rgba(22,29,39,0.08))" }}
> >
Book a demo Book a demo
</a> </a>
<a
href="https://git.redclaw.dev/osobh/clawmates"
className="inline-flex h-14 items-center justify-center rounded-full border border-white/25 px-10 text-base font-semibold text-white transition-colors hover:bg-white/10 sm:h-16"
>
Read the docs
</a>
</div> </div>
</div> </div>
{/* Soft fade into the white section below. */} {/* Soft fade into the white section below. */}
@@ -77,25 +89,38 @@ export function Hero() {
); );
} }
/* ---------- Crew strip (honest replacement for the company-logo marquee) ---------- */ /* ---------- Crew strip (agent-token roster on the open Claw runtime) ---------- */
const CREW = [
"Marketing Claw",
"Support Claw",
"Research Claw",
"Engineering Claw",
"Ops Claw",
"Growth Claw",
"Analytics Claw",
"Design Claw",
];
export function CrewStrip() { export function CrewStrip() {
return ( return (
<div className="relative w-full" style={{ zIndex: 1 }}> <div className="relative w-full bg-white" style={{ zIndex: 1 }}>
<div className="relative z-[1] flex flex-col items-center gap-6 pt-8 pb-14 lg:gap-8"> <div className="relative z-[1] mx-auto flex max-w-[1120px] flex-col items-center gap-7 px-6 pt-10 pb-14">
<p className="text-center text-[16px] font-semibold text-[#647289]"> <p className="text-center text-[16px] font-semibold text-[#647289]">
A whole crew, built on the open{" "} A whole crew, built on the open{" "}
<span className="text-marketing-coral-strong">Claw</span> runtime <span className="text-marketing-coral-strong">Claw</span> runtime
</p> </p>
<div className="w-full overflow-hidden opacity-75"> <div className="flex w-full flex-wrap items-center justify-center gap-2.5">
<Image {CREW.map((name) => (
src="/images/marketing/claw-carousel-strip.png" <div
alt="The clawmate crew" key={name}
width={4096} className="flex items-center gap-2.5 rounded-2xl border border-marketing-border bg-white px-3 py-2"
height={123} >
unoptimized <AgentToken name={name} size={30} />
sizes="100vw" <span className="text-[13px] font-medium whitespace-nowrap text-marketing-ink">
className="block h-auto w-full max-w-none" {name}
/> </span>
</div>
))}
</div> </div>
</div> </div>
</div> </div>
@@ -118,14 +143,14 @@ export function Pitch() {
> >
<div className="flex w-full max-w-[874px] flex-col items-center gap-[40px]"> <div className="flex w-full max-w-[874px] flex-col items-center gap-[40px]">
<h2 <h2
className="w-[348px] text-center text-[40px] leading-none font-extrabold tracking-[-1.6px] sm:w-[600px] sm:text-[50px] lg:w-[874px] lg:text-[64px] lg:tracking-[-2.56px]" className="w-[348px] text-center text-[40px] leading-none font-[650] tracking-[-1.6px] sm:w-[600px] sm:text-[50px] lg:w-[874px] lg:text-[64px] lg:tracking-[-2.56px]"
style={{ color: "#161d27" }} style={{ color: "#161d27" }}
> >
Multiply your brainpower Multiply your brainpower
<br className="hidden lg:block" /> with a team of custom, <br className="hidden lg:block" /> with a team of custom,
<br className="hidden lg:block" /> collaborative{" "} <br className="hidden lg:block" /> collaborative{" "}
<br className="inline sm:hidden" /> <br className="inline sm:hidden" />
<span className="text-marketing-coral">AI coworkers</span> AI coworkers
</h2> </h2>
<div className="grid grid-cols-2 justify-items-center gap-x-4 gap-y-8 sm:grid-cols-4 lg:gap-x-0 lg:gap-y-0"> <div className="grid grid-cols-2 justify-items-center gap-x-4 gap-y-8 sm:grid-cols-4 lg:gap-x-0 lg:gap-y-0">
{BADGES.map((b) => ( {BADGES.map((b) => (
@@ -165,10 +190,10 @@ export function OneClick() {
<div className="relative" style={{ width: 137, height: 64 }}> <div className="relative" style={{ width: 137, height: 64 }}>
<div <div
className="absolute top-0 left-0 flex items-center justify-center bg-white" className="absolute top-0 left-0 flex items-center justify-center bg-white"
style={{ width: 64, height: 64, borderRadius: 16, border: "2px dashed #e95656" }} style={{ width: 64, height: 64, borderRadius: 16, border: "2px dashed #e0584a" }}
> >
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden> <svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden>
<path d="M12 5v14M5 12h14" stroke="#e95656" strokeWidth="2.5" strokeLinecap="round" /> <path d="M12 5v14M5 12h14" stroke="#e0584a" strokeWidth="2.5" strokeLinecap="round" />
</svg> </svg>
</div> </div>
<svg <svg
@@ -183,10 +208,10 @@ export function OneClick() {
</div> </div>
<div className="flex max-w-[623px] flex-col gap-4"> <div className="flex max-w-[623px] flex-col gap-4">
<h2 <h2
className="m-0 font-extrabold" className="m-0 font-[650]"
style={{ color: "#161d27", fontSize: "clamp(36px, 5vw, 56px)", lineHeight: 0.9, letterSpacing: "-0.04em" }} style={{ color: "#161d27", fontSize: "clamp(36px, 5vw, 56px)", lineHeight: 0.9, letterSpacing: "-0.04em" }}
> >
<span className="text-marketing-coral">One-click </span>setup One-click setup
</h2> </h2>
<p <p
className="m-0 max-w-[448px] font-medium" className="m-0 max-w-[448px] font-medium"
@@ -203,19 +228,10 @@ export function OneClick() {
style={{ width: 375, maxWidth: "100%", backgroundColor: "white", border: "1px solid #e2e8f0", borderRadius: 32, boxShadow: "0px 17px 40px 0px rgba(0,0,0,0.1)" }} style={{ width: 375, maxWidth: "100%", backgroundColor: "white", border: "1px solid #e2e8f0", borderRadius: 32, boxShadow: "0px 17px 40px 0px rgba(0,0,0,0.1)" }}
> >
<div <div
className="relative flex w-full items-end justify-center overflow-hidden" className="relative flex w-full items-center justify-center overflow-hidden"
style={{ height: 208, backgroundColor: "#bfd2ff" }} style={{ height: 168, background: "linear-gradient(160deg, #1e293b, #0b1220)" }}
> >
<Image <AgentToken name="Sandy Clawson" size={76} />
src="/images/marketing/support-claw.png"
alt="A clawmate"
width={1530}
height={1830}
unoptimized
sizes="156px"
className="object-contain object-bottom"
style={{ width: 156, height: 187 }}
/>
</div> </div>
<div className="flex w-full flex-col gap-6 px-6"> <div className="flex w-full flex-col gap-6 px-6">
<div className="flex flex-col gap-4"> <div className="flex flex-col gap-4">
@@ -232,7 +248,7 @@ export function OneClick() {
{["Shared with your team", "Talks with other Claws"].map((row) => ( {["Shared with your team", "Talks with other Claws"].map((row) => (
<div key={row} className="flex items-center justify-between"> <div key={row} className="flex items-center justify-between">
<span className="font-medium" style={{ color: "#475569", fontSize: 14, letterSpacing: "-0.02em" }}>{row}</span> <span className="font-medium" style={{ color: "#475569", fontSize: 14, letterSpacing: "-0.02em" }}>{row}</span>
<span aria-hidden className="inline-flex items-center justify-end" style={{ width: 36, height: 20, padding: 2, borderRadius: 9999, backgroundColor: "#e95656" }}> <span aria-hidden className="inline-flex items-center justify-end" style={{ width: 36, height: 20, padding: 2, borderRadius: 9999, backgroundColor: "#e0584a" }}>
<span className="block" style={{ width: 16, height: 16, borderRadius: 9999, backgroundColor: "white", boxShadow: "0px 0px 1px 0px rgba(0,0,0,0.4), 0px 1px 3px 0px rgba(0,0,0,0.1)" }} /> <span className="block" style={{ width: 16, height: 16, borderRadius: 9999, backgroundColor: "white", boxShadow: "0px 0px 1px 0px rgba(0,0,0,0.4), 0px 1px 3px 0px rgba(0,0,0,0.1)" }} />
</span> </span>
</div> </div>
@@ -272,8 +288,8 @@ export function Works() {
<img src="/images/marketing/icon-slack.svg" alt="" style={{ width: 46, height: 46 }} /> <img src="/images/marketing/icon-slack.svg" alt="" style={{ width: 46, height: 46 }} />
</div> </div>
<div className="flex max-w-[623px] flex-col gap-4"> <div className="flex max-w-[623px] flex-col gap-4">
<h2 className="m-0 font-extrabold" style={{ color: "#0f172a", fontSize: "clamp(32px, 5vw, 56px)", lineHeight: 0.9, letterSpacing: "-0.04em" }}> <h2 className="m-0 font-[650]" style={{ color: "#0f172a", fontSize: "clamp(32px, 5vw, 56px)", lineHeight: 0.9, letterSpacing: "-0.04em" }}>
Works <span className="text-marketing-coral">where you do</span> Works where you do
</h2> </h2>
<p className="m-0 max-w-[524px] font-medium" style={{ color: "rgba(10,15,30,0.75)", fontSize: "clamp(16px, 1.4vw, 20px)", lineHeight: 1.6 }}> <p className="m-0 max-w-[524px] font-medium" style={{ color: "rgba(10,15,30,0.75)", fontSize: "clamp(16px, 1.4vw, 20px)", lineHeight: 1.6 }}>
Each clawmate has their own computer and can collaborate over Each clawmate has their own computer and can collaborate over
@@ -321,8 +337,8 @@ export function AlwaysOn() {
<div className="relative z-10 flex min-w-0 flex-1 flex-col items-start justify-center gap-8 lg:justify-start lg:pt-[88px]"> <div className="relative z-10 flex min-w-0 flex-1 flex-col items-start justify-center gap-8 lg:justify-start lg:pt-[88px]">
<img src="/images/moon.svg" alt="" width={61} height={64} className="block" /> <img src="/images/moon.svg" alt="" width={61} height={64} className="block" />
<div className="flex max-w-[623px] flex-col gap-4"> <div className="flex max-w-[623px] flex-col gap-4">
<h2 className="m-0 font-extrabold" style={{ color: "#f8fafc", fontSize: "clamp(36px, 5vw, 56px)", lineHeight: 0.9, letterSpacing: "-0.04em" }}> <h2 className="m-0 font-[650]" style={{ color: "#f8fafc", fontSize: "clamp(36px, 5vw, 56px)", lineHeight: 0.9, letterSpacing: "-0.04em" }}>
Always <span className="text-marketing-coral">on</span> Always on
</h2> </h2>
<p className="m-0 max-w-[496px] font-medium" style={{ color: "#cbd5e1", fontSize: "clamp(16px, 1.4vw, 20px)", lineHeight: 1.6 }}> <p className="m-0 max-w-[496px] font-medium" style={{ color: "#cbd5e1", fontSize: "clamp(16px, 1.4vw, 20px)", lineHeight: 1.6 }}>
Your team of clawmates get real work done Your team of clawmates get real work done
@@ -331,12 +347,46 @@ export function AlwaysOn() {
</p> </p>
</div> </div>
</div> </div>
<div className="relative flex min-w-0 flex-1 items-center justify-center lg:items-stretch lg:justify-stretch"> <div className="relative z-10 flex min-w-0 flex-1 items-center justify-center lg:py-[64px] lg:pr-[64px]">
<div className="relative w-full lg:hidden" style={{ maxWidth: 543, aspectRatio: "449 / 496" }}> <div className="w-full max-w-[520px] overflow-hidden rounded-2xl border border-white/10 bg-[#0b1220] font-mono text-[12.5px] leading-relaxed shadow-2xl">
<Image src="/images/marketing/always-composite.png" alt="A clawmate working through the night" fill unoptimized sizes="543px" className="object-contain" /> <div className="flex items-center gap-1.5 border-b border-white/10 px-4 py-3">
</div> <span className="size-2.5 rounded-full bg-white/20" />
<div className="relative hidden w-full lg:block lg:self-stretch"> <span className="size-2.5 rounded-full bg-white/20" />
<Image src="/images/marketing/always-composite-desktop.png" alt="A clawmate working through the night" fill unoptimized sizes="50vw" className="object-cover object-center" /> <span className="size-2.5 rounded-full bg-white/20" />
<span className="ml-2 text-[11px] text-marketing-slate-light">
marketing-claw · activity
</span>
</div>
<div className="flex flex-col gap-1.5 px-4 py-4 text-marketing-slate-light">
<p>
<span className="text-marketing-slate-light">02:14</span>{" "}
<span className="text-marketing-azure">→</span> drafting the weekly
report…
</p>
<p>
<span className="text-marketing-slate-light">02:15</span>{" "}
<span className="text-marketing-azure">→</span> querying the
analytics warehouse
</p>
<p>
<span className="text-marketing-slate-light">02:17</span>{" "}
<span className="text-marketing-teal">✓</span> 3 tool calls
completed
</p>
<p className="rounded-md bg-white/[0.04] px-2 py-1.5">
<span className="text-marketing-teal">●</span> awaiting human
approval — <span className="text-white">send email → team@</span>
</p>
<p>
<span className="text-marketing-slate-light">02:19</span>{" "}
<span className="text-marketing-teal">✓</span> approved by you ·
sent
</p>
<p className="flex items-center gap-2 text-marketing-slate-light">
<span className="inline-block size-2 rounded-full bg-marketing-teal" />
running while you sleep
</p>
</div>
</div> </div>
</div> </div>
</div> </div>
@@ -350,64 +400,54 @@ export function SkillsShowcase() {
<div className="relative w-screen" style={{ left: "50%", marginLeft: "-50vw" }}> <div className="relative w-screen" style={{ left: "50%", marginLeft: "-50vw" }}>
<section <section
id="deck" id="deck"
className="flex w-full scroll-mt-24 flex-col items-center overflow-x-hidden bg-[#ebf4fd] px-6 pt-[104px] pb-[104px] sm:pt-[176px] sm:pb-[200px]" className="flex w-full scroll-mt-24 flex-col items-center overflow-x-hidden bg-marketing-mist px-6 pt-[104px] pb-[104px] sm:pt-[176px] sm:pb-[200px]"
> >
<div className="flex w-full flex-col items-center gap-[56px]" style={{ maxWidth: 1014 }}> <div className="flex w-full flex-col items-center gap-[56px]" style={{ maxWidth: 1014 }}>
<div className="flex max-w-[544px] flex-col items-center gap-4"> <div className="flex max-w-[544px] flex-col items-center gap-4">
<h2 className="text-center text-[32px] leading-none font-extrabold tracking-[-1.28px] text-[#161d27] sm:text-[48px] sm:tracking-[-2.24px] lg:text-[56px]"> <h2 className="text-center text-[32px] leading-none font-[650] tracking-[-1.28px] text-[#161d27] sm:text-[48px] sm:tracking-[-2.24px] lg:text-[56px]">
Your work, <span className="text-marketing-coral-strong">your way</span> Your work, your way
</h2> </h2>
<p className="max-w-[468px] text-center text-[18px] leading-[1.6] font-medium text-[#0a0f1e]/75 sm:text-[20px]"> <p className="max-w-[468px] text-center text-[18px] leading-[1.6] font-medium text-[#0a0f1e]/75 sm:text-[20px]">
Teach your clawmates to work the way your company does. Share skills Teach your clawmates to work the way your company does. Share skills
with your whole team. with your whole team.
</p> </p>
</div> </div>
{/* Desktop */} <div className="grid w-full gap-6 sm:grid-cols-3">
<div className="hidden w-full sm:block"> {[
<div className="relative w-full" style={{ aspectRatio: "1014 / 165" }}> {
<div className="absolute top-0 left-1/2 -translate-x-1/2 rounded-[16px] bg-[#56b1e9]" style={{ width: "24.46%", aspectRatio: "248 / 163" }} /> Icon: Wand2,
<img src="/images/marketing/skills-left.gif" alt="Create skill illustration" className="absolute" style={{ left: "3%", top: "10%", width: "19.7%" }} /> title: "Create any new skill",
<img src="/images/marketing/skills-center-desktop.svg" alt="" className="absolute left-1/2 z-10 -translate-x-1/2" style={{ top: "6%", width: "60.65%" }} /> body: "Turn your team's workflows into custom skills simply by chatting.",
<img src="/images/marketing/skills-right.gif" alt="Share skills illustration" className="absolute" style={{ right: "3%", top: "10%", width: "19.7%" }} /> },
</div> {
<div className="mt-4 flex w-full items-start"> Icon: Package,
<div className="flex w-[23%] flex-col items-center gap-2 text-center"> title: "Install our skill packs",
<h3 className="text-[18px] leading-[1.1] font-semibold tracking-[-0.18px] text-[#161d27]">Create any new skill</h3> body: "Get started with our library of battle-tested skills. Tweak as you need.",
<p className="max-w-[241px] text-[14px] leading-[1.4] text-[#161d27]">Turn your team&apos;s workflows into custom skills simply by chatting.</p> },
{
Icon: Share2,
title: "Share skills easily",
body: "Your team builds once and gets the benefits of AI together.",
},
].map(({ Icon, title, body }) => (
<div
key={title}
className="flex flex-col items-center gap-4 rounded-3xl border border-marketing-border bg-white px-6 py-10 text-center"
>
<span
className="flex size-14 items-center justify-center rounded-2xl"
style={{ backgroundColor: "rgba(59,130,246,0.1)" }}
>
<Icon aria-hidden size={26} strokeWidth={1.75} className="text-marketing-azure" />
</span>
<h3 className="text-[18px] leading-[1.1] font-semibold tracking-[-0.18px] text-marketing-ink">
{title}
</h3>
<p className="max-w-[260px] text-[14px] leading-[1.5] text-marketing-slate">
{body}
</p>
</div> </div>
<div className="flex flex-1 flex-col items-center gap-2 text-center"> ))}
<h3 className="text-[18px] leading-[1.1] font-semibold tracking-[-0.18px] text-[#161d27]">Install our skill packs</h3>
<p className="max-w-[272px] text-[14px] leading-[1.4] text-[#161d27]">Get started with our library of battle-tested skills. Tweak as you need.</p>
</div>
<div className="flex w-[27%] flex-col items-center gap-2 text-center">
<h3 className="text-[18px] leading-[1.1] font-semibold tracking-[-0.18px] text-[#161d27]">Share skills easily</h3>
<p className="max-w-[247px] text-[14px] leading-[1.4] text-[#161d27]">Your team builds once and gets the benefits of AI together.</p>
</div>
</div>
</div>
{/* Mobile */}
<div className="flex w-full flex-col items-center gap-[80px] sm:hidden">
<div className="flex flex-col items-center gap-4">
<img src="/images/marketing/skills-left.gif" alt="Create skill illustration" className="h-auto w-[160px]" />
<div className="flex flex-col items-center gap-2 text-center">
<h3 className="text-[18px] leading-[1.1] font-semibold tracking-[-0.18px] text-[#161d27]">Create any new skill</h3>
<p className="max-w-[241px] text-[14px] leading-[1.4] text-[#161d27]">Turn your team&apos;s workflows into custom skills simply by chatting.</p>
</div>
</div>
<div className="flex flex-col items-center gap-4">
<img src="/images/marketing/skills-center-desktop.svg" alt="" className="h-auto w-[300px]" />
<div className="flex flex-col items-center gap-2 text-center">
<h3 className="text-[18px] leading-[1.1] font-semibold tracking-[-0.18px] text-[#161d27]">Install our skill packs</h3>
<p className="max-w-[272px] text-[14px] leading-[1.4] text-[#161d27]">Get started with our library of battle-tested skills. Tweak as you need.</p>
</div>
</div>
<div className="flex flex-col items-center gap-4">
<img src="/images/marketing/skills-right.gif" alt="Share skills illustration" className="h-auto w-[160px]" />
<div className="flex flex-col items-center gap-2 text-center">
<h3 className="text-[18px] leading-[1.1] font-semibold tracking-[-0.18px] text-[#161d27]">Share skills easily</h3>
<p className="max-w-[247px] text-[14px] leading-[1.4] text-[#161d27]">Your team builds once and gets the benefits of AI together.</p>
</div>
</div>
</div> </div>
</div> </div>
</section> </section>
@@ -428,21 +468,27 @@ export function Security() {
<section id="security" className="flex w-full flex-col items-center px-6 py-[104px] sm:py-[128px]"> <section id="security" className="flex w-full flex-col items-center px-6 py-[104px] sm:py-[128px]">
<div className="flex w-full max-w-[1100px] flex-col items-center gap-10"> <div className="flex w-full max-w-[1100px] flex-col items-center gap-10">
<div className="flex flex-col items-center gap-4 text-center"> <div className="flex flex-col items-center gap-4 text-center">
<h2 className="text-[36px] leading-none font-extrabold tracking-[-2.24px] text-[#161d27] sm:text-[48px] lg:text-[56px]"> <h2 className="text-[36px] leading-none font-[650] tracking-[-2.24px] text-[#161d27] sm:text-[48px] lg:text-[56px]">
Enhanced <span className="text-marketing-coral">security</span> Enhanced security
</h2> </h2>
<p className="max-w-[484px] text-[18px] leading-[1.6] text-[#0a0f1e]/75 sm:text-[20px]"> <p className="max-w-[484px] text-[18px] leading-[1.6] text-[#0a0f1e]/75 sm:text-[20px]">
Clawmates is built for security-minded teams, adding a layer of Clawmates is built for security-minded teams, adding a layer of
control and safety on top of the open Claw runtime. control and safety on top of the open Claw runtime.
</p> </p>
</div> </div>
<div className="flex items-center justify-center gap-[14px]"> <div className="flex items-center justify-center py-2">
<div className="h-[140px] sm:h-[170px] lg:h-[198px]"> <span
<img src="/images/marketing/security-hand-key.png" alt="Hand inserting a key into a vault" className="h-full w-auto" /> className="relative flex items-center justify-center rounded-[28px] border border-marketing-border bg-marketing-mist"
</div> style={{ width: 132, height: 132 }}
<div className="-my-[10px] h-[154px] sm:-my-[12px] sm:h-[186px] lg:-my-[14px] lg:h-[217px]"> >
<img src="/images/marketing/key-snap.gif" alt="A clawmate securing a vault" className="h-full w-auto" /> <ShieldCheck aria-hidden size={64} strokeWidth={1.5} className="text-marketing-azure" />
</div> <span
className="absolute -right-2 -bottom-2 flex size-9 items-center justify-center rounded-full bg-marketing-teal text-white"
style={{ boxShadow: "0 6px 16px rgba(20,184,166,0.4)" }}
>
<Lock aria-hidden size={16} strokeWidth={2} />
</span>
</span>
</div> </div>
<div className="grid w-full grid-cols-1 gap-10 pt-8 sm:grid-cols-2 lg:grid-cols-4"> <div className="grid w-full grid-cols-1 gap-10 pt-8 sm:grid-cols-2 lg:grid-cols-4">
{SECURITY.map((s) => ( {SECURITY.map((s) => (
@@ -474,8 +520,18 @@ export function Footer() {
<div className="relative flex w-full flex-col items-center overflow-hidden bg-[#f9fbff] px-6 pt-[127px] pb-[160px] sm:pb-[120px]"> <div className="relative flex w-full flex-col items-center overflow-hidden bg-[#f9fbff] px-6 pt-[127px] pb-[160px] sm:pb-[120px]">
<div className="absolute inset-0 h-full w-full opacity-[0.07]" style={{ backgroundImage: "url('/images/marketing/dot-pattern.svg')", backgroundSize: "cover", backgroundPosition: "center" }} /> <div className="absolute inset-0 h-full w-full opacity-[0.07]" style={{ backgroundImage: "url('/images/marketing/dot-pattern.svg')", backgroundSize: "cover", backgroundPosition: "center" }} />
<div className="relative flex w-full max-w-[561px] flex-col items-center gap-[40px] sm:gap-[56px]"> <div className="relative flex w-full max-w-[561px] flex-col items-center gap-[40px] sm:gap-[56px]">
<img src="/images/marketing/footer-team.svg" alt="A team working together" className="h-auto w-[140px] sm:w-[190px]" /> <div className="flex items-center justify-center gap-2.5">
<h2 className="text-center text-[40px] leading-none font-extrabold tracking-[-2.56px] text-[#161d27] sm:text-[56px] lg:text-[64px]"> {[
{ n: "Marketing Claw", a: "#3b82f6" },
{ n: "Support Claw", a: "#14b8a6" },
{ n: "Research Claw", a: "#3b82f6" },
{ n: "Ops Claw", a: "#3b82f6" },
{ n: "Growth Claw", a: "#14b8a6" },
].map(({ n, a }) => (
<AgentToken key={n} name={n} size={44} accent={a} />
))}
</div>
<h2 className="text-center text-[40px] leading-none font-[650] tracking-[-2.56px] text-[#161d27] sm:text-[56px] lg:text-[64px]">
Build your AI crew Build your AI crew
</h2> </h2>
<div className="flex w-full max-w-[454px] flex-col gap-4 sm:flex-row"> <div className="flex w-full max-w-[454px] flex-col gap-4 sm:flex-row">
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

After

Width:  |  Height:  |  Size: 960 KiB