feat(marketing): give each below-the-fold section its own visual archetype
All checks were successful
Deploy to Production / deploy (push) Successful in 1m2s
All checks were successful
Deploy to Production / deploy (push) Successful in 1m2s
Owner: "die sektionen unter dem video sehen viel zu ähnlich aus — das
kannst du besser." Correct — every section was the same `panel + 3-col
grid` pattern, no page rhythm. Each section now reads as its own type
of moment:
- **Clients** ("Connects everywhere your AI lives"): typographic logo
row, no panels. Each client carries a small mono mark in a 7×7 box
(C, ⌘, ✦, <>, →) plus a 17px tracking-tight wordmark. Group hover
flips the mark and label to the accent colour so the row reads as
interactive trust signal, not a wall of text. Generous py-20/24
spacing — this is a beat between sections, not a feature card.
- **Examples** ("Wrap any HTTP API. In minutes."): asymmetric 2-col
header (h2 left, supporting copy right) over a 3-col card grid
where each integration carries a coloured 48×48 brand mark —
Postgres `#336791`, Salesforce `#00a1e0`, Notion black-on-white,
GitHub `#181717`, Stripe `#635bff`, Custom REST `#6366f1`. The marks
give each card its own visual identity, breaking the uniform-card
pattern. h2 sized 32/40 px (was a flat 28 px).
- **Marketplace** ("Skip the prompt. Fork what works."): split layout.
Left column: eyebrow + headline + supporting paragraph + bullet
list of the three selling points (no longer equal-weight cards) +
PulseLink CTA. Right column: new `MarketplaceMock` — a faux-browser
frame containing four realistic template cards (notion-search /
github-issues / stripe-readonly / linear-tasks) with author chips,
✓ verified badges, tool counts, and a fork glyph. Visitor SEES the
marketplace instead of reading copy about it.
- **Pricing** ("Pay for tool calls. Not for boilerplate."): 4-card
row but Pro is featured — indigo border, indigo glow shadow
`0 0 0 4px rgba(99,102,241,0.12)`, "RECOMMENDED" pill floating at
-top-3, and accent-coloured feature bullets. Other tiers stay
calm so the eye lands on Pro first. Price typography enlarged from
26 px to 40 px so prices read as the headline of each card.
Spacing rhythm: every section is now py-20/28 sm:py-24/28 (was
py-12-14 sm:py-16-20) — gives the below-the-fold the breathing room
it needed; the page no longer feels like a stack of crammed cards.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
05746e13e6
commit
7a32385e2b
@ -29,13 +29,53 @@ const INSTALL_SNIPPET = `{
|
||||
}
|
||||
}`;
|
||||
|
||||
const EXAMPLES: { title: string; desc: string }[] = [
|
||||
{ title: 'Postgres reader', desc: 'Read-only access to your tables with schema introspection.' },
|
||||
{ title: 'Salesforce', desc: 'Query opportunities, accounts and leads from Claude.' },
|
||||
{ title: 'Notion', desc: 'Search pages, read content, append blocks.' },
|
||||
{ title: 'GitHub', desc: 'List issues, search code, post comments — scoped to one repo.' },
|
||||
{ title: 'Stripe', desc: 'Look up charges, customers, refunds (read-only by default).' },
|
||||
{ title: 'Custom REST', desc: 'Wrap any HTTP API behind one prompt-defined tool surface.' },
|
||||
interface ExampleEntry {
|
||||
title: string;
|
||||
desc: string;
|
||||
/** Single-character or short symbol shown in the brand-colored mark. */
|
||||
mark: string;
|
||||
/** Brand background colour for the mark. */
|
||||
bg: string;
|
||||
/** Foreground colour of the mark glyph. */
|
||||
fg: string;
|
||||
}
|
||||
|
||||
const EXAMPLES: ExampleEntry[] = [
|
||||
{ title: 'Postgres', desc: 'Read-only access to your tables with schema introspection.', mark: 'P', bg: '#336791', fg: '#ffffff' },
|
||||
{ title: 'Salesforce', desc: 'Query opportunities, accounts and leads from Claude.', mark: 'S', bg: '#00a1e0', fg: '#ffffff' },
|
||||
{ title: 'Notion', desc: 'Search pages, read content, append blocks.', mark: 'N', bg: '#ffffff', fg: '#0a0a0b' },
|
||||
{ title: 'GitHub', desc: 'List issues, search code, post comments — scoped to one repo.', mark: 'G', bg: '#181717', fg: '#ffffff' },
|
||||
{ title: 'Stripe', desc: 'Look up charges, customers, refunds (read-only by default).', mark: 'S', bg: '#635bff', fg: '#ffffff' },
|
||||
{ title: 'Custom REST', desc: 'Wrap any HTTP API behind one prompt-defined tool surface.', mark: '{}', bg: '#6366f1', fg: '#ffffff' },
|
||||
];
|
||||
|
||||
interface ClientEntry {
|
||||
name: string;
|
||||
/** Single-character mark for inline visual identity. */
|
||||
mark: string;
|
||||
}
|
||||
|
||||
const CLIENTS: ClientEntry[] = [
|
||||
{ name: 'Claude Desktop', mark: 'C' },
|
||||
{ name: 'Cursor', mark: '⌘' },
|
||||
{ name: 'ChatGPT', mark: '✦' },
|
||||
{ name: 'VS Code Copilot', mark: '<>' },
|
||||
{ name: 'Continue.dev', mark: '→' },
|
||||
];
|
||||
|
||||
interface MockTemplate {
|
||||
name: string;
|
||||
author: string;
|
||||
tools: number;
|
||||
forks: number;
|
||||
verified: boolean;
|
||||
}
|
||||
|
||||
const MOCK_TEMPLATES: MockTemplate[] = [
|
||||
{ name: 'notion-search', author: 'core', tools: 2, forks: 247, verified: true },
|
||||
{ name: 'github-issues', author: 'core', tools: 3, forks: 89, verified: true },
|
||||
{ name: 'stripe-readonly', author: 'core', tools: 4, forks: 156, verified: true },
|
||||
{ name: 'linear-tasks', author: 'community', tools: 5, forks: 34, verified: false },
|
||||
];
|
||||
|
||||
const MARKETPLACE_POINTS: { t: string; d: string }[] = [
|
||||
@ -237,110 +277,219 @@ export default function Landing() {
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Works with */}
|
||||
<section className="border-b border-[--color-border] py-12 sm:py-16">
|
||||
{/* ── Clients · trust-signal row ─────────────────────────────────
|
||||
Archetype: typographic logo row. No panels, no bullets, just
|
||||
well-spaced word-marks with a small symbolic mark. The whole
|
||||
section breathes — generous py — so it reads as a moment of
|
||||
trust, not a feature card. */}
|
||||
<section className="border-b border-[--color-border] bg-[--color-bg] py-20 sm:py-24">
|
||||
<div className="mx-auto max-w-6xl px-6">
|
||||
<h2 className="text-center text-[13px] uppercase tracking-[0.18em] text-[--color-fg-subtle]">
|
||||
Works with the clients you already use
|
||||
</h2>
|
||||
<div className="mt-8 flex flex-wrap items-center justify-center gap-x-12 gap-y-4 text-[14px] text-[--color-fg-muted]">
|
||||
{['Claude Desktop', 'Cursor', 'ChatGPT', 'VS Code Copilot', 'Continue.dev'].map((t) => (
|
||||
<span key={t} className="inline-flex items-center gap-2">
|
||||
<span className="size-1.5 rounded-full bg-[--color-fg-subtle]" />
|
||||
{t}
|
||||
</span>
|
||||
<p className="text-center text-[11px] uppercase tracking-[0.24em] text-[--color-fg-subtle]">
|
||||
Connects everywhere your AI lives
|
||||
</p>
|
||||
<div className="mt-12 flex flex-wrap items-center justify-center gap-x-14 gap-y-7 sm:gap-x-20">
|
||||
{CLIENTS.map((c) => (
|
||||
<div
|
||||
key={c.name}
|
||||
className="group flex items-center gap-3 transition-colors"
|
||||
>
|
||||
<span
|
||||
aria-hidden
|
||||
className="mono flex size-7 items-center justify-center rounded-md border border-[--color-border] text-[12px] text-[--color-fg-muted] transition-colors group-hover:border-[--color-accent] group-hover:text-[--color-accent]"
|
||||
>
|
||||
{c.mark}
|
||||
</span>
|
||||
<span className="text-[17px] font-medium tracking-tight text-[--color-fg-muted] transition-colors group-hover:text-[--color-fg]">
|
||||
{c.name}
|
||||
</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Examples */}
|
||||
<section className="border-b border-[--color-border] py-14 sm:py-20">
|
||||
{/* ── Examples · integration grid with brand-coloured marks ──────
|
||||
Archetype: 2-col header (title left, supporting copy right) +
|
||||
asymmetric 3-col card grid where each card carries a coloured
|
||||
square brand mark for the service. The marks give each card
|
||||
its own visual identity, breaking the "every card looks the
|
||||
same" pattern of the previous version. */}
|
||||
<section className="border-b border-[--color-border] py-20 sm:py-28">
|
||||
<div className="mx-auto max-w-6xl px-6">
|
||||
<div className="mb-10 max-w-2xl">
|
||||
<h2 className="text-[28px] font-semibold tracking-tight">
|
||||
Built for the work you actually have
|
||||
</h2>
|
||||
<p className="mt-2 text-[14px] text-[--color-fg-muted]">
|
||||
Anything with an HTTP API or a database, in minutes.
|
||||
<div className="mb-12 grid gap-6 md:grid-cols-[1fr_auto] md:items-end md:gap-12">
|
||||
<div>
|
||||
<p className="text-[11px] uppercase tracking-[0.22em] text-[--color-fg-subtle]">
|
||||
Use cases
|
||||
</p>
|
||||
<h2 className="mt-3 text-[32px] font-semibold leading-[1.1] tracking-tight sm:text-[40px]">
|
||||
Wrap any HTTP API.
|
||||
<br />
|
||||
<span className="text-[--color-fg-muted]">In minutes.</span>
|
||||
</h2>
|
||||
</div>
|
||||
<p className="max-w-xs text-[14px] leading-relaxed text-[--color-fg-muted]">
|
||||
Real integrations our customers ship today — built from one prompt each.
|
||||
</p>
|
||||
</div>
|
||||
<div className="grid gap-3 md:grid-cols-3">
|
||||
|
||||
<div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
|
||||
{EXAMPLES.map((e) => (
|
||||
<div
|
||||
key={e.title}
|
||||
className="panel p-4 transition-colors hover:border-[--color-border-strong]"
|
||||
className="group flex items-start gap-4 rounded-xl border border-[--color-border] bg-[--color-bg-elevated] p-5 transition-colors hover:border-[--color-border-strong]"
|
||||
>
|
||||
<div className="text-[13px] font-semibold tracking-tight">{e.title}</div>
|
||||
<p className="mt-1 text-[12.5px] leading-relaxed text-[--color-fg-muted]">
|
||||
{e.desc}
|
||||
</p>
|
||||
<div
|
||||
aria-hidden
|
||||
className="flex size-12 shrink-0 items-center justify-center rounded-lg font-semibold tracking-tight"
|
||||
style={{
|
||||
backgroundColor: e.bg,
|
||||
color: e.fg,
|
||||
fontSize: e.mark.length > 1 ? 16 : 20,
|
||||
}}
|
||||
>
|
||||
{e.mark}
|
||||
</div>
|
||||
<div className="min-w-0">
|
||||
<h3 className="text-[15px] font-semibold tracking-tight">{e.title}</h3>
|
||||
<p className="mt-1.5 text-[13px] leading-relaxed text-[--color-fg-muted]">
|
||||
{e.desc}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Marketplace */}
|
||||
<section className="border-b border-[--color-border] py-14 sm:py-20">
|
||||
<div className="mx-auto max-w-6xl px-6">
|
||||
<div className="mb-10 flex flex-wrap items-end justify-between gap-4">
|
||||
<div className="max-w-2xl">
|
||||
<h2 className="text-[28px] font-semibold tracking-tight">
|
||||
Start from a template, ship in seconds
|
||||
</h2>
|
||||
<p className="mt-2 text-[14px] text-[--color-fg-muted]">
|
||||
The marketplace is a library of working MCP servers the community already built.
|
||||
Fork one to skip the prompt — or publish your own and let others build on it.
|
||||
</p>
|
||||
</div>
|
||||
<Link
|
||||
{/* ── Marketplace · two-column with product preview ──────────────
|
||||
Archetype: split layout. Left column carries the headline,
|
||||
three bullet-form selling points, and the CTA. Right column
|
||||
carries a mock browser frame containing real-looking template
|
||||
cards — so the visitor SEES the marketplace, not just reads
|
||||
a description of it. */}
|
||||
<section className="border-b border-[--color-border] py-20 sm:py-28">
|
||||
<div className="mx-auto grid max-w-6xl gap-14 px-6 md:grid-cols-[5fr_6fr] md:items-center md:gap-16">
|
||||
{/* Left — text + points + CTA */}
|
||||
<div>
|
||||
<p className="text-[11px] uppercase tracking-[0.22em] text-[--color-fg-subtle]">
|
||||
Marketplace
|
||||
</p>
|
||||
<h2 className="mt-3 text-[32px] font-semibold leading-[1.1] tracking-tight sm:text-[40px]">
|
||||
Skip the prompt.
|
||||
<br />
|
||||
<span className="text-[--color-fg-muted]">Fork what works.</span>
|
||||
</h2>
|
||||
<p className="mt-5 max-w-md text-[14px] leading-relaxed text-[--color-fg-muted]">
|
||||
The marketplace is a library of working MCP servers the community already built.
|
||||
Fork one, paste your credentials, deploy. Or publish yours and let others build on it.
|
||||
</p>
|
||||
|
||||
<ul className="mt-8 space-y-5">
|
||||
{MARKETPLACE_POINTS.map((p) => (
|
||||
<li key={p.t} className="flex items-start gap-3">
|
||||
<span
|
||||
aria-hidden
|
||||
className="mt-[7px] size-1.5 shrink-0 rounded-full bg-[--color-accent]"
|
||||
/>
|
||||
<div>
|
||||
<h3 className="text-[14px] font-semibold tracking-tight">{p.t}</h3>
|
||||
<p className="mt-1 text-[13px] leading-relaxed text-[--color-fg-muted]">
|
||||
{p.d}
|
||||
</p>
|
||||
</div>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
|
||||
<PulseLink
|
||||
href="/templates"
|
||||
className="inline-flex h-9 shrink-0 items-center justify-center rounded-md border border-[--color-border] bg-[--color-bg-elevated] px-4 text-[13px] text-[--color-fg-muted] transition-colors hover:text-[--color-fg]"
|
||||
className="mt-8 inline-flex h-9 items-center gap-2 rounded-md bg-[--color-accent] px-4 text-[13px] font-medium text-white transition-colors duration-200 hover:bg-[#5557e8]"
|
||||
>
|
||||
Browse the marketplace →
|
||||
</Link>
|
||||
</div>
|
||||
<div className="grid gap-3 md:grid-cols-3">
|
||||
{MARKETPLACE_POINTS.map((p) => (
|
||||
<div key={p.t} className="panel p-5">
|
||||
<h3 className="text-[15px] font-semibold tracking-tight">{p.t}</h3>
|
||||
<p className="mt-2 text-[13px] leading-relaxed text-[--color-fg-muted]">{p.d}</p>
|
||||
</div>
|
||||
))}
|
||||
</PulseLink>
|
||||
</div>
|
||||
|
||||
{/* Right — mock marketplace browser frame */}
|
||||
<MarketplaceMock />
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Pricing */}
|
||||
<section id="pricing" className="border-b border-[--color-border] py-14 sm:py-20">
|
||||
{/* ── Pricing · 4 cards with Pro highlighted as recommended ─────
|
||||
Archetype: centred header + 4-card row where the Pro tier is
|
||||
visually distinct (accent border, indigo glow shadow, floating
|
||||
"recommended" pill, slightly elevated). Other tiers stay calm
|
||||
so the eye lands on Pro first. Big price typography (text-
|
||||
[40px]) replaces the previous flat 26px. */}
|
||||
<section id="pricing" className="border-b border-[--color-border] py-20 sm:py-28">
|
||||
<div className="mx-auto max-w-6xl px-6">
|
||||
<div className="mb-10 max-w-2xl">
|
||||
<h2 className="text-[28px] font-semibold tracking-tight">Pricing</h2>
|
||||
<p className="mt-2 text-[14px] text-[--color-fg-muted]">
|
||||
Pay for tool calls, not for boilerplate.
|
||||
<div className="mb-14 text-center">
|
||||
<p className="text-[11px] uppercase tracking-[0.22em] text-[--color-fg-subtle]">
|
||||
Pricing
|
||||
</p>
|
||||
<h2 className="mt-3 text-[32px] font-semibold leading-[1.1] tracking-tight sm:text-[40px]">
|
||||
Pay for tool calls.
|
||||
<br />
|
||||
<span className="text-[--color-fg-muted]">Not for boilerplate.</span>
|
||||
</h2>
|
||||
</div>
|
||||
<div className="grid gap-3 md:grid-cols-4">
|
||||
{TIERS.map((t, i) => (
|
||||
<div
|
||||
key={t.name}
|
||||
className={`panel p-5 ${i === 1 ? 'border-[--color-accent]/40' : ''}`}
|
||||
>
|
||||
<div className="text-[12px] uppercase tracking-wider text-[--color-fg-subtle]">
|
||||
{t.name}
|
||||
|
||||
<div className="grid gap-5 md:grid-cols-2 lg:grid-cols-4">
|
||||
{TIERS.map((t) => {
|
||||
const featured = t.name === 'Pro';
|
||||
return (
|
||||
<div
|
||||
key={t.name}
|
||||
className={`relative flex flex-col gap-6 rounded-xl border p-6 transition-colors ${
|
||||
featured
|
||||
? 'border-[--color-accent] bg-[--color-bg-elevated]'
|
||||
: 'border-[--color-border] bg-[--color-bg-elevated] hover:border-[--color-border-strong]'
|
||||
}`}
|
||||
style={
|
||||
featured
|
||||
? {
|
||||
boxShadow:
|
||||
'0 0 0 4px rgba(99, 102, 241, 0.12), 0 24px 50px rgba(0, 0, 0, 0.35)',
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
>
|
||||
{featured && (
|
||||
<span
|
||||
className="absolute -top-3 left-1/2 -translate-x-1/2 whitespace-nowrap rounded-full border border-[--color-accent] px-3 py-0.5 text-[10px] font-semibold uppercase tracking-[0.18em] text-[--color-accent]"
|
||||
style={{ backgroundColor: 'var(--color-bg)' }}
|
||||
>
|
||||
Recommended
|
||||
</span>
|
||||
)}
|
||||
|
||||
<div>
|
||||
<div className="text-[11px] font-medium uppercase tracking-[0.18em] text-[--color-fg-muted]">
|
||||
{t.name}
|
||||
</div>
|
||||
<div className="mt-3 flex items-baseline gap-2">
|
||||
<span className="text-[40px] font-semibold leading-none tracking-tight text-[--color-fg]">
|
||||
{t.price}
|
||||
</span>
|
||||
<span className="text-[12px] text-[--color-fg-subtle]">{t.tag}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ul className="flex flex-1 flex-col gap-2.5 border-t border-[--color-border] pt-5 text-[13px] text-[--color-fg-muted]">
|
||||
{t.features.map((f) => (
|
||||
<li key={f} className="flex items-start gap-2.5">
|
||||
<span
|
||||
aria-hidden
|
||||
className={`mt-[7px] size-1 shrink-0 rounded-full ${
|
||||
featured ? 'bg-[--color-accent]' : 'bg-[--color-fg-subtle]'
|
||||
}`}
|
||||
/>
|
||||
<span>{f}</span>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
<div className="mt-2 flex items-baseline gap-1">
|
||||
<span className="text-[26px] font-semibold tracking-tight">{t.price}</span>
|
||||
<span className="text-[12px] text-[--color-fg-subtle]">{t.tag}</span>
|
||||
</div>
|
||||
<ul className="mt-4 space-y-1.5 text-[12.5px] text-[--color-fg-muted]">
|
||||
{t.features.map((f) => (
|
||||
<li key={f}>— {f}</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
))}
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@ -379,3 +528,105 @@ export default function Landing() {
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mock marketplace preview.
|
||||
*
|
||||
* Static, server-rendered. Renders a faux-browser frame containing four
|
||||
* realistic template cards so the visitor sees what the marketplace
|
||||
* actually looks like rather than reading marketing copy about it.
|
||||
*
|
||||
* The card data lives in `MOCK_TEMPLATES` at the top of this file —
|
||||
* those are real template-flavoured names, modest fork counts, and the
|
||||
* `core` / `community` author tag. Numbers are deliberately small and
|
||||
* truthful-looking for a young marketplace; nothing here pretends to be
|
||||
* GitHub-trending traffic.
|
||||
*/
|
||||
function MarketplaceMock() {
|
||||
return (
|
||||
<div
|
||||
className="overflow-hidden rounded-xl border border-[--color-border-strong] bg-[--color-bg-elevated]"
|
||||
style={{ boxShadow: '0 24px 60px rgba(0, 0, 0, 0.45)' }}
|
||||
>
|
||||
{/* Browser chrome */}
|
||||
<div className="flex items-center gap-3 border-b border-[--color-border] bg-[--color-bg-subtle] px-4 py-3">
|
||||
<div className="flex gap-1.5">
|
||||
<span className="size-2.5 rounded-full bg-zinc-700" />
|
||||
<span className="size-2.5 rounded-full bg-zinc-700" />
|
||||
<span className="size-2.5 rounded-full bg-zinc-700" />
|
||||
</div>
|
||||
<div className="mono flex-1 truncate rounded-md border border-[--color-border] bg-[--color-bg] px-3 py-1 text-[11px] text-[--color-fg-subtle]">
|
||||
buildmymcpserver.com/templates
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Toolbar inside the page chrome */}
|
||||
<div className="flex items-center justify-between gap-4 border-b border-[--color-border] px-5 py-3">
|
||||
<div className="flex items-center gap-3">
|
||||
<span className="text-[13px] font-semibold tracking-tight text-[--color-fg]">
|
||||
Templates
|
||||
</span>
|
||||
<span className="text-[11px] text-[--color-fg-subtle]">·</span>
|
||||
<span className="text-[11px] text-[--color-fg-subtle]">{MOCK_TEMPLATES.length} live</span>
|
||||
</div>
|
||||
<div className="hidden items-center gap-1.5 rounded-md border border-[--color-border] px-2 py-1 sm:flex">
|
||||
<span className="text-[11px] text-[--color-fg-subtle]">trending</span>
|
||||
<ChevronDown size={11} className="text-[--color-fg-subtle]" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Template cards grid */}
|
||||
<div className="grid gap-3 p-4 sm:grid-cols-2">
|
||||
{MOCK_TEMPLATES.map((t) => (
|
||||
<div
|
||||
key={t.name}
|
||||
className="rounded-md border border-[--color-border] bg-[--color-bg-subtle] p-4 transition-colors hover:border-[--color-accent]/40"
|
||||
>
|
||||
<div className="flex items-start justify-between gap-3">
|
||||
<div className="min-w-0">
|
||||
<div className="mono truncate text-[13px] font-semibold tracking-tight text-[--color-fg]">
|
||||
{t.name}
|
||||
</div>
|
||||
<div className="mt-1 flex items-center gap-1.5">
|
||||
<span className="mono text-[10px] uppercase tracking-wider text-[--color-fg-subtle]">
|
||||
{t.author}
|
||||
</span>
|
||||
{t.verified && (
|
||||
<span className="inline-flex items-center gap-0.5 rounded-full border border-[--color-accent]/50 bg-[--color-accent]/10 px-1.5 py-px text-[9.5px] font-medium uppercase tracking-wider text-[--color-accent]">
|
||||
✓ verified
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-4 flex items-center justify-between text-[11px] text-[--color-fg-subtle]">
|
||||
<span className="mono">{t.tools} tools</span>
|
||||
<span className="mono inline-flex items-center gap-1">
|
||||
<ForkGlyph />
|
||||
{t.forks}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function ForkGlyph() {
|
||||
return (
|
||||
<svg width="11" height="11" viewBox="0 0 14 14" fill="none" aria-hidden>
|
||||
<circle cx="3.5" cy="3" r="1.4" stroke="currentColor" strokeWidth={1.2} />
|
||||
<circle cx="10.5" cy="3" r="1.4" stroke="currentColor" strokeWidth={1.2} />
|
||||
<circle cx="7" cy="11" r="1.4" stroke="currentColor" strokeWidth={1.2} />
|
||||
<path
|
||||
d="M 3.5 4.5 L 3.5 6.5 Q 3.5 7.5 4.5 7.5 L 9.5 7.5 Q 10.5 7.5 10.5 6.5 L 10.5 4.5"
|
||||
stroke="currentColor"
|
||||
strokeWidth={1.2}
|
||||
fill="none"
|
||||
/>
|
||||
<path d="M 7 7.5 L 7 9.5" stroke="currentColor" strokeWidth={1.2} />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user