# Retro grid

A perspective grid floor scrolling towards a horizon under a striped, glowing sun, drawn as a dither.

> 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 dithercn agent skill, for building any dither on the engine, is at [/.well-known/agent-skills/dithercn/SKILL.md](/.well-known/agent-skills/dithercn/SKILL.md).

> **This is an example, not the only option.** It is one component built on the dithercn 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 `DitherShader` ([Write your own dither](/docs/engine/write-your-own.md)), and read this example's source for technique. Its full source is in [https://dithercn.dev/r/retro-grid.json](https://dithercn.dev/r/retro-grid.json), under `files[].content`.

## Installation [#installation]

```bash
npx shadcn@latest add https://dithercn.dev/r/retro-grid.json
```

## Usage [#usage]

```tsx
import { RetroGrid } from "@/components/dithercn/retro-grid";

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

The floor is a grid seen from a low camera, scrolling slowly towards you. Lines stay about one cell wide at every depth and fade out where they would crowd closer than a few cells, so the horizon doesn't break into moiré. The sun sits half sunk behind the horizon, with slits through its lower half that thicken towards the ground and drift down. Grid squares keep their size against the box height, so a phone shows fewer columns, not thinner ones.

## Examples [#examples]

### Sunset [#sunset]

Four warm colours, from a deep violet paper through magenta to a pale gold sun. A bigger `sun` and `cell={4}` give it the chunky look of an old game.

```tsx title="examples/retro-grid-sunset.tsx"
import { RetroGrid } from "@/components/dithercn/retro-grid";

export default function RetroGridSunset() {
  return (
    <RetroGrid
      horizon={0.46}
      sun={0.5}
      columns={14}
      cell={4}
      palette={[
        "oklch(0.18 0.05 300)",
        "oklch(0.4 0.17 330)",
        "oklch(0.64 0.2 10)",
        "oklch(0.86 0.15 75)",
      ]}
      className="absolute inset-0"
    />
  );
}
```

### Without the sun [#without-the-sun]

`sun={0}` leaves only the glow along the horizon, which clears the sky for a headline.

```tsx title="examples/retro-grid-headline.tsx"
import { RetroGrid } from "@/components/dithercn/retro-grid";

export default function RetroGridHeadline() {
  return (
    <section className="relative isolate flex size-full flex-col items-center justify-start gap-3 px-6 pt-14 text-center sm:pt-20">
      <RetroGrid
        horizon={0.5}
        sun={0}
        speed={0.5}
        className="absolute inset-0 -z-10"
      />
      <h3 className="max-w-md text-3xl font-medium tracking-[-0.03em] text-balance">
        Press start
      </h3>
      <p className="text-muted-foreground max-w-sm text-sm text-pretty">
        With the sun off, the sky stays clear for a headline and the floor keeps
        rolling underneath.
      </p>
    </section>
  );
}
```

## Props [#props]

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `horizon` | `number` | `0.42` | Height of the horizon, from 0 (bottom) to 1 (top). |
| `sun` | `number` | `0.4` | Size of the sun as a share of the box height. 0 hides it. |
| `columns` | `number` | `12` | How many squares across the front of the floor in a 16:10 box. Narrower boxes show fewer. |
| `palette` | `[DitherColor, DitherColor, ...DitherColor[]]` | `Paper, two tints of --dither-ink, then --dither-ink` | Colours from paper to ink: palette names such as "blue", CSS variable names, or any CSS colour. |
| `matrix` | `"bayer2" \| "bayer4" \| "bayer8" \| "blue-noise"` | `"bayer4"` | The threshold pattern. See Dither engine. |
| `cell` | `number` | `--dither-cell` | Size of one dither cell in CSS pixels. |
| `speed` | `number` | `1` | How fast the floor scrolls and the sun's slits drift. |
| `animate` | `boolean` | `true` | false stops the motion: a still frame if it starts off, the current frame if it was moving. |
| `className` | `string` | `–` | Size and position. The scene 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 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 horizon line, a soft sun and a fade in CSS.