Skip to content

Chalk

Chalk is a pub and taproom site drawn on the chalkboard behind the bar: chalk headlines with circled words, hand-drawn doodles that draw themselves in, kraft paper by day and a slate board at night. The tap list is the heart of it; then come the kitchen menu, the week’s nights and specials, a small shop, a journal and a visit page that says whether you’re open right now.

Chalk 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.

Page Edit it in
Home Pages → Home page (a list of sections)
On tap, food (the menu), what’s on, shop, journal, visit, 404 Pages → the page’s own entry
Name, contact, address, opening hours, navigation, header button, profiles Pages → Site settings
Beers Bar → Beers
Events Bar → Events
Gift cards and merch Bar → Shop items
Journal posts Content → Journal
Buttons, labels, chat, search, emails, game texts Content → Interface texts
Privacy, terms Pages → Legal

In headlines, a word wrapped in *stars* gets a chalk circle drawn around it, as in “Sixteen taps and a very *good* chair”.

Each beer has a name, brewery, style, strength (ABV) and a list of prices per size (a third, a half, a pint, or anything you like). Give it a tap number and it’s on the board, sorted by tap; leave the number empty and it shows under “Coming soon”. An optional badge adds a chalk tag (“New”, “Last keg”), and chalk picks its color. The tap list can be filtered by style; the filter is plain radio buttons, so it works without JavaScript. The home page shows the first few taps.

Pages → Food page holds the menu in sections (snacks, plates, something sweet…), each dish with a description, a price and dietary marks: v vegetarian, vg vegan, gf gluten free (the legend’s words are editable). Write your allergen note below it.

An event either repeats every week on a day (a quiz on Tuesdays) or happens once on a date. Weekly nights make the board on the home page and the events page; one-offs show under “Coming up”, soonest first, and drop off after their date with the next build. Events can have a photo.

Site settings hold the hours for every day (leave a day empty when you’re closed) and your time zone. The footer and the visit page list them, and a small line says “Open now, till 23:00”, “Opens today at 16:00” or “Closed, opens Tuesday at 16:00”, worked out in the visitor’s browser. A closing time after midnight counts as the same night. Search engines get the hours too.

Everything works without keys; each feature switches on with its variables in .env.example.

Feature Where Service
Shop Shop page: a Buy button per item with a Stripe Price id (one-time) Stripe
Book a table Visit page, loads on click Cal.com
Contact form Visit page; messages go to the email in Site settings Resend
Fresh kegs (newsletter) Home, tap list and journal, with a welcome email Supabase
Ask the bar Chat on every page, answers from your taps, menu, events, hours and shop Claude
Search ⌘K or the search button: beers, menu, events, shop, visit, journal built in, or Algolia
Analytics Every page; Google Analytics only after consent Plausible, Umami, Google Analytics

After a payment, the Stripe webhook (/api/stripe/webhook) emails the buyer; add your own steps there, such as sending the gift card code.

The visit page shows a map picture (Pages → Visit page → Map) with your address. Add your latitude and longitude and it also offers directions (Google Maps, in a new tab) and a live OpenStreetMap, which loads only when the visitor opens it, so nothing is requested from a third party before that.

The home page is built from these sections, in any order: Hero, On tap now, The week, Food (up to three photos), The place (with the opening hours), Latest journal posts, Newsletter sign-up and Closing call to action.

src/content/singletons/brand.json (Pages → Brand in Keystatic) holds three chalks: the first chalk (buttons, circles, the active tap filter) and a second and third for tags, doodles and colored headings. On a chalk fill the text is slate, so a chalk is lightened until that reads; used as text it is lightened on the board and darkened on paper until it passes WCAG AA, and a color that can’t get there stops the build with a message. Brand also sets the chalk texture (on headlines and the background) and the fonts: text, headings and a handwriting face used only for small asides.

Chalk is ready for more languages: see Languages. The day names for the opening hours are in Interface texts.

A small game, Pour the pint: hold to pour (press and hold, or hold Space) and let go before it spills. The head settles, and the closer the top ends up to the line on the glass, the better. Five pints a round; the tap glugs and pours faster each time. The best score is kept in the visitor’s browser.

  • AGENTS.md describes the project for coding assistants (Claude Code reads it through CLAUDE.md, Cursor through .cursor/rules/), including what makes the look.
  • /llms.txt lists your pages, what’s on tap, the regular nights, opening hours and journal posts for AI assistants, in every language.
  • Pages carry JSON-LD: the bar with its opening hours, the tap list and food as menus with prices, events, shop items, questions and each post.
Terminal window
pnpm dev # local site, editor at /keystatic
pnpm build # production build
pnpm 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).