Flume
Flume is a site for a plumber: emergency repairs, drain cleaning, water heaters, repiping, leak detection and fixtures for homes. It is cinematic and calm, built from one picture: copper and clear water under a hard raking light on a dark ground. The home page opens on a short silent film of water running along a copper channel, edge to edge on every screen, with the phone number and a free quote right on it. Behind every page the net of light that water throws on the floor of a basin drifts as you scroll; the colours are water cyan, copper and clear aqua on a cool porcelain white. The demo is a fictional business, Tidewell Plumbing & Drain.
Flume 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) |
| Services, jobs, guides, 404 | Pages → the page’s own entry |
| Prices (trip fee, packages, how a visit works, booking, deposits and vouchers, questions) | Pages → Prices page |
| Contact (quote form, towns, map, hours, details, questions) | Pages → Contact page |
| Services (icon, badge colour, price from, how long, what’s included, typical jobs, questions, photo) | Content → Services |
| Jobs (where, when, called, on site in, time, cost, photo, story) | Content → Jobs |
| Guides (one can be for members only) | Content → Guides |
| Name, phone, address, license, navigation, header button, profiles | Pages → Site settings |
| Buttons, labels, chat, emails, game texts | Content → Interface texts |
| Privacy, terms, guarantee | Pages → Legal |
In headlines, words wrapped in *stars* fill with water as they scroll into view and stay in the water
colour, as in “Water where you want it. *Nowhere else.*”.
The opening film
Section titled “The opening film”The home page’s first section is the film. Its texts are yours: the status line (“On call now”), the
small line, the headline, the lead, two buttons (make the first one your phone number as a tel: link
and it gets a phone icon) and up to three facts under them. The picture is two files:
- Photo: the film’s first frame, 16:9 and at least 1920 pixels wide, dark at the top where the text
sits. It shows at once and is what search engines and slow phones see. Set Photo focus to the part
that should stay in view on a narrow screen (e.g.
50% 60%). - Film: a short silent MP4 loop in
public/media/(about 2 MB, 1280 wide), e.g./media/hero.mp4. It starts loading only after the page has, fades in over the photo and pauses when you scroll past. Leave it empty to show the photo only. Visitors who prefer reduced motion or save data see the photo.
A dark scrim under the text keeps it readable over the brightest frame; if you swap in a much brighter film, check that the text still reads.
Services and jobs
Section titled “Services and jobs”Each service has a round badge in one of the three colours: water cyan, copper (keep it for the emergency service) or clear aqua. Jobs are shown as service tickets: when the call came in, how soon you were on site, the time on site and the cost, with a “Fixed” stamp.
Prices, booking and payments
Section titled “Prices, booking and payments”The prices page holds your trip fee on a disc of water with its small print (evenings, nights, how the repair is priced), up to four packages (mark one as the popular one), how a visit works as steps along a copper pipe that fills with water (also on the home page), booking an estimate with Cal.com, and deposits and gift vouchers you take with Stripe or Lemon Squeezy: each one gets a one-time price id. Without keys, the booking shows a preview of the calendar and the payment buttons explain how to switch them on.
The map of the area
Section titled “The map of the area”The map is drawn from OpenStreetMap in your colours, with a
pin on your shop and a ring for the area you cover. It is part of the page (no embed, no cookies) and
follows the theme and your accent. To draw your own, put your shop’s coordinates in map.config.json and
run pnpm map -- fetch. detail: "area" (the default in Flume) draws the main roads, railways, water and
woods of a whole district, and Contact page → Map → Radius sets the ring; detail: "streets" draws the
streets and buildings round one address instead.
Integrations
Section titled “Integrations”Everything works without keys; each feature switches on with its variables in .env.example.
| Feature | Where | Service |
|---|---|---|
| Book an estimate | Prices page, loads on click; a preview of the calendar until connected | Cal.com |
| Deposits and gift vouchers | Prices page (one-time prices) | Stripe or Lemon Squeezy |
| Guides by email | Home and guides pages, with a welcome email | Supabase or Mailchimp |
| Members-only guides | A guide marked members only shows its text after signing in | Clerk |
| Quote form | Contact page; messages go to the email in Site settings | Resend |
| AI chat | On every page, answers about services, prices, jobs and areas; tells anyone with a leak to shut off the main and call, and never gives instructions for gas or permit work | Claude or OpenAI |
| Search | ⌘K or the search button: services, jobs, guides, prices, contact | built in, or Algolia |
| Analytics | Every page; Google Analytics only after consent | Plausible, Umami, PostHog, Google Analytics |
| Photos | Served from your Cloudinary account when it is set | Cloudinary |
Sections
Section titled “Sections”The home page is built from these sections, in any order: Opening (the film), Services (cards with a round badge), How a visit works (a copper pipe that fills with water), Recent jobs (service tickets), Numbers (on pressure gauges whose needles sweep up), The area on a map, Guides, Guides by email (a panel of deep water that fills as it scrolls in) and Closing call (a band of deep water with a photo standing in it). With reduced motion nothing moves.
Colors and brand
Section titled “Colors and brand”src/content/singletons/brand.json (Pages → Brand in Keystatic) holds three colors: the accent
(water cyan: buttons, links, the water in drawings and marked words), the second (copper: the pipes,
numbers and the emergency service) and the third (clear aqua: highlights and small fills). The accent
and copper are darkened until white text on them is readable, aqua is lightened until dark text on it is;
a color that can’t get there stops the build with a message. Brand also sets the fonts and the corners
(rounded with pill buttons, or nearly square). The site opens on the porcelain day theme even when the
visitor’s system is dark; the toggle switches to the night, and the browser remembers the choice. The
header strip, the tab bar and the deep-water bands look the same in both.
Languages
Section titled “Languages”Flume is ready for more languages: see Languages.
The 404 page
Section titled “The 404 page”A small game, Rough-in: a wall is open between floors, with the water main on the left and three to five fixtures across it. Lay pipe bay by bay (tap or drag, or the arrow keys and Enter) so one run feeds every fixture from the main, branching where you like; a stud can’t be passed and a joist costs two bays. Then open the valve: if every fixture gets water, the wall scores 100 × the cheapest possible run ÷ yours (the cheapest run is worked out exactly for every wall). Three walls, bigger each time; 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, services, jobs and guides for AI assistants, in every language.- Pages carry JSON-LD: the business as a
Plumberwith the areas it serves and its packages, services asServices with their price, jobs asCreativeWorks, how a visit works as aHowTo, questions as aFAQPage, and each guide 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).
