CTA

CTA 01 — Glow Card

Rounded call-to-action card with primary glow blobs, dotted texture and staggered reveals.

$ npx shadcn@latest add @ludusvibe/cta-01
Open in v0

Code

Installed to components/sections/cta-01.tsx — it's yours to edit.

"use client"

import * as React from "react"
import { ArrowRight } from "lucide-react"

import { buttonVariants } from "@/components/ui/button"
import { Reveal } from "@/components/ludus/reveal"
import { cn } from "@/lib/utils"

type Cta = { label: string; href: string }

export type Cta01Props = {
  eyebrow?: string
  title?: React.ReactNode
  description?: string
  primaryCta?: Cta
  secondaryCta?: Cta
  /** Heading element — use "h1" when this is the page's main heading. */
  as?: "h1" | "h2"
  className?: string
}

export function Cta01({
  eyebrow = "Ready when you are",
  title = "Build your next launch in an afternoon",
  description = "Install any section with one command, wire up your copy, and ship. Your colors, your fonts, your brand — automatically.",
  primaryCta = { label: "Get started free", href: "#" },
  secondaryCta = { label: "Talk to us", href: "#" },
  as: Heading = "h2",
  className,
}: Cta01Props) {
  return (
    <section className={cn("bg-background px-6 py-24", className)}>
      <div className="relative mx-auto max-w-5xl overflow-hidden rounded-3xl border bg-card px-6 py-20 text-center shadow-sm md:py-28">
        <div
          aria-hidden
          className="absolute -top-24 -left-24 size-64 rounded-full bg-primary/20 blur-3xl"
        />
        <div
          aria-hidden
          className="absolute -right-24 -bottom-24 size-64 rounded-full bg-primary/20 blur-3xl"
        />
        <div
          aria-hidden
          className="absolute inset-0 [background-image:radial-gradient(var(--border)_1px,transparent_1px)] [background-size:16px_16px] [mask-image:radial-gradient(ellipse_at_center,black,transparent_75%)]"
        />

        <div className="relative">
          <Reveal>
            <p className="text-sm font-medium tracking-widest text-primary uppercase">
              {eyebrow}
            </p>
          </Reveal>
          <Reveal delay={0.1}>
            <Heading className="mx-auto mt-4 max-w-2xl text-balance font-heading text-4xl font-semibold tracking-tight md:text-5xl">
              {title}
            </Heading>
          </Reveal>
          <Reveal delay={0.2}>
            <p className="mx-auto mt-5 max-w-xl text-pretty text-muted-foreground md:text-lg">
              {description}
            </p>
          </Reveal>
          <Reveal delay={0.3}>
            <div className="mt-9 flex flex-col items-center justify-center gap-3 sm:flex-row">
              <a
                href={primaryCta.href}
                className={cn(buttonVariants({ size: "lg" }), "group")}
              >
                {primaryCta.label}
                <ArrowRight className="transition-transform group-hover:translate-x-0.5" />
              </a>
              <a
                href={secondaryCta.href}
                className={buttonVariants({ size: "lg", variant: "ghost" })}
              >
                {secondaryCta.label}
              </a>
            </div>
          </Reveal>
        </div>
      </div>
    </section>
  )
}