Web InnoventixFreeCode

Floating UI Cards Hero with Mouse Parallax

Original · free

A hero with glassy floating UI cards that drift continuously and shift on mouse-parallax depth around a staggered centre headline.

byWeb InnoventixReact + Tailwind
floating cards heroparallax heroanimated heroframer motion parallaxfloating ui cardshero section
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/ahero-floating-cards-parallax.json
ahero-floating-cards-parallax.tsx
"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">
          &ldquo;This flow is so much cleaner now, ship it.&rdquo;
        </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

motion

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 quote

Similar components

Browse all →
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.

Image Backdrop Hero

Image Backdrop Hero

Original

A 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

Gradient Mesh Hero with Staggered Text Reveal

Original

A 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

Typewriter Rotating Words Hero

Original

A 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

Aurora Hero with Shimmer CTA and Logo Marquee

Original

A 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

Gradient Conversion Hero

MIT

Centered, 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

Split Showcase Hero

MIT

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

Aurora Gradient Hero

Aurora Gradient Hero

MIT

Animated 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.