CTA (Call-to-Action)
Call-to-action section with dark background.
Default Usage
import { CTA } from '@/components/landing';
<CTA />
Location: src/components/landing/CTA.tsx
Features
- Dark gradient background
- Grid pattern overlay
- Two CTA buttons
- Scroll animation
Variants
Variant 1: Dark with Grid (Default)
Dark background with grid pattern overlay.
// src/components/landing/CTA.tsx - Default implementation
Best for: Strong contrast, visual interest
Variant 2: Split CTA with Image
Image on one side, CTA on the other.
// src/components/landing/CTASplit.tsx
'use client';
import { useTranslations } from 'next-intl';
import Link from 'next/link';
import Image from 'next/image';
import { useScrollAnimation } from '@/hooks';
import { Button } from '@/components/ui';
import { ArrowRightIcon } from '@/components/icons';
export default function CTASplit() {
const t = useTranslations('landing.cta');
const { elementRef, isVisible } = useScrollAnimation();
return (
<section className="py-20 sm:py-32 bg-zinc-50 dark:bg-zinc-900/50">
<div className="container mx-auto px-4">
<div
ref={elementRef as React.RefObject<HTMLDivElement>}
className={`scroll-fade-in ${isVisible ? 'visible' : ''}`}
>
<div className="grid lg:grid-cols-2 gap-12 items-center max-w-6xl mx-auto bg-white dark:bg-zinc-900 rounded-3xl overflow-hidden shadow-2xl">
{/* Left: Image */}
<div className="relative h-64 lg:h-full min-h-[400px]">
<Image
src="/images/cta-dashboard.png"
alt="Dashboard"
fill
className="object-cover"
/>
<div className="absolute inset-0 bg-gradient-to-r from-transparent to-white/50 dark:to-zinc-900/50" />
</div>
{/* Right: Content */}
<div className="p-8 lg:p-12">
<h2 className="text-3xl sm:text-4xl font-bold mb-4">
{t('title')}
</h2>
<p className="text-zinc-600 dark:text-zinc-400 text-lg mb-8">
{t('description')}
</p>
<div className="space-y-4 mb-8">
<div className="flex items-center gap-3">
<div className="flex-shrink-0 w-6 h-6 rounded-full bg-green-100 dark:bg-green-900/30 flex items-center justify-center">
✓
</div>
<span>14-day free trial, no credit card required</span>
</div>
<div className="flex items-center gap-3">
<div className="flex-shrink-0 w-6 h-6 rounded-full bg-green-100 dark:bg-green-900/30 flex items-center justify-center">
✓
</div>
<span>Cancel anytime with one click</span>
</div>
<div className="flex items-center gap-3">
<div className="flex-shrink-0 w-6 h-6 rounded-full bg-green-100 dark:bg-green-900/30 flex items-center justify-center">
✓
</div>
<span>Setup in under 5 minutes</span>
</div>
</div>
<div className="flex flex-col sm:flex-row gap-4">
<Button color="dark" className="gap-2">
{t('primaryButton')}
<ArrowRightIcon className="w-4 h-4" />
</Button>
<Button as={Link} href="/contact" outline>
Talk to Sales
</Button>
</div>
</div>
</div>
</div>
</div>
</section>
);
}
Best for: Product showcases, visual products, highlighting specific features
Variant 3: Minimal Centered
Simple centered CTA with clean design.
// src/components/landing/CTASimple.tsx
'use client';
import { useTranslations } from 'next-intl';
import Link from 'next/link';
import { useScrollAnimation } from '@/hooks';
import { Button } from '@/components/ui';
import { ArrowRightIcon } from '@/components/icons';
export default function CTASimple() {
const t = useTranslations('landing.cta');
const { elementRef, isVisible } = useScrollAnimation();
return (
<section className="py-20 sm:py-32">
<div className="container mx-auto px-4">
<div
ref={elementRef as React.RefObject<HTMLDivElement>}
className={`scroll-fade-in ${isVisible ? 'visible' : ''}`}
>
<div className="max-w-3xl mx-auto text-center">
<h2 className="text-4xl sm:text-5xl font-bold mb-6">
{t('title')}
</h2>
<p className="text-xl text-zinc-600 dark:text-zinc-400 mb-10">
{t('description')}
</p>
<div className="flex flex-col sm:flex-row gap-4 justify-center items-center">
<Button
as={Link}
href="/register"
color="dark"
className="gap-2 text-lg px-8 py-6"
>
{t('primaryButton')}
<ArrowRightIcon className="w-5 h-5" />
</Button>
<div className="text-sm text-zinc-600 dark:text-zinc-400">
No credit card required - Free 14-day trial
</div>
</div>
{/* Social proof */}
<div className="mt-12 flex items-center justify-center gap-8">
<div className="text-sm">
<div className="flex -space-x-2 justify-center mb-2">
{[1, 2, 3, 4, 5].map((i) => (
<div
key={i}
className="w-10 h-10 rounded-full bg-zinc-200 dark:bg-zinc-700 border-2 border-white dark:border-zinc-900"
/>
))}
</div>
<div className="text-zinc-600 dark:text-zinc-400">
Join 10,000+ users
</div>
</div>
</div>
</div>
</div>
</div>
</section>
);
}
Best for: Clean designs, minimalist brands, bottom-of-page CTAs
Choosing a Variant
| Variant | Use When |
|---|---|
| Dark with Grid | Strong visual impact, standard landing pages |
| Split with Image | Have product screenshots, want visual balance |
| Minimal Centered | Clean/minimalist design, subtle approach |