Skip to content

Terra

Terra is a site for a garden designer or landscaping company: design-and-build studios, landscapers who lay patios, plant and light gardens, landscape architects and garden maintenance crews. It is set in a garden after dark: deep slate green with the faint contour lines of a site survey, terracotta, lamp gold and moss, a soft serif and a glass pill nav. The home page opens on one back garden, photographed from the same spot and built as you scroll, with the rating, the headline, one line, Book a design visit and Call over it from the first frame. The demo is a fictional studio, Hollin & Stone.

Terra 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 (every service as a card, what every project includes, questions) Pages → Services page
A service (a page each: from price, how long, what’s included, how it goes, questions, photo) Content → Services
Gardens (every garden as a card) Pages → Projects page
A garden (a page each: before and after, the brief, the plan, plants used, facts, the story) Content → Projects
Process (the steps, book a design visit, the design deposit, questions) Pages → Process page
Care plans (monthly plans, the year of care, questions) Pages → Care plans page
Quote (what to tell us, typical budgets, the quote form, questions) Pages → Quote page
Journal Content → Journal (one guide can be members-only)
Contact (the map of the area, where you work, studio hours, message form, questions) Pages → Contact page
Name, phone, address, area covered, rating, hours, navigation, profiles Pages → Site settings
Buttons, labels, chat, emails, game texts Content → Interface texts
Privacy, terms, design and deposit terms Pages → Legal

In headlines, words wrapped in *stars* are set in italic over a string line between two pegs, the way a garden is set out on site, as in “Gardens built to *grow into*”.

The hero is the site’s signature. Four photos of the same garden 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 bare plot, with the plan set out in pegs and string. It is there from the first frame and is the page’s largest image, so it loads first.
  2. The stone: the terrace, steps and beds rise up the frame behind a glowing line like fresh mortar.
  3. The planting, spreading out from the beds behind a green-gold seam.
  4. Dusk: the sky darkens from the top down, then the garden lights come on one by one, the fire bowl flickers and specks of light drift over the borders.

A readout counts what each stage took (for example “Week 6 · 42 m² of sandstone”, “Season 1 · 380 plants”, “Dusk · 14 lights”) 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 garden at dusk, with the four stages listed under it.

To use your own garden, take four photos from a tripod (the path or the main view in the middle), or generate one and edit it into the other three so nothing moves. The positions of the lights that bloom at dusk are in the lights list at the top of src/components/sections/Hero.astro, in percent of the photo’s width and height.

Each service has a page with a from price (and a note like “for a garden up to 200 m²”), how long it takes, what’s included, how it goes and questions; search engines get it as a schema.org Service with an offer. Each garden has a page with a before-and-after slider, the brief, the plan as numbered design moves, the plants used with their botanical names, the facts and the services it took (a garden’s services link it to those services’ pages). On the cards, the plot before is wiped away to the garden after as you scroll.

Book a design visit with Cal.com (it loads on click; until it’s connected the page shows a preview of the calendar with your times). The design deposit is paid with Stripe (a one-time Price id) or Lemon Squeezy (a variant id) in Pages → Process page → Design deposit. Care plans are monthly subscriptions: a Stripe monthly Price id (or a Lemon Squeezy subscription variant id) on each plan. Without keys the buttons explain how to switch them on.

The contact page and the home section “Where we work” show a map of the area round the studio, drawn from OpenStreetMap in your colors, with a pin, a ring round the area you cover (in km, set on each), 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. List the towns and villages you cover in Site settings → Area covered.

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

Feature Where Service
Book a design visit Process page, loads on click; a preview of the calendar until connected Cal.com
Design deposit and care plans Process page (one-time) and care plans page (monthly) Stripe or Lemon Squeezy
Seasonal notes by email Home and journal pages, with a welcome email Supabase or Mailchimp
Quote requests and messages Quote and contact pages; to the email in Site settings Resend
AI chat Every page; answers about services, prices from, gardens, the process, care plans and the area; never quotes a garden without a visit Claude or OpenAI
Members-only guide Journal Clerk
Search ⌘K or the search button: services, gardens, 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, Recent gardens, Numbers (on a surveyor’s tape that pulls out as it scrolls in), How it works (the steps along a line of path lights that come on one by one), Care plans (a photo that drifts like a camera on a slider), Journal, Seasonal notes (a moss band with specks of light), Where we work (the map of the area) and Closing call (a terrace at night beside the headline, dark in both themes).

src/content/singletons/brand.json (Pages → Brand in Keystatic) holds three colors: the accent (terracotta: Book buttons, marks, string lines), the second (lamp gold: stars, small capitals, rules and the glow of the lights) and the third (moss: the favourite care plan, badges, the seasonal notes band). Buttons and moss are darkened until their white text is readable, lamp gold 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. The site opens in its dark theme even when the visitor’s system is light; the toggle switches to the day (limestone and graphite) and the browser remembers it.

Terra is ready for more languages: see Languages.

A small game, Light the path: a garden plan at night, a stone path winding through beds and hedges. Put lamps in the beds (tap a bed, or move with the arrow keys and press Enter) until every stone of the path is lit. Each lamp lights the squares round it, but not through a hedge. Use as few lamps as you can: each garden is checked first for the fewest lamps it needs, and you score 100 × that ÷ yours. Three gardens, 7×7, 8×8 and 9×9; 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, gardens and the journal for AI assistants, in every language.
  • Pages carry JSON-LD: the studio as a HomeAndConstructionBusiness (the area it serves, hours, rating), services as Services with offers, gardens as CreativeWorks, the deposit and care plans as offers, 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).