l8components

Call to Action

Closing call-to-action card with a rotating gradient border.

Ready to build something great?

Start with a block, make it yours, and ship it today.

Installation

npx shadcn@latest add @l8/cta

Usage

import { CtaBlock } from '@/components/blocks/cta';

export default function Page() {
  return <CtaBlock />;
}

Source

components/blocks/cta.tsx
"use client"

import Link from "next/link"
import { motion } from "motion/react"
import { ArrowRightIcon } from "lucide-react"

import { buttonVariants } from "@/components/ui/button"
import { Reveal } from "@/components/motion"

export function CtaBlock() {
  return (
    <section className="px-6 py-16">
      <Reveal className="relative mx-auto max-w-4xl overflow-hidden rounded-xl bg-border p-px">
        {/* rotating conic gradient peeks through the 1px padding as an animated border */}
        <motion.div
          aria-hidden
          className="absolute top-1/2 left-1/2 aspect-square w-[200%] -translate-1/2 bg-[conic-gradient(from_0deg,transparent_0%,var(--primary)_15%,transparent_30%)]"
          animate={{ rotate: 360 }}
          transition={{ duration: 6, repeat: Infinity, ease: "linear" }}
        />
        <div className="relative rounded-[calc(var(--radius-xl)-1px)] bg-card px-8 py-14 text-center">
          <h2 className="text-3xl font-semibold tracking-tight text-balance">Ready to build something great?</h2>
          <p className="mx-auto mt-3 max-w-md text-muted-foreground">
            Start with a block, make it yours, and ship it today.
          </p>
          <div className="mt-8 flex justify-center">
            <Link href="/docs" className={buttonVariants({ size: "lg", className: "group rounded-full px-5" })}>
              Get started
              <ArrowRightIcon data-icon="inline-end" className="transition-transform group-hover:translate-x-0.5" />
            </Link>
          </div>
        </div>
      </Reveal>
    </section>
  )
}

On this page