Add comprehensive /features page + allow Unsplash imagery
This commit is contained in:
@@ -0,0 +1,196 @@
|
||||
import type { Metadata } from "next";
|
||||
import Link from "next/link";
|
||||
import {
|
||||
Sparkles,
|
||||
Wand2,
|
||||
ShieldCheck,
|
||||
Globe,
|
||||
Zap,
|
||||
HeartHandshake,
|
||||
ArrowRight,
|
||||
} from "lucide-react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "About",
|
||||
description:
|
||||
"PodcastYes is an AI studio that turns a single idea into a finished, publishable podcast — script, voices, and cover art — in minutes. Learn why we built it and what we believe.",
|
||||
};
|
||||
|
||||
const STATS = [
|
||||
{ value: "3", label: "AI models in one workflow" },
|
||||
{ value: "14+", label: "Realistic narrator voices" },
|
||||
{ value: "13+", label: "Languages supported" },
|
||||
{ value: "Minutes", label: "From idea to finished episode" },
|
||||
];
|
||||
|
||||
const VALUES = [
|
||||
{
|
||||
icon: Sparkles,
|
||||
title: "Creativity for everyone",
|
||||
body: "Powerful production shouldn't require gear, a budget, or technical skill. If you can describe an idea, you can turn it into a finished episode.",
|
||||
},
|
||||
{
|
||||
icon: Wand2,
|
||||
title: "Quality you'd actually publish",
|
||||
body: "AI drafts are a starting point, not the finish line. Every script and voice is editable, so the final cut always sounds like you.",
|
||||
},
|
||||
{
|
||||
icon: ShieldCheck,
|
||||
title: "Built responsibly",
|
||||
body: "We screen content against a clear policy, never use your private work to train our models, and make sure you own everything you create.",
|
||||
},
|
||||
{
|
||||
icon: Globe,
|
||||
title: "Global from day one",
|
||||
body: "Stories aren't only told in English. With 13+ languages, you can produce for an audience anywhere — no re-recording required.",
|
||||
},
|
||||
{
|
||||
icon: Zap,
|
||||
title: "Fast, but never careless",
|
||||
body: "Minutes from idea to episode, with the controls to get the details right before you hit publish. Speed and craft aren't a trade-off.",
|
||||
},
|
||||
{
|
||||
icon: HeartHandshake,
|
||||
title: "Honest and transparent",
|
||||
body: "Simple plans, clear limits, cancel anytime. No dark patterns and no surprises — just a tool that respects your time and your work.",
|
||||
},
|
||||
];
|
||||
|
||||
export default function AboutPage() {
|
||||
return (
|
||||
<>
|
||||
{/* Hero */}
|
||||
<section className="bg-hero-wash">
|
||||
<div className="container max-w-4xl py-24 text-center md:py-32">
|
||||
<p className="text-[13px] font-semibold uppercase tracking-[0.04em] text-brand">About us</p>
|
||||
<h1 className="mt-4 text-balance font-display text-5xl font-extrabold leading-[1.05] tracking-tight md:text-6xl">
|
||||
Making great podcasts possible for everyone
|
||||
</h1>
|
||||
<p className="mx-auto mt-6 max-w-2xl text-lg text-muted-foreground sm:text-xl">
|
||||
PodcastYes is an AI studio that turns a single idea into a finished, publishable episode —
|
||||
script, voices, and cover art — in minutes. No microphone, no editing suite, no production
|
||||
budget.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Stats */}
|
||||
<section className="border-y border-border bg-card">
|
||||
<div className="container grid grid-cols-2 gap-8 py-14 lg:grid-cols-4">
|
||||
{STATS.map((s) => (
|
||||
<div key={s.label} className="text-center">
|
||||
<p className="font-display text-4xl font-extrabold tracking-tight text-brand md:text-5xl">
|
||||
{s.value}
|
||||
</p>
|
||||
<p className="mt-2 text-sm text-muted-foreground">{s.label}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Mission */}
|
||||
<section className="py-24 md:py-28">
|
||||
<div className="container max-w-3xl text-center">
|
||||
<p className="text-[13px] font-semibold uppercase tracking-[0.04em] text-brand">Our mission</p>
|
||||
<p className="mt-5 text-balance font-display text-3xl font-bold leading-tight tracking-tight md:text-4xl">
|
||||
To remove every barrier between a great idea and a published podcast — so anyone with
|
||||
something to say can be{" "}
|
||||
<span className="text-brand">heard</span>.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Story */}
|
||||
<section className="border-t border-border bg-secondary py-24 md:py-28">
|
||||
<div className="container max-w-3xl">
|
||||
<p className="text-[13px] font-semibold uppercase tracking-[0.04em] text-brand">Our story</p>
|
||||
<h2 className="mt-3 font-display text-3xl font-extrabold tracking-tight md:text-4xl">
|
||||
Why we built PodcastYes
|
||||
</h2>
|
||||
<div className="mt-8 space-y-5 text-lg leading-relaxed text-muted-foreground">
|
||||
<p>
|
||||
Podcasting is one of the most personal ways to reach an audience — and one of the
|
||||
hardest to start. Scripting, recording, editing, designing artwork, and publishing can
|
||||
take days and a stack of tools and skills most people simply don't have. Brilliant
|
||||
ideas die in that gap between “I should make a podcast” and actually
|
||||
shipping one.
|
||||
</p>
|
||||
<p>
|
||||
We thought the modern AI stack could collapse all of that into a single workflow. GPT-4
|
||||
can write a tight, on-brand script. ElevenLabs can voice it with realistic, multi-speaker
|
||||
narration. DALL·E can design cover art that matches the topic. Stitched together, they
|
||||
turn “I have a topic” into “I have an episode.”
|
||||
</p>
|
||||
<p>
|
||||
So we built PodcastYes: a studio that lives in your browser. Describe an idea, fine-tune
|
||||
the result in a real editor, download the MP3 — then repurpose it into a blog post, a
|
||||
social thread, or a newsletter. We're a small team of engineers, audio nerds, and
|
||||
storytellers obsessed with making production effortless without making it feel generic.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Values */}
|
||||
<section className="py-24 md:py-28">
|
||||
<div className="container">
|
||||
<div className="mx-auto max-w-2xl text-center">
|
||||
<p className="text-[13px] font-semibold uppercase tracking-[0.04em] text-brand">
|
||||
What we believe
|
||||
</p>
|
||||
<h2 className="mt-3 font-display text-3xl font-extrabold tracking-tight md:text-4xl">
|
||||
The principles behind the product
|
||||
</h2>
|
||||
</div>
|
||||
<div className="mt-16 grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
|
||||
{VALUES.map((v) => (
|
||||
<div
|
||||
key={v.title}
|
||||
className="rounded-2xl border border-border bg-card p-7 transition-all hover:-translate-y-0.5 hover:shadow-md"
|
||||
>
|
||||
<span className="flex h-12 w-12 items-center justify-center rounded-2xl bg-brand/10 text-brand">
|
||||
<v.icon className="h-6 w-6" />
|
||||
</span>
|
||||
<h3 className="mt-5 font-display text-lg font-bold tracking-tight">{v.title}</h3>
|
||||
<p className="mt-2 leading-relaxed text-muted-foreground">{v.body}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* CTA */}
|
||||
<section className="pb-24 md:pb-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">
|
||||
Come make something worth listening to
|
||||
</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>
|
||||
<div className="mt-9 flex flex-col justify-center gap-3 sm:flex-row">
|
||||
<Button asChild size="lg" variant="brand">
|
||||
<Link href="/sign-up">
|
||||
Start free <ArrowRight className="h-4 w-4" />
|
||||
</Link>
|
||||
</Button>
|
||||
<Button
|
||||
asChild
|
||||
size="lg"
|
||||
variant="outline"
|
||||
className="border-white/25 bg-transparent text-primary-foreground hover:bg-white/10 hover:text-primary-foreground"
|
||||
>
|
||||
<Link href="/pricing">See pricing</Link>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,763 @@
|
||||
import type { Metadata } from "next";
|
||||
import Link from "next/link";
|
||||
import {
|
||||
ArrowRight,
|
||||
FileText,
|
||||
AudioLines,
|
||||
ImageIcon,
|
||||
Languages,
|
||||
Repeat,
|
||||
ListMusic,
|
||||
Share2,
|
||||
Users,
|
||||
KeyRound,
|
||||
CreditCard,
|
||||
Edit3,
|
||||
Download,
|
||||
Sparkles,
|
||||
Mic2,
|
||||
Radio,
|
||||
MessagesSquare,
|
||||
Palette,
|
||||
Globe2,
|
||||
Workflow,
|
||||
Gauge,
|
||||
ShieldCheck,
|
||||
Wand2,
|
||||
Mail,
|
||||
Hash,
|
||||
Clock,
|
||||
Check,
|
||||
Rocket,
|
||||
} from "lucide-react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Card, CardContent } from "@/components/ui/card";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Features",
|
||||
description:
|
||||
"Everything PodcastYes does — AI scriptwriting, realistic multi-voice audio, cover art, repurposing, a season generator, 13+ languages, team white-label, an API, and more.",
|
||||
};
|
||||
|
||||
const HERO_IMG =
|
||||
"https://images.unsplash.com/photo-1590602847861-f357a9332bbc?auto=format&fit=crop&w=1600&q=80";
|
||||
const AUDIO_IMG =
|
||||
"https://images.unsplash.com/photo-1598488035139-bdbb2231ce04?auto=format&fit=crop&w=1400&q=80";
|
||||
const TEAM_IMG =
|
||||
"https://images.unsplash.com/photo-1521737604893-d14cc237f11d?auto=format&fit=crop&w=1400&q=80";
|
||||
|
||||
export default function FeaturesPage() {
|
||||
return (
|
||||
<>
|
||||
{/* 1 — Hero */}
|
||||
<section className="relative overflow-hidden bg-hero-wash">
|
||||
<div className="container grid items-center gap-12 py-20 md:grid-cols-2 md:py-28">
|
||||
<div className="space-y-7">
|
||||
<Eyebrow>Every feature, one workflow</Eyebrow>
|
||||
<h1 className="text-balance font-display text-4xl font-extrabold leading-[1.05] tracking-tight sm:text-5xl md:text-6xl">
|
||||
The entire podcast studio, <span className="text-brand">powered by AI</span>
|
||||
</h1>
|
||||
<p className="max-w-xl text-lg text-muted-foreground">
|
||||
Write, narrate, illustrate, edit, repurpose, and publish — PodcastYes replaces a
|
||||
writer, a voice actor, an editor, and a designer with one clean, end-to-end workflow.
|
||||
No microphone, no software, no skills required.
|
||||
</p>
|
||||
<div className="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="/pricing">See pricing</Link>
|
||||
</Button>
|
||||
</div>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
Free plan — 3 scripts & 1 audio generation / month. No card required.
|
||||
</p>
|
||||
</div>
|
||||
<div className="relative">
|
||||
<div className="overflow-hidden rounded-3xl border border-border shadow-xl">
|
||||
{/* eslint-disable-next-line @next/next/no-img-element */}
|
||||
<img
|
||||
src={HERO_IMG}
|
||||
alt="Studio condenser microphone"
|
||||
className="h-full w-full object-cover"
|
||||
width={1600}
|
||||
height={1067}
|
||||
/>
|
||||
</div>
|
||||
<div className="absolute -bottom-5 -left-5 hidden rounded-2xl border border-border bg-card p-4 shadow-lg sm:block">
|
||||
<div className="flex items-center gap-3">
|
||||
<span className="flex h-10 w-10 items-center justify-center rounded-xl bg-brand/10 text-brand">
|
||||
<Sparkles className="h-5 w-5" />
|
||||
</span>
|
||||
<div>
|
||||
<p className="text-sm font-semibold">Topic → episode</p>
|
||||
<p className="text-xs text-muted-foreground">in minutes, not hours</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* 2 — Model strip */}
|
||||
<section className="border-y border-border bg-secondary/60 py-10">
|
||||
<div className="container flex flex-col items-center gap-6 text-center">
|
||||
<p className="text-[13px] font-semibold uppercase tracking-[0.04em] text-muted-foreground">
|
||||
Best-in-class AI, stitched into one product
|
||||
</p>
|
||||
<div className="grid w-full gap-4 sm:grid-cols-3">
|
||||
<ModelChip icon={FileText} name="GPT-4" role="Scriptwriting" />
|
||||
<ModelChip icon={AudioLines} name="ElevenLabs" role="Realistic voices" />
|
||||
<ModelChip icon={ImageIcon} name="DALL·E" role="Cover art" />
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* 3 — AI script generation */}
|
||||
<FeatureBand
|
||||
eyebrow="AI scriptwriting"
|
||||
icon={FileText}
|
||||
title="Scripts that actually sound good out loud"
|
||||
body="Describe a topic and GPT-4 writes a structured, on-brand episode — intro, segments, and outro — tailored to your tone, audience, and target length. It writes for the ear, not the page: natural, spoken-word dialogue with no stage directions to clean up."
|
||||
bullets={[
|
||||
"Set tone, audience, length and format up front",
|
||||
"Structured sections you can edit and re-order",
|
||||
"Per-section regeneration when you want a fresh take",
|
||||
"13+ languages, written natively (not translated)",
|
||||
]}
|
||||
/>
|
||||
|
||||
{/* 4 — Multi-voice audio (with image) */}
|
||||
<FeatureBand
|
||||
reverse
|
||||
tinted
|
||||
eyebrow="Realistic multi-voice audio"
|
||||
icon={AudioLines}
|
||||
title="14+ lifelike voices, multi-speaker dialogue"
|
||||
body="ElevenLabs turns your script into broadcast-quality audio. Cast a different voice for every speaker, and PodcastYes synthesizes the dialogue, stitches the segments, and loudness-normalizes the whole episode into one clean MP3 — automatically."
|
||||
bullets={[
|
||||
"14+ premium voices across accents and styles",
|
||||
"True multi-speaker conversations, not one narrator",
|
||||
"Automatic segmentation, stitching & normalization",
|
||||
"Download a publish-ready MP3 in a click",
|
||||
]}
|
||||
image={AUDIO_IMG}
|
||||
imageAlt="Audio mixing console"
|
||||
/>
|
||||
|
||||
{/* 5 — Formats */}
|
||||
<section className="py-20 md:py-24">
|
||||
<div className="container">
|
||||
<SectionHeading
|
||||
eyebrow="Any format"
|
||||
title="Solo, interview, or a full panel"
|
||||
subtitle="Pick a format and PodcastYes casts the right number of voices and writes for it."
|
||||
/>
|
||||
<div className="mt-14 grid gap-6 md:grid-cols-3">
|
||||
<FormatCard
|
||||
icon={Mic2}
|
||||
title="Solo"
|
||||
body="One host narrating directly to the listener — perfect for explainers, essays, and daily updates."
|
||||
/>
|
||||
<FormatCard
|
||||
icon={MessagesSquare}
|
||||
title="Interview"
|
||||
body="A host and a guest in natural back-and-forth, each with their own distinct voice."
|
||||
/>
|
||||
<FormatCard
|
||||
icon={Radio}
|
||||
title="Multi-host"
|
||||
body="A lively panel of co-hosts who react to each other — banter, debate, and chemistry included."
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* 6 — Cover art */}
|
||||
<FeatureBand
|
||||
tinted
|
||||
eyebrow="AI cover art"
|
||||
icon={Palette}
|
||||
title="Scroll-stopping artwork, generated for you"
|
||||
body="Every episode gets bespoke cover art from DALL·E, matched to your topic and tone — bold, modern, and square-format ready for every directory. Don't love it? Regenerate until it's perfect."
|
||||
bullets={[
|
||||
"On-topic, on-brand art in one click",
|
||||
"One-tap regeneration for new directions",
|
||||
"Square album-cover format, podcast-directory ready",
|
||||
"Downloaded with your episode assets",
|
||||
]}
|
||||
visual={<ArtVisual />}
|
||||
/>
|
||||
|
||||
{/* 7 — Languages */}
|
||||
<section className="py-20 md:py-24">
|
||||
<div className="container">
|
||||
<SectionHeading
|
||||
eyebrow="Go global"
|
||||
title="Publish in 13+ languages"
|
||||
subtitle="Reach a worldwide audience without re-recording anything. Scripts are written natively and narrated by multilingual voices."
|
||||
/>
|
||||
<div className="mx-auto mt-12 flex max-w-3xl flex-wrap justify-center gap-2.5">
|
||||
{[
|
||||
"English",
|
||||
"Spanish",
|
||||
"French",
|
||||
"German",
|
||||
"Italian",
|
||||
"Portuguese",
|
||||
"Dutch",
|
||||
"Polish",
|
||||
"Hindi",
|
||||
"Japanese",
|
||||
"Korean",
|
||||
"Chinese",
|
||||
"Arabic",
|
||||
"Turkish",
|
||||
"Russian",
|
||||
].map((l) => (
|
||||
<span
|
||||
key={l}
|
||||
className="inline-flex items-center gap-1.5 rounded-full border border-border bg-card px-4 py-2 text-sm font-medium shadow-sm"
|
||||
>
|
||||
<Globe2 className="h-3.5 w-3.5 text-brand" />
|
||||
{l}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* 8 — Workflow */}
|
||||
<section className="border-y border-border bg-secondary/60 py-20 md:py-24">
|
||||
<div className="container">
|
||||
<SectionHeading
|
||||
eyebrow="How it flows"
|
||||
title="Three steps to a finished episode"
|
||||
subtitle="Configure once. The AI does the heavy lifting. You fine-tune and publish."
|
||||
/>
|
||||
<div className="mt-14 grid gap-6 md:grid-cols-3">
|
||||
<StepCard
|
||||
n="01"
|
||||
icon={Workflow}
|
||||
title="Configure"
|
||||
body="Topic, tone, format, length, audience, language, and your cast of voices."
|
||||
/>
|
||||
<StepCard
|
||||
n="02"
|
||||
icon={Wand2}
|
||||
title="Generate"
|
||||
body="GPT-4 writes, ElevenLabs records, DALL·E illustrates — with a live progress stepper."
|
||||
/>
|
||||
<StepCard
|
||||
n="03"
|
||||
icon={Rocket}
|
||||
title="Publish"
|
||||
body="Fine-tune, download the MP3 and assets, share a public link, or repurpose it."
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* 9 — Script editor */}
|
||||
<FeatureBand
|
||||
eyebrow="Full control"
|
||||
icon={Edit3}
|
||||
title="A real editor, not a black box"
|
||||
body="Generated doesn't mean final. Tweak any line, regenerate a single section, then re-record just the audio that changed — so a small edit never costs a full re-render. Live word counts and spoken-duration estimates keep you on target."
|
||||
bullets={[
|
||||
"Edit every line; dirty-state save bar",
|
||||
"Regenerate one section at a time",
|
||||
"Re-record audio for only what you changed",
|
||||
"Copy the full transcript in one click",
|
||||
]}
|
||||
/>
|
||||
|
||||
{/* 10 — Player & downloads */}
|
||||
<FeatureBand
|
||||
reverse
|
||||
tinted
|
||||
eyebrow="Studio-grade output"
|
||||
icon={Download}
|
||||
title="Listen, scrub, and export everything"
|
||||
body="A built-in waveform player lets you preview and scrub your episode in the browser. When you're ready, download the MP3 — or grab a single ZIP with the audio, cover art, transcript, and show notes, ready to publish anywhere."
|
||||
bullets={[
|
||||
"In-browser waveform player with volume + scrub",
|
||||
"One-click MP3 download",
|
||||
"Download everything as a tidy .zip",
|
||||
"Auto-generated transcript & show notes",
|
||||
]}
|
||||
visual={<PlayerVisual />}
|
||||
/>
|
||||
|
||||
{/* 11 — Repurposing */}
|
||||
<section className="py-20 md:py-24">
|
||||
<div className="container">
|
||||
<SectionHeading
|
||||
eyebrow="Do more with every episode"
|
||||
title="One recording, a week of content"
|
||||
subtitle="Turn any episode into the formats your audience already reads — instantly."
|
||||
/>
|
||||
<div className="mt-14 grid gap-6 md:grid-cols-3">
|
||||
<FormatCard icon={FileText} title="Blog post" body="An SEO-friendly article with headings, drawn straight from your episode." />
|
||||
<FormatCard icon={Hash} title="Social thread" body="A punchy, numbered thread with a strong hook, ready to post." />
|
||||
<FormatCard icon={Mail} title="Newsletter" body="A friendly email edition with takeaways and a call-to-action to listen." />
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* 12 — Series generator */}
|
||||
<FeatureBand
|
||||
tinted
|
||||
eyebrow="Think in seasons"
|
||||
icon={ListMusic}
|
||||
title="Plan an entire season from one prompt"
|
||||
body="The series generator maps out a cohesive season — titles, topics, and summaries for every episode — from a single theme. Then generate each episode straight from the plan. Available on Pro and Agency."
|
||||
bullets={[
|
||||
"A full season outline from one idea",
|
||||
"Per-episode titles, topics & summaries",
|
||||
"Generate any planned episode in a click",
|
||||
"Keep a whole show consistent and on-theme",
|
||||
]}
|
||||
/>
|
||||
|
||||
{/* 13 — Share & publish */}
|
||||
<FeatureBand
|
||||
eyebrow="Share instantly"
|
||||
icon={Share2}
|
||||
title="A public link for every episode"
|
||||
body="Flip on sharing and get a clean, no-login public page where anyone can listen — with the cover, an embedded player, and show notes. Perfect for a quick preview, a client review, or distribution before it hits the directories."
|
||||
bullets={[
|
||||
"Beautiful public listen page, zero login",
|
||||
"Embedded streaming player with seek support",
|
||||
"Carries your white-label branding (Agency)",
|
||||
"Toggle on or off anytime",
|
||||
]}
|
||||
visual={<ShareVisual />}
|
||||
/>
|
||||
|
||||
{/* 14 — Teams / white-label (with image) */}
|
||||
<FeatureBand
|
||||
reverse
|
||||
tinted
|
||||
eyebrow="For studios & agencies"
|
||||
icon={Users}
|
||||
title="A workspace built for teams"
|
||||
body="The Agency plan adds a 5-seat shared workspace, white-label mode, and custom branding — so you can produce podcasts for clients under your own brand, with your color and logo flowing through the app and every public share page."
|
||||
bullets={[
|
||||
"5-seat team workspace with invitations",
|
||||
"White-label mode — remove PodcastYes branding",
|
||||
"Custom brand color & logo across the app",
|
||||
"Branded public share pages for clients",
|
||||
]}
|
||||
image={TEAM_IMG}
|
||||
imageAlt="A team collaborating around a laptop"
|
||||
/>
|
||||
|
||||
{/* 15 — API */}
|
||||
<FeatureBand
|
||||
eyebrow="Build on it"
|
||||
icon={KeyRound}
|
||||
title="Generate episodes from your own apps"
|
||||
body="Pro and Agency unlock a developer API with scoped keys, so you can create and fetch episodes programmatically — wire PodcastYes into your CMS, automate a daily show, or build it into your own product."
|
||||
bullets={[
|
||||
"Scoped, revocable API keys",
|
||||
"Create + list episodes over REST",
|
||||
"Same plan limits and quotas enforced",
|
||||
"Rate-limited and ready for automation",
|
||||
]}
|
||||
visual={<ApiVisual />}
|
||||
/>
|
||||
|
||||
{/* 16 — Plans, usage & billing */}
|
||||
<section className="border-y border-border bg-secondary/60 py-20 md:py-24">
|
||||
<div className="container grid items-center gap-10 md:grid-cols-2">
|
||||
<div className="space-y-5">
|
||||
<Eyebrow>Transparent & flexible</Eyebrow>
|
||||
<h2 className="font-display text-3xl font-extrabold tracking-tight sm:text-4xl">
|
||||
Clear limits, your choice of payment
|
||||
</h2>
|
||||
<p className="text-muted-foreground">
|
||||
Start free and upgrade as you grow. A live usage dashboard shows exactly where you
|
||||
stand against your plan, with friendly nudges before you hit a limit. Pay with a card
|
||||
via Stripe or with PayPal — whichever you prefer.
|
||||
</p>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
<FeatureChip icon={Gauge} label="Live usage meters" />
|
||||
<FeatureChip icon={CreditCard} label="Stripe & PayPal" />
|
||||
<FeatureChip icon={ShieldCheck} label="Cancel anytime" />
|
||||
</div>
|
||||
<Button asChild>
|
||||
<Link href="/pricing">
|
||||
Compare plans <ArrowRight className="h-4 w-4" />
|
||||
</Link>
|
||||
</Button>
|
||||
</div>
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
<MiniStat value="4" label="Plans, Free → Agency" />
|
||||
<MiniStat value="2" label="Payment providers" />
|
||||
<MiniStat value="14+" label="Voices included" />
|
||||
<MiniStat value="13+" label="Languages" />
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* 17 — Everything included grid */}
|
||||
<section className="py-20 md:py-24">
|
||||
<div className="container">
|
||||
<SectionHeading
|
||||
eyebrow="The whole toolkit"
|
||||
title="Everything that comes in the box"
|
||||
subtitle="One subscription, the complete production pipeline."
|
||||
/>
|
||||
<div className="mt-14 grid gap-5 sm:grid-cols-2 lg:grid-cols-3">
|
||||
{EVERYTHING.map((f) => (
|
||||
<div key={f.title} className="flex gap-4 rounded-2xl border border-border bg-card p-5">
|
||||
<span className="flex h-10 w-10 shrink-0 items-center justify-center rounded-xl bg-brand/10 text-brand">
|
||||
<f.icon className="h-5 w-5" />
|
||||
</span>
|
||||
<div className="space-y-1">
|
||||
<p className="font-semibold">{f.title}</p>
|
||||
<p className="text-sm text-muted-foreground">{f.body}</p>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* 18 — CTA */}
|
||||
<section className="pb-24">
|
||||
<div className="container">
|
||||
<div className="overflow-hidden rounded-3xl bg-primary px-8 py-16 text-center text-primary-foreground">
|
||||
<h2 className="font-display text-3xl font-extrabold tracking-tight sm:text-4xl">
|
||||
See it produce your first episode
|
||||
</h2>
|
||||
<p className="mx-auto mt-3 max-w-xl text-primary-foreground/75">
|
||||
Spin up a fully produced episode on the free plan in a couple of minutes — then decide.
|
||||
</p>
|
||||
<div className="mt-8 flex flex-col justify-center gap-3 sm:flex-row">
|
||||
<Button asChild size="lg" variant="secondary">
|
||||
<Link href="/sign-up">
|
||||
Get started free <ArrowRight className="h-4 w-4" />
|
||||
</Link>
|
||||
</Button>
|
||||
<Button
|
||||
asChild
|
||||
size="lg"
|
||||
variant="outline"
|
||||
className="border-primary-foreground/30 bg-transparent text-primary-foreground hover:bg-primary-foreground/10"
|
||||
>
|
||||
<Link href="/pricing">View pricing</Link>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
/* ─────────────────────────── helpers ─────────────────────────── */
|
||||
|
||||
function Eyebrow({ children }: { children: React.ReactNode }) {
|
||||
return <p className="text-[13px] font-semibold uppercase tracking-[0.04em] text-brand">{children}</p>;
|
||||
}
|
||||
|
||||
function SectionHeading({
|
||||
eyebrow,
|
||||
title,
|
||||
subtitle,
|
||||
}: {
|
||||
eyebrow: string;
|
||||
title: string;
|
||||
subtitle: string;
|
||||
}) {
|
||||
return (
|
||||
<div className="mx-auto max-w-2xl text-center">
|
||||
<Eyebrow>{eyebrow}</Eyebrow>
|
||||
<h2 className="mt-3 font-display text-3xl font-extrabold tracking-tight sm:text-4xl">{title}</h2>
|
||||
<p className="mt-4 text-lg text-muted-foreground">{subtitle}</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function FeatureBand({
|
||||
eyebrow,
|
||||
icon: Icon,
|
||||
title,
|
||||
body,
|
||||
bullets,
|
||||
image,
|
||||
imageAlt,
|
||||
visual,
|
||||
reverse,
|
||||
tinted,
|
||||
}: {
|
||||
eyebrow: string;
|
||||
icon: React.ComponentType<{ className?: string }>;
|
||||
title: string;
|
||||
body: string;
|
||||
bullets?: string[];
|
||||
image?: string;
|
||||
imageAlt?: string;
|
||||
visual?: React.ReactNode;
|
||||
reverse?: boolean;
|
||||
tinted?: boolean;
|
||||
}) {
|
||||
return (
|
||||
<section className={tinted ? "border-y border-border bg-secondary/60 py-20 md:py-24" : "py-20 md:py-24"}>
|
||||
<div className="container grid items-center gap-12 md:grid-cols-2">
|
||||
<div className={reverse ? "md:order-2" : ""}>
|
||||
<span className="mb-5 inline-flex h-11 w-11 items-center justify-center rounded-2xl bg-brand/10 text-brand">
|
||||
<Icon className="h-5 w-5" />
|
||||
</span>
|
||||
<Eyebrow>{eyebrow}</Eyebrow>
|
||||
<h2 className="mt-3 font-display text-3xl font-extrabold tracking-tight sm:text-4xl">{title}</h2>
|
||||
<p className="mt-4 text-lg text-muted-foreground">{body}</p>
|
||||
{bullets && (
|
||||
<ul className="mt-6 space-y-3">
|
||||
{bullets.map((b) => (
|
||||
<li key={b} className="flex items-start gap-3">
|
||||
<span className="mt-0.5 flex h-5 w-5 shrink-0 items-center justify-center rounded-full bg-brand/10 text-brand">
|
||||
<Check className="h-3.5 w-3.5" />
|
||||
</span>
|
||||
<span className="text-sm">{b}</span>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
)}
|
||||
</div>
|
||||
<div className={reverse ? "md:order-1" : ""}>
|
||||
{image ? (
|
||||
<div className="overflow-hidden rounded-3xl border border-border shadow-xl">
|
||||
{/* eslint-disable-next-line @next/next/no-img-element */}
|
||||
<img src={image} alt={imageAlt ?? ""} className="h-full w-full object-cover" width={1400} height={933} />
|
||||
</div>
|
||||
) : (
|
||||
visual
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
function ModelChip({
|
||||
icon: Icon,
|
||||
name,
|
||||
role,
|
||||
}: {
|
||||
icon: React.ComponentType<{ className?: string }>;
|
||||
name: string;
|
||||
role: string;
|
||||
}) {
|
||||
return (
|
||||
<div className="flex items-center justify-center gap-3 rounded-2xl border border-border bg-card px-5 py-4 shadow-sm">
|
||||
<span className="flex h-10 w-10 items-center justify-center rounded-xl bg-brand/10 text-brand">
|
||||
<Icon className="h-5 w-5" />
|
||||
</span>
|
||||
<div className="text-left">
|
||||
<p className="font-display font-bold leading-none">{name}</p>
|
||||
<p className="text-xs text-muted-foreground">{role}</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function FormatCard({
|
||||
icon: Icon,
|
||||
title,
|
||||
body,
|
||||
}: {
|
||||
icon: React.ComponentType<{ className?: string }>;
|
||||
title: string;
|
||||
body: string;
|
||||
}) {
|
||||
return (
|
||||
<Card className="transition-all hover:-translate-y-0.5 hover:shadow-md">
|
||||
<CardContent className="space-y-3 p-6">
|
||||
<span className="flex h-11 w-11 items-center justify-center rounded-2xl bg-brand/10 text-brand">
|
||||
<Icon className="h-5 w-5" />
|
||||
</span>
|
||||
<h3 className="font-display text-lg font-bold">{title}</h3>
|
||||
<p className="text-sm text-muted-foreground">{body}</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
function StepCard({
|
||||
n,
|
||||
icon: Icon,
|
||||
title,
|
||||
body,
|
||||
}: {
|
||||
n: string;
|
||||
icon: React.ComponentType<{ className?: string }>;
|
||||
title: string;
|
||||
body: string;
|
||||
}) {
|
||||
return (
|
||||
<Card className="relative overflow-hidden">
|
||||
<CardContent className="space-y-3 p-6">
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="flex h-11 w-11 items-center justify-center rounded-2xl bg-brand/10 text-brand">
|
||||
<Icon className="h-5 w-5" />
|
||||
</span>
|
||||
<span className="font-display text-4xl font-extrabold text-muted-foreground/15">{n}</span>
|
||||
</div>
|
||||
<h3 className="font-display text-lg font-bold">{title}</h3>
|
||||
<p className="text-sm text-muted-foreground">{body}</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
function FeatureChip({
|
||||
icon: Icon,
|
||||
label,
|
||||
}: {
|
||||
icon: React.ComponentType<{ className?: string }>;
|
||||
label: string;
|
||||
}) {
|
||||
return (
|
||||
<span className="inline-flex items-center gap-1.5 rounded-full border border-border bg-card px-3 py-1.5 text-sm font-medium">
|
||||
<Icon className="h-3.5 w-3.5 text-brand" /> {label}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
function MiniStat({ value, label }: { value: string; label: string }) {
|
||||
return (
|
||||
<div className="rounded-2xl border border-border bg-card p-5 text-center shadow-sm">
|
||||
<p className="font-display text-4xl font-extrabold tracking-tight text-brand">{value}</p>
|
||||
<p className="mt-1 text-xs text-muted-foreground">{label}</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
/* lightweight, dependency-free "product" visuals for image-less bands */
|
||||
|
||||
function ArtVisual() {
|
||||
return (
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
{["from-brand/30 to-brand/5", "from-foreground/20 to-foreground/5", "from-amber-400/30 to-amber-400/5", "from-emerald-400/30 to-emerald-400/5"].map(
|
||||
(g, i) => (
|
||||
<div
|
||||
key={i}
|
||||
className={`flex aspect-square items-center justify-center rounded-2xl border border-border bg-gradient-to-br ${g}`}
|
||||
>
|
||||
<ImageIcon className="h-8 w-8 text-foreground/40" />
|
||||
</div>
|
||||
)
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function PlayerVisual() {
|
||||
return (
|
||||
<div className="rounded-3xl border border-border bg-card p-6 shadow-xl">
|
||||
<div className="flex items-center gap-4">
|
||||
<span className="flex h-12 w-12 items-center justify-center rounded-2xl bg-brand text-brand-foreground">
|
||||
<AudioLines className="h-6 w-6" />
|
||||
</span>
|
||||
<div className="min-w-0 flex-1">
|
||||
<p className="truncate font-semibold">The history of coffee, ep. 1</p>
|
||||
<p className="text-xs text-muted-foreground">12:04 · solo · EN</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-5 flex items-end gap-[3px]">
|
||||
{Array.from({ length: 48 }).map((_, i) => (
|
||||
<span
|
||||
key={i}
|
||||
className="w-full rounded-full bg-brand/60"
|
||||
style={{ height: `${10 + Math.abs(Math.sin(i * 0.7)) * 38}px` }}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
<div className="mt-5 flex gap-2">
|
||||
<Button size="sm" className="flex-1">
|
||||
<Download className="h-4 w-4" /> MP3
|
||||
</Button>
|
||||
<Button size="sm" variant="outline" className="flex-1">
|
||||
<Download className="h-4 w-4" /> .zip
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function ShareVisual() {
|
||||
return (
|
||||
<div className="rounded-3xl border border-border bg-card p-6 shadow-xl">
|
||||
<div className="flex items-center gap-2 border-b border-border pb-3">
|
||||
<span className="h-3 w-3 rounded-full bg-destructive/40" />
|
||||
<span className="h-3 w-3 rounded-full bg-warning/50" />
|
||||
<span className="h-3 w-3 rounded-full bg-success/50" />
|
||||
<span className="ml-3 truncate rounded-full bg-secondary px-3 py-1 text-xs text-muted-foreground">
|
||||
podcastyes.app/p/aZ9k…
|
||||
</span>
|
||||
</div>
|
||||
<div className="mt-5 flex gap-4">
|
||||
<div className="flex h-20 w-20 shrink-0 items-center justify-center rounded-2xl bg-gradient-to-br from-brand/30 to-brand/5">
|
||||
<Mic2 className="h-8 w-8 text-brand" />
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Badge variant="success" className="gap-1">
|
||||
<Share2 className="h-3 w-3" /> Public
|
||||
</Badge>
|
||||
<p className="font-display font-bold leading-tight">Your episode, live for anyone</p>
|
||||
<p className="flex items-center gap-1 text-xs text-muted-foreground">
|
||||
<Clock className="h-3 w-3" /> no login required
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function ApiVisual() {
|
||||
return (
|
||||
<div className="overflow-hidden rounded-3xl border border-border bg-foreground shadow-xl">
|
||||
<div className="flex items-center gap-2 border-b border-white/10 px-4 py-3">
|
||||
<KeyRound className="h-4 w-4 text-background/70" />
|
||||
<span className="font-mono text-xs text-background/70">POST /api/v1/episodes</span>
|
||||
</div>
|
||||
<pre className="overflow-x-auto p-5 font-mono text-xs leading-relaxed text-background/90">
|
||||
<code>{`curl -X POST https://podcastyes.app/api/v1/episodes \\
|
||||
-H "Authorization: Bearer pky_live_…" \\
|
||||
-d '{
|
||||
"topic": "Why deep work matters",
|
||||
"format": "SOLO",
|
||||
"language": "en"
|
||||
}'
|
||||
|
||||
→ 201 { "id": "ep_8fk2…", "status": "QUEUED" }`}</code>
|
||||
</pre>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const EVERYTHING = [
|
||||
{ icon: FileText, title: "GPT-4 scripts", body: "Structured, spoken-word scripts in seconds." },
|
||||
{ icon: AudioLines, title: "Multi-voice audio", body: "14+ realistic voices, multi-speaker." },
|
||||
{ icon: ImageIcon, title: "AI cover art", body: "Bespoke DALL·E artwork per episode." },
|
||||
{ icon: Languages, title: "13+ languages", body: "Native scripts and narration." },
|
||||
{ icon: Edit3, title: "Script editor", body: "Edit, regenerate sections, re-record." },
|
||||
{ icon: Download, title: "MP3 + ZIP export", body: "Audio, art, transcript & notes." },
|
||||
{ icon: Repeat, title: "Repurposing", body: "Blog, social thread, newsletter." },
|
||||
{ icon: ListMusic, title: "Series generator", body: "Plan whole seasons from one prompt." },
|
||||
{ icon: Share2, title: "Public share pages", body: "No-login listen links, branded." },
|
||||
{ icon: Users, title: "Team workspace", body: "5 seats, invitations, roles." },
|
||||
{ icon: Palette, title: "White-label", body: "Your brand color, logo, no PodcastYes." },
|
||||
{ icon: KeyRound, title: "Developer API", body: "Generate episodes programmatically." },
|
||||
{ icon: Gauge, title: "Usage dashboard", body: "Live meters and limit nudges." },
|
||||
{ icon: CreditCard, title: "Stripe & PayPal", body: "Pay your way; cancel anytime." },
|
||||
{ icon: Sparkles, title: "Live generation", body: "Watch each stage stream in real time." },
|
||||
{ icon: ShieldCheck, title: "Yours to keep", body: "Download and publish anywhere." },
|
||||
];
|
||||
+11
-10
@@ -4,7 +4,7 @@
|
||||
|
||||
@layer base {
|
||||
:root {
|
||||
/* Wix-inspired: white base, near-black ink, single Wix-Blue accent */
|
||||
/* White base, near-black ink, single ORANGE accent */
|
||||
--background: 0 0% 100%;
|
||||
--foreground: 0 0% 7%;
|
||||
--card: 0 0% 100%;
|
||||
@@ -16,10 +16,10 @@
|
||||
--primary: 0 0% 5%;
|
||||
--primary-foreground: 0 0% 100%;
|
||||
|
||||
/* WIX BLUE — links, focus, active states, accents */
|
||||
--brand: 217 100% 53%;
|
||||
/* ORANGE — links, focus, active states, accents (#E65100) */
|
||||
--brand: 21 100% 45%;
|
||||
--brand-foreground: 0 0% 100%;
|
||||
--brand-hover: 219 90% 46%;
|
||||
--brand-hover: 21 100% 39%;
|
||||
|
||||
--secondary: 0 0% 96%;
|
||||
--secondary-foreground: 0 0% 7%;
|
||||
@@ -31,11 +31,12 @@
|
||||
--destructive: 4 86% 58%;
|
||||
--destructive-foreground: 0 0% 100%;
|
||||
--success: 157 100% 30%;
|
||||
--warning: 24 100% 50%;
|
||||
/* amber — kept distinct from the orange brand accent */
|
||||
--warning: 38 100% 50%;
|
||||
|
||||
--border: 0 0% 89%;
|
||||
--input: 0 0% 89%;
|
||||
--ring: 217 100% 53%;
|
||||
--ring: 21 100% 45%;
|
||||
--radius: 0.875rem;
|
||||
}
|
||||
|
||||
@@ -50,9 +51,9 @@
|
||||
--primary: 0 0% 100%;
|
||||
--primary-foreground: 0 0% 5%;
|
||||
|
||||
--brand: 217 100% 60%;
|
||||
--brand: 24 100% 58%;
|
||||
--brand-foreground: 0 0% 100%;
|
||||
--brand-hover: 217 100% 66%;
|
||||
--brand-hover: 24 100% 64%;
|
||||
|
||||
--secondary: 0 0% 13%;
|
||||
--secondary-foreground: 0 0% 98%;
|
||||
@@ -64,11 +65,11 @@
|
||||
--destructive: 4 80% 58%;
|
||||
--destructive-foreground: 0 0% 100%;
|
||||
--success: 157 70% 45%;
|
||||
--warning: 24 100% 55%;
|
||||
--warning: 40 100% 55%;
|
||||
|
||||
--border: 0 0% 16%;
|
||||
--input: 0 0% 16%;
|
||||
--ring: 217 100% 60%;
|
||||
--ring: 24 100% 58%;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user