# Dubai

Dubai at dusk from the desert in dots: the Burj Khalifa rising far above a cluster of towers in blue haze, its stepped spire gold in the last light, over rose and amber dunes under a gold-to-blue sky.

> 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/dubai.json](https://asciicn.dev/r/dubai.json), under `files[].content`.

## Installation [#installation]

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

## Usage [#usage]

```tsx
import { Dubai } from "@/components/asciicn/dubai";

export function Hero() {
  return (
    <section className="relative isolate min-h-[480px]">
      <Dubai intensity={0.85} 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 blue at the top of the sky and in the shadows between the dunes, middle dots through the rose and violet, and the largest dots on the lit spire, the afterglow and the sunlit dune crests.

The sun has just set to the left, behind the desert. The sky runs from a hazy gold horizon through rose to deep blue, with thin clouds lit from below and the first stars overhead.

The Burj Khalifa rises far above everything else. Its wings step back in turn as it climbs, so the setbacks alternate sides, and it narrows to a long spire. The lower floors already stand in the blue of dusk with a few lit windows; above them the faces turned to the sunset are still gold and amber, and the far face takes rose from the sky. A red beacon pulses slowly on the tip. A cluster of towers stands round its foot in blue haze, with lit windows and warm edges on the side facing the light, and further towers fade into the haze along the horizon, where the city's glow lies.

In front, three rows of dunes run to the bottom of the frame. The faces turned to the sunset are rose and amber; behind each crest a violet shadow widens down the slip face. The far dunes are hazier and paler, and fine ripples cross the near one.

Motion is slow: the beacon pulses, a window turns on or off now and then, dust drifts over the dunes, thin clouds move and stars twinkle faintly. The pointer does nothing.

The Burj stands right of centre at every aspect, and the towers in the middle of the box stay low, so a centred headline sits over open sky. On a tall phone screen it stands near the right edge, beside the text rather than behind it.

It draws in `dots` by default on square 7px cells, so the dots lie in an even lattice, about 200 across a 1440px screen, with `bayer4` dithering between dot sizes for smooth gradients. `square={false}` returns to the usual text cells, twice as tall as wide; `braille` and `quadrants` use them by default. Other ramp charsets such as `standard` or `dense` read the same tones as typed glyphs. In `truecolor`, the default, the scene paints its own dusk-blue paper in both themes. `mono` with a `phosphor` and `duotone` with a `ramp` read the same scene by tone alone.

`intensity` dims the colours in step and shrinks the dots more gently, so the shapes keep their place behind text.

## Examples [#examples]

### Hero [#hero]

`intensity={0.85}` quiets the scene a little behind a centred headline and two buttons. The Burj stays right of the text.

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

export default function DubaiHero() {
  return (
    <section className="relative isolate flex size-full min-h-[420px] flex-col items-center justify-center gap-5 px-6 text-center text-white">
      <Dubai intensity={0.85} className="absolute inset-0 -z-10" />
      <h3 className="max-w-xl text-3xl font-medium tracking-[-0.03em] text-balance sm:text-5xl">
        Build higher than the heat
      </h3>
      <p className="max-w-md text-sm text-pretty text-white/75 sm:text-base">
        Dubai at dusk in halftone 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 text-sm font-medium text-[#1a1206]"
        >
          Get started
        </a>
        <a
          href="#docs"
          className="rounded-full border border-white/25 bg-white/5 px-5 py-2 text-sm font-medium text-white backdrop-blur-sm"
        >
          Read the docs
        </a>
      </div>
    </section>
  );
}
```

### Duotone [#duotone]

`colorMode="duotone"` with a four-colour `ramp` from indigo to pale gold reads the dusk by tone alone, at `cell={6}` in a card.

```tsx title="examples/dubai-duotone.tsx"
import { Dubai } from "@/components/asciicn/dubai";

// The same dusk read by tone alone through a two-ink ramp, in a card.
export default function DubaiDuotone() {
  return (
    <div className="relative isolate h-80 w-full max-w-2xl overflow-hidden rounded-xl">
      <Dubai
        colorMode="duotone"
        ramp={["#0e0a24", "#4a2a64", "#d9725a", "#ffe0a6"]}
        cell={6}
        className="absolute inset-0"
      />
    </div>
  );
}
```

## Props [#props]

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `intensity` | `number` | `1` | How strongly it draws, from 0 (faint) to 1. Lower it so text on top stays readable. |
| `charset` | `CharsetName` | `"dots"` | Which glyphs draw the scene. See Charsets. |
| `chars` | `string` | `–` | A custom ramp from empty to dense, such as " .oO@". Wins over charset. |
| `colorMode` | `"mono" \| "truecolor" \| "ansi16" \| "duotone" \| "palette"` | `"truecolor"` | How glyphs are coloured. truecolor uses the scene's own colours, mono uses the theme ink or a phosphor, duotone runs tone through a ramp. "mono" when a phosphor is set. |
| `phosphor` | `"p1" \| "p3" \| "ibm" \| "blueprint"` | `–` | A CRT ink and glass for mono mode. Setting one switches colorMode to mono. |
| `ramp` | `RampName \| string[]` | `"infrared"` | 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"` | `"bayer4"` | Ordered dithering between neighbouring dot sizes. The default turns four dots into smooth tone. |
| `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` | Square cells, so the dots lie on an even lattice. false uses the font's narrower cells, the default for braille and quadrants. |
| `speed` | `number` | `1` | How fast it 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` | `0` | The moment drawn when motion is off or reduced, in seconds. |
| `handle` | `RefObject<AsciiHandle \| null>` | `–` | Filled with a handle that reads back the current frame, for export to text, ANSI, SVG or PNG. |
| `paper` | `AsciiColor` | `–` | Paper behind the glyphs. By default the scene's dusk blue in truecolor, ansi16 and duotone, and the theme's paper (or the phosphor's) otherwise. |
| `fallback` | `ReactNode` | `–` | Shown without WebGL and until the first frame. By default the dusk as a flat gradient. |
| `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. An `interactive` prop passed by a gallery is accepted and ignored.
* 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, and releases its WebGL context when far offscreen. Without WebGL it shows a flat dusk gradient.
* The whole scene is one shader pass on the GPU, with one short loop over the twelve towers round the Burj. `braille` samples eight times per cell and `quadrants` four; a larger `cell` makes it cheaper. See [Performance](/docs/engine/performance).