SS1WORK

Ember & Salt

A restaurant that does not exist, with a reservation system that does. It only offers tables that are really free, and a service board that runs the night.

CLIENT
FICTIONAL RESTAURANT
PROBLEM
OFFERING TABLES THAT ARE TAKEN
ROUTE
RULES IN CODE, ONE DOCUMENT A NIGHT
The Ember & Salt demo's home page, as a screenshot
Role
Design and build
Year
2026
Client
Fictional (a made-up wood-fire restaurant)
Stack
React, Vite, Netlify Functions, Netlify Blobs, zod, Playwright

What this is

Ember & Salt is a wood-fire restaurant in Windhoek with fourteen tables, dinner six nights a week and lunch on Fridays and Saturdays. It is made up. What it proves is the part of a booking system that is easy to get wrong, which is working out when a table is truly free. A diner picks a party size and a date and sees only the times that are really available, because the system knows table sizes, which tables can be pushed together, and how long each party usually stays. The back office runs a service live, and the menu responds to what the kitchen has tonight. There are four menus (dinner, lunch, the six-course tasting menu and drinks), and a diner can add the tasting menu, with or without wine pairing, to a reservation.

Try this

  1. Reserve a table for four this Saturday and look at which times are really free
  2. Switch on the demo clock at 18:30, then open the service board and seat a walk-in
  3. Take a dish off the menu in admin and watch it sink on the public menu

How it works

Following one reservation from click to service

BrowserNetlify CDNFunctionsSeed dataBlobs storeNightly reset
  1. You choose a party and a date

    The page asks the server for the night. Busy Fridays and quiet Tuesdays are generated from a few rules, plus anything you have booked yourself, so the room already has a believable amount of business in it.

  2. The free times are worked out, not stored

    A pure function lays a 15 minute grid over the service, gives each existing booking the tables and time it needs for a party of its size, and keeps only the seatings where a table, or a pair of tables, is free for the whole turn. Times inside the two hour notice window are left out.

  3. You pick a time and give your details

    The details are checked for size and shape, a hidden field and a minimum time on the form catch simple bots, and each address is limited to a handful of changes every ten minutes.

  4. The table is chosen and written in one step

    The best fit is the smallest table that seats the party. It is saved into that night's single document with a check that nothing else changed since it was read, so the table cannot also go to someone else.

  5. You can change or cancel it

    A change is tested with your own booking left out, then swapped in as one step, so a move that fails leaves you exactly where you were. A cancellation frees the table straight away.

  6. The service board reads the same night

    The back office sees the same document the public site writes to. Marking a no-show frees the table for the rest of its turn, a walk-in takes the best free tables from this minute, and taking a dish off the menu sinks it on the public page at once.

Real versus mocked

What is real and what is mocked in this demo
PartStatusDetail
Table assignmentRealFifteen minute grid, turn times by party size, best fit, joined tables, notice window, last seating and closed dates, all in one tested function.
No double bookingRealChecked by a property test over thousands of random requests, with 40 parallel reservations for the same tables and with two real browsers
Change and cancelRealA change swaps in one step and never loses the old table if the new one is taken.
Service boardRealArrived, seated, no-show, walk-ins, the 86 list and specials all change what the public sees. Changes affect your own copy only.
Demo clockMockedA private clock so you can see the restaurant in service at any hour. A real restaurant would not have one.
Existing bookingsMockedGenerated from the date, not real people. The names are invented.
MenuMockedInvented. No real dishes, suppliers or trademarks.
DepositsMockedThere is no payment and nothing is ever sent, not even the waiting list or a private dining enquiry.

Data and privacy

Ember & Salt is fictional, so use made-up names and details. What you enter lives in your own private copy of the demo, which no other visitor can see, for up to 24 hours. A nightly job at 02:00 Windhoek time clears it. Nothing is charged, nothing is sent, and the demo clock only changes what you see.

Under the hood

Initial JS
129 KB gzipped, React, Router and the motion code included (the budget is 150 KB). Measured on the live site.
Lighthouse
Live site, mobile, three runs: Performance 77 to 91, Accessibility 96, Best Practices 93, SEO 100.
  • demos/restaurant/src/lib/slots.js The rules that decide which times a table can honestly be offered.
  • demos/restaurant/src/lib/day.js Reserve, change, cancel, no-show and walk-in on one night's document.
  • demos/restaurant/src/lib/seeded.js Existing bookings, generated so every night looks real.
  • packages/demo-kit/src/store.js The store and its atomic update, shared by every demo.

What I would do differently

The demo clock lets a visitor see the restaurant in service at any hour, but it runs through every rule that cares what time it is. If I did it again I would make time an injected input from the first line, so the clock is a test tool first and a demo feature second.

More demos

  • Namib HorizonsA small safari company that does not exist, with a booking system that does. Seats are counted live, held for 15 minutes and sold without ever being sold twice.
  • Kalahari ThreadsA clothing label that does not exist, with a shop that tells the truth. The bag is checked against the real shelf every time it opens, and an order is taken whole or not at all.

All work