Skip to content

Spark

Spark is a site for an electrician or a small electrical contractor: rewiring, fuse boards, EV chargers, lighting, solar panels and batteries, inspections and certificates, and emergency call-outs. It is drawn edge to edge like an electrical drawing: drafting paper with a fine grid by day, a navy blueprint at night, wire runs and circuit symbols at the edges, electric blue, copper and lamp amber, and a technical grotesque for headings. On the home page a house drawn as a wiring schematic runs across the whole window and, as you scroll, the main switch flips on the fuse board, current runs along the circuits and the house switches on room by room: the ground floor lights, the sockets, the bedrooms, the EV charger on the drive and the solar panels on the roof, until night falls and the whole house glows. The demo is a fictional business, Halden Electrical.

Spark 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)
Services, jobs, advice, 404 Pages → the page’s own entry
Prices (hourly rate and call-outs, packages, how a job works, booking, deposits and vouchers, questions) Pages → Prices page
Contact (quote form, areas, map and its ring, hours, details, questions) Pages → Contact page
Services (circuit symbol, price from, how long, what’s included, typical jobs, questions, photo) Content → Services
Jobs (where, when, time, cost, before and after photos, story) Content → Jobs
Advice Content → Advice
Name, phone, address, registration and insurance, 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* get a copper conductor underneath with a terminal at each end, as in “Your home, *switched on*”.

The home page’s opening names exactly five circuits, in the order the drawing switches them on: ground floor lights, the sockets, first floor lights, the EV charger and the solar panels with their battery. Change the words to your own (keep each to the same kind of circuit, since the drawing doesn’t change), the title of the circuit chart beside the headline, the meter’s label and the drawing’s title in its corner. With reduced motion, or in a browser without scroll-driven animations, the house is shown fully lit at night.

The services page lists every service like the circuit chart inside a fuse board’s door: a row each, numbered C1, C2… in their order, with the service’s symbol (lamp, socket, switch, fuse board, EV charger, solar panel, battery, meter, tester or lightning bolt), the price from and how long it takes. On the home page the featured services come first, as cards.

Each job has a before and an after photo of the same view. On the cards (home page, jobs page, a service’s page) the after photo wipes in as the card scrolls past; on the job’s own page a slider lets visitors compare them (drag, or the arrow keys). Take both photos from the same spot.

The prices page holds your hourly rate on a meter’s display with its small print (minimum, call-out, emergencies, materials), up to four fixed-price packages (mark one as the popular one), how a job works as terminals along a cable (also on the home page), booking a survey with Cal.com, and deposits and vouchers you take with Stripe or Lemon Squeezy: each one gets a one-time Price id (or a variant id). Without keys, the booking shows a preview of the calendar and the payment buttons explain how to switch them on.

The map is drawn from OpenStreetMap in your colors, with a pin on your base and a dashed ring for the area you cover (Contact page → Map → Radius, in km; 0 hides it). It is part of the page (no embed, no cookies) and follows the theme and your accent. To draw your own area, put your base’s coordinates in map.config.json and run pnpm map -- fetch. detail: "area" (the default in Spark) draws the main roads, railways, water and woods of a district; make size about three times your radius in each direction (36,000 × 16,000 m for 12 km). detail: "streets" draws the streets and buildings round one address instead.

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

Feature Where Service
Book a survey Prices page, loads on click; a preview of the calendar until connected Cal.com
Deposits and vouchers Prices page (one-time prices) Stripe or Lemon Squeezy
Advice by email Home and advice pages, with a welcome email Supabase or Mailchimp
Members-only advice Articles marked “Members only” are read 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, areas and emergencies; never talks anyone through electrical work Claude or OpenAI
Search ⌘K or the search button: services, jobs, advice, prices, contact built in, or Algolia
Analytics Every page; Google Analytics only after consent Plausible, Umami, PostHog, Google Analytics
Photos Served through Cloudinary when its cloud name is set Cloudinary

The home page is built from these sections, in any order: Switched on (the opening), Services (cards numbered like circuits that switch on as they arrive), Recent jobs (before and after), How a job works (terminals along a cable that current runs along), Numbers (on meter displays that light up), The area covered (the map), Advice, Advice by email and Closing call (a navy band where a wall switch turns on the light). With reduced motion, everything stands still and switched on.

src/content/singletons/brand.json (Pages → Brand in Keystatic) holds three colors: the accent (electric blue: buttons, live wires, marks), the second (copper: conductors and underlines) and the third (lamp amber: the light of every lamp and the highlights). 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 and the corners (square, like a drawing, or slightly rounded). The site opens in the day theme even when the visitor’s system is dark; the toggle switches to the night, a navy blueprint, and the browser remembers the choice.

Spark is ready for more languages: see Languages.

A small game, Find the fault: one connection on a circuit has come loose and everything after it is dead (the lamps at the ends show which runs are out). Test junction boxes with a tap or click (or the arrow keys and Enter) to see whether they are live, and pin the loose connection down in as few tests as you can. Each circuit scores 100 × the fewest tests that always find the fault ÷ your tests; five circuits, the last three with branches. 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/).
  • /llms.txt lists your pages, services, jobs and advice for AI assistants, in every language.
  • Pages carry JSON-LD: the business as an Electrician with the areas it serves and its packages, services as Services with their price, jobs as CreativeWorks, how a job works as a HowTo, questions as a FAQPage, and each article as a BlogPosting.
Terminal window
pnpm dev # local site, editor at /keystatic
pnpm build # production build
pnpm map -- fetch # draw the map round map.config.json from OpenStreetMap
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).