Cellar
Cellar is a site for a vineyard and winery with a cellar door: estate wineries with a tasting room, small family vineyards that sell their wine direct by the bottle, the case and through a wine club, and cideries or small distilleries with a tasting room. It is set in a cellar by candlelight: a wine-dark room with the faint courses of a brick vault behind every page, claret, candle gold and vine green, a wine-label serif and a glass pill nav. The demo is a fictional estate, Ravelin Hill, on one hillside in a made-up valley.
The first screen is one row of vines through one year, seen from a single spot. As you scroll, bare winter vines in frost and mist bud in spring, fill out and turn colour in summer, hang heavy with dark grapes beside a picking crate at golden hour, and stand at dusk with a glass of red on the upturned crate. A readout counts the season, the sugar in °Brix along a ripening curve and the bottles, and the five steps follow in a glass card. The headline, one line, Shop wines, Book a tasting and the rating stay over it from the first frame.
Cellar 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.
Pages and their content
Section titled “Pages and their content”| Page | Edit it in |
|---|---|
| Home | Pages → Home page (a list of sections) |
| Wines (every wine, shipping, the age notice, questions) | Pages → Wines page |
| A wine (a page each: story, grape and vintage, tasting notes, food pairing, vineyard and cellar facts, how to serve it, a bottle or a case, questions, photo) | Content → Wines |
| Wine club (tiers, what members get, how a shipment goes, questions) | Pages → Wine club page |
| Visit & tastings (the tastings, booking, map, hours, getting here, the terrace, message form, questions) | Pages → Visit page |
| Events & weddings (the spaces, how it works, a venue visit, an enquiry form, questions) | Pages → Events page |
| The estate (the story in chapters, the year in the vineyard, facts) | Pages → Estate page |
| Gift vouchers | Pages → Gifts page |
| Journal (harvest notes) | Content → Journal (one post can be for club members only) |
| Name, phone, address, rating, cellar door hours, age notice, navigation, profiles | Pages → Site settings |
| Buttons, labels, chat, emails, game texts | Content → Interface texts |
| Privacy, terms of sale, shipping | Pages → Legal |
In headlines, words wrapped in *stars* are set in italic and filled with wine from the bottom up as
they come into view, as in “One hillside, *one year* in every bottle”.
The year (the hero)
Section titled “The year (the hero)”The hero pins five photos of the same row of vines, taken from exactly the same spot: winter, budburst, véraison, harvest and dusk. As you scroll, each is revealed into the last behind a soft seam of light: spring rises up the slope as the mist lifts, véraison opens out from the sun, the harvest light floods in from the low sun with dust turning in the beams, and dusk falls from the sky with the first stars and a glint on the glass. The readout counts to what you set for each step (the season’s name, the sugar in °Brix, the bottles) and draws the ripening curve through them; the five steps follow one at a time in the card.
Make your own five photos from one: shoot (or generate) the first frame with the row in the middle and the sky quiet where the headline sits, then edit it four times so nothing but the season changes. Phones get a tall crop of the middle of each photo, so keep the row, the crate and the glass in the centre. The first photo loads with the page and the others just after, so the page stays fast. With reduced motion, or in a browser without scroll-driven animations, the hero is a still frame: the harvest, the readout at the pick, the curve drawn, and the five steps listed under it.
Wines, cases, the club and vouchers
Section titled “Wines, cases, the club and vouchers”Each wine has its grape, vintage and style (the colour of the wine in the small glass beside it),
tasting notes, food pairing, vineyard and cellar facts, how to serve it, and the price of a bottle and
of a case of six. Buy a bottle and Buy a case go through Stripe (a one-time Price id each, on every wine)
or Lemon Squeezy (variant ids in the same fields). The club’s tiers take a recurring Price id (monthly,
or every three months for a quarterly tier) and the gift vouchers a one-time one. Without keys the
buttons explain how to switch payments on. Wines are published for search engines as schema.org
Products with their offers.
Wine is age-restricted: the age notice in Site settings sits beside every Buy button and in the footer, and the terms of sale say who may buy and that deliveries are signed for with ID. Only sell where you hold the licence to ship wine, and turn on your payment provider’s age and address checks.
Tastings and events
Section titled “Tastings and events”The visit page lists your tastings (length, price and what’s poured) and books them through Cal.com; the events page books venue visits the same way (its own Cal.com link, or the tasting one) and takes enquiries by email. Until Cal.com is connected, both show a preview of the calendar.
The map
Section titled “The map”The visit page and the home section “Find us” show a map of the lanes round the winery, drawn from
OpenStreetMap in your colors, with a pin, your address and
directions links. It is part of the page (no embed, no cookies) and follows the theme and your accent.
To draw your own, put your coordinates in map.config.json and run pnpm map -- fetch.
Integrations
Section titled “Integrations”Everything works without keys; each feature switches on with its variables in .env.example.
| Feature | Where | Service |
|---|---|---|
| Bottles, cases, the wine club, gift vouchers | Wine pages, the club and gifts pages | Stripe or Lemon Squeezy |
| Tastings and venue visits | Visit and events pages, loads on click; a preview of the calendar until connected | Cal.com |
| Cellar letters | Home and journal pages, with a welcome email | Supabase or Mailchimp |
| Event enquiries, messages, order emails | Events and visit pages; to the email in Site settings | Resend |
| AI chat | Every page; answers about the wines, pairings, the club, tastings, events and visiting; never encourages anyone under age | Claude or OpenAI |
| Members-only harvest notes | Journal | Clerk |
| Search | ⌘K or the search button: wines, tastings, pages, journal | built in, or Algolia |
| Analytics | Every page; Google Analytics only after consent | Plausible, Umami, Google Analytics, PostHog |
| Photos | Production builds | Cloudinary (optional) |
Sections
Section titled “Sections”The home page is built from these sections, in any order: Hero (the year), The wines (cards whose glass fills as they rise), The estate (the winery comes up out of the dark as it scrolls in), Wine club (a vine-green band), Numbers (a cellar book with the hillside drawing itself behind it), Tastings, Journal, Cellar letters, Find us (the map and the hours) and Closing call (a photo across the window, dark in both themes).
Colors and brand
Section titled “Colors and brand”src/content/singletons/brand.json (Pages → Brand in Keystatic) holds three colors: the accent
(claret: Shop and Book buttons, marks), the second (candle gold: stars, small capitals, the readout)
and the third (vine green: the club band and badges). Buttons and the green fill are darkened until
their white text is readable, gold is adjusted for each theme; a color that can’t get there stops the
build with a message. Brand also sets the fonts and the corners. The mist, sunlight, dusk and the wine
in the glasses use the vineyard’s own colours, so they stay true whatever accent you pick. The site
opens in its dark theme even when the visitor’s system is light; the toggle switches to the day
(limestone and ink) and the browser remembers it.
Languages
Section titled “Languages”Cellar is ready for more languages: see Languages.
The 404 page
Section titled “The 404 page”A small game, Stack the cellar: barrels come down on a hoist; move it (pointer, drag or the arrow keys) and drop them (tap, Space or Enter). They fall, roll and settle under real physics into the saddles between the barrels below; one dropped on the crown of another rolls off. Lose three off the end of the rack and the game is over. When a cellar’s barrels are down and still, each scores ten for every tier it rests on. Three cellars, with racks for 3, 4 and 5 barrels across. 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, wines, club tiers, tastings and the journal for AI assistants, in every language.- Pages carry JSON-LD: the business as a
Winery(price range, hours), wines asProducts with offers for a bottle and a case, club tiers, tastings, spaces and vouchers as offers, questions as aFAQPage, and each journal post as aBlogPosting.
Commands
Section titled “Commands”pnpm dev # local site, editor at /keystaticpnpm build # production buildpnpm map -- fetch # draw the map round map.config.json from OpenStreetMappnpm 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).