1018 lines
49 KiB
TypeScript
1018 lines
49 KiB
TypeScript
import {Footer, Navbar, SectionHeader} from '../components';
|
|
import {motion} from 'framer-motion';
|
|
import {Bricolage_Grotesque, Hanken_Grotesk, JetBrains_Mono} from 'next/font/google';
|
|
import {DASHBOARD_URI, LANDING_URI, WIKI_URI} from '../lib/constants';
|
|
import React from 'react';
|
|
import Artur from '../../public/assets/artur.png';
|
|
import Joe from '../../public/assets/joe.png';
|
|
import Noah from '../../public/assets/noah.png';
|
|
import Pierre from '../../public/assets/pierre.png';
|
|
import Jonni from '../../public/assets/jonni.png';
|
|
import Alisson from '../../public/assets/alisson.png';
|
|
import Image from 'next/image';
|
|
import Script from 'next/script';
|
|
import Link from 'next/link';
|
|
import {
|
|
ArrowRight,
|
|
ArrowUpRight,
|
|
BarChart3,
|
|
Globe,
|
|
Inbox,
|
|
Mail,
|
|
Megaphone,
|
|
PackageOpen,
|
|
Send,
|
|
Shield,
|
|
User,
|
|
Users,
|
|
Workflow
|
|
} from 'lucide-react';
|
|
|
|
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 testimonials = [
|
|
{
|
|
testimonial: 'Transparent and intuitive UI, extremely easy setup & automation and great support.',
|
|
author: 'Artur Czemiel',
|
|
image: Artur,
|
|
role: 'Founder at GraphQL Editor',
|
|
featured: true,
|
|
},
|
|
{
|
|
testimonial: 'Lots of care put into Plunk',
|
|
author: 'Jonni Lundy',
|
|
image: Jonni,
|
|
role: 'Founding Operations Manager at Resend',
|
|
},
|
|
{
|
|
testimonial: "I've been using Plunk for building & sending out marketing emails and genuinely love it!",
|
|
author: 'Joe Ashwell',
|
|
image: Joe,
|
|
role: 'Founder at UnwindHR',
|
|
},
|
|
{
|
|
testimonial: 'I loved the ease of use, beautiful UI and great UX. Everything simply works.',
|
|
author: 'Alisson Leal',
|
|
image: Alisson,
|
|
role: 'Founder at Brapi',
|
|
},
|
|
{
|
|
testimonial: 'Simple to use, efficient and no regrets!',
|
|
author: 'Noah Di Gesu',
|
|
image: Noah,
|
|
role: 'Founder at Smoothey',
|
|
},
|
|
{
|
|
testimonial: 'Clean design, easy to understand, fair pricing.',
|
|
author: 'Pierre Jacquel',
|
|
image: Pierre,
|
|
role: 'Founder at Landingly',
|
|
},
|
|
];
|
|
|
|
const features = [
|
|
{
|
|
icon: <Workflow className="h-6 w-6" strokeWidth={1.5} />,
|
|
title: 'Workflow Automation',
|
|
description:
|
|
'Visual builder for complex email sequences with triggers, delays, and conditional logic. No code required.',
|
|
feature: true,
|
|
},
|
|
{
|
|
icon: <Users className="h-6 w-6" strokeWidth={1.5} />,
|
|
title: 'Dynamic Segments',
|
|
description: 'Real-time audience segmentation based on contact data and behavior.',
|
|
},
|
|
{
|
|
icon: <Mail className="h-6 w-6" strokeWidth={1.5} />,
|
|
title: 'Campaign Management',
|
|
description: 'Broadcast emails with scheduling and performance tracking.',
|
|
},
|
|
{
|
|
icon: <BarChart3 className="h-6 w-6" strokeWidth={1.5} />,
|
|
title: 'Analytics',
|
|
description: 'Detailed metrics on opens, clicks, bounces, and conversions across campaigns.',
|
|
},
|
|
{
|
|
icon: <Inbox className="h-6 w-6" strokeWidth={1.5} />,
|
|
title: 'Inbound Email',
|
|
description: 'Receive and process incoming emails with webhook notifications.',
|
|
},
|
|
{
|
|
icon: <Globe className="h-6 w-6" strokeWidth={1.5} />,
|
|
title: 'Custom Domains',
|
|
description: 'Brand consistency with DKIM authentication and custom sending domains.',
|
|
},
|
|
];
|
|
|
|
const competitors = [
|
|
{name: 'Resend', slug: 'resend'},
|
|
{name: 'SendGrid', slug: 'sendgrid'},
|
|
{name: 'Mailchimp', slug: 'mailchimp'},
|
|
{name: 'Customer.io', slug: 'customerio'},
|
|
{name: 'Mailgun', slug: 'mailgun'},
|
|
];
|
|
|
|
const tickerItems = [
|
|
'Open Source',
|
|
'AGPL-3.0',
|
|
'Self-Hostable',
|
|
'$0.001 / email',
|
|
'Unlimited Contacts',
|
|
'GDPR Compliant',
|
|
'5,000+ GitHub Stars',
|
|
'EU Hosted',
|
|
];
|
|
|
|
export default function Index() {
|
|
return (
|
|
<>
|
|
<Script
|
|
id={`faq-schema-index`}
|
|
type="application/ld+json"
|
|
dangerouslySetInnerHTML={{
|
|
__html: JSON.stringify({
|
|
'@context': 'https://schema.org',
|
|
'@type': 'FAQPage',
|
|
'mainEntity': [
|
|
{
|
|
'@type': 'Question',
|
|
'name': 'How is Plunk different from other email automation tools?',
|
|
'acceptedAnswer': {
|
|
'@type': 'Answer',
|
|
'text':
|
|
'Plunk is the email tool built for SaaS businesses, indie hackers and developers. Plunk allows you to create complex, automated email flows and to trigger them from anywhere through a single API call.',
|
|
},
|
|
},
|
|
{
|
|
'@type': 'Question',
|
|
'name': 'Can I use Plunk for transactional emails?',
|
|
'acceptedAnswer': {
|
|
'@type': 'Answer',
|
|
'text':
|
|
'Yes, Plunk is a full-fledged email tool that allows you to send transactional emails as well as marketing emails. You can use Plunk to send emails to your customers when they sign up, when they cancel their subscription, when they upgrade their plan, etc.',
|
|
},
|
|
},
|
|
{
|
|
'@type': 'Question',
|
|
'name': 'Can I use Plunk for sending newsletters?',
|
|
'acceptedAnswer': {
|
|
'@type': 'Answer',
|
|
'text':
|
|
'Yes, Plunk allows you to send newsletters and other broadcast emails to multiple contacts at once.',
|
|
},
|
|
},
|
|
{
|
|
'@type': 'Question',
|
|
'name': 'What programming languages and frameworks does Plunk support?',
|
|
'acceptedAnswer': {
|
|
'@type': 'Answer',
|
|
'text':
|
|
'Plunk supports all programming languages and frameworks that are capable of sending API calls. You can use Plunk to send emails from your backend, frontend, mobile app, or any other platform.',
|
|
},
|
|
},
|
|
{
|
|
'@type': 'Question',
|
|
'name': 'How much does Plunk cost?',
|
|
'acceptedAnswer': {
|
|
'@type': 'Answer',
|
|
'text':
|
|
'Plunk offers a free plan that includes 1000 emails per month. You can upgrade to a pay-as-you-go plan that costs $0.001 per email.',
|
|
},
|
|
},
|
|
],
|
|
}),
|
|
}}
|
|
/>
|
|
<Script
|
|
id={`corp-schema-index`}
|
|
type="application/ld+json"
|
|
dangerouslySetInnerHTML={{
|
|
__html: JSON.stringify({
|
|
'@context': 'https://schema.org',
|
|
'@type': 'Corporation',
|
|
'name': 'Plunk',
|
|
'alternateName': 'UsePlunk',
|
|
'url': LANDING_URI,
|
|
'logo': `${LANDING_URI}/assets/logo.png`,
|
|
'sameAs': ['https://www.twitter.com/useplunk', LANDING_URI],
|
|
}),
|
|
}}
|
|
/>
|
|
<Script
|
|
id={`software-schema-index`}
|
|
type="application/ld+json"
|
|
dangerouslySetInnerHTML={{
|
|
__html: JSON.stringify({
|
|
'@context': 'https://schema.org',
|
|
'@type': 'SoftwareApplication',
|
|
'name': 'Plunk',
|
|
'applicationCategory': 'Email Marketing Software',
|
|
'operatingSystem': 'Web, Docker',
|
|
'offers': {
|
|
'@type': 'Offer',
|
|
'price': '0',
|
|
'priceCurrency': 'USD',
|
|
'priceSpecification': {
|
|
'@type': 'UnitPriceSpecification',
|
|
'price': '0.001',
|
|
'priceCurrency': 'USD',
|
|
'unitText': 'email',
|
|
},
|
|
},
|
|
'featureList':
|
|
'Workflow Automation, Dynamic Segmentation, Campaign Management, Analytics, Developer API, Custom Domains, Self-Hosting, Open Source',
|
|
}),
|
|
}}
|
|
/>
|
|
|
|
<Navbar />
|
|
|
|
<div className={`${display.variable} ${body.variable} ${mono.variable}`}>
|
|
<main
|
|
className={'text-neutral-800'}
|
|
>
|
|
{/* ========== HERO ========== */}
|
|
<section className={'relative overflow-hidden'}>
|
|
<div
|
|
aria-hidden
|
|
className={
|
|
'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#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-24 pt-20 sm:px-10 sm:pt-28 lg:pb-36'}>
|
|
{/* Top meta row */}
|
|
<motion.div
|
|
initial={{opacity: 0, y: 8}}
|
|
animate={{opacity: 1, y: 0}}
|
|
transition={{duration: 0.5, ease: [0.22, 1, 0.36, 1]}}
|
|
style={{fontFamily: 'var(--font-mono)'}}
|
|
className={
|
|
'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={'font-medium text-neutral-900'}>§ 01 — Plunk</span>
|
|
</motion.div>
|
|
|
|
{/* Centered hero — single clear message, CTA directly below */}
|
|
<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(3rem,9vw,8rem)] font-extrabold leading-none tracking-[-0.04em] text-neutral-900'
|
|
}
|
|
>
|
|
The open-source
|
|
<br />
|
|
email platform
|
|
</h1>
|
|
<p className={'mx-auto mt-8 max-w-2xl text-lg leading-relaxed text-neutral-600 sm:text-xl'}>
|
|
Transactional emails, marketing campaigns, and workflow automation — in one platform. Self-hostable,
|
|
$0.001 per email, no contact limits.
|
|
</p>
|
|
|
|
<div className={'mt-10 flex flex-wrap justify-center gap-3'}>
|
|
<motion.a
|
|
whileHover={{scale: 1.015}}
|
|
whileTap={{scale: 0.985}}
|
|
href={`${DASHBOARD_URI}/auth/signup`}
|
|
className={
|
|
'group inline-flex items-center gap-2 rounded-full bg-neutral-900 px-8 py-4 text-base font-semibold text-white shadow-[0_10px_30px_-10px_rgba(23,23,23,0.35)] transition hover:bg-neutral-800'
|
|
}
|
|
>
|
|
Get started free
|
|
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-0.5" />
|
|
</motion.a>
|
|
<Link
|
|
href={WIKI_URI}
|
|
target={'_blank'}
|
|
rel={'noopener noreferrer'}
|
|
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'
|
|
}
|
|
>
|
|
Read the docs
|
|
</Link>
|
|
</div>
|
|
</motion.div>
|
|
|
|
{/* Stat strip */}
|
|
<motion.div
|
|
initial={{opacity: 0, y: 16}}
|
|
whileInView={{opacity: 1, y: 0}}
|
|
viewport={{once: true, margin: '-10%'}}
|
|
transition={{duration: 0.9, delay: 0.25, ease: [0.22, 1, 0.36, 1]}}
|
|
className={
|
|
'mt-20 grid grid-cols-2 gap-x-12 gap-y-10 border-t border-neutral-200 pt-10 sm:mt-28 sm:grid-cols-4 sm:gap-x-20'
|
|
}
|
|
>
|
|
{[
|
|
{value: '$0.001', label: 'per email, flat'},
|
|
{value: '5,000+', label: 'stars on GitHub'},
|
|
{value: '∞', label: 'contacts, always free'},
|
|
{value: '< 5min', label: 'to first email sent'},
|
|
].map(stat => (
|
|
<div key={stat.label} className={'flex flex-col gap-2'}>
|
|
<div
|
|
style={{fontFamily: 'var(--font-display)'}}
|
|
className={'text-4xl font-extrabold tracking-[-0.02em] text-neutral-900 sm:text-5xl'}
|
|
>
|
|
{stat.value}
|
|
</div>
|
|
<div
|
|
style={{fontFamily: 'var(--font-mono)'}}
|
|
className={'text-[11px] uppercase tracking-[0.18em] text-neutral-500'}
|
|
>
|
|
{stat.label}
|
|
</div>
|
|
</div>
|
|
))}
|
|
</motion.div>
|
|
</div>
|
|
</section>
|
|
|
|
{/* ========== MARQUEE TICKER ========== */}
|
|
<section className={'overflow-hidden border-y border-neutral-900 bg-neutral-900 py-7'} aria-hidden>
|
|
<div className={'flex'}>
|
|
<div className={'marquee-track flex shrink-0 items-center gap-14 whitespace-nowrap pr-14'}>
|
|
{[...tickerItems, ...tickerItems].map((item, i) => (
|
|
<span
|
|
key={i}
|
|
style={{fontFamily: 'var(--font-display)'}}
|
|
className={
|
|
'flex items-center gap-14 text-4xl font-semibold tracking-[-0.02em] text-white sm:text-5xl'
|
|
}
|
|
>
|
|
{item}
|
|
<span className={'text-neutral-600'}>✦</span>
|
|
</span>
|
|
))}
|
|
</div>
|
|
<div className={'marquee-track flex shrink-0 items-center gap-14 whitespace-nowrap pr-14'} aria-hidden>
|
|
{[...tickerItems, ...tickerItems].map((item, i) => (
|
|
<span
|
|
key={`b-${i}`}
|
|
style={{fontFamily: 'var(--font-display)'}}
|
|
className={
|
|
'flex items-center gap-14 text-4xl font-semibold tracking-[-0.02em] text-white sm:text-5xl'
|
|
}
|
|
>
|
|
{item}
|
|
<span className={'text-neutral-600'}>✦</span>
|
|
</span>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
{/* ========== COMPETITORS — EDITORIAL LIST ========== */}
|
|
<section className={'mx-auto max-w-[88rem] px-6 py-20 sm:px-10 sm:py-28'}>
|
|
<SectionHeader
|
|
number={'02'}
|
|
label={'The Alternatives'}
|
|
title={'Replace your email stack'}
|
|
subtitle={'One tool in place of Resend, SendGrid, Mailchimp, Customer.io, and Mailgun.'}
|
|
/>
|
|
|
|
<ul className={'mt-12 divide-y divide-neutral-200 border-y border-neutral-200'}>
|
|
{competitors.map((c, i) => (
|
|
<motion.li
|
|
key={c.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={`/vs/${c.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'}
|
|
>
|
|
{String(i + 1).padStart(3, '0')}
|
|
</span>
|
|
<span
|
|
style={{fontFamily: 'var(--font-display)'}}
|
|
className={
|
|
'text-4xl font-bold tracking-[-0.03em] text-neutral-900 transition-transform duration-300 group-hover:-translate-x-1 sm:text-6xl lg:text-7xl'
|
|
}
|
|
>
|
|
{c.name}
|
|
</span>
|
|
</div>
|
|
<div className={'flex items-center gap-4'}>
|
|
<span
|
|
style={{fontFamily: 'var(--font-mono)'}}
|
|
className={
|
|
'hidden text-xs uppercase tracking-[0.18em] text-neutral-500 transition group-hover:text-neutral-900 sm:inline'
|
|
}
|
|
>
|
|
vs Plunk
|
|
</span>
|
|
<span
|
|
className={
|
|
'flex h-11 w-11 items-center justify-center rounded-full border border-neutral-300 text-neutral-900 transition group-hover:border-neutral-900 group-hover:bg-neutral-900 group-hover:text-white sm:h-14 sm:w-14'
|
|
}
|
|
>
|
|
<ArrowUpRight className={'h-5 w-5'} strokeWidth={2} />
|
|
</span>
|
|
</div>
|
|
</Link>
|
|
</motion.li>
|
|
))}
|
|
</ul>
|
|
</section>
|
|
|
|
{/* ========== PROBLEM — THREE OVERSIZED STATEMENTS ========== */}
|
|
<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={'03'}
|
|
label={'The Problem'}
|
|
title={"Most email tools weren't built to scale."}
|
|
subtitle={'Three things Plunk gets right, out of the box.'}
|
|
/>
|
|
|
|
<div className={'mt-20 grid gap-10 sm:grid-cols-3 sm:gap-20 lg:gap-28'}>
|
|
{[
|
|
{
|
|
tag: 'Setup',
|
|
big: '< 5 min',
|
|
title: 'Zero-configuration start',
|
|
body: 'Most email platforms take days to configure. Plunk is running in under five minutes — domain, DKIM and first send.',
|
|
},
|
|
{
|
|
tag: 'Pricing',
|
|
big: '0 limits',
|
|
title: 'Pay per email, never per contact',
|
|
body: 'Other platforms charge more as your list grows. Plunk stores unlimited contacts for free and bills only on send.',
|
|
},
|
|
{
|
|
tag: 'Ownership',
|
|
big: 'AGPL-3.0',
|
|
title: 'No lock-in, ever',
|
|
body: 'Closed-source platforms own your stack. Plunk is fully inspectable, forkable, and self-hostable on your own infra.',
|
|
},
|
|
].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 lg:text-7xl'}
|
|
>
|
|
{item.big}
|
|
</div>
|
|
<div className={'h-px w-full bg-neutral-300'} />
|
|
<h3 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>
|
|
|
|
{/* ========== FEATURES — BENTO ========== */}
|
|
<section className={'mx-auto max-w-[88rem] px-6 py-28 sm:px-10 sm:py-36'}>
|
|
<SectionHeader
|
|
number={'04'}
|
|
label={'Capabilities'}
|
|
title={'Everything you need.'}
|
|
titleAccent={'Nothing you don\u2019t.'}
|
|
subtitle={'Every Plunk install ships with the full platform — no upsell pages, no locked modules.'}
|
|
/>
|
|
|
|
<div className={'mt-16 grid gap-5 sm:grid-cols-2 lg:grid-cols-3'}>
|
|
{features.map((feature, index) => {
|
|
const highlighted = feature.feature;
|
|
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-72 flex-col justify-between overflow-hidden rounded-[28px] border border-neutral-900 bg-neutral-900 p-8 text-white'
|
|
: 'flex min-h-72 flex-col justify-between overflow-hidden 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-10 text-2xl font-bold tracking-[-0.025em] ${
|
|
highlighted ? 'text-white' : 'text-neutral-900'
|
|
}`}
|
|
>
|
|
{feature.title}
|
|
</h3>
|
|
<p
|
|
className={`mt-3 text-sm leading-relaxed ${
|
|
highlighted ? 'text-neutral-300' : 'text-neutral-600'
|
|
}`}
|
|
>
|
|
{feature.description}
|
|
</p>
|
|
</div>
|
|
</motion.div>
|
|
);
|
|
})}
|
|
</div>
|
|
</section>
|
|
|
|
{/* ========== UNIFIED CONTACTS ========== */}
|
|
<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={'05'}
|
|
label={'Data Model'}
|
|
title={'One contact,'}
|
|
titleAccent={'complete history.'}
|
|
subtitle={
|
|
'Every interaction flows into a single contact record. Transactional, campaign and workflow events — one source of truth.'
|
|
}
|
|
/>
|
|
|
|
<div className={'mx-auto mt-20 max-w-5xl'}>
|
|
<div className={'grid gap-6 lg:grid-cols-3'}>
|
|
{[
|
|
{
|
|
icon: <Send className="h-7 w-7" strokeWidth={1.5} />,
|
|
title: 'Transactional',
|
|
sub: 'Receipts, resets',
|
|
},
|
|
{
|
|
icon: <Megaphone className="h-7 w-7" strokeWidth={1.5} />,
|
|
title: 'Campaigns',
|
|
sub: 'Newsletters, launches',
|
|
},
|
|
{
|
|
icon: <Workflow className="h-7 w-7" strokeWidth={1.5} />,
|
|
title: 'Workflows',
|
|
sub: 'Onboarding, drip sequences',
|
|
},
|
|
].map((item, i) => (
|
|
<motion.div
|
|
key={item.title}
|
|
initial={{opacity: 0, y: 16}}
|
|
whileInView={{opacity: 1, y: 0}}
|
|
viewport={{once: true}}
|
|
transition={{duration: 0.5, delay: 0.1 + i * 0.1, ease: [0.22, 1, 0.36, 1]}}
|
|
className={'rounded-[24px] border border-neutral-200 bg-white p-8 text-left'}
|
|
>
|
|
<div className={'text-neutral-900'}>{item.icon}</div>
|
|
<h3 style={{fontFamily: 'var(--font-display)'}} className={'mt-10 text-2xl font-bold tracking-[-0.02em] text-neutral-900'}>
|
|
{item.title}
|
|
</h3>
|
|
<p className={'mt-2 text-sm text-neutral-600'}>{item.sub}</p>
|
|
</motion.div>
|
|
))}
|
|
</div>
|
|
|
|
<div className={'relative my-12 hidden lg:block'}>
|
|
<svg className={'mx-auto h-28 w-full'} viewBox="0 0 600 120" preserveAspectRatio="none">
|
|
<defs>
|
|
<marker id="arrowhead" markerWidth="10" markerHeight="10" refX="9" refY="3" orient="auto">
|
|
<polygon points="0 0, 10 3, 0 6" fill="#a3a3a3" />
|
|
</marker>
|
|
</defs>
|
|
<motion.path
|
|
d="M 100 0 Q 150 60, 250 110"
|
|
stroke="#d4d4d4"
|
|
strokeWidth="1.5"
|
|
fill="none"
|
|
markerEnd="url(#arrowhead)"
|
|
initial={{pathLength: 0}}
|
|
whileInView={{pathLength: 1}}
|
|
viewport={{once: true}}
|
|
transition={{duration: 1.2, delay: 0.4, ease: [0.22, 1, 0.36, 1]}}
|
|
/>
|
|
<motion.path
|
|
d="M 300 0 L 300 110"
|
|
stroke="#d4d4d4"
|
|
strokeWidth="1.5"
|
|
fill="none"
|
|
markerEnd="url(#arrowhead)"
|
|
initial={{pathLength: 0}}
|
|
whileInView={{pathLength: 1}}
|
|
viewport={{once: true}}
|
|
transition={{duration: 1.2, delay: 0.5, ease: [0.22, 1, 0.36, 1]}}
|
|
/>
|
|
<motion.path
|
|
d="M 500 0 Q 450 60, 350 110"
|
|
stroke="#d4d4d4"
|
|
strokeWidth="1.5"
|
|
fill="none"
|
|
markerEnd="url(#arrowhead)"
|
|
initial={{pathLength: 0}}
|
|
whileInView={{pathLength: 1}}
|
|
viewport={{once: true}}
|
|
transition={{duration: 1.2, delay: 0.6, ease: [0.22, 1, 0.36, 1]}}
|
|
/>
|
|
</svg>
|
|
</div>
|
|
|
|
<motion.div
|
|
initial={{opacity: 0, y: 16}}
|
|
whileInView={{opacity: 1, y: 0}}
|
|
viewport={{once: true}}
|
|
transition={{duration: 0.8, delay: 0.9, ease: [0.22, 1, 0.36, 1]}}
|
|
className={'mx-auto max-w-xl'}
|
|
>
|
|
<div className={'overflow-hidden rounded-[20px] border border-neutral-200 bg-white'}>
|
|
<div className={'flex items-center gap-5 p-6'}>
|
|
<div
|
|
className={
|
|
'flex h-14 w-14 flex-shrink-0 items-center justify-center rounded-full bg-neutral-900'
|
|
}
|
|
>
|
|
<User className="h-7 w-7 text-white" strokeWidth={1.5} />
|
|
</div>
|
|
<div className={'flex-1 space-y-1'}>
|
|
<div
|
|
style={{fontFamily: 'var(--font-mono)'}}
|
|
className={'text-sm font-medium text-neutral-900'}
|
|
>
|
|
hello@useplunk.com
|
|
</div>
|
|
<div
|
|
style={{fontFamily: 'var(--font-mono)'}}
|
|
className={'text-[11px] uppercase tracking-[0.18em] text-neutral-500'}
|
|
>
|
|
CONTACT · ACTIVE
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div className={'grid grid-cols-3 gap-px border-t border-neutral-200 bg-neutral-200'}>
|
|
{[
|
|
{big: '1,247', small: 'Emails received'},
|
|
{big: '89%', small: 'Open rate'},
|
|
{big: '12', small: 'Workflows'},
|
|
].map(s => (
|
|
<div key={s.small} className={'bg-white px-4 py-4 text-center'}>
|
|
<div
|
|
style={{fontFamily: 'var(--font-display)'}}
|
|
className={'text-2xl font-bold tracking-[-0.02em] text-neutral-900'}
|
|
>
|
|
{s.big}
|
|
</div>
|
|
<div
|
|
style={{fontFamily: 'var(--font-mono)'}}
|
|
className={'mt-1 text-[10px] uppercase tracking-[0.18em] text-neutral-500'}
|
|
>
|
|
{s.small}
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</motion.div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
{/* ========== OPEN SOURCE ========== */}
|
|
<section className={'mx-auto max-w-[88rem] px-6 py-28 sm:px-10 sm:py-36'}>
|
|
<SectionHeader
|
|
number={'06'}
|
|
label={'Open Source'}
|
|
title={'Privacy first.'}
|
|
titleAccent={'Code visible.'}
|
|
subtitle={'AGPL-3.0 licensed, EU-hosted, GDPR compliant. Inspect the code, self-host, or use our cloud.'}
|
|
/>
|
|
|
|
<div className={'mt-14 grid gap-5 sm:grid-cols-3'}>
|
|
{[
|
|
{
|
|
icon: <PackageOpen className="h-8 w-8" strokeWidth={1.25} />,
|
|
title: 'Open Source',
|
|
meta: 'AGPL-3.0',
|
|
note: '5,000+ stars on GitHub',
|
|
},
|
|
{
|
|
icon: <Shield className="h-8 w-8" strokeWidth={1.25} />,
|
|
title: 'Privacy First',
|
|
meta: 'EU hosted',
|
|
note: 'GDPR compliant',
|
|
},
|
|
{
|
|
icon: <Globe className="h-8 w-8" strokeWidth={1.25} />,
|
|
title: 'Self-Hostable',
|
|
meta: 'Deploy anywhere',
|
|
note: 'Docker Compose ready',
|
|
},
|
|
].map((item, i) => (
|
|
<motion.div
|
|
key={item.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={'flex flex-col gap-8 rounded-[24px] border border-neutral-200 bg-white p-10'}
|
|
>
|
|
<div className={'flex items-start justify-between'}>
|
|
<div className={'text-neutral-900'}>{item.icon}</div>
|
|
<span
|
|
style={{fontFamily: 'var(--font-mono)'}}
|
|
className={'text-[11px] uppercase tracking-[0.18em] text-neutral-400'}
|
|
>
|
|
{item.meta}
|
|
</span>
|
|
</div>
|
|
<div>
|
|
<h3 style={{fontFamily: 'var(--font-display)'}} className={'text-2xl font-bold tracking-[-0.02em] text-neutral-900'}>
|
|
{item.title}
|
|
</h3>
|
|
<p className={'mt-2 text-sm text-neutral-600'}>{item.note}</p>
|
|
</div>
|
|
</motion.div>
|
|
))}
|
|
</div>
|
|
|
|
<div className={'mt-12 flex justify-center'}>
|
|
<motion.a
|
|
whileHover={{scale: 1.02}}
|
|
whileTap={{scale: 0.98}}
|
|
href={'https://github.com/useplunk/plunk'}
|
|
target={'_blank'}
|
|
rel={'noopener noreferrer'}
|
|
className={
|
|
'group inline-flex items-center gap-2 rounded-full border border-neutral-300 bg-white px-7 py-3.5 text-sm font-semibold text-neutral-900 transition hover:border-neutral-900'
|
|
}
|
|
>
|
|
View on GitHub
|
|
<ArrowUpRight className="h-4 w-4 transition-transform group-hover:-translate-y-0.5 group-hover:translate-x-0.5" />
|
|
</motion.a>
|
|
</div>
|
|
</section>
|
|
|
|
{/* ========== PRICING — BIG MOMENT ========== */}
|
|
<section className={'border-t border-neutral-200 bg-neutral-50/60'}>
|
|
<div className={'mx-auto max-w-[88rem] px-6 py-40 sm:px-10 sm:py-56'}>
|
|
<SectionHeader
|
|
number={'07'}
|
|
label={'Pricing'}
|
|
title={'Simple.'}
|
|
titleAccent={'Transparent.'}
|
|
subtitle={'Pay for what you send, nothing more. No tiers. No surprises at scale.'}
|
|
/>
|
|
|
|
<motion.div
|
|
initial={{opacity: 0, y: 24}}
|
|
whileInView={{opacity: 1, y: 0}}
|
|
viewport={{once: true}}
|
|
transition={{duration: 0.9, ease: [0.22, 1, 0.36, 1]}}
|
|
className={'mt-24 text-center'}
|
|
>
|
|
<div className={'flex items-baseline justify-center gap-3 text-neutral-900'}>
|
|
<span
|
|
style={{fontFamily: 'var(--font-display)'}}
|
|
className={'text-7xl font-extrabold tracking-[-0.035em] sm:text-8xl'}
|
|
>
|
|
$0.001
|
|
</span>
|
|
<span className={'text-xl text-neutral-500 sm:text-2xl'}>/email</span>
|
|
</div>
|
|
<div className={'mx-auto mt-16 max-w-4xl'}>
|
|
<p
|
|
style={{fontFamily: 'var(--font-mono)'}}
|
|
className={'mb-8 text-[11px] uppercase tracking-[0.2em] text-neutral-500'}
|
|
>
|
|
For the same plan, others charge
|
|
</p>
|
|
<div className={'grid gap-8 sm:grid-cols-3'}>
|
|
<div className={'flex flex-col items-center gap-y-2'}>
|
|
<svg role="img" className="h-8 w-8" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
|
<title>Mailchimp</title>
|
|
<path d="M11.267 0C6.791-.015-1.82 10.246 1.397 12.964l.79.669a3.88 3.88 0 0 0-.22 1.792c.084.84.518 1.644 1.22 2.266.666.59 1.542.964 2.392.964 1.406 3.24 4.62 5.228 8.386 5.34 4.04.12 7.433-1.776 8.854-5.182.093-.24.488-1.316.488-2.267 0-.956-.54-1.352-.885-1.352-.01-.037-.078-.286-.172-.586-.093-.3-.19-.51-.19-.51.375-.563.382-1.065.332-1.35-.053-.353-.2-.653-.496-.964-.296-.311-.902-.63-1.753-.868l-.446-.124c-.002-.019-.024-1.053-.043-1.497-.014-.32-.042-.822-.197-1.315-.186-.668-.508-1.253-.911-1.627 1.112-1.152 1.806-2.422 1.804-3.511-.003-2.095-2.576-2.729-5.746-1.416l-.672.285A678.22 678.22 0 0 0 12.7.504C12.304.159 11.817.002 11.267 0zm.073.873c.166 0 .322.019.465.058.297.084 1.28 1.224 1.28 1.224s-1.826 1.013-3.52 2.426c-2.28 1.757-4.005 4.311-5.037 7.082-.811.158-1.526.618-1.963 1.253-.261-.218-.748-.64-.834-.804-.698-1.326.761-3.902 1.781-5.357C5.834 3.44 9.37.867 11.34.873zm3.286 3.273c.04-.002.06.05.028.074-.143.11-.299.26-.413.414a.04.04 0 0 0 .031.064c.659.004 1.587.235 2.192.574.041.023.012.103-.034.092-.915-.21-2.414-.369-3.97.01-1.39.34-2.45.863-3.224 1.426-.04.028-.086-.023-.055-.06.896-1.035 1.999-1.935 2.987-2.44.034-.018.07.019.052.052-.079.143-.23.447-.278.678-.007.035.032.063.062.042.615-.42 1.684-.868 2.622-.926zm3.023 3.205l.056.001a.896.896 0 0 1 .456.146c.534.355.61 1.216.638 1.845.015.36.059 1.229.074 1.478.034.571.184.651.487.751.17.057.33.098.563.164.706.198 1.125.4 1.39.658.157.162.23.333.253.497.083.608-.472 1.36-1.942 2.041-1.607.746-3.557.935-4.904.785l-.471-.053c-1.078-.145-1.693 1.247-1.046 2.201.417.615 1.552 1.015 2.688 1.015 2.604 0 4.605-1.111 5.35-2.072a.987.987 0 0 0 .06-.085c.036-.055.006-.085-.04-.054-.608.416-3.31 2.069-6.2 1.571 0 0-.351-.057-.672-.182-.255-.1-.788-.344-.853-.891 2.333.72 3.801.039 3.801.039a.072.072 0 0 0 .042-.072.067.067 0 0 0-.074-.06s-1.911.283-3.718-.378c.197-.64.72-.408 1.51-.345a11.045 11.045 0 0 0 3.647-.394c.818-.234 1.892-.697 2.727-1.356.281.618.38 1.299.38 1.299s.219-.04.4.073c.173.106.299.326.213.895-.176 1.063-.628 1.926-1.387 2.72a5.714 5.714 0 0 1-1.666 1.244c-.34.18-.704.334-1.087.46-2.863.935-5.794-.093-6.739-2.3a3.545 3.545 0 0 1-.189-.522c-.403-1.455-.06-3.2 1.008-4.299.065-.07.132-.153.132-.256 0-.087-.055-.179-.102-.243-.374-.543-1.669-1.466-1.409-3.254.187-1.284 1.31-2.189 2.357-2.135.089.004.177.01.266.015.453.027.85.085 1.223.1.625.028 1.187-.063 1.853-.618.225-.187.405-.35.71-.401.028-.005.092-.028.215-.028zm.022 2.18a.42.42 0 0 0-.06.005c-.335.054-.347.468-.228 1.04.068.32.187.595.32.765.175-.02.343-.022.498 0 .089-.205.104-.557.024-.942-.112-.535-.261-.872-.554-.868zm-3.66 1.546a1.724 1.724 0 0 0-1.016.326c-.16.117-.311.28-.29.378.008.032.031.056.088.063.131.015.592-.217 1.122-.25.374-.023.684.094.923.2.239.104.386.173.443.113.037-.038.026-.11-.031-.204-.118-.192-.36-.387-.618-.497a1.601 1.601 0 0 0-.621-.129zm4.082.81c-.171-.003-.313.186-.317.42-.004.236.131.43.303.432.172.003.314-.185.318-.42.004-.236-.132-.429-.304-.432zm-3.58.172c-.05 0-.102.002-.155.008-.311.05-.483.152-.593.247-.094.082-.152.173-.152.237a.075.075 0 0 0 .075.076c.07 0 .228-.063.228-.063a1.98 1.98 0 0 1 1.001-.104c.157.018.23.027.265-.026.01-.016.022-.049-.01-.1-.063-.103-.311-.269-.66-.275zm2.26.4c-.127 0-.235.051-.283.148-.075.154.035.363.246.466.21.104.443.063.52-.09.075-.155-.035-.364-.246-.467a.542.542 0 0 0-.237-.058zm-11.635.024c.048 0 .098 0 .149.003.73.04 1.806.6 2.052 2.19.217 1.41-.128 2.843-1.449 3.069-.123.02-.248.029-.374.026-1.22-.033-2.539-1.132-2.67-2.435-.145-1.44.591-2.548 1.894-2.811.117-.024.252-.04.398-.042zm-.07.927a1.144 1.144 0 0 0-.847.364c-.38.418-.439.988-.366 1.19.027.073.07.094.1.098.064.008.16-.039.22-.2a1.2 1.2 0 0 0 .017-.052 1.58 1.58 0 0 1 .157-.37.689.689 0 0 1 .955-.199c.266.174.369.5.255.81-.058.161-.154.469-.133.721.043.511.357.717.64.738.274.01.466-.143.515-.256.029-.067.005-.107-.011-.125-.043-.053-.113-.037-.18-.021a.638.638 0 0 1-.16.022.347.347 0 0 1-.294-.148c-.078-.12-.073-.3.013-.504.011-.028.025-.058.04-.092.138-.308.368-.825.11-1.317-.195-.37-.513-.602-.894-.65a1.135 1.135 0 0 0-.138-.01z"></path>
|
|
</svg>
|
|
<span className={'text-sm font-semibold text-neutral-900'}>Mailchimp</span>
|
|
<span className={'text-sm text-neutral-500'}>$0.004 / email</span>
|
|
</div>
|
|
<div className={'flex flex-col items-center gap-y-2'}>
|
|
<svg role="img" viewBox="0 0 24 24" className="h-8 w-8" xmlns="http://www.w3.org/2000/svg">
|
|
<title>Twilio SendGrid</title>
|
|
<path d="M12 0C5.381-.008.008 5.352 0 11.971V12c0 6.64 5.359 12 12 12 6.64 0 12-5.36 12-12 0-6.641-5.36-12-12-12zm0 20.801c-4.846.015-8.786-3.904-8.801-8.75V12c-.014-4.846 3.904-8.786 8.75-8.801H12c4.847-.014 8.786 3.904 8.801 8.75V12c.015 4.847-3.904 8.786-8.75 8.801H12zm5.44-11.76c0 1.359-1.12 2.479-2.481 2.479-1.366-.007-2.472-1.113-2.479-2.479 0-1.361 1.12-2.481 2.479-2.481 1.361 0 2.481 1.12 2.481 2.481zm0 5.919c0 1.36-1.12 2.48-2.481 2.48-1.367-.008-2.473-1.114-2.479-2.48 0-1.359 1.12-2.479 2.479-2.479 1.361-.001 2.481 1.12 2.481 2.479zm-5.919 0c0 1.36-1.12 2.48-2.479 2.48-1.368-.007-2.475-1.113-2.481-2.48 0-1.359 1.12-2.479 2.481-2.479 1.358-.001 2.479 1.12 2.479 2.479zm0-5.919c0 1.359-1.12 2.479-2.479 2.479-1.367-.007-2.475-1.112-2.481-2.479 0-1.361 1.12-2.481 2.481-2.481 1.358 0 2.479 1.12 2.479 2.481z"></path>
|
|
</svg>
|
|
<span className={'text-sm font-semibold text-neutral-900'}>SendGrid</span>
|
|
<span className={'text-sm text-neutral-500'}>$0.002 / email</span>
|
|
</div>
|
|
<div className={'flex flex-col items-center gap-y-2'}>
|
|
<svg role="img" viewBox="0 0 24 24" className="h-8 w-8" xmlns="http://www.w3.org/2000/svg">
|
|
<title>Mailgun</title>
|
|
<path d="M11.837 0c6.602 0 11.984 5.381 11.984 11.994-.017 2.99-3.264 4.84-5.844 3.331a3.805 3.805 0 0 1-.06-.035l-.055-.033-.022.055c-2.554 4.63-9.162 4.758-11.894.232-2.732-4.527.46-10.313 5.746-10.416a6.868 6.868 0 0 1 7.002 6.866 1.265 1.265 0 0 0 2.52 0c0-5.18-4.197-9.38-9.377-9.387C4.611 2.594.081 10.41 3.683 16.673c3.238 5.632 11.08 6.351 15.289 1.402l1.997 1.686A11.95 11.95 0 0 1 11.837 24C2.6 23.72-2.87 13.543 1.992 5.684A12.006 12.006 0 0 1 11.837 0Zm0 7.745c-3.276-.163-5.5 3.281-4.003 6.2a4.26 4.26 0 0 0 4.014 2.31c3.276-.171 5.137-3.824 3.35-6.575a4.26 4.26 0 0 0-3.36-1.935Zm0 2.53c1.324 0 2.152 1.433 1.49 2.58a1.72 1.72 0 0 1-1.49.86 1.72 1.72 0 1 1 0-3.44Z"></path>
|
|
</svg>
|
|
<span className={'text-sm font-semibold text-neutral-900'}>Mailgun</span>
|
|
<span className={'text-sm text-neutral-500'}>$0.003 / email</span>
|
|
</div>
|
|
</div>
|
|
<p className={'mt-8 text-xs text-neutral-400'}>
|
|
Based on plans matching Plunk at 10,000 emails per month.
|
|
</p>
|
|
</div>
|
|
|
|
<div className={'mt-16 flex flex-wrap justify-center gap-3'}>
|
|
<Link
|
|
href={'/pricing'}
|
|
className={
|
|
'rounded-full border border-neutral-300 bg-white px-7 py-3.5 text-sm font-semibold text-neutral-900 transition hover:border-neutral-900'
|
|
}
|
|
>
|
|
Pricing details
|
|
</Link>
|
|
<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-neutral-900 px-7 py-3.5 text-sm font-semibold text-white transition hover:bg-neutral-800'
|
|
}
|
|
>
|
|
Start for free
|
|
<ArrowRight className="h-4 w-4" />
|
|
</motion.a>
|
|
</div>
|
|
</motion.div>
|
|
</div>
|
|
</section>
|
|
|
|
{/* ========== TESTIMONIALS — BENTO ========== */}
|
|
<section className={'mx-auto max-w-[88rem] px-6 py-28 sm:px-10 sm:py-36'}>
|
|
<SectionHeader
|
|
number={'08'}
|
|
label={'Trust'}
|
|
title={'Quiet praise,'}
|
|
titleAccent={'from operators.'}
|
|
subtitle={'No hyperbole. Just the people building products on Plunk.'}
|
|
/>
|
|
|
|
<div className={'mt-16 grid gap-5 sm:grid-cols-2 lg:grid-cols-3'}>
|
|
{testimonials.map((t, i) => {
|
|
const highlighted = t.featured;
|
|
return (
|
|
<motion.figure
|
|
key={t.author}
|
|
initial={{opacity: 0, y: 16}}
|
|
whileInView={{opacity: 1, y: 0}}
|
|
viewport={{once: true}}
|
|
transition={{duration: 0.5, delay: i * 0.06, ease: [0.22, 1, 0.36, 1]}}
|
|
className={
|
|
highlighted
|
|
? 'flex min-h-72 flex-col justify-between rounded-[28px] border border-neutral-900 bg-neutral-900 p-8 text-white'
|
|
: 'flex min-h-72 flex-col justify-between rounded-[28px] border border-neutral-200 bg-white p-8'
|
|
}
|
|
>
|
|
<blockquote
|
|
style={highlighted ? {fontFamily: 'var(--font-display)'} : undefined}
|
|
className={
|
|
highlighted
|
|
? 'text-xl font-medium leading-[1.2] tracking-[-0.015em] text-white sm:text-2xl'
|
|
: 'text-sm leading-relaxed text-neutral-700'
|
|
}
|
|
>
|
|
“{t.testimonial}”
|
|
</blockquote>
|
|
<figcaption className={'mt-6 flex items-center gap-3'}>
|
|
<div
|
|
className={`relative h-10 w-10 overflow-hidden rounded-full ${
|
|
highlighted ? 'border border-neutral-700' : ''
|
|
}`}
|
|
>
|
|
<Image src={t.image} alt={t.author} placeholder="blur" className={'object-cover'} />
|
|
</div>
|
|
<div>
|
|
<div className={`text-xs font-semibold ${highlighted ? 'text-white' : 'text-neutral-900'}`}>
|
|
{t.author}
|
|
</div>
|
|
<div
|
|
style={{fontFamily: 'var(--font-mono)'}}
|
|
className={`mt-0.5 text-[10px] uppercase tracking-[0.18em] ${
|
|
highlighted ? 'text-neutral-400' : 'text-neutral-500'
|
|
}`}
|
|
>
|
|
{t.role}
|
|
</div>
|
|
</div>
|
|
</figcaption>
|
|
</motion.figure>
|
|
);
|
|
})}
|
|
</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]'
|
|
}
|
|
>
|
|
Start sending in 5 minutes.
|
|
</motion.h2>
|
|
|
|
<motion.div
|
|
initial={{opacity: 0, y: 16}}
|
|
whileInView={{opacity: 1, y: 0}}
|
|
viewport={{once: true}}
|
|
transition={{duration: 0.9, delay: 0.15, ease: [0.22, 1, 0.36, 1]}}
|
|
className={'flex max-w-md flex-col gap-6'}
|
|
>
|
|
<p className={'text-base text-neutral-300 sm:text-lg'}>
|
|
Free plan available. $0.001 per email on paid. No contact limits, no surprises.
|
|
</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={WIKI_URI}
|
|
target={'_blank'}
|
|
rel={'noopener noreferrer'}
|
|
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'
|
|
}
|
|
>
|
|
Read the docs
|
|
</Link>
|
|
</div>
|
|
</motion.div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
</main>
|
|
</div>
|
|
|
|
<Footer />
|
|
</>
|
|
);
|
|
}
|
|
|