# San Francisco

The Golden Gate Bridge at blue hour in halftone dots: Art Deco towers in International Orange catching the last light, fog rolling under the deck and over the Marin Headlands, city lights on the far shore and the bay mirroring the 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/san-francisco.json](https://asciicn.dev/r/san-francisco.json), under `files[].content`.

## Installation [#installation]

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

## Usage [#usage]

```tsx
import { SanFrancisco } from "@/components/asciicn/san-francisco";

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

The view is at an angle across the water at blue hour, just after sunset. The north tower stands near on the left, taller and wider, and the south tower far on the right, smaller and hazier, with the deck and the main cable receding between them. Each tower has two legs, four portal struts above the deck, stepped tops and X bracing below the deck, standing on concrete piers. The faces that turn toward the afterglow are lit warm orange and the far side of each leg falls into deep rust. Fine hangers drop from the cable to the deck and fade as they crowd together toward the far tower. The Marin Headlands rise behind the near tower, and the low hills of the Presidio and the city's lights sit past the far one.

The whole frame is painted. The sky runs from deep blue at the top through mauve to a warm afterglow low behind the bridge, with thin streaks of high cloud. A bank of fog lies under the deck, rises toward the far tower until it hides parts of the far deck and the tower's base, and piles up against the headlands, lit warm on top and blue grey underneath. The bay below mirrors all of it, and the afterglow lays a path of glints on the water. Dark areas stay quiet: the deep sky, the fog's shadow and the far water draw the smallest dots in colours a shade above the paper, and the large bright dots are kept for the bridge, the glow and its reflection.

Nothing built moves, and the pointer has no effect. The motion is slow: the fog drifts east under the deck, ripples break the reflections into streaks, the red aircraft lights on the tower tops blink softly out of step with each other, a few stars twinkle, and one boat crosses the bay every few minutes.

Wide boxes keep the angled view and spread it with the box. In a portrait box, narrower than about 0.85 wide to 1 tall, the view turns square on: the towers stand at the left and right edges with their tops near half height, the deck runs low at about three quarters of the way down, and the afterglow is held back, so a centred headline and its buttons sit between the towers and above the span instead of over the bridge. Tower legs, struts, the cable, the hangers and the deck are laid out on whole cells, so they come out as clean lines of dots at any size.

It draws in `dots` by default, on square 7px cells so the dots lay an even halftone lattice, with `bayer4` dithering so the dot sizes blend into smooth gradients. In `truecolor` mode, also the default, every dot takes its own colour and the scene paints its own dusk 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.

`fog` sets how thick the bank is, from none at 0. `traffic` sets how many cars cross the deck as single dots of light, up to six. `boat={false}` takes the boat off the water. `intensity` thins every dot at once. Around 0.7 keeps the bridge clear behind a headline; lower it under body text.

## Examples [#examples]

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

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

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

// The bridge full-bleed behind a centred headline. The scene paints its own
// dusk in both themes, so the copy on top stays light.
export default function SanFranciscoHero() {
  return (
    <section className="relative isolate flex size-full min-h-[480px] flex-col items-center justify-center gap-4 overflow-hidden px-6 pb-[20vh] text-center text-white sm:pb-0">
      <SanFrancisco intensity={0.7} className="absolute inset-0 -z-10" />
      <p className="font-mono text-xs tracking-[0.3em] text-white/70 uppercase">
        San Francisco
      </p>
      <h3 className="max-w-xl text-4xl font-medium tracking-[-0.03em] text-balance sm:text-5xl">
        Ship before the fog lifts
      </h3>
      <p className="max-w-md text-sm text-pretty text-white/75">
        A blue-hour backdrop for your launch 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>
  );
}
```

### Amber terminal [#amber-terminal]

`phosphor="p3"` draws the scene in amber on dark glass. `braille` dots, `fog={0.9}` and a CRT finish from `fx` make it look like a night camera on an old monitor.

```tsx title="examples/san-francisco-phosphor.tsx"
import { SanFrancisco } from "@/components/asciicn/san-francisco";

// Amber phosphor, Braille dots and a heavy fog: the bridge on an old monitor.
export default function SanFranciscoPhosphor() {
  return (
    <SanFrancisco
      phosphor="p3"
      charset="braille"
      fog={0.9}
      fx={{ bloom: 0.45, scanlines: 0.4, vignette: 0.4 }}
      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. |
| `fog` | `number` | `0.6` | How thick the fog bank under the deck and over the headlands is, from 0 (none) to 1. |
| `traffic` | `number` | `0.2` | How many cars cross the bridge, from 0 (none) to 1 (six). |
| `boat` | `boolean` | `true` | The boat crossing the bay. |
| `paper` | `AsciiColor` | `the scene's dusk, or the theme's paper` | The surface behind the glyphs. truecolor, ansi16 and duotone paint the scene's own dusk; 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"` | `"bayer4", or "none" in braille and quadrants` | Ordered dithering between neighbouring glyph levels. On dots it keeps the sky a smooth gradient. |
| `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` | `20` | 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.
* 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 a CSS gradient in the scene's colours.
* The whole scene is drawn on the GPU in one pass, and the water reads the scene above it a second time for the reflection. See [Performance](/docs/engine/performance).