Files
podcastdistributiona/app/(marketing)/page.tsx
T
2026-06-07 03:58:32 -04:00

243 lines
10 KiB
TypeScript

import Link from "next/link";
import {
ArrowRight,
FileText,
AudioLines,
ImageIcon,
Sparkles,
Languages,
Users,
Repeat,
ListChecks,
Check,
} from "lucide-react";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { Card, CardContent } from "@/components/ui/card";
import { PLAN_ORDER, PLANS } from "@/lib/billing/plans";
import { formatPrice } from "@/lib/utils";
export default function LandingPage() {
return (
<>
{/* Hero */}
<section className="relative overflow-hidden bg-hero-wash">
<div className="container flex flex-col items-center gap-7 py-24 text-center md:py-36">
<Badge variant="secondary" className="py-1.5">
<Sparkles className="h-3.5 w-3.5 text-brand" />
GPT-4 · ElevenLabs · DALL·E in one workflow
</Badge>
<h1 className="max-w-4xl text-balance font-display text-5xl font-extrabold leading-[1.05] tracking-tight sm:text-6xl md:text-7xl">
From a topic idea to a{" "}
<span className="text-brand">finished podcast</span> in minutes
</h1>
<p className="max-w-2xl text-lg text-muted-foreground sm:text-xl">
PodcastYes writes the script, records realistic multi-voice audio, and designs the cover
art automatically. No microphone, no editing, no design skills required.
</p>
<div className="mt-2 flex flex-col gap-3 sm:flex-row">
<Button asChild size="lg">
<Link href="/sign-up">
Start free <ArrowRight className="h-4 w-4" />
</Link>
</Button>
<Button asChild size="lg" variant="outline">
<Link href="/#how-it-works">See how it works</Link>
</Button>
</div>
<p className="text-sm text-muted-foreground">
Free plan includes 3 scripts &amp; 1 audio generation / month. No card required.
</p>
</div>
</section>
{/* How it works */}
<section id="how-it-works" className="border-t border-border bg-secondary py-24 md:py-28">
<div className="container">
<SectionHeading
eyebrow="How it works"
title="Three steps to a published episode"
subtitle="Configure once. The AI generates everything. You fine-tune and publish."
/>
<div className="mt-16 grid gap-6 md:grid-cols-3">
{STEPS.map((step, i) => (
<Card key={step.title} className="relative transition-shadow hover:shadow-md">
<CardContent className="space-y-4 p-8">
<div className="flex items-center justify-between">
<span className="flex h-12 w-12 items-center justify-center rounded-2xl bg-brand/10 text-brand">
<step.icon className="h-6 w-6" />
</span>
<span className="font-display text-5xl font-extrabold text-foreground/[0.08]">
{String(i + 1).padStart(2, "0")}
</span>
</div>
<h3 className="font-display text-xl font-bold tracking-tight">{step.title}</h3>
<p className="text-muted-foreground">{step.body}</p>
</CardContent>
</Card>
))}
</div>
</div>
</section>
{/* Features */}
<section id="features" className="py-24 md:py-28">
<div className="container">
<SectionHeading
eyebrow="Everything in one place"
title="The whole podcast toolkit"
subtitle="Replace a writer, a voice actor, an editor, and a designer with one workflow."
/>
<div className="mt-16 grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
{FEATURES.map((f) => (
<div
key={f.title}
className="flex gap-4 rounded-2xl border border-border bg-card p-6 transition-all hover:-translate-y-0.5 hover:shadow-md"
>
<span className="flex h-11 w-11 shrink-0 items-center justify-center rounded-2xl bg-brand/10 text-brand">
<f.icon className="h-5 w-5" />
</span>
<div className="space-y-1">
<h3 className="font-display font-bold tracking-tight">{f.title}</h3>
<p className="text-sm text-muted-foreground">{f.body}</p>
</div>
</div>
))}
</div>
</div>
</section>
{/* Pricing preview */}
<section id="pricing" className="border-t border-border bg-secondary py-24 md:py-28">
<div className="container">
<SectionHeading
eyebrow="Pricing"
title="Start free, upgrade as you grow"
subtitle="Simple monthly plans. Cancel anytime."
/>
<div className="mt-16 grid gap-6 lg:grid-cols-4">
{PLAN_ORDER.map((key) => {
const plan = PLANS[key];
return (
<Card
key={key}
className={
plan.highlight
? "relative ring-2 ring-brand shadow-lg"
: "relative"
}
>
{plan.highlight && (
<Badge variant="brand" className="absolute -top-3 left-1/2 -translate-x-1/2 bg-brand text-brand-foreground shadow-sm">
Most popular
</Badge>
)}
<CardContent className="space-y-6 p-7">
<div>
<h3 className="font-display text-lg font-bold tracking-tight">{plan.name}</h3>
<p className="mt-1 text-sm text-muted-foreground">{plan.tagline}</p>
</div>
<div className="flex items-baseline gap-1">
<span className="font-display text-4xl font-extrabold tracking-tight">{formatPrice(plan.priceMonthly)}</span>
<span className="text-sm text-muted-foreground">/mo</span>
</div>
<Button
asChild
className="w-full"
variant={plan.highlight ? "default" : "outline"}
>
<Link href="/sign-up">{key === "free" ? "Start free" : `Choose ${plan.name}`}</Link>
</Button>
<ul className="space-y-2.5 text-sm">
{plan.bullets.slice(0, 5).map((b) => (
<li key={b} className="flex gap-2.5">
<Check className="mt-0.5 h-4 w-4 shrink-0 text-brand" />
<span className="text-muted-foreground">{b}</span>
</li>
))}
</ul>
</CardContent>
</Card>
);
})}
</div>
<p className="mt-10 text-center text-sm text-muted-foreground">
Full comparison on the{" "}
<Link href="/pricing" className="font-semibold text-brand hover:underline">
pricing page
</Link>
.
</p>
</div>
</section>
{/* CTA */}
<section className="py-24 md:py-28">
<div className="container">
<div className="relative overflow-hidden rounded-3xl bg-primary px-8 py-20 text-center text-primary-foreground">
<div className="pointer-events-none absolute inset-0 bg-[radial-gradient(60%_80%_at_50%_0%,hsl(var(--brand)/0.35),transparent_70%)]" />
<div className="relative">
<h2 className="font-display text-4xl font-extrabold tracking-tight sm:text-5xl">
Make your first episode today
</h2>
<p className="mx-auto mt-4 max-w-xl text-lg text-primary-foreground/75">
Spin up a fully produced episode on the free plan in a couple of minutes then decide.
</p>
<Button asChild size="lg" variant="brand" className="mt-9">
<Link href="/sign-up">
Get started free <ArrowRight className="h-4 w-4" />
</Link>
</Button>
</div>
</div>
</div>
</section>
</>
);
}
function SectionHeading({
eyebrow,
title,
subtitle,
}: {
eyebrow: string;
title: string;
subtitle: string;
}) {
return (
<div className="mx-auto max-w-2xl text-center">
<p className="text-[13px] font-semibold uppercase tracking-[0.04em] text-brand">{eyebrow}</p>
<h2 className="mt-3 font-display text-3xl font-extrabold tracking-tight sm:text-4xl md:text-5xl">{title}</h2>
<p className="mt-4 text-lg text-muted-foreground">{subtitle}</p>
</div>
);
}
const STEPS = [
{
icon: FileText,
title: "Configure your episode",
body: "Set the topic, tone, length, audience, and language. Pick a format: solo, interview, or multi-host.",
},
{
icon: AudioLines,
title: "AI generates everything",
body: "GPT-4 writes the script, ElevenLabs records it with realistic voices, and DALL·E designs the cover art.",
},
{
icon: ImageIcon,
title: "Fine-tune & publish",
body: "Edit the script, regenerate sections, download the MP3 and assets, and repurpose into blogs and social posts.",
},
];
const FEATURES = [
{ icon: FileText, title: "AI script generation", body: "Structured, on-brand scripts tailored to your tone, format, and audience." },
{ icon: AudioLines, title: "Multi-voice audio", body: "14+ realistic voices and multi-speaker dialogue for interviews and panels." },
{ icon: ImageIcon, title: "AI cover art", body: "Eye-catching episode artwork generated to match your topic in one click." },
{ icon: Repeat, title: "Content repurposing", body: "Turn any episode into blog posts, social threads, and newsletters instantly." },
{ icon: ListChecks, title: "Series generator", body: "Plan an entire season — titles, topics, and episodes — from a single prompt." },
{ icon: Languages, title: "13+ languages", body: "Produce episodes for a global audience without re-recording anything." },
];