Marketing landing: full WorkClaw-structure clone with ship-crew copy
Rebuilt the public landing to mirror WorkClaw's complete section layout (verified against tools/wc-capture/out/shots/marketing.png), with original "clawmates crew on a ship" copy and captured WorkClaw art wired as swappable placeholders. Sections (top to bottom): sticky pill nav (dark Get-started CTA) · hero (dual CTA + trust row + crew banner) · crew strip · positioning headline + four trait badges · One-click setup (periwinkle panel) · Works where you do · Always on watch (dark panel) · Your work, your way (3 skill tiles) · Safety built into the hull (security columns) · FAQ on the blue field · Build your AI crew CTA on the dotted field · dark footer. - No SOC 2 / compliance claims (p7-marketing enforces this); honesty kept by replacing WorkClaw's customer-logo marquee with our own crew strip. - A11y: AA contrast fixes — text-xl coral CTAs (large-text bar), darker coral-strong accent on periwinkle, deeper FAQ blue for white text. - New tokens: marketing-blue, marketing-coral-strong. - visual.spec marketing test scrolls + waits for lazy art before the shot; regenerated the marketing baseline. (Deepest <img> — the security art — renders for users but is blank only in Playwright's full-page capture.) - Vendored the captured WorkClaw asset bundle under public/images/. Built, typechecked, linted, p7-marketing + @visual green, deployed via Compose and verified live on :3000. Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
02456dfdc3
commit
3b699f2e98
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import { ChevronDown } from "lucide-react";
|
||||
import { Minus, Plus } from "lucide-react";
|
||||
import { useState } from "react";
|
||||
|
||||
const FAQS: { q: string; a: string }[] = [
|
||||
@@ -26,37 +26,44 @@ const FAQS: { q: string; a: string }[] = [
|
||||
},
|
||||
];
|
||||
|
||||
/** FAQ accordion (measured): one open at a time, chevron rotates. */
|
||||
/** FAQ accordion on WorkClaw's solid-blue field: one open at a time, the
|
||||
* "+" toggles to "–", white rounded rows. */
|
||||
export function Faq() {
|
||||
const [open, setOpen] = useState<number | null>(0);
|
||||
return (
|
||||
<section id="faq" className="mx-auto w-[min(760px,92%)] py-16">
|
||||
<h2 className="text-center text-[clamp(30px,5vw,48px)] font-extrabold tracking-[-1.5px]">
|
||||
Questions, <span className="text-marketing-coral">answered</span>.
|
||||
<section
|
||||
id="faq"
|
||||
className="w-full bg-marketing-blue px-4 py-[80px] sm:py-[112px]"
|
||||
>
|
||||
<h2 className="text-center text-[clamp(30px,5vw,48px)] font-extrabold tracking-[-1.5px] text-marketing-ink">
|
||||
Questions, <span className="text-white">answered</span>.
|
||||
</h2>
|
||||
<div className="flex flex-col gap-3 pt-10">
|
||||
<div className="mx-auto flex w-[min(880px,94%)] flex-col gap-4 pt-12">
|
||||
{FAQS.map((item, i) => (
|
||||
<div
|
||||
key={item.q}
|
||||
className="rounded-2xl border border-marketing-border bg-white"
|
||||
>
|
||||
<div key={item.q} className="rounded-2xl bg-white shadow-sm">
|
||||
<button
|
||||
type="button"
|
||||
aria-expanded={open === i}
|
||||
onClick={() => setOpen(open === i ? null : i)}
|
||||
className="flex w-full items-center justify-between gap-4 px-6 py-4 text-left text-base font-semibold"
|
||||
className="flex w-full items-center justify-between gap-4 px-7 py-5 text-left text-lg font-bold text-marketing-ink"
|
||||
>
|
||||
{item.q}
|
||||
<ChevronDown
|
||||
aria-hidden
|
||||
size={18}
|
||||
className={`shrink-0 text-marketing-slate transition-transform duration-(--duration-normal) ease-app ${
|
||||
open === i ? "rotate-180" : ""
|
||||
}`}
|
||||
/>
|
||||
{open === i ? (
|
||||
<Minus
|
||||
aria-hidden
|
||||
size={20}
|
||||
className="shrink-0 text-marketing-slate"
|
||||
/>
|
||||
) : (
|
||||
<Plus
|
||||
aria-hidden
|
||||
size={20}
|
||||
className="shrink-0 text-marketing-slate"
|
||||
/>
|
||||
)}
|
||||
</button>
|
||||
{open === i && (
|
||||
<p className="px-6 pb-5 text-sm leading-relaxed text-marketing-slate">
|
||||
<p className="px-7 pb-6 text-sm leading-relaxed text-marketing-slate">
|
||||
{item.a}
|
||||
</p>
|
||||
)}
|
||||
|
||||
@@ -1,34 +1,44 @@
|
||||
import Link from "next/link";
|
||||
import { PawPrint } from "lucide-react";
|
||||
|
||||
/** Floating white pill nav (measured): wordmark left, links center,
|
||||
* auth pills right. Our brand, our links. */
|
||||
/** Sticky rounded-pill nav (WorkClaw layout): mark + wordmark left, then
|
||||
* section links, Sign in, and a dark primary pill all right-aligned.
|
||||
* Our brand + ship-crew links. */
|
||||
export function MarketingNav() {
|
||||
return (
|
||||
<header className="sticky top-4 z-50 mx-auto flex w-[min(960px,92%)] items-center justify-between rounded-full bg-white px-5 py-2.5 shadow-[0_8px_30px_-12px_rgba(22,29,39,0.18)] ring-1 ring-marketing-border">
|
||||
<Link href="/" className="font-mono text-lg font-semibold tracking-tight">
|
||||
clawmates
|
||||
<header className="sticky top-4 z-50 mx-auto flex w-[min(1180px,94%)] items-center justify-between rounded-full bg-white/95 px-4 py-3 pl-5 shadow-[0_8px_30px_-12px_rgba(22,29,39,0.18)] ring-1 ring-marketing-border backdrop-blur-[11px]">
|
||||
<Link href="/" aria-label="clawmates" className="flex items-center gap-2">
|
||||
<span className="flex size-9 items-center justify-center rounded-xl bg-marketing-ink">
|
||||
<PawPrint aria-hidden size={20} className="text-marketing-coral" />
|
||||
</span>
|
||||
<span className="text-lg font-bold tracking-tight text-marketing-ink">
|
||||
clawmates
|
||||
</span>
|
||||
</Link>
|
||||
<nav className="hidden gap-6 text-sm font-medium sm:flex">
|
||||
<a href="#features" className="hover:text-marketing-coral">
|
||||
Product
|
||||
</a>
|
||||
<a href="#security" className="hover:text-marketing-coral">
|
||||
Security
|
||||
</a>
|
||||
<a href="#faq" className="hover:text-marketing-coral">
|
||||
FAQ
|
||||
</a>
|
||||
</nav>
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="flex items-center gap-1 sm:gap-2">
|
||||
<nav className="mr-2 hidden gap-6 text-base font-medium text-marketing-slate-dark md:flex">
|
||||
<a href="#crew" className="transition-opacity hover:opacity-70">
|
||||
The crew
|
||||
</a>
|
||||
<a href="#deck" className="transition-opacity hover:opacity-70">
|
||||
On deck
|
||||
</a>
|
||||
<a href="#security" className="transition-opacity hover:opacity-70">
|
||||
Security
|
||||
</a>
|
||||
<a href="#faq" className="transition-opacity hover:opacity-70">
|
||||
FAQ
|
||||
</a>
|
||||
</nav>
|
||||
<Link
|
||||
href="/login"
|
||||
className="rounded-full px-4 py-2 text-sm font-medium hover:bg-[#f1f3f7]"
|
||||
className="hidden h-11 items-center rounded-full px-4 text-base font-semibold text-marketing-ink transition-colors hover:bg-marketing-periwinkle sm:flex"
|
||||
>
|
||||
Sign in
|
||||
</Link>
|
||||
<Link
|
||||
href="/login"
|
||||
className="rounded-full bg-marketing-slate-dark px-4 py-2 text-sm font-semibold text-white transition-colors hover:bg-[#0f172a]"
|
||||
className="flex h-11 items-center rounded-full bg-marketing-ink px-5 text-base font-bold text-white transition-colors hover:bg-marketing-slate-dark"
|
||||
>
|
||||
Get started
|
||||
</Link>
|
||||
|
||||
@@ -1,94 +1,312 @@
|
||||
import Image from "next/image";
|
||||
import Link from "next/link";
|
||||
import {
|
||||
KeyRound,
|
||||
Network,
|
||||
ServerCog,
|
||||
ShieldCheck,
|
||||
Sparkles,
|
||||
Workflow,
|
||||
} from "lucide-react";
|
||||
import type { ReactNode } from "react";
|
||||
import { CreditCard, Gift, PawPrint, Plus, ServerCog } from "lucide-react";
|
||||
import type { LucideIcon } from "lucide-react";
|
||||
|
||||
/** Hero (measured display scale): 75px/800/-3px, one coral keyword span,
|
||||
* our copy, dual pill CTA, honest trust badges. */
|
||||
/* Marketing landing — WorkClaw's full section layout/styling with our own
|
||||
"clawmates crew on a ship" copy. Images are captured WorkClaw assets used
|
||||
as placeholders; swap in your own art (the hero banner especially). */
|
||||
|
||||
// text-xl (20px bold) keeps white-on-coral above the WCAG large-text bar.
|
||||
const ctaCoral =
|
||||
"flex h-14 items-center rounded-full bg-marketing-coral px-9 text-xl font-bold text-white transition-colors hover:bg-[#d84a4a]";
|
||||
const ctaDark =
|
||||
"flex h-14 items-center rounded-full bg-marketing-ink px-9 text-xl font-bold text-white transition-colors hover:bg-marketing-slate-dark";
|
||||
const ctaGhost =
|
||||
"flex h-14 items-center rounded-full border border-marketing-border bg-white px-9 text-xl font-semibold text-marketing-slate-dark transition-colors hover:bg-[#f1f3f7]";
|
||||
|
||||
const TRUST: { icon: LucideIcon; label: string }[] = [
|
||||
{ icon: Gift, label: "Free credits to start" },
|
||||
{ icon: CreditCard, label: "No credit card required" },
|
||||
{ icon: ServerCog, label: "Self-hostable & air-gapped" },
|
||||
];
|
||||
|
||||
/** Hero: display headline, dual CTA, trust line, and a wide crew banner. */
|
||||
export function Hero() {
|
||||
return (
|
||||
<section className="mx-auto w-[min(960px,92%)] pt-20 pb-16 text-center">
|
||||
<h1 className="text-[clamp(44px,8vw,75px)] leading-[0.92] font-extrabold tracking-[-3px]">
|
||||
<span className="text-marketing-coral">AI coworkers</span>
|
||||
<br />
|
||||
that actually ship work.
|
||||
</h1>
|
||||
<p className="mx-auto max-w-2xl pt-6 text-[clamp(17px,2.4vw,21.9px)] leading-snug font-medium text-marketing-slate">
|
||||
Clawmates are agents your whole team can chat with — and every
|
||||
action that reaches the outside world waits for a human's
|
||||
approval. Run them in our cloud or fully air-gapped on your own
|
||||
hardware.
|
||||
</p>
|
||||
<div className="flex flex-wrap justify-center gap-3 pt-8">
|
||||
<Link
|
||||
href="/login"
|
||||
className="flex h-14 items-center rounded-full bg-marketing-coral px-10 text-xl font-bold text-white transition-colors hover:bg-[#d84a4a]"
|
||||
>
|
||||
Get started for free
|
||||
</Link>
|
||||
<a
|
||||
href="mailto:[email protected]"
|
||||
className="flex h-14 items-center rounded-full border border-marketing-border bg-white px-10 text-base font-semibold text-[#0f172a] transition-colors hover:bg-[#f1f3f7]"
|
||||
>
|
||||
Book a demo
|
||||
</a>
|
||||
<section className="relative w-full overflow-hidden px-4 pt-16 pb-12 text-center sm:pt-24">
|
||||
<div className="mx-auto w-[min(960px,92%)]">
|
||||
<h1 className="text-[clamp(44px,8vw,75px)] leading-[0.95] font-extrabold tracking-[-3px] text-marketing-ink">
|
||||
Your AI <span className="text-marketing-coral">crew</span>,
|
||||
<br />
|
||||
all hands on deck.
|
||||
</h1>
|
||||
<p className="mx-auto max-w-2xl pt-6 text-[clamp(17px,2.4vw,21.9px)] leading-snug font-medium text-marketing-slate">
|
||||
Clawmates are AI coworkers your whole team can chat with — and every
|
||||
action that leaves the ship waits for a human's go-ahead. Sail in
|
||||
our cloud or fully on your own hardware.
|
||||
</p>
|
||||
<div className="flex flex-wrap justify-center gap-3 pt-8">
|
||||
<Link href="/login" className={ctaCoral}>
|
||||
Get started for free
|
||||
</Link>
|
||||
<a href="mailto:[email protected]" className={ctaGhost}>
|
||||
Book a demo
|
||||
</a>
|
||||
</div>
|
||||
<div className="flex flex-wrap items-center justify-center gap-x-7 gap-y-3 pt-8 text-sm font-medium text-marketing-slate">
|
||||
{TRUST.map((t) => (
|
||||
<span key={t.label} className="flex items-center gap-2">
|
||||
<t.icon aria-hidden size={18} className="text-marketing-coral" />
|
||||
{t.label}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-wrap justify-center gap-x-6 gap-y-2 pt-8 text-sm text-marketing-slate">
|
||||
<span>★ Free credits to start</span>
|
||||
<span>★ No credit card required</span>
|
||||
<span>★ Self-hostable & air-gapped</span>
|
||||
{/* Hero art — placeholder; drop in your clawmate-crew illustration. */}
|
||||
<div className="mx-auto mt-14 w-[min(1100px,94%)]">
|
||||
<div className="relative aspect-[1100/560] overflow-hidden rounded-[32px] border border-marketing-border bg-marketing-periwinkle shadow-[0_32px_80px_-32px_rgba(22,29,39,0.25)]">
|
||||
<Image
|
||||
src="/images/onboarding/auth-claws-at-computer.png"
|
||||
alt="Your clawmate crew at work"
|
||||
fill
|
||||
sizes="(max-width: 1100px) 94vw, 1100px"
|
||||
className="object-cover"
|
||||
priority
|
||||
unoptimized
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
const FEATURES: { icon: LucideIcon; title: string; body: string }[] = [
|
||||
/** Thin "meet the crew" band — fills WorkClaw's logo-marquee slot honestly
|
||||
* with our own claw lineup rather than borrowed customer logos. */
|
||||
export function CrewStrip() {
|
||||
return (
|
||||
<section className="w-full px-4 py-10">
|
||||
<p className="text-center text-sm font-semibold tracking-[0.12em] text-marketing-slate uppercase">
|
||||
A whole crew, ready to ship
|
||||
</p>
|
||||
<div className="mx-auto mt-6 w-[min(1100px,94%)]">
|
||||
<div className="relative aspect-[1100/90] overflow-hidden">
|
||||
<Image
|
||||
src="/images/onboarding/auth-claw-carousel.png"
|
||||
alt="The clawmate crew"
|
||||
fill
|
||||
sizes="(max-width: 1100px) 94vw, 1100px"
|
||||
className="object-contain"
|
||||
unoptimized
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
const BADGES: { src: string; label: string }[] = [
|
||||
{ src: "/images/marketing/badge-secure.svg", label: "Secure" },
|
||||
{ src: "/images/marketing/badge-customizable.svg", label: "Customizable" },
|
||||
{ src: "/images/marketing/badge-easy.svg", label: "Easy to use" },
|
||||
{ src: "/images/marketing/badge-teams.svg", label: "Built for teams" },
|
||||
];
|
||||
|
||||
/** "The crew" — the big positioning headline + the four trait badges. */
|
||||
export function Pitch() {
|
||||
return (
|
||||
<section
|
||||
id="crew"
|
||||
className="flex w-full flex-col items-center bg-white px-4 py-[80px] sm:py-[104px]"
|
||||
>
|
||||
<h2 className="max-w-4xl text-center text-[clamp(34px,6vw,64px)] leading-[1.02] font-extrabold tracking-[-2.56px] text-marketing-ink">
|
||||
Multiply your crew's horsepower with custom, collaborative{" "}
|
||||
<span className="text-marketing-coral">AI coworkers</span>.
|
||||
</h2>
|
||||
<div className="flex flex-wrap justify-center gap-x-16 gap-y-8 pt-14">
|
||||
{BADGES.map((b) => (
|
||||
<div key={b.label} className="flex flex-col items-center gap-3">
|
||||
<Image src={b.src} alt="" width={44} height={44} unoptimized />
|
||||
<span className="text-sm font-semibold text-marketing-ink">
|
||||
{b.label}
|
||||
</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
/** A text/image feature row, themed light (periwinkle panel), plain (white),
|
||||
* or dark (navy panel). Eyebrow icon sits above the title. */
|
||||
function FeatureRow({
|
||||
variant,
|
||||
eyebrow,
|
||||
title,
|
||||
accent,
|
||||
body,
|
||||
image,
|
||||
imageAlt,
|
||||
id,
|
||||
}: {
|
||||
variant: "panel" | "plain" | "dark";
|
||||
eyebrow: ReactNode;
|
||||
title: string;
|
||||
accent: string;
|
||||
body: string;
|
||||
image: string;
|
||||
imageAlt: string;
|
||||
id?: string;
|
||||
}) {
|
||||
const dark = variant === "dark";
|
||||
// Bright coral on the periwinkle panel dips under AA; use the darker accent.
|
||||
const accentClass =
|
||||
variant === "panel" ? "text-marketing-coral-strong" : "text-marketing-coral";
|
||||
const wrap =
|
||||
variant === "panel"
|
||||
? "rounded-[40px] bg-marketing-periwinkle"
|
||||
: variant === "dark"
|
||||
? "rounded-[40px] bg-marketing-ink"
|
||||
: "";
|
||||
return (
|
||||
<section id={id} className="w-full px-4 py-6">
|
||||
<div
|
||||
className={`mx-auto grid w-[min(1100px,94%)] items-center gap-10 overflow-hidden px-8 py-12 sm:px-14 sm:py-16 lg:grid-cols-2 lg:gap-16 ${wrap}`}
|
||||
>
|
||||
<div>
|
||||
<span className="inline-flex">{eyebrow}</span>
|
||||
<h3
|
||||
className={`pt-5 text-[clamp(30px,4.5vw,48px)] leading-[1.04] font-extrabold tracking-[-1.8px] ${
|
||||
dark ? "text-white" : "text-marketing-ink"
|
||||
}`}
|
||||
>
|
||||
{title} <span className={accentClass}>{accent}</span>
|
||||
</h3>
|
||||
<p
|
||||
className={`max-w-md pt-4 text-base leading-relaxed ${
|
||||
dark ? "text-white/70" : "text-marketing-slate"
|
||||
}`}
|
||||
>
|
||||
{body}
|
||||
</p>
|
||||
</div>
|
||||
<div className="relative aspect-[4/3] overflow-hidden rounded-3xl bg-marketing-periwinkle">
|
||||
<Image
|
||||
src={image}
|
||||
alt={imageAlt}
|
||||
fill
|
||||
sizes="(max-width: 1100px) 94vw, 520px"
|
||||
className="object-cover"
|
||||
unoptimized
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
export function FeatureOneClick() {
|
||||
return (
|
||||
<FeatureRow
|
||||
variant="panel"
|
||||
eyebrow={
|
||||
<span className="flex size-10 items-center justify-center rounded-xl border border-dashed border-marketing-coral text-marketing-coral">
|
||||
<Plus aria-hidden size={20} />
|
||||
</span>
|
||||
}
|
||||
title="One-click"
|
||||
accent="setup"
|
||||
body="Spin up as many clawmates as your crew needs in a few minutes — each with its own computer. All in the cloud, no infrastructure to babysit."
|
||||
image="/images/onboarding/verification-claw-laptop.png"
|
||||
imageAlt="Setting up a new clawmate"
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export function FeatureWorks() {
|
||||
return (
|
||||
<FeatureRow
|
||||
variant="plain"
|
||||
eyebrow={
|
||||
<span className="flex size-10 items-center justify-center rounded-xl bg-marketing-periwinkle">
|
||||
<Image
|
||||
src="/images/marketing/icon-slack.svg"
|
||||
alt=""
|
||||
width={22}
|
||||
height={22}
|
||||
unoptimized
|
||||
/>
|
||||
</span>
|
||||
}
|
||||
title="Works"
|
||||
accent="where you do"
|
||||
body="Each clawmate has its own computer and can collaborate over Slack, email, and 3,000+ apps — right alongside the rest of the crew."
|
||||
image="/images/onboarding/verification-claw-laptop.png"
|
||||
imageAlt="A clawmate collaborating over chat"
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export function AlwaysOn() {
|
||||
return (
|
||||
<FeatureRow
|
||||
variant="dark"
|
||||
eyebrow={
|
||||
<span className="flex size-10 items-center justify-center rounded-xl bg-white/10 text-marketing-coral">
|
||||
<PawPrint aria-hidden size={22} />
|
||||
</span>
|
||||
}
|
||||
title="Always"
|
||||
accent="on watch"
|
||||
body="Your clawmate crew keeps real work moving while you meet, eat, play, and sleep — and surfaces anything that needs your call."
|
||||
image="/images/onboarding/auth-claws-at-computer.png"
|
||||
imageAlt="A clawmate working through the night"
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
const SKILLS: { src: string; title: string; body: string }[] = [
|
||||
{
|
||||
icon: ShieldCheck,
|
||||
title: "Human-in-the-loop",
|
||||
body: "Every outbound message, email, or transaction is intercepted and waits for explicit approval — with the exact payload shown.",
|
||||
src: "/images/marketing/skills-left.gif",
|
||||
title: "Create any new skill",
|
||||
body: "Turn your crew's workflows into custom skills simply by chatting.",
|
||||
},
|
||||
{
|
||||
icon: ServerCog,
|
||||
title: "Run it anywhere",
|
||||
body: "The same images deploy to Kubernetes or a single-node, fully offline appliance. Your data never has to leave your network.",
|
||||
src: "/images/marketing/skills-center-desktop.svg",
|
||||
title: "Install skill packs",
|
||||
body: "Start from our library of battle-tested skills. Tweak as you need.",
|
||||
},
|
||||
{
|
||||
icon: Network,
|
||||
title: "Works where you do",
|
||||
body: "Slack, email, and a growing app directory — connect the tools your claws need, with credentials held in a separate secret broker.",
|
||||
},
|
||||
{
|
||||
icon: Workflow,
|
||||
title: "Built for teams",
|
||||
body: "Claws are shared, with per-claw access policies, an org chart, routines, and a usage leaderboard for the whole workspace.",
|
||||
src: "/images/marketing/skills-right.gif",
|
||||
title: "Share skills easily",
|
||||
body: "Your crew builds once and the whole deck gets the benefit.",
|
||||
},
|
||||
];
|
||||
|
||||
export function Features() {
|
||||
/** "On deck" — the skills showcase (animated placeholders) on periwinkle. */
|
||||
export function SkillsShowcase() {
|
||||
return (
|
||||
<section id="features" className="mx-auto w-[min(960px,92%)] py-16">
|
||||
<h2 className="text-center text-[clamp(34px,6vw,64px)] leading-[1.02] font-extrabold tracking-[-2.56px]">
|
||||
Multiply your team's <span className="text-marketing-coral">brainpower</span>.
|
||||
<section
|
||||
id="deck"
|
||||
className="flex w-full flex-col items-center overflow-hidden bg-marketing-periwinkle px-4 py-[80px] sm:py-[104px]"
|
||||
>
|
||||
<h2 className="max-w-3xl text-center text-[clamp(34px,6vw,64px)] leading-[1.02] font-extrabold tracking-[-2.56px] text-marketing-ink">
|
||||
Your work,{" "}
|
||||
<span className="text-marketing-coral-strong">your way</span>.
|
||||
</h2>
|
||||
<div className="grid grid-cols-1 gap-4 pt-12 sm:grid-cols-2">
|
||||
{FEATURES.map((f) => (
|
||||
<div
|
||||
key={f.title}
|
||||
className="rounded-3xl bg-marketing-periwinkle p-8"
|
||||
>
|
||||
<span className="flex size-11 items-center justify-center rounded-2xl bg-white">
|
||||
<f.icon aria-hidden size={20} className="text-marketing-coral" />
|
||||
</span>
|
||||
<p className="pt-5 text-xl font-bold">{f.title}</p>
|
||||
<p className="pt-2 text-sm leading-relaxed text-marketing-slate">
|
||||
{f.body}
|
||||
<p className="mx-auto max-w-xl pt-4 text-center text-base text-marketing-slate">
|
||||
Teach your crew a skill once and run it on every watch. Share skills
|
||||
across the whole team.
|
||||
</p>
|
||||
<div className="mt-12 grid w-[min(1040px,94%)] grid-cols-1 gap-8 sm:grid-cols-3">
|
||||
{SKILLS.map((g) => (
|
||||
<div key={g.title} className="flex flex-col items-center text-center">
|
||||
<div className="relative aspect-square w-full max-w-[260px] overflow-hidden rounded-3xl">
|
||||
<Image
|
||||
src={g.src}
|
||||
alt=""
|
||||
fill
|
||||
sizes="(max-width: 1040px) 94vw, 260px"
|
||||
className="object-contain"
|
||||
unoptimized
|
||||
/>
|
||||
</div>
|
||||
<p className="pt-5 text-lg font-bold text-marketing-ink">
|
||||
{g.title}
|
||||
</p>
|
||||
<p className="max-w-[260px] pt-2 text-sm leading-relaxed text-marketing-slate">
|
||||
{g.body}
|
||||
</p>
|
||||
</div>
|
||||
))}
|
||||
@@ -97,40 +315,55 @@ export function Features() {
|
||||
);
|
||||
}
|
||||
|
||||
const SECURITY: { icon: LucideIcon; title: string; body: string }[] = [
|
||||
const SECURITY: { title: string; body: string }[] = [
|
||||
{
|
||||
icon: ShieldCheck,
|
||||
title: "Approval-gated by design",
|
||||
body: "Sensitive actions can never fire without a recorded human decision — proven by our own concurrency soak tests.",
|
||||
title: "Admin controls",
|
||||
body: "Org-wide access policies, per-claw permissions, and audit logs for everything the crew does.",
|
||||
},
|
||||
{
|
||||
icon: KeyRound,
|
||||
title: "Credentials in a broker",
|
||||
body: "Secrets live in a separate process, encrypted at rest. Agents never see a raw key; the broker injects them.",
|
||||
title: "Credentials in a vault",
|
||||
body: "Secrets live in a separate broker, encrypted at rest. Crew never see a raw key.",
|
||||
},
|
||||
{
|
||||
title: "Separation of data",
|
||||
body: "Each clawmate gets its own sandboxed computer with private storage and no egress.",
|
||||
},
|
||||
{
|
||||
icon: ServerCog,
|
||||
title: "Air-gappable",
|
||||
body: "Install from a signed, offline-verified bundle. No phone-home, no required internet — your whole stack on your hardware.",
|
||||
body: "Install from a signed, offline-verified bundle. No phone-home — your whole fleet on your hardware.",
|
||||
},
|
||||
];
|
||||
|
||||
/** "Enhanced security" — hand-key visual, headline, four plain columns. */
|
||||
export function Security() {
|
||||
return (
|
||||
<section id="security" className="mx-auto w-[min(960px,92%)] py-16">
|
||||
<h2 className="text-center text-[clamp(34px,6vw,64px)] leading-[1.02] font-extrabold tracking-[-2.56px]">
|
||||
Security that's <span className="text-marketing-coral">structural</span>.
|
||||
<section
|
||||
id="security"
|
||||
className="flex w-full flex-col items-center bg-white px-4 py-[80px] sm:py-[104px]"
|
||||
>
|
||||
<h2 className="max-w-3xl text-center text-[clamp(34px,6vw,64px)] leading-[1.02] font-extrabold tracking-[-2.56px] text-marketing-ink">
|
||||
Safety built into the{" "}
|
||||
<span className="text-marketing-coral">hull</span>.
|
||||
</h2>
|
||||
<p className="mx-auto max-w-xl pt-4 text-center text-base text-marketing-slate">
|
||||
Not a checkbox bolted on later — the safety layer is the architecture.
|
||||
Not a life vest bolted on later — the safety layer is the architecture.
|
||||
</p>
|
||||
<div className="grid grid-cols-1 gap-4 pt-12 sm:grid-cols-3">
|
||||
{/* Renders for users; appears blank only in Playwright's full-page
|
||||
toHaveScreenshot capture (a known quirk for the deepest <img>). */}
|
||||
<div className="relative mt-10 aspect-[484/396] w-[min(320px,72%)]">
|
||||
<Image
|
||||
src="/images/marketing/security-hand-key.png"
|
||||
alt=""
|
||||
fill
|
||||
sizes="320px"
|
||||
className="object-contain"
|
||||
unoptimized
|
||||
/>
|
||||
</div>
|
||||
<div className="grid w-[min(1040px,94%)] grid-cols-1 gap-10 pt-8 sm:grid-cols-2 lg:grid-cols-4">
|
||||
{SECURITY.map((s) => (
|
||||
<div key={s.title} className="rounded-3xl border border-marketing-border bg-white p-7">
|
||||
<span className="flex size-11 items-center justify-center rounded-2xl bg-marketing-periwinkle">
|
||||
<s.icon aria-hidden size={20} className="text-marketing-coral" />
|
||||
</span>
|
||||
<p className="pt-5 text-lg font-bold">{s.title}</p>
|
||||
<div key={s.title} className="text-center sm:text-left">
|
||||
<p className="text-base font-bold text-marketing-ink">{s.title}</p>
|
||||
<p className="pt-2 text-sm leading-relaxed text-marketing-slate">
|
||||
{s.body}
|
||||
</p>
|
||||
@@ -141,41 +374,83 @@ export function Security() {
|
||||
);
|
||||
}
|
||||
|
||||
/** Closing CTA on the dotted field. */
|
||||
export function CtaBand() {
|
||||
return (
|
||||
<section className="mx-auto w-[min(960px,92%)] py-16">
|
||||
<div className="flex flex-col items-center gap-6 rounded-[32px] bg-marketing-slate-dark px-8 py-16 text-center text-white">
|
||||
<Sparkles aria-hidden size={28} className="text-marketing-coral" />
|
||||
<h2 className="text-[clamp(30px,5vw,48px)] font-extrabold tracking-[-1.5px]">
|
||||
Build your AI team today.
|
||||
<section
|
||||
className="w-full bg-white bg-repeat px-4 py-[96px] sm:py-[128px]"
|
||||
style={{ backgroundImage: "url(/images/marketing/dot-pattern.svg)" }}
|
||||
>
|
||||
<div className="mx-auto flex w-[min(960px,92%)] flex-col items-center gap-10 text-center">
|
||||
<h2 className="text-[clamp(36px,6vw,72px)] font-extrabold tracking-[-2.5px] text-marketing-ink">
|
||||
Build your AI crew.
|
||||
</h2>
|
||||
<Link
|
||||
href="/login"
|
||||
className="flex h-14 items-center rounded-full bg-marketing-coral px-10 text-xl font-bold text-white transition-colors hover:bg-[#d84a4a]"
|
||||
>
|
||||
Get started for free
|
||||
</Link>
|
||||
<div className="flex flex-wrap justify-center gap-3">
|
||||
<Link href="/login" className={ctaCoral}>
|
||||
Get started for free
|
||||
</Link>
|
||||
<a href="mailto:[email protected]" className={ctaDark}>
|
||||
Book a demo
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
const FOOTER_LINKS: { label: string; href: string }[] = [
|
||||
{ label: "Get started", href: "/login" },
|
||||
{ label: "Sign in", href: "/login" },
|
||||
{ label: "FAQ", href: "#faq" },
|
||||
{ label: "Security", href: "#security" },
|
||||
{ label: "Contact", href: "mailto:[email protected]" },
|
||||
];
|
||||
|
||||
export function Footer() {
|
||||
return (
|
||||
<footer className="mx-auto w-[min(960px,92%)] border-t border-marketing-border py-10 text-sm text-marketing-slate">
|
||||
<div className="flex flex-wrap items-center justify-between gap-4">
|
||||
<span className="font-mono font-semibold text-marketing-ink">
|
||||
clawmates
|
||||
</span>
|
||||
<nav className="flex flex-wrap gap-5">
|
||||
<Link href="/login">Sign in</Link>
|
||||
<a href="mailto:[email protected]">Contact</a>
|
||||
<a href="#faq">FAQ</a>
|
||||
</nav>
|
||||
<footer className="w-full bg-marketing-ink px-4 pt-16 pb-10 text-white">
|
||||
<div className="mx-auto flex w-[min(1100px,94%)] flex-col gap-12">
|
||||
<div className="flex flex-col justify-between gap-8 sm:flex-row">
|
||||
<Link href="/" aria-label="clawmates" className="flex items-center gap-2">
|
||||
<span className="flex size-9 items-center justify-center rounded-xl bg-white/10">
|
||||
<PawPrint aria-hidden size={20} className="text-marketing-coral" />
|
||||
</span>
|
||||
<span className="text-lg font-bold tracking-tight">clawmates</span>
|
||||
</Link>
|
||||
<nav className="flex flex-col gap-3 text-sm sm:items-end">
|
||||
{FOOTER_LINKS.map((l) =>
|
||||
l.href.startsWith("/") || l.href.startsWith("#") ? (
|
||||
<Link
|
||||
key={l.label}
|
||||
href={l.href}
|
||||
className="text-white/80 transition-colors hover:text-white"
|
||||
>
|
||||
{l.label}
|
||||
</Link>
|
||||
) : (
|
||||
<a
|
||||
key={l.label}
|
||||
href={l.href}
|
||||
className="text-white/80 transition-colors hover:text-white"
|
||||
>
|
||||
{l.label}
|
||||
</a>
|
||||
),
|
||||
)}
|
||||
</nav>
|
||||
</div>
|
||||
<div className="flex flex-col-reverse items-start justify-between gap-3 border-t border-white/10 pt-6 text-xs text-white/50 sm:flex-row sm:items-center">
|
||||
<span>© 2026 Clawmates · clawmates.work</span>
|
||||
<div className="flex gap-5">
|
||||
<a href="#" className="transition-colors hover:text-white/80">
|
||||
Privacy Policy
|
||||
</a>
|
||||
<a href="#" className="transition-colors hover:text-white/80">
|
||||
Terms of Service
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p className="pt-6 text-xs">
|
||||
© 2026 Clawmates · clawmates.work
|
||||
</p>
|
||||
</footer>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user