ReferenceComponentsEvergreenupdated 2026.086 min read
Hub›Part III · Interactive & furniture
Part III · Interactive & furniture

Interactive & furniture

A live canvas demo and the contract behind it, then the quiet components every note is framed by — the ones you have been looking at since the first page.

§3.1DemoMount — live

The division of labor is the package's usual one: the mount markup (stage, controls slot, caption slot) ships in the package; the demo module and its loader belong to the site. This site keeps its loader in src/lib/demo-loader.ts and calls mountAllDemos() once from the layout; the call runs on every page, but a demo module chunk is fetched only for a page that carries a [data-demo] mount.

A demo that takes pointer input on its canvas passes interactive — the stage then claims touch gestures and shows a crosshair. This one is passive (render-only), so it leaves the flag off and a swipe over the canvas still scrolls the page. It draws two-source wave interference with the page's own ink token, so it follows the theme:

Demo · Two-source wave interference
Demo · Two-source wave interference

Two point sources emit circular waves; where crests meet crests the ink pools, where crests meet troughs the paper shows through. Toggle the theme — the demo re-inks itself from the live tokens.

The module contract is one default export, mount(ctx), returning a cleanup function; the loader resolves module ids like waves/interference however the site pleases (import.meta.glob here).

§3.2Page furniture

The remaining components frame a note rather than fill it:

  • Hero opens a note: kicker, display title, a lede that goes through the full Markdown pipeline, a meta line, and optional tocLabel that adds an unnumbered "intro" row to the sidebar. The note's frontmatter title stays the short canonical one for <title> and cards; the hero's may be long.
  • PartHero opens a chapter of a hub — this page's own head. Its kicker is never typed: the route passes the chapter's "Part III · …" label in as props.partLabel.
  • Part divides a long single-page note into parts; the numbering preset turns it into the "PART II · Foundations" group rows of the sidebar. The kitchen-sink is cut that way.
  • HubCard and .hub-grid are a hub's landing cards; .path is its reading-path box — both on the overview of this gallery.
  • LocalToc renders an in-page jump list; it accepts both ToC shapes the two numbering presets produce, and hides itself under a configurable minimum. Below, live, on this chapter's own ToC.
  • SidebarMemory keeps a scrolling sidebar where the reader left it across page loads, and centres the current item ([aria-current="page"] by default) whenever it would otherwise be out of view. Drop it inside the sidebar's scroll box, after the navigation markup; it runs before first paint, so the sidebar never flashes at the top. The demo's own sidebar carries it.
  • LineageSvg frames an SVG that carries no words — a lineage tree, a taxonomy — as a card; a diagram with words in it is a FlowDiagram, below.
  • PageFooter is the small print at a note's foot — the line under every note here.
  • The browse pieces live in the wiki chapter; the Markdown side of the gallery is the kitchen-sink.

§3.3LocalToc and FlowDiagram, live

LocalToc fed this page's own build-time ToC — the same data the sidebar consumes, handed to the note as props.toc:

The same figure as a FlowDiagram — the boxes are HTML that size to their words, the arrows are measured after layout, so nothing can leave its box in any font:

Fig. — where the appearance layer sits
tokens.css
base.cssthe reading column
browse.cssthe browse shelf
componentsconsume both

§3.4FlowDiagram — boxes that size to their words

A diagram that carries words is a FlowDiagram (or a mermaid fence). A hand-positioned <svg> with <text> is drawn against one font and breaks in the next wider one — and every site renders with its own; LineageSvg stays for SVG that carries no text a font could widen out of shape. The spec is data: cols, nodes (col / row / span, a tone, lines, a tag, ghost for a dashed note, mono for paths), edges (label, dashed, off for a broken link), optional lanes and heads:

Fig. — one change, three lanes
Author
Reviewer
Build
Writea note or a component
Open a PRone branch
Reviewapprove or ask
Build and deployon merge

Lanes label the rows and draw the separators; a tone colors a box's border and tag; a wire goes around every box it does not join and every heading; a wire's label is always drawn: a wire between neighbouring boxes of one row widens their gap for it, a label wraps or shrinks to the room it finds, and a label with no room clear of the boxes and the other wires becomes a numbered key on its wire, or beside it on a short lead, its words listed under the diagram.

A heads entry titles the rows under it, so a diagram drawn as groups is a heading row followed by the group's boxes; wires go around a heading's words as they go around a box. A wire with no way between the boxes runs down the diagram's gutter — the strip on either side of the boxes, inside the frame's padding — and the wire layer covers the gutter, so the wire and its key stay inside the figure:

Fig. — a wire back up one column
Planwhat to change
Build
Measureagainst the ground truth
Fig. — two groups, wires between them
What the model is given
What the model computes from it
Photosseveral views
Camerasposes and lenses
Features per view
Fuse the views
Closed surface

Each box is at least ten letters wide, and each column as wide as the longest word in its boxes, so no word is split; a snake_case name may break after an underscore. On a column too narrow for all of them, a phone's for one, the diagram scrolls sideways inside its frame while the title and the caption stand still; the diagram keeps the structure it was written with.

When several labelled wires leave one box, some labels find no room clear of the boxes and become keys. A key is placed as a label is: never on a box, a heading, a label or another key. It sits on its wire where the wire has a clear spot, and otherwise beside the wire, joined to it by a short lead:

Fig. — one box, five labelled wires
A ray enters the band
Walk this stretcha budget of M cells
Redo one level coarserthe interval still holds the hit
Walk it with no budgetonly at the coarsest level
Report the intervalit holds the first hit
Take the next crossingnone left: the ray misses

§3.5Furniture without a component

A few pieces are plain classes in base.css, for sites that render them from their own layout or write them as HTML in prose:

ClassWhat it is
.page-head + .kicker, .page-desc, .page-datea frontmatter-driven page head (kicker, h1, description, date) rendered by a layout instead of a <Hero>
.banner, .banner-fallbacka one-line notice under the head; the fallback variant is the muted one
.page-foota two-column small-print footer (left slot, right slot)
.speakthe plain-language gloss under a deep-dive heading; its label is --speak-label
.path + .title, .route, .arrowa reading-path box on a hub
.ref-taga small monospace tag in a reference list (a venue, a year)
.tag, .tag.teal / .mustard / .violetthe paper-card badges, usable anywhere
.measured + .measured-head, .measured-body, .measured-pane (.doc), .measured-tagthe documented-versus-measured comparison card: a solid teal title bar over two panes, the .doc pane carrying the claim and the other the measurement — a silhouette distinct from every callout
.paper .idea-labelthe small uppercase key-idea label inside a PaperCard body, e.g. <span class="idea-label">Key idea</span>
Titles, sections and body text, in this language.
    ↑↓ · Enter · Escastro-inkstone