Skip to content

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.

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.*”.

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.

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 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.

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 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.

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

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.

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.

Gloss is ready for more languages: see Languages.

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.

  • 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, cars and guides for AI assistants, in every language.
  • Pages carry JSON-LD: the studio as an AutomotiveBusiness with its rating, the areas it serves and its packages and plans as offers, services as Services with a price per vehicle size, finished cars as CreativeWorks, how a detail works as a HowTo, questions as a FAQPage, and each guide 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).