Landing Pattern 03
Style direction: Reference landing study
$ npx cactus add oclave
Copied!
Aa
InterDisplay
Aa
InterBody
Recreate Site Spec (Exact Current Implementation)
Use this document to recreate the current site exactly. The design token variables are defined first, then each section/component is listed with full code.
Design Values Vars (Shadcn-style)
Path: index.css
@import "tailwindcss";
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;700&display=swap');
:root {
--background: #ffffff;
--foreground: #111111;
--card: #f7f7f7;
--card-foreground: #111111;
--popover: #ffffff;
--popover-foreground: #111111;
--primary: #1258fd;
--primary-foreground: #ffffff;
--secondary: #f2f5ff;
--secondary-foreground: #111111;
--muted: #f7f7f7;
--muted-foreground: #666666;
--accent: #e8efff;
--accent-foreground: #111111;
--destructive: #dc2626;
--destructive-foreground: #ffffff;
--border: #dddddd;
--input: #dddddd;
--ring: #1258fd;
--chart-1: #1258fd;
--chart-2: #3b82f6;
--chart-3: #22c55e;
--chart-4: #eab308;
--chart-5: #f97316;
--radius: 0.75rem;
--sidebar: #f7f7f7;
--sidebar-foreground: #111111;
--sidebar-primary: #1258fd;
--sidebar-primary-foreground: #ffffff;
--sidebar-accent: #e8efff;
--sidebar-accent-foreground: #111111;
--sidebar-border: #dddddd;
--sidebar-ring: #1258fd;
}
@theme inline {
--color-background: var(--background);
--color-foreground: var(--foreground);
--color-card: var(--card);
--color-card-foreground: var(--card-foreground);
--color-popover: var(--popover);
--color-popover-foreground: var(--popover-foreground);
--color-primary: var(--primary);
--color-primary-foreground: var(--primary-foreground);
--color-secondary: var(--secondary);
--color-secondary-foreground: var(--secondary-foreground);
--color-muted: var(--muted);
--color-muted-foreground: var(--muted-foreground);
--color-accent: var(--accent);
--color-accent-foreground: var(--accent-foreground);
--color-destructive: var(--destructive);
--color-destructive-foreground: var(--destructive-foreground);
--color-border: var(--border);
--color-input: var(--input);
--color-ring: var(--ring);
--color-chart-1: var(--chart-1);
--color-chart-2: var(--chart-2);
--color-chart-3: var(--chart-3);
--color-chart-4: var(--chart-4);
--color-chart-5: var(--chart-5);
--radius-sm: calc(var(--radius) - 4px);
--radius-md: calc(var(--radius) - 2px);
--radius-lg: var(--radius);
--radius-xl: calc(var(--radius) + 4px);
--color-sidebar: var(--sidebar);
--color-sidebar-foreground: var(--sidebar-foreground);
--color-sidebar-primary: var(--sidebar-primary);
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
--color-sidebar-accent: var(--sidebar-accent);
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
--color-sidebar-border: var(--sidebar-border);
--color-sidebar-ring: var(--sidebar-ring);
}
App Shell Composition
Path: App.tsx
import { BenefitsSection } from './components/BenefitsSection'
import { CtaSection } from './components/CtaSection'
import { FeaturesSection } from './components/FeaturesSection'
import { FooterSection } from './components/FooterSection'
import { HeroSection } from './components/HeroSection'
import { Navbar } from './components/Navbar'
import { PricingSection } from './components/PricingSection'
import { TestimonialsSection } from './components/TestimonialsSection'
import { UseCasesSection } from './components/UseCasesSection'
function App() {
return (
<div className="relative overflow-x-clip bg-background font-[Inter] text-foreground">
<div className="pointer-events-none absolute inset-x-0 top-0 h-[1214px] min-[810px]:h-[1585px]">
<div className="absolute inset-0 bg-primary min-[810px]:hidden" />
<div className="absolute inset-0 bg-[linear-gradient(180deg,#8fb0fe_0%,#1258fd_10%,#1258fd_60%,#e4ecff_70%,#ffffff_77%,#ffffff_100%)] min-[810px]:hidden" />
<div className="absolute inset-0 hidden bg-primary min-[810px]:block" />
<div className="absolute inset-0 hidden bg-[linear-gradient(180deg,#1e61fd_0%,#1258fd_8%,#1258fd_66%,#e3ebff_74%,#ffffff_82%,#ffffff_100%)] min-[810px]:block" />
</div>
<Navbar />
<main className="relative z-10">
<HeroSection />
<FeaturesSection />
<BenefitsSection />
<UseCasesSection />
<TestimonialsSection />
<PricingSection />
<CtaSection />
</main>
<div className="relative z-10">
<FooterSection />
</div>
</div>
)
}
export default App
Shared Button Style
Path: lib/buttonStyles.ts
export const darkGradientButtonClass =
'relative overflow-hidden border border-primary-foreground/15 bg-[linear-gradient(180deg,#1f2025_0%,#121317_58%,#0a0a0d_100%)] text-primary-foreground shadow-[0_8px_20px_rgba(0,0,0,0.24),inset_0_1px_0_rgba(255,255,255,0.12)] transition-[box-shadow,transform] duration-200 ease-out after:pointer-events-none after:absolute after:inset-0 after:rounded-[inherit] after:bg-[linear-gradient(180deg,rgba(255,255,255,0.2)_0%,rgba(255,255,255,0)_55%)] after:opacity-75 after:transition-opacity after:duration-200 hover:after:opacity-100 hover:shadow-[0_10px_22px_rgba(0,0,0,0.28),inset_0_1px_0_rgba(255,255,255,0.16)]'
Content + Asset Data
Path: content.ts
import avatar1 from './assets/avatars/avatar-1.jpg'
import avatar2 from './assets/avatars/avatar-2.jpg'
import avatar3 from './assets/avatars/avatar-3.jpg'
import avatar4 from './assets/avatars/avatar-4.jpg'
import avatar5 from './assets/avatars/avatar-5.jpg'
import avatar6 from './assets/avatars/avatar-6.jpg'
import benefitsLeftImage from './assets/images/benefits-left.png'
import benefitsRightImage from './assets/images/benefits-right.png'
import ctaImage from './assets/images/cta.png'
import featuresImage from './assets/images/features.png'
import heroImage from './assets/images/hero.png'
import useCasesImage from './assets/images/use-cases.png'
export const imageAssets = {
hero: heroImage,
features: featuresImage,
benefitsLeft: benefitsLeftImage,
benefitsRight: benefitsRightImage,
useCases: useCasesImage,
cta: ctaImage,
}
export const testimonials = [
{
quote:
'"Drafting, feedback, and SEO used to live in separate tools. This platform brought everything together into a single workflow, reduced friction between teams, and made our publishing process far more predictable."',
name: 'Daniel Moore',
role: 'Growth Lead',
avatar: avatar1,
},
{
quote:
'"Our writers collaborate more confidently because expectations, feedback, and revisions are always visible. Everyone knows what to do next, which has improved both speed and quality."',
name: 'Mr. Rahman',
role: 'Editorial Lead',
avatar: avatar2,
},
{
quote:
'"Client approvals are faster and more professional now. Stakeholders can comment directly on the draft, and nothing gets lost in emails or messages."',
name: 'Laur Góm',
role: 'SEO Specialist',
avatar: avatar3,
},
{
quote:
'"The SEO guidance helps us optimize content before publishing, not after. That alone has improved our search performance and saved hours per post."',
name: 'Michael Chen',
role: 'Agency Owner',
avatar: avatar4,
},
{
quote:
'"We increased publishing consistency without hiring more writers. Our existing team simply works better together."',
name: 'Nadia Islam',
role: 'Marketing Director',
avatar: avatar5,
},
{
quote:
'"New writers ramp up quickly because the structure, comments, and examples are already there. Onboarding time has dropped significantly."',
name: 'Priya Patel',
role: 'Product Marketer',
avatar: avatar6,
},
]
Section: Navbar
Path: components/Navbar.tsx
import { darkGradientButtonClass } from '../lib/buttonStyles'
const links = [
{ label: 'Features', href: '#features-section' },
{ label: 'Benefits', href: '#benefits-section' },
{ label: 'Use Cases', href: '#use-cases-section' },
{ label: 'Testimonials', href: '#testimonial-section' },
]
export function Navbar() {
return (
<header className="fixed inset-x-0 top-0 z-50 border-b border-primary-foreground/20 bg-background/5 backdrop-blur-[18px]">
<div className="mx-auto flex h-[70px] w-full max-w-[1200px] items-center justify-between px-5 min-[810px]:px-0">
<a className="flex items-center gap-2 text-primary-foreground" href="#">
<span className="relative inline-block h-5 w-5 rounded-full border border-primary-foreground/70">
<span className="absolute left-[3px] top-[8px] h-[2px] w-[12px] -rotate-[35deg] bg-background/90" />
</span>
<span className="text-[19px] font-semibold tracking-[-0.02em]">Clave</span>
</a>
<nav className="hidden items-center gap-9 min-[810px]:flex">
{links.map((link) => (
<a className="text-[14px] font-medium text-primary-foreground" href={link.href} key={link.label}>
{link.label}
</a>
))}
</nav>
<a
className={`${darkGradientButtonClass} hidden h-12 items-center rounded-xl px-4 text-[16px] font-medium min-[810px]:inline-flex`}
href="#pricing-section"
>
Get Started
</a>
<button
aria-label="Menu button"
className="inline-flex h-10 w-10 items-center justify-center rounded-[10px] border border-primary-foreground/25 bg-background/10 text-primary-foreground min-[810px]:hidden"
type="button"
>
<span className="block h-[2px] w-[16px] bg-primary-foreground shadow-[0_6px_0_0_var(--primary-foreground),0_-6px_0_0_var(--primary-foreground)]" />
</button>
</div>
</header>
)
}
Section: Hero
Path: components/HeroSection.tsx
import { imageAssets } from '../content'
import logoGrid1 from '../assets/logos/logo-grid-1.svg'
import logoGrid2 from '../assets/logos/logo-grid-2.svg'
import logoGrid3 from '../assets/logos/logo-grid-3.svg'
import logoGrid4 from '../assets/logos/logo-grid-4.svg'
import logoGrid5 from '../assets/logos/logo-grid-5.svg'
import logoGrid6 from '../assets/logos/logo-grid-6.svg'
import logoGrid7 from '../assets/logos/logo-grid-7.svg'
import logoGrid8 from '../assets/logos/logo-grid-8.svg'
import { darkGradientButtonClass } from '../lib/buttonStyles'
const desktopLogos = [
{ src: logoGrid1, width: 96 },
{ src: logoGrid2, width: 104 },
{ src: logoGrid3, width: 96 },
{ src: logoGrid4, width: 64 },
{ src: logoGrid5, width: 130 },
{ src: logoGrid6, width: 108 },
{ src: logoGrid7, width: 136 },
{ src: logoGrid8, width: 130 },
]
const mobileLogos = [
{ src: logoGrid1, width: 88 },
{ src: logoGrid2, width: 93 },
{ src: logoGrid3, width: 86 },
{ src: logoGrid4, width: 54 },
{ src: logoGrid5, width: 86 },
{ src: logoGrid6, width: 72 },
{ src: logoGrid7, width: 88 },
{ src: logoGrid8, width: 86 },
]
export function HeroSection() {
return (
<section className="relative min-h-[1214px] px-5 pt-[124px] min-[810px]:min-h-[1585px] min-[810px]:px-0 min-[810px]:pt-[174px]" id="hero-section">
<div className="mx-auto flex w-full max-w-[1440px] flex-col items-start gap-14 px-5 min-[810px]:gap-16 min-[810px]:px-[120px]">
<div className="flex w-full max-w-[680px] flex-col items-start gap-5 text-left min-[810px]:gap-6">
<div className="rounded-xl border border-border bg-card px-3 py-2 text-[14px] font-medium text-foreground">
⚡ Version 2.3 is live now
</div>
<h1 className="max-w-[350px] text-[43.56px] font-medium leading-[1.1] tracking-[-0.03em] text-primary-foreground min-[810px]:max-w-[640px] min-[810px]:text-[58px]">
Create high-quality blogs faster, with your team.
</h1>
<p className="max-w-[350px] text-[16px] font-medium leading-[1.65] text-primary-foreground min-[810px]:max-w-[640px]">
Plan, write, and publish high‑quality blog content with your team in one focused workspace.
Drafts, feedback, and approvals stay aligned from first outline.
</p>
<div className="flex flex-wrap items-center justify-start gap-3">
<a
className="flex h-12 items-center rounded-xl border border-border bg-card px-4 text-[16px] font-medium text-foreground"
href="#features-section"
>
See how it works
</a>
<a
className={`${darkGradientButtonClass} flex h-12 items-center rounded-xl px-4 text-[16px] font-medium`}
href="#pricing-section"
>
Start writing for free
</a>
</div>
<p className="text-left text-[14px] font-medium text-primary-foreground">30- day free trial</p>
</div>
<div className="w-full max-w-[1184px]">
<img
alt="Collaborative editor dashboard"
className="mx-auto h-auto w-[342px] rounded-[14px] border border-primary-foreground/20 object-cover min-[810px]:w-full min-[810px]:rounded-[16px]"
src={imageAssets.hero}
/>
</div>
<div className="flex w-full max-w-[700px] flex-col items-center gap-7 min-[810px]:gap-8">
<p className="text-[14px] font-medium text-muted-foreground min-[810px]:text-[16px]">
Trusted by world's leading companies
</p>
<div className="hidden grid-cols-4 gap-x-16 gap-y-8 min-[810px]:grid">
{desktopLogos.map((logo) => (
<img
key={`${logo.src}-${logo.width}`}
alt="Company logo"
className="h-10 object-contain opacity-90"
src={logo.src}
style={{ width: logo.width }}
/>
))}
</div>
<div className="grid grid-cols-4 gap-x-5 gap-y-4 min-[810px]:hidden">
{mobileLogos.map((logo) => (
<img
key={`${logo.src}-${logo.width}`}
alt="Company logo"
className="h-8 object-contain opacity-90"
src={logo.src}
style={{ width: logo.width }}
/>
))}
</div>
</div>
</div>
</section>
)
}
Section: Features
Path: components/FeaturesSection.tsx
import { imageAssets } from '../content'
const items = [
'Real‑time collaboration',
'Smart writing assistant',
'Content organization',
'Inline comments and feedback',
'SEO optimization tools',
'Version history and rollback',
]
export function FeaturesSection() {
return (
<section className="relative py-20 min-[810px]:py-28" id="features-section">
<div className="mx-auto flex w-full max-w-[1440px] flex-col gap-10 px-5 min-[810px]:gap-14 min-[810px]:px-[120px]">
<div className="flex flex-col gap-4">
<p className="w-fit rounded-xl border border-border bg-card px-3 py-1 text-[14px] font-medium text-muted-foreground">
◌ Features
</p>
<h2 className="max-w-[640px] text-left text-[36px] font-medium leading-[1.1] tracking-[-0.03em] text-foreground min-[810px]:text-[48px]">
Everything your team needs to write blogs
</h2>
</div>
<div className="flex flex-col gap-8 min-[810px]:grid min-[810px]:grid-cols-[1fr_705px] min-[810px]:items-start min-[810px]:gap-10">
<div className="flex flex-col gap-5">
<div className="flex flex-col gap-3">
<h3 className="text-[20px] font-medium text-foreground">✎ {items[0]}</h3>
<p className="max-w-[500px] text-[16px] font-medium leading-[1.7] text-muted-foreground">
Write together without version conflicts. See edits, comments, and suggestions instantly as
your team works in the same document, in real time.
</p>
</div>
{items.slice(1).map((item) => (
<h3 className="text-[20px] font-medium text-foreground" key={item}>
✦ {item}
</h3>
))}
</div>
<div className="w-full max-w-[705px] rounded-[16px] border-[8px] border-primary p-[8px]">
<img
alt="Feature interface"
className="h-auto w-full rounded-[10px] object-cover"
src={imageAssets.features}
/>
</div>
</div>
</div>
</section>
)
}
Section: Benefits
Path: components/BenefitsSection.tsx
import { imageAssets } from '../content'
const highlights = [
{
title: 'Publish faster',
description: 'Reduce back‑and‑forth and move from draft to publish in less time.',
icon: '◈',
},
{
title: 'Consistent quality',
description: 'Keep tone, structure, and standards consistent across all blog posts.',
icon: '☰',
},
{
title: 'Better team alignment',
description: 'Everyone works from the same document, with full context and clarity.',
icon: '◔',
},
]
export function BenefitsSection() {
return (
<section className="relative py-20 min-[810px]:py-28" id="benefits-section">
<div className="mx-auto flex w-full max-w-[1440px] flex-col gap-10 px-5 min-[810px]:gap-14 min-[810px]:px-[120px]">
<div className="flex flex-col gap-4">
<p className="w-fit rounded-xl border border-border bg-card px-3 py-1 text-[14px] font-medium text-muted-foreground">
◌ Benefits
</p>
<h2 className="max-w-[640px] text-left text-[36px] font-medium leading-[1.1] tracking-[-0.03em] text-foreground min-[810px]:text-[48px]">
Why teams choose our blog writing software
</h2>
</div>
<div className="grid gap-6 min-[810px]:grid-cols-[674px_1fr] min-[810px]:gap-3">
<article className="rounded-[14px] border border-border bg-card p-6 min-[810px]:p-6">
<h3 className="text-[20px] font-medium text-foreground">SEO‑ready content</h3>
<p className="mt-2 max-w-[500px] text-[16px] font-medium leading-[1.7] text-muted-foreground">
Write content that is optimized for search engines from the start.
</p>
<img
alt="SEO chart"
className="mt-5 h-[148px] w-full rounded-[14px] border border-border object-cover min-[810px]:h-[291px]"
src={imageAssets.benefitsLeft}
/>
</article>
<article className="rounded-[14px] border border-border bg-card p-6 min-[810px]:p-6">
<h3 className="text-[20px] font-medium text-foreground">Scales with your team</h3>
<p className="mt-2 max-w-[420px] text-[16px] font-medium leading-[1.7] text-muted-foreground">
From solo writers to large content teams, workflows adapt as you grow.
</p>
<img
alt="Team chart"
className="mt-5 h-[200px] w-full rounded-[14px] border border-border object-cover min-[810px]:h-[291px]"
src={imageAssets.benefitsRight}
/>
</article>
</div>
<div className="grid gap-8 min-[810px]:grid-cols-3 min-[810px]:gap-12">
{highlights.map((item) => (
<article className="flex flex-col gap-2" key={item.title}>
<h3 className="text-[20px] font-medium text-foreground">
{item.icon} {item.title}
</h3>
<p className="max-w-[360px] text-[16px] font-medium leading-[1.7] text-muted-foreground">{item.description}</p>
</article>
))}
</div>
</div>
</section>
)
}
Section: Use Cases
Path: components/UseCasesSection.tsx
import { imageAssets } from '../content'
const useCases = [
{
title: 'Marketing teams',
description: 'Plan and publish blog content collaboratively while meeting deadlines.',
},
{
title: 'Content agencies',
description: 'Manage multiple clients and writers without losing control of quality.',
},
{
title: 'Founders and startups',
description: 'Create consistent blog content without complex tools or processes.',
},
]
export function UseCasesSection() {
return (
<section className="relative py-20 min-[810px]:py-28" id="use-cases-section">
<div className="mx-auto flex w-full max-w-[1440px] flex-col gap-10 px-5 min-[810px]:gap-14 min-[810px]:px-[120px]">
<div className="flex flex-col gap-4">
<p className="w-fit rounded-xl border border-border bg-card px-3 py-1 text-[14px] font-medium text-muted-foreground">
◌ Use Cases
</p>
<h2 className="max-w-[700px] text-left text-[36px] font-medium leading-[1.1] tracking-[-0.03em] text-foreground min-[810px]:text-[48px]">
Built for modern content teams
</h2>
</div>
<div className="grid gap-8 min-[810px]:grid-cols-3 min-[810px]:gap-12">
{useCases.map((item) => (
<article className="flex flex-col gap-2" key={item.title}>
<h3 className="text-[20px] font-medium text-foreground">{item.title}</h3>
<p className="max-w-[360px] text-[16px] font-medium leading-[1.7] text-muted-foreground">{item.description}</p>
</article>
))}
</div>
<div className="w-full rounded-[16px] border-[8px] border-primary p-[8px]">
<img
alt="Use cases dashboard"
className="h-auto w-full rounded-[10px] object-cover"
src={imageAssets.useCases}
/>
</div>
</div>
</section>
)
}
Section: Testimonials
Path: components/TestimonialsSection.tsx
import { testimonials } from '../content'
function TestimonialCard({
quote,
name,
role,
avatar,
}: {
quote: string
name: string
role: string
avatar: string
}) {
return (
<article className="rounded-[14px] border border-border bg-card p-6">
<p className="text-[16px] font-medium leading-[1.6] text-muted-foreground">{quote}</p>
<div className="mt-7 flex items-center gap-4">
<img alt={name} className="h-[52px] w-[52px] rounded-full object-cover" src={avatar} />
<div>
<p className="text-[20px] font-medium text-foreground">{name}</p>
<p className="mt-1 text-[16px] font-medium text-muted-foreground">{role}</p>
</div>
</div>
</article>
)
}
export function TestimonialsSection() {
return (
<section className="relative py-20 min-[810px]:py-28" id="testimonial-section">
<div className="mx-auto flex w-full max-w-[1440px] flex-col gap-10 px-5 min-[810px]:gap-14 min-[810px]:px-[120px]">
<div className="flex flex-col gap-4">
<p className="w-fit rounded-xl border border-border bg-card px-3 py-1 text-[14px] font-medium text-muted-foreground">
◌ Testimonials
</p>
<h2 className="max-w-[760px] text-left text-[36px] font-medium leading-[1.1] tracking-[-0.03em] text-foreground min-[810px]:text-[48px]">
See what people who trust us are saying
</h2>
</div>
<div className="grid gap-4 min-[810px]:grid-cols-2 min-[810px]:gap-5">
{testimonials.map((item) => (
<TestimonialCard
avatar={item.avatar}
key={`${item.name}-${item.role}`}
name={item.name}
quote={item.quote}
role={item.role}
/>
))}
</div>
</div>
</section>
)
}
Section: Pricing
Path: components/PricingSection.tsx
import { darkGradientButtonClass } from '../lib/buttonStyles'
type PricingCardProps = {
title: string
description: string
price: string
monthly?: boolean
features: string[]
button: string
buttonVariant?: 'dark' | 'blue'
trial?: boolean
}
function PricingCard({
title,
description,
price,
monthly = true,
features,
button,
buttonVariant = 'dark',
trial = false,
}: PricingCardProps) {
return (
<article className="flex h-full flex-col rounded-[14px] border border-border bg-card p-6">
<h3 className="text-[20px] font-medium text-foreground">{title}</h3>
<p className="mt-2 text-[16px] font-medium text-muted-foreground">{description}</p>
<div className="mt-6 flex items-end gap-2">
<p className="text-[36px] font-medium leading-none text-foreground min-[810px]:text-[48px]">{price}</p>
{monthly ? <p className="text-[16px] font-medium text-muted-foreground">/month</p> : null}
</div>
<p className="mt-6 text-[16px] font-medium text-foreground">Features:</p>
<ul className="mt-2 space-y-2">
{features.map((feature) => (
<li className="text-[16px] font-medium text-muted-foreground" key={feature}>
<span className="mr-2 text-muted-foreground/70">✓</span>
{feature}
</li>
))}
</ul>
<a
className={`mt-8 flex h-12 items-center justify-center rounded-xl px-4 text-[16px] font-medium text-primary-foreground ${
buttonVariant === 'blue' ? 'border border-primary bg-primary' : darkGradientButtonClass
}`}
href="#"
>
{button}
</a>
{trial ? <p className="mt-4 text-left text-[14px] font-medium text-muted-foreground">30- day free trial</p> : null}
</article>
)
}
export function PricingSection() {
return (
<section className="relative py-20 min-[810px]:py-28" id="pricing-section">
<div className="mx-auto flex w-full max-w-[1440px] flex-col gap-10 px-5 min-[810px]:gap-14 min-[810px]:px-[120px]">
<div className="flex flex-col gap-4">
<p className="w-fit rounded-xl border border-border bg-card px-3 py-1 text-[14px] font-medium text-muted-foreground">
◌ Pricing
</p>
<h2 className="max-w-[640px] text-left text-[36px] font-medium leading-[1.1] tracking-[-0.03em] text-foreground min-[810px]:text-[48px]">
Simple pricing for every stage
</h2>
</div>
<div className="flex w-fit rounded-xl border border-border bg-background p-[3px]">
<button
className="h-10 rounded-[10px] bg-foreground px-3 text-[16px] font-medium text-primary-foreground"
type="button"
>
Monthly
</button>
<button className="h-10 rounded-[10px] px-3 text-[16px] font-medium text-muted-foreground" type="button">
Yearly (Save 20%)
</button>
</div>
<div className="grid gap-5 min-[810px]:grid-cols-3 min-[810px]:gap-8">
<PricingCard
button="Get Started"
description="Perfect for individuals getting started."
features={['1 workspace', 'Up to 3 drafts', 'Basic collaboration', 'Limited SEO tools']}
monthly={false}
price="Free"
title="Basic"
/>
<div className="relative">
<p className="absolute right-4 top-4 rounded-xl border border-border bg-card px-3 py-1 text-[14px] font-medium text-foreground">
Most Popular
</p>
<PricingCard
button="Book a Demo"
buttonVariant="blue"
description="Best for growing teams."
features={[
'Unlimited drafts',
'Real‑time collaboration',
'Full SEO optimization',
'Comment history and version control',
]}
price="39$"
title="Pro"
trial
/>
</div>
<PricingCard
button="Get Started"
description="For agencies and large content teams."
features={['Everything in Pro Plus:', 'Multiple workspaces', 'Advanced permissions', 'Priority support']}
price="99$"
title="Team"
/>
</div>
</div>
</section>
)
}
Section: CTA
Path: components/CtaSection.tsx
import { imageAssets } from '../content'
import { darkGradientButtonClass } from '../lib/buttonStyles'
export function CtaSection() {
return (
<section className="relative py-20 min-[810px]:py-28" id="cta-section">
<div className="mx-auto flex w-full max-w-[1440px] flex-col gap-10 px-5 min-[810px]:gap-14 min-[810px]:px-[120px]">
<img
alt="Call to action dashboard"
className="w-full object-contain"
src={imageAssets.cta}
/>
<div className="flex w-full max-w-[500px] flex-col items-start gap-4">
<h2 className="text-left text-[36px] font-medium leading-[1.1] tracking-[-0.03em] text-foreground min-[810px]:text-[48px]">
Start writing better blogs today
</h2>
<p className="text-left text-[16px] font-medium leading-[1.7] text-muted-foreground">
Join teams who publish faster, collaborate better, and create blog content that performs.
</p>
<a
className={`${darkGradientButtonClass} flex h-12 items-center rounded-xl px-4 text-[16px] font-medium`}
href="#pricing-section"
>
Start writing for free
</a>
<p className="text-[14px] font-medium text-muted-foreground">30- day free trial</p>
</div>
</div>
</section>
)
}
Section: Footer
Path: components/FooterSection.tsx
import { darkGradientButtonClass } from '../lib/buttonStyles'
const footerLinks = [
{ label: 'Features', href: '#features-section' },
{ label: 'Benefits', href: '#benefits-section' },
{ label: 'Use Cases', href: '#use-cases-section' },
{ label: 'Testimonials', href: '#testimonial-section' },
{ label: 'Pricing', href: '#pricing-section' },
]
export function FooterSection() {
return (
<footer className="relative bg-card py-16 min-[810px]:py-20">
<div className="mx-auto flex w-full max-w-[1440px] flex-col gap-12 px-5 min-[810px]:px-[120px]">
<div className="grid gap-10 min-[810px]:grid-cols-[1fr_280px_320px]">
<div className="flex flex-col gap-5">
<a className="flex items-center gap-2 text-foreground" href="#">
<span className="inline-block h-5 w-5 rounded-md bg-primary" />
<span className="text-[19px] font-semibold tracking-[-0.02em]">oclave</span>
</a>
<p className="max-w-[500px] text-[14px] font-medium leading-[1.7] text-muted-foreground">
Build better blog content with a collaborative writing platform designed for modern teams.
</p>
</div>
<div className="flex flex-col gap-4">
<p className="text-[16px] font-medium text-foreground">Links</p>
{footerLinks.map((item) => (
<a className="text-[14px] font-medium text-muted-foreground" href={item.href} key={item.label}>
{item.label}
</a>
))}
</div>
<div className="flex flex-col gap-4">
<p className="text-[16px] font-medium text-foreground">Subscribe to our newsletter</p>
<p className="text-[14px] font-medium leading-[1.7] text-muted-foreground">
Subscribe to our newsletter and get the latest tips, updates, and update insights delivered to
your inbox.
</p>
<input
className="h-12 w-full rounded-xl border border-border bg-background px-4 text-[14px] font-medium outline-none"
placeholder="name@oclave.com"
type="email"
/>
<button className={`${darkGradientButtonClass} h-12 w-[150px] rounded-xl text-[16px] font-medium`} type="button">
Submit
</button>
</div>
</div>
<div className="h-px w-full bg-border" />
<div className="flex flex-col gap-3 text-left min-[810px]:flex-row min-[810px]:items-center min-[810px]:justify-between">
<a className="text-[14px] font-medium text-foreground" href="mailto:support@clave.com">
support@clave.com
</a>
<p className="text-[14px] font-medium text-muted-foreground">© 2024 oclave all rights reserved.</p>
</div>
</div>
</footer>
)
}