# Cta 9

> Full-bleed inverse conversion band with radial glow — footer-10 inverse DNA for dramatic close.

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

- Page, with a live preview: https://shadcn.exchange/r/nusaiba/cta-9
- Screenshot: https://abzjhwgwpdpz7ua5.public.blob.vercel-storage.com/shots/nusaiba/cta-9-light-415977a406b4e88c.png
- Registry item: https://nusaiba.dev/r/base-nova/cta-9.json
- Categories: cta
- Listed: 2026-10-13, source last changed 2026-10-13

## Install

```bash
npx shadcn@latest add https://nusaiba.dev/r/base-nova/cta-9.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: `motion`
- Registry items: `@nusaiba/foundation`, `button`

## Files

### `registry/blocks/cta/9/cta-section.tsx`

```tsx
"use client";

import Link from "next/link";
import { useRef } from "react";
import { ArrowRightIcon } from "lucide-react";
import { motion, useInView, useReducedMotion } from "motion/react";
import { buttonVariants } from "@/components/ui/button";
import { motionStagger, motionViewport } from "@/lib/motion-tokens";
import { cn } from "@/lib/utils";
import { SectionShell } from "@/components/layout-contract";

const spring = { type: "spring" as const, duration: 0.3, bounce: 0 };

export function CtaInverseBleedSection() {
	const reduceMotion = useReducedMotion();
	const ref = useRef<HTMLElement>(null);
	const inView = useInView(ref, motionViewport);

	const itemVariants = reduceMotion
		? { hidden: { opacity: 1 }, visible: { opacity: 1 } }
		: {
				hidden: { opacity: 0, filter: "blur(4px)", y: 8 },
				visible: { opacity: 1, filter: "blur(0px)", y: 0, transition: spring },
			};

	return (
		<SectionShell spacingMode="section" className="relative overflow-hidden bg-muted/40 text-foreground shadow-[0_-1px_0_rgba(0,0,0,0.03)] dark:shadow-[0_-1px_0_rgba(255,255,255,0.04)]" ref={ref}>
			<motion.div
				animate={
					reduceMotion
						? undefined
						: { opacity: [0.35, 0.55, 0.35], scale: [1, 1.03, 1] }
				}
				aria-hidden
				className="pointer-events-none absolute inset-x-8 top-1/2 -z-0 h-56 -translate-y-1/2 rounded-full bg-foreground/5 blur-3xl md:inset-x-16 md:h-72"
				transition={{ duration: 5, repeat: Number.POSITIVE_INFINITY, ease: "easeInOut" }}
			/>

			<motion.div
				animate={inView ? "visible" : "hidden"}
				className="relative z-10 mx-auto w-full max-w-2xl text-center"
				initial="hidden"
				variants={{
					hidden: {},
					visible: { transition: { staggerChildren: motionStagger.item, delayChildren: 0.04 } },
				}}
			>
				<motion.p
					className="font-medium text-muted-foreground text-xs uppercase tracking-[0.22em]"
					variants={itemVariants}
				>
					Pro
				</motion.p>
				<motion.h2
					className="mt-3 text-balance font-medium text-3xl tracking-tight md:text-5xl"
					variants={itemVariants}
				>
					Own the full catalog
				</motion.h2>
				<motion.p
					className="mx-auto mt-4 max-w-md text-pretty text-muted-foreground text-sm md:text-base"
					variants={itemVariants}
				>
					Install every Pro block with your registry token — motion patterns, commercial
					license, lifetime updates.
				</motion.p>
				<motion.div
					className="mt-8 flex flex-col items-center justify-center gap-3 sm:flex-row"
					variants={itemVariants}
				>
					<Link
						className={cn(buttonVariants(), "active:scale-[0.96] transition-transform")}
						href="/pricing"
					>
						Get Pro access
						<ArrowRightIcon data-icon="inline-end" />
					</Link>
					<Link
						className={cn(
							buttonVariants({ variant: "outline" }),
							"active:scale-[0.96] transition-[transform,background-color]",
						)}
						href="/blocks"
					>
						Browse blocks
					</Link>
				</motion.div>
			</motion.div>
		</SectionShell>
	);
}
```
