Colors, Fonts & Dark Mode
Files: src/styles/theme.css, src/config/fonts.json · Skill level: Beginner
A rebrand in Kivo is a handful of values, not a search-and-replace. Every component uses named color tokens, so changing a token changes it everywhere.
Brand And Surface Colors
Open src/styles/theme.css. The colors that change between light and dark mode are set twice, once per palette:
/* Light palette (default) */:root { --theme-primary: #7c3aed; --theme-primary-soft: #f3edff; --theme-accent: #f97316; --theme-danger: #dc2626; --theme-body: #ffffff; --theme-light: #f6f6f7; --theme-dark: #0d0d0d; --theme-text-default: #52525b; --theme-border-light: #e4e4e7;}
/* Dark palette: used when <html> has the `dark` class */:root.dark { --theme-primary: #9466f8; --theme-primary-soft: #1d1530; /* ...same names, dark values... */}| Token | Used for | Tailwind classes |
|---|---|---|
--theme-primary | Buttons, links, highlights, active states, the logo dot | bg-primary, text-primary, border-primary |
--theme-primary-soft | Soft tint behind badges, icons, and chips | bg-primary-soft |
--theme-accent | Secondary highlight color | bg-accent, text-accent |
--theme-danger | Outage bars and incident tags on /status/ | bg-danger, text-danger |
--theme-body | Page background | bg-body |
--theme-light | Raised surfaces: cards, code windows, hover backgrounds | bg-theme-light |
--theme-dark | Headings and strong text (near-white in dark mode) | text-dark |
--theme-text-default | Body text | text-text-default |
--theme-border-light | Borders and dividers | border-border-light |
A few fixed colors sit in the @theme block at the top of the file: --color-body-dark, --color-theme-dark, --color-light, and --color-border-dark. They are used by always-dark areas such as dark CTA bands.
Dark Mode
- Visitors switch with the sun/moon button in the header. Their choice is saved in their browser.
- Visitors who never chose get their operating system’s setting.
- The switch adds or removes the
darkclass on<html>, which swaps in the:root.darkpalette.
Blog post images can have a dark version too: add imageDark next to image in the post’s frontmatter.
To make your site dark by default or light only, the change is in code. Ask your assistant: “In src/layouts/components/global/Head.astro, make dark mode the default when the visitor has not chosen” or “Remove the theme switcher and always use the light palette.”
Fonts
Kivo uses Inter for all text and JetBrains Mono for code. Both are set in src/config/fonts.json:
{ "name": "Inter", "variants": [ { "style": "normal", "weight": "400" }, { "style": "normal", "weight": "500" }, { "style": "normal", "weight": "600" } ], "preload": true, "display": "swap", "cssVariable": "--font-primary", "provider": "google", "subsets": ["latin"], "fallback": "sans-serif"}To change the main font, replace "name" with any Google Fonts family name and keep "cssVariable": "--font-primary". List only the weights you use: every weight is an extra file to download. The font files are downloaded and served from your own site, so visitors never load them from Google.
| Field | What it does |
|---|---|
name | Font family name, exactly as it is written on the provider’s site |
variants | The styles and weights to include |
cssVariable | --font-primary for text, --font-code for code. Don’t rename these |
provider | google (default), fontsource, bunny, fontshare, or local for your own files |
preload | true loads the font earlier. Use it for the main font only |
subsets | Character sets, for example ["latin", "latin-ext"] for accented languages |
fallback | Font used while yours loads |
Type Scale
Heading sizes are calculated from two numbers at the top of theme.css:
--text-base: 1rem; /* body text size (16px) */--text-base-scale: 1.23; /* each heading level is 1.23× the one below */--text-base-sm: calc(var(--text-base) * 0.9); /* base size on small screens */Raise --text-base-scale for bigger, bolder headings, or lower it for a quieter look. h1 to h6 and the large display sizes all follow.
Breakpoints
Screen widths where the layout changes, also in theme.css:
| Name | Width |
|---|---|
sm | 540px |
md | 768px |
lg | 1024px |
xl | 1320px |
Code Block Colors
[settings.markup.codeBlocks] theme in config.toml: auto gives light code blocks in light mode and dark ones in dark mode; dark keeps them dark in both, like the homepage code window.
Do It With AI
Rebrand the colors. Primary [HEX], accent [HEX]. In src/styles/theme.css update --theme-primary,--theme-primary-soft, and --theme-accent in :root and :root.dark. Choose dark-mode values with atleast 4.5:1 contrast on the dark --theme-body, and soft tints for --theme-primary-soft. Then replaceInter with [FONT] in src/config/fonts.json, keeping the cssVariable, weights, and fallback.