Wag
Wag is a site for a dog shelter or rescue: shelters, foster networks, breed rescues, municipal animal shelters and dog sanctuaries. Its pages are kraft paper with the dogs cut out of their photos and set on top, each on a soft blob in its own colour, with name tags shaped like dog tags, speech bubbles in a marker hand and paw prints. On the home page the dogs looking for a home walk in one at a time as you scroll, stop to say hello and trot off as the next one arrives. The demo is a fictional rescue, Second Chance Dog Rescue.
Wag 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) |
| Dogs, adopt (steps, fee, questions), help (ways, donations, wishlist), happy tails, visit (opening hours), 404 | Pages → the page’s own entry |
| Dogs (age, size, breed, good with, traits, story, photo, status, sponsorship) | Content → Dogs |
| Happy tails | Content → Happy tails |
| Name, charity details, address, navigation, header button, profiles | Pages → Site settings |
| Buttons, labels, filters, chat, emails, game texts | Content → Interface texts |
| Privacy, terms | Pages → Legal |
In headlines, words wrapped in *stars* get a marker stroke underneath that draws itself as they
scroll into view, as in “Every dog deserves a *second chance*”.
Dogs and their photos
Section titled “Dogs and their photos”Each dog is an entry with its age (as you’d say it, “about 3 years”) and age group, size, breed, when they arrived, whether they get on with children, cats and other dogs (yes, no or ask us), a few traits, a short summary, the line in their speech bubble and their story. The status is looking for a home, reserved or adopted; only dogs looking for a home walk in on the home page, and adopted ones stay on the dogs page, marked, until you remove them. The dogs page filters by size, age and who they get on with, with no JavaScript.
The photo is a cut-out: a PNG with a transparent background, the whole dog in frame, facing right. Remove the background with any tool (most phones’ photo apps do it) and export a PNG; it is served as AVIF or WebP with its transparency. The peeking dogs on the dogs and adopt pages are cut-outs of a head and front paws.
Integrations
Section titled “Integrations”Everything works without keys; each feature switches on with its variables in .env.example.
| Feature | Where | Service |
|---|---|---|
| Donate once, sponsor a dog monthly | Help page (one-time Price ids), each dog’s page (a monthly Price id) | Stripe |
| Book a meet-and-greet | Adopt page, loads on click; a preview of the calendar until connected | Cal.com |
| Newsletter, volunteer sign-up | Home, happy tails and help 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 about the dogs, adopting, helping and visiting; never promises a dog | Claude |
| Search | ⌘K or the search button: dogs, happy tails, adopt, help, visit | built in, or Algolia |
| Analytics | Every page; Google Analytics only after consent | Plausible, Umami, Google Analytics |
Sections
Section titled “Sections”The home page is built from these sections, in any order: Meet them one by one (the dogs walking in), Our dogs (cards whose dogs hop out as you point at them), How to adopt (steps along a trail of paw prints), Ways to help (tags that swing in on their strings), In numbers, Happy tails (polaroids), Newsletter sign-up and Closing call. With reduced motion, the dogs stand in a row with their bubbles and nothing moves.
Colors and brand
Section titled “Colors and brand”src/content/singletons/brand.json (Pages → Brand in Keystatic) holds three colors: the
accent (collar red: buttons, paw prints and the marker underline), the second (tennis-ball
yellow) and the third (sky blue), used for fills and the blobs under the dogs. Buttons are
darkened until their white text is readable, the second and third are lightened until ink text on
them is; a color that can’t get there stops the build with a message. Brand also sets the fonts
(text, headings, and the marker hand for bubbles, tags and captions) and the corners. The site
opens in the day theme (kraft paper) even when the visitor’s system is dark; the toggle switches
to the night theme, a warm evening brown, and the browser remembers the choice.
Languages
Section titled “Languages”Wag is ready for more languages: see Languages.
The 404 page
Section titled “The 404 page”A small game, Which bowl?: a treat goes under one of three dog bowls, the bowls shuffle, faster every round, and you pick the bowl with the treat (tap it, or press 1, 2 or 3). Five rounds; 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, dogs and happy tails for AI assistants, in every language.- Pages carry JSON-LD: the rescue as an
AnimalShelter, the dogs as anItemList, adopting as aHowTo, questions as aFAQPage, and each happy tail as aBlogPosting.
Commands
Section titled “Commands”pnpm dev # local site, editor at /keystaticpnpm 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).