Theme
filepress ships a default Essay theme (fonts + layout CSS in the engine). Sites can override it the CSS Zen Garden way: keep the HTML, drop in a stylesheet.
Adding an override
At the site root (next to filepress.config.ts), add:
theme.css— plain CSS (nesting OK). Created empty on firstfilepress devif missing.
If the file is empty/absent of rules, the default Essay look is unchanged.
Load order:
- Engine Essay theme (
getfilepress/@filepress/core/theme) —@layer filepress - Named preset from config
theme(essay|ink|folio) — Essay is a no-op sheet - Your
theme.css—@layer site
@layer filepress, site is declared first. Site rules win even if Vite injects Essay CSS later (dev) or splits the sheets (build). First paint inlines your theme.css (minus remote @import) in the document head so the page does not flash Essay parchment, then restyle.
You still write :root in theme.css. The engine lifts it to :root:root and wraps the sheet in @layer site. Remote @import (Google Fonts) stays outside the layer and may swap after first paint.
export default defineFilepressConfig({
title: 'My Site',
url: 'https://my.site',
theme: 'ink' // optional; default 'essay'
});
/* theme.css — retoken example */
:root {
--accent: #1e4d6b;
--accent-strong: #163a52;
}
@media (prefers-color-scheme: dark) {
:root {
--accent: #8eb6d4;
--accent-strong: #b0cce3;
}
}
/* Or restyle structure */
.post-title {
letter-spacing: -0.03em;
}
.site-header {
border-bottom: none;
}
Design tokens (public)
Set these on :root (and in a prefers-color-scheme: dark block if you care about dark mode).
| Token | Role |
|---|---|
--font-serif |
Body / reading type |
--font-sans |
UI, meta, nav |
--font-mono |
Code |
--bg |
Page background |
--surface |
Raised surfaces |
--ink |
Primary text |
--ink-soft |
Secondary text |
--ink-faint |
Tertiary / chrome |
--rule |
Hairline borders |
--rule-strong |
Stronger borders |
--accent |
Links, emphasis |
--accent-strong |
Hover / stronger accent |
--accent-wash |
Soft accent background |
--measure |
Comfortable reading width |
--measure-wide |
Layout column (header/footer) |
--gap |
Page horizontal padding |
--radius |
Small radii (buttons, tags) |
Structural classes (public)
Treat these as the stable styling API. Prefer overriding them (or tokens) over depending on incidental wrappers.
Chrome: .wrap · .site-header · .site-id · .site-title · .site-logo · .site-brand-copy · .site-wordmark · .site-tagline · .site-nav · .nav-icon · .nav-label · .has-icon · .nav-github · .site-footer · .footer-links
Nav and footerLinks entries may set icon: 'github'. Chrome renders the mark beside the label, opens the link in a new tab, and adds .has-icon / .nav-github for theme overrides (see product-site theme.css or IngotVault for a pill-style control).
Index: .hero · .hero-lede · .eyebrow · .featured · .post-list · .post-card · .post-title · .excerpt · .read-more · .card-tags · .byline · .reading-time · .draft-label · .pager · .page-count · .empty-state · .error-page · .error-code · .error-actions
The masthead carries the site identity inside one title link: optional logo image, then a .site-brand-copy stack of .site-wordmark (site title) and .site-tagline. Omit logo and FilePress uses /logo.png from static/ (a missing file is hidden). Pass logo: "" or null for a text-only masthead. The index hero shows the optional lede from site config; with no lede the hero collapses to a visually-hidden h1 that keeps semantics.
Post: .post-header · .draft-banner · .prose · .post-nav · .post-nav-label · .post-nav-title · .older · .newer
Static page: .static-page · .page-header · .prose · .draft-banner
Shared: .meta · .eyebrow · .tag-list · .newsletter · .button
Topics: .topic-group · .topic-posts · .count · .date
Prose content also uses standard elements inside .prose (h2–h4, a, img, figure, figcaption, blockquote, code, pre, table, …).
Tips
- Start with tokens; reach for class overrides only when layout needs to change.
- Keep specificity low so future engine CSS doesn’t fight you.
- Custom fonts: self-host under
static/and set--font-serif/--font-sans, or@importintheme.css(third-party font URLs affect privacy/perf).
Genie Mode (dev-only — shipped)
In filepress dev, a floating Genie control opens a design cockpit:
| Available now (M0–M2) | Notes |
|---|---|
| Token / structure steers | Accent, density, dark/light presets |
| Openverse stock + local upload | Hero / page background (and logo upload → config) |
| Version rail + activate | Gitignored .filepress-genie/; each row shows the applied look and the original prompt (click to copy); bake into theme.css / static/ |
| Live inspire (1–3 URLs) | Reuses import inspire pipeline |
| Ollama refine | Optional; host + model picker; Scan network (ollanet); streamed chat + 10m default timeout (FILEPRESS_OLLAMA_TIMEOUT_MS) |
| Config patch | lede / tagline / logo on activate |
Hand-edited theme.css remains fully supported. Genie never ships in preview or production builds. Spec: GENIE_MODE_SPEC.md. Ollama optional for the LLM path; Finetuna recommended for a tuned local model.