Web InnoventixFreeCode

Spotlight Magic Card

card.tsx · attributed

A reusable spotlight magic card for React and Tailwind, with hover and motion.

byMagic UI (magicuidesign)React + Tailwind
spotlightmagiccardcards
Open

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/src-spotlight-magic-card.json
src-spotlight-magic-card.tsx
/* Source: Magic UI (magicuidesign) — https://github.com/magicuidesign/magicui/blob/main/apps/www/registry/magicui/magic-card.tsx — MIT. Included under its original licence.
   Copyright (c) Magic UI. Adapted: dropped next-themes + shadcn tokens and the "orb" mode, kept the pointer-follow gradient-border spotlight; concrete zinc/white surface with dark: variants. */
"use client";

import { useCallback, useEffect } from "react";
import {
  motion,
  useMotionTemplate,
  useMotionValue,
  type MotionValue,
} from "motion/react";

const cn = (...c: Array<string | false | null | undefined>) =>
  c.filter(Boolean).join(" ");

interface MagicCardProps {
  children?: React.ReactNode;
  className?: string;
  gradientSize?: number;
  gradientColor?: string;
  gradientOpacity?: number;
  gradientFrom?: string;
  gradientTo?: string;
}

function MagicCard({
  children,
  className,
  gradientSize = 220,
  gradientColor = "rgba(99,102,241,0.30)",
  gradientOpacity = 0.85,
  gradientFrom = "#9E7AFF",
  gradientTo = "#FE8BBB",
}: MagicCardProps) {
  const mouseX: MotionValue<number> = useMotionValue(-gradientSize);
  const mouseY: MotionValue<number> = useMotionValue(-gradientSize);

  const handlePointerMove = useCallback(
    (e: React.PointerEvent<HTMLDivElement>) => {
      const rect = e.currentTarget.getBoundingClientRect();
      mouseX.set(e.clientX - rect.left);
      mouseY.set(e.clientY - rect.top);
    },
    [mouseX, mouseY]
  );

  const reset = useCallback(() => {
    mouseX.set(-gradientSize);
    mouseY.set(-gradientSize);
  }, [mouseX, mouseY, gradientSize]);

  useEffect(() => {
    reset();
  }, [reset]);

  const borderBackground = useMotionTemplate`radial-gradient(${gradientSize}px circle at ${mouseX}px ${mouseY}px, ${gradientFrom}, ${gradientTo}, transparent 100%)`;
  const spotlightBackground = useMotionTemplate`radial-gradient(${gradientSize}px circle at ${mouseX}px ${mouseY}px, ${gradientColor}, transparent 100%)`;

  return (
    <div
      className={cn(
        "group relative isolate overflow-hidden rounded-2xl",
        className
      )}
      onPointerMove={handlePointerMove}
      onPointerEnter={handlePointerMove}
      onPointerLeave={reset}
    >
      {/* gradient border layer — only the 1px ring around the surface shows through */}
      <motion.div
        aria-hidden
        className="pointer-events-none absolute inset-0 z-0 rounded-2xl"
        style={{ background: borderBackground }}
      />
      {/* card surface, inset by the border width */}
      <div className="absolute inset-px z-10 rounded-[15px] bg-white dark:bg-zinc-950" />
      {/* soft spotlight glow over the surface, following the pointer */}
      <motion.div
        aria-hidden
        className="pointer-events-none absolute inset-px z-20 rounded-[15px]"
        style={{ background: spotlightBackground, opacity: gradientOpacity }}
      />
      <div className="relative z-30">{children}</div>
    </div>
  );
}

export default function SpotlightMagicCard() {
  return (
    <section className="bg-white px-6 py-16 dark:bg-zinc-950 md:py-24">
      <div className="mx-auto max-w-2xl text-center">
        <p className="text-sm font-semibold uppercase tracking-widest text-indigo-600 dark:text-indigo-400">
          Interactive
        </p>
        <h2 className="mt-3 text-balance text-3xl font-bold tracking-tight text-zinc-900 sm:text-4xl dark:text-white">
          A spotlight that follows your cursor
        </h2>
        <p className="mt-4 text-lg text-zinc-600 dark:text-zinc-400">
          Move your pointer across the cards. The gradient border and inner glow
          track the cursor in real time.
        </p>
      </div>

      <div className="mx-auto mt-12 grid max-w-4xl gap-6 sm:grid-cols-2">
        {[
          {
            label: "Realtime",
            title: "Live collaboration",
            body: "Everyone edits the same page at once, with changes that appear the instant they happen.",
          },
          {
            label: "Secure",
            title: "Encrypted by default",
            body: "Data is protected at rest and in transit, so your work stays yours from the first keystroke.",
          },
        ].map((card) => (
          <MagicCard key={card.title} className="h-full">
            <div className="p-8">
              <span className="inline-flex items-center rounded-full bg-indigo-50 px-3 py-1 text-xs font-semibold uppercase tracking-wide text-indigo-600 dark:bg-indigo-500/10 dark:text-indigo-400">
                {card.label}
              </span>
              <h3 className="mt-5 text-xl font-bold text-zinc-900 dark:text-white">
                {card.title}
              </h3>
              <p className="mt-2 text-sm leading-relaxed text-zinc-600 dark:text-zinc-400">
                {card.body}
              </p>
              <p className="mt-6 inline-flex items-center gap-1 text-sm font-semibold text-indigo-600 dark:text-indigo-400">
                Learn more
                <svg
                  aria-hidden="true"
                  viewBox="0 0 20 20"
                  fill="none"
                  stroke="currentColor"
                  strokeWidth={2}
                  strokeLinecap="round"
                  strokeLinejoin="round"
                  className="h-4 w-4"
                >
                  <path d="M4 10h12M11 5l5 5-5 5" />
                </svg>
              </p>
            </div>
          </MagicCard>
        ))}
      </div>
    </section>
  );
}

Dependencies

motion

Licence

Magic UI (magicuidesign) (original) · Licensed under card.tsx.

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 quote

Similar components

Browse all →
3D Tilt Cards

3D Tilt Cards

Original

A responsive grid of cards that tilt in 3D toward your cursor with a light glare and lifted depth layers, powered by Framer Motion springs.

Spotlight Follow Cards

Spotlight Follow Cards

Original

Feature cards where a soft radial spotlight and a glowing border chase the cursor on hover, with a staggered scroll reveal and an animated shimmer line.

3D Flip Cards

3D Flip Cards

Original

Pricing-style cards that flip in 3D on hover or tap to reveal details on the back, keyboard accessible with a staggered entrance animation.

Animated Gradient Border Cards

Animated Gradient Border Cards

Original

Cards wrapped in a live conic gradient border that rotates and speeds up on hover, with a shimmer sweep and a scrolling tag marquee.

Glow Effect Card

Glow Effect Card

primitives

A reusable glow effect card for React and Tailwind, with hover and motion.

Neon Gradient Card

Neon Gradient Card

gradient-card.tsx

A reusable neon gradient card for React and Tailwind, with hover and motion.

Tilt Spotlight Card

Tilt Spotlight Card

primitives

A reusable tilt spotlight card for React and Tailwind, with hover and motion.

Spotlight Hero

Spotlight Hero

Original

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

Split Hero

Split Hero

Original

A two-column hero pairing a headline and CTAs with a product mock and social proof.

Gradient Spotlight Hero

Gradient Spotlight Hero

Original

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

App Preview Hero

App Preview Hero

Original

A 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

Waitlist Capture Hero

Original

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