Skip to content

Halo

Halo is a site for a digital studio: web design and development studios, branding agencies, freelancers’ studios, SEO and AI automation consultancies. It is set in black space with light as the only colour: a faint star field edge to edge, dark glass and hairline cards that catch the light at their top edge, and pills of light for buttons. On the home page a centred headline sits over the glowing rim of a huge dark planet with client marks running across it; as you scroll, the planet rises into a full eclipse, its light closes into a ring round the disc (the halo) and a few words appear inside it. The demo is a fictional remote studio, Halcyon Studio.

Halo 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, journal, 404 Pages → the page’s own entry
Pricing (packages and their deposit, care plans, always included, discovery call, questions) Pages → Pricing page
Contact (project brief choices, message form, details, questions) Pages → Contact page
Services (glyph, tags, price from, timeline, what you get, when it fits, how it runs, questions) Content → Services
Case studies (client, industry, year, services, photo, challenge, results, quote, the story) Content → Work
Journal posts (one can be members-only) Content → Journal
Name, email, address, navigation, header button, profiles Pages → Site settings
Buttons, labels, chat, emails, game texts Content → Interface texts
Privacy, terms Pages → Legal

In headlines, words wrapped in *stars* are lit: set in the italic, lighter, like the second line of the home page’s headline (“Build your digital future. *We build the website.*”).

The home page opens with the Horizon section: a badge, the headline, a lead, two buttons, the client marks (a name and one of eight neutral shapes each; never use real logos you have no rights to) and the words that appear inside the eclipse. The whole scene is CSS, played by the scroll; with reduced motion, or in a browser without scroll-driven animations, the opening stands still and the eclipse follows it as a still frame. The light takes its colour from the accent; in the light theme it becomes a warm dawn behind a pale moon.

Each case study has a 16:10 photo (a device on a desk works well), up to four results (short values such as “+148%” or “1.2 s”) and the client’s words. The photo on a card morphs into the case study’s own page when it opens. Link a case study to its services by their file names; it then shows on those services’ pages.

Up to four project packages (mark one as the popular one: it is lit by a ring of light), each with a deposit that reserves a slot, and up to four care plans billed monthly. Give each package a one-time Stripe Price id (or a Lemon Squeezy variant id) for its deposit, and each care plan a monthly recurring Price id. Without keys, the payment buttons explain how to switch them on. The discovery call (Cal.com) appears on the pricing and contact pages; without a link it shows a preview of the calendar.

The contact page asks what kind of project it is, the budget and the timeline as pills, then the name, email and a few sentences. The choices are sent above the message to the email in Site settings; edit the options under Pages → Contact page → Project brief.

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

Feature Where Service
Discovery call Pricing and contact pages, loads on click; a preview until connected Cal.com
Deposits and care plans Pricing page (one-time and monthly prices) Stripe or Lemon Squeezy
Newsletter Home and journal pages, with a welcome email Supabase or Mailchimp
Project brief Contact page; briefs go to the email in Site settings Resend
AI chat Every page, answers about services, prices, the process and past work Claude or OpenAI
Members-only posts A journal post marked members-only Clerk
Search ⌘K or the search button: services, work, journal, pricing, contact built in, or Algolia
Analytics Every page; Google Analytics only after consent Plausible, Umami, PostHog, Google Analytics
Photos from a CDN Production builds Cloudinary

The home page is built from these sections, in any order: The horizon (the opening), Services (an index; a beam sweeps the row you point at), Selected work, Process (a satellite travels an orbit through the steps as you scroll), Numbers (they count up), The team (portraits in rim light), the journal, the newsletter and the Closing call (a ring of light draws itself round the headline). Blocks come up out of a soft glow as they scroll in. With reduced motion nothing moves.

src/content/singletons/brand.json (Pages → Brand in Keystatic) holds two lights: the accent (every glow, the halo, links and marks; buttons are a near-white tint of it at night and a deep shade of it by day) and the second light (the warm dawn glow in the light theme). Every text colour is checked for contrast in both themes; a colour that can’t be made readable stops the build with a message. Brand also sets the fonts (every heading font has an italic for the lit words) and the corners. The site opens at night even when the visitor’s system is light; the toggle switches to dawn, and the browser remembers the choice.

Halo is ready for more languages: see Languages.

A small game, Slingshot: put a probe into orbit round the planet with the dashed ring. Drag forward from the launcher to set the angle and speed (or use the arrow keys or the buttons; a short dotted line shows the start of the path) and let go, press Space or Launch. Every planet pulls on the probe; it locks into orbit when it runs along the ring, and the more nearly it runs along it, the more points. Three star systems, three probes each; 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, case studies and posts for AI assistants, in every language.
  • Pages carry JSON-LD: the studio as a ProfessionalService with its packages and plans as offers, services as Services with their price, case studies as CreativeWorks, questions as a FAQPage, and each post as a BlogPosting.
Terminal window
pnpm dev # local site, editor at /keystatic
pnpm build # production build
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).