Spotlight card

Free · MIT

A soft spotlight and a lit border follow the pointer across a card; in a group, neighboring cards' borders light up too.

MarkdownOpen in v0
Open in v0

Installation

$ npx shadcn@latest add https://goodui.dev/r/spotlight-card.json

The file lands in components/goodui/spotlight-card.tsx and is yours to edit. With the @goodui registry added, npx shadcn@latest add @goodui/spotlight-card works too.

Usage

import { CalendarCheck, CreditCard, MessageSquare } from "lucide-react"
import { SpotlightCard, SpotlightGroup } from "@/components/goodui/spotlight-card"

const features = [
  { icon: CalendarCheck, title: "Online booking", text: "Clients pick a slot from your real availability." },
  { icon: MessageSquare, title: "SMS reminders", text: "Automatic reminders 24 hours and 2 hours before." },
  { icon: CreditCard, title: "Deposits", text: "Take a card deposit when the booking is made." },
]

export function Features() {
  return (
    <SpotlightGroup className="grid gap-4 sm:grid-cols-3">
      {features.map((f) => (
        <SpotlightCard key={f.title} className="p-6">
          <f.icon className="size-5 text-primary" />
          <h3 className="mt-4 font-semibold">{f.title}</h3>
          <p className="mt-1 text-sm text-muted-foreground">{f.text}</p>
        </SpotlightCard>
      ))}
    </SpotlightGroup>
  )
}

When to use

Use it for
  • Feature grids and bento layouts on a landing page, where a soft light following the cursor adds depth.
  • A grid of plans, integrations or services where neighboring borders should light up together (SpotlightGroup).
  • Dark sections, where the lit border reads especially well.
Reach for something else
  • A single card that also needs variants, tones, padding and header/footer parts: card with animation="spotlight" is simpler and gives the same effect.
  • Clickable rows in dense lists and tables: use a plain hover background; a spotlight per row is noisy.
  • Touch-first screens: the effect needs a hovering pointer. Use card or tilt-card for a press response.
If you needUse
One card with the effectSpotlightCard
A grid where neighboring borders light up togetherSpotlightGroup around SpotlightCards
Brand-colored lightspotlightColor="color-mix(in oklch, var(--primary) 12%, transparent)" borderColor="var(--primary)"
Card with a 2px borderborderWidth={2} plus border-2
Single card with variants and tonescard with animation="spotlight"

Examples

Single card in the brand color

<SpotlightCard
  className="p-6"
  size={420}
  spotlightColor="color-mix(in oklch, var(--primary) 12%, transparent)"
  borderColor="var(--primary)"
>
  <h3 className="font-semibold">Pro plan</h3>
  <p className="text-sm text-muted-foreground">Unlimited staff and locations.</p>
</SpotlightCard>

API reference

SpotlightCard

PropTypeDefault
spotlightColor
Fill color of the soft spotlight.
string—
borderColor
Color of the lit border.
string—
size
Diameter of the spotlight in px.
number360
borderWidth
Border width the highlight should cover, in px (match the card's border).
number1

Also accepts every <div> attribute.

SpotlightGroup

Also accepts every <div> attribute.

Accessibility

  • SpotlightCard is a plain <div> with card styles; the light is drawn with pseudo-elements that ignore the pointer and are not announced.
  • If the whole card is clickable, put a real link or button inside it; the card itself is not focusable.
  • The effect follows the pointer only; keyboard users see a normal card.

Motion

  • A soft radial fill (`size` px, 360) and a lit border ring (75% of that size) follow the pointer and fade in and out over 0.35 s.
  • Inside a SpotlightGroup, moving anywhere over the group lights the borders of every card near the pointer, while only the hovered card gets the fill.
  • The light follows the pointer directly; nothing loops.
  • Reduced motion: the fade in and out is instant.
  • Pointer moves only write two CSS variables; React does not re-render. SpotlightGroup batches updates to one per animation frame.

Notes for AI

Coding agents read these rules through MCP and llms.txt, or paste this page with Copy page.

  • Put padding and layout on SpotlightCard with className (p-6 …); it already has rounded-xl, border, bg-card.
  • SpotlightGroup is a plain div: give it the grid classes. Cards can be nested at any depth inside it.
  • Colors are any CSS color; use translucent fills (color-mix with transparent), or the content gets washed out.
  • Match borderWidth to the card's border width so the lit ring covers it exactly.

FAQ

Core card animation="spotlight" or SpotlightCard?

For one card, the Core card is simpler and adds variants, tones and parts. SpotlightCard adds SpotlightGroup (linked borders across a grid) and custom colors, size and border width.

Do the cards have to be direct children of SpotlightGroup?

No. The group finds every SpotlightCard inside it at any depth, so wrappers and grid cells are fine.

Related