Cipher
Cipher is a site for an escape room venue: escape rooms, puzzle venues, immersive game venues. It is drawn like a heist blueprint. The home page opens on your venue’s floor plan in 3D, on a deep blue blueprint with its walls raised. As you scroll, the camera goes to the way in, then to each room in turn, and the room’s floor lights up in its own colour (and stays lit), with a card beside it: the room’s name, its line, difficulty, players and price. At the end the whole venue is lit. Ultramarine, flamingo and mint on blueprint paper with a grid, stencil headings, panels like drawing sheets with crop marks, buttons like stamped tags. The demo is a fictional venue in Rotterdam, Lockwork, with five rooms.
Cipher comes in two variants, chosen when you create the site: files/Sanity (static pages, any host) and
EmDash (--cms emdash, rendered on request on Cloudflare). The pages are the same in
both.
Your floor plan
Section titled “Your floor plan”The plan is drawn from data, so it can be any venue. Edit it in Pages → The floor plan:
- Set the venue’s
widthandheightin metres. - Add your areas as rectangles (
x,y,w,hin metres, from the top-left corner). Link an area to a room by the room’s file name (e.g.the-vault): it takes the room’s colour, name and number. Leave it empty for the lobby, corridors, the lounge. Mark one area as the entrance. Keep areas edge to edge, so their walls line up. - Add the doors: the middle of each door on a wall, its width, and whether that wall runs up and down. The walls are drawn with a gap there and a door swing.
- Add a few pieces of furniture (rectangles and circles) if you like: they make the plan read.
Rooms light up in the order of the areas. The same plan shows flat on the rooms page and on each room’s page, with that room lit. With reduced motion the plan stands lit and the cards are a list under it.
Pages and their content
Section titled “Pages and their content”| Page | Edit it in |
|---|---|
| Home | Pages → Home page (a list of sections; the floor plan’s texts are in its first section) |
| Rooms (a filter by difficulty, the rooms, the plan, the difficulty scale) | Pages → Rooms page and Content → Rooms |
| A room (picture, difficulty, players, time, age, price, booking, story, close-up, the plan) | Content → Rooms |
| Groups (what groups book, how it works, booking a date) | Pages → Groups page |
| Gift vouchers (vouchers with checkout, how they work, the small print) | Pages → Gift vouchers page |
| Journal | Pages → Journal page and Content → Journal |
| Visit (hours, the map, safety, getting here, questions, the contact form) | Pages → Visit page |
| Name, contact, navigation | Pages → Site settings |
| The floor plan | Pages → The floor plan |
In headlines, words wrapped in *stars* sit on a flamingo highlighter band.
Rooms, booking and vouchers
Section titled “Rooms, booking and vouchers”Each room has a tagline, summary, difficulty (1 to 5, shown as padlocks; the five names are in
Interface texts → Rooms), players, time, age, the share of teams that get out (optional), a price and a
note (e.g. “2 to 6 players, the same price”), a tall picture, a wide close-up, a colour and its
number (order). Turn on “Book online” and add a Stripe Price id (or a Lemon Squeezy variant id), and
the room’s button takes the team to checkout; after paying they get an email and come back to the
rooms page with a message. Gift vouchers work the same way, each with its own price id. Groups book a
call with Cal.com.
Integrations
Section titled “Integrations”Everything works without keys; each feature switches on with its variables in .env.example.
| Feature | Where | Service |
|---|---|---|
| Booking and gift vouchers | Each room’s page, the vouchers page | Stripe or Lemon Squeezy |
| Groups and parties | Groups page, loads on click | Cal.com |
| Newsletter | Home and journal pages, with a welcome email | Supabase or Mailchimp |
| Contact form | Visit page; messages go to the email in Site settings | Resend |
| AI chat | Every page; answers from your rooms (never the solutions), groups, vouchers, visit details and journal | Claude or OpenAI |
| Search | ⌘K or the search button: rooms, vouchers, groups, journal, visit | built in, or Algolia |
| Analytics | Every page; Google Analytics only after consent | Plausible, Umami, Google Analytics, PostHog |
| Members-only posts | Journal | Clerk |
Sections
Section titled “Sections”The home page is built from these sections, in any order: The floor plan (the signature), Rooms, How it works, Feature (e.g. groups), Numbers, Journal, Newsletter and a closing call over a photo from edge to edge.
Colors and brand
Section titled “Colors and brand”src/content/singletons/brand.json (Pages → Brand in Keystatic) holds three colors: the accent
(ultramarine: buttons, the grid, links, the night blueprint’s hue), the second (flamingo: rooms,
the highlighter band, button shadows) and the third (mint: rooms and fills). Every room picks one
of the three. Buttons are darkened until their white text reads; every color is adjusted for each
theme, and one that can’t get there stops the build with a message. Brand also sets the fonts (text,
stencilled headings, labels) and the corners. The site opens by day; night comes from the toggle.
The visit page shows a map of the streets around you, drawn from OpenStreetMap: set your entrance’s
coordinates in map.config.json and run npm run map -- fetch.
Languages
Section titled “Languages”Cipher is ready for more languages: see Languages.
The 404 page
Section titled “The 404 page”A small game, Crack the code: set the dials of a combination lock and try the code. After each try the lock tells you how many symbols are right and in place, and how many are right but on another dial. Three locks: three dials of five symbols, then four of six, then four of eight. Each lock scores 100 × par ÷ your tries (at most 100), nothing if you run out. Tap a dial to turn it, or use the arrow keys and Enter. The best score is kept in the visitor’s browser.
AI assistants and search engines
Section titled “AI assistants and search engines”AGENTS.mddescribes the project for coding assistants (Claude Code reads it throughCLAUDE.md, Cursor through.cursor/rules/)./llms.txtlists your pages and rooms for AI assistants, in every language.- Pages carry JSON-LD: the venue as an
EntertainmentBusiness, rooms asProducts with their price, vouchers as anOfferCatalog, groups as aService, questions as aFAQPage, posts asBlogPostings.
Commands
Section titled “Commands”pnpm dev # local site, editor at /keystaticpnpm map # redraw the visit page's map (npm run map -- fetch)pnpm build # production buildpnpm cms sanity schema|seed # move content to Sanity (see Content → Sanity)In the EmDash variant: npm run dev, npm run deploy (Cloudflare) and npm run emdash:schema (after
changing the content model).
