Developer Reference

Fernlight — Developer & Theme Reference

Fernlight is a calm, editorial full-site-editing (FSE) block theme for writers and slow-living blogs. It ships a curated palette, a serif/sans type pairing, a consistent spacing scale, 7 style variations, and 52 inserter-enabled block patterns. This document is the technical reference for the theme and its companion plugin.

Requirements

  • WordPress 6.6 or newer
  • PHP 7.4 or newer
  • A block theme–capable environment (FSE). No page builder required.

At a glance

  • Type: Block theme (theme.json v3), full site editing.
  • Patterns: 52 inserter-enabled patterns + 8 template-only helper patterns.
  • Style variations: 7 (Sage default, plus Clay, Dusk, Ink, Sky, Warm Sand, and Dark).
  • Companion plugin: fernlight-companion — optional editorial blocks. The theme is fully functional without it.
  • CSS: Design system in theme.json + a single enqueued stylesheet; WooCommerce styles are split off and only loaded when WooCommerce is active.

File structure

fernlight/
├── style.css                 Theme header (required); design lives in theme.json + CSS
├── theme.json                Palette, type, spacing, layout (v3)
├── functions.php             Setup + conditional asset enqueue
├── readme.txt                WordPress.org readme
├── screenshot.png            1200×900
├── templates/                Block templates (index, single, archive, 404, search…)
├── parts/                    Header, footer template parts
├── patterns/                 60 PHP pattern files (52 inserter + 8 template-only)
├── styles/                   7 style-variation JSON files
├── inc/                      block-patterns.php (categories), perf-a11y.php (font preload)
└── assets/
    ├── css/                  post-styles.css (+ .min) and woocommerce.css (+ .min)
    └── fonts/                Cormorant Garamond + DM Sans (woff2)

Design tokens (theme.json)

Color — semantic roles

Fernlight uses role-named color slugs (not hue names), so every style variation can re-skin the theme by swapping the same eight roles. Default (Sage) values:

SlugDefaultRole
contrast#2C4A5APrimary text / strong foreground
muted#7A9BADSecondary text, meta, eyebrows
accent#C8D8B0Accent / highlight
surface#F4F7FARaised surface (cards, bands)
surface-2#DDE8EFSecondary surface
on-invert#FFFFFFText on inverted backgrounds
base#FFFFFFPage background
invert#2C4A5AInverted background (dark blocks)

Patterns reference these roles only (e.g. backgroundColor:"surface", textColor:"muted"), never raw hex — which is what makes a one-file variation swap re-skin the whole library.

Typography

  • Families: cormorant (Cormorant Garamond — display/headings), dm-sans (DM Sans — body and chrome).
  • Font sizes: small 0.875rem · body 1rem · medium 1.125rem · large 1.5rem · h3 1.5rem · h2 2rem · h1 3rem. Headings also use fluid clamp() sizing in several patterns.

Spacing scale

2xs 0.25rem · xs 0.5rem · s 1rem · m 1.5rem · l 2rem · xl 3rem · 2xl 5rem. Reference as var:preset|spacing|m.

Layout

contentSize 720px (the reading measure) · wideSize 1140px (wide alignment).

Style variations

Each file in styles/ is a theme.json-shaped palette that overrides the eight color roles. Switch them under Appearance → Editor → Styles.

  • Sage (default) — soft green/blue editorial calm.
  • Clay, Dusk, Ink, Sky, Warm Sand — alternate light palettes.
  • Dark — a full dark palette (base #11171B, contrast #E6EDF1, accent #9DBE9A, surfaces #1B2329 / #27323B). Because patterns use role tokens, dark mode is a selectable variation rather than a separate stylesheet.

Pattern catalog

Patterns auto-register from patterns/*.php via header comments. Categories are registered in inc/block-patterns.php:

  • fernlight-editorial — Editorial
  • fernlight-page-sections — Page sections
  • fernlight-post-parts — Post parts
  • fernlight-archive — Archive

The 52 inserter-enabled patterns group as: Heroes & headers (6), Editorial sections (13), Post building blocks (13), Newsletter & CTA (3), Post lists & archives (10), Full-page layouts (7). The 8 Inserter: no patterns (template-*) are wired into block templates (404 text, search form, no-results messages) and aren't shown in the inserter.

Full-page patterns (page-about, page-now, page-resources, page-work-with-me, page-contact, page-essay, wow-page-start-here) use templateLock:"contentOnly" so editors replace copy without breaking the layout.

Companion plugin blocks

fernlight-companion (separate, optional install) adds six editorial blocks: divider, newsletter (platform-agnostic sign-up), post-callout, post-hero, pull-quote, and related-grid. The theme never hard-depends on the plugin; patterns degrade gracefully if it is inactive.

CSS architecture

  • theme.json defines presets and block styles (the bulk of the design).
  • assets/css/post-styles.css is the single front-end stylesheet, enqueued from functions.php. It defines internal aliases (e.g. --sage: var(--wp--preset--color--accent)) over the semantic presets.
  • assets/css/woocommerce.css is only enqueued when class_exists( 'WooCommerce' ), keeping WooCommerce overrides off the global path.
  • Minified .min.css files are the production artifacts (built with lightningcss).

Accessibility

WordPress core supplies the block-theme "Skip to content" link, targeting the #fern-main landmark; the theme styles it via .skip-link and does not duplicate it. Focus states are strengthened in post-styles.css: a 3px :focus-visible outline globally, plus a tinted ring on navigation links.

Build & tooling

npm run build:css     Minify post-styles.css and woocommerce.css (lightningcss)
npm run lint          composer lint (WPCS) + stylelint
npm run lint:css      stylelint
npm run i18n          regenerate the .pot translation template
npm run package       build installable dist zips (bin/build-zip.sh)

CI (.github/workflows/quality.yml) runs PHP syntax + WPCS, stylelint, JS/JSON checks, the WordPress theme-review action, and uploads the packaged zips.

Internationalization

All user-facing strings use fernlight as the text domain. Run npm run i18n to refresh languages/fernlight.pot.