# Sydney

Sydney Harbour at blue hour in halftone dots: the Opera House's sails catching a warm glow, the Harbour Bridge with its lamps lit, the city in cool haze and the harbour mirroring them under a peach afterglow.

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

## Installation [#installation]

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

## Usage [#usage]

```tsx
import { Sydney } from "@/components/asciicn/sydney";

export function Hero() {
  return (
    <section className="relative isolate flex min-h-[480px] flex-col items-center justify-center text-white">
      <Sydney intensity={0.75} className="absolute inset-0 -z-10" />
      <h1>Your headline</h1>
    </section>
  );
}
```

The harbour is seen from the east at blue hour, just after sunset. The Opera House stands on the left on its podium: two halls of overlapping curved shells, the taller hall behind and the lower one in front, with heights and leans that differ from shell to shell and the tallest tip at the north end. Each shell is shaded as a volume: the face toward the afterglow is lit warm cream with a soft ridge, its back turns away into cool lavender, the underside shows in shadow under the overhang, and every shell in front throws a soft shadow on the one behind it. Glass walls under the tallest tips glow amber, and the restaurant's two small shells sit at the south end above the stairs.

The Harbour Bridge spans the right of the frame: a granite pylon at each end, lit on the face toward the glow, and the arch between its two chords, with a hazy truss, hangers down to the deck and lamps along the arch and the deck. The city's towers stand behind in cool haze, with a needle tower among them and North Sydney past the bridge.

The whole frame is painted. The sky runs from deep blue at the top through lavender to a peach afterglow low between the house and the bridge. The harbour mirrors the sails, the arch and the glow through slow ripples, and the afterglow lays a path of glints on the water. Far things draw smaller, hazier dots than near ones, and only the lit sails, the glow and its reflection draw the largest.

Nothing built moves, and the pointer has no effect. The motion is slow: ripples break and shift the reflections, a few windows switch on or off, fading over a couple of seconds, red lights on the crown of the arch and the needle tower blink softly, stars twinkle, and one green and cream ferry crosses the harbour every few minutes.

The middle of a wide box stays quiet for a headline: the house sits on the left and the bridge on the right. On a tall box both close in and sit low, the tallest shell just right of centre and the arch rising behind it, so a phone shows them under the copy.

It draws in `dots` by default, on square 7px cells so the dots lay an even halftone lattice, with `blue-noise` dithering so the dot sizes blend into smooth gradients without a regular pattern. In `truecolor` mode, also the default, every dot takes its own colour and the scene paints its own blue hour behind them, so it looks the same on light and dark pages. `braille` and `standard` draw the same scene in other glyphs; Braille and quadrants keep their usual tall cells. In `mono` mode every glyph takes the ink or a `phosphor`, and in `duotone` mode the scene runs through a `ramp`, `ember` by default.

`ferry={false}` takes the ferry off the water. `intensity` thins every dot at once. Around 0.75 keeps the sails clear behind a headline; lower it under body text.

## Examples [#examples]

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

The harbour full-bleed behind a centred headline and two buttons, at `intensity={0.75}`. The scene stays dark in both themes, so the copy on top is white.

```tsx title="examples/sydney-hero.tsx"
import { Sydney } from "@/components/asciicn/sydney";
import { Button } from "@/components/ui/button";

// The harbour full-bleed behind a centred headline. The house and the
// bridge stand either side of the copy, and the scene paints its own blue
// hour in both themes, so the text on top stays light.
export default function SydneyHero() {
  return (
    <section className="relative isolate flex size-full min-h-[480px] flex-col items-center justify-start gap-4 overflow-hidden px-6 pt-[14vh] text-center text-white sm:justify-center sm:pt-0">
      <Sydney intensity={0.75} className="absolute inset-0 -z-10" />
      <p className="font-mono text-xs tracking-[0.3em] text-white/70 uppercase">
        Sydney
      </p>
      <h3 className="max-w-xl text-4xl font-medium tracking-[-0.03em] text-balance sm:text-5xl">
        Launch before the lights come up
      </h3>
      <p className="max-w-md text-sm text-pretty text-white/75">
        A harbour at blue hour for your landing page, drawn in halftone dots.
      </p>
      <div className="mt-2 flex gap-2">
        <Button
          size="sm"
          className="bg-white text-neutral-950 hover:bg-white/90"
        >
          Get started
        </Button>
        <Button
          size="sm"
          variant="outline"
          className="border-white/30 bg-white/5 text-white hover:bg-white/15 hover:text-white"
        >
          Read the docs
        </Button>
      </div>
    </section>
  );
}
```

### Duotone [#duotone]

`colorMode="duotone"` with `ramp="heliograph"` runs every tone through one blue ramp, so the scene reads by dot size alone, and `ferry={false}` leaves the water still.

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

// One blue ramp for every tone: the harbour reads by dot size alone.
export default function SydneyDuotone() {
  return (
    <Sydney
      colorMode="duotone"
      ramp="heliograph"
      ferry={false}
      className="absolute inset-0"
    />
  );
}
```

## Props [#props]

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `intensity` | `number` | `1` | How much of the scene shows, from 0 (empty paper) to 1. Lower it under text. |
| `ferry` | `boolean` | `true` | The ferry crossing the harbour, with its wake and reflection. |
| `paper` | `AsciiColor` | `the scene's blue hour, or the theme's paper` | The surface behind the glyphs. truecolor, ansi16 and duotone paint the scene's own blue hour; mono and palette keep the theme's paper. Ignored when a phosphor brings its own 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[]` | `"ember" in duotone` | 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", or "none" in braille and quadrants` | Dithering between neighbouring glyph levels. On dots it keeps the sky a smooth 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. |
| `cell` | `number` | `7` | Height of one glyph cell in CSS pixels. With square cells it sets the width too. |
| `square` | `boolean` | `true, or false in braille and quadrants` | Cells as wide as they are tall, so the dots lay an even halftone lattice instead of rows. |
| `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` | `24` | Frame rate cap. |
| `stillTime` | `number` | `30` | The moment drawn when motion is off or reduced, in seconds. |
| `fallback` | `ReactNode` | `a blue-hour 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. The default, 30 seconds, puts the ferry on the water below the glow.
* 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.
* The whole harbour is one shader pass on the GPU. Water samples also draw the mirrored scene, so the harbour costs about twice as much as the sky. See [Performance](/docs/engine/performance).