# CTA

> CTA variant for block.

A shadcn/ui block from the [@uiable](https://uiable.com) registry, listed on [shadcn.exchange](https://shadcn.exchange/r/uiable/block-cta).

- Page, with a live preview: https://shadcn.exchange/r/uiable/block-cta
- Screenshot: https://abzjhwgwpdpz7ua5.public.blob.vercel-storage.com/shots/uiable/block-cta-light-de567cd7a38d7ea0.png
- Registry item: https://uiable.com/r/block-cta.json
- Categories: landing
- Listed: 2026-10-13, source last changed 2026-10-13

## Install

```bash
npx shadcn@latest add https://uiable.com/r/block-cta.json
```

Run it in a project that has shadcn/ui set up. It adds the files below and installs what they depend on.

## Dependencies

- npm packages: `cn`, `framer-motion`, `lucide-react`

## Files

### `src/components/uiable/blocks/landing/cta/cta.tsx`

```tsx
"use client"

// next
import Link from "next/link"

// third-party
import { motion } from "framer-motion"

// project-imports
import SectionHeader from "@/components/uiable/blocks/landing/components/SectionHeader"

// assets
import { ArrowRight } from "lucide-react"

//  ------------------------------ | CTA | ------------------------------  //

export default function Cta() {
  return (
    <section className="mx-auto flex w-full flex-col items-center gap-8 px-4 py-12.5 text-center sm:px-8">
      <SectionHeader
        title="One payment unlocks everything"
        titleClassName="tracking-tight"
        subtitle="Get all Pro blocks, templates, and dashboards with one purchase. Yours for life."
        className="max-w-2xl items-center"
      />

      <motion.div
        initial={{ opacity: 0, y: 16 }}
        whileInView={{ opacity: 1, y: 0 }}
        viewport={{ once: true, margin: "-80px" }}
        transition={{ duration: 0.4, ease: "easeOut" }}
        whileHover={{ scale: 1.03 }}
        whileTap={{ scale: 0.98 }}
        className="relative"
      >
        <motion.span
          aria-hidden
          className="pointer-events-none absolute -inset-3 -z-10 rounded-full bg-primary/40 blur-2xl"
          animate={{ opacity: [0.5, 0.85, 0.5] }}
          transition={{ repeat: Infinity, duration: 3, ease: "easeInOut" }}
        />

        <Link
          href="/pricing"
          className="group relative inline-flex h-14 items-center justify-center gap-2.5 overflow-hidden rounded-full px-10 text-lg font-semibold text-background shadow-xl shadow-primary/25"
        >
          <span
            aria-hidden
            className="absolute inset-0 overflow-hidden rounded-full"
          >
            <motion.span
              className="absolute top-1/2 left-1/2 aspect-square w-[250%] -translate-x-1/2 -translate-y-1/2"
              style={{
                background:
                  "conic-gradient(from 0deg, var(--chart-2), var(--primary), var(--chart-2), var(--primary), var(--chart-2))",
              }}
              animate={{ rotate: 360 }}
              transition={{ repeat: Infinity, duration: 3, ease: "linear" }}
            />
            <span className="absolute inset-[2.5px] rounded-full bg-foreground transition-colors group-hover:bg-foreground/90" />
          </span>

          <span className="relative z-10">Get all access</span>
          <motion.span
            className="relative z-10 flex"
            animate={{ x: [0, 5, 0] }}
            transition={{ repeat: Infinity, duration: 1.4, ease: "easeInOut" }}
          >
            <ArrowRight
              aria-hidden="true"
              className="size-5 transition-transform group-hover:translate-x-1"
            />
          </motion.span>
        </Link>
      </motion.div>
    </section>
  )
}
```

### `src/components/uiable/blocks/landing/components/SectionHeader.tsx`

```tsx
// third-party
import { cn } from "cn"

// types
interface SectionHeaderProps {
  title: string
  subtitle: string
  className?: string
  titleClassName?: string
  subtitleClassName?: string
}

//  ------------------------------ | BLOCK - SECTION HEADER | ------------------------------  //

export default function SectionHeader({
  title,
  subtitle,
  className,
  titleClassName,
  subtitleClassName,
}: SectionHeaderProps) {
  return (
    <div className={cn("flex flex-col gap-2 md:gap-3", className)}>
      <h2
        className={cn(
          "text-2xl leading-tight font-medium tracking-normal text-foreground sm:text-3xl sm:leading-8 md:text-4xl md:leading-9",
          titleClassName
        )}
      >
        {title}
      </h2>

      <p
        className={cn(
          "text-base leading-relaxed font-normal tracking-normal text-muted-foreground sm:text-lg",
          subtitleClassName
        )}
      >
        {subtitle}
      </p>
    </div>
  )
}
```
