ui: Polish marketing website
This commit is contained in:
@@ -13,26 +13,21 @@ interface ComparisonTableProps {
|
|||||||
rows: ComparisonRow[];
|
rows: ComparisonRow[];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Reusable comparison table component for competitor pages
|
|
||||||
*/
|
|
||||||
export function ComparisonTable({competitorName, rows}: ComparisonTableProps) {
|
export function ComparisonTable({competitorName, rows}: ComparisonTableProps) {
|
||||||
return (
|
return (
|
||||||
<div className={'overflow-hidden rounded-xl border border-neutral-200'}>
|
<div className={'overflow-hidden rounded-[24px] border border-neutral-200'}>
|
||||||
{/* Header */}
|
|
||||||
<div className={'grid grid-cols-3 gap-px bg-neutral-200'}>
|
<div className={'grid grid-cols-3 gap-px bg-neutral-200'}>
|
||||||
<div className={'bg-white p-6'}>
|
<div className={'bg-neutral-50 p-6'}>
|
||||||
<span className={'text-sm font-semibold text-neutral-900'}>Feature</span>
|
<span style={{fontFamily: 'var(--font-mono)'}} className={'text-[11px] uppercase tracking-[0.18em] text-neutral-500'}>Feature</span>
|
||||||
</div>
|
</div>
|
||||||
<div className={'bg-white p-6 text-center'}>
|
<div className={'bg-neutral-900 p-6 text-center'}>
|
||||||
<span className={'text-sm font-semibold text-neutral-900'}>Plunk</span>
|
<span style={{fontFamily: 'var(--font-mono)'}} className={'text-[11px] uppercase tracking-[0.18em] text-white'}>Plunk</span>
|
||||||
</div>
|
</div>
|
||||||
<div className={'bg-white p-6 text-center'}>
|
<div className={'bg-neutral-50 p-6 text-center'}>
|
||||||
<span className={'text-sm font-semibold text-neutral-900'}>{competitorName}</span>
|
<span style={{fontFamily: 'var(--font-mono)'}} className={'text-[11px] uppercase tracking-[0.18em] text-neutral-500'}>{competitorName}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Rows */}
|
|
||||||
<div className={'grid gap-px bg-neutral-200'}>
|
<div className={'grid gap-px bg-neutral-200'}>
|
||||||
{rows.map((row, index) => (
|
{rows.map((row, index) => (
|
||||||
<motion.div
|
<motion.div
|
||||||
@@ -40,7 +35,7 @@ export function ComparisonTable({competitorName, rows}: ComparisonTableProps) {
|
|||||||
initial={{opacity: 0, y: 10}}
|
initial={{opacity: 0, y: 10}}
|
||||||
whileInView={{opacity: 1, y: 0}}
|
whileInView={{opacity: 1, y: 0}}
|
||||||
viewport={{once: true}}
|
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'}
|
className={'grid grid-cols-3 gap-px bg-neutral-200'}
|
||||||
>
|
>
|
||||||
<div className={'bg-white p-6'}>
|
<div className={'bg-white p-6'}>
|
||||||
@@ -52,10 +47,10 @@ export function ComparisonTable({competitorName, rows}: ComparisonTableProps) {
|
|||||||
row.plunk ? (
|
row.plunk ? (
|
||||||
<Check className="h-5 w-5 text-neutral-900" strokeWidth={2} />
|
<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>
|
||||||
</div>
|
</div>
|
||||||
@@ -65,10 +60,10 @@ export function ComparisonTable({competitorName, rows}: ComparisonTableProps) {
|
|||||||
row.competitor ? (
|
row.competitor ? (
|
||||||
<Check className="h-5 w-5 text-neutral-900" strokeWidth={2} />
|
<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>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -12,9 +12,6 @@ interface FAQSectionProps {
|
|||||||
schemaId?: string;
|
schemaId?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Reusable FAQ section component with structured data support
|
|
||||||
*/
|
|
||||||
export function FAQSection({faqs, schemaId = 'faq-schema'}: FAQSectionProps) {
|
export function FAQSection({faqs, schemaId = 'faq-schema'}: FAQSectionProps) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -37,34 +34,44 @@ export function FAQSection({faqs, schemaId = 'faq-schema'}: FAQSectionProps) {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<section className={'py-32'}>
|
<section className={'border-t border-neutral-200'}>
|
||||||
<motion.div
|
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||||
initial={{opacity: 0, y: 20}}
|
<motion.div
|
||||||
whileInView={{opacity: 1, y: 0}}
|
initial={{opacity: 0, y: 20}}
|
||||||
viewport={{once: true}}
|
whileInView={{opacity: 1, y: 0}}
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
viewport={{once: true}}
|
||||||
className={'mx-auto max-w-4xl'}
|
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||||
>
|
className={'mb-16'}
|
||||||
<h2 className={'mb-16 text-center text-5xl font-bold tracking-tight text-neutral-900'}>
|
>
|
||||||
Frequently asked questions
|
<h2
|
||||||
</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) => (
|
{faqs.map((faq, index) => (
|
||||||
<motion.div
|
<motion.div
|
||||||
key={index}
|
key={index}
|
||||||
initial={{opacity: 0, y: 20}}
|
initial={{opacity: 0, y: 16}}
|
||||||
whileInView={{opacity: 1, y: 0}}
|
whileInView={{opacity: 1, y: 0}}
|
||||||
viewport={{once: true}}
|
viewport={{once: true}}
|
||||||
transition={{duration: 0.5, delay: index * 0.1, ease: [0.22, 1, 0.36, 1]}}
|
transition={{duration: 0.5, delay: index * 0.06, ease: [0.22, 1, 0.36, 1]}}
|
||||||
className={'border-b border-neutral-200 pb-8 last:border-b-0'}
|
className={'py-8'}
|
||||||
>
|
>
|
||||||
<h3 className={'text-xl font-semibold text-neutral-900'}>{faq.question}</h3>
|
<h3
|
||||||
<p className={'mt-4 leading-relaxed text-neutral-600'}>{faq.answer}</p>
|
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>
|
</motion.div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</motion.div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ export default function Footer() {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<footer className={'border-t border-neutral-200 bg-white'}>
|
<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">
|
<div className="grid gap-12 lg:grid-cols-12">
|
||||||
{/* Logo and description */}
|
{/* Logo and description */}
|
||||||
<div className="space-y-6 lg:col-span-3">
|
<div className="space-y-6 lg:col-span-3">
|
||||||
@@ -59,7 +59,7 @@ export default function Footer() {
|
|||||||
{/* Links */}
|
{/* Links */}
|
||||||
<div className="grid grid-cols-2 gap-8 lg:col-span-9 lg:grid-cols-5">
|
<div className="grid grid-cols-2 gap-8 lg:col-span-9 lg:grid-cols-5">
|
||||||
<div>
|
<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">
|
<ul role="list" className="mt-6 space-y-4">
|
||||||
<li>
|
<li>
|
||||||
<Link href={'/pricing'} className="text-sm text-neutral-600 transition hover:text-neutral-900">
|
<Link href={'/pricing'} className="text-sm text-neutral-600 transition hover:text-neutral-900">
|
||||||
@@ -90,7 +90,7 @@ export default function Footer() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<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">
|
<ul role="list" className="mt-6 space-y-4">
|
||||||
<li>
|
<li>
|
||||||
<Link href={'/features/email-editor'} className="text-sm text-neutral-600 transition hover:text-neutral-900">
|
<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>
|
||||||
|
|
||||||
<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">
|
<ul role="list" className="mt-6 space-y-4">
|
||||||
<li>
|
<li>
|
||||||
<Link href={'/vs'} className="text-sm text-neutral-600 transition hover:text-neutral-900">
|
<Link href={'/vs'} className="text-sm text-neutral-600 transition hover:text-neutral-900">
|
||||||
@@ -162,7 +162,7 @@ export default function Footer() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<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">
|
<ul role="list" className="mt-6 space-y-4">
|
||||||
<li>
|
<li>
|
||||||
<Link href={'/discord'} className="text-sm text-neutral-600 transition hover:text-neutral-900">
|
<Link href={'/discord'} className="text-sm text-neutral-600 transition hover:text-neutral-900">
|
||||||
@@ -181,7 +181,7 @@ export default function Footer() {
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</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">
|
<ul role="list" className="mt-6 space-y-4">
|
||||||
<li>
|
<li>
|
||||||
<Link href={'/privacy'} className="text-sm text-neutral-600 transition hover:text-neutral-900">
|
<Link href={'/privacy'} className="text-sm text-neutral-600 transition hover:text-neutral-900">
|
||||||
@@ -202,7 +202,7 @@ export default function Footer() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<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">
|
<ul role="list" className="mt-6 space-y-4">
|
||||||
<li>
|
<li>
|
||||||
<Link href={'/guides/email-deliverability'} className="text-sm text-neutral-600 transition hover:text-neutral-900">
|
<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);
|
const [featuresOpen, setFeaturesOpen] = useState(false);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<header className={'sticky top-0 z-40 w-full border-b border-neutral-100 bg-white/95 backdrop-blur-sm'}>
|
<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-7xl px-8 xl:px-0'}>
|
<div className={'relative mx-auto max-w-[88rem] px-6 sm:px-10'}>
|
||||||
<div className={'py-5'}>
|
<div className={'py-5'}>
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<div className="flex items-center gap-12">
|
<div className="flex items-center gap-12">
|
||||||
@@ -83,14 +83,14 @@ export default function Navbar() {
|
|||||||
onMouseEnter={() => setFeaturesOpen(true)}
|
onMouseEnter={() => setFeaturesOpen(true)}
|
||||||
onMouseLeave={() => setFeaturesOpen(false)}
|
onMouseLeave={() => setFeaturesOpen(false)}
|
||||||
className={
|
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 => (
|
{featuresMenu.map(feature => (
|
||||||
<Link
|
<Link
|
||||||
key={feature.href}
|
key={feature.href}
|
||||||
href={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
|
<div
|
||||||
className={
|
className={
|
||||||
@@ -166,7 +166,7 @@ export default function Navbar() {
|
|||||||
whileTap={{scale: 0.98}}
|
whileTap={{scale: 0.98}}
|
||||||
href={`${DASHBOARD_URI}/auth/signup`}
|
href={`${DASHBOARD_URI}/auth/signup`}
|
||||||
className={
|
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
|
Get started
|
||||||
@@ -226,7 +226,7 @@ export default function Navbar() {
|
|||||||
className="space-y-1 p-4"
|
className="space-y-1 p-4"
|
||||||
>
|
>
|
||||||
<div className="mb-2">
|
<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
|
Features
|
||||||
</div>
|
</div>
|
||||||
{featuresMenu.map(feature => (
|
{featuresMenu.map(feature => (
|
||||||
@@ -293,7 +293,7 @@ export default function Navbar() {
|
|||||||
</a>
|
</a>
|
||||||
<a
|
<a
|
||||||
href={`${DASHBOARD_URI}/auth/signup`}
|
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
|
Get started
|
||||||
</a>
|
</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 />
|
<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'}>
|
<div className={'flex flex-col lg:flex-row gap-8 lg:gap-12 py-8 sm:py-16 w-full'}>
|
||||||
{/* Main Content */}
|
{/* Main Content */}
|
||||||
<article className={'flex-1 max-w-full lg:max-w-4xl w-full'}>
|
<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 './ComparisonTable';
|
||||||
export * from './FAQSection';
|
export * from './FAQSection';
|
||||||
export * from './CodeBlock';
|
export * from './CodeBlock';
|
||||||
|
export * from './SectionHeader';
|
||||||
|
|||||||
@@ -7,6 +7,28 @@ import {SWRConfig} from 'swr';
|
|||||||
import {network} from '../lib/network';
|
import {network} from '../lib/network';
|
||||||
import {DefaultSeo} from 'next-seo';
|
import {DefaultSeo} from 'next-seo';
|
||||||
import Script from 'next/script';
|
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
|
* Main app component
|
||||||
@@ -25,7 +47,7 @@ function App({Component, pageProps}: AppProps) {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<div className={`${display.variable} ${body.variable} ${mono.variable}`}>
|
||||||
<Head>
|
<Head>
|
||||||
<title>Plunk | The Open-Source Email Platform</title>
|
<title>Plunk | The Open-Source Email Platform</title>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" key={'viewport'} />
|
<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'} />
|
<Toaster position={'top-right'} />
|
||||||
|
|
||||||
<Component {...pageProps} />
|
<Component {...pageProps} />
|
||||||
</>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,14 +6,6 @@ export default class MyDocument extends Document {
|
|||||||
return (
|
return (
|
||||||
<Html lang="en">
|
<Html lang="en">
|
||||||
<Head>
|
<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 */}
|
{/* Start favicon */}
|
||||||
<link rel="apple-touch-icon" sizes="180x180" href="/favicon/apple-touch-icon.png" />
|
<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" />
|
<link rel="icon" type="image/png" sizes="32x32" href="/favicon/favicon-32x32.png" />
|
||||||
|
|||||||
@@ -8,36 +8,34 @@ import Head from 'next/head';
|
|||||||
|
|
||||||
const features = [
|
const features = [
|
||||||
{
|
{
|
||||||
icon: <Type className="h-5 w-5" />,
|
icon: <Type className="h-6 w-6" strokeWidth={1.5} />,
|
||||||
title: 'Visual WYSIWYG Editor',
|
title: 'Visual WYSIWYG Editor',
|
||||||
description:
|
description:
|
||||||
'Rich text editing with formatting toolbar. Bold, italic, headings, lists, links, images, and tables. No code required.',
|
'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',
|
title: 'Full HTML Editor',
|
||||||
description:
|
description: 'Syntax highlighting, auto-completion, and bracket matching. Write custom HTML when you need complete control.',
|
||||||
'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',
|
title: 'Smart Mode Switching',
|
||||||
description:
|
description: 'Automatically detects complex HTML and switches to code mode. Warns you before changes that would lose custom formatting.',
|
||||||
'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',
|
title: 'Powerful Variables',
|
||||||
description:
|
description: 'Autocomplete with {{variable}} syntax. Supports fallbacks, nested properties, and custom contact fields.',
|
||||||
'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',
|
title: 'Live Preview',
|
||||||
description: 'Preview with real contact data. Test on desktop, tablet, and mobile views before sending.',
|
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',
|
title: 'Email-Safe HTML',
|
||||||
description: 'Automatic CSS inlining and email-client-friendly code generation. Yes, even in Outlook.',
|
description: 'Automatic CSS inlining and email-client-friendly code generation. Yes, even in Outlook.',
|
||||||
},
|
},
|
||||||
@@ -45,21 +43,21 @@ const features = [
|
|||||||
|
|
||||||
const useCases = [
|
const useCases = [
|
||||||
{
|
{
|
||||||
icon: <Code2 className="h-6 w-6" />,
|
icon: <Code2 className="h-6 w-6" strokeWidth={1.5} />,
|
||||||
title: 'For Developers',
|
title: 'For Developers',
|
||||||
description:
|
description:
|
||||||
'Full HTML control when you need it. Powerful variable system with autocomplete and fallbacks. Use templates in API calls, workflows, and campaigns.',
|
'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',
|
title: 'For Marketers',
|
||||||
description:
|
description:
|
||||||
'Visual editor for quick changes. Live preview with real customer data. Create professional emails without waiting for developers.',
|
'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',
|
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',
|
title: 'For Teams',
|
||||||
description:
|
description:
|
||||||
'One tool for everyone. Developers can code, marketers can design, everyone can preview. Reusable templates across campaigns and workflows.',
|
'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() {
|
export default function EmailEditorFeature() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -79,10 +74,7 @@ export default function EmailEditorFeature() {
|
|||||||
name="description"
|
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."
|
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
|
<meta property="og:title" content="Email Editor - Create Beautiful Emails Without Fighting Your Tools | Plunk" />
|
||||||
property="og:title"
|
|
||||||
content="Email Editor - Create Beautiful Emails Without Fighting Your Tools | Plunk"
|
|
||||||
/>
|
|
||||||
<meta
|
<meta
|
||||||
property="og:description"
|
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."
|
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 />
|
<Navbar />
|
||||||
|
|
||||||
<main className={'mx-auto max-w-7xl px-8 sm:px-0'}>
|
<main className={'text-neutral-800'}>
|
||||||
{/* Hero Section */}
|
|
||||||
<section className={'relative py-20 sm:py-32'}>
|
{/* Hero */}
|
||||||
{/* Subtle background grid */}
|
<section className={'relative overflow-hidden'}>
|
||||||
<div
|
<div
|
||||||
|
aria-hidden
|
||||||
className={
|
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%)]'
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
<div className={'mx-auto max-w-[88rem] px-6 pb-20 pt-20 sm:px-10 sm:pt-28 sm:pb-28'}>
|
||||||
<motion.div
|
<motion.div
|
||||||
initial={{opacity: 0, y: 20}}
|
initial={{opacity: 0, y: 16}}
|
||||||
animate={{opacity: 1, y: 0}}
|
animate={{opacity: 1, y: 0}}
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||||
className={'mx-auto max-w-4xl text-center'}
|
>
|
||||||
>
|
<div
|
||||||
<div className={'mb-6 inline-flex items-center gap-2 rounded-full bg-neutral-100 px-4 py-2 text-sm'}>
|
style={{fontFamily: 'var(--font-mono)'}}
|
||||||
<Mail className="h-4 w-4 text-neutral-600" />
|
className={'mb-6 text-[11px] uppercase tracking-[0.18em] text-neutral-500'}
|
||||||
<span className={'font-medium text-neutral-600'}>Email Editor & Templates</span>
|
>
|
||||||
</div>
|
Email Editor & Templates
|
||||||
|
</div>
|
||||||
<h1 className={'text-6xl font-bold tracking-tight text-neutral-900 sm:text-7xl lg:text-8xl text-balance'}>
|
<h1
|
||||||
The Email Editor
|
style={{fontFamily: 'var(--font-display)'}}
|
||||||
<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`}
|
|
||||||
className={
|
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'}>
|
The editor that
|
||||||
Try the editor free
|
<br />
|
||||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-1" />
|
speaks both languages.
|
||||||
</span>
|
</h1>
|
||||||
</motion.a>
|
<p className={'mt-6 max-w-2xl text-xl text-neutral-600'}>
|
||||||
<Link
|
Switch seamlessly between visual and code editing. Preview with real customer data. Create templates that
|
||||||
href={WIKI_URI}
|
work everywhere.
|
||||||
target={'_blank'}
|
</p>
|
||||||
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>
|
|
||||||
|
|
||||||
{/* Features Grid */}
|
<div className={'mt-10 flex flex-wrap gap-3'}>
|
||||||
<section className={'py-20'}>
|
<motion.a
|
||||||
<motion.div
|
whileHover={{scale: 1.015}}
|
||||||
initial={{opacity: 0, y: 20}}
|
whileTap={{scale: 0.985}}
|
||||||
whileInView={{opacity: 1, y: 0}}
|
href={`${DASHBOARD_URI}/auth/signup`}
|
||||||
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
|
|
||||||
className={
|
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}
|
Try the editor free
|
||||||
</div>
|
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-0.5" />
|
||||||
<h3 className={'mt-6 text-lg font-semibold text-neutral-900'}>{feature.title}</h3>
|
</motion.a>
|
||||||
<p className={'mt-2 text-sm leading-relaxed text-neutral-600'}>{feature.description}</p>
|
<Link
|
||||||
</motion.div>
|
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>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{/* How It Works */}
|
{/* Features grid */}
|
||||||
<section className={'py-20'}>
|
<section className={'border-t border-neutral-200'}>
|
||||||
<motion.div
|
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||||
initial={{opacity: 0, y: 20}}
|
<motion.div
|
||||||
whileInView={{opacity: 1, y: 0}}
|
initial={{opacity: 0, y: 20}}
|
||||||
viewport={{once: true}}
|
whileInView={{opacity: 1, y: 0}}
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
viewport={{once: true}}
|
||||||
className={'mx-auto max-w-4xl text-center'}
|
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||||
>
|
className={'mb-16'}
|
||||||
<h2 className={'text-4xl font-bold tracking-tight text-neutral-900 sm:text-5xl text-balance'}>
|
>
|
||||||
From first draft to send
|
<h2
|
||||||
</h2>
|
style={{fontFamily: 'var(--font-display)'}}
|
||||||
<p className={'mt-6 text-lg text-neutral-600'}>Create, preview, and deploy templates in minutes</p>
|
className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}
|
||||||
</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]}}
|
|
||||||
>
|
>
|
||||||
<div className={'mb-5 flex items-center gap-4'}>
|
Two editors, one experience
|
||||||
<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'}>
|
</h2>
|
||||||
1
|
<p className={'mt-4 text-lg text-neutral-600'}>Visual editing for speed, code editing for control</p>
|
||||||
</div>
|
</motion.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>
|
|
||||||
|
|
||||||
<motion.div
|
<div className={'grid gap-4 sm:grid-cols-2 lg:grid-cols-3'}>
|
||||||
initial={{opacity: 0, y: 20}}
|
{features.map((feature, index) => {
|
||||||
whileInView={{opacity: 1, y: 0}}
|
const highlighted = feature.featured;
|
||||||
viewport={{once: true}}
|
return (
|
||||||
transition={{duration: 0.5, delay: 0.2, ease: [0.22, 1, 0.36, 1]}}
|
<motion.div
|
||||||
>
|
key={feature.title}
|
||||||
<div className={'mb-5 flex items-center gap-4'}>
|
initial={{opacity: 0, y: 16}}
|
||||||
<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'}>
|
whileInView={{opacity: 1, y: 0}}
|
||||||
2
|
viewport={{once: true}}
|
||||||
</div>
|
transition={{duration: 0.5, delay: index * 0.06, ease: [0.22, 1, 0.36, 1]}}
|
||||||
</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
|
|
||||||
className={
|
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 className={'flex items-start justify-between'}>
|
||||||
</div>
|
<div className={highlighted ? 'text-white' : 'text-neutral-900'}>{feature.icon}</div>
|
||||||
<div className={'flex-1'}>
|
<span
|
||||||
<h3 className={'text-xl font-semibold text-neutral-900'}>{useCase.title}</h3>
|
style={{fontFamily: 'var(--font-mono)'}}
|
||||||
<p className={'mt-2 text-neutral-600'}>{useCase.description}</p>
|
className={`text-[11px] uppercase tracking-[0.18em] ${highlighted ? 'text-neutral-500' : 'text-neutral-400'}`}
|
||||||
<div className={'mt-4 rounded-lg bg-neutral-50 p-4'}>
|
>
|
||||||
<p className={'text-sm text-neutral-700'}>{useCase.example}</p>
|
{String(index + 1).padStart(2, '0')}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div>
|
||||||
</div>
|
<h3
|
||||||
</motion.div>
|
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>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{/* CTA Section */}
|
{/* How it works */}
|
||||||
<section className={'relative overflow-hidden border-t border-neutral-200 py-20'}>
|
<section className={'border-t border-neutral-200 bg-neutral-50/60'}>
|
||||||
<div
|
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||||
className={
|
<motion.div
|
||||||
'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%)]'
|
initial={{opacity: 0, y: 20}}
|
||||||
}
|
whileInView={{opacity: 1, y: 0}}
|
||||||
/>
|
viewport={{once: true}}
|
||||||
<motion.div
|
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||||
initial={{opacity: 0, y: 20}}
|
className={'mb-16 text-center'}
|
||||||
whileInView={{opacity: 1, y: 0}}
|
>
|
||||||
viewport={{once: true}}
|
<h2
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
style={{fontFamily: 'var(--font-display)'}}
|
||||||
className={'mx-auto max-w-3xl text-center'}
|
className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}
|
||||||
>
|
|
||||||
<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'
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
<span className={'flex items-center gap-2'}>
|
From first draft to send
|
||||||
Get started for free
|
</h2>
|
||||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-1" />
|
<p className={'mt-4 text-lg text-neutral-600'}>Create, preview, and deploy templates in minutes</p>
|
||||||
</span>
|
</motion.div>
|
||||||
</motion.a>
|
|
||||||
<Link
|
<div className={'mx-auto max-w-4xl'}>
|
||||||
href={'/pricing'}
|
<div className={'grid gap-px bg-neutral-200 sm:grid-cols-3'}>
|
||||||
className={
|
{[
|
||||||
'rounded-lg border border-neutral-300 px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-400'
|
{
|
||||||
}
|
step: '01',
|
||||||
>
|
title: 'Create your template',
|
||||||
View pricing
|
body: 'Use the visual editor for quick formatting or write custom HTML. Add variables with autocomplete.',
|
||||||
</Link>
|
},
|
||||||
|
{
|
||||||
|
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>
|
</div>
|
||||||
</motion.div>
|
</div>
|
||||||
</section>
|
</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>
|
</main>
|
||||||
|
|
||||||
<Footer />
|
<Footer />
|
||||||
|
|||||||
@@ -8,33 +8,33 @@ import Head from 'next/head';
|
|||||||
|
|
||||||
const features = [
|
const features = [
|
||||||
{
|
{
|
||||||
icon: <Database className="h-5 w-5" />,
|
icon: <Database className="h-6 w-6" strokeWidth={1.5} />,
|
||||||
title: 'Automatic Contact Capture',
|
title: 'Automatic Contact Capture',
|
||||||
description: 'Every sender is automatically added to your contact database with no manual data entry required.',
|
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',
|
title: 'Workflow Automation',
|
||||||
description: 'Trigger automated workflows when emails are received to create sophisticated two-way communication.',
|
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',
|
title: 'Built-in Security',
|
||||||
description:
|
description: 'Spam, virus, SPF, DKIM, and DMARC filtering keeps your inbox clean. The spam stays out, the good stuff gets in.',
|
||||||
'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',
|
title: 'Webhook Notifications',
|
||||||
description: 'Get instant notifications with rich metadata whenever an email arrives at your domain.',
|
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',
|
title: 'Simple DNS Setup',
|
||||||
description: 'Add one MX record to your domain and start receiving emails immediately. No PhD required.',
|
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',
|
title: 'Real-Time Processing',
|
||||||
description: 'Emails are processed instantly and can trigger workflows or webhooks in real-time.',
|
description: 'Emails are processed instantly and can trigger workflows or webhooks in real-time.',
|
||||||
},
|
},
|
||||||
@@ -42,21 +42,21 @@ const features = [
|
|||||||
|
|
||||||
const useCases = [
|
const useCases = [
|
||||||
{
|
{
|
||||||
icon: <Mail className="h-6 w-6" />,
|
icon: <Mail className="h-6 w-6" strokeWidth={1.5} />,
|
||||||
title: 'Support Ticket Creation',
|
title: 'Support Ticket Creation',
|
||||||
description:
|
description:
|
||||||
'Automatically create support tickets when customers email [email protected]. Send auto-replies and route to your help desk system via webhooks. Your support team will thank you.',
|
'Automatically create support tickets when customers email [email protected]. 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'],
|
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',
|
title: 'Lead Capture from Email',
|
||||||
description:
|
description:
|
||||||
'Receive emails at [email protected] and automatically add senders to your CRM. Trigger nurture workflows based on when they reached out.',
|
'Receive emails at [email protected] 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'],
|
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',
|
title: 'Two-Way Conversations',
|
||||||
description:
|
description:
|
||||||
'Let customers reply to your campaign emails and automatically trigger engagement workflows. Tag contacts as "engaged" when they respond.',
|
'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() {
|
export default function InboundEmailFeature() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -85,343 +82,292 @@ export default function InboundEmailFeature() {
|
|||||||
|
|
||||||
<Navbar />
|
<Navbar />
|
||||||
|
|
||||||
<main className={'mx-auto max-w-7xl px-8 sm:px-0'}>
|
<main className={'text-neutral-800'}>
|
||||||
{/* Hero Section */}
|
|
||||||
<section className={'relative py-20 sm:py-32'}>
|
{/* Hero */}
|
||||||
{/* Subtle background grid */}
|
<section className={'relative overflow-hidden'}>
|
||||||
<div
|
<div
|
||||||
|
aria-hidden
|
||||||
className={
|
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%)]'
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
<div className={'mx-auto max-w-[88rem] px-6 pb-20 pt-20 sm:px-10 sm:pt-28 sm:pb-28'}>
|
||||||
<motion.div
|
<motion.div
|
||||||
initial={{opacity: 0, y: 20}}
|
initial={{opacity: 0, y: 16}}
|
||||||
animate={{opacity: 1, y: 0}}
|
animate={{opacity: 1, y: 0}}
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||||
className={'mx-auto max-w-4xl text-center'}
|
>
|
||||||
>
|
<div
|
||||||
<div className={'mb-6 inline-flex items-center gap-2 rounded-full bg-neutral-100 px-4 py-2 text-sm'}>
|
style={{fontFamily: 'var(--font-mono)'}}
|
||||||
<Inbox className="h-4 w-4 text-neutral-600" />
|
className={'mb-6 text-[11px] uppercase tracking-[0.18em] text-neutral-500'}
|
||||||
<span className={'font-medium text-neutral-600'}>Inbound Email</span>
|
>
|
||||||
</div>
|
Inbound Email
|
||||||
|
</div>
|
||||||
<h1 className={'text-6xl font-bold tracking-tight text-neutral-900 sm:text-7xl lg:text-8xl text-balance'}>
|
<h1
|
||||||
Turn Incoming Emails
|
style={{fontFamily: 'var(--font-display)'}}
|
||||||
<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`}
|
|
||||||
className={
|
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'}>
|
Emails in,
|
||||||
Start receiving emails
|
<br />
|
||||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-1" />
|
actions out.
|
||||||
</span>
|
</h1>
|
||||||
</motion.a>
|
<p className={'mt-6 max-w-2xl text-xl text-neutral-600'}>
|
||||||
<Link
|
Receive emails at your custom domain and automatically trigger workflows, capture leads, or create support
|
||||||
href={WIKI_URI}
|
tickets. Two-way email communication made simple.
|
||||||
target={'_blank'}
|
</p>
|
||||||
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>
|
|
||||||
|
|
||||||
{/* Features Grid */}
|
<div className={'mt-10 flex flex-wrap gap-3'}>
|
||||||
<section className={'py-20'}>
|
<motion.a
|
||||||
<motion.div
|
whileHover={{scale: 1.015}}
|
||||||
initial={{opacity: 0, y: 20}}
|
whileTap={{scale: 0.985}}
|
||||||
whileInView={{opacity: 1, y: 0}}
|
href={`${DASHBOARD_URI}/auth/signup`}
|
||||||
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
|
|
||||||
className={
|
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}
|
Start receiving emails
|
||||||
</div>
|
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-0.5" />
|
||||||
<h3 className={'mt-6 text-lg font-semibold text-neutral-900'}>{feature.title}</h3>
|
</motion.a>
|
||||||
<p className={'mt-2 text-sm leading-relaxed text-neutral-600'}>{feature.description}</p>
|
<Link
|
||||||
</motion.div>
|
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>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{/* How It Works */}
|
{/* Features grid */}
|
||||||
<section className={'py-20'}>
|
<section className={'border-t border-neutral-200'}>
|
||||||
<motion.div
|
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||||
initial={{opacity: 0, y: 20}}
|
<motion.div
|
||||||
whileInView={{opacity: 1, y: 0}}
|
initial={{opacity: 0, y: 20}}
|
||||||
viewport={{once: true}}
|
whileInView={{opacity: 1, y: 0}}
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
viewport={{once: true}}
|
||||||
className={'mx-auto max-w-4xl text-center'}
|
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||||
>
|
className={'mb-16'}
|
||||||
<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>
|
<h2
|
||||||
</motion.div>
|
style={{fontFamily: 'var(--font-display)'}}
|
||||||
|
className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}
|
||||||
<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]}}
|
|
||||||
>
|
>
|
||||||
<div className={'mb-5 flex items-center gap-4'}>
|
Complete inbound email solution
|
||||||
<div
|
</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={
|
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 className={'flex items-start justify-between'}>
|
||||||
</div>
|
<div className={highlighted ? 'text-white' : 'text-neutral-900'}>{feature.icon}</div>
|
||||||
</div>
|
<span
|
||||||
<h3 className={'text-lg font-semibold text-neutral-900'}>Verify your domain</h3>
|
style={{fontFamily: 'var(--font-mono)'}}
|
||||||
<p className={'mt-2 text-sm leading-relaxed text-neutral-600'}>
|
className={`text-[11px] uppercase tracking-[0.18em] ${highlighted ? 'text-neutral-500' : 'text-neutral-400'}`}
|
||||||
Add and verify your custom domain in Plunk by configuring DKIM and SPF records in your DNS settings.
|
>
|
||||||
</p>
|
{String(index + 1).padStart(2, '0')}
|
||||||
</motion.div>
|
</span>
|
||||||
|
</div>
|
||||||
<motion.div
|
<div>
|
||||||
initial={{opacity: 0, y: 20}}
|
<h3
|
||||||
whileInView={{opacity: 1, y: 0}}
|
style={{fontFamily: 'var(--font-display)'}}
|
||||||
viewport={{once: true}}
|
className={`mt-8 text-xl font-bold tracking-[-0.02em] ${highlighted ? 'text-white' : 'text-neutral-900'}`}
|
||||||
transition={{duration: 0.5, delay: 0.2, ease: [0.22, 1, 0.36, 1]}}
|
>
|
||||||
>
|
{feature.title}
|
||||||
<div className={'mb-5 flex items-center gap-4'}>
|
</h3>
|
||||||
<div
|
<p className={`mt-2 text-sm leading-relaxed ${highlighted ? 'text-neutral-300' : 'text-neutral-600'}`}>
|
||||||
className={
|
{feature.description}
|
||||||
'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'
|
</p>
|
||||||
}
|
</div>
|
||||||
>
|
</motion.div>
|
||||||
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>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{/* Use Cases */}
|
{/* How it works */}
|
||||||
<section className={'py-20'}>
|
<section className={'border-t border-neutral-200 bg-neutral-50/60'}>
|
||||||
<motion.div
|
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||||
initial={{opacity: 0, y: 20}}
|
<motion.div
|
||||||
whileInView={{opacity: 1, y: 0}}
|
initial={{opacity: 0, y: 20}}
|
||||||
viewport={{once: true}}
|
whileInView={{opacity: 1, y: 0}}
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
viewport={{once: true}}
|
||||||
className={'mb-16 text-center'}
|
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'}>
|
<h2
|
||||||
From support to sales, inbound email unlocks new automation possibilities
|
style={{fontFamily: 'var(--font-display)'}}
|
||||||
</p>
|
className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}
|
||||||
</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'}>
|
Set up in minutes
|
||||||
<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?
|
|
||||||
</h2>
|
</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',
|
step: '01',
|
||||||
description: 'Your MX record routes the email to Plunk for processing',
|
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',
|
step: '02',
|
||||||
description: 'Automatic validation of spam, virus, SPF, DKIM, and DMARC',
|
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',
|
step: '03',
|
||||||
description: 'The sender is automatically added to your contact database',
|
title: 'Start receiving',
|
||||||
|
body: 'Emails sent to any address at your domain are automatically received and can trigger workflows or webhooks.',
|
||||||
},
|
},
|
||||||
{
|
].map((item, i) => (
|
||||||
title: 'Workflows trigger automatically',
|
<motion.div
|
||||||
description: 'Configured workflows start running based on the incoming email',
|
key={item.step}
|
||||||
},
|
initial={{opacity: 0, y: 20}}
|
||||||
].map((step, i, arr) => (
|
whileInView={{opacity: 1, y: 0}}
|
||||||
<div key={step.title} className={'relative flex gap-6'}>
|
viewport={{once: true}}
|
||||||
{/* Vertical connector */}
|
transition={{duration: 0.5, delay: i * 0.1, ease: [0.22, 1, 0.36, 1]}}
|
||||||
{i < arr.length - 1 && (
|
className={'bg-white p-10'}
|
||||||
<div className={'absolute left-[1.125rem] top-10 bottom-0 w-px bg-neutral-200'} />
|
>
|
||||||
)}
|
<div
|
||||||
<div className={'relative flex-shrink-0'}>
|
style={{fontFamily: 'var(--font-mono)'}}
|
||||||
<div
|
className={'mb-6 text-[11px] uppercase tracking-[0.18em] text-neutral-400'}
|
||||||
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'
|
Step {item.step}
|
||||||
}
|
|
||||||
>
|
|
||||||
{i + 1}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div className={i < arr.length - 1 ? 'pb-8' : ''}>
|
<h3 className={'text-lg font-semibold text-neutral-900'}>{item.title}</h3>
|
||||||
<p className={'font-semibold text-neutral-900'}>{step.title}</p>
|
<p className={'mt-2 text-sm leading-relaxed text-neutral-600'}>{item.body}</p>
|
||||||
<p className={'mt-1 text-sm text-neutral-600'}>{step.description}</p>
|
</motion.div>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</motion.div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{/* CTA Section */}
|
{/* Use cases */}
|
||||||
<section className={'relative overflow-hidden border-t border-neutral-200 py-20'}>
|
<section className={'border-t border-neutral-200'}>
|
||||||
<div
|
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||||
className={
|
<motion.div
|
||||||
'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%)]'
|
initial={{opacity: 0, y: 20}}
|
||||||
}
|
whileInView={{opacity: 1, y: 0}}
|
||||||
/>
|
viewport={{once: true}}
|
||||||
<motion.div
|
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||||
initial={{opacity: 0, y: 20}}
|
className={'mb-16'}
|
||||||
whileInView={{opacity: 1, y: 0}}
|
>
|
||||||
viewport={{once: true}}
|
<h2
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
style={{fontFamily: 'var(--font-display)'}}
|
||||||
className={'mx-auto max-w-3xl text-center'}
|
className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}
|
||||||
>
|
|
||||||
<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'
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
<span className={'flex items-center gap-2'}>
|
Powerful use cases
|
||||||
Get started for free
|
</h2>
|
||||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-1" />
|
<p className={'mt-4 text-lg text-neutral-600'}>From support to sales, inbound email unlocks new automation possibilities</p>
|
||||||
</span>
|
</motion.div>
|
||||||
</motion.a>
|
|
||||||
<Link
|
<div className={'space-y-4'}>
|
||||||
href={'/pricing'}
|
{useCases.map((useCase, index) => (
|
||||||
className={
|
<motion.div
|
||||||
'rounded-lg border border-neutral-300 px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-400'
|
key={useCase.title}
|
||||||
}
|
initial={{opacity: 0, y: 20}}
|
||||||
>
|
whileInView={{opacity: 1, y: 0}}
|
||||||
View pricing
|
viewport={{once: true}}
|
||||||
</Link>
|
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>
|
</div>
|
||||||
</motion.div>
|
</div>
|
||||||
</section>
|
</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>
|
</main>
|
||||||
|
|
||||||
<Footer />
|
<Footer />
|
||||||
|
|||||||
@@ -8,37 +8,35 @@ import Head from 'next/head';
|
|||||||
|
|
||||||
const features = [
|
const features = [
|
||||||
{
|
{
|
||||||
icon: <Filter className="h-5 w-5" />,
|
icon: <Filter className="h-6 w-6" strokeWidth={1.5} />,
|
||||||
title: 'Dynamic Filtering',
|
title: 'Dynamic Filtering',
|
||||||
description:
|
description: 'Create segments based on contact data, custom fields, email activity, and events with powerful AND/OR logic.',
|
||||||
'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',
|
title: 'Real-Time Updates',
|
||||||
description: 'Dynamic segments automatically update as contact data changes, always keeping your audience current.',
|
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',
|
title: 'Workflow Integration',
|
||||||
description:
|
description: 'Trigger workflows when contacts enter or exit segments, or use segment conditions in workflow branching.',
|
||||||
'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',
|
title: 'Campaign Targeting',
|
||||||
description:
|
description: 'Send targeted campaigns to specific segments instead of your entire contact list. Less noise, more signal.',
|
||||||
'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',
|
title: 'Static Segments',
|
||||||
description: 'Manually curate contact lists for special groups like beta testers or VIP customers.',
|
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',
|
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',
|
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'],
|
filters: ['Last activity older than 60 days', 'Email sent but not opened', 'Subscribed equals true'],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -62,28 +60,25 @@ const filterExamples = [
|
|||||||
|
|
||||||
const useCases = [
|
const useCases = [
|
||||||
{
|
{
|
||||||
icon: <Mail className="h-6 w-6" />,
|
icon: <Mail className="h-6 w-6" strokeWidth={1.5} />,
|
||||||
title: 'Targeted Campaigns',
|
title: 'Targeted Campaigns',
|
||||||
description:
|
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',
|
title: 'Behavior-Based Workflows',
|
||||||
description:
|
description:
|
||||||
'Trigger workflows when contacts enter segments like "VIP Customers" or "Churning Users". Create personalized automations based on segment membership.',
|
'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',
|
title: 'A/B Testing',
|
||||||
description:
|
description:
|
||||||
'Create segments for test groups and control groups. Send different campaigns to each segment and measure results.',
|
'Create segments for test groups and control groups. Send different campaigns to each segment and measure results.',
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
export default function SegmentsFeature() {
|
export default function SegmentsFeature() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -96,320 +91,349 @@ export default function SegmentsFeature() {
|
|||||||
<meta property="og:title" content="Audience Segmentation - Smart Contact Organization | Plunk" />
|
<meta property="og:title" content="Audience Segmentation - Smart Contact Organization | Plunk" />
|
||||||
<meta
|
<meta
|
||||||
property="og:description"
|
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>
|
</Head>
|
||||||
|
|
||||||
<Navbar />
|
<Navbar />
|
||||||
|
|
||||||
<main className={'mx-auto max-w-7xl px-8 sm:px-0'}>
|
<main className={'text-neutral-800'}>
|
||||||
{/* Hero Section */}
|
|
||||||
<section className={'relative py-20 sm:py-32'}>
|
{/* Hero */}
|
||||||
{/* Subtle background grid */}
|
<section className={'relative overflow-hidden'}>
|
||||||
<div
|
<div
|
||||||
|
aria-hidden
|
||||||
className={
|
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%)]'
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
<div className={'mx-auto max-w-[88rem] px-6 pb-20 pt-20 sm:px-10 sm:pt-28 sm:pb-28'}>
|
||||||
<motion.div
|
<motion.div
|
||||||
initial={{opacity: 0, y: 20}}
|
initial={{opacity: 0, y: 16}}
|
||||||
animate={{opacity: 1, y: 0}}
|
animate={{opacity: 1, y: 0}}
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||||
className={'mx-auto max-w-4xl text-center'}
|
>
|
||||||
>
|
<div
|
||||||
<div className={'mb-6 inline-flex items-center gap-2 rounded-full bg-neutral-100 px-4 py-2 text-sm'}>
|
style={{fontFamily: 'var(--font-mono)'}}
|
||||||
<Users className="h-4 w-4 text-neutral-600" />
|
className={'mb-6 text-[11px] uppercase tracking-[0.18em] text-neutral-500'}
|
||||||
<span className={'font-medium text-neutral-600'}>Audience Segmentation</span>
|
>
|
||||||
</div>
|
Audience Segmentation
|
||||||
|
</div>
|
||||||
<h1 className={'text-6xl font-bold tracking-tight text-neutral-900 sm:text-7xl lg:text-8xl text-balance'}>
|
<h1
|
||||||
Target the Right Audience,
|
style={{fontFamily: 'var(--font-display)'}}
|
||||||
<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`}
|
|
||||||
className={
|
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'}>
|
Target the right audience,
|
||||||
Start segmenting
|
<br />
|
||||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-1" />
|
every time.
|
||||||
</span>
|
</h1>
|
||||||
</motion.a>
|
<p className={'mt-6 max-w-2xl text-xl text-neutral-600'}>
|
||||||
<Link
|
Organize contacts into dynamic segments based on behavior, attributes, and engagement. Send targeted
|
||||||
href={WIKI_URI}
|
campaigns and trigger personalized workflows.
|
||||||
target={'_blank'}
|
</p>
|
||||||
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>
|
|
||||||
|
|
||||||
{/* Features Grid */}
|
<div className={'mt-10 flex flex-wrap gap-3'}>
|
||||||
<section className={'py-20'}>
|
<motion.a
|
||||||
<motion.div
|
whileHover={{scale: 1.015}}
|
||||||
initial={{opacity: 0, y: 20}}
|
whileTap={{scale: 0.985}}
|
||||||
whileInView={{opacity: 1, y: 0}}
|
href={`${DASHBOARD_URI}/auth/signup`}
|
||||||
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
|
|
||||||
className={
|
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}
|
Start segmenting
|
||||||
</div>
|
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-0.5" />
|
||||||
<h3 className={'mt-6 text-lg font-semibold text-neutral-900'}>{feature.title}</h3>
|
</motion.a>
|
||||||
<p className={'mt-2 text-sm leading-relaxed text-neutral-600'}>{feature.description}</p>
|
<Link
|
||||||
</motion.div>
|
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>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{/* Filter Examples */}
|
{/* Features grid */}
|
||||||
<section className={'py-20'}>
|
<section className={'border-t border-neutral-200'}>
|
||||||
<motion.div
|
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||||
initial={{opacity: 0, y: 20}}
|
<motion.div
|
||||||
whileInView={{opacity: 1, y: 0}}
|
initial={{opacity: 0, y: 20}}
|
||||||
viewport={{once: true}}
|
whileInView={{opacity: 1, y: 0}}
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
viewport={{once: true}}
|
||||||
className={'mb-16 text-center'}
|
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||||
>
|
className={'mb-16'}
|
||||||
<h2 className={'text-4xl font-bold tracking-tight text-neutral-900 sm:text-5xl text-balance'}>
|
>
|
||||||
Flexible filtering options
|
<h2
|
||||||
</h2>
|
style={{fontFamily: 'var(--font-display)'}}
|
||||||
<p className={'mt-4 text-lg text-neutral-600'}>Build complex segments with nested AND/OR logic</p>
|
className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}
|
||||||
</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'}
|
|
||||||
>
|
>
|
||||||
<div className={'flex items-start justify-between gap-6'}>
|
The right message to the right person
|
||||||
<div className={'flex-1'}>
|
</h2>
|
||||||
<h3 className={'text-xl font-semibold text-neutral-900'}>{example.title}</h3>
|
<p className={'mt-4 text-lg text-neutral-600'}>Build precise audiences and send campaigns that land</p>
|
||||||
<p className={'mt-2 text-neutral-600'}>{example.description}</p>
|
</motion.div>
|
||||||
</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>
|
|
||||||
|
|
||||||
{/* Types of Segments */}
|
<div className={'grid gap-4 sm:grid-cols-2 lg:grid-cols-3'}>
|
||||||
<section className={'py-20'}>
|
{features.map((feature, index) => {
|
||||||
<motion.div
|
const highlighted = feature.featured;
|
||||||
initial={{opacity: 0, y: 20}}
|
return (
|
||||||
whileInView={{opacity: 1, y: 0}}
|
<motion.div
|
||||||
viewport={{once: true}}
|
key={feature.title}
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
initial={{opacity: 0, y: 16}}
|
||||||
className={'mx-auto max-w-4xl text-center'}
|
whileInView={{opacity: 1, y: 0}}
|
||||||
>
|
viewport={{once: true}}
|
||||||
<h2 className={'text-4xl font-bold tracking-tight text-neutral-900 sm:text-5xl text-balance'}>Two types of segments</h2>
|
transition={{duration: 0.5, delay: index * 0.06, ease: [0.22, 1, 0.36, 1]}}
|
||||||
<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
|
|
||||||
className={
|
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 className={'flex items-start justify-between'}>
|
||||||
</div>
|
<div className={highlighted ? 'text-white' : 'text-neutral-900'}>{feature.icon}</div>
|
||||||
<div className={'flex-1'}>
|
<span
|
||||||
<h3 className={'text-xl font-semibold text-neutral-900'}>{useCase.title}</h3>
|
style={{fontFamily: 'var(--font-mono)'}}
|
||||||
<p className={'mt-2 text-neutral-600'}>{useCase.description}</p>
|
className={`text-[11px] uppercase tracking-[0.18em] ${highlighted ? 'text-neutral-500' : 'text-neutral-400'}`}
|
||||||
</div>
|
>
|
||||||
</div>
|
{String(index + 1).padStart(2, '0')}
|
||||||
</motion.div>
|
</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>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{/* CTA Section */}
|
{/* Filter examples */}
|
||||||
<section className={'relative overflow-hidden border-t border-neutral-200 py-20'}>
|
<section className={'border-t border-neutral-200 bg-neutral-50/60'}>
|
||||||
<div
|
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||||
className={
|
<motion.div
|
||||||
'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%)]'
|
initial={{opacity: 0, y: 20}}
|
||||||
}
|
whileInView={{opacity: 1, y: 0}}
|
||||||
/>
|
viewport={{once: true}}
|
||||||
<motion.div
|
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||||
initial={{opacity: 0, y: 20}}
|
className={'mb-16'}
|
||||||
whileInView={{opacity: 1, y: 0}}
|
>
|
||||||
viewport={{once: true}}
|
<h2
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
style={{fontFamily: 'var(--font-display)'}}
|
||||||
className={'mx-auto max-w-3xl text-center'}
|
className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}
|
||||||
>
|
|
||||||
<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'
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
<span className={'flex items-center gap-2'}>
|
Flexible filtering options
|
||||||
Get started for free
|
</h2>
|
||||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-1" />
|
<p className={'mt-4 text-lg text-neutral-600'}>Build complex segments with nested AND/OR logic</p>
|
||||||
</span>
|
</motion.div>
|
||||||
</motion.a>
|
|
||||||
<Link
|
<div className={'space-y-4'}>
|
||||||
href={'/pricing'}
|
{filterExamples.map((example, index) => (
|
||||||
className={
|
<motion.div
|
||||||
'rounded-lg border border-neutral-300 px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-400'
|
key={example.title}
|
||||||
}
|
initial={{opacity: 0, y: 20}}
|
||||||
>
|
whileInView={{opacity: 1, y: 0}}
|
||||||
View pricing
|
viewport={{once: true}}
|
||||||
</Link>
|
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>
|
</div>
|
||||||
</motion.div>
|
</div>
|
||||||
</section>
|
</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>
|
</main>
|
||||||
|
|
||||||
<Footer />
|
<Footer />
|
||||||
|
|||||||
@@ -8,34 +8,33 @@ import Head from 'next/head';
|
|||||||
|
|
||||||
const features = [
|
const features = [
|
||||||
{
|
{
|
||||||
icon: <Settings className="h-5 w-5" />,
|
icon: <Settings className="h-6 w-6" strokeWidth={1.5} />,
|
||||||
title: 'Simple Configuration',
|
title: 'Simple Configuration',
|
||||||
description: 'Quick setup with your project credentials. Works with any email client or application.',
|
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',
|
title: 'Secure Connections',
|
||||||
description: 'TLS/SSL encryption on ports 465 and 587. Your emails are always transmitted securely.',
|
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',
|
title: 'Universal Compatibility',
|
||||||
description:
|
description: 'Works with Outlook, Thunderbird, Apple Mail, or any SMTP-compatible application.',
|
||||||
'Works with Outlook, Thunderbird, Apple Mail, or any SMTP-compatible application. Even that ancient email client from 2005.',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
icon: <Server className="h-5 w-5" />,
|
icon: <Server className="h-6 w-6" strokeWidth={1.5} />,
|
||||||
title: 'Domain Validation',
|
title: 'Domain Validation',
|
||||||
description: 'Automatic verification that your sender domain is verified before accepting emails.',
|
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',
|
title: 'Full Feature Support',
|
||||||
description:
|
description: 'Attachments, custom headers, HTML emails, and multiple recipients.',
|
||||||
'Attachments, custom headers, HTML emails, and multiple recipients. Send those cat memes with confidence.',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
icon: <Code2 className="h-5 w-5" />,
|
icon: <Code2 className="h-6 w-6" strokeWidth={1.5} />,
|
||||||
title: 'Same Infrastructure',
|
title: 'Same Infrastructure',
|
||||||
description: 'SMTP emails use the same reliable delivery infrastructure as API emails with full tracking.',
|
description: 'SMTP emails use the same reliable delivery infrastructure as API emails with full tracking.',
|
||||||
},
|
},
|
||||||
@@ -54,21 +53,21 @@ const comparisonData = [
|
|||||||
|
|
||||||
const useCases = [
|
const useCases = [
|
||||||
{
|
{
|
||||||
icon: <Settings className="h-6 w-6" />,
|
icon: <Settings className="h-6 w-6" strokeWidth={1.5} />,
|
||||||
title: 'Legacy System Integration',
|
title: 'Legacy System Integration',
|
||||||
description:
|
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',
|
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',
|
title: 'Email Client Sending',
|
||||||
description:
|
description:
|
||||||
'Marketing teams can send emails directly from Outlook, Thunderbird, or Apple Mail using familiar tools without learning new APIs.',
|
'Marketing teams can send emails directly from Outlook, Thunderbird, or Apple Mail using familiar tools without learning new APIs.',
|
||||||
benefit: 'No technical knowledge needed',
|
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',
|
title: 'Framework Compatibility',
|
||||||
description:
|
description:
|
||||||
'Works with any framework or language that supports SMTP. Perfect for older systems or platforms without HTTP API support.',
|
'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() {
|
export default function SMTPFeature() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -97,236 +93,283 @@ export default function SMTPFeature() {
|
|||||||
|
|
||||||
<Navbar />
|
<Navbar />
|
||||||
|
|
||||||
<main className={'mx-auto max-w-7xl px-8 sm:px-0'}>
|
<main className={'text-neutral-800'}>
|
||||||
{/* Hero Section */}
|
|
||||||
<section className={'relative py-20 sm:py-32'}>
|
{/* Hero */}
|
||||||
{/* Subtle background grid */}
|
<section className={'relative overflow-hidden'}>
|
||||||
<div
|
<div
|
||||||
|
aria-hidden
|
||||||
className={
|
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%)]'
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
<div className={'mx-auto max-w-[88rem] px-6 pb-20 pt-20 sm:px-10 sm:pt-28 sm:pb-28'}>
|
||||||
<motion.div
|
<motion.div
|
||||||
initial={{opacity: 0, y: 20}}
|
initial={{opacity: 0, y: 16}}
|
||||||
animate={{opacity: 1, y: 0}}
|
animate={{opacity: 1, y: 0}}
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||||
className={'mx-auto max-w-4xl text-center'}
|
>
|
||||||
>
|
<div
|
||||||
<div className={'mb-6 inline-flex items-center gap-2 rounded-full bg-neutral-100 px-4 py-2 text-sm'}>
|
style={{fontFamily: 'var(--font-mono)'}}
|
||||||
<Server className="h-4 w-4 text-neutral-600" />
|
className={'mb-6 text-[11px] uppercase tracking-[0.18em] text-neutral-500'}
|
||||||
<span className={'font-medium text-neutral-600'}>SMTP Email Sending</span>
|
>
|
||||||
</div>
|
SMTP
|
||||||
|
</div>
|
||||||
<h1 className={'text-6xl font-bold tracking-tight text-neutral-900 sm:text-7xl lg:text-8xl text-balance'}>
|
<h1
|
||||||
Send Emails via SMTP or API
|
style={{fontFamily: 'var(--font-display)'}}
|
||||||
</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`}
|
|
||||||
className={
|
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'}>
|
Send via SMTP
|
||||||
Get SMTP credentials
|
<br />
|
||||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-1" />
|
or API. Your call.
|
||||||
</span>
|
</h1>
|
||||||
</motion.a>
|
<p className={'mt-6 max-w-2xl text-xl text-neutral-600'}>
|
||||||
<Link
|
Use our HTTP API for modern apps or drop in SMTP credentials for any legacy system. Same deliverability,
|
||||||
href={WIKI_URI}
|
same pricing, zero lock-in.
|
||||||
target={'_blank'}
|
</p>
|
||||||
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>
|
|
||||||
|
|
||||||
{/* Features Grid */}
|
<div className={'mt-10 flex flex-wrap gap-3'}>
|
||||||
<section className={'py-20'}>
|
<motion.a
|
||||||
<motion.div
|
whileHover={{scale: 1.015}}
|
||||||
initial={{opacity: 0, y: 20}}
|
whileTap={{scale: 0.985}}
|
||||||
whileInView={{opacity: 1, y: 0}}
|
href={`${DASHBOARD_URI}/auth/signup`}
|
||||||
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
|
|
||||||
className={
|
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}
|
Get SMTP credentials
|
||||||
</div>
|
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-0.5" />
|
||||||
<h3 className={'mt-6 text-lg font-semibold text-neutral-900'}>{feature.title}</h3>
|
</motion.a>
|
||||||
<p className={'mt-2 text-sm leading-relaxed text-neutral-600'}>{feature.description}</p>
|
<Link
|
||||||
</motion.div>
|
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>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{/* Comparison Table */}
|
{/* Features grid */}
|
||||||
<section className={'py-20'}>
|
<section className={'border-t border-neutral-200'}>
|
||||||
<motion.div
|
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||||
initial={{opacity: 0, y: 20}}
|
<motion.div
|
||||||
whileInView={{opacity: 1, y: 0}}
|
initial={{opacity: 0, y: 20}}
|
||||||
viewport={{once: true}}
|
whileInView={{opacity: 1, y: 0}}
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
viewport={{once: true}}
|
||||||
className={'mb-12 text-center'}
|
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||||
>
|
className={'mb-16'}
|
||||||
<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>
|
<h2
|
||||||
</motion.div>
|
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={'grid gap-4 sm:grid-cols-2 lg:grid-cols-3'}>
|
||||||
<div className={'overflow-hidden rounded-xl border border-neutral-200 bg-white'}>
|
{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'}>
|
<table className={'w-full'}>
|
||||||
<thead className={'bg-neutral-50'}>
|
<thead className={'border-b border-neutral-200 bg-neutral-50'}>
|
||||||
<tr>
|
<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-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={'px-6 py-4 text-center text-sm font-semibold text-neutral-500'}>Traditional SMTP</th>
|
||||||
<th className={'bg-neutral-100 px-6 py-4 text-center text-sm font-semibold text-neutral-900'}>
|
<th className={'bg-neutral-900 px-6 py-4 text-center text-sm font-semibold text-white'}>Plunk SMTP</th>
|
||||||
Plunk SMTP
|
<th className={'px-6 py-4 text-center text-sm font-semibold text-neutral-500'}>Plunk API</th>
|
||||||
</th>
|
|
||||||
<th className={'px-6 py-4 text-center text-sm font-semibold text-neutral-900'}>Plunk API</th>
|
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody className={'divide-y divide-neutral-200'}>
|
<tbody className={'divide-y divide-neutral-100'}>
|
||||||
{comparisonData.map((row, index) => (
|
{comparisonData.map((row, index) => (
|
||||||
<tr key={index} className={'transition hover:bg-neutral-50'}>
|
<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-sm font-medium text-neutral-900'}>{row.feature}</td>
|
||||||
<td className={'px-6 py-4 text-center text-sm text-neutral-600'}>{row.traditional}</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-medium text-neutral-900'}>
|
<td className={'bg-neutral-50 px-6 py-4 text-center text-sm font-semibold text-neutral-900'}>{row.plunkSMTP}</td>
|
||||||
{row.plunkSMTP}
|
<td className={'px-6 py-4 text-center text-sm text-neutral-500'}>{row.plunkAPI}</td>
|
||||||
</td>
|
|
||||||
<td className={'px-6 py-4 text-center text-sm text-neutral-600'}>{row.plunkAPI}</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
))}
|
))}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<div className={'mt-6 rounded-lg bg-neutral-50 p-4 text-center'}>
|
<p className={'mt-4 text-sm text-neutral-500'}>
|
||||||
<p className={'text-sm text-neutral-600'}>
|
Recommendation: Use the API for modern applications with workflow automation. Use SMTP for email clients
|
||||||
<strong>Recommendation:</strong> Use API for modern applications with workflow automation. Use SMTP for
|
and legacy systems.
|
||||||
email clients and legacy systems.
|
</p>
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{/* Use Cases */}
|
{/* Use cases */}
|
||||||
<section className={'py-20'}>
|
<section className={'border-t border-neutral-200'}>
|
||||||
<motion.div
|
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||||
initial={{opacity: 0, y: 20}}
|
<motion.div
|
||||||
whileInView={{opacity: 1, y: 0}}
|
initial={{opacity: 0, y: 20}}
|
||||||
viewport={{once: true}}
|
whileInView={{opacity: 1, y: 0}}
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
viewport={{once: true}}
|
||||||
className={'mb-16 text-center'}
|
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||||
>
|
className={'mb-16'}
|
||||||
<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>
|
<h2
|
||||||
</motion.div>
|
style={{fontFamily: 'var(--font-display)'}}
|
||||||
|
className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}
|
||||||
<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'}>
|
When to use SMTP
|
||||||
<div
|
</h2>
|
||||||
className={
|
<p className={'mt-4 text-lg text-neutral-600'}>Perfect for these scenarios</p>
|
||||||
'flex h-14 w-14 flex-shrink-0 items-center justify-center rounded-xl bg-neutral-900 text-white'
|
</motion.div>
|
||||||
}
|
|
||||||
>
|
<div className={'space-y-4'}>
|
||||||
{useCase.icon}
|
{useCases.map((useCase, index) => (
|
||||||
</div>
|
<motion.div
|
||||||
<div className={'flex-1'}>
|
key={useCase.title}
|
||||||
<h3 className={'text-xl font-semibold text-neutral-900'}>{useCase.title}</h3>
|
initial={{opacity: 0, y: 20}}
|
||||||
<p className={'mt-2 text-neutral-600'}>{useCase.description}</p>
|
whileInView={{opacity: 1, y: 0}}
|
||||||
<div className={'mt-4 inline-flex items-center gap-2 rounded-full bg-neutral-100 px-4 py-2'}>
|
viewport={{once: true}}
|
||||||
<div className={'h-2 w-2 rounded-full bg-green-500'} />
|
transition={{duration: 0.5, delay: index * 0.1, ease: [0.22, 1, 0.36, 1]}}
|
||||||
<span className={'text-sm font-medium text-neutral-700'}>{useCase.benefit}</span>
|
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>
|
</div>
|
||||||
</div>
|
</motion.div>
|
||||||
</motion.div>
|
))}
|
||||||
))}
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{/* CTA Section */}
|
{/* CTA */}
|
||||||
<section className={'relative overflow-hidden border-t border-neutral-200 py-20'}>
|
<section className={'relative overflow-hidden border-t border-neutral-900 bg-neutral-900 text-white'}>
|
||||||
<div
|
<div className={'mx-auto max-w-[88rem] px-6 py-32 sm:px-10 sm:py-40'}>
|
||||||
className={
|
<div className={'flex flex-col items-start gap-12 lg:flex-row lg:items-end lg:justify-between'}>
|
||||||
'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.h2
|
||||||
}
|
initial={{opacity: 0, y: 16}}
|
||||||
/>
|
whileInView={{opacity: 1, y: 0}}
|
||||||
<motion.div
|
viewport={{once: true}}
|
||||||
initial={{opacity: 0, y: 20}}
|
transition={{duration: 0.9, ease: [0.22, 1, 0.36, 1]}}
|
||||||
whileInView={{opacity: 1, y: 0}}
|
style={{fontFamily: 'var(--font-display)'}}
|
||||||
viewport={{once: true}}
|
className={'text-[clamp(2.5rem,7vw,6rem)] font-extrabold leading-[0.95] tracking-[-0.035em]'}
|
||||||
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'
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
<span className={'flex items-center gap-2'}>
|
Start sending via SMTP today.
|
||||||
Get started for free
|
</motion.h2>
|
||||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-1" />
|
<motion.div
|
||||||
</span>
|
initial={{opacity: 0, y: 16}}
|
||||||
</motion.a>
|
whileInView={{opacity: 1, y: 0}}
|
||||||
<Link
|
viewport={{once: true}}
|
||||||
href={'/pricing'}
|
transition={{duration: 0.9, delay: 0.15, ease: [0.22, 1, 0.36, 1]}}
|
||||||
className={
|
className={'flex max-w-md flex-col gap-6'}
|
||||||
'rounded-lg border border-neutral-300 px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-400'
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
View pricing
|
<p className={'text-base text-neutral-300 sm:text-lg'}>
|
||||||
</Link>
|
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>
|
</div>
|
||||||
</motion.div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<Footer />
|
<Footer />
|
||||||
|
|||||||
@@ -8,32 +8,33 @@ import Head from 'next/head';
|
|||||||
|
|
||||||
const features = [
|
const features = [
|
||||||
{
|
{
|
||||||
icon: <Zap className="h-5 w-5" />,
|
icon: <Zap className="h-6 w-6" strokeWidth={1.5} />,
|
||||||
title: 'Event-Driven Triggers',
|
title: 'Event-Driven Triggers',
|
||||||
description: 'Start workflows automatically when users sign up, make a purchase, or perform any custom action.',
|
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',
|
title: 'Smart Email Sequences',
|
||||||
description: 'Send personalized emails at the right time with dynamic content based on user data.',
|
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',
|
title: 'Time-Based Delays',
|
||||||
description: 'Add strategic delays between steps to create perfectly timed email journeys. Patience is a virtue.',
|
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',
|
title: 'Conditional Logic',
|
||||||
description: 'Branch workflows based on user behavior, attributes, or engagement to personalize every journey.',
|
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',
|
title: 'External Integrations',
|
||||||
description: 'Connect to external systems with webhooks to sync data or trigger actions outside of Plunk.',
|
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',
|
title: 'Re-entry Control',
|
||||||
description: 'Decide whether contacts can enter workflows multiple times or just once. No spam, just strategy.',
|
description: 'Decide whether contacts can enter workflows multiple times or just once. No spam, just strategy.',
|
||||||
},
|
},
|
||||||
@@ -41,21 +42,21 @@ const features = [
|
|||||||
|
|
||||||
const useCases = [
|
const useCases = [
|
||||||
{
|
{
|
||||||
icon: <UserPlus className="h-6 w-6" />,
|
icon: <UserPlus className="h-6 w-6" strokeWidth={1.5} />,
|
||||||
title: 'User Onboarding',
|
title: 'User Onboarding',
|
||||||
description:
|
description:
|
||||||
'Welcome new users with a personalized email series that guides them through your product features and helps them get started.',
|
'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',
|
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',
|
title: 'Abandoned Cart Recovery',
|
||||||
description:
|
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',
|
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',
|
title: 'Re-engagement Campaigns',
|
||||||
description:
|
description:
|
||||||
'Win back inactive users with targeted campaigns based on their last activity and engagement patterns.',
|
'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() {
|
export default function WorkflowsFeature() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -84,269 +82,299 @@ export default function WorkflowsFeature() {
|
|||||||
|
|
||||||
<Navbar />
|
<Navbar />
|
||||||
|
|
||||||
<main className={'mx-auto max-w-7xl px-8 sm:px-0'}>
|
<main className={'text-neutral-800'}>
|
||||||
{/* Hero Section */}
|
|
||||||
<section className={'relative py-20 sm:py-32'}>
|
{/* Hero */}
|
||||||
{/* Subtle background grid */}
|
<section className={'relative overflow-hidden'}>
|
||||||
<div
|
<div
|
||||||
|
aria-hidden
|
||||||
className={
|
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%)]'
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
<div className={'mx-auto max-w-[88rem] px-6 pb-20 pt-20 sm:px-10 sm:pt-28 sm:pb-28'}>
|
||||||
<motion.div
|
<motion.div
|
||||||
initial={{opacity: 0, y: 20}}
|
initial={{opacity: 0, y: 16}}
|
||||||
animate={{opacity: 1, y: 0}}
|
animate={{opacity: 1, y: 0}}
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||||
className={'mx-auto max-w-4xl text-center'}
|
>
|
||||||
>
|
<div
|
||||||
<div className={'mb-6 inline-flex items-center gap-2 rounded-full bg-neutral-100 px-4 py-2 text-sm'}>
|
style={{fontFamily: 'var(--font-mono)'}}
|
||||||
<Zap className="h-4 w-4 text-neutral-600" />
|
className={'mb-6 text-[11px] uppercase tracking-[0.18em] text-neutral-500'}
|
||||||
<span className={'font-medium text-neutral-600'}>Workflow Automation</span>
|
>
|
||||||
</div>
|
Workflow Automation
|
||||||
|
</div>
|
||||||
<h1 className={'text-6xl font-bold tracking-tight text-neutral-900 sm:text-7xl lg:text-8xl text-balance'}>
|
<h1
|
||||||
Email Automation
|
style={{fontFamily: 'var(--font-display)'}}
|
||||||
<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`}
|
|
||||||
className={
|
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'}>
|
Email automation
|
||||||
Start building workflows
|
<br />
|
||||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-1" />
|
that actually works.
|
||||||
</span>
|
</h1>
|
||||||
</motion.a>
|
<p className={'mt-6 max-w-2xl text-xl text-neutral-600'}>
|
||||||
<Link
|
Turn events into personalized email journeys. Build sophisticated automation workflows with our visual
|
||||||
href={WIKI_URI}
|
no-code builder.
|
||||||
target={'_blank'}
|
</p>
|
||||||
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>
|
|
||||||
|
|
||||||
{/* Features Grid */}
|
<div className={'mt-10 flex flex-wrap gap-3'}>
|
||||||
<section className={'py-20'}>
|
<motion.a
|
||||||
<motion.div
|
whileHover={{scale: 1.015}}
|
||||||
initial={{opacity: 0, y: 20}}
|
whileTap={{scale: 0.985}}
|
||||||
whileInView={{opacity: 1, y: 0}}
|
href={`${DASHBOARD_URI}/auth/signup`}
|
||||||
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
|
|
||||||
className={
|
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}
|
Start building workflows
|
||||||
</div>
|
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-0.5" />
|
||||||
<h3 className={'mt-6 text-lg font-semibold text-neutral-900'}>{feature.title}</h3>
|
</motion.a>
|
||||||
<p className={'mt-2 text-sm leading-relaxed text-neutral-600'}>{feature.description}</p>
|
<Link
|
||||||
</motion.div>
|
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>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{/* How It Works */}
|
{/* Features grid */}
|
||||||
<section className={'py-20'}>
|
<section className={'border-t border-neutral-200'}>
|
||||||
<motion.div
|
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||||
initial={{opacity: 0, y: 20}}
|
<motion.div
|
||||||
whileInView={{opacity: 1, y: 0}}
|
initial={{opacity: 0, y: 20}}
|
||||||
viewport={{once: true}}
|
whileInView={{opacity: 1, y: 0}}
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
viewport={{once: true}}
|
||||||
className={'mx-auto max-w-4xl text-center'}
|
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||||
>
|
className={'mb-16'}
|
||||||
<h2 className={'text-4xl font-bold tracking-tight text-neutral-900 sm:text-5xl text-balance'}>
|
>
|
||||||
Visual workflow builder
|
<h2
|
||||||
</h2>
|
style={{fontFamily: 'var(--font-display)'}}
|
||||||
<p className={'mt-6 text-lg text-neutral-600'}>
|
className={
|
||||||
Create complex email automations without writing a single line of code
|
'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'
|
||||||
</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]}}
|
|
||||||
>
|
>
|
||||||
<div className={'mb-5 flex items-center gap-4'}>
|
Everything you need for email automation
|
||||||
<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'}>
|
</h2>
|
||||||
1
|
<p className={'mt-4 text-lg text-neutral-600'}>Powerful features that make complex automations simple</p>
|
||||||
</div>
|
</motion.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>
|
|
||||||
|
|
||||||
<motion.div
|
<div className={'grid gap-4 sm:grid-cols-2 lg:grid-cols-3'}>
|
||||||
initial={{opacity: 0, y: 20}}
|
{features.map((feature, index) => {
|
||||||
whileInView={{opacity: 1, y: 0}}
|
const highlighted = feature.featured;
|
||||||
viewport={{once: true}}
|
return (
|
||||||
transition={{duration: 0.5, delay: 0.2, ease: [0.22, 1, 0.36, 1]}}
|
<motion.div
|
||||||
>
|
key={feature.title}
|
||||||
<div className={'mb-5 flex items-center gap-4'}>
|
initial={{opacity: 0, y: 16}}
|
||||||
<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'}>
|
whileInView={{opacity: 1, y: 0}}
|
||||||
2
|
viewport={{once: true}}
|
||||||
</div>
|
transition={{duration: 0.5, delay: index * 0.06, ease: [0.22, 1, 0.36, 1]}}
|
||||||
</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
|
|
||||||
className={
|
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 className={'flex items-start justify-between'}>
|
||||||
</div>
|
<div className={highlighted ? 'text-white' : 'text-neutral-900'}>{feature.icon}</div>
|
||||||
<div className={'flex-1'}>
|
<span
|
||||||
<h3 className={'text-xl font-semibold text-neutral-900'}>{useCase.title}</h3>
|
style={{fontFamily: 'var(--font-mono)'}}
|
||||||
<p className={'mt-2 text-neutral-600'}>{useCase.description}</p>
|
className={`text-[11px] uppercase tracking-[0.18em] ${highlighted ? 'text-neutral-500' : 'text-neutral-400'}`}
|
||||||
<div className={'mt-4 rounded-lg bg-neutral-50 p-4'}>
|
>
|
||||||
<p className={'font-mono text-sm text-neutral-700'}>{useCase.example}</p>
|
{String(index + 1).padStart(2, '0')}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div>
|
||||||
</div>
|
<h3
|
||||||
</motion.div>
|
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>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{/* CTA Section */}
|
{/* How it works */}
|
||||||
<section className={'relative overflow-hidden border-t border-neutral-200 py-20'}>
|
<section className={'border-t border-neutral-200 bg-neutral-50/60'}>
|
||||||
<div
|
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||||
className={
|
<motion.div
|
||||||
'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%)]'
|
initial={{opacity: 0, y: 20}}
|
||||||
}
|
whileInView={{opacity: 1, y: 0}}
|
||||||
/>
|
viewport={{once: true}}
|
||||||
<motion.div
|
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||||
initial={{opacity: 0, y: 20}}
|
className={'mb-16 text-center'}
|
||||||
whileInView={{opacity: 1, y: 0}}
|
>
|
||||||
viewport={{once: true}}
|
<h2
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
style={{fontFamily: 'var(--font-display)'}}
|
||||||
className={'mx-auto max-w-3xl text-center'}
|
className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}
|
||||||
>
|
|
||||||
<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'
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
<span className={'flex items-center gap-2'}>
|
Visual workflow builder
|
||||||
Get started for free
|
</h2>
|
||||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-1" />
|
<p className={'mt-4 text-lg text-neutral-600'}>
|
||||||
</span>
|
Create complex email automations without writing a single line of code
|
||||||
</motion.a>
|
</p>
|
||||||
<Link
|
</motion.div>
|
||||||
href={'/pricing'}
|
|
||||||
className={
|
<div className={'mx-auto max-w-4xl'}>
|
||||||
'rounded-lg border border-neutral-300 px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-400'
|
<div className={'grid gap-px bg-neutral-200 sm:grid-cols-3'}>
|
||||||
}
|
{[
|
||||||
>
|
{
|
||||||
View pricing
|
step: '01',
|
||||||
</Link>
|
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>
|
</div>
|
||||||
</motion.div>
|
</div>
|
||||||
</section>
|
</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>
|
</main>
|
||||||
|
|
||||||
<Footer />
|
<Footer />
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ interface Guide {
|
|||||||
title: string;
|
title: string;
|
||||||
description: string;
|
description: string;
|
||||||
href: string;
|
href: string;
|
||||||
icon: React.ComponentType<{className?: string}>;
|
icon: React.ComponentType<{className?: string; strokeWidth?: number}>;
|
||||||
badge?: string;
|
badge?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,9 +94,6 @@ const guides: Guide[] = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
|
||||||
* Email Guides hub page
|
|
||||||
*/
|
|
||||||
export default function GuidesIndex() {
|
export default function GuidesIndex() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -115,154 +112,171 @@ export default function GuidesIndex() {
|
|||||||
|
|
||||||
<Navbar />
|
<Navbar />
|
||||||
|
|
||||||
<main className={'mx-auto max-w-7xl px-8 sm:px-0'}>
|
<main className={'text-neutral-800'}>
|
||||||
{/* Hero Section */}
|
|
||||||
<section className={'relative py-32 sm:py-48'}>
|
{/* Hero */}
|
||||||
|
<section className={'relative overflow-hidden'}>
|
||||||
<div
|
<div
|
||||||
|
aria-hidden
|
||||||
className={
|
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%)]'
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
<div className={'mx-auto max-w-[88rem] px-6 pb-20 pt-20 sm:px-10 sm:pt-28 sm:pb-28'}>
|
||||||
<motion.div
|
<motion.div
|
||||||
initial={{opacity: 0, y: 20}}
|
initial={{opacity: 0, y: 16}}
|
||||||
animate={{opacity: 1, y: 0}}
|
animate={{opacity: 1, y: 0}}
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
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'
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
<Book className="h-4 w-4 text-neutral-600" />
|
<div
|
||||||
<span className={'text-sm text-neutral-600'}>Free Email Guides</span>
|
style={{fontFamily: 'var(--font-mono)'}}
|
||||||
</div>
|
className={'mb-6 text-[11px] uppercase tracking-[0.18em] text-neutral-500'}
|
||||||
|
>
|
||||||
<h1 className={'text-6xl font-bold tracking-tight text-neutral-900 sm:text-7xl lg:text-8xl'}>
|
Free Guides
|
||||||
Master email
|
</div>
|
||||||
<br />
|
<h1
|
||||||
marketing & deliverability
|
style={{fontFamily: 'var(--font-display)'}}
|
||||||
</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`}
|
|
||||||
className={
|
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'}>
|
Master email,
|
||||||
Try Plunk free
|
<br />
|
||||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-1" />
|
start to finish.
|
||||||
</span>
|
</h1>
|
||||||
</motion.a>
|
<p className={'mt-6 max-w-2xl text-xl text-neutral-600'}>
|
||||||
</div>
|
Free guides on email authentication, deliverability, best practices, and technical implementation.
|
||||||
</motion.div>
|
</p>
|
||||||
</section>
|
|
||||||
|
|
||||||
{/* Guides Grid */}
|
<div className={'mt-10 flex flex-wrap gap-3'}>
|
||||||
<section className={'py-32'}>
|
<motion.a
|
||||||
<motion.div
|
whileHover={{scale: 1.015}}
|
||||||
initial={{opacity: 0, y: 20}}
|
whileTap={{scale: 0.985}}
|
||||||
whileInView={{opacity: 1, y: 0}}
|
href={`${DASHBOARD_URI}/auth/signup`}
|
||||||
viewport={{once: true}}
|
className={
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
'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'
|
||||||
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]}}
|
|
||||||
>
|
>
|
||||||
<Link
|
Try Plunk free
|
||||||
href={guide.href}
|
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-0.5" />
|
||||||
className={
|
</motion.a>
|
||||||
'group block h-full rounded-2xl border border-neutral-200 bg-white p-8 transition hover:border-neutral-300 hover:shadow-lg'
|
</div>
|
||||||
}
|
</motion.div>
|
||||||
>
|
|
||||||
<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>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{/* CTA Section */}
|
{/* Guides grid */}
|
||||||
<section className={'relative overflow-hidden border-t border-neutral-200 py-32'}>
|
<section className={'border-t border-neutral-200'}>
|
||||||
<div
|
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||||
className={
|
<motion.div
|
||||||
'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%)]'
|
initial={{opacity: 0, y: 20}}
|
||||||
}
|
whileInView={{opacity: 1, y: 0}}
|
||||||
/>
|
viewport={{once: true}}
|
||||||
<motion.div
|
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||||
initial={{opacity: 0, y: 20}}
|
className={'mb-16'}
|
||||||
whileInView={{opacity: 1, y: 0}}
|
>
|
||||||
viewport={{once: true}}
|
<h2
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
style={{fontFamily: 'var(--font-display)'}}
|
||||||
className={'mx-auto max-w-3xl text-center'}
|
className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}
|
||||||
>
|
|
||||||
<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'
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
Get started free
|
Browse all guides
|
||||||
</motion.a>
|
</h2>
|
||||||
<Link
|
<p className={'mt-4 text-lg text-neutral-600'}>Everything you need to master email</p>
|
||||||
href="/pricing"
|
</motion.div>
|
||||||
className={
|
|
||||||
'rounded-lg border border-neutral-300 px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-400'
|
<div className={'grid gap-4 sm:grid-cols-2 lg:grid-cols-3'}>
|
||||||
}
|
{guides.map((guide, index) => {
|
||||||
>
|
const Icon = guide.icon;
|
||||||
View pricing
|
return (
|
||||||
</Link>
|
<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>
|
</div>
|
||||||
</motion.div>
|
</div>
|
||||||
</section>
|
</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>
|
</main>
|
||||||
|
|
||||||
<Footer />
|
<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 {Footer, Navbar} from '../components';
|
||||||
import {motion} from 'framer-motion';
|
import {motion} from 'framer-motion';
|
||||||
import {DASHBOARD_URI} from '../lib/constants';
|
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 Link from 'next/link';
|
||||||
import {GithubIcon} from 'lucide-react';
|
import {GithubIcon} from 'lucide-react';
|
||||||
|
|
||||||
@@ -55,9 +67,6 @@ const includedFeatures = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
export default function Pricing() {
|
export default function Pricing() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -69,232 +78,295 @@ export default function Pricing() {
|
|||||||
openGraph={{
|
openGraph={{
|
||||||
title: 'Plunk Pricing | The Open-Source Email Platform',
|
title: 'Plunk Pricing | The Open-Source Email Platform',
|
||||||
description:
|
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={[
|
additionalMetaTags={[{property: 'title', content: 'Plunk Pricing | The Open-Source Email Platform'}]}
|
||||||
{
|
|
||||||
property: 'title',
|
|
||||||
content: 'Plunk Pricing | The Open-Source Email Platform',
|
|
||||||
},
|
|
||||||
]}
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Navbar />
|
<Navbar />
|
||||||
|
|
||||||
<main className={'mx-auto max-w-7xl px-8 sm:px-0'}>
|
<main className={'text-neutral-800'}>
|
||||||
|
|
||||||
{/* Hero */}
|
{/* Hero */}
|
||||||
<section className={'relative py-20 sm:py-32'}>
|
<section className={'relative overflow-hidden'}>
|
||||||
<div
|
<div
|
||||||
|
aria-hidden
|
||||||
className={
|
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%)]'
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
<div className={'mx-auto max-w-[88rem] px-6 pb-20 pt-20 sm:px-10 sm:pt-28 sm:pb-28'}>
|
||||||
<motion.div
|
<motion.div
|
||||||
initial={{opacity: 0, y: 20}}
|
initial={{opacity: 0, y: 16}}
|
||||||
animate={{opacity: 1, y: 0}}
|
animate={{opacity: 1, y: 0}}
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||||
className={'mx-auto max-w-4xl text-center'}
|
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">
|
<h1
|
||||||
Simple, transparent pricing
|
style={{fontFamily: 'var(--font-display)'}}
|
||||||
</h1>
|
className={
|
||||||
<p className="mx-auto mt-6 max-w-2xl text-xl text-neutral-600">
|
'text-[clamp(2.75rem,7vw,6.5rem)] font-extrabold leading-[0.92] tracking-[-0.04em] text-neutral-900'
|
||||||
1,000 emails free every month. Then $0.001 per email. Unlimited contacts, no hidden fees.
|
}
|
||||||
</p>
|
>
|
||||||
</motion.div>
|
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>
|
</section>
|
||||||
|
|
||||||
{/* Pricing tiers */}
|
{/* Pricing tiers */}
|
||||||
<section className={'pb-20'}>
|
<section className={'border-t border-neutral-200'}>
|
||||||
<div className={'mx-auto grid max-w-4xl gap-px bg-neutral-200 sm:grid-cols-2'}>
|
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||||
{/* Free */}
|
<div className={'mx-auto grid max-w-4xl gap-px bg-neutral-200 sm:grid-cols-2'}>
|
||||||
<motion.div
|
{/* Free */}
|
||||||
initial={{opacity: 0, y: 20}}
|
<motion.div
|
||||||
animate={{opacity: 1, y: 0}}
|
initial={{opacity: 0, y: 20}}
|
||||||
transition={{delay: 0.1, duration: 0.6, ease: [0.22, 1, 0.36, 1]}}
|
animate={{opacity: 1, y: 0}}
|
||||||
className={'flex flex-col bg-white p-10'}
|
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'}
|
|
||||||
>
|
>
|
||||||
Start for free
|
<p
|
||||||
</motion.a>
|
style={{fontFamily: 'var(--font-mono)'}}
|
||||||
</motion.div>
|
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 */}
|
<ul className={'mt-8 flex-1 space-y-3'}>
|
||||||
<motion.div
|
{[
|
||||||
initial={{opacity: 0, y: 20}}
|
'Transactional emails',
|
||||||
animate={{opacity: 1, y: 0}}
|
'Workflow automation',
|
||||||
transition={{delay: 0.2, duration: 0.6, ease: [0.22, 1, 0.36, 1]}}
|
'Campaign broadcasts',
|
||||||
className={'flex flex-col bg-white p-10'}
|
'Custom domains',
|
||||||
>
|
'Click & open tracking',
|
||||||
<p className={'text-sm font-semibold uppercase tracking-widest text-neutral-400'}>Pay as you grow</p>
|
'Unlimited contacts',
|
||||||
<div className={'mt-4 flex items-baseline gap-2'}>
|
].map(item => (
|
||||||
<span className={'text-6xl font-bold tracking-tight text-neutral-900'}>$0.001</span>
|
<li key={item} className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||||
<span className={'text-lg text-neutral-500'}>/ email</span>
|
<Check className={'h-4 w-4 flex-shrink-0 text-neutral-900'} />
|
||||||
</div>
|
{item}
|
||||||
<p className={'mt-2 text-sm'}> </p>
|
</li>
|
||||||
|
))}
|
||||||
<ul className={'mt-8 flex-1 space-y-3'}>
|
<li className={'flex items-center gap-3 text-sm text-neutral-400'}>
|
||||||
{['Everything in Free', 'No Plunk branding', 'Monthly spend cap', 'Unlimited emails'].map(item => (
|
<X className={'h-4 w-4 flex-shrink-0'} />
|
||||||
<li key={item} className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
Plunk branding on emails
|
||||||
<Check className={'h-4 w-4 flex-shrink-0 text-neutral-900'} />
|
|
||||||
{item}
|
|
||||||
</li>
|
</li>
|
||||||
))}
|
</ul>
|
||||||
</ul>
|
|
||||||
|
|
||||||
<motion.a
|
<motion.a
|
||||||
href={`${DASHBOARD_URI}/auth/signup`}
|
href={`${DASHBOARD_URI}/auth/signup`}
|
||||||
whileHover={{scale: 1.02}}
|
whileHover={{scale: 1.02}}
|
||||||
whileTap={{scale: 0.98}}
|
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'}
|
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>
|
<ul className={'mt-8 flex-1 space-y-3'}>
|
||||||
</motion.div>
|
{['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>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{/* Every feature included */}
|
{/* Every feature included */}
|
||||||
<section className={'py-20'}>
|
<section className={'border-t border-neutral-200 bg-neutral-50/60'}>
|
||||||
<motion.div
|
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||||
initial={{opacity: 0, y: 20}}
|
<motion.div
|
||||||
whileInView={{opacity: 1, y: 0}}
|
initial={{opacity: 0, y: 20}}
|
||||||
viewport={{once: true}}
|
whileInView={{opacity: 1, y: 0}}
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
viewport={{once: true}}
|
||||||
className={'mb-16 text-center'}
|
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
|
||||||
</h2>
|
style={{fontFamily: 'var(--font-display)'}}
|
||||||
<p className={'mt-4 text-lg text-neutral-600'}>No feature tiers, no add-ons, no surprises</p>
|
className={
|
||||||
</motion.div>
|
'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'
|
||||||
|
}
|
||||||
<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 transition group-hover:scale-110'}>
|
Every feature on every plan
|
||||||
{feature.icon}
|
</h2>
|
||||||
</div>
|
<p className={'mt-4 text-lg text-neutral-600'}>No feature tiers, no add-ons, no surprises</p>
|
||||||
<h3 className={'mt-6 text-lg font-semibold text-neutral-900'}>{feature.title}</h3>
|
</motion.div>
|
||||||
<p className={'mt-2 text-sm leading-relaxed text-neutral-600'}>{feature.description}</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>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{/* Self-host */}
|
{/* Self-host */}
|
||||||
<section className={'py-20'}>
|
<section className={'border-t border-neutral-200'}>
|
||||||
<motion.div
|
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||||
initial={{opacity: 0, y: 20}}
|
<motion.div
|
||||||
whileInView={{opacity: 1, y: 0}}
|
initial={{opacity: 0, y: 20}}
|
||||||
viewport={{once: true}}
|
whileInView={{opacity: 1, y: 0}}
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
viewport={{once: true}}
|
||||||
className={'overflow-hidden rounded-xl border border-neutral-200 bg-white'}
|
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 className={'flex flex-col items-center gap-6 p-10 sm:flex-row sm:gap-0'}>
|
||||||
<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'}>
|
<div className={'flex-1 text-center sm:text-left'}>
|
||||||
<PackageOpen className={'h-3.5 w-3.5'} />
|
<div
|
||||||
Self-hostable
|
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>
|
</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>
|
||||||
<div className={'sm:ml-auto sm:pl-8'}>
|
</motion.div>
|
||||||
<motion.button
|
</div>
|
||||||
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>
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{/* CTA */}
|
{/* CTA */}
|
||||||
<section className={'relative overflow-hidden border-t border-neutral-200 py-20'}>
|
<section className={'relative overflow-hidden border-t border-neutral-900 bg-neutral-900 text-white'}>
|
||||||
<div
|
<div className={'mx-auto max-w-[88rem] px-6 py-32 sm:px-10 sm:py-40'}>
|
||||||
className={
|
<div className={'flex flex-col items-start gap-12 lg:flex-row lg:items-end lg:justify-between'}>
|
||||||
'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.h2
|
||||||
}
|
initial={{opacity: 0, y: 16}}
|
||||||
/>
|
whileInView={{opacity: 1, y: 0}}
|
||||||
<motion.div
|
viewport={{once: true}}
|
||||||
initial={{opacity: 0, y: 20}}
|
transition={{duration: 0.9, ease: [0.22, 1, 0.36, 1]}}
|
||||||
whileInView={{opacity: 1, y: 0}}
|
style={{fontFamily: 'var(--font-display)'}}
|
||||||
viewport={{once: true}}
|
className={'text-[clamp(2.5rem,7vw,6rem)] font-extrabold leading-[0.95] tracking-[-0.035em]'}
|
||||||
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'}
|
|
||||||
>
|
>
|
||||||
<span className={'flex items-center gap-2'}>
|
Start sending in 5 minutes.
|
||||||
Create free account
|
</motion.h2>
|
||||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-1" />
|
|
||||||
</span>
|
<motion.div
|
||||||
</motion.a>
|
initial={{opacity: 0, y: 16}}
|
||||||
<Link
|
whileInView={{opacity: 1, y: 0}}
|
||||||
href={'https://github.com/useplunk/plunk'}
|
viewport={{once: true}}
|
||||||
target={'_blank'}
|
transition={{duration: 0.9, delay: 0.15, ease: [0.22, 1, 0.36, 1]}}
|
||||||
className={'rounded-lg border border-neutral-300 px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-400'}
|
className={'flex max-w-md flex-col gap-6'}
|
||||||
>
|
>
|
||||||
Self-host for free
|
<p className={'text-base text-neutral-300 sm:text-lg'}>
|
||||||
</Link>
|
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>
|
</div>
|
||||||
</motion.div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<Footer />
|
<Footer />
|
||||||
|
|||||||
@@ -1,31 +1,50 @@
|
|||||||
import {Footer, Navbar} from '../../components';
|
import {Footer, Navbar, SectionHeader} from '../../components';
|
||||||
import {motion} from 'framer-motion';
|
import {motion} from 'framer-motion';
|
||||||
import {DASHBOARD_URI} from '../../lib/constants';
|
import {DASHBOARD_URI} from '../../lib/constants';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import {NextSeo} from 'next-seo';
|
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 = [
|
const tools = [
|
||||||
{
|
{
|
||||||
name: 'Markdown to Email',
|
name: 'Markdown to Email',
|
||||||
slug: 'markdown-to-email',
|
slug: 'markdown-to-email',
|
||||||
description: 'Convert rich text to email-safe HTML with our visual editor and instant preview.',
|
description: 'Convert rich text to email-safe HTML with a visual editor and instant preview.',
|
||||||
features: ['Visual Editor', 'Email-Safe HTML', 'Inline CSS', 'Copy to Clipboard'],
|
|
||||||
icon: Code2,
|
icon: Code2,
|
||||||
|
number: '01',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Email Verification',
|
name: 'Email Verification',
|
||||||
slug: 'verify-email',
|
slug: 'verify-email',
|
||||||
description: 'Verify email addresses instantly. Check DNS, MX records, typos, and disposable domains.',
|
description: 'Verify email addresses instantly. Check DNS, MX records, typos, and disposable domains.',
|
||||||
features: ['DNS Validation', 'Typo Detection', 'MX Records', 'Disposable Check'],
|
|
||||||
icon: Search,
|
icon: Search,
|
||||||
|
number: '02',
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
|
||||||
* Free Email Tools index page
|
|
||||||
*/
|
|
||||||
export default function ToolsIndex() {
|
export default function ToolsIndex() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -44,225 +63,261 @@ export default function ToolsIndex() {
|
|||||||
|
|
||||||
<Navbar />
|
<Navbar />
|
||||||
|
|
||||||
<main className={'mx-auto max-w-7xl px-8 sm:px-0'}>
|
<div className={`${display.variable} ${body.variable} ${mono.variable}`}>
|
||||||
{/* Hero Section */}
|
<main className={'text-neutral-800'}>
|
||||||
<section className={'relative py-32 sm:py-48'}>
|
{/* ========== HERO ========== */}
|
||||||
<div
|
<section className={'relative overflow-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%)]'
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<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
|
<div
|
||||||
|
aria-hidden
|
||||||
className={
|
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'}>
|
<div className={'mx-auto max-w-[88rem] px-6 pb-24 pt-20 sm:px-10 sm:pt-28 lg:pb-36'}>
|
||||||
Free tools for
|
<motion.div
|
||||||
<br />
|
initial={{opacity: 0, y: 8}}
|
||||||
email developers
|
animate={{opacity: 1, y: 0}}
|
||||||
</h1>
|
transition={{duration: 0.5, ease: [0.22, 1, 0.36, 1]}}
|
||||||
|
style={{fontFamily: 'var(--font-mono)'}}
|
||||||
<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`}
|
|
||||||
className={
|
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'}>
|
<span className={'font-medium text-neutral-900'}>§ Tools — Plunk</span>
|
||||||
Try Plunk free
|
</motion.div>
|
||||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-1" />
|
|
||||||
</span>
|
<motion.div
|
||||||
</motion.a>
|
initial={{opacity: 0, y: 16}}
|
||||||
<Link
|
animate={{opacity: 1, y: 0}}
|
||||||
href="/guides"
|
transition={{duration: 0.9, ease: [0.22, 1, 0.36, 1]}}
|
||||||
className={
|
className={'mx-auto max-w-5xl text-center'}
|
||||||
'rounded-lg border border-neutral-300 bg-white px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-400'
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
Browse guides
|
<h1
|
||||||
</Link>
|
style={{fontFamily: 'var(--font-display)'}}
|
||||||
</div>
|
className={
|
||||||
</motion.div>
|
'text-[clamp(3rem,9vw,8rem)] font-extrabold leading-[0.92] tracking-[-0.04em] text-neutral-900'
|
||||||
</section>
|
}
|
||||||
|
>
|
||||||
|
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 */}
|
<div className={'mt-10 flex flex-wrap justify-center gap-3'}>
|
||||||
<section className={'py-32'}>
|
<motion.a
|
||||||
<motion.div
|
whileHover={{scale: 1.015}}
|
||||||
initial={{opacity: 0, y: 20}}
|
whileTap={{scale: 0.985}}
|
||||||
whileInView={{opacity: 1, y: 0}}
|
href={`${DASHBOARD_URI}/auth/signup`}
|
||||||
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]}}
|
|
||||||
className={
|
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'}>
|
Try Plunk free
|
||||||
<div
|
<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={
|
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" />
|
Open tool
|
||||||
</div>
|
</span>
|
||||||
<Sparkles className="h-5 w-5 text-neutral-400" />
|
<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>
|
</div>
|
||||||
<h3 className={'text-2xl font-bold text-neutral-900 mb-3'}>{tool.name}</h3>
|
</Link>
|
||||||
<p className={'mb-6 leading-relaxed text-neutral-600'}>{tool.description}</p>
|
</motion.li>
|
||||||
<div className={'space-y-2'}>
|
))}
|
||||||
{tool.features.map(feature => (
|
</ul>
|
||||||
<div key={feature} className={'flex items-center gap-2 text-sm text-neutral-600'}>
|
</section>
|
||||||
<div className={'h-1.5 w-1.5 rounded-full bg-neutral-900'} />
|
|
||||||
<span>{feature}</span>
|
{/* ========== WHY ========== */}
|
||||||
</div>
|
<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>
|
||||||
|
<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>
|
</motion.div>
|
||||||
</Link>
|
))}
|
||||||
);
|
</div>
|
||||||
})}
|
|
||||||
</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>
|
||||||
</section>
|
|
||||||
</main>
|
{/* ========== 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 />
|
<Footer />
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -1,21 +1,40 @@
|
|||||||
import {Footer, Navbar} from '../../components';
|
import {Footer, Navbar, SectionHeader} from '../../components';
|
||||||
import {motion} from 'framer-motion';
|
import {motion} from 'framer-motion';
|
||||||
import {DASHBOARD_URI} from '../../lib/constants';
|
import {DASHBOARD_URI} from '../../lib/constants';
|
||||||
import React, {useMemo, useState} from 'react';
|
import React, {useMemo, useState} from 'react';
|
||||||
import {NextSeo} from 'next-seo';
|
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 {MarkdownEmailEditor} from '../../components/tools/MarkdownEmailEditor';
|
||||||
import {convertToCompleteEmailHtml} from '../../lib/emailHtmlConverter';
|
import {convertToCompleteEmailHtml} from '../../lib/emailHtmlConverter';
|
||||||
import {Button} from '@plunk/ui';
|
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() {
|
export default function MarkdownToEmail() {
|
||||||
const [editorContent, setEditorContent] = useState('<p>Hello!</p><p>Try editing this text...</p>');
|
const [editorContent, setEditorContent] = useState('<p>Hello!</p><p>Try editing this text...</p>');
|
||||||
const [copied, setCopied] = useState(false);
|
const [copied, setCopied] = useState(false);
|
||||||
|
|
||||||
// Convert editor content to complete, ready-to-send email HTML
|
const emailSafeHtml = useMemo(() => convertToCompleteEmailHtml(editorContent), [editorContent]);
|
||||||
const emailSafeHtml = useMemo(() => {
|
|
||||||
return convertToCompleteEmailHtml(editorContent);
|
|
||||||
}, [editorContent]);
|
|
||||||
|
|
||||||
const handleCopy = async () => {
|
const handleCopy = async () => {
|
||||||
await navigator.clipboard.writeText(emailSafeHtml);
|
await navigator.clipboard.writeText(emailSafeHtml);
|
||||||
@@ -40,123 +59,230 @@ export default function MarkdownToEmail() {
|
|||||||
|
|
||||||
<Navbar />
|
<Navbar />
|
||||||
|
|
||||||
<main className={'mx-auto max-w-7xl px-8 sm:px-0'}>
|
<div className={`${display.variable} ${body.variable} ${mono.variable}`}>
|
||||||
{/* Hero Section */}
|
<main className={'text-neutral-800'}>
|
||||||
<section className={'relative py-32 sm:py-48'}>
|
{/* ========== HERO ========== */}
|
||||||
<div
|
<section className={'relative overflow-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%)]'
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<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
|
<div
|
||||||
|
aria-hidden
|
||||||
className={
|
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'}>
|
<div className={'mx-auto max-w-[88rem] px-6 pb-24 pt-20 sm:px-10 sm:pt-28 lg:pb-36'}>
|
||||||
Markdown to Email
|
<motion.div
|
||||||
<br />
|
initial={{opacity: 0, y: 8}}
|
||||||
HTML Converter
|
animate={{opacity: 1, y: 0}}
|
||||||
</h1>
|
transition={{duration: 0.5, ease: [0.22, 1, 0.36, 1]}}
|
||||||
|
style={{fontFamily: 'var(--font-mono)'}}
|
||||||
<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`}
|
|
||||||
className={
|
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'}>
|
<span className={'font-medium text-neutral-900'}>§ T-01 — Tool</span>
|
||||||
Start with Plunk
|
<a
|
||||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-1" />
|
href="/tools"
|
||||||
</span>
|
className={'text-neutral-500 transition hover:text-neutral-900'}
|
||||||
</motion.a>
|
>
|
||||||
|
← 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>
|
</div>
|
||||||
</motion.div>
|
</section>
|
||||||
</section>
|
|
||||||
</main>
|
{/* ========== 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 />
|
<Footer />
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import {Footer, Navbar} from '../../components';
|
import {Footer, Navbar, SectionHeader} from '../../components';
|
||||||
import {motion} from 'framer-motion';
|
import {motion} from 'framer-motion';
|
||||||
import {DASHBOARD_URI} from '../../lib/constants';
|
import {DASHBOARD_URI} from '../../lib/constants';
|
||||||
import React, {useState} from 'react';
|
import React, {useState} from 'react';
|
||||||
@@ -9,6 +9,28 @@ import {verifyEmail} from '../../lib/emailVerification';
|
|||||||
import {EmailVerificationResult} from '../../components/tools/EmailVerificationResult';
|
import {EmailVerificationResult} from '../../components/tools/EmailVerificationResult';
|
||||||
import {Button, Input} from '@plunk/ui';
|
import {Button, Input} from '@plunk/ui';
|
||||||
import {EMAIL_VERIFICATION_FEATURES} from '../../lib/toolsContent';
|
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() {
|
export default function VerifyEmailPage() {
|
||||||
const [email, setEmail] = useState('');
|
const [email, setEmail] = useState('');
|
||||||
@@ -48,184 +70,218 @@ export default function VerifyEmailPage() {
|
|||||||
|
|
||||||
<Navbar />
|
<Navbar />
|
||||||
|
|
||||||
<main className={'mx-auto max-w-7xl px-8 sm:px-0'}>
|
<div className={`${display.variable} ${body.variable} ${mono.variable}`}>
|
||||||
{/* Hero Section */}
|
<main className={'text-neutral-800'}>
|
||||||
<section className={'relative py-32 sm:py-48'}>
|
{/* ========== HERO ========== */}
|
||||||
<div
|
<section className={'relative overflow-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%)]'
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<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
|
<div
|
||||||
|
aria-hidden
|
||||||
className={
|
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'}>
|
<div className={'mx-auto max-w-[88rem] px-6 pb-24 pt-20 sm:px-10 sm:pt-28 lg:pb-36'}>
|
||||||
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="[email protected]"
|
|
||||||
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 && (
|
|
||||||
<motion.div
|
<motion.div
|
||||||
initial={{opacity: 0, y: 20}}
|
initial={{opacity: 0, y: 8}}
|
||||||
animate={{opacity: 1, y: 0}}
|
animate={{opacity: 1, y: 0}}
|
||||||
transition={{duration: 0.5}}
|
transition={{duration: 0.5, ease: [0.22, 1, 0.36, 1]}}
|
||||||
className="mt-8"
|
style={{fontFamily: 'var(--font-mono)'}}
|
||||||
>
|
|
||||||
<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`}
|
|
||||||
className={
|
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'}>
|
<span className={'font-medium text-neutral-900'}>§ T-02 — Tool</span>
|
||||||
Start with Plunk
|
<a href="/tools" className={'text-neutral-500 transition hover:text-neutral-900'}>
|
||||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-1" />
|
← All tools
|
||||||
</span>
|
</a>
|
||||||
</motion.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>
|
</div>
|
||||||
</motion.div>
|
</section>
|
||||||
</section>
|
|
||||||
</main>
|
{/* ========== 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="[email protected]"
|
||||||
|
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 />
|
<Footer />
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import {DASHBOARD_URI, WIKI_URI} from '../../lib/constants';
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import {NextSeo} from 'next-seo';
|
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 {ComparisonRow} from '../../components/ComparisonTable';
|
||||||
import type {FAQ} from '../../components/FAQSection';
|
import type {FAQ} from '../../components/FAQSection';
|
||||||
|
|
||||||
@@ -49,9 +49,6 @@ const faqs: FAQ[] = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
|
||||||
* Plunk vs ActiveCampaign comparison page
|
|
||||||
*/
|
|
||||||
export default function ActiveCampaignComparison() {
|
export default function ActiveCampaignComparison() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -70,367 +67,132 @@ export default function ActiveCampaignComparison() {
|
|||||||
|
|
||||||
<Navbar />
|
<Navbar />
|
||||||
|
|
||||||
<main className={'mx-auto max-w-7xl px-8 sm:px-0'}>
|
<main className={'text-neutral-800'}>
|
||||||
{/* 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
|
{/* Hero */}
|
||||||
initial={{opacity: 0, y: 20}}
|
<section className={'relative overflow-hidden'}>
|
||||||
animate={{opacity: 1, y: 0}}
|
<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%)]'} />
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
<div className={'mx-auto max-w-[88rem] px-6 pb-20 pt-20 sm:px-10 sm:pt-28 sm:pb-28'}>
|
||||||
className={'mx-auto max-w-4xl text-center'}
|
<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'}>
|
||||||
<div
|
Plunk vs ActiveCampaign
|
||||||
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>
|
|
||||||
</div>
|
</div>
|
||||||
<h3 className={'mt-6 text-2xl font-bold text-neutral-900'}>Simple pay-as-you-go</h3>
|
<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'}>
|
||||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
Open-source alternative
|
||||||
Only pay for emails sent. All features included, no tier gating, no forced upgrades.
|
<br />
|
||||||
</p>
|
for ActiveCampaign
|
||||||
<div className={'mt-6 text-4xl font-bold text-neutral-900'}>Pay-as-you-go</div>
|
</h1>
|
||||||
<div className={'mt-8 space-y-3'}>
|
<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={'flex items-center gap-3 text-sm text-neutral-600'}>
|
<div className={'mt-10 flex flex-wrap gap-3'}>
|
||||||
<div className={'h-5 w-5 rounded-full bg-neutral-900 flex items-center justify-center'}>
|
<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={'h-1.5 w-1.5 rounded-full bg-white'} />
|
Get started free <ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-0.5" />
|
||||||
</div>
|
</motion.a>
|
||||||
<span>All automation features included</span>
|
<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'}>
|
||||||
</div>
|
View documentation
|
||||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
</Link>
|
||||||
<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>
|
|
||||||
</div>
|
</div>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{/* Key Advantages */}
|
{/* Pricing comparison */}
|
||||||
<section className={'py-32'}>
|
<section className={'border-t border-neutral-200'}>
|
||||||
<motion.div
|
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||||
initial={{opacity: 0, y: 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'}>
|
||||||
whileInView={{opacity: 1, y: 0}}
|
<h2 style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}>
|
||||||
viewport={{once: true}}
|
Enterprise Features Without Enterprise Prices
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
</h2>
|
||||||
className={'mb-20 text-center'}
|
<p className={'mt-4 text-lg text-neutral-600'}>Email automation that doesn't break the bank</p>
|
||||||
>
|
|
||||||
<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>
|
|
||||||
</motion.div>
|
</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>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{/* Feature Comparison */}
|
{/* Key advantages */}
|
||||||
<section className={'py-32'}>
|
<section className={'border-t border-neutral-200 bg-neutral-50/60'}>
|
||||||
<motion.div
|
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||||
initial={{opacity: 0, y: 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'}>
|
||||||
whileInView={{opacity: 1, y: 0}}
|
<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>
|
||||||
viewport={{once: true}}
|
<p className={'mt-4 text-lg text-neutral-600'}>Powerful email workflows without the enterprise overhead</p>
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
</motion.div>
|
||||||
className={'mb-16 text-center'}
|
<div className={'grid gap-px bg-neutral-200 sm:grid-cols-2 lg:grid-cols-3'}>
|
||||||
>
|
{[
|
||||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>Feature Comparison</h2>
|
{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.'},
|
||||||
</motion.div>
|
{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>
|
</section>
|
||||||
|
|
||||||
{/* FAQ */}
|
{/* FAQ */}
|
||||||
<FAQSection faqs={faqs} schemaId="faq-schema-activecampaign" />
|
<FAQSection faqs={faqs} schemaId="faq-schema-activecampaign" />
|
||||||
|
|
||||||
{/* CTA */}
|
{/* CTA */}
|
||||||
<section className={'relative overflow-hidden border-t border-neutral-200 py-32'}>
|
<section className={'relative overflow-hidden border-t border-neutral-900 bg-neutral-900 text-white'}>
|
||||||
<div
|
<div className={'mx-auto max-w-[88rem] px-6 py-32 sm:px-10 sm:py-40'}>
|
||||||
className={
|
<div className={'flex flex-col items-start gap-12 lg:flex-row lg:items-end lg:justify-between'}>
|
||||||
'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.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
|
<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'}>
|
||||||
initial={{opacity: 0, y: 20}}
|
<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>
|
||||||
whileInView={{opacity: 1, y: 0}}
|
<div className={'flex flex-wrap gap-3'}>
|
||||||
viewport={{once: true}}
|
<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'}>
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
Get started free <ArrowRight className="h-4 w-4" />
|
||||||
className={'mx-auto max-w-3xl text-center'}
|
</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'}>
|
||||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>
|
View pricing
|
||||||
Get email automation without the bloat
|
</Link>
|
||||||
</h2>
|
</div>
|
||||||
<p className={'mt-6 text-lg text-neutral-600'}>
|
</motion.div>
|
||||||
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>
|
|
||||||
</div>
|
</div>
|
||||||
</motion.div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</main>
|
|
||||||
|
|
||||||
|
</main>
|
||||||
<Footer />
|
<Footer />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
+105
-342
@@ -4,7 +4,7 @@ import {DASHBOARD_URI, WIKI_URI} from '../../lib/constants';
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import {NextSeo} from 'next-seo';
|
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 {ComparisonRow} from '../../components/ComparisonTable';
|
||||||
import type {FAQ} from '../../components/FAQSection';
|
import type {FAQ} from '../../components/FAQSection';
|
||||||
|
|
||||||
@@ -49,9 +49,6 @@ const faqs: FAQ[] = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
|
||||||
* Plunk vs Bento comparison page
|
|
||||||
*/
|
|
||||||
export default function BentoComparison() {
|
export default function BentoComparison() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -70,365 +67,131 @@ export default function BentoComparison() {
|
|||||||
|
|
||||||
<Navbar />
|
<Navbar />
|
||||||
|
|
||||||
<main className={'mx-auto max-w-7xl px-8 sm:px-0'}>
|
<main className={'text-neutral-800'}>
|
||||||
{/* 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
|
{/* Hero */}
|
||||||
initial={{opacity: 0, y: 20}}
|
<section className={'relative overflow-hidden'}>
|
||||||
animate={{opacity: 1, y: 0}}
|
<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%)]'} />
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
<div className={'mx-auto max-w-[88rem] px-6 pb-20 pt-20 sm:px-10 sm:pt-28 sm:pb-28'}>
|
||||||
className={'mx-auto max-w-4xl text-center'}
|
<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'}>
|
||||||
<div
|
Plunk vs Bento
|
||||||
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>
|
|
||||||
</div>
|
</div>
|
||||||
<h3 className={'mt-6 text-2xl font-bold text-neutral-900'}>Pay per email sent</h3>
|
<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'}>
|
||||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
Open-source alternative
|
||||||
Pay-as-you-go for email only. No CRM or chat features you don't need. Simple, transparent pricing.
|
<br />
|
||||||
</p>
|
for Bento
|
||||||
<div className={'mt-6 text-4xl font-bold text-neutral-900'}>Pay-as-you-go</div>
|
</h1>
|
||||||
<div className={'mt-8 space-y-3'}>
|
<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={'flex items-center gap-3 text-sm text-neutral-600'}>
|
<div className={'mt-10 flex flex-wrap gap-3'}>
|
||||||
<div className={'h-5 w-5 rounded-full bg-neutral-900 flex items-center justify-center'}>
|
<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={'h-1.5 w-1.5 rounded-full bg-white'} />
|
Get started free <ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-0.5" />
|
||||||
</div>
|
</motion.a>
|
||||||
<span>Only pay for emails sent</span>
|
<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'}>
|
||||||
</div>
|
View documentation
|
||||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
</Link>
|
||||||
<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>
|
|
||||||
</div>
|
</div>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{/* Key Advantages */}
|
{/* Pricing comparison */}
|
||||||
<section className={'py-32'}>
|
<section className={'border-t border-neutral-200'}>
|
||||||
<motion.div
|
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||||
initial={{opacity: 0, y: 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'}>
|
||||||
whileInView={{opacity: 1, y: 0}}
|
<h2 style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}>
|
||||||
viewport={{once: true}}
|
Focused Email vs All-in-One Complexity
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
</h2>
|
||||||
className={'mb-20 text-center'}
|
<p className={'mt-4 text-lg text-neutral-600'}>Pay for what you use, not what you don't need</p>
|
||||||
>
|
|
||||||
<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>
|
|
||||||
</motion.div>
|
</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>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{/* Feature Comparison */}
|
{/* Key advantages */}
|
||||||
<section className={'py-32'}>
|
<section className={'border-t border-neutral-200 bg-neutral-50/60'}>
|
||||||
<motion.div
|
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||||
initial={{opacity: 0, y: 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'}>
|
||||||
whileInView={{opacity: 1, y: 0}}
|
<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>
|
||||||
viewport={{once: true}}
|
<p className={'mt-4 text-lg text-neutral-600'}>Everything you need for email, nothing you don't</p>
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
</motion.div>
|
||||||
className={'mb-16 text-center'}
|
<div className={'grid gap-px bg-neutral-200 sm:grid-cols-2 lg:grid-cols-3'}>
|
||||||
>
|
{[
|
||||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>Feature Comparison</h2>
|
{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.'},
|
||||||
</motion.div>
|
{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>
|
</section>
|
||||||
|
|
||||||
{/* FAQ */}
|
{/* FAQ */}
|
||||||
<FAQSection faqs={faqs} schemaId="faq-schema-bento" />
|
<FAQSection faqs={faqs} schemaId="faq-schema-bento" />
|
||||||
|
|
||||||
{/* CTA */}
|
{/* CTA */}
|
||||||
<section className={'relative overflow-hidden border-t border-neutral-200 py-32'}>
|
<section className={'relative overflow-hidden border-t border-neutral-900 bg-neutral-900 text-white'}>
|
||||||
<div
|
<div className={'mx-auto max-w-[88rem] px-6 py-32 sm:px-10 sm:py-40'}>
|
||||||
className={
|
<div className={'flex flex-col items-start gap-12 lg:flex-row lg:items-end lg:justify-between'}>
|
||||||
'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.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
|
<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'}>
|
||||||
initial={{opacity: 0, y: 20}}
|
<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>
|
||||||
whileInView={{opacity: 1, y: 0}}
|
<div className={'flex flex-wrap gap-3'}>
|
||||||
viewport={{once: true}}
|
<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'}>
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
Get started free <ArrowRight className="h-4 w-4" />
|
||||||
className={'mx-auto max-w-3xl text-center'}
|
</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'}>
|
||||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>Get focused email automation</h2>
|
View pricing
|
||||||
<p className={'mt-6 text-lg text-neutral-600'}>
|
</Link>
|
||||||
Join developers choosing focused email solutions over all-in-one complexity. Start free, no credit card
|
</div>
|
||||||
required.
|
</motion.div>
|
||||||
</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>
|
|
||||||
</div>
|
</div>
|
||||||
</motion.div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</main>
|
|
||||||
|
|
||||||
|
</main>
|
||||||
<Footer />
|
<Footer />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
+127
-338
@@ -4,7 +4,7 @@ import {DASHBOARD_URI, WIKI_URI} from '../../lib/constants';
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import {NextSeo} from 'next-seo';
|
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 {ComparisonRow} from '../../components/ComparisonTable';
|
||||||
import type {FAQ} from '../../components/FAQSection';
|
import type {FAQ} from '../../components/FAQSection';
|
||||||
|
|
||||||
@@ -69,364 +69,153 @@ export default function BrevoComparison() {
|
|||||||
|
|
||||||
<Navbar />
|
<Navbar />
|
||||||
|
|
||||||
<main className={'mx-auto max-w-7xl px-8 sm:px-0'}>
|
<main className={'text-neutral-800'}>
|
||||||
{/* 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
|
{/* Hero */}
|
||||||
initial={{opacity: 0, y: 20}}
|
<section className={'relative overflow-hidden'}>
|
||||||
animate={{opacity: 1, y: 0}}
|
<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%)]'} />
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
<div className={'mx-auto max-w-[88rem] px-6 pb-20 pt-20 sm:px-10 sm:pt-28 sm:pb-28'}>
|
||||||
className={'mx-auto max-w-4xl text-center'}
|
<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'}>
|
||||||
<div
|
Plunk vs Brevo
|
||||||
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>
|
|
||||||
</div>
|
</div>
|
||||||
<h3 className={'mt-6 text-2xl font-bold text-neutral-900'}>Pay per email</h3>
|
<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'}>
|
||||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
Open-source alternative
|
||||||
Simple pay-as-you-go pricing. Unlimited contacts, pay only for emails sent.
|
<br />
|
||||||
</p>
|
for Brevo
|
||||||
<div className={'mt-6 text-4xl font-bold text-neutral-900'}>$0.001/email</div>
|
</h1>
|
||||||
<div className={'mt-8 space-y-3'}>
|
<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={'flex items-center gap-3 text-sm text-neutral-600'}>
|
<div className={'mt-10 flex flex-wrap gap-3'}>
|
||||||
<div className={'h-5 w-5 rounded-full bg-neutral-900 flex items-center justify-center'}>
|
<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={'h-1.5 w-1.5 rounded-full bg-white'} />
|
Get started free <ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-0.5" />
|
||||||
</div>
|
</motion.a>
|
||||||
<span>Unlimited contacts included</span>
|
<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'}>
|
||||||
</div>
|
View documentation
|
||||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
</Link>
|
||||||
<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>
|
|
||||||
</div>
|
</div>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{/* Key Advantages */}
|
{/* Pricing comparison */}
|
||||||
<section className={'py-32'}>
|
<section className={'border-t border-neutral-200'}>
|
||||||
<motion.div
|
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||||
initial={{opacity: 0, y: 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'}>
|
||||||
whileInView={{opacity: 1, y: 0}}
|
<h2 style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}>
|
||||||
viewport={{once: true}}
|
Pricing That Scales With You
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
</h2>
|
||||||
className={'mb-20 text-center'}
|
<p className={'mt-4 text-lg text-neutral-600'}>Pay for emails sent, not contacts stored</p>
|
||||||
>
|
|
||||||
<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>
|
|
||||||
</motion.div>
|
</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>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{/* Feature Comparison */}
|
{/* Key advantages */}
|
||||||
<section className={'py-32'}>
|
<section className={'border-t border-neutral-200 bg-neutral-50/60'}>
|
||||||
<motion.div
|
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||||
initial={{opacity: 0, y: 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'}>
|
||||||
whileInView={{opacity: 1, y: 0}}
|
<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>
|
||||||
viewport={{once: true}}
|
<p className={'mt-4 text-lg text-neutral-600'}>Focus on email, not feature overload</p>
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
</motion.div>
|
||||||
className={'mb-16 text-center'}
|
<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'}>
|
||||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>Feature-by-Feature Comparison</h2>
|
<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>
|
||||||
<p className={'mt-4 text-lg text-neutral-600'}>See exactly what you get with each platform</p>
|
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>Simpler Pricing</h3>
|
||||||
</motion.div>
|
<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>
|
</section>
|
||||||
|
|
||||||
{/* FAQ */}
|
{/* FAQ */}
|
||||||
<FAQSection faqs={faqs} schemaId="faq-schema-brevo" />
|
<FAQSection faqs={faqs} schemaId="faq-schema-brevo" />
|
||||||
|
|
||||||
{/* CTA */}
|
{/* CTA */}
|
||||||
<section className={'relative overflow-hidden border-t border-neutral-200 py-32'}>
|
<section className={'relative overflow-hidden border-t border-neutral-900 bg-neutral-900 text-white'}>
|
||||||
<div
|
<div className={'mx-auto max-w-[88rem] px-6 py-32 sm:px-10 sm:py-40'}>
|
||||||
className={
|
<div className={'flex flex-col items-start gap-12 lg:flex-row lg:items-end lg:justify-between'}>
|
||||||
'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.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
|
<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'}>
|
||||||
initial={{opacity: 0, y: 20}}
|
<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>
|
||||||
whileInView={{opacity: 1, y: 0}}
|
<div className={'flex flex-wrap gap-3'}>
|
||||||
viewport={{once: true}}
|
<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'}>
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
Get started free <ArrowRight className="h-4 w-4" />
|
||||||
className={'mx-auto max-w-3xl text-center'}
|
</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'}>
|
||||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>Make the switch to simplicity</h2>
|
View pricing
|
||||||
<p className={'mt-6 text-lg text-neutral-600'}>
|
</Link>
|
||||||
Join developers choosing focused tools over bloated marketing suites. Start free, no credit card required.
|
</div>
|
||||||
</p>
|
</motion.div>
|
||||||
<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>
|
|
||||||
</div>
|
</div>
|
||||||
</motion.div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</main>
|
|
||||||
|
|
||||||
|
</main>
|
||||||
<Footer />
|
<Footer />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import {DASHBOARD_URI, WIKI_URI} from '../../lib/constants';
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import {NextSeo} from 'next-seo';
|
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 {ComparisonRow} from '../../components/ComparisonTable';
|
||||||
import type {FAQ} from '../../components/FAQSection';
|
import type {FAQ} from '../../components/FAQSection';
|
||||||
|
|
||||||
@@ -70,365 +70,152 @@ export default function ConvertkitComparison() {
|
|||||||
|
|
||||||
<Navbar />
|
<Navbar />
|
||||||
|
|
||||||
<main className={'mx-auto max-w-7xl px-8 sm:px-0'}>
|
<main className={'text-neutral-800'}>
|
||||||
{/* 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
|
{/* Hero */}
|
||||||
initial={{opacity: 0, y: 20}}
|
<section className={'relative overflow-hidden'}>
|
||||||
animate={{opacity: 1, y: 0}}
|
<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%)]'} />
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
<div className={'mx-auto max-w-[88rem] px-6 pb-20 pt-20 sm:px-10 sm:pt-28 sm:pb-28'}>
|
||||||
className={'mx-auto max-w-4xl text-center'}
|
<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'}>
|
||||||
<div
|
Plunk vs ConvertKit
|
||||||
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>
|
|
||||||
</div>
|
</div>
|
||||||
<h3 className={'mt-6 text-2xl font-bold text-neutral-900'}>Pay per email sent</h3>
|
<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'}>
|
||||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
Open-source alternative
|
||||||
Pay-as-you-go pricing. Only pay for emails you send, not for subscribers you store.
|
<br />
|
||||||
</p>
|
for ConvertKit
|
||||||
<div className={'mt-6 text-4xl font-bold text-neutral-900'}>Pay-as-you-go</div>
|
</h1>
|
||||||
<div className={'mt-8 space-y-3'}>
|
<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={'flex items-center gap-3 text-sm text-neutral-600'}>
|
<div className={'mt-10 flex flex-wrap gap-3'}>
|
||||||
<div className={'h-5 w-5 rounded-full bg-neutral-900 flex items-center justify-center'}>
|
<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={'h-1.5 w-1.5 rounded-full bg-white'} />
|
Get started free <ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-0.5" />
|
||||||
</div>
|
</motion.a>
|
||||||
<span>Unlimited subscribers at no cost</span>
|
<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'}>
|
||||||
</div>
|
View documentation
|
||||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
</Link>
|
||||||
<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>
|
|
||||||
</div>
|
</div>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{/* Key Advantages */}
|
{/* Pricing comparison */}
|
||||||
<section className={'py-32'}>
|
<section className={'border-t border-neutral-200'}>
|
||||||
<motion.div
|
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||||
initial={{opacity: 0, y: 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'}>
|
||||||
whileInView={{opacity: 1, y: 0}}
|
<h2 style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}>
|
||||||
viewport={{once: true}}
|
Pay for Emails, Not Subscribers
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
</h2>
|
||||||
className={'mb-20 text-center'}
|
<p className={'mt-4 text-lg text-neutral-600'}>Pricing that grows with usage, not list size</p>
|
||||||
>
|
|
||||||
<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>
|
|
||||||
</motion.div>
|
</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>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{/* Feature Comparison */}
|
{/* Key advantages */}
|
||||||
<section className={'py-32'}>
|
<section className={'border-t border-neutral-200 bg-neutral-50/60'}>
|
||||||
<motion.div
|
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||||
initial={{opacity: 0, y: 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'}>
|
||||||
whileInView={{opacity: 1, y: 0}}
|
<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>
|
||||||
viewport={{once: true}}
|
</motion.div>
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
<div className={'grid gap-px bg-neutral-200 sm:grid-cols-2 lg:grid-cols-3'}>
|
||||||
className={'mb-16 text-center'}
|
<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>
|
||||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>Feature Comparison</h2>
|
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>Developer-First API</h3>
|
||||||
</motion.div>
|
<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>
|
</section>
|
||||||
|
|
||||||
{/* FAQ */}
|
{/* FAQ */}
|
||||||
<FAQSection faqs={faqs} schemaId="faq-schema-convertkit" />
|
<FAQSection faqs={faqs} schemaId="faq-schema-convertkit" />
|
||||||
|
|
||||||
{/* CTA */}
|
{/* CTA */}
|
||||||
<section className={'relative overflow-hidden border-t border-neutral-200 py-32'}>
|
<section className={'relative overflow-hidden border-t border-neutral-900 bg-neutral-900 text-white'}>
|
||||||
<div
|
<div className={'mx-auto max-w-[88rem] px-6 py-32 sm:px-10 sm:py-40'}>
|
||||||
className={
|
<div className={'flex flex-col items-start gap-12 lg:flex-row lg:items-end lg:justify-between'}>
|
||||||
'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.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
|
<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'}>
|
||||||
initial={{opacity: 0, y: 20}}
|
<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>
|
||||||
whileInView={{opacity: 1, y: 0}}
|
<div className={'flex flex-wrap gap-3'}>
|
||||||
viewport={{once: true}}
|
<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'}>
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
Get started free <ArrowRight className="h-4 w-4" />
|
||||||
className={'mx-auto max-w-3xl text-center'}
|
</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'}>
|
||||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>
|
View pricing
|
||||||
Ready for a developer-first email platform?
|
</Link>
|
||||||
</h2>
|
</div>
|
||||||
<p className={'mt-6 text-lg text-neutral-600'}>
|
</motion.div>
|
||||||
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>
|
|
||||||
</div>
|
</div>
|
||||||
</motion.div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</main>
|
|
||||||
|
|
||||||
|
</main>
|
||||||
<Footer />
|
<Footer />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import {DASHBOARD_URI, WIKI_URI} from '../../lib/constants';
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import {NextSeo} from 'next-seo';
|
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 {ComparisonRow} from '../../components/ComparisonTable';
|
||||||
import type {FAQ} from '../../components/FAQSection';
|
import type {FAQ} from '../../components/FAQSection';
|
||||||
|
|
||||||
@@ -65,311 +65,124 @@ export default function CustomerioComparison() {
|
|||||||
|
|
||||||
<Navbar />
|
<Navbar />
|
||||||
|
|
||||||
<main className={'mx-auto max-w-7xl px-8 sm:px-0'}>
|
<main className={'text-neutral-800'}>
|
||||||
{/* 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
|
{/* Hero */}
|
||||||
initial={{opacity: 0, y: 20}}
|
<section className={'relative overflow-hidden'}>
|
||||||
animate={{opacity: 1, y: 0}}
|
<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%)]'} />
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
<div className={'mx-auto max-w-[88rem] px-6 pb-20 pt-20 sm:px-10 sm:pt-28 sm:pb-28'}>
|
||||||
className={'mx-auto max-w-4xl text-center'}
|
<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'}>
|
||||||
<div
|
Plunk vs Customer.io
|
||||||
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>
|
|
||||||
</div>
|
</div>
|
||||||
<h3 className={'mt-6 text-2xl font-bold text-neutral-900'}>Pay per email sent</h3>
|
<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'}>
|
||||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
Open-source alternative
|
||||||
Pay-as-you-go pricing. Only pay for emails you actually send.
|
<br />
|
||||||
</p>
|
for Customer.io
|
||||||
<div className={'mt-6 text-4xl font-bold text-neutral-900'}>Pay-as-you-go</div>
|
</h1>
|
||||||
<div className={'mt-8 space-y-3'}>
|
<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={'flex items-center gap-3 text-sm text-neutral-600'}>
|
<div className={'mt-10 flex flex-wrap gap-3'}>
|
||||||
<div className={'h-5 w-5 rounded-full bg-neutral-900 flex items-center justify-center'}>
|
<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={'h-1.5 w-1.5 rounded-full bg-white'} />
|
Try Plunk free <ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-0.5" />
|
||||||
</div>
|
</motion.a>
|
||||||
<span>Only pay for emails you actually send</span>
|
<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'}>
|
||||||
</div>
|
View documentation
|
||||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
</Link>
|
||||||
<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>
|
|
||||||
</div>
|
</div>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{/* Feature Comparison */}
|
{/* Pricing comparison */}
|
||||||
<section className={'py-32'}>
|
<section className={'border-t border-neutral-200'}>
|
||||||
<motion.div
|
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||||
initial={{opacity: 0, y: 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'}>
|
||||||
whileInView={{opacity: 1, y: 0}}
|
<h2 style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}>
|
||||||
viewport={{once: true}}
|
Simple Pricing That Scales
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
</h2>
|
||||||
className={'mb-16 text-center'}
|
<p className={'mt-4 text-lg text-neutral-600'}>Transparent pay-as-you-go vs complex enterprise tiers</p>
|
||||||
>
|
</motion.div>
|
||||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>Feature-by-Feature</h2>
|
<div className={'grid gap-4 lg:grid-cols-2'}>
|
||||||
</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-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>
|
||||||
<ComparisonTable competitorName="Customer.io" rows={comparisonData} />
|
<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>
|
</section>
|
||||||
|
|
||||||
{/* Key Advantages */}
|
{/* Key advantages */}
|
||||||
<section className={'py-32'}>
|
<section className={'border-t border-neutral-200 bg-neutral-50/60'}>
|
||||||
<motion.div
|
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||||
initial={{opacity: 0, y: 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'}>
|
||||||
whileInView={{opacity: 1, y: 0}}
|
<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>
|
||||||
viewport={{once: true}}
|
<p className={'mt-4 text-lg text-neutral-600'}>Why developers choose Plunk</p>
|
||||||
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>
|
|
||||||
</motion.div>
|
</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
|
<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'}>
|
||||||
initial={{opacity: 0, y: 20}}
|
<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>
|
||||||
whileInView={{opacity: 1, y: 0}}
|
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>Transparent Pricing</h3>
|
||||||
viewport={{once: true}}
|
<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>
|
||||||
transition={{duration: 0.5, delay: 0.2, ease: [0.22, 1, 0.36, 1]}}
|
</motion.div>
|
||||||
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
|
<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'}>
|
||||||
initial={{opacity: 0, y: 20}}
|
<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>
|
||||||
whileInView={{opacity: 1, y: 0}}
|
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>Open Source</h3>
|
||||||
viewport={{once: true}}
|
<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>
|
||||||
transition={{duration: 0.5, delay: 0.3, ease: [0.22, 1, 0.36, 1]}}
|
</motion.div>
|
||||||
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
|
<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'}>
|
||||||
initial={{opacity: 0, y: 20}}
|
<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>
|
||||||
whileInView={{opacity: 1, y: 0}}
|
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>Quick Setup</h3>
|
||||||
viewport={{once: true}}
|
<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>
|
||||||
transition={{duration: 0.5, delay: 0.4, ease: [0.22, 1, 0.36, 1]}}
|
</motion.div>
|
||||||
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
|
<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'}>
|
||||||
initial={{opacity: 0, y: 20}}
|
<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>
|
||||||
whileInView={{opacity: 1, y: 0}}
|
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>Self-Hosting Option</h3>
|
||||||
viewport={{once: true}}
|
<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>
|
||||||
transition={{duration: 0.5, delay: 0.5, ease: [0.22, 1, 0.36, 1]}}
|
</motion.div>
|
||||||
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
|
<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'}>
|
||||||
initial={{opacity: 0, y: 20}}
|
<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>
|
||||||
whileInView={{opacity: 1, y: 0}}
|
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>Simplicity at Scale</h3>
|
||||||
viewport={{once: true}}
|
<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>
|
||||||
transition={{duration: 0.5, delay: 0.6, ease: [0.22, 1, 0.36, 1]}}
|
</motion.div>
|
||||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
</div>
|
||||||
>
|
</div>
|
||||||
<div
|
</section>
|
||||||
className={
|
|
||||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
{/* Feature comparison table */}
|
||||||
}
|
<section className={'border-t border-neutral-200'}>
|
||||||
>
|
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||||
<BarChart3 className="h-5 w-5" />
|
<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'}>
|
||||||
</div>
|
<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>
|
||||||
<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>
|
</motion.div>
|
||||||
|
<ComparisonTable competitorName="Customer.io" rows={comparisonData} />
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
@@ -377,51 +190,28 @@ export default function CustomerioComparison() {
|
|||||||
<FAQSection faqs={faqs} schemaId="faq-schema-customerio" />
|
<FAQSection faqs={faqs} schemaId="faq-schema-customerio" />
|
||||||
|
|
||||||
{/* CTA */}
|
{/* CTA */}
|
||||||
<section className={'relative overflow-hidden border-t border-neutral-200 py-32'}>
|
<section className={'relative overflow-hidden border-t border-neutral-900 bg-neutral-900 text-white'}>
|
||||||
<div
|
<div className={'mx-auto max-w-[88rem] px-6 py-32 sm:px-10 sm:py-40'}>
|
||||||
className={
|
<div className={'flex flex-col items-start gap-12 lg:flex-row lg:items-end lg:justify-between'}>
|
||||||
'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.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
|
<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'}>
|
||||||
initial={{opacity: 0, y: 20}}
|
<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>
|
||||||
whileInView={{opacity: 1, y: 0}}
|
<div className={'flex flex-wrap gap-3'}>
|
||||||
viewport={{once: true}}
|
<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'}>
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
Get started free <ArrowRight className="h-4 w-4" />
|
||||||
className={'mx-auto max-w-3xl text-center'}
|
</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'}>
|
||||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>Try Plunk free</h2>
|
View pricing
|
||||||
<p className={'mt-6 text-lg text-neutral-600'}>
|
</Link>
|
||||||
1,000 emails/month free. No credit card required. Developer-friendly from day one.
|
</div>
|
||||||
</p>
|
</motion.div>
|
||||||
<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>
|
|
||||||
</div>
|
</div>
|
||||||
</motion.div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</main>
|
|
||||||
|
|
||||||
|
</main>
|
||||||
<Footer />
|
<Footer />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
+189
-187
@@ -87,9 +87,6 @@ const competitors = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
|
||||||
* Plunk vs Competitors index page
|
|
||||||
*/
|
|
||||||
export default function CompetitorsIndex() {
|
export default function CompetitorsIndex() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -108,220 +105,225 @@ export default function CompetitorsIndex() {
|
|||||||
|
|
||||||
<Navbar />
|
<Navbar />
|
||||||
|
|
||||||
<main className={'mx-auto max-w-7xl px-8 sm:px-0'}>
|
<main className={'text-neutral-800'}>
|
||||||
{/* Hero Section */}
|
|
||||||
<section className={'relative py-32 sm:py-48'}>
|
{/* Hero */}
|
||||||
|
<section className={'relative overflow-hidden'}>
|
||||||
<div
|
<div
|
||||||
className={
|
aria-hidden
|
||||||
'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%)]'
|
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
|
<motion.div
|
||||||
initial={{opacity: 0, y: 20}}
|
initial={{opacity: 0, y: 16}}
|
||||||
animate={{opacity: 1, y: 0}}
|
animate={{opacity: 1, y: 0}}
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
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'}>Email Platform Comparisons</span>
|
<div style={{fontFamily: 'var(--font-mono)'}} className={'mb-6 text-[11px] uppercase tracking-[0.18em] text-neutral-500'}>
|
||||||
</div>
|
Comparisons
|
||||||
|
</div>
|
||||||
<h1 className={'text-6xl font-bold tracking-tight text-neutral-900 sm:text-7xl lg:text-8xl text-balance'}>
|
<h1
|
||||||
Plunk vs the
|
style={{fontFamily: 'var(--font-display)'}}
|
||||||
<br />
|
className={'text-[clamp(2.75rem,7vw,6.5rem)] font-extrabold leading-[0.92] tracking-[-0.04em] text-neutral-900'}
|
||||||
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'
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
<span className={'flex items-center gap-2'}>
|
Plunk vs the
|
||||||
Get started free
|
<br />
|
||||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-1" />
|
competition.
|
||||||
</span>
|
</h1>
|
||||||
</motion.a>
|
<p className={'mt-6 max-w-2xl text-xl text-neutral-600'}>
|
||||||
<Link
|
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.
|
||||||
href={WIKI_URI}
|
</p>
|
||||||
target={'_blank'}
|
<div className={'mt-10 flex flex-wrap gap-3'}>
|
||||||
className={
|
<motion.a
|
||||||
'rounded-lg border border-neutral-300 bg-white px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-400'
|
whileHover={{scale: 1.015}}
|
||||||
}
|
whileTap={{scale: 0.985}}
|
||||||
>
|
href={`${DASHBOARD_URI}/auth/signup`}
|
||||||
View documentation
|
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>
|
|
||||||
</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'
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
<div className={'mb-4 flex items-center justify-between'}>
|
Get started free
|
||||||
<h3 className={'text-xl font-bold text-neutral-900'}>{competitor.name}</h3>
|
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-0.5" />
|
||||||
</div>
|
</motion.a>
|
||||||
<p className={'mb-6 leading-relaxed text-neutral-600'}>{competitor.description}</p>
|
<Link
|
||||||
<div className={'mb-6 space-y-2'}>
|
href={WIKI_URI}
|
||||||
{competitor.features.map(feature => (
|
target={'_blank'}
|
||||||
<div key={feature} className={'flex items-center gap-2 text-sm text-neutral-600'}>
|
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'}
|
||||||
<div className={'h-1.5 w-1.5 rounded-full bg-neutral-900'} />
|
>
|
||||||
<span>{feature}</span>
|
View documentation
|
||||||
</div>
|
</Link>
|
||||||
))}
|
</div>
|
||||||
</div>
|
</motion.div>
|
||||||
</motion.div>
|
|
||||||
</Link>
|
|
||||||
))}
|
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{/* Why Choose Plunk */}
|
{/* Competitors grid */}
|
||||||
<section className={'py-32'}>
|
<section className={'border-t border-neutral-200'}>
|
||||||
<motion.div
|
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||||
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'}>
|
|
||||||
<motion.div
|
<motion.div
|
||||||
initial={{opacity: 0, y: 20}}
|
initial={{opacity: 0, y: 20}}
|
||||||
whileInView={{opacity: 1, y: 0}}
|
whileInView={{opacity: 1, y: 0}}
|
||||||
viewport={{once: true}}
|
viewport={{once: true}}
|
||||||
transition={{duration: 0.5, delay: 0.1, ease: [0.22, 1, 0.36, 1]}}
|
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||||
className={
|
className={'mb-16'}
|
||||||
'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-neutral-900 mb-4" />
|
<h2
|
||||||
<h3 className={'text-2xl font-bold text-neutral-900'}>Transactional + Marketing</h3>
|
style={{fontFamily: 'var(--font-display)'}}
|
||||||
<p className={'mt-4 leading-relaxed text-neutral-600'}>
|
className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}
|
||||||
Send transactional emails with the same reliability as dedicated providers, plus marketing campaigns, automation, and segmentation. All in one platform.
|
>
|
||||||
</p>
|
All comparisons
|
||||||
|
</h2>
|
||||||
|
<p className={'mt-4 text-lg text-neutral-600'}>See how Plunk stacks up against popular email platforms</p>
|
||||||
</motion.div>
|
</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
|
<motion.div
|
||||||
initial={{opacity: 0, y: 20}}
|
initial={{opacity: 0, y: 20}}
|
||||||
whileInView={{opacity: 1, y: 0}}
|
whileInView={{opacity: 1, y: 0}}
|
||||||
viewport={{once: true}}
|
viewport={{once: true}}
|
||||||
transition={{duration: 0.5, delay: 0.2, ease: [0.22, 1, 0.36, 1]}}
|
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||||
className={
|
className={'mb-16'}
|
||||||
'rounded-2xl border border-neutral-200 bg-white p-8 transition hover:border-neutral-300 hover:shadow-lg'
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
<Code className="h-8 w-8 text-neutral-900 mb-4" />
|
<h2
|
||||||
<h3 className={'text-2xl font-bold text-neutral-900'}>Open Source & Self-Hostable</h3>
|
style={{fontFamily: 'var(--font-display)'}}
|
||||||
<p className={'mt-4 leading-relaxed text-neutral-600'}>
|
className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}
|
||||||
AGPL-3.0 licensed code you can inspect, modify, and self-host. Full control over your data and
|
>
|
||||||
infrastructure. No vendor lock-in.
|
Why Plunk wins
|
||||||
</p>
|
</h2>
|
||||||
|
<p className={'mt-4 text-lg text-neutral-600'}>One platform for all your email needs</p>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
|
|
||||||
<motion.div
|
<div className={'grid gap-px bg-neutral-200 sm:grid-cols-3'}>
|
||||||
initial={{opacity: 0, y: 20}}
|
{[
|
||||||
whileInView={{opacity: 1, y: 0}}
|
{
|
||||||
viewport={{once: true}}
|
icon: <Mail className="h-5 w-5" />,
|
||||||
transition={{duration: 0.5, delay: 0.3, ease: [0.22, 1, 0.36, 1]}}
|
title: 'Transactional + Marketing',
|
||||||
className={
|
body: 'Send transactional emails with the same reliability as dedicated providers, plus marketing campaigns, automation, and segmentation. All in one platform.',
|
||||||
'rounded-2xl border border-neutral-200 bg-white p-8 transition hover:border-neutral-300 hover:shadow-lg'
|
},
|
||||||
}
|
{
|
||||||
>
|
icon: <Code className="h-5 w-5" />,
|
||||||
<DollarSign className="h-8 w-8 text-neutral-900 mb-4" />
|
title: 'Open Source & Self-Hostable',
|
||||||
<h3 className={'text-2xl font-bold text-neutral-900'}>Simple Pricing</h3>
|
body: 'AGPL-3.0 licensed code you can inspect, modify, and self-host. Full control over your data and infrastructure. No vendor lock-in.',
|
||||||
<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.
|
icon: <DollarSign className="h-5 w-5" />,
|
||||||
</p>
|
title: 'Simple Pricing',
|
||||||
</motion.div>
|
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>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{/* CTA */}
|
{/* CTA */}
|
||||||
<section className={'relative overflow-hidden border-t border-neutral-200 py-32'}>
|
<section className={'relative overflow-hidden border-t border-neutral-900 bg-neutral-900 text-white'}>
|
||||||
<div
|
<div className={'mx-auto max-w-[88rem] px-6 py-32 sm:px-10 sm:py-40'}>
|
||||||
className={
|
<div className={'flex flex-col items-start gap-12 lg:flex-row lg:items-end lg:justify-between'}>
|
||||||
'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.h2
|
||||||
}
|
initial={{opacity: 0, y: 16}}
|
||||||
/>
|
whileInView={{opacity: 1, y: 0}}
|
||||||
<motion.div
|
viewport={{once: true}}
|
||||||
initial={{opacity: 0, y: 20}}
|
transition={{duration: 0.9, ease: [0.22, 1, 0.36, 1]}}
|
||||||
whileInView={{opacity: 1, y: 0}}
|
style={{fontFamily: 'var(--font-display)'}}
|
||||||
viewport={{once: true}}
|
className={'text-[clamp(2.5rem,7vw,6rem)] font-extrabold leading-[0.95] tracking-[-0.035em]'}
|
||||||
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'
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
<span className={'flex items-center gap-2'}>
|
Ready to try Plunk?
|
||||||
Get started free
|
</motion.h2>
|
||||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-1" />
|
<motion.div
|
||||||
</span>
|
initial={{opacity: 0, y: 16}}
|
||||||
</motion.a>
|
whileInView={{opacity: 1, y: 0}}
|
||||||
<Link
|
viewport={{once: true}}
|
||||||
href="/pricing"
|
transition={{duration: 0.9, delay: 0.15, ease: [0.22, 1, 0.36, 1]}}
|
||||||
className={
|
className={'flex max-w-md flex-col gap-6'}
|
||||||
'rounded-lg border border-neutral-300 px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-400'
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
View pricing
|
<p className={'text-base text-neutral-300 sm:text-lg'}>
|
||||||
</Link>
|
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>
|
||||||
</motion.div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<Footer />
|
<Footer />
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import {DASHBOARD_URI, WIKI_URI} from '../../lib/constants';
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import {NextSeo} from 'next-seo';
|
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 {ComparisonRow} from '../../components/ComparisonTable';
|
||||||
import type {FAQ} from '../../components/FAQSection';
|
import type {FAQ} from '../../components/FAQSection';
|
||||||
|
|
||||||
@@ -49,9 +49,6 @@ const faqs: FAQ[] = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
|
||||||
* Plunk vs Klaviyo comparison page
|
|
||||||
*/
|
|
||||||
export default function KlaviyoComparison() {
|
export default function KlaviyoComparison() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -70,368 +67,132 @@ export default function KlaviyoComparison() {
|
|||||||
|
|
||||||
<Navbar />
|
<Navbar />
|
||||||
|
|
||||||
<main className={'mx-auto max-w-7xl px-8 sm:px-0'}>
|
<main className={'text-neutral-800'}>
|
||||||
{/* 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
|
{/* Hero */}
|
||||||
initial={{opacity: 0, y: 20}}
|
<section className={'relative overflow-hidden'}>
|
||||||
animate={{opacity: 1, y: 0}}
|
<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%)]'} />
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
<div className={'mx-auto max-w-[88rem] px-6 pb-20 pt-20 sm:px-10 sm:pt-28 sm:pb-28'}>
|
||||||
className={'mx-auto max-w-4xl text-center'}
|
<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'}>
|
||||||
<div
|
Plunk vs Klaviyo
|
||||||
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>
|
|
||||||
</div>
|
</div>
|
||||||
<h3 className={'mt-6 text-2xl font-bold text-neutral-900'}>Pay per email sent</h3>
|
<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'}>
|
||||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
Open-source alternative
|
||||||
Pay-as-you-go pricing. Only pay for emails sent, not contacts stored. Predictable costs as you scale.
|
<br />
|
||||||
</p>
|
for Klaviyo
|
||||||
<div className={'mt-6 text-4xl font-bold text-neutral-900'}>Pay-as-you-go</div>
|
</h1>
|
||||||
<div className={'mt-8 space-y-3'}>
|
<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={'flex items-center gap-3 text-sm text-neutral-600'}>
|
<div className={'mt-10 flex flex-wrap gap-3'}>
|
||||||
<div className={'h-5 w-5 rounded-full bg-neutral-900 flex items-center justify-center'}>
|
<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={'h-1.5 w-1.5 rounded-full bg-white'} />
|
Get started free <ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-0.5" />
|
||||||
</div>
|
</motion.a>
|
||||||
<span>Unlimited contacts at no extra cost</span>
|
<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'}>
|
||||||
</div>
|
View documentation
|
||||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
</Link>
|
||||||
<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>
|
|
||||||
</div>
|
</div>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{/* Key Advantages */}
|
{/* Pricing comparison */}
|
||||||
<section className={'py-32'}>
|
<section className={'border-t border-neutral-200'}>
|
||||||
<motion.div
|
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||||
initial={{opacity: 0, y: 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'}>
|
||||||
whileInView={{opacity: 1, y: 0}}
|
<h2 style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}>
|
||||||
viewport={{once: true}}
|
E-commerce Email Without the Premium Price
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
</h2>
|
||||||
className={'mb-20 text-center'}
|
<p className={'mt-4 text-lg text-neutral-600'}>Pay for emails sent, not contacts stored</p>
|
||||||
>
|
|
||||||
<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>
|
|
||||||
</motion.div>
|
</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>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{/* Feature Comparison */}
|
{/* Key advantages */}
|
||||||
<section className={'py-32'}>
|
<section className={'border-t border-neutral-200 bg-neutral-50/60'}>
|
||||||
<motion.div
|
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||||
initial={{opacity: 0, y: 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'}>
|
||||||
whileInView={{opacity: 1, y: 0}}
|
<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>
|
||||||
viewport={{once: true}}
|
<p className={'mt-4 text-lg text-neutral-600'}>All the automation power, at a fraction of the cost</p>
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
</motion.div>
|
||||||
className={'mb-16 text-center'}
|
<div className={'grid gap-px bg-neutral-200 sm:grid-cols-2 lg:grid-cols-3'}>
|
||||||
>
|
{[
|
||||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>Feature Comparison</h2>
|
{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.'},
|
||||||
</motion.div>
|
{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>
|
</section>
|
||||||
|
|
||||||
{/* FAQ */}
|
{/* FAQ */}
|
||||||
<FAQSection faqs={faqs} schemaId="faq-schema-klaviyo" />
|
<FAQSection faqs={faqs} schemaId="faq-schema-klaviyo" />
|
||||||
|
|
||||||
{/* CTA */}
|
{/* CTA */}
|
||||||
<section className={'relative overflow-hidden border-t border-neutral-200 py-32'}>
|
<section className={'relative overflow-hidden border-t border-neutral-900 bg-neutral-900 text-white'}>
|
||||||
<div
|
<div className={'mx-auto max-w-[88rem] px-6 py-32 sm:px-10 sm:py-40'}>
|
||||||
className={
|
<div className={'flex flex-col items-start gap-12 lg:flex-row lg:items-end lg:justify-between'}>
|
||||||
'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.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
|
<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'}>
|
||||||
initial={{opacity: 0, y: 20}}
|
<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>
|
||||||
whileInView={{opacity: 1, y: 0}}
|
<div className={'flex flex-wrap gap-3'}>
|
||||||
viewport={{once: true}}
|
<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'}>
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
Get started free <ArrowRight className="h-4 w-4" />
|
||||||
className={'mx-auto max-w-3xl text-center'}
|
</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'}>
|
||||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>
|
View pricing
|
||||||
E-commerce email at a fraction of the cost
|
</Link>
|
||||||
</h2>
|
</div>
|
||||||
<p className={'mt-6 text-lg text-neutral-600'}>
|
</motion.div>
|
||||||
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>
|
|
||||||
</div>
|
</div>
|
||||||
</motion.div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</main>
|
|
||||||
|
|
||||||
|
</main>
|
||||||
<Footer />
|
<Footer />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
+127
-340
@@ -4,7 +4,7 @@ import {DASHBOARD_URI, WIKI_URI} from '../../lib/constants';
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import {NextSeo} from 'next-seo';
|
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 {ComparisonRow} from '../../components/ComparisonTable';
|
||||||
import type {FAQ} from '../../components/FAQSection';
|
import type {FAQ} from '../../components/FAQSection';
|
||||||
|
|
||||||
@@ -69,366 +69,153 @@ export default function LoopsComparison() {
|
|||||||
|
|
||||||
<Navbar />
|
<Navbar />
|
||||||
|
|
||||||
<main className={'mx-auto max-w-7xl px-8 sm:px-0'}>
|
<main className={'text-neutral-800'}>
|
||||||
{/* 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
|
{/* Hero */}
|
||||||
initial={{opacity: 0, y: 20}}
|
<section className={'relative overflow-hidden'}>
|
||||||
animate={{opacity: 1, y: 0}}
|
<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%)]'} />
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
<div className={'mx-auto max-w-[88rem] px-6 pb-20 pt-20 sm:px-10 sm:pt-28 sm:pb-28'}>
|
||||||
className={'mx-auto max-w-4xl text-center'}
|
<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'}>
|
||||||
<div
|
Plunk vs Loops
|
||||||
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>
|
|
||||||
</div>
|
</div>
|
||||||
<h3 className={'mt-6 text-2xl font-bold text-neutral-900'}>Pay per email sent</h3>
|
<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'}>
|
||||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
Open-source alternative
|
||||||
Pay-as-you-go pricing with unlimited contacts. No monthly commitments or contact-based limits.
|
<br />
|
||||||
</p>
|
for Loops
|
||||||
<div className={'mt-6 text-4xl font-bold text-neutral-900'}>$0.001/email</div>
|
</h1>
|
||||||
<div className={'mt-8 space-y-3'}>
|
<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={'flex items-center gap-3 text-sm text-neutral-600'}>
|
<div className={'mt-10 flex flex-wrap gap-3'}>
|
||||||
<div className={'h-5 w-5 rounded-full bg-neutral-900 flex items-center justify-center'}>
|
<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={'h-1.5 w-1.5 rounded-full bg-white'} />
|
Get started free <ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-0.5" />
|
||||||
</div>
|
</motion.a>
|
||||||
<span>Unlimited contacts at no extra cost</span>
|
<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'}>
|
||||||
</div>
|
View documentation
|
||||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
</Link>
|
||||||
<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>
|
|
||||||
</div>
|
</div>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{/* Key Advantages */}
|
{/* Pricing comparison */}
|
||||||
<section className={'py-32'}>
|
<section className={'border-t border-neutral-200'}>
|
||||||
<motion.div
|
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||||
initial={{opacity: 0, y: 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'}>
|
||||||
whileInView={{opacity: 1, y: 0}}
|
<h2 style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}>
|
||||||
viewport={{once: true}}
|
Transparent Pricing vs Vendor Lock-In
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
</h2>
|
||||||
className={'mb-20 text-center'}
|
<p className={'mt-4 text-lg text-neutral-600'}>Pay per email, not per contact</p>
|
||||||
>
|
|
||||||
<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>
|
|
||||||
</motion.div>
|
</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>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{/* Feature Comparison */}
|
{/* Key advantages */}
|
||||||
<section className={'py-32'}>
|
<section className={'border-t border-neutral-200 bg-neutral-50/60'}>
|
||||||
<motion.div
|
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||||
initial={{opacity: 0, y: 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'}>
|
||||||
whileInView={{opacity: 1, y: 0}}
|
<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>
|
||||||
viewport={{once: true}}
|
<p className={'mt-4 text-lg text-neutral-600'}>Open-source transparency meets modern SaaS features</p>
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
</motion.div>
|
||||||
className={'mb-16 text-center'}
|
<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'}>
|
||||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>Feature-by-Feature Comparison</h2>
|
<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>
|
||||||
<p className={'mt-4 text-lg text-neutral-600'}>See exactly what you get with each platform</p>
|
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>Open Source & Transparent</h3>
|
||||||
</motion.div>
|
<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>
|
</section>
|
||||||
|
|
||||||
{/* FAQ */}
|
{/* FAQ */}
|
||||||
<FAQSection faqs={faqs} schemaId="faq-schema-loops" />
|
<FAQSection faqs={faqs} schemaId="faq-schema-loops" />
|
||||||
|
|
||||||
{/* CTA */}
|
{/* CTA */}
|
||||||
<section className={'relative overflow-hidden border-t border-neutral-200 py-32'}>
|
<section className={'relative overflow-hidden border-t border-neutral-900 bg-neutral-900 text-white'}>
|
||||||
<div
|
<div className={'mx-auto max-w-[88rem] px-6 py-32 sm:px-10 sm:py-40'}>
|
||||||
className={
|
<div className={'flex flex-col items-start gap-12 lg:flex-row lg:items-end lg:justify-between'}>
|
||||||
'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.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
|
<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'}>
|
||||||
initial={{opacity: 0, y: 20}}
|
<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>
|
||||||
whileInView={{opacity: 1, y: 0}}
|
<div className={'flex flex-wrap gap-3'}>
|
||||||
viewport={{once: true}}
|
<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'}>
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
Get started free <ArrowRight className="h-4 w-4" />
|
||||||
className={'mx-auto max-w-3xl text-center'}
|
</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'}>
|
||||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>Switch to open source</h2>
|
View pricing
|
||||||
<p className={'mt-6 text-lg text-neutral-600'}>
|
</Link>
|
||||||
Join developers choosing transparency and control over proprietary platforms. Start free, no credit card
|
</div>
|
||||||
required.
|
</motion.div>
|
||||||
</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>
|
|
||||||
</div>
|
</div>
|
||||||
</motion.div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</main>
|
|
||||||
|
|
||||||
|
</main>
|
||||||
<Footer />
|
<Footer />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import {DASHBOARD_URI, WIKI_URI} from '../../lib/constants';
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import {NextSeo} from 'next-seo';
|
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 {ComparisonRow} from '../../components/ComparisonTable';
|
||||||
import type {FAQ} from '../../components/FAQSection';
|
import type {FAQ} from '../../components/FAQSection';
|
||||||
|
|
||||||
@@ -70,360 +70,154 @@ export default function MailchimpComparison() {
|
|||||||
|
|
||||||
<Navbar />
|
<Navbar />
|
||||||
|
|
||||||
<main className={'mx-auto max-w-7xl px-8 sm:px-0'}>
|
<main className={'text-neutral-800'}>
|
||||||
{/* 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
|
{/* Hero */}
|
||||||
initial={{opacity: 0, y: 20}}
|
<section className={'relative overflow-hidden'}>
|
||||||
animate={{opacity: 1, y: 0}}
|
<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%)]'} />
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
<div className={'mx-auto max-w-[88rem] px-6 pb-20 pt-20 sm:px-10 sm:pt-28 sm:pb-28'}>
|
||||||
className={'mx-auto max-w-4xl text-center'}
|
<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'}>
|
||||||
<div
|
Plunk vs Mailchimp
|
||||||
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>
|
|
||||||
</div>
|
</div>
|
||||||
<h3 className={'mt-6 text-2xl font-bold text-neutral-900'}>Pay per email sent</h3>
|
<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'}>
|
||||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
Open-source alternative
|
||||||
Pay-as-you-go pricing. Only pay for emails you actually send, not for contacts stored.
|
<br />
|
||||||
</p>
|
for Mailchimp
|
||||||
<div className={'mt-6 text-4xl font-bold text-neutral-900'}>Pay-as-you-go</div>
|
</h1>
|
||||||
<div className={'mt-8 space-y-3'}>
|
<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={'flex items-center gap-3 text-sm text-neutral-600'}>
|
<div className={'mt-10 flex flex-wrap gap-3'}>
|
||||||
<div className={'h-5 w-5 rounded-full bg-neutral-900 flex items-center justify-center'}>
|
<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={'h-1.5 w-1.5 rounded-full bg-white'} />
|
Try Plunk free <ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-0.5" />
|
||||||
</div>
|
</motion.a>
|
||||||
<span>Only pay for emails you actually send</span>
|
<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'}>
|
||||||
</div>
|
View documentation
|
||||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
</Link>
|
||||||
<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>
|
|
||||||
</div>
|
</div>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{/* Key Advantages */}
|
{/* Pricing comparison */}
|
||||||
<section className={'py-32'}>
|
<section className={'border-t border-neutral-200'}>
|
||||||
<motion.div
|
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||||
initial={{opacity: 0, y: 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'}>
|
||||||
whileInView={{opacity: 1, y: 0}}
|
<h2 style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}>
|
||||||
viewport={{once: true}}
|
The Pricing Model That Makes Sense
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
</h2>
|
||||||
className={'mb-20 text-center'}
|
<p className={'mt-4 text-lg text-neutral-600'}>Pay for what you use, not for what you store</p>
|
||||||
>
|
|
||||||
<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>
|
|
||||||
</motion.div>
|
</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>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{/* Feature Comparison */}
|
{/* Key advantages */}
|
||||||
<section className={'py-32'}>
|
<section className={'border-t border-neutral-200 bg-neutral-50/60'}>
|
||||||
<motion.div
|
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||||
initial={{opacity: 0, y: 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'}>
|
||||||
whileInView={{opacity: 1, y: 0}}
|
<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>
|
||||||
viewport={{once: true}}
|
</motion.div>
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
<div className={'grid gap-px bg-neutral-200 sm:grid-cols-2 lg:grid-cols-3'}>
|
||||||
className={'mb-16 text-center'}
|
<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>
|
||||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>Feature Comparison</h2>
|
<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>
|
||||||
</motion.div>
|
<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>
|
</section>
|
||||||
|
|
||||||
{/* FAQ */}
|
{/* FAQ */}
|
||||||
<FAQSection faqs={faqs} schemaId="faq-schema-mailchimp" />
|
<FAQSection faqs={faqs} schemaId="faq-schema-mailchimp" />
|
||||||
|
|
||||||
{/* CTA */}
|
{/* CTA */}
|
||||||
<section className={'relative overflow-hidden border-t border-neutral-200 py-32'}>
|
<section className={'relative overflow-hidden border-t border-neutral-900 bg-neutral-900 text-white'}>
|
||||||
<div
|
<div className={'mx-auto max-w-[88rem] px-6 py-32 sm:px-10 sm:py-40'}>
|
||||||
className={
|
<div className={'flex flex-col items-start gap-12 lg:flex-row lg:items-end lg:justify-between'}>
|
||||||
'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.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
|
<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'}>
|
||||||
initial={{opacity: 0, y: 20}}
|
<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>
|
||||||
whileInView={{opacity: 1, y: 0}}
|
<div className={'flex flex-wrap gap-3'}>
|
||||||
viewport={{once: true}}
|
<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'}>
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
Get started free <ArrowRight className="h-4 w-4" />
|
||||||
className={'mx-auto max-w-3xl text-center'}
|
</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'}>
|
||||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>
|
View pricing
|
||||||
Ready for a better developer experience?
|
</Link>
|
||||||
</h2>
|
</div>
|
||||||
<p className={'mt-6 text-lg text-neutral-600'}>
|
</motion.div>
|
||||||
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>
|
|
||||||
</div>
|
</div>
|
||||||
</motion.div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</main>
|
|
||||||
|
|
||||||
|
</main>
|
||||||
<Footer />
|
<Footer />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import {DASHBOARD_URI, WIKI_URI} from '../../lib/constants';
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import {NextSeo} from 'next-seo';
|
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 {ComparisonRow} from '../../components/ComparisonTable';
|
||||||
import type {FAQ} from '../../components/FAQSection';
|
import type {FAQ} from '../../components/FAQSection';
|
||||||
|
|
||||||
@@ -49,9 +49,6 @@ const faqs: FAQ[] = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
|
||||||
* Plunk vs MailerLite comparison page
|
|
||||||
*/
|
|
||||||
export default function MailerliteComparison() {
|
export default function MailerliteComparison() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -70,369 +67,132 @@ export default function MailerliteComparison() {
|
|||||||
|
|
||||||
<Navbar />
|
<Navbar />
|
||||||
|
|
||||||
<main className={'mx-auto max-w-7xl px-8 sm:px-0'}>
|
<main className={'text-neutral-800'}>
|
||||||
{/* 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
|
{/* Hero */}
|
||||||
initial={{opacity: 0, y: 20}}
|
<section className={'relative overflow-hidden'}>
|
||||||
animate={{opacity: 1, y: 0}}
|
<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%)]'} />
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
<div className={'mx-auto max-w-[88rem] px-6 pb-20 pt-20 sm:px-10 sm:pt-28 sm:pb-28'}>
|
||||||
className={'mx-auto max-w-4xl text-center'}
|
<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'}>
|
||||||
<div
|
Plunk vs MailerLite
|
||||||
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>
|
|
||||||
</div>
|
</div>
|
||||||
<h3 className={'mt-6 text-2xl font-bold text-neutral-900'}>Pay per email sent</h3>
|
<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'}>
|
||||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
Open-source alternative
|
||||||
Pay-as-you-go pricing. Open-source and self-hostable for full control.
|
<br />
|
||||||
</p>
|
for MailerLite
|
||||||
<div className={'mt-6 text-4xl font-bold text-neutral-900'}>Pay-as-you-go</div>
|
</h1>
|
||||||
<div className={'mt-8 space-y-3'}>
|
<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={'flex items-center gap-3 text-sm text-neutral-600'}>
|
<div className={'mt-10 flex flex-wrap gap-3'}>
|
||||||
<div className={'h-5 w-5 rounded-full bg-neutral-900 flex items-center justify-center'}>
|
<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={'h-1.5 w-1.5 rounded-full bg-white'} />
|
Get started free <ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-0.5" />
|
||||||
</div>
|
</motion.a>
|
||||||
<span>Unlimited contacts, no subscriber fees</span>
|
<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'}>
|
||||||
</div>
|
View documentation
|
||||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
</Link>
|
||||||
<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>
|
|
||||||
</div>
|
</div>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{/* Key Advantages */}
|
{/* Pricing comparison */}
|
||||||
<section className={'py-32'}>
|
<section className={'border-t border-neutral-200'}>
|
||||||
<motion.div
|
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||||
initial={{opacity: 0, y: 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'}>
|
||||||
whileInView={{opacity: 1, y: 0}}
|
<h2 style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}>
|
||||||
viewport={{once: true}}
|
Open Source Meets Developer Experience
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
</h2>
|
||||||
className={'mb-20 text-center'}
|
<p className={'mt-4 text-lg text-neutral-600'}>Pay for emails sent, not subscribers stored</p>
|
||||||
>
|
|
||||||
<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>
|
|
||||||
</motion.div>
|
</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>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{/* Feature Comparison */}
|
{/* Key advantages */}
|
||||||
<section className={'py-32'}>
|
<section className={'border-t border-neutral-200 bg-neutral-50/60'}>
|
||||||
<motion.div
|
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||||
initial={{opacity: 0, y: 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'}>
|
||||||
whileInView={{opacity: 1, y: 0}}
|
<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>
|
||||||
viewport={{once: true}}
|
<p className={'mt-4 text-lg text-neutral-600'}>Full control, transparent code, pay only for what you send</p>
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
</motion.div>
|
||||||
className={'mb-16 text-center'}
|
<div className={'grid gap-px bg-neutral-200 sm:grid-cols-2 lg:grid-cols-3'}>
|
||||||
>
|
{[
|
||||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>Feature Comparison</h2>
|
{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.'},
|
||||||
</motion.div>
|
{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>
|
</section>
|
||||||
|
|
||||||
{/* FAQ */}
|
{/* FAQ */}
|
||||||
<FAQSection faqs={faqs} schemaId="faq-schema-mailerlite" />
|
<FAQSection faqs={faqs} schemaId="faq-schema-mailerlite" />
|
||||||
|
|
||||||
{/* CTA */}
|
{/* CTA */}
|
||||||
<section className={'relative overflow-hidden border-t border-neutral-200 py-32'}>
|
<section className={'relative overflow-hidden border-t border-neutral-900 bg-neutral-900 text-white'}>
|
||||||
<div
|
<div className={'mx-auto max-w-[88rem] px-6 py-32 sm:px-10 sm:py-40'}>
|
||||||
className={
|
<div className={'flex flex-col items-start gap-12 lg:flex-row lg:items-end lg:justify-between'}>
|
||||||
'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.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
|
<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'}>
|
||||||
initial={{opacity: 0, y: 20}}
|
<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>
|
||||||
whileInView={{opacity: 1, y: 0}}
|
<div className={'flex flex-wrap gap-3'}>
|
||||||
viewport={{once: true}}
|
<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'}>
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
Get started free <ArrowRight className="h-4 w-4" />
|
||||||
className={'mx-auto max-w-3xl text-center'}
|
</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'}>
|
||||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>
|
View pricing
|
||||||
Experience true developer-first email
|
</Link>
|
||||||
</h2>
|
</div>
|
||||||
<p className={'mt-6 text-lg text-neutral-600'}>
|
</motion.div>
|
||||||
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>
|
|
||||||
</div>
|
</div>
|
||||||
</motion.div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</main>
|
|
||||||
|
|
||||||
|
</main>
|
||||||
<Footer />
|
<Footer />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import {DASHBOARD_URI, WIKI_URI} from '../../lib/constants';
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import {NextSeo} from 'next-seo';
|
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 {ComparisonRow} from '../../components/ComparisonTable';
|
||||||
import type {FAQ} from '../../components/FAQSection';
|
import type {FAQ} from '../../components/FAQSection';
|
||||||
|
|
||||||
@@ -65,309 +65,124 @@ export default function MailgunComparison() {
|
|||||||
|
|
||||||
<Navbar />
|
<Navbar />
|
||||||
|
|
||||||
<main className={'mx-auto max-w-7xl px-8 sm:px-0'}>
|
<main className={'text-neutral-800'}>
|
||||||
{/* 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
|
{/* Hero */}
|
||||||
initial={{opacity: 0, y: 20}}
|
<section className={'relative overflow-hidden'}>
|
||||||
animate={{opacity: 1, y: 0}}
|
<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%)]'} />
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
<div className={'mx-auto max-w-[88rem] px-6 pb-20 pt-20 sm:px-10 sm:pt-28 sm:pb-28'}>
|
||||||
className={'mx-auto max-w-4xl text-center'}
|
<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'}>
|
||||||
<div
|
Plunk vs Mailgun
|
||||||
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>
|
|
||||||
</div>
|
</div>
|
||||||
<h3 className={'mt-6 text-2xl font-bold text-neutral-900'}>Pay per email sent</h3>
|
<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'}>
|
||||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
Open-source alternative
|
||||||
Pay-as-you-go pricing. Only pay for emails you actually send.
|
<br />
|
||||||
</p>
|
for Mailgun
|
||||||
<div className={'mt-6 text-4xl font-bold text-neutral-900'}>Pay-as-you-go</div>
|
</h1>
|
||||||
<div className={'mt-8 space-y-3'}>
|
<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={'flex items-center gap-3 text-sm text-neutral-600'}>
|
<div className={'mt-10 flex flex-wrap gap-3'}>
|
||||||
<div className={'h-5 w-5 rounded-full bg-neutral-900 flex items-center justify-center'}>
|
<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={'h-1.5 w-1.5 rounded-full bg-white'} />
|
Try Plunk free <ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-0.5" />
|
||||||
</div>
|
</motion.a>
|
||||||
<span>Only pay for emails you actually send</span>
|
<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'}>
|
||||||
</div>
|
View documentation
|
||||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
</Link>
|
||||||
<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>
|
|
||||||
</div>
|
</div>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{/* Feature Comparison */}
|
{/* Pricing comparison */}
|
||||||
<section className={'py-32'}>
|
<section className={'border-t border-neutral-200'}>
|
||||||
<motion.div
|
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||||
initial={{opacity: 0, y: 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'}>
|
||||||
whileInView={{opacity: 1, y: 0}}
|
<h2 style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}>
|
||||||
viewport={{once: true}}
|
The Pricing Model That Makes Sense
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
</h2>
|
||||||
className={'mb-16 text-center'}
|
<p className={'mt-4 text-lg text-neutral-600'}>Pay for what you use, not fixed subscriptions</p>
|
||||||
>
|
</motion.div>
|
||||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>Feature-by-Feature</h2>
|
<div className={'grid gap-4 lg:grid-cols-2'}>
|
||||||
</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-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>
|
||||||
<ComparisonTable competitorName="Mailgun" rows={comparisonData} />
|
<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>
|
</section>
|
||||||
|
|
||||||
{/* What Plunk Adds */}
|
{/* Key advantages */}
|
||||||
<section className={'py-32'}>
|
<section className={'border-t border-neutral-200 bg-neutral-50/60'}>
|
||||||
<motion.div
|
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||||
initial={{opacity: 0, y: 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'}>
|
||||||
whileInView={{opacity: 1, y: 0}}
|
<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>
|
||||||
viewport={{once: true}}
|
<p className={'mt-4 text-lg text-neutral-600'}>Beyond transactional emails</p>
|
||||||
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>
|
|
||||||
</motion.div>
|
</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
|
<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'}>
|
||||||
initial={{opacity: 0, y: 20}}
|
<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>
|
||||||
whileInView={{opacity: 1, y: 0}}
|
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>Workflow Automation</h3>
|
||||||
viewport={{once: true}}
|
<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>
|
||||||
transition={{duration: 0.5, delay: 0.2, ease: [0.22, 1, 0.36, 1]}}
|
</motion.div>
|
||||||
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
|
<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'}>
|
||||||
initial={{opacity: 0, y: 20}}
|
<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>
|
||||||
whileInView={{opacity: 1, y: 0}}
|
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>Dynamic Segmentation</h3>
|
||||||
viewport={{once: true}}
|
<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>
|
||||||
transition={{duration: 0.5, delay: 0.3, ease: [0.22, 1, 0.36, 1]}}
|
</motion.div>
|
||||||
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
|
<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'}>
|
||||||
initial={{opacity: 0, y: 20}}
|
<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>
|
||||||
whileInView={{opacity: 1, y: 0}}
|
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>Open Source</h3>
|
||||||
viewport={{once: true}}
|
<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>
|
||||||
transition={{duration: 0.5, delay: 0.4, ease: [0.22, 1, 0.36, 1]}}
|
</motion.div>
|
||||||
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
|
<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'}>
|
||||||
initial={{opacity: 0, y: 20}}
|
<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>
|
||||||
whileInView={{opacity: 1, y: 0}}
|
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>Self-Hostable</h3>
|
||||||
viewport={{once: true}}
|
<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>
|
||||||
transition={{duration: 0.5, delay: 0.5, ease: [0.22, 1, 0.36, 1]}}
|
</motion.div>
|
||||||
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
|
<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'}>
|
||||||
initial={{opacity: 0, y: 20}}
|
<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>
|
||||||
whileInView={{opacity: 1, y: 0}}
|
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>All-in-One Platform</h3>
|
||||||
viewport={{once: true}}
|
<p className={'mt-3 leading-relaxed text-neutral-600'}>One platform for transactional, marketing, and automation. No need for multiple tools or integrations.</p>
|
||||||
transition={{duration: 0.5, delay: 0.6, ease: [0.22, 1, 0.36, 1]}}
|
</motion.div>
|
||||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
</div>
|
||||||
>
|
</div>
|
||||||
<div
|
</section>
|
||||||
className={
|
|
||||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
{/* Feature comparison table */}
|
||||||
}
|
<section className={'border-t border-neutral-200'}>
|
||||||
>
|
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||||
<Layers className="h-5 w-5" />
|
<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'}>
|
||||||
</div>
|
<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>
|
||||||
<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>
|
</motion.div>
|
||||||
|
<ComparisonTable competitorName="Mailgun" rows={comparisonData} />
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
@@ -375,51 +190,28 @@ export default function MailgunComparison() {
|
|||||||
<FAQSection faqs={faqs} schemaId="faq-schema-mailgun" />
|
<FAQSection faqs={faqs} schemaId="faq-schema-mailgun" />
|
||||||
|
|
||||||
{/* CTA */}
|
{/* CTA */}
|
||||||
<section className={'relative overflow-hidden border-t border-neutral-200 py-32'}>
|
<section className={'relative overflow-hidden border-t border-neutral-900 bg-neutral-900 text-white'}>
|
||||||
<div
|
<div className={'mx-auto max-w-[88rem] px-6 py-32 sm:px-10 sm:py-40'}>
|
||||||
className={
|
<div className={'flex flex-col items-start gap-12 lg:flex-row lg:items-end lg:justify-between'}>
|
||||||
'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.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
|
<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'}>
|
||||||
initial={{opacity: 0, y: 20}}
|
<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>
|
||||||
whileInView={{opacity: 1, y: 0}}
|
<div className={'flex flex-wrap gap-3'}>
|
||||||
viewport={{once: true}}
|
<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'}>
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
Get started free <ArrowRight className="h-4 w-4" />
|
||||||
className={'mx-auto max-w-3xl text-center'}
|
</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'}>
|
||||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>Try Plunk free</h2>
|
View pricing
|
||||||
<p className={'mt-6 text-lg text-neutral-600'}>
|
</Link>
|
||||||
1,000 emails/month free. No credit card required. Add marketing and automation when you need it.
|
</div>
|
||||||
</p>
|
</motion.div>
|
||||||
<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>
|
|
||||||
</div>
|
</div>
|
||||||
</motion.div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</main>
|
|
||||||
|
|
||||||
|
</main>
|
||||||
<Footer />
|
<Footer />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import {DASHBOARD_URI, WIKI_URI} from '../../lib/constants';
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import {NextSeo} from 'next-seo';
|
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 {ComparisonRow} from '../../components/ComparisonTable';
|
||||||
import type {FAQ} from '../../components/FAQSection';
|
import type {FAQ} from '../../components/FAQSection';
|
||||||
|
|
||||||
@@ -66,365 +66,153 @@ export default function PostmarkComparison() {
|
|||||||
|
|
||||||
<Navbar />
|
<Navbar />
|
||||||
|
|
||||||
<main className={'mx-auto max-w-7xl px-8 sm:px-0'}>
|
<main className={'text-neutral-800'}>
|
||||||
{/* 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
|
{/* Hero */}
|
||||||
initial={{opacity: 0, y: 20}}
|
<section className={'relative overflow-hidden'}>
|
||||||
animate={{opacity: 1, y: 0}}
|
<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%)]'} />
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
<div className={'mx-auto max-w-[88rem] px-6 pb-20 pt-20 sm:px-10 sm:pt-28 sm:pb-28'}>
|
||||||
className={'mx-auto max-w-4xl text-center'}
|
<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'}>
|
||||||
<div
|
Plunk vs Postmark
|
||||||
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>
|
|
||||||
</div>
|
</div>
|
||||||
<h3 className={'mt-6 text-2xl font-bold text-neutral-900'}>Transactional + Marketing</h3>
|
<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'}>
|
||||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
Open-source alternative
|
||||||
Reliable transactional emails plus marketing campaigns, workflows, and segmentation in one platform.
|
<br />
|
||||||
</p>
|
for Postmark
|
||||||
<div className={'mt-6 text-4xl font-bold text-neutral-900'}>All-in-one</div>
|
</h1>
|
||||||
<div className={'mt-8 space-y-3'}>
|
<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={'flex items-center gap-3 text-sm text-neutral-600'}>
|
<div className={'mt-10 flex flex-wrap gap-3'}>
|
||||||
<div className={'h-5 w-5 rounded-full bg-neutral-900 flex items-center justify-center'}>
|
<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={'h-1.5 w-1.5 rounded-full bg-white'} />
|
Get started free <ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-0.5" />
|
||||||
</div>
|
</motion.a>
|
||||||
<span>Transactional emails included</span>
|
<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'}>
|
||||||
</div>
|
View documentation
|
||||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
</Link>
|
||||||
<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>
|
|
||||||
</div>
|
</div>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{/* Key Advantages */}
|
{/* Pricing comparison */}
|
||||||
<section className={'py-32'}>
|
<section className={'border-t border-neutral-200'}>
|
||||||
<motion.div
|
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||||
initial={{opacity: 0, y: 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'}>
|
||||||
whileInView={{opacity: 1, y: 0}}
|
<h2 style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}>
|
||||||
viewport={{once: true}}
|
One Platform for All Your Emails
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
</h2>
|
||||||
className={'mb-20 text-center'}
|
<p className={'mt-4 text-lg text-neutral-600'}>Transactional reliability meets marketing power</p>
|
||||||
>
|
|
||||||
<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>
|
|
||||||
</motion.div>
|
</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>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{/* Feature Comparison */}
|
{/* Key advantages */}
|
||||||
<section className={'py-32'}>
|
<section className={'border-t border-neutral-200 bg-neutral-50/60'}>
|
||||||
<motion.div
|
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||||
initial={{opacity: 0, y: 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'}>
|
||||||
whileInView={{opacity: 1, y: 0}}
|
<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>
|
||||||
viewport={{once: true}}
|
<p className={'mt-4 text-lg text-neutral-600'}>Do more with one platform instead of two</p>
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
</motion.div>
|
||||||
className={'mb-16 text-center'}
|
<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'}>
|
||||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>Feature-by-Feature Comparison</h2>
|
<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>
|
||||||
<p className={'mt-4 text-lg text-neutral-600'}>See exactly what you get with each platform</p>
|
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>Marketing Campaigns Included</h3>
|
||||||
</motion.div>
|
<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>
|
</section>
|
||||||
|
|
||||||
{/* FAQ */}
|
{/* FAQ */}
|
||||||
<FAQSection faqs={faqs} schemaId="faq-schema-postmark" />
|
<FAQSection faqs={faqs} schemaId="faq-schema-postmark" />
|
||||||
|
|
||||||
{/* CTA */}
|
{/* CTA */}
|
||||||
<section className={'relative overflow-hidden border-t border-neutral-200 py-32'}>
|
<section className={'relative overflow-hidden border-t border-neutral-900 bg-neutral-900 text-white'}>
|
||||||
<div
|
<div className={'mx-auto max-w-[88rem] px-6 py-32 sm:px-10 sm:py-40'}>
|
||||||
className={
|
<div className={'flex flex-col items-start gap-12 lg:flex-row lg:items-end lg:justify-between'}>
|
||||||
'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.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
|
<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'}>
|
||||||
initial={{opacity: 0, y: 20}}
|
<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>
|
||||||
whileInView={{opacity: 1, y: 0}}
|
<div className={'flex flex-wrap gap-3'}>
|
||||||
viewport={{once: true}}
|
<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'}>
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
Get started free <ArrowRight className="h-4 w-4" />
|
||||||
className={'mx-auto max-w-3xl text-center'}
|
</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'}>
|
||||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>Get more from your email platform</h2>
|
View pricing
|
||||||
<p className={'mt-6 text-lg text-neutral-600'}>
|
</Link>
|
||||||
Stop juggling multiple tools. Get transactional reliability plus marketing power in one platform. Start
|
</div>
|
||||||
free.
|
</motion.div>
|
||||||
</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>
|
|
||||||
</div>
|
</div>
|
||||||
</motion.div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</main>
|
|
||||||
|
|
||||||
|
</main>
|
||||||
<Footer />
|
<Footer />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import {DASHBOARD_URI, WIKI_URI} from '../../lib/constants';
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import {NextSeo} from 'next-seo';
|
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 {ComparisonRow} from '../../components/ComparisonTable';
|
||||||
import type {FAQ} from '../../components/FAQSection';
|
import type {FAQ} from '../../components/FAQSection';
|
||||||
|
|
||||||
@@ -65,309 +65,124 @@ export default function ResendComparison() {
|
|||||||
|
|
||||||
<Navbar />
|
<Navbar />
|
||||||
|
|
||||||
<main className={'mx-auto max-w-7xl px-8 sm:px-0'}>
|
<main className={'text-neutral-800'}>
|
||||||
{/* 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
|
{/* Hero */}
|
||||||
initial={{opacity: 0, y: 20}}
|
<section className={'relative overflow-hidden'}>
|
||||||
animate={{opacity: 1, y: 0}}
|
<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%)]'} />
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
<div className={'mx-auto max-w-[88rem] px-6 pb-20 pt-20 sm:px-10 sm:pt-28 sm:pb-28'}>
|
||||||
className={'mx-auto max-w-4xl text-center'}
|
<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'}>
|
||||||
<div
|
Plunk vs Resend
|
||||||
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>
|
|
||||||
</div>
|
</div>
|
||||||
<h3 className={'mt-6 text-2xl font-bold text-neutral-900'}>Pay per email sent</h3>
|
<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'}>
|
||||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
Open-source alternative
|
||||||
Pay-as-you-go pricing. Only pay for emails you actually send.
|
<br />
|
||||||
</p>
|
for Resend
|
||||||
<div className={'mt-6 text-4xl font-bold text-neutral-900'}>Pay-as-you-go</div>
|
</h1>
|
||||||
<div className={'mt-8 space-y-3'}>
|
<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={'flex items-center gap-3 text-sm text-neutral-600'}>
|
<div className={'mt-10 flex flex-wrap gap-3'}>
|
||||||
<div className={'h-5 w-5 rounded-full bg-neutral-900 flex items-center justify-center'}>
|
<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={'h-1.5 w-1.5 rounded-full bg-white'} />
|
Try Plunk free <ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-0.5" />
|
||||||
</div>
|
</motion.a>
|
||||||
<span>Only pay for emails you actually send</span>
|
<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'}>
|
||||||
</div>
|
View documentation
|
||||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
</Link>
|
||||||
<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>
|
|
||||||
</div>
|
</div>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{/* Feature Comparison */}
|
{/* Pricing comparison */}
|
||||||
<section className={'py-32'}>
|
<section className={'border-t border-neutral-200'}>
|
||||||
<motion.div
|
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||||
initial={{opacity: 0, y: 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'}>
|
||||||
whileInView={{opacity: 1, y: 0}}
|
<h2 style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}>
|
||||||
viewport={{once: true}}
|
The Pricing Model That Makes Sense
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
</h2>
|
||||||
className={'mb-16 text-center'}
|
<p className={'mt-4 text-lg text-neutral-600'}>Pay for what you use, not fixed subscriptions</p>
|
||||||
>
|
</motion.div>
|
||||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>Feature-by-Feature</h2>
|
<div className={'grid gap-4 lg:grid-cols-2'}>
|
||||||
</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-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>
|
||||||
<ComparisonTable competitorName="Resend" rows={comparisonData} />
|
<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>
|
</section>
|
||||||
|
|
||||||
{/* What Plunk Adds */}
|
{/* Key advantages */}
|
||||||
<section className={'py-32'}>
|
<section className={'border-t border-neutral-200 bg-neutral-50/60'}>
|
||||||
<motion.div
|
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||||
initial={{opacity: 0, y: 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'}>
|
||||||
whileInView={{opacity: 1, y: 0}}
|
<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>
|
||||||
viewport={{once: true}}
|
<p className={'mt-4 text-lg text-neutral-600'}>Beyond transactional emails</p>
|
||||||
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>
|
|
||||||
</motion.div>
|
</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
|
<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'}>
|
||||||
initial={{opacity: 0, y: 20}}
|
<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>
|
||||||
whileInView={{opacity: 1, y: 0}}
|
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>Workflow Automation</h3>
|
||||||
viewport={{once: true}}
|
<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>
|
||||||
transition={{duration: 0.5, delay: 0.2, ease: [0.22, 1, 0.36, 1]}}
|
</motion.div>
|
||||||
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
|
<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'}>
|
||||||
initial={{opacity: 0, y: 20}}
|
<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>
|
||||||
whileInView={{opacity: 1, y: 0}}
|
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>Dynamic Segmentation</h3>
|
||||||
viewport={{once: true}}
|
<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>
|
||||||
transition={{duration: 0.5, delay: 0.3, ease: [0.22, 1, 0.36, 1]}}
|
</motion.div>
|
||||||
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
|
<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'}>
|
||||||
initial={{opacity: 0, y: 20}}
|
<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>
|
||||||
whileInView={{opacity: 1, y: 0}}
|
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>Open Source</h3>
|
||||||
viewport={{once: true}}
|
<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>
|
||||||
transition={{duration: 0.5, delay: 0.4, ease: [0.22, 1, 0.36, 1]}}
|
</motion.div>
|
||||||
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
|
<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'}>
|
||||||
initial={{opacity: 0, y: 20}}
|
<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>
|
||||||
whileInView={{opacity: 1, y: 0}}
|
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>Self-Hostable</h3>
|
||||||
viewport={{once: true}}
|
<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>
|
||||||
transition={{duration: 0.5, delay: 0.5, ease: [0.22, 1, 0.36, 1]}}
|
</motion.div>
|
||||||
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
|
<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'}>
|
||||||
initial={{opacity: 0, y: 20}}
|
<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>
|
||||||
whileInView={{opacity: 1, y: 0}}
|
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>All-in-One Platform</h3>
|
||||||
viewport={{once: true}}
|
<p className={'mt-3 leading-relaxed text-neutral-600'}>One platform for transactional, marketing, and automation. No need for multiple tools or integrations.</p>
|
||||||
transition={{duration: 0.5, delay: 0.6, ease: [0.22, 1, 0.36, 1]}}
|
</motion.div>
|
||||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
</div>
|
||||||
>
|
</div>
|
||||||
<div
|
</section>
|
||||||
className={
|
|
||||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
{/* Feature comparison table */}
|
||||||
}
|
<section className={'border-t border-neutral-200'}>
|
||||||
>
|
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||||
<Layers className="h-5 w-5" />
|
<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'}>
|
||||||
</div>
|
<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>
|
||||||
<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>
|
</motion.div>
|
||||||
|
<ComparisonTable competitorName="Resend" rows={comparisonData} />
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
@@ -375,51 +190,28 @@ export default function ResendComparison() {
|
|||||||
<FAQSection faqs={faqs} schemaId="faq-schema-resend" />
|
<FAQSection faqs={faqs} schemaId="faq-schema-resend" />
|
||||||
|
|
||||||
{/* CTA */}
|
{/* CTA */}
|
||||||
<section className={'relative overflow-hidden border-t border-neutral-200 py-32'}>
|
<section className={'relative overflow-hidden border-t border-neutral-900 bg-neutral-900 text-white'}>
|
||||||
<div
|
<div className={'mx-auto max-w-[88rem] px-6 py-32 sm:px-10 sm:py-40'}>
|
||||||
className={
|
<div className={'flex flex-col items-start gap-12 lg:flex-row lg:items-end lg:justify-between'}>
|
||||||
'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.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
|
<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'}>
|
||||||
initial={{opacity: 0, y: 20}}
|
<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>
|
||||||
whileInView={{opacity: 1, y: 0}}
|
<div className={'flex flex-wrap gap-3'}>
|
||||||
viewport={{once: true}}
|
<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'}>
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
Get started free <ArrowRight className="h-4 w-4" />
|
||||||
className={'mx-auto max-w-3xl text-center'}
|
</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'}>
|
||||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>Try Plunk free</h2>
|
View pricing
|
||||||
<p className={'mt-6 text-lg text-neutral-600'}>
|
</Link>
|
||||||
1,000 emails/month free. No credit card required. Add marketing and automation when you need it.
|
</div>
|
||||||
</p>
|
</motion.div>
|
||||||
<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>
|
|
||||||
</div>
|
</div>
|
||||||
</motion.div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</main>
|
|
||||||
|
|
||||||
|
</main>
|
||||||
<Footer />
|
<Footer />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import {DASHBOARD_URI, WIKI_URI} from '../../lib/constants';
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import {NextSeo} from 'next-seo';
|
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 {ComparisonRow} from '../../components/ComparisonTable';
|
||||||
import type {FAQ} from '../../components/FAQSection';
|
import type {FAQ} from '../../components/FAQSection';
|
||||||
|
|
||||||
@@ -69,364 +69,153 @@ export default function SendGridComparison() {
|
|||||||
|
|
||||||
<Navbar />
|
<Navbar />
|
||||||
|
|
||||||
<main className={'mx-auto max-w-7xl px-8 sm:px-0'}>
|
<main className={'text-neutral-800'}>
|
||||||
{/* 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
|
{/* Hero */}
|
||||||
initial={{opacity: 0, y: 20}}
|
<section className={'relative overflow-hidden'}>
|
||||||
animate={{opacity: 1, y: 0}}
|
<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%)]'} />
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
<div className={'mx-auto max-w-[88rem] px-6 pb-20 pt-20 sm:px-10 sm:pt-28 sm:pb-28'}>
|
||||||
className={'mx-auto max-w-4xl text-center'}
|
<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'}>
|
||||||
<div
|
Plunk vs SendGrid
|
||||||
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>
|
|
||||||
</div>
|
</div>
|
||||||
<h3 className={'mt-6 text-2xl font-bold text-neutral-900'}>Pay per email sent</h3>
|
<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'}>
|
||||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
Open-source alternative
|
||||||
Pay-as-you-go pricing. Only pay for emails you actually send, no monthly minimums.
|
<br />
|
||||||
</p>
|
for SendGrid
|
||||||
<div className={'mt-6 text-4xl font-bold text-neutral-900'}>Pay-as-you-go</div>
|
</h1>
|
||||||
<div className={'mt-8 space-y-3'}>
|
<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={'flex items-center gap-3 text-sm text-neutral-600'}>
|
<div className={'mt-10 flex flex-wrap gap-3'}>
|
||||||
<div className={'h-5 w-5 rounded-full bg-neutral-900 flex items-center justify-center'}>
|
<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={'h-1.5 w-1.5 rounded-full bg-white'} />
|
Get started free <ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-0.5" />
|
||||||
</div>
|
</motion.a>
|
||||||
<span>No monthly minimum or commitment</span>
|
<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'}>
|
||||||
</div>
|
View documentation
|
||||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
</Link>
|
||||||
<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>
|
|
||||||
</div>
|
</div>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{/* Key Advantages */}
|
{/* Pricing comparison */}
|
||||||
<section className={'py-32'}>
|
<section className={'border-t border-neutral-200'}>
|
||||||
<motion.div
|
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||||
initial={{opacity: 0, y: 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'}>
|
||||||
whileInView={{opacity: 1, y: 0}}
|
<h2 style={{fontFamily: 'var(--font-display)'}} className={'text-[clamp(2rem,5vw,4rem)] font-extrabold leading-[0.95] tracking-[-0.03em] text-neutral-900'}>
|
||||||
viewport={{once: true}}
|
The Pricing Model That Makes Sense
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
</h2>
|
||||||
className={'mb-20 text-center'}
|
<p className={'mt-4 text-lg text-neutral-600'}>Pay for what you use, not for what you might use</p>
|
||||||
>
|
|
||||||
<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>
|
|
||||||
</motion.div>
|
</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>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{/* Feature Comparison */}
|
{/* Key advantages */}
|
||||||
<section className={'py-32'}>
|
<section className={'border-t border-neutral-200 bg-neutral-50/60'}>
|
||||||
<motion.div
|
<div className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10'}>
|
||||||
initial={{opacity: 0, y: 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'}>
|
||||||
whileInView={{opacity: 1, y: 0}}
|
<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>
|
||||||
viewport={{once: true}}
|
<p className={'mt-4 text-lg text-neutral-600'}>Built for modern developers, not enterprise sales teams</p>
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
</motion.div>
|
||||||
className={'mb-16 text-center'}
|
<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'}>
|
||||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>Feature-by-Feature Comparison</h2>
|
<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>
|
||||||
<p className={'mt-4 text-lg text-neutral-600'}>See exactly what you get with each platform</p>
|
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-6 text-xl font-bold tracking-[-0.02em] text-neutral-900'}>Simple, Transparent Pricing</h3>
|
||||||
</motion.div>
|
<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>
|
</section>
|
||||||
|
|
||||||
{/* FAQ */}
|
{/* FAQ */}
|
||||||
<FAQSection faqs={faqs} schemaId="faq-schema-sendgrid" />
|
<FAQSection faqs={faqs} schemaId="faq-schema-sendgrid" />
|
||||||
|
|
||||||
{/* CTA */}
|
{/* CTA */}
|
||||||
<section className={'relative overflow-hidden border-t border-neutral-200 py-32'}>
|
<section className={'relative overflow-hidden border-t border-neutral-900 bg-neutral-900 text-white'}>
|
||||||
<div
|
<div className={'mx-auto max-w-[88rem] px-6 py-32 sm:px-10 sm:py-40'}>
|
||||||
className={
|
<div className={'flex flex-col items-start gap-12 lg:flex-row lg:items-end lg:justify-between'}>
|
||||||
'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.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
|
<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'}>
|
||||||
initial={{opacity: 0, y: 20}}
|
<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>
|
||||||
whileInView={{opacity: 1, y: 0}}
|
<div className={'flex flex-wrap gap-3'}>
|
||||||
viewport={{once: true}}
|
<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'}>
|
||||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
Get started free <ArrowRight className="h-4 w-4" />
|
||||||
className={'mx-auto max-w-3xl text-center'}
|
</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'}>
|
||||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900 text-balance'}>Make the switch today</h2>
|
View pricing
|
||||||
<p className={'mt-6 text-lg text-neutral-600'}>
|
</Link>
|
||||||
Join hundreds of developers who've ditched SendGrid's complexity for Plunk's simplicity.
|
</div>
|
||||||
</p>
|
</motion.div>
|
||||||
<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>
|
|
||||||
</div>
|
</div>
|
||||||
</motion.div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</main>
|
|
||||||
|
|
||||||
|
</main>
|
||||||
<Footer />
|
<Footer />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -161,6 +161,26 @@
|
|||||||
|
|
||||||
body {
|
body {
|
||||||
@apply bg-background text-neutral-800;
|
@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;
|
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