# CTA Banner

> Call-to-action banner with a soft glow and dotted pattern, centered or left aligned.

- Author: Atelier UI
- License: MIT
- Page: https://chromotion.dev/en/components/cta-banner
- Site: Atelier UI (https://chromotion.dev)

## Install

```bash
npx shadcn@latest add https://chromotion.dev/r/cta-banner.json
```

Stack: React + TypeScript + Tailwind CSS v4, shadcn/ui conventions. `cn` comes from `@/lib/utils`.

## Dependencies

```bash
npm install lucide-react
```

## Usage

```tsx title="components/cta-banner-demo.tsx"
import { CtaBanner } from "@/components/cta-banner"

export default function CtaBannerDemo() {
  return (
    <CtaBanner
      className="w-full max-w-4xl"
      title="Ship your next launch this week"
      description="Start with production-ready blocks and spend your time on what makes your product different."
      primaryAction={{ label: "Get started", href: "#" }}
      secondaryAction={{ label: "Talk to sales", href: "#" }}
    />
  )
}
```

## Source

```tsx title="components/cta-banner.tsx"
import * as React from "react"
import { ArrowRight } from "lucide-react"

import { cn } from "@/lib/utils"

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

export interface CtaBannerProps extends Omit<React.ComponentProps<"section">, "title"> {
  title: React.ReactNode
  description?: React.ReactNode
  primaryAction: Action
  secondaryAction?: Action
  /** Color of the glow behind the banner */
  glowColor?: string
  /** Dotted pattern over the banner */
  showPattern?: boolean
  align?: "center" | "left"
}

export function CtaBanner({
  title,
  description,
  primaryAction,
  secondaryAction,
  glowColor = "#f97316",
  showPattern = true,
  align = "center",
  className,
  ...props
}: CtaBannerProps) {
  return (
    <section
      className={cn(
        "relative isolate overflow-hidden rounded-3xl border bg-card px-6 py-14 text-card-foreground shadow-sm sm:px-12 sm:py-20",
        className
      )}
      {...props}
    >
      <div
        aria-hidden
        className="absolute -top-1/2 left-1/2 -z-10 size-[42rem] -translate-x-1/2 rounded-full opacity-25 blur-3xl"
        style={{ background: `radial-gradient(closest-side, ${glowColor}, transparent)` }}
      />
      {showPattern && (
        <div
          aria-hidden
          className="absolute inset-0 -z-10 text-foreground/[0.07] [mask-image:radial-gradient(ellipse_at_center,black,transparent_75%)]"
          style={{ backgroundImage: "radial-gradient(currentColor 1px, transparent 1px)", backgroundSize: "18px 18px" }}
        />
      )}
      <div className={cn("mx-auto flex max-w-2xl flex-col gap-4", align === "center" ? "items-center text-center" : "mx-0 items-start")}>
        <h2 className="text-3xl font-semibold tracking-tight text-balance sm:text-4xl">{title}</h2>
        {description && <p className="text-base text-pretty text-muted-foreground sm:text-lg">{description}</p>}
        <div className="mt-4 flex flex-wrap items-center gap-3">
          <a
            href={primaryAction.href}
            className="group inline-flex h-11 items-center gap-2 rounded-full bg-primary px-6 text-sm font-medium text-primary-foreground shadow-sm transition-[opacity,box-shadow] hover:opacity-90 focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:outline-none"
          >
            {primaryAction.label}
            <ArrowRight className="size-4 transition-transform group-hover:translate-x-0.5" />
          </a>
          {secondaryAction && (
            <a
              href={secondaryAction.href}
              className="inline-flex h-11 items-center rounded-full border bg-background px-6 text-sm font-medium transition-colors hover:bg-accent focus-visible:ring-2 focus-visible:ring-ring focus-visible:outline-none"
            >
              {secondaryAction.label}
            </a>
          )}
        </div>
      </div>
    </section>
  )
}
```
