Themes
Contents
OnyxFolio ships with two CSS themes and a dark/light mode toggle. All styling is in plain CSS — no build step.
Dark / light mode toggle
A sun/moon toggle in the header switches between dark and light mode. The preference is persisted in localStorage and restored on every page load.
The toggle works by flipping a data-theme="light" attribute on the <html> element. CSS variables handle the colour differences so a single toggle covers the entire site.
CSS file structure
| File | Description |
|---|---|
frontend/static/base.css |
All layout, typography, components. Uses CSS custom properties throughout. Obsidian palette is the default. |
frontend/static/callouts-base.css |
Callout box structure and icons — theme-agnostic. |
frontend/static/theme-obsidian.css |
Callout type colours for the Obsidian theme (dark + light). |
frontend/static/theme-omarchy.css |
Catppuccin Mocha/Latte variable overrides + callout type colours. |
frontend/static/code.css |
Code block styles: Tokyo Night Dark syntax highlighting, language labels, copy button. |
base.css + callouts-base.css are always loaded. Only one theme-*.css file is loaded at a time, selected from the frontmatter.
Selecting a theme
Site-wide theme
Add theme to your root homepage's frontmatter:
---
website: true
type: homepage
title: My Site
theme: omarchy
---
This applies the selected theme to every page on the site. If theme is not set, the site defaults to obsidian.
Per-page theme override
Any individual page can override the site theme with its own theme frontmatter field:
---
website: true
title: My Special Page
theme: omarchy
---
That page renders with the overridden theme; all other pages continue using the site-wide default.
Priority: page frontmatter → homepage frontmatter → obsidian (built-in fallback).
Creating a new theme
The CSS token architecture means a new theme only needs to declare the variables it differs from the defaults. A theme that changes nothing but the background:
/* theme-custom.css */
:root {
--bg: #2d1b33;
--bg-raised: #251528;
--banner-gradient: transparent, rgba(45,27,51,0.5), #2d1b33;
}
Place the file in frontend/static/ as theme-custom.css, then reference it in your homepage frontmatter:
theme: custom
Everything else (layout, typography, callout structure, navigation) inherits from base.css. Only the variables you declare are overridden.
CSS custom property reference
Key variables defined in base.css that themes can override:
| Variable | Purpose |
|---|---|
--bg |
Page background |
--bg-raised |
Elevated surfaces (code blocks, mermaid, transclusions) |
--bg-card |
Card / form surfaces |
--bg-stripe |
Table alternating row tint |
--bg-hover |
Row / badge hover tint |
--text |
Body text |
--text-muted |
Secondary text |
--text-dim |
Tertiary text (breadcrumbs, pagination info) |
--accent |
Links, active borders, highlights |
--site-title |
Site title colour in header |
--border |
Primary border colour |
--border-subtle |
Soft inner borders (post entries, search results) |
--h1-color … --h6-color |
Per-heading colour tokens |
--callout-base-bg |
Default callout background |
--callout-base-border |
Default callout border-left colour |
--tag-color |
Tag badge text colour |
--banner-meta-color |
Subtitle / meta text on banner images |
--inline-code-bg / --inline-code-text |
Inline code chip |
--mark-bg / --mark-fg |
==highlight== background and text |
Print stylesheet
A @media print stylesheet is included in base.html. When printing, it:
- Hides the nav, header controls, and sidebar
- Resets colours to black on white
- Appends the full URL after every link (
a[href]::after { content: " (" attr(href) ")"; })
Mobile styles
Responsive layout adjusts at 600 px viewport width:
- Nav collapses to a hamburger menu
- Listing cards stack vertically
- Font sizes scale down slightly
See also
- Code Blocks — code block syntax highlighting (Tokyo Night Dark)
- Math and Diagrams — Mermaid diagram theme adaptation