# Contours

A topographic map drawn as a dither: contour lines over slowly drifting hills, with heavier index lines and a light hillshade.

> 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).

<ComponentPreview src="examples/contours-demo.tsx" size="full" align="stretch" controls="contoursControls">
  <ContoursDemo />
</ComponentPreview>

## Installation [#installation]

<InstallBlock name="contours" />

## Usage [#usage]

```tsx
import { Contours } from "@/components/dithercn/contours";

export function Section() {
  return (
    <section className="relative isolate min-h-[480px]">
      <Contours className="absolute inset-0 -z-10" />
      <h2>Your heading</h2>
    </section>
  );
}
```

Contour lines trace even steps of height across a field of low hills. Every fifth line is drawn heavier, as on a survey map, and slopes facing away from a light in the top left pick up a light stipple. The hills drift and slowly change shape. They keep their size in pixels, so a narrow box shows a smaller piece of the same map rather than a squashed one.

## Examples [#examples]

### Survey map [#survey-map]

More `lines`, a smaller `scale` and a little more `relief` in green and brown give an old ordnance survey sheet. `cell={2}` keeps the lines fine.

<ComponentPreview src="examples/contours-survey.tsx" size="full" align="stretch">
  <ContoursSurvey />
</ComponentPreview>

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

Set `index` and `relief` to 0 for plain lines, and pass two soft tints of the ink so the lines never reach full contrast.

<ComponentPreview src="examples/contours-headline.tsx" size="lg" align="stretch">
  <ContoursHeadline />
</ComponentPreview>

## Props [#props]

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `lines` | `number` | `14` | How many contour lines from the lowest ground to the highest, from 4 to 32. |
| `scale` | `number` | `1` | Size of the hills. Higher values pack more of them in. |
| `index` | `number` | `5` | Every how many lines one is drawn heavier. 0 draws them all the same. |
| `relief` | `number` | `0.5` | How strongly slopes facing away from the light are shaded, from 0 to 1. |
| `palette` | `[DitherColor, DitherColor, ...DitherColor[]]` | `Paper, a tint 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 hills drift. |
| `animate` | `boolean` | `true` | false draws one still frame. |
| `className` | `string` | `–` | Size and position. The map 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 faint CSS rings.