Vend
Pick a plan. Press the button.
Field notes
A pricing page that is a Japanese vending machine on a rainy night. Each plan is a shelf of cans with an LED price, a coin switches monthly and yearly, and pressing a button drops the can into the tray, spins a 7777 roulette and opens the plan. Wipe the fogged glass with your cursor.
- 3D
- Pointer interaction
- SaaS
- Dark theme
Vend is the pricing page of Afterrain, a fictional background-jobs service. The page is a Japanese street vending machine at night, in the rain, with neon on the wall and its reflection in the wet street. The three plans are three shelves of cans, each with an amber LED price strip. Drop a coin in the slot to switch to yearly billing: the LEDs flip like split-flap. Press a button and that shelf's gravity rack rolls one can forward, it drops into the tray, the camera moves in, and the plan's features and call to action open beside it. A four-digit roulette over the tray spins as the can lands; 7777 shows a coupon code for paid plans, and the demo tour always wins.
Rain fogs the glass, and dragging the cursor or a finger across it wipes a clear track that fogs back over a few seconds, while the price strips always stay clear. After the first click there are synthesized sound effects (button, coin, the can landing, the roulette, the 7777 jingle), and the sound button adds rain and the hum of the neon. A 12-second tour runs until the visitor does something and then hands over mid-motion. Every 3D control has a keyboard twin, reduced motion shows Pro already in the tray, and without WebGL the page shows three plain pricing cards. The copy, prices and coupon live in one file, plans.ts.
How it's built
- One frame from one clock: the whole machine is a Frame computed from a small state (which plan, when it was pressed, yearly or not) and the time. The demo tour, the preview recorder and a visitor use the same code path, so frame 0 equals frame 12, and the first click adopts the tour's state mid-motion.
- A rack that loops: the vending row sits one can back when pressed and rolls exactly one can forward while the front can drops, so every can ends in a slot and the next vend starts from the same picture.
- A wet street without a reflection pass: the machine and the wall are drawn a second time upside down under a ground plane whose puddles are see-through. Chrome, cans and glass reflect three's RoomEnvironment, and every label, LED and sign is a canvas texture drawn after the web fonts load, so there are no image files.
- Fog with no memory: the fog is one canvas redrawn every frame, full fog and droplets first, then every wipe cut out with destination-out at a strength set by its age. It grows back without keeping pixels, and any frame can be drawn from the list of wipes.
- Sound from nothing: every effect is synthesized with Web Audio, oscillators and filtered noise. The audio context is created only inside a real click or key, so the tour and the recorder stay silent.
Inside the prompt
Every file below is written out in full, so your agent creates the project exactly — no guessing, no missing pieces.
vend-pricing/
├─ .gitignore
├─ index.html
├─ package.json
├─ tsconfig.json
├─ vite.config.ts
└─ src/
├─ App.tsx
├─ index.css
├─ main.tsx
├─ vite-env.d.ts
├─ components/
│ ├─ Machine.tsx
│ ├─ Panel.tsx
│ ├─ Scene.tsx
│ └─ Street.tsx
└─ lib/
├─ labels.ts
├─ live.ts
├─ plans.ts
├─ sfx.ts
├─ time.ts
└─ timeline.tsRecut it
- Rename the product and rewrite the plans
src/lib/plans.ts → PRODUCT / HEADLINE / PLANS - Change the roulette odds, code or reward
src/lib/plans.ts → LUCKY - Change the yearly discount
src/lib/plans.ts + src/lib/labels.ts → yearly / drawBilling() - Point the buttons at your checkout
src/components/Panel.tsx → href="#start" - Recolour the neon and LEDs
src/index.css + src/lib/labels.ts → @theme / AMBER, CYAN, MAGENTA - Thicker or thinner fog, a wider wipe
src/lib/labels.ts + src/lib/timeline.ts → drawFog() / WIPE_R / wipeStrength - Retune or silence a sound
src/lib/sfx.ts → sfx / setAmbience() - Vend a different plan in the tour, or retime it
src/lib/plans.ts + src/lib/timeline.ts → TOUR_TIER / TOUR_PRESS, TOUR_CLOSE - Move the camera
src/components/Scene.tsx → useShots()
Also in the vault

Monolith
Hero SectionA floating hexagonal basalt monolith split by glowing cyan fissures, with drifting debris, a light shaft, and pointer parallax. Procedural GLSL stone — no textures, no models, no network.

Kinetics
Hero SectionA dark SaaS hero where giant type slides with scroll inertia, glass stat cards tick like a live dashboard, and a frosted dock magnifies under the pointer. Pure DOM and Framer Motion — no canvas, no images.

CodePulse
ToolPaste a snippet and export a glowing, typed-out code clip as MP4 — square for X, vertical for Reels, Shorts, and TikTok. A Remotion composition with VS Code-grade highlighting and a live browser preview.