A documentation site theme for Foreshock, built on Lume 3 and the theme-boilerplate (naked + reset). Dark instrument-panel aesthetic, signal-amber accent, Space Grotesk + IBM Plex Mono, an animated seismograph figure component, a data-driven sidebar, and an auto-generated on-page table of contents.
deno task serve # dev server with live reload
deno task build # production build into _site/Requires Deno. No Node, no npm.
src/
_data.yml site metas + brand strings
_data/sidebar.ts ← the sidebar (order + labels)
styles.css CSS entry (bundled by lightningcss)
index.md the "/" page (Overview)
concepts/ one folder per sidebar category
_data.yml sets category + layout for the folder
*.md
reference/ operate/ more categories, same pattern
_includes/
layouts/base.vto html shell (nav, footer, modal)
layouts/docs.vto three-column docs page
partials/ nav, footer, modal
css/ reset · foreshock (design system) · docs
js/ foreshock.js (seismograph) · docs.js (TOC)
uploads/favicon.svg
The sidebar is driven by two things, both plain data — no template edits needed.
1. Category order & labels — src/_data/sidebar.ts
export default [
{ id: "overview", label: "Overview" },
{ id: "concepts", label: "Concepts" },
{ id: "reference", label: "Reference" },
{ id: "operate", label: "Operate" },
];Reorder the array to reorder the sidebar. Rename a label to rename a
group. Add a { id, label } to add a group (then create a matching
src/<id>/ folder — see below).
2. Which page goes where — the folder + front matter
A page's category is inherited from its folder via that folder's
_data.yml:
# src/concepts/_data.yml
category: concepts
layout: layouts/docs.vto
kind: ConceptIts position inside the group comes from front matter:
---
title: Common-mode rejection
menu: Common-mode rejection # optional shorter label for the sidebar
order: 2 # position within the category
---So: move a file between folders to move it between groups; change
order to reorder within a group; edit sidebar.ts to reorder or
rename the groups themselves. A page whose category isn't in
sidebar.ts simply won't appear.
- Add
{ id: "guides", label: "Guides" }tosidebar.ts. - Create
src/guides/_data.ymlwithcategory: guidesandlayout: layouts/docs.vto. - Drop
.mdfiles insrc/guides/withorder:front matter. - (Optional) add a matching block to the loop in
_cms.ts.
Front matter fields the layout understands:
| field | purpose |
|---|---|
title |
page title + breadcrumb |
menu |
shorter label for sidebar/footer (falls back to title) |
order |
position within the category |
lead |
intro paragraph under the title |
kind |
badge in the meta row, e.g. Concept (folder default) |
readTime |
e.g. 9 min read |
updated |
e.g. 2026-05-28 |
description |
meta description / og |
Body is Markdown. Headings, code fences (syntax-highlighted via
highlight.js), lists, and blockquotes are all styled. ## headings are
auto-numbered and auto-collected into the right-hand table of contents.
These use raw HTML inside Markdown (Lume allows it):
<div class="callout">
<span class="lab">// Definition</span>
<p>A short, highlighted aside.</p>
</div>
<div class="callout callout--warn"> … </div> <!-- red / warning variant -->
<div class="figure"> <!-- animated seismograph rows -->
<div class="figure__rows">
<div class="figrow"><span class="label">CH A</span>
<canvas data-seismograph data-amp="0.7" data-density="0.05" data-cursor="false"></canvas>
</div>
</div>
<p class="figcap">FIG.1 — caption</p>
</div>Blockquotes (> …) render as pull quotes.
mod.ts exports the theme so a separate Lume site can consume it:
import foreshockDocs from "https://cdn.jsdelivr.net/gh/OWNER/REPO@tag/mod.ts";
site.use(foreshockDocs());Publish with a git tag so jsDelivr can serve it.
- Syntax highlighting uses Lume's
code_highlight(highlight.js); the theme lives indocs.cssunder the.hljs-*selectors. - The
<title>comes from themetasplugin (pagetitle). To append a site suffix, set a computed title or adjustmetasin_data.yml. - Nav "Product"/"Pricing" links point at
/#…placeholders — wire them to real pages when the marketing site lands.