Gloss
Gloss is a site for a car detailing and ceramic coating studio: detailers, paint protection film and window tint shops, and mobile valeters. It is set in a detailing bay at night: behind every page a honeycomb of hexagon light tubes glows on the ceiling, light bars run down the walls, and strip lights’ reflections sweep across photos, cards and headlines. The home page opens on a full-bleed photo with the studio’s name set on an arc, the rating, a red “Book” button and an outlined “Call” button; further down a black bonnet under the hexagon lights is corrected as you scroll, in four photos of the same panel: swirl marks under a gliding inspection light, the polisher’s glowing edge taking them away to a tape line and then everywhere, a mirror, and finally water beading up on the coating. The demo is a fictional studio, Mirrorline Detailing.
Gloss opens in its night theme, whatever the visitor’s system prefers; the toggle switches to a white
studio, and the browser remembers the choice. It 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, work, care guides, 404 | Pages → the page’s own entry |
| Prices (vehicle sizes, price builder, packages, maintenance plan, how a detail works, booking, deposits and vouchers, questions) | Pages → Prices page |
| Visit (quote form, where the van goes, map and its ring, hours, details, questions) | Pages → Visit page |
| Services (icon, four prices, how long, what’s included, good for, questions, photo) | Content → Services |
| Work (vehicle, date, time, cost, readings, before and after photos, story) | Content → Work |
| Care guides (one can be members-only) | Content → Care guides |
| Name, phone, address, credentials, navigation, header button, profiles | Pages → Site settings |
| Buttons, labels, the phone bar, chat, emails, game texts | Content → Interface texts |
| Privacy, terms, warranty | Pages → Legal |
In headlines, words wrapped in *stars* are set in a lighter italic that a strip light’s reflection
sweeps across, as in “Swirls hide in the dark. *We don’t.*”.
Under the light
Section titled “Under the light”Home page → Under the light holds the heading, four captions (inspect, correct, refine, protect) and four photos of the same panel: swirled, half corrected with a tape line, corrected, and coated with water beads. They are revealed one after another behind the polisher’s glowing edge as you scroll, so take them from exactly the same spot (16:10, the paint in the middle). They load only after the page has, so the opening stays fast.
The hero
Section titled “The hero”Home page → Hero holds the two lines of the logotype (the first is set on an arc, the second in the accent between two rules), the rating chip (its value and label; an empty value hides it), the positioning line (the page’s title for search engines), the main button, the small line under the buttons, the running line of services and the photo. The second button always calls the phone number in Site settings. Use a wide, dark photo with space above the car; the photo sits a little low on wide screens so the car shows under the buttons.
Prices by vehicle size
Section titled “Prices by vehicle size”Prices page → Vehicle sizes holds exactly four sizes, in order (small, medium, large, XL in the demo), and every service has four prices in the same order; the first is shown as “from”. The price builder on the prices page lets visitors pick their car’s size and tick what it needs, shows each service’s price for that size and adds them up with the deposit. It works without JavaScript except for the total.
Work: before and after
Section titled “Work: before and after”Each finished car has a before and an after photo of the same view, the same size. On the cards the after photo wipes in as the card scrolls past, behind a glowing light bar; on the car’s own page a slider lets visitors compare them (drag, or the arrow keys). Readings (label and value, such as the gloss before and after) show beside the time and the cost.
Booking, payments and the maintenance plan
Section titled “Booking, payments and the maintenance plan”Booking a detail or an inspection uses Cal.com. Payments use Stripe (or Lemon Squeezy): the booking deposit and gift vouchers each get a one-time Price id (Prices page → Deposits and gift vouchers), the maintenance plans a monthly one (Prices page → Maintenance plan). Without keys, the booking shows a preview of the calendar and the payment buttons explain how to switch them on.
The map
Section titled “The map”The map is drawn from OpenStreetMap in your colors, with a
pin on your studio and a dashed ring for the area the van covers (Visit 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 studio’s coordinates in map.config.json and run pnpm map -- fetch. detail: "area" (the default in Gloss) draws the main roads, railways, water and woods of a district; make
size a little under three times your radius in each direction. 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 a detail or an inspection | Prices page, loads on click; a preview of the calendar until connected | Cal.com |
| Deposit, gift vouchers, maintenance plan | Prices page (one-time and monthly Price ids) | Stripe or Lemon Squeezy |
| Care tips by email | Home and care guides pages, with a welcome email | Supabase or Mailchimp |
| Quote form | Visit page; messages go to the email in Site settings | Resend |
| AI chat | Every page; answers about services, prices by size, packages, the plan and the area; never promises a scratch will come out | Claude or OpenAI |
| Members-only care guide | Care guides marked members-only | Clerk |
| Search | ⌘K or the search button: services, cars, guides, prices, visit | built in, or Algolia |
| Analytics | Every page; Google Analytics only after consent | Plausible, Umami, PostHog, Google Analytics |
| Photo delivery | Every photo, in production builds | Cloudinary |
Sections
Section titled “Sections”The home page is built from these sections, in any order: Hero, Services (cards with a sheen of light), Under the light (the pinned bonnet), Finished cars (before and after), How a detail works (steps under light tubes that switch on one by one), Numbers (gloss meter readouts), Where we are (the map), Care guides, Care tips by email (a strip light crosses the panel) and Closing call. With reduced motion, or in a browser without scroll-driven animations, Under the light is a still frame, the coated bonnet, with its four captions as a list, 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
(signal red: buttons, the logotype’s second line, marks), the second (ice blue: reflections, light
tubes and glints) and the third (amber: the rating stars and small badges). 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 (a high-contrast
serif with an italic for headings) and the corners.
Languages
Section titled “Languages”Gloss is ready for more languages: see Languages.
The 404 page
Section titled “The 404 page”A small game, Bead off: rain beads up on a freshly coated bonnet. Tilt it with the arrow keys, WASD, a swipe or the buttons, and every bead slides as far as it can; two beads of the same size that meet merge into a bigger one, and beads of size three or more that end up at the edge you tilted towards roll off and score their size squared. Small beads cling, and a new drop lands after every tilt. 40 tilts, or fewer if the panel fills up with no move left; 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, cars and guides for AI assistants, in every language.- Pages carry JSON-LD: the studio as an
AutomotiveBusinesswith its rating, the areas it serves and its packages and plans as offers, services asServices with a price per vehicle size, finished cars asCreativeWorks, how a detail 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).