Mira Astro documentation

Colours, illustrations and photos

Switch between the clinical and holistic presets, make your own colours, use the illustrations, and replace the placeholder images with your own photos.

The two presets

Mira comes with two colour presets, both in light and dark mode and both meeting the WCAG AA contrast standard for every text and background pair:

  • Clinical (the default): calm teal with a warm sand accent.
  • Holistic: deep herbal green with a turmeric accent, on warm cream.

Choose one with palette in src/site.config.ts. A single page can use the other one with palette: holistic in its file; the demo’s second home page does this. The style guide (/style-guide/) has a switch to compare them.

How the colours work

Mira’s colours come in three layers, all in src/styles/tokens/:

File What’s in it
colors.css The colour scales, from 50 (lightest) to 950 (darkest), and what each preset uses for its primary, accent, neutral and highlight colours. It’s written by npm run palette; don’t edit it by hand.
theme.css What each colour is for: --brand (Book buttons and links), --accent, --highlight (marks, stars, “opens soon”), the treatment colours (--physio, --holistic, --massage), text, surfaces and lines, each with a light-mode and a dark-mode value. Blocks only use these names.
scale.css Type sizes, spacing, corners, shadows and page width.

Your own colours

  1. Open scripts/palette.mjs. Each colour family at the top has a hue (0–360, its position on the colour wheel) and a chroma (how vivid it is, around 0.08–0.15).
  2. Change a hue. Teal is about 200, blue 245, green 145, turmeric 70, terracotta 42, plum 330.
  3. Or point a preset at different families in presets, for example clinical: { p: 'sky', a: 'sand', n: 'stone', h: 'amber' }.
  4. Run npm run palette. It rewrites colors.css and prints the contrast of every pair the theme uses in both presets and both modes, marking any that fail.

Any online “hex to OKLCH” converter tells you your colour’s hue.

Section tones

The eight tones you can give a block (default, mist, warm, sage, sky, sunken, brand and night) are at the bottom of theme.css. They follow the preset: mist is a whisper of your primary colour, warm of your accent. brand and night are dark: everything inside them switches to its dark-mode colours.

Light and dark mode

The site follows each visitor’s system setting, and the moon button in the header lets them choose. Their choice is remembered on their device.

Illustrations

The 20 illustrations in src/assets/art/ are part of the theme, and yours to use on any site built with it. They’re drawn with the theme’s colours, not fixed ones, so they change with your preset and in dark mode, and they’re drawn into the page, so they add no image requests.

Kind Names
Treatments physio-assessment, manual-therapy, sports-physio, home-visit, herbal-heat-therapy, acupuncture, ayurvedic-massage, deep-tissue-massage
Conditions condition-lower-back-pain, condition-sciatica, condition-neck-pain, condition-knee-pain, condition-frozen-shoulder, condition-arthritis, condition-sports-injuries, condition-stress-tension
Scenes scene-clinic (tall, for heroes), scene-consultation, scene-booking, scene-room

Use them with art: in a hero (split or conditions variant), page header (simple variant) or call to action (split variant), and in condition and treatment files, which show them on cards and their page header. The style guide shows every one.

The eight condition drawings share one figure and are drawn by scripts/art-conditions.mjs. To add a condition, copy one of its lines, change the highlight, and run node scripts/art-conditions.mjs.

To draw your own, use only the theme’s colour classes (art-bg, art-1, art-2, art-3, art-fig, art-line and the others listed at the top of src/components/Art.astro) instead of hex colours, so your drawing re-colours like the rest.

Heading font

Headings use Lexend, a typeface designed to make reading easier, through Astro’s built-in Fonts API. It’s one 39 KB file served from your own site, with no requests to Google. Body text uses each device’s system font, which costs nothing to load, and starts a little larger than usual (17–18px) for easier reading.

To use a different font, install it from Fontsource:

npm install @fontsource-variable/fraunces

Then, in astro.config.mjs, change name and point src at the new font’s file in node_modules/@fontsource-variable/<font>/files/, usually the one ending latin-wght-normal.woff2.

The header and footer show a leaf icon beside your clinic’s name. To use your own logo, replace the logo-mark icon and the name after it in src/components/Header.astro (two places: the header and the phone menu) and src/components/Footer.astro with an image, for example <img src="/logo.svg" alt="Your clinic" width="140" height="40" />, and put the file in public/. Replace public/favicon.svg with your own icon too.

Photos

Photos live in src/assets/images/, and pages and content files refer to them by file name:

image: location-riverside.jpg
imageAlt: A treatment room at Riverside Clinic

Mira resizes every photo when you build, converts it to AVIF and WebP, and gives each visitor only the size their screen needs, so you can upload large, good-quality JPGs straight from your camera or phone. Where a photo is cropped into a strip or circle, imagePosition (or photoPosition for team photos) keeps the right part in view: top, center, bottom, or a value such as "50% 20%".

The placeholder images

The demo uses free-licence photos whose licence doesn’t allow passing them on, so the download replaces them with calm placeholders. They’re drawn by scripts/placeholders.mjs before every npm run dev and npm run build, but only for file names that are missing: your own photos are never touched.

Replace them in either of two ways:

  • Same names. Save your photo as src/assets/images/hero-clinic.jpg and it’s used everywhere the placeholder was.
  • New names. Add our-room.jpg and change image: in the pages that should use it.

Or use an illustration instead, with art:.

Good photo sizes

Where Shape At least
Hero (split) Tall, 4:5 1200 × 1500
Hero (overlay) and page header strip Wide, 3:2 2000 × 1333
Clinic, blog and gallery photos 3:2 or 4:3 1600 wide
Team photos Square, face near the top 800 × 800

Write imageAlt to describe what the photo shows, not who the people are.