Cards
PrismCard
A holographic foil shifts its rainbow as the pointer moves, with a soft light under the pointer, like a collector card.
Download
- React
- Tailwind CSS v4
- motion
components/ui/prism-card.tsx
"use client";
import type { CSSProperties, ReactNode } from "react";
import { useReducedMotion } from "motion/react";
type PrismCardProps = {
children: ReactNode;
className?: string;
/** Foil colours. */
colors?: string[];
/** Strength of the foil at rest and on hover, 0 to 1. */
intensity?: number;
};
/* PrismCard: a holographic foil shifts its rainbow as the pointer moves, like a collector card. */
export function PrismCard({
children,
className = "rounded-2xl border border-white/10 bg-[#16132a] p-6 text-white",
colors = ["#ff6b8b", "#ffd36b", "#6bffb0", "#6bd5ff", "#a78bfa", "#ff6b8b"],
intensity = 0.55,
}: PrismCardProps) {
const reduce = useReducedMotion();
return (
<div
onPointerMove={(e) => {
if (reduce) return;
const b = e.currentTarget.getBoundingClientRect();
e.currentTarget.style.setProperty("--mx", `${((e.clientX - b.left) / b.width) * 100}%`);
e.currentTarget.style.setProperty("--my", `${((e.clientY - b.top) / b.height) * 100}%`);
}}
className={`group relative isolate overflow-hidden ${className}`}
style={{ "--mx": "50%", "--my": "50%", "--on": intensity } as CSSProperties}
>
<span
aria-hidden
className="pointer-events-none absolute inset-0 -z-10 opacity-25 mix-blend-color-dodge transition-opacity duration-300 group-hover:opacity-[var(--on)]"
style={{
backgroundImage: `linear-gradient(115deg, ${colors.join(", ")})`,
backgroundSize: "300% 300%",
backgroundPosition: "var(--mx) var(--my)",
}}
/>
<span
aria-hidden
className="pointer-events-none absolute inset-0 -z-10 opacity-0 transition-opacity duration-300 group-hover:opacity-100"
style={{ background: "radial-gradient(circle at var(--mx) var(--my), rgba(255,255,255,0.18), transparent 45%)" }}
/>
{children}
</div>
);
}
1. Install the dependency.
npm i motion2. Paste the Code tab into
components/ui/prism-card.tsx. The styles are Tailwind CSS v4 classes.3. Use it. This is the preview above:
app/prism-card-demo.tsx
import { PrismCard } from "@/components/ui/prism-card"; export default function PrismCardExample() { return ( <div className="grid h-full place-items-center bg-[#0b0a14] p-6"> <PrismCard className="aspect-[5/7] w-full max-w-[220px] rounded-2xl border border-white/15 bg-gradient-to-br from-[#2a2350] to-[#120f22] p-5 text-white"> <p className="font-mono text-[11px] uppercase tracking-[0.2em] text-white/70">Rare · 07/50</p> <p className="mt-auto pt-40 text-2xl font-semibold">Night Owl</p> <p className="mt-1 text-sm text-white/60">Move the pointer to tilt the foil.</p> </PrismCard> </div> ); }
Props
| Name | Type | Default | What it does |
|---|---|---|---|
| children | ReactNode | — | Card content. |
| colors | string[] | rainbow | Foil colours. |
| intensity | number | 0.55 | Foil strength on hover, 0 to 1. |
| className | string | dark violet card | Replaces the default look. |