A small, generic design layer for Quartz 4 sites, meant to be added as a git submodule. It owns structure, not color:
theme.scss— mobile-friendliness + layout polish (image overflow fix, denser mobile tables, full-width mobile file explorer, larger tap targets). It uses CSS variables for every color, so it composes on top of any palette.layout.ts— shared component arrangement viamakeLayout(Component)(file explorer available on mobile; graph desktop-only).palettes.ts— optional hand-rolled color palettes (default,icespire).
Colors are a separate concern. For a big catalog of ready-made looks, layer a community color theme such as
saberzero1/quartz-themeson top (see Adding colors). This repo deliberately stays color-agnostic so the same structure works under any palette.
From your Quartz repo root (the folder that contains quartz.config.ts):
git submodule add https://github.com/kastruppro/quartz-theme.git themeThis places the submodule at
theme/next toquartz.config.ts. If your Quartz root is a subfolder (e.g. these campaigns usesource/), run it from there — the relative paths below are unchanged.
1. quartz/styles/custom.scss — pull in the structure layer. Note the
../../ : custom.scss lives two levels below the Quartz root:
@use "./base.scss";
// @use "./themes"; // optional: community color theme (see below)
@use "../../theme/theme.scss"; // this repo (path is relative to custom.scss)2. quartz.layout.ts — use the shared layout:
import * as Component from "./quartz/components"
import { makeLayout } from "./theme/layout"
export const { sharedPageComponents, defaultContentPageLayout, defaultListPageLayout } =
makeLayout(Component)3. quartz.config.ts — (optional) pick a checked-in palette:
import { palettes } from "./theme/palettes"
// ...
colors: palettes.default, // or palettes.icespire, or your own inline block4. CI — make the build fetch the submodule:
- uses: actions/checkout@v4
with:
fetch-depth: 0
submodules: recursiveYou have two independent options — pick one (or neither, and just use a
quartz.config.ts colors block).
Use saberzero1/quartz-themes —
hundreds of ported Obsidian themes. It drops an _index.scss into
quartz/styles/themes/ and overrides Quartz's color variables. Prefer
dual-mode themes (light + dark) so you keep the dark-mode toggle.
Fetch a theme (run from your Quartz root):
curl -s -S https://raw.githubusercontent.com/saberzero1/quartz-themes/master/action.sh | bash -s -- nord…or in CI, before the build step:
env:
THEME_NAME: nord
# ...
- name: Fetch color theme
run: curl -s -S https://raw.githubusercontent.com/saberzero1/quartz-themes/master/action.sh | bash -s -- $THEME_NAMEThen ensure custom.scss imports it before this repo's structure layer:
@use "./base.scss";
@use "./themes"; // community colors
@use "../../theme/theme.scss"; // structure on topIcy themes that suit a wintry site: nord, iceberg, frost, northern-sky,
obsidian-nord-enhanced.
Add a palette to palettes.ts (copy icespire, change the hexes) and point
quartz.config.ts at it. No build-time fetching; fully checked in.
- Edit a file here, commit & push this repo.
- In each site that uses it:
(See
git submodule update --remote theme git add theme && git commit -m "Bump quartz-theme"
update-theme.shin the consuming monorepo for a loop over many sites.)
Want your own version instead of depending on kastruppro/quartz-theme? It's
three files + a repo:
- Create the repo with these files:
theme.scss— your structural/mobile CSS. Usevar(--...)for all colors so it stays palette-agnostic. Hard-code the800pxmobile breakpoint to match Quartz's default and avoid coupling to Quartz internals.layout.ts— exportmakeLayout(Component)returning{ sharedPageComponents, defaultContentPageLayout, defaultListPageLayout }. TakeComponentas an argument (don't import Quartz components here) so the file has no path dependency on the consuming repo.palettes.ts— (optional) exported palette objects.README.md— this guide.
gh repo create <you>/quartz-theme --public --source=. --push
- Add it as a submodule in each Quartz site and wire the three thin files exactly as in Quick start.
- Enable
submodules: recursivein each site's CI checkout. - (Optional) layer
saberzero1/quartz-themesfor colors per Adding colors.
That's the whole pattern: one source of truth for structure (submodule), colors chosen per-site (community theme or local palette), and a one-line CI change so builds fetch the submodule.