ui: Polish marketing website
This commit is contained in:
@@ -13,26 +13,21 @@ interface ComparisonTableProps {
|
||||
rows: ComparisonRow[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Reusable comparison table component for competitor pages
|
||||
*/
|
||||
export function ComparisonTable({competitorName, rows}: ComparisonTableProps) {
|
||||
return (
|
||||
<div className={'overflow-hidden rounded-xl border border-neutral-200'}>
|
||||
{/* Header */}
|
||||
<div className={'overflow-hidden rounded-[24px] border border-neutral-200'}>
|
||||
<div className={'grid grid-cols-3 gap-px bg-neutral-200'}>
|
||||
<div className={'bg-white p-6'}>
|
||||
<span className={'text-sm font-semibold text-neutral-900'}>Feature</span>
|
||||
<div className={'bg-neutral-50 p-6'}>
|
||||
<span style={{fontFamily: 'var(--font-mono)'}} className={'text-[11px] uppercase tracking-[0.18em] text-neutral-500'}>Feature</span>
|
||||
</div>
|
||||
<div className={'bg-white p-6 text-center'}>
|
||||
<span className={'text-sm font-semibold text-neutral-900'}>Plunk</span>
|
||||
<div className={'bg-neutral-900 p-6 text-center'}>
|
||||
<span style={{fontFamily: 'var(--font-mono)'}} className={'text-[11px] uppercase tracking-[0.18em] text-white'}>Plunk</span>
|
||||
</div>
|
||||
<div className={'bg-white p-6 text-center'}>
|
||||
<span className={'text-sm font-semibold text-neutral-900'}>{competitorName}</span>
|
||||
<div className={'bg-neutral-50 p-6 text-center'}>
|
||||
<span style={{fontFamily: 'var(--font-mono)'}} className={'text-[11px] uppercase tracking-[0.18em] text-neutral-500'}>{competitorName}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Rows */}
|
||||
<div className={'grid gap-px bg-neutral-200'}>
|
||||
{rows.map((row, index) => (
|
||||
<motion.div
|
||||
@@ -40,7 +35,7 @@ export function ComparisonTable({competitorName, rows}: ComparisonTableProps) {
|
||||
initial={{opacity: 0, y: 10}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: index * 0.05, ease: [0.22, 1, 0.36, 1]}}
|
||||
transition={{duration: 0.4, delay: index * 0.04, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'grid grid-cols-3 gap-px bg-neutral-200'}
|
||||
>
|
||||
<div className={'bg-white p-6'}>
|
||||
@@ -52,10 +47,10 @@ export function ComparisonTable({competitorName, rows}: ComparisonTableProps) {
|
||||
row.plunk ? (
|
||||
<Check className="h-5 w-5 text-neutral-900" strokeWidth={2} />
|
||||
) : (
|
||||
<X className="h-5 w-5 text-neutral-400" strokeWidth={2} />
|
||||
<X className="h-5 w-5 text-neutral-300" strokeWidth={2} />
|
||||
)
|
||||
) : (
|
||||
<span className={'text-sm text-neutral-900'}>{row.plunk}</span>
|
||||
<span className={'text-sm font-medium text-neutral-900'}>{row.plunk}</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
@@ -65,10 +60,10 @@ export function ComparisonTable({competitorName, rows}: ComparisonTableProps) {
|
||||
row.competitor ? (
|
||||
<Check className="h-5 w-5 text-neutral-900" strokeWidth={2} />
|
||||
) : (
|
||||
<X className="h-5 w-5 text-neutral-400" strokeWidth={2} />
|
||||
<X className="h-5 w-5 text-neutral-300" strokeWidth={2} />
|
||||
)
|
||||
) : (
|
||||
<span className={'text-sm text-neutral-900'}>{row.competitor}</span>
|
||||
<span className={'text-sm text-neutral-600'}>{row.competitor}</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -12,9 +12,6 @@ interface FAQSectionProps {
|
||||
schemaId?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reusable FAQ section component with structured data support
|
||||
*/
|
||||
export function FAQSection({faqs, schemaId = 'faq-schema'}: FAQSectionProps) {
|
||||
return (
|
||||
<>
|
||||
@@ -37,34 +34,44 @@ export function FAQSection({faqs, schemaId = 'faq-schema'}: FAQSectionProps) {
|
||||
}}
|
||||
/>
|
||||
|
||||
<section className={'py-32'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mx-auto max-w-4xl'}
|
||||
>
|
||||
<h2 className={'mb-16 text-center text-5xl font-bold tracking-tight text-neutral-900'}>
|
||||
Frequently asked questions
|
||||
</h2>
|
||||
<section className={'border-t border-neutral-200'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-16'}
|
||||
>
|
||||
<h2
|
||||
style={{fontFamily: 'var(--font-display)'}}
|
||||
className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}
|
||||
>
|
||||
Frequently asked questions
|
||||
</h2>
|
||||
</motion.div>
|
||||
|
||||
<div className={'space-y-8'}>
|
||||
<div className={'mx-auto max-w-3xl divide-y divide-neutral-200'}>
|
||||
{faqs.map((faq, index) => (
|
||||
<motion.div
|
||||
key={index}
|
||||
initial={{opacity: 0, y: 20}}
|
||||
initial={{opacity: 0, y: 16}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: index * 0.1, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'border-b border-neutral-200 pb-8 last:border-b-0'}
|
||||
transition={{duration: 0.5, delay: index * 0.06, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'py-8'}
|
||||
>
|
||||
<h3 className={'text-xl font-semibold text-neutral-900'}>{faq.question}</h3>
|
||||
<p className={'mt-4 leading-relaxed text-neutral-600'}>{faq.answer}</p>
|
||||
<h3
|
||||
style={{fontFamily: 'var(--font-display)'}}
|
||||
className={'text-lg font-bold tracking-[-0.02em] text-neutral-900'}
|
||||
>
|
||||
{faq.question}
|
||||
</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>{faq.answer}</p>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -10,7 +10,7 @@ export default function Footer() {
|
||||
return (
|
||||
<>
|
||||
<footer className={'border-t border-neutral-200 bg-white'}>
|
||||
<div className="mx-auto max-w-7xl px-8 py-20 xl:px-0">
|
||||
<div className="mx-auto max-w-[88rem] px-6 py-20 sm:px-10">
|
||||
<div className="grid gap-12 lg:grid-cols-12">
|
||||
{/* Logo and description */}
|
||||
<div className="space-y-6 lg:col-span-3">
|
||||
@@ -59,7 +59,7 @@ export default function Footer() {
|
||||
{/* Links */}
|
||||
<div className="grid grid-cols-2 gap-8 lg:col-span-9 lg:grid-cols-5">
|
||||
<div>
|
||||
<h3 className="text-sm font-semibold text-neutral-900">Product</h3>
|
||||
<h3 style={{fontFamily: 'var(--font-mono)'}} className="text-[11px] font-semibold uppercase tracking-[0.18em] text-neutral-500">Product</h3>
|
||||
<ul role="list" className="mt-6 space-y-4">
|
||||
<li>
|
||||
<Link href={'/pricing'} className="text-sm text-neutral-600 transition hover:text-neutral-900">
|
||||
@@ -90,7 +90,7 @@ export default function Footer() {
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 className="text-sm font-semibold text-neutral-900">Features</h3>
|
||||
<h3 style={{fontFamily: 'var(--font-mono)'}} className="text-[11px] font-semibold uppercase tracking-[0.18em] text-neutral-500">Features</h3>
|
||||
<ul role="list" className="mt-6 space-y-4">
|
||||
<li>
|
||||
<Link href={'/features/email-editor'} className="text-sm text-neutral-600 transition hover:text-neutral-900">
|
||||
@@ -121,7 +121,7 @@ export default function Footer() {
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 className="text-sm font-semibold text-neutral-900">Compare</h3>
|
||||
<h3 style={{fontFamily: 'var(--font-mono)'}} className="text-[11px] font-semibold uppercase tracking-[0.18em] text-neutral-500">Compare</h3>
|
||||
<ul role="list" className="mt-6 space-y-4">
|
||||
<li>
|
||||
<Link href={'/vs'} className="text-sm text-neutral-600 transition hover:text-neutral-900">
|
||||
@@ -162,7 +162,7 @@ export default function Footer() {
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 className="text-sm font-semibold text-neutral-900">Community</h3>
|
||||
<h3 style={{fontFamily: 'var(--font-mono)'}} className="text-[11px] font-semibold uppercase tracking-[0.18em] text-neutral-500">Community</h3>
|
||||
<ul role="list" className="mt-6 space-y-4">
|
||||
<li>
|
||||
<Link href={'/discord'} className="text-sm text-neutral-600 transition hover:text-neutral-900">
|
||||
@@ -181,7 +181,7 @@ export default function Footer() {
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h3 className="mt-8 text-sm font-semibold text-neutral-900">Legal</h3>
|
||||
<h3 style={{fontFamily: 'var(--font-mono)'}} className="mt-8 text-[11px] font-semibold uppercase tracking-[0.18em] text-neutral-500">Legal</h3>
|
||||
<ul role="list" className="mt-6 space-y-4">
|
||||
<li>
|
||||
<Link href={'/privacy'} className="text-sm text-neutral-600 transition hover:text-neutral-900">
|
||||
@@ -202,7 +202,7 @@ export default function Footer() {
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 className="text-sm font-semibold text-neutral-900">Guides</h3>
|
||||
<h3 style={{fontFamily: 'var(--font-mono)'}} className="text-[11px] font-semibold uppercase tracking-[0.18em] text-neutral-500">Guides</h3>
|
||||
<ul role="list" className="mt-6 space-y-4">
|
||||
<li>
|
||||
<Link href={'/guides/email-deliverability'} className="text-sm text-neutral-600 transition hover:text-neutral-900">
|
||||
|
||||
@@ -47,8 +47,8 @@ export default function Navbar() {
|
||||
const [featuresOpen, setFeaturesOpen] = useState(false);
|
||||
|
||||
return (
|
||||
<header className={'sticky top-0 z-40 w-full border-b border-neutral-100 bg-white/95 backdrop-blur-sm'}>
|
||||
<div className={'relative mx-auto max-w-7xl px-8 xl:px-0'}>
|
||||
<header className={'sticky top-0 z-40 w-full border-b border-neutral-200 bg-white/95 backdrop-blur-sm'}>
|
||||
<div className={'relative mx-auto max-w-[88rem] px-6 sm:px-10'}>
|
||||
<div className={'py-5'}>
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center gap-12">
|
||||
@@ -83,14 +83,14 @@ export default function Navbar() {
|
||||
onMouseEnter={() => setFeaturesOpen(true)}
|
||||
onMouseLeave={() => setFeaturesOpen(false)}
|
||||
className={
|
||||
'absolute left-0 top-full z-50 mt-2 w-80 rounded-lg border border-neutral-200 bg-white p-2 shadow-lg'
|
||||
'absolute left-0 top-full z-50 mt-2 w-80 rounded-[16px] border border-neutral-200 bg-white p-2 shadow-lg'
|
||||
}
|
||||
>
|
||||
{featuresMenu.map(feature => (
|
||||
<Link
|
||||
key={feature.href}
|
||||
href={feature.href}
|
||||
className={'flex items-start gap-3 rounded-lg p-3 transition hover:bg-neutral-50'}
|
||||
className={'flex items-start gap-3 rounded-[10px] p-3 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
@@ -166,7 +166,7 @@ export default function Navbar() {
|
||||
whileTap={{scale: 0.98}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
className={
|
||||
'rounded-lg bg-neutral-900 px-6 py-2.5 text-sm font-semibold text-white shadow-sm transition hover:bg-neutral-800'
|
||||
'rounded-full bg-neutral-900 px-6 py-2.5 text-sm font-semibold text-white transition hover:bg-neutral-800'
|
||||
}
|
||||
>
|
||||
Get started
|
||||
@@ -226,7 +226,7 @@ export default function Navbar() {
|
||||
className="space-y-1 p-4"
|
||||
>
|
||||
<div className="mb-2">
|
||||
<div className="px-4 py-2 text-xs font-semibold uppercase tracking-wider text-neutral-500">
|
||||
<div style={{fontFamily: 'var(--font-mono)'}} className="px-4 py-2 text-[11px] font-semibold uppercase tracking-[0.18em] text-neutral-500">
|
||||
Features
|
||||
</div>
|
||||
{featuresMenu.map(feature => (
|
||||
@@ -293,7 +293,7 @@ export default function Navbar() {
|
||||
</a>
|
||||
<a
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
className="mt-2 block rounded-lg bg-neutral-900 px-4 py-3 text-center text-sm font-semibold text-white transition hover:bg-neutral-800"
|
||||
className="mt-2 block rounded-full bg-neutral-900 px-4 py-3 text-center text-sm font-semibold text-white transition hover:bg-neutral-800"
|
||||
>
|
||||
Get started
|
||||
</a>
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
import {motion} from 'framer-motion';
|
||||
import React from 'react';
|
||||
|
||||
export function SectionHeader({
|
||||
number,
|
||||
label,
|
||||
title,
|
||||
titleAccent,
|
||||
subtitle,
|
||||
}: {
|
||||
number: string;
|
||||
label: string;
|
||||
title: string;
|
||||
titleAccent?: string;
|
||||
subtitle?: string;
|
||||
}) {
|
||||
return (
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 16}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true, margin: '-10%'}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'grid gap-8 lg:grid-cols-12 lg:gap-16'}
|
||||
>
|
||||
<div
|
||||
style={{fontFamily: 'var(--font-mono)'}}
|
||||
className={
|
||||
'flex items-center gap-4 border-t border-neutral-900 pt-4 text-[11px] uppercase tracking-[0.2em] text-neutral-700 lg:col-span-3 lg:self-start'
|
||||
}
|
||||
>
|
||||
<span className={'font-medium text-neutral-900'}>§ {number}</span>
|
||||
<span className={'text-neutral-500'}>{label}</span>
|
||||
</div>
|
||||
<div className={'lg:col-span-9'}>
|
||||
<h2
|
||||
style={{fontFamily: 'var(--font-display)'}}
|
||||
className={
|
||||
'text-[clamp(2.25rem,5.5vw,4.5rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'
|
||||
}
|
||||
>
|
||||
{title}
|
||||
{titleAccent && <> {titleAccent}</>}
|
||||
</h2>
|
||||
{subtitle && <p className={'mt-6 max-w-2xl text-lg leading-relaxed text-neutral-600'}>{subtitle}</p>}
|
||||
</div>
|
||||
</motion.div>
|
||||
);
|
||||
}
|
||||
@@ -114,7 +114,7 @@ export function GuideLayout({
|
||||
|
||||
<Navbar />
|
||||
|
||||
<main className={'mx-auto max-w-7xl px-4 sm:px-8 w-full overflow-x-hidden'}>
|
||||
<main className={'mx-auto max-w-[88rem] px-4 sm:px-8 w-full overflow-x-hidden'}>
|
||||
<div className={'flex flex-col lg:flex-row gap-8 lg:gap-12 py-8 sm:py-16 w-full'}>
|
||||
{/* Main Content */}
|
||||
<article className={'flex-1 max-w-full lg:max-w-4xl w-full'}>
|
||||
|
||||
@@ -3,3 +3,4 @@ export * from './Footer';
|
||||
export * from './ComparisonTable';
|
||||
export * from './FAQSection';
|
||||
export * from './CodeBlock';
|
||||
export * from './SectionHeader';
|
||||
|
||||
@@ -7,6 +7,28 @@ import {SWRConfig} from 'swr';
|
||||
import {network} from '../lib/network';
|
||||
import {DefaultSeo} from 'next-seo';
|
||||
import Script from 'next/script';
|
||||
import {Bricolage_Grotesque, Hanken_Grotesk, JetBrains_Mono} from 'next/font/google';
|
||||
|
||||
const display = Bricolage_Grotesque({
|
||||
subsets: ['latin'],
|
||||
variable: '--font-display',
|
||||
display: 'swap',
|
||||
weight: ['400', '500', '600', '700', '800'],
|
||||
});
|
||||
|
||||
const body = Hanken_Grotesk({
|
||||
subsets: ['latin'],
|
||||
variable: '--font-body',
|
||||
display: 'swap',
|
||||
weight: ['400', '500', '600', '700'],
|
||||
});
|
||||
|
||||
const mono = JetBrains_Mono({
|
||||
subsets: ['latin'],
|
||||
variable: '--font-mono',
|
||||
display: 'swap',
|
||||
weight: ['400', '500'],
|
||||
});
|
||||
|
||||
/**
|
||||
* Main app component
|
||||
@@ -25,7 +47,7 @@ function App({Component, pageProps}: AppProps) {
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className={`${display.variable} ${body.variable} ${mono.variable}`}>
|
||||
<Head>
|
||||
<title>Plunk | The Open-Source Email Platform</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" key={'viewport'} />
|
||||
@@ -33,7 +55,7 @@ function App({Component, pageProps}: AppProps) {
|
||||
<Toaster position={'top-right'} />
|
||||
|
||||
<Component {...pageProps} />
|
||||
</>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,14 +6,6 @@ export default class MyDocument extends Document {
|
||||
return (
|
||||
<Html lang="en">
|
||||
<Head>
|
||||
{/* Start fonts */}
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" />
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800;900&family=JetBrains+Mono:wght@500&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
{/* End fonts */}
|
||||
{/* Start favicon */}
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/favicon/apple-touch-icon.png" />
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/favicon/favicon-32x32.png" />
|
||||
|
||||
@@ -8,36 +8,34 @@ import Head from 'next/head';
|
||||
|
||||
const features = [
|
||||
{
|
||||
icon: <Type className="h-5 w-5" />,
|
||||
icon: <Type className="h-6 w-6" strokeWidth={1.5} />,
|
||||
title: 'Visual WYSIWYG Editor',
|
||||
description:
|
||||
'Rich text editing with formatting toolbar. Bold, italic, headings, lists, links, images, and tables. No code required.',
|
||||
featured: true,
|
||||
},
|
||||
{
|
||||
icon: <Code2 className="h-5 w-5" />,
|
||||
icon: <Code2 className="h-6 w-6" strokeWidth={1.5} />,
|
||||
title: 'Full HTML Editor',
|
||||
description:
|
||||
'Syntax highlighting, auto-completion, and bracket matching. Write custom HTML when you need complete control.',
|
||||
description: 'Syntax highlighting, auto-completion, and bracket matching. Write custom HTML when you need complete control.',
|
||||
},
|
||||
{
|
||||
icon: <Zap className="h-5 w-5" />,
|
||||
icon: <Zap className="h-6 w-6" strokeWidth={1.5} />,
|
||||
title: 'Smart Mode Switching',
|
||||
description:
|
||||
'Automatically detects complex HTML and switches to code mode. Warns you before changes that would lose custom formatting.',
|
||||
description: 'Automatically detects complex HTML and switches to code mode. Warns you before changes that would lose custom formatting.',
|
||||
},
|
||||
{
|
||||
icon: <Sparkles className="h-5 w-5" />,
|
||||
icon: <Sparkles className="h-6 w-6" strokeWidth={1.5} />,
|
||||
title: 'Powerful Variables',
|
||||
description:
|
||||
'Autocomplete with {{variable}} syntax. Supports fallbacks, nested properties, and custom contact fields.',
|
||||
description: 'Autocomplete with {{variable}} syntax. Supports fallbacks, nested properties, and custom contact fields.',
|
||||
},
|
||||
{
|
||||
icon: <Eye className="h-5 w-5" />,
|
||||
icon: <Eye className="h-6 w-6" strokeWidth={1.5} />,
|
||||
title: 'Live Preview',
|
||||
description: 'Preview with real contact data. Test on desktop, tablet, and mobile views before sending.',
|
||||
},
|
||||
{
|
||||
icon: <Palette className="h-5 w-5" />,
|
||||
icon: <Palette className="h-6 w-6" strokeWidth={1.5} />,
|
||||
title: 'Email-Safe HTML',
|
||||
description: 'Automatic CSS inlining and email-client-friendly code generation. Yes, even in Outlook.',
|
||||
},
|
||||
@@ -45,21 +43,21 @@ const features = [
|
||||
|
||||
const useCases = [
|
||||
{
|
||||
icon: <Code2 className="h-6 w-6" />,
|
||||
icon: <Code2 className="h-6 w-6" strokeWidth={1.5} />,
|
||||
title: 'For Developers',
|
||||
description:
|
||||
'Full HTML control when you need it. Powerful variable system with autocomplete and fallbacks. Use templates in API calls, workflows, and campaigns.',
|
||||
example: 'Password resets → API-triggered alerts → Webhook notifications → Those cat meme attachments',
|
||||
example: 'Password resets → API-triggered alerts → Webhook notifications',
|
||||
},
|
||||
{
|
||||
icon: <Palette className="h-6 w-6" />,
|
||||
icon: <Palette className="h-6 w-6" strokeWidth={1.5} />,
|
||||
title: 'For Marketers',
|
||||
description:
|
||||
'Visual editor for quick changes. Live preview with real customer data. Create professional emails without waiting for developers.',
|
||||
example: 'Product announcements → Newsletter campaigns → Promotional emails → Customer onboarding',
|
||||
},
|
||||
{
|
||||
icon: <Zap className="h-6 w-6" />,
|
||||
icon: <Zap className="h-6 w-6" strokeWidth={1.5} />,
|
||||
title: 'For Teams',
|
||||
description:
|
||||
'One tool for everyone. Developers can code, marketers can design, everyone can preview. Reusable templates across campaigns and workflows.',
|
||||
@@ -67,9 +65,6 @@ const useCases = [
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export default function EmailEditorFeature() {
|
||||
return (
|
||||
<>
|
||||
@@ -79,10 +74,7 @@ export default function EmailEditorFeature() {
|
||||
name="description"
|
||||
content="The email editor that speaks both languages. Switch seamlessly between visual and code editing, preview with real data, and create templates that work everywhere."
|
||||
/>
|
||||
<meta
|
||||
property="og:title"
|
||||
content="Email Editor - Create Beautiful Emails Without Fighting Your Tools | Plunk"
|
||||
/>
|
||||
<meta property="og:title" content="Email Editor - Create Beautiful Emails Without Fighting Your Tools | Plunk" />
|
||||
<meta
|
||||
property="og:description"
|
||||
content="The email editor that speaks both languages. Switch seamlessly between visual and code editing, preview with real data, and create templates that work everywhere."
|
||||
@@ -91,265 +83,292 @@ export default function EmailEditorFeature() {
|
||||
|
||||
<Navbar />
|
||||
|
||||
<main className={'mx-auto max-w-7xl px-8 sm:px-0'}>
|
||||
{/* Hero Section */}
|
||||
<section className={'relative py-20 sm:py-32'}>
|
||||
{/* Subtle background grid */}
|
||||
<main className={'text-neutral-800'}>
|
||||
|
||||
{/* Hero */}
|
||||
<section className={'relative overflow-hidden'}>
|
||||
<div
|
||||
aria-hidden
|
||||
className={
|
||||
'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#e5e7eb_1px,transparent_1px),linear-gradient(to_bottom,#e5e7eb_1px,transparent_1px)] bg-[size:4rem_4rem] [mask-image:radial-gradient(ellipse_80%_50%_at_50%_0%,#000_70%,transparent_110%)]'
|
||||
'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#eeeeee_1px,transparent_1px),linear-gradient(to_bottom,#eeeeee_1px,transparent_1px)] bg-[size:6rem_6rem] [mask-image:radial-gradient(ellipse_70%_60%_at_50%_30%,#000_40%,transparent_95%)]'
|
||||
}
|
||||
/>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
animate={{opacity: 1, y: 0}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mx-auto max-w-4xl text-center'}
|
||||
>
|
||||
<div className={'mb-6 inline-flex items-center gap-2 rounded-full bg-neutral-100 px-4 py-2 text-sm'}>
|
||||
<Mail className="h-4 w-4 text-neutral-600" />
|
||||
<span className={'font-medium text-neutral-600'}>Email Editor & Templates</span>
|
||||
</div>
|
||||
|
||||
<h1 className={'text-6xl font-bold tracking-tight text-neutral-900 sm:text-7xl lg:text-8xl text-balance'}>
|
||||
The Email Editor
|
||||
<br />
|
||||
That Speaks Both Languages
|
||||
</h1>
|
||||
<p className={'mx-auto mt-8 max-w-2xl text-xl text-neutral-600'}>
|
||||
Switch seamlessly between visual and code editing. Preview with real customer data. Create templates that
|
||||
work everywhere.
|
||||
</p>
|
||||
|
||||
<div className={'mt-12 flex flex-wrap justify-center gap-4'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.02}}
|
||||
whileTap={{scale: 0.98}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
<div className={'mx-auto max-w-[88rem] px-6 pb-20 pt-20 sm:px-10 sm:pt-28 sm:pb-28'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 16}}
|
||||
animate={{opacity: 1, y: 0}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
>
|
||||
<div
|
||||
style={{fontFamily: 'var(--font-mono)'}}
|
||||
className={'mb-6 text-[11px] uppercase tracking-[0.18em] text-neutral-500'}
|
||||
>
|
||||
Email Editor & Templates
|
||||
</div>
|
||||
<h1
|
||||
style={{fontFamily: 'var(--font-display)'}}
|
||||
className={
|
||||
'group rounded-lg bg-neutral-900 px-8 py-4 text-base font-semibold text-white shadow-lg shadow-neutral-900/10 transition hover:bg-neutral-800'
|
||||
'text-[clamp(2.75rem,7vw,6.5rem)] font-extrabold leading-[0.92] tracking-[-0.04em] text-neutral-900'
|
||||
}
|
||||
>
|
||||
<span className={'flex items-center gap-2'}>
|
||||
Try the editor free
|
||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-1" />
|
||||
</span>
|
||||
</motion.a>
|
||||
<Link
|
||||
href={WIKI_URI}
|
||||
target={'_blank'}
|
||||
className={
|
||||
'rounded-lg border border-neutral-300 bg-white px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-400'
|
||||
}
|
||||
>
|
||||
View documentation
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
</section>
|
||||
The editor that
|
||||
<br />
|
||||
speaks both languages.
|
||||
</h1>
|
||||
<p className={'mt-6 max-w-2xl text-xl text-neutral-600'}>
|
||||
Switch seamlessly between visual and code editing. Preview with real customer data. Create templates that
|
||||
work everywhere.
|
||||
</p>
|
||||
|
||||
{/* Features Grid */}
|
||||
<section className={'py-20'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-16 text-center'}
|
||||
>
|
||||
<h2 className={'text-4xl font-bold tracking-tight text-neutral-900 sm:text-5xl text-balance'}>
|
||||
Two editors, one experience
|
||||
</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Visual editing for speed, code editing for control</p>
|
||||
</motion.div>
|
||||
|
||||
<div className={'grid gap-px bg-neutral-200 sm:grid-cols-2 lg:grid-cols-3'}>
|
||||
{features.map((feature, index) => (
|
||||
<motion.div
|
||||
key={feature.title}
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: index * 0.1, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-10 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
<div className={'mt-10 flex flex-wrap gap-3'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.015}}
|
||||
whileTap={{scale: 0.985}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
'group inline-flex items-center gap-2 rounded-full bg-neutral-900 px-8 py-4 text-base font-semibold text-white shadow-[0_10px_30px_-10px_rgba(23,23,23,0.35)] transition hover:bg-neutral-800'
|
||||
}
|
||||
>
|
||||
{feature.icon}
|
||||
</div>
|
||||
<h3 className={'mt-6 text-lg font-semibold text-neutral-900'}>{feature.title}</h3>
|
||||
<p className={'mt-2 text-sm leading-relaxed text-neutral-600'}>{feature.description}</p>
|
||||
</motion.div>
|
||||
))}
|
||||
Try the editor free
|
||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-0.5" />
|
||||
</motion.a>
|
||||
<Link
|
||||
href={WIKI_URI}
|
||||
target={'_blank'}
|
||||
className={
|
||||
'inline-flex items-center gap-2 rounded-full border border-neutral-300 bg-white px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-900'
|
||||
}
|
||||
>
|
||||
View documentation
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* How It Works */}
|
||||
<section className={'py-20'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mx-auto max-w-4xl text-center'}
|
||||
>
|
||||
<h2 className={'text-4xl font-bold tracking-tight text-neutral-900 sm:text-5xl text-balance'}>
|
||||
From first draft to send
|
||||
</h2>
|
||||
<p className={'mt-6 text-lg text-neutral-600'}>Create, preview, and deploy templates in minutes</p>
|
||||
</motion.div>
|
||||
|
||||
<div className={'mx-auto mt-16 max-w-5xl'}>
|
||||
<div className={'grid gap-12 lg:grid-cols-3'}>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.1, ease: [0.22, 1, 0.36, 1]}}
|
||||
{/* Features grid */}
|
||||
<section className={'border-t border-neutral-200'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-16'}
|
||||
>
|
||||
<h2
|
||||
style={{fontFamily: 'var(--font-display)'}}
|
||||
className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}
|
||||
>
|
||||
<div className={'mb-5 flex items-center gap-4'}>
|
||||
<div className={'flex h-14 w-14 items-center justify-center rounded-full border-2 border-neutral-200 bg-white text-xl font-bold text-neutral-900'}>
|
||||
1
|
||||
</div>
|
||||
</div>
|
||||
<h3 className={'text-lg font-semibold text-neutral-900'}>Create your template</h3>
|
||||
<p className={'mt-2 text-sm leading-relaxed text-neutral-600'}>
|
||||
Use the visual editor for quick formatting or write custom HTML. Add variables with autocomplete.
|
||||
</p>
|
||||
</motion.div>
|
||||
Two editors, one experience
|
||||
</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Visual editing for speed, code editing for control</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.2, ease: [0.22, 1, 0.36, 1]}}
|
||||
>
|
||||
<div className={'mb-5 flex items-center gap-4'}>
|
||||
<div className={'flex h-14 w-14 items-center justify-center rounded-full border-2 border-neutral-200 bg-white text-xl font-bold text-neutral-900'}>
|
||||
2
|
||||
</div>
|
||||
</div>
|
||||
<h3 className={'text-lg font-semibold text-neutral-900'}>Preview with real data</h3>
|
||||
<p className={'mt-2 text-sm leading-relaxed text-neutral-600'}>
|
||||
Select any contact and see exactly what they'll receive. Test on desktop, tablet, and mobile. No
|
||||
surprises.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.3, ease: [0.22, 1, 0.36, 1]}}
|
||||
>
|
||||
<div className={'mb-5 flex items-center gap-4'}>
|
||||
<div className={'flex h-14 w-14 items-center justify-center rounded-full border-2 border-neutral-200 bg-white text-xl font-bold text-neutral-900'}>
|
||||
3
|
||||
</div>
|
||||
</div>
|
||||
<h3 className={'text-lg font-semibold text-neutral-900'}>Use everywhere</h3>
|
||||
<p className={'mt-2 text-sm leading-relaxed text-neutral-600'}>
|
||||
Use your template in campaigns, workflows, and API calls. One template, unlimited uses.
|
||||
</p>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Use Cases */}
|
||||
<section className={'py-20'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-16 text-center'}
|
||||
>
|
||||
<h2 className={'text-4xl font-bold tracking-tight text-neutral-900 sm:text-5xl text-balance'}>Built for every team</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Whether you're a developer, marketer, or founder</p>
|
||||
</motion.div>
|
||||
|
||||
<div className={'mx-auto max-w-5xl space-y-8'}>
|
||||
{useCases.map((useCase, index) => (
|
||||
<motion.div
|
||||
key={useCase.title}
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: index * 0.1, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'rounded-xl border border-neutral-200 bg-white p-8'}
|
||||
>
|
||||
<div className={'flex items-start gap-6'}>
|
||||
<div
|
||||
<div className={'grid gap-4 sm:grid-cols-2 lg:grid-cols-3'}>
|
||||
{features.map((feature, index) => {
|
||||
const highlighted = feature.featured;
|
||||
return (
|
||||
<motion.div
|
||||
key={feature.title}
|
||||
initial={{opacity: 0, y: 16}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: index * 0.06, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={
|
||||
'flex h-14 w-14 flex-shrink-0 items-center justify-center rounded-xl bg-neutral-900 text-white'
|
||||
highlighted
|
||||
? 'flex min-h-[16rem] flex-col justify-between rounded-[28px] border border-neutral-900 bg-neutral-900 p-8 text-white'
|
||||
: 'flex min-h-[16rem] flex-col justify-between rounded-[28px] border border-neutral-200 bg-white p-8 transition hover:border-neutral-900'
|
||||
}
|
||||
>
|
||||
{useCase.icon}
|
||||
</div>
|
||||
<div className={'flex-1'}>
|
||||
<h3 className={'text-xl font-semibold text-neutral-900'}>{useCase.title}</h3>
|
||||
<p className={'mt-2 text-neutral-600'}>{useCase.description}</p>
|
||||
<div className={'mt-4 rounded-lg bg-neutral-50 p-4'}>
|
||||
<p className={'text-sm text-neutral-700'}>{useCase.example}</p>
|
||||
<div className={'flex items-start justify-between'}>
|
||||
<div className={highlighted ? 'text-white' : 'text-neutral-900'}>{feature.icon}</div>
|
||||
<span
|
||||
style={{fontFamily: 'var(--font-mono)'}}
|
||||
className={`text-[11px] uppercase tracking-[0.18em] ${highlighted ? 'text-neutral-500' : 'text-neutral-400'}`}
|
||||
>
|
||||
{String(index + 1).padStart(2, '0')}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
))}
|
||||
<div>
|
||||
<h3
|
||||
style={{fontFamily: 'var(--font-display)'}}
|
||||
className={`mt-8 text-xl font-bold tracking-[-0.02em] ${highlighted ? 'text-white' : 'text-neutral-900'}`}
|
||||
>
|
||||
{feature.title}
|
||||
</h3>
|
||||
<p className={`mt-2 text-sm leading-relaxed ${highlighted ? 'text-neutral-300' : 'text-neutral-600'}`}>
|
||||
{feature.description}
|
||||
</p>
|
||||
</div>
|
||||
</motion.div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* CTA Section */}
|
||||
<section className={'relative overflow-hidden border-t border-neutral-200 py-20'}>
|
||||
<div
|
||||
className={
|
||||
'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#e5e7eb_1px,transparent_1px),linear-gradient(to_bottom,#e5e7eb_1px,transparent_1px)] bg-[size:4rem_4rem] [mask-image:radial-gradient(ellipse_80%_50%_at_50%_100%,#000_70%,transparent_110%)]'
|
||||
}
|
||||
/>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mx-auto max-w-3xl text-center'}
|
||||
>
|
||||
<h2 className={'text-4xl font-bold tracking-tight text-neutral-900 sm:text-5xl text-balance'}>
|
||||
Build your first template today
|
||||
</h2>
|
||||
<p className={'mt-6 text-lg text-neutral-600'}>
|
||||
1,000 emails free every month. Then $0.001 per email. No contact limits, no credit card required.
|
||||
</p>
|
||||
<div className={'mt-12 flex flex-wrap justify-center gap-4'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.02}}
|
||||
whileTap={{scale: 0.98}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
className={
|
||||
'group rounded-lg bg-neutral-900 px-8 py-4 text-base font-semibold text-white transition hover:bg-neutral-800'
|
||||
}
|
||||
{/* How it works */}
|
||||
<section className={'border-t border-neutral-200 bg-neutral-50/60'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-16 text-center'}
|
||||
>
|
||||
<h2
|
||||
style={{fontFamily: 'var(--font-display)'}}
|
||||
className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}
|
||||
>
|
||||
<span className={'flex items-center gap-2'}>
|
||||
Get started for free
|
||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-1" />
|
||||
</span>
|
||||
</motion.a>
|
||||
<Link
|
||||
href={'/pricing'}
|
||||
className={
|
||||
'rounded-lg border border-neutral-300 px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-400'
|
||||
}
|
||||
>
|
||||
View pricing
|
||||
</Link>
|
||||
From first draft to send
|
||||
</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Create, preview, and deploy templates in minutes</p>
|
||||
</motion.div>
|
||||
|
||||
<div className={'mx-auto max-w-4xl'}>
|
||||
<div className={'grid gap-px bg-neutral-200 sm:grid-cols-3'}>
|
||||
{[
|
||||
{
|
||||
step: '01',
|
||||
title: 'Create your template',
|
||||
body: 'Use the visual editor for quick formatting or write custom HTML. Add variables with autocomplete.',
|
||||
},
|
||||
{
|
||||
step: '02',
|
||||
title: 'Preview with real data',
|
||||
body: 'Select any contact and see exactly what they\'ll receive. Test on desktop, tablet, and mobile.',
|
||||
},
|
||||
{
|
||||
step: '03',
|
||||
title: 'Use everywhere',
|
||||
body: 'Use your template in campaigns, workflows, and API calls. One template, unlimited uses.',
|
||||
},
|
||||
].map((item, i) => (
|
||||
<motion.div
|
||||
key={item.step}
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: i * 0.1, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'bg-white p-10'}
|
||||
>
|
||||
<div
|
||||
style={{fontFamily: 'var(--font-mono)'}}
|
||||
className={'mb-6 text-[11px] uppercase tracking-[0.18em] text-neutral-400'}
|
||||
>
|
||||
Step {item.step}
|
||||
</div>
|
||||
<h3 className={'text-lg font-semibold text-neutral-900'}>{item.title}</h3>
|
||||
<p className={'mt-2 text-sm leading-relaxed text-neutral-600'}>{item.body}</p>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Use cases */}
|
||||
<section className={'border-t border-neutral-200'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-16'}
|
||||
>
|
||||
<h2
|
||||
style={{fontFamily: 'var(--font-display)'}}
|
||||
className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}
|
||||
>
|
||||
Built for every team
|
||||
</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Whether you're a developer, marketer, or founder</p>
|
||||
</motion.div>
|
||||
|
||||
<div className={'space-y-4'}>
|
||||
{useCases.map((useCase, index) => (
|
||||
<motion.div
|
||||
key={useCase.title}
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: index * 0.1, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'rounded-[24px] border border-neutral-200 bg-white p-8'}
|
||||
>
|
||||
<div className={'flex items-start gap-6'}>
|
||||
<div className={'flex h-14 w-14 flex-shrink-0 items-center justify-center rounded-full border border-neutral-200 text-neutral-900'}>
|
||||
{useCase.icon}
|
||||
</div>
|
||||
<div className={'flex-1'}>
|
||||
<h3
|
||||
style={{fontFamily: 'var(--font-display)'}}
|
||||
className={'text-xl font-bold tracking-[-0.02em] text-neutral-900'}
|
||||
>
|
||||
{useCase.title}
|
||||
</h3>
|
||||
<p className={'mt-2 text-neutral-600'}>{useCase.description}</p>
|
||||
<div className={'mt-4 rounded-xl border border-neutral-100 bg-neutral-50 p-4'}>
|
||||
<p style={{fontFamily: 'var(--font-mono)'}} className={'text-sm text-neutral-600'}>
|
||||
{useCase.example}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* CTA */}
|
||||
<section className={'relative overflow-hidden border-t border-neutral-900 bg-neutral-900 text-white'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-32 sm:px-10 sm:py-40'}>
|
||||
<div className={'flex flex-col items-start gap-12 lg:flex-row lg:items-end lg:justify-between'}>
|
||||
<motion.h2
|
||||
initial={{opacity: 0, y: 16}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.9, ease: [0.22, 1, 0.36, 1]}}
|
||||
style={{fontFamily: 'var(--font-display)'}}
|
||||
className={'text-[clamp(2.5rem,7vw,6rem)] font-extrabold leading-[0.95] tracking-[-0.035em]'}
|
||||
>
|
||||
Build your first template today.
|
||||
</motion.h2>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 16}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.9, delay: 0.15, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'flex max-w-md flex-col gap-6'}
|
||||
>
|
||||
<p className={'text-base text-neutral-300 sm:text-lg'}>
|
||||
Free plan available. $0.001 per email on paid. No credit card required.
|
||||
</p>
|
||||
<div className={'flex flex-wrap gap-3'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.015}}
|
||||
whileTap={{scale: 0.985}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
className={'inline-flex items-center gap-2 rounded-full bg-white px-7 py-3.5 text-sm font-semibold text-neutral-900 transition hover:bg-neutral-100'}
|
||||
>
|
||||
Get started for free
|
||||
<ArrowRight className="h-4 w-4" />
|
||||
</motion.a>
|
||||
<Link
|
||||
href={'/pricing'}
|
||||
className={'inline-flex items-center gap-2 rounded-full border border-neutral-700 px-7 py-3.5 text-sm font-semibold text-white transition hover:border-white'}
|
||||
>
|
||||
View pricing
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</main>
|
||||
|
||||
<Footer />
|
||||
|
||||
@@ -8,33 +8,33 @@ import Head from 'next/head';
|
||||
|
||||
const features = [
|
||||
{
|
||||
icon: <Database className="h-5 w-5" />,
|
||||
icon: <Database className="h-6 w-6" strokeWidth={1.5} />,
|
||||
title: 'Automatic Contact Capture',
|
||||
description: 'Every sender is automatically added to your contact database with no manual data entry required.',
|
||||
featured: true,
|
||||
},
|
||||
{
|
||||
icon: <Zap className="h-5 w-5" />,
|
||||
icon: <Zap className="h-6 w-6" strokeWidth={1.5} />,
|
||||
title: 'Workflow Automation',
|
||||
description: 'Trigger automated workflows when emails are received to create sophisticated two-way communication.',
|
||||
},
|
||||
{
|
||||
icon: <Shield className="h-5 w-5" />,
|
||||
icon: <Shield className="h-6 w-6" strokeWidth={1.5} />,
|
||||
title: 'Built-in Security',
|
||||
description:
|
||||
'Spam, virus, SPF, DKIM, and DMARC filtering keeps your inbox clean. The spam stays out, the good stuff gets in.',
|
||||
description: 'Spam, virus, SPF, DKIM, and DMARC filtering keeps your inbox clean. The spam stays out, the good stuff gets in.',
|
||||
},
|
||||
{
|
||||
icon: <Bell className="h-5 w-5" />,
|
||||
icon: <Bell className="h-6 w-6" strokeWidth={1.5} />,
|
||||
title: 'Webhook Notifications',
|
||||
description: 'Get instant notifications with rich metadata whenever an email arrives at your domain.',
|
||||
},
|
||||
{
|
||||
icon: <Mail className="h-5 w-5" />,
|
||||
icon: <Mail className="h-6 w-6" strokeWidth={1.5} />,
|
||||
title: 'Simple DNS Setup',
|
||||
description: 'Add one MX record to your domain and start receiving emails immediately. No PhD required.',
|
||||
},
|
||||
{
|
||||
icon: <Inbox className="h-5 w-5" />,
|
||||
icon: <Inbox className="h-6 w-6" strokeWidth={1.5} />,
|
||||
title: 'Real-Time Processing',
|
||||
description: 'Emails are processed instantly and can trigger workflows or webhooks in real-time.',
|
||||
},
|
||||
@@ -42,21 +42,21 @@ const features = [
|
||||
|
||||
const useCases = [
|
||||
{
|
||||
icon: <Mail className="h-6 w-6" />,
|
||||
icon: <Mail className="h-6 w-6" strokeWidth={1.5} />,
|
||||
title: 'Support Ticket Creation',
|
||||
description:
|
||||
'Automatically create support tickets when customers email support@yourdomain.com. Send auto-replies and route to your help desk system via webhooks. Your support team will thank you.',
|
||||
benefits: ['Instant acknowledgment', 'Automatic ticket creation', 'No emails missed'],
|
||||
},
|
||||
{
|
||||
icon: <Database className="h-6 w-6" />,
|
||||
icon: <Database className="h-6 w-6" strokeWidth={1.5} />,
|
||||
title: 'Lead Capture from Email',
|
||||
description:
|
||||
'Receive emails at info@yourdomain.com and automatically add senders to your CRM. Trigger nurture workflows based on when they reached out.',
|
||||
benefits: ['Zero-friction lead capture', 'Auto-segmentation', 'Instant follow-up'],
|
||||
},
|
||||
{
|
||||
icon: <Zap className="h-6 w-6" />,
|
||||
icon: <Zap className="h-6 w-6" strokeWidth={1.5} />,
|
||||
title: 'Two-Way Conversations',
|
||||
description:
|
||||
'Let customers reply to your campaign emails and automatically trigger engagement workflows. Tag contacts as "engaged" when they respond.',
|
||||
@@ -64,9 +64,6 @@ const useCases = [
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export default function InboundEmailFeature() {
|
||||
return (
|
||||
<>
|
||||
@@ -85,343 +82,292 @@ export default function InboundEmailFeature() {
|
||||
|
||||
<Navbar />
|
||||
|
||||
<main className={'mx-auto max-w-7xl px-8 sm:px-0'}>
|
||||
{/* Hero Section */}
|
||||
<section className={'relative py-20 sm:py-32'}>
|
||||
{/* Subtle background grid */}
|
||||
<main className={'text-neutral-800'}>
|
||||
|
||||
{/* Hero */}
|
||||
<section className={'relative overflow-hidden'}>
|
||||
<div
|
||||
aria-hidden
|
||||
className={
|
||||
'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#e5e7eb_1px,transparent_1px),linear-gradient(to_bottom,#e5e7eb_1px,transparent_1px)] bg-[size:4rem_4rem] [mask-image:radial-gradient(ellipse_80%_50%_at_50%_0%,#000_70%,transparent_110%)]'
|
||||
'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#eeeeee_1px,transparent_1px),linear-gradient(to_bottom,#eeeeee_1px,transparent_1px)] bg-[size:6rem_6rem] [mask-image:radial-gradient(ellipse_70%_60%_at_50%_30%,#000_40%,transparent_95%)]'
|
||||
}
|
||||
/>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
animate={{opacity: 1, y: 0}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mx-auto max-w-4xl text-center'}
|
||||
>
|
||||
<div className={'mb-6 inline-flex items-center gap-2 rounded-full bg-neutral-100 px-4 py-2 text-sm'}>
|
||||
<Inbox className="h-4 w-4 text-neutral-600" />
|
||||
<span className={'font-medium text-neutral-600'}>Inbound Email</span>
|
||||
</div>
|
||||
|
||||
<h1 className={'text-6xl font-bold tracking-tight text-neutral-900 sm:text-7xl lg:text-8xl text-balance'}>
|
||||
Turn Incoming Emails
|
||||
<br />
|
||||
into Actions
|
||||
</h1>
|
||||
<p className={'mx-auto mt-8 max-w-2xl text-xl text-neutral-600'}>
|
||||
Receive emails at your custom domain and automatically trigger workflows, capture leads, or create support
|
||||
tickets. Two-way email communication made simple.
|
||||
</p>
|
||||
|
||||
<div className={'mt-12 flex flex-wrap justify-center gap-4'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.02}}
|
||||
whileTap={{scale: 0.98}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
<div className={'mx-auto max-w-[88rem] px-6 pb-20 pt-20 sm:px-10 sm:pt-28 sm:pb-28'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 16}}
|
||||
animate={{opacity: 1, y: 0}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
>
|
||||
<div
|
||||
style={{fontFamily: 'var(--font-mono)'}}
|
||||
className={'mb-6 text-[11px] uppercase tracking-[0.18em] text-neutral-500'}
|
||||
>
|
||||
Inbound Email
|
||||
</div>
|
||||
<h1
|
||||
style={{fontFamily: 'var(--font-display)'}}
|
||||
className={
|
||||
'group rounded-lg bg-neutral-900 px-8 py-4 text-base font-semibold text-white shadow-lg shadow-neutral-900/10 transition hover:bg-neutral-800'
|
||||
'text-[clamp(2.75rem,7vw,6.5rem)] font-extrabold leading-[0.92] tracking-[-0.04em] text-neutral-900'
|
||||
}
|
||||
>
|
||||
<span className={'flex items-center gap-2'}>
|
||||
Start receiving emails
|
||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-1" />
|
||||
</span>
|
||||
</motion.a>
|
||||
<Link
|
||||
href={WIKI_URI}
|
||||
target={'_blank'}
|
||||
className={
|
||||
'rounded-lg border border-neutral-300 bg-white px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-400'
|
||||
}
|
||||
>
|
||||
View documentation
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
</section>
|
||||
Emails in,
|
||||
<br />
|
||||
actions out.
|
||||
</h1>
|
||||
<p className={'mt-6 max-w-2xl text-xl text-neutral-600'}>
|
||||
Receive emails at your custom domain and automatically trigger workflows, capture leads, or create support
|
||||
tickets. Two-way email communication made simple.
|
||||
</p>
|
||||
|
||||
{/* Features Grid */}
|
||||
<section className={'py-20'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-16 text-center'}
|
||||
>
|
||||
<h2 className={'text-4xl font-bold tracking-tight text-neutral-900 sm:text-5xl text-balance'}>
|
||||
Complete inbound email solution
|
||||
</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>
|
||||
Everything you need to receive and process incoming emails
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<div className={'grid gap-px bg-neutral-200 sm:grid-cols-2 lg:grid-cols-3'}>
|
||||
{features.map((feature, index) => (
|
||||
<motion.div
|
||||
key={feature.title}
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: index * 0.1, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-10 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
<div className={'mt-10 flex flex-wrap gap-3'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.015}}
|
||||
whileTap={{scale: 0.985}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
'group inline-flex items-center gap-2 rounded-full bg-neutral-900 px-8 py-4 text-base font-semibold text-white shadow-[0_10px_30px_-10px_rgba(23,23,23,0.35)] transition hover:bg-neutral-800'
|
||||
}
|
||||
>
|
||||
{feature.icon}
|
||||
</div>
|
||||
<h3 className={'mt-6 text-lg font-semibold text-neutral-900'}>{feature.title}</h3>
|
||||
<p className={'mt-2 text-sm leading-relaxed text-neutral-600'}>{feature.description}</p>
|
||||
</motion.div>
|
||||
))}
|
||||
Start receiving emails
|
||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-0.5" />
|
||||
</motion.a>
|
||||
<Link
|
||||
href={WIKI_URI}
|
||||
target={'_blank'}
|
||||
className={
|
||||
'inline-flex items-center gap-2 rounded-full border border-neutral-300 bg-white px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-900'
|
||||
}
|
||||
>
|
||||
View documentation
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* How It Works */}
|
||||
<section className={'py-20'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mx-auto max-w-4xl text-center'}
|
||||
>
|
||||
<h2 className={'text-4xl font-bold tracking-tight text-neutral-900 sm:text-5xl text-balance'}>Set up in minutes</h2>
|
||||
<p className={'mt-6 text-lg text-neutral-600'}>Get started with inbound email in three simple steps</p>
|
||||
</motion.div>
|
||||
|
||||
<div className={'mx-auto mt-16 max-w-5xl'}>
|
||||
<div className={'grid gap-12 lg:grid-cols-3'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.1, ease: [0.22, 1, 0.36, 1]}}
|
||||
{/* Features grid */}
|
||||
<section className={'border-t border-neutral-200'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-16'}
|
||||
>
|
||||
<h2
|
||||
style={{fontFamily: 'var(--font-display)'}}
|
||||
className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}
|
||||
>
|
||||
<div className={'mb-5 flex items-center gap-4'}>
|
||||
<div
|
||||
Complete inbound email solution
|
||||
</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Everything you need to receive and process incoming emails</p>
|
||||
</motion.div>
|
||||
|
||||
<div className={'grid gap-4 sm:grid-cols-2 lg:grid-cols-3'}>
|
||||
{features.map((feature, index) => {
|
||||
const highlighted = feature.featured;
|
||||
return (
|
||||
<motion.div
|
||||
key={feature.title}
|
||||
initial={{opacity: 0, y: 16}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: index * 0.06, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={
|
||||
'flex h-14 w-14 items-center justify-center rounded-full border-2 border-neutral-200 bg-white text-xl font-bold text-neutral-900'
|
||||
highlighted
|
||||
? 'flex min-h-[16rem] flex-col justify-between rounded-[28px] border border-neutral-900 bg-neutral-900 p-8 text-white'
|
||||
: 'flex min-h-[16rem] flex-col justify-between rounded-[28px] border border-neutral-200 bg-white p-8 transition hover:border-neutral-900'
|
||||
}
|
||||
>
|
||||
1
|
||||
</div>
|
||||
</div>
|
||||
<h3 className={'text-lg font-semibold text-neutral-900'}>Verify your domain</h3>
|
||||
<p className={'mt-2 text-sm leading-relaxed text-neutral-600'}>
|
||||
Add and verify your custom domain in Plunk by configuring DKIM and SPF records in your DNS settings.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.2, ease: [0.22, 1, 0.36, 1]}}
|
||||
>
|
||||
<div className={'mb-5 flex items-center gap-4'}>
|
||||
<div
|
||||
className={
|
||||
'flex h-14 w-14 items-center justify-center rounded-full border-2 border-neutral-200 bg-white text-xl font-bold text-neutral-900'
|
||||
}
|
||||
>
|
||||
2
|
||||
</div>
|
||||
</div>
|
||||
<h3 className={'text-lg font-semibold text-neutral-900'}>Add MX record</h3>
|
||||
<p className={'mt-2 text-sm leading-relaxed text-neutral-600'}>
|
||||
Add one MX record to your DNS to route incoming emails to Plunk. Copy the record from your dashboard.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.3, ease: [0.22, 1, 0.36, 1]}}
|
||||
>
|
||||
<div className={'mb-5 flex items-center gap-4'}>
|
||||
<div
|
||||
className={
|
||||
'flex h-14 w-14 items-center justify-center rounded-full border-2 border-neutral-200 bg-white text-xl font-bold text-neutral-900'
|
||||
}
|
||||
>
|
||||
3
|
||||
</div>
|
||||
</div>
|
||||
<h3 className={'text-lg font-semibold text-neutral-900'}>Start receiving</h3>
|
||||
<p className={'mt-2 text-sm leading-relaxed text-neutral-600'}>
|
||||
Emails sent to any address at your domain are automatically received and can trigger workflows or
|
||||
webhooks.
|
||||
</p>
|
||||
</motion.div>
|
||||
<div className={'flex items-start justify-between'}>
|
||||
<div className={highlighted ? 'text-white' : 'text-neutral-900'}>{feature.icon}</div>
|
||||
<span
|
||||
style={{fontFamily: 'var(--font-mono)'}}
|
||||
className={`text-[11px] uppercase tracking-[0.18em] ${highlighted ? 'text-neutral-500' : 'text-neutral-400'}`}
|
||||
>
|
||||
{String(index + 1).padStart(2, '0')}
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<h3
|
||||
style={{fontFamily: 'var(--font-display)'}}
|
||||
className={`mt-8 text-xl font-bold tracking-[-0.02em] ${highlighted ? 'text-white' : 'text-neutral-900'}`}
|
||||
>
|
||||
{feature.title}
|
||||
</h3>
|
||||
<p className={`mt-2 text-sm leading-relaxed ${highlighted ? 'text-neutral-300' : 'text-neutral-600'}`}>
|
||||
{feature.description}
|
||||
</p>
|
||||
</div>
|
||||
</motion.div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Use Cases */}
|
||||
<section className={'py-20'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-16 text-center'}
|
||||
>
|
||||
<h2 className={'text-4xl font-bold tracking-tight text-neutral-900 sm:text-5xl text-balance'}>Powerful use cases</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>
|
||||
From support to sales, inbound email unlocks new automation possibilities
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<div className={'mx-auto max-w-5xl space-y-8'}>
|
||||
{useCases.map((useCase, index) => (
|
||||
<motion.div
|
||||
key={useCase.title}
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: index * 0.1, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'rounded-xl border border-neutral-200 bg-white p-8'}
|
||||
{/* How it works */}
|
||||
<section className={'border-t border-neutral-200 bg-neutral-50/60'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-16 text-center'}
|
||||
>
|
||||
<h2
|
||||
style={{fontFamily: 'var(--font-display)'}}
|
||||
className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}
|
||||
>
|
||||
<div className={'flex items-start gap-6'}>
|
||||
<div
|
||||
className={
|
||||
'flex h-14 w-14 flex-shrink-0 items-center justify-center rounded-xl bg-neutral-900 text-white'
|
||||
}
|
||||
>
|
||||
{useCase.icon}
|
||||
</div>
|
||||
<div className={'flex-1'}>
|
||||
<h3 className={'text-xl font-semibold text-neutral-900'}>{useCase.title}</h3>
|
||||
<p className={'mt-2 text-neutral-600'}>{useCase.description}</p>
|
||||
<div className={'mt-4 flex flex-wrap gap-2'}>
|
||||
{useCase.benefits.map(benefit => (
|
||||
<span
|
||||
key={benefit}
|
||||
className={'rounded-full bg-neutral-100 px-3 py-1 text-sm text-neutral-700'}
|
||||
>
|
||||
{benefit}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Technical Details */}
|
||||
<section className={'py-20'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mx-auto max-w-4xl'}
|
||||
>
|
||||
<div className={'rounded-2xl border border-neutral-200 bg-white p-8 sm:p-12'}>
|
||||
<h2 className={'text-3xl font-bold tracking-tight text-neutral-900 text-balance'}>
|
||||
What happens when an email arrives?
|
||||
Set up in minutes
|
||||
</h2>
|
||||
<div className={'mt-10'}>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>One MX record is all it takes</p>
|
||||
</motion.div>
|
||||
|
||||
<div className={'mx-auto max-w-4xl'}>
|
||||
<div className={'grid gap-px bg-neutral-200 sm:grid-cols-3'}>
|
||||
{[
|
||||
{
|
||||
title: 'Email arrives at your domain',
|
||||
description: 'Your MX record routes the email to Plunk for processing',
|
||||
step: '01',
|
||||
title: 'Verify your domain',
|
||||
body: 'Add and verify your custom domain in Plunk by configuring DKIM and SPF records in your DNS settings.',
|
||||
},
|
||||
{
|
||||
title: 'Security checks pass',
|
||||
description: 'Automatic validation of spam, virus, SPF, DKIM, and DMARC',
|
||||
step: '02',
|
||||
title: 'Add MX record',
|
||||
body: 'Add one MX record to your DNS to route incoming emails to Plunk. Copy the record directly from your dashboard.',
|
||||
},
|
||||
{
|
||||
title: 'Contact is created or updated',
|
||||
description: 'The sender is automatically added to your contact database',
|
||||
step: '03',
|
||||
title: 'Start receiving',
|
||||
body: 'Emails sent to any address at your domain are automatically received and can trigger workflows or webhooks.',
|
||||
},
|
||||
{
|
||||
title: 'Workflows trigger automatically',
|
||||
description: 'Configured workflows start running based on the incoming email',
|
||||
},
|
||||
].map((step, i, arr) => (
|
||||
<div key={step.title} className={'relative flex gap-6'}>
|
||||
{/* Vertical connector */}
|
||||
{i < arr.length - 1 && (
|
||||
<div className={'absolute left-[1.125rem] top-10 bottom-0 w-px bg-neutral-200'} />
|
||||
)}
|
||||
<div className={'relative flex-shrink-0'}>
|
||||
<div
|
||||
className={
|
||||
'flex h-9 w-9 items-center justify-center rounded-full border-2 border-neutral-200 bg-white text-sm font-bold text-neutral-900'
|
||||
}
|
||||
>
|
||||
{i + 1}
|
||||
</div>
|
||||
].map((item, i) => (
|
||||
<motion.div
|
||||
key={item.step}
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: i * 0.1, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'bg-white p-10'}
|
||||
>
|
||||
<div
|
||||
style={{fontFamily: 'var(--font-mono)'}}
|
||||
className={'mb-6 text-[11px] uppercase tracking-[0.18em] text-neutral-400'}
|
||||
>
|
||||
Step {item.step}
|
||||
</div>
|
||||
<div className={i < arr.length - 1 ? 'pb-8' : ''}>
|
||||
<p className={'font-semibold text-neutral-900'}>{step.title}</p>
|
||||
<p className={'mt-1 text-sm text-neutral-600'}>{step.description}</p>
|
||||
</div>
|
||||
</div>
|
||||
<h3 className={'text-lg font-semibold text-neutral-900'}>{item.title}</h3>
|
||||
<p className={'mt-2 text-sm leading-relaxed text-neutral-600'}>{item.body}</p>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* CTA Section */}
|
||||
<section className={'relative overflow-hidden border-t border-neutral-200 py-20'}>
|
||||
<div
|
||||
className={
|
||||
'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#e5e7eb_1px,transparent_1px),linear-gradient(to_bottom,#e5e7eb_1px,transparent_1px)] bg-[size:4rem_4rem] [mask-image:radial-gradient(ellipse_80%_50%_at_50%_100%,#000_70%,transparent_110%)]'
|
||||
}
|
||||
/>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mx-auto max-w-3xl text-center'}
|
||||
>
|
||||
<h2 className={'text-4xl font-bold tracking-tight text-neutral-900 sm:text-5xl text-balance'}>
|
||||
Your domain can receive emails too
|
||||
</h2>
|
||||
<p className={'mt-6 text-lg text-neutral-600'}>
|
||||
Set up inbound email on any verified domain in minutes. Replies, support tickets, and webhooks, all from
|
||||
one platform.
|
||||
</p>
|
||||
<div className={'mt-12 flex flex-wrap justify-center gap-4'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.02}}
|
||||
whileTap={{scale: 0.98}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
className={
|
||||
'group rounded-lg bg-neutral-900 px-8 py-4 text-base font-semibold text-white transition hover:bg-neutral-800'
|
||||
}
|
||||
{/* Use cases */}
|
||||
<section className={'border-t border-neutral-200'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-16'}
|
||||
>
|
||||
<h2
|
||||
style={{fontFamily: 'var(--font-display)'}}
|
||||
className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}
|
||||
>
|
||||
<span className={'flex items-center gap-2'}>
|
||||
Get started for free
|
||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-1" />
|
||||
</span>
|
||||
</motion.a>
|
||||
<Link
|
||||
href={'/pricing'}
|
||||
className={
|
||||
'rounded-lg border border-neutral-300 px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-400'
|
||||
}
|
||||
>
|
||||
View pricing
|
||||
</Link>
|
||||
Powerful use cases
|
||||
</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>From support to sales, inbound email unlocks new automation possibilities</p>
|
||||
</motion.div>
|
||||
|
||||
<div className={'space-y-4'}>
|
||||
{useCases.map((useCase, index) => (
|
||||
<motion.div
|
||||
key={useCase.title}
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: index * 0.1, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'rounded-[24px] border border-neutral-200 bg-white p-8'}
|
||||
>
|
||||
<div className={'flex items-start gap-6'}>
|
||||
<div className={'flex h-14 w-14 flex-shrink-0 items-center justify-center rounded-full border border-neutral-200 text-neutral-900'}>
|
||||
{useCase.icon}
|
||||
</div>
|
||||
<div className={'flex-1'}>
|
||||
<h3
|
||||
style={{fontFamily: 'var(--font-display)'}}
|
||||
className={'text-xl font-bold tracking-[-0.02em] text-neutral-900'}
|
||||
>
|
||||
{useCase.title}
|
||||
</h3>
|
||||
<p className={'mt-2 text-neutral-600'}>{useCase.description}</p>
|
||||
<div className={'mt-4 rounded-xl border border-neutral-100 bg-neutral-50 p-4'}>
|
||||
<p style={{fontFamily: 'var(--font-mono)'}} className={'text-sm text-neutral-600'}>
|
||||
{useCase.benefits.join(' → ')}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* CTA */}
|
||||
<section className={'relative overflow-hidden border-t border-neutral-900 bg-neutral-900 text-white'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-32 sm:px-10 sm:py-40'}>
|
||||
<div className={'flex flex-col items-start gap-12 lg:flex-row lg:items-end lg:justify-between'}>
|
||||
<motion.h2
|
||||
initial={{opacity: 0, y: 16}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.9, ease: [0.22, 1, 0.36, 1]}}
|
||||
style={{fontFamily: 'var(--font-display)'}}
|
||||
className={'text-[clamp(2.5rem,7vw,6rem)] font-extrabold leading-[0.95] tracking-[-0.035em]'}
|
||||
>
|
||||
Your domain can receive emails too.
|
||||
</motion.h2>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 16}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.9, delay: 0.15, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'flex max-w-md flex-col gap-6'}
|
||||
>
|
||||
<p className={'text-base text-neutral-300 sm:text-lg'}>
|
||||
Free plan available. $0.001 per email on paid. No credit card required.
|
||||
</p>
|
||||
<div className={'flex flex-wrap gap-3'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.015}}
|
||||
whileTap={{scale: 0.985}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
className={'inline-flex items-center gap-2 rounded-full bg-white px-7 py-3.5 text-sm font-semibold text-neutral-900 transition hover:bg-neutral-100'}
|
||||
>
|
||||
Get started for free
|
||||
<ArrowRight className="h-4 w-4" />
|
||||
</motion.a>
|
||||
<Link
|
||||
href={'/pricing'}
|
||||
className={'inline-flex items-center gap-2 rounded-full border border-neutral-700 px-7 py-3.5 text-sm font-semibold text-white transition hover:border-white'}
|
||||
>
|
||||
View pricing
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</main>
|
||||
|
||||
<Footer />
|
||||
|
||||
@@ -8,37 +8,35 @@ import Head from 'next/head';
|
||||
|
||||
const features = [
|
||||
{
|
||||
icon: <Filter className="h-5 w-5" />,
|
||||
icon: <Filter className="h-6 w-6" strokeWidth={1.5} />,
|
||||
title: 'Dynamic Filtering',
|
||||
description:
|
||||
'Create segments based on contact data, custom fields, email activity, and events with powerful AND/OR logic.',
|
||||
description: 'Create segments based on contact data, custom fields, email activity, and events with powerful AND/OR logic.',
|
||||
featured: true,
|
||||
},
|
||||
{
|
||||
icon: <TrendingUp className="h-5 w-5" />,
|
||||
icon: <TrendingUp className="h-6 w-6" strokeWidth={1.5} />,
|
||||
title: 'Real-Time Updates',
|
||||
description: 'Dynamic segments automatically update as contact data changes, always keeping your audience current.',
|
||||
},
|
||||
{
|
||||
icon: <GitBranch className="h-5 w-5" />,
|
||||
icon: <GitBranch className="h-6 w-6" strokeWidth={1.5} />,
|
||||
title: 'Workflow Integration',
|
||||
description:
|
||||
'Trigger workflows when contacts enter or exit segments, or use segment conditions in workflow branching.',
|
||||
description: 'Trigger workflows when contacts enter or exit segments, or use segment conditions in workflow branching.',
|
||||
},
|
||||
{
|
||||
icon: <Target className="h-5 w-5" />,
|
||||
icon: <Target className="h-6 w-6" strokeWidth={1.5} />,
|
||||
title: 'Campaign Targeting',
|
||||
description:
|
||||
'Send targeted campaigns to specific segments instead of your entire contact list. Less noise, more signal.',
|
||||
description: 'Send targeted campaigns to specific segments instead of your entire contact list. Less noise, more signal.',
|
||||
},
|
||||
{
|
||||
icon: <Users className="h-5 w-5" />,
|
||||
icon: <Users className="h-6 w-6" strokeWidth={1.5} />,
|
||||
title: 'Static Segments',
|
||||
description: 'Manually curate contact lists for special groups like beta testers or VIP customers.',
|
||||
},
|
||||
{
|
||||
icon: <Mail className="h-5 w-5" />,
|
||||
icon: <Mail className="h-6 w-6" strokeWidth={1.5} />,
|
||||
title: 'Behavior-Based',
|
||||
description: 'Segment by email engagement - who opened, clicked, bounced, or never received your emails.',
|
||||
description: 'Segment by email engagement — who opened, clicked, bounced, or never received your emails.',
|
||||
},
|
||||
];
|
||||
|
||||
@@ -50,7 +48,7 @@ const filterExamples = [
|
||||
},
|
||||
{
|
||||
title: 'Re-engagement Needed',
|
||||
description: 'Find inactive users who need a nudge to come back. Sometimes they just need a reminder.',
|
||||
description: 'Find inactive users who need a nudge to come back',
|
||||
filters: ['Last activity older than 60 days', 'Email sent but not opened', 'Subscribed equals true'],
|
||||
},
|
||||
{
|
||||
@@ -62,28 +60,25 @@ const filterExamples = [
|
||||
|
||||
const useCases = [
|
||||
{
|
||||
icon: <Mail className="h-6 w-6" />,
|
||||
icon: <Mail className="h-6 w-6" strokeWidth={1.5} />,
|
||||
title: 'Targeted Campaigns',
|
||||
description:
|
||||
'Send newsletters and announcements to specific audience segments instead of blasting everyone. Increase open rates by sending relevant content to the right people. Your unsubscribe rate will thank you.',
|
||||
'Send newsletters and announcements to specific audience segments instead of blasting everyone. Increase open rates by sending relevant content to the right people.',
|
||||
},
|
||||
{
|
||||
icon: <GitBranch className="h-6 w-6" />,
|
||||
icon: <GitBranch className="h-6 w-6" strokeWidth={1.5} />,
|
||||
title: 'Behavior-Based Workflows',
|
||||
description:
|
||||
'Trigger workflows when contacts enter segments like "VIP Customers" or "Churning Users". Create personalized automations based on segment membership.',
|
||||
},
|
||||
{
|
||||
icon: <Target className="h-6 w-6" />,
|
||||
icon: <Target className="h-6 w-6" strokeWidth={1.5} />,
|
||||
title: 'A/B Testing',
|
||||
description:
|
||||
'Create segments for test groups and control groups. Send different campaigns to each segment and measure results.',
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export default function SegmentsFeature() {
|
||||
return (
|
||||
<>
|
||||
@@ -96,320 +91,349 @@ export default function SegmentsFeature() {
|
||||
<meta property="og:title" content="Audience Segmentation - Smart Contact Organization | Plunk" />
|
||||
<meta
|
||||
property="og:description"
|
||||
content="Create dynamic and static segments to organize your contacts. Filter by behavior, attributes, and engagement. Target campaigns and trigger workflows based on segment membership."
|
||||
content="Create dynamic and static segments to organize your contacts. Filter by behavior, attributes, and engagement."
|
||||
/>
|
||||
</Head>
|
||||
|
||||
<Navbar />
|
||||
|
||||
<main className={'mx-auto max-w-7xl px-8 sm:px-0'}>
|
||||
{/* Hero Section */}
|
||||
<section className={'relative py-20 sm:py-32'}>
|
||||
{/* Subtle background grid */}
|
||||
<main className={'text-neutral-800'}>
|
||||
|
||||
{/* Hero */}
|
||||
<section className={'relative overflow-hidden'}>
|
||||
<div
|
||||
aria-hidden
|
||||
className={
|
||||
'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#e5e7eb_1px,transparent_1px),linear-gradient(to_bottom,#e5e7eb_1px,transparent_1px)] bg-[size:4rem_4rem] [mask-image:radial-gradient(ellipse_80%_50%_at_50%_0%,#000_70%,transparent_110%)]'
|
||||
'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#eeeeee_1px,transparent_1px),linear-gradient(to_bottom,#eeeeee_1px,transparent_1px)] bg-[size:6rem_6rem] [mask-image:radial-gradient(ellipse_70%_60%_at_50%_30%,#000_40%,transparent_95%)]'
|
||||
}
|
||||
/>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
animate={{opacity: 1, y: 0}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mx-auto max-w-4xl text-center'}
|
||||
>
|
||||
<div className={'mb-6 inline-flex items-center gap-2 rounded-full bg-neutral-100 px-4 py-2 text-sm'}>
|
||||
<Users className="h-4 w-4 text-neutral-600" />
|
||||
<span className={'font-medium text-neutral-600'}>Audience Segmentation</span>
|
||||
</div>
|
||||
|
||||
<h1 className={'text-6xl font-bold tracking-tight text-neutral-900 sm:text-7xl lg:text-8xl text-balance'}>
|
||||
Target the Right Audience,
|
||||
<br />
|
||||
Every Time
|
||||
</h1>
|
||||
<p className={'mx-auto mt-8 max-w-2xl text-xl text-neutral-600'}>
|
||||
Organize contacts into dynamic segments based on behavior, attributes, and engagement. Send targeted
|
||||
campaigns and trigger personalized workflows.
|
||||
</p>
|
||||
|
||||
<div className={'mt-12 flex flex-wrap justify-center gap-4'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.02}}
|
||||
whileTap={{scale: 0.98}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
<div className={'mx-auto max-w-[88rem] px-6 pb-20 pt-20 sm:px-10 sm:pt-28 sm:pb-28'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 16}}
|
||||
animate={{opacity: 1, y: 0}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
>
|
||||
<div
|
||||
style={{fontFamily: 'var(--font-mono)'}}
|
||||
className={'mb-6 text-[11px] uppercase tracking-[0.18em] text-neutral-500'}
|
||||
>
|
||||
Audience Segmentation
|
||||
</div>
|
||||
<h1
|
||||
style={{fontFamily: 'var(--font-display)'}}
|
||||
className={
|
||||
'group rounded-lg bg-neutral-900 px-8 py-4 text-base font-semibold text-white shadow-lg shadow-neutral-900/10 transition hover:bg-neutral-800'
|
||||
'text-[clamp(2.75rem,7vw,6.5rem)] font-extrabold leading-[0.92] tracking-[-0.04em] text-neutral-900'
|
||||
}
|
||||
>
|
||||
<span className={'flex items-center gap-2'}>
|
||||
Start segmenting
|
||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-1" />
|
||||
</span>
|
||||
</motion.a>
|
||||
<Link
|
||||
href={WIKI_URI}
|
||||
target={'_blank'}
|
||||
className={
|
||||
'rounded-lg border border-neutral-300 bg-white px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-400'
|
||||
}
|
||||
>
|
||||
View documentation
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
</section>
|
||||
Target the right audience,
|
||||
<br />
|
||||
every time.
|
||||
</h1>
|
||||
<p className={'mt-6 max-w-2xl text-xl text-neutral-600'}>
|
||||
Organize contacts into dynamic segments based on behavior, attributes, and engagement. Send targeted
|
||||
campaigns and trigger personalized workflows.
|
||||
</p>
|
||||
|
||||
{/* Features Grid */}
|
||||
<section className={'py-20'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-16 text-center'}
|
||||
>
|
||||
<h2 className={'text-4xl font-bold tracking-tight text-neutral-900 sm:text-5xl text-balance'}>
|
||||
The right message to the right person
|
||||
</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Build precise audiences and send campaigns that land</p>
|
||||
</motion.div>
|
||||
|
||||
<div className={'grid gap-px bg-neutral-200 sm:grid-cols-2 lg:grid-cols-3'}>
|
||||
{features.map((feature, index) => (
|
||||
<motion.div
|
||||
key={feature.title}
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: index * 0.1, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-10 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
<div className={'mt-10 flex flex-wrap gap-3'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.015}}
|
||||
whileTap={{scale: 0.985}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
'group inline-flex items-center gap-2 rounded-full bg-neutral-900 px-8 py-4 text-base font-semibold text-white shadow-[0_10px_30px_-10px_rgba(23,23,23,0.35)] transition hover:bg-neutral-800'
|
||||
}
|
||||
>
|
||||
{feature.icon}
|
||||
</div>
|
||||
<h3 className={'mt-6 text-lg font-semibold text-neutral-900'}>{feature.title}</h3>
|
||||
<p className={'mt-2 text-sm leading-relaxed text-neutral-600'}>{feature.description}</p>
|
||||
</motion.div>
|
||||
))}
|
||||
Start segmenting
|
||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-0.5" />
|
||||
</motion.a>
|
||||
<Link
|
||||
href={WIKI_URI}
|
||||
target={'_blank'}
|
||||
className={
|
||||
'inline-flex items-center gap-2 rounded-full border border-neutral-300 bg-white px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-900'
|
||||
}
|
||||
>
|
||||
View documentation
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Filter Examples */}
|
||||
<section className={'py-20'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-16 text-center'}
|
||||
>
|
||||
<h2 className={'text-4xl font-bold tracking-tight text-neutral-900 sm:text-5xl text-balance'}>
|
||||
Flexible filtering options
|
||||
</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Build complex segments with nested AND/OR logic</p>
|
||||
</motion.div>
|
||||
|
||||
<div className={'mx-auto max-w-5xl space-y-6'}>
|
||||
{filterExamples.map((example, index) => (
|
||||
<motion.div
|
||||
key={example.title}
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: index * 0.1, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'rounded-xl border border-neutral-200 bg-white p-8'}
|
||||
{/* Features grid */}
|
||||
<section className={'border-t border-neutral-200'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-16'}
|
||||
>
|
||||
<h2
|
||||
style={{fontFamily: 'var(--font-display)'}}
|
||||
className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}
|
||||
>
|
||||
<div className={'flex items-start justify-between gap-6'}>
|
||||
<div className={'flex-1'}>
|
||||
<h3 className={'text-xl font-semibold text-neutral-900'}>{example.title}</h3>
|
||||
<p className={'mt-2 text-neutral-600'}>{example.description}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className={'mt-6 space-y-2'}>
|
||||
{example.filters.map((filter, filterIndex) => (
|
||||
<div key={filterIndex} className={'flex items-center gap-3 rounded-lg bg-neutral-50 px-4 py-3'}>
|
||||
<Filter className="h-4 w-4 flex-shrink-0 text-neutral-400" />
|
||||
<span className={'font-mono text-sm text-neutral-700'}>{filter}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
The right message to the right person
|
||||
</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Build precise audiences and send campaigns that land</p>
|
||||
</motion.div>
|
||||
|
||||
{/* Types of Segments */}
|
||||
<section className={'py-20'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mx-auto max-w-4xl text-center'}
|
||||
>
|
||||
<h2 className={'text-4xl font-bold tracking-tight text-neutral-900 sm:text-5xl text-balance'}>Two types of segments</h2>
|
||||
<p className={'mt-6 text-lg text-neutral-600'}>Choose between dynamic filtering or manual curation</p>
|
||||
</motion.div>
|
||||
|
||||
<div className={'mx-auto mt-16 max-w-5xl'}>
|
||||
<div className={'grid gap-8 lg:grid-cols-2'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.1, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'rounded-xl border border-neutral-200 bg-white p-8'}
|
||||
>
|
||||
<div className={'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white'}>
|
||||
<TrendingUp className="h-6 w-6" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Dynamic Segments</h3>
|
||||
<p className={'mt-2 text-neutral-600'}>
|
||||
Automatically update based on filter conditions. As contact data changes, segment membership updates
|
||||
in real-time.
|
||||
</p>
|
||||
<div className={'mt-6 space-y-2'}>
|
||||
<div className={'flex items-center gap-2 text-sm text-neutral-600'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-neutral-900'} />
|
||||
<span>Filter-based membership</span>
|
||||
</div>
|
||||
<div className={'flex items-center gap-2 text-sm text-neutral-600'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-neutral-900'} />
|
||||
<span>Automatic updates</span>
|
||||
</div>
|
||||
<div className={'flex items-center gap-2 text-sm text-neutral-600'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-neutral-900'} />
|
||||
<span>Optional entry/exit tracking</span>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.2, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'rounded-xl border border-neutral-200 bg-white p-8'}
|
||||
>
|
||||
<div className={'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white'}>
|
||||
<Users className="h-6 w-6" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Static Segments</h3>
|
||||
<p className={'mt-2 text-neutral-600'}>
|
||||
Manually curate your segment by adding specific contacts. Membership stays fixed until you change it.
|
||||
</p>
|
||||
<div className={'mt-6 space-y-2'}>
|
||||
<div className={'flex items-center gap-2 text-sm text-neutral-600'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-neutral-900'} />
|
||||
<span>Manual contact selection</span>
|
||||
</div>
|
||||
<div className={'flex items-center gap-2 text-sm text-neutral-600'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-neutral-900'} />
|
||||
<span>Fixed membership</span>
|
||||
</div>
|
||||
<div className={'flex items-center gap-2 text-sm text-neutral-600'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-neutral-900'} />
|
||||
<span>Perfect for VIP lists</span>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Use Cases */}
|
||||
<section className={'py-20'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-16 text-center'}
|
||||
>
|
||||
<h2 className={'text-4xl font-bold tracking-tight text-neutral-900 sm:text-5xl text-balance'}>
|
||||
Use segments everywhere
|
||||
</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>From targeted campaigns to automated workflows</p>
|
||||
</motion.div>
|
||||
|
||||
<div className={'mx-auto max-w-5xl space-y-8'}>
|
||||
{useCases.map((useCase, index) => (
|
||||
<motion.div
|
||||
key={useCase.title}
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: index * 0.1, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'rounded-xl border border-neutral-200 bg-white p-8'}
|
||||
>
|
||||
<div className={'flex items-start gap-6'}>
|
||||
<div
|
||||
<div className={'grid gap-4 sm:grid-cols-2 lg:grid-cols-3'}>
|
||||
{features.map((feature, index) => {
|
||||
const highlighted = feature.featured;
|
||||
return (
|
||||
<motion.div
|
||||
key={feature.title}
|
||||
initial={{opacity: 0, y: 16}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: index * 0.06, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={
|
||||
'flex h-14 w-14 flex-shrink-0 items-center justify-center rounded-xl bg-neutral-900 text-white'
|
||||
highlighted
|
||||
? 'flex min-h-[16rem] flex-col justify-between rounded-[28px] border border-neutral-900 bg-neutral-900 p-8 text-white'
|
||||
: 'flex min-h-[16rem] flex-col justify-between rounded-[28px] border border-neutral-200 bg-white p-8 transition hover:border-neutral-900'
|
||||
}
|
||||
>
|
||||
{useCase.icon}
|
||||
</div>
|
||||
<div className={'flex-1'}>
|
||||
<h3 className={'text-xl font-semibold text-neutral-900'}>{useCase.title}</h3>
|
||||
<p className={'mt-2 text-neutral-600'}>{useCase.description}</p>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
))}
|
||||
<div className={'flex items-start justify-between'}>
|
||||
<div className={highlighted ? 'text-white' : 'text-neutral-900'}>{feature.icon}</div>
|
||||
<span
|
||||
style={{fontFamily: 'var(--font-mono)'}}
|
||||
className={`text-[11px] uppercase tracking-[0.18em] ${highlighted ? 'text-neutral-500' : 'text-neutral-400'}`}
|
||||
>
|
||||
{String(index + 1).padStart(2, '0')}
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<h3
|
||||
style={{fontFamily: 'var(--font-display)'}}
|
||||
className={`mt-8 text-xl font-bold tracking-[-0.02em] ${highlighted ? 'text-white' : 'text-neutral-900'}`}
|
||||
>
|
||||
{feature.title}
|
||||
</h3>
|
||||
<p className={`mt-2 text-sm leading-relaxed ${highlighted ? 'text-neutral-300' : 'text-neutral-600'}`}>
|
||||
{feature.description}
|
||||
</p>
|
||||
</div>
|
||||
</motion.div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* CTA Section */}
|
||||
<section className={'relative overflow-hidden border-t border-neutral-200 py-20'}>
|
||||
<div
|
||||
className={
|
||||
'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#e5e7eb_1px,transparent_1px),linear-gradient(to_bottom,#e5e7eb_1px,transparent_1px)] bg-[size:4rem_4rem] [mask-image:radial-gradient(ellipse_80%_50%_at_50%_100%,#000_70%,transparent_110%)]'
|
||||
}
|
||||
/>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mx-auto max-w-3xl text-center'}
|
||||
>
|
||||
<h2 className={'text-4xl font-bold tracking-tight text-neutral-900 sm:text-5xl text-balance'}>
|
||||
Stop sending the same email to everyone
|
||||
</h2>
|
||||
<p className={'mt-6 text-lg text-neutral-600'}>
|
||||
Build precise audience segments and watch your open rates climb. 1,000 emails free, no credit card required.
|
||||
</p>
|
||||
<div className={'mt-12 flex flex-wrap justify-center gap-4'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.02}}
|
||||
whileTap={{scale: 0.98}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
className={
|
||||
'group rounded-lg bg-neutral-900 px-8 py-4 text-base font-semibold text-white transition hover:bg-neutral-800'
|
||||
}
|
||||
{/* Filter examples */}
|
||||
<section className={'border-t border-neutral-200 bg-neutral-50/60'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-16'}
|
||||
>
|
||||
<h2
|
||||
style={{fontFamily: 'var(--font-display)'}}
|
||||
className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}
|
||||
>
|
||||
<span className={'flex items-center gap-2'}>
|
||||
Get started for free
|
||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-1" />
|
||||
</span>
|
||||
</motion.a>
|
||||
<Link
|
||||
href={'/pricing'}
|
||||
className={
|
||||
'rounded-lg border border-neutral-300 px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-400'
|
||||
}
|
||||
>
|
||||
View pricing
|
||||
</Link>
|
||||
Flexible filtering options
|
||||
</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Build complex segments with nested AND/OR logic</p>
|
||||
</motion.div>
|
||||
|
||||
<div className={'space-y-4'}>
|
||||
{filterExamples.map((example, index) => (
|
||||
<motion.div
|
||||
key={example.title}
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: index * 0.1, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'rounded-[24px] border border-neutral-200 bg-white p-8'}
|
||||
>
|
||||
<h3
|
||||
style={{fontFamily: 'var(--font-display)'}}
|
||||
className={'text-xl font-bold tracking-[-0.02em] text-neutral-900'}
|
||||
>
|
||||
{example.title}
|
||||
</h3>
|
||||
<p className={'mt-1 text-neutral-600'}>{example.description}</p>
|
||||
<div className={'mt-6 space-y-2'}>
|
||||
{example.filters.map((filter, filterIndex) => (
|
||||
<div key={filterIndex} className={'flex items-center gap-3 rounded-xl border border-neutral-100 bg-neutral-50 px-4 py-3'}>
|
||||
<Filter className="h-4 w-4 flex-shrink-0 text-neutral-400" />
|
||||
<span style={{fontFamily: 'var(--font-mono)'}} className={'text-sm text-neutral-700'}>
|
||||
{filter}
|
||||
</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Segment types */}
|
||||
<section className={'border-t border-neutral-200'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-16'}
|
||||
>
|
||||
<h2
|
||||
style={{fontFamily: 'var(--font-display)'}}
|
||||
className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}
|
||||
>
|
||||
Two types of segments
|
||||
</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Choose between dynamic filtering or manual curation</p>
|
||||
</motion.div>
|
||||
|
||||
<div className={'grid gap-4 sm:grid-cols-2'}>
|
||||
{[
|
||||
{
|
||||
icon: <TrendingUp className="h-6 w-6" strokeWidth={1.5} />,
|
||||
title: 'Dynamic Segments',
|
||||
description: 'Automatically update based on filter conditions. As contact data changes, segment membership updates in real-time.',
|
||||
bullets: ['Filter-based membership', 'Automatic updates', 'Optional entry/exit tracking'],
|
||||
},
|
||||
{
|
||||
icon: <Users className="h-6 w-6" strokeWidth={1.5} />,
|
||||
title: 'Static Segments',
|
||||
description: 'Manually curate your segment by adding specific contacts. Membership stays fixed until you change it.',
|
||||
bullets: ['Manual contact selection', 'Fixed membership', 'Perfect for VIP lists'],
|
||||
},
|
||||
].map((type, i) => (
|
||||
<motion.div
|
||||
key={type.title}
|
||||
initial={{opacity: 0, y: 16}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: i * 0.1, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'rounded-[24px] border border-neutral-200 bg-white p-8'}
|
||||
>
|
||||
<div className={'text-neutral-900'}>{type.icon}</div>
|
||||
<h3
|
||||
style={{fontFamily: 'var(--font-display)'}}
|
||||
className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}
|
||||
>
|
||||
{type.title}
|
||||
</h3>
|
||||
<p className={'mt-2 text-neutral-600'}>{type.description}</p>
|
||||
<ul className={'mt-6 space-y-2'}>
|
||||
{type.bullets.map(b => (
|
||||
<li key={b} className={'flex items-center gap-2 text-sm text-neutral-600'}>
|
||||
<div className={'h-1.5 w-1.5 flex-shrink-0 rounded-full bg-neutral-900'} />
|
||||
{b}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Use cases */}
|
||||
<section className={'border-t border-neutral-200 bg-neutral-50/60'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-16'}
|
||||
>
|
||||
<h2
|
||||
style={{fontFamily: 'var(--font-display)'}}
|
||||
className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}
|
||||
>
|
||||
Use segments everywhere
|
||||
</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>From targeted campaigns to automated workflows</p>
|
||||
</motion.div>
|
||||
|
||||
<div className={'space-y-4'}>
|
||||
{useCases.map((useCase, index) => (
|
||||
<motion.div
|
||||
key={useCase.title}
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: index * 0.1, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'rounded-[24px] border border-neutral-200 bg-white p-8'}
|
||||
>
|
||||
<div className={'flex items-start gap-6'}>
|
||||
<div className={'flex h-14 w-14 flex-shrink-0 items-center justify-center rounded-full border border-neutral-200 text-neutral-900'}>
|
||||
{useCase.icon}
|
||||
</div>
|
||||
<div className={'flex-1'}>
|
||||
<h3
|
||||
style={{fontFamily: 'var(--font-display)'}}
|
||||
className={'text-xl font-bold tracking-[-0.02em] text-neutral-900'}
|
||||
>
|
||||
{useCase.title}
|
||||
</h3>
|
||||
<p className={'mt-2 text-neutral-600'}>{useCase.description}</p>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* CTA */}
|
||||
<section className={'relative overflow-hidden border-t border-neutral-900 bg-neutral-900 text-white'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-32 sm:px-10 sm:py-40'}>
|
||||
<div className={'flex flex-col items-start gap-12 lg:flex-row lg:items-end lg:justify-between'}>
|
||||
<motion.h2
|
||||
initial={{opacity: 0, y: 16}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.9, ease: [0.22, 1, 0.36, 1]}}
|
||||
style={{fontFamily: 'var(--font-display)'}}
|
||||
className={'text-[clamp(2.5rem,7vw,6rem)] font-extrabold leading-[0.95] tracking-[-0.035em]'}
|
||||
>
|
||||
Stop sending the same email to everyone.
|
||||
</motion.h2>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 16}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.9, delay: 0.15, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'flex max-w-md flex-col gap-6'}
|
||||
>
|
||||
<p className={'text-base text-neutral-300 sm:text-lg'}>
|
||||
Build precise audience segments and watch your open rates climb. 1,000 emails free, no credit card
|
||||
required.
|
||||
</p>
|
||||
<div className={'flex flex-wrap gap-3'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.015}}
|
||||
whileTap={{scale: 0.985}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
className={'inline-flex items-center gap-2 rounded-full bg-white px-7 py-3.5 text-sm font-semibold text-neutral-900 transition hover:bg-neutral-100'}
|
||||
>
|
||||
Get started for free
|
||||
<ArrowRight className="h-4 w-4" />
|
||||
</motion.a>
|
||||
<Link
|
||||
href={'/pricing'}
|
||||
className={'inline-flex items-center gap-2 rounded-full border border-neutral-700 px-7 py-3.5 text-sm font-semibold text-white transition hover:border-white'}
|
||||
>
|
||||
View pricing
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</main>
|
||||
|
||||
<Footer />
|
||||
|
||||
@@ -8,34 +8,33 @@ import Head from 'next/head';
|
||||
|
||||
const features = [
|
||||
{
|
||||
icon: <Settings className="h-5 w-5" />,
|
||||
icon: <Settings className="h-6 w-6" strokeWidth={1.5} />,
|
||||
title: 'Simple Configuration',
|
||||
description: 'Quick setup with your project credentials. Works with any email client or application.',
|
||||
featured: true,
|
||||
},
|
||||
{
|
||||
icon: <Lock className="h-5 w-5" />,
|
||||
icon: <Lock className="h-6 w-6" strokeWidth={1.5} />,
|
||||
title: 'Secure Connections',
|
||||
description: 'TLS/SSL encryption on ports 465 and 587. Your emails are always transmitted securely.',
|
||||
},
|
||||
{
|
||||
icon: <Mail className="h-5 w-5" />,
|
||||
icon: <Mail className="h-6 w-6" strokeWidth={1.5} />,
|
||||
title: 'Universal Compatibility',
|
||||
description:
|
||||
'Works with Outlook, Thunderbird, Apple Mail, or any SMTP-compatible application. Even that ancient email client from 2005.',
|
||||
description: 'Works with Outlook, Thunderbird, Apple Mail, or any SMTP-compatible application.',
|
||||
},
|
||||
{
|
||||
icon: <Server className="h-5 w-5" />,
|
||||
icon: <Server className="h-6 w-6" strokeWidth={1.5} />,
|
||||
title: 'Domain Validation',
|
||||
description: 'Automatic verification that your sender domain is verified before accepting emails.',
|
||||
},
|
||||
{
|
||||
icon: <Shield className="h-5 w-5" />,
|
||||
icon: <Shield className="h-6 w-6" strokeWidth={1.5} />,
|
||||
title: 'Full Feature Support',
|
||||
description:
|
||||
'Attachments, custom headers, HTML emails, and multiple recipients. Send those cat memes with confidence.',
|
||||
description: 'Attachments, custom headers, HTML emails, and multiple recipients.',
|
||||
},
|
||||
{
|
||||
icon: <Code2 className="h-5 w-5" />,
|
||||
icon: <Code2 className="h-6 w-6" strokeWidth={1.5} />,
|
||||
title: 'Same Infrastructure',
|
||||
description: 'SMTP emails use the same reliable delivery infrastructure as API emails with full tracking.',
|
||||
},
|
||||
@@ -54,21 +53,21 @@ const comparisonData = [
|
||||
|
||||
const useCases = [
|
||||
{
|
||||
icon: <Settings className="h-6 w-6" />,
|
||||
icon: <Settings className="h-6 w-6" strokeWidth={1.5} />,
|
||||
title: 'Legacy System Integration',
|
||||
description:
|
||||
'Already have applications using SMTP? No need to rewrite code. Just swap your SMTP credentials and keep everything else the same. Your PM will love you.',
|
||||
'Already have applications using SMTP? No need to rewrite code. Just swap your SMTP credentials and keep everything else the same.',
|
||||
benefit: 'Zero code changes required',
|
||||
},
|
||||
{
|
||||
icon: <Mail className="h-6 w-6" />,
|
||||
icon: <Mail className="h-6 w-6" strokeWidth={1.5} />,
|
||||
title: 'Email Client Sending',
|
||||
description:
|
||||
'Marketing teams can send emails directly from Outlook, Thunderbird, or Apple Mail using familiar tools without learning new APIs.',
|
||||
benefit: 'No technical knowledge needed',
|
||||
},
|
||||
{
|
||||
icon: <Code2 className="h-6 w-6" />,
|
||||
icon: <Code2 className="h-6 w-6" strokeWidth={1.5} />,
|
||||
title: 'Framework Compatibility',
|
||||
description:
|
||||
'Works with any framework or language that supports SMTP. Perfect for older systems or platforms without HTTP API support.',
|
||||
@@ -76,9 +75,6 @@ const useCases = [
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export default function SMTPFeature() {
|
||||
return (
|
||||
<>
|
||||
@@ -97,236 +93,283 @@ export default function SMTPFeature() {
|
||||
|
||||
<Navbar />
|
||||
|
||||
<main className={'mx-auto max-w-7xl px-8 sm:px-0'}>
|
||||
{/* Hero Section */}
|
||||
<section className={'relative py-20 sm:py-32'}>
|
||||
{/* Subtle background grid */}
|
||||
<main className={'text-neutral-800'}>
|
||||
|
||||
{/* Hero */}
|
||||
<section className={'relative overflow-hidden'}>
|
||||
<div
|
||||
aria-hidden
|
||||
className={
|
||||
'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#e5e7eb_1px,transparent_1px),linear-gradient(to_bottom,#e5e7eb_1px,transparent_1px)] bg-[size:4rem_4rem] [mask-image:radial-gradient(ellipse_80%_50%_at_50%_0%,#000_70%,transparent_110%)]'
|
||||
'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#eeeeee_1px,transparent_1px),linear-gradient(to_bottom,#eeeeee_1px,transparent_1px)] bg-[size:6rem_6rem] [mask-image:radial-gradient(ellipse_70%_60%_at_50%_30%,#000_40%,transparent_95%)]'
|
||||
}
|
||||
/>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
animate={{opacity: 1, y: 0}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mx-auto max-w-4xl text-center'}
|
||||
>
|
||||
<div className={'mb-6 inline-flex items-center gap-2 rounded-full bg-neutral-100 px-4 py-2 text-sm'}>
|
||||
<Server className="h-4 w-4 text-neutral-600" />
|
||||
<span className={'font-medium text-neutral-600'}>SMTP Email Sending</span>
|
||||
</div>
|
||||
|
||||
<h1 className={'text-6xl font-bold tracking-tight text-neutral-900 sm:text-7xl lg:text-8xl text-balance'}>
|
||||
Send Emails via SMTP or API
|
||||
</h1>
|
||||
<p className={'mx-auto mt-8 max-w-2xl text-xl text-neutral-600'}>
|
||||
Use our HTTP API for modern apps or drop in SMTP credentials for any legacy system. Same deliverability, same pricing, zero lock-in.
|
||||
</p>
|
||||
|
||||
<div className={'mt-12 flex flex-wrap justify-center gap-4'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.02}}
|
||||
whileTap={{scale: 0.98}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
<div className={'mx-auto max-w-[88rem] px-6 pb-20 pt-20 sm:px-10 sm:pt-28 sm:pb-28'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 16}}
|
||||
animate={{opacity: 1, y: 0}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
>
|
||||
<div
|
||||
style={{fontFamily: 'var(--font-mono)'}}
|
||||
className={'mb-6 text-[11px] uppercase tracking-[0.18em] text-neutral-500'}
|
||||
>
|
||||
SMTP
|
||||
</div>
|
||||
<h1
|
||||
style={{fontFamily: 'var(--font-display)'}}
|
||||
className={
|
||||
'group rounded-lg bg-neutral-900 px-8 py-4 text-base font-semibold text-white shadow-lg shadow-neutral-900/10 transition hover:bg-neutral-800'
|
||||
'text-[clamp(2.75rem,7vw,6.5rem)] font-extrabold leading-[0.92] tracking-[-0.04em] text-neutral-900'
|
||||
}
|
||||
>
|
||||
<span className={'flex items-center gap-2'}>
|
||||
Get SMTP credentials
|
||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-1" />
|
||||
</span>
|
||||
</motion.a>
|
||||
<Link
|
||||
href={WIKI_URI}
|
||||
target={'_blank'}
|
||||
className={
|
||||
'rounded-lg border border-neutral-300 bg-white px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-400'
|
||||
}
|
||||
>
|
||||
View documentation
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
</section>
|
||||
Send via SMTP
|
||||
<br />
|
||||
or API. Your call.
|
||||
</h1>
|
||||
<p className={'mt-6 max-w-2xl text-xl text-neutral-600'}>
|
||||
Use our HTTP API for modern apps or drop in SMTP credentials for any legacy system. Same deliverability,
|
||||
same pricing, zero lock-in.
|
||||
</p>
|
||||
|
||||
{/* Features Grid */}
|
||||
<section className={'py-20'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-16 text-center'}
|
||||
>
|
||||
<h2 className={'text-4xl font-bold tracking-tight text-neutral-900 sm:text-5xl text-balance'}>SMTP that works with everything</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Full authentication, tracking, and deliverability out of the box</p>
|
||||
</motion.div>
|
||||
|
||||
<div className={'grid gap-px bg-neutral-200 sm:grid-cols-2 lg:grid-cols-3'}>
|
||||
{features.map((feature, index) => (
|
||||
<motion.div
|
||||
key={feature.title}
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: index * 0.1, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-10 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
<div className={'mt-10 flex flex-wrap gap-3'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.015}}
|
||||
whileTap={{scale: 0.985}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
'group inline-flex items-center gap-2 rounded-full bg-neutral-900 px-8 py-4 text-base font-semibold text-white shadow-[0_10px_30px_-10px_rgba(23,23,23,0.35)] transition hover:bg-neutral-800'
|
||||
}
|
||||
>
|
||||
{feature.icon}
|
||||
</div>
|
||||
<h3 className={'mt-6 text-lg font-semibold text-neutral-900'}>{feature.title}</h3>
|
||||
<p className={'mt-2 text-sm leading-relaxed text-neutral-600'}>{feature.description}</p>
|
||||
</motion.div>
|
||||
))}
|
||||
Get SMTP credentials
|
||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-0.5" />
|
||||
</motion.a>
|
||||
<Link
|
||||
href={WIKI_URI}
|
||||
target={'_blank'}
|
||||
className={
|
||||
'inline-flex items-center gap-2 rounded-full border border-neutral-300 bg-white px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-900'
|
||||
}
|
||||
>
|
||||
View documentation
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Comparison Table */}
|
||||
<section className={'py-20'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-12 text-center'}
|
||||
>
|
||||
<h2 className={'text-4xl font-bold tracking-tight text-neutral-900 sm:text-5xl text-balance'}>SMTP vs API</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Choose the right option for your use case</p>
|
||||
</motion.div>
|
||||
{/* Features grid */}
|
||||
<section className={'border-t border-neutral-200'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-16'}
|
||||
>
|
||||
<h2
|
||||
style={{fontFamily: 'var(--font-display)'}}
|
||||
className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}
|
||||
>
|
||||
SMTP that works with everything
|
||||
</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>
|
||||
Full authentication, tracking, and deliverability out of the box
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<div className={'mx-auto max-w-4xl'}>
|
||||
<div className={'overflow-hidden rounded-xl border border-neutral-200 bg-white'}>
|
||||
<div className={'grid gap-4 sm:grid-cols-2 lg:grid-cols-3'}>
|
||||
{features.map((feature, index) => {
|
||||
const highlighted = feature.featured;
|
||||
return (
|
||||
<motion.div
|
||||
key={feature.title}
|
||||
initial={{opacity: 0, y: 16}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: index * 0.06, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={
|
||||
highlighted
|
||||
? 'flex min-h-[16rem] flex-col justify-between rounded-[28px] border border-neutral-900 bg-neutral-900 p-8 text-white'
|
||||
: 'flex min-h-[16rem] flex-col justify-between rounded-[28px] border border-neutral-200 bg-white p-8 transition hover:border-neutral-900'
|
||||
}
|
||||
>
|
||||
<div className={'flex items-start justify-between'}>
|
||||
<div className={highlighted ? 'text-white' : 'text-neutral-900'}>{feature.icon}</div>
|
||||
<span
|
||||
style={{fontFamily: 'var(--font-mono)'}}
|
||||
className={`text-[11px] uppercase tracking-[0.18em] ${highlighted ? 'text-neutral-500' : 'text-neutral-400'}`}
|
||||
>
|
||||
{String(index + 1).padStart(2, '0')}
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<h3
|
||||
style={{fontFamily: 'var(--font-display)'}}
|
||||
className={`mt-8 text-xl font-bold tracking-[-0.02em] ${highlighted ? 'text-white' : 'text-neutral-900'}`}
|
||||
>
|
||||
{feature.title}
|
||||
</h3>
|
||||
<p className={`mt-2 text-sm leading-relaxed ${highlighted ? 'text-neutral-300' : 'text-neutral-600'}`}>
|
||||
{feature.description}
|
||||
</p>
|
||||
</div>
|
||||
</motion.div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Comparison table */}
|
||||
<section className={'border-t border-neutral-200 bg-neutral-50/60'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-12'}
|
||||
>
|
||||
<h2
|
||||
style={{fontFamily: 'var(--font-display)'}}
|
||||
className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}
|
||||
>
|
||||
SMTP vs API
|
||||
</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Choose the right option for your use case</p>
|
||||
</motion.div>
|
||||
|
||||
<div className={'overflow-hidden rounded-[24px] border border-neutral-200 bg-white'}>
|
||||
<table className={'w-full'}>
|
||||
<thead className={'bg-neutral-50'}>
|
||||
<thead className={'border-b border-neutral-200 bg-neutral-50'}>
|
||||
<tr>
|
||||
<th className={'px-6 py-4 text-left text-sm font-semibold text-neutral-900'}>Feature</th>
|
||||
<th className={'px-6 py-4 text-center text-sm font-semibold text-neutral-900'}>Traditional SMTP</th>
|
||||
<th className={'bg-neutral-100 px-6 py-4 text-center text-sm font-semibold text-neutral-900'}>
|
||||
Plunk SMTP
|
||||
</th>
|
||||
<th className={'px-6 py-4 text-center text-sm font-semibold text-neutral-900'}>Plunk API</th>
|
||||
<th className={'px-6 py-4 text-center text-sm font-semibold text-neutral-500'}>Traditional SMTP</th>
|
||||
<th className={'bg-neutral-900 px-6 py-4 text-center text-sm font-semibold text-white'}>Plunk SMTP</th>
|
||||
<th className={'px-6 py-4 text-center text-sm font-semibold text-neutral-500'}>Plunk API</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className={'divide-y divide-neutral-200'}>
|
||||
<tbody className={'divide-y divide-neutral-100'}>
|
||||
{comparisonData.map((row, index) => (
|
||||
<tr key={index} className={'transition hover:bg-neutral-50'}>
|
||||
<td className={'px-6 py-4 text-sm text-neutral-900'}>{row.feature}</td>
|
||||
<td className={'px-6 py-4 text-center text-sm text-neutral-600'}>{row.traditional}</td>
|
||||
<td className={'bg-neutral-50 px-6 py-4 text-center text-sm font-medium text-neutral-900'}>
|
||||
{row.plunkSMTP}
|
||||
</td>
|
||||
<td className={'px-6 py-4 text-center text-sm text-neutral-600'}>{row.plunkAPI}</td>
|
||||
<td className={'px-6 py-4 text-sm font-medium text-neutral-900'}>{row.feature}</td>
|
||||
<td className={'px-6 py-4 text-center text-sm text-neutral-500'}>{row.traditional}</td>
|
||||
<td className={'bg-neutral-50 px-6 py-4 text-center text-sm font-semibold text-neutral-900'}>{row.plunkSMTP}</td>
|
||||
<td className={'px-6 py-4 text-center text-sm text-neutral-500'}>{row.plunkAPI}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div className={'mt-6 rounded-lg bg-neutral-50 p-4 text-center'}>
|
||||
<p className={'text-sm text-neutral-600'}>
|
||||
<strong>Recommendation:</strong> Use API for modern applications with workflow automation. Use SMTP for
|
||||
email clients and legacy systems.
|
||||
</p>
|
||||
</div>
|
||||
<p className={'mt-4 text-sm text-neutral-500'}>
|
||||
Recommendation: Use the API for modern applications with workflow automation. Use SMTP for email clients
|
||||
and legacy systems.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Use Cases */}
|
||||
<section className={'py-20'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-16 text-center'}
|
||||
>
|
||||
<h2 className={'text-4xl font-bold tracking-tight text-neutral-900 sm:text-5xl text-balance'}>When to use SMTP</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Perfect for these scenarios</p>
|
||||
</motion.div>
|
||||
|
||||
<div className={'mx-auto max-w-5xl space-y-8'}>
|
||||
{useCases.map((useCase, index) => (
|
||||
<motion.div
|
||||
key={useCase.title}
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: index * 0.1, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'rounded-xl border border-neutral-200 bg-white p-8'}
|
||||
{/* Use cases */}
|
||||
<section className={'border-t border-neutral-200'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-16'}
|
||||
>
|
||||
<h2
|
||||
style={{fontFamily: 'var(--font-display)'}}
|
||||
className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}
|
||||
>
|
||||
<div className={'flex items-start gap-6'}>
|
||||
<div
|
||||
className={
|
||||
'flex h-14 w-14 flex-shrink-0 items-center justify-center rounded-xl bg-neutral-900 text-white'
|
||||
}
|
||||
>
|
||||
{useCase.icon}
|
||||
</div>
|
||||
<div className={'flex-1'}>
|
||||
<h3 className={'text-xl font-semibold text-neutral-900'}>{useCase.title}</h3>
|
||||
<p className={'mt-2 text-neutral-600'}>{useCase.description}</p>
|
||||
<div className={'mt-4 inline-flex items-center gap-2 rounded-full bg-neutral-100 px-4 py-2'}>
|
||||
<div className={'h-2 w-2 rounded-full bg-green-500'} />
|
||||
<span className={'text-sm font-medium text-neutral-700'}>{useCase.benefit}</span>
|
||||
When to use SMTP
|
||||
</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Perfect for these scenarios</p>
|
||||
</motion.div>
|
||||
|
||||
<div className={'space-y-4'}>
|
||||
{useCases.map((useCase, index) => (
|
||||
<motion.div
|
||||
key={useCase.title}
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: index * 0.1, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'rounded-[24px] border border-neutral-200 bg-white p-8'}
|
||||
>
|
||||
<div className={'flex items-start gap-6'}>
|
||||
<div className={'flex h-14 w-14 flex-shrink-0 items-center justify-center rounded-full border border-neutral-200 text-neutral-900'}>
|
||||
{useCase.icon}
|
||||
</div>
|
||||
<div className={'flex-1'}>
|
||||
<h3
|
||||
style={{fontFamily: 'var(--font-display)'}}
|
||||
className={'text-xl font-bold tracking-[-0.02em] text-neutral-900'}
|
||||
>
|
||||
{useCase.title}
|
||||
</h3>
|
||||
<p className={'mt-2 text-neutral-600'}>{useCase.description}</p>
|
||||
<div
|
||||
style={{fontFamily: 'var(--font-mono)'}}
|
||||
className={'mt-4 inline-flex items-center gap-2 text-[11px] uppercase tracking-[0.18em] text-neutral-500'}
|
||||
>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-neutral-900'} />
|
||||
{useCase.benefit}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
))}
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* CTA Section */}
|
||||
<section className={'relative overflow-hidden border-t border-neutral-200 py-20'}>
|
||||
<div
|
||||
className={
|
||||
'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#e5e7eb_1px,transparent_1px),linear-gradient(to_bottom,#e5e7eb_1px,transparent_1px)] bg-[size:4rem_4rem] [mask-image:radial-gradient(ellipse_80%_50%_at_50%_100%,#000_70%,transparent_110%)]'
|
||||
}
|
||||
/>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mx-auto max-w-3xl text-center'}
|
||||
>
|
||||
<h2 className={'text-4xl font-bold tracking-tight text-neutral-900 sm:text-5xl text-balance'}>Start sending via SMTP</h2>
|
||||
<p className={'mt-6 text-lg text-neutral-600'}>
|
||||
Get your SMTP credentials and start sending emails from any client or application. No credit card
|
||||
required.
|
||||
</p>
|
||||
<div className={'mt-12 flex flex-wrap justify-center gap-4'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.02}}
|
||||
whileTap={{scale: 0.98}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
className={
|
||||
'group rounded-lg bg-neutral-900 px-8 py-4 text-base font-semibold text-white transition hover:bg-neutral-800'
|
||||
}
|
||||
{/* CTA */}
|
||||
<section className={'relative overflow-hidden border-t border-neutral-900 bg-neutral-900 text-white'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-32 sm:px-10 sm:py-40'}>
|
||||
<div className={'flex flex-col items-start gap-12 lg:flex-row lg:items-end lg:justify-between'}>
|
||||
<motion.h2
|
||||
initial={{opacity: 0, y: 16}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.9, ease: [0.22, 1, 0.36, 1]}}
|
||||
style={{fontFamily: 'var(--font-display)'}}
|
||||
className={'text-[clamp(2.5rem,7vw,6rem)] font-extrabold leading-[0.95] tracking-[-0.035em]'}
|
||||
>
|
||||
<span className={'flex items-center gap-2'}>
|
||||
Get started for free
|
||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-1" />
|
||||
</span>
|
||||
</motion.a>
|
||||
<Link
|
||||
href={'/pricing'}
|
||||
className={
|
||||
'rounded-lg border border-neutral-300 px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-400'
|
||||
}
|
||||
Start sending via SMTP today.
|
||||
</motion.h2>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 16}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.9, delay: 0.15, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'flex max-w-md flex-col gap-6'}
|
||||
>
|
||||
View pricing
|
||||
</Link>
|
||||
<p className={'text-base text-neutral-300 sm:text-lg'}>
|
||||
Get your SMTP credentials and start sending from any client or application. No credit card required.
|
||||
</p>
|
||||
<div className={'flex flex-wrap gap-3'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.015}}
|
||||
whileTap={{scale: 0.985}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
className={'inline-flex items-center gap-2 rounded-full bg-white px-7 py-3.5 text-sm font-semibold text-neutral-900 transition hover:bg-neutral-100'}
|
||||
>
|
||||
Get started for free
|
||||
<ArrowRight className="h-4 w-4" />
|
||||
</motion.a>
|
||||
<Link
|
||||
href={'/pricing'}
|
||||
className={'inline-flex items-center gap-2 rounded-full border border-neutral-700 px-7 py-3.5 text-sm font-semibold text-white transition hover:border-white'}
|
||||
>
|
||||
View pricing
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</main>
|
||||
|
||||
<Footer />
|
||||
|
||||
@@ -8,32 +8,33 @@ import Head from 'next/head';
|
||||
|
||||
const features = [
|
||||
{
|
||||
icon: <Zap className="h-5 w-5" />,
|
||||
icon: <Zap className="h-6 w-6" strokeWidth={1.5} />,
|
||||
title: 'Event-Driven Triggers',
|
||||
description: 'Start workflows automatically when users sign up, make a purchase, or perform any custom action.',
|
||||
featured: true,
|
||||
},
|
||||
{
|
||||
icon: <Mail className="h-5 w-5" />,
|
||||
icon: <Mail className="h-6 w-6" strokeWidth={1.5} />,
|
||||
title: 'Smart Email Sequences',
|
||||
description: 'Send personalized emails at the right time with dynamic content based on user data.',
|
||||
},
|
||||
{
|
||||
icon: <Clock className="h-5 w-5" />,
|
||||
icon: <Clock className="h-6 w-6" strokeWidth={1.5} />,
|
||||
title: 'Time-Based Delays',
|
||||
description: 'Add strategic delays between steps to create perfectly timed email journeys. Patience is a virtue.',
|
||||
},
|
||||
{
|
||||
icon: <GitBranch className="h-5 w-5" />,
|
||||
icon: <GitBranch className="h-6 w-6" strokeWidth={1.5} />,
|
||||
title: 'Conditional Logic',
|
||||
description: 'Branch workflows based on user behavior, attributes, or engagement to personalize every journey.',
|
||||
},
|
||||
{
|
||||
icon: <Webhook className="h-5 w-5" />,
|
||||
icon: <Webhook className="h-6 w-6" strokeWidth={1.5} />,
|
||||
title: 'External Integrations',
|
||||
description: 'Connect to external systems with webhooks to sync data or trigger actions outside of Plunk.',
|
||||
},
|
||||
{
|
||||
icon: <RefreshCw className="h-5 w-5" />,
|
||||
icon: <RefreshCw className="h-6 w-6" strokeWidth={1.5} />,
|
||||
title: 'Re-entry Control',
|
||||
description: 'Decide whether contacts can enter workflows multiple times or just once. No spam, just strategy.',
|
||||
},
|
||||
@@ -41,21 +42,21 @@ const features = [
|
||||
|
||||
const useCases = [
|
||||
{
|
||||
icon: <UserPlus className="h-6 w-6" />,
|
||||
icon: <UserPlus className="h-6 w-6" strokeWidth={1.5} />,
|
||||
title: 'User Onboarding',
|
||||
description:
|
||||
'Welcome new users with a personalized email series that guides them through your product features and helps them get started.',
|
||||
example: 'Trigger on signup → Send welcome email → Wait 2 days → Send getting started tips',
|
||||
},
|
||||
{
|
||||
icon: <Mail className="h-6 w-6" />,
|
||||
icon: <Mail className="h-6 w-6" strokeWidth={1.5} />,
|
||||
title: 'Abandoned Cart Recovery',
|
||||
description:
|
||||
'Automatically remind customers about items left in their cart with timely follow-ups and special incentives. Those forgotten items need a gentle nudge.',
|
||||
'Automatically remind customers about items left in their cart with timely follow-ups and special incentives.',
|
||||
example: 'Trigger on cart abandoned → Wait 1 hour → Send reminder → Wait 1 day → Send discount offer',
|
||||
},
|
||||
{
|
||||
icon: <RefreshCw className="h-6 w-6" />,
|
||||
icon: <RefreshCw className="h-6 w-6" strokeWidth={1.5} />,
|
||||
title: 'Re-engagement Campaigns',
|
||||
description:
|
||||
'Win back inactive users with targeted campaigns based on their last activity and engagement patterns.',
|
||||
@@ -63,9 +64,6 @@ const useCases = [
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export default function WorkflowsFeature() {
|
||||
return (
|
||||
<>
|
||||
@@ -84,269 +82,299 @@ export default function WorkflowsFeature() {
|
||||
|
||||
<Navbar />
|
||||
|
||||
<main className={'mx-auto max-w-7xl px-8 sm:px-0'}>
|
||||
{/* Hero Section */}
|
||||
<section className={'relative py-20 sm:py-32'}>
|
||||
{/* Subtle background grid */}
|
||||
<main className={'text-neutral-800'}>
|
||||
|
||||
{/* Hero */}
|
||||
<section className={'relative overflow-hidden'}>
|
||||
<div
|
||||
aria-hidden
|
||||
className={
|
||||
'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#e5e7eb_1px,transparent_1px),linear-gradient(to_bottom,#e5e7eb_1px,transparent_1px)] bg-[size:4rem_4rem] [mask-image:radial-gradient(ellipse_80%_50%_at_50%_0%,#000_70%,transparent_110%)]'
|
||||
'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#eeeeee_1px,transparent_1px),linear-gradient(to_bottom,#eeeeee_1px,transparent_1px)] bg-[size:6rem_6rem] [mask-image:radial-gradient(ellipse_70%_60%_at_50%_30%,#000_40%,transparent_95%)]'
|
||||
}
|
||||
/>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
animate={{opacity: 1, y: 0}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mx-auto max-w-4xl text-center'}
|
||||
>
|
||||
<div className={'mb-6 inline-flex items-center gap-2 rounded-full bg-neutral-100 px-4 py-2 text-sm'}>
|
||||
<Zap className="h-4 w-4 text-neutral-600" />
|
||||
<span className={'font-medium text-neutral-600'}>Workflow Automation</span>
|
||||
</div>
|
||||
|
||||
<h1 className={'text-6xl font-bold tracking-tight text-neutral-900 sm:text-7xl lg:text-8xl text-balance'}>
|
||||
Email Automation
|
||||
<br />
|
||||
That Actually Works
|
||||
</h1>
|
||||
<p className={'mx-auto mt-8 max-w-2xl text-xl text-neutral-600'}>
|
||||
Turn events into personalized email journeys. Build sophisticated automation workflows with our visual
|
||||
no-code builder.
|
||||
</p>
|
||||
|
||||
<div className={'mt-12 flex flex-wrap justify-center gap-4'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.02}}
|
||||
whileTap={{scale: 0.98}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
<div className={'mx-auto max-w-[88rem] px-6 pb-20 pt-20 sm:px-10 sm:pt-28 sm:pb-28'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 16}}
|
||||
animate={{opacity: 1, y: 0}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
>
|
||||
<div
|
||||
style={{fontFamily: 'var(--font-mono)'}}
|
||||
className={'mb-6 text-[11px] uppercase tracking-[0.18em] text-neutral-500'}
|
||||
>
|
||||
Workflow Automation
|
||||
</div>
|
||||
<h1
|
||||
style={{fontFamily: 'var(--font-display)'}}
|
||||
className={
|
||||
'group rounded-lg bg-neutral-900 px-8 py-4 text-base font-semibold text-white shadow-lg shadow-neutral-900/10 transition hover:bg-neutral-800'
|
||||
'text-[clamp(2.75rem,7vw,6.5rem)] font-extrabold leading-[0.92] tracking-[-0.04em] text-neutral-900'
|
||||
}
|
||||
>
|
||||
<span className={'flex items-center gap-2'}>
|
||||
Start building workflows
|
||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-1" />
|
||||
</span>
|
||||
</motion.a>
|
||||
<Link
|
||||
href={WIKI_URI}
|
||||
target={'_blank'}
|
||||
className={
|
||||
'rounded-lg border border-neutral-300 bg-white px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-400'
|
||||
}
|
||||
>
|
||||
View documentation
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
</section>
|
||||
Email automation
|
||||
<br />
|
||||
that actually works.
|
||||
</h1>
|
||||
<p className={'mt-6 max-w-2xl text-xl text-neutral-600'}>
|
||||
Turn events into personalized email journeys. Build sophisticated automation workflows with our visual
|
||||
no-code builder.
|
||||
</p>
|
||||
|
||||
{/* Features Grid */}
|
||||
<section className={'py-20'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-16 text-center'}
|
||||
>
|
||||
<h2 className={'text-4xl font-bold tracking-tight text-neutral-900 sm:text-5xl text-balance'}>
|
||||
Everything you need for email automation
|
||||
</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Powerful features that make complex automations simple</p>
|
||||
</motion.div>
|
||||
|
||||
<div className={'grid gap-px bg-neutral-200 sm:grid-cols-2 lg:grid-cols-3'}>
|
||||
{features.map((feature, index) => (
|
||||
<motion.div
|
||||
key={feature.title}
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: index * 0.1, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-10 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
<div className={'mt-10 flex flex-wrap gap-3'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.015}}
|
||||
whileTap={{scale: 0.985}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
'group inline-flex items-center gap-2 rounded-full bg-neutral-900 px-8 py-4 text-base font-semibold text-white shadow-[0_10px_30px_-10px_rgba(23,23,23,0.35)] transition hover:bg-neutral-800'
|
||||
}
|
||||
>
|
||||
{feature.icon}
|
||||
</div>
|
||||
<h3 className={'mt-6 text-lg font-semibold text-neutral-900'}>{feature.title}</h3>
|
||||
<p className={'mt-2 text-sm leading-relaxed text-neutral-600'}>{feature.description}</p>
|
||||
</motion.div>
|
||||
))}
|
||||
Start building workflows
|
||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-0.5" />
|
||||
</motion.a>
|
||||
<Link
|
||||
href={WIKI_URI}
|
||||
target={'_blank'}
|
||||
className={
|
||||
'inline-flex items-center gap-2 rounded-full border border-neutral-300 bg-white px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-900'
|
||||
}
|
||||
>
|
||||
View documentation
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* How It Works */}
|
||||
<section className={'py-20'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mx-auto max-w-4xl text-center'}
|
||||
>
|
||||
<h2 className={'text-4xl font-bold tracking-tight text-neutral-900 sm:text-5xl text-balance'}>
|
||||
Visual workflow builder
|
||||
</h2>
|
||||
<p className={'mt-6 text-lg text-neutral-600'}>
|
||||
Create complex email automations without writing a single line of code
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<div className={'mx-auto mt-16 max-w-5xl'}>
|
||||
<div className={'grid gap-12 lg:grid-cols-3'}>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.1, ease: [0.22, 1, 0.36, 1]}}
|
||||
{/* Features grid */}
|
||||
<section className={'border-t border-neutral-200'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-16'}
|
||||
>
|
||||
<h2
|
||||
style={{fontFamily: 'var(--font-display)'}}
|
||||
className={
|
||||
'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'
|
||||
}
|
||||
>
|
||||
<div className={'mb-5 flex items-center gap-4'}>
|
||||
<div className={'flex h-14 w-14 items-center justify-center rounded-full border-2 border-neutral-200 bg-white text-xl font-bold text-neutral-900'}>
|
||||
1
|
||||
</div>
|
||||
</div>
|
||||
<h3 className={'text-lg font-semibold text-neutral-900'}>Choose a trigger</h3>
|
||||
<p className={'mt-2 text-sm leading-relaxed text-neutral-600'}>
|
||||
Select an event that starts your workflow, like user signup, purchase, or any custom action you track.
|
||||
</p>
|
||||
</motion.div>
|
||||
Everything you need for email automation
|
||||
</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Powerful features that make complex automations simple</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.2, ease: [0.22, 1, 0.36, 1]}}
|
||||
>
|
||||
<div className={'mb-5 flex items-center gap-4'}>
|
||||
<div className={'flex h-14 w-14 items-center justify-center rounded-full border-2 border-neutral-200 bg-white text-xl font-bold text-neutral-900'}>
|
||||
2
|
||||
</div>
|
||||
</div>
|
||||
<h3 className={'text-lg font-semibold text-neutral-900'}>Build your flow</h3>
|
||||
<p className={'mt-2 text-sm leading-relaxed text-neutral-600'}>
|
||||
Drag and drop steps to create your workflow. Add emails, delays, conditions, webhooks, and more.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.3, ease: [0.22, 1, 0.36, 1]}}
|
||||
>
|
||||
<div className={'mb-5 flex items-center gap-4'}>
|
||||
<div className={'flex h-14 w-14 items-center justify-center rounded-full border-2 border-neutral-200 bg-white text-xl font-bold text-neutral-900'}>
|
||||
3
|
||||
</div>
|
||||
</div>
|
||||
<h3 className={'text-lg font-semibold text-neutral-900'}>Activate and monitor</h3>
|
||||
<p className={'mt-2 text-sm leading-relaxed text-neutral-600'}>
|
||||
Enable your workflow and watch it run automatically. Monitor executions in real-time with full
|
||||
visibility.
|
||||
</p>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Use Cases */}
|
||||
<section className={'py-20'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-16 text-center'}
|
||||
>
|
||||
<h2 className={'text-4xl font-bold tracking-tight text-neutral-900 sm:text-5xl text-balance'}>
|
||||
Built for every use case
|
||||
</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>From onboarding to re-engagement, workflows handle it all</p>
|
||||
</motion.div>
|
||||
|
||||
<div className={'mx-auto max-w-5xl space-y-8'}>
|
||||
{useCases.map((useCase, index) => (
|
||||
<motion.div
|
||||
key={useCase.title}
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: index * 0.1, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'rounded-xl border border-neutral-200 bg-white p-8'}
|
||||
>
|
||||
<div className={'flex items-start gap-6'}>
|
||||
<div
|
||||
<div className={'grid gap-4 sm:grid-cols-2 lg:grid-cols-3'}>
|
||||
{features.map((feature, index) => {
|
||||
const highlighted = feature.featured;
|
||||
return (
|
||||
<motion.div
|
||||
key={feature.title}
|
||||
initial={{opacity: 0, y: 16}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: index * 0.06, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={
|
||||
'flex h-14 w-14 flex-shrink-0 items-center justify-center rounded-xl bg-neutral-900 text-white'
|
||||
highlighted
|
||||
? 'flex min-h-[16rem] flex-col justify-between rounded-[28px] border border-neutral-900 bg-neutral-900 p-8 text-white'
|
||||
: 'flex min-h-[16rem] flex-col justify-between rounded-[28px] border border-neutral-200 bg-white p-8 transition hover:border-neutral-900'
|
||||
}
|
||||
>
|
||||
{useCase.icon}
|
||||
</div>
|
||||
<div className={'flex-1'}>
|
||||
<h3 className={'text-xl font-semibold text-neutral-900'}>{useCase.title}</h3>
|
||||
<p className={'mt-2 text-neutral-600'}>{useCase.description}</p>
|
||||
<div className={'mt-4 rounded-lg bg-neutral-50 p-4'}>
|
||||
<p className={'font-mono text-sm text-neutral-700'}>{useCase.example}</p>
|
||||
<div className={'flex items-start justify-between'}>
|
||||
<div className={highlighted ? 'text-white' : 'text-neutral-900'}>{feature.icon}</div>
|
||||
<span
|
||||
style={{fontFamily: 'var(--font-mono)'}}
|
||||
className={`text-[11px] uppercase tracking-[0.18em] ${highlighted ? 'text-neutral-500' : 'text-neutral-400'}`}
|
||||
>
|
||||
{String(index + 1).padStart(2, '0')}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
))}
|
||||
<div>
|
||||
<h3
|
||||
style={{fontFamily: 'var(--font-display)'}}
|
||||
className={`mt-8 text-xl font-bold tracking-[-0.02em] ${highlighted ? 'text-white' : 'text-neutral-900'}`}
|
||||
>
|
||||
{feature.title}
|
||||
</h3>
|
||||
<p className={`mt-2 text-sm leading-relaxed ${highlighted ? 'text-neutral-300' : 'text-neutral-600'}`}>
|
||||
{feature.description}
|
||||
</p>
|
||||
</div>
|
||||
</motion.div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* CTA Section */}
|
||||
<section className={'relative overflow-hidden border-t border-neutral-200 py-20'}>
|
||||
<div
|
||||
className={
|
||||
'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#e5e7eb_1px,transparent_1px),linear-gradient(to_bottom,#e5e7eb_1px,transparent_1px)] bg-[size:4rem_4rem] [mask-image:radial-gradient(ellipse_80%_50%_at_50%_100%,#000_70%,transparent_110%)]'
|
||||
}
|
||||
/>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mx-auto max-w-3xl text-center'}
|
||||
>
|
||||
<h2 className={'text-4xl font-bold tracking-tight text-neutral-900 sm:text-5xl text-balance'}>
|
||||
Set up your first workflow in minutes
|
||||
</h2>
|
||||
<p className={'mt-6 text-lg text-neutral-600'}>
|
||||
1,000 emails free every month. Then $0.001 per email. No contact limits, no credit card required.
|
||||
</p>
|
||||
<div className={'mt-12 flex flex-wrap justify-center gap-4'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.02}}
|
||||
whileTap={{scale: 0.98}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
className={
|
||||
'group rounded-lg bg-neutral-900 px-8 py-4 text-base font-semibold text-white transition hover:bg-neutral-800'
|
||||
}
|
||||
{/* How it works */}
|
||||
<section className={'border-t border-neutral-200 bg-neutral-50/60'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-16 text-center'}
|
||||
>
|
||||
<h2
|
||||
style={{fontFamily: 'var(--font-display)'}}
|
||||
className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}
|
||||
>
|
||||
<span className={'flex items-center gap-2'}>
|
||||
Get started for free
|
||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-1" />
|
||||
</span>
|
||||
</motion.a>
|
||||
<Link
|
||||
href={'/pricing'}
|
||||
className={
|
||||
'rounded-lg border border-neutral-300 px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-400'
|
||||
}
|
||||
>
|
||||
View pricing
|
||||
</Link>
|
||||
Visual workflow builder
|
||||
</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>
|
||||
Create complex email automations without writing a single line of code
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<div className={'mx-auto max-w-4xl'}>
|
||||
<div className={'grid gap-px bg-neutral-200 sm:grid-cols-3'}>
|
||||
{[
|
||||
{
|
||||
step: '01',
|
||||
title: 'Choose a trigger',
|
||||
body: 'Select an event that starts your workflow, like user signup, purchase, or any custom action you track.',
|
||||
},
|
||||
{
|
||||
step: '02',
|
||||
title: 'Build your flow',
|
||||
body: 'Drag and drop steps to create your workflow. Add emails, delays, conditions, webhooks, and more.',
|
||||
},
|
||||
{
|
||||
step: '03',
|
||||
title: 'Activate and monitor',
|
||||
body: 'Enable your workflow and watch it run automatically. Monitor executions in real-time with full visibility.',
|
||||
},
|
||||
].map((item, i) => (
|
||||
<motion.div
|
||||
key={item.step}
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: i * 0.1, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'bg-white p-10'}
|
||||
>
|
||||
<div
|
||||
style={{fontFamily: 'var(--font-mono)'}}
|
||||
className={'mb-6 text-[11px] uppercase tracking-[0.18em] text-neutral-400'}
|
||||
>
|
||||
Step {item.step}
|
||||
</div>
|
||||
<h3 className={'text-lg font-semibold text-neutral-900'}>{item.title}</h3>
|
||||
<p className={'mt-2 text-sm leading-relaxed text-neutral-600'}>{item.body}</p>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Use cases */}
|
||||
<section className={'border-t border-neutral-200'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-16'}
|
||||
>
|
||||
<h2
|
||||
style={{fontFamily: 'var(--font-display)'}}
|
||||
className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}
|
||||
>
|
||||
Built for every use case
|
||||
</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>From onboarding to re-engagement, workflows handle it all</p>
|
||||
</motion.div>
|
||||
|
||||
<div className={'space-y-4'}>
|
||||
{useCases.map((useCase, index) => (
|
||||
<motion.div
|
||||
key={useCase.title}
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: index * 0.1, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'rounded-[24px] border border-neutral-200 bg-white p-8'}
|
||||
>
|
||||
<div className={'flex items-start gap-6'}>
|
||||
<div className={'flex h-14 w-14 flex-shrink-0 items-center justify-center rounded-full border border-neutral-200 bg-white text-neutral-900'}>
|
||||
{useCase.icon}
|
||||
</div>
|
||||
<div className={'flex-1'}>
|
||||
<h3
|
||||
style={{fontFamily: 'var(--font-display)'}}
|
||||
className={'text-xl font-bold tracking-[-0.02em] text-neutral-900'}
|
||||
>
|
||||
{useCase.title}
|
||||
</h3>
|
||||
<p className={'mt-2 text-neutral-600'}>{useCase.description}</p>
|
||||
<div className={'mt-4 rounded-xl border border-neutral-100 bg-neutral-50 p-4'}>
|
||||
<p
|
||||
style={{fontFamily: 'var(--font-mono)'}}
|
||||
className={'text-sm text-neutral-600'}
|
||||
>
|
||||
{useCase.example}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* CTA */}
|
||||
<section className={'relative overflow-hidden border-t border-neutral-900 bg-neutral-900 text-white'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-32 sm:px-10 sm:py-40'}>
|
||||
<div className={'flex flex-col items-start gap-12 lg:flex-row lg:items-end lg:justify-between'}>
|
||||
<motion.h2
|
||||
initial={{opacity: 0, y: 16}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.9, ease: [0.22, 1, 0.36, 1]}}
|
||||
style={{fontFamily: 'var(--font-display)'}}
|
||||
className={'text-[clamp(2.5rem,7vw,6rem)] font-extrabold leading-[0.95] tracking-[-0.035em]'}
|
||||
>
|
||||
Set up your first workflow in minutes.
|
||||
</motion.h2>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 16}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.9, delay: 0.15, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'flex max-w-md flex-col gap-6'}
|
||||
>
|
||||
<p className={'text-base text-neutral-300 sm:text-lg'}>
|
||||
Free plan available. $0.001 per email on paid. No credit card required.
|
||||
</p>
|
||||
<div className={'flex flex-wrap gap-3'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.015}}
|
||||
whileTap={{scale: 0.985}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
className={'inline-flex items-center gap-2 rounded-full bg-white px-7 py-3.5 text-sm font-semibold text-neutral-900 transition hover:bg-neutral-100'}
|
||||
>
|
||||
Get started for free
|
||||
<ArrowRight className="h-4 w-4" />
|
||||
</motion.a>
|
||||
<Link
|
||||
href={'/pricing'}
|
||||
className={'inline-flex items-center gap-2 rounded-full border border-neutral-700 px-7 py-3.5 text-sm font-semibold text-white transition hover:border-white'}
|
||||
>
|
||||
View pricing
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</main>
|
||||
|
||||
<Footer />
|
||||
|
||||
@@ -10,7 +10,7 @@ interface Guide {
|
||||
title: string;
|
||||
description: string;
|
||||
href: string;
|
||||
icon: React.ComponentType<{className?: string}>;
|
||||
icon: React.ComponentType<{className?: string; strokeWidth?: number}>;
|
||||
badge?: string;
|
||||
}
|
||||
|
||||
@@ -94,9 +94,6 @@ const guides: Guide[] = [
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
* Email Guides hub page
|
||||
*/
|
||||
export default function GuidesIndex() {
|
||||
return (
|
||||
<>
|
||||
@@ -115,154 +112,171 @@ export default function GuidesIndex() {
|
||||
|
||||
<Navbar />
|
||||
|
||||
<main className={'mx-auto max-w-7xl px-8 sm:px-0'}>
|
||||
{/* Hero Section */}
|
||||
<section className={'relative py-32 sm:py-48'}>
|
||||
<main className={'text-neutral-800'}>
|
||||
|
||||
{/* Hero */}
|
||||
<section className={'relative overflow-hidden'}>
|
||||
<div
|
||||
aria-hidden
|
||||
className={
|
||||
'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#e5e7eb_1px,transparent_1px),linear-gradient(to_bottom,#e5e7eb_1px,transparent_1px)] bg-[size:4rem_4rem] [mask-image:radial-gradient(ellipse_80%_50%_at_50%_0%,#000_70%,transparent_110%)]'
|
||||
'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#eeeeee_1px,transparent_1px),linear-gradient(to_bottom,#eeeeee_1px,transparent_1px)] bg-[size:6rem_6rem] [mask-image:radial-gradient(ellipse_70%_60%_at_50%_30%,#000_40%,transparent_95%)]'
|
||||
}
|
||||
/>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
animate={{opacity: 1, y: 0}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mx-auto max-w-4xl text-center'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'mb-6 inline-flex items-center gap-2 rounded-full border border-neutral-200 bg-white px-4 py-2'
|
||||
}
|
||||
<div className={'mx-auto max-w-[88rem] px-6 pb-20 pt-20 sm:px-10 sm:pt-28 sm:pb-28'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 16}}
|
||||
animate={{opacity: 1, y: 0}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
>
|
||||
<Book className="h-4 w-4 text-neutral-600" />
|
||||
<span className={'text-sm text-neutral-600'}>Free Email Guides</span>
|
||||
</div>
|
||||
|
||||
<h1 className={'text-6xl font-bold tracking-tight text-neutral-900 sm:text-7xl lg:text-8xl'}>
|
||||
Master email
|
||||
<br />
|
||||
marketing & deliverability
|
||||
</h1>
|
||||
|
||||
<p className={'mx-auto mt-8 max-w-2xl text-xl text-neutral-600'}>
|
||||
Free guides on email authentication, deliverability, best practices, and technical implementation. Learn
|
||||
from the experts.
|
||||
</p>
|
||||
|
||||
<div className={'mt-12 flex flex-wrap justify-center gap-4'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.02}}
|
||||
whileTap={{scale: 0.98}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
<div
|
||||
style={{fontFamily: 'var(--font-mono)'}}
|
||||
className={'mb-6 text-[11px] uppercase tracking-[0.18em] text-neutral-500'}
|
||||
>
|
||||
Free Guides
|
||||
</div>
|
||||
<h1
|
||||
style={{fontFamily: 'var(--font-display)'}}
|
||||
className={
|
||||
'group rounded-lg bg-neutral-900 px-8 py-4 text-base font-semibold text-white shadow-lg shadow-neutral-900/10 transition hover:bg-neutral-800'
|
||||
'text-[clamp(2.75rem,7vw,6.5rem)] font-extrabold leading-[0.92] tracking-[-0.04em] text-neutral-900'
|
||||
}
|
||||
>
|
||||
<span className={'flex items-center gap-2'}>
|
||||
Try Plunk free
|
||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-1" />
|
||||
</span>
|
||||
</motion.a>
|
||||
</div>
|
||||
</motion.div>
|
||||
</section>
|
||||
Master email,
|
||||
<br />
|
||||
start to finish.
|
||||
</h1>
|
||||
<p className={'mt-6 max-w-2xl text-xl text-neutral-600'}>
|
||||
Free guides on email authentication, deliverability, best practices, and technical implementation.
|
||||
</p>
|
||||
|
||||
{/* Guides Grid */}
|
||||
<section className={'py-32'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-16 text-center'}
|
||||
>
|
||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900'}>Browse all guides</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Everything you need to master email</p>
|
||||
</motion.div>
|
||||
|
||||
<div className={'grid gap-6 sm:grid-cols-2 lg:grid-cols-3'}>
|
||||
{guides.map((guide, index) => {
|
||||
const Icon = guide.icon;
|
||||
return (
|
||||
<motion.div
|
||||
key={guide.href}
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: index * 0.05, ease: [0.22, 1, 0.36, 1]}}
|
||||
<div className={'mt-10 flex flex-wrap gap-3'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.015}}
|
||||
whileTap={{scale: 0.985}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
className={
|
||||
'group inline-flex items-center gap-2 rounded-full bg-neutral-900 px-8 py-4 text-base font-semibold text-white shadow-[0_10px_30px_-10px_rgba(23,23,23,0.35)] transition hover:bg-neutral-800'
|
||||
}
|
||||
>
|
||||
<Link
|
||||
href={guide.href}
|
||||
className={
|
||||
'group block h-full rounded-2xl border border-neutral-200 bg-white p-8 transition hover:border-neutral-300 hover:shadow-lg'
|
||||
}
|
||||
>
|
||||
<div className={'flex items-start justify-between mb-4'}>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<Icon className="h-5 w-5" />
|
||||
</div>
|
||||
{guide.badge && (
|
||||
<span className={'rounded-full bg-neutral-100 px-3 py-1 text-xs font-medium text-neutral-700'}>
|
||||
{guide.badge}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<h3 className={'text-xl font-semibold text-neutral-900 mb-2 group-hover:text-neutral-700'}>
|
||||
{guide.title}
|
||||
</h3>
|
||||
<p className={'text-sm text-neutral-600 leading-relaxed'}>{guide.description}</p>
|
||||
</Link>
|
||||
</motion.div>
|
||||
);
|
||||
})}
|
||||
Try Plunk free
|
||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-0.5" />
|
||||
</motion.a>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* CTA Section */}
|
||||
<section className={'relative overflow-hidden border-t border-neutral-200 py-32'}>
|
||||
<div
|
||||
className={
|
||||
'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#e5e7eb_1px,transparent_1px),linear-gradient(to_bottom,#e5e7eb_1px,transparent_1px)] bg-[size:4rem_4rem] [mask-image:radial-gradient(ellipse_80%_50%_at_50%_100%,#000_70%,transparent_110%)]'
|
||||
}
|
||||
/>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mx-auto max-w-3xl text-center'}
|
||||
>
|
||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900'}>Ready to get started?</h2>
|
||||
<p className={'mt-6 text-lg text-neutral-600'}>
|
||||
Put these guides into practice with Plunk's modern email platform. Start free, no credit card required.
|
||||
</p>
|
||||
<div className={'mt-12 flex flex-wrap justify-center gap-4'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.02}}
|
||||
whileTap={{scale: 0.98}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
className={
|
||||
'rounded-lg bg-neutral-900 px-8 py-4 text-base font-semibold text-white transition hover:bg-neutral-800'
|
||||
}
|
||||
{/* Guides grid */}
|
||||
<section className={'border-t border-neutral-200'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-16'}
|
||||
>
|
||||
<h2
|
||||
style={{fontFamily: 'var(--font-display)'}}
|
||||
className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}
|
||||
>
|
||||
Get started free
|
||||
</motion.a>
|
||||
<Link
|
||||
href="/pricing"
|
||||
className={
|
||||
'rounded-lg border border-neutral-300 px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-400'
|
||||
}
|
||||
>
|
||||
View pricing
|
||||
</Link>
|
||||
Browse all guides
|
||||
</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Everything you need to master email</p>
|
||||
</motion.div>
|
||||
|
||||
<div className={'grid gap-4 sm:grid-cols-2 lg:grid-cols-3'}>
|
||||
{guides.map((guide, index) => {
|
||||
const Icon = guide.icon;
|
||||
return (
|
||||
<motion.div
|
||||
key={guide.href}
|
||||
initial={{opacity: 0, y: 16}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: index * 0.04, ease: [0.22, 1, 0.36, 1]}}
|
||||
>
|
||||
<Link
|
||||
href={guide.href}
|
||||
className={
|
||||
'group flex min-h-[16rem] flex-col justify-between rounded-[28px] border border-neutral-200 bg-white p-8 transition hover:border-neutral-900'
|
||||
}
|
||||
>
|
||||
<div className={'flex items-start justify-between'}>
|
||||
<div className={'text-neutral-900'}>
|
||||
<Icon className="h-6 w-6" strokeWidth={1.5} />
|
||||
</div>
|
||||
{guide.badge && (
|
||||
<span
|
||||
style={{fontFamily: 'var(--font-mono)'}}
|
||||
className={'text-[11px] uppercase tracking-[0.18em] text-neutral-400'}
|
||||
>
|
||||
{guide.badge}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<div>
|
||||
<h3
|
||||
style={{fontFamily: 'var(--font-display)'}}
|
||||
className={'mt-8 text-xl font-bold tracking-[-0.02em] text-neutral-900'}
|
||||
>
|
||||
{guide.title}
|
||||
</h3>
|
||||
<p className={'mt-2 text-sm leading-relaxed text-neutral-600'}>{guide.description}</p>
|
||||
</div>
|
||||
</Link>
|
||||
</motion.div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* CTA */}
|
||||
<section className={'relative overflow-hidden border-t border-neutral-900 bg-neutral-900 text-white'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-32 sm:px-10 sm:py-40'}>
|
||||
<div className={'flex flex-col items-start gap-12 lg:flex-row lg:items-end lg:justify-between'}>
|
||||
<motion.h2
|
||||
initial={{opacity: 0, y: 16}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.9, ease: [0.22, 1, 0.36, 1]}}
|
||||
style={{fontFamily: 'var(--font-display)'}}
|
||||
className={'text-[clamp(2.5rem,7vw,6rem)] font-extrabold leading-[0.95] tracking-[-0.035em]'}
|
||||
>
|
||||
Put it into practice.
|
||||
</motion.h2>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 16}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.9, delay: 0.15, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'flex max-w-md flex-col gap-6'}
|
||||
>
|
||||
<p className={'text-base text-neutral-300 sm:text-lg'}>
|
||||
Start free. No credit card required.
|
||||
</p>
|
||||
<div className={'flex flex-wrap gap-3'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.015}}
|
||||
whileTap={{scale: 0.985}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
className={'inline-flex items-center gap-2 rounded-full bg-white px-7 py-3.5 text-sm font-semibold text-neutral-900 transition hover:bg-neutral-100'}
|
||||
>
|
||||
Get started free
|
||||
<ArrowRight className="h-4 w-4" />
|
||||
</motion.a>
|
||||
<Link
|
||||
href={'/pricing'}
|
||||
className={'inline-flex items-center gap-2 rounded-full border border-neutral-700 px-7 py-3.5 text-sm font-semibold text-white transition hover:border-white'}
|
||||
>
|
||||
View pricing
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</main>
|
||||
|
||||
<Footer />
|
||||
|
||||
+775
-618
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
+265
-193
@@ -3,7 +3,19 @@ import React from 'react';
|
||||
import {Footer, Navbar} from '../components';
|
||||
import {motion} from 'framer-motion';
|
||||
import {DASHBOARD_URI} from '../lib/constants';
|
||||
import {ArrowRight, BarChart3, Code2, Globe, Mail, PackageOpen, Shield, Users, Zap, X, Check} from 'lucide-react';
|
||||
import {
|
||||
ArrowRight,
|
||||
BarChart3,
|
||||
Code2,
|
||||
Globe,
|
||||
Mail,
|
||||
PackageOpen,
|
||||
Shield,
|
||||
Users,
|
||||
Zap,
|
||||
X,
|
||||
Check,
|
||||
} from 'lucide-react';
|
||||
import Link from 'next/link';
|
||||
import {GithubIcon} from 'lucide-react';
|
||||
|
||||
@@ -55,9 +67,6 @@ const includedFeatures = [
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export default function Pricing() {
|
||||
return (
|
||||
<>
|
||||
@@ -69,232 +78,295 @@ export default function Pricing() {
|
||||
openGraph={{
|
||||
title: 'Plunk Pricing | The Open-Source Email Platform',
|
||||
description:
|
||||
'Transparent email pricing at $0.001 per email with no contact limits. Free plan includes 1,000 emails/month across transactional, workflow, and campaign emails. No hidden fees, pay only for what you use.',
|
||||
'Transparent email pricing at $0.001 per email with no contact limits. Free plan includes 1,000 emails/month. No hidden fees.',
|
||||
}}
|
||||
additionalMetaTags={[
|
||||
{
|
||||
property: 'title',
|
||||
content: 'Plunk Pricing | The Open-Source Email Platform',
|
||||
},
|
||||
]}
|
||||
additionalMetaTags={[{property: 'title', content: 'Plunk Pricing | The Open-Source Email Platform'}]}
|
||||
/>
|
||||
|
||||
<Navbar />
|
||||
|
||||
<main className={'mx-auto max-w-7xl px-8 sm:px-0'}>
|
||||
<main className={'text-neutral-800'}>
|
||||
|
||||
{/* Hero */}
|
||||
<section className={'relative py-20 sm:py-32'}>
|
||||
<section className={'relative overflow-hidden'}>
|
||||
<div
|
||||
aria-hidden
|
||||
className={
|
||||
'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#e5e7eb_1px,transparent_1px),linear-gradient(to_bottom,#e5e7eb_1px,transparent_1px)] bg-[size:4rem_4rem] [mask-image:radial-gradient(ellipse_80%_50%_at_50%_0%,#000_70%,transparent_110%)]'
|
||||
'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#eeeeee_1px,transparent_1px),linear-gradient(to_bottom,#eeeeee_1px,transparent_1px)] bg-[size:6rem_6rem] [mask-image:radial-gradient(ellipse_70%_60%_at_50%_30%,#000_40%,transparent_95%)]'
|
||||
}
|
||||
/>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
animate={{opacity: 1, y: 0}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mx-auto max-w-4xl text-center'}
|
||||
>
|
||||
<h1 className="text-5xl font-bold tracking-tight text-neutral-900 sm:text-6xl lg:text-7xl text-balance">
|
||||
Simple, transparent pricing
|
||||
</h1>
|
||||
<p className="mx-auto mt-6 max-w-2xl text-xl text-neutral-600">
|
||||
1,000 emails free every month. Then $0.001 per email. Unlimited contacts, no hidden fees.
|
||||
</p>
|
||||
</motion.div>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 pb-20 pt-20 sm:px-10 sm:pt-28 sm:pb-28'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 16}}
|
||||
animate={{opacity: 1, y: 0}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mx-auto max-w-4xl text-center'}
|
||||
>
|
||||
<h1
|
||||
style={{fontFamily: 'var(--font-display)'}}
|
||||
className={
|
||||
'text-[clamp(2.75rem,7vw,6.5rem)] font-extrabold leading-[0.92] tracking-[-0.04em] text-neutral-900'
|
||||
}
|
||||
>
|
||||
Simple, transparent pricing
|
||||
</h1>
|
||||
<p className={'mx-auto mt-6 max-w-2xl text-xl text-neutral-600'}>
|
||||
Free plan: 1,000 emails per month. Paid plan: $0.001 per email. Unlimited contacts, no hidden fees.
|
||||
</p>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Pricing tiers */}
|
||||
<section className={'pb-20'}>
|
||||
<div className={'mx-auto grid max-w-4xl gap-px bg-neutral-200 sm:grid-cols-2'}>
|
||||
{/* Free */}
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
animate={{opacity: 1, y: 0}}
|
||||
transition={{delay: 0.1, duration: 0.6, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'flex flex-col bg-white p-10'}
|
||||
>
|
||||
<p className={'text-sm font-semibold uppercase tracking-widest text-neutral-400'}>Free forever</p>
|
||||
<div className={'mt-4 flex items-baseline gap-2'}>
|
||||
<span className={'text-6xl font-bold tracking-tight text-neutral-900'}>1,000</span>
|
||||
<span className={'text-lg text-neutral-500'}>emails / mo</span>
|
||||
</div>
|
||||
<p className={'mt-2 text-sm text-neutral-500'}>No credit card required</p>
|
||||
|
||||
<ul className={'mt-8 flex-1 space-y-3'}>
|
||||
{['Transactional emails', 'Workflow automation', 'Campaign broadcasts', 'Custom domains', 'Click & open tracking', 'Unlimited contacts'].map(item => (
|
||||
<li key={item} className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<Check className={'h-4 w-4 flex-shrink-0 text-neutral-900'} />
|
||||
{item}
|
||||
</li>
|
||||
))}
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-400'}>
|
||||
<X className={'h-4 w-4 flex-shrink-0'} />
|
||||
Plunk branding on emails
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<motion.a
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
whileHover={{scale: 1.02}}
|
||||
whileTap={{scale: 0.98}}
|
||||
className={'mt-10 block w-full rounded-lg border border-neutral-300 px-6 py-3 text-center text-sm font-semibold text-neutral-900 transition hover:border-neutral-400'}
|
||||
<section className={'border-t border-neutral-200'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||
<div className={'mx-auto grid max-w-4xl gap-px bg-neutral-200 sm:grid-cols-2'}>
|
||||
{/* Free */}
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
animate={{opacity: 1, y: 0}}
|
||||
transition={{delay: 0.1, duration: 0.6, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'flex flex-col bg-white p-10'}
|
||||
>
|
||||
Start for free
|
||||
</motion.a>
|
||||
</motion.div>
|
||||
<p
|
||||
style={{fontFamily: 'var(--font-mono)'}}
|
||||
className={'text-[11px] font-semibold uppercase tracking-[0.18em] text-neutral-400'}
|
||||
>
|
||||
Free forever
|
||||
</p>
|
||||
<div className={'mt-4 flex items-baseline gap-2'}>
|
||||
<span
|
||||
style={{fontFamily: 'var(--font-display)'}}
|
||||
className={'text-6xl font-extrabold tracking-[-0.03em] text-neutral-900'}
|
||||
>
|
||||
1,000
|
||||
</span>
|
||||
<span className={'text-lg text-neutral-500'}>emails / mo</span>
|
||||
</div>
|
||||
<p className={'mt-2 text-sm text-neutral-500'}>No credit card required</p>
|
||||
|
||||
{/* Pay as you grow */}
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
animate={{opacity: 1, y: 0}}
|
||||
transition={{delay: 0.2, duration: 0.6, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'flex flex-col bg-white p-10'}
|
||||
>
|
||||
<p className={'text-sm font-semibold uppercase tracking-widest text-neutral-400'}>Pay as you grow</p>
|
||||
<div className={'mt-4 flex items-baseline gap-2'}>
|
||||
<span className={'text-6xl font-bold tracking-tight text-neutral-900'}>$0.001</span>
|
||||
<span className={'text-lg text-neutral-500'}>/ email</span>
|
||||
</div>
|
||||
<p className={'mt-2 text-sm'}> </p>
|
||||
|
||||
<ul className={'mt-8 flex-1 space-y-3'}>
|
||||
{['Everything in Free', 'No Plunk branding', 'Monthly spend cap', 'Unlimited emails'].map(item => (
|
||||
<li key={item} className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<Check className={'h-4 w-4 flex-shrink-0 text-neutral-900'} />
|
||||
{item}
|
||||
<ul className={'mt-8 flex-1 space-y-3'}>
|
||||
{[
|
||||
'Transactional emails',
|
||||
'Workflow automation',
|
||||
'Campaign broadcasts',
|
||||
'Custom domains',
|
||||
'Click & open tracking',
|
||||
'Unlimited contacts',
|
||||
].map(item => (
|
||||
<li key={item} className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<Check className={'h-4 w-4 flex-shrink-0 text-neutral-900'} />
|
||||
{item}
|
||||
</li>
|
||||
))}
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-400'}>
|
||||
<X className={'h-4 w-4 flex-shrink-0'} />
|
||||
Plunk branding on emails
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
<motion.a
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
whileHover={{scale: 1.02}}
|
||||
whileTap={{scale: 0.98}}
|
||||
className={'mt-10 block w-full rounded-lg bg-neutral-900 px-6 py-3 text-center text-sm font-semibold text-white transition hover:bg-neutral-800'}
|
||||
<motion.a
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
whileHover={{scale: 1.02}}
|
||||
whileTap={{scale: 0.98}}
|
||||
className={
|
||||
'mt-10 block w-full rounded-full border border-neutral-300 px-6 py-3 text-center text-sm font-semibold text-neutral-900 transition hover:border-neutral-900'
|
||||
}
|
||||
>
|
||||
Start for free
|
||||
</motion.a>
|
||||
</motion.div>
|
||||
|
||||
{/* Pay as you grow */}
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
animate={{opacity: 1, y: 0}}
|
||||
transition={{delay: 0.2, duration: 0.6, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'flex flex-col bg-neutral-900 p-10 text-white'}
|
||||
>
|
||||
Get started
|
||||
<p
|
||||
style={{fontFamily: 'var(--font-mono)'}}
|
||||
className={'text-[11px] font-semibold uppercase tracking-[0.18em] text-neutral-400'}
|
||||
>
|
||||
Pay as you grow
|
||||
</p>
|
||||
<div className={'mt-4 flex items-baseline gap-2'}>
|
||||
<span
|
||||
style={{fontFamily: 'var(--font-display)'}}
|
||||
className={'text-6xl font-extrabold tracking-[-0.03em] text-white'}
|
||||
>
|
||||
$0.001
|
||||
</span>
|
||||
<span className={'text-lg text-neutral-400'}>/ email</span>
|
||||
</div>
|
||||
<p className={'mt-2 text-sm'}> </p>
|
||||
|
||||
</motion.a>
|
||||
</motion.div>
|
||||
<ul className={'mt-8 flex-1 space-y-3'}>
|
||||
{['Everything in Free', 'No Plunk branding', 'Monthly spend cap', 'Unlimited emails'].map(item => (
|
||||
<li key={item} className={'flex items-center gap-3 text-sm text-neutral-300'}>
|
||||
<Check className={'h-4 w-4 flex-shrink-0 text-white'} />
|
||||
{item}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
|
||||
<motion.a
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
whileHover={{scale: 1.02}}
|
||||
whileTap={{scale: 0.98}}
|
||||
className={
|
||||
'mt-10 block w-full rounded-full bg-white px-6 py-3 text-center text-sm font-semibold text-neutral-900 transition hover:bg-neutral-100'
|
||||
}
|
||||
>
|
||||
Get started
|
||||
</motion.a>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Every feature included */}
|
||||
<section className={'py-20'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-16 text-center'}
|
||||
>
|
||||
<h2 className={'text-4xl font-bold tracking-tight text-neutral-900 sm:text-5xl text-balance'}>
|
||||
Every feature on every plan
|
||||
</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>No feature tiers, no add-ons, no surprises</p>
|
||||
</motion.div>
|
||||
|
||||
<div className={'grid gap-px bg-neutral-200 sm:grid-cols-2 lg:grid-cols-3'}>
|
||||
{includedFeatures.map((feature, index) => (
|
||||
<motion.div
|
||||
key={feature.title}
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: index * 0.05, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-10 transition hover:bg-neutral-50'}
|
||||
<section className={'border-t border-neutral-200 bg-neutral-50/60'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-16 text-center'}
|
||||
>
|
||||
<h2
|
||||
style={{fontFamily: 'var(--font-display)'}}
|
||||
className={
|
||||
'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'
|
||||
}
|
||||
>
|
||||
<div className={'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'}>
|
||||
{feature.icon}
|
||||
</div>
|
||||
<h3 className={'mt-6 text-lg font-semibold text-neutral-900'}>{feature.title}</h3>
|
||||
<p className={'mt-2 text-sm leading-relaxed text-neutral-600'}>{feature.description}</p>
|
||||
</motion.div>
|
||||
))}
|
||||
Every feature on every plan
|
||||
</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>No feature tiers, no add-ons, no surprises</p>
|
||||
</motion.div>
|
||||
|
||||
<div className={'grid gap-px bg-neutral-200 sm:grid-cols-2 lg:grid-cols-3'}>
|
||||
{includedFeatures.map((feature, index) => (
|
||||
<motion.div
|
||||
key={feature.title}
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: index * 0.05, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-10 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div className={'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white'}>
|
||||
{feature.icon}
|
||||
</div>
|
||||
<h3 className={'mt-6 text-lg font-semibold text-neutral-900'}>{feature.title}</h3>
|
||||
<p className={'mt-2 text-sm leading-relaxed text-neutral-600'}>{feature.description}</p>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Self-host */}
|
||||
<section className={'py-20'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'overflow-hidden rounded-xl border border-neutral-200 bg-white'}
|
||||
>
|
||||
<div className={'flex flex-col items-center gap-6 p-10 sm:flex-row sm:gap-0'}>
|
||||
<div className={'flex-1 text-center sm:text-left'}>
|
||||
<div className={'mb-3 inline-flex items-center gap-2 rounded-full bg-neutral-100 px-3 py-1 text-sm font-medium text-neutral-700'}>
|
||||
<PackageOpen className={'h-3.5 w-3.5'} />
|
||||
Self-hostable
|
||||
<section className={'border-t border-neutral-200'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'overflow-hidden rounded-[24px] border border-neutral-200 bg-white'}
|
||||
>
|
||||
<div className={'flex flex-col items-center gap-6 p-10 sm:flex-row sm:gap-0'}>
|
||||
<div className={'flex-1 text-center sm:text-left'}>
|
||||
<div
|
||||
style={{fontFamily: 'var(--font-mono)'}}
|
||||
className={'mb-3 inline-flex items-center gap-2 text-[11px] uppercase tracking-[0.18em] text-neutral-500'}
|
||||
>
|
||||
<PackageOpen className={'h-3.5 w-3.5'} />
|
||||
Self-hostable
|
||||
</div>
|
||||
<h2
|
||||
style={{fontFamily: 'var(--font-display)'}}
|
||||
className={'text-2xl font-bold tracking-[-0.025em] text-neutral-900'}
|
||||
>
|
||||
Run it on your own infrastructure
|
||||
</h2>
|
||||
<p className={'mt-2 text-neutral-600'}>
|
||||
Full data ownership, no per-email costs, and GDPR compliance by default. Deploy with Docker Compose
|
||||
in minutes.
|
||||
</p>
|
||||
</div>
|
||||
<div className={'sm:ml-auto sm:pl-8'}>
|
||||
<motion.button
|
||||
onClick={() => window.open('https://github.com/useplunk/plunk', '_blank')}
|
||||
whileHover={{scale: 1.02}}
|
||||
whileTap={{scale: 0.98}}
|
||||
className={
|
||||
'flex w-full items-center justify-center gap-x-3 rounded-full bg-neutral-900 px-6 py-3 text-base font-semibold text-white transition hover:bg-neutral-800 sm:w-auto'
|
||||
}
|
||||
>
|
||||
<GithubIcon size={18} />
|
||||
View on GitHub
|
||||
</motion.button>
|
||||
</div>
|
||||
<h2 className={'text-2xl font-bold text-neutral-900'}>Run it on your own infrastructure</h2>
|
||||
<p className={'mt-2 text-neutral-600'}>
|
||||
Full data ownership, no per-email costs, and GDPR compliance by default. Deploy with Docker Compose in minutes.
|
||||
</p>
|
||||
</div>
|
||||
<div className={'sm:ml-auto sm:pl-8'}>
|
||||
<motion.button
|
||||
onClick={() => {
|
||||
window.open('https://github.com/useplunk/plunk', '_blank');
|
||||
}}
|
||||
whileHover={{scale: 1.02}}
|
||||
whileTap={{scale: 0.98}}
|
||||
className={'flex w-full items-center justify-center gap-x-3 rounded-lg bg-neutral-900 px-6 py-3 text-base font-semibold text-white transition hover:bg-neutral-800 sm:w-auto'}
|
||||
>
|
||||
<GithubIcon size={18} />
|
||||
View on GitHub
|
||||
</motion.button>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* CTA */}
|
||||
<section className={'relative overflow-hidden border-t border-neutral-200 py-20'}>
|
||||
<div
|
||||
className={
|
||||
'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#e5e7eb_1px,transparent_1px),linear-gradient(to_bottom,#e5e7eb_1px,transparent_1px)] bg-[size:4rem_4rem] [mask-image:radial-gradient(ellipse_80%_50%_at_50%_100%,#000_70%,transparent_110%)]'
|
||||
}
|
||||
/>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mx-auto max-w-3xl text-center'}
|
||||
>
|
||||
<h2 className={'text-4xl font-bold tracking-tight text-neutral-900 sm:text-5xl text-balance'}>
|
||||
Start sending in 5 minutes
|
||||
</h2>
|
||||
<p className={'mt-6 text-lg text-neutral-600'}>
|
||||
1,000 emails free every month. No credit card required.
|
||||
</p>
|
||||
<div className={'mt-12 flex flex-wrap justify-center gap-4'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.02}}
|
||||
whileTap={{scale: 0.98}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
className={'group rounded-lg bg-neutral-900 px-8 py-4 text-base font-semibold text-white transition hover:bg-neutral-800'}
|
||||
<section className={'relative overflow-hidden border-t border-neutral-900 bg-neutral-900 text-white'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-32 sm:px-10 sm:py-40'}>
|
||||
<div className={'flex flex-col items-start gap-12 lg:flex-row lg:items-end lg:justify-between'}>
|
||||
<motion.h2
|
||||
initial={{opacity: 0, y: 16}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.9, ease: [0.22, 1, 0.36, 1]}}
|
||||
style={{fontFamily: 'var(--font-display)'}}
|
||||
className={'text-[clamp(2.5rem,7vw,6rem)] font-extrabold leading-[0.95] tracking-[-0.035em]'}
|
||||
>
|
||||
<span className={'flex items-center gap-2'}>
|
||||
Create free account
|
||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-1" />
|
||||
</span>
|
||||
</motion.a>
|
||||
<Link
|
||||
href={'https://github.com/useplunk/plunk'}
|
||||
target={'_blank'}
|
||||
className={'rounded-lg border border-neutral-300 px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-400'}
|
||||
Start sending in 5 minutes.
|
||||
</motion.h2>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 16}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.9, delay: 0.15, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'flex max-w-md flex-col gap-6'}
|
||||
>
|
||||
Self-host for free
|
||||
</Link>
|
||||
<p className={'text-base text-neutral-300 sm:text-lg'}>
|
||||
Start free. No credit card required.
|
||||
</p>
|
||||
<div className={'flex flex-wrap gap-3'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.015}}
|
||||
whileTap={{scale: 0.985}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
className={
|
||||
'inline-flex items-center gap-2 rounded-full bg-white px-7 py-3.5 text-sm font-semibold text-neutral-900 transition hover:bg-neutral-100'
|
||||
}
|
||||
>
|
||||
Create free account
|
||||
<ArrowRight className="h-4 w-4" />
|
||||
</motion.a>
|
||||
<Link
|
||||
href={'https://github.com/useplunk/plunk'}
|
||||
target={'_blank'}
|
||||
className={
|
||||
'inline-flex items-center gap-2 rounded-full border border-neutral-700 px-7 py-3.5 text-sm font-semibold text-white transition hover:border-white'
|
||||
}
|
||||
>
|
||||
Self-host for free
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</main>
|
||||
|
||||
<Footer />
|
||||
|
||||
@@ -1,31 +1,50 @@
|
||||
import {Footer, Navbar} from '../../components';
|
||||
import {Footer, Navbar, SectionHeader} from '../../components';
|
||||
import {motion} from 'framer-motion';
|
||||
import {DASHBOARD_URI} from '../../lib/constants';
|
||||
import React from 'react';
|
||||
import Link from 'next/link';
|
||||
import {NextSeo} from 'next-seo';
|
||||
import {ArrowRight, Code2, Mail, Search, Sparkles, Wrench} from 'lucide-react';
|
||||
import {ArrowRight, ArrowUpRight, Code2, Search} from 'lucide-react';
|
||||
import {Bricolage_Grotesque, Hanken_Grotesk, JetBrains_Mono} from 'next/font/google';
|
||||
|
||||
const display = Bricolage_Grotesque({
|
||||
subsets: ['latin'],
|
||||
variable: '--font-display',
|
||||
display: 'swap',
|
||||
weight: ['400', '500', '600', '700', '800'],
|
||||
});
|
||||
|
||||
const body = Hanken_Grotesk({
|
||||
subsets: ['latin'],
|
||||
variable: '--font-body',
|
||||
display: 'swap',
|
||||
weight: ['400', '500', '600', '700'],
|
||||
});
|
||||
|
||||
const mono = JetBrains_Mono({
|
||||
subsets: ['latin'],
|
||||
variable: '--font-mono',
|
||||
display: 'swap',
|
||||
weight: ['400', '500'],
|
||||
});
|
||||
|
||||
const tools = [
|
||||
{
|
||||
name: 'Markdown to Email',
|
||||
slug: 'markdown-to-email',
|
||||
description: 'Convert rich text to email-safe HTML with our visual editor and instant preview.',
|
||||
features: ['Visual Editor', 'Email-Safe HTML', 'Inline CSS', 'Copy to Clipboard'],
|
||||
description: 'Convert rich text to email-safe HTML with a visual editor and instant preview.',
|
||||
icon: Code2,
|
||||
number: '01',
|
||||
},
|
||||
{
|
||||
name: 'Email Verification',
|
||||
slug: 'verify-email',
|
||||
description: 'Verify email addresses instantly. Check DNS, MX records, typos, and disposable domains.',
|
||||
features: ['DNS Validation', 'Typo Detection', 'MX Records', 'Disposable Check'],
|
||||
icon: Search,
|
||||
number: '02',
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
* Free Email Tools index page
|
||||
*/
|
||||
export default function ToolsIndex() {
|
||||
return (
|
||||
<>
|
||||
@@ -44,225 +63,261 @@ export default function ToolsIndex() {
|
||||
|
||||
<Navbar />
|
||||
|
||||
<main className={'mx-auto max-w-7xl px-8 sm:px-0'}>
|
||||
{/* Hero Section */}
|
||||
<section className={'relative py-32 sm:py-48'}>
|
||||
<div
|
||||
className={
|
||||
'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#e5e7eb_1px,transparent_1px),linear-gradient(to_bottom,#e5e7eb_1px,transparent_1px)] bg-[size:4rem_4rem] [mask-image:radial-gradient(ellipse_80%_50%_at_50%_0%,#000_70%,transparent_110%)]'
|
||||
}
|
||||
/>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
animate={{opacity: 1, y: 0}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mx-auto max-w-4xl text-center'}
|
||||
>
|
||||
<div className={`${display.variable} ${body.variable} ${mono.variable}`}>
|
||||
<main className={'text-neutral-800'}>
|
||||
{/* ========== HERO ========== */}
|
||||
<section className={'relative overflow-hidden'}>
|
||||
<div
|
||||
aria-hidden
|
||||
className={
|
||||
'mb-6 inline-flex items-center gap-2 rounded-full border border-neutral-200 bg-white px-4 py-2'
|
||||
'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#eeeeee_1px,transparent_1px),linear-gradient(to_bottom,#eeeeee_1px,transparent_1px)] bg-[size:6rem_6rem] [mask-image:radial-gradient(ellipse_70%_60%_at_50%_30%,#000_40%,transparent_95%)]'
|
||||
}
|
||||
>
|
||||
<Wrench className="h-4 w-4 text-neutral-600" />
|
||||
<span className={'text-sm text-neutral-600'}>Free Email Tools</span>
|
||||
</div>
|
||||
/>
|
||||
|
||||
<h1 className={'text-6xl font-bold tracking-tight text-neutral-900 sm:text-7xl lg:text-8xl text-balance'}>
|
||||
Free tools for
|
||||
<br />
|
||||
email developers
|
||||
</h1>
|
||||
|
||||
<p className={'mx-auto mt-8 max-w-2xl text-xl text-neutral-600'}>
|
||||
Build better emails with our free tools. Convert markdown to email-safe HTML, verify email addresses, and
|
||||
more. No sign-up required.
|
||||
</p>
|
||||
|
||||
<div className={'mt-12 flex flex-wrap justify-center gap-4'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.02}}
|
||||
whileTap={{scale: 0.98}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
<div className={'mx-auto max-w-[88rem] px-6 pb-24 pt-20 sm:px-10 sm:pt-28 lg:pb-36'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 8}}
|
||||
animate={{opacity: 1, y: 0}}
|
||||
transition={{duration: 0.5, ease: [0.22, 1, 0.36, 1]}}
|
||||
style={{fontFamily: 'var(--font-mono)'}}
|
||||
className={
|
||||
'group rounded-lg bg-neutral-900 px-8 py-4 text-base font-semibold text-white shadow-lg shadow-neutral-900/10 transition hover:bg-neutral-800'
|
||||
'mb-16 flex items-center justify-between border-t border-neutral-900/90 pt-4 text-[11px] uppercase tracking-[0.18em] text-neutral-700 sm:mb-24'
|
||||
}
|
||||
>
|
||||
<span className={'flex items-center gap-2'}>
|
||||
Try Plunk free
|
||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-1" />
|
||||
</span>
|
||||
</motion.a>
|
||||
<Link
|
||||
href="/guides"
|
||||
className={
|
||||
'rounded-lg border border-neutral-300 bg-white px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-400'
|
||||
}
|
||||
<span className={'font-medium text-neutral-900'}>§ Tools — Plunk</span>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 16}}
|
||||
animate={{opacity: 1, y: 0}}
|
||||
transition={{duration: 0.9, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mx-auto max-w-5xl text-center'}
|
||||
>
|
||||
Browse guides
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
</section>
|
||||
<h1
|
||||
style={{fontFamily: 'var(--font-display)'}}
|
||||
className={
|
||||
'text-[clamp(3rem,9vw,8rem)] font-extrabold leading-[0.92] tracking-[-0.04em] text-neutral-900'
|
||||
}
|
||||
>
|
||||
Free email
|
||||
<br />
|
||||
developer tools
|
||||
</h1>
|
||||
<p className={'mx-auto mt-8 max-w-2xl text-lg leading-relaxed text-neutral-600 sm:text-xl'}>
|
||||
Convert markdown to email-safe HTML, verify addresses, and more. No sign-up required.
|
||||
</p>
|
||||
|
||||
{/* Tools Grid */}
|
||||
<section className={'py-32'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-16 text-center'}
|
||||
>
|
||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>Available Tools</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Everything you need to work with emails</p>
|
||||
</motion.div>
|
||||
|
||||
<div className={'grid gap-8 md:grid-cols-2 lg:grid-cols-2 max-w-4xl mx-auto'}>
|
||||
{tools.map((tool, index) => {
|
||||
const Icon = tool.icon;
|
||||
return (
|
||||
<Link key={tool.slug} href={`/tools/${tool.slug}`}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: index * 0.1, ease: [0.22, 1, 0.36, 1]}}
|
||||
<div className={'mt-10 flex flex-wrap justify-center gap-3'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.015}}
|
||||
whileTap={{scale: 0.985}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
className={
|
||||
'group rounded-2xl border border-neutral-200 bg-white p-8 transition hover:border-neutral-300 hover:shadow-lg cursor-pointer h-full'
|
||||
'group inline-flex items-center gap-2 rounded-full bg-neutral-900 px-8 py-4 text-base font-semibold text-white shadow-[0_10px_30px_-10px_rgba(23,23,23,0.35)] transition hover:bg-neutral-800'
|
||||
}
|
||||
>
|
||||
<div className={'flex items-start justify-between mb-4'}>
|
||||
<div
|
||||
Try Plunk free
|
||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-0.5" />
|
||||
</motion.a>
|
||||
<Link
|
||||
href="/guides"
|
||||
className={
|
||||
'inline-flex items-center gap-2 rounded-full border border-neutral-300 bg-white px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-900'
|
||||
}
|
||||
>
|
||||
Browse guides
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* ========== TOOLS LIST ========== */}
|
||||
<section className={'mx-auto max-w-[88rem] px-6 py-28 sm:px-10 sm:py-36'}>
|
||||
<SectionHeader
|
||||
number={'01'}
|
||||
label={'Tools'}
|
||||
title={'Available tools.'}
|
||||
subtitle={'Everything you need to work with email. No sign-up, no limits.'}
|
||||
/>
|
||||
|
||||
<ul className={'mt-20 divide-y divide-neutral-200 border-y border-neutral-200'}>
|
||||
{tools.map((tool, i) => (
|
||||
<motion.li
|
||||
key={tool.slug}
|
||||
initial={{opacity: 0, y: 12}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: i * 0.06, ease: [0.22, 1, 0.36, 1]}}
|
||||
>
|
||||
<Link
|
||||
href={`/tools/${tool.slug}`}
|
||||
className={
|
||||
'group flex items-center justify-between gap-6 py-6 transition-colors hover:bg-neutral-50 sm:py-8'
|
||||
}
|
||||
>
|
||||
<div className={'flex items-center gap-6 sm:gap-10'}>
|
||||
<span
|
||||
style={{fontFamily: 'var(--font-mono)'}}
|
||||
className={'w-12 text-xs tabular-nums tracking-[0.18em] text-neutral-400 sm:w-16'}
|
||||
>
|
||||
{tool.number}
|
||||
</span>
|
||||
<div>
|
||||
<span
|
||||
style={{fontFamily: 'var(--font-display)'}}
|
||||
className={
|
||||
'block text-4xl font-bold tracking-[-0.03em] text-neutral-900 transition-transform duration-300 group-hover:-translate-x-1 sm:text-5xl lg:text-6xl'
|
||||
}
|
||||
>
|
||||
{tool.name}
|
||||
</span>
|
||||
<p className={'mt-2 text-sm text-neutral-500'}>{tool.description}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className={'flex items-center gap-4'}>
|
||||
<span
|
||||
style={{fontFamily: 'var(--font-mono)'}}
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
'hidden text-xs uppercase tracking-[0.18em] text-neutral-500 transition group-hover:text-neutral-900 sm:inline'
|
||||
}
|
||||
>
|
||||
<Icon className="h-5 w-5" />
|
||||
</div>
|
||||
<Sparkles className="h-5 w-5 text-neutral-400" />
|
||||
Open tool
|
||||
</span>
|
||||
<span
|
||||
className={
|
||||
'flex h-11 w-11 items-center justify-center rounded-full border border-neutral-300 text-neutral-900 transition group-hover:border-neutral-900 group-hover:bg-neutral-900 group-hover:text-white sm:h-14 sm:w-14'
|
||||
}
|
||||
>
|
||||
<ArrowUpRight className={'h-5 w-5'} strokeWidth={2} />
|
||||
</span>
|
||||
</div>
|
||||
<h3 className={'text-2xl font-bold text-neutral-900 mb-3'}>{tool.name}</h3>
|
||||
<p className={'mb-6 leading-relaxed text-neutral-600'}>{tool.description}</p>
|
||||
<div className={'space-y-2'}>
|
||||
{tool.features.map(feature => (
|
||||
<div key={feature} className={'flex items-center gap-2 text-sm text-neutral-600'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-neutral-900'} />
|
||||
<span>{feature}</span>
|
||||
</div>
|
||||
))}
|
||||
</Link>
|
||||
</motion.li>
|
||||
))}
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
{/* ========== WHY ========== */}
|
||||
<section className={'border-t border-neutral-200 bg-neutral-50/60'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-28 sm:px-10 sm:py-36'}>
|
||||
<SectionHeader
|
||||
number={'02'}
|
||||
label={'Why'}
|
||||
title={'Built for developers,'}
|
||||
titleAccent={'free forever.'}
|
||||
subtitle={'No sign-up, no paywalls. Tools built by email experts for real-world workflows.'}
|
||||
/>
|
||||
|
||||
<div className={'mt-20 grid gap-10 sm:grid-cols-3 sm:gap-16'}>
|
||||
{[
|
||||
{
|
||||
tag: 'Access',
|
||||
big: '$0',
|
||||
title: 'Free forever',
|
||||
body: 'No sign-up, no paywalls, no limits. Use these tools as much as you need, completely free.',
|
||||
},
|
||||
{
|
||||
tag: 'Focus',
|
||||
big: 'Dev-first',
|
||||
title: 'Developer-focused',
|
||||
body: 'Built by developers who work with email every day. Clean outputs, instant results, real-world workflows.',
|
||||
},
|
||||
{
|
||||
tag: 'Output',
|
||||
big: '100%',
|
||||
title: 'Production ready',
|
||||
body: 'Email-safe HTML that works across all email clients. Industry-standard validation. Battle-tested by thousands.',
|
||||
},
|
||||
].map((item, i) => (
|
||||
<motion.div
|
||||
key={item.tag}
|
||||
initial={{opacity: 0, y: 16}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.6, delay: i * 0.1, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'flex flex-col gap-6'}
|
||||
>
|
||||
<span
|
||||
style={{fontFamily: 'var(--font-mono)'}}
|
||||
className={'text-[11px] uppercase tracking-[0.2em] text-neutral-500'}
|
||||
>
|
||||
/ {item.tag}
|
||||
</span>
|
||||
<div
|
||||
style={{fontFamily: 'var(--font-display)'}}
|
||||
className={'text-5xl font-extrabold tracking-[-0.035em] text-neutral-900 sm:text-6xl'}
|
||||
>
|
||||
{item.big}
|
||||
</div>
|
||||
<div className={'h-px w-full bg-neutral-300'} />
|
||||
<h3
|
||||
style={{fontFamily: 'var(--font-display)'}}
|
||||
className={'text-xl font-semibold text-neutral-900'}
|
||||
>
|
||||
{item.title}
|
||||
</h3>
|
||||
<p className={'text-base leading-relaxed text-neutral-600'}>{item.body}</p>
|
||||
</motion.div>
|
||||
</Link>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Why Use These Tools */}
|
||||
<section className={'border-t border-neutral-200 py-32'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-16 text-center'}
|
||||
>
|
||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>Why use these tools?</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Built by email experts for email developers</p>
|
||||
</motion.div>
|
||||
|
||||
<div className={'grid gap-8 lg:grid-cols-3'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.1, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={
|
||||
'rounded-2xl border border-neutral-200 bg-white p-8 transition hover:border-neutral-300 hover:shadow-lg'
|
||||
}
|
||||
>
|
||||
<Mail className="h-8 w-8 text-blue-500 mb-4" />
|
||||
<h3 className={'text-2xl font-bold text-neutral-900'}>Free Forever</h3>
|
||||
<p className={'mt-4 leading-relaxed text-neutral-600'}>
|
||||
No sign-up, no paywalls, no limits. Use our tools as much as you need, completely free. We believe in
|
||||
giving back to the email development community.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.2, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={
|
||||
'rounded-2xl border border-neutral-200 bg-white p-8 transition hover:border-neutral-300 hover:shadow-lg'
|
||||
}
|
||||
>
|
||||
<Code2 className="h-8 w-8 text-green-500 mb-4" />
|
||||
<h3 className={'text-2xl font-bold text-neutral-900'}>Developer-Focused</h3>
|
||||
<p className={'mt-4 leading-relaxed text-neutral-600'}>
|
||||
Built by developers who work with email every day. Clean outputs, instant results, and designed for
|
||||
real-world email workflows.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.3, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={
|
||||
'rounded-2xl border border-neutral-200 bg-white p-8 transition hover:border-neutral-300 hover:shadow-lg'
|
||||
}
|
||||
>
|
||||
<Sparkles className="h-8 w-8 text-yellow-500 mb-4" />
|
||||
<h3 className={'text-2xl font-bold text-neutral-900'}>Production Ready</h3>
|
||||
<p className={'mt-4 leading-relaxed text-neutral-600'}>
|
||||
Generate email-safe HTML that works across all email clients. Verify emails with industry-standard
|
||||
checks. Our tools are battle-tested and used by thousands of developers.
|
||||
</p>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* CTA */}
|
||||
<section className={'border-t border-neutral-200 py-32'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mx-auto max-w-3xl text-center'}
|
||||
>
|
||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>Need production-grade email tools?</h2>
|
||||
<p className={'mt-6 text-lg text-neutral-600'}>
|
||||
These free tools are great for development, but Plunk offers so much more: templates, scheduling,
|
||||
automation, analytics, and deliverability optimization. Start free, scale as you grow.
|
||||
</p>
|
||||
<div className={'mt-12 flex flex-wrap justify-center gap-4'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.02}}
|
||||
whileTap={{scale: 0.98}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
className={
|
||||
'rounded-lg bg-neutral-900 px-8 py-4 text-base font-semibold text-white transition hover:bg-neutral-800'
|
||||
}
|
||||
>
|
||||
Start with Plunk
|
||||
</motion.a>
|
||||
<Link
|
||||
href="/pricing"
|
||||
className={
|
||||
'rounded-lg border border-neutral-300 px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-400'
|
||||
}
|
||||
>
|
||||
View pricing
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
</section>
|
||||
</main>
|
||||
</section>
|
||||
|
||||
{/* ========== CTA ========== */}
|
||||
<section className={'relative overflow-hidden border-t border-neutral-900 bg-neutral-900 text-white'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-32 sm:px-10 sm:py-40'}>
|
||||
<div className={'flex flex-col items-start gap-12 lg:flex-row lg:items-end lg:justify-between'}>
|
||||
<motion.h2
|
||||
initial={{opacity: 0, y: 16}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.9, ease: [0.22, 1, 0.36, 1]}}
|
||||
style={{fontFamily: 'var(--font-display)'}}
|
||||
className={
|
||||
'text-[clamp(2.5rem,7vw,6rem)] font-extrabold leading-[0.95] tracking-[-0.035em]'
|
||||
}
|
||||
>
|
||||
Need production-grade email?
|
||||
</motion.h2>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 16}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.9, delay: 0.15, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'flex max-w-md flex-col gap-6'}
|
||||
>
|
||||
<p className={'text-base text-neutral-300 sm:text-lg'}>
|
||||
Templates, scheduling, automation, analytics, and deliverability. Start free, scale as you grow.
|
||||
</p>
|
||||
<div className={'flex flex-wrap gap-3'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.015}}
|
||||
whileTap={{scale: 0.985}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
className={
|
||||
'inline-flex items-center gap-2 rounded-full bg-white px-7 py-3.5 text-sm font-semibold text-neutral-900 transition hover:bg-neutral-100'
|
||||
}
|
||||
>
|
||||
Start with Plunk
|
||||
<ArrowRight className="h-4 w-4" />
|
||||
</motion.a>
|
||||
<Link
|
||||
href="/pricing"
|
||||
className={
|
||||
'inline-flex items-center gap-2 rounded-full border border-neutral-700 px-7 py-3.5 text-sm font-semibold text-white transition hover:border-white'
|
||||
}
|
||||
>
|
||||
View pricing
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<Footer />
|
||||
</>
|
||||
|
||||
@@ -1,21 +1,40 @@
|
||||
import {Footer, Navbar} from '../../components';
|
||||
import {Footer, Navbar, SectionHeader} from '../../components';
|
||||
import {motion} from 'framer-motion';
|
||||
import {DASHBOARD_URI} from '../../lib/constants';
|
||||
import React, {useMemo, useState} from 'react';
|
||||
import {NextSeo} from 'next-seo';
|
||||
import {ArrowRight, Check, Code2, Copy, Sparkles} from 'lucide-react';
|
||||
import {ArrowRight, Check, Code2, Copy} from 'lucide-react';
|
||||
import {MarkdownEmailEditor} from '../../components/tools/MarkdownEmailEditor';
|
||||
import {convertToCompleteEmailHtml} from '../../lib/emailHtmlConverter';
|
||||
import {Button} from '@plunk/ui';
|
||||
import {Bricolage_Grotesque, Hanken_Grotesk, JetBrains_Mono} from 'next/font/google';
|
||||
|
||||
const display = Bricolage_Grotesque({
|
||||
subsets: ['latin'],
|
||||
variable: '--font-display',
|
||||
display: 'swap',
|
||||
weight: ['400', '500', '600', '700', '800'],
|
||||
});
|
||||
|
||||
const body = Hanken_Grotesk({
|
||||
subsets: ['latin'],
|
||||
variable: '--font-body',
|
||||
display: 'swap',
|
||||
weight: ['400', '500', '600', '700'],
|
||||
});
|
||||
|
||||
const mono = JetBrains_Mono({
|
||||
subsets: ['latin'],
|
||||
variable: '--font-mono',
|
||||
display: 'swap',
|
||||
weight: ['400', '500'],
|
||||
});
|
||||
|
||||
export default function MarkdownToEmail() {
|
||||
const [editorContent, setEditorContent] = useState('<p>Hello!</p><p>Try editing this text...</p>');
|
||||
const [copied, setCopied] = useState(false);
|
||||
|
||||
// Convert editor content to complete, ready-to-send email HTML
|
||||
const emailSafeHtml = useMemo(() => {
|
||||
return convertToCompleteEmailHtml(editorContent);
|
||||
}, [editorContent]);
|
||||
const emailSafeHtml = useMemo(() => convertToCompleteEmailHtml(editorContent), [editorContent]);
|
||||
|
||||
const handleCopy = async () => {
|
||||
await navigator.clipboard.writeText(emailSafeHtml);
|
||||
@@ -40,123 +59,230 @@ export default function MarkdownToEmail() {
|
||||
|
||||
<Navbar />
|
||||
|
||||
<main className={'mx-auto max-w-7xl px-8 sm:px-0'}>
|
||||
{/* Hero Section */}
|
||||
<section className={'relative py-32 sm:py-48'}>
|
||||
<div
|
||||
className={
|
||||
'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#e5e7eb_1px,transparent_1px),linear-gradient(to_bottom,#e5e7eb_1px,transparent_1px)] bg-[size:4rem_4rem] [mask-image:radial-gradient(ellipse_80%_50%_at_50%_0%,#000_70%,transparent_110%)]'
|
||||
}
|
||||
/>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
animate={{opacity: 1, y: 0}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mx-auto max-w-4xl text-center'}
|
||||
>
|
||||
<div className={`${display.variable} ${body.variable} ${mono.variable}`}>
|
||||
<main className={'text-neutral-800'}>
|
||||
{/* ========== HERO ========== */}
|
||||
<section className={'relative overflow-hidden'}>
|
||||
<div
|
||||
aria-hidden
|
||||
className={
|
||||
'mb-6 inline-flex items-center gap-2 rounded-full border border-neutral-200 bg-white px-4 py-2'
|
||||
'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#eeeeee_1px,transparent_1px),linear-gradient(to_bottom,#eeeeee_1px,transparent_1px)] bg-[size:6rem_6rem] [mask-image:radial-gradient(ellipse_70%_60%_at_50%_30%,#000_40%,transparent_95%)]'
|
||||
}
|
||||
>
|
||||
<Sparkles className="h-4 w-4 text-neutral-600" />
|
||||
<span className={'text-sm text-neutral-600'}>Free Tool</span>
|
||||
</div>
|
||||
/>
|
||||
|
||||
<h1 className={'text-6xl font-bold tracking-tight text-neutral-900 sm:text-7xl lg:text-8xl text-balance'}>
|
||||
Markdown to Email
|
||||
<br />
|
||||
HTML Converter
|
||||
</h1>
|
||||
|
||||
<p className={'mx-auto mt-8 max-w-2xl text-xl text-neutral-600'}>
|
||||
Create beautiful, email-safe HTML instantly. Format your text with our visual editor and get
|
||||
production-ready HTML with inlined styles that works across all email clients.
|
||||
</p>
|
||||
</motion.div>
|
||||
</section>
|
||||
|
||||
{/* Editor Section */}
|
||||
<section className={'py-16'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'grid gap-6 lg:grid-cols-2'}
|
||||
>
|
||||
{/* Left: Editor */}
|
||||
<div>
|
||||
<div className="mb-4 flex items-center justify-between">
|
||||
<h2 className="text-xl font-semibold text-neutral-900">Visual Editor</h2>
|
||||
<div className="flex items-center gap-2 text-sm text-neutral-600">
|
||||
<Code2 className="h-4 w-4" />
|
||||
<span>Format your content</span>
|
||||
</div>
|
||||
</div>
|
||||
<MarkdownEmailEditor value={editorContent} onChange={setEditorContent} />
|
||||
</div>
|
||||
|
||||
{/* Right: Email-Safe HTML Output */}
|
||||
<div>
|
||||
<div className="mb-4 flex items-center justify-between">
|
||||
<h2 className="text-xl font-semibold text-neutral-900">Email-Safe HTML</h2>
|
||||
<Button onClick={handleCopy} size="sm" variant="outline" className="gap-2">
|
||||
{copied ? (
|
||||
<>
|
||||
<Check className="h-4 w-4" />
|
||||
Copied!
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Copy className="h-4 w-4" />
|
||||
Copy
|
||||
</>
|
||||
)}
|
||||
</Button>
|
||||
</div>
|
||||
<div className="border border-neutral-200 rounded-lg overflow-hidden bg-white">
|
||||
<pre className="p-4 text-xs font-mono overflow-x-auto min-h-[500px] max-h-[500px] overflow-y-auto">
|
||||
<code className="text-neutral-700">{emailSafeHtml}</code>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
</section>
|
||||
|
||||
{/* CTA Section */}
|
||||
<section className={'border-t border-neutral-200 py-32'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mx-auto max-w-3xl text-center'}
|
||||
>
|
||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>Ready to send great emails?</h2>
|
||||
<p className={'mt-6 text-lg text-neutral-600'}>
|
||||
This tool is great for creating email HTML, but Plunk handles everything: templates, sending, tracking,
|
||||
and deliverability. Start free, no credit card required.
|
||||
</p>
|
||||
<div className={'mt-12 flex flex-wrap justify-center gap-4'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.02}}
|
||||
whileTap={{scale: 0.98}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
<div className={'mx-auto max-w-[88rem] px-6 pb-24 pt-20 sm:px-10 sm:pt-28 lg:pb-36'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 8}}
|
||||
animate={{opacity: 1, y: 0}}
|
||||
transition={{duration: 0.5, ease: [0.22, 1, 0.36, 1]}}
|
||||
style={{fontFamily: 'var(--font-mono)'}}
|
||||
className={
|
||||
'group rounded-lg bg-neutral-900 px-8 py-4 text-base font-semibold text-white transition hover:bg-neutral-800'
|
||||
'mb-16 flex items-center justify-between border-t border-neutral-900/90 pt-4 text-[11px] uppercase tracking-[0.18em] text-neutral-700 sm:mb-24'
|
||||
}
|
||||
>
|
||||
<span className={'flex items-center gap-2'}>
|
||||
Start with Plunk
|
||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-1" />
|
||||
</span>
|
||||
</motion.a>
|
||||
<span className={'font-medium text-neutral-900'}>§ T-01 — Tool</span>
|
||||
<a
|
||||
href="/tools"
|
||||
className={'text-neutral-500 transition hover:text-neutral-900'}
|
||||
>
|
||||
← All tools
|
||||
</a>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 16}}
|
||||
animate={{opacity: 1, y: 0}}
|
||||
transition={{duration: 0.9, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mx-auto max-w-5xl text-center'}
|
||||
>
|
||||
<h1
|
||||
style={{fontFamily: 'var(--font-display)'}}
|
||||
className={
|
||||
'text-[clamp(2.5rem,7vw,6.5rem)] font-extrabold leading-[0.92] tracking-[-0.04em] text-neutral-900'
|
||||
}
|
||||
>
|
||||
Markdown to
|
||||
<br />
|
||||
Email HTML
|
||||
</h1>
|
||||
<p className={'mx-auto mt-8 max-w-2xl text-lg leading-relaxed text-neutral-600 sm:text-xl'}>
|
||||
Format your content with the visual editor and get production-ready HTML with inlined styles that works across all email clients.
|
||||
</p>
|
||||
</motion.div>
|
||||
</div>
|
||||
</motion.div>
|
||||
</section>
|
||||
</main>
|
||||
</section>
|
||||
|
||||
{/* ========== EDITOR ========== */}
|
||||
<section className={'mx-auto max-w-[88rem] px-6 py-16 sm:px-10 sm:py-20'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'grid gap-6 lg:grid-cols-2'}
|
||||
>
|
||||
{/* Left: Editor */}
|
||||
<div>
|
||||
<div className={'mb-4 flex items-center justify-between'}>
|
||||
<div className={'flex items-center gap-3'}>
|
||||
<Code2 className={'h-4 w-4 text-neutral-500'} strokeWidth={1.5} />
|
||||
<span
|
||||
style={{fontFamily: 'var(--font-mono)'}}
|
||||
className={'text-[11px] uppercase tracking-[0.18em] text-neutral-500'}
|
||||
>
|
||||
Visual Editor
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<MarkdownEmailEditor value={editorContent} onChange={setEditorContent} />
|
||||
</div>
|
||||
|
||||
{/* Right: Email-Safe HTML Output */}
|
||||
<div>
|
||||
<div className={'mb-4 flex items-center justify-between'}>
|
||||
<span
|
||||
style={{fontFamily: 'var(--font-mono)'}}
|
||||
className={'text-[11px] uppercase tracking-[0.18em] text-neutral-500'}
|
||||
>
|
||||
Email-Safe HTML
|
||||
</span>
|
||||
<Button onClick={handleCopy} size="sm" variant="outline" className={'gap-2'}>
|
||||
{copied ? (
|
||||
<>
|
||||
<Check className={'h-4 w-4'} />
|
||||
Copied!
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Copy className={'h-4 w-4'} />
|
||||
Copy
|
||||
</>
|
||||
)}
|
||||
</Button>
|
||||
</div>
|
||||
<div className={'overflow-hidden rounded-[16px] border border-neutral-200 bg-white'}>
|
||||
<pre className={'max-h-[500px] min-h-[500px] overflow-x-auto overflow-y-auto p-4 text-xs'}>
|
||||
<code style={{fontFamily: 'var(--font-mono)'}} className={'text-neutral-700'}>
|
||||
{emailSafeHtml}
|
||||
</code>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
</section>
|
||||
|
||||
{/* ========== ABOUT ========== */}
|
||||
<section className={'border-t border-neutral-200 bg-neutral-50/60'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-28 sm:px-10 sm:py-36'}>
|
||||
<SectionHeader
|
||||
number={'01'}
|
||||
label={'How it works'}
|
||||
title={'Write once,'}
|
||||
titleAccent={'send everywhere.'}
|
||||
subtitle={
|
||||
'Email clients ignore most CSS. This tool inlines every style rule so your formatting survives any inbox.'
|
||||
}
|
||||
/>
|
||||
|
||||
<div className={'mt-20 grid gap-10 sm:grid-cols-3 sm:gap-16'}>
|
||||
{[
|
||||
{
|
||||
tag: 'Step 1',
|
||||
big: 'Write',
|
||||
title: 'Format your content',
|
||||
body: 'Use the visual editor to format text, add headings, lists, and links — just like a word processor.',
|
||||
},
|
||||
{
|
||||
tag: 'Step 2',
|
||||
big: 'Convert',
|
||||
title: 'Styles get inlined',
|
||||
body: 'Every CSS rule is moved inline so email clients like Outlook, Gmail, and Apple Mail render it correctly.',
|
||||
},
|
||||
{
|
||||
tag: 'Step 3',
|
||||
big: 'Copy',
|
||||
title: 'Drop it in your send',
|
||||
body: 'Copy the output HTML and paste it into any email service, SMTP template, or API payload.',
|
||||
},
|
||||
].map((item, i) => (
|
||||
<motion.div
|
||||
key={item.tag}
|
||||
initial={{opacity: 0, y: 16}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.6, delay: i * 0.1, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'flex flex-col gap-6'}
|
||||
>
|
||||
<span
|
||||
style={{fontFamily: 'var(--font-mono)'}}
|
||||
className={'text-[11px] uppercase tracking-[0.2em] text-neutral-500'}
|
||||
>
|
||||
/ {item.tag}
|
||||
</span>
|
||||
<div
|
||||
style={{fontFamily: 'var(--font-display)'}}
|
||||
className={'text-5xl font-extrabold tracking-[-0.035em] text-neutral-900 sm:text-6xl'}
|
||||
>
|
||||
{item.big}
|
||||
</div>
|
||||
<div className={'h-px w-full bg-neutral-300'} />
|
||||
<h3
|
||||
style={{fontFamily: 'var(--font-display)'}}
|
||||
className={'text-xl font-semibold text-neutral-900'}
|
||||
>
|
||||
{item.title}
|
||||
</h3>
|
||||
<p className={'text-base leading-relaxed text-neutral-600'}>{item.body}</p>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* ========== CTA ========== */}
|
||||
<section className={'relative overflow-hidden border-t border-neutral-900 bg-neutral-900 text-white'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-32 sm:px-10 sm:py-40'}>
|
||||
<div className={'flex flex-col items-start gap-12 lg:flex-row lg:items-end lg:justify-between'}>
|
||||
<motion.h2
|
||||
initial={{opacity: 0, y: 16}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.9, ease: [0.22, 1, 0.36, 1]}}
|
||||
style={{fontFamily: 'var(--font-display)'}}
|
||||
className={'text-[clamp(2.5rem,7vw,6rem)] font-extrabold leading-[0.95] tracking-[-0.035em]'}
|
||||
>
|
||||
Ready to send great emails?
|
||||
</motion.h2>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 16}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.9, delay: 0.15, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'flex max-w-md flex-col gap-6'}
|
||||
>
|
||||
<p className={'text-base text-neutral-300 sm:text-lg'}>
|
||||
Plunk handles everything: templates, sending, tracking, and deliverability. Start free, no credit card required.
|
||||
</p>
|
||||
<div className={'flex flex-wrap gap-3'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.015}}
|
||||
whileTap={{scale: 0.985}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
className={
|
||||
'inline-flex items-center gap-2 rounded-full bg-white px-7 py-3.5 text-sm font-semibold text-neutral-900 transition hover:bg-neutral-100'
|
||||
}
|
||||
>
|
||||
Start with Plunk
|
||||
<ArrowRight className={'h-4 w-4'} />
|
||||
</motion.a>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<Footer />
|
||||
</>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {Footer, Navbar} from '../../components';
|
||||
import {Footer, Navbar, SectionHeader} from '../../components';
|
||||
import {motion} from 'framer-motion';
|
||||
import {DASHBOARD_URI} from '../../lib/constants';
|
||||
import React, {useState} from 'react';
|
||||
@@ -9,6 +9,28 @@ import {verifyEmail} from '../../lib/emailVerification';
|
||||
import {EmailVerificationResult} from '../../components/tools/EmailVerificationResult';
|
||||
import {Button, Input} from '@plunk/ui';
|
||||
import {EMAIL_VERIFICATION_FEATURES} from '../../lib/toolsContent';
|
||||
import {Bricolage_Grotesque, Hanken_Grotesk, JetBrains_Mono} from 'next/font/google';
|
||||
|
||||
const display = Bricolage_Grotesque({
|
||||
subsets: ['latin'],
|
||||
variable: '--font-display',
|
||||
display: 'swap',
|
||||
weight: ['400', '500', '600', '700', '800'],
|
||||
});
|
||||
|
||||
const body = Hanken_Grotesk({
|
||||
subsets: ['latin'],
|
||||
variable: '--font-body',
|
||||
display: 'swap',
|
||||
weight: ['400', '500', '600', '700'],
|
||||
});
|
||||
|
||||
const mono = JetBrains_Mono({
|
||||
subsets: ['latin'],
|
||||
variable: '--font-mono',
|
||||
display: 'swap',
|
||||
weight: ['400', '500'],
|
||||
});
|
||||
|
||||
export default function VerifyEmailPage() {
|
||||
const [email, setEmail] = useState('');
|
||||
@@ -48,184 +70,218 @@ export default function VerifyEmailPage() {
|
||||
|
||||
<Navbar />
|
||||
|
||||
<main className={'mx-auto max-w-7xl px-8 sm:px-0'}>
|
||||
{/* Hero Section */}
|
||||
<section className={'relative py-32 sm:py-48'}>
|
||||
<div
|
||||
className={
|
||||
'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#e5e7eb_1px,transparent_1px),linear-gradient(to_bottom,#e5e7eb_1px,transparent_1px)] bg-[size:4rem_4rem] [mask-image:radial-gradient(ellipse_80%_50%_at_50%_0%,#000_70%,transparent_110%)]'
|
||||
}
|
||||
/>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
animate={{opacity: 1, y: 0}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mx-auto max-w-4xl text-center'}
|
||||
>
|
||||
<div className={`${display.variable} ${body.variable} ${mono.variable}`}>
|
||||
<main className={'text-neutral-800'}>
|
||||
{/* ========== HERO ========== */}
|
||||
<section className={'relative overflow-hidden'}>
|
||||
<div
|
||||
aria-hidden
|
||||
className={
|
||||
'mb-6 inline-flex items-center gap-2 rounded-full border border-neutral-200 bg-white px-4 py-2'
|
||||
'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#eeeeee_1px,transparent_1px),linear-gradient(to_bottom,#eeeeee_1px,transparent_1px)] bg-[size:6rem_6rem] [mask-image:radial-gradient(ellipse_70%_60%_at_50%_30%,#000_40%,transparent_95%)]'
|
||||
}
|
||||
>
|
||||
<Search className="h-4 w-4 text-neutral-600" />
|
||||
<span className={'text-sm text-neutral-600'}>Free Tool</span>
|
||||
</div>
|
||||
/>
|
||||
|
||||
<h1 className={'text-6xl font-bold tracking-tight text-neutral-900 sm:text-7xl lg:text-8xl text-balance'}>
|
||||
Email Verification
|
||||
<br />
|
||||
Tool
|
||||
</h1>
|
||||
|
||||
<p className={'mx-auto mt-8 max-w-2xl text-xl text-neutral-600'}>
|
||||
Verify email addresses instantly. Check for typos, disposable domains, DNS configuration, and more. Get
|
||||
detailed verification results in seconds.
|
||||
</p>
|
||||
</motion.div>
|
||||
</section>
|
||||
|
||||
{/* Verification Tool Section */}
|
||||
<section className={'pb-16'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mx-auto max-w-2xl'}
|
||||
>
|
||||
{/* Input Form */}
|
||||
<div className="rounded-lg border border-neutral-200 bg-white p-8 shadow-lg">
|
||||
<form onSubmit={handleVerify} className="space-y-4">
|
||||
<div>
|
||||
<label htmlFor="email" className="block text-sm font-medium text-neutral-900 mb-2">
|
||||
Email Address
|
||||
</label>
|
||||
<Input
|
||||
id="email"
|
||||
type="email"
|
||||
value={email}
|
||||
onChange={e => setEmail(e.target.value)}
|
||||
placeholder="user@example.com"
|
||||
required
|
||||
disabled={loading}
|
||||
className="w-full"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Button type="submit" disabled={loading || !email} className="w-full gap-2">
|
||||
{loading ? (
|
||||
<>
|
||||
<Loader2 className="h-4 w-4 animate-spin" />
|
||||
Verifying...
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<CheckCircle className="h-4 w-4" />
|
||||
Verify Email
|
||||
</>
|
||||
)}
|
||||
</Button>
|
||||
</form>
|
||||
|
||||
{/* Error Display */}
|
||||
{error && (
|
||||
<div className="mt-4 rounded-lg border border-red-200 bg-red-50 p-4">
|
||||
<p className="text-sm text-red-700">{error}</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Results Display */}
|
||||
{result && (
|
||||
<div className={'mx-auto max-w-[88rem] px-6 pb-24 pt-20 sm:px-10 sm:pt-28 lg:pb-36'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
initial={{opacity: 0, y: 8}}
|
||||
animate={{opacity: 1, y: 0}}
|
||||
transition={{duration: 0.5}}
|
||||
className="mt-8"
|
||||
>
|
||||
<EmailVerificationResult result={result} />
|
||||
</motion.div>
|
||||
)}
|
||||
</motion.div>
|
||||
</section>
|
||||
|
||||
{/* Educational Content */}
|
||||
<section className={'border-t border-neutral-200 py-32'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-16 text-center'}
|
||||
>
|
||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>Why verify email addresses?</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>
|
||||
Email verification helps improve deliverability and protect your sender reputation.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<div className={'grid gap-6 sm:grid-cols-2 lg:grid-cols-3'}>
|
||||
{EMAIL_VERIFICATION_FEATURES.map((feature, index) => {
|
||||
const Icon = feature.icon;
|
||||
return (
|
||||
<motion.div
|
||||
key={feature.title}
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: index * 0.05, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={
|
||||
'group block h-full rounded-2xl border border-neutral-200 bg-white p-8 transition hover:border-neutral-300 hover:shadow-lg'
|
||||
}
|
||||
>
|
||||
<div
|
||||
className={'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white mb-4'}
|
||||
>
|
||||
<Icon className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'text-xl font-semibold text-neutral-900 mb-2'}>{feature.title}</h3>
|
||||
<p className={'text-sm text-neutral-600 leading-relaxed'}>{feature.description}</p>
|
||||
</motion.div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* CTA Section */}
|
||||
<section className={'border-t border-neutral-200 py-32'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mx-auto max-w-3xl text-center'}
|
||||
>
|
||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>
|
||||
Ready for production-grade email verification?
|
||||
</h2>
|
||||
<p className={'mt-6 text-lg text-neutral-600'}>
|
||||
This tool is great for testing individual emails, but Plunk offers bulk verification, real-time
|
||||
validation, and seamless integration with your email workflows. Start free, no credit card required.
|
||||
</p>
|
||||
<div className={'mt-12 flex flex-wrap justify-center gap-4'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.02}}
|
||||
whileTap={{scale: 0.98}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
transition={{duration: 0.5, ease: [0.22, 1, 0.36, 1]}}
|
||||
style={{fontFamily: 'var(--font-mono)'}}
|
||||
className={
|
||||
'group rounded-lg bg-neutral-900 px-8 py-4 text-base font-semibold text-white transition hover:bg-neutral-800'
|
||||
'mb-16 flex items-center justify-between border-t border-neutral-900/90 pt-4 text-[11px] uppercase tracking-[0.18em] text-neutral-700 sm:mb-24'
|
||||
}
|
||||
>
|
||||
<span className={'flex items-center gap-2'}>
|
||||
Start with Plunk
|
||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-1" />
|
||||
</span>
|
||||
</motion.a>
|
||||
<span className={'font-medium text-neutral-900'}>§ T-02 — Tool</span>
|
||||
<a href="/tools" className={'text-neutral-500 transition hover:text-neutral-900'}>
|
||||
← All tools
|
||||
</a>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 16}}
|
||||
animate={{opacity: 1, y: 0}}
|
||||
transition={{duration: 0.9, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mx-auto max-w-5xl text-center'}
|
||||
>
|
||||
<h1
|
||||
style={{fontFamily: 'var(--font-display)'}}
|
||||
className={
|
||||
'text-[clamp(2.5rem,7vw,6.5rem)] font-extrabold leading-[0.92] tracking-[-0.04em] text-neutral-900'
|
||||
}
|
||||
>
|
||||
Email address
|
||||
<br />
|
||||
verification
|
||||
</h1>
|
||||
<p className={'mx-auto mt-8 max-w-2xl text-lg leading-relaxed text-neutral-600 sm:text-xl'}>
|
||||
Check for typos, disposable domains, DNS configuration, and MX records. Detailed results in seconds.
|
||||
</p>
|
||||
</motion.div>
|
||||
</div>
|
||||
</motion.div>
|
||||
</section>
|
||||
</main>
|
||||
</section>
|
||||
|
||||
{/* ========== VERIFICATION TOOL ========== */}
|
||||
<section className={'mx-auto max-w-[88rem] px-6 py-16 sm:px-10 sm:py-20'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mx-auto max-w-2xl'}
|
||||
>
|
||||
<div className={'overflow-hidden rounded-[20px] border border-neutral-200 bg-white'}>
|
||||
<div className={'border-b border-neutral-200 px-8 py-5'}>
|
||||
<div className={'flex items-center gap-3'}>
|
||||
<Search className={'h-4 w-4 text-neutral-500'} strokeWidth={1.5} />
|
||||
<span
|
||||
style={{fontFamily: 'var(--font-mono)'}}
|
||||
className={'text-[11px] uppercase tracking-[0.18em] text-neutral-500'}
|
||||
>
|
||||
Verify an address
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form onSubmit={handleVerify} className={'space-y-4 p-8'}>
|
||||
<div>
|
||||
<label htmlFor="email" className={'mb-2 block text-sm font-medium text-neutral-900'}>
|
||||
Email address
|
||||
</label>
|
||||
<Input
|
||||
id="email"
|
||||
type="email"
|
||||
value={email}
|
||||
onChange={e => setEmail(e.target.value)}
|
||||
placeholder="user@example.com"
|
||||
required
|
||||
disabled={loading}
|
||||
className={'w-full'}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Button type="submit" disabled={loading || !email} className={'w-full gap-2'}>
|
||||
{loading ? (
|
||||
<>
|
||||
<Loader2 className={'h-4 w-4 animate-spin'} />
|
||||
Verifying…
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<CheckCircle className={'h-4 w-4'} />
|
||||
Verify email
|
||||
</>
|
||||
)}
|
||||
</Button>
|
||||
</form>
|
||||
|
||||
{error && (
|
||||
<div className={'mx-8 mb-8 rounded-lg border border-red-200 bg-red-50 p-4'}>
|
||||
<p className={'text-sm text-red-700'}>{error}</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{result && (
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 16}}
|
||||
animate={{opacity: 1, y: 0}}
|
||||
transition={{duration: 0.5, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mt-6'}
|
||||
>
|
||||
<EmailVerificationResult result={result} />
|
||||
</motion.div>
|
||||
)}
|
||||
</motion.div>
|
||||
</section>
|
||||
|
||||
{/* ========== WHY VERIFY ========== */}
|
||||
<section className={'border-t border-neutral-200 bg-neutral-50/60'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-28 sm:px-10 sm:py-36'}>
|
||||
<SectionHeader
|
||||
number={'01'}
|
||||
label={'Why verify'}
|
||||
title={'Protect your'}
|
||||
titleAccent={'sender reputation.'}
|
||||
subtitle={'Invalid addresses hurt deliverability. Verification keeps your list clean before you send.'}
|
||||
/>
|
||||
|
||||
<div className={'mt-20 grid gap-4 sm:grid-cols-2 lg:grid-cols-3'}>
|
||||
{EMAIL_VERIFICATION_FEATURES.map((feature, index) => {
|
||||
const Icon = feature.icon;
|
||||
return (
|
||||
<motion.div
|
||||
key={feature.title}
|
||||
initial={{opacity: 0, y: 16}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: index * 0.05, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={
|
||||
'flex min-h-[14rem] flex-col justify-between rounded-[28px] border border-neutral-200 bg-white p-8 transition hover:border-neutral-900'
|
||||
}
|
||||
>
|
||||
<div className={'text-neutral-900'}>
|
||||
<Icon className={'h-6 w-6'} strokeWidth={1.5} />
|
||||
</div>
|
||||
<div>
|
||||
<h3
|
||||
style={{fontFamily: 'var(--font-display)'}}
|
||||
className={'mt-10 text-xl font-bold tracking-[-0.02em] text-neutral-900'}
|
||||
>
|
||||
{feature.title}
|
||||
</h3>
|
||||
<p className={'mt-2 text-sm leading-relaxed text-neutral-600'}>{feature.description}</p>
|
||||
</div>
|
||||
</motion.div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* ========== CTA ========== */}
|
||||
<section className={'relative overflow-hidden border-t border-neutral-900 bg-neutral-900 text-white'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-32 sm:px-10 sm:py-40'}>
|
||||
<div className={'flex flex-col items-start gap-12 lg:flex-row lg:items-end lg:justify-between'}>
|
||||
<motion.h2
|
||||
initial={{opacity: 0, y: 16}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.9, ease: [0.22, 1, 0.36, 1]}}
|
||||
style={{fontFamily: 'var(--font-display)'}}
|
||||
className={'text-[clamp(2.5rem,7vw,6rem)] font-extrabold leading-[0.95] tracking-[-0.035em]'}
|
||||
>
|
||||
Ready for production-grade verification?
|
||||
</motion.h2>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 16}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.9, delay: 0.15, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'flex max-w-md flex-col gap-6'}
|
||||
>
|
||||
<p className={'text-base text-neutral-300 sm:text-lg'}>
|
||||
Bulk verification, real-time validation, and seamless integration with your email workflows. Start free, no credit card required.
|
||||
</p>
|
||||
<div className={'flex flex-wrap gap-3'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.015}}
|
||||
whileTap={{scale: 0.985}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
className={
|
||||
'inline-flex items-center gap-2 rounded-full bg-white px-7 py-3.5 text-sm font-semibold text-neutral-900 transition hover:bg-neutral-100'
|
||||
}
|
||||
>
|
||||
Start with Plunk
|
||||
<ArrowRight className={'h-4 w-4'} />
|
||||
</motion.a>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<Footer />
|
||||
</>
|
||||
|
||||
@@ -4,7 +4,7 @@ import {DASHBOARD_URI, WIKI_URI} from '../../lib/constants';
|
||||
import React from 'react';
|
||||
import Link from 'next/link';
|
||||
import {NextSeo} from 'next-seo';
|
||||
import {ArrowRight, Code2, DollarSign, Globe, PackageOpen, Workflow, Zap} from 'lucide-react';
|
||||
import {ArrowRight, Check, Code2, DollarSign, Globe, PackageOpen, Workflow, Zap} from 'lucide-react';
|
||||
import type {ComparisonRow} from '../../components/ComparisonTable';
|
||||
import type {FAQ} from '../../components/FAQSection';
|
||||
|
||||
@@ -49,9 +49,6 @@ const faqs: FAQ[] = [
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
* Plunk vs ActiveCampaign comparison page
|
||||
*/
|
||||
export default function ActiveCampaignComparison() {
|
||||
return (
|
||||
<>
|
||||
@@ -70,367 +67,132 @@ export default function ActiveCampaignComparison() {
|
||||
|
||||
<Navbar />
|
||||
|
||||
<main className={'mx-auto max-w-7xl px-8 sm:px-0'}>
|
||||
{/* Hero Section */}
|
||||
<section className={'relative py-32 sm:py-48'}>
|
||||
<div
|
||||
className={
|
||||
'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#e5e7eb_1px,transparent_1px),linear-gradient(to_bottom,#e5e7eb_1px,transparent_1px)] bg-[size:4rem_4rem] [mask-image:radial-gradient(ellipse_80%_50%_at_50%_0%,#000_70%,transparent_110%)]'
|
||||
}
|
||||
/>
|
||||
<main className={'text-neutral-800'}>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
animate={{opacity: 1, y: 0}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mx-auto max-w-4xl text-center'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'mb-6 inline-flex items-center gap-2 rounded-full border border-neutral-200 bg-white px-4 py-2'
|
||||
}
|
||||
>
|
||||
<span className={'text-sm text-neutral-600'}>Comparing</span>
|
||||
<span className={'text-sm font-semibold text-neutral-900'}>Plunk vs ActiveCampaign</span>
|
||||
</div>
|
||||
|
||||
<h1 className={'text-6xl font-bold tracking-tight text-neutral-900 sm:text-7xl lg:text-8xl text-balance'}>
|
||||
Open-source alternative
|
||||
<br />
|
||||
for ActiveCampaign
|
||||
</h1>
|
||||
|
||||
<p className={'mx-auto mt-8 max-w-2xl text-xl text-neutral-600'}>
|
||||
ActiveCampaign is powerful but expensive and complex. Plunk delivers essential email automation without
|
||||
CRM bloat, sales features, or enterprise pricing. Built for developers, not marketing departments.
|
||||
</p>
|
||||
|
||||
<div className={'mt-12 flex flex-wrap justify-center gap-4'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.02}}
|
||||
whileTap={{scale: 0.98}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
className={
|
||||
'group rounded-lg bg-neutral-900 px-8 py-4 text-base font-semibold text-white shadow-lg shadow-neutral-900/10 transition hover:bg-neutral-800'
|
||||
}
|
||||
>
|
||||
<span className={'flex items-center gap-2'}>
|
||||
Get started free
|
||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-1" />
|
||||
</span>
|
||||
</motion.a>
|
||||
<Link
|
||||
href={WIKI_URI}
|
||||
target={'_blank'}
|
||||
className={
|
||||
'rounded-lg border border-neutral-300 bg-white px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-400'
|
||||
}
|
||||
>
|
||||
View documentation
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
</section>
|
||||
|
||||
{/* Pricing Model Comparison */}
|
||||
<section className={'py-32'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-16 text-center'}
|
||||
>
|
||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>
|
||||
Enterprise Features Without Enterprise Prices
|
||||
</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Email automation that doesn't break the bank</p>
|
||||
</motion.div>
|
||||
|
||||
<div className={'grid gap-8 lg:grid-cols-2'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, x: -20}}
|
||||
whileInView={{opacity: 1, x: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'rounded-2xl border-2 border-neutral-900 bg-white p-10'}
|
||||
>
|
||||
<div className={'mb-4 inline-flex items-center gap-2 rounded-full bg-neutral-900 px-4 py-1.5'}>
|
||||
<span className={'text-sm font-semibold text-white'}>Plunk</span>
|
||||
{/* Hero */}
|
||||
<section className={'relative overflow-hidden'}>
|
||||
<div aria-hidden className={'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#eeeeee_1px,transparent_1px),linear-gradient(to_bottom,#eeeeee_1px,transparent_1px)] bg-[size:6rem_6rem] [mask-image:radial-gradient(ellipse_70%_60%_at_50%_30%,#000_40%,transparent_95%)]'} />
|
||||
<div className={'mx-auto max-w-[88rem] px-6 pb-20 pt-20 sm:px-10 sm:pt-28 sm:pb-28'}>
|
||||
<motion.div initial={{opacity: 0, y: 16}} animate={{opacity: 1, y: 0}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}>
|
||||
<div style={{fontFamily: 'var(--font-mono)'}} className={'mb-6 text-[11px] uppercase tracking-[0.18em] text-neutral-500'}>
|
||||
Plunk vs ActiveCampaign
|
||||
</div>
|
||||
<h3 className={'mt-6 text-2xl font-bold text-neutral-900'}>Simple pay-as-you-go</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Only pay for emails sent. All features included, no tier gating, no forced upgrades.
|
||||
</p>
|
||||
<div className={'mt-6 text-4xl font-bold text-neutral-900'}>Pay-as-you-go</div>
|
||||
<div className={'mt-8 space-y-3'}>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-900 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-white'} />
|
||||
</div>
|
||||
<span>All automation features included</span>
|
||||
</div>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-900 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-white'} />
|
||||
</div>
|
||||
<span>No monthly minimums or contracts</span>
|
||||
</div>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-900 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-white'} />
|
||||
</div>
|
||||
<span>Typical savings: 50-80% vs ActiveCampaign</span>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, x: 20}}
|
||||
whileInView={{opacity: 1, x: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'rounded-2xl border border-neutral-200 bg-neutral-50 p-10'}
|
||||
>
|
||||
<div className={'mb-4 inline-flex items-center gap-2 rounded-full bg-neutral-200 px-4 py-1.5'}>
|
||||
<span className={'text-sm font-semibold text-neutral-900'}>ActiveCampaign</span>
|
||||
</div>
|
||||
<h3 className={'mt-6 text-2xl font-bold text-neutral-900'}>Expensive subscription tiers</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Complex pricing with feature gating. Automation requires higher tiers.
|
||||
</p>
|
||||
<div className={'mt-6 text-4xl font-bold text-neutral-900'}>From $29/month</div>
|
||||
<div className={'mt-8 space-y-3'}>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-300 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-neutral-600'} />
|
||||
</div>
|
||||
<span>Advanced automation: $149+/month</span>
|
||||
</div>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-300 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-neutral-600'} />
|
||||
</div>
|
||||
<span>Feature limits on lower tiers</span>
|
||||
</div>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-300 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-neutral-600'} />
|
||||
</div>
|
||||
<span>Includes CRM/sales features you may not need</span>
|
||||
</div>
|
||||
<h1 style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2.75rem,7vw,6.5rem)] font-extrabold leading-[0.92] tracking-[-0.04em] text-neutral-900'}>
|
||||
Open-source alternative
|
||||
<br />
|
||||
for ActiveCampaign
|
||||
</h1>
|
||||
<p className={'mt-6 max-w-2xl text-xl text-neutral-600'}>ActiveCampaign is powerful but expensive and complex. Plunk delivers essential email automation without CRM bloat, sales features, or enterprise pricing. Built for developers, not marketing departments.</p>
|
||||
<div className={'mt-10 flex flex-wrap gap-3'}>
|
||||
<motion.a whileHover={{scale: 1.015}} whileTap={{scale: 0.985}} href={`${DASHBOARD_URI}/auth/signup`} className={'group inline-flex items-center gap-2 rounded-full bg-neutral-900 px-8 py-4 text-base font-semibold text-white shadow-[0_10px_30px_-10px_rgba(23,23,23,0.35)] transition hover:bg-neutral-800'}>
|
||||
Get started free <ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-0.5" />
|
||||
</motion.a>
|
||||
<Link href={WIKI_URI} target={'_blank'} className={'inline-flex items-center gap-2 rounded-full border border-neutral-300 bg-white px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-900'}>
|
||||
View documentation
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Key Advantages */}
|
||||
<section className={'py-32'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-20 text-center'}
|
||||
>
|
||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>Automation Without Complexity</h2>
|
||||
</motion.div>
|
||||
|
||||
<div className={'grid gap-px bg-neutral-200 sm:grid-cols-2 lg:grid-cols-3'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.1, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<DollarSign className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Affordable Pricing</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Pay-as-you-go with all features included. No expensive tier upgrades required for automation. Typically
|
||||
50-80% cheaper than ActiveCampaign.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.2, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<Zap className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>5-Minute Setup</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Start sending in minutes. No CRM to configure, no sales pipeline to set up. Just authenticate and build
|
||||
your email workflows.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.3, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<Code2 className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Developer-First</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Clean API designed for developers, not marketing teams. Integrate email into your product without
|
||||
learning complex enterprise software.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.4, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<PackageOpen className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Open Source</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
AGPL-3.0 licensed. Full transparency into how your emails are processed. Contribute features, understand
|
||||
the system. ActiveCampaign is proprietary.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.5, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<Globe className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Self-Hostable</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Deploy on your own infrastructure with Docker. Full data control, compliance-ready, no vendor lock-in.
|
||||
ActiveCampaign is cloud-only.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.6, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<Workflow className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Workflow Automation</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Event-based triggers, segmentation, and automated sequences. All the email automation power of
|
||||
ActiveCampaign without CRM complexity.
|
||||
</p>
|
||||
{/* Pricing comparison */}
|
||||
<section className={'border-t border-neutral-200'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}} className={'mb-16'}>
|
||||
<h2 style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}>
|
||||
Enterprise Features Without Enterprise Prices
|
||||
</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Email automation that doesn't break the bank</p>
|
||||
</motion.div>
|
||||
<div className={'grid gap-4 lg:grid-cols-2'}>
|
||||
<motion.div initial={{opacity: 0, x: -20}} whileInView={{opacity: 1, x: 0}} viewport={{once: true}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}} className={'rounded-[24px] border border-neutral-900 bg-neutral-900 p-10 text-white'}>
|
||||
<div style={{fontFamily: 'var(--font-mono)'}} className={'text-[11px] uppercase tracking-[0.18em] text-neutral-400'}>Plunk</div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-2xl font-bold tracking-[-0.025em] text-white'}>Simple pay-as-you-go</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-300'}>Only pay for emails sent. All features included, no tier gating, no forced upgrades.</p>
|
||||
<div style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-4xl font-extrabold tracking-[-0.03em] text-white'}>Pay-as-you-go</div>
|
||||
<ul className={'mt-8 space-y-3'}>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-300'}><Check className="h-4 w-4 flex-shrink-0 text-neutral-400" />All automation features included</li>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-300'}><Check className="h-4 w-4 flex-shrink-0 text-neutral-400" />No monthly minimums or contracts</li>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-300'}><Check className="h-4 w-4 flex-shrink-0 text-neutral-400" />Typical savings: 50-80% vs ActiveCampaign</li>
|
||||
</ul>
|
||||
</motion.div>
|
||||
<motion.div initial={{opacity: 0, x: 20}} whileInView={{opacity: 1, x: 0}} viewport={{once: true}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}} className={'rounded-[24px] border border-neutral-200 bg-white p-10'}>
|
||||
<div style={{fontFamily: 'var(--font-mono)'}} className={'text-[11px] uppercase tracking-[0.18em] text-neutral-500'}>ActiveCampaign</div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-2xl font-bold tracking-[-0.025em] text-neutral-900'}>Expensive subscription tiers</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>Complex pricing with feature gating. Automation requires higher tiers.</p>
|
||||
<div style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-4xl font-extrabold tracking-[-0.03em] text-neutral-900'}>From $29/month</div>
|
||||
<ul className={'mt-8 space-y-3'}>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-600'}><div className={'h-1.5 w-1.5 flex-shrink-0 rounded-full bg-neutral-400'} />Advanced automation: $149+/month</li>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-600'}><div className={'h-1.5 w-1.5 flex-shrink-0 rounded-full bg-neutral-400'} />Feature limits on lower tiers</li>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-600'}><div className={'h-1.5 w-1.5 flex-shrink-0 rounded-full bg-neutral-400'} />Includes CRM/sales features you may not need</li>
|
||||
</ul>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Feature Comparison */}
|
||||
<section className={'py-32'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-16 text-center'}
|
||||
>
|
||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>Feature Comparison</h2>
|
||||
</motion.div>
|
||||
{/* Key advantages */}
|
||||
<section className={'border-t border-neutral-200 bg-neutral-50/60'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}} className={'mb-16'}>
|
||||
<h2 style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}>Automation Without Complexity</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Powerful email workflows without the enterprise overhead</p>
|
||||
</motion.div>
|
||||
<div className={'grid gap-px bg-neutral-200 sm:grid-cols-2 lg:grid-cols-3'}>
|
||||
{[
|
||||
{icon: <Workflow className="h-5 w-5" />, title: 'Workflow Automation', body: 'Build automated email sequences with triggers, delays, and conditions. No CRM required. Pure email automation that integrates with your product.'},
|
||||
{icon: <Code2 className="h-5 w-5" />, title: 'Developer-First API', body: 'Integrate email into your application with a clean REST API. No complex marketing UI to navigate — just code and send.'},
|
||||
{icon: <DollarSign className="h-5 w-5" />, title: '50-80% Cost Savings', body: 'ActiveCampaign charges $149+/month for automation features. Plunk charges for emails sent only. The savings add up fast.'},
|
||||
{icon: <PackageOpen className="h-5 w-5" />, title: 'Open Source', body: 'AGPL-3.0 licensed. Inspect the code, understand the system, contribute features. No proprietary algorithms or black-box systems.'},
|
||||
{icon: <Globe className="h-5 w-5" />, title: 'Self-Hostable', body: 'Deploy on your own infrastructure with Docker. Full data ownership and compliance control. ActiveCampaign is cloud-only.'},
|
||||
{icon: <Zap className="h-5 w-5" />, title: 'Fast Setup', body: 'Start sending in 5 minutes. Simple authentication, clean API, comprehensive docs. No CRM to configure before you can send your first email.'},
|
||||
].map((item, i) => (
|
||||
<motion.div key={item.title} initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.5, delay: i * 0.1, ease: [0.22, 1, 0.36, 1]}} className={'bg-white p-10'}>
|
||||
<div className={'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white'}>{item.icon}</div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>{item.title}</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>{item.body}</p>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<ComparisonTable competitorName="ActiveCampaign" rows={comparisonData} />
|
||||
{/* Feature comparison table */}
|
||||
<section className={'border-t border-neutral-200'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}} className={'mb-16'}>
|
||||
<h2 style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}>Feature comparison</h2>
|
||||
</motion.div>
|
||||
<ComparisonTable competitorName="ActiveCampaign" rows={comparisonData} />
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* FAQ */}
|
||||
<FAQSection faqs={faqs} schemaId="faq-schema-activecampaign" />
|
||||
|
||||
{/* CTA */}
|
||||
<section className={'relative overflow-hidden border-t border-neutral-200 py-32'}>
|
||||
<div
|
||||
className={
|
||||
'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#e5e7eb_1px,transparent_1px),linear-gradient(to_bottom,#e5e7eb_1px,transparent_1px)] bg-[size:4rem_4rem] [mask-image:radial-gradient(ellipse_80%_50%_at_50%_100%,#000_70%,transparent_110%)]'
|
||||
}
|
||||
/>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mx-auto max-w-3xl text-center'}
|
||||
>
|
||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>
|
||||
Get email automation without the bloat
|
||||
</h2>
|
||||
<p className={'mt-6 text-lg text-neutral-600'}>
|
||||
Join developers choosing focused email automation over enterprise complexity. Start free, no credit card
|
||||
required.
|
||||
</p>
|
||||
<div className={'mt-12 flex flex-wrap justify-center gap-4'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.02}}
|
||||
whileTap={{scale: 0.98}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
className={
|
||||
'group rounded-lg bg-neutral-900 px-8 py-4 text-base font-semibold text-white transition hover:bg-neutral-800'
|
||||
}
|
||||
>
|
||||
<span className={'flex items-center gap-2'}>
|
||||
Get started free
|
||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-1" />
|
||||
</span>
|
||||
</motion.a>
|
||||
<Link
|
||||
href="/pricing"
|
||||
className={
|
||||
'rounded-lg border border-neutral-300 px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-400'
|
||||
}
|
||||
>
|
||||
View pricing
|
||||
</Link>
|
||||
<section className={'relative overflow-hidden border-t border-neutral-900 bg-neutral-900 text-white'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-32 sm:px-10 sm:py-40'}>
|
||||
<div className={'flex flex-col items-start gap-12 lg:flex-row lg:items-end lg:justify-between'}>
|
||||
<motion.h2 initial={{opacity: 0, y: 16}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.9, ease: [0.22, 1, 0.36, 1]}} style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2.5rem,7vw,6rem)] font-extrabold leading-[0.95] tracking-[-0.035em]'}>
|
||||
Email automation, not enterprise complexity.
|
||||
</motion.h2>
|
||||
<motion.div initial={{opacity: 0, y: 16}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.9, delay: 0.15, ease: [0.22, 1, 0.36, 1]}} className={'flex max-w-md flex-col gap-6'}>
|
||||
<p className={'text-base text-neutral-300 sm:text-lg'}>Save 50-80% on email automation. Open-source, self-hostable, pay-as-you-go. Start free.</p>
|
||||
<div className={'flex flex-wrap gap-3'}>
|
||||
<motion.a whileHover={{scale: 1.015}} whileTap={{scale: 0.985}} href={`${DASHBOARD_URI}/auth/signup`} className={'inline-flex items-center gap-2 rounded-full bg-white px-7 py-3.5 text-sm font-semibold text-neutral-900 transition hover:bg-neutral-100'}>
|
||||
Get started free <ArrowRight className="h-4 w-4" />
|
||||
</motion.a>
|
||||
<Link href={'/pricing'} className={'inline-flex items-center gap-2 rounded-full border border-neutral-700 px-7 py-3.5 text-sm font-semibold text-white transition hover:border-white'}>
|
||||
View pricing
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
</main>
|
||||
<Footer />
|
||||
</>
|
||||
);
|
||||
|
||||
+105
-342
@@ -4,7 +4,7 @@ import {DASHBOARD_URI, WIKI_URI} from '../../lib/constants';
|
||||
import React from 'react';
|
||||
import Link from 'next/link';
|
||||
import {NextSeo} from 'next-seo';
|
||||
import {ArrowRight, Code2, DollarSign, Globe, Mail, PackageOpen, Zap} from 'lucide-react';
|
||||
import {ArrowRight, Check, Code2, DollarSign, Globe, PackageOpen, Zap} from 'lucide-react';
|
||||
import type {ComparisonRow} from '../../components/ComparisonTable';
|
||||
import type {FAQ} from '../../components/FAQSection';
|
||||
|
||||
@@ -49,9 +49,6 @@ const faqs: FAQ[] = [
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
* Plunk vs Bento comparison page
|
||||
*/
|
||||
export default function BentoComparison() {
|
||||
return (
|
||||
<>
|
||||
@@ -70,365 +67,131 @@ export default function BentoComparison() {
|
||||
|
||||
<Navbar />
|
||||
|
||||
<main className={'mx-auto max-w-7xl px-8 sm:px-0'}>
|
||||
{/* Hero Section */}
|
||||
<section className={'relative py-32 sm:py-48'}>
|
||||
<div
|
||||
className={
|
||||
'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#e5e7eb_1px,transparent_1px),linear-gradient(to_bottom,#e5e7eb_1px,transparent_1px)] bg-[size:4rem_4rem] [mask-image:radial-gradient(ellipse_80%_50%_at_50%_0%,#000_70%,transparent_110%)]'
|
||||
}
|
||||
/>
|
||||
<main className={'text-neutral-800'}>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
animate={{opacity: 1, y: 0}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mx-auto max-w-4xl text-center'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'mb-6 inline-flex items-center gap-2 rounded-full border border-neutral-200 bg-white px-4 py-2'
|
||||
}
|
||||
>
|
||||
<span className={'text-sm text-neutral-600'}>Comparing</span>
|
||||
<span className={'text-sm font-semibold text-neutral-900'}>Plunk vs Bento</span>
|
||||
</div>
|
||||
|
||||
<h1 className={'text-6xl font-bold tracking-tight text-neutral-900 sm:text-7xl lg:text-8xl text-balance'}>
|
||||
Open-source alternative
|
||||
<br />
|
||||
for Bento
|
||||
</h1>
|
||||
|
||||
<p className={'mx-auto mt-8 max-w-2xl text-xl text-neutral-600'}>
|
||||
Bento is an all-in-one platform. Plunk is focused on email. Get powerful email automation without CRM,
|
||||
live chat, or multi-channel complexity. Developer-first, API-driven, transparent pricing.
|
||||
</p>
|
||||
|
||||
<div className={'mt-12 flex flex-wrap justify-center gap-4'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.02}}
|
||||
whileTap={{scale: 0.98}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
className={
|
||||
'group rounded-lg bg-neutral-900 px-8 py-4 text-base font-semibold text-white shadow-lg shadow-neutral-900/10 transition hover:bg-neutral-800'
|
||||
}
|
||||
>
|
||||
<span className={'flex items-center gap-2'}>
|
||||
Get started free
|
||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-1" />
|
||||
</span>
|
||||
</motion.a>
|
||||
<Link
|
||||
href={WIKI_URI}
|
||||
target={'_blank'}
|
||||
className={
|
||||
'rounded-lg border border-neutral-300 bg-white px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-400'
|
||||
}
|
||||
>
|
||||
View documentation
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
</section>
|
||||
|
||||
{/* Pricing Model Comparison */}
|
||||
<section className={'py-32'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-16 text-center'}
|
||||
>
|
||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>
|
||||
Focused Email vs All-in-One Complexity
|
||||
</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Pay for what you use, not what you don't need</p>
|
||||
</motion.div>
|
||||
|
||||
<div className={'grid gap-8 lg:grid-cols-2'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, x: -20}}
|
||||
whileInView={{opacity: 1, x: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'rounded-2xl border-2 border-neutral-900 bg-white p-10'}
|
||||
>
|
||||
<div className={'mb-4 inline-flex items-center gap-2 rounded-full bg-neutral-900 px-4 py-1.5'}>
|
||||
<span className={'text-sm font-semibold text-white'}>Plunk</span>
|
||||
{/* Hero */}
|
||||
<section className={'relative overflow-hidden'}>
|
||||
<div aria-hidden className={'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#eeeeee_1px,transparent_1px),linear-gradient(to_bottom,#eeeeee_1px,transparent_1px)] bg-[size:6rem_6rem] [mask-image:radial-gradient(ellipse_70%_60%_at_50%_30%,#000_40%,transparent_95%)]'} />
|
||||
<div className={'mx-auto max-w-[88rem] px-6 pb-20 pt-20 sm:px-10 sm:pt-28 sm:pb-28'}>
|
||||
<motion.div initial={{opacity: 0, y: 16}} animate={{opacity: 1, y: 0}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}>
|
||||
<div style={{fontFamily: 'var(--font-mono)'}} className={'mb-6 text-[11px] uppercase tracking-[0.18em] text-neutral-500'}>
|
||||
Plunk vs Bento
|
||||
</div>
|
||||
<h3 className={'mt-6 text-2xl font-bold text-neutral-900'}>Pay per email sent</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Pay-as-you-go for email only. No CRM or chat features you don't need. Simple, transparent pricing.
|
||||
</p>
|
||||
<div className={'mt-6 text-4xl font-bold text-neutral-900'}>Pay-as-you-go</div>
|
||||
<div className={'mt-8 space-y-3'}>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-900 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-white'} />
|
||||
</div>
|
||||
<span>Only pay for emails sent</span>
|
||||
</div>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-900 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-white'} />
|
||||
</div>
|
||||
<span>No monthly commitments</span>
|
||||
</div>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-900 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-white'} />
|
||||
</div>
|
||||
<span>Focus on email, nothing more</span>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, x: 20}}
|
||||
whileInView={{opacity: 1, x: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'rounded-2xl border border-neutral-200 bg-neutral-50 p-10'}
|
||||
>
|
||||
<div className={'mb-4 inline-flex items-center gap-2 rounded-full bg-neutral-200 px-4 py-1.5'}>
|
||||
<span className={'text-sm font-semibold text-neutral-900'}>Bento</span>
|
||||
</div>
|
||||
<h3 className={'mt-6 text-2xl font-bold text-neutral-900'}>Trial then subscription</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
30-day unlimited trial, then subscription pricing. Includes CRM, chat, and multi-channel features.
|
||||
</p>
|
||||
<div className={'mt-6 text-4xl font-bold text-neutral-900'}>30-day trial</div>
|
||||
<div className={'mt-8 space-y-3'}>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-300 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-neutral-600'} />
|
||||
</div>
|
||||
<span>Trial ends, then monthly subscription</span>
|
||||
</div>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-300 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-neutral-600'} />
|
||||
</div>
|
||||
<span>Includes features beyond email</span>
|
||||
</div>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-300 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-neutral-600'} />
|
||||
</div>
|
||||
<span>All-in-one platform approach</span>
|
||||
</div>
|
||||
<h1 style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2.75rem,7vw,6.5rem)] font-extrabold leading-[0.92] tracking-[-0.04em] text-neutral-900'}>
|
||||
Open-source alternative
|
||||
<br />
|
||||
for Bento
|
||||
</h1>
|
||||
<p className={'mt-6 max-w-2xl text-xl text-neutral-600'}>Bento is an all-in-one platform. Plunk is focused on email. Get powerful email automation without CRM, live chat, or multi-channel complexity. Developer-first, API-driven, transparent pricing.</p>
|
||||
<div className={'mt-10 flex flex-wrap gap-3'}>
|
||||
<motion.a whileHover={{scale: 1.015}} whileTap={{scale: 0.985}} href={`${DASHBOARD_URI}/auth/signup`} className={'group inline-flex items-center gap-2 rounded-full bg-neutral-900 px-8 py-4 text-base font-semibold text-white shadow-[0_10px_30px_-10px_rgba(23,23,23,0.35)] transition hover:bg-neutral-800'}>
|
||||
Get started free <ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-0.5" />
|
||||
</motion.a>
|
||||
<Link href={WIKI_URI} target={'_blank'} className={'inline-flex items-center gap-2 rounded-full border border-neutral-300 bg-white px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-900'}>
|
||||
View documentation
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Key Advantages */}
|
||||
<section className={'py-32'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-20 text-center'}
|
||||
>
|
||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>Developer-First Email Platform</h2>
|
||||
</motion.div>
|
||||
|
||||
<div className={'grid gap-px bg-neutral-200 sm:grid-cols-2 lg:grid-cols-3'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.1, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<Code2 className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>API-First Design</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Built for developers who integrate email into their applications. Clean REST API, comprehensive docs,
|
||||
webhook support.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.2, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<PackageOpen className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Open Source</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
AGPL-3.0 licensed. Full code transparency, contribute features, understand the system. Bento is
|
||||
proprietary closed-source.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.3, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<DollarSign className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Pay-as-you-go</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Only pay for emails sent. No subscriptions, no trials that expire, no forced plan upgrades. Predictable
|
||||
costs based on usage.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.4, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<Zap className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Simple Setup</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Start sending in 5 minutes. No CRM to configure, no multi-channel setup, no live chat integration. Just
|
||||
email, done right.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.5, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<Globe className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Self-Hostable</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Deploy on your infrastructure with Docker. Full data control, compliance-ready, no vendor lock-in. Bento
|
||||
is cloud-only.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.6, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<Mail className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Email-Focused</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Do one thing exceptionally well: email. No feature bloat, no CRM complexity, no multi-channel confusion.
|
||||
Just powerful email automation.
|
||||
</p>
|
||||
{/* Pricing comparison */}
|
||||
<section className={'border-t border-neutral-200'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}} className={'mb-16'}>
|
||||
<h2 style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}>
|
||||
Focused Email vs All-in-One Complexity
|
||||
</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Pay for what you use, not what you don't need</p>
|
||||
</motion.div>
|
||||
<div className={'grid gap-4 lg:grid-cols-2'}>
|
||||
<motion.div initial={{opacity: 0, x: -20}} whileInView={{opacity: 1, x: 0}} viewport={{once: true}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}} className={'rounded-[24px] border border-neutral-900 bg-neutral-900 p-10 text-white'}>
|
||||
<div style={{fontFamily: 'var(--font-mono)'}} className={'text-[11px] uppercase tracking-[0.18em] text-neutral-400'}>Plunk</div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-2xl font-bold tracking-[-0.025em] text-white'}>Pay per email sent</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-300'}>Pay-as-you-go for email only. No CRM or chat features you don't need. Simple, transparent pricing.</p>
|
||||
<div style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-4xl font-extrabold tracking-[-0.03em] text-white'}>Pay-as-you-go</div>
|
||||
<ul className={'mt-8 space-y-3'}>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-300'}><Check className="h-4 w-4 flex-shrink-0 text-neutral-400" />Only pay for emails sent</li>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-300'}><Check className="h-4 w-4 flex-shrink-0 text-neutral-400" />No monthly commitments</li>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-300'}><Check className="h-4 w-4 flex-shrink-0 text-neutral-400" />Focus on email, nothing more</li>
|
||||
</ul>
|
||||
</motion.div>
|
||||
<motion.div initial={{opacity: 0, x: 20}} whileInView={{opacity: 1, x: 0}} viewport={{once: true}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}} className={'rounded-[24px] border border-neutral-200 bg-white p-10'}>
|
||||
<div style={{fontFamily: 'var(--font-mono)'}} className={'text-[11px] uppercase tracking-[0.18em] text-neutral-500'}>Bento</div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-2xl font-bold tracking-[-0.025em] text-neutral-900'}>Trial then subscription</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>30-day unlimited trial, then subscription pricing. Includes CRM, chat, and multi-channel features.</p>
|
||||
<div style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-4xl font-extrabold tracking-[-0.03em] text-neutral-900'}>30-day trial</div>
|
||||
<ul className={'mt-8 space-y-3'}>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-600'}><div className={'h-1.5 w-1.5 flex-shrink-0 rounded-full bg-neutral-400'} />Trial ends, then monthly subscription</li>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-600'}><div className={'h-1.5 w-1.5 flex-shrink-0 rounded-full bg-neutral-400'} />Includes features beyond email</li>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-600'}><div className={'h-1.5 w-1.5 flex-shrink-0 rounded-full bg-neutral-400'} />All-in-one platform approach</li>
|
||||
</ul>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Feature Comparison */}
|
||||
<section className={'py-32'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-16 text-center'}
|
||||
>
|
||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>Feature Comparison</h2>
|
||||
</motion.div>
|
||||
{/* Key advantages */}
|
||||
<section className={'border-t border-neutral-200 bg-neutral-50/60'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}} className={'mb-16'}>
|
||||
<h2 style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}>Developer-First Email Platform</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Everything you need for email, nothing you don't</p>
|
||||
</motion.div>
|
||||
<div className={'grid gap-px bg-neutral-200 sm:grid-cols-2 lg:grid-cols-3'}>
|
||||
{[
|
||||
{icon: <Code2 className="h-5 w-5" />, title: 'API-First Design', body: 'Built for developers who integrate email into their applications. Clean REST API, comprehensive docs, webhook support.'},
|
||||
{icon: <PackageOpen className="h-5 w-5" />, title: 'Open Source', body: 'AGPL-3.0 licensed. Full code transparency, contribute features, understand the system. Bento is proprietary closed-source.'},
|
||||
{icon: <DollarSign className="h-5 w-5" />, title: 'Pay-as-you-go', body: 'Only pay for emails sent. No subscriptions, no trials that expire, no forced plan upgrades. Predictable costs based on usage.'},
|
||||
{icon: <Zap className="h-5 w-5" />, title: 'Simple Setup', body: 'Start sending in 5 minutes. No CRM to configure, no multi-channel setup, no live chat integration. Just email, done right.'},
|
||||
{icon: <Globe className="h-5 w-5" />, title: 'Self-Hostable', body: 'Deploy on your infrastructure with Docker. Full data ownership, compliance control, no vendor lock-in. Bento is cloud-only.'},
|
||||
].map((item, i) => (
|
||||
<motion.div key={item.title} initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.5, delay: i * 0.1, ease: [0.22, 1, 0.36, 1]}} className={'bg-white p-10'}>
|
||||
<div className={'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white'}>{item.icon}</div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>{item.title}</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>{item.body}</p>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<ComparisonTable competitorName="Bento" rows={comparisonData} />
|
||||
{/* Feature comparison table */}
|
||||
<section className={'border-t border-neutral-200'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}} className={'mb-16'}>
|
||||
<h2 style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}>Feature comparison</h2>
|
||||
</motion.div>
|
||||
<ComparisonTable competitorName="Bento" rows={comparisonData} />
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* FAQ */}
|
||||
<FAQSection faqs={faqs} schemaId="faq-schema-bento" />
|
||||
|
||||
{/* CTA */}
|
||||
<section className={'relative overflow-hidden border-t border-neutral-200 py-32'}>
|
||||
<div
|
||||
className={
|
||||
'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#e5e7eb_1px,transparent_1px),linear-gradient(to_bottom,#e5e7eb_1px,transparent_1px)] bg-[size:4rem_4rem] [mask-image:radial-gradient(ellipse_80%_50%_at_50%_100%,#000_70%,transparent_110%)]'
|
||||
}
|
||||
/>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mx-auto max-w-3xl text-center'}
|
||||
>
|
||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>Get focused email automation</h2>
|
||||
<p className={'mt-6 text-lg text-neutral-600'}>
|
||||
Join developers choosing focused email solutions over all-in-one complexity. Start free, no credit card
|
||||
required.
|
||||
</p>
|
||||
<div className={'mt-12 flex flex-wrap justify-center gap-4'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.02}}
|
||||
whileTap={{scale: 0.98}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
className={
|
||||
'group rounded-lg bg-neutral-900 px-8 py-4 text-base font-semibold text-white transition hover:bg-neutral-800'
|
||||
}
|
||||
>
|
||||
<span className={'flex items-center gap-2'}>
|
||||
Get started free
|
||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-1" />
|
||||
</span>
|
||||
</motion.a>
|
||||
<Link
|
||||
href="/pricing"
|
||||
className={
|
||||
'rounded-lg border border-neutral-300 px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-400'
|
||||
}
|
||||
>
|
||||
View pricing
|
||||
</Link>
|
||||
<section className={'relative overflow-hidden border-t border-neutral-900 bg-neutral-900 text-white'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-32 sm:px-10 sm:py-40'}>
|
||||
<div className={'flex flex-col items-start gap-12 lg:flex-row lg:items-end lg:justify-between'}>
|
||||
<motion.h2 initial={{opacity: 0, y: 16}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.9, ease: [0.22, 1, 0.36, 1]}} style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2.5rem,7vw,6rem)] font-extrabold leading-[0.95] tracking-[-0.035em]'}>
|
||||
Focused email. No bloat.
|
||||
</motion.h2>
|
||||
<motion.div initial={{opacity: 0, y: 16}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.9, delay: 0.15, ease: [0.22, 1, 0.36, 1]}} className={'flex max-w-md flex-col gap-6'}>
|
||||
<p className={'text-base text-neutral-300 sm:text-lg'}>API-first email without CRM complexity. Open-source, self-hostable, pay-as-you-go. Start free.</p>
|
||||
<div className={'flex flex-wrap gap-3'}>
|
||||
<motion.a whileHover={{scale: 1.015}} whileTap={{scale: 0.985}} href={`${DASHBOARD_URI}/auth/signup`} className={'inline-flex items-center gap-2 rounded-full bg-white px-7 py-3.5 text-sm font-semibold text-neutral-900 transition hover:bg-neutral-100'}>
|
||||
Get started free <ArrowRight className="h-4 w-4" />
|
||||
</motion.a>
|
||||
<Link href={'/pricing'} className={'inline-flex items-center gap-2 rounded-full border border-neutral-700 px-7 py-3.5 text-sm font-semibold text-white transition hover:border-white'}>
|
||||
View pricing
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
</main>
|
||||
<Footer />
|
||||
</>
|
||||
);
|
||||
|
||||
+127
-338
@@ -4,7 +4,7 @@ import {DASHBOARD_URI, WIKI_URI} from '../../lib/constants';
|
||||
import React from 'react';
|
||||
import Link from 'next/link';
|
||||
import {NextSeo} from 'next-seo';
|
||||
import {ArrowRight, BarChart3, DollarSign, Globe, PackageOpen, Users, Zap} from 'lucide-react';
|
||||
import {ArrowRight, BarChart3, Check, DollarSign, Globe, PackageOpen, Users, Zap} from 'lucide-react';
|
||||
import type {ComparisonRow} from '../../components/ComparisonTable';
|
||||
import type {FAQ} from '../../components/FAQSection';
|
||||
|
||||
@@ -69,364 +69,153 @@ export default function BrevoComparison() {
|
||||
|
||||
<Navbar />
|
||||
|
||||
<main className={'mx-auto max-w-7xl px-8 sm:px-0'}>
|
||||
{/* Hero Section */}
|
||||
<section className={'relative py-32 sm:py-48'}>
|
||||
<div
|
||||
className={
|
||||
'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#e5e7eb_1px,transparent_1px),linear-gradient(to_bottom,#e5e7eb_1px,transparent_1px)] bg-[size:4rem_4rem] [mask-image:radial-gradient(ellipse_80%_50%_at_50%_0%,#000_70%,transparent_110%)]'
|
||||
}
|
||||
/>
|
||||
<main className={'text-neutral-800'}>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
animate={{opacity: 1, y: 0}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mx-auto max-w-4xl text-center'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'mb-6 inline-flex items-center gap-2 rounded-full border border-neutral-200 bg-white px-4 py-2'
|
||||
}
|
||||
>
|
||||
<span className={'text-sm text-neutral-600'}>Comparing</span>
|
||||
<span className={'text-sm font-semibold text-neutral-900'}>Plunk vs Brevo</span>
|
||||
</div>
|
||||
|
||||
<h1 className={'text-6xl font-bold tracking-tight text-neutral-900 sm:text-7xl lg:text-8xl text-balance'}>
|
||||
Open-source alternative
|
||||
<br />
|
||||
for Brevo
|
||||
</h1>
|
||||
|
||||
<p className={'mx-auto mt-8 max-w-2xl text-xl text-neutral-600'}>
|
||||
Simpler pricing, cleaner API, open-source code. All the email power, none of the bloat. Built for
|
||||
developers, not marketing teams.
|
||||
</p>
|
||||
|
||||
<div className={'mt-12 flex flex-wrap justify-center gap-4'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.02}}
|
||||
whileTap={{scale: 0.98}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
className={
|
||||
'group rounded-lg bg-neutral-900 px-8 py-4 text-base font-semibold text-white shadow-lg shadow-neutral-900/10 transition hover:bg-neutral-800'
|
||||
}
|
||||
>
|
||||
<span className={'flex items-center gap-2'}>
|
||||
Get started free
|
||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-1" />
|
||||
</span>
|
||||
</motion.a>
|
||||
<Link
|
||||
href={WIKI_URI}
|
||||
target={'_blank'}
|
||||
className={
|
||||
'rounded-lg border border-neutral-300 bg-white px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-400'
|
||||
}
|
||||
>
|
||||
View documentation
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
</section>
|
||||
|
||||
{/* Pricing Model Comparison */}
|
||||
<section className={'py-32'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-16 text-center'}
|
||||
>
|
||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>Pricing That Scales With You</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Pay for emails sent, not contacts stored</p>
|
||||
</motion.div>
|
||||
|
||||
<div className={'grid gap-8 lg:grid-cols-2'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, x: -20}}
|
||||
whileInView={{opacity: 1, x: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'rounded-2xl border-2 border-neutral-900 bg-white p-10'}
|
||||
>
|
||||
<div className={'mb-4 inline-flex items-center gap-2 rounded-full bg-neutral-900 px-4 py-1.5'}>
|
||||
<span className={'text-sm font-semibold text-white'}>Plunk</span>
|
||||
{/* Hero */}
|
||||
<section className={'relative overflow-hidden'}>
|
||||
<div aria-hidden className={'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#eeeeee_1px,transparent_1px),linear-gradient(to_bottom,#eeeeee_1px,transparent_1px)] bg-[size:6rem_6rem] [mask-image:radial-gradient(ellipse_70%_60%_at_50%_30%,#000_40%,transparent_95%)]'} />
|
||||
<div className={'mx-auto max-w-[88rem] px-6 pb-20 pt-20 sm:px-10 sm:pt-28 sm:pb-28'}>
|
||||
<motion.div initial={{opacity: 0, y: 16}} animate={{opacity: 1, y: 0}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}>
|
||||
<div style={{fontFamily: 'var(--font-mono)'}} className={'mb-6 text-[11px] uppercase tracking-[0.18em] text-neutral-500'}>
|
||||
Plunk vs Brevo
|
||||
</div>
|
||||
<h3 className={'mt-6 text-2xl font-bold text-neutral-900'}>Pay per email</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Simple pay-as-you-go pricing. Unlimited contacts, pay only for emails sent.
|
||||
</p>
|
||||
<div className={'mt-6 text-4xl font-bold text-neutral-900'}>$0.001/email</div>
|
||||
<div className={'mt-8 space-y-3'}>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-900 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-white'} />
|
||||
</div>
|
||||
<span>Unlimited contacts included</span>
|
||||
</div>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-900 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-white'} />
|
||||
</div>
|
||||
<span>All features on all plans</span>
|
||||
</div>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-900 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-white'} />
|
||||
</div>
|
||||
<span>No monthly minimums</span>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, x: 20}}
|
||||
whileInView={{opacity: 1, x: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'rounded-2xl border border-neutral-200 bg-neutral-50 p-10'}
|
||||
>
|
||||
<div className={'mb-4 inline-flex items-center gap-2 rounded-full bg-neutral-200 px-4 py-1.5'}>
|
||||
<span className={'text-sm font-semibold text-neutral-900'}>Brevo</span>
|
||||
</div>
|
||||
<h3 className={'mt-6 text-2xl font-bold text-neutral-900'}>Tiered by contacts</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Monthly subscription tiers based on contact count with feature restrictions on lower plans.
|
||||
</p>
|
||||
<div className={'mt-6 text-4xl font-bold text-neutral-900'}>Contact-based</div>
|
||||
<div className={'mt-8 space-y-3'}>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-300 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-neutral-600'} />
|
||||
</div>
|
||||
<span>Pricing increases with contacts</span>
|
||||
</div>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-300 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-neutral-600'} />
|
||||
</div>
|
||||
<span>Features gated by tier</span>
|
||||
</div>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-300 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-neutral-600'} />
|
||||
</div>
|
||||
<span>Monthly subscription required</span>
|
||||
</div>
|
||||
<h1 style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2.75rem,7vw,6.5rem)] font-extrabold leading-[0.92] tracking-[-0.04em] text-neutral-900'}>
|
||||
Open-source alternative
|
||||
<br />
|
||||
for Brevo
|
||||
</h1>
|
||||
<p className={'mt-6 max-w-2xl text-xl text-neutral-600'}>Simpler pricing, cleaner API, open-source code. All the email power, none of the bloat. Built for developers, not marketing teams.</p>
|
||||
<div className={'mt-10 flex flex-wrap gap-3'}>
|
||||
<motion.a whileHover={{scale: 1.015}} whileTap={{scale: 0.985}} href={`${DASHBOARD_URI}/auth/signup`} className={'group inline-flex items-center gap-2 rounded-full bg-neutral-900 px-8 py-4 text-base font-semibold text-white shadow-[0_10px_30px_-10px_rgba(23,23,23,0.35)] transition hover:bg-neutral-800'}>
|
||||
Get started free <ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-0.5" />
|
||||
</motion.a>
|
||||
<Link href={WIKI_URI} target={'_blank'} className={'inline-flex items-center gap-2 rounded-full border border-neutral-300 bg-white px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-900'}>
|
||||
View documentation
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Key Advantages */}
|
||||
<section className={'py-32'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-20 text-center'}
|
||||
>
|
||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>Why Choose Plunk Over Brevo</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Focus on email, not feature overload</p>
|
||||
</motion.div>
|
||||
|
||||
<div className={'grid gap-px bg-neutral-200 sm:grid-cols-2 lg:grid-cols-3'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.1, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<DollarSign className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Simpler Pricing</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Pay $0.001 per email with unlimited contacts. No contact-based tiers, no surprise charges as you grow.
|
||||
Predictable costs.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.2, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<Zap className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Developer-First</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Clean API, clear documentation, 5-minute setup. Built for developers who want to ship fast, not navigate
|
||||
complex marketing suites.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.3, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<PackageOpen className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Open Source</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
AGPL-3.0 licensed. Inspect the code, contribute features, fork if needed. Full transparency, no vendor
|
||||
lock-in. Brevo is proprietary.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.4, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<Globe className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Self-Hostable</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Run on your infrastructure with Docker. Full data control, compliance-ready, cost-optimized. Brevo is
|
||||
cloud-only.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.5, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<Users className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Unlimited Contacts</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Store unlimited contacts at no extra cost. Brevo charges more as your contact list grows. With Plunk,
|
||||
you only pay for emails sent.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.6, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<BarChart3 className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Email-Focused</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Plunk does email and does it well. No SMS, chat, CRM bloat. If you need just email automation, Plunk is
|
||||
simpler and more focused.
|
||||
</p>
|
||||
{/* Pricing comparison */}
|
||||
<section className={'border-t border-neutral-200'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}} className={'mb-16'}>
|
||||
<h2 style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}>
|
||||
Pricing That Scales With You
|
||||
</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Pay for emails sent, not contacts stored</p>
|
||||
</motion.div>
|
||||
<div className={'grid gap-4 lg:grid-cols-2'}>
|
||||
<motion.div initial={{opacity: 0, x: -20}} whileInView={{opacity: 1, x: 0}} viewport={{once: true}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}} className={'rounded-[24px] border border-neutral-900 bg-neutral-900 p-10 text-white'}>
|
||||
<div style={{fontFamily: 'var(--font-mono)'}} className={'text-[11px] uppercase tracking-[0.18em] text-neutral-400'}>Plunk</div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-2xl font-bold tracking-[-0.025em] text-white'}>Pay per email</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-300'}>Simple pay-as-you-go pricing. Unlimited contacts, pay only for emails sent.</p>
|
||||
<div style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-4xl font-extrabold tracking-[-0.03em] text-white'}>$0.001/email</div>
|
||||
<ul className={'mt-8 space-y-3'}>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-300'}><Check className="h-4 w-4 flex-shrink-0 text-neutral-400" />Unlimited contacts included</li>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-300'}><Check className="h-4 w-4 flex-shrink-0 text-neutral-400" />All features on all plans</li>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-300'}><Check className="h-4 w-4 flex-shrink-0 text-neutral-400" />No monthly minimums</li>
|
||||
</ul>
|
||||
</motion.div>
|
||||
<motion.div initial={{opacity: 0, x: 20}} whileInView={{opacity: 1, x: 0}} viewport={{once: true}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}} className={'rounded-[24px] border border-neutral-200 bg-white p-10'}>
|
||||
<div style={{fontFamily: 'var(--font-mono)'}} className={'text-[11px] uppercase tracking-[0.18em] text-neutral-500'}>Brevo</div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-2xl font-bold tracking-[-0.025em] text-neutral-900'}>Tiered by contacts</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>Monthly subscription tiers based on contact count with feature restrictions on lower plans.</p>
|
||||
<div style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-4xl font-extrabold tracking-[-0.03em] text-neutral-900'}>Contact-based</div>
|
||||
<ul className={'mt-8 space-y-3'}>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-600'}><div className={'h-1.5 w-1.5 flex-shrink-0 rounded-full bg-neutral-400'} />Pricing increases with contacts</li>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-600'}><div className={'h-1.5 w-1.5 flex-shrink-0 rounded-full bg-neutral-400'} />Features gated by tier</li>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-600'}><div className={'h-1.5 w-1.5 flex-shrink-0 rounded-full bg-neutral-400'} />Monthly subscription required</li>
|
||||
</ul>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Feature Comparison */}
|
||||
<section className={'py-32'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-16 text-center'}
|
||||
>
|
||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>Feature-by-Feature Comparison</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>See exactly what you get with each platform</p>
|
||||
</motion.div>
|
||||
{/* Key advantages */}
|
||||
<section className={'border-t border-neutral-200 bg-neutral-50/60'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}} className={'mb-16'}>
|
||||
<h2 style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}>Why Choose Plunk Over Brevo</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Focus on email, not feature overload</p>
|
||||
</motion.div>
|
||||
<div className={'grid gap-px bg-neutral-200 sm:grid-cols-2 lg:grid-cols-3'}>
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.5, delay: 0.1, ease: [0.22, 1, 0.36, 1]}} className={'bg-white p-10'}>
|
||||
<div className={'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white'}><DollarSign className="h-5 w-5" /></div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>Simpler Pricing</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>Pay $0.001 per email with unlimited contacts. No contact-based tiers, no surprise charges as you grow. Predictable costs.</p>
|
||||
</motion.div>
|
||||
|
||||
<ComparisonTable competitorName="Brevo" rows={comparisonData} />
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.5, delay: 0.2, ease: [0.22, 1, 0.36, 1]}} className={'bg-white p-10'}>
|
||||
<div className={'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white'}><Zap className="h-5 w-5" /></div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>Developer-First</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>Clean API, clear documentation, 5-minute setup. Built for developers who want to ship fast, not navigate complex marketing suites.</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.5, delay: 0.3, ease: [0.22, 1, 0.36, 1]}} className={'bg-white p-10'}>
|
||||
<div className={'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white'}><PackageOpen className="h-5 w-5" /></div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>Open Source</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>AGPL-3.0 licensed. Inspect the code, contribute features, fork if needed. Full transparency, no vendor lock-in. Brevo is proprietary.</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.5, delay: 0.4, ease: [0.22, 1, 0.36, 1]}} className={'bg-white p-10'}>
|
||||
<div className={'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white'}><Globe className="h-5 w-5" /></div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>Self-Hostable</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>Run on your infrastructure with Docker. Full data control, compliance-ready, cost-optimized. Brevo is cloud-only.</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.5, delay: 0.5, ease: [0.22, 1, 0.36, 1]}} className={'bg-white p-10'}>
|
||||
<div className={'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white'}><Users className="h-5 w-5" /></div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>Unlimited Contacts</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>Store unlimited contacts at no extra cost. Brevo charges more as your contact list grows. With Plunk, you only pay for emails sent.</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.5, delay: 0.6, ease: [0.22, 1, 0.36, 1]}} className={'bg-white p-10'}>
|
||||
<div className={'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white'}><BarChart3 className="h-5 w-5" /></div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>Email-Focused</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>Plunk does email and does it well. No SMS, chat, CRM bloat. If you need just email automation, Plunk is simpler and more focused.</p>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Feature comparison table */}
|
||||
<section className={'border-t border-neutral-200'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}} className={'mb-16'}>
|
||||
<h2 style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}>Feature comparison</h2>
|
||||
</motion.div>
|
||||
<ComparisonTable competitorName="Brevo" rows={comparisonData} />
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* FAQ */}
|
||||
<FAQSection faqs={faqs} schemaId="faq-schema-brevo" />
|
||||
|
||||
{/* CTA */}
|
||||
<section className={'relative overflow-hidden border-t border-neutral-200 py-32'}>
|
||||
<div
|
||||
className={
|
||||
'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#e5e7eb_1px,transparent_1px),linear-gradient(to_bottom,#e5e7eb_1px,transparent_1px)] bg-[size:4rem_4rem] [mask-image:radial-gradient(ellipse_80%_50%_at_50%_100%,#000_70%,transparent_110%)]'
|
||||
}
|
||||
/>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mx-auto max-w-3xl text-center'}
|
||||
>
|
||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>Make the switch to simplicity</h2>
|
||||
<p className={'mt-6 text-lg text-neutral-600'}>
|
||||
Join developers choosing focused tools over bloated marketing suites. Start free, no credit card required.
|
||||
</p>
|
||||
<div className={'mt-12 flex flex-wrap justify-center gap-4'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.02}}
|
||||
whileTap={{scale: 0.98}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
className={
|
||||
'group rounded-lg bg-neutral-900 px-8 py-4 text-base font-semibold text-white transition hover:bg-neutral-800'
|
||||
}
|
||||
>
|
||||
<span className={'flex items-center gap-2'}>
|
||||
Get started free
|
||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-1" />
|
||||
</span>
|
||||
</motion.a>
|
||||
<Link
|
||||
href="/pricing"
|
||||
className={
|
||||
'rounded-lg border border-neutral-300 px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-400'
|
||||
}
|
||||
>
|
||||
View pricing details
|
||||
</Link>
|
||||
<section className={'relative overflow-hidden border-t border-neutral-900 bg-neutral-900 text-white'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-32 sm:px-10 sm:py-40'}>
|
||||
<div className={'flex flex-col items-start gap-12 lg:flex-row lg:items-end lg:justify-between'}>
|
||||
<motion.h2 initial={{opacity: 0, y: 16}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.9, ease: [0.22, 1, 0.36, 1]}} style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2.5rem,7vw,6rem)] font-extrabold leading-[0.95] tracking-[-0.035em]'}>
|
||||
Make the switch to simplicity
|
||||
</motion.h2>
|
||||
<motion.div initial={{opacity: 0, y: 16}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.9, delay: 0.15, ease: [0.22, 1, 0.36, 1]}} className={'flex max-w-md flex-col gap-6'}>
|
||||
<p className={'text-base text-neutral-300 sm:text-lg'}>Join developers choosing focused tools over bloated marketing suites. Start free, no credit card required.</p>
|
||||
<div className={'flex flex-wrap gap-3'}>
|
||||
<motion.a whileHover={{scale: 1.015}} whileTap={{scale: 0.985}} href={`${DASHBOARD_URI}/auth/signup`} className={'inline-flex items-center gap-2 rounded-full bg-white px-7 py-3.5 text-sm font-semibold text-neutral-900 transition hover:bg-neutral-100'}>
|
||||
Get started free <ArrowRight className="h-4 w-4" />
|
||||
</motion.a>
|
||||
<Link href={'/pricing'} className={'inline-flex items-center gap-2 rounded-full border border-neutral-700 px-7 py-3.5 text-sm font-semibold text-white transition hover:border-white'}>
|
||||
View pricing
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
</main>
|
||||
<Footer />
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -4,7 +4,7 @@ import {DASHBOARD_URI, WIKI_URI} from '../../lib/constants';
|
||||
import React from 'react';
|
||||
import Link from 'next/link';
|
||||
import {NextSeo} from 'next-seo';
|
||||
import {ArrowRight, Code2, DollarSign, Globe, PackageOpen, Users, Zap} from 'lucide-react';
|
||||
import {ArrowRight, Check, Code2, DollarSign, Globe, PackageOpen, Users, Zap} from 'lucide-react';
|
||||
import type {ComparisonRow} from '../../components/ComparisonTable';
|
||||
import type {FAQ} from '../../components/FAQSection';
|
||||
|
||||
@@ -70,365 +70,152 @@ export default function ConvertkitComparison() {
|
||||
|
||||
<Navbar />
|
||||
|
||||
<main className={'mx-auto max-w-7xl px-8 sm:px-0'}>
|
||||
{/* Hero Section */}
|
||||
<section className={'relative py-32 sm:py-48'}>
|
||||
<div
|
||||
className={
|
||||
'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#e5e7eb_1px,transparent_1px),linear-gradient(to_bottom,#e5e7eb_1px,transparent_1px)] bg-[size:4rem_4rem] [mask-image:radial-gradient(ellipse_80%_50%_at_50%_0%,#000_70%,transparent_110%)]'
|
||||
}
|
||||
/>
|
||||
<main className={'text-neutral-800'}>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
animate={{opacity: 1, y: 0}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mx-auto max-w-4xl text-center'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'mb-6 inline-flex items-center gap-2 rounded-full border border-neutral-200 bg-white px-4 py-2'
|
||||
}
|
||||
>
|
||||
<span className={'text-sm text-neutral-600'}>Comparing</span>
|
||||
<span className={'text-sm font-semibold text-neutral-900'}>Plunk vs ConvertKit</span>
|
||||
</div>
|
||||
|
||||
<h1 className={'text-6xl font-bold tracking-tight text-neutral-900 sm:text-7xl lg:text-8xl text-balance'}>
|
||||
Open-source alternative
|
||||
<br />
|
||||
for ConvertKit
|
||||
</h1>
|
||||
|
||||
<p className={'mx-auto mt-8 max-w-2xl text-xl text-neutral-600'}>
|
||||
ConvertKit is built for creators. Plunk is built for developers who need powerful email automation without
|
||||
the creator-focused bloat. Same automation, better DX, pay-as-you-go.
|
||||
</p>
|
||||
|
||||
<div className={'mt-12 flex flex-wrap justify-center gap-4'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.02}}
|
||||
whileTap={{scale: 0.98}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
className={
|
||||
'group rounded-lg bg-neutral-900 px-8 py-4 text-base font-semibold text-white shadow-lg shadow-neutral-900/10 transition hover:bg-neutral-800'
|
||||
}
|
||||
>
|
||||
<span className={'flex items-center gap-2'}>
|
||||
Get started free
|
||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-1" />
|
||||
</span>
|
||||
</motion.a>
|
||||
<Link
|
||||
href={WIKI_URI}
|
||||
target={'_blank'}
|
||||
className={
|
||||
'rounded-lg border border-neutral-300 bg-white px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-400'
|
||||
}
|
||||
>
|
||||
View documentation
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
</section>
|
||||
|
||||
{/* Pricing Model Comparison */}
|
||||
<section className={'py-32'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-16 text-center'}
|
||||
>
|
||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>Pay for Emails, Not Subscribers</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Pricing that grows with usage, not list size</p>
|
||||
</motion.div>
|
||||
|
||||
<div className={'grid gap-8 lg:grid-cols-2'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, x: -20}}
|
||||
whileInView={{opacity: 1, x: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'rounded-2xl border-2 border-neutral-900 bg-white p-10'}
|
||||
>
|
||||
<div className={'mb-4 inline-flex items-center gap-2 rounded-full bg-neutral-900 px-4 py-1.5'}>
|
||||
<span className={'text-sm font-semibold text-white'}>Plunk</span>
|
||||
{/* Hero */}
|
||||
<section className={'relative overflow-hidden'}>
|
||||
<div aria-hidden className={'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#eeeeee_1px,transparent_1px),linear-gradient(to_bottom,#eeeeee_1px,transparent_1px)] bg-[size:6rem_6rem] [mask-image:radial-gradient(ellipse_70%_60%_at_50%_30%,#000_40%,transparent_95%)]'} />
|
||||
<div className={'mx-auto max-w-[88rem] px-6 pb-20 pt-20 sm:px-10 sm:pt-28 sm:pb-28'}>
|
||||
<motion.div initial={{opacity: 0, y: 16}} animate={{opacity: 1, y: 0}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}>
|
||||
<div style={{fontFamily: 'var(--font-mono)'}} className={'mb-6 text-[11px] uppercase tracking-[0.18em] text-neutral-500'}>
|
||||
Plunk vs ConvertKit
|
||||
</div>
|
||||
<h3 className={'mt-6 text-2xl font-bold text-neutral-900'}>Pay per email sent</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Pay-as-you-go pricing. Only pay for emails you send, not for subscribers you store.
|
||||
</p>
|
||||
<div className={'mt-6 text-4xl font-bold text-neutral-900'}>Pay-as-you-go</div>
|
||||
<div className={'mt-8 space-y-3'}>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-900 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-white'} />
|
||||
</div>
|
||||
<span>Unlimited subscribers at no cost</span>
|
||||
</div>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-900 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-white'} />
|
||||
</div>
|
||||
<span>Only pay when you actually send</span>
|
||||
</div>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-900 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-white'} />
|
||||
</div>
|
||||
<span>Grow your list without price increases</span>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, x: 20}}
|
||||
whileInView={{opacity: 1, x: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'rounded-2xl border border-neutral-200 bg-neutral-50 p-10'}
|
||||
>
|
||||
<div className={'mb-4 inline-flex items-center gap-2 rounded-full bg-neutral-200 px-4 py-1.5'}>
|
||||
<span className={'text-sm font-semibold text-neutral-900'}>ConvertKit</span>
|
||||
</div>
|
||||
<h3 className={'mt-6 text-2xl font-bold text-neutral-900'}>Pay per subscriber count</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Monthly subscription based on total subscribers, whether you email them or not.
|
||||
</p>
|
||||
<div className={'mt-6 text-4xl font-bold text-neutral-900'}>From $25/month</div>
|
||||
<div className={'mt-8 space-y-3'}>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-300 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-neutral-600'} />
|
||||
</div>
|
||||
<span>Price increases with subscriber count</span>
|
||||
</div>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-300 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-neutral-600'} />
|
||||
</div>
|
||||
<span>Pay even if you don't send emails</span>
|
||||
</div>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-300 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-neutral-600'} />
|
||||
</div>
|
||||
<span>10K subscribers = $119/month</span>
|
||||
</div>
|
||||
<h1 style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2.75rem,7vw,6.5rem)] font-extrabold leading-[0.92] tracking-[-0.04em] text-neutral-900'}>
|
||||
Open-source alternative
|
||||
<br />
|
||||
for ConvertKit
|
||||
</h1>
|
||||
<p className={'mt-6 max-w-2xl text-xl text-neutral-600'}>ConvertKit is built for creators. Plunk is built for developers who need powerful email automation without the creator-focused bloat. Same automation, better DX, pay-as-you-go.</p>
|
||||
<div className={'mt-10 flex flex-wrap gap-3'}>
|
||||
<motion.a whileHover={{scale: 1.015}} whileTap={{scale: 0.985}} href={`${DASHBOARD_URI}/auth/signup`} className={'group inline-flex items-center gap-2 rounded-full bg-neutral-900 px-8 py-4 text-base font-semibold text-white shadow-[0_10px_30px_-10px_rgba(23,23,23,0.35)] transition hover:bg-neutral-800'}>
|
||||
Get started free <ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-0.5" />
|
||||
</motion.a>
|
||||
<Link href={WIKI_URI} target={'_blank'} className={'inline-flex items-center gap-2 rounded-full border border-neutral-300 bg-white px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-900'}>
|
||||
View documentation
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Key Advantages */}
|
||||
<section className={'py-32'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-20 text-center'}
|
||||
>
|
||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>Built for Developers, Not Creators</h2>
|
||||
</motion.div>
|
||||
|
||||
<div className={'grid gap-px bg-neutral-200 sm:grid-cols-2 lg:grid-cols-3'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.1, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<Code2 className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Developer-First API</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Modern REST API designed for developers. No visual builder complexity, just clean endpoints for sending
|
||||
emails and managing workflows.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.2, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<DollarSign className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Pay-as-you-go Pricing</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Only pay for emails sent, not subscribers stored. Grow your list without worrying about tier upgrades or
|
||||
subscription increases.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.3, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<PackageOpen className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Open Source</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
AGPL-3.0 licensed. Inspect the code, contribute features, understand exactly how your emails are sent.
|
||||
ConvertKit is proprietary.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.4, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<Globe className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Self-Hostable</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Run on your own infrastructure with Docker. Full data control, compliance-ready, cost-optimized for
|
||||
scale. ConvertKit is cloud-only.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.5, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<Zap className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>5-Minute Setup</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Start sending emails in minutes. No form builders to configure, no landing pages to design. Just
|
||||
authenticate and send.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.6, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<Users className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Unlimited Contacts</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Store unlimited contacts without penalty. No subscriber tiers, no forced upgrades. Your contact database
|
||||
grows freely.
|
||||
</p>
|
||||
{/* Pricing comparison */}
|
||||
<section className={'border-t border-neutral-200'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}} className={'mb-16'}>
|
||||
<h2 style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}>
|
||||
Pay for Emails, Not Subscribers
|
||||
</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Pricing that grows with usage, not list size</p>
|
||||
</motion.div>
|
||||
<div className={'grid gap-4 lg:grid-cols-2'}>
|
||||
<motion.div initial={{opacity: 0, x: -20}} whileInView={{opacity: 1, x: 0}} viewport={{once: true}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}} className={'rounded-[24px] border border-neutral-900 bg-neutral-900 p-10 text-white'}>
|
||||
<div style={{fontFamily: 'var(--font-mono)'}} className={'text-[11px] uppercase tracking-[0.18em] text-neutral-400'}>Plunk</div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-2xl font-bold tracking-[-0.025em] text-white'}>Pay per email sent</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-300'}>Pay-as-you-go pricing. Only pay for emails you send, not for subscribers you store.</p>
|
||||
<div style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-4xl font-extrabold tracking-[-0.03em] text-white'}>Pay-as-you-go</div>
|
||||
<ul className={'mt-8 space-y-3'}>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-300'}><Check className="h-4 w-4 flex-shrink-0 text-neutral-400" />Unlimited subscribers at no cost</li>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-300'}><Check className="h-4 w-4 flex-shrink-0 text-neutral-400" />Only pay when you actually send</li>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-300'}><Check className="h-4 w-4 flex-shrink-0 text-neutral-400" />Grow your list without price increases</li>
|
||||
</ul>
|
||||
</motion.div>
|
||||
<motion.div initial={{opacity: 0, x: 20}} whileInView={{opacity: 1, x: 0}} viewport={{once: true}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}} className={'rounded-[24px] border border-neutral-200 bg-white p-10'}>
|
||||
<div style={{fontFamily: 'var(--font-mono)'}} className={'text-[11px] uppercase tracking-[0.18em] text-neutral-500'}>ConvertKit</div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-2xl font-bold tracking-[-0.025em] text-neutral-900'}>Pay per subscriber count</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>Monthly subscription based on total subscribers, whether you email them or not.</p>
|
||||
<div style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-4xl font-extrabold tracking-[-0.03em] text-neutral-900'}>From $25/month</div>
|
||||
<ul className={'mt-8 space-y-3'}>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-600'}><div className={'h-1.5 w-1.5 flex-shrink-0 rounded-full bg-neutral-400'} />Price increases with subscriber count</li>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-600'}><div className={'h-1.5 w-1.5 flex-shrink-0 rounded-full bg-neutral-400'} />Pay even if you don't send emails</li>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-600'}><div className={'h-1.5 w-1.5 flex-shrink-0 rounded-full bg-neutral-400'} />10K subscribers = $119/month</li>
|
||||
</ul>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Feature Comparison */}
|
||||
<section className={'py-32'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-16 text-center'}
|
||||
>
|
||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>Feature Comparison</h2>
|
||||
</motion.div>
|
||||
{/* Key advantages */}
|
||||
<section className={'border-t border-neutral-200 bg-neutral-50/60'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}} className={'mb-16'}>
|
||||
<h2 style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}>Built for Developers, Not Creators</h2>
|
||||
</motion.div>
|
||||
<div className={'grid gap-px bg-neutral-200 sm:grid-cols-2 lg:grid-cols-3'}>
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.5, delay: 0.1, ease: [0.22, 1, 0.36, 1]}} className={'bg-white p-10'}>
|
||||
<div className={'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white'}><Code2 className="h-5 w-5" /></div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>Developer-First API</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>Modern REST API designed for developers. No visual builder complexity, just clean endpoints for sending emails and managing workflows.</p>
|
||||
</motion.div>
|
||||
|
||||
<ComparisonTable competitorName="ConvertKit" rows={comparisonData} />
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.5, delay: 0.2, ease: [0.22, 1, 0.36, 1]}} className={'bg-white p-10'}>
|
||||
<div className={'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white'}><DollarSign className="h-5 w-5" /></div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>Pay-as-you-go Pricing</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>Only pay for emails sent, not subscribers stored. Grow your list without worrying about tier upgrades or subscription increases.</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.5, delay: 0.3, ease: [0.22, 1, 0.36, 1]}} className={'bg-white p-10'}>
|
||||
<div className={'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white'}><PackageOpen className="h-5 w-5" /></div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>Open Source</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>AGPL-3.0 licensed. Inspect the code, contribute features, understand exactly how your emails are sent. ConvertKit is proprietary.</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.5, delay: 0.4, ease: [0.22, 1, 0.36, 1]}} className={'bg-white p-10'}>
|
||||
<div className={'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white'}><Globe className="h-5 w-5" /></div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>Self-Hostable</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>Run on your own infrastructure with Docker. Full data control, compliance-ready, cost-optimized for scale. ConvertKit is cloud-only.</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.5, delay: 0.5, ease: [0.22, 1, 0.36, 1]}} className={'bg-white p-10'}>
|
||||
<div className={'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white'}><Zap className="h-5 w-5" /></div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>5-Minute Setup</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>Start sending emails in minutes. No form builders to configure, no landing pages to design. Just authenticate and send.</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.5, delay: 0.6, ease: [0.22, 1, 0.36, 1]}} className={'bg-white p-10'}>
|
||||
<div className={'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white'}><Users className="h-5 w-5" /></div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>Unlimited Contacts</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>Store unlimited contacts without penalty. No subscriber tiers, no forced upgrades. Your contact database grows freely.</p>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Feature comparison table */}
|
||||
<section className={'border-t border-neutral-200'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}} className={'mb-16'}>
|
||||
<h2 style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}>Feature comparison</h2>
|
||||
</motion.div>
|
||||
<ComparisonTable competitorName="ConvertKit" rows={comparisonData} />
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* FAQ */}
|
||||
<FAQSection faqs={faqs} schemaId="faq-schema-convertkit" />
|
||||
|
||||
{/* CTA */}
|
||||
<section className={'relative overflow-hidden border-t border-neutral-200 py-32'}>
|
||||
<div
|
||||
className={
|
||||
'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#e5e7eb_1px,transparent_1px),linear-gradient(to_bottom,#e5e7eb_1px,transparent_1px)] bg-[size:4rem_4rem] [mask-image:radial-gradient(ellipse_80%_50%_at_50%_100%,#000_70%,transparent_110%)]'
|
||||
}
|
||||
/>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mx-auto max-w-3xl text-center'}
|
||||
>
|
||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>
|
||||
Ready for a developer-first email platform?
|
||||
</h2>
|
||||
<p className={'mt-6 text-lg text-neutral-600'}>
|
||||
Join developers who've switched from ConvertKit to Plunk for better API design and transparent
|
||||
pay-as-you-go pricing.
|
||||
</p>
|
||||
<div className={'mt-12 flex flex-wrap justify-center gap-4'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.02}}
|
||||
whileTap={{scale: 0.98}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
className={
|
||||
'group rounded-lg bg-neutral-900 px-8 py-4 text-base font-semibold text-white transition hover:bg-neutral-800'
|
||||
}
|
||||
>
|
||||
<span className={'flex items-center gap-2'}>
|
||||
Get started free
|
||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-1" />
|
||||
</span>
|
||||
</motion.a>
|
||||
<Link
|
||||
href="/pricing"
|
||||
className={
|
||||
'rounded-lg border border-neutral-300 px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-400'
|
||||
}
|
||||
>
|
||||
View pricing
|
||||
</Link>
|
||||
<section className={'relative overflow-hidden border-t border-neutral-900 bg-neutral-900 text-white'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-32 sm:px-10 sm:py-40'}>
|
||||
<div className={'flex flex-col items-start gap-12 lg:flex-row lg:items-end lg:justify-between'}>
|
||||
<motion.h2 initial={{opacity: 0, y: 16}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.9, ease: [0.22, 1, 0.36, 1]}} style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2.5rem,7vw,6rem)] font-extrabold leading-[0.95] tracking-[-0.035em]'}>
|
||||
Ready for a developer-first email platform?
|
||||
</motion.h2>
|
||||
<motion.div initial={{opacity: 0, y: 16}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.9, delay: 0.15, ease: [0.22, 1, 0.36, 1]}} className={'flex max-w-md flex-col gap-6'}>
|
||||
<p className={'text-base text-neutral-300 sm:text-lg'}>Join developers who've switched from ConvertKit to Plunk for better API design and transparent pay-as-you-go pricing.</p>
|
||||
<div className={'flex flex-wrap gap-3'}>
|
||||
<motion.a whileHover={{scale: 1.015}} whileTap={{scale: 0.985}} href={`${DASHBOARD_URI}/auth/signup`} className={'inline-flex items-center gap-2 rounded-full bg-white px-7 py-3.5 text-sm font-semibold text-neutral-900 transition hover:bg-neutral-100'}>
|
||||
Get started free <ArrowRight className="h-4 w-4" />
|
||||
</motion.a>
|
||||
<Link href={'/pricing'} className={'inline-flex items-center gap-2 rounded-full border border-neutral-700 px-7 py-3.5 text-sm font-semibold text-white transition hover:border-white'}>
|
||||
View pricing
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
</main>
|
||||
<Footer />
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -4,7 +4,7 @@ import {DASHBOARD_URI, WIKI_URI} from '../../lib/constants';
|
||||
import React from 'react';
|
||||
import Link from 'next/link';
|
||||
import {NextSeo} from 'next-seo';
|
||||
import {ArrowRight, BarChart3, Code2, DollarSign, Globe, PackageOpen, Zap} from 'lucide-react';
|
||||
import {ArrowRight, BarChart3, Check, Code2, DollarSign, Globe, PackageOpen, Zap} from 'lucide-react';
|
||||
import type {ComparisonRow} from '../../components/ComparisonTable';
|
||||
import type {FAQ} from '../../components/FAQSection';
|
||||
|
||||
@@ -65,311 +65,124 @@ export default function CustomerioComparison() {
|
||||
|
||||
<Navbar />
|
||||
|
||||
<main className={'mx-auto max-w-7xl px-8 sm:px-0'}>
|
||||
{/* Hero Section */}
|
||||
<section className={'relative py-32 sm:py-48'}>
|
||||
<div
|
||||
className={
|
||||
'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#e5e7eb_1px,transparent_1px),linear-gradient(to_bottom,#e5e7eb_1px,transparent_1px)] bg-[size:4rem_4rem] [mask-image:radial-gradient(ellipse_80%_50%_at_50%_0%,#000_70%,transparent_110%)]'
|
||||
}
|
||||
/>
|
||||
<main className={'text-neutral-800'}>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
animate={{opacity: 1, y: 0}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mx-auto max-w-4xl text-center'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'mb-6 inline-flex items-center gap-2 rounded-full border border-neutral-200 bg-white px-4 py-2'
|
||||
}
|
||||
>
|
||||
<span className={'text-sm text-neutral-600'}>Comparing</span>
|
||||
<span className={'text-sm font-semibold text-neutral-900'}>Plunk vs Customer.io</span>
|
||||
</div>
|
||||
|
||||
<h1 className={'text-6xl font-bold tracking-tight text-neutral-900 sm:text-7xl lg:text-8xl text-balance'}>
|
||||
Open-source alternative
|
||||
<br />
|
||||
for Customer.io
|
||||
</h1>
|
||||
|
||||
<p className={'mx-auto mt-8 max-w-2xl text-xl text-neutral-600'}>
|
||||
Customer.io starts at $100/month and takes weeks to set up. Plunk delivers the same event-driven automation in an open-source platform you can be sending from in under 5 minutes.
|
||||
</p>
|
||||
|
||||
<div className={'mt-12 flex flex-wrap justify-center gap-4'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.02}}
|
||||
whileTap={{scale: 0.98}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
className={
|
||||
'group rounded-lg bg-neutral-900 px-8 py-4 text-base font-semibold text-white shadow-lg shadow-neutral-900/10 transition hover:bg-neutral-800'
|
||||
}
|
||||
>
|
||||
<span className={'flex items-center gap-2'}>
|
||||
Try Plunk free
|
||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-1" />
|
||||
</span>
|
||||
</motion.a>
|
||||
<Link
|
||||
href={WIKI_URI}
|
||||
target={'_blank'}
|
||||
className={
|
||||
'rounded-lg border border-neutral-300 bg-white px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-400'
|
||||
}
|
||||
>
|
||||
View documentation
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
</section>
|
||||
|
||||
{/* Pricing Model Comparison */}
|
||||
<section className={'py-32'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-16 text-center'}
|
||||
>
|
||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>Simple Pricing That Scales</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Transparent pay-as-you-go vs complex enterprise tiers</p>
|
||||
</motion.div>
|
||||
|
||||
<div className={'grid gap-8 lg:grid-cols-2'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, x: -20}}
|
||||
whileInView={{opacity: 1, x: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'rounded-2xl border-2 border-neutral-900 bg-white p-10'}
|
||||
>
|
||||
<div className={'mb-4 inline-flex items-center gap-2 rounded-full bg-neutral-900 px-4 py-1.5'}>
|
||||
<span className={'text-sm font-semibold text-white'}>Plunk</span>
|
||||
{/* Hero */}
|
||||
<section className={'relative overflow-hidden'}>
|
||||
<div aria-hidden className={'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#eeeeee_1px,transparent_1px),linear-gradient(to_bottom,#eeeeee_1px,transparent_1px)] bg-[size:6rem_6rem] [mask-image:radial-gradient(ellipse_70%_60%_at_50%_30%,#000_40%,transparent_95%)]'} />
|
||||
<div className={'mx-auto max-w-[88rem] px-6 pb-20 pt-20 sm:px-10 sm:pt-28 sm:pb-28'}>
|
||||
<motion.div initial={{opacity: 0, y: 16}} animate={{opacity: 1, y: 0}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}>
|
||||
<div style={{fontFamily: 'var(--font-mono)'}} className={'mb-6 text-[11px] uppercase tracking-[0.18em] text-neutral-500'}>
|
||||
Plunk vs Customer.io
|
||||
</div>
|
||||
<h3 className={'mt-6 text-2xl font-bold text-neutral-900'}>Pay per email sent</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Pay-as-you-go pricing. Only pay for emails you actually send.
|
||||
</p>
|
||||
<div className={'mt-6 text-4xl font-bold text-neutral-900'}>Pay-as-you-go</div>
|
||||
<div className={'mt-8 space-y-3'}>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-900 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-white'} />
|
||||
</div>
|
||||
<span>Only pay for emails you actually send</span>
|
||||
</div>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-900 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-white'} />
|
||||
</div>
|
||||
<span>No contact-based pricing complexity</span>
|
||||
</div>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-900 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-white'} />
|
||||
</div>
|
||||
<span>All features included, no upsells</span>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, x: 20}}
|
||||
whileInView={{opacity: 1, x: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'rounded-2xl border border-neutral-200 bg-neutral-50 p-10'}
|
||||
>
|
||||
<div className={'mb-4 inline-flex items-center gap-2 rounded-full bg-neutral-200 px-4 py-1.5'}>
|
||||
<span className={'text-sm font-semibold text-neutral-900'}>Customer.io</span>
|
||||
</div>
|
||||
<h3 className={'mt-6 text-2xl font-bold text-neutral-900'}>Complex usage-based pricing</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Pricing based on profiles, messages, and feature tiers.
|
||||
</p>
|
||||
<div className={'mt-6 text-4xl font-bold text-neutral-900'}>Tiered complexity</div>
|
||||
<div className={'mt-8 space-y-3'}>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-300 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-neutral-600'} />
|
||||
</div>
|
||||
<span>Pay for profiles and messages sent</span>
|
||||
</div>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-300 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-neutral-600'} />
|
||||
</div>
|
||||
<span>Enterprise pricing can be expensive</span>
|
||||
</div>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-300 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-neutral-600'} />
|
||||
</div>
|
||||
<span>Advanced features locked behind tiers</span>
|
||||
</div>
|
||||
<h1 style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2.75rem,7vw,6.5rem)] font-extrabold leading-[0.92] tracking-[-0.04em] text-neutral-900'}>
|
||||
Open-source alternative
|
||||
<br />
|
||||
for Customer.io
|
||||
</h1>
|
||||
<p className={'mt-6 max-w-2xl text-xl text-neutral-600'}>Customer.io starts at $100/month and takes weeks to set up. Plunk delivers the same event-driven automation in an open-source platform you can be sending from in under 5 minutes.</p>
|
||||
<div className={'mt-10 flex flex-wrap gap-3'}>
|
||||
<motion.a whileHover={{scale: 1.015}} whileTap={{scale: 0.985}} href={`${DASHBOARD_URI}/auth/signup`} className={'group inline-flex items-center gap-2 rounded-full bg-neutral-900 px-8 py-4 text-base font-semibold text-white shadow-[0_10px_30px_-10px_rgba(23,23,23,0.35)] transition hover:bg-neutral-800'}>
|
||||
Try Plunk free <ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-0.5" />
|
||||
</motion.a>
|
||||
<Link href={WIKI_URI} target={'_blank'} className={'inline-flex items-center gap-2 rounded-full border border-neutral-300 bg-white px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-900'}>
|
||||
View documentation
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Feature Comparison */}
|
||||
<section className={'py-32'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-16 text-center'}
|
||||
>
|
||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>Feature-by-Feature</h2>
|
||||
</motion.div>
|
||||
|
||||
<ComparisonTable competitorName="Customer.io" rows={comparisonData} />
|
||||
{/* Pricing comparison */}
|
||||
<section className={'border-t border-neutral-200'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}} className={'mb-16'}>
|
||||
<h2 style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}>
|
||||
Simple Pricing That Scales
|
||||
</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Transparent pay-as-you-go vs complex enterprise tiers</p>
|
||||
</motion.div>
|
||||
<div className={'grid gap-4 lg:grid-cols-2'}>
|
||||
<motion.div initial={{opacity: 0, x: -20}} whileInView={{opacity: 1, x: 0}} viewport={{once: true}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}} className={'rounded-[24px] border border-neutral-900 bg-neutral-900 p-10 text-white'}>
|
||||
<div style={{fontFamily: 'var(--font-mono)'}} className={'text-[11px] uppercase tracking-[0.18em] text-neutral-400'}>Plunk</div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-2xl font-bold tracking-[-0.025em] text-white'}>Pay per email sent</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-300'}>Pay-as-you-go pricing. Only pay for emails you actually send.</p>
|
||||
<div style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-4xl font-extrabold tracking-[-0.03em] text-white'}>Pay-as-you-go</div>
|
||||
<ul className={'mt-8 space-y-3'}>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-300'}><Check className="h-4 w-4 flex-shrink-0 text-neutral-400" />Only pay for emails you actually send</li>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-300'}><Check className="h-4 w-4 flex-shrink-0 text-neutral-400" />No contact-based pricing complexity</li>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-300'}><Check className="h-4 w-4 flex-shrink-0 text-neutral-400" />All features included, no upsells</li>
|
||||
</ul>
|
||||
</motion.div>
|
||||
<motion.div initial={{opacity: 0, x: 20}} whileInView={{opacity: 1, x: 0}} viewport={{once: true}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}} className={'rounded-[24px] border border-neutral-200 bg-white p-10'}>
|
||||
<div style={{fontFamily: 'var(--font-mono)'}} className={'text-[11px] uppercase tracking-[0.18em] text-neutral-500'}>Customer.io</div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-2xl font-bold tracking-[-0.025em] text-neutral-900'}>Complex usage-based pricing</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>Pricing based on profiles, messages, and feature tiers.</p>
|
||||
<div style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-4xl font-extrabold tracking-[-0.03em] text-neutral-900'}>Tiered complexity</div>
|
||||
<ul className={'mt-8 space-y-3'}>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-600'}><div className={'h-1.5 w-1.5 flex-shrink-0 rounded-full bg-neutral-400'} />Pay for profiles and messages sent</li>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-600'}><div className={'h-1.5 w-1.5 flex-shrink-0 rounded-full bg-neutral-400'} />Enterprise pricing can be expensive</li>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-600'}><div className={'h-1.5 w-1.5 flex-shrink-0 rounded-full bg-neutral-400'} />Advanced features locked behind tiers</li>
|
||||
</ul>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Key Advantages */}
|
||||
<section className={'py-32'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-20 text-center'}
|
||||
>
|
||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>Key Advantages</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Why developers choose Plunk</p>
|
||||
</motion.div>
|
||||
|
||||
<div className={'grid gap-px bg-neutral-200 sm:grid-cols-2 lg:grid-cols-3'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.1, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<Code2 className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Developer-First Experience</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Clean, simple APIs designed for developers. No complex visual builders or marketing jargon. Integrate in
|
||||
minutes, not weeks.
|
||||
</p>
|
||||
{/* Key advantages */}
|
||||
<section className={'border-t border-neutral-200 bg-neutral-50/60'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}} className={'mb-16'}>
|
||||
<h2 style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}>Key Advantages</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Why developers choose Plunk</p>
|
||||
</motion.div>
|
||||
<div className={'grid gap-px bg-neutral-200 sm:grid-cols-2 lg:grid-cols-3'}>
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.5, delay: 0.1, ease: [0.22, 1, 0.36, 1]}} className={'bg-white p-10'}>
|
||||
<div className={'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white'}><Code2 className="h-5 w-5" /></div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>Developer-First Experience</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>Clean, simple APIs designed for developers. No complex visual builders or marketing jargon. Integrate in minutes, not weeks.</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.2, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<DollarSign className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Transparent Pricing</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Pay-as-you-go pricing with no hidden costs or complex tiers. No need to pay for contact lists or profile
|
||||
counts - just emails sent.
|
||||
</p>
|
||||
</motion.div>
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.5, delay: 0.2, ease: [0.22, 1, 0.36, 1]}} className={'bg-white p-10'}>
|
||||
<div className={'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white'}><DollarSign className="h-5 w-5" /></div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>Transparent Pricing</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>Pay-as-you-go pricing with no hidden costs or complex tiers. No need to pay for contact lists or profile counts - just emails sent.</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.3, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<PackageOpen className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Open Source</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
AGPL-3.0 licensed. Inspect the code, contribute features, fork if needed. No vendor lock-in with
|
||||
proprietary platforms.
|
||||
</p>
|
||||
</motion.div>
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.5, delay: 0.3, ease: [0.22, 1, 0.36, 1]}} className={'bg-white p-10'}>
|
||||
<div className={'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white'}><PackageOpen className="h-5 w-5" /></div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>Open Source</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>AGPL-3.0 licensed. Inspect the code, contribute features, fork if needed. No vendor lock-in with proprietary platforms.</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.4, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<Zap className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Quick Setup</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Minutes to integrate and start sending. No lengthy onboarding, no sales calls, no enterprise setup
|
||||
processes. Start free immediately.
|
||||
</p>
|
||||
</motion.div>
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.5, delay: 0.4, ease: [0.22, 1, 0.36, 1]}} className={'bg-white p-10'}>
|
||||
<div className={'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white'}><Zap className="h-5 w-5" /></div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>Quick Setup</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>Minutes to integrate and start sending. No lengthy onboarding, no sales calls, no enterprise setup processes. Start free immediately.</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.5, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<Globe className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Self-Hosting Option</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Run on your infrastructure with Docker. Full data control, compliance-ready. Pay only AWS SES fees when
|
||||
self-hosting.
|
||||
</p>
|
||||
</motion.div>
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.5, delay: 0.5, ease: [0.22, 1, 0.36, 1]}} className={'bg-white p-10'}>
|
||||
<div className={'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white'}><Globe className="h-5 w-5" /></div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>Self-Hosting Option</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>Run on your infrastructure with Docker. Full data control, compliance-ready. Pay only AWS SES fees when self-hosting.</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.6, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<BarChart3 className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Simplicity at Scale</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Simple workflows that scale without over-engineering. Get enterprise capabilities without enterprise
|
||||
complexity or dedicated ops teams.
|
||||
</p>
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.5, delay: 0.6, ease: [0.22, 1, 0.36, 1]}} className={'bg-white p-10'}>
|
||||
<div className={'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white'}><BarChart3 className="h-5 w-5" /></div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>Simplicity at Scale</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>Simple workflows that scale without over-engineering. Get enterprise capabilities without enterprise complexity or dedicated ops teams.</p>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Feature comparison table */}
|
||||
<section className={'border-t border-neutral-200'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}} className={'mb-16'}>
|
||||
<h2 style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}>Feature comparison</h2>
|
||||
</motion.div>
|
||||
<ComparisonTable competitorName="Customer.io" rows={comparisonData} />
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -377,51 +190,28 @@ export default function CustomerioComparison() {
|
||||
<FAQSection faqs={faqs} schemaId="faq-schema-customerio" />
|
||||
|
||||
{/* CTA */}
|
||||
<section className={'relative overflow-hidden border-t border-neutral-200 py-32'}>
|
||||
<div
|
||||
className={
|
||||
'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#e5e7eb_1px,transparent_1px),linear-gradient(to_bottom,#e5e7eb_1px,transparent_1px)] bg-[size:4rem_4rem] [mask-image:radial-gradient(ellipse_80%_50%_at_50%_100%,#000_70%,transparent_110%)]'
|
||||
}
|
||||
/>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mx-auto max-w-3xl text-center'}
|
||||
>
|
||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>Try Plunk free</h2>
|
||||
<p className={'mt-6 text-lg text-neutral-600'}>
|
||||
1,000 emails/month free. No credit card required. Developer-friendly from day one.
|
||||
</p>
|
||||
<div className={'mt-12 flex flex-wrap justify-center gap-4'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.02}}
|
||||
whileTap={{scale: 0.98}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
className={
|
||||
'group rounded-lg bg-neutral-900 px-8 py-4 text-base font-semibold text-white transition hover:bg-neutral-800'
|
||||
}
|
||||
>
|
||||
<span className={'flex items-center gap-2'}>
|
||||
Get started free
|
||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-1" />
|
||||
</span>
|
||||
</motion.a>
|
||||
<Link
|
||||
href={WIKI_URI}
|
||||
target={'_blank'}
|
||||
className={
|
||||
'rounded-lg border border-neutral-300 px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-400'
|
||||
}
|
||||
>
|
||||
Read documentation
|
||||
</Link>
|
||||
<section className={'relative overflow-hidden border-t border-neutral-900 bg-neutral-900 text-white'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-32 sm:px-10 sm:py-40'}>
|
||||
<div className={'flex flex-col items-start gap-12 lg:flex-row lg:items-end lg:justify-between'}>
|
||||
<motion.h2 initial={{opacity: 0, y: 16}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.9, ease: [0.22, 1, 0.36, 1]}} style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2.5rem,7vw,6rem)] font-extrabold leading-[0.95] tracking-[-0.035em]'}>
|
||||
Try Plunk free
|
||||
</motion.h2>
|
||||
<motion.div initial={{opacity: 0, y: 16}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.9, delay: 0.15, ease: [0.22, 1, 0.36, 1]}} className={'flex max-w-md flex-col gap-6'}>
|
||||
<p className={'text-base text-neutral-300 sm:text-lg'}>1,000 emails/month free. No credit card required. Developer-friendly from day one.</p>
|
||||
<div className={'flex flex-wrap gap-3'}>
|
||||
<motion.a whileHover={{scale: 1.015}} whileTap={{scale: 0.985}} href={`${DASHBOARD_URI}/auth/signup`} className={'inline-flex items-center gap-2 rounded-full bg-white px-7 py-3.5 text-sm font-semibold text-neutral-900 transition hover:bg-neutral-100'}>
|
||||
Get started free <ArrowRight className="h-4 w-4" />
|
||||
</motion.a>
|
||||
<Link href={'/pricing'} className={'inline-flex items-center gap-2 rounded-full border border-neutral-700 px-7 py-3.5 text-sm font-semibold text-white transition hover:border-white'}>
|
||||
View pricing
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
</main>
|
||||
<Footer />
|
||||
</>
|
||||
);
|
||||
|
||||
+189
-187
@@ -87,9 +87,6 @@ const competitors = [
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
* Plunk vs Competitors index page
|
||||
*/
|
||||
export default function CompetitorsIndex() {
|
||||
return (
|
||||
<>
|
||||
@@ -108,220 +105,225 @@ export default function CompetitorsIndex() {
|
||||
|
||||
<Navbar />
|
||||
|
||||
<main className={'mx-auto max-w-7xl px-8 sm:px-0'}>
|
||||
{/* Hero Section */}
|
||||
<section className={'relative py-32 sm:py-48'}>
|
||||
<main className={'text-neutral-800'}>
|
||||
|
||||
{/* Hero */}
|
||||
<section className={'relative overflow-hidden'}>
|
||||
<div
|
||||
className={
|
||||
'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#e5e7eb_1px,transparent_1px),linear-gradient(to_bottom,#e5e7eb_1px,transparent_1px)] bg-[size:4rem_4rem] [mask-image:radial-gradient(ellipse_80%_50%_at_50%_0%,#000_70%,transparent_110%)]'
|
||||
}
|
||||
aria-hidden
|
||||
className={'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#eeeeee_1px,transparent_1px),linear-gradient(to_bottom,#eeeeee_1px,transparent_1px)] bg-[size:6rem_6rem] [mask-image:radial-gradient(ellipse_70%_60%_at_50%_30%,#000_40%,transparent_95%)]'}
|
||||
/>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
animate={{opacity: 1, y: 0}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mx-auto max-w-4xl text-center'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'mb-6 inline-flex items-center gap-2 rounded-full border border-neutral-200 bg-white px-4 py-2'
|
||||
}
|
||||
<div className={'mx-auto max-w-[88rem] px-6 pb-20 pt-20 sm:px-10 sm:pt-28 sm:pb-28'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 16}}
|
||||
animate={{opacity: 1, y: 0}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
>
|
||||
<span className={'text-sm text-neutral-600'}>Email Platform Comparisons</span>
|
||||
</div>
|
||||
|
||||
<h1 className={'text-6xl font-bold tracking-tight text-neutral-900 sm:text-7xl lg:text-8xl text-balance'}>
|
||||
Plunk vs the
|
||||
<br />
|
||||
competition
|
||||
</h1>
|
||||
|
||||
<p className={'mx-auto mt-8 max-w-2xl text-xl text-neutral-600'}>
|
||||
Most email platforms charge by the contact, lock you in, and split transactional from marketing. Plunk does all three in one open-source platform at $0.001 per email.
|
||||
</p>
|
||||
|
||||
<div className={'mt-12 flex flex-wrap justify-center gap-4'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.02}}
|
||||
whileTap={{scale: 0.98}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
className={
|
||||
'group rounded-lg bg-neutral-900 px-8 py-4 text-base font-semibold text-white shadow-lg shadow-neutral-900/10 transition hover:bg-neutral-800'
|
||||
}
|
||||
<div style={{fontFamily: 'var(--font-mono)'}} className={'mb-6 text-[11px] uppercase tracking-[0.18em] text-neutral-500'}>
|
||||
Comparisons
|
||||
</div>
|
||||
<h1
|
||||
style={{fontFamily: 'var(--font-display)'}}
|
||||
className={'text-[clamp(2.75rem,7vw,6.5rem)] font-extrabold leading-[0.92] tracking-[-0.04em] text-neutral-900'}
|
||||
>
|
||||
<span className={'flex items-center gap-2'}>
|
||||
Get started free
|
||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-1" />
|
||||
</span>
|
||||
</motion.a>
|
||||
<Link
|
||||
href={WIKI_URI}
|
||||
target={'_blank'}
|
||||
className={
|
||||
'rounded-lg border border-neutral-300 bg-white px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-400'
|
||||
}
|
||||
>
|
||||
View documentation
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
</section>
|
||||
|
||||
{/* Competitors Grid */}
|
||||
<section className={'py-32'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-16 text-center'}
|
||||
>
|
||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>
|
||||
Compare Plunk with Industry Leaders
|
||||
</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>See how Plunk stacks up against popular email platforms</p>
|
||||
</motion.div>
|
||||
|
||||
<div className={'grid gap-8 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4'}>
|
||||
{competitors.map((competitor, index) => (
|
||||
<Link key={competitor.slug} href={`/vs/${competitor.slug}`}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: index * 0.1, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={
|
||||
'group rounded-2xl border border-neutral-200 bg-white p-8 transition hover:border-neutral-300 hover:shadow-lg cursor-pointer'
|
||||
}
|
||||
Plunk vs the
|
||||
<br />
|
||||
competition.
|
||||
</h1>
|
||||
<p className={'mt-6 max-w-2xl text-xl text-neutral-600'}>
|
||||
Most email platforms charge by the contact, lock you in, and split transactional from marketing. Plunk does all three in one open-source platform at $0.001 per email.
|
||||
</p>
|
||||
<div className={'mt-10 flex flex-wrap gap-3'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.015}}
|
||||
whileTap={{scale: 0.985}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
className={'group inline-flex items-center gap-2 rounded-full bg-neutral-900 px-8 py-4 text-base font-semibold text-white shadow-[0_10px_30px_-10px_rgba(23,23,23,0.35)] transition hover:bg-neutral-800'}
|
||||
>
|
||||
<div className={'mb-4 flex items-center justify-between'}>
|
||||
<h3 className={'text-xl font-bold text-neutral-900'}>{competitor.name}</h3>
|
||||
</div>
|
||||
<p className={'mb-6 leading-relaxed text-neutral-600'}>{competitor.description}</p>
|
||||
<div className={'mb-6 space-y-2'}>
|
||||
{competitor.features.map(feature => (
|
||||
<div key={feature} className={'flex items-center gap-2 text-sm text-neutral-600'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-neutral-900'} />
|
||||
<span>{feature}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</motion.div>
|
||||
</Link>
|
||||
))}
|
||||
Get started free
|
||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-0.5" />
|
||||
</motion.a>
|
||||
<Link
|
||||
href={WIKI_URI}
|
||||
target={'_blank'}
|
||||
className={'inline-flex items-center gap-2 rounded-full border border-neutral-300 bg-white px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-900'}
|
||||
>
|
||||
View documentation
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Why Choose Plunk */}
|
||||
<section className={'py-32'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-16 text-center'}
|
||||
>
|
||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>Why Choose Plunk</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>One platform for all your email needs</p>
|
||||
</motion.div>
|
||||
|
||||
<div className={'grid gap-8 lg:grid-cols-3'}>
|
||||
{/* Competitors grid */}
|
||||
<section className={'border-t border-neutral-200'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.1, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={
|
||||
'rounded-2xl border border-neutral-200 bg-white p-8 transition hover:border-neutral-300 hover:shadow-lg'
|
||||
}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-16'}
|
||||
>
|
||||
<Mail className="h-8 w-8 text-neutral-900 mb-4" />
|
||||
<h3 className={'text-2xl font-bold text-neutral-900'}>Transactional + Marketing</h3>
|
||||
<p className={'mt-4 leading-relaxed text-neutral-600'}>
|
||||
Send transactional emails with the same reliability as dedicated providers, plus marketing campaigns, automation, and segmentation. All in one platform.
|
||||
</p>
|
||||
<h2
|
||||
style={{fontFamily: 'var(--font-display)'}}
|
||||
className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}
|
||||
>
|
||||
All comparisons
|
||||
</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>See how Plunk stacks up against popular email platforms</p>
|
||||
</motion.div>
|
||||
|
||||
<div className={'grid gap-4 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4'}>
|
||||
{competitors.map((competitor, index) => (
|
||||
<motion.div
|
||||
key={competitor.slug}
|
||||
initial={{opacity: 0, y: 16}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: index * 0.04, ease: [0.22, 1, 0.36, 1]}}
|
||||
>
|
||||
<Link
|
||||
href={`/vs/${competitor.slug}`}
|
||||
className={'group flex min-h-[14rem] flex-col justify-between rounded-[28px] border border-neutral-200 bg-white p-8 transition hover:border-neutral-900'}
|
||||
>
|
||||
<div className={'flex items-start justify-between'}>
|
||||
<h3
|
||||
style={{fontFamily: 'var(--font-display)'}}
|
||||
className={'text-xl font-bold tracking-[-0.02em] text-neutral-900'}
|
||||
>
|
||||
{competitor.name}
|
||||
</h3>
|
||||
<ArrowRight className="h-4 w-4 text-neutral-400 transition-transform group-hover:translate-x-0.5 group-hover:text-neutral-900" />
|
||||
</div>
|
||||
<div>
|
||||
<p className={'text-sm text-neutral-600'}>{competitor.description}</p>
|
||||
<div className={'mt-4 flex flex-wrap gap-1.5'}>
|
||||
{competitor.features.map(feature => (
|
||||
<span
|
||||
key={feature}
|
||||
style={{fontFamily: 'var(--font-mono)'}}
|
||||
className={'text-[10px] uppercase tracking-[0.12em] text-neutral-400'}
|
||||
>
|
||||
{feature}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Why Plunk */}
|
||||
<section className={'border-t border-neutral-200 bg-neutral-50/60'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.2, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={
|
||||
'rounded-2xl border border-neutral-200 bg-white p-8 transition hover:border-neutral-300 hover:shadow-lg'
|
||||
}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-16'}
|
||||
>
|
||||
<Code className="h-8 w-8 text-neutral-900 mb-4" />
|
||||
<h3 className={'text-2xl font-bold text-neutral-900'}>Open Source & Self-Hostable</h3>
|
||||
<p className={'mt-4 leading-relaxed text-neutral-600'}>
|
||||
AGPL-3.0 licensed code you can inspect, modify, and self-host. Full control over your data and
|
||||
infrastructure. No vendor lock-in.
|
||||
</p>
|
||||
<h2
|
||||
style={{fontFamily: 'var(--font-display)'}}
|
||||
className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}
|
||||
>
|
||||
Why Plunk wins
|
||||
</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>One platform for all your email needs</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.3, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={
|
||||
'rounded-2xl border border-neutral-200 bg-white p-8 transition hover:border-neutral-300 hover:shadow-lg'
|
||||
}
|
||||
>
|
||||
<DollarSign className="h-8 w-8 text-neutral-900 mb-4" />
|
||||
<h3 className={'text-2xl font-bold text-neutral-900'}>Simple Pricing</h3>
|
||||
<p className={'mt-4 leading-relaxed text-neutral-600'}>
|
||||
Pay-as-you-go pricing with all features included. No separate charges for transactional vs marketing
|
||||
emails. No tiers, no commitments.
|
||||
</p>
|
||||
</motion.div>
|
||||
<div className={'grid gap-px bg-neutral-200 sm:grid-cols-3'}>
|
||||
{[
|
||||
{
|
||||
icon: <Mail className="h-5 w-5" />,
|
||||
title: 'Transactional + Marketing',
|
||||
body: 'Send transactional emails with the same reliability as dedicated providers, plus marketing campaigns, automation, and segmentation. All in one platform.',
|
||||
},
|
||||
{
|
||||
icon: <Code className="h-5 w-5" />,
|
||||
title: 'Open Source & Self-Hostable',
|
||||
body: 'AGPL-3.0 licensed code you can inspect, modify, and self-host. Full control over your data and infrastructure. No vendor lock-in.',
|
||||
},
|
||||
{
|
||||
icon: <DollarSign className="h-5 w-5" />,
|
||||
title: 'Simple Pricing',
|
||||
body: 'Pay-as-you-go with all features included. No separate charges for transactional vs marketing emails. No tiers, no commitments.',
|
||||
},
|
||||
].map((item, i) => (
|
||||
<motion.div
|
||||
key={item.title}
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: i * 0.1, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'bg-white p-10'}
|
||||
>
|
||||
<div className={'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white'}>
|
||||
{item.icon}
|
||||
</div>
|
||||
<h3
|
||||
style={{fontFamily: 'var(--font-display)'}}
|
||||
className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}
|
||||
>
|
||||
{item.title}
|
||||
</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>{item.body}</p>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* CTA */}
|
||||
<section className={'relative overflow-hidden border-t border-neutral-200 py-32'}>
|
||||
<div
|
||||
className={
|
||||
'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#e5e7eb_1px,transparent_1px),linear-gradient(to_bottom,#e5e7eb_1px,transparent_1px)] bg-[size:4rem_4rem] [mask-image:radial-gradient(ellipse_80%_50%_at_50%_100%,#000_70%,transparent_110%)]'
|
||||
}
|
||||
/>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mx-auto max-w-3xl text-center'}
|
||||
>
|
||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>Ready to try Plunk?</h2>
|
||||
<p className={'mt-6 text-lg text-neutral-600'}>
|
||||
Join thousands of developers using Plunk for reliable email delivery. Start free, scale as you grow.
|
||||
</p>
|
||||
<div className={'mt-12 flex flex-wrap justify-center gap-4'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.02}}
|
||||
whileTap={{scale: 0.98}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
className={
|
||||
'group rounded-lg bg-neutral-900 px-8 py-4 text-base font-semibold text-white transition hover:bg-neutral-800'
|
||||
}
|
||||
<section className={'relative overflow-hidden border-t border-neutral-900 bg-neutral-900 text-white'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-32 sm:px-10 sm:py-40'}>
|
||||
<div className={'flex flex-col items-start gap-12 lg:flex-row lg:items-end lg:justify-between'}>
|
||||
<motion.h2
|
||||
initial={{opacity: 0, y: 16}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.9, ease: [0.22, 1, 0.36, 1]}}
|
||||
style={{fontFamily: 'var(--font-display)'}}
|
||||
className={'text-[clamp(2.5rem,7vw,6rem)] font-extrabold leading-[0.95] tracking-[-0.035em]'}
|
||||
>
|
||||
<span className={'flex items-center gap-2'}>
|
||||
Get started free
|
||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-1" />
|
||||
</span>
|
||||
</motion.a>
|
||||
<Link
|
||||
href="/pricing"
|
||||
className={
|
||||
'rounded-lg border border-neutral-300 px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-400'
|
||||
}
|
||||
Ready to try Plunk?
|
||||
</motion.h2>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 16}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.9, delay: 0.15, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'flex max-w-md flex-col gap-6'}
|
||||
>
|
||||
View pricing
|
||||
</Link>
|
||||
<p className={'text-base text-neutral-300 sm:text-lg'}>
|
||||
Start free. No credit card required.
|
||||
</p>
|
||||
<div className={'flex flex-wrap gap-3'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.015}}
|
||||
whileTap={{scale: 0.985}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
className={'inline-flex items-center gap-2 rounded-full bg-white px-7 py-3.5 text-sm font-semibold text-neutral-900 transition hover:bg-neutral-100'}
|
||||
>
|
||||
Get started free
|
||||
<ArrowRight className="h-4 w-4" />
|
||||
</motion.a>
|
||||
<Link
|
||||
href={'/pricing'}
|
||||
className={'inline-flex items-center gap-2 rounded-full border border-neutral-700 px-7 py-3.5 text-sm font-semibold text-white transition hover:border-white'}
|
||||
>
|
||||
View pricing
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</main>
|
||||
|
||||
<Footer />
|
||||
|
||||
@@ -4,7 +4,7 @@ import {DASHBOARD_URI, WIKI_URI} from '../../lib/constants';
|
||||
import React from 'react';
|
||||
import Link from 'next/link';
|
||||
import {NextSeo} from 'next-seo';
|
||||
import {ArrowRight, Code2, DollarSign, Globe, Package, PackageOpen, Zap} from 'lucide-react';
|
||||
import {ArrowRight, Check, Code2, DollarSign, Globe, Package, PackageOpen, Zap} from 'lucide-react';
|
||||
import type {ComparisonRow} from '../../components/ComparisonTable';
|
||||
import type {FAQ} from '../../components/FAQSection';
|
||||
|
||||
@@ -49,9 +49,6 @@ const faqs: FAQ[] = [
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
* Plunk vs Klaviyo comparison page
|
||||
*/
|
||||
export default function KlaviyoComparison() {
|
||||
return (
|
||||
<>
|
||||
@@ -70,368 +67,132 @@ export default function KlaviyoComparison() {
|
||||
|
||||
<Navbar />
|
||||
|
||||
<main className={'mx-auto max-w-7xl px-8 sm:px-0'}>
|
||||
{/* Hero Section */}
|
||||
<section className={'relative py-32 sm:py-48'}>
|
||||
<div
|
||||
className={
|
||||
'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#e5e7eb_1px,transparent_1px),linear-gradient(to_bottom,#e5e7eb_1px,transparent_1px)] bg-[size:4rem_4rem] [mask-image:radial-gradient(ellipse_80%_50%_at_50%_0%,#000_70%,transparent_110%)]'
|
||||
}
|
||||
/>
|
||||
<main className={'text-neutral-800'}>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
animate={{opacity: 1, y: 0}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mx-auto max-w-4xl text-center'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'mb-6 inline-flex items-center gap-2 rounded-full border border-neutral-200 bg-white px-4 py-2'
|
||||
}
|
||||
>
|
||||
<span className={'text-sm text-neutral-600'}>Comparing</span>
|
||||
<span className={'text-sm font-semibold text-neutral-900'}>Plunk vs Klaviyo</span>
|
||||
</div>
|
||||
|
||||
<h1 className={'text-6xl font-bold tracking-tight text-neutral-900 sm:text-7xl lg:text-8xl text-balance'}>
|
||||
Open-source alternative
|
||||
<br />
|
||||
for Klaviyo
|
||||
</h1>
|
||||
|
||||
<p className={'mx-auto mt-8 max-w-2xl text-xl text-neutral-600'}>
|
||||
Klaviyo is powerful for e-commerce but extremely expensive. Plunk delivers the same email automation, including full e-commerce support, at a fraction of the cost. No hidden fees, no contact-based pricing.
|
||||
</p>
|
||||
|
||||
<div className={'mt-12 flex flex-wrap justify-center gap-4'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.02}}
|
||||
whileTap={{scale: 0.98}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
className={
|
||||
'group rounded-lg bg-neutral-900 px-8 py-4 text-base font-semibold text-white shadow-lg shadow-neutral-900/10 transition hover:bg-neutral-800'
|
||||
}
|
||||
>
|
||||
<span className={'flex items-center gap-2'}>
|
||||
Get started free
|
||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-1" />
|
||||
</span>
|
||||
</motion.a>
|
||||
<Link
|
||||
href={WIKI_URI}
|
||||
target={'_blank'}
|
||||
className={
|
||||
'rounded-lg border border-neutral-300 bg-white px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-400'
|
||||
}
|
||||
>
|
||||
View documentation
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
</section>
|
||||
|
||||
{/* Pricing Model Comparison */}
|
||||
<section className={'py-32'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-16 text-center'}
|
||||
>
|
||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>
|
||||
E-commerce Email Without the Premium Price
|
||||
</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Pay for emails sent, not contacts stored</p>
|
||||
</motion.div>
|
||||
|
||||
<div className={'grid gap-8 lg:grid-cols-2'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, x: -20}}
|
||||
whileInView={{opacity: 1, x: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'rounded-2xl border-2 border-neutral-900 bg-white p-10'}
|
||||
>
|
||||
<div className={'mb-4 inline-flex items-center gap-2 rounded-full bg-neutral-900 px-4 py-1.5'}>
|
||||
<span className={'text-sm font-semibold text-white'}>Plunk</span>
|
||||
{/* Hero */}
|
||||
<section className={'relative overflow-hidden'}>
|
||||
<div aria-hidden className={'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#eeeeee_1px,transparent_1px),linear-gradient(to_bottom,#eeeeee_1px,transparent_1px)] bg-[size:6rem_6rem] [mask-image:radial-gradient(ellipse_70%_60%_at_50%_30%,#000_40%,transparent_95%)]'} />
|
||||
<div className={'mx-auto max-w-[88rem] px-6 pb-20 pt-20 sm:px-10 sm:pt-28 sm:pb-28'}>
|
||||
<motion.div initial={{opacity: 0, y: 16}} animate={{opacity: 1, y: 0}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}>
|
||||
<div style={{fontFamily: 'var(--font-mono)'}} className={'mb-6 text-[11px] uppercase tracking-[0.18em] text-neutral-500'}>
|
||||
Plunk vs Klaviyo
|
||||
</div>
|
||||
<h3 className={'mt-6 text-2xl font-bold text-neutral-900'}>Pay per email sent</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Pay-as-you-go pricing. Only pay for emails sent, not contacts stored. Predictable costs as you scale.
|
||||
</p>
|
||||
<div className={'mt-6 text-4xl font-bold text-neutral-900'}>Pay-as-you-go</div>
|
||||
<div className={'mt-8 space-y-3'}>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-900 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-white'} />
|
||||
</div>
|
||||
<span>Unlimited contacts at no extra cost</span>
|
||||
</div>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-900 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-white'} />
|
||||
</div>
|
||||
<span>No surprise charges as you grow</span>
|
||||
</div>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-900 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-white'} />
|
||||
</div>
|
||||
<span>Typical savings: 60-90% vs Klaviyo</span>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, x: 20}}
|
||||
whileInView={{opacity: 1, x: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'rounded-2xl border border-neutral-200 bg-neutral-50 p-10'}
|
||||
>
|
||||
<div className={'mb-4 inline-flex items-center gap-2 rounded-full bg-neutral-200 px-4 py-1.5'}>
|
||||
<span className={'text-sm font-semibold text-neutral-900'}>Klaviyo</span>
|
||||
</div>
|
||||
<h3 className={'mt-6 text-2xl font-bold text-neutral-900'}>Contact-based tiers</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Expensive pricing based on contact count. Costs escalate quickly as your list grows.
|
||||
</p>
|
||||
<div className={'mt-6 text-4xl font-bold text-neutral-900'}>From $20/month</div>
|
||||
<div className={'mt-8 space-y-3'}>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-300 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-neutral-600'} />
|
||||
</div>
|
||||
<span>10K contacts = $150-300+/month</span>
|
||||
</div>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-300 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-neutral-600'} />
|
||||
</div>
|
||||
<span>Price increases with contact list growth</span>
|
||||
</div>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-300 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-neutral-600'} />
|
||||
</div>
|
||||
<span>Hidden costs for additional features</span>
|
||||
</div>
|
||||
<h1 style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2.75rem,7vw,6.5rem)] font-extrabold leading-[0.92] tracking-[-0.04em] text-neutral-900'}>
|
||||
Open-source alternative
|
||||
<br />
|
||||
for Klaviyo
|
||||
</h1>
|
||||
<p className={'mt-6 max-w-2xl text-xl text-neutral-600'}>Klaviyo is powerful for e-commerce but extremely expensive. Plunk delivers the same email automation, including full e-commerce support, at a fraction of the cost. No hidden fees, no contact-based pricing.</p>
|
||||
<div className={'mt-10 flex flex-wrap gap-3'}>
|
||||
<motion.a whileHover={{scale: 1.015}} whileTap={{scale: 0.985}} href={`${DASHBOARD_URI}/auth/signup`} className={'group inline-flex items-center gap-2 rounded-full bg-neutral-900 px-8 py-4 text-base font-semibold text-white shadow-[0_10px_30px_-10px_rgba(23,23,23,0.35)] transition hover:bg-neutral-800'}>
|
||||
Get started free <ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-0.5" />
|
||||
</motion.a>
|
||||
<Link href={WIKI_URI} target={'_blank'} className={'inline-flex items-center gap-2 rounded-full border border-neutral-300 bg-white px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-900'}>
|
||||
View documentation
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Key Advantages */}
|
||||
<section className={'py-32'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-20 text-center'}
|
||||
>
|
||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>
|
||||
E-commerce Email, Developer-Friendly
|
||||
</h2>
|
||||
</motion.div>
|
||||
|
||||
<div className={'grid gap-px bg-neutral-200 sm:grid-cols-2 lg:grid-cols-3'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.1, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<DollarSign className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Affordable Pricing</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Pay-as-you-go instead of expensive contact-based tiers. Save 60-90% compared to Klaviyo while getting
|
||||
the same email automation power.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.2, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<Package className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>E-commerce Ready</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Handle order confirmations, shipping notifications, abandoned carts, and product campaigns. All
|
||||
e-commerce email use cases via flexible API.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.3, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<Code2 className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Developer-Friendly</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Modern API designed for developers. Integrate with Shopify, WooCommerce, or any e-commerce platform via
|
||||
webhooks and API calls.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.4, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<PackageOpen className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Open Source</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
AGPL-3.0 licensed. Full transparency into how your emails work. No black-box algorithms or proprietary
|
||||
systems. Klaviyo is closed-source.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.5, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<Globe className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Self-Hostable</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Run on your infrastructure with Docker. Full data ownership, compliance control, cost optimization at
|
||||
scale. Klaviyo is cloud-only.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.6, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<Zap className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Simple Integration</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Connect your store via webhooks or API. No complex Shopify app to configure. Build exactly the
|
||||
integration you need with full control.
|
||||
</p>
|
||||
{/* Pricing comparison */}
|
||||
<section className={'border-t border-neutral-200'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}} className={'mb-16'}>
|
||||
<h2 style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}>
|
||||
E-commerce Email Without the Premium Price
|
||||
</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Pay for emails sent, not contacts stored</p>
|
||||
</motion.div>
|
||||
<div className={'grid gap-4 lg:grid-cols-2'}>
|
||||
<motion.div initial={{opacity: 0, x: -20}} whileInView={{opacity: 1, x: 0}} viewport={{once: true}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}} className={'rounded-[24px] border border-neutral-900 bg-neutral-900 p-10 text-white'}>
|
||||
<div style={{fontFamily: 'var(--font-mono)'}} className={'text-[11px] uppercase tracking-[0.18em] text-neutral-400'}>Plunk</div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-2xl font-bold tracking-[-0.025em] text-white'}>Pay per email sent</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-300'}>Pay-as-you-go pricing. Only pay for emails sent, not contacts stored. Predictable costs as you scale.</p>
|
||||
<div style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-4xl font-extrabold tracking-[-0.03em] text-white'}>Pay-as-you-go</div>
|
||||
<ul className={'mt-8 space-y-3'}>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-300'}><Check className="h-4 w-4 flex-shrink-0 text-neutral-400" />Unlimited contacts at no extra cost</li>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-300'}><Check className="h-4 w-4 flex-shrink-0 text-neutral-400" />No surprise charges as you grow</li>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-300'}><Check className="h-4 w-4 flex-shrink-0 text-neutral-400" />Typical savings: 60-90% vs Klaviyo</li>
|
||||
</ul>
|
||||
</motion.div>
|
||||
<motion.div initial={{opacity: 0, x: 20}} whileInView={{opacity: 1, x: 0}} viewport={{once: true}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}} className={'rounded-[24px] border border-neutral-200 bg-white p-10'}>
|
||||
<div style={{fontFamily: 'var(--font-mono)'}} className={'text-[11px] uppercase tracking-[0.18em] text-neutral-500'}>Klaviyo</div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-2xl font-bold tracking-[-0.025em] text-neutral-900'}>Contact-based tiers</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>Expensive pricing based on contact count. Costs escalate quickly as your list grows.</p>
|
||||
<div style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-4xl font-extrabold tracking-[-0.03em] text-neutral-900'}>From $20/month</div>
|
||||
<ul className={'mt-8 space-y-3'}>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-600'}><div className={'h-1.5 w-1.5 flex-shrink-0 rounded-full bg-neutral-400'} />10K contacts = $150-300+/month</li>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-600'}><div className={'h-1.5 w-1.5 flex-shrink-0 rounded-full bg-neutral-400'} />Price increases with contact list growth</li>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-600'}><div className={'h-1.5 w-1.5 flex-shrink-0 rounded-full bg-neutral-400'} />Hidden costs for additional features</li>
|
||||
</ul>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Feature Comparison */}
|
||||
<section className={'py-32'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-16 text-center'}
|
||||
>
|
||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>Feature Comparison</h2>
|
||||
</motion.div>
|
||||
{/* Key advantages */}
|
||||
<section className={'border-t border-neutral-200 bg-neutral-50/60'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}} className={'mb-16'}>
|
||||
<h2 style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}>E-commerce Email, Developer-Friendly</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>All the automation power, at a fraction of the cost</p>
|
||||
</motion.div>
|
||||
<div className={'grid gap-px bg-neutral-200 sm:grid-cols-2 lg:grid-cols-3'}>
|
||||
{[
|
||||
{icon: <DollarSign className="h-5 w-5" />, title: 'Affordable Pricing', body: 'Pay-as-you-go instead of expensive contact-based tiers. Save 60-90% compared to Klaviyo while getting the same email automation power.'},
|
||||
{icon: <Package className="h-5 w-5" />, title: 'E-commerce Ready', body: 'Handle order confirmations, shipping notifications, abandoned carts, and product campaigns. All e-commerce email use cases via flexible API.'},
|
||||
{icon: <Code2 className="h-5 w-5" />, title: 'Developer-Friendly', body: 'Modern API designed for developers. Integrate with Shopify, WooCommerce, or any e-commerce platform via webhooks and API calls.'},
|
||||
{icon: <PackageOpen className="h-5 w-5" />, title: 'Open Source', body: 'AGPL-3.0 licensed. Full transparency into how your emails work. No black-box algorithms or proprietary systems. Klaviyo is closed-source.'},
|
||||
{icon: <Globe className="h-5 w-5" />, title: 'Self-Hostable', body: 'Run on your infrastructure with Docker. Full data ownership, compliance control, cost optimization at scale. Klaviyo is cloud-only.'},
|
||||
{icon: <Zap className="h-5 w-5" />, title: 'Simple Integration', body: 'Connect your store via webhooks or API. No complex Shopify app to configure. Build exactly the integration you need with full control.'},
|
||||
].map((item, i) => (
|
||||
<motion.div key={item.title} initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.5, delay: i * 0.1, ease: [0.22, 1, 0.36, 1]}} className={'bg-white p-10'}>
|
||||
<div className={'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white'}>{item.icon}</div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>{item.title}</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>{item.body}</p>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<ComparisonTable competitorName="Klaviyo" rows={comparisonData} />
|
||||
{/* Feature comparison table */}
|
||||
<section className={'border-t border-neutral-200'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}} className={'mb-16'}>
|
||||
<h2 style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}>Feature comparison</h2>
|
||||
</motion.div>
|
||||
<ComparisonTable competitorName="Klaviyo" rows={comparisonData} />
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* FAQ */}
|
||||
<FAQSection faqs={faqs} schemaId="faq-schema-klaviyo" />
|
||||
|
||||
{/* CTA */}
|
||||
<section className={'relative overflow-hidden border-t border-neutral-200 py-32'}>
|
||||
<div
|
||||
className={
|
||||
'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#e5e7eb_1px,transparent_1px),linear-gradient(to_bottom,#e5e7eb_1px,transparent_1px)] bg-[size:4rem_4rem] [mask-image:radial-gradient(ellipse_80%_50%_at_50%_100%,#000_70%,transparent_110%)]'
|
||||
}
|
||||
/>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mx-auto max-w-3xl text-center'}
|
||||
>
|
||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>
|
||||
E-commerce email at a fraction of the cost
|
||||
</h2>
|
||||
<p className={'mt-6 text-lg text-neutral-600'}>
|
||||
Join e-commerce developers who've switched from Klaviyo to Plunk for dramatic cost savings and better API
|
||||
design.
|
||||
</p>
|
||||
<div className={'mt-12 flex flex-wrap justify-center gap-4'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.02}}
|
||||
whileTap={{scale: 0.98}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
className={
|
||||
'group rounded-lg bg-neutral-900 px-8 py-4 text-base font-semibold text-white transition hover:bg-neutral-800'
|
||||
}
|
||||
>
|
||||
<span className={'flex items-center gap-2'}>
|
||||
Get started free
|
||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-1" />
|
||||
</span>
|
||||
</motion.a>
|
||||
<Link
|
||||
href="/pricing"
|
||||
className={
|
||||
'rounded-lg border border-neutral-300 px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-400'
|
||||
}
|
||||
>
|
||||
View pricing
|
||||
</Link>
|
||||
<section className={'relative overflow-hidden border-t border-neutral-900 bg-neutral-900 text-white'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-32 sm:px-10 sm:py-40'}>
|
||||
<div className={'flex flex-col items-start gap-12 lg:flex-row lg:items-end lg:justify-between'}>
|
||||
<motion.h2 initial={{opacity: 0, y: 16}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.9, ease: [0.22, 1, 0.36, 1]}} style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2.5rem,7vw,6rem)] font-extrabold leading-[0.95] tracking-[-0.035em]'}>
|
||||
E-commerce email at a fraction of the cost.
|
||||
</motion.h2>
|
||||
<motion.div initial={{opacity: 0, y: 16}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.9, delay: 0.15, ease: [0.22, 1, 0.36, 1]}} className={'flex max-w-md flex-col gap-6'}>
|
||||
<p className={'text-base text-neutral-300 sm:text-lg'}>Save 60-90% vs Klaviyo. Open-source, self-hostable, pay-as-you-go. No contact-based tiers. Start free.</p>
|
||||
<div className={'flex flex-wrap gap-3'}>
|
||||
<motion.a whileHover={{scale: 1.015}} whileTap={{scale: 0.985}} href={`${DASHBOARD_URI}/auth/signup`} className={'inline-flex items-center gap-2 rounded-full bg-white px-7 py-3.5 text-sm font-semibold text-neutral-900 transition hover:bg-neutral-100'}>
|
||||
Get started free <ArrowRight className="h-4 w-4" />
|
||||
</motion.a>
|
||||
<Link href={'/pricing'} className={'inline-flex items-center gap-2 rounded-full border border-neutral-700 px-7 py-3.5 text-sm font-semibold text-white transition hover:border-white'}>
|
||||
View pricing
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
</main>
|
||||
<Footer />
|
||||
</>
|
||||
);
|
||||
|
||||
+127
-340
@@ -4,7 +4,7 @@ import {DASHBOARD_URI, WIKI_URI} from '../../lib/constants';
|
||||
import React from 'react';
|
||||
import Link from 'next/link';
|
||||
import {NextSeo} from 'next-seo';
|
||||
import {ArrowRight, BarChart3, DollarSign, Globe, PackageOpen, Users, Zap} from 'lucide-react';
|
||||
import {ArrowRight, BarChart3, Check, DollarSign, Globe, PackageOpen, Users, Zap} from 'lucide-react';
|
||||
import type {ComparisonRow} from '../../components/ComparisonTable';
|
||||
import type {FAQ} from '../../components/FAQSection';
|
||||
|
||||
@@ -69,366 +69,153 @@ export default function LoopsComparison() {
|
||||
|
||||
<Navbar />
|
||||
|
||||
<main className={'mx-auto max-w-7xl px-8 sm:px-0'}>
|
||||
{/* Hero Section */}
|
||||
<section className={'relative py-32 sm:py-48'}>
|
||||
<div
|
||||
className={
|
||||
'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#e5e7eb_1px,transparent_1px),linear-gradient(to_bottom,#e5e7eb_1px,transparent_1px)] bg-[size:4rem_4rem] [mask-image:radial-gradient(ellipse_80%_50%_at_50%_0%,#000_70%,transparent_110%)]'
|
||||
}
|
||||
/>
|
||||
<main className={'text-neutral-800'}>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
animate={{opacity: 1, y: 0}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mx-auto max-w-4xl text-center'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'mb-6 inline-flex items-center gap-2 rounded-full border border-neutral-200 bg-white px-4 py-2'
|
||||
}
|
||||
>
|
||||
<span className={'text-sm text-neutral-600'}>Comparing</span>
|
||||
<span className={'text-sm font-semibold text-neutral-900'}>Plunk vs Loops</span>
|
||||
</div>
|
||||
|
||||
<h1 className={'text-6xl font-bold tracking-tight text-neutral-900 sm:text-7xl lg:text-8xl text-balance'}>
|
||||
Open-source alternative
|
||||
<br />
|
||||
for Loops
|
||||
</h1>
|
||||
|
||||
<p className={'mx-auto mt-8 max-w-2xl text-xl text-neutral-600'}>
|
||||
Same modern features, but open-source and self-hostable. No contact limits, no proprietary lock-in, no
|
||||
hidden costs. Built for transparency.
|
||||
</p>
|
||||
|
||||
<div className={'mt-12 flex flex-wrap justify-center gap-4'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.02}}
|
||||
whileTap={{scale: 0.98}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
className={
|
||||
'group rounded-lg bg-neutral-900 px-8 py-4 text-base font-semibold text-white shadow-lg shadow-neutral-900/10 transition hover:bg-neutral-800'
|
||||
}
|
||||
>
|
||||
<span className={'flex items-center gap-2'}>
|
||||
Get started free
|
||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-1" />
|
||||
</span>
|
||||
</motion.a>
|
||||
<Link
|
||||
href={WIKI_URI}
|
||||
target={'_blank'}
|
||||
className={
|
||||
'rounded-lg border border-neutral-300 bg-white px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-400'
|
||||
}
|
||||
>
|
||||
View documentation
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
</section>
|
||||
|
||||
{/* Pricing Model Comparison */}
|
||||
<section className={'py-32'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-16 text-center'}
|
||||
>
|
||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>
|
||||
Transparent Pricing vs Vendor Lock-In
|
||||
</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Pay per email, not per contact</p>
|
||||
</motion.div>
|
||||
|
||||
<div className={'grid gap-8 lg:grid-cols-2'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, x: -20}}
|
||||
whileInView={{opacity: 1, x: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'rounded-2xl border-2 border-neutral-900 bg-white p-10'}
|
||||
>
|
||||
<div className={'mb-4 inline-flex items-center gap-2 rounded-full bg-neutral-900 px-4 py-1.5'}>
|
||||
<span className={'text-sm font-semibold text-white'}>Plunk</span>
|
||||
{/* Hero */}
|
||||
<section className={'relative overflow-hidden'}>
|
||||
<div aria-hidden className={'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#eeeeee_1px,transparent_1px),linear-gradient(to_bottom,#eeeeee_1px,transparent_1px)] bg-[size:6rem_6rem] [mask-image:radial-gradient(ellipse_70%_60%_at_50%_30%,#000_40%,transparent_95%)]'} />
|
||||
<div className={'mx-auto max-w-[88rem] px-6 pb-20 pt-20 sm:px-10 sm:pt-28 sm:pb-28'}>
|
||||
<motion.div initial={{opacity: 0, y: 16}} animate={{opacity: 1, y: 0}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}>
|
||||
<div style={{fontFamily: 'var(--font-mono)'}} className={'mb-6 text-[11px] uppercase tracking-[0.18em] text-neutral-500'}>
|
||||
Plunk vs Loops
|
||||
</div>
|
||||
<h3 className={'mt-6 text-2xl font-bold text-neutral-900'}>Pay per email sent</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Pay-as-you-go pricing with unlimited contacts. No monthly commitments or contact-based limits.
|
||||
</p>
|
||||
<div className={'mt-6 text-4xl font-bold text-neutral-900'}>$0.001/email</div>
|
||||
<div className={'mt-8 space-y-3'}>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-900 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-white'} />
|
||||
</div>
|
||||
<span>Unlimited contacts at no extra cost</span>
|
||||
</div>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-900 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-white'} />
|
||||
</div>
|
||||
<span>All features included on all plans</span>
|
||||
</div>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-900 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-white'} />
|
||||
</div>
|
||||
<span>Open-source and self-hostable</span>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, x: 20}}
|
||||
whileInView={{opacity: 1, x: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'rounded-2xl border border-neutral-200 bg-neutral-50 p-10'}
|
||||
>
|
||||
<div className={'mb-4 inline-flex items-center gap-2 rounded-full bg-neutral-200 px-4 py-1.5'}>
|
||||
<span className={'text-sm font-semibold text-neutral-900'}>Loops</span>
|
||||
</div>
|
||||
<h3 className={'mt-6 text-2xl font-bold text-neutral-900'}>Subscription tiers by contacts</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Monthly subscription based on contact count with tier-based limits and feature restrictions.
|
||||
</p>
|
||||
<div className={'mt-6 text-4xl font-bold text-neutral-900'}>Tiered pricing</div>
|
||||
<div className={'mt-8 space-y-3'}>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-300 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-neutral-600'} />
|
||||
</div>
|
||||
<span>Contact-based pricing limits</span>
|
||||
</div>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-300 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-neutral-600'} />
|
||||
</div>
|
||||
<span>Feature limits on lower tiers</span>
|
||||
</div>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-300 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-neutral-600'} />
|
||||
</div>
|
||||
<span>Proprietary, cloud-only platform</span>
|
||||
</div>
|
||||
<h1 style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2.75rem,7vw,6.5rem)] font-extrabold leading-[0.92] tracking-[-0.04em] text-neutral-900'}>
|
||||
Open-source alternative
|
||||
<br />
|
||||
for Loops
|
||||
</h1>
|
||||
<p className={'mt-6 max-w-2xl text-xl text-neutral-600'}>Same modern features, but open-source and self-hostable. No contact limits, no proprietary lock-in, no hidden costs. Built for transparency.</p>
|
||||
<div className={'mt-10 flex flex-wrap gap-3'}>
|
||||
<motion.a whileHover={{scale: 1.015}} whileTap={{scale: 0.985}} href={`${DASHBOARD_URI}/auth/signup`} className={'group inline-flex items-center gap-2 rounded-full bg-neutral-900 px-8 py-4 text-base font-semibold text-white shadow-[0_10px_30px_-10px_rgba(23,23,23,0.35)] transition hover:bg-neutral-800'}>
|
||||
Get started free <ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-0.5" />
|
||||
</motion.a>
|
||||
<Link href={WIKI_URI} target={'_blank'} className={'inline-flex items-center gap-2 rounded-full border border-neutral-300 bg-white px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-900'}>
|
||||
View documentation
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Key Advantages */}
|
||||
<section className={'py-32'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-20 text-center'}
|
||||
>
|
||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>Why Choose Plunk Over Loops</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Open-source transparency meets modern SaaS features</p>
|
||||
</motion.div>
|
||||
|
||||
<div className={'grid gap-px bg-neutral-200 sm:grid-cols-2 lg:grid-cols-3'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.1, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<PackageOpen className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Open Source & Transparent</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
AGPL-3.0 licensed. Inspect the code, contribute features, understand exactly how your emails are sent.
|
||||
No black boxes.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.2, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<Globe className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Self-Hostable</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Run on your infrastructure with Docker. Full data control, compliance-ready, cost-optimized for scale.
|
||||
Loops is cloud-only.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.3, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<Users className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Unlimited Contacts</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
No contact-based limits. Grow your audience without worrying about tier upgrades or surprise charges.
|
||||
Pay for emails, not contacts.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.4, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<DollarSign className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Predictable Pricing</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Pay-as-you-go per email. No surprise costs as you grow. No forced tier upgrades. No sales calls. Just
|
||||
simple, transparent pricing.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.5, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<Zap className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Full API Access</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Complete API access on all plans. No feature restrictions, no "contact sales" for API access. Everything
|
||||
documented and ready to use.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.6, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<BarChart3 className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>All Features Included</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Transactional emails, campaigns, workflows, segmentation. All included. No artificial feature gating based on your plan.
|
||||
</p>
|
||||
{/* Pricing comparison */}
|
||||
<section className={'border-t border-neutral-200'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}} className={'mb-16'}>
|
||||
<h2 style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}>
|
||||
Transparent Pricing vs Vendor Lock-In
|
||||
</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Pay per email, not per contact</p>
|
||||
</motion.div>
|
||||
<div className={'grid gap-4 lg:grid-cols-2'}>
|
||||
<motion.div initial={{opacity: 0, x: -20}} whileInView={{opacity: 1, x: 0}} viewport={{once: true}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}} className={'rounded-[24px] border border-neutral-900 bg-neutral-900 p-10 text-white'}>
|
||||
<div style={{fontFamily: 'var(--font-mono)'}} className={'text-[11px] uppercase tracking-[0.18em] text-neutral-400'}>Plunk</div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-2xl font-bold tracking-[-0.025em] text-white'}>Pay per email sent</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-300'}>Pay-as-you-go pricing with unlimited contacts. No monthly commitments or contact-based limits.</p>
|
||||
<div style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-4xl font-extrabold tracking-[-0.03em] text-white'}>$0.001/email</div>
|
||||
<ul className={'mt-8 space-y-3'}>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-300'}><Check className="h-4 w-4 flex-shrink-0 text-neutral-400" />Unlimited contacts at no extra cost</li>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-300'}><Check className="h-4 w-4 flex-shrink-0 text-neutral-400" />All features included on all plans</li>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-300'}><Check className="h-4 w-4 flex-shrink-0 text-neutral-400" />Open-source and self-hostable</li>
|
||||
</ul>
|
||||
</motion.div>
|
||||
<motion.div initial={{opacity: 0, x: 20}} whileInView={{opacity: 1, x: 0}} viewport={{once: true}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}} className={'rounded-[24px] border border-neutral-200 bg-white p-10'}>
|
||||
<div style={{fontFamily: 'var(--font-mono)'}} className={'text-[11px] uppercase tracking-[0.18em] text-neutral-500'}>Loops</div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-2xl font-bold tracking-[-0.025em] text-neutral-900'}>Subscription tiers by contacts</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>Monthly subscription based on contact count with tier-based limits and feature restrictions.</p>
|
||||
<div style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-4xl font-extrabold tracking-[-0.03em] text-neutral-900'}>Tiered pricing</div>
|
||||
<ul className={'mt-8 space-y-3'}>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-600'}><div className={'h-1.5 w-1.5 flex-shrink-0 rounded-full bg-neutral-400'} />Contact-based pricing limits</li>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-600'}><div className={'h-1.5 w-1.5 flex-shrink-0 rounded-full bg-neutral-400'} />Feature limits on lower tiers</li>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-600'}><div className={'h-1.5 w-1.5 flex-shrink-0 rounded-full bg-neutral-400'} />Proprietary, cloud-only platform</li>
|
||||
</ul>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Feature Comparison */}
|
||||
<section className={'py-32'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-16 text-center'}
|
||||
>
|
||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>Feature-by-Feature Comparison</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>See exactly what you get with each platform</p>
|
||||
</motion.div>
|
||||
{/* Key advantages */}
|
||||
<section className={'border-t border-neutral-200 bg-neutral-50/60'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}} className={'mb-16'}>
|
||||
<h2 style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}>Why Choose Plunk Over Loops</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Open-source transparency meets modern SaaS features</p>
|
||||
</motion.div>
|
||||
<div className={'grid gap-px bg-neutral-200 sm:grid-cols-2 lg:grid-cols-3'}>
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.5, delay: 0.1, ease: [0.22, 1, 0.36, 1]}} className={'bg-white p-10'}>
|
||||
<div className={'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white'}><PackageOpen className="h-5 w-5" /></div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>Open Source & Transparent</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>AGPL-3.0 licensed. Inspect the code, contribute features, understand exactly how your emails are sent. No black boxes.</p>
|
||||
</motion.div>
|
||||
|
||||
<ComparisonTable competitorName="Loops" rows={comparisonData} />
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.5, delay: 0.2, ease: [0.22, 1, 0.36, 1]}} className={'bg-white p-10'}>
|
||||
<div className={'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white'}><Globe className="h-5 w-5" /></div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>Self-Hostable</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>Run on your infrastructure with Docker. Full data control, compliance-ready, cost-optimized for scale. Loops is cloud-only.</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.5, delay: 0.3, ease: [0.22, 1, 0.36, 1]}} className={'bg-white p-10'}>
|
||||
<div className={'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white'}><Users className="h-5 w-5" /></div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>Unlimited Contacts</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>No contact-based limits. Grow your audience without worrying about tier upgrades or surprise charges. Pay for emails, not contacts.</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.5, delay: 0.4, ease: [0.22, 1, 0.36, 1]}} className={'bg-white p-10'}>
|
||||
<div className={'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white'}><DollarSign className="h-5 w-5" /></div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>Predictable Pricing</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>Pay-as-you-go per email. No surprise costs as you grow. No forced tier upgrades. No sales calls. Just simple, transparent pricing.</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.5, delay: 0.5, ease: [0.22, 1, 0.36, 1]}} className={'bg-white p-10'}>
|
||||
<div className={'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white'}><Zap className="h-5 w-5" /></div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>Full API Access</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>Complete API access on all plans. No feature restrictions, no "contact sales" for API access. Everything documented and ready to use.</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.5, delay: 0.6, ease: [0.22, 1, 0.36, 1]}} className={'bg-white p-10'}>
|
||||
<div className={'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white'}><BarChart3 className="h-5 w-5" /></div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>All Features Included</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>Transactional emails, campaigns, workflows, segmentation. All included. No artificial feature gating based on your plan.</p>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Feature comparison table */}
|
||||
<section className={'border-t border-neutral-200'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}} className={'mb-16'}>
|
||||
<h2 style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}>Feature comparison</h2>
|
||||
</motion.div>
|
||||
<ComparisonTable competitorName="Loops" rows={comparisonData} />
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* FAQ */}
|
||||
<FAQSection faqs={faqs} schemaId="faq-schema-loops" />
|
||||
|
||||
{/* CTA */}
|
||||
<section className={'relative overflow-hidden border-t border-neutral-200 py-32'}>
|
||||
<div
|
||||
className={
|
||||
'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#e5e7eb_1px,transparent_1px),linear-gradient(to_bottom,#e5e7eb_1px,transparent_1px)] bg-[size:4rem_4rem] [mask-image:radial-gradient(ellipse_80%_50%_at_50%_100%,#000_70%,transparent_110%)]'
|
||||
}
|
||||
/>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mx-auto max-w-3xl text-center'}
|
||||
>
|
||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>Switch to open source</h2>
|
||||
<p className={'mt-6 text-lg text-neutral-600'}>
|
||||
Join developers choosing transparency and control over proprietary platforms. Start free, no credit card
|
||||
required.
|
||||
</p>
|
||||
<div className={'mt-12 flex flex-wrap justify-center gap-4'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.02}}
|
||||
whileTap={{scale: 0.98}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
className={
|
||||
'group rounded-lg bg-neutral-900 px-8 py-4 text-base font-semibold text-white transition hover:bg-neutral-800'
|
||||
}
|
||||
>
|
||||
<span className={'flex items-center gap-2'}>
|
||||
Get started free
|
||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-1" />
|
||||
</span>
|
||||
</motion.a>
|
||||
<Link
|
||||
href="/pricing"
|
||||
className={
|
||||
'rounded-lg border border-neutral-300 px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-400'
|
||||
}
|
||||
>
|
||||
View pricing details
|
||||
</Link>
|
||||
<section className={'relative overflow-hidden border-t border-neutral-900 bg-neutral-900 text-white'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-32 sm:px-10 sm:py-40'}>
|
||||
<div className={'flex flex-col items-start gap-12 lg:flex-row lg:items-end lg:justify-between'}>
|
||||
<motion.h2 initial={{opacity: 0, y: 16}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.9, ease: [0.22, 1, 0.36, 1]}} style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2.5rem,7vw,6rem)] font-extrabold leading-[0.95] tracking-[-0.035em]'}>
|
||||
Switch to open source
|
||||
</motion.h2>
|
||||
<motion.div initial={{opacity: 0, y: 16}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.9, delay: 0.15, ease: [0.22, 1, 0.36, 1]}} className={'flex max-w-md flex-col gap-6'}>
|
||||
<p className={'text-base text-neutral-300 sm:text-lg'}>Join developers choosing transparency and control over proprietary platforms. Start free, no credit card required.</p>
|
||||
<div className={'flex flex-wrap gap-3'}>
|
||||
<motion.a whileHover={{scale: 1.015}} whileTap={{scale: 0.985}} href={`${DASHBOARD_URI}/auth/signup`} className={'inline-flex items-center gap-2 rounded-full bg-white px-7 py-3.5 text-sm font-semibold text-neutral-900 transition hover:bg-neutral-100'}>
|
||||
Get started free <ArrowRight className="h-4 w-4" />
|
||||
</motion.a>
|
||||
<Link href={'/pricing'} className={'inline-flex items-center gap-2 rounded-full border border-neutral-700 px-7 py-3.5 text-sm font-semibold text-white transition hover:border-white'}>
|
||||
View pricing
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
</main>
|
||||
<Footer />
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -4,7 +4,7 @@ import {DASHBOARD_URI, WIKI_URI} from '../../lib/constants';
|
||||
import React from 'react';
|
||||
import Link from 'next/link';
|
||||
import {NextSeo} from 'next-seo';
|
||||
import {ArrowRight, Code2, DollarSign, Mail, PackageOpen, Zap} from 'lucide-react';
|
||||
import {ArrowRight, Check, Code2, DollarSign, Mail, PackageOpen, Zap} from 'lucide-react';
|
||||
import type {ComparisonRow} from '../../components/ComparisonTable';
|
||||
import type {FAQ} from '../../components/FAQSection';
|
||||
|
||||
@@ -70,360 +70,154 @@ export default function MailchimpComparison() {
|
||||
|
||||
<Navbar />
|
||||
|
||||
<main className={'mx-auto max-w-7xl px-8 sm:px-0'}>
|
||||
{/* Hero Section */}
|
||||
<section className={'relative py-32 sm:py-48'}>
|
||||
<div
|
||||
className={
|
||||
'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#e5e7eb_1px,transparent_1px),linear-gradient(to_bottom,#e5e7eb_1px,transparent_1px)] bg-[size:4rem_4rem] [mask-image:radial-gradient(ellipse_80%_50%_at_50%_0%,#000_70%,transparent_110%)]'
|
||||
}
|
||||
/>
|
||||
<main className={'text-neutral-800'}>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
animate={{opacity: 1, y: 0}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mx-auto max-w-4xl text-center'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'mb-6 inline-flex items-center gap-2 rounded-full border border-neutral-200 bg-white px-4 py-2'
|
||||
}
|
||||
>
|
||||
<span className={'text-sm text-neutral-600'}>Comparing</span>
|
||||
<span className={'text-sm font-semibold text-neutral-900'}>Plunk vs Mailchimp</span>
|
||||
</div>
|
||||
|
||||
<h1 className={'text-6xl font-bold tracking-tight text-neutral-900 sm:text-7xl lg:text-8xl text-balance'}>
|
||||
Open-source alternative
|
||||
<br />
|
||||
for Mailchimp
|
||||
</h1>
|
||||
|
||||
<p className={'mx-auto mt-8 max-w-2xl text-xl text-neutral-600'}>
|
||||
Mailchimp is for marketers. Plunk is for developers who need full control, modern API, and transparent
|
||||
pay-as-you-go pricing. Same features, better DX.
|
||||
</p>
|
||||
|
||||
<div className={'mt-12 flex flex-wrap justify-center gap-4'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.02}}
|
||||
whileTap={{scale: 0.98}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
className={
|
||||
'group rounded-lg bg-neutral-900 px-8 py-4 text-base font-semibold text-white shadow-lg shadow-neutral-900/10 transition hover:bg-neutral-800'
|
||||
}
|
||||
>
|
||||
<span className={'flex items-center gap-2'}>
|
||||
Try Plunk free
|
||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-1" />
|
||||
</span>
|
||||
</motion.a>
|
||||
<Link
|
||||
href={WIKI_URI}
|
||||
target={'_blank'}
|
||||
className={
|
||||
'rounded-lg border border-neutral-300 bg-white px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-400'
|
||||
}
|
||||
>
|
||||
View documentation
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
</section>
|
||||
|
||||
{/* Pricing Model Comparison */}
|
||||
<section className={'py-32'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-16 text-center'}
|
||||
>
|
||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>The Pricing Model That Makes Sense</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Pay for what you use, not for what you store</p>
|
||||
</motion.div>
|
||||
|
||||
<div className={'grid gap-8 lg:grid-cols-2'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, x: -20}}
|
||||
whileInView={{opacity: 1, x: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'rounded-2xl border-2 border-neutral-900 bg-white p-10'}
|
||||
>
|
||||
<div className={'mb-4 inline-flex items-center gap-2 rounded-full bg-neutral-900 px-4 py-1.5'}>
|
||||
<span className={'text-sm font-semibold text-white'}>Plunk</span>
|
||||
{/* Hero */}
|
||||
<section className={'relative overflow-hidden'}>
|
||||
<div aria-hidden className={'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#eeeeee_1px,transparent_1px),linear-gradient(to_bottom,#eeeeee_1px,transparent_1px)] bg-[size:6rem_6rem] [mask-image:radial-gradient(ellipse_70%_60%_at_50%_30%,#000_40%,transparent_95%)]'} />
|
||||
<div className={'mx-auto max-w-[88rem] px-6 pb-20 pt-20 sm:px-10 sm:pt-28 sm:pb-28'}>
|
||||
<motion.div initial={{opacity: 0, y: 16}} animate={{opacity: 1, y: 0}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}>
|
||||
<div style={{fontFamily: 'var(--font-mono)'}} className={'mb-6 text-[11px] uppercase tracking-[0.18em] text-neutral-500'}>
|
||||
Plunk vs Mailchimp
|
||||
</div>
|
||||
<h3 className={'mt-6 text-2xl font-bold text-neutral-900'}>Pay per email sent</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Pay-as-you-go pricing. Only pay for emails you actually send, not for contacts stored.
|
||||
</p>
|
||||
<div className={'mt-6 text-4xl font-bold text-neutral-900'}>Pay-as-you-go</div>
|
||||
<div className={'mt-8 space-y-3'}>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-900 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-white'} />
|
||||
</div>
|
||||
<span>Only pay for emails you actually send</span>
|
||||
</div>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-900 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-white'} />
|
||||
</div>
|
||||
<span>Unlimited contacts in your database</span>
|
||||
</div>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-900 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-white'} />
|
||||
</div>
|
||||
<span>No penalties for growing your list</span>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, x: 20}}
|
||||
whileInView={{opacity: 1, x: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'rounded-2xl border border-neutral-200 bg-neutral-50 p-10'}
|
||||
>
|
||||
<div className={'mb-4 inline-flex items-center gap-2 rounded-full bg-neutral-200 px-4 py-1.5'}>
|
||||
<span className={'text-sm font-semibold text-neutral-900'}>Mailchimp</span>
|
||||
</div>
|
||||
<h3 className={'mt-6 text-2xl font-bold text-neutral-900'}>Pay per contact stored</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Charged for every contact in your list, whether you email them or not.
|
||||
</p>
|
||||
<div className={'mt-6 text-4xl font-bold text-neutral-900'}>Fixed subscription</div>
|
||||
<div className={'mt-8 space-y-3'}>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-300 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-neutral-600'} />
|
||||
</div>
|
||||
<span>Pay for contacts even if you don't email them</span>
|
||||
</div>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-300 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-neutral-600'} />
|
||||
</div>
|
||||
<span>Growing your list = automatic price increase</span>
|
||||
</div>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-300 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-neutral-600'} />
|
||||
</div>
|
||||
<span>Duplicate contacts count multiple times</span>
|
||||
</div>
|
||||
<h1 style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2.75rem,7vw,6.5rem)] font-extrabold leading-[0.92] tracking-[-0.04em] text-neutral-900'}>
|
||||
Open-source alternative
|
||||
<br />
|
||||
for Mailchimp
|
||||
</h1>
|
||||
<p className={'mt-6 max-w-2xl text-xl text-neutral-600'}>Mailchimp is for marketers. Plunk is for developers who need full control, modern API, and transparent pay-as-you-go pricing. Same features, better DX.</p>
|
||||
<div className={'mt-10 flex flex-wrap gap-3'}>
|
||||
<motion.a whileHover={{scale: 1.015}} whileTap={{scale: 0.985}} href={`${DASHBOARD_URI}/auth/signup`} className={'group inline-flex items-center gap-2 rounded-full bg-neutral-900 px-8 py-4 text-base font-semibold text-white shadow-[0_10px_30px_-10px_rgba(23,23,23,0.35)] transition hover:bg-neutral-800'}>
|
||||
Try Plunk free <ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-0.5" />
|
||||
</motion.a>
|
||||
<Link href={WIKI_URI} target={'_blank'} className={'inline-flex items-center gap-2 rounded-full border border-neutral-300 bg-white px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-900'}>
|
||||
View documentation
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Key Advantages */}
|
||||
<section className={'py-32'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-20 text-center'}
|
||||
>
|
||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>Why Developers Choose Plunk</h2>
|
||||
</motion.div>
|
||||
|
||||
<div className={'grid gap-px bg-neutral-200 sm:grid-cols-2 lg:grid-cols-3'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.1, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<DollarSign className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Pay-as-you-go Pricing</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Only pay for emails you send, not for contacts you store. No monthly minimums or fixed subscription
|
||||
costs.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.2, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<Code2 className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>API-First</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Modern REST API designed for developers. 10x easier to integrate than Mailchimp's marketing-focused API.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.3, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<Zap className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>5-Minute Setup</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Start sending in minutes. No audiences to configure, no lists to manage. Just send emails.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.4, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<PackageOpen className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Open Source</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
AGPL-3.0 licensed. Inspect the code, self-host, no vendor lock-in. Mailchimp is proprietary.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.5, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<Mail className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>All-in-One</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Transactional and marketing emails in one platform. No need for separate Mandrill account.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.6, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<ArrowRight className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Event-Driven</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Trigger workflows based on user actions. Advanced automation that Mailchimp can't match.
|
||||
</p>
|
||||
{/* Pricing comparison */}
|
||||
<section className={'border-t border-neutral-200'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}} className={'mb-16'}>
|
||||
<h2 style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}>
|
||||
The Pricing Model That Makes Sense
|
||||
</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Pay for what you use, not for what you store</p>
|
||||
</motion.div>
|
||||
<div className={'grid gap-4 lg:grid-cols-2'}>
|
||||
{/* Plunk card - DARK */}
|
||||
<motion.div initial={{opacity: 0, x: -20}} whileInView={{opacity: 1, x: 0}} viewport={{once: true}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}} className={'rounded-[24px] border border-neutral-900 bg-neutral-900 p-10 text-white'}>
|
||||
<div style={{fontFamily: 'var(--font-mono)'}} className={'text-[11px] uppercase tracking-[0.18em] text-neutral-400'}>Plunk</div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-2xl font-bold tracking-[-0.025em] text-white'}>Pay per email sent</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-300'}>Pay-as-you-go pricing. Only pay for emails you actually send, not for contacts stored.</p>
|
||||
<div style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-4xl font-extrabold tracking-[-0.03em] text-white'}>Pay-as-you-go</div>
|
||||
<ul className={'mt-8 space-y-3'}>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-300'}><Check className="h-4 w-4 flex-shrink-0 text-neutral-400" />Only pay for emails you actually send</li>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-300'}><Check className="h-4 w-4 flex-shrink-0 text-neutral-400" />Unlimited contacts in your database</li>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-300'}><Check className="h-4 w-4 flex-shrink-0 text-neutral-400" />No penalties for growing your list</li>
|
||||
</ul>
|
||||
</motion.div>
|
||||
{/* Competitor card - LIGHT */}
|
||||
<motion.div initial={{opacity: 0, x: 20}} whileInView={{opacity: 1, x: 0}} viewport={{once: true}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}} className={'rounded-[24px] border border-neutral-200 bg-white p-10'}>
|
||||
<div style={{fontFamily: 'var(--font-mono)'}} className={'text-[11px] uppercase tracking-[0.18em] text-neutral-500'}>Mailchimp</div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-2xl font-bold tracking-[-0.025em] text-neutral-900'}>Pay per contact stored</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>Charged for every contact in your list, whether you email them or not.</p>
|
||||
<div style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-4xl font-extrabold tracking-[-0.03em] text-neutral-900'}>Fixed subscription</div>
|
||||
<ul className={'mt-8 space-y-3'}>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-600'}><div className={'h-1.5 w-1.5 flex-shrink-0 rounded-full bg-neutral-400'} />Pay for contacts even if you don't email them</li>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-600'}><div className={'h-1.5 w-1.5 flex-shrink-0 rounded-full bg-neutral-400'} />Growing your list = automatic price increase</li>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-600'}><div className={'h-1.5 w-1.5 flex-shrink-0 rounded-full bg-neutral-400'} />Duplicate contacts count multiple times</li>
|
||||
</ul>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Feature Comparison */}
|
||||
<section className={'py-32'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-16 text-center'}
|
||||
>
|
||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>Feature Comparison</h2>
|
||||
</motion.div>
|
||||
{/* Key advantages */}
|
||||
<section className={'border-t border-neutral-200 bg-neutral-50/60'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}} className={'mb-16'}>
|
||||
<h2 style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}>Why Developers Choose Plunk</h2>
|
||||
</motion.div>
|
||||
<div className={'grid gap-px bg-neutral-200 sm:grid-cols-2 lg:grid-cols-3'}>
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.5, delay: 0.1, ease: [0.22, 1, 0.36, 1]}} className={'bg-white p-10'}>
|
||||
<div className={'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white'}><DollarSign className="h-5 w-5" /></div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>Pay-as-you-go Pricing</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>Only pay for emails you send, not for contacts you store. No monthly minimums or fixed subscription costs.</p>
|
||||
</motion.div>
|
||||
|
||||
<ComparisonTable competitorName="Mailchimp" rows={comparisonData} />
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.5, delay: 0.2, ease: [0.22, 1, 0.36, 1]}} className={'bg-white p-10'}>
|
||||
<div className={'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white'}><Code2 className="h-5 w-5" /></div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>API-First</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>Modern REST API designed for developers. 10x easier to integrate than Mailchimp's marketing-focused API.</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.5, delay: 0.3, ease: [0.22, 1, 0.36, 1]}} className={'bg-white p-10'}>
|
||||
<div className={'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white'}><Zap className="h-5 w-5" /></div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>5-Minute Setup</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>Start sending in minutes. No audiences to configure, no lists to manage. Just send emails.</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.5, delay: 0.4, ease: [0.22, 1, 0.36, 1]}} className={'bg-white p-10'}>
|
||||
<div className={'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white'}><PackageOpen className="h-5 w-5" /></div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>Open Source</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>AGPL-3.0 licensed. Inspect the code, self-host, no vendor lock-in. Mailchimp is proprietary.</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.5, delay: 0.5, ease: [0.22, 1, 0.36, 1]}} className={'bg-white p-10'}>
|
||||
<div className={'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white'}><Mail className="h-5 w-5" /></div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>All-in-One</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>Transactional and marketing emails in one platform. No need for separate Mandrill account.</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.5, delay: 0.6, ease: [0.22, 1, 0.36, 1]}} className={'bg-white p-10'}>
|
||||
<div className={'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white'}><ArrowRight className="h-5 w-5" /></div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>Event-Driven</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>Trigger workflows based on user actions. Advanced automation that Mailchimp can't match.</p>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Feature comparison table */}
|
||||
<section className={'border-t border-neutral-200'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}} className={'mb-16'}>
|
||||
<h2 style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}>Feature comparison</h2>
|
||||
</motion.div>
|
||||
<ComparisonTable competitorName="Mailchimp" rows={comparisonData} />
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* FAQ */}
|
||||
<FAQSection faqs={faqs} schemaId="faq-schema-mailchimp" />
|
||||
|
||||
{/* CTA */}
|
||||
<section className={'relative overflow-hidden border-t border-neutral-200 py-32'}>
|
||||
<div
|
||||
className={
|
||||
'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#e5e7eb_1px,transparent_1px),linear-gradient(to_bottom,#e5e7eb_1px,transparent_1px)] bg-[size:4rem_4rem] [mask-image:radial-gradient(ellipse_80%_50%_at_50%_100%,#000_70%,transparent_110%)]'
|
||||
}
|
||||
/>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mx-auto max-w-3xl text-center'}
|
||||
>
|
||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>
|
||||
Ready for a better developer experience?
|
||||
</h2>
|
||||
<p className={'mt-6 text-lg text-neutral-600'}>
|
||||
Join developers who've switched from Mailchimp to Plunk for better DX and transparent pay-as-you-go
|
||||
pricing.
|
||||
</p>
|
||||
<div className={'mt-12 flex flex-wrap justify-center gap-4'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.02}}
|
||||
whileTap={{scale: 0.98}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
className={
|
||||
'group rounded-lg bg-neutral-900 px-8 py-4 text-base font-semibold text-white transition hover:bg-neutral-800'
|
||||
}
|
||||
>
|
||||
<span className={'flex items-center gap-2'}>
|
||||
Get started free
|
||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-1" />
|
||||
</span>
|
||||
</motion.a>
|
||||
<Link
|
||||
href="/pricing"
|
||||
className={
|
||||
'rounded-lg border border-neutral-300 px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-400'
|
||||
}
|
||||
>
|
||||
View pricing
|
||||
</Link>
|
||||
<section className={'relative overflow-hidden border-t border-neutral-900 bg-neutral-900 text-white'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-32 sm:px-10 sm:py-40'}>
|
||||
<div className={'flex flex-col items-start gap-12 lg:flex-row lg:items-end lg:justify-between'}>
|
||||
<motion.h2 initial={{opacity: 0, y: 16}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.9, ease: [0.22, 1, 0.36, 1]}} style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2.5rem,7vw,6rem)] font-extrabold leading-[0.95] tracking-[-0.035em]'}>
|
||||
Ready for a better developer experience?
|
||||
</motion.h2>
|
||||
<motion.div initial={{opacity: 0, y: 16}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.9, delay: 0.15, ease: [0.22, 1, 0.36, 1]}} className={'flex max-w-md flex-col gap-6'}>
|
||||
<p className={'text-base text-neutral-300 sm:text-lg'}>Join developers who've switched from Mailchimp to Plunk for better DX and transparent pay-as-you-go pricing.</p>
|
||||
<div className={'flex flex-wrap gap-3'}>
|
||||
<motion.a whileHover={{scale: 1.015}} whileTap={{scale: 0.985}} href={`${DASHBOARD_URI}/auth/signup`} className={'inline-flex items-center gap-2 rounded-full bg-white px-7 py-3.5 text-sm font-semibold text-neutral-900 transition hover:bg-neutral-100'}>
|
||||
Get started free <ArrowRight className="h-4 w-4" />
|
||||
</motion.a>
|
||||
<Link href={'/pricing'} className={'inline-flex items-center gap-2 rounded-full border border-neutral-700 px-7 py-3.5 text-sm font-semibold text-white transition hover:border-white'}>
|
||||
View pricing
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
</main>
|
||||
<Footer />
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -4,7 +4,7 @@ import {DASHBOARD_URI, WIKI_URI} from '../../lib/constants';
|
||||
import React from 'react';
|
||||
import Link from 'next/link';
|
||||
import {NextSeo} from 'next-seo';
|
||||
import {ArrowRight, Code2, DollarSign, Globe, PackageOpen, Users, Zap} from 'lucide-react';
|
||||
import {ArrowRight, Check, Code2, DollarSign, Globe, PackageOpen, Users, Zap} from 'lucide-react';
|
||||
import type {ComparisonRow} from '../../components/ComparisonTable';
|
||||
import type {FAQ} from '../../components/FAQSection';
|
||||
|
||||
@@ -49,9 +49,6 @@ const faqs: FAQ[] = [
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
* Plunk vs MailerLite comparison page
|
||||
*/
|
||||
export default function MailerliteComparison() {
|
||||
return (
|
||||
<>
|
||||
@@ -70,369 +67,132 @@ export default function MailerliteComparison() {
|
||||
|
||||
<Navbar />
|
||||
|
||||
<main className={'mx-auto max-w-7xl px-8 sm:px-0'}>
|
||||
{/* Hero Section */}
|
||||
<section className={'relative py-32 sm:py-48'}>
|
||||
<div
|
||||
className={
|
||||
'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#e5e7eb_1px,transparent_1px),linear-gradient(to_bottom,#e5e7eb_1px,transparent_1px)] bg-[size:4rem_4rem] [mask-image:radial-gradient(ellipse_80%_50%_at_50%_0%,#000_70%,transparent_110%)]'
|
||||
}
|
||||
/>
|
||||
<main className={'text-neutral-800'}>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
animate={{opacity: 1, y: 0}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mx-auto max-w-4xl text-center'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'mb-6 inline-flex items-center gap-2 rounded-full border border-neutral-200 bg-white px-4 py-2'
|
||||
}
|
||||
>
|
||||
<span className={'text-sm text-neutral-600'}>Comparing</span>
|
||||
<span className={'text-sm font-semibold text-neutral-900'}>Plunk vs MailerLite</span>
|
||||
</div>
|
||||
|
||||
<h1 className={'text-6xl font-bold tracking-tight text-neutral-900 sm:text-7xl lg:text-8xl text-balance'}>
|
||||
Open-source alternative
|
||||
<br />
|
||||
for MailerLite
|
||||
</h1>
|
||||
|
||||
<p className={'mx-auto mt-8 max-w-2xl text-xl text-neutral-600'}>
|
||||
MailerLite is developer-friendly. Plunk is developer-FIRST. Open-source, self-hostable, with API-first
|
||||
design and pay-as-you-go pricing instead of subscriber tiers.
|
||||
</p>
|
||||
|
||||
<div className={'mt-12 flex flex-wrap justify-center gap-4'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.02}}
|
||||
whileTap={{scale: 0.98}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
className={
|
||||
'group rounded-lg bg-neutral-900 px-8 py-4 text-base font-semibold text-white shadow-lg shadow-neutral-900/10 transition hover:bg-neutral-800'
|
||||
}
|
||||
>
|
||||
<span className={'flex items-center gap-2'}>
|
||||
Get started free
|
||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-1" />
|
||||
</span>
|
||||
</motion.a>
|
||||
<Link
|
||||
href={WIKI_URI}
|
||||
target={'_blank'}
|
||||
className={
|
||||
'rounded-lg border border-neutral-300 bg-white px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-400'
|
||||
}
|
||||
>
|
||||
View documentation
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
</section>
|
||||
|
||||
{/* Pricing Model Comparison */}
|
||||
<section className={'py-32'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-16 text-center'}
|
||||
>
|
||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>
|
||||
Open Source Meets Developer Experience
|
||||
</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Pay for emails sent, not subscribers stored</p>
|
||||
</motion.div>
|
||||
|
||||
<div className={'grid gap-8 lg:grid-cols-2'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, x: -20}}
|
||||
whileInView={{opacity: 1, x: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'rounded-2xl border-2 border-neutral-900 bg-white p-10'}
|
||||
>
|
||||
<div className={'mb-4 inline-flex items-center gap-2 rounded-full bg-neutral-900 px-4 py-1.5'}>
|
||||
<span className={'text-sm font-semibold text-white'}>Plunk</span>
|
||||
{/* Hero */}
|
||||
<section className={'relative overflow-hidden'}>
|
||||
<div aria-hidden className={'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#eeeeee_1px,transparent_1px),linear-gradient(to_bottom,#eeeeee_1px,transparent_1px)] bg-[size:6rem_6rem] [mask-image:radial-gradient(ellipse_70%_60%_at_50%_30%,#000_40%,transparent_95%)]'} />
|
||||
<div className={'mx-auto max-w-[88rem] px-6 pb-20 pt-20 sm:px-10 sm:pt-28 sm:pb-28'}>
|
||||
<motion.div initial={{opacity: 0, y: 16}} animate={{opacity: 1, y: 0}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}>
|
||||
<div style={{fontFamily: 'var(--font-mono)'}} className={'mb-6 text-[11px] uppercase tracking-[0.18em] text-neutral-500'}>
|
||||
Plunk vs MailerLite
|
||||
</div>
|
||||
<h3 className={'mt-6 text-2xl font-bold text-neutral-900'}>Pay per email sent</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Pay-as-you-go pricing. Open-source and self-hostable for full control.
|
||||
</p>
|
||||
<div className={'mt-6 text-4xl font-bold text-neutral-900'}>Pay-as-you-go</div>
|
||||
<div className={'mt-8 space-y-3'}>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-900 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-white'} />
|
||||
</div>
|
||||
<span>Unlimited contacts, no subscriber fees</span>
|
||||
</div>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-900 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-white'} />
|
||||
</div>
|
||||
<span>Self-host or use our cloud</span>
|
||||
</div>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-900 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-white'} />
|
||||
</div>
|
||||
<span>Full code transparency (AGPL-3.0)</span>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, x: 20}}
|
||||
whileInView={{opacity: 1, x: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'rounded-2xl border border-neutral-200 bg-neutral-50 p-10'}
|
||||
>
|
||||
<div className={'mb-4 inline-flex items-center gap-2 rounded-full bg-neutral-200 px-4 py-1.5'}>
|
||||
<span className={'text-sm font-semibold text-neutral-900'}>MailerLite</span>
|
||||
</div>
|
||||
<h3 className={'mt-6 text-2xl font-bold text-neutral-900'}>Pay per subscriber count</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Monthly subscription based on total subscribers. Proprietary cloud-only platform.
|
||||
</p>
|
||||
<div className={'mt-6 text-4xl font-bold text-neutral-900'}>From $10/month</div>
|
||||
<div className={'mt-8 space-y-3'}>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-300 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-neutral-600'} />
|
||||
</div>
|
||||
<span>Pricing based on subscriber count</span>
|
||||
</div>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-300 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-neutral-600'} />
|
||||
</div>
|
||||
<span>Cloud-only, no self-hosting</span>
|
||||
</div>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-300 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-neutral-600'} />
|
||||
</div>
|
||||
<span>Proprietary closed-source code</span>
|
||||
</div>
|
||||
<h1 style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2.75rem,7vw,6.5rem)] font-extrabold leading-[0.92] tracking-[-0.04em] text-neutral-900'}>
|
||||
Open-source alternative
|
||||
<br />
|
||||
for MailerLite
|
||||
</h1>
|
||||
<p className={'mt-6 max-w-2xl text-xl text-neutral-600'}>MailerLite is developer-friendly. Plunk is developer-FIRST. Open-source, self-hostable, with API-first design and pay-as-you-go pricing instead of subscriber tiers.</p>
|
||||
<div className={'mt-10 flex flex-wrap gap-3'}>
|
||||
<motion.a whileHover={{scale: 1.015}} whileTap={{scale: 0.985}} href={`${DASHBOARD_URI}/auth/signup`} className={'group inline-flex items-center gap-2 rounded-full bg-neutral-900 px-8 py-4 text-base font-semibold text-white shadow-[0_10px_30px_-10px_rgba(23,23,23,0.35)] transition hover:bg-neutral-800'}>
|
||||
Get started free <ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-0.5" />
|
||||
</motion.a>
|
||||
<Link href={WIKI_URI} target={'_blank'} className={'inline-flex items-center gap-2 rounded-full border border-neutral-300 bg-white px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-900'}>
|
||||
View documentation
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Key Advantages */}
|
||||
<section className={'py-32'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-20 text-center'}
|
||||
>
|
||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>
|
||||
The Truly Developer-First Alternative
|
||||
</h2>
|
||||
</motion.div>
|
||||
|
||||
<div className={'grid gap-px bg-neutral-200 sm:grid-cols-2 lg:grid-cols-3'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.1, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<PackageOpen className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Open Source</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
AGPL-3.0 licensed. Inspect the code, contribute features, understand exactly how your platform works.
|
||||
MailerLite is proprietary.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.2, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<Code2 className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>API-First Design</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Built for developers from day one. Modern REST API with comprehensive documentation. Integrate email
|
||||
into your product seamlessly.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.3, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<DollarSign className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Pay per Email</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Only pay for emails sent, not subscribers stored. Grow your contact list without worrying about tier
|
||||
upgrades or price increases.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.4, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<Globe className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Self-Hostable</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Deploy on your infrastructure with Docker. Full data ownership, compliance control, no vendor lock-in.
|
||||
MailerLite is cloud-only.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.5, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<Zap className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Fast Setup</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Start sending in 5 minutes. Simple authentication, clean API endpoints, comprehensive docs. No visual
|
||||
builder learning curve.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.6, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<Users className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Unlimited Contacts</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Store unlimited contacts without additional cost. Your database grows freely, pricing stays predictable
|
||||
based on emails sent.
|
||||
</p>
|
||||
{/* Pricing comparison */}
|
||||
<section className={'border-t border-neutral-200'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}} className={'mb-16'}>
|
||||
<h2 style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}>
|
||||
Open Source Meets Developer Experience
|
||||
</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Pay for emails sent, not subscribers stored</p>
|
||||
</motion.div>
|
||||
<div className={'grid gap-4 lg:grid-cols-2'}>
|
||||
<motion.div initial={{opacity: 0, x: -20}} whileInView={{opacity: 1, x: 0}} viewport={{once: true}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}} className={'rounded-[24px] border border-neutral-900 bg-neutral-900 p-10 text-white'}>
|
||||
<div style={{fontFamily: 'var(--font-mono)'}} className={'text-[11px] uppercase tracking-[0.18em] text-neutral-400'}>Plunk</div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-2xl font-bold tracking-[-0.025em] text-white'}>Pay per email sent</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-300'}>Pay-as-you-go pricing. Open-source and self-hostable for full control.</p>
|
||||
<div style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-4xl font-extrabold tracking-[-0.03em] text-white'}>Pay-as-you-go</div>
|
||||
<ul className={'mt-8 space-y-3'}>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-300'}><Check className="h-4 w-4 flex-shrink-0 text-neutral-400" />Unlimited contacts, no subscriber fees</li>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-300'}><Check className="h-4 w-4 flex-shrink-0 text-neutral-400" />Self-host or use our cloud</li>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-300'}><Check className="h-4 w-4 flex-shrink-0 text-neutral-400" />Full code transparency (AGPL-3.0)</li>
|
||||
</ul>
|
||||
</motion.div>
|
||||
<motion.div initial={{opacity: 0, x: 20}} whileInView={{opacity: 1, x: 0}} viewport={{once: true}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}} className={'rounded-[24px] border border-neutral-200 bg-white p-10'}>
|
||||
<div style={{fontFamily: 'var(--font-mono)'}} className={'text-[11px] uppercase tracking-[0.18em] text-neutral-500'}>MailerLite</div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-2xl font-bold tracking-[-0.025em] text-neutral-900'}>Pay per subscriber count</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>Monthly subscription based on total subscribers. Proprietary cloud-only platform.</p>
|
||||
<div style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-4xl font-extrabold tracking-[-0.03em] text-neutral-900'}>From $10/month</div>
|
||||
<ul className={'mt-8 space-y-3'}>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-600'}><div className={'h-1.5 w-1.5 flex-shrink-0 rounded-full bg-neutral-400'} />Pricing based on subscriber count</li>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-600'}><div className={'h-1.5 w-1.5 flex-shrink-0 rounded-full bg-neutral-400'} />Cloud-only, no self-hosting</li>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-600'}><div className={'h-1.5 w-1.5 flex-shrink-0 rounded-full bg-neutral-400'} />Proprietary closed-source code</li>
|
||||
</ul>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Feature Comparison */}
|
||||
<section className={'py-32'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-16 text-center'}
|
||||
>
|
||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>Feature Comparison</h2>
|
||||
</motion.div>
|
||||
{/* Key advantages */}
|
||||
<section className={'border-t border-neutral-200 bg-neutral-50/60'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}} className={'mb-16'}>
|
||||
<h2 style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}>The Truly Developer-First Alternative</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Full control, transparent code, pay only for what you send</p>
|
||||
</motion.div>
|
||||
<div className={'grid gap-px bg-neutral-200 sm:grid-cols-2 lg:grid-cols-3'}>
|
||||
{[
|
||||
{icon: <PackageOpen className="h-5 w-5" />, title: 'Open Source', body: 'AGPL-3.0 licensed. Inspect the code, contribute features, understand exactly how your platform works. MailerLite is proprietary.'},
|
||||
{icon: <Code2 className="h-5 w-5" />, title: 'API-First Design', body: 'Built for developers from day one. Modern REST API with comprehensive documentation. Integrate email into your product seamlessly.'},
|
||||
{icon: <DollarSign className="h-5 w-5" />, title: 'Pay per Email', body: 'Only pay for emails sent, not subscribers stored. Grow your contact list without worrying about tier upgrades or price increases.'},
|
||||
{icon: <Globe className="h-5 w-5" />, title: 'Self-Hostable', body: 'Deploy on your infrastructure with Docker. Full data ownership, compliance control, no vendor lock-in. MailerLite is cloud-only.'},
|
||||
{icon: <Zap className="h-5 w-5" />, title: 'Fast Setup', body: 'Start sending in 5 minutes. Simple authentication, clean API endpoints, comprehensive docs. No visual builder learning curve.'},
|
||||
{icon: <Users className="h-5 w-5" />, title: 'Unlimited Contacts', body: 'Store unlimited contacts without additional cost. Your database grows freely, pricing stays predictable based on emails sent.'},
|
||||
].map((item, i) => (
|
||||
<motion.div key={item.title} initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.5, delay: i * 0.1, ease: [0.22, 1, 0.36, 1]}} className={'bg-white p-10'}>
|
||||
<div className={'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white'}>{item.icon}</div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>{item.title}</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>{item.body}</p>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<ComparisonTable competitorName="MailerLite" rows={comparisonData} />
|
||||
{/* Feature comparison table */}
|
||||
<section className={'border-t border-neutral-200'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}} className={'mb-16'}>
|
||||
<h2 style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}>Feature comparison</h2>
|
||||
</motion.div>
|
||||
<ComparisonTable competitorName="MailerLite" rows={comparisonData} />
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* FAQ */}
|
||||
<FAQSection faqs={faqs} schemaId="faq-schema-mailerlite" />
|
||||
|
||||
{/* CTA */}
|
||||
<section className={'relative overflow-hidden border-t border-neutral-200 py-32'}>
|
||||
<div
|
||||
className={
|
||||
'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#e5e7eb_1px,transparent_1px),linear-gradient(to_bottom,#e5e7eb_1px,transparent_1px)] bg-[size:4rem_4rem] [mask-image:radial-gradient(ellipse_80%_50%_at_50%_100%,#000_70%,transparent_110%)]'
|
||||
}
|
||||
/>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mx-auto max-w-3xl text-center'}
|
||||
>
|
||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>
|
||||
Experience true developer-first email
|
||||
</h2>
|
||||
<p className={'mt-6 text-lg text-neutral-600'}>
|
||||
Join developers choosing open-source transparency and API-first design. Start free, no credit card
|
||||
required.
|
||||
</p>
|
||||
<div className={'mt-12 flex flex-wrap justify-center gap-4'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.02}}
|
||||
whileTap={{scale: 0.98}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
className={
|
||||
'group rounded-lg bg-neutral-900 px-8 py-4 text-base font-semibold text-white transition hover:bg-neutral-800'
|
||||
}
|
||||
>
|
||||
<span className={'flex items-center gap-2'}>
|
||||
Get started free
|
||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-1" />
|
||||
</span>
|
||||
</motion.a>
|
||||
<Link
|
||||
href="/pricing"
|
||||
className={
|
||||
'rounded-lg border border-neutral-300 px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-400'
|
||||
}
|
||||
>
|
||||
View pricing
|
||||
</Link>
|
||||
<section className={'relative overflow-hidden border-t border-neutral-900 bg-neutral-900 text-white'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-32 sm:px-10 sm:py-40'}>
|
||||
<div className={'flex flex-col items-start gap-12 lg:flex-row lg:items-end lg:justify-between'}>
|
||||
<motion.h2 initial={{opacity: 0, y: 16}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.9, ease: [0.22, 1, 0.36, 1]}} style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2.5rem,7vw,6rem)] font-extrabold leading-[0.95] tracking-[-0.035em]'}>
|
||||
Experience true developer-first email.
|
||||
</motion.h2>
|
||||
<motion.div initial={{opacity: 0, y: 16}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.9, delay: 0.15, ease: [0.22, 1, 0.36, 1]}} className={'flex max-w-md flex-col gap-6'}>
|
||||
<p className={'text-base text-neutral-300 sm:text-lg'}>Open-source transparency and API-first design. Unlimited contacts. Pay only for emails sent. Start free.</p>
|
||||
<div className={'flex flex-wrap gap-3'}>
|
||||
<motion.a whileHover={{scale: 1.015}} whileTap={{scale: 0.985}} href={`${DASHBOARD_URI}/auth/signup`} className={'inline-flex items-center gap-2 rounded-full bg-white px-7 py-3.5 text-sm font-semibold text-neutral-900 transition hover:bg-neutral-100'}>
|
||||
Get started free <ArrowRight className="h-4 w-4" />
|
||||
</motion.a>
|
||||
<Link href={'/pricing'} className={'inline-flex items-center gap-2 rounded-full border border-neutral-700 px-7 py-3.5 text-sm font-semibold text-white transition hover:border-white'}>
|
||||
View pricing
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
</main>
|
||||
<Footer />
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -4,7 +4,7 @@ import {DASHBOARD_URI, WIKI_URI} from '../../lib/constants';
|
||||
import React from 'react';
|
||||
import Link from 'next/link';
|
||||
import {NextSeo} from 'next-seo';
|
||||
import {ArrowRight, BarChart3, Globe, Layers, PackageOpen, Users, Workflow} from 'lucide-react';
|
||||
import {ArrowRight, BarChart3, Check, Globe, Layers, PackageOpen, Users, Workflow} from 'lucide-react';
|
||||
import type {ComparisonRow} from '../../components/ComparisonTable';
|
||||
import type {FAQ} from '../../components/FAQSection';
|
||||
|
||||
@@ -65,309 +65,124 @@ export default function MailgunComparison() {
|
||||
|
||||
<Navbar />
|
||||
|
||||
<main className={'mx-auto max-w-7xl px-8 sm:px-0'}>
|
||||
{/* Hero Section */}
|
||||
<section className={'relative py-32 sm:py-48'}>
|
||||
<div
|
||||
className={
|
||||
'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#e5e7eb_1px,transparent_1px),linear-gradient(to_bottom,#e5e7eb_1px,transparent_1px)] bg-[size:4rem_4rem] [mask-image:radial-gradient(ellipse_80%_50%_at_50%_0%,#000_70%,transparent_110%)]'
|
||||
}
|
||||
/>
|
||||
<main className={'text-neutral-800'}>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
animate={{opacity: 1, y: 0}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mx-auto max-w-4xl text-center'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'mb-6 inline-flex items-center gap-2 rounded-full border border-neutral-200 bg-white px-4 py-2'
|
||||
}
|
||||
>
|
||||
<span className={'text-sm text-neutral-600'}>Comparing</span>
|
||||
<span className={'text-sm font-semibold text-neutral-900'}>Plunk vs Mailgun</span>
|
||||
</div>
|
||||
|
||||
<h1 className={'text-6xl font-bold tracking-tight text-neutral-900 sm:text-7xl lg:text-8xl text-balance'}>
|
||||
Open-source alternative
|
||||
<br />
|
||||
for Mailgun
|
||||
</h1>
|
||||
|
||||
<p className={'mx-auto mt-8 max-w-2xl text-xl text-neutral-600'}>
|
||||
Mailgun only handles transactional email. Plunk adds marketing campaigns, workflow automation, and segmentation on top, all open-source and self-hostable at $0.001 per email.
|
||||
</p>
|
||||
|
||||
<div className={'mt-12 flex flex-wrap justify-center gap-4'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.02}}
|
||||
whileTap={{scale: 0.98}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
className={
|
||||
'group rounded-lg bg-neutral-900 px-8 py-4 text-base font-semibold text-white shadow-lg shadow-neutral-900/10 transition hover:bg-neutral-800'
|
||||
}
|
||||
>
|
||||
<span className={'flex items-center gap-2'}>
|
||||
Try Plunk free
|
||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-1" />
|
||||
</span>
|
||||
</motion.a>
|
||||
<Link
|
||||
href={WIKI_URI}
|
||||
target={'_blank'}
|
||||
className={
|
||||
'rounded-lg border border-neutral-300 bg-white px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-400'
|
||||
}
|
||||
>
|
||||
View documentation
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
</section>
|
||||
|
||||
{/* Pricing Model Comparison */}
|
||||
<section className={'py-32'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-16 text-center'}
|
||||
>
|
||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>The Pricing Model That Makes Sense</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Pay for what you use, not fixed subscriptions</p>
|
||||
</motion.div>
|
||||
|
||||
<div className={'grid gap-8 lg:grid-cols-2'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, x: -20}}
|
||||
whileInView={{opacity: 1, x: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'rounded-2xl border-2 border-neutral-900 bg-white p-10'}
|
||||
>
|
||||
<div className={'mb-4 inline-flex items-center gap-2 rounded-full bg-neutral-900 px-4 py-1.5'}>
|
||||
<span className={'text-sm font-semibold text-white'}>Plunk</span>
|
||||
{/* Hero */}
|
||||
<section className={'relative overflow-hidden'}>
|
||||
<div aria-hidden className={'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#eeeeee_1px,transparent_1px),linear-gradient(to_bottom,#eeeeee_1px,transparent_1px)] bg-[size:6rem_6rem] [mask-image:radial-gradient(ellipse_70%_60%_at_50%_30%,#000_40%,transparent_95%)]'} />
|
||||
<div className={'mx-auto max-w-[88rem] px-6 pb-20 pt-20 sm:px-10 sm:pt-28 sm:pb-28'}>
|
||||
<motion.div initial={{opacity: 0, y: 16}} animate={{opacity: 1, y: 0}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}>
|
||||
<div style={{fontFamily: 'var(--font-mono)'}} className={'mb-6 text-[11px] uppercase tracking-[0.18em] text-neutral-500'}>
|
||||
Plunk vs Mailgun
|
||||
</div>
|
||||
<h3 className={'mt-6 text-2xl font-bold text-neutral-900'}>Pay per email sent</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Pay-as-you-go pricing. Only pay for emails you actually send.
|
||||
</p>
|
||||
<div className={'mt-6 text-4xl font-bold text-neutral-900'}>Pay-as-you-go</div>
|
||||
<div className={'mt-8 space-y-3'}>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-900 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-white'} />
|
||||
</div>
|
||||
<span>Only pay for emails you actually send</span>
|
||||
</div>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-900 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-white'} />
|
||||
</div>
|
||||
<span>Scale up or down without commitment</span>
|
||||
</div>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-900 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-white'} />
|
||||
</div>
|
||||
<span>Marketing and automation included</span>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, x: 20}}
|
||||
whileInView={{opacity: 1, x: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'rounded-2xl border border-neutral-200 bg-neutral-50 p-10'}
|
||||
>
|
||||
<div className={'mb-4 inline-flex items-center gap-2 rounded-full bg-neutral-200 px-4 py-1.5'}>
|
||||
<span className={'text-sm font-semibold text-neutral-900'}>Mailgun</span>
|
||||
</div>
|
||||
<h3 className={'mt-6 text-2xl font-bold text-neutral-900'}>Tiered monthly plans</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Monthly subscription with tiered email volume limits.
|
||||
</p>
|
||||
<div className={'mt-6 text-4xl font-bold text-neutral-900'}>Fixed tiers</div>
|
||||
<div className={'mt-8 space-y-3'}>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-300 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-neutral-600'} />
|
||||
</div>
|
||||
<span>Locked into monthly subscription tiers</span>
|
||||
</div>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-300 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-neutral-600'} />
|
||||
</div>
|
||||
<span>Need to upgrade plan as you grow</span>
|
||||
</div>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-300 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-neutral-600'} />
|
||||
</div>
|
||||
<span>Transactional only, no marketing</span>
|
||||
</div>
|
||||
<h1 style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2.75rem,7vw,6.5rem)] font-extrabold leading-[0.92] tracking-[-0.04em] text-neutral-900'}>
|
||||
Open-source alternative
|
||||
<br />
|
||||
for Mailgun
|
||||
</h1>
|
||||
<p className={'mt-6 max-w-2xl text-xl text-neutral-600'}>Mailgun only handles transactional email. Plunk adds marketing campaigns, workflow automation, and segmentation on top, all open-source and self-hostable at $0.001 per email.</p>
|
||||
<div className={'mt-10 flex flex-wrap gap-3'}>
|
||||
<motion.a whileHover={{scale: 1.015}} whileTap={{scale: 0.985}} href={`${DASHBOARD_URI}/auth/signup`} className={'group inline-flex items-center gap-2 rounded-full bg-neutral-900 px-8 py-4 text-base font-semibold text-white shadow-[0_10px_30px_-10px_rgba(23,23,23,0.35)] transition hover:bg-neutral-800'}>
|
||||
Try Plunk free <ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-0.5" />
|
||||
</motion.a>
|
||||
<Link href={WIKI_URI} target={'_blank'} className={'inline-flex items-center gap-2 rounded-full border border-neutral-300 bg-white px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-900'}>
|
||||
View documentation
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Feature Comparison */}
|
||||
<section className={'py-32'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-16 text-center'}
|
||||
>
|
||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>Feature-by-Feature</h2>
|
||||
</motion.div>
|
||||
|
||||
<ComparisonTable competitorName="Mailgun" rows={comparisonData} />
|
||||
{/* Pricing comparison */}
|
||||
<section className={'border-t border-neutral-200'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}} className={'mb-16'}>
|
||||
<h2 style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}>
|
||||
The Pricing Model That Makes Sense
|
||||
</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Pay for what you use, not fixed subscriptions</p>
|
||||
</motion.div>
|
||||
<div className={'grid gap-4 lg:grid-cols-2'}>
|
||||
<motion.div initial={{opacity: 0, x: -20}} whileInView={{opacity: 1, x: 0}} viewport={{once: true}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}} className={'rounded-[24px] border border-neutral-900 bg-neutral-900 p-10 text-white'}>
|
||||
<div style={{fontFamily: 'var(--font-mono)'}} className={'text-[11px] uppercase tracking-[0.18em] text-neutral-400'}>Plunk</div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-2xl font-bold tracking-[-0.025em] text-white'}>Pay per email sent</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-300'}>Pay-as-you-go pricing. Only pay for emails you actually send.</p>
|
||||
<div style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-4xl font-extrabold tracking-[-0.03em] text-white'}>Pay-as-you-go</div>
|
||||
<ul className={'mt-8 space-y-3'}>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-300'}><Check className="h-4 w-4 flex-shrink-0 text-neutral-400" />Only pay for emails you actually send</li>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-300'}><Check className="h-4 w-4 flex-shrink-0 text-neutral-400" />Scale up or down without commitment</li>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-300'}><Check className="h-4 w-4 flex-shrink-0 text-neutral-400" />Marketing and automation included</li>
|
||||
</ul>
|
||||
</motion.div>
|
||||
<motion.div initial={{opacity: 0, x: 20}} whileInView={{opacity: 1, x: 0}} viewport={{once: true}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}} className={'rounded-[24px] border border-neutral-200 bg-white p-10'}>
|
||||
<div style={{fontFamily: 'var(--font-mono)'}} className={'text-[11px] uppercase tracking-[0.18em] text-neutral-500'}>Mailgun</div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-2xl font-bold tracking-[-0.025em] text-neutral-900'}>Tiered monthly plans</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>Monthly subscription with tiered email volume limits.</p>
|
||||
<div style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-4xl font-extrabold tracking-[-0.03em] text-neutral-900'}>Fixed tiers</div>
|
||||
<ul className={'mt-8 space-y-3'}>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-600'}><div className={'h-1.5 w-1.5 flex-shrink-0 rounded-full bg-neutral-400'} />Locked into monthly subscription tiers</li>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-600'}><div className={'h-1.5 w-1.5 flex-shrink-0 rounded-full bg-neutral-400'} />Need to upgrade plan as you grow</li>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-600'}><div className={'h-1.5 w-1.5 flex-shrink-0 rounded-full bg-neutral-400'} />Transactional only, no marketing</li>
|
||||
</ul>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* What Plunk Adds */}
|
||||
<section className={'py-32'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-20 text-center'}
|
||||
>
|
||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>What Plunk Adds</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Beyond transactional emails</p>
|
||||
</motion.div>
|
||||
|
||||
<div className={'grid gap-px bg-neutral-200 sm:grid-cols-3'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.1, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<BarChart3 className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Marketing Campaigns</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Send one-time broadcasts to all contacts or specific segments. Schedule sends, track performance.
|
||||
Mailgun doesn't offer this.
|
||||
</p>
|
||||
{/* Key advantages */}
|
||||
<section className={'border-t border-neutral-200 bg-neutral-50/60'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}} className={'mb-16'}>
|
||||
<h2 style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}>What Plunk Adds</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Beyond transactional emails</p>
|
||||
</motion.div>
|
||||
<div className={'grid gap-px bg-neutral-200 sm:grid-cols-3'}>
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.5, delay: 0.1, ease: [0.22, 1, 0.36, 1]}} className={'bg-white p-10'}>
|
||||
<div className={'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white'}><BarChart3 className="h-5 w-5" /></div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>Marketing Campaigns</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>Send one-time broadcasts to all contacts or specific segments. Schedule sends, track performance. Mailgun doesn't offer this.</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.2, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<Workflow className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Workflow Automation</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Build multi-step email sequences with triggers, delays, and conditions. Perfect for onboarding, drip
|
||||
campaigns, cart abandonment.
|
||||
</p>
|
||||
</motion.div>
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.5, delay: 0.2, ease: [0.22, 1, 0.36, 1]}} className={'bg-white p-10'}>
|
||||
<div className={'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white'}><Workflow className="h-5 w-5" /></div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>Workflow Automation</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>Build multi-step email sequences with triggers, delays, and conditions. Perfect for onboarding, drip campaigns, cart abandonment.</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.3, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<Users className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Dynamic Segmentation</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Create audience segments that update automatically based on contact data and behavior. Target campaigns
|
||||
precisely.
|
||||
</p>
|
||||
</motion.div>
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.5, delay: 0.3, ease: [0.22, 1, 0.36, 1]}} className={'bg-white p-10'}>
|
||||
<div className={'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white'}><Users className="h-5 w-5" /></div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>Dynamic Segmentation</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>Create audience segments that update automatically based on contact data and behavior. Target campaigns precisely.</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.4, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<PackageOpen className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Open Source</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
AGPL-3.0 licensed. Inspect the code, contribute features, no vendor lock-in. Mailgun is proprietary.
|
||||
</p>
|
||||
</motion.div>
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.5, delay: 0.4, ease: [0.22, 1, 0.36, 1]}} className={'bg-white p-10'}>
|
||||
<div className={'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white'}><PackageOpen className="h-5 w-5" /></div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>Open Source</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>AGPL-3.0 licensed. Inspect the code, contribute features, no vendor lock-in. Mailgun is proprietary.</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.5, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<Globe className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Self-Hostable</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Run on your infrastructure with Docker. Full data control, compliance-ready. Pay only AWS SES fees when
|
||||
self-hosting.
|
||||
</p>
|
||||
</motion.div>
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.5, delay: 0.5, ease: [0.22, 1, 0.36, 1]}} className={'bg-white p-10'}>
|
||||
<div className={'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white'}><Globe className="h-5 w-5" /></div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>Self-Hostable</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>Run on your infrastructure with Docker. Full data control, compliance-ready. Pay only AWS SES fees when self-hosting.</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.6, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<Layers className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>All-in-One Platform</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
One platform for transactional, marketing, and automation. No need for multiple tools or integrations.
|
||||
</p>
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.5, delay: 0.6, ease: [0.22, 1, 0.36, 1]}} className={'bg-white p-10'}>
|
||||
<div className={'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white'}><Layers className="h-5 w-5" /></div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>All-in-One Platform</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>One platform for transactional, marketing, and automation. No need for multiple tools or integrations.</p>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Feature comparison table */}
|
||||
<section className={'border-t border-neutral-200'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}} className={'mb-16'}>
|
||||
<h2 style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}>Feature comparison</h2>
|
||||
</motion.div>
|
||||
<ComparisonTable competitorName="Mailgun" rows={comparisonData} />
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -375,51 +190,28 @@ export default function MailgunComparison() {
|
||||
<FAQSection faqs={faqs} schemaId="faq-schema-mailgun" />
|
||||
|
||||
{/* CTA */}
|
||||
<section className={'relative overflow-hidden border-t border-neutral-200 py-32'}>
|
||||
<div
|
||||
className={
|
||||
'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#e5e7eb_1px,transparent_1px),linear-gradient(to_bottom,#e5e7eb_1px,transparent_1px)] bg-[size:4rem_4rem] [mask-image:radial-gradient(ellipse_80%_50%_at_50%_100%,#000_70%,transparent_110%)]'
|
||||
}
|
||||
/>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mx-auto max-w-3xl text-center'}
|
||||
>
|
||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>Try Plunk free</h2>
|
||||
<p className={'mt-6 text-lg text-neutral-600'}>
|
||||
1,000 emails/month free. No credit card required. Add marketing and automation when you need it.
|
||||
</p>
|
||||
<div className={'mt-12 flex flex-wrap justify-center gap-4'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.02}}
|
||||
whileTap={{scale: 0.98}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
className={
|
||||
'group rounded-lg bg-neutral-900 px-8 py-4 text-base font-semibold text-white transition hover:bg-neutral-800'
|
||||
}
|
||||
>
|
||||
<span className={'flex items-center gap-2'}>
|
||||
Get started free
|
||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-1" />
|
||||
</span>
|
||||
</motion.a>
|
||||
<Link
|
||||
href={WIKI_URI}
|
||||
target={'_blank'}
|
||||
className={
|
||||
'rounded-lg border border-neutral-300 px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-400'
|
||||
}
|
||||
>
|
||||
Read documentation
|
||||
</Link>
|
||||
<section className={'relative overflow-hidden border-t border-neutral-900 bg-neutral-900 text-white'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-32 sm:px-10 sm:py-40'}>
|
||||
<div className={'flex flex-col items-start gap-12 lg:flex-row lg:items-end lg:justify-between'}>
|
||||
<motion.h2 initial={{opacity: 0, y: 16}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.9, ease: [0.22, 1, 0.36, 1]}} style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2.5rem,7vw,6rem)] font-extrabold leading-[0.95] tracking-[-0.035em]'}>
|
||||
Try Plunk free
|
||||
</motion.h2>
|
||||
<motion.div initial={{opacity: 0, y: 16}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.9, delay: 0.15, ease: [0.22, 1, 0.36, 1]}} className={'flex max-w-md flex-col gap-6'}>
|
||||
<p className={'text-base text-neutral-300 sm:text-lg'}>1,000 emails/month free. No credit card required. Add marketing and automation when you need it.</p>
|
||||
<div className={'flex flex-wrap gap-3'}>
|
||||
<motion.a whileHover={{scale: 1.015}} whileTap={{scale: 0.985}} href={`${DASHBOARD_URI}/auth/signup`} className={'inline-flex items-center gap-2 rounded-full bg-white px-7 py-3.5 text-sm font-semibold text-neutral-900 transition hover:bg-neutral-100'}>
|
||||
Get started free <ArrowRight className="h-4 w-4" />
|
||||
</motion.a>
|
||||
<Link href={'/pricing'} className={'inline-flex items-center gap-2 rounded-full border border-neutral-700 px-7 py-3.5 text-sm font-semibold text-white transition hover:border-white'}>
|
||||
View pricing
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
</main>
|
||||
<Footer />
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -4,7 +4,7 @@ import {DASHBOARD_URI, WIKI_URI} from '../../lib/constants';
|
||||
import React from 'react';
|
||||
import Link from 'next/link';
|
||||
import {NextSeo} from 'next-seo';
|
||||
import {ArrowRight, BarChart3, DollarSign, Globe, PackageOpen, Users, Zap} from 'lucide-react';
|
||||
import {ArrowRight, BarChart3, Check, DollarSign, Globe, PackageOpen, Users, Zap} from 'lucide-react';
|
||||
import type {ComparisonRow} from '../../components/ComparisonTable';
|
||||
import type {FAQ} from '../../components/FAQSection';
|
||||
|
||||
@@ -66,365 +66,153 @@ export default function PostmarkComparison() {
|
||||
|
||||
<Navbar />
|
||||
|
||||
<main className={'mx-auto max-w-7xl px-8 sm:px-0'}>
|
||||
{/* Hero Section */}
|
||||
<section className={'relative py-32 sm:py-48'}>
|
||||
<div
|
||||
className={
|
||||
'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#e5e7eb_1px,transparent_1px),linear-gradient(to_bottom,#e5e7eb_1px,transparent_1px)] bg-[size:4rem_4rem] [mask-image:radial-gradient(ellipse_80%_50%_at_50%_0%,#000_70%,transparent_110%)]'
|
||||
}
|
||||
/>
|
||||
<main className={'text-neutral-800'}>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
animate={{opacity: 1, y: 0}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mx-auto max-w-4xl text-center'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'mb-6 inline-flex items-center gap-2 rounded-full border border-neutral-200 bg-white px-4 py-2'
|
||||
}
|
||||
>
|
||||
<span className={'text-sm text-neutral-600'}>Comparing</span>
|
||||
<span className={'text-sm font-semibold text-neutral-900'}>Plunk vs Postmark</span>
|
||||
</div>
|
||||
|
||||
<h1 className={'text-6xl font-bold tracking-tight text-neutral-900 sm:text-7xl lg:text-8xl text-balance'}>
|
||||
Open-source alternative
|
||||
<br />
|
||||
for Postmark
|
||||
</h1>
|
||||
|
||||
<p className={'mx-auto mt-8 max-w-2xl text-xl text-neutral-600'}>
|
||||
Everything Postmark offers for transactional emails, plus marketing campaigns, workflow automation, and
|
||||
segmentation. One platform, no extra cost.
|
||||
</p>
|
||||
|
||||
<div className={'mt-12 flex flex-wrap justify-center gap-4'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.02}}
|
||||
whileTap={{scale: 0.98}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
className={
|
||||
'group rounded-lg bg-neutral-900 px-8 py-4 text-base font-semibold text-white shadow-lg shadow-neutral-900/10 transition hover:bg-neutral-800'
|
||||
}
|
||||
>
|
||||
<span className={'flex items-center gap-2'}>
|
||||
Get started free
|
||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-1" />
|
||||
</span>
|
||||
</motion.a>
|
||||
<Link
|
||||
href={WIKI_URI}
|
||||
target={'_blank'}
|
||||
className={
|
||||
'rounded-lg border border-neutral-300 bg-white px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-400'
|
||||
}
|
||||
>
|
||||
View documentation
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
</section>
|
||||
|
||||
{/* Pricing Model Comparison */}
|
||||
<section className={'py-32'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-16 text-center'}
|
||||
>
|
||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>One Platform for All Your Emails</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Transactional reliability meets marketing power</p>
|
||||
</motion.div>
|
||||
|
||||
<div className={'grid gap-8 lg:grid-cols-2'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, x: -20}}
|
||||
whileInView={{opacity: 1, x: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'rounded-2xl border-2 border-neutral-900 bg-white p-10'}
|
||||
>
|
||||
<div className={'mb-4 inline-flex items-center gap-2 rounded-full bg-neutral-900 px-4 py-1.5'}>
|
||||
<span className={'text-sm font-semibold text-white'}>Plunk</span>
|
||||
{/* Hero */}
|
||||
<section className={'relative overflow-hidden'}>
|
||||
<div aria-hidden className={'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#eeeeee_1px,transparent_1px),linear-gradient(to_bottom,#eeeeee_1px,transparent_1px)] bg-[size:6rem_6rem] [mask-image:radial-gradient(ellipse_70%_60%_at_50%_30%,#000_40%,transparent_95%)]'} />
|
||||
<div className={'mx-auto max-w-[88rem] px-6 pb-20 pt-20 sm:px-10 sm:pt-28 sm:pb-28'}>
|
||||
<motion.div initial={{opacity: 0, y: 16}} animate={{opacity: 1, y: 0}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}>
|
||||
<div style={{fontFamily: 'var(--font-mono)'}} className={'mb-6 text-[11px] uppercase tracking-[0.18em] text-neutral-500'}>
|
||||
Plunk vs Postmark
|
||||
</div>
|
||||
<h3 className={'mt-6 text-2xl font-bold text-neutral-900'}>Transactional + Marketing</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Reliable transactional emails plus marketing campaigns, workflows, and segmentation in one platform.
|
||||
</p>
|
||||
<div className={'mt-6 text-4xl font-bold text-neutral-900'}>All-in-one</div>
|
||||
<div className={'mt-8 space-y-3'}>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-900 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-white'} />
|
||||
</div>
|
||||
<span>Transactional emails included</span>
|
||||
</div>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-900 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-white'} />
|
||||
</div>
|
||||
<span>Marketing campaigns included</span>
|
||||
</div>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-900 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-white'} />
|
||||
</div>
|
||||
<span>Workflow automation included</span>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, x: 20}}
|
||||
whileInView={{opacity: 1, x: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'rounded-2xl border border-neutral-200 bg-neutral-50 p-10'}
|
||||
>
|
||||
<div className={'mb-4 inline-flex items-center gap-2 rounded-full bg-neutral-200 px-4 py-1.5'}>
|
||||
<span className={'text-sm font-semibold text-neutral-900'}>Postmark</span>
|
||||
</div>
|
||||
<h3 className={'mt-6 text-2xl font-bold text-neutral-900'}>Transactional only</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Excellent for transactional emails, but no marketing features. Need a second service for campaigns.
|
||||
</p>
|
||||
<div className={'mt-6 text-4xl font-bold text-neutral-900'}>Limited scope</div>
|
||||
<div className={'mt-8 space-y-3'}>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-300 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-neutral-600'} />
|
||||
</div>
|
||||
<span>Transactional emails only</span>
|
||||
</div>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-300 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-neutral-600'} />
|
||||
</div>
|
||||
<span>No marketing campaigns</span>
|
||||
</div>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-300 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-neutral-600'} />
|
||||
</div>
|
||||
<span>No workflow automation</span>
|
||||
</div>
|
||||
<h1 style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2.75rem,7vw,6.5rem)] font-extrabold leading-[0.92] tracking-[-0.04em] text-neutral-900'}>
|
||||
Open-source alternative
|
||||
<br />
|
||||
for Postmark
|
||||
</h1>
|
||||
<p className={'mt-6 max-w-2xl text-xl text-neutral-600'}>Everything Postmark offers for transactional emails, plus marketing campaigns, workflow automation, and segmentation. One platform, no extra cost.</p>
|
||||
<div className={'mt-10 flex flex-wrap gap-3'}>
|
||||
<motion.a whileHover={{scale: 1.015}} whileTap={{scale: 0.985}} href={`${DASHBOARD_URI}/auth/signup`} className={'group inline-flex items-center gap-2 rounded-full bg-neutral-900 px-8 py-4 text-base font-semibold text-white shadow-[0_10px_30px_-10px_rgba(23,23,23,0.35)] transition hover:bg-neutral-800'}>
|
||||
Get started free <ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-0.5" />
|
||||
</motion.a>
|
||||
<Link href={WIKI_URI} target={'_blank'} className={'inline-flex items-center gap-2 rounded-full border border-neutral-300 bg-white px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-900'}>
|
||||
View documentation
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Key Advantages */}
|
||||
<section className={'py-32'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-20 text-center'}
|
||||
>
|
||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>Why Choose Plunk Over Postmark</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Do more with one platform instead of two</p>
|
||||
</motion.div>
|
||||
|
||||
<div className={'grid gap-px bg-neutral-200 sm:grid-cols-2 lg:grid-cols-3'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.1, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<BarChart3 className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Marketing Campaigns Included</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Send newsletters, announcements, and promotional emails without needing a separate marketing platform.
|
||||
One platform, one bill.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.2, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<Zap className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Workflow Automation</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Build automated email sequences with triggers, delays, and conditions. Onboard users, nurture leads,
|
||||
re-engage customers. All automated.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.3, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<Users className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Dynamic Segmentation</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Segment your audience based on behavior, properties, and engagement. Send targeted emails to the right
|
||||
people at the right time.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.4, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<PackageOpen className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Open Source & Transparent</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
AGPL-3.0 licensed. Inspect the code, contribute features, understand exactly how it works. No
|
||||
proprietary black boxes.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.5, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<Globe className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Self-Hostable</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Run on your infrastructure with Docker. Full data control, compliance-ready, cost-optimized. Postmark is
|
||||
cloud-only.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.6, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<DollarSign className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Pay-As-You-Go Pricing</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Simple per-email pricing with all features included. No separate charges for transactional vs marketing
|
||||
emails. No tiers, no commitments.
|
||||
</p>
|
||||
{/* Pricing comparison */}
|
||||
<section className={'border-t border-neutral-200'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}} className={'mb-16'}>
|
||||
<h2 style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}>
|
||||
One Platform for All Your Emails
|
||||
</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Transactional reliability meets marketing power</p>
|
||||
</motion.div>
|
||||
<div className={'grid gap-4 lg:grid-cols-2'}>
|
||||
<motion.div initial={{opacity: 0, x: -20}} whileInView={{opacity: 1, x: 0}} viewport={{once: true}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}} className={'rounded-[24px] border border-neutral-900 bg-neutral-900 p-10 text-white'}>
|
||||
<div style={{fontFamily: 'var(--font-mono)'}} className={'text-[11px] uppercase tracking-[0.18em] text-neutral-400'}>Plunk</div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-2xl font-bold tracking-[-0.025em] text-white'}>Transactional + Marketing</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-300'}>Reliable transactional emails plus marketing campaigns, workflows, and segmentation in one platform.</p>
|
||||
<div style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-4xl font-extrabold tracking-[-0.03em] text-white'}>All-in-one</div>
|
||||
<ul className={'mt-8 space-y-3'}>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-300'}><Check className="h-4 w-4 flex-shrink-0 text-neutral-400" />Transactional emails included</li>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-300'}><Check className="h-4 w-4 flex-shrink-0 text-neutral-400" />Marketing campaigns included</li>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-300'}><Check className="h-4 w-4 flex-shrink-0 text-neutral-400" />Workflow automation included</li>
|
||||
</ul>
|
||||
</motion.div>
|
||||
<motion.div initial={{opacity: 0, x: 20}} whileInView={{opacity: 1, x: 0}} viewport={{once: true}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}} className={'rounded-[24px] border border-neutral-200 bg-white p-10'}>
|
||||
<div style={{fontFamily: 'var(--font-mono)'}} className={'text-[11px] uppercase tracking-[0.18em] text-neutral-500'}>Postmark</div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-2xl font-bold tracking-[-0.025em] text-neutral-900'}>Transactional only</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>Excellent for transactional emails, but no marketing features. Need a second service for campaigns.</p>
|
||||
<div style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-4xl font-extrabold tracking-[-0.03em] text-neutral-900'}>Limited scope</div>
|
||||
<ul className={'mt-8 space-y-3'}>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-600'}><div className={'h-1.5 w-1.5 flex-shrink-0 rounded-full bg-neutral-400'} />Transactional emails only</li>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-600'}><div className={'h-1.5 w-1.5 flex-shrink-0 rounded-full bg-neutral-400'} />No marketing campaigns</li>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-600'}><div className={'h-1.5 w-1.5 flex-shrink-0 rounded-full bg-neutral-400'} />No workflow automation</li>
|
||||
</ul>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Feature Comparison */}
|
||||
<section className={'py-32'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-16 text-center'}
|
||||
>
|
||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>Feature-by-Feature Comparison</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>See exactly what you get with each platform</p>
|
||||
</motion.div>
|
||||
{/* Key advantages */}
|
||||
<section className={'border-t border-neutral-200 bg-neutral-50/60'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}} className={'mb-16'}>
|
||||
<h2 style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}>Why Choose Plunk Over Postmark</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Do more with one platform instead of two</p>
|
||||
</motion.div>
|
||||
<div className={'grid gap-px bg-neutral-200 sm:grid-cols-2 lg:grid-cols-3'}>
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.5, delay: 0.1, ease: [0.22, 1, 0.36, 1]}} className={'bg-white p-10'}>
|
||||
<div className={'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white'}><BarChart3 className="h-5 w-5" /></div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>Marketing Campaigns Included</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>Send newsletters, announcements, and promotional emails without needing a separate marketing platform. One platform, one bill.</p>
|
||||
</motion.div>
|
||||
|
||||
<ComparisonTable competitorName="Postmark" rows={comparisonData} />
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.5, delay: 0.2, ease: [0.22, 1, 0.36, 1]}} className={'bg-white p-10'}>
|
||||
<div className={'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white'}><Zap className="h-5 w-5" /></div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>Workflow Automation</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>Build automated email sequences with triggers, delays, and conditions. Onboard users, nurture leads, re-engage customers. All automated.</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.5, delay: 0.3, ease: [0.22, 1, 0.36, 1]}} className={'bg-white p-10'}>
|
||||
<div className={'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white'}><Users className="h-5 w-5" /></div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>Dynamic Segmentation</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>Segment your audience based on behavior, properties, and engagement. Send targeted emails to the right people at the right time.</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.5, delay: 0.4, ease: [0.22, 1, 0.36, 1]}} className={'bg-white p-10'}>
|
||||
<div className={'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white'}><PackageOpen className="h-5 w-5" /></div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>Open Source & Transparent</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>AGPL-3.0 licensed. Inspect the code, contribute features, understand exactly how it works. No proprietary black boxes.</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.5, delay: 0.5, ease: [0.22, 1, 0.36, 1]}} className={'bg-white p-10'}>
|
||||
<div className={'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white'}><Globe className="h-5 w-5" /></div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>Self-Hostable</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>Run on your infrastructure with Docker. Full data control, compliance-ready, cost-optimized. Postmark is cloud-only.</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.5, delay: 0.6, ease: [0.22, 1, 0.36, 1]}} className={'bg-white p-10'}>
|
||||
<div className={'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white'}><DollarSign className="h-5 w-5" /></div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>Pay-As-You-Go Pricing</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>Simple per-email pricing with all features included. No separate charges for transactional vs marketing emails. No tiers, no commitments.</p>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Feature comparison table */}
|
||||
<section className={'border-t border-neutral-200'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}} className={'mb-16'}>
|
||||
<h2 style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}>Feature comparison</h2>
|
||||
</motion.div>
|
||||
<ComparisonTable competitorName="Postmark" rows={comparisonData} />
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* FAQ */}
|
||||
<FAQSection faqs={faqs} schemaId="faq-schema-postmark" />
|
||||
|
||||
{/* CTA */}
|
||||
<section className={'relative overflow-hidden border-t border-neutral-200 py-32'}>
|
||||
<div
|
||||
className={
|
||||
'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#e5e7eb_1px,transparent_1px),linear-gradient(to_bottom,#e5e7eb_1px,transparent_1px)] bg-[size:4rem_4rem] [mask-image:radial-gradient(ellipse_80%_50%_at_50%_100%,#000_70%,transparent_110%)]'
|
||||
}
|
||||
/>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mx-auto max-w-3xl text-center'}
|
||||
>
|
||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>Get more from your email platform</h2>
|
||||
<p className={'mt-6 text-lg text-neutral-600'}>
|
||||
Stop juggling multiple tools. Get transactional reliability plus marketing power in one platform. Start
|
||||
free.
|
||||
</p>
|
||||
<div className={'mt-12 flex flex-wrap justify-center gap-4'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.02}}
|
||||
whileTap={{scale: 0.98}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
className={
|
||||
'group rounded-lg bg-neutral-900 px-8 py-4 text-base font-semibold text-white transition hover:bg-neutral-800'
|
||||
}
|
||||
>
|
||||
<span className={'flex items-center gap-2'}>
|
||||
Get started free
|
||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-1" />
|
||||
</span>
|
||||
</motion.a>
|
||||
<Link
|
||||
href="/pricing"
|
||||
className={
|
||||
'rounded-lg border border-neutral-300 px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-400'
|
||||
}
|
||||
>
|
||||
View pricing details
|
||||
</Link>
|
||||
<section className={'relative overflow-hidden border-t border-neutral-900 bg-neutral-900 text-white'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-32 sm:px-10 sm:py-40'}>
|
||||
<div className={'flex flex-col items-start gap-12 lg:flex-row lg:items-end lg:justify-between'}>
|
||||
<motion.h2 initial={{opacity: 0, y: 16}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.9, ease: [0.22, 1, 0.36, 1]}} style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2.5rem,7vw,6rem)] font-extrabold leading-[0.95] tracking-[-0.035em]'}>
|
||||
Get more from your email platform
|
||||
</motion.h2>
|
||||
<motion.div initial={{opacity: 0, y: 16}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.9, delay: 0.15, ease: [0.22, 1, 0.36, 1]}} className={'flex max-w-md flex-col gap-6'}>
|
||||
<p className={'text-base text-neutral-300 sm:text-lg'}>Stop juggling multiple tools. Get transactional reliability plus marketing power in one platform. Start free.</p>
|
||||
<div className={'flex flex-wrap gap-3'}>
|
||||
<motion.a whileHover={{scale: 1.015}} whileTap={{scale: 0.985}} href={`${DASHBOARD_URI}/auth/signup`} className={'inline-flex items-center gap-2 rounded-full bg-white px-7 py-3.5 text-sm font-semibold text-neutral-900 transition hover:bg-neutral-100'}>
|
||||
Get started free <ArrowRight className="h-4 w-4" />
|
||||
</motion.a>
|
||||
<Link href={'/pricing'} className={'inline-flex items-center gap-2 rounded-full border border-neutral-700 px-7 py-3.5 text-sm font-semibold text-white transition hover:border-white'}>
|
||||
View pricing
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
</main>
|
||||
<Footer />
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -4,7 +4,7 @@ import {DASHBOARD_URI, WIKI_URI} from '../../lib/constants';
|
||||
import React from 'react';
|
||||
import Link from 'next/link';
|
||||
import {NextSeo} from 'next-seo';
|
||||
import {ArrowRight, BarChart3, Globe, Layers, PackageOpen, Users, Workflow} from 'lucide-react';
|
||||
import {ArrowRight, BarChart3, Check, Globe, Layers, PackageOpen, Users, Workflow} from 'lucide-react';
|
||||
import type {ComparisonRow} from '../../components/ComparisonTable';
|
||||
import type {FAQ} from '../../components/FAQSection';
|
||||
|
||||
@@ -65,309 +65,124 @@ export default function ResendComparison() {
|
||||
|
||||
<Navbar />
|
||||
|
||||
<main className={'mx-auto max-w-7xl px-8 sm:px-0'}>
|
||||
{/* Hero Section */}
|
||||
<section className={'relative py-32 sm:py-48'}>
|
||||
<div
|
||||
className={
|
||||
'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#e5e7eb_1px,transparent_1px),linear-gradient(to_bottom,#e5e7eb_1px,transparent_1px)] bg-[size:4rem_4rem] [mask-image:radial-gradient(ellipse_80%_50%_at_50%_0%,#000_70%,transparent_110%)]'
|
||||
}
|
||||
/>
|
||||
<main className={'text-neutral-800'}>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
animate={{opacity: 1, y: 0}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mx-auto max-w-4xl text-center'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'mb-6 inline-flex items-center gap-2 rounded-full border border-neutral-200 bg-white px-4 py-2'
|
||||
}
|
||||
>
|
||||
<span className={'text-sm text-neutral-600'}>Comparing</span>
|
||||
<span className={'text-sm font-semibold text-neutral-900'}>Plunk vs Resend</span>
|
||||
</div>
|
||||
|
||||
<h1 className={'text-6xl font-bold tracking-tight text-neutral-900 sm:text-7xl lg:text-8xl text-balance'}>
|
||||
Open-source alternative
|
||||
<br />
|
||||
for Resend
|
||||
</h1>
|
||||
|
||||
<p className={'mx-auto mt-8 max-w-2xl text-xl text-neutral-600'}>
|
||||
Resend is transactional-only. Plunk gives you transactional emails, marketing campaigns, and workflow automation in a single open-source platform. No second tool, no second bill.
|
||||
</p>
|
||||
|
||||
<div className={'mt-12 flex flex-wrap justify-center gap-4'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.02}}
|
||||
whileTap={{scale: 0.98}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
className={
|
||||
'group rounded-lg bg-neutral-900 px-8 py-4 text-base font-semibold text-white shadow-lg shadow-neutral-900/10 transition hover:bg-neutral-800'
|
||||
}
|
||||
>
|
||||
<span className={'flex items-center gap-2'}>
|
||||
Try Plunk free
|
||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-1" />
|
||||
</span>
|
||||
</motion.a>
|
||||
<Link
|
||||
href={WIKI_URI}
|
||||
target={'_blank'}
|
||||
className={
|
||||
'rounded-lg border border-neutral-300 bg-white px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-400'
|
||||
}
|
||||
>
|
||||
View documentation
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
</section>
|
||||
|
||||
{/* Pricing Model Comparison */}
|
||||
<section className={'py-32'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-16 text-center'}
|
||||
>
|
||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>The Pricing Model That Makes Sense</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Pay for what you use, not fixed subscriptions</p>
|
||||
</motion.div>
|
||||
|
||||
<div className={'grid gap-8 lg:grid-cols-2'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, x: -20}}
|
||||
whileInView={{opacity: 1, x: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'rounded-2xl border-2 border-neutral-900 bg-white p-10'}
|
||||
>
|
||||
<div className={'mb-4 inline-flex items-center gap-2 rounded-full bg-neutral-900 px-4 py-1.5'}>
|
||||
<span className={'text-sm font-semibold text-white'}>Plunk</span>
|
||||
{/* Hero */}
|
||||
<section className={'relative overflow-hidden'}>
|
||||
<div aria-hidden className={'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#eeeeee_1px,transparent_1px),linear-gradient(to_bottom,#eeeeee_1px,transparent_1px)] bg-[size:6rem_6rem] [mask-image:radial-gradient(ellipse_70%_60%_at_50%_30%,#000_40%,transparent_95%)]'} />
|
||||
<div className={'mx-auto max-w-[88rem] px-6 pb-20 pt-20 sm:px-10 sm:pt-28 sm:pb-28'}>
|
||||
<motion.div initial={{opacity: 0, y: 16}} animate={{opacity: 1, y: 0}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}>
|
||||
<div style={{fontFamily: 'var(--font-mono)'}} className={'mb-6 text-[11px] uppercase tracking-[0.18em] text-neutral-500'}>
|
||||
Plunk vs Resend
|
||||
</div>
|
||||
<h3 className={'mt-6 text-2xl font-bold text-neutral-900'}>Pay per email sent</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Pay-as-you-go pricing. Only pay for emails you actually send.
|
||||
</p>
|
||||
<div className={'mt-6 text-4xl font-bold text-neutral-900'}>Pay-as-you-go</div>
|
||||
<div className={'mt-8 space-y-3'}>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-900 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-white'} />
|
||||
</div>
|
||||
<span>Only pay for emails you actually send</span>
|
||||
</div>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-900 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-white'} />
|
||||
</div>
|
||||
<span>Scale up or down without commitment</span>
|
||||
</div>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-900 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-white'} />
|
||||
</div>
|
||||
<span>Marketing and automation included</span>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, x: 20}}
|
||||
whileInView={{opacity: 1, x: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'rounded-2xl border border-neutral-200 bg-neutral-50 p-10'}
|
||||
>
|
||||
<div className={'mb-4 inline-flex items-center gap-2 rounded-full bg-neutral-200 px-4 py-1.5'}>
|
||||
<span className={'text-sm font-semibold text-neutral-900'}>Resend</span>
|
||||
</div>
|
||||
<h3 className={'mt-6 text-2xl font-bold text-neutral-900'}>Fixed subscription tiers</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Monthly subscription with fixed email limits per tier.
|
||||
</p>
|
||||
<div className={'mt-6 text-4xl font-bold text-neutral-900'}>Fixed subscription</div>
|
||||
<div className={'mt-8 space-y-3'}>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-300 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-neutral-600'} />
|
||||
</div>
|
||||
<span>Locked into monthly subscription tiers</span>
|
||||
</div>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-300 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-neutral-600'} />
|
||||
</div>
|
||||
<span>Need to upgrade plan as you grow</span>
|
||||
</div>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-300 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-neutral-600'} />
|
||||
</div>
|
||||
<span>Transactional only, no marketing</span>
|
||||
</div>
|
||||
<h1 style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2.75rem,7vw,6.5rem)] font-extrabold leading-[0.92] tracking-[-0.04em] text-neutral-900'}>
|
||||
Open-source alternative
|
||||
<br />
|
||||
for Resend
|
||||
</h1>
|
||||
<p className={'mt-6 max-w-2xl text-xl text-neutral-600'}>Resend is transactional-only. Plunk gives you transactional emails, marketing campaigns, and workflow automation in a single open-source platform. No second tool, no second bill.</p>
|
||||
<div className={'mt-10 flex flex-wrap gap-3'}>
|
||||
<motion.a whileHover={{scale: 1.015}} whileTap={{scale: 0.985}} href={`${DASHBOARD_URI}/auth/signup`} className={'group inline-flex items-center gap-2 rounded-full bg-neutral-900 px-8 py-4 text-base font-semibold text-white shadow-[0_10px_30px_-10px_rgba(23,23,23,0.35)] transition hover:bg-neutral-800'}>
|
||||
Try Plunk free <ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-0.5" />
|
||||
</motion.a>
|
||||
<Link href={WIKI_URI} target={'_blank'} className={'inline-flex items-center gap-2 rounded-full border border-neutral-300 bg-white px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-900'}>
|
||||
View documentation
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Feature Comparison */}
|
||||
<section className={'py-32'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-16 text-center'}
|
||||
>
|
||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>Feature-by-Feature</h2>
|
||||
</motion.div>
|
||||
|
||||
<ComparisonTable competitorName="Resend" rows={comparisonData} />
|
||||
{/* Pricing comparison */}
|
||||
<section className={'border-t border-neutral-200'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}} className={'mb-16'}>
|
||||
<h2 style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}>
|
||||
The Pricing Model That Makes Sense
|
||||
</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Pay for what you use, not fixed subscriptions</p>
|
||||
</motion.div>
|
||||
<div className={'grid gap-4 lg:grid-cols-2'}>
|
||||
<motion.div initial={{opacity: 0, x: -20}} whileInView={{opacity: 1, x: 0}} viewport={{once: true}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}} className={'rounded-[24px] border border-neutral-900 bg-neutral-900 p-10 text-white'}>
|
||||
<div style={{fontFamily: 'var(--font-mono)'}} className={'text-[11px] uppercase tracking-[0.18em] text-neutral-400'}>Plunk</div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-2xl font-bold tracking-[-0.025em] text-white'}>Pay per email sent</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-300'}>Pay-as-you-go pricing. Only pay for emails you actually send.</p>
|
||||
<div style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-4xl font-extrabold tracking-[-0.03em] text-white'}>Pay-as-you-go</div>
|
||||
<ul className={'mt-8 space-y-3'}>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-300'}><Check className="h-4 w-4 flex-shrink-0 text-neutral-400" />Only pay for emails you actually send</li>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-300'}><Check className="h-4 w-4 flex-shrink-0 text-neutral-400" />Scale up or down without commitment</li>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-300'}><Check className="h-4 w-4 flex-shrink-0 text-neutral-400" />Marketing and automation included</li>
|
||||
</ul>
|
||||
</motion.div>
|
||||
<motion.div initial={{opacity: 0, x: 20}} whileInView={{opacity: 1, x: 0}} viewport={{once: true}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}} className={'rounded-[24px] border border-neutral-200 bg-white p-10'}>
|
||||
<div style={{fontFamily: 'var(--font-mono)'}} className={'text-[11px] uppercase tracking-[0.18em] text-neutral-500'}>Resend</div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-2xl font-bold tracking-[-0.025em] text-neutral-900'}>Fixed subscription tiers</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>Monthly subscription with fixed email limits per tier.</p>
|
||||
<div style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-4xl font-extrabold tracking-[-0.03em] text-neutral-900'}>Fixed subscription</div>
|
||||
<ul className={'mt-8 space-y-3'}>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-600'}><div className={'h-1.5 w-1.5 flex-shrink-0 rounded-full bg-neutral-400'} />Locked into monthly subscription tiers</li>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-600'}><div className={'h-1.5 w-1.5 flex-shrink-0 rounded-full bg-neutral-400'} />Need to upgrade plan as you grow</li>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-600'}><div className={'h-1.5 w-1.5 flex-shrink-0 rounded-full bg-neutral-400'} />Transactional only, no marketing</li>
|
||||
</ul>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* What Plunk Adds */}
|
||||
<section className={'py-32'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-20 text-center'}
|
||||
>
|
||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>What Plunk Adds</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Beyond transactional emails</p>
|
||||
</motion.div>
|
||||
|
||||
<div className={'grid gap-px bg-neutral-200 sm:grid-cols-3'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.1, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<BarChart3 className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Marketing Campaigns</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Send one-time broadcasts to all contacts or specific segments. Schedule sends, track performance. Resend
|
||||
doesn't offer this.
|
||||
</p>
|
||||
{/* Key advantages */}
|
||||
<section className={'border-t border-neutral-200 bg-neutral-50/60'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}} className={'mb-16'}>
|
||||
<h2 style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}>What Plunk Adds</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Beyond transactional emails</p>
|
||||
</motion.div>
|
||||
<div className={'grid gap-px bg-neutral-200 sm:grid-cols-3'}>
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.5, delay: 0.1, ease: [0.22, 1, 0.36, 1]}} className={'bg-white p-10'}>
|
||||
<div className={'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white'}><BarChart3 className="h-5 w-5" /></div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>Marketing Campaigns</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>Send one-time broadcasts to all contacts or specific segments. Schedule sends, track performance. Resend doesn't offer this.</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.2, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<Workflow className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Workflow Automation</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Build multi-step email sequences with triggers, delays, and conditions. Perfect for onboarding, drip
|
||||
campaigns, cart abandonment.
|
||||
</p>
|
||||
</motion.div>
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.5, delay: 0.2, ease: [0.22, 1, 0.36, 1]}} className={'bg-white p-10'}>
|
||||
<div className={'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white'}><Workflow className="h-5 w-5" /></div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>Workflow Automation</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>Build multi-step email sequences with triggers, delays, and conditions. Perfect for onboarding, drip campaigns, cart abandonment.</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.3, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<Users className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Dynamic Segmentation</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Create audience segments that update automatically based on contact data and behavior. Target campaigns
|
||||
precisely.
|
||||
</p>
|
||||
</motion.div>
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.5, delay: 0.3, ease: [0.22, 1, 0.36, 1]}} className={'bg-white p-10'}>
|
||||
<div className={'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white'}><Users className="h-5 w-5" /></div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>Dynamic Segmentation</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>Create audience segments that update automatically based on contact data and behavior. Target campaigns precisely.</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.4, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<PackageOpen className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Open Source</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
AGPL-3.0 licensed. Inspect the code, contribute features, no vendor lock-in. Resend is proprietary.
|
||||
</p>
|
||||
</motion.div>
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.5, delay: 0.4, ease: [0.22, 1, 0.36, 1]}} className={'bg-white p-10'}>
|
||||
<div className={'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white'}><PackageOpen className="h-5 w-5" /></div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>Open Source</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>AGPL-3.0 licensed. Inspect the code, contribute features, no vendor lock-in. Resend is proprietary.</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.5, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<Globe className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Self-Hostable</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Run on your infrastructure with Docker. Full data control, compliance-ready. Pay only AWS SES fees when
|
||||
self-hosting.
|
||||
</p>
|
||||
</motion.div>
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.5, delay: 0.5, ease: [0.22, 1, 0.36, 1]}} className={'bg-white p-10'}>
|
||||
<div className={'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white'}><Globe className="h-5 w-5" /></div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>Self-Hostable</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>Run on your infrastructure with Docker. Full data control, compliance-ready. Pay only AWS SES fees when self-hosting.</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.6, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<Layers className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>All-in-One Platform</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
One platform for transactional, marketing, and automation. No need for multiple tools or integrations.
|
||||
</p>
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.5, delay: 0.6, ease: [0.22, 1, 0.36, 1]}} className={'bg-white p-10'}>
|
||||
<div className={'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white'}><Layers className="h-5 w-5" /></div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>All-in-One Platform</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>One platform for transactional, marketing, and automation. No need for multiple tools or integrations.</p>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Feature comparison table */}
|
||||
<section className={'border-t border-neutral-200'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}} className={'mb-16'}>
|
||||
<h2 style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}>Feature comparison</h2>
|
||||
</motion.div>
|
||||
<ComparisonTable competitorName="Resend" rows={comparisonData} />
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -375,51 +190,28 @@ export default function ResendComparison() {
|
||||
<FAQSection faqs={faqs} schemaId="faq-schema-resend" />
|
||||
|
||||
{/* CTA */}
|
||||
<section className={'relative overflow-hidden border-t border-neutral-200 py-32'}>
|
||||
<div
|
||||
className={
|
||||
'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#e5e7eb_1px,transparent_1px),linear-gradient(to_bottom,#e5e7eb_1px,transparent_1px)] bg-[size:4rem_4rem] [mask-image:radial-gradient(ellipse_80%_50%_at_50%_100%,#000_70%,transparent_110%)]'
|
||||
}
|
||||
/>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mx-auto max-w-3xl text-center'}
|
||||
>
|
||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>Try Plunk free</h2>
|
||||
<p className={'mt-6 text-lg text-neutral-600'}>
|
||||
1,000 emails/month free. No credit card required. Add marketing and automation when you need it.
|
||||
</p>
|
||||
<div className={'mt-12 flex flex-wrap justify-center gap-4'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.02}}
|
||||
whileTap={{scale: 0.98}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
className={
|
||||
'group rounded-lg bg-neutral-900 px-8 py-4 text-base font-semibold text-white transition hover:bg-neutral-800'
|
||||
}
|
||||
>
|
||||
<span className={'flex items-center gap-2'}>
|
||||
Get started free
|
||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-1" />
|
||||
</span>
|
||||
</motion.a>
|
||||
<Link
|
||||
href={WIKI_URI}
|
||||
target={'_blank'}
|
||||
className={
|
||||
'rounded-lg border border-neutral-300 px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-400'
|
||||
}
|
||||
>
|
||||
Read documentation
|
||||
</Link>
|
||||
<section className={'relative overflow-hidden border-t border-neutral-900 bg-neutral-900 text-white'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-32 sm:px-10 sm:py-40'}>
|
||||
<div className={'flex flex-col items-start gap-12 lg:flex-row lg:items-end lg:justify-between'}>
|
||||
<motion.h2 initial={{opacity: 0, y: 16}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.9, ease: [0.22, 1, 0.36, 1]}} style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2.5rem,7vw,6rem)] font-extrabold leading-[0.95] tracking-[-0.035em]'}>
|
||||
Try Plunk free
|
||||
</motion.h2>
|
||||
<motion.div initial={{opacity: 0, y: 16}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.9, delay: 0.15, ease: [0.22, 1, 0.36, 1]}} className={'flex max-w-md flex-col gap-6'}>
|
||||
<p className={'text-base text-neutral-300 sm:text-lg'}>1,000 emails/month free. No credit card required. Add marketing and automation when you need it.</p>
|
||||
<div className={'flex flex-wrap gap-3'}>
|
||||
<motion.a whileHover={{scale: 1.015}} whileTap={{scale: 0.985}} href={`${DASHBOARD_URI}/auth/signup`} className={'inline-flex items-center gap-2 rounded-full bg-white px-7 py-3.5 text-sm font-semibold text-neutral-900 transition hover:bg-neutral-100'}>
|
||||
Get started free <ArrowRight className="h-4 w-4" />
|
||||
</motion.a>
|
||||
<Link href={'/pricing'} className={'inline-flex items-center gap-2 rounded-full border border-neutral-700 px-7 py-3.5 text-sm font-semibold text-white transition hover:border-white'}>
|
||||
View pricing
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
</main>
|
||||
<Footer />
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -4,7 +4,7 @@ import {DASHBOARD_URI, WIKI_URI} from '../../lib/constants';
|
||||
import React from 'react';
|
||||
import Link from 'next/link';
|
||||
import {NextSeo} from 'next-seo';
|
||||
import {ArrowRight, BarChart3, DollarSign, Globe, PackageOpen, Users, Zap} from 'lucide-react';
|
||||
import {ArrowRight, BarChart3, Check, DollarSign, Globe, PackageOpen, Users, Zap} from 'lucide-react';
|
||||
import type {ComparisonRow} from '../../components/ComparisonTable';
|
||||
import type {FAQ} from '../../components/FAQSection';
|
||||
|
||||
@@ -69,364 +69,153 @@ export default function SendGridComparison() {
|
||||
|
||||
<Navbar />
|
||||
|
||||
<main className={'mx-auto max-w-7xl px-8 sm:px-0'}>
|
||||
{/* Hero Section */}
|
||||
<section className={'relative py-32 sm:py-48'}>
|
||||
<div
|
||||
className={
|
||||
'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#e5e7eb_1px,transparent_1px),linear-gradient(to_bottom,#e5e7eb_1px,transparent_1px)] bg-[size:4rem_4rem] [mask-image:radial-gradient(ellipse_80%_50%_at_50%_0%,#000_70%,transparent_110%)]'
|
||||
}
|
||||
/>
|
||||
<main className={'text-neutral-800'}>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
animate={{opacity: 1, y: 0}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mx-auto max-w-4xl text-center'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'mb-6 inline-flex items-center gap-2 rounded-full border border-neutral-200 bg-white px-4 py-2'
|
||||
}
|
||||
>
|
||||
<span className={'text-sm text-neutral-600'}>Comparing</span>
|
||||
<span className={'text-sm font-semibold text-neutral-900'}>Plunk vs SendGrid</span>
|
||||
</div>
|
||||
|
||||
<h1 className={'text-6xl font-bold tracking-tight text-neutral-900 sm:text-7xl lg:text-8xl text-balance'}>
|
||||
Open-source alternative
|
||||
<br />
|
||||
for SendGrid
|
||||
</h1>
|
||||
|
||||
<p className={'mx-auto mt-8 max-w-2xl text-xl text-neutral-600'}>
|
||||
Pay-as-you-go instead of fixed subscriptions. No complex setup, no feature gating, no enterprise sales
|
||||
pitches. Built for developers, not procurement teams.
|
||||
</p>
|
||||
|
||||
<div className={'mt-12 flex flex-wrap justify-center gap-4'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.02}}
|
||||
whileTap={{scale: 0.98}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
className={
|
||||
'group rounded-lg bg-neutral-900 px-8 py-4 text-base font-semibold text-white shadow-lg shadow-neutral-900/10 transition hover:bg-neutral-800'
|
||||
}
|
||||
>
|
||||
<span className={'flex items-center gap-2'}>
|
||||
Get started free
|
||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-1" />
|
||||
</span>
|
||||
</motion.a>
|
||||
<Link
|
||||
href={WIKI_URI}
|
||||
target={'_blank'}
|
||||
className={
|
||||
'rounded-lg border border-neutral-300 bg-white px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-400'
|
||||
}
|
||||
>
|
||||
View documentation
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
</section>
|
||||
|
||||
{/* Pricing Model Comparison */}
|
||||
<section className={'py-32'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-16 text-center'}
|
||||
>
|
||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>The Pricing Model That Makes Sense</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Pay for what you use, not for what you might use</p>
|
||||
</motion.div>
|
||||
|
||||
<div className={'grid gap-8 lg:grid-cols-2'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, x: -20}}
|
||||
whileInView={{opacity: 1, x: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'rounded-2xl border-2 border-neutral-900 bg-white p-10'}
|
||||
>
|
||||
<div className={'mb-4 inline-flex items-center gap-2 rounded-full bg-neutral-900 px-4 py-1.5'}>
|
||||
<span className={'text-sm font-semibold text-white'}>Plunk</span>
|
||||
{/* Hero */}
|
||||
<section className={'relative overflow-hidden'}>
|
||||
<div aria-hidden className={'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#eeeeee_1px,transparent_1px),linear-gradient(to_bottom,#eeeeee_1px,transparent_1px)] bg-[size:6rem_6rem] [mask-image:radial-gradient(ellipse_70%_60%_at_50%_30%,#000_40%,transparent_95%)]'} />
|
||||
<div className={'mx-auto max-w-[88rem] px-6 pb-20 pt-20 sm:px-10 sm:pt-28 sm:pb-28'}>
|
||||
<motion.div initial={{opacity: 0, y: 16}} animate={{opacity: 1, y: 0}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}>
|
||||
<div style={{fontFamily: 'var(--font-mono)'}} className={'mb-6 text-[11px] uppercase tracking-[0.18em] text-neutral-500'}>
|
||||
Plunk vs SendGrid
|
||||
</div>
|
||||
<h3 className={'mt-6 text-2xl font-bold text-neutral-900'}>Pay per email sent</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Pay-as-you-go pricing. Only pay for emails you actually send, no monthly minimums.
|
||||
</p>
|
||||
<div className={'mt-6 text-4xl font-bold text-neutral-900'}>Pay-as-you-go</div>
|
||||
<div className={'mt-8 space-y-3'}>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-900 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-white'} />
|
||||
</div>
|
||||
<span>No monthly minimum or commitment</span>
|
||||
</div>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-900 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-white'} />
|
||||
</div>
|
||||
<span>Marketing campaigns included</span>
|
||||
</div>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-900 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-white'} />
|
||||
</div>
|
||||
<span>Workflow automation included</span>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, x: 20}}
|
||||
whileInView={{opacity: 1, x: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'rounded-2xl border border-neutral-200 bg-neutral-50 p-10'}
|
||||
>
|
||||
<div className={'mb-4 inline-flex items-center gap-2 rounded-full bg-neutral-200 px-4 py-1.5'}>
|
||||
<span className={'text-sm font-semibold text-neutral-900'}>SendGrid</span>
|
||||
</div>
|
||||
<h3 className={'mt-6 text-2xl font-bold text-neutral-900'}>Monthly subscription tiers</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Fixed monthly fees based on email volume tiers with feature restrictions.
|
||||
</p>
|
||||
<div className={'mt-6 text-4xl font-bold text-neutral-900'}>Fixed subscription</div>
|
||||
<div className={'mt-8 space-y-3'}>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-300 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-neutral-600'} />
|
||||
</div>
|
||||
<span>Locked into monthly subscription plan</span>
|
||||
</div>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-300 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-neutral-600'} />
|
||||
</div>
|
||||
<span>Marketing is a separate paid product</span>
|
||||
</div>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-300 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-neutral-600'} />
|
||||
</div>
|
||||
<span>Automation locked to enterprise tier</span>
|
||||
</div>
|
||||
<h1 style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2.75rem,7vw,6.5rem)] font-extrabold leading-[0.92] tracking-[-0.04em] text-neutral-900'}>
|
||||
Open-source alternative
|
||||
<br />
|
||||
for SendGrid
|
||||
</h1>
|
||||
<p className={'mt-6 max-w-2xl text-xl text-neutral-600'}>Pay-as-you-go instead of fixed subscriptions. No complex setup, no feature gating, no enterprise sales pitches. Built for developers, not procurement teams.</p>
|
||||
<div className={'mt-10 flex flex-wrap gap-3'}>
|
||||
<motion.a whileHover={{scale: 1.015}} whileTap={{scale: 0.985}} href={`${DASHBOARD_URI}/auth/signup`} className={'group inline-flex items-center gap-2 rounded-full bg-neutral-900 px-8 py-4 text-base font-semibold text-white shadow-[0_10px_30px_-10px_rgba(23,23,23,0.35)] transition hover:bg-neutral-800'}>
|
||||
Get started free <ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-0.5" />
|
||||
</motion.a>
|
||||
<Link href={WIKI_URI} target={'_blank'} className={'inline-flex items-center gap-2 rounded-full border border-neutral-300 bg-white px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-900'}>
|
||||
View documentation
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Key Advantages */}
|
||||
<section className={'py-32'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-20 text-center'}
|
||||
>
|
||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>Why Choose Plunk Over SendGrid</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Built for modern developers, not enterprise sales teams</p>
|
||||
</motion.div>
|
||||
|
||||
<div className={'grid gap-px bg-neutral-200 sm:grid-cols-2 lg:grid-cols-3'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.1, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<DollarSign className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Simple, Transparent Pricing</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Pay-as-you-go per email. No hidden fees, no complex tiers, no enterprise sales calls. Start free, scale
|
||||
as you grow.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.2, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<Zap className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>5-Minute Setup</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Start sending emails in minutes, not hours. Modern API, clear documentation, no complex configuration.
|
||||
Copy-paste and go.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.3, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<BarChart3 className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Marketing Included</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Campaigns, workflows, and segmentation at no extra cost. SendGrid requires their separate Marketing
|
||||
Campaigns product with additional fees.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.4, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<PackageOpen className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Open Source & Transparent</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
AGPL-3.0 licensed. Inspect the code, contribute features, self-host if needed. No black boxes, no vendor
|
||||
lock-in.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.5, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<Globe className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Self-Hostable</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Run on your infrastructure with Docker. Full data control, compliance-ready, cost-optimized. SendGrid is
|
||||
cloud-only.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.6, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<Users className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>No Feature Gating</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
All features available on all plans. No artificial limits, no forced upgrades to "enterprise" for basic
|
||||
automation.
|
||||
</p>
|
||||
{/* Pricing comparison */}
|
||||
<section className={'border-t border-neutral-200'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}} className={'mb-16'}>
|
||||
<h2 style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}>
|
||||
The Pricing Model That Makes Sense
|
||||
</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Pay for what you use, not for what you might use</p>
|
||||
</motion.div>
|
||||
<div className={'grid gap-4 lg:grid-cols-2'}>
|
||||
<motion.div initial={{opacity: 0, x: -20}} whileInView={{opacity: 1, x: 0}} viewport={{once: true}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}} className={'rounded-[24px] border border-neutral-900 bg-neutral-900 p-10 text-white'}>
|
||||
<div style={{fontFamily: 'var(--font-mono)'}} className={'text-[11px] uppercase tracking-[0.18em] text-neutral-400'}>Plunk</div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-2xl font-bold tracking-[-0.025em] text-white'}>Pay per email sent</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-300'}>Pay-as-you-go pricing. Only pay for emails you actually send, no monthly minimums.</p>
|
||||
<div style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-4xl font-extrabold tracking-[-0.03em] text-white'}>Pay-as-you-go</div>
|
||||
<ul className={'mt-8 space-y-3'}>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-300'}><Check className="h-4 w-4 flex-shrink-0 text-neutral-400" />No monthly minimum or commitment</li>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-300'}><Check className="h-4 w-4 flex-shrink-0 text-neutral-400" />Marketing campaigns included</li>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-300'}><Check className="h-4 w-4 flex-shrink-0 text-neutral-400" />Workflow automation included</li>
|
||||
</ul>
|
||||
</motion.div>
|
||||
<motion.div initial={{opacity: 0, x: 20}} whileInView={{opacity: 1, x: 0}} viewport={{once: true}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}} className={'rounded-[24px] border border-neutral-200 bg-white p-10'}>
|
||||
<div style={{fontFamily: 'var(--font-mono)'}} className={'text-[11px] uppercase tracking-[0.18em] text-neutral-500'}>SendGrid</div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-2xl font-bold tracking-[-0.025em] text-neutral-900'}>Monthly subscription tiers</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>Fixed monthly fees based on email volume tiers with feature restrictions.</p>
|
||||
<div style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-4xl font-extrabold tracking-[-0.03em] text-neutral-900'}>Fixed subscription</div>
|
||||
<ul className={'mt-8 space-y-3'}>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-600'}><div className={'h-1.5 w-1.5 flex-shrink-0 rounded-full bg-neutral-400'} />Locked into monthly subscription plan</li>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-600'}><div className={'h-1.5 w-1.5 flex-shrink-0 rounded-full bg-neutral-400'} />Marketing is a separate paid product</li>
|
||||
<li className={'flex items-center gap-3 text-sm text-neutral-600'}><div className={'h-1.5 w-1.5 flex-shrink-0 rounded-full bg-neutral-400'} />Automation locked to enterprise tier</li>
|
||||
</ul>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Feature Comparison */}
|
||||
<section className={'py-32'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-16 text-center'}
|
||||
>
|
||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>Feature-by-Feature Comparison</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>See exactly what you get with each platform</p>
|
||||
</motion.div>
|
||||
{/* Key advantages */}
|
||||
<section className={'border-t border-neutral-200 bg-neutral-50/60'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}} className={'mb-16'}>
|
||||
<h2 style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}>Why Choose Plunk Over SendGrid</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Built for modern developers, not enterprise sales teams</p>
|
||||
</motion.div>
|
||||
<div className={'grid gap-px bg-neutral-200 sm:grid-cols-2 lg:grid-cols-3'}>
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.5, delay: 0.1, ease: [0.22, 1, 0.36, 1]}} className={'bg-white p-10'}>
|
||||
<div className={'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white'}><DollarSign className="h-5 w-5" /></div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>Simple, Transparent Pricing</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>Pay-as-you-go per email. No hidden fees, no complex tiers, no enterprise sales calls. Start free, scale as you grow.</p>
|
||||
</motion.div>
|
||||
|
||||
<ComparisonTable competitorName="SendGrid" rows={comparisonData} />
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.5, delay: 0.2, ease: [0.22, 1, 0.36, 1]}} className={'bg-white p-10'}>
|
||||
<div className={'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white'}><Zap className="h-5 w-5" /></div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>5-Minute Setup</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>Start sending emails in minutes, not hours. Modern API, clear documentation, no complex configuration. Copy-paste and go.</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.5, delay: 0.3, ease: [0.22, 1, 0.36, 1]}} className={'bg-white p-10'}>
|
||||
<div className={'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white'}><BarChart3 className="h-5 w-5" /></div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>Marketing Included</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>Campaigns, workflows, and segmentation at no extra cost. SendGrid requires their separate Marketing Campaigns product with additional fees.</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.5, delay: 0.4, ease: [0.22, 1, 0.36, 1]}} className={'bg-white p-10'}>
|
||||
<div className={'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white'}><PackageOpen className="h-5 w-5" /></div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>Open Source & Transparent</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>AGPL-3.0 licensed. Inspect the code, contribute features, self-host if needed. No black boxes, no vendor lock-in.</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.5, delay: 0.5, ease: [0.22, 1, 0.36, 1]}} className={'bg-white p-10'}>
|
||||
<div className={'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white'}><Globe className="h-5 w-5" /></div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>Self-Hostable</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>Run on your infrastructure with Docker. Full data control, compliance-ready, cost-optimized. SendGrid is cloud-only.</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.5, delay: 0.6, ease: [0.22, 1, 0.36, 1]}} className={'bg-white p-10'}>
|
||||
<div className={'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white'}><Users className="h-5 w-5" /></div>
|
||||
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>No Feature Gating</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>All features available on all plans. No artificial limits, no forced upgrades to "enterprise" for basic automation.</p>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Feature comparison table */}
|
||||
<section className={'border-t border-neutral-200'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||
<motion.div initial={{opacity: 0, y: 20}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}} className={'mb-16'}>
|
||||
<h2 style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}>Feature comparison</h2>
|
||||
</motion.div>
|
||||
<ComparisonTable competitorName="SendGrid" rows={comparisonData} />
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* FAQ */}
|
||||
<FAQSection faqs={faqs} schemaId="faq-schema-sendgrid" />
|
||||
|
||||
{/* CTA */}
|
||||
<section className={'relative overflow-hidden border-t border-neutral-200 py-32'}>
|
||||
<div
|
||||
className={
|
||||
'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#e5e7eb_1px,transparent_1px),linear-gradient(to_bottom,#e5e7eb_1px,transparent_1px)] bg-[size:4rem_4rem] [mask-image:radial-gradient(ellipse_80%_50%_at_50%_100%,#000_70%,transparent_110%)]'
|
||||
}
|
||||
/>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mx-auto max-w-3xl text-center'}
|
||||
>
|
||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>Make the switch today</h2>
|
||||
<p className={'mt-6 text-lg text-neutral-600'}>
|
||||
Join hundreds of developers who've ditched SendGrid's complexity for Plunk's simplicity.
|
||||
</p>
|
||||
<div className={'mt-12 flex flex-wrap justify-center gap-4'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.02}}
|
||||
whileTap={{scale: 0.98}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
className={
|
||||
'group rounded-lg bg-neutral-900 px-8 py-4 text-base font-semibold text-white transition hover:bg-neutral-800'
|
||||
}
|
||||
>
|
||||
<span className={'flex items-center gap-2'}>
|
||||
Get started free
|
||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-1" />
|
||||
</span>
|
||||
</motion.a>
|
||||
<Link
|
||||
href="/pricing"
|
||||
className={
|
||||
'rounded-lg border border-neutral-300 px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-400'
|
||||
}
|
||||
>
|
||||
View pricing details
|
||||
</Link>
|
||||
<section className={'relative overflow-hidden border-t border-neutral-900 bg-neutral-900 text-white'}>
|
||||
<div className={'mx-auto max-w-[88rem] px-6 py-32 sm:px-10 sm:py-40'}>
|
||||
<div className={'flex flex-col items-start gap-12 lg:flex-row lg:items-end lg:justify-between'}>
|
||||
<motion.h2 initial={{opacity: 0, y: 16}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.9, ease: [0.22, 1, 0.36, 1]}} style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2.5rem,7vw,6rem)] font-extrabold leading-[0.95] tracking-[-0.035em]'}>
|
||||
Make the switch today
|
||||
</motion.h2>
|
||||
<motion.div initial={{opacity: 0, y: 16}} whileInView={{opacity: 1, y: 0}} viewport={{once: true}} transition={{duration: 0.9, delay: 0.15, ease: [0.22, 1, 0.36, 1]}} className={'flex max-w-md flex-col gap-6'}>
|
||||
<p className={'text-base text-neutral-300 sm:text-lg'}>Join hundreds of developers who've ditched SendGrid's complexity for Plunk's simplicity.</p>
|
||||
<div className={'flex flex-wrap gap-3'}>
|
||||
<motion.a whileHover={{scale: 1.015}} whileTap={{scale: 0.985}} href={`${DASHBOARD_URI}/auth/signup`} className={'inline-flex items-center gap-2 rounded-full bg-white px-7 py-3.5 text-sm font-semibold text-neutral-900 transition hover:bg-neutral-100'}>
|
||||
Get started free <ArrowRight className="h-4 w-4" />
|
||||
</motion.a>
|
||||
<Link href={'/pricing'} className={'inline-flex items-center gap-2 rounded-full border border-neutral-700 px-7 py-3.5 text-sm font-semibold text-white transition hover:border-white'}>
|
||||
View pricing
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
</main>
|
||||
<Footer />
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -161,6 +161,26 @@
|
||||
|
||||
body {
|
||||
@apply bg-background text-neutral-800;
|
||||
font-family: var(--font-body, ui-sans-serif, system-ui, sans-serif);
|
||||
font-feature-settings: "rlig" 1, "calt" 1;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
font-family: var(--font-display, ui-sans-serif, system-ui, sans-serif);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes marquee-x {
|
||||
from { transform: translateX(0); }
|
||||
to { transform: translateX(-50%); }
|
||||
}
|
||||
|
||||
.marquee-track {
|
||||
animation: marquee-x 40s linear infinite;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.marquee-track {
|
||||
animation: none;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user