Floating UI Cards Hero with Mouse Parallax
Original · freeA hero with glassy floating UI cards that drift continuously and shift on mouse-parallax depth around a staggered centre headline.
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/ahero-floating-cards-parallax.json"use client";
import type { PointerEvent, ReactNode } from "react";
import { motion, useMotionValue, useReducedMotion, useSpring, useTransform } from "motion/react";
type FloatingCardProps = {
children: ReactNode;
className: string;
depth: number;
delay: number;
duration: number;
sx: ReturnType<typeof useSpring>;
sy: ReturnType<typeof useSpring>;
reduce: boolean;
};
function FloatingCard({ children, className, depth, delay, duration, sx, sy, reduce }: FloatingCardProps) {
const tx = useTransform(sx, (v) => v * depth);
const ty = useTransform(sy, (v) => v * depth);
return (
<motion.div
className={`absolute ${className}`}
style={reduce ? undefined : { x: tx, y: ty }}
initial={reduce ? { opacity: 0 } : { opacity: 0, scale: 0.8, y: 30 }}
whileInView={reduce ? { opacity: 1 } : { opacity: 1, scale: 1, y: 0 }}
viewport={{ once: true }}
transition={{ duration: 0.7, delay, ease: "easeOut" }}
>
<motion.div
animate={reduce ? undefined : { y: [0, -12, 0] }}
transition={{ duration, repeat: Infinity, ease: "easeInOut" }}
className="rounded-2xl border border-zinc-200/80 bg-white/80 p-4 shadow-xl shadow-zinc-900/5 backdrop-blur-md dark:border-white/10 dark:bg-zinc-900/70 dark:shadow-black/30"
>
{children}
</motion.div>
</motion.div>
);
}
export default function AheroFloatingCardsParallax() {
const reduce = useReducedMotion();
const mx = useMotionValue(0);
const my = useMotionValue(0);
const sx = useSpring(mx, { stiffness: 60, damping: 18, mass: 0.6 });
const sy = useSpring(my, { stiffness: 60, damping: 18, mass: 0.6 });
function handleMove(e: PointerEvent<HTMLDivElement>) {
if (reduce) return;
const rect = e.currentTarget.getBoundingClientRect();
mx.set(((e.clientX - rect.left) / rect.width - 0.5) * 44);
my.set(((e.clientY - rect.top) / rect.height - 0.5) * 44);
}
function handleLeave() {
mx.set(0);
my.set(0);
}
return (
<section
onPointerMove={handleMove}
onPointerLeave={handleLeave}
className="relative isolate flex min-h-screen items-center justify-center overflow-hidden bg-zinc-50 px-6 py-24 dark:bg-zinc-950"
>
<div aria-hidden="true" className="pointer-events-none absolute inset-0 -z-10">
<div className="absolute left-1/2 top-1/2 h-[40rem] w-[40rem] -translate-x-1/2 -translate-y-1/2 rounded-full bg-gradient-to-br from-indigo-300 via-violet-300 to-transparent opacity-40 blur-3xl dark:from-indigo-700 dark:via-violet-800 dark:opacity-30" />
<div className="absolute inset-0 bg-[radial-gradient(circle_at_center,transparent_55%,rgba(244,244,245,0.9)_100%)] dark:bg-[radial-gradient(circle_at_center,transparent_55%,rgba(9,9,11,0.9)_100%)]" />
</div>
{/* Floating cards */}
<FloatingCard sx={sx} sy={sy} reduce={!!reduce} depth={1.2} delay={0.15} duration={6} className="left-[6%] top-[16%] hidden w-52 lg:block">
<div className="flex items-center gap-3">
<span className="flex h-10 w-10 items-center justify-center rounded-xl bg-emerald-100 text-emerald-600 dark:bg-emerald-500/15 dark:text-emerald-400">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={2} strokeLinecap="round" strokeLinejoin="round" aria-hidden="true" className="h-5 w-5">
<path d="M4 17l6-6 4 4 6-6" />
</svg>
</span>
<div>
<p className="text-xs text-zinc-500 dark:text-zinc-400">Revenue</p>
<p className="text-lg font-semibold text-zinc-900 dark:text-white">+38.2%</p>
</div>
</div>
<div className="mt-3 flex h-8 items-end gap-1">
{[40, 65, 50, 80, 60, 92, 74].map((h, i) => (
<span key={i} className="flex-1 rounded-sm bg-emerald-400/80 dark:bg-emerald-500/70" style={{ height: `${h}%` }} />
))}
</div>
</FloatingCard>
<FloatingCard sx={sx} sy={sy} reduce={!!reduce} depth={0.6} delay={0.3} duration={7.5} className="right-[7%] top-[14%] hidden w-60 md:block">
<div className="flex items-center gap-2">
<span className="flex h-8 w-8 items-center justify-center rounded-full bg-indigo-100 text-indigo-600 dark:bg-indigo-500/15 dark:text-indigo-400">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={2} strokeLinecap="round" strokeLinejoin="round" aria-hidden="true" className="h-4 w-4">
<path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" />
</svg>
</span>
<p className="text-sm font-semibold text-zinc-900 dark:text-white">New comment</p>
</div>
<p className="mt-2 text-sm text-zinc-600 dark:text-zinc-300">
“This flow is so much cleaner now, ship it.”
</p>
</FloatingCard>
<FloatingCard sx={sx} sy={sy} reduce={!!reduce} depth={0.9} delay={0.45} duration={6.8} className="bottom-[16%] left-[9%] hidden w-56 md:block">
<p className="text-xs font-medium uppercase tracking-wide text-zinc-500 dark:text-zinc-400">Team online</p>
<div className="mt-3 flex items-center">
<div className="flex -space-x-2">
{["bg-rose-400", "bg-amber-400", "bg-sky-400", "bg-violet-400"].map((c, i) => (
<span key={i} className={`h-8 w-8 rounded-full border-2 border-white ${c} dark:border-zinc-900`} />
))}
</div>
<span className="ml-3 text-sm font-medium text-zinc-700 dark:text-zinc-300">+12 active</span>
</div>
</FloatingCard>
<FloatingCard sx={sx} sy={sy} reduce={!!reduce} depth={1.35} delay={0.6} duration={5.6} className="bottom-[14%] right-[8%] hidden w-52 lg:block">
<div className="flex items-center justify-between">
<p className="text-sm font-semibold text-zinc-900 dark:text-white">Launch</p>
<span className="rounded-full bg-violet-100 px-2 py-0.5 text-xs font-medium text-violet-700 dark:bg-violet-500/15 dark:text-violet-300">92%</span>
</div>
<div className="mt-3 h-2 w-full overflow-hidden rounded-full bg-zinc-200 dark:bg-zinc-700">
<div className="h-full w-[92%] rounded-full bg-gradient-to-r from-violet-500 to-indigo-500" />
</div>
<p className="mt-2 text-xs text-zinc-500 dark:text-zinc-400">11 of 12 tasks done</p>
</FloatingCard>
{/* Centre content */}
<motion.div
initial="hidden"
animate="show"
variants={{ hidden: {}, show: { transition: { staggerChildren: 0.12, delayChildren: 0.1 } } }}
className="relative z-10 mx-auto max-w-2xl text-center"
>
<motion.span
variants={reduce ? { hidden: { opacity: 0 }, show: { opacity: 1 } } : { hidden: { opacity: 0, y: 18 }, show: { opacity: 1, y: 0, transition: { duration: 0.5 } } }}
className="inline-flex items-center gap-2 rounded-full border border-zinc-200 bg-white px-4 py-1.5 text-sm font-medium text-zinc-600 shadow-sm dark:border-zinc-800 dark:bg-zinc-900 dark:text-zinc-300"
>
<span className="h-2 w-2 rounded-full bg-indigo-500" />
Everything in one canvas
</motion.span>
<motion.h1
variants={reduce ? { hidden: { opacity: 0 }, show: { opacity: 1 } } : { hidden: { opacity: 0, y: 24 }, show: { opacity: 1, y: 0, transition: { duration: 0.65, ease: "easeOut" } } }}
className="mt-6 text-5xl font-semibold tracking-tight text-zinc-900 dark:text-white sm:text-6xl"
>
Your whole workflow,
<span className="block bg-gradient-to-r from-indigo-600 via-violet-600 to-fuchsia-500 bg-clip-text text-transparent dark:from-indigo-400 dark:via-violet-400 dark:to-fuchsia-400">
floating in one place
</span>
</motion.h1>
<motion.p
variants={reduce ? { hidden: { opacity: 0 }, show: { opacity: 1 } } : { hidden: { opacity: 0, y: 18 }, show: { opacity: 1, y: 0, transition: { duration: 0.6 } } }}
className="mx-auto mt-6 max-w-lg text-lg leading-relaxed text-zinc-600 dark:text-zinc-400"
>
Metrics, messages and momentum, all on one living surface that moves with you as you work.
</motion.p>
<motion.div
variants={reduce ? { hidden: { opacity: 0 }, show: { opacity: 1 } } : { hidden: { opacity: 0, y: 18 }, show: { opacity: 1, y: 0, transition: { duration: 0.6 } } }}
className="mt-9 flex flex-col items-center justify-center gap-3 sm:flex-row"
>
<motion.a
href="#"
whileHover={reduce ? undefined : { scale: 1.03 }}
whileTap={reduce ? undefined : { scale: 0.97 }}
className="inline-flex w-full items-center justify-center gap-2 rounded-xl bg-zinc-900 px-6 py-3 text-sm font-semibold text-white shadow-lg shadow-zinc-900/10 transition-colors hover:bg-zinc-800 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-indigo-500 focus-visible:ring-offset-2 focus-visible:ring-offset-zinc-50 dark:bg-white dark:text-zinc-900 dark:hover:bg-zinc-200 dark:focus-visible:ring-offset-zinc-950 sm:w-auto"
>
Open the canvas
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={2} strokeLinecap="round" strokeLinejoin="round" aria-hidden="true" className="h-4 w-4">
<path d="M5 12h14M13 6l6 6-6 6" />
</svg>
</motion.a>
<motion.a
href="#"
whileHover={reduce ? undefined : { scale: 1.03 }}
whileTap={reduce ? undefined : { scale: 0.97 }}
className="inline-flex w-full items-center justify-center gap-2 rounded-xl border border-zinc-200 bg-white px-6 py-3 text-sm font-semibold text-zinc-700 transition-colors hover:bg-zinc-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-zinc-400 focus-visible:ring-offset-2 focus-visible:ring-offset-zinc-50 dark:border-zinc-800 dark:bg-zinc-900 dark:text-zinc-200 dark:hover:bg-zinc-800 dark:focus-visible:ring-offset-zinc-950 sm:w-auto"
>
See how it works
</motion.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 →
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.

Image Backdrop Hero
OriginalA cinematic full-bleed hero with a layered image-style backdrop, overlaid left-aligned copy and a trusted-by logos strip.

Gradient Mesh Hero with Staggered Text Reveal
OriginalA full-screen hero pairing a drifting animated gradient-mesh backdrop with a word-by-word staggered blur-in headline and a logo marquee under the fold.

Typewriter Rotating Words Hero
OriginalA hero whose headline cycles through rotating words with a live typewriter caret over an animated grid backdrop, degrading to a gentle word swap when reduced motion is on.

Aurora Hero with Shimmer CTA and Logo Marquee
OriginalA dark hero with animated aurora light beams, a shimmering sweep across the primary CTA, and dual-direction logo marquees beneath the fold.

Gradient Conversion Hero
MITCentered, full-screen marketing hero with a colour-accent headline word, supporting copy, and dual primary/secondary CTA buttons. Dark-mode ready and dependency-free.

Split Showcase Hero
MITTwo-column hero on a dark background — headline, paragraph, and two buttons beside a gradient media panel. Responsive column stack on mobile.

Aurora Gradient Hero
MITAnimated hero with a shimmering animated-gradient badge and an aurora gradient-text headline over an ambient radial glow. Self-contained CSS animations, dependency-free, respects prefers-reduced-motion.

