Themes
How color themes work, and how to add your own using Material Theme Builder.
The example site ships four themes: Light and Dark (the defaults, a cool blue that matches the Bora logo), plus Green Light and Green Dark. Switch the active family with the toggle in the topbar, and pick any specific theme from the settings drawer. Your choice persists across visits and carries from the homepage into the docs.
How it works
- Each theme is one CSS file at
static/docs/css/theme-<id>.css. It holds the Material color variables, scoped under[data-theme="<id>"]. site.jsonregisters each theme. Switching themes only changes thedata-themeattribute on the<html>element, and the matching file supplies the colors.- Only the default theme in each family loads up front (one light, one dark). Other variants load the first time someone picks them. A returning visitor’s saved choice is applied before the first paint, so there is no flash and nothing extra is downloaded.
"themes": [
{ "id": "light", "label": "Light", "dark": false, "default": true },
{ "id": "dark", "label": "Dark", "dark": true, "default": true },
{ "id": "light-green", "label": "Green Light", "dark": false, "default": false },
{ "id": "dark-green", "label": "Green Dark", "dark": true, "default": false }
]The dark field groups a theme into the light or dark family. The topbar toggle switches between the two families’ defaults. The settings drawer lists every registered theme.
Important
A dark theme’s
idmust start withdark. The dark code-block palette and the dark treatments of UI elements (admonitions, badges, version banners) apply to any[data-theme^="dark"], so name dark themes likedark,dark-oceanordark-green. Light themes have no prefix requirement. Thedark: trueflag and thedarkid prefix do two different jobs: the flag groups the theme for the toggle, and the prefix switches the code and component styling to their dark form.
Adding your own theme
-
Generate the palette with Material Theme Builder. Pick your brand color and export as Web (CSS). The export gives you a light block and a dark block, each wrapped in a class such as
.lightor.dark. -
Re-scope each block to the attribute the theme reads. Replace the exported class selector with
[data-theme="<id>"], and give the dark block an id that starts withdark. The variables themselves do not change.[data-theme="ocean"] { --md-sys-color-primary: rgb(0 101 142); --md-sys-color-on-primary: rgb(255 255 255); /* the rest of the exported variables, unchanged */ } -
Save each block as its own file at
static/docs/css/theme-<id>.css, for exampletheme-ocean.cssandtheme-dark-ocean.css. Your site’sstatic/folder merges with the theme’s, so you do not need to fork anything. -
Register the themes in
site.json:{ "id": "ocean", "label": "Ocean", "dark": false, "default": false }, { "id": "dark-ocean", "label": "Ocean Dark", "dark": true, "default": false }
Each theme then appears in the settings drawer and loads the first time it is picked. To make one the family default, set "default": true on it and remove that flag from the theme it replaces.
Tip
High-contrast and brand variants work the same way. Material Theme Builder can export them all at once. Each one is a single file plus a single line in the registry.
Related knobs
themeColorin site.json tints the browser UI per scheme (reference).- Code block colors come from
theme-syntax.css(Chroma classes). Override it from your site’sstatic/the same way. - Warning accents (admonitions, banners) default to amber. Override with
--nti-color-warninginside your theme file.