Keystone
Every layer, on purpose.
Field notes
A light product page for a mechanical keyboard that types its own name, lifts apart into six labelled layers and goes back together. Hover a key, or type on your own keyboard, and its 3D twin goes down. No models, no textures.
- 3D
- Pointer interaction
- Product
- Light theme
Keystone is a product page for a fictional 65% keyboard, in a paper-and-ink palette with one orange accent. The board types K-E-Y-S-T-O-N-E while a typing line fills in beside it, then comes apart layer by layer: keycaps, switches, brass plate, PCB, foam and the aluminium case, each with a spec label. It goes back together, backspaces the word away, and starts again on a 12-second loop.
All 68 keys are real objects. Hover one and it presses; type on your own keyboard and the matching key goes down on screen. The whole board is built from Three.js primitives with legends drawn into one canvas texture, so there is no model or image to download, and anyone who prefers reduced motion sees it held apart with every layer labelled.
How it's built
- A layout you can read: the 65% board is five strings like "Tab:1.5 Q W E …" in layout.ts. One parse gives every key its label, width and position, and a real keydown finds its key by the same label.
- Legends from one canvas: every label is drawn once into a 2048 × 512 atlas after the web font loads, and each keycap carries a small plane whose UVs point at its own cell. The recorder only starts once the atlas is drawn.
- An exploded view that reads: each layer rises by its index, keycaps and switches leave left to right, and the board tips back toward eye level as it comes apart, so the six layers show as separate bands instead of stacking up in perspective.
- Light without the grey: NeutralToneMapping instead of ACES keeps the cream caps and orange accents true, and a shadowMaterial plane under the case catches one directional light's shadow on the paper background.
Inside the prompt
Every file below is written out in full, so your agent creates the project exactly — no guessing, no missing pieces.
keystone-keyboard/
├─ .gitignore
├─ index.html
├─ package.json
├─ tsconfig.json
├─ vite.config.ts
└─ src/
├─ App.tsx
├─ index.css
├─ main.tsx
├─ vite-env.d.ts
├─ components/
│ ├─ Hero.tsx
│ ├─ Keyboard.tsx
│ ├─ LayerLabels.tsx
│ └─ Scene.tsx
└─ lib/
├─ layout.ts
├─ legends.ts
├─ loop.ts
└─ timeline.tsRecut it
- Rename the product and rewrite the pitch
src/components/Hero.tsx → Hero() - Change the layout: add a numpad or go to 60%
src/lib/layout.ts → ROWS - Recolour the keycaps and legends
src/components/Keyboard.tsx → CAP_COLOR / LEGEND_COLOR - Swap the case, plate or PCB finish
src/components/Keyboard.tsx → useParts() - Edit the layer names and specs
src/lib/timeline.ts → LAYERS - Type a different word, or retime the loop
src/lib/timeline.ts → WORD / explode() - Move or resize the board
src/components/Scene.tsx → useLayout()
