# Ripple — a koi pond under water you can touch

A drop-in piece from [Funeral Thirsty](https://www.funeralthirsty.com/studies/ripple.html). Give it a pond and a photograph. The picture sits under a grid of heights: a tap presses a ring into the surface, the ring spreads and settles, and the picture bends through the slope. The same photograph can be the picture itself, or set in drills. The water does not mind which.

The drills are the Facets engine. This kit carries `facets.js` as well as `ripple.js`, so the folder stands alone.

No build step, no dependencies, no framework. Two scripts, one attribute.

## Unzipping

The zip is flat: its files land in whatever folder you unzip it into, with `index.html` at the top. Make a folder called `ripple` first if you want them contained. Design tools that import the zip open that `index.html`, the site, as the entry.

## The minimum that installs it

```html
<section class="piece" id="piece">
  <img id="photo" src="your-photo.jpg" alt="">
  <canvas id="drills" data-facets="your-photo.jpg" data-dpr="1" data-idle="off"></canvas>
  <canvas id="water"></canvas>
</section>
<script src="facets.js"></script>
<script src="ripple.js"></script>
```

`facets.js` has to load first. It finds `canvas[data-facets]` and draws the drills. `ripple.js` reads the same attribute for the photograph it puts under the water.

Size the piece with CSS. On the study it is one screen, at least 480px. The photograph, the drills and the water fill it. Serve the page over a web server: browsers refuse to let a page read a photograph's pixels when it is opened straight from disk. Any server will do, including `python3 -m http.server`.

Leave `data-facets` off and the engine loads `../assets/studies/facets/koi.jpg`, which is the study's own file and will 404 inside this kit. A kit page always sets the attribute. The path is resolved against the page, not against the script. `#photo` should name the same file: without WebGL the water is hidden and that image is what shows.

`#skins` and `#hint` are optional. Leave them out and the pond still runs. `Ripple.skin("photo")` switches the picture without the buttons. The styles are in `ripple.css`, and in `styles.css` as the site uses them.

`data-dpr="1"` asks the drill engine to draw at one pixel per CSS pixel, because that canvas only feeds the water. `data-idle="off"` holds the light still until a hand or a tilt moves it. Both are Facets options. Leave them off and the drills still draw; they cost more, and the light wanders on its own.

## What is in this folder

| Path | What it is |
|---|---|
| `index.html` | The site: the Ripple study page itself, rebuilt from the files in this kit. Open this first. Uses `styles.css`, `facets.js` and `ripple.js`. |
| `ripple.js` | The pond. The height grid, the rings, the refraction shader, and `window.Ripple`. |
| `facets.js` | The drill engine, byte for byte with the studio's. Load it before `ripple.js`. |
| `ripple.css` | The pond, and the few styles the demo and previews use. |
| `demo/index.html` | The pond, and nothing else. No hint, no skin switch, no title. |
| `OPTIONS.md` | The DOM the engine expects, the attributes it reads, and the JavaScript interface. |
| `components/` | Preview pages for design tools: the pond, the palette, the type. Each opens in a browser on its own. |
| `tokens/tokens.json` | The kit's colours, type and sizes in the W3C Design Tokens format (2025.10). |
| `tokens/tokens.css` | The same values as CSS custom properties. |
| `DESIGN.md` | The guideline: colour, type, spacing, layout, components, motion, voice, brand, anti-patterns. |
| `design-system-spec.json` | The manifest Claude Design reads. |
| `manifest.json`, `tokens.css`, `design-tokens.json`, `components.html`, `USAGE.md`, `preview/` | The Open Design layer: its manifest, its token contract, its token JSON, a component fixture, a usage guide and preview pages (the site, colors, typography, spacing). |
| `assets/sample/` | One sample photograph, generated for the studio and released under CC0. The page shows it, and the drills read it. |
| `assets/fonts/` | IBM Plex Mono, under the SIL Open Font License, with the license text. |
| `LICENSE.md` | MIT for the code, CC0 for the photograph, and what is not licensed. |

## Loading it into a design tool

The kit carries two layers, one for each tool, describing the same system.

**Open Design.** Import `ripple.zip` and it opens on `index.html`, the site, with every other page listed alongside it. Read as a design system, the same archive supplies `manifest.json`, `DESIGN.md`, `tokens.css`, `components.html`, `USAGE.md` and the pages under `preview/`, and Ripple becomes a system other work can be rendered in.

**Claude Design.** Reads `design-system-spec.json`, the component previews under `components/` with their first-line `@dsCard` markers, and `tokens/tokens.json` in the W3C Design Tokens format.

## Making it yours

Change `--deep`, `--ink`, `--ink-soft` and `--glow` in `tokens/tokens.css` (or `tokens.css`) and the page around the pond moves with them. `--red` is a sample red, recorded so the palette matches the other water studies. The engine reads none of these. The water, the crests and the drills take their colour from the photograph.

The cell size, the damping, the refraction, and the strength of a tap, a drag and an idle drop live in `ripple.js`. The token file records those numbers. Editing the token does not change the water; edit the script.

Point `data-facets` at another file to change the picture. Keep `data-dpr="1"` on a canvas that only feeds the water.
