Colors & Fonts
Files: src/styles/theme.css, src/config/fonts.json, src/config/config.toml ([settings.colorScheme]) · Skill level: Beginner
A rebrand in Homio is a handful of values, not a search-and-replace. Every component uses named color tokens, so changing a token changes it everywhere, including the logo mark and the generated social cards. Homio has a light palette and a dark palette.

Where The Colors Live
Open src/styles/theme.css. The values are in two blocks:
:root { ... }: the light palette (the default):root.dark { ... }: the dark palette
Each value is a --theme-* variable. Components never use hex codes: they use Tailwind classes such as bg-sage or text-primary, which read these variables. Change a value in both blocks, and keep the variable names.
The Color Tokens
| Role | Variable | Light | Dark | Tailwind classes |
|---|---|---|---|---|
| Page background | --theme-body | #ffffff | #0e130f | bg-body |
| Cards and white surfaces | --theme-card | #ffffff | #151c16 | bg-card |
| Soft panels (reviews, blog, FAQ rows) | --theme-sage | #f2f5ee | #151c16 | bg-sage |
| Light green tint (icon circles, footer panel) | --theme-mint | #e4f3da | #1b2e1c | bg-mint |
| Soft sunflower tint (service cards, quote card) | --theme-blush | #fff6d1 | #2a2410 | bg-blush |
| Warm cream (the handyman home) | --theme-cream | #f3f1e6 | #1a1d16 | bg-cream |
| Block green (the big brand-green blocks) | --theme-deep | #24842f | #1d6b27 | bg-deep |
| Deep green (dark blocks, dark footers) | --theme-forest | #163e25 | #0b1f12 | bg-forest |
| Text green (links, icons, checks) | --theme-primary | #217b2c | #6cc576 | text-primary, bg-primary |
| Text green on hover | --theme-primary-hover | #1c6c25 | #8bd593 | text-primary-hover |
| Text on green | --theme-on-primary | #ffffff | #0e130f | text-on-primary |
| Sunflower (main pill buttons) | --theme-accent | #ffd23f | #ffd23f | bg-accent |
| Sunflower on hover | --theme-accent-hover | #f5c518 | #ffdc66 | bg-accent-hover |
| Text on sunflower | --theme-on-accent | #111511 | #111511 | text-on-accent |
| Dark gold for small accents on white | --theme-accent-strong | #7a5d00 | #ffd23f | text-accent-strong |
| Headings (ink) | --theme-dark | #111511 | #eef3ec | text-dark |
| Body text | --theme-text-default | #5a615b | #a9b5aa | text-text-default |
| Borders and dividers | --theme-border-light | #e2e8dd | #263127 | border-border-light |
| Form field borders | --theme-border-input | #7d877f | #6f7c71 | border-border-input |
| Focus ring | --theme-focus | #24842f | #6cc576 | ring-focus, outline-focus |
| States | --theme-danger, --theme-success, --theme-warning | #b42318, #217b2c, #9a5a00 | #f2726a, #6cc576, #f0b44c | text-danger, … |
--theme-light and --theme-primary-soft repeat the mint value, and --theme-sand repeats sage. Change them together with --theme-mint and --theme-sage.
Copies To Change With The Palette
A few values appear twice in theme.css. Update them with the main tokens:
--page-*variables at the end of:rootand:root.dark(--page-primary,--page-dark,--page-text, …). Cards on a colored block (a white review card on the green block) use them to get the page colors back. Keep them equal to the matching--theme-*values.- Static helpers in the
@theme inlineblock, which stay the same in light and dark mode:--color-emerald(#24842f, the brand green for white text),--color-sunflower(#ffd23f),--color-mist(#e4f3da, white button hover),--color-light(#c9d8cc, text on the deep green footers), and--color-body-dark(#111511). - The colored blocks under
@layer components:.block-deep(brand-green block),.block-forest(deep-green block), and.block-coral(the name is kept from an older version: it is the sunflower block, with ink text). They set the text and border colors used inside each block. .band-ink: the near-black band, which uses the dark palette inside it.
The #24842f green also appears in src/assets/images/favicon.svg and the two standalone logo files. Regenerate the favicon after a color change (see Site Identity & Logo).
Button Styles
Buttons in content files take their look from variant:
| You write | Button |
|---|---|
variant: "fill" | The main pill button, sunflower with ink text |
variant: "accent" | A brand-green pill with white text. One per view |
variant: "soft" | A soft tinted pill for the second action |
variant: "outline" | An outlined pill |
variant: "fill-white" | A white pill, for photos and dark bands |
variant: "text" | A text link |
Some sections change a variant to fit their background; the comment next to variant: in the section file says when. See Common Changes for every button option.
Corners
The radius tokens are in the @theme inline block of theme.css:
| Token | Value | Used for | Class |
|---|---|---|---|
--radius-btn | 9999px (a pill) | Buttons and icon buttons | rounded-btn |
--radius-field | 0.625rem (10 px) | Inputs, selects, segmented controls | rounded-field |
--radius-ui | 1.5rem (24 px) | Cards, tiles, images | rounded-ui |
--radius-panel | 2rem (32 px) | Large photos and soft panels | rounded-panel |
--radius-block | 2rem (32 px) | Color blocks and the footer panel | rounded-block |
--radius-tag | 0.375rem (6 px) | Check squares and rating squares | rounded-tag |
For square buttons, for example, set --radius-btn: 0.5rem;. Homio uses no shadows: the shadow scales are reset.
Fonts
Homio uses three fonts from Google Fonts, set in src/config/fonts.json, one entry per role:
| Font | Role | cssVariable |
|---|---|---|
| Figtree | Body text, buttons, forms | --font-primary |
| Lexend | Headings and big numbers | --font-heading |
| JetBrains Mono | Prices, totals, and ticket codes | --font-code |
{ "name": "Lexend", "variants": [{ "style": "normal", "weight": "300 600" }], "preload": true, "display": "swap", "cssVariable": "--font-heading", "provider": "google", "subsets": ["latin"], "fallback": "sans-serif"}To change a font, replace name with another Google Font name, exactly as Google writes it ("DM Sans", "Plus Jakarta Sans"). Keep cssVariable, provider, and fallback, and keep a weight range the new font has: Homio ships 300 to 600 for headings (Lexend) and 400 to 700 for body text (Figtree). Add a subset such as "latin-ext" if your language needs it. Then restart npm run dev: fonts are read only when the server starts.
Astro downloads the fonts and serves them from your own site, so visitors don’t load anything from Google.
Type Sizes
Heading sizes are fluid: they grow from phone to desktop between 375 px and 1280 px wide. They are in theme.css as --text-display, --text-h1 to --text-h6, --text-stat (big numbers), --text-lead, --text-copy (body, 16 px), --text-label (small caps labels), and --text-total / --text-total-lg (prices). Each has a --line-height, --letter-spacing, and --font-weight beside it. Headings use weight 400.
Breakpoints
sm 540 px, md 768 px, lg 1024 px, xl 1320 px. The mobile action bar shows below md; the full header menu shows from lg.
Dark Mode
[settings.colorScheme] default = "system" # system | light | dark: used until a visitor picks one switcher = true # Show the light/dark button in the header, mobile menu, and footersystemfollows the visitor’s device setting.lightordarkstarts every visitor on that palette.- The sun and moon button switches it. The visitor’s choice is remembered in their browser.
switcher = falsehides every button. Visitors then always getdefault, and an earlier choice is ignored. Useswitcher = falsewithdefault = "light"for a site without dark mode.
When you change colors, check both palettes. Photos and the sunflower buttons stay the same in dark mode.
Do It With AI
My brand colors are: green [HEX] and button color [HEX]. In src/styles/theme.css, in :root,set --theme-deep to my green, and --theme-primary and --theme-primary-hover to darker shades ofit with at least 4.5:1 contrast on #ffffff and #f2f5ee. Set --theme-accent and--theme-accent-hover to my button color, and --theme-on-accent to black or white, whichevercontrasts more. Make lighter versions for :root.dark. Update the matching --page-* values,--color-emerald, and --color-sunflower. Keep every variable name. List the values and theircontrast ratios.Change the heading font to [GOOGLE FONT] and the body font to [GOOGLE FONT] insrc/config/fonts.json. Keep the cssVariable values, the provider, and the fallback, and useweight ranges the fonts have. Don't edit CSS files. Then tell me to restart npm run dev.