Kanzo UI

The archive

The hall's closed contracts as a graph — a WebGL canvas, a docked inspector, and the standing orders read against it.

Open full size

The other shape a shell takes: no page, no scroll, a canvas that fills whatever is left. Here it is the Amber Hall's archive — 536 closed contracts, the 938 field reports filed against them, and the members, beasts, tags and regions they share. 1,543 vertices, 4,280 edges, drawn on the GPU.

ShellMain holds the canvas full-bleed and a Resizable docks a ShellAside beside it, so the inspector is a panel of a splitter rather than a floating overlay: the drag, the keyboard resize and the ARIA all come from the machine. Two orthogonal switches, which is the IDE shape — the header picks what the main region shows (Graph · Sightings), the footer strip's ShellDockSwitcher picks which inspector the dock holds (Info · Ask · Orders · Settings) and collapses it when you click the active icon again, a state Tabs cannot express.

The reference composition

This is the composition a product copies. One GraphRoot sits outside the shell, so the canvas, the inspector and every dock panel read one graph and one crossfilter. The canvas, the toolbar, the legend, the counts in the footer, the search and the inspector are @kanzo-tech/graph's parts, and the showcase writes none of them. What it writes is the product's: the channels the graph wears, the hall's name in the inspector, and the dock's panels — Info (the search and the inspector), Ask (@kanzo-tech/ai/data: useAskChat over a recorded model, each answer a dashboard tile read for real under the page's filter, drawn in an AnswerCard with Filter the page to these rows), Orders and Settings (GraphSettings: the graph's section, PreferencesSections namespace="graph", above the gestures). The graph's settings sit beside the canvas they change; the Preferences drawer keeps only what is app-wide — the theme, density, radius and fonts. fossil's attach attaches the graph as the catalog archive, and the graph and the analytics subpath's panels read it through the page's one engine — Discovery workspace is the wiring.

The archive carries no positions, so the layout runs on the GPU when it loads; the toolbar pauses and re-runs it. A look or a zoom costs no query. A lasso or a click publishes the reader's pick into the page's crossfilter as one dense_id clause, and every panel follows; a panel's filter greys out what it drops on the canvas.

The canvas authors no colour: it draws in the page theme's categorical scale, so a theme from the theme generator recolours it with everything else.

The standing orders

The Orders panel holds the hall's own rule document — the same small language the board's copy is written in, over on The Guild — parsed, compiled to SQL, and read against the archive:

order "a contract is signed for" {
  when    contract
  require signed at least 1
  else    violation "No warden's name on it."
}

Each order becomes one count(*) FILTER (WHERE …), and the whole report is one query. Focus an order and the ids that break it are published into the crossfilter, so the canvas lights up exactly those nodes. Drop your own .orders file on the panel and it reads that instead; anything it cannot compile is named rather than dropped, because otherwise you cannot tell "in order" from "never read".

Sightings

The other main view is a Dashboard over the world's own analytical relation, one row per reported sighting — the boghound met in the bestiary and as a hub on the canvas. Everything on it is one hand-written spec and the relation: a filter row, four tiles trending along the hour, a line, bars by hall coloured by the verdict's status scale, bounty by region split into panels, and a fit of distance against bounty over the rows, and the beasts as bars. The spec is written by hand because a showcase should look chosen; drop value and the same component draws the automatic dashboard from the relation's stats. Edit any card and the spec in state is what changed — the whole of what a host would persist. The editor draws in the page's Format aside at the body's end edge, shown while a tile is edited, the way draw.io's Format panel is.

sightings has no date column, so the ordered axis is hour, and each tile's delta compares an hour with the one before. The view has its own MosaicProvider: it reads a different relation from the canvas, and a part says which relation it reads. It is nested in the graph's, and the page's slots are the outermost provider's, so the dashboard reaches the TileEditorAside the shell places beside ShellMain.

Worth exercising in the frame

Lasso a cluster and watch the toolbar count it. Find a contract in the Info search and the canvas frames it while the inspector reads its row. Switch the Look in the dock's Settings; Ink moves identity from colour to shape, and the legend's rows do not move. Focus an order. Then switch to Sightings: brush the hourly curve and every panel narrows with it, click a hall's bar and the chip under the filters says so, and open a card's editor to turn the line into an area.

Source

docs/showcases/workspace/
├── default.tsx           — the shell: sidebar, header, splitter, footer strip, the canvas's parts placed
├── data.tsx              — the chrome (halls, nav, viewer), straight from the world
├── duck.ts               — each view's relations, registered once in the page's one engine
├── graph-data.ts         — the archive as rows; what the graph is compiled FROM, not read from
├── corpus/               — the mapping, the shape and the script that compile it with fossil
├── graph-view.tsx        — the GraphRoot composition, each look's channels, and the dock panels
├── graph-finding.tsx     — a finding a panel can point the canvas at
├── orders.ts             — the standing-orders language, compiled to SQL predicates
├── order-builder.ts      — the same document, written back out
└── sightings-charts.tsx  — a `Dashboard` over the world's sightings, from a hand-written spec