The demo document got worse, so we made it the test
A demo that shows three features tells you three things work. The one that shipped yesterday had quietly shrunk to a welcome note — and building a real one immediately exposed four features the renderer had been silently dropping, including citations, which vanished entirely.
Why Care?
The operator asked why the markdown sample had lost features. It had — and worse than reported. When the workspace landed, the app started opening a new content/welcome.md that was three paragraphs of welcome text. The feature-rich sample was still on disk as SAMPLE.ts, no longer imported by anything.
A demo is a claim about what works. Shrinking it does not just look bad; it removes the only surface where a person sees the whole product at once.
So the demo was rebuilt to exercise everything — and rebuilding it immediately found four features the renderer had been silently dropping.
What the demo found
Every one of these rendered something, which is exactly why 29 passing assertions never caught them.
Citations vanished entirely. lfm consumes footnoteDefinition nodes out of the tree and attaches them to tree.data.citations, leaving a bare footnoteReference behind. That node has no children and no value — so the renderer’s fallback branch produced nothing at all. A claim’s source disappeared with no trace.
hProperties were being thrown away. lfm computes presentational classes and hangs them on node.data.hProperties. The renderer read them for headings and callouts and ignored them everywhere else, so $$ Eyebrow produced a bare <p> with its eyebrow class discarded. Reading them rather than recomputing is the same discipline already applied to heading ids: one place decides, the render layer obeys.
Heading blocks were three loose elements. $$ eyebrow / ## heading / && subheading is a heading-block container directive that should be an <hgroup>. It fell through the unregistered-directive branch and rendered its children with no grouping.
Task lists lost their state. listItem.checked was ignored, so - [x] and - [ ] were identical bullets.
The demo is now a fixture
workspace/content/welcome.md is what a person sees on first launch, so a feature that stops rendering is a first-impression bug. The test suite now renders the real file — not a copy — and asserts 28 named features plus the nesting case:
✓ the demo document renders every feature it claims (30 tests)
heading block (hgroup) · eyebrow class from hProperties · citation marker
sources bibliography · callout warning tone · unknown callout type keeps its
type · table centre alignment · task list checked · …
The demo cannot drift away from what the renderer supports, because drifting turns the suite red. 69 assertions total, up from 29.
Two things the demo taught us about our own syntax
Writing it surfaced a mistake worth recording rather than quietly fixing. ::badge{…} was written inline, mid-sentence. A :: leaf directive is block-level in remark-directive and must own its line; inline needs the single-colon text form. The demo now demonstrates each in its valid position, which is more useful than the version that silently rendered nothing.
Second: an orphan [^missing] with no definition is not a footnoteReference at all. remark-gfm only creates one when a matching definition exists, so it stays literal text — the marker remains visible to the author instead of disappearing. That is good behaviour, and it is now a documented test rather than an assumption.
Also
A second trigger-pack, Badge, so the demo exercises leaf directives and not only containers. And @types/node, because svelte-check went red the moment a test imported node:fs — the ladder catching a config gap before it reached anyone.
What’s Next
The demo lists its own gaps in a table at the bottom — wikilinks, code-fence formats, link previews, image carousel — each with the reason it is not wired up. That table is the honest roadmap for the render layer, and it is in the document rather than only in a plan.