Clew Manual

Extending Clew

Theming and CSS snippets

Clew ships with a dark theme and a light one, and every colour in both is a CSS custom property — one token set, two value sets. That makes theme switching instant, and it makes restyling the app a matter of overriding variables rather than fighting selectors. This chapter covers switching themes, what the themes reach (the whole app and rendered notes), the custom-property surface itself, and CSS snippets: per-vault stylesheets that travel with the vault.

Switching themes

Three routes to the same switch:

The theme is an app-global setting — it is stored with Clew's other application settings, not per vault, so every vault you open shares it.

The Math and Theorems demo note open in Clew's light theme, with the same layout and panels as the dark screenshots elsewhere in the manual
The demo vault's Math and Theorems note in the light theme. Chrome, panels, and the rendered preview all follow the switch.

What theming covers

A theme switch is not cosmetic trim around the edges; it propagates through all three layers of the interface:

Two special cases inside rendered notes are worth knowing. Mermaid diagrams genuinely re-render on a theme switch: the preview keeps each diagram's source, re-initializes mermaid with its dark or default (light) theme, and redraws — so diagram text and lines follow the app rather than being baked into one look. Code highlighting does not switch: syntax colours in fenced code blocks come from highlight.js's Atom One Dark scheme in both themes (the block's background does follow the theme). Interactive maps adapt too — in the dark theme, map tiles are filtered to match unless a map opts out.

The typeface is part of the theme as well, and it is the same in both: notes are set in Avenir Next, in the editor and on the rendered page alike. Avenir Next ships with macOS and cannot be bundled, so on other platforms the stack falls through to a humanist neighbour — Avenir, then Segoe UI on Windows, Cantarell on GNOME, then the system font — rather than dropping to a bare sans-serif. The editor reads it from --clew-editor-font, so a CSS snippet can put your own face there; the rendered page has its own copy of the same stack, and changing that is a vault script's job (see below). A figure can be set in the same face, with font=note — see Diagrams.

The theming surface: custom properties

Both themes are defined in one place each: styles/themes/dark.css and styles/themes/light.css in Clew's source, each a single rule on body[data-theme='dark'] or body[data-theme='light'] assigning the full token set. The important groups, with representative names:

GroupTokens (representative)Control
Surfaces--clew-bg-primary, --clew-bg-secondary, --clew-bg-tertiary, --clew-borderWindow, panel, and control backgrounds; every border
Text--clew-text-normal, --clew-text-muted, --clew-text-faintThe three text emphasis levels used everywhere
Accent--clew-accent, --clew-accent-hover, --clew-selection, --clew-active-itemThe purple: active states, selection, links in chrome
Feedback--clew-danger, --clew-search-match, --clew-search-match-selectedDestructive affordances and search highlights
Editor content--clew-heading, --clew-formatting, --clew-link, --clew-code, --clew-quoteSource-mode tinting
Canvas--clew-canvas-bg, --clew-canvas-node-bg, --clew-canvas-edge, --clew-canvas-ink, --clew-canvas-1 … --clew-canvas-6The canvas surface and its six named node/stroke colours
Typography--clew-ui-font, --clew-editor-font, --clew-mono-font, --clew-editor-font-size, --clew-editor-line-widthFont stacks and editor metrics

The last two tokens are also settings: Settings → Appearance's Editor font size and Editor line width write --clew-editor-font-size and --clew-editor-line-width directly, which is why they apply without a restart. The same mechanism is available to you — any token can be overridden from a snippet.

CSS snippets

Snippets are Clew's user-CSS mechanism, and the mechanism is a folder: drop .css files into .clew/snippets/ inside the vault, and every one of them is injected into the app window when the vault opens. There is no manifest and no enable switch — a file present in the folder is active, a file removed is gone. Because snippets live in the vault's own .clew/ folder, they travel with it: clone a shared vault and you get its look along with its notes.

The canonical first snippet overrides the accent colour:

You write (.clew/snippets/accent.css)

/* A calmer blue accent in the dark theme. */
body[data-theme='dark'] {
	--clew-accent: #4a9ed8;
	--clew-accent-hover: #6cb4e4;
}

Scoping the rule to body[data-theme='dark'] keeps the light theme untouched; scope to body[data-theme='light'] for the reverse, or plain body for both. And snippets are not limited to variables — they are ordinary CSS, loaded after Clew's own stylesheets, so they can restyle any part of the chrome, the panels, or the editor.

Caution Snippets are read when the vault opens: after editing one, reopen the vault to see the change. And a snippet is arbitrary CSS with the last word — a bad selector can hide the tab bar or collapse the sidebar. If a snippet leaves the app unusable, remove (or rename) the file in .clew/snippets/ with any file manager and reopen the vault; nothing else is affected.

Styling the app versus styling rendered notes

One boundary matters when you start theming in earnest: snippets style the app window — chrome, panels, editor, canvas. A rendered note is a separate document (reading mode runs in its own preview frame), so app snippets do not reach inside it. Its look comes from the engine's own styles plus Clew's preview stylesheet, keyed to the same theme switch via the frame's data-theme attribute and the --preview-* tokens.

To add styling inside every rendered note, use the JS twin of the snippets convention: vault scripts. Files in .clew/scripts/*.js are loaded into every rendered note, and a one-line script that appends a <style> element restyles all previews:

You write (.clew/scripts/preview-style.js)

document.head.insertAdjacentHTML('beforeend', `<style>
	blockquote { font-style: italic; }
	h1, h2 { letter-spacing: -0.01em; }
</style>`);

A vault plugin with a preview surface can do the same with more structure. For per-note styling rather than per-vault, a note can of course carry its own <style> element — see How rendering works.

Tip When hunting for the right token or selector to override, open the developer tools (View → Toggle Developer Tools) and inspect the element — every colour you see resolves to a --clew-* variable, and the inspector shows which.
Obsidian compatibility Obsidian's themes and CSS snippets live in .obsidian/snippets/ and target Obsidian's own class names and variables — they have no effect on Clew, and Clew's snippets in .clew/snippets/ have no effect on Obsidian. The two styling systems coexist in one vault without interference. Notes themselves are untouched by any of this: theming never writes to your files.

Reference

WhatWhereNotes
Theme settingSettings → Appearance → Theme; View → Appearance; palette commandsApp-global; dark is the default
Theme definitionsstyles/themes/dark.css, styles/themes/light.css (Clew source)One rule each on body[data-theme]; identical token sets
App theming surface--clew-* custom propertiesSurfaces, text, accent, editor content, canvas, typography
Preview theming surface--preview-* custom properties on the preview documentFollows the app theme via data-theme
CSS snippets<vault>/.clew/snippets/*.cssAll files load at vault open; no manifest; app window only
Preview styling<vault>/.clew/scripts/*.js, or a plugin preview surfaceScripts load into every rendered note
Mermaid diagramsRe-rendered on theme switchDark theme in dark mode, default in light
Code highlightinghighlight.js Atom One DarkFixed scheme in both themes; block background follows the theme
Editor metricsSettings → AppearanceFont size and line width write the corresponding tokens live

See also