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
- Open
scripts/palette.mjs. Each colour family at the top has ahue(0–360, its position on the colour wheel) and achroma(how vivid it is, around 0.08–0.15). - Change a hue. Teal is about 200, blue 245, green 145, turmeric 70, terracotta 42, plum 330.
- Or point a preset at different families in
presets, for exampleclinical: { p: 'sky', a: 'sand', n: 'stone', h: 'amber' }. - Run
npm run palette. It rewritescolors.cssand 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.
Logo
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.jpgand it’s used everywhere the placeholder was. - New names. Add
our-room.jpgand changeimage: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.