Into the future
Customize
Usage
import { HorizonGrid } from "@/components/motionkit/horizon-grid";
<HorizonGrid className="h-96 rounded-3xl pt-20 text-center">
<h1>Your hero</h1>
</HorizonGrid>Motion
The exact curves this component runs, plotted with Motion's own maths.
Roll forward
Runs on its own
Works in the App Router as is. Requires Tailwind CSS v4.
npm install motionSave as components/motionkit/horizon-grid.tsx.
"use client";
import type { ReactNode } from "react";
import { motion, useReducedMotion } from "motion/react";
type HorizonGridProps = {
children?: ReactNode;
/** Grid square size in pixels. */
cell?: number;
/** Tilt of the floor in degrees. Higher looks flatter. */
angle?: number;
/** Seconds for the grid to travel one square toward the viewer. */
duration?: number;
/** Line and horizon colour. */
color?: string;
className?: string;
};
export function HorizonGrid({
children,
cell = 40,
angle = 70,
duration = 1.2,
color = "#2E9098",
className = "",
}: HorizonGridProps) {
const reduceMotion = useReducedMotion();
return (
<div className={`relative isolate overflow-hidden bg-[#0C1010] ${className}`}>
<div aria-hidden className="absolute inset-x-0 bottom-0 -z-10 h-[45%] overflow-hidden [perspective-origin:50%_0%] [perspective:200px]">
{/* the floor hinges on the bottom edge and tips away; moving the pattern by exactly one square loops seamlessly */}
<motion.div
className="absolute -inset-x-full bottom-0 h-[400%]"
style={{
rotateX: angle,
originY: 1,
backgroundImage: `linear-gradient(to right, ${color} 1px, transparent 1px), linear-gradient(to bottom, ${color} 1px, transparent 1px)`,
backgroundSize: `${cell}px ${cell}px`,
opacity: 0.55,
}}
animate={reduceMotion ? undefined : { backgroundPosition: ["0px 0px", `0px ${cell}px`] }}
transition={{ duration, repeat: Infinity, ease: "linear" }}
/>
{/* fade the far edge into the horizon */}
<div className="absolute inset-0 bg-[linear-gradient(to_bottom,#0C1010,transparent_60%)]" />
</div>
{/* the horizon line and its glow */}
<div
aria-hidden
className="absolute inset-x-0 top-[55%] -z-10 h-px"
style={{ background: `linear-gradient(to right, transparent, ${color}, transparent)`, boxShadow: `0 0 40px 6px ${color}55` }}
/>
{children}
</div>
);
}
| Prop | Type | Default | Description |
|---|---|---|---|
| cell | number | 40 | Grid square size in pixels. |
| angle | number | 70 | Tilt of the floor in degrees. Higher looks flatter. |
| duration | number | 1.2 | Seconds for the grid to travel one square toward the viewer. |
| color | string | "#2E9098" | Line and horizon colour. |
To infinity
Infinite Perspective Grid
A true 3D floor of glowing lines that recedes forever to a lit horizon, with an optional ceiling for a tunnel.
Ambient by default
Aurora Background
Drifting, blurred color fields for hero sections and empty states.
Warm, textured, alive
Grain Gradient
Slow, drifting colour with a fine film grain, for warm editorial heroes.