The reusable visual vocabulary for writings posts: every figure a post can reach for, as live reference implementations. Four tiers, from quiet text structures to one-per-post interactive explorers. Two production components are adopted, not forked.
tokens site palette, both themescolor = role constant per post, never cycledvalidated CVD-checked pairs onlylabels collision-managed at every statemotion reduced-motion fallback alwaystouch hover never load-bearing
A Text-first
Structure doing the explaining, with subtle or no interactivity. Cheapest to author, most reusable. Default here before reaching for a chart.
A1<StatTile>: the number is the pointno js
backlog
0
caught up
index seeks / poll
1
constant, any cursor age
event age
39,438
blocks · grows on quiet feeds
Use when one value carries the argument. Tabular numerals, optional spark with emphasized endpoint. Never three tiles saying the same thing.
A2<TermPair>: two concepts held apartno js
receipt
What I have safely stored. Durable, transactional, points at a row you hold.
bookmark
Where I was looking. Ephemeral, recomputed by the first poll, free to lose.
Use when a post rests on a two-way distinction. The role colors established here follow both terms through every later figure in the post.
A3<Matrix>: tradeoff grid with cost chipsno js
you lose the
bookmark
One free question on restart.
~1ms, once
you lose the
receipt
Duplicates or silent gaps.
your data
Use when the point is an asymmetry of consequences. Semantic chip colors (ok/alarm) are separate from role colors and never reused as series.
A4<AnnotatedPayload>: a wire shape, explained in placeinteractive
checkpoint: the receipt, last delivered cursor, committed with your rows.
last_delivered_height: event recency; parks on a quiet filter.
scanned_height: verified-through position; rides the tip when caught up.
blocks_behind: tip − scanned. Backlog, not event age.
Use when explaining a JSON/wire shape field by field. Hover or focus a field to light its note; on touch, tap toggles. Fields are real buttons, keyboard reachable.
A5<Sidenote>: precision without derailinginteractive
The catalog seeks to your cursor in logarithmic time¹1. B-tree index on (filter, cursor); the seek is O(log n) over the event count, not the block count. and reads forward, so a poll costs the same at any cursor age.
Use whena hedge, source, or precision upgrade would break the paragraph’s stride. ≥1100px the note lives in the right margin beside its reference (as in a post; shown inline here); narrower viewports tap to expand inline.
A6<AnnotatedCode>: logic, explained line by lineinteractive
one transaction: everything inside commits together or not at all.
lock first: a second writer fails loudly here, before touching data.
the handler's rows: user inserts go through the lent tx.
cursor last, same tx: the receipt rides with the rows it describes.
Use whenthe argument is the ORDER of operations. A4’s sibling: payloads get field notes, logic gets line notes. Lines are buttons; hover, focus, or tap.
Use whena migration or fix is the story. Deletions tinted alarm, additions tinted ok, both at 8%: semantic colors, never the role palette. The “result” view is what a reader copies.
Committed separately, a crash between the two either re-delivers the batch (duplicates) or skips it (a gap), depending on which write landed first. The classic torn-batch bug.
The new canonical chain re-supplies the fork block itself. An exclusive > leaves one block of orphaned rows that survives the fork forever, silently.
On a multi-fork page every rollback call carries the same rewind cursor but its own fork height. A sink that derives the delete range from the cursor under-deletes, silently.
Use when a contract has numbered obligations. Each row is anchor-linkable (#inv-9), so docs and reviews can cite an invariant by URL. Click expands the failure story: the reason the rule exists.
A9<Term>: hover-defined vocabularyinteractive
The stays parked while the rides the tip.
Use whena post coins terms and readers may land mid-page. Dotted underline signals “defined here”; hover on pointer devices, tap or focus elsewhere. One glossary per post keeps definitions identical at every mention.
A10<SpecSheet>: the facts about one thingno js
endpointGET /v1/index/contract-calls
authkey optional (keyless = recent window)
paginationcursor keyset, limit ≤ 200
cursor formatblock_height:event_index
orderingascending, total (one order per feed)
Use when a post references a surface and the reader needs its vitals without leaving. Adopts the console data-table voice: mono, hairline rows, uppercase keys. Static on purpose.
A11<SourceQuote>: the primary source, citedno js
Roll the projection back to the fork: delete everything at or above the fork point and commit the rewound cursor in the same transaction. Deleting without the rewound cursor is the classic silent-gap bug.
Use when the story layer quotes a spec, RFC, or source file. The citation names the exact artifact; paraphrase never wears quote marks.
B Diagrams
Spatial explanations: positions, flows, sequences. The tier where label collision management earns its keep: every diagram must survive its own extreme states.
B1<PositionTrack>: positions on one axiscollision-fixed
last_delivered8,637,064scanned · tip8,676,502
Collision rule: markers within 8% of each other merge their flags into one combined label and collapse duplicate values. Values sit on their own tier below the rail; flags stagger when neighboring groups sit close.
B2<FlowLoop>: request / response with cost counterscss motion
consumer
GET …?cursor=8637064:1
catalog
{ rows: [], next: null }
polls: 0 · blocks read client-side: 0
Use when the mechanism is a loop between two parties. The counter row is the argument; the shuttle is atmosphere (and pauses under reduced-motion).
B3<Timeline>: ordered events on a time axisno js
block 100last sale102fork detectedtip103
Use whenorder carries the information. Shares B1’s flag collision rule. Major ticks in role colors; minor ticks stay faint.
B4<Lifecycle>: a state machine you can walkinteractive
Press step to start the machine.
Use when a system has named states and the edges are the story. Active state carries the accent (the flow-diagram node grammar); the caption narrates each transition in words.
Use whenshowing where a post’s subject sits in the system. Adopts the service-flow node grammar: Chrome default, tinted data stage, ONE filled accent node for the product surface. Edge dashes march (still under reduced-motion).
B6<SequenceDiagram>: who says what, whencss hover
Use whenthree or more parties exchange messages and ORDER matters. Hover or focus a message: it and both endpoints light. Returns are dashed. Keep to ≤6 messages; past that it’s two diagrams.
B7<LayerStack>: where you are in the stackinteractive
Hover or tap a layer.
Use whenorienting a reader before a deep dive. A layer lifts sideways on hover/tap and narrates itself. Order is physical: the chain at the bottom, the reader’s code on top.
B8<TreeWalk>: the log-time seek, performedinteractive
Pick a key: the path lights one level at a time.
Use when“logarithmic” needs to be felt, not asserted. Three comparisons reach any of millions of keys; the counter says so. Path lights stepwise (instant under reduced-motion).
B9<BeforeAfter>: one geometry, two statesinteractive
receipt103:0
fork102
Use when the same scene changes state. One geometry, toggled: the orphaned range (tinted) empties and the receipt rewinds below the fork. Nothing redraws; only the deltas move, so the eye tracks WHAT changed.
B10<StateRow>: a status, advancinginteractive
click to advance · pending: in the mempool, nothing durable yet
Use when a linear status progression needs to be operated to be understood. House badge colors by state; past states dim, the current one fills. Arrow keys work; wraps around.
C Charts
Full dataviz method: validated palette, thin marks, recessive grid, always a hover layer, direct labels with collision resolution.
C1<LineChart>: change over time, ≤4 seriescollision-fixed
event agebacklog
Collision rules: end labels resolve vertical collisions (nudged ≥14px apart, clamped inside the plot); the tooltip clamps to both container edges instead of clipping; threshold labels claim their own y-band before direct labels place.
C2<BarChart>: magnitudes, comparedno js
Use when comparing magnitudes across a handful of entities. Thin marks, 4px rounded data-end only, every bar direct-labeled. One hue: identity lives in the axis, not the palette.
C3<SmallMultiples>: same measure, many entitiesno js
Use when the comparison is across entities, not within one chart. Shared scales always (a per-panel scale is a lie); one measure, panel titles in mono; endpoint dots instead of a legend.
C4<CellStrip>: density along an axisno js
Use when showing where things are along a range (matching blocks, gaps, occupancy). 2px surface gaps between cells; hits in the role color, never a new hue.
C5<Distribution>: the spread, not the averageinteractive
Use when an average would hide the story. Percentile markers are dashed ink (not a series color) and direct-labeled; per-bin hover gives the exact count.
C6<DeltaBars>: before and after, pairedinteractive
walker (reads blocks)catalog (one seek)
Use whena change’s size is the argument. Pairs share a baseline; the role colors carry which regime is which, consistently with every other figure in the post.
C7<InlineSpark>: a trend inside the sentenceno js
Backlog fell through the backfill and held at zero, while event age kept climbing.
Use when a sentence mentions a trend and a full chart would be ceremony. Word-scale, no axes, endpoint dot, aria-label carrying the reading. Never for values a reader must compare precisely.
C8<HeatCalendar>: activity across daysno js
nonemany
Use when WHEN things happened matters more than how many. Sequential single-hue ramp, lightness monotonic, 2px gaps; the empty recent weeks ARE the story for a dormant contract.
D Explorers
A parameter the reader can move. Highest cost to build and to read: at most one per post, placed at the section it proves.
D1<ParamExplorer>: slide a parameter, watch the regime changecollision-fixed
sparse delivery: receipt lags the bookmark by 35,988 blocks, none of which contain anything addressed to you
Collision rule: when the two pointers come within 10% they collapse into one merged pointer with a combined label. The readout sentence is part of the figure: it states the regime in words at every slider position.
D2<ScenarioToggle>: two named worldsinteractive
Use when two named scenarios share one figure shape. Segmented buttons switch which world renders; panels are plain children, so any static figure can be toggled.
D3<StepThrough>: an algorithm, one move at a timeinteractive
step 1 of 5
BEGININSERT rows (the handler's writes)UPSERT cursor '8637064:1'COMMIT-- crash here instead? --
Open the transaction. Nothing is visible to anyone else yet.
Use when the reader must hold intermediate state in their head. Arrow keys work; the final step rewinds the story to the crash case, which is the payoff.
D4<Predict>: commit to a guess firstinteractive
A consumer is caught up on a quiet contract. You restart it. What does resuming from print?
The checkpoint comes back with the same cursor, because it is a receipt for the last delivered row and nothing was delivered while the contract was quiet. The first poll re-verifies the empty range in one seek; the scan position is recomputed, not stored.
Use whena post’s aha benefits from the reader being wrong first. The guess commits before the reveal; wrong picks stay visible so the correction lands. One per post, at the turn.
D5<CrossHighlight>: input and output, wired togetherinteractive
Use when the reader should see WHICH input produced WHICH output. Hover or focus either side; its counterpart lights. Unpaired fields staying dim is information too: they came along for free.
D7<CopyBlock>: hand it to your agentadopts production
Build a checkpointed indexer
Read /docs/sinks and implement a ConsumerSink for my store.
Hold the 13 invariants; start from the bun:sqlite reference sink.
Run the conformance kit (attachSinkConformance) before wiring it in.
Rule: adopts the production agent-prompt block; one implementation, two mounts, never forked. (D6 <MiniSandbox> stays a reserved slot: the dataset sandbox it adopted left production, so it returns when a post needs a live request cell.)