Skip to content

Putty

Putty is a site for a bakery, a cake studio or a café, a sweet shop or a toy maker with a counter: anyone whose products are made by hand and sold by the day. It’s made like a claymation: the page is a modelling board, pictures are pressed into slabs of plasticine and pinned with a ball of clay, buttons are clay pills that squash when pressed, and on the home page a lump of clay is remodelled into a ball of dough, a loaf, a croissant and a cake as the story scrolls past, while Bun the dough ball walks by. The baking week, bakes to pre-order, celebration cakes, baking classes, a journal and a visit page complete it.

Putty 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)
Menu, cakes, classes, journal, visit, 404 Pages → the page’s own entry
Bakes (price, size, when baked, keeps, ingredients, allergens, price tag, pre-orders) Content → Bakes
Journal posts Content → Journal
Name, description, email, phone, address, navigation, header button, profiles, social picture Pages → Site settings
Buttons, labels, chat, search, emails, game texts Content → Interface texts
Privacy, terms Pages → Legal

In headlines, words wrapped in *stars* are rolled in butter-coloured clay, as in “Squished with love, baked *this morning*”.

The story section keeps a board on screen while its chapters (two to four) scroll past. Each chapter picks one of four shapes, a ball of dough, a loaf, a croissant or a cake, and the clay on the board squashes and springs into that shape in the jerky steps of stop-motion as the chapter comes into view. Bun, the dough-ball mascot, walks across the bottom of the board as you read. The shapes and Bun are drawn in code (src/components/Clay.astro, Bun.astro) in the brand’s colours, so they follow any palette. Visitors who prefer reduced motion see the last shape standing.

  • A bake has a tagline, summary, price, size, when it is baked, how it keeps, its ingredients and allergens, a picture (4:5), a price tag and a colour. The bake’s page and the AI chat repeat the allergens exactly as you write them.
  • Pre-orders: turn on “Sell with Stripe Checkout” and put a one-time Price id there; the bake’s page gets a working button. Buyers come back to the menu, and the Stripe webhook (/api/stripe/webhook) emails them, where you can add your own steps.
  • The baking week (home page): seven days, Monday first, each with what comes out of the oven; today is marked.
  • Quotes on the home page: only real quotes with their source.

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

Feature Where Service
Pre-orders Each bake’s page Stripe
Cake consultations Cakes page; a preview of the calendar until it’s connected Cal.com
Newsletter and the class list Home, journal and classes pages, with a welcome email Supabase
Contact form Visit page; messages go to the email in Site settings Resend
AI chat On every page, answers from your bakes (with allergens), the baking week, cakes, classes, visit page and journal Claude
Search ⌘K or the search button: bakes, journal, cakes, classes, visit built in, or Algolia
Analytics Every page; Google Analytics only after consent Plausible, Umami, Google Analytics

The home page is built from these sections, in any order: The opening, The baking week, The clay story, Bakes, Feature (a picture and a text, e.g. cakes or classes), Numbers, Quotes, From the journal, Newsletter sign-up and Closing call.

src/content/singletons/brand.json (Pages → Brand in Keystatic) holds three colors: the accent (buttons, links and the plum clay), the second (mint fills and clay) and the third (butter fills, crusts and icing). Buttons are darkened until their white text is readable, the second and third are lightened until dark text on them is; a color that can’t get there stops the build with a message. The site opens in the day theme whatever the visitor’s system is set to; the night theme, the bakery after closing in deep plum, comes on with the toggle (pictures stay on cream clay). Brand also sets the fonts (a round, chunky face for headings, the text font and the label font) and the corners.

Putty is ready for more languages: see Languages.

A small game, Sort it: clay balls are jumbled in jars; move the top ball onto a jar with the same colour on top, or into an empty jar, until every jar holds one colour. Tap a jar and then another, or use the keys 1 to 7. Three rounds, each with one more colour; every deal is checked to be solvable, and each colour also has its own mark so it never relies on colour alone. The best score is kept in the visitor’s browser. The game follows the light and dark theme.

  • AGENTS.md describes the project for coding assistants (Claude Code reads it through CLAUDE.md, Cursor through .cursor/rules/).
  • /llms.txt lists your pages, bakes and journal for AI assistants, in every language.
  • Pages carry JSON-LD: the bakery as a Bakery, bakes as Products, classes as Events, the visit questions as a FAQPage, 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).