Deliver the full Wave A contract for the editorial theme (personal
essayist / independent newsletter persona).
- 49 mandatory builtin overrides in templates/overrides/editorial/,
re-skinned from the frozen builtins: hairline rules, small-caps labels,
drop caps, narrow reading measure, oxblood accent. All content fields,
provider fields, custom tags ({% img %}/{% form %}/{% signup_form %}),
hx wiring, navbar drawer JS and auth/contact form wiring preserved
verbatim; legacy button/card field reads reconciled (link/style/label,
media/text).
- 7 page templates (default, full-width, landing, article, blog-index,
contact, auth); article is the reading centrepiece with drop-cap opener,
marginalia rail and a CSS-only reading-progress underline. All set the
html.dark class and route body font through var(--font-body).
- Block rework: masthead/byline/pullquote/section_label/colophon deleted
(now overrides of navbar/post-metadata/quote/divider/footer). Persona
blocks: dropcap_intro, marginalia, reading_list, field_notes.
- 4 presets, all mode "both", book-paper light + sepia-on-charcoal dark.
- Bundled Playfair Display + Source Serif 4 (OFL, latin subset) in
assets/fonts with license record; fonts.json populated; every
font-family via var(--font-heading|body|mono, fallback).
- Themed email-safe wrapper (tables, inline styles, literal fonts).
- Master pages + seed demo site (home, about, blog with 3 essays,
contact with form + data table + row_inserted email-admins workflow,
login) in essayist voice.
- required_icon_packs=["lucide"]; RECOMMENDED_FONTS/ICONS updated.
Motion tier: CSS-first (progress underline, marginalia fade-in;
prefers-reduced-motion honored). Verified: make + ninja plugin verify +
check-safety all exit 0. Visual quality UNVERIFIED until Wave B.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2.4 KiB
Editorial — fonts
This theme bundles a Latin subset of two open-licence (SIL OFL 1.1)
serif families, so it looks correct the moment it is activated — no admin
setup required. The bundled faces are declared in fonts.json and land in
the typography picker as source=template rows.
| Slot | Bundled family | Weights / styles | Role |
|---|---|---|---|
| Heading | Playfair Display | 700 normal, 900 italic | Didone display face for the masthead wordmark and headlines |
| Body | Source Serif 4 | 400 normal, 400 italic | Long-read body type; italic for marginalia and captions |
The bundled woff2 files and their licence record live in assets/fonts/
(OFL.txt). Every font-family in the theme is routed through
var(--font-heading, ...), var(--font-body, ...) and var(--font-mono, ...)
with a fallback stack, so the layout is usable before any font is assigned
and the admin font picker stays in full control.
Assigning the bundled faces
- In the BlockNinja admin, open Settings → Theme → Typography.
- In the Bundled tab, assign Playfair Display to the Heading slot.
- Assign Source Serif 4 to the Body slot.
- Leave Mono as the system default, or assign JetBrains Mono from the Google Fonts tab — it is used for the masthead kicker, datelines and the colophon ISSN.
Optional upgrades (Google Fonts tab)
- Spectral (
google:Spectral) — a refined small-caps serif. Assign it to the body slot if you want the small-caps section labels to carry true small-caps rather than the synthesizedfont-variant: small-capsfallback. - Newsreader (
google:Newsreader) — an alternative reading serif for the body slot; swaps in without any CSS change viavar(--font-body). - JetBrains Mono (
google:JetBrains Mono) — for the Mono slot (kicker / dateline / ISSN).
Bundling a commercial display face (out of scope for Wave A)
If the brand locks in a licensed display face (e.g. Migra or PP Editorial
New) in place of Playfair Display, licence and subset the woff2 set, drop it
in assets/fonts/, and add the family + variants to fonts.json. The CSS
does not change — the same var(--font-heading) consumer picks up whichever
face an admin assigns.