diff --git a/apps/web/public/fonts/AnthropicMono-Italic.woff2 b/apps/web/public/fonts/AnthropicMono-Italic.woff2
new file mode 100644
index 0000000..526fad9
Binary files /dev/null and b/apps/web/public/fonts/AnthropicMono-Italic.woff2 differ
diff --git a/apps/web/public/fonts/AnthropicMono-Roman.woff2 b/apps/web/public/fonts/AnthropicMono-Roman.woff2
new file mode 100644
index 0000000..f9f73ea
Binary files /dev/null and b/apps/web/public/fonts/AnthropicMono-Roman.woff2 differ
diff --git a/apps/web/public/fonts/AnthropicSans-Italic.woff2 b/apps/web/public/fonts/AnthropicSans-Italic.woff2
new file mode 100644
index 0000000..84e7ed1
Binary files /dev/null and b/apps/web/public/fonts/AnthropicSans-Italic.woff2 differ
diff --git a/apps/web/public/fonts/AnthropicSans-Roman.woff2 b/apps/web/public/fonts/AnthropicSans-Roman.woff2
new file mode 100644
index 0000000..57824da
Binary files /dev/null and b/apps/web/public/fonts/AnthropicSans-Roman.woff2 differ
diff --git a/apps/web/public/fonts/AnthropicSerif-Italic.woff2 b/apps/web/public/fonts/AnthropicSerif-Italic.woff2
new file mode 100644
index 0000000..4b0d098
Binary files /dev/null and b/apps/web/public/fonts/AnthropicSerif-Italic.woff2 differ
diff --git a/apps/web/public/fonts/AnthropicSerif-Roman.woff2 b/apps/web/public/fonts/AnthropicSerif-Roman.woff2
new file mode 100644
index 0000000..ef2960a
Binary files /dev/null and b/apps/web/public/fonts/AnthropicSerif-Roman.woff2 differ
diff --git a/apps/web/public/images/hero-mesh.png b/apps/web/public/images/hero-mesh.png
new file mode 100644
index 0000000..d351e58
Binary files /dev/null and b/apps/web/public/images/hero-mesh.png differ
diff --git a/apps/web/src/app/[locale]/(marketing)/legal/[slug]/page.tsx b/apps/web/src/app/[locale]/(marketing)/legal/[slug]/page.tsx
deleted file mode 100644
index af8884e..0000000
--- a/apps/web/src/app/[locale]/(marketing)/legal/[slug]/page.tsx
+++ /dev/null
@@ -1,76 +0,0 @@
-import { notFound } from "next/navigation";
-
-import {
- CollectionType,
- getContentItemBySlug,
- getContentItems,
-} from "@turbostarter/cms";
-import { getTranslation } from "@turbostarter/i18n/server";
-
-import { getMetadata } from "~/lib/metadata";
-import { Mdx } from "~/modules/common/mdx";
-import {
- Section,
- SectionBadge,
- SectionDescription,
- SectionHeader,
- SectionTitle,
-} from "~/modules/marketing/layout/section";
-
-interface PageParams {
- params: Promise<{
- slug: string;
- locale: string;
- }>;
-}
-
-export default async function Page({ params }: PageParams) {
- const item = getContentItemBySlug({
- collection: CollectionType.LEGAL,
- slug: (await params).slug,
- locale: (await params).locale,
- });
-
- if (!item) {
- return notFound();
- }
-
- const { t } = await getTranslation({ ns: "common" });
-
- return (
-
-
- {t("legal.label")}
- {item.title}
- {item.description}
-
-
-
- );
-}
-
-export function generateStaticParams() {
- return getContentItems({ collection: CollectionType.LEGAL }).items.map(
- ({ slug, locale }) => ({
- slug,
- locale,
- }),
- );
-}
-
-export async function generateMetadata({ params }: PageParams) {
- const item = getContentItemBySlug({
- collection: CollectionType.LEGAL,
- slug: (await params).slug,
- locale: (await params).locale,
- });
-
- if (!item) {
- return notFound();
- }
-
- return getMetadata({
- title: item.title,
- description: item.description,
- })({ params });
-}
diff --git a/apps/web/src/app/[locale]/(marketing)/page.tsx b/apps/web/src/app/[locale]/(marketing)/page.tsx
index c859939..af3898b 100644
--- a/apps/web/src/app/[locale]/(marketing)/page.tsx
+++ b/apps/web/src/app/[locale]/(marketing)/page.tsx
@@ -1,42 +1,29 @@
-"use client";
-
-import { useTranslation } from "@turbostarter/i18n";
-import { buttonVariants } from "@turbostarter/ui-web/button";
-import { Icons } from "@turbostarter/ui-web/icons";
-
-import { pathsConfig } from "~/config/paths";
-import { TurboLink } from "~/modules/common/turbo-link";
+import { Hero } from "~/modules/marketing/home/hero";
+import { Surfaces } from "~/modules/marketing/home/surfaces";
+import { Pricing } from "~/modules/marketing/home/pricing";
+import { LaptopToLaptop } from "~/modules/marketing/home/laptop-to-laptop";
+import { Features } from "~/modules/marketing/home/features";
+import { MeetsYou } from "~/modules/marketing/home/meets-you";
+import { FAQ } from "~/modules/marketing/home/faq";
+import { CallToAction } from "~/modules/marketing/home/cta";
+import { LatestNewsToaster } from "~/modules/marketing/home/toaster";
const HomePage = () => {
- const { t } = useTranslation("common");
-
return (
-
-
-
- {t("home.title", { defaultValue: "Welcome to TurboStarter" })}
-
-
- {t("home.description", { defaultValue: "The fastest way to build your next SaaS. Authentication, billing, database, and UI components — all pre-configured and ready to go." })}
-
+ Anthropic built Claude Code per developer. The next unlock is
+ between developers. Build the layer with us.
+
+
+
+
+
+ Star on GitHub
+
+ →
+
+
+
+ Read the docs
+
+
+
+
+
+ );
+};
diff --git a/apps/web/src/modules/marketing/home/faq.tsx b/apps/web/src/modules/marketing/home/faq.tsx
index 786b8f1..511b98d 100644
--- a/apps/web/src/modules/marketing/home/faq.tsx
+++ b/apps/web/src/modules/marketing/home/faq.tsx
@@ -1,89 +1,103 @@
-import { getTranslation } from "@turbostarter/i18n/server";
-import {
- Accordion,
- AccordionContent,
- AccordionItem,
- AccordionTrigger,
-} from "@turbostarter/ui-web/accordion";
-import { buttonVariants } from "@turbostarter/ui-web/button";
-import { Icons } from "@turbostarter/ui-web/icons";
+"use client";
+import { useState } from "react";
+import { Reveal } from "./_reveal";
-import { pathsConfig } from "~/config/paths";
-import { TurboLink } from "~/modules/common/turbo-link";
-import {
- Section,
- SectionHeader,
- SectionBadge,
- SectionTitle,
- SectionDescription,
-} from "~/modules/marketing/layout/section";
-
-const questions = [
- {
- question: "faq.question.whatDoesOurPlatformDo.question",
- answer: "faq.question.whatDoesOurPlatformDo.answer",
- },
- {
- question: "faq.question.howWillThisBenefitMyBusiness.question",
- answer: "faq.question.howWillThisBenefitMyBusiness.answer",
- },
- {
- question: "faq.question.isMyDataSafe.question",
- answer: "faq.question.isMyDataSafe.answer",
- },
- {
- question: "faq.question.whatKindOfIntegrationsAreAvailable.question",
- answer: "faq.question.whatKindOfIntegrationsAreAvailable.answer",
- },
- {
- question: "faq.question.howEasyIsItToOnboardMyTeam.question",
- answer: "faq.question.howEasyIsItToOnboardMyTeam.answer",
- },
- {
- question: "faq.question.whatTypesOfBusinessesCanUseThis.question",
- answer: "faq.question.whatTypesOfBusinessesCanUseThis.answer",
- },
- {
- question: "faq.question.canICustomizeThisToFitMyBusinessNeeds.question",
- answer: "faq.question.canICustomizeThisToFitMyBusinessNeeds.answer",
- },
-] as const;
-
-export const Faq = async () => {
- const { t } = await getTranslation({ ns: "marketing" });
+const ITEMS = [
+ {
+ q: "Is claudemesh free?",
+ a: "Yes — the broker, CLI, dashboard, and SDK are MIT-licensed and free forever. Solo developers and small teams can self-host at no cost. Paid tiers add hosted brokers, SSO, audit retention, and support.",
+ },
+ {
+ q: "How do I get started?",
+ a: "Install the broker with one curl command. Add one env var to your Claude Code config. Your session joins the mesh. `npx claudemesh init` does both in 60 seconds.",
+ },
+ {
+ q: "Does claudemesh send my code or prompts to the cloud?",
+ a: "No. The broker is a local WebSocket server. Messages stay on your network. The only data that leaves your machines is what your Claude Code already sends to Anthropic — we don't touch it.",
+ },
+ {
+ q: "Do I need to run a server?",
+ a: "Yes — one machine on your network runs the broker. That can be your laptop, a shared dev box, a Raspberry Pi, or a container in your cluster. It's one binary, SQLite-backed, ~15 MB.",
+ },
+ {
+ q: "Does it work across offices / continents?",
+ a: "Yes. Put the broker on a VPS, or expose it through Tailscale / WireGuard. Every Claude Code session that can reach the broker joins the mesh.",
+ },
+ {
+ q: "How does it route messages?",
+ a: "By peer name (alex, jordan), by repo, or by priority level (now / next / low). Messages are queued until the target peer is idle, then delivered. You can also set a peer to DND to block all but priority:now.",
+ },
+ {
+ q: "Which Claude Code versions work with claudemesh?",
+ a: "Claude Code 2.0 and above. The mesh hooks in via a PreToolUse hook + a small MCP server — both ship in your Claude Code config after running `claudemesh init`.",
+ },
+];
+export const FAQ = () => {
+ const [open, setOpen] = useState(0);
return (
-
-
- {t("faq.label")}
- {t("faq.title")}
-
- {t("faq.description")}
-
-
-
+