Skip to content

Commit 860d5eb

Browse files
sktbrdclaude
andcommitted
feat(base): pitch page for Base ecosystem programs
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent eea2936 commit 860d5eb

7 files changed

Lines changed: 253 additions & 0 deletions

File tree

messages/en/base.json

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
{
2+
"eyebrow": "Built on Base",
3+
"title": "Gnars runs entirely on Base",
4+
"lede": "Gnars is a community-owned action-sports DAO running its whole stack on Base — daily auctions, onchain governance, a transparent treasury, NFT drops, swaps, and staking. Chain id 8453, end to end, since day one.",
5+
"ctaAuctions": "See the live auction",
6+
"ctaGovernance": "Browse governance",
7+
"featuresTitle": "A complete DAO, all onchain",
8+
"features": {
9+
"auctions": {
10+
"title": "Daily auctions",
11+
"desc": "One Gnar at a time: the daily auction that funds the treasury and mints membership, Nouns-style."
12+
},
13+
"governance": {
14+
"title": "Onchain governance",
15+
"desc": "Proposals, voting, queueing, and execution through the Nouns Builder governor — every decision settles on Base."
16+
},
17+
"treasury": {
18+
"title": "Transparent treasury",
19+
"desc": "Every asset, inflow, and DeFi position readable onchain — and when a price can't be read, the page says so instead of printing a zero."
20+
},
21+
"droposals": {
22+
"title": "Droposals",
23+
"desc": "NFT drops proposed, voted, and executed by governance, with revenue splits verified onchain."
24+
},
25+
"swap": {
26+
"title": "Swap",
27+
"desc": "Token swaps on Base via the 0x API, straight from the site."
28+
},
29+
"staking": {
30+
"title": "Staking",
31+
"desc": "Back Gnars riders through yield vaults, and back the Gnars Builder subnet on Morpheus with MOR — both live on Base."
32+
}
33+
},
34+
"underHoodTitle": "Base-native under the hood",
35+
"underHood": {
36+
"aa": "Account abstraction with sponsored gas — smart accounts by default, so a first-timer's vote or bid costs them nothing.",
37+
"login": "Social and email login next to every major wallet — built for skaters, not just crypto natives.",
38+
"farcaster": "Farcaster mini-app integration — the auction and stake flows run inside the feed.",
39+
"mobile": "Mobile-first: every DAO feature works on a phone."
40+
},
41+
"culture": "What Gnars brings to Base is an audience crypto doesn't reach on its own: skate, BMX, and surf culture, funding real riders and real videos through a DAO that actually executes onchain."
42+
}

messages/en/metadata.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
{
2+
"base": {
3+
"title": "Gnars on Base — A Complete Onchain DAO",
4+
"description": "Gnars runs its whole stack on Base: daily auctions, onchain governance, a transparent treasury, droposals, swaps, and staking — with sponsored gas and social login."
5+
},
26
"morpheus": {
37
"title": "Gnars × Morpheus — Stake or Die",
48
"description": "Gnars runs a Builder subnet on Morpheus, the decentralized AI network. Stake MOR to back the subnet, unlock the $gnars airdrop bucket by bucket, and put Morpheus in front of skate culture."

messages/pt-br/base.json

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
{
2+
"eyebrow": "Construído na Base",
3+
"title": "A Gnars roda inteira na Base",
4+
"lede": "A Gnars é uma DAO de esportes de ação de propriedade da comunidade rodando toda a sua stack na Base — leilões diários, governança onchain, tesouro transparente, drops de NFT, swaps e staking. Chain id 8453, de ponta a ponta, desde o primeiro dia.",
5+
"ctaAuctions": "Ver o leilão ao vivo",
6+
"ctaGovernance": "Explorar a governança",
7+
"featuresTitle": "Uma DAO completa, toda onchain",
8+
"features": {
9+
"auctions": {
10+
"title": "Leilões diários",
11+
"desc": "Um Gnar por vez: o leilão diário que financia o tesouro e minta a membership, no estilo Nouns."
12+
},
13+
"governance": {
14+
"title": "Governança onchain",
15+
"desc": "Propostas, votação, fila e execução pelo governor do Nouns Builder — toda decisão liquida na Base."
16+
},
17+
"treasury": {
18+
"title": "Tesouro transparente",
19+
"desc": "Todo ativo, entrada e posição DeFi legível onchain — e quando um preço não pode ser lido, a página avisa em vez de imprimir zero."
20+
},
21+
"droposals": {
22+
"title": "Droposals",
23+
"desc": "Drops de NFT propostos, votados e executados pela governança, com splits de receita verificados onchain."
24+
},
25+
"swap": {
26+
"title": "Swap",
27+
"desc": "Swaps de token na Base via 0x API, direto do site."
28+
},
29+
"staking": {
30+
"title": "Staking",
31+
"desc": "Apoie os riders da Gnars com vaults de rendimento, e apoie a subnet Gnars Builder na Morpheus com MOR — os dois ao vivo na Base."
32+
}
33+
},
34+
"underHoodTitle": "Base-native por baixo do capô",
35+
"underHood": {
36+
"aa": "Account abstraction com gás patrocinado — smart accounts por padrão, então o primeiro voto ou lance de alguém não custa nada.",
37+
"login": "Login social e por e-mail ao lado de todas as carteiras principais — feito pra skatista, não só pra cripto-nativo.",
38+
"farcaster": "Integração de mini-app do Farcaster — os fluxos de leilão e stake rodam dentro do feed.",
39+
"mobile": "Mobile-first: toda funcionalidade da DAO funciona no celular."
40+
},
41+
"culture": "O que a Gnars traz pra Base é uma audiência que a cripto não alcança sozinha: a cultura do skate, BMX e surf, financiando riders e vídeos de verdade através de uma DAO que executa onchain de fato."
42+
}

messages/pt-br/metadata.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
{
2+
"base": {
3+
"title": "Gnars na Base — Uma DAO Completa Onchain",
4+
"description": "A Gnars roda toda a sua stack na Base: leilões diários, governança onchain, tesouro transparente, droposals, swaps e staking — com gás patrocinado e login social."
5+
},
26
"morpheus": {
37
"title": "Gnars × Morpheus — Stake or Die",
48
"description": "A Gnars roda uma subnet Builder na Morpheus, a rede de IA descentralizada. Faça stake de MOR para apoiar a subnet, destravar o airdrop de $gnars bucket por bucket e colocar a Morpheus na frente da cultura do skate."

src/app/[locale]/base/page.tsx

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import type { Metadata } from "next";
2+
import { getTranslations, setRequestLocale } from "next-intl/server";
3+
import { BasePageContent } from "@/components/base/BasePageContent";
4+
5+
// The pitch page for Base ecosystem programs (Base Batches): everything Gnars
6+
// runs on Base, with links to the live surfaces. See BasePageContent.
7+
8+
export async function generateMetadata({
9+
params,
10+
}: {
11+
params: Promise<{ locale: string }>;
12+
}): Promise<Metadata> {
13+
const { locale } = await params;
14+
const t = await getTranslations({ locale, namespace: "metadata.base" });
15+
const path = "/base";
16+
const canonical = locale === "en" ? path : `/pt-br${path}`;
17+
return {
18+
title: t("title"),
19+
description: t("description"),
20+
alternates: {
21+
canonical,
22+
languages: {
23+
en: path,
24+
"pt-br": `/pt-br${path}`,
25+
"x-default": path,
26+
},
27+
},
28+
openGraph: {
29+
title: t("title"),
30+
description: t("description"),
31+
locale: locale === "pt-br" ? "pt_BR" : "en_US",
32+
type: "website",
33+
},
34+
twitter: {
35+
card: "summary_large_image",
36+
title: t("title"),
37+
description: t("description"),
38+
},
39+
};
40+
}
41+
42+
export default async function BasePage({ params }: { params: Promise<{ locale: string }> }) {
43+
const { locale } = await params;
44+
setRequestLocale(locale);
45+
46+
return (
47+
<div className="py-10">
48+
<BasePageContent />
49+
</div>
50+
);
51+
}
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
"use client";
2+
3+
// The /base landing — the pitch page for Base ecosystem programs (Base Batches
4+
// and friends). One job: show that Gnars is a COMPLETE onchain DAO living on
5+
// Base — auctions, governance, treasury, droposals, swap, staking — with the
6+
// Base-native plumbing (sponsored gas, social login, Farcaster mini-app)
7+
// spelled out. Every feature card links to the live surface, because the pitch
8+
// is that it all already works.
9+
import { useTranslations } from "next-intl";
10+
import { ArrowLeftRight, Disc3, Gavel, HandCoins, Landmark, PiggyBank } from "lucide-react";
11+
import { CARD, CARD_PAD, MUTED } from "@/components/stake/stake-ui";
12+
import { Button } from "@/components/ui/button";
13+
import { Link } from "@/i18n/navigation";
14+
15+
// Base brand blue — the page's one accent, used the way /stake uses gold.
16+
const BASE_BLUE = "#0052FF";
17+
18+
const FEATURES = [
19+
{ key: "auctions", href: "/auctions", Icon: Gavel },
20+
{ key: "governance", href: "/proposals", Icon: Landmark },
21+
{ key: "treasury", href: "/treasury", Icon: PiggyBank },
22+
{ key: "droposals", href: "/droposals", Icon: Disc3 },
23+
{ key: "swap", href: "/swap", Icon: ArrowLeftRight },
24+
{ key: "staking", href: "/stake", Icon: HandCoins },
25+
] as const;
26+
27+
const UNDER_HOOD = ["aa", "login", "farcaster", "mobile"] as const;
28+
29+
export function BasePageContent() {
30+
const t = useTranslations("base");
31+
32+
return (
33+
<div className="mx-auto flex w-full max-w-5xl flex-col gap-6 px-4 sm:px-6">
34+
{/* Hero */}
35+
<section className={`${CARD} ${CARD_PAD} sm:p-8`}>
36+
<span
37+
className="inline-flex items-center gap-1.5 rounded-full px-3 py-1 text-[11px] font-bold uppercase tracking-wider text-white"
38+
style={{ backgroundColor: BASE_BLUE }}
39+
>
40+
{/* Base's mark is a plain circle — drawn, not an asset we redistribute. */}
41+
<span className="h-2.5 w-2.5 rounded-full bg-white" aria-hidden />
42+
{t("eyebrow")}
43+
</span>
44+
<h1 className="mt-3 text-3xl font-black tracking-tight sm:text-5xl">{t("title")}</h1>
45+
<p className={`mt-3 max-w-2xl text-sm sm:text-base ${MUTED}`}>{t("lede")}</p>
46+
<div className="mt-5 flex flex-wrap items-center gap-3">
47+
<Button
48+
asChild
49+
className="border-0 font-bold text-white hover:opacity-90"
50+
style={{ backgroundColor: BASE_BLUE }}
51+
>
52+
<Link href="/auctions">{t("ctaAuctions")}</Link>
53+
</Button>
54+
<Button asChild variant="outline">
55+
<Link href="/proposals">{t("ctaGovernance")}</Link>
56+
</Button>
57+
</div>
58+
</section>
59+
60+
{/* Feature grid — each card is a link to the live surface */}
61+
<section className={`${CARD} ${CARD_PAD} sm:p-8`}>
62+
<h2 className="text-lg font-bold tracking-tight">{t("featuresTitle")}</h2>
63+
<ul className="mt-4 grid gap-3 sm:grid-cols-2 lg:grid-cols-3">
64+
{FEATURES.map(({ key, href, Icon }) => (
65+
<li key={key}>
66+
<Link
67+
href={href}
68+
className="group flex h-full flex-col rounded-2xl border border-border/60 bg-background/40 p-4 transition-colors hover:border-[#0052FF]/50"
69+
>
70+
<span
71+
className="flex h-10 w-10 items-center justify-center rounded-xl text-white"
72+
style={{ backgroundColor: BASE_BLUE }}
73+
>
74+
<Icon className="h-5 w-5" aria-hidden />
75+
</span>
76+
<span className="mt-3 text-sm font-semibold group-hover:underline">
77+
{t(`features.${key}.title`)}
78+
</span>
79+
<span className={`mt-1 text-xs leading-relaxed ${MUTED}`}>
80+
{t(`features.${key}.desc`)}
81+
</span>
82+
</Link>
83+
</li>
84+
))}
85+
</ul>
86+
</section>
87+
88+
{/* The Base-native plumbing — the part reviewers actually ask about */}
89+
<section className={`${CARD} ${CARD_PAD}`}>
90+
<h2 className="text-lg font-bold tracking-tight">{t("underHoodTitle")}</h2>
91+
<ul className="mt-3 grid gap-2.5 sm:grid-cols-2">
92+
{UNDER_HOOD.map((k) => (
93+
<li key={k} className="flex items-start gap-2.5 text-sm">
94+
<span
95+
className="mt-1.5 h-2 w-2 shrink-0 rounded-full"
96+
style={{ backgroundColor: BASE_BLUE }}
97+
aria-hidden
98+
/>
99+
<span className={MUTED}>{t(`underHood.${k}`)}</span>
100+
</li>
101+
))}
102+
</ul>
103+
<p className="mt-5 max-w-3xl text-sm leading-relaxed">{t("culture")}</p>
104+
</section>
105+
</div>
106+
);
107+
}

src/i18n/request.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ const NAMESPACES = [
2626
"map",
2727
"installations",
2828
"bounties",
29+
"base",
2930
"blogs",
3031
"shop",
3132
"store",
@@ -62,6 +63,7 @@ const loaders: Record<string, () => Promise<unknown>> = {
6263
"en/map": () => import("../../messages/en/map.json"),
6364
"en/installations": () => import("../../messages/en/installations.json"),
6465
"en/bounties": () => import("../../messages/en/bounties.json"),
66+
"en/base": () => import("../../messages/en/base.json"),
6567
"en/blogs": () => import("../../messages/en/blogs.json"),
6668
"en/shop": () => import("../../messages/en/shop.json"),
6769
"en/store": () => import("../../messages/en/store.json"),
@@ -92,6 +94,7 @@ const loaders: Record<string, () => Promise<unknown>> = {
9294
"pt-br/map": () => import("../../messages/pt-br/map.json"),
9395
"pt-br/installations": () => import("../../messages/pt-br/installations.json"),
9496
"pt-br/bounties": () => import("../../messages/pt-br/bounties.json"),
97+
"pt-br/base": () => import("../../messages/pt-br/base.json"),
9598
"pt-br/blogs": () => import("../../messages/pt-br/blogs.json"),
9699
"pt-br/shop": () => import("../../messages/pt-br/shop.json"),
97100
"pt-br/store": () => import("../../messages/pt-br/store.json"),

0 commit comments

Comments
 (0)