# Hong Kong

Victoria Harbour at blue hour in coloured dots: lit towers climbing to the misty ridge of Victoria Peak, the Bank of China Tower and Two IFC, long reflections and a red-sailed junk under a magenta to deep 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/hong-kong.json](https://asciicn.dev/r/hong-kong.json), under `files[].content`.

## Installation [#installation]

```bash
npx shadcn@latest add https://asciicn.dev/r/hong-kong.json
```

## Usage [#usage]

```tsx
import { HongKong } from "@/components/asciicn/hong-kong";

export function Hero() {
  return (
    <section className="relative isolate min-h-[480px]">
      <HongKong intensity={0.6} className="absolute inset-0 -z-10" />
      <h1>Your headline</h1>
    </section>
  );
}
```

The view looks across Victoria Harbour from Kowloon at blue hour. Victoria Peak fills the middle of the sky as a dark, wooded ridge with a lower spur in front of it. Its slopes facing the afterglow catch a little magenta and the rest falls into shadow, and soft banks of mist lie across its upper slopes. The sky behind it runs from hot magenta along the crest through mauve and violet to a deep, quiet blue overhead, where a few stars show.

Below the Peak, the towers of the Mid-Levels climb its slope in violet haze, and in front of them runs the waterfront: a wall of dark towers lit in warm, white, cool and teal windows, floor by floor, with a few crowns in slowly changing LED colours. Two landmarks stand either side of the frame. The Bank of China Tower is on the left, with dark glass, white edges, softer X braces and slanted roofs that step up to twin masts. Two IFC is on the right, striped with vertical light, with a crown of fins in front of the afterglow.

The harbour mirrors the city in long coloured streaks, broken by slow ripples, and a column of rose glints runs under the afterglow. A junk with three battened red sails crosses it.

Motion is slow and sparse: the junk takes about two minutes to cross a wide screen, the reflections shimmer, a few windows switch on or off over tens of seconds, the mist drifts, the red light on the Bank of China mast pulses and the stars twinkle. Nothing responds to the pointer.

It draws in `dots` by default on square 7px cells, about 200 columns across a 1440px screen. Dot size carries tone: small, dim dots in the deep sky, the shadowed hills and the open water, and large ones only for the landmarks' lit edges, the windows, the afterglow and its reflection. Dots, `braille` and `quadrants` use `blue-noise` dithering, which blends neighbouring sizes without stripes. In `truecolor`, the default, every dot takes the scene's own colour on a night paper, so it looks the same on light and dark pages.

The middle of the frame stays calm for a headline. The landmarks stand outside the middle half of the width, the waterfront towers are lowest in the centre and their windows dim there, and the junk sails below the text. In narrow boxes the two towers move to the edges and the Peak stays centred, so a phone crop keeps all three.

`intensity` dims the colours and shrinks the dots, most of all in the middle band where a headline sits. Lower it to keep text on top easy to read.

## Examples [#examples]

### Behind a headline [#behind-a-headline]

Full-bleed behind a centred headline and two buttons. `intensity={0.65}` quiets the middle band so the text reads first, while the two towers frame it.

```tsx title="examples/hong-kong-hero.tsx"
import { HongKong } from "@/components/asciicn/hong-kong";

// Full-bleed behind a centred headline. At 0.65 intensity the middle band,
// where the text sits, drops back most; the two towers stand either side
// of it and the junk crosses the harbour below.
export default function HongKongHero() {
  return (
    <section className="relative isolate flex size-full min-h-[480px] flex-col items-center justify-center gap-5 overflow-hidden bg-[#060818] px-6 py-16 text-center text-white">
      <HongKong intensity={0.65} className="absolute inset-0 -z-10" />
      <h3 className="[text-shadow:0_1px_12px_rgb(6_8_24)] max-w-xl text-4xl font-medium tracking-[-0.03em] text-balance sm:text-5xl">
        Last junk to Central
      </h3>
      <p className="[text-shadow:0_1px_12px_rgb(6_8_24)] max-w-md text-sm text-pretty text-white/90 sm:text-base">
        Victoria Harbour at blue hour 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>
  );
}
```

### In a tall card [#in-a-tall-card]

In a 9:19 box the Bank of China Tower and Two IFC move to the edges and the Peak stays centred, so all three stay in view.

```tsx title="examples/hong-kong-tall.tsx"
import { HongKong } from "@/components/asciicn/hong-kong";

// A phone-shaped card: in a narrow box the Bank of China Tower and Two IFC
// move to the edges and the Peak stays centred, so all three stay in view.
export default function HongKongTall() {
  return (
    <div className="relative isolate aspect-[9/19] w-56 overflow-hidden rounded-[2rem] border border-white/10 bg-[#060818]">
      <HongKong 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 most, so text on top stays readable. |
| `lights` | `number` | `1` | How strongly the few LED crowns on the waterfront show their slowly changing colours, from 0 (plain white) to 1. |
| `junk` | `boolean` | `true` | Draws the junk with red sails crossing the harbour, about every two minutes on a wide screen. |
| `ferry` | `boolean` | `true` | Deprecated. Use junk. false still turns the boat off. |
| `mist` | `number` | `1` | How much mist drifts on Victoria Peak and between its ridges, from 0 (none) to 1. |
| `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[]` | `–` | 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"` | `"blue-noise" in dots, braille and quadrants, "none" otherwise` | Dithering between neighbouring glyph levels. Blue noise blends dot sizes across the sky's gradient without stripes. |
| `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. |
| `interactive` | `boolean` | `–` | Accepted so any stage can pass it, and ignored: the city does not respond to the pointer. |
| `square` | `boolean` | `true for dots and other one-glyph charsets` | Cells as wide as they are tall, so the dots lay an even lattice. Braille and quadrants default to false, since they would stretch. |
| `cell` | `number` | `7` | Height of one glyph cell in CSS pixels, and its width too when square. |
| `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` | `3` | The moment drawn when motion is off or reduced, in seconds. The default shows the junk just right of centre. |
| `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 night colour 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 a blue-hour 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.
* 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 blue-hour gradient.
* Nothing responds to the pointer, and there is no `interaction` prop.
* The whole scene is one GPU pass. The harbour draws the city a second time for its reflection, so its cost follows the number of samples. `braille` samples eight times per cell; a larger `cell` makes it cheaper. See [Performance](/docs/engine/performance).