Strata
Your data, set in stone.
Field notes
Scroll and the camera sinks down a shaft of hexagonal basalt columns, past four chapters, to a molten core. Instanced Three.js prisms, one small lava shader, and a scroll spring: no models, no textures.
- 3D
- Scroll-driven
- WebGL shader
- Dark theme
Strata is a scroll story for a product that wants its landing page to feel deep. The page scroll drives a camera down a shaft walled with stacked hexagonal basalt columns, turning half a lap on the way. Four chapters (Surface, Sediment, Basalt, Core) fade in at their depth while a gauge counts the metres, the rock warms from dusty grey to scorched red, and sparks rise from a cracked, glowing core where the final call to action waits.
The shaft is about 1,600 instanced six-sided prisms, placed and coloured by a seeded generator, so it is identical on every load. A spring on the scroll gives the descent weight, the fog and a warm point light at the bottom do the colour grading, and the core is one short noise shader. Anyone who prefers reduced motion scrolls without the spring, and the sparks and core hold still.
How it's built
- One draw call for the whole shaft: every basalt column is an instance of a single six-sided CylinderGeometry, scaled to its own height. A seeded generator walks two rings around the shaft and stacks columns of random height down each slot, leaving a thin joint between them, and one in ten juts inward as a ledge.
- Depth is colour, not texture: each column gets an instance colour from its depth (sediment, shale, basalt, scorched rock), and the scene fog shifts from cold blue-black to deep red as the camera descends. A warm point light at the core and a cool headlamp riding with the camera do the rest.
- Scroll with weight: the page is a tall empty track. Framer Motion's scroll progress goes through a spring into one shared motion value, and both the WebGL camera and the DOM chapters read that value, so text and 3D can never drift apart.
- A lava floor that loops: the core shader samples layered noise at an offset that travels once around a circle per loop, so the flow never jumps when the 10-second preview wraps. Cracks are where the noise crosses its midline, and they are drawn brighter than white so Bloom catches them.
Inside the prompt
Every file below is written out in full, so your agent creates the project exactly — no guessing, no missing pieces.
strata-descent/
├─ .gitignore
├─ index.html
├─ package.json
├─ tsconfig.json
├─ vite.config.ts
└─ src/
├─ App.tsx
├─ index.css
├─ main.tsx
├─ vite-env.d.ts
├─ components/
│ ├─ Chapters.tsx
│ └─ StrataScene.tsx
├─ lib/
│ └─ loop.ts
└─ shaders/
└─ coreShader.tsRecut it
- Rewrite the four chapters, their layer names, and depths
src/components/Chapters.tsx → CHAPTERS - Rename the product in the header
src/components/Chapters.tsx → Chapters() - Recolour the rock from rim to core
src/components/StrataScene.tsx → ROCK - Make the shaft deeper or wider, or thin out the columns
src/components/StrataScene.tsx → buildColumns() - Change how much the camera turns on the way down
src/components/StrataScene.tsx → CameraRig() - Give the descent more or less inertia
src/App.tsx → useScrollDepth() - Recolour the lava or change how it flows
src/shaders/coreShader.ts → fragmentShader
More in Landing Page
All landing page templates →
Cairn
Landing PageA complete SaaS landing page where the app window pins in place and changes screens as you scroll: KPIs count up, a funnel grows, a cohort grid fills in, an alert fires. Every chart is hand-built HTML and SVG. No chart library, no images, no WebGL.

Meridian
Landing PageA dark hero for an API or infra product: a dotted globe drawn from real coastlines, with traffic arcs firing between cities and landing in a ping. Drag to spin it. No models, no textures, no map requests.

Relay
Landing PageA landing page for an AI agent that isn't purple: ink on warm paper, one orange. The hero is a live tool-call graph where every call leaves a wet-ink trail, tools answer when you click them, and scrolling folds the whole run into a timeline. One raw WebGL2 shader, no three.js.