# Ridgelines

Stacked ridge lines like a pulsar plot, each hiding the ones behind it, 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).

<ComponentPreview src="examples/ridgelines-demo.tsx" size="full" align="stretch" controls="ridgelinesControls">
  <RidgelinesDemo />
</ComponentPreview>

## Installation [#installation]

<InstallBlock name="ridgelines" />

## Usage [#usage]

```tsx
import { Ridgelines } from "@/components/dithercn/ridgelines";

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

Each line is flat at the ends and peaked in the middle, and each one hides the lines behind it. The peaks shift slowly. A faint shade under the tallest peaks makes them read as solid ridges. Lines stay one cell wide and at least four cells apart, so a short box draws fewer of them.

## Examples [#examples]

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

Fewer `lines`, a narrower `spread` and small cells fit a pulsar plot in a card.

<ComponentPreview src="examples/ridgelines-signal.tsx">
  <RidgelinesSignal />
</ComponentPreview>

### Mountain range [#mountain-range]

`spread={1}` raises peaks across the whole width. A lower `amplitude` keeps them low, and a three-colour palette shades the slopes.

<ComponentPreview src="examples/ridgelines-range.tsx" size="lg" align="stretch">
  <RidgelinesRange />
</ComponentPreview>

## Props [#props]

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `lines` | `number` | `32` | How many lines, from 6 to 64. A short box draws fewer. |
| `amplitude` | `number` | `1` | Height of the peaks. 2 is twice as tall. |
| `spread` | `number` | `0.5` | Width of the peaked band, as a share of the box, from 0.1 to 1. |
| `shade` | `number` | `0.25` | Faint tone under the raised peaks, from 0 to 0.5. 0 keeps only the lines. |
| `palette` | `[DitherColor, DitherColor, ...DitherColor[]]` | `["--dither-paper", "--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 it moves. |
| `animate` | `boolean` | `true` | false draws one still frame. |
| `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 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 thin CSS lines in the same colours.
* It costs one small draw per frame at 30 fps, at one pixel per dither cell. See [Performance](/docs/engine/performance).