Web InnoventixFreeCode

Retro Perspective Grid

Original · free

A launch and waitlist section set over an infinite neon grid that scrolls into a glowing horizon with rising particles.

byWeb InnoventixReact + Tailwind
animated grid backgroundretro gridperspective gridwaitlist heroneon gridscrolling grid
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/bg-retro-grid.json
bg-retro-grid.tsx
"use client";

import { motion, useReducedMotion, type Variants } from "motion/react";

const gridImage =
  "linear-gradient(to right, currentColor 1px, transparent 1px), linear-gradient(to bottom, currentColor 1px, transparent 1px)";

const fade: Variants = {
  hidden: { opacity: 0, y: 20 },
  show: (i: number) => ({
    opacity: 1,
    y: 0,
    transition: { duration: 0.6, delay: i * 0.1, ease: [0.22, 1, 0.36, 1] },
  }),
};

const particles = [
  { left: "14%", delay: "0s", dur: "7s", size: "h-1.5 w-1.5" },
  { left: "34%", delay: "-3s", dur: "9s", size: "h-1 w-1" },
  { left: "52%", delay: "-1.5s", dur: "8s", size: "h-1.5 w-1.5" },
  { left: "71%", delay: "-4.5s", dur: "10s", size: "h-1 w-1" },
  { left: "88%", delay: "-2s", dur: "7.5s", size: "h-1.5 w-1.5" },
];

export default function BgRetroGrid() {
  const reduce = useReducedMotion();

  return (
    <section className="relative isolate flex min-h-[640px] w-full items-center justify-center overflow-hidden bg-white px-6 py-24 dark:bg-slate-950">
      <style>{`
        @keyframes brg-scroll { from { background-position: 0 0, 0 0; } to { background-position: 0 48px, 0 48px; } }
        @keyframes brg-rise { 0% { transform: translateY(0); opacity: 0; } 12% { opacity: 1; } 88% { opacity: 1; } 100% { transform: translateY(-260px); opacity: 0; } }
        @keyframes brg-pulse { 0%,100% { opacity: 0.55; transform: translate(-50%,-50%) scale(1); } 50% { opacity: 0.85; transform: translate(-50%,-50%) scale(1.12); } }
        .brg-grid { animation: brg-scroll 2s linear infinite; }
        .brg-particle { animation: brg-rise linear infinite; }
        .brg-glow { animation: brg-pulse 6s ease-in-out infinite; }
        @media (prefers-reduced-motion: reduce) {
          .brg-grid, .brg-particle, .brg-glow { animation: none !important; }
        }
      `}</style>

      {/* perspective floor grid */}
      <div
        aria-hidden="true"
        className="pointer-events-none absolute inset-0 -z-10 overflow-hidden"
      >
        <div className="absolute bottom-0 left-1/2 h-[70%] w-[320%] -translate-x-1/2 [perspective:900px]">
          <div
            className="brg-grid absolute inset-0 origin-bottom text-indigo-500/25 [transform:rotateX(72deg)] dark:text-indigo-400/20"
            style={{
              backgroundImage: gridImage,
              backgroundSize: "48px 48px",
              maskImage: "linear-gradient(to top, black 8%, transparent 78%)",
              WebkitMaskImage: "linear-gradient(to top, black 8%, transparent 78%)",
            }}
          />
        </div>

        {/* horizon glow */}
        <div className="brg-glow absolute left-1/2 top-1/2 h-44 w-[78%] rounded-full bg-indigo-500/25 blur-3xl dark:bg-indigo-500/30" />

        {/* rising particles */}
        <div className="absolute inset-x-0 bottom-1/4 top-1/4">
          {!reduce &&
            particles.map((p, i) => (
              <span
                key={i}
                className={`brg-particle absolute bottom-0 rounded-full bg-indigo-500 shadow-[0_0_12px_2px_rgba(99,102,241,0.6)] dark:bg-indigo-300 ${p.size}`}
                style={{ left: p.left, animationDelay: p.delay, animationDuration: p.dur }}
              />
            ))}
        </div>
      </div>

      <div className="relative mx-auto max-w-2xl text-center">
        <motion.span
          custom={0}
          variants={fade}
          initial="hidden"
          whileInView="show"
          viewport={{ once: true, amount: 0.4 }}
          className="inline-flex items-center gap-2 rounded-full border border-indigo-200 bg-indigo-50/70 px-4 py-1.5 text-xs font-semibold uppercase tracking-widest text-indigo-600 backdrop-blur dark:border-indigo-400/20 dark:bg-indigo-500/10 dark:text-indigo-300"
        >
          <svg
            viewBox="0 0 24 24"
            fill="none"
            stroke="currentColor"
            strokeWidth={2}
            strokeLinecap="round"
            strokeLinejoin="round"
            aria-hidden="true"
            className="h-3.5 w-3.5"
          >
            <path d="M13 2 3 14h7l-1 8 10-12h-7z" />
          </svg>
          Built for velocity
        </motion.span>

        <motion.h1
          custom={1}
          variants={fade}
          initial="hidden"
          whileInView="show"
          viewport={{ once: true, amount: 0.4 }}
          className="mt-6 text-4xl font-semibold tracking-tight text-slate-900 sm:text-6xl dark:text-white"
        >
          Ship on an infinite grid
        </motion.h1>

        <motion.p
          custom={2}
          variants={fade}
          initial="hidden"
          whileInView="show"
          viewport={{ once: true, amount: 0.4 }}
          className="mx-auto mt-5 max-w-lg text-base leading-relaxed text-slate-600 sm:text-lg dark:text-slate-400"
        >
          A receding neon grid gives your launch page endless depth while your
          message stays crisp and centred at the horizon.
        </motion.p>

        <motion.form
          custom={3}
          variants={fade}
          initial="hidden"
          whileInView="show"
          viewport={{ once: true, amount: 0.4 }}
          onSubmit={(e) => e.preventDefault()}
          className="mx-auto mt-9 flex w-full max-w-md flex-col gap-3 sm:flex-row"
        >
          <label htmlFor="brg-email" className="sr-only">
            Email address
          </label>
          <input
            id="brg-email"
            type="email"
            required
            placeholder="you@example.com"
            className="w-full flex-1 rounded-full border border-slate-300 bg-white/80 px-5 py-3 text-sm text-slate-900 shadow-sm outline-none backdrop-blur transition placeholder:text-slate-400 focus:border-indigo-500 focus:ring-2 focus:ring-indigo-500/30 dark:border-white/15 dark:bg-white/5 dark:text-white dark:placeholder:text-slate-500"
          />
          <button
            type="submit"
            className="inline-flex items-center justify-center gap-2 rounded-full bg-indigo-600 px-6 py-3 text-sm font-semibold text-white shadow-lg shadow-indigo-500/25 transition hover:bg-indigo-500 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-indigo-500 focus-visible:ring-offset-2 focus-visible:ring-offset-white dark:focus-visible:ring-offset-slate-950"
          >
            Join waitlist
          </button>
        </motion.form>
      </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 →
Aurora Blobs Background

Aurora Blobs Background

Original

An animated hero section with soft, ever-drifting aurora gradient blobs floating behind staggered, blur-in content.

Conic Gradient Flow

Conic Gradient Flow

Original

A frosted hero backed by twin counter-rotating conic gradients, with flowing gradient text and an animated gradient-border stat card.

Spotlight Follow Background

Spotlight Follow Background

Original

A dot-grid section where a spring-eased spotlight follows the cursor and reveals a hidden lattice of coloured dots.

Dot Pattern Background

Dot Pattern Background

pattern.tsx

A reusable animated background for React and Tailwind: dot pattern background.

Flickering Grid Background

Flickering Grid Background

grid.tsx

A reusable animated background for React and Tailwind: flickering grid background.

Grid Pattern Background

Grid Pattern Background

pattern.tsx

A reusable animated background for React and Tailwind: grid pattern background.

Retro Grid Background

Retro Grid Background

grid.json

A reusable animated background for React and Tailwind: retro grid background.

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.