# Miami

Ocean Drive at nightfall in dots: art deco hotels with soft neon on their stepped parapets, palms in silhouette, the glass towers of Brickell in blue haze and a bay holding the neon in broken reflections.

> For the complete documentation index, see [llms.txt](/llms.txt). Markdown variants are available by appending `.md` to any URL or sending an `Accept: text/markdown` header. The asciicn agent skill, for building any ASCII effect on the engine, is at [/.well-known/agent-skills/asciicn/SKILL.md](/.well-known/agent-skills/asciicn/SKILL.md).

> **This is an example, not the only option.** It is one component built on the asciicn engine. Install it when it is what you were asked for. For any other look, don't stretch its props to fit: write your own field on `AsciiShader` ([Write your own](/docs/engine/write-your-own.md)), or draw a CPU grid with `AsciiGrid`, and read this example's source for technique. Its full source is in [https://asciicn.dev/r/miami.json](https://asciicn.dev/r/miami.json), under `files[].content`.

## Installation [#installation]

```bash
npx shadcn@latest add https://asciicn.dev/r/miami.json
```

## Usage [#usage]

```tsx
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 [#examples]

### Hero [#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.

```tsx title="examples/miami-hero.tsx"
import { Miami } from "@/components/asciicn/miami";

// Full-bleed behind a centred headline. At 0.6 intensity the middle band, where the text sits, drops back most; the hotels, palms
// and towers at the edges still read.
export default function MiamiHero() {
  return (
    <section className="relative isolate flex size-full min-h-[480px] flex-col items-center justify-center gap-5 overflow-hidden bg-[#0b0719] px-6 py-16 text-center text-white">
      <Miami intensity={0.6} className="absolute inset-0 -z-10" />
      <h3 className="[text-shadow:0_1px_12px_rgb(11_7_25)] max-w-xl text-4xl font-medium tracking-[-0.03em] text-balance sm:text-5xl">
        Ship it before the neon comes on
      </h3>
      <p className="[text-shadow:0_1px_12px_rgb(11_7_25)] max-w-md text-sm text-pretty text-white/90 sm:text-base">
        Ocean Drive at nightfall in coloured dots, calm enough to sit behind
        your headline.
      </p>
      <div className="flex flex-wrap items-center justify-center gap-3">
        <a
          href="#get-started"
          className="rounded-full bg-[#fcb442] px-5 py-2.5 text-sm font-medium text-[#1a1203] transition-colors hover:bg-[#ffc560]"
        >
          Get started
        </a>
        <a
          href="#docs"
          className="rounded-full border border-white/25 bg-black/30 px-5 py-2.5 text-sm font-medium text-white backdrop-blur-sm transition-colors hover:bg-black/45"
        >
          Read the docs
        </a>
      </div>
    </section>
  );
}
```

### Finer dots [#finer-dots]

`cell={5}` packs more dots into a small card, so the parapets, palms and windows keep their detail.

```tsx title="examples/miami-fine.tsx"
import { Miami } from "@/components/asciicn/miami";

// A 5px cell packs more dots into a small card, so the parapets, palms and
// windows keep their detail.
export default function MiamiFine() {
  return (
    <div className="relative isolate h-96 w-full max-w-2xl overflow-hidden rounded-xl">
      <Miami cell={5} className="absolute inset-0" />
    </div>
  );
}
```

### Neon turned down [#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.

```tsx title="examples/miami-low-neon.tsx"
import { Miami } from "@/components/asciicn/miami";

// The neon turned down: the hotels keep their pastel walls and lit windows,
// and the bay loses most of its coloured streaks.
export default function MiamiLowNeon() {
  return (
    <div className="relative isolate h-96 w-full max-w-2xl overflow-hidden rounded-xl">
      <Miami neon={0.25} className="absolute inset-0" />
    </div>
  );
}
```

## Props [#props]

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `intensity` | `number` | `1` | How strongly it draws, from 0 (faint) to 1. Lower values quiet the middle band, where a headline sits, most. |
| `neon` | `number` | `1` | Brightness of the neon on the hotels and the lit tower crowns, from 0 (off) to 1. |
| `paper` | `AsciiColor` | `a violet night in truecolor, ansi16 and duotone` | The surface behind the glyphs. Otherwise the theme's paper, or the phosphor's glass. |
| `charset` | `CharsetName` | `"dots"` | Which glyphs draw the tones. See Charsets. |
| `chars` | `string` | `–` | A custom ramp from empty to dense, such as " .oO@". Wins over charset. |
| `colorMode` | `"mono" \| "truecolor" \| "ansi16" \| "duotone" \| "palette"` | `"truecolor", or "mono" with a phosphor` | How glyphs are coloured. truecolor keeps the scene's own colours; mono uses the ink or phosphor; duotone runs the tone through a ramp. |
| `phosphor` | `"p1" \| "p3" \| "ibm" \| "blueprint"` | `–` | A CRT ink and glass that replace the ink and paper. |
| `ramp` | `RampName \| string[]` | `–` | In duotone mode, the colour ramp from dark to light. |
| `ansi` | `"vga" \| "xterm"` | `"vga"` | In ansi16 mode, which 16-colour table. |
| `grade` | `Grade` | `–` | Brightness, contrast, gamma and saturation applied to tones before glyphs are picked. |
| `invert` | `boolean` | `false` | Dense glyphs for dark tones instead of bright ones. |
| `threshold` | `number` | `0.5` | Braille and quadrants: the tone that lights a dot. |
| `edgeThreshold` | `number` | `0.22` | Edge charset: how strong a change in tone must be to draw - / \| or \. |
| `dither` | `"none" \| "bayer2" \| "bayer4" \| "bayer8" \| "blue-noise"` | `"none"` | Ordered dithering between neighbouring glyph levels. |
| `background` | `"paper" \| "transparent"` | `"paper"` | "transparent" draws the glyphs only, over your own surface. |
| `fx` | `PostFx` | `–` | CRT finish: scanlines, bloom, curvature, glitch, flicker and vignette, each 0 to 1. |
| `cell` | `number` | `7` | Height of one glyph cell in CSS pixels. |
| `square` | `boolean` | `true for one-glyph charsets, false for braille and quadrants` | Cells as wide as they are tall, so the dots lie in an even lattice. false uses text cells, twice as tall as wide. |
| `speed` | `number` | `1` | How fast everything moves. |
| `animate` | `boolean` | `true` | false stops the motion: a still frame if it starts off, the current frame if it was moving. |
| `fps` | `number` | `30` | Frame rate cap. |
| `stillTime` | `number` | `12` | The moment drawn when motion is off or reduced, in seconds. |
| `fallback` | `ReactNode` | `the dusk as a flat gradient` | Shown without WebGL and until the first frame. |
| `handle` | `RefObject<AsciiHandle \| null>` | `–` | Filled with a handle that reads back the current frame, for export to text, ANSI, SVG or PNG. |
| `className` | `string` | `–` | Size and position. The background fills this box. |

## Notes [#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 `stillTime` and 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. `braille` samples eight times per cell and `quadrants` four. See [Performance](/docs/engine/performance).