A perspective floor of grid lines gliding toward you under a glowing horizon, tinted with any theme color, tilt and cell size adjustable, still under reduced motion.
Ship it tonight
Back to the future of UI
A grid that keeps moving toward you while you build.
import { RetroGrid } from "@/components/ballmac/retro-grid"
export default function RetroGridDemo() {
return (
<div className="relative flex h-80 w-full max-w-2xl flex-col items-center justify-center overflow-hidden rounded-2xl border bg-background">
<RetroGrid tone="chart-1" />
<div className="relative z-10 grid justify-items-center gap-3 px-6 text-center">
<p className="font-mono text-xs tracking-widest text-muted-foreground uppercase">Ship it tonight</p>
<h3 className="text-4xl font-semibold tracking-tight text-foreground sm:text-5xl">Back to the future of UI</h3>
<p className="max-w-sm text-sm text-muted-foreground">A grid that keeps moving toward you while you build.</p>
</div>
</div>
)
}Installation
$ pnpm dlx shadcn@latest add @ballmac/retro-gridInstall the dependencies.
$ pnpm add motion@^12Copy the source into your project.
components/ballmac/retro-grid.tsx// Ballmac UI: Retro Grid. https://ui.ballmac.com/components/retro-grid "use client" import * as React from "react" import { motion, useReducedMotion } from "motion/react" import { cn } from "@/lib/utils" type GridTone = "foreground" | "primary" | "chart-1" | "chart-2" | "chart-3" | "chart-4" | "chart-5" const VAR: Record<GridTone, string> = { foreground: "var(--foreground)", primary: "var(--primary)", "chart-1": "var(--chart-1)", "chart-2": "var(--chart-2)", "chart-3": "var(--chart-3)", "chart-4": "var(--chart-4)", "chart-5": "var(--chart-5)", } type RetroGridProps = Omit<React.ComponentProps<"div">, "children"> & { /** Tilt of the floor in degrees. Higher is flatter and looks deeper. */ angle?: number /** Size of one grid cell in pixels, at the front of the floor. */ cellSize?: number /** Line color. */ tone?: GridTone /** Seconds the floor takes to slide forward by one cell. Higher is slower. */ speed?: number /** Soft glow along the horizon. */ glow?: boolean } /** A perspective floor of grid lines that glides toward you, with a glowing horizon. Decorative. */ function RetroGrid({ angle = 62, cellSize = 64, tone = "foreground", speed = 1.4, glow = true, className, ...props }: RetroGridProps) { const reduce = useReducedMotion() const line = `color-mix(in oklab, ${VAR[tone]} 52%, transparent)` return ( <div data-slot="retro-grid" aria-hidden="true" className={cn("pointer-events-none absolute inset-0 overflow-hidden opacity-90 [perspective:240px]", className)} {...props} > <div className="absolute inset-0 [mask-image:linear-gradient(to_bottom,transparent_0%,black_38%)]" style={{ transform: `rotateX(${angle}deg)` }}> <motion.div className="absolute -inset-x-[200%] -top-[100%] h-[300%]" style={{ backgroundImage: `linear-gradient(to right, ${line} 1.5px, transparent 0), linear-gradient(to bottom, ${line} 1.5px, transparent 0)`, backgroundSize: `${cellSize}px ${cellSize}px`, }} animate={reduce ? undefined : { backgroundPositionY: [0, cellSize] }} transition={{ duration: speed, repeat: Infinity, ease: "linear" }} /> </div> {glow && ( <span className="absolute inset-x-0 top-0 h-2/5" style={{ background: `radial-gradient(70% 90% at 50% 0%, color-mix(in oklab, ${VAR[tone === "foreground" ? "chart-1" : tone]} 28%, transparent), transparent 75%)` }} /> )} <span className="absolute inset-0 bg-gradient-to-b from-background via-transparent to-transparent" /> </div> ) } export { RetroGrid, type RetroGridProps, type GridTone }Update the import paths to match your project setup.
Usage
import { RetroGrid } from "@/components/ballmac/retro-grid"The full example is in the Code tab above.
Examples
Tones and tilt
import { RetroGrid, type GridTone } from "@/components/ballmac/retro-grid"
const sets: { tone: GridTone; angle: number }[] = [
{ tone: "chart-4", angle: 70 },
{ tone: "chart-2", angle: 58 },
{ tone: "foreground", angle: 64 },
{ tone: "chart-3", angle: 66 },
]
export default function RetroGridTones() {
return (
<div className="grid w-full max-w-xl grid-cols-2 gap-3">
{sets.map(({ tone, angle }) => (
<div key={tone} className="relative h-36 overflow-hidden rounded-xl border bg-background">
<RetroGrid tone={tone} angle={angle} cellSize={44} />
<span className="absolute bottom-2 start-3 z-10 font-mono text-[11px] text-muted-foreground">
{tone} · {angle}°
</span>
</div>
))}
</div>
)
}API reference
| Prop | Type | Default |
|---|---|---|
angleTilt of the floor in degrees. Higher is flatter and looks deeper. | number | 62 |
cellSizeSize of one grid cell in pixels, at the front of the floor. | number | 64 |
toneLine color. | GridTone | "foreground" |
speedSeconds the floor takes to slide forward by one cell. Higher is slower. | number | 1.4 |
glowSoft glow along the horizon. | boolean | true |
Also accepts the standard attributes of its root element.
Accessibility
| Key | Action |
|---|---|
| Screen readers | Decorative: aria-hidden and pointer-events-none |
| Reduced motion | The floor is still |
Use with AI
Place <RetroGrid angle cellSize tone speed glow /> inside a relative, overflow-hidden parent and put content above it. It fades into the page background at the horizon. With the shadcn MCP server set up (guide), ask your agent:
Add the Ballmac UI Retro Grid (@ballmac/retro-grid) to this project with the shadcn MCP, then use it where it fits.
Use it for
- Landing page heroes with a technical or retro mood
- Under a centered headline and call to action
Not for
- Dense UI behind small text
- Pages with many competing backgrounds
Registry JSON: https://ui.ballmac.com/r/retro-grid.json
Credits
Free to use in personal and commercial projects.
- npm
- motion@^12
- Registry
- shadcn/utils
Pairs well with
Grid Pattern
A crisp square-grid background in the border color with optional dashed lines, filled cells, softly lighting random cells and an edge fade, drawn as one SVG pattern.
Light Rays
Soft beams of theme-colored light fanning down from the top edge, each swaying and breathing at its own pace, deterministic so the server and browser match.
Aurora Background
Soft, slowly drifting aurora light made of blurred token-colored glows with fine vertical curtains and an optional radial fade. Pure CSS layers, paused off-screen, still under reduced motion.
Beams Background
Hairline rails with thin light beams rising along them and dissolving near the top, over a soft glow. Canvas, token colors, DPR aware, pauses off-screen, a still frame under reduced motion.