Themes
Contents
InkStone ships with two CSS themes and a dark/light mode toggle. All styling is in plain CSS — no build step.
Theme toggle
A three-state toggle in the header cycles through System → Light → Dark → System:
| Icon | Mode | Behaviour |
|---|---|---|
| ⊙ | System | Follows prefers-color-scheme; updates live if the OS theme changes |
| ☀ | Light | Always light, regardless of OS setting |
| ☾ | Dark | Always dark, regardless of OS setting |
The preference is stored in localStorage. When no value is saved (or after selecting System), the site follows the OS prefers-color-scheme media query in real time.
The toggle works by setting a data-theme="light" or data-theme="dark" attribute on the <html> element. CSS variables handle colour differences so a single attribute 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.
Default theme for new visitors
Set default_theme in your root homepage's frontmatter to control what new visitors see before they've touched the toggle:
---
website: true
type: homepage
title: My Site
default_theme: dark # "dark" | "light" | "system" (default)
---
| Value | Behaviour |
|---|---|
dark |
Forces dark mode for new visitors |
light |
Forces light mode for new visitors |
system |
Follows the visitor's OS prefers-color-scheme (default if omitted) |
Visitors can always override with the toggle; their choice is saved in localStorage and takes precedence on return visits.
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 links wrap below the site title (no hamburger — always visible)
- Breadcrumbs stay on a single horizontal line
- 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
InkStone