Richdoc is a small framework for documents written by an agent and read by a person in a browser. This page exercises every tag in the vocabulary the way a real document should — read top-to-bottom, with occasional asides dropping down to a Notes section at the foot of the page.
Every richdoc ships with a floating preview picker in the bottom-right corner. Open it to switch between the two themes (Editorial / Graphite), three modes (Light / Dark / Auto), and four page widths (Narrow / Standard / Wide / Full). Your choices persist per file. Suppress the picker with <rd-page prefs="off">.
Squeeze the page to Narrow in a wide browser to see the multi-column layouts, stat tiles, and TOC adapt to the chosen content width — responsiveness is driven by container queries on rd-page, not the viewport.
The look is intentionally editorial: warm paper, Fraunces display, Geist body, hairlines instead of cards, oldstyle figures, and the occasional pull-quote.
Five callout types, each with a Lucide icon and tracked small-caps title. They are quieter than the old filled blocks — a tinted background and a 2 px left rule do the work.
rd-cols collapses to a single column under ~720 px. Do not put more than four columns or content becomes unreadable on tablets.
rd-* tags. The linter fails and the rendered doc shows empty boxes.
Use rd-cols for genuinely parallel content. Cards are the natural child. Each accent value lights up a top rule and a coloured kicker label so the card reads typographically, not as a tinted block.
Neutral context, links, references.
Positive outcomes, recommendations.
Things to watch out for, fragile areas.
Hard blockers, breaking changes.
templateSet template on rd-cols for a CSS-Grid string that defines arbitrary column ratios. Below 720 px it still collapses to one column.
Use the wide column for the primary thought. Use the narrow column for a related card, a quote, or a small comparison.
This pattern is editorial-native: think of it as a body column with a sidebar.
Muted cards are for asides, footnotes, or quiet credits. No border; italic by default.
Use rd-stat for dashboard tiles. The numeral is set in Fraunces at optical size 144 with tabular figures, sitting under a hairline rule — confident, not boxy.
Pull-quotes use the native <blockquote> element — styled by richdoc.css with an oversized opening glyph, Fraunces italic, and small-caps attribution via <cite> or <footer>.
Instead of imagining that our main task is to instruct a computer what to do, let us concentrate rather on explaining to human beings what we want a computer to do.
Donald Knuth — Literate Programming, 1984
For decision matrices. Tones get a coloured dot prefix and a low-opacity stripe — readable in print, distinctive on screen.
Use rd-kv for short status blocks at the top of a doc. No outer box, just hairlines.
Code lives in rd-code. The bar at the top shows the language as a tracked small-caps kicker and an optional title in Fraunces italic. Syntax highlighting loads on demand from highlight.js and is themed against the editorial palette — no third-party stylesheet.
rd-diff renders a unified diff with additions and deletions colour-coded. If lang is set, the line bodies are syntax-highlighted by the same engine that powers rd-code.
Use rd-math for KaTeX-rendered formulas. Block display by default; pass display="inline" for inline use, e.g. the relation
Inline SVG glyphs from the full Lucide library (~1,900 names at the pinned lucide-static version). A core set ships inline in richdoc.js; everything else is lazy-loaded from jsDelivr on first reference and cached. Run richdoc components --tag rd-icon for the authoritative list.
Sizes:
Tabbed content for the same idea expressed three ways. First tab is active; arrow keys navigate.
Tabs are good for the same content rendered three ways: language variants, before/after, examples by stack.
They are not for hiding important decisions — humans scanning the doc will miss whatever isn't on the active tab.
Sequenced events: release history, project milestones, incident postmortems. Dates in tracked small-caps, titles in Fraunces italic, the rule is dotted.
rd-icon, rd-math, rd-diff, glossary support via rd-kv layout="stacked");
rd-code upgraded with syntax highlighting and line numbers.
richdoc site for static collections with sidebar nav and search.
One element, ~25 diagram languages. Source is sent to a Kroki-compatible endpoint (default kroki.io) and the rendered SVG embeds inline. Set endpoint per-element or <rd-page diagram-endpoint="…"> for the whole doc; for sensitive content point at a self-hosted Kroki. Hover any diagram and click the corner maximize button for the fullscreen pan/zoom viewer (0 fit, 1 reset, arrow keys pan, Esc close).
Wrap an image, SVG, or diagram with a centred caption. The caption is set in Fraunces italic with a "Fig." kicker in the accent colour.
Use rd-detail for content that is relevant but not on the main path — appendices, full error logs, derivations. Native <details> under the hood, so it works without JS and remains keyboard-accessible.
Free-form HTML lets agents drift. One doc invents <callout>, the next uses <note>, the third leaves it as bold-italic prose. The reader experience fragments and the agent has no way to verify their output.
A closed vocabulary plus a validator makes both ends of the loop reliable: the agent always knows what is allowed, and the reader always sees the same components.
Pass the open attribute to start expanded.
For action items with optional assignee and due date. Hairline-separated rows, ticks in display face when complete.
Inline status pills, prefixed with a coloured dot:
Use rd-kv layout="stacked" for a definition list. Terms are set in Fraunces italic, the block is bracketed by hairline rules, rows separated by dotted lines.
rd-* custom elements.72, 144) for display.Use <rd-callout type="tldr"> as the first block after the hero. It's a focal summary band with an oversized eyebrow and slightly larger body type than the surrounding prose. See the very top of this page.
Use rd-hero instead of an ad-hoc <h1> + rd-kv opener. It coordinates eyebrow, title, lede, and meta into one display block, and accepts any inline children (e.g. an rd-kv) as an "extras" strip below the meta line. The top of this page demonstrates the full structure.
Doc-status ribbons sit at the top of the page. Five types:
Linear progress / capacity bar. Accepts a 0..1 decimal, N%, or N/M fraction. The fill animates from 0 to the target on entry.
Numbered procedural steps with a rich body per step. Use this for runbooks, onboarding flows, migration guides. Distinct from rd-timeline (dated history) and rd-checklist (task tracking).
Run richdoc init docs once in the directory that will hold your .html file.
Pick a template: richdoc new docs/plan.html -t plan.
Use only the rd-* tags from the vocabulary. Plain HTML is welcome inside any block.
Run richdoc lint docs/plan.html. Linting cleanly is part of "done".
Two-column ✓/✗ grid for decision documents. Distinct from rd-compare — that's a matrix; this is one-sided evaluation of a single option.
ADR-style decision header + rationale. Four statuses control the left rule colour and the status pill.
Bundle size is not a concern for documentation artefacts. Plot's grammar-of-graphics defaults match the editorial voice better than anything we'd hand-roll, and one library covers every chart type plus sparklines.
A floating-gutter sidenote (rd-margin) was prototyped but rejected: the page column is centred at 1280px with no reserved gutter, so the negative-margin float overflowed off-screen on 1024–1500px viewports — the exact range the wide-mode media query targeted. rd-cite with rd-ref already covers the related authoring case on every viewport.
Superseded by ADR-014.
Too much per-chart code; Plot covers the same surface with a much smaller author API.
Dated reverse-chron entries for changelogs, release notes, status reports. The kind glyph and tint differ between release / change / note.
Expanded the framework's structural vocabulary — hero, banner, progress, steps, pros/cons, decision records, updates, terminal sessions, API blocks, and rubrics all landed in one release.
Introduced Decision & planning and Reference groupings in the schema registry. Mirrored in the SKILL.md tag tables.
The 20-component plan was reviewed and accepted. Implementation phases queued.
Question/answer disclosure uses rd-detail variant="question" — questions render in display Fraunces, answers in body Inter, with hairline separators between entries.
Use Markdown where the renderer might be anything (GitHub, chat, CLI). For documents read in a browser, richdoc gives a much richer presentation with no extra effort.
No — the linter will reject unknown rd-* tags. The fixed vocabulary is the point. Extensions ship through a new release.
Yes. The two shipped assets (richdoc.css, richdoc.js) work over file://. Components that need a CDN library (mermaid, KaTeX, charts) degrade to a readable fallback when offline.
Terminal transcripts for runbooks and tutorials. Distinct from rd-code — no syntax highlighting, no copy button, just prompt → output.
Single-endpoint reference block. Method pill is coloured per HTTP verb; status pills tint themselves based on the 2xx/4xx/5xx class.
{ ok, issues[] }.issues[] contains details.Weighted scoring grid for comparison documents — like rd-compare but with numeric scores, weights, and an automatic totals row. The winning column highlights.
Bibliography support follows the footnote pattern but with square-bracketed numbers and a separate collector. Authors write rd-cite markers inlinerd-ref entries anywhere in the doc
Multiple cites to the same key share a number
SVG charts via Observable Plot, lazy-loaded from jsDelivr on first use. Six kinds out of the box. If Plot can't load (offline, blocked CDN), each chart falls back to a clean table of the underlying data.
Tiny inline trends share the chart engine via <rd-chart variant="sparkline"> — stripped of axes, titles, legends. They render in tables, in prose, or inside rd-stat. Latency last 30 days:
Spoilers use rd-detail variant="reveal" — content hides behind an eye-icon button until the reader is ready. Useful for runbook solutions, exam answers, or any "think before you peek" pattern.
The same component can also wrap multiple paragraphs, callouts, or even code blocks — anything that should not be eye-deep on first read.
You can still use everyday semantic HTML inside any component or directly inside rd-page:
code, and links all work.<ul> lists pick up an en-dash bullet."The best documentation is the kind you actually read." — anonymous
Horizontal rules separate sections of free-form prose where rd-section would feel heavy.