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
@@ -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
* 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.
* Re-tuned to a light, brand palette (pale periwinkle base; soft blue→violet→coral
* blooms) so the dark hero copy stays readable. Scoped to its container, not the
* Re-themed to a dark, infrastructure palette (deep-ink base; glowing azure/indigo
* 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. */
// --- tunables (all easy to tweak) ---------------------------------------
@@ -16,16 +16,19 @@ const BASE_SPEED = 0.06;
const RANGE_SPEED = 0.7;
const BASE_TTL = 180;
const RANGE_TTL = 260;
const BASE_RADIUS = 120;
const RANGE_RADIUS = 240;
const BASE_RADIUS = 140;
const RANGE_RADIUS = 260;
const NOISE_OFF = 0.0015; // x/y/z noise sampling step
const BLUR_PX = 50;
const BASE_COLOR = "#edf3fc"; // pale periwinkle base (matches the hero fill)
const HUE_MIN = 205; // blue
const HUE_MAX = 360; // → indigo / violet / magenta / coral
const SAT = 70;
const LIGHT = 74;
const ALPHA = 0.5; // peak blob opacity (scaled by fade-in/out)
const BLUR_PX = 55;
const BASE_COLOR = "#0b1220"; // deep ink — blooms read as glowing light sources
const ALPHA = 1; // global multiplier on each blob's peak alpha
// Cool glow palette on dark [r, g, b, peakAlpha]. Azure + indigo dominate; a
// faint ember adds warmth (re-themed from the original hue-band approach).
const PALETTE: [number, number, number, number][] = [
[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 rand = (n: number) => n * Math.random();
@@ -152,17 +155,18 @@ export function HeroAmbient() {
const simplex = new SimplexNoise();
const circles = new Float32Array(CIRCLE_COUNT * PROPS);
let baseHue = HUE_MIN;
let tick = 0;
let raf = 0;
let running = true;
function initCircle(i: number) {
const x = rand(a.width);
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 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(
[
x,
@@ -172,7 +176,7 @@ export function HeroAmbient() {
0,
BASE_TTL + rand(RANGE_TTL),
BASE_RADIUS + rand(RANGE_RADIUS),
hue,
colorIndex,
],
i,
);
@@ -184,10 +188,11 @@ export function HeroAmbient() {
life: number,
ttl: number,
radius: number,
hue: number,
colorIndex: number,
) {
const [r, g, b, peak] = PALETTE[colorIndex] ?? PALETTE[0];
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.arc(x, y, radius, 0, TAU);
actx.fill();
@@ -216,8 +221,7 @@ export function HeroAmbient() {
actx.clearRect(0, 0, a.width, a.height);
bctx.fillStyle = BASE_COLOR;
bctx.fillRect(0, 0, b.width, b.height);
baseHue += 0.05; // slow drift keeps the band gently shifting
if (baseHue > HUE_MAX) baseHue = HUE_MIN;
tick++; // advances the noise field used when respawning circles
for (let i = 0; i < circles.length; i += PROPS) updateCircle(i);
bctx.save();
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}
href={l.href}
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]">
{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 Link from "next/link";
import { AgentToken } from "./AgentToken";
import { HeroAmbient } from "./HeroAmbient";
/* Marketing landing — WorkClaw's full section layout/styling reproduced 1:1,
Clawmates-branded with honest claims (no borrowed customer logos, no
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. */
const ctaCoral =
"inline-flex items-center justify-center rounded-full bg-marketing-coral-strong font-semibold text-white transition-colors hover:bg-[#bd2d2d]";
const ctaGhost =
"inline-flex items-center justify-center rounded-full bg-white font-semibold text-[#0f172a] transition-colors hover:bg-[#f1f3f7]";
"inline-flex items-center justify-center rounded-full bg-marketing-coral-strong font-semibold text-white transition-colors hover:bg-[#a63a2f]";
/* ---------- Hero ---------- */
export function Hero() {
return (
<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 }}
>
{/* 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"
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
className="m-0 font-extrabold"
className="m-0 font-[675]"
style={{
color: "#161d27",
fontSize: "clamp(49px, 6.667vw, 96px)",
lineHeight: 0.9,
letterSpacing: "-0.04em",
color: "#f5f8fc",
fontSize: "clamp(40px, 5vw, 64px)",
lineHeight: 1.02,
letterSpacing: "-0.02em",
}}
>
Scale your
<br />
<span className="text-marketing-coral-strong">Large World</span>
Build safe, scalable
<br className="hidden sm:inline" /> agentic systems
</h1>
<p
className="m-0 font-medium"
style={{
color: "#475569",
fontSize: "clamp(16px, 1.944vw, 28px)",
lineHeight: 1.3,
letterSpacing: "-0.04em",
maxWidth: 659,
color: "#cbd5e1",
fontSize: "clamp(16px, 1.6vw, 22px)",
lineHeight: 1.45,
letterSpacing: "-0.01em",
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>
</div>
<div
className="flex w-full flex-col items-stretch justify-center px-4 sm:flex-row sm:items-start sm:px-0"
style={{ gap: 16, maxWidth: 538 }}
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: 460 }}
>
<a
href="mailto:[email protected]"
className={`${ctaGhost} h-14 border border-[#e2e8f0] px-10 text-base sm:h-16`}
style={{ filter: "drop-shadow(0 4px 12px rgba(22,29,39,0.08))" }}
className={`${ctaCoral} h-14 px-10 text-base sm:h-16`}
>
Book a demo
</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>
{/* 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() {
return (
<div className="relative w-full" 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 w-full bg-white" style={{ zIndex: 1 }}>
<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]">
A whole crew, built on the open{" "}
<span className="text-marketing-coral-strong">Claw</span> runtime
</p>
<div className="w-full overflow-hidden opacity-75">
<Image
src="/images/marketing/claw-carousel-strip.png"
alt="The clawmate crew"
width={4096}
height={123}
unoptimized
sizes="100vw"
className="block h-auto w-full max-w-none"
/>
<div className="flex w-full flex-wrap items-center justify-center gap-2.5">
{CREW.map((name) => (
<div
key={name}
className="flex items-center gap-2.5 rounded-2xl border border-marketing-border bg-white px-3 py-2"
>
<AgentToken name={name} size={30} />
<span className="text-[13px] font-medium whitespace-nowrap text-marketing-ink">
{name}
</span>
</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]">
<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" }}
>
Multiply your brainpower
<br className="hidden lg:block" /> with a team of custom,
<br className="hidden lg:block" /> collaborative{" "}
<br className="inline sm:hidden" />
<span className="text-marketing-coral">AI coworkers</span>
AI coworkers
</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">
{BADGES.map((b) => (
@@ -165,10 +190,10 @@ export function OneClick() {
<div className="relative" style={{ width: 137, height: 64 }}>
<div
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>
<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>
</div>
<svg
@@ -183,10 +208,10 @@ export function OneClick() {
</div>
<div className="flex max-w-[623px] flex-col gap-4">
<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" }}
>
<span className="text-marketing-coral">One-click </span>setup
One-click setup
</h2>
<p
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)" }}
>
<div
className="relative flex w-full items-end justify-center overflow-hidden"
style={{ height: 208, backgroundColor: "#bfd2ff" }}
className="relative flex w-full items-center justify-center overflow-hidden"
style={{ height: 168, background: "linear-gradient(160deg, #1e293b, #0b1220)" }}
>
<Image
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 }}
/>
<AgentToken name="Sandy Clawson" size={76} />
</div>
<div className="flex w-full flex-col gap-6 px-6">
<div className="flex flex-col gap-4">
@@ -232,7 +248,7 @@ export function OneClick() {
{["Shared with your team", "Talks with other Claws"].map((row) => (
<div key={row} className="flex items-center justify-between">
<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>
</div>
@@ -272,8 +288,8 @@ export function Works() {
<img src="/images/marketing/icon-slack.svg" alt="" style={{ width: 46, height: 46 }} />
</div>
<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" }}>
Works <span className="text-marketing-coral">where you do</span>
<h2 className="m-0 font-[650]" style={{ color: "#0f172a", fontSize: "clamp(32px, 5vw, 56px)", lineHeight: 0.9, letterSpacing: "-0.04em" }}>
Works where you do
</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 }}>
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]">
<img src="/images/moon.svg" alt="" width={61} height={64} className="block" />
<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" }}>
Always <span className="text-marketing-coral">on</span>
<h2 className="m-0 font-[650]" style={{ color: "#f8fafc", fontSize: "clamp(36px, 5vw, 56px)", lineHeight: 0.9, letterSpacing: "-0.04em" }}>
Always on
</h2>
<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
@@ -331,12 +347,46 @@ export function AlwaysOn() {
</p>
</div>
</div>
<div className="relative flex min-w-0 flex-1 items-center justify-center lg:items-stretch lg:justify-stretch">
<div className="relative w-full lg:hidden" style={{ maxWidth: 543, aspectRatio: "449 / 496" }}>
<Image src="/images/marketing/always-composite.png" alt="A clawmate working through the night" fill unoptimized sizes="543px" className="object-contain" />
</div>
<div className="relative hidden w-full lg:block lg:self-stretch">
<Image src="/images/marketing/always-composite-desktop.png" alt="A clawmate working through the night" fill unoptimized sizes="50vw" className="object-cover object-center" />
<div className="relative z-10 flex min-w-0 flex-1 items-center justify-center lg:py-[64px] lg:pr-[64px]">
<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">
<div className="flex items-center gap-1.5 border-b border-white/10 px-4 py-3">
<span className="size-2.5 rounded-full bg-white/20" />
<span className="size-2.5 rounded-full bg-white/20" />
<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>
@@ -350,64 +400,54 @@ export function SkillsShowcase() {
<div className="relative w-screen" style={{ left: "50%", marginLeft: "-50vw" }}>
<section
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 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]">
Your work, <span className="text-marketing-coral-strong">your way</span>
<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, your way
</h2>
<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
with your whole team.
</p>
</div>
{/* Desktop */}
<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" }} />
<img src="/images/marketing/skills-left.gif" alt="Create skill illustration" className="absolute" style={{ left: "3%", top: "10%", width: "19.7%" }} />
<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%" }} />
<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">
<div className="flex w-[23%] 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 className="grid w-full gap-6 sm:grid-cols-3">
{[
{
Icon: Wand2,
title: "Create any new skill",
body: "Turn your team's workflows into custom skills simply by chatting.",
},
{
Icon: Package,
title: "Install our skill packs",
body: "Get started with our library of battle-tested skills. Tweak as you need.",
},
{
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 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>
</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]">
<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">
<h2 className="text-[36px] leading-none font-extrabold tracking-[-2.24px] text-[#161d27] sm:text-[48px] lg:text-[56px]">
Enhanced <span className="text-marketing-coral">security</span>
<h2 className="text-[36px] leading-none font-[650] tracking-[-2.24px] text-[#161d27] sm:text-[48px] lg:text-[56px]">
Enhanced security
</h2>
<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
control and safety on top of the open Claw runtime.
</p>
</div>
<div className="flex items-center justify-center gap-[14px]">
<div className="h-[140px] sm:h-[170px] lg:h-[198px]">
<img src="/images/marketing/security-hand-key.png" alt="Hand inserting a key into a vault" className="h-full w-auto" />
</div>
<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" />
</div>
<div className="flex items-center justify-center py-2">
<span
className="relative flex items-center justify-center rounded-[28px] border border-marketing-border bg-marketing-mist"
style={{ width: 132, height: 132 }}
>
<ShieldCheck aria-hidden size={64} strokeWidth={1.5} className="text-marketing-azure" />
<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 className="grid w-full grid-cols-1 gap-10 pt-8 sm:grid-cols-2 lg:grid-cols-4">
{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="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]">
<img src="/images/marketing/footer-team.svg" alt="A team working together" className="h-auto w-[140px] sm:w-[190px]" />
<h2 className="text-center text-[40px] leading-none font-extrabold tracking-[-2.56px] text-[#161d27] sm:text-[56px] lg:text-[64px]">
<div className="flex items-center justify-center gap-2.5">
{[
{ 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
</h2>
<div className="flex w-full max-w-[454px] flex-col gap-4 sm:flex-row">