| name | building-explainers |
| description | Build an interactive explainer component for the explorable-papers project. Use when the user wants to add or create an educational component, concept widget, interactive diagram, or click-to-expand explainer, or mentions assets/explainers. |
Build one explainer: a click-to-expand component that teaches a single concept on top of a verbatim paper. Build it as interactive HTML panels stepped with next/prev — let the reader do things (type, tamper, generate, sign), not just watch. Follow these steps in order; the process is fixed so any agent produces the same quality.
An explainer lives at assets/explainers/<concept-key>.js, registers into window.EXPLAINERS, and uses the same id as window.GLOSSARY. The loader (assets/explainer-panel.js) then shows the ⊕ marker on every keyword tagged data-term="<concept-key>" automatically. Read the reference explainer (assets/explainers/digital-signatures.js) before you write a new one, and copy its structure.
Order of work (adding several explainers to a paper)
Build, verify, and hand off explainers in the paper's own reading order — top to bottom, earliest section first, one fully finished (steps 1–7) before starting the next. The reviewer reads the paper start to finish as a first-time learner and reviews each explainer where it appears in the text, so delivering in reading order lets their review flow with the reading instead of jumping around the page. Do not batch them out of order or pick by "most impressive first"; follow the sequence the reader will actually encounter.
Core principles
- Teach the concept, not the paper's notation. The explainer exists for the reader's understanding — that is the only goal. Fidelity to the paper is not a goal here: the paper's exact words already sit right next to the explainer on the page, verbatim, so the widget does not need to reproduce its notation, encodings, symbols, or variable names. When the paper's formalism would confuse a first-timer — a terse encoding like
[0,i,K,V], a math symbol like ceil(), a one-letter variable — translate it into plain terms or drop it. Borrow from the paper only the part that makes the idea click; leave the rest to the verbatim text. If you find yourself copying the paper's notation into the UI because "that's how the paper writes it", stop — that reasoning is backwards.
- Layout is HTML/CSS, never hand-placed SVG coordinates. Use
<div>s, fl/grid, and the .exw-* classes in style.css. The browser positions things, so nothing clips, overlaps, or crams — that is the failure mode hand-coded SVG kept producing. Use SVG only for a single static summary picture at the end, if one helps at all.
- Make it real when the concept can be run. If the concept is something a browser can actually compute, run it for real (e.g.
window.crypto.subtle for keys/hashes/signatures). Real beats faked: the reader tampers with a message and watches verification fail. Concepts with nothing to compute (ordering, incentives) get a small interactive widget or a diagram instead — but always prefer direct manipulation over animation.
- One idea per step, stepped with next/prev. Each step is one panel the reader advances through.
- Plain prose; let the widget carry the abstraction. A step's intro paragraph should say, in concrete words, what the reader is about to do and see — not pre-explain the concept in data-structure or math jargon the widget is about to make obvious. Ban terms like "keyed by", "the value is a count", "maps X to Y" from the setup; a reader hasn't seen the table yet, so describing it in hash-map vocabulary is two abstractions deep. Say "each row is an owner and a balance", not "a table keyed by owner where the value is a count". If you catch yourself describing in words a structure the reader will see rendered a line later, cut the description and point at the widget ("toggle to compare"). If a jargon term is genuinely needed, introduce it once the widget is on screen to anchor it.
Steps
-
Pin the thesis. In one sentence, write the single idea you want the reader to walk away understanding. Not a summary — the one point. Example: "a signature proves who authorized something, but not when." Done when: you have that one sentence, and every later step supports it.
-
Pick the concept key. Choose the kebab-case id. It must exist in window.GLOSSARY (assets/glossary-data.js) — add the hover definition there if missing. The visible word on the page does not have to match this key: any phrasing tagged data-term="<key>" opens this explainer. Done when: the key exists in GLOSSARY.
-
Decide what the reader does at each step. Split the thesis into ordered steps, each showing one idea. Use as many steps as the subject needs — let its complexity decide; don't pad a simple idea or cram a complex one. Two things every explainer must cover, usually in an early step: the problem the concept solves (what breaks or is missing without it — a reader who doesn't know why a thing exists can't follow how it works), and where the name comes from if it isn't self-evident (opaque, borrowed, or misleading names like "gas", "smart contract", "non-fungible" quietly confuse first-time readers unless you say why it's called that). For each step, name the concrete thing the reader does (type and tamper, generate a key, sign, verify, drag, toggle). If a step has nothing to do, make it a short card, not a wall of text. The last step states the thesis and links the next related concept with <a href="#sec-N">. Done when: every step has a one-line title and a named interaction (or a clear reason it is static), an early step states the problem and (if needed) the name's origin, and the last step states the thesis and links onward.
-
Build the panels. Copy TEMPLATE.js to assets/explainers/<key>.js. Fill in the {title, blurb, mount, unmount} contract. In mount, render the steps as .exw-step panels, wire the next/prev nav, and wire each step's interactions. Run real computation where the concept allows. Done when: node --check assets/explainers/<key>.js passes.
-
Verify it works (functional QA). Register the component in the harness first: add it to the two-line list in dev/explainer-preview.html (one <script> tag, one entry in the MODULES array). The harness mounts your one explainer in isolation with the real panel chrome — no navigating the paper to reach it. Then run /ui-qa against dev/explainer-preview.html?key=<key> with a functional checklist: one item per panel covering each interaction's success and failure path (a verify that should pass, a tamper that should fail, a slider past its threshold). Spawn the /ui-qa sub-agent — driving the browser yourself with MCP tools does not satisfy this step. Done when: the /ui-qa sub-agent returns PASS on every panel; fix and re-run on anything that fails. If you cannot run /ui-qa (unavailable, no browser), say so explicitly and stop — do not self-certify from your own checks.
-
Verify it teaches (clarity QA). This is a separate, required step from step 5 — passing the functional check does not cover it, and you may not skip it. You wrote the copy, so you cannot read it cold; the whole point is a reader who didn't. Run /ui-qa against the same harness URL with an open clarity mandate — not a checklist of specific things to hunt for. Tell it to genuinely become a first-time learner meeting this concept for the first time: step every panel, trigger each interaction, read every word, and report anything that made it stop, squint, re-read, or fail to follow — in its own judgment as a confused reader. Do not hand it an enumerated list of terms to look for; a list narrows it to only what you already suspected and it skims past everything else as if normal (that is exactly how the first DAO explainer's [0,1,grant,Dave] encoding slipped through — the checklist named words, so the agent flagged words and waved the notation through). Name things only as examples of the kind of thing that trips a first reader — an undefined term, notation or a symbol shown without a plain gloss, a label that doesn't match what's on screen, a dense clause, something described before it's on screen — never as the whole list; the point is to widen its eye, not fence it in. Because clarity is an open comprehension judgment, not a mechanical check, run this pass on a capable model, not the cheapest tier — a weak reader will wave through what a sharp one catches. See the "Teach the concept, not the paper's notation" principle for what counts as a confusion. Your own inline browser reading does not satisfy this step — spawn the /ui-qa sub-agent. Treat the confusions it returns as a punch list: fix the real ones, then re-run step 5 on what you changed. Done when: the /ui-qa clarity sub-agent returns PASS, or you have fixed the confusions it found. If you cannot run /ui-qa, say so explicitly and stop — do not self-certify.
-
Wire into the paper. Add <script src="assets/explainers/<key>.js"></script> to index.html (before explainer-panel.js), then tag the keyword in the prose with data-term="<key>" — its first mention in each paragraph that uses it (see Wiring keywords below for where). Open the real page once to check the chips appear and the panel opens below the paragraph. Done when: clicking the keyword on the real page opens the verified panel.
Wiring keywords
A keyword is "properly linked" when its data-term resolves to a glossary key (so the tooltip works) and, for keys with a module, opens the right panel. Check this by reading the source on the spot — don't build a linter, just look:
- Tag the first occurrence in each paragraph. A reader may start reading from any paragraph, so make the explainer reachable from wherever the concept comes up: tag the keyword's first mention in every body paragraph that uses it. Not just one spot for the whole page — but not every repeat inside a paragraph either (chipping the same word three times in one paragraph is noise). Skip section headings and the table-of-contents nav — those are structure, not reading prose — and skip any mention where the word means something else (see the next rule).
- Match meaning, not just spelling. Before tagging, read the sentence: only tag it if the word there means the concept the explainer teaches. A passing mention in a different sense should stay plain.
- Every
data-term needs a glossary entry. If assets/glossary-data.js has no key, the tooltip silently breaks — add the definition (skill step 2) or fix the typo.
- Every explainer module needs at least one tag that opens it. A module no
data-term references is dead — the reader can never reach it. After wiring, confirm grep data-term=\"<key>\" index.html finds your tag.
- Hover-only is a valid choice. A keyword can have a glossary definition and no explainer — it stays a dotted hover term. Only add a module when the concept is worth a full interactive panel.
Clarity checklist
The reader's experience is the product. These are mistakes that have actually reached users. Every item must pass live, on screen.
- Layout never clips, overlaps, or crams. Because layout is HTML/CSS, this should be automatic — if it isn't, you are hand-placing things you shouldn't.
- Every interaction works and matches its caption. A button that says "verify" must run a real verify and show a real result.
- One idea per step, and the step's title says which idea.
- An early step states the problem the concept solves. Before the mechanism, say why the concept exists — what breaks or is missing without it. The reference explainer opens with the problem ("a message can be changed in transit"), then shows the fix.
- The name is explained when it isn't self-evident. If the concept's name is opaque, borrowed, or misleading ("gas", "smart contract", "non-fungible"), an early step says where the name comes from and why it fits. Don't leave a first-time reader guessing why it's called that.
- Every sentence reads clean on the first pass. No CS/math jargon before it's defined ("keyed by", "the value is a count", "maps X to Y"), no stack of dense parallel clauses, nothing that describes something not yet on screen. Read each intro paragraph aloud as a first-time learner: if you have to re-read a sentence, rewrite it shorter and more concrete. A clarity QA agent may wave through prose that is technically defined-in-context but still makes a human re-read — so this is on you at write time, not just the QA pass.
- Distinct things look distinct. A secret (private key) and a shared value (public key) read differently at a glance — reuse
.exw-key.priv / .exw-key.pub and the semantic colors.
- Color means the same thing everywhere. Interactive UI is blue (
--ix); green = good/verify, purple = sign, red = bad/danger. Never give one color two meanings.
- The last step states the thesis and links the related concept.
Notes
- One file per concept, à la carte — a page loads only the explainers it cites. A keyword whose module isn't loaded stays a plain hover term.
- The contract requires only
title + mount. unmount should clear the panel (panel.innerHTML = '') and stop anything still running.
- No build step, no new dependencies. Vanilla JS, the browser's APIs, and
style.css. Add new widget styles as .exw-* classes there.
dev/explainer-preview.html is the isolated test harness — it loads style.css + the explainer modules and mounts any one by ?key=. It is a dev tool, not part of the published site. Web Crypto needs a secure context, so serve over http://localhost (it counts as secure); file:// will not work.
- After editing a module, hard-reload the harness (reload with cache ignored) before re-verifying — the browser caches the
.js and a plain reload can show stale code.