Cityscape
A night skyline with flickering windows and rooftop signs.
Still up? So is the city.
Installation
npx shadcn@latest add https://neonkit.heyaadi.com/r/cityscape.jsonUsage
import { Cityscape } from "@/components/ui/cityscape"
<section className="relative overflow-hidden bg-[#05060a]">
<Cityscape signs={["HOTEL", "24H"]} />
<h1 className="relative">Still up? So is the city.</h1>
</section>Examples
Your own signs
Up to three rooftop signs, each with its own color. The first stands on scaffolding; the others get a tube frame.
Time of night
lights sets the share of lit windows. Same seed, same skyline: only the hour changes.
Seeds
Every seed builds a different skyline, and the same one every time.
Footer with parallax
With parallax on, the back rows drift as the page scrolls. Scroll this page to see it.
API reference
Stacked SVG layers that fill the nearest positioned parent. The skyline is a 1600 by 400 scene anchored to the bottom edge: narrow boxes crop the sides, and buildings scale with the box height. To keep the city low in a tall hero, size the layer, for example className="top-auto h-64". Accepts native div attributes.
| Prop | Type | Default |
|---|---|---|
color | NeonColorSky glow, haze, crown lighting and the first sign. The second sign takes a contrasting hue mixed from it. | inherited |
seed | numberWhich skyline to build. The same seed always gives the same city. | 7 |
lights | numberShare of windows lit, 0 to 1. The default reads as two in the morning. | 0.16 |
signs | (string | { text: string; color?: NeonColor })[]Up to three rooftop signs, placed near the middle so they survive narrow crops. Pass [] for none. | ["HOTEL", "24H"] |
flicker | booleanWindows switch on and off, TVs flicker, beacons blink and signs stutter. | true |
stars | booleanFaint stars above the skyline. | true |
parallax | booleanBack rows lag behind as the page scrolls. A number sets the far row's travel in pixels (default 28). | false |
Accessibility
- Decorative: rendered with aria-hidden and pointer-events: none.
- Sign lettering inherits the font of the layer. It looks best with a monoline face such as Tilt Neon: set it with className or style on the Cityscape.
- The skyline is generated in the browser after hydration (it's tens of kilobytes of path data you don't want in your HTML), then fades in.
- Lit windows share one path per color, so the whole city is a few dozen nodes. Flicker runs on a slow timer with direct style writes: no animation frames and no re-renders. It pauses offscreen and in hidden tabs.
- Under prefers-reduced-motion the city is a still frame: no flicker, no fade and no parallax.