Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
536 changes: 532 additions & 4 deletions package-lock.json

Large diffs are not rendered by default.

13 changes: 10 additions & 3 deletions src/components/site/home/CoreConcepts.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,28 @@ export function CoreConcepts() {
const items = [
{
tag: "SKILLS",
plain: "What your agent can do",
title: "Capabilities, installable.",
body: "Cardiology Diagnostics. Growth Hacking. Legal Due Diligence. Discrete units of expertise an agent can install on demand.",
sample: ["cardiology-diagnostics", "growth-hacking-pro", "legal-due-diligence"],
},
{
tag: "PLAYBOOKS",
plain: "How it runs a process end-to-end",
title: "Workflows that ship results.",
body: "Complete operational logic for real-world processes — from enterprise sales motions to medical consultations.",
sample: ["enterprise-sales-flow", "medical-consultation-v2", "startup-validation"],
},
{
tag: "SOULS",
plain: "How it sounds and decides",
title: "Personality as code.",
body: "Tone, style, principles, decision-making. Give your agent a Challenger-rep soul, a McKinsey soul, or a humanized doctor soul.",
sample: ["challenger-rep-soul", "mckinsey-consultant", "humanized-doctor"],
},
{
tag: "GUARDRAILS",
plain: "What it must never do",
title: "Safety, by default.",
body: "Block hallucinations, regulatory violations, out-of-domain behavior and unsafe actions before they reach your users.",
sample: ["medical-guardrails", "finance-compliance", "no-hallucination"],
Expand All @@ -36,7 +40,7 @@ export function CoreConcepts() {
The Stack
</span>
<h2 className="mt-3 text-4xl font-semibold tracking-tight md:text-5xl">
Four primitives. Infinite agents.
Four building blocks. Infinite agents.
</h2>
</div>
<Link
Expand All @@ -52,8 +56,11 @@ export function CoreConcepts() {
key={it.tag}
className="group rounded-2xl border border-border bg-background p-7 shadow-sm transition-all hover:border-primary/40 hover:shadow-elevated"
>
<div className="font-mono text-[11px] uppercase tracking-[0.2em] text-primary">
{it.tag}
<div className="flex flex-wrap items-baseline gap-x-3 gap-y-1">
<span className="font-mono text-[11px] uppercase tracking-[0.2em] text-primary">
{it.tag}
</span>
<span className="text-xs text-muted-foreground">{it.plain}</span>
</div>
<h3 className="mt-3 text-2xl font-semibold tracking-tight">{it.title}</h3>
<p className="mt-3 text-sm leading-relaxed text-muted-foreground">{it.body}</p>
Expand Down
6 changes: 3 additions & 3 deletions src/components/site/home/CtaSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,15 @@ export function CtaSection() {
<div className="mt-7 flex flex-col items-center justify-center gap-3 sm:flex-row">
<Link
to="/connect"
className="inline-flex h-11 items-center rounded-md bg-primary px-6 text-sm font-medium text-primary-foreground shadow-elevated transition-all hover:opacity-95"
className="inline-flex h-11 items-center rounded-md bg-primary px-6 text-sm font-semibold text-primary-foreground shadow-elevated transition-all hover:opacity-95"
>
Connect your agent →
Connect your agent — free →
</Link>
<Link
to="/marketplace"
className="inline-flex h-11 items-center rounded-md border border-border bg-surface-elevated px-6 text-sm font-medium text-foreground transition-colors hover:bg-accent"
>
Browse the registry
Browse the skills
</Link>
</div>
</div>
Expand Down
181 changes: 58 additions & 123 deletions src/components/site/home/Hero.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { Link } from "@tanstack/react-router";
import { lazy, Suspense, useState } from "react";
import { BadgeCheck, Landmark, ShieldAlert, Clock } from "lucide-react";
import { Typewriter } from "@/components/site/Typewriter";
import { lazy, Suspense } from "react";
import { CopyButton } from "@/components/site/CopyButton";
import { CountUp } from "@/components/site/CountUp";
import { SITE_STATS, SKILLS_LABEL } from "@/lib/site-stats";
Expand All @@ -10,25 +8,15 @@ const McpInstallAnimation = lazy(() =>
import("@/components/site/McpInstallAnimation").then((m) => ({ default: m.McpInstallAnimation })),
);

const CONNECT_TOOLS: { id: string; label: string; steps: string }[] = [
{ id: "claude", label: "Claude", steps: "Paste into Claude → Settings → Connectors." },
{ id: "cursor", label: "Cursor", steps: "Paste into Cursor → Settings → MCP → Add server." },
{
id: "chatgpt",
label: "ChatGPT",
steps: "Add as a connector in ChatGPT (Settings → Connectors / GPTs).",
},
{
id: "other",
label: "Other",
steps: "Add the URL as an MCP server in any MCP-compatible client.",
},
];
const MCP_URL = "https://superagentskill.com/api/mcp";

/**
* Conversion-first hero: one static headline (no rotating text — it caused
* overflow, layout shift and comprehension problems), one primary CTA, and
* the raw MCP URL demoted to a compact secondary path for people who already
* know what MCP is. The step-by-step connect flow lives at /connect.
*/
export function Hero() {
const mcpUrl = "https://superagentskill.com/api/mcp";
const [toolId, setToolId] = useState("claude");
const tool = CONNECT_TOOLS.find((t) => t.id === toolId) ?? CONNECT_TOOLS[0];
return (
<section className="relative overflow-hidden border-b border-border">
<div className="absolute inset-0 grid-bg opacity-60" aria-hidden />
Expand All @@ -37,111 +25,64 @@ export function Hero() {
<div className="grid items-center gap-10 lg:grid-cols-[1.05fr_1fr] lg:gap-14">
{/* LEFT — message + primary action */}
<div className="relative z-10 min-w-0 fade-up text-center lg:text-left">
<div className="inline-flex max-w-full items-center gap-2 rounded-full border border-border bg-surface-elevated px-3 py-1 text-xs text-muted-foreground shadow-sm sm:max-w-none">
<div className="inline-flex max-w-full items-center gap-2 rounded-full border border-border bg-surface-elevated px-3 py-1 text-xs text-muted-foreground shadow-sm">
<span className="inline-block h-1.5 w-1.5 rounded-full bg-signal pulse-dot" />
<span className="min-w-0 truncate sm:whitespace-normal">
{SKILLS_LABEL} signed skills · Works with Claude, Cursor &amp; ChatGPT
{SKILLS_LABEL} signed skills · Free to start
</span>
</div>
<h1 className="mt-5 text-balance text-[2rem] font-semibold leading-[1.08] tracking-tight sm:text-5xl lg:text-6xl xl:text-[64px]">
Turn Claude or Cursor into a{" "}
<span className="block text-primary text-[1.75rem] sm:text-4xl lg:text-5xl xl:text-[3.5rem] leading-[1.15] mt-1">
<Typewriter
className="inline-block max-w-full break-words"
words={[
"cybersec expert.",
"senior SRE.",
"fintech officer.",
"HIPAA clinician.",
"Stripe expert.",
"CRO specialist.",
]}
/>
</span>
<span className="mt-2 block text-foreground/90">In 30 seconds. No code.</span>
<h1 className="mt-5 text-balance text-4xl font-semibold leading-[1.1] tracking-tight sm:text-5xl lg:text-6xl">
Turn Claude, Cursor or ChatGPT into{" "}
<span className="text-primary">an expert in your field</span> — in 30 seconds.
</h1>
<p className="mx-auto mt-5 max-w-xl text-pretty px-1 text-base leading-relaxed text-muted-foreground lg:mx-0 lg:px-0 lg:text-lg">
Paste one link. Your agent gains{" "}
<p className="mx-auto mt-5 max-w-xl text-pretty text-base leading-relaxed text-muted-foreground lg:mx-0 lg:text-lg">
Paste one link and your agent gains{" "}
<span className="text-foreground">{SKILLS_LABEL} expert skills</span> — every one
signed, tested against jailbreaks, and scored in public. No code. No fine-tuning. Free
to start.
signed, tested against jailbreaks and scored in public. No code. No fine-tuning.
</p>

{/* Benefit cues — why it's worth the 30 seconds */}
<ul className="mx-auto mt-5 flex max-w-xl flex-wrap justify-center gap-x-5 gap-y-2 text-sm text-muted-foreground lg:mx-0 lg:justify-start">
{["Works in 30 seconds", "No code or fine-tuning", "Tested against jailbreaks"].map(
(b) => (
<li key={b} className="inline-flex items-center gap-1.5">
<span className="inline-block size-1.5 rounded-full bg-signal" aria-hidden />
<span className="text-foreground/90">{b}</span>
</li>
),
)}
</ul>
{/* One primary action, one visually subordinate alternative */}
<div className="mt-7 flex flex-col items-center gap-3 sm:flex-row sm:justify-center lg:justify-start">
<Link
to="/connect"
className="inline-flex h-12 w-full items-center justify-center rounded-md bg-primary px-7 text-[15px] font-semibold text-primary-foreground shadow-elevated transition-all hover:scale-[1.02] hover:opacity-95 sm:w-auto"
>
Connect your agent — free →
</Link>
<Link
to="/marketplace"
className="inline-flex h-12 w-full items-center justify-center rounded-md border border-border bg-surface-elevated px-6 text-[15px] font-medium text-foreground transition-colors hover:bg-accent sm:w-auto"
>
Browse the skills
</Link>
</div>
<p className="mx-auto mt-3 max-w-[22rem] text-xs leading-relaxed text-muted-foreground sm:max-w-none lg:mx-0">
Free forever · No credit card · No signup to browse · Open source (Apache 2.0)
</p>

{/* MCP URL — the primary above-the-fold action */}
<div className="mt-6 min-w-0 rounded-xl border border-border bg-background/80 p-3 shadow-elevated backdrop-blur">
{/* Tool picker — swaps the connect instructions */}
<div className="mb-2 flex flex-wrap items-center gap-1.5">
<span className="mr-1 font-mono text-[10px] uppercase tracking-wider text-muted-foreground">
Connecting
</span>
{CONNECT_TOOLS.map((t) => (
<button
key={t.id}
type="button"
onClick={() => setToolId(t.id)}
aria-pressed={t.id === toolId}
className={
"rounded-full border px-2.5 py-0.5 text-[11px] font-medium transition-colors " +
(t.id === toolId
? "border-primary bg-primary text-primary-foreground"
: "border-border bg-background text-muted-foreground hover:border-primary/40 hover:text-foreground")
}
>
{t.label}
</button>
))}
</div>
<div className="flex min-w-0 items-center justify-between gap-2">
<div className="flex min-w-0 flex-1 items-center gap-2 overflow-hidden px-1 sm:px-2">
{/* Secondary path for people who already know MCP */}
<div className="mx-auto mt-8 max-w-xl rounded-xl border border-border bg-background/80 p-3 text-left shadow-sm backdrop-blur lg:mx-0">
<p className="px-1 text-[11px] text-muted-foreground">
<span className="font-medium text-foreground">Already use MCP?</span> Paste this URL
into your client — it works instantly, no restart.
</p>
<div className="mt-2 flex min-w-0 items-center justify-between gap-2">
<div className="flex min-w-0 flex-1 items-center gap-2 overflow-hidden px-1">
<span className="hidden font-mono text-[10px] uppercase tracking-wider text-primary sm:inline">
MCP
</span>
<code className="truncate font-mono text-xs text-foreground sm:text-sm">
{mcpUrl}
{MCP_URL}
</code>
</div>
<CopyButton
value={mcpUrl}
value={MCP_URL}
label="Copy URL"
className="shrink-0 px-2 sm:px-2.5"
shortLabel="Copy"
/>
</div>
<p className="mt-2 break-words text-[11px] text-muted-foreground">
{tool.steps} Works immediately — no restart.
</p>
</div>

{/* Single primary CTA; secondary is a quiet text link */}
<div className="mt-5 flex flex-col items-center gap-2.5 lg:items-start">
<Link
to="/marketplace"
className="inline-flex h-12 w-full items-center justify-center rounded-md bg-primary px-7 text-[15px] font-semibold text-primary-foreground shadow-elevated transition-all hover:scale-[1.02] hover:opacity-95 sm:w-auto"
>
Browse the skills →
</Link>
<Link
to="/connect"
className="text-sm font-medium text-muted-foreground underline-offset-4 transition-colors hover:text-foreground hover:underline"
>
Or walk me through connecting step by step →
</Link>
</div>
<p className="mx-auto mt-3 max-w-[20rem] text-xs leading-relaxed text-muted-foreground sm:max-w-none lg:mx-0">
Free forever · No signup to browse · No credit card · Open source (Apache 2.0)
</p>
</div>

{/* RIGHT — live install demo */}
Expand All @@ -159,30 +100,24 @@ export function Hero() {
</div>
</div>

{/* Trust metrics — slim band spanning full width */}
<div className="mt-12 grid grid-cols-2 gap-3 border-t border-border/60 pt-8 sm:gap-4 md:grid-cols-4">
{/* Trust metrics — one quiet line, not four competing cards */}
<dl className="mt-12 grid grid-cols-2 gap-y-6 border-t border-border/60 pt-8 text-center sm:grid-cols-4 sm:divide-x sm:divide-border/60">
{[
{ Icon: BadgeCheck, v: SITE_STATS.skills, suffix: "+", label: "Skills shipped" },
{ Icon: Landmark, v: SITE_STATS.souls, suffix: "+", label: "Souls available" },
{ Icon: ShieldAlert, v: SITE_STATS.playbooks, suffix: "+", label: "Playbooks ready" },
{ Icon: Clock, v: SITE_STATS.mcpSetupSeconds, suffix: "s", label: "MCP setup" },
{ v: SITE_STATS.skills, suffix: "+", label: "Expert skills" },
{ v: SITE_STATS.playbooks, suffix: "+", label: "Playbooks" },
{ v: SITE_STATS.souls, suffix: "+", label: "Souls" },
{ v: SITE_STATS.mcpSetupSeconds, suffix: "s", label: "Setup time" },
].map((m) => (
<div
key={m.label}
className="flex min-w-0 items-center gap-2 rounded-xl border border-border bg-surface/60 px-3 py-3 sm:gap-3 sm:px-4"
>
<m.Icon className="h-5 w-5 shrink-0 text-primary" strokeWidth={1.75} aria-hidden />
<div className="min-w-0">
<div className="font-mono text-xl font-semibold leading-none tracking-tight text-foreground">
<CountUp to={m.v} suffix={m.suffix} decimals={0} />
</div>
<div className="mt-1 text-[10px] uppercase leading-tight tracking-wider text-muted-foreground sm:text-[11px]">
{m.label}
</div>
</div>
<div key={m.label} className="flex min-w-0 flex-col px-2">
<dt className="order-2 mt-1.5 text-[11px] uppercase leading-tight tracking-wider text-muted-foreground">
{m.label}
</dt>
<dd className="order-1 font-mono text-2xl font-semibold leading-none tracking-tight text-foreground">
<CountUp to={m.v} suffix={m.suffix} decimals={0} />
</dd>
</div>
))}
</div>
</dl>
</div>
</section>
);
Expand Down
12 changes: 11 additions & 1 deletion src/components/site/home/HowItWorks.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { Link } from "@tanstack/react-router";

export function HowItWorks() {
const steps = [
{
Expand All @@ -8,7 +10,7 @@ export function HowItWorks() {
{
n: "02",
title: "Pick a skill — or describe one",
body: "Browse ready-made experts, or just say what you do: “I run a cardiology clinic.” SkillForge installs the right skills, playbooks and guardrails — or forges a custom one from your own context.",
body: "Browse ready-made experts, or just say what you do: “I run a cardiology clinic.” The right skills and guardrails get installed — or a custom one is built from your own context.",
},
{
n: "03",
Expand Down Expand Up @@ -42,6 +44,14 @@ export function HowItWorks() {
<p className="mt-6 text-center text-xs uppercase tracking-[0.2em] text-muted-foreground">
One endpoint · Claude Code · Cursor · ChatGPT · Continue · Cline · Any MCP client
</p>
<div className="mt-8 text-center">
<Link
to="/connect"
className="inline-flex h-11 items-center rounded-md bg-primary px-6 text-sm font-semibold text-primary-foreground shadow-elevated transition-all hover:opacity-95"
>
Start with step 1 — connect free →
</Link>
</div>
</div>
</section>
);
Expand Down
2 changes: 1 addition & 1 deletion src/components/site/home/IndustryDemo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ export function IndustryDemo() {
search={{ prompt: e.prompt }}
className="group mt-1 inline-flex items-center gap-1.5 rounded-md bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground hover:opacity-95"
>
Forge live
Try this live
<span className="transition-transform group-hover:translate-x-0.5">→</span>
</Link>
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/components/site/home/PlansTeaser.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export function PlansTeaser() {
"All marketplace packages included",
];
return (
<section className="border-b border-border bg-surface/40 py-24">
<section className="border-b border-border py-24">
<div className="mx-auto max-w-6xl px-6">
<div className="mx-auto max-w-2xl text-center">
<span className="font-mono text-xs uppercase tracking-[0.2em] text-primary">Pricing</span>
Expand Down
2 changes: 1 addition & 1 deletion src/components/site/home/Proof.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export function Proof() {
},
];
return (
<section className="border-b border-border bg-surface/40 py-20">
<section className="border-b border-border py-20">
<div className="mx-auto max-w-5xl px-6">
<div className="mx-auto max-w-2xl text-center">
<span className="font-mono text-xs uppercase tracking-[0.2em] text-primary">
Expand Down
9 changes: 5 additions & 4 deletions src/routes/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,10 @@ const FAQ_LD = {
};

/**
* One narrative, seven sections:
* hook (Hero) → ease (HowItWorks) → differentiation (Proof) →
* show-don't-tell (IndustryDemo) → vocabulary (CoreConcepts) →
* One narrative, seven sections, ordered as a conversion funnel:
* hook (Hero) → ease (HowItWorks) → show-don't-tell (IndustryDemo, the
* most persuasive section, before any technical deep-dive) →
* differentiation/trust (Proof) → vocabulary (CoreConcepts) →
* monetization (PlansTeaser) → objections + close (Faq, CtaSection).
*/
function Home() {
Expand All @@ -110,8 +111,8 @@ function Home() {
<Nav />
<Hero />
<HowItWorks />
<Proof />
<IndustryDemo />
<Proof />
<CoreConcepts />
<PlansTeaser />
<Faq />
Expand Down
Loading