Poke restaurant — playful ordering site
A playful one-page site where customers build a bowl and show a QR receipt at the till.
- Vanilla JS
- Motion One
- Canvas API
- qrcode-generator
- jsQR
- PWA
- Puppeteer
- 2,304lines in 5 files, no build step
- 4text stages along the scroll-driven video hero
- 3Puppeteer QA scripts at phone and desktop sizes
Build a bowl, scan it at the till
One page with no build step: a scroll-driven video hero, a bowl builder whose cart becomes a QR receipt, and a till view that scans it. No online payment.
Tap a block to see what it does.
- Input
- Infrastructure
- Logic
- People
- Output
Input
Hero clips
The hero film in two cuts, 16:9 for desktop and 9:16 for phones, each framed for its screen.
- MP4
Hands to Scrub engine

Infrastructure
No-build page
One HTML page, one CSS file and plain JS; installable as a PWA, served in development by a small server that never caches the HTML.
- PWA
- Python
Hands to Scrub engine, Sticker motion, Bowl builder
Logic
Scrub engine
Plays the hero with the scroll: clips as blob URLs, lazy preload, crossfades, iOS priming, frame-rate-independent damping, poster with reduced motion.
- Vanilla JS
- Blob URLs
Gets from Hero clips, No-build pageHands to Live theme colour
Logic
Sticker motion
Spring reveals and letter staggers with Motion One, draggable reel lanes, and a rescue pass for titles left invisible, a bug Puppeteer caught.
- Motion One
- Puppeteer
Gets from No-build page
People
Bowl builder
The customer picks base, proteins, vegetables, crunch and sauces within the size's limits; finished bowls go into a cart saved on the device.
- localStorage
Gets from No-build pageHands to QR receipt
Logic
Live theme colour
Samples the top and bottom strips of the video frame on a canvas and sets the browser's theme colour, so its bars blend into the hero.
- Canvas API
Gets from Scrub engine
Output
QR receipt
The order is encoded in a QR link; the receipt can be saved as a PNG drawn on canvas, sent on WhatsApp or shown at the till.
- qrcode-generator
- Canvas API
Gets from Bowl builderHands to Till view
People
Till view
Staff scan receipts with the phone camera (BarcodeDetector, or jsQR on iPhone); orders pile up in one list and expire after six hours.
- getUserMedia
- BarcodeDetector
- jsQR
Gets from QR receipt
The problem
A neighbourhood poke restaurant lived on Instagram and a delivery app. It wanted a site with the same playful energy as its brand, one that brings orders into the shop without an online checkout.
What I built
- Made the brand kit first: logos generated with ChatGPT images and a palette sampled from the shop's own material.
- Produced the hero video and wrote a scroll-scrub engine that plays it as you scroll, with separate 16:9 and 9:16 cuts and four text stages.
- Built a bowl builder with a cart: base, proteins, vegetables, crunch and sauces, with limits that change with the bowl size.
- Turned the cart into a receipt with a QR code that the customer can save as an image, send on WhatsApp or show at the till.
- Added a till view for the staff: they scan receipts with the phone camera and the orders pile up in one list.
The hard part
Smooth video scrubbing on iPhones. The engine loads each clip as a blob URL so it can always seek, primes playback on the first touch, crossfades between clips and smooths the scroll with frame-rate-independent damping. With reduced motion it shows a poster instead.
Result
A finished one-page site with its deploy bundle ready: 2,304 lines in 5 files, no build step, checked by Puppeteer scripts at phone and desktop sizes. I then packaged the design and motion method as a reusable Claude Code skill and used it on later client sites.
My role
Solo. I set the creative direction, made the brand kit and the hero video, ran the QA and packaged the build; I developed the code together with an AI coding agent.