Installation
pnpm dlx shadcn@latest add https://asciicn.dev/r/miami.jsonUsage
import { Miami } from "@/components/asciicn/miami";
export function Hero() {
return (
<section className="relative isolate min-h-[480px]">
<Miami intensity={0.6} className="absolute inset-0 -z-10" />
<h1>Your headline</h1>
</section>
);
}The whole frame is painted in halftone dots. Each dot takes its own colour, and its size carries the light: the smallest dots in the deep violet at the top of the sky, middle dots through the magenta and the hot coral along the horizon, and the biggest dots kept for the moon, the neon and lit windows.
The view is from the bay, looking across the beach at Ocean Drive after sunset. A row of art deco hotels stands along the sand, their pastel walls washed with light from the street: a cafe arcade at the bottom, eyebrow ledges over each row of windows, a glass-block pylon up the middle, and a stepped parapet on top. Neon in pink, teal or amber traces the top of each parapet, with a spire, a name sign or a vertical blade sign on some of them. Palms stand in silhouette between the hotels.
Behind them the glass towers of Brickell rise in blue haze, the far ones paler, a few with lit crowns and the tallest with a red beacon. A young crescent moon hangs low in the afterglow above them.
The bay mirrors the street, darker and quieter, so only the lights come through, broken into dashes by the ripples. Each hotel's neon runs down the water in a soft streak, and the moon lays a pale glitter path.
Motion is slow: the neon breathes, the water shimmers, a few windows turn on or off every couple of minutes, the palms barely sway, thin clouds drift, and stars twinkle faintly. The pointer does nothing.
The hotels keep their size when the box changes shape, so a phone shows two or three of them instead of squashed ones. On wide boxes a palm stands in the middle and the hotels and towers there stay lower, so the band behind a headline is mostly sky; Brickell and the moon sit to the left. On tall boxes a hotel stands in the middle, below where a headline would sit.
It draws in dots by default on square 7px cells, so the dots lie in an even lattice, about 200 across a 1440px screen. square={false} returns to the usual text cells, twice as tall as wide, and is the default for braille and quadrants, which would stretch. Other ramp charsets such as standard or dense read the same tones as typed glyphs. In truecolor, the default, the scene paints its own violet night paper in both themes. mono with a phosphor and duotone with a ramp read the same scene by tone alone.
intensity quiets the middle band, where a headline sits, more than the edges. It dims the colours in step and shrinks the dots more gently, so the shapes keep their place behind text. neon turns the neon and the lit tower crowns down without touching the rest.
Examples
Hero
intensity={0.6} drops the middle of the scene back behind a centred headline and two buttons, while the hotels, palms and towers at the edges still read.
Finer dots
cell={5} packs more dots into a small card, so the parapets, palms and windows keep their detail.
Neon turned down
neon={0.25} leaves the pastel walls and lit windows and dims the neon on the parapets, the tower crowns and their streaks in the bay.
Props
| Prop | Type | Default |
|---|---|---|
| intensity How strongly it draws, from 0 (faint) to 1. Lower values quiet the middle band, where a headline sits, most. | Type: number | Default 1 |
| neon Brightness of the neon on the hotels and the lit tower crowns, from 0 (off) to 1. | Type: number | Default 1 |
| paper The surface behind the glyphs. Otherwise the theme's paper, or the phosphor's glass. | Type: AsciiColor | Default a violet night in truecolor, ansi16 and duotone |
| charset Which glyphs draw the tones. See Charsets. | Type: CharsetName | Default "dots" |
| chars A custom ramp from empty to dense, such as " .oO@". Wins over charset. | Type: string | Default – |
| colorMode How glyphs are coloured. truecolor keeps the scene's own colours; mono uses the ink or phosphor; duotone runs the tone through a ramp. | Type: "mono" | "truecolor" | "ansi16" | "duotone" | "palette" | Default "truecolor", or "mono" with a phosphor |
| phosphor A CRT ink and glass that replace the ink and paper. | Type: "p1" | "p3" | "ibm" | "blueprint" | Default – |
| ramp In duotone mode, the colour ramp from dark to light. | Type: RampName | string[] | Default – |
| ansi In ansi16 mode, which 16-colour table. | Type: "vga" | "xterm" | Default "vga" |
| grade Brightness, contrast, gamma and saturation applied to tones before glyphs are picked. | Type: Grade | Default – |
| invert Dense glyphs for dark tones instead of bright ones. | Type: boolean | Default false |
| threshold Braille and quadrants: the tone that lights a dot. | Type: number | Default 0.5 |
| edgeThreshold Edge charset: how strong a change in tone must be to draw - / | or \. | Type: number | Default 0.22 |
| dither Ordered dithering between neighbouring glyph levels. | Type: "none" | "bayer2" | "bayer4" | "bayer8" | "blue-noise" | Default "none" |
| background "transparent" draws the glyphs only, over your own surface. | Type: "paper" | "transparent" | Default "paper" |
| fx CRT finish: scanlines, bloom, curvature, glitch, flicker and vignette, each 0 to 1. | Type: PostFx | Default – |
| cell Height of one glyph cell in CSS pixels. | Type: number | Default 7 |
| square Cells as wide as they are tall, so the dots lie in an even lattice. false uses text cells, twice as tall as wide. | Type: boolean | Default true for one-glyph charsets, false for braille and quadrants |
| speed How fast everything moves. | Type: number | Default 1 |
| animate false stops the motion: a still frame if it starts off, the current frame if it was moving. | Type: boolean | Default true |
| fps Frame rate cap. | Type: number | Default 30 |
| stillTime The moment drawn when motion is off or reduced, in seconds. | Type: number | Default 12 |
| fallback Shown without WebGL and until the first frame. | Type: ReactNode | Default the dusk as a flat gradient |
| handle Filled with a handle that reads back the current frame, for export to text, ANSI, SVG or PNG. | Type: RefObject<AsciiHandle | null> | Default – |
| className Size and position. The background fills this box. | Type: string | Default – |
Notes
- It is decorative and hidden from assistive technology. Put real text on top of it, not inside it.
- It ignores the pointer: no parallax and no hover effect.
- With reduced motion turned on, it draws one still frame at
stillTimeand stops. - It pauses when scrolled out of view or when the tab is hidden. Without WebGL it shows the dusk as a flat gradient.
- The whole scene is one shader pass on the GPU. Water samples also draw the mirrored street, so the bay costs about twice as much as the sky.
braillesamples eight times per cell andquadrantsfour. See Performance.