Skip to content

Forma

Forma is a site for an architecture and interior design studio: residential architects, interior designers, design-and-build firms. It is set on a drawing sheet: graphite (or white drafting paper in the light theme) with a fine drafting grid and crop marks, black, white and concrete with one precise accent, a grotesque for headings and a drafting mono for labels and dimensions. The home page opens on one site, photographed from the same spot and built as you scroll, with the rating, the headline, one line, Start a project and See our work over it from the first frame. The demo is a fictional studio, Pell Varga Architects.

Forma 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)
Projects (every project as a card, a filter by type) Pages → Projects page
A project (a page each: before and after, the brief, the site, design moves, a drawing, materials, credits, award, the story) Content → Projects
Services (every service as a row with its fee, what every project includes, questions) Pages → Services page
A service (a page each: fee, how long, what’s included, the stages and their share of the fee, questions, photo) Content → Services
Process (the stages, book an initial consultation, the feasibility study, questions) Pages → Process page
Studio (principles, the team, awards and press, questions) Pages → Studio page
Journal Content → Journal (one note can be members-only)
Contact (the enquiry form, the map, studio hours, visiting, questions) Pages → Contact page
Name, phone, address, rating, hours, navigation, profiles Pages → Site settings
Buttons, labels, chat, emails, game texts Content → Interface texts
Privacy, terms, terms of appointment Pages → Legal

In headlines, words wrapped in *stars* are underlined with a dimension line (a thin accent line between two ticks), as in “Houses drawn from *the ground up*”.

The hero is the site’s signature. Four photos of the same site from exactly the same spot (Pages → Home page → Hero → Photos) are revealed one after another as you scroll while the screen stays put:

  1. The empty site, pegged out with a string line, with the plan drawn over it in fine lines: the house’s outline, grid lines and a dimension. It is there from the first frame and is the page’s largest image, so it loads first.
  2. The structure: concrete walls and a timber frame, revealed behind a laser level’s line sweeping across, in morning mist with dust in the light.
  3. The finished house by day, brought in by a raking band of sunlight.
  4. Blue hour: the light goes, the glass comes on panel by panel, the downlights wash the walls and the pool picks up the reflections.

A readout counts what each stage took (for example “Sketch · week 1”, “Structure · 186 m²”, “Complete · EPC A · 64 weeks on site”, “Lived in”) and the captions follow in a glass card with a progress line; write your own in the hero’s four stages. The later photos load after the page has loaded, so they never slow it down. With reduced motion, or in a browser without scroll-driven animations, the hero is one still: the house at blue hour, with the four stages listed under it.

To use your own house, take four photos from a tripod (the house in the middle), or generate one and edit it into the other three so nothing moves. The plan drawn over the first photo and the places where the glass and downlights light up are drawn for the demo house: change panels, downlights and the plan at the top of src/components/sections/Hero.astro, or switch the plan off in the hero’s settings.

Each project has a type (new build, extension, interior, conversion, or your own): the projects page filters by it without any JavaScript. A project’s page has a before-and-after slider, the brief and the site, the design moves, one drawing (a plan or a section, shown on white in both themes), the story, the materials, the credits and an award; search engines get it as a schema.org CreativeWork. On the cards, the site before is wiped away to the building after behind a laser line as you scroll.

Each service has a page with its fee (a percentage of the build cost or a fixed fee, and a note), how long it takes, what’s included, its stages with their share of the fee and questions; search engines get it as a Service with an offer. The process page lists the stages of a project (the RIBA plan of work, grouped into six) with when, the fee and what happens.

Book an initial consultation with Cal.com (it loads on click; until it’s connected the page shows a preview of the calendar with your times). The feasibility study is paid with Stripe (a one-time Price id) or Lemon Squeezy (a variant id) in Pages → Process page → Feasibility study. Without keys the buttons explain how to switch them on.

The contact page’s enquiry form asks for a name, email, an optional phone, the kind of project, a build budget and when, each picked from a short list you set in Pages → Contact page → Enquiry form, and a message. The choices are written above the message in the email you receive (Resend, to the email in Site settings).

The contact page and the home section “Visit the studio” show a map of the streets round the studio, drawn from OpenStreetMap in your colors, with a pin, your address and directions links. It is part of the page (no embed, no cookies) and follows the theme and your accent. To draw your own, put your coordinates in map.config.json and run pnpm map -- fetch.

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

Feature Where Service
Book an initial consultation Process page, loads on click; a preview of the calendar until connected Cal.com
Feasibility study Process page (one-time payment) Stripe or Lemon Squeezy
Newsletter Home and journal pages, with a welcome email Supabase or Mailchimp
Enquiries Contact page; to the email in Site settings Resend
AI chat Every page; answers about services, fees, projects, the stages and the studio; never promises planning permission Claude or OpenAI
Members-only note Journal Clerk
Search ⌘K or the search button: projects, services, pages, journal built in, or Algolia
Analytics Every page; Google Analytics only after consent Plausible, Umami, Google Analytics, PostHog
Photos Production builds Cloudinary (optional)

The home page is built from these sections, in any order: Hero, Services (a register, one row per service), Selected projects (two to a row, the second column set lower), Numbers (along a dimension chain that measures out), How we work (the stages as bays of a building section, their columns standing up as they scroll in), The studio (a photo drifting like a camera on a track, the text on an overlapping sheet), Journal, Newsletter (a blueprint band), Visit the studio (the map) and Closing call (a photo with a slot of sun moving across it, dark in both themes).

src/content/singletons/brand.json (Pages → Brand in Keystatic) holds three colors: the accent (signal orange: buttons, marks, dimension lines and the hero’s laser line), the second (concrete: small capitals, rules, readouts) and the third (blue hour: the members badge and the newsletter’s blueprint band). Buttons and the third color are darkened until their white text is readable, concrete is adjusted for each theme; a color that can’t get there stops the build with a message. Brand also sets the fonts and the corners (square by default, or softly rounded). The site opens in its dark theme even when the visitor’s system is light; the toggle switches to drafting paper and ink and the browser remembers it.

Forma is ready for more languages: see Languages.

A small game, Load path: a building drawn in section, its floor slabs stacked, the upper ones shorter, offset or cantilevered. Put columns under the slabs (tap a grid line, or move with the arrow keys and press Enter), then run the load test (the button or T). It stands when every column stands on a column below it down to the foundation, no span or cantilever is longer than its slab allows (less under a heavy load, a roof garden or a library) and nothing stands in a hatched zone. A failed test shows what sags. Each building is solved first for the fewest columns it needs, and you score 100 × that ÷ yours. Three buildings; 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, projects, services and the journal for AI assistants, in every language.
  • Pages carry JSON-LD: the studio as a ProfessionalService (hours, rating, team and awards), services as Services with offers, projects as CreativeWorks with their awards and materials, the feasibility study as an offer, questions as a FAQPage, and each journal post 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).