Skip to content

Commit 21c7e37

Browse files
committed
Add $VOICEBOX token section below the hero
1 parent 45b64e0 commit 21c7e37

2 files changed

Lines changed: 109 additions & 0 deletions

File tree

landing/src/app/page.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {Navbar} from "@/components/Navbar";
1212
import {Personalities} from "@/components/Personalities";
1313
import {AppleIcon, LinuxIcon, WindowsIcon} from "@/components/PlatformIcons";
1414
import {SupportedModels} from "@/components/SupportedModels";
15+
import {TokenSection} from "@/components/TokenSection";
1516
import {TutorialsSection} from "@/components/TutorialsSection";
1617
import {VoiceCreator} from "@/components/VoiceCreator";
1718
import {GITHUB_REPO} from "@/lib/constants";
@@ -130,6 +131,9 @@ export default function Home() {
130131
</div>
131132
</section>
132133

134+
{/* ── $VOICEBOX token ──────────────────────────────────────── */}
135+
<TokenSection />
136+
133137
{/* ── Features ─────────────────────────────────────────────── */}
134138
<Features />
135139

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
"use client";
2+
3+
import {ArrowUpRight, Check, Coins, Copy} from "lucide-react";
4+
import {useState} from "react";
5+
import {
6+
TOKEN_CONTRACT_ADDRESS,
7+
TOKEN_PUMP_URL,
8+
TOKEN_TICKER,
9+
} from "@/lib/constants";
10+
11+
export function TokenSection() {
12+
const [copied, setCopied] = useState(false);
13+
14+
const handleCopy = async () => {
15+
try {
16+
await navigator.clipboard.writeText(TOKEN_CONTRACT_ADDRESS);
17+
setCopied(true);
18+
setTimeout(() => setCopied(false), 2000);
19+
} catch {
20+
// Clipboard unavailable (e.g. insecure context) — silently no-op.
21+
}
22+
};
23+
24+
return (
25+
<section id="token" className="border-t border-border py-24">
26+
<div className="relative mx-auto max-w-4xl px-6">
27+
{/* Subtle accent glow */}
28+
<div className="pointer-events-none absolute inset-0 -z-10 flex justify-center">
29+
<div className="h-[260px] w-[520px] rounded-full bg-accent/10 blur-[140px]" />
30+
</div>
31+
32+
{/* Header */}
33+
<div className="text-center mb-10">
34+
<div className="inline-flex items-center gap-2 rounded-full border border-border/60 bg-card/40 backdrop-blur-sm px-3 py-1 mb-4">
35+
<Coins className="h-3 w-3 text-accent" />
36+
<span className="text-[11px] font-medium uppercase tracking-wider text-muted-foreground">
37+
Official token
38+
</span>
39+
</div>
40+
<h2 className="text-3xl font-semibold tracking-tight text-foreground md:text-4xl mb-4">
41+
{TOKEN_TICKER} on Solana
42+
</h2>
43+
<p className="text-muted-foreground max-w-2xl mx-auto">
44+
The official {TOKEN_TICKER} token for supporters who want to back
45+
the project and have some fun. Voicebox is and always will be{" "}
46+
<b className="text-foreground">free and open source</b> — the token
47+
is entirely optional and not required to use anything here.
48+
</p>
49+
</div>
50+
51+
{/* Contract address + CTA */}
52+
<div className="mx-auto max-w-2xl rounded-2xl border border-border bg-card/60 backdrop-blur-sm p-5 sm:p-6">
53+
<div className="flex items-center gap-2 mb-3">
54+
<span className="text-[11px] font-medium uppercase tracking-wider text-muted-foreground">
55+
Contract address
56+
</span>
57+
<span className="ml-auto inline-flex items-center gap-1.5 rounded-full border border-border/60 bg-background/60 px-2 py-0.5 text-[10px] font-medium text-muted-foreground">
58+
<span className="h-1.5 w-1.5 rounded-full bg-accent" />
59+
Solana
60+
</span>
61+
</div>
62+
63+
<div className="flex flex-col gap-3 sm:flex-row sm:items-center">
64+
{/* Address bar */}
65+
<button
66+
type="button"
67+
onClick={handleCopy}
68+
title="Copy contract address"
69+
aria-label={
70+
copied ? "Contract address copied" : "Copy contract address"
71+
}
72+
className="group flex min-w-0 flex-1 items-center gap-3 rounded-xl border border-border bg-background/60 px-4 py-3 text-left transition-colors hover:border-accent/40"
73+
>
74+
<code className="min-w-0 flex-1 truncate font-mono text-xs text-foreground/90 sm:text-sm">
75+
{TOKEN_CONTRACT_ADDRESS}
76+
</code>
77+
{copied ? (
78+
<span className="inline-flex shrink-0 items-center gap-1.5 text-xs font-medium text-accent">
79+
<Check className="h-4 w-4" />
80+
Copied
81+
</span>
82+
) : (
83+
<span className="inline-flex shrink-0 items-center gap-1.5 text-xs font-medium text-muted-foreground transition-colors group-hover:text-foreground">
84+
<Copy className="h-4 w-4" />
85+
Copy
86+
</span>
87+
)}
88+
</button>
89+
90+
{/* Buy CTA */}
91+
<a
92+
href={TOKEN_PUMP_URL}
93+
target="_blank"
94+
rel="noopener noreferrer"
95+
className="inline-flex shrink-0 items-center justify-center gap-2 rounded-xl bg-accent px-5 py-3 text-sm font-semibold text-white shadow-[0_4px_20px_hsl(43_60%_50%/0.3),inset_0_2px_0_rgba(255,255,255,0.2),inset_0_-2px_0_rgba(0,0,0,0.1)] transition-all hover:bg-accent-faint"
96+
>
97+
Buy on pump.fun
98+
<ArrowUpRight className="h-4 w-4" />
99+
</a>
100+
</div>
101+
</div>
102+
</div>
103+
</section>
104+
);
105+
}

0 commit comments

Comments
 (0)