The default color scheme. "system" follows the OS (the default); set
"dark" or "light" to force one. Visitors can still toggle, and their
choice is remembered.
Theming
Brand your docs entirely from markline.json — logo, favicon, fonts, colors, and the full palette. No code to fork.
Everything visual is driven by the theme block (and a couple of topbar
fields) in your config — no component overrides required.
The config file
Markline reads markline.json, falling back to docs.json so projects
migrating from a docs.json config work unchanged.
theme in that file. Image paths (logo,
favicon) are served from your project's public/ directory.Default theme
theme.appearance"system" | "light" | "dark""theme": { "appearance": "dark" } // open in dark mode by default
Logo & favicon
The logo can be an icon + wordmark (the common docs pattern), light/dark images, or just text.
theme.logo.iconstring/logo-mark.svg).theme.logo.textstringname).theme.logo.light / theme.logo.darkstringicon is set.theme.faviconstring/favicon.svg."theme": {
"logo": { "icon": "/logo-mark.svg", "text": "acme" },
"favicon": "/favicon.svg"
}
Accent color
theme.colors.primarystringtheme.colors.primaryDarkstring"theme": { "colors": { "primary": "#4f46e5", "primaryDark": "#818cf8" } }
Using a light accent (e.g. lime or yellow)? White text on it is invisible.
Set the on-accent text color with the --c-on-brand variable (see below) — it
controls text/icons on brand-colored surfaces (buttons, badges, numbered
cards).
Full palette
For deeper theming, override any CSS custom property via
theme.cssVariables, split into light and dark. Color values are
space-separated RGB triples (e.g. 247 246 241), not hex.
light and dark if you customize the palette —
otherwise dark mode falls back to Markline's default dark.The tokens you'll reach for most:
| Token | Meaning |
|---|---|
--c-brand, --c-brand-deep | Accent + hover (also set via colors) |
--c-on-brand | Text/icon color on brand surfaces |
--c-paper, --c-paper-2 | Page and raised surface backgrounds |
--c-ink, --c-ink-soft, --c-ink-2, --c-ink-3 | Text shades |
--c-slate-0 … --c-slate-8 | Neutral scale (borders, muted text) |
"theme": {
"cssVariables": {
"light": {
"--c-paper": "247 246 241",
"--c-ink": "15 15 14",
"--c-on-brand": "15 15 14"
},
"dark": {
"--c-paper": "18 18 14",
"--c-ink": "232 231 224",
"--c-on-brand": "15 15 14"
}
}
}
Fonts
theme.font.sans / theme.font.monostringFont-family overrides. The font must be system-available or self-loaded (e.g.
via a @font-face in a stylesheet you include). Defaults to Geist.
"theme": { "font": { "sans": "Inter", "mono": "JetBrains Mono" } }
Label pill
topbar.badgestringA small bordered pill shown next to the logo — handy for a version or status
label, e.g. "docs · v1" or "beta".
Worked example
A complete warm, lime-accented theme that defaults to dark:
{
"name": "acme",
"theme": {
"appearance": "dark",
"logo": { "icon": "/mark.svg", "text": "acme" },
"favicon": "/mark.svg",
"colors": { "primary": "#D7FC50", "primaryDark": "#C2E63D" },
"cssVariables": {
"light": { "--c-on-brand": "15 15 14", "--c-paper": "247 246 241", "--c-ink": "15 15 14" },
"dark": { "--c-on-brand": "15 15 14", "--c-paper": "18 18 14", "--c-ink": "232 231 224" }
}
},
"topbar": { "badge": "docs · v1" }
}
theme values takes effect on the next markline dev reload —
no rebuild of the framework, ever.