Restaurant Digital Experience
A two-branch restaurant site where the chosen location persists and shapes the rest of the visit — a large menu with search and virtualised rendering, a basket, reservations and a gallery.
- Built for
- Moon Grill
- Branches
- Two, persisted
- Menu
- Structured data + search
- Flows
- Order and reserve

Overview
A family restaurant experience for a business with two branches. Choosing a branch is the first thing that happens and it persists across visits, because it determines which kitchen an order and a reservation belong to. Behind it sits a large structured menu with category navigation and search, a persisted basket and a reservation flow.
Objective
Handle a multi-branch restaurant properly — where an order or a table booking is meaningless until you know which location it is for.
Problem and opportunity
Most restaurant sites treat multiple branches as a line in the footer. If the site is going to take orders and reservations, the branch has to be a first-class piece of state rather than an afterthought.
Solution
A branch selection step on first visit, persisted so returning visitors are not asked twice, surfaced permanently in the header so it can be changed at any point. The menu is held as structured data with a pairings layer, and rendered through virtualisation so the length of the catalogue does not cost scrolling performance.
Technology
- Framework
- Next.js 16React 19TypeScript
- State
- Zustand with persistence — branch, cart, favourites
- Performance
- TanStack Virtualnext/image
- Styling
- Tailwind CSS 4Framer Motionlucide-react
Key features
What is actually in the build.
- 01
Branch as persisted state
A selection modal on first visit, stored locally and shown in the header, with each branch carrying its own contact routing.
- 02
Structured menu experience
A large menu held as data with category navigation, search and a pairings layer, rendered with virtualisation to keep long lists smooth.
- 03
Basket and checkout
A floating basket bar that animates its running total as items change, opening into a checkout modal.
- 04
Reservations and concierge
A table reservation section alongside signature dishes, the craft story, a gallery with lightbox and testimonials.
On a phone
Designed for the small screen too.

Captured from the live deployment at 390 × 844. The mobile layout is composed rather than scaled down — navigation, density and the primary action are all decided again for the narrow viewport.
UX and interface decisions
Warm dark with brass
A near-black ground with brass accents and a serif display face — the register a family restaurant with a live-fire kitchen actually occupies.
Cursor companion on desktop only
A contextual cursor that reacts to interactive regions, disabled entirely on coarse pointers.
Totals that animate as numbers
The basket total transitions between values rather than snapping, so a change registers without needing a flash or a toast.
Technical approach
Partial persistence
Only the selected branch is persisted from the branch store — modal state deliberately is not, so a returning visitor is never greeted by a dialog they already dismissed.
Hydration gating
The basket bar waits for the persisted cart to load before it can appear, which keeps the first client render matching the server.
Challenges
The parts that needed a second attempt.
A large menu that still feels fast
Hundreds of dishes across several categories is enough to make naive rendering visibly stutter on a mid-range phone. Virtualisation keeps only what is on screen mounted.
Next project
Healthcare & Clinic Experience
Vessante Aesthetic Institute · Concept build
