Tidal Glass
N° 0022An underwater scene that rises through the surface as you scroll.
Aurora curtains woven from light threads ripple over a starfield and hills, and scrolling turns the night sky to a peach dawn.
38 KB of text that builds one HTML file. Paste it into Claude Code, Cursor or v0 to rebuild this page.
Aurora curtains woven from hundreds of individual light threads ripple over a starfield and a ridge of hills, and scrolling carries the whole sky from deep indigo night to a peach dawn while the headline turns from a night line to a morning line.
Signature momentMid scroll, the woven curtains hang pale gold over a horizon that has just turned rose, with the last stars above them.
Three aurora planes at 16, 25 and 38 units of depth, each a unit plane folded in the vertex shader. The fragment shader draws 170 threads across the near curtain by default (60 to 400), each with its own hashed brightness and a 4 to 9 second flicker.
A domain warped value noise field, evaluated per vertex on a 96 by 24 grid, sets the wavy lower border, the fade of the rays and a travelling over and under weave; edge on folds read up to 1.6 times brighter.
Scroll through 2.5 viewports moves every colour through three keyframes, night, twilight and dawn, eased in and out; the stars fade between 30 and 82 percent and the headline turns from the night line to the morning line at 70 percent.
1,400 seeded points on a far sphere (0 to 3,000), six percent of them larger, over three ridges of 1D noise that take the horizon colour as the sky warms.
Lyngen, Blue hour, Ember, Glacier, Moss, Rose, Fine weave, Ink and Storm change the palette, thread density, ripple speed, star count and the page tone; three of them put a light page under the dark hero.
Raw WebGL2 in a Worker on an OffscreenCanvas, so context creation and shader compiles never block the page: Lighthouse mobile 100 with 0 ms of blocking time, 65 KB of HTML plus 15 KB of stills.
DUSKLAYER.set()| Control | Key | Range | Default |
|---|---|---|---|
| Thread density (threads across the near curtain) | threadDensity | 60 to 400 | 170 |
| Ripple speed | rippleSpeed | 0.2 to 3 | 1 |
| Ripple amplitude (fold depth and lower edge wave) | rippleAmplitude | 0 to 1 | 0.5 |
| Curtains (2 on phones) | curtainCount | 2 to 4 | 3 |
| Curtain brightness | curtainBrightness | 0.3 to 2 | 1 |
| Palette (night, twilight and dawn set) | palette | select: lyngen, ember, glacier, moss, rose, ink | lyngen |
| Stars | starCount | 0 to 3000 | 1400 |
| Star twinkle | starTwinkle | 0 to 1 | 0.5 |
| Hill height (fraction of the viewport) | hillHeight | 0.1 to 0.5 | 0.26 |
| Horizon glow | horizonGlow | 0 to 2 | 1 |
| Dawn at rest (0 is full night before scrolling) | dawnOffset | 0 to 0.8 | 0 |
| Grain | grain | 0 to 0.08 | 0 |
| Seed (stars, ridges, thread brightness) | seed | 1 to 9999 | 7 |
| Accent (buttons and focus) | accent | color | #F2B98A |
| Page tone below the hero | pageTone | select: dark, light | dark |
Something wrong with this layer? Report a problem and we fix it in the next version.
One text file, 38 KB, 10 sections. Every number the page uses is in it, so another model can rebuild the layer without seeing this one.
# Night Loom: build prompt
## Role
You are a senior creative front-end developer. Build the layer below as one self-contained `index.html`: the home page of {{BRAND_NAME}}, {{TAGLINE}}. The hero is a WebGL2 sky: aurora curtains woven from hundreds of individual light threads ripple over a starfield and a ridge of procedural hills, and scrolling through the hero (2.5 viewports) carries the whole palette from deep indigo night through a rose twilight to a peach dawn, while the headline turns from a night line to a morning line at 70 percent. Below the hero the page is what a small lodge publishes: three rooms with prices, a sky calendar table, a getting here list with a booking card, a four group footer. Raw WebGL2 with four small shader programs written here, no Three.js, no framework. It must read as a real lodge's site, not a demo.
## Output contract
- One file `index.html`, no build step: HTML, CSS and one ES module. Three 480 by 360 WebP stills in `./assets/` are crops of this scene at scroll 0, 0.5 and 1 with the copy hidden; render them from the finished page, or leave the `figure` elements with their sky coloured background.
- Import map with one exact version: `"lenis": "https://cdn.jsdelivr.net/npm/lenis@1.3.27/dist/lenis.mjs"`. Load it with `import('lenis')` after the scene has booted (`autoRaf: false`, `lerp: 0.1`), never under `?capture=1` or reduced motion; until it resolves read `scrollY`.
- Fonts: one Google Fonts link after two preconnects, non-blocking (`media="print" onload="this.media='all'"`) with a `noscript` copy: `{{FONT_DISPLAY}}:opsz,wght@7..72,300;7..72,500` and `{{FONT_BODY}}:wght@400;500`, `display=swap`. Metric matched local fallbacks so nothing reflows, one `@font-face` per local font, chained in the stack: display `local('Georgia')` size-adjust 88.9%, ascent-override 132.4%, descent-override 34.6%; `local('DejaVu Serif')` 89.6% / 131.3% / 34.4%; `local('Liberation Serif')` 114.7% / 102.6% / 26.8%; body `local('Arial')` 105% / 93% / 24.6%; `local('Liberation Sans')` 104.9% / 93.1% / 24.6%; `local('DejaVu Sans')` 91.4% / 106.8% / 28.2%; `line-gap-override: 0%` on all.
[35,115 more characters. Copy the prompt to get all of it.]An underwater scene that rises through the surface as you scroll.
Chrome lettering breaks apart under soft studio light, one letter at a time as you scroll.
A chrome C forms from liquid metal, bristles into ferrofluid spikes near your cursor and slumps into a pool on scroll.