Spotlight Follow Background
Original · freeA dot-grid section where a spring-eased spotlight follows the cursor and reveals a hidden lattice of coloured dots.
Copy prompt gives Claude Code, Cursor or v0 a ready-to-paste prompt that recreates this exact component.
npx shadcn@latest add https://webinnoventix.com/r/bg-spotlight-follow.json"use client";
import { useRef, type MouseEvent } from "react";
import {
motion,
useMotionValue,
useMotionTemplate,
useSpring,
useReducedMotion,
type Variants,
} from "motion/react";
const dotImage = "radial-gradient(currentColor 1px, transparent 1px)";
const fade: Variants = {
hidden: { opacity: 0, y: 22 },
show: (i: number) => ({
opacity: 1,
y: 0,
transition: { duration: 0.6, delay: i * 0.1, ease: [0.22, 1, 0.36, 1] },
}),
};
export default function BgSpotlightFollow() {
const ref = useRef<HTMLElement>(null);
const reduce = useReducedMotion();
const x = useMotionValue(50);
const y = useMotionValue(40);
const springX = useSpring(x, { stiffness: 140, damping: 22, mass: 0.4 });
const springY = useSpring(y, { stiffness: 140, damping: 22, mass: 0.4 });
const glow = useMotionTemplate`radial-gradient(420px circle at ${springX}% ${springY}%, rgba(99,102,241,0.28), transparent 60%)`;
const revealMask = useMotionTemplate`radial-gradient(220px circle at ${springX}% ${springY}%, black 20%, transparent 75%)`;
const handleMove = (event: MouseEvent<HTMLElement>) => {
const el = ref.current;
if (!el) return;
const rect = el.getBoundingClientRect();
x.set(((event.clientX - rect.left) / rect.width) * 100);
y.set(((event.clientY - rect.top) / rect.height) * 100);
};
return (
<section
ref={ref}
onMouseMove={handleMove}
className="relative isolate flex min-h-[640px] w-full items-center justify-center overflow-hidden bg-slate-50 px-6 py-24 dark:bg-slate-950"
>
{/* base dot grid */}
<div
aria-hidden="true"
className="pointer-events-none absolute inset-0 -z-10 text-slate-900/10 dark:text-white/10"
style={{ backgroundImage: dotImage, backgroundSize: "24px 24px" }}
/>
{/* coloured dots revealed only under the spotlight */}
<motion.div
aria-hidden="true"
className="pointer-events-none absolute inset-0 -z-10 text-indigo-500 dark:text-indigo-400"
style={{
backgroundImage: dotImage,
backgroundSize: "24px 24px",
maskImage: reduce ? undefined : revealMask,
WebkitMaskImage: reduce ? undefined : revealMask,
opacity: reduce ? 0 : 1,
}}
/>
{/* soft glow that trails the cursor */}
<motion.div
aria-hidden="true"
className="pointer-events-none absolute inset-0 -z-10"
style={{ background: reduce ? undefined : glow }}
/>
<motion.div
variants={fade}
initial="hidden"
whileInView="show"
viewport={{ once: true, amount: 0.35 }}
custom={0}
className="relative mx-auto max-w-2xl text-center"
>
<motion.span
variants={fade}
custom={0}
className="inline-flex items-center gap-2 rounded-full border border-slate-200/70 bg-white/70 px-4 py-1.5 text-sm font-medium text-slate-600 shadow-sm backdrop-blur dark:border-white/10 dark:bg-white/5 dark:text-slate-300"
>
<svg
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth={2}
strokeLinecap="round"
strokeLinejoin="round"
aria-hidden="true"
className="h-4 w-4 text-indigo-500 dark:text-indigo-400"
>
<circle cx="12" cy="12" r="4" />
<path d="M12 2v2M12 20v2M2 12h2M20 12h2M5 5l1.5 1.5M17.5 17.5 19 19M19 5l-1.5 1.5M6.5 17.5 5 19" />
</svg>
Move your cursor
</motion.span>
<motion.h1
variants={fade}
custom={1}
className="mt-6 text-4xl font-semibold tracking-tight text-slate-900 sm:text-6xl dark:text-white"
>
Follow the light
</motion.h1>
<motion.p
variants={fade}
custom={2}
className="mx-auto mt-5 max-w-xl text-base leading-relaxed text-slate-600 sm:text-lg dark:text-slate-400"
>
A spotlight tracks your pointer with a gentle spring, lighting up a
hidden lattice of colour as it passes. It settles calmly to centre
when you leave.
</motion.p>
<motion.div variants={fade} custom={3} className="mt-9">
<a
href="#"
className="group inline-flex items-center gap-2 rounded-full bg-slate-900 px-6 py-3 text-sm font-semibold text-white shadow-lg transition hover:bg-slate-700 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-slate-900 focus-visible:ring-offset-2 focus-visible:ring-offset-slate-50 dark:bg-white dark:text-slate-900 dark:hover:bg-slate-200 dark:focus-visible:ring-white dark:focus-visible:ring-offset-slate-950"
>
Explore the effect
<svg
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth={2}
strokeLinecap="round"
strokeLinejoin="round"
aria-hidden="true"
className="h-4 w-4 transition group-hover:translate-x-0.5"
>
<path d="M5 12h14M13 6l6 6-6 6" />
</svg>
</a>
</motion.div>
</motion.div>
</section>
);
}Dependencies
Licence
Built by Web Innoventix. Free for personal and commercial use, no attribution required.
Built by Web Innoventix
Need a custom interface, a full website, or SEO that gets you cited by AI? We design, build and rank it end to end.
Get a free quoteSimilar components
Browse all →
Aurora Blobs Background
OriginalAn animated hero section with soft, ever-drifting aurora gradient blobs floating behind staggered, blur-in content.

Retro Perspective Grid
OriginalA launch and waitlist section set over an infinite neon grid that scrolls into a glowing horizon with rising particles.

Conic Gradient Flow
OriginalA frosted hero backed by twin counter-rotating conic gradients, with flowing gradient text and an animated gradient-border stat card.

Dot Pattern Background
pattern.tsxA reusable animated background for React and Tailwind: dot pattern background.

Flickering Grid Background
grid.tsxA reusable animated background for React and Tailwind: flickering grid background.

Grid Pattern Background
pattern.tsxA reusable animated background for React and Tailwind: grid pattern background.

Retro Grid Background
grid.jsonA reusable animated background for React and Tailwind: retro grid background.

Spotlight Hero
OriginalA centred hero with a soft radial spotlight, badge and dual call-to-action.

Split Hero
OriginalA two-column hero pairing a headline and CTAs with a product mock and social proof.

Gradient Spotlight Hero
OriginalA minimal centred hero with a soft gradient-mesh backdrop, announcement pill and dual call-to-action buttons.

App Preview Hero
OriginalA centred hero that pairs headline copy with a realistic product dashboard mock built entirely from markup, complete with browser chrome and a floating notification card.

Waitlist Capture Hero
OriginalA dark, focused hero with an inline email capture form and avatar social proof, ready for pre-launch waitlists.

