0009: Docs on the site

Status

Accepted (2026-10-06)

Context

The docs (docs/ and CONTEXT.md) were readable only in the repository, in GitHub's file view, while the site's landing page pointed there for the mapping reference and configuration. The site already parses Markdown with remark and is styled by Pico, which styles plain HTML (headings, tables, code) without classes.

Decision

scripts/write-docs.mjs renders docs/ and CONTEXT.md as site pages before every Web UI build and dev server start, into web/docs/, which web/vite.config.ts builds along with the other pages. The rendering is remark-parse and remark-gfm, as the converter reads Markdown, then remark-rehype, rehype-slug for GitHub's heading anchors, Shiki for code blocks, and rehype-stringify. docs/ keeps its layout under /docs/, a folder's README becomes its index page, and CONTEXT.md becomes /docs/context.html. A relative link to a published file goes to its page, a link to any other file of the repository to GitHub, so the Markdown links stay as they read on GitHub.

/docs/index.html is generated, not rendered from docs/README.md: it lists every published page by its first heading, a folder's pages nested under its index, so a new doc appears without editing a list. docs/README.md stays the index on GitHub.

The pages' layout is VitePress's, as binarypoetry.ch's pages are: the text keeps its reading width, 688px at 16px, as 43rem so the measure, about 90 characters, holds as Pico scales the type up with the viewport. A page's outline, its second-level headings, stays in view beside the text on a screen 1024px wide or more and marks the section being read, the one script the docs add (web/src/docsOutline.ts). From 1280px, the docs are listed on its other side, as on the index, the page itself marked; the outline comes first, being the one a reader of a page uses more. Beside them the text narrows, to about 75 and 63 characters, until 1536px: Pico's container widens more slowly than its type, and a measure that short still reads well. Beyond that, the styling is Pico's, but for a scrolling wrapper for wide tables and Shiki's bold and italic.

Code is highlighted at build time in binarypoetry.ch's Shiki themes, Light Plus with the brand colors in place of the three it replaces for contrast, and Synthwave '84, on Pico's code background. Shiki is the one highlighter with an org grammar (highlight.js and Prism have none). Its light-dark() colors follow the color-scheme Pico sets for the theme toggle, so the pages ship no highlighting script.

Every page's head boilerplate, header and footer come from one place, web/chrome.ts, which a Vite plugin fills into each page's placeholders; the docs pages use the same placeholders, and the nav gains a Docs link.

Consequences