Here is the most meta lesson in the whole course: this very page was made by visual-teach. Every lesson you have read — the warm-neutral look, the dark-mode toggle, the live demos, the Simple-then-Technical layering, the English and Brazilian-Portuguese versions — came out of one engine that turns a topic into a self-contained, interactive HTML course. And the engine did not run on its own: the loop you have been learning treats a finished visual-teach course as a deliverable — its Course Gate — so the same LEARN → ANALYZE → EXECUTE → VERIFY discipline that ships code also ships the teaching about it. This lesson opens the engine up and lets you drive its parts.
Most tools that "explain" something hand you a wall of text. visual-teach does something different: you give it a topic, and it produces a small website that teaches that topic — a set of HTML pages that open with a double-click, need no internet, and let the reader poke at the ideas instead of only reading about them.
Each page is built to the same recipe. There is a friendly plain-language layer that anyone can follow, and a technical layer folded behind a toggle for the reader who wants the exact detail. There are diagrams drawn as vectors so they stay crisp and re-colour themselves in dark mode. There are live demos — little simulators, animations, sliders, slide decks — that turn a sentence into something you operate. And the whole thing ships in two languages by default: English and Brazilian Portuguese.
The trick that holds it together is a single shared shell. The top bar, the side navigation, the colours, the fonts, the dark-mode button — those are byte-for-byte identical on every page. Only the middle, the actual lesson, changes. So a 14-lesson course feels like one consistent product, not 14 hand-made pages that drift apart.
Think of it like a print magazine with a strict house style. Every article sits in the same grid, same masthead, same fonts, same page furniture — so the reader never has to relearn how to read it. The writers only fill the article well; the template guarantees the rest. visual-teach is that house style, except the "articles" are interactive and the template is enforced in code. Where the analogy breaks: a magazine's template is a suggestion a designer can quietly override; here the shell is copied verbatim and any drift between two pages is treated as a defect.
Every page is a single .html file with inline CSS, inline SVG, and inline vanilla JS — zero external requests. No CDN, no web font, no <img>, no data: raster. That is what makes a course openable from file://, e-mailable as an attachment, archivable, and safe to read on a plane. The cost is discipline: no framework, no build step, and every diagram drawn as vector by hand.
A course is a hub (index.html), a folder of lessons (lessons/0001…), an optional gallery page, and the raw demo exemplars. English lives at the root; each translation mirrors the whole tree under its code (pt/index.html, pt/lessons/…) with the same filenames. The .vc-lang selector lists exactly the languages that exist, and never points at a dead link.
visual-teach distils two things at once: the narrative lesson (read once) and a durable reference document (returned to again and again — cheat-sheets, glossaries, flowcharts). The pedagogy file calls the reference document "the durable half" — the part most teaching forgets. This course's per-lesson pages double as that reference.
You have spent twelve lessons on a loop that ships work: it learns the real state, analyzes the gap, executes one bounded unit, and verifies the result at a real boundary before deciding what to do next. visual-teach is where that loop pays a second dividend. When a piece of work is done, the loop does not just hand you the artifact — it can also hand you the teaching about it, generated as a full visual-teach course. That deliverable is the loop's Course Gate.
So this course is not a side project bolted onto the loop. It is an output of the loop. The same engine that proved the code works also produced the lesson explaining how it works — which is exactly why "the engine that built this course" is more than a slogan.
Think of a research lab. The experiment is the work; the published paper is how the knowledge survives past the people who ran it. A lab that never writes up its results loses them. The Course Gate is the write-up step made automatic — the loop finishes the experiment and files the paper in the same run. Where it breaks: a paper is read-only prose; a visual-teach course is interactive and re-testable, closer to a paper you can run.
In the loop's vocabulary a gate is a verification you cannot skip. The Proof Gate proves the artifact works at a real boundary; the Course Gate proves the knowledge is captured and teachable. Both are deliverables of the same run, so "we shipped it but never documented it" stops being possible by construction.
Generating the course is not a human chore. Under the loop, an executor builds each lesson and an independent validator checks it against the goal — the human's only role is observability (reading the log, the review, the status). The Course Gate inherits exactly that: a course is produced and verified without a person hand-authoring HTML.
Before the parts, the whole. A visual-teach course is four kinds of thing wired together. Read the sheet top to bottom; each box says what it is and where it lives on disk.
pt/.The hub (index.html) is built from assets/index-template.html and is the only page that groups lessons by Module. Lessons are built from assets/lesson-template.html. The demo exemplars under assets/demos/NN-slug.html are not shipped to the reader — they are the source you lift markup, CSS, and JS out of when filling a lesson. The gallery is an optional index of the live demos.
PT-BR is not a translation toggle inside one file; it is a parallel directory tree. pt/lessons/0013-visual-teach.html is the same file as the English one with <html lang="pt-BR">, the .cur flipped in .vc-lang, the relative link depth fixed, and only the prose translated — never the code, commands, or identifiers.
The single most important rule in the engine is also the simplest: the parts of the page that are not the lesson are copied exactly the same onto every page. The colour tokens, the base styles, the top step-bar with its dark-mode button and language picker, the side navigation, the bottom wizard nav, the footer, and the shared JavaScript — all of it is one block of bytes, repeated verbatim.
Only two slots are a lesson's own: a place for the lesson's extra CSS (the styling for its demos) and a place for the lesson's JavaScript (wiring those demos). Everything else is off-limits. If you needed a new shared component, you would add it to the template so all pages get it — you would never style it on one page.
Think of a chain café. Walk into any branch and the counter, menu board, cup sizes, and signage are identical — only today's specials change. You order without thinking because the layout never moves. The shell is that fixed fit-out; the lesson is the daily special. Where it breaks: a café manager can repaint a wall; here the fit-out is enforced byte-for-byte, and two branches that differ would be a bug.
assets/lesson-template.html — the two slots, verbatim
/* ===== BEGIN SHARED SHELL (byte-identical across all pages) ===== */ /* … tokens, base CSS, stepbar, nav … copy verbatim, never edit per page … */ /* ===== END SHARED SHELL ===== */ /* ===== LESSON-SPECIFIC (only this lesson's demo CSS goes here) ===== */ .d05_btn { background: var(--btn-bg); /* uses shared tokens → dark mode for free */ } /* ===== END LESSON-SPECIFIC ===== */
If each page hand-rolls its own header, the pages drift: a padding here, a colour there, a stale nav link somewhere else. By mandating the shell as a copied block, a course of any size has exactly one header, one footer, one nav, one set of tokens, and one theme engine. Auditing is trivial — diff any two pages and only the lesson body and its CSS/JS should differ.
The shell ships two :root blocks: the light palette and a :root[data-theme="dark"] override that redefines the same variable names. Because every component (and this lesson's demos) reads var(--token) and never a hard-coded hex, flipping one attribute on <html> re-themes the entire page. A pre-paint script in <head> sets the saved or OS-preferred theme before first paint, so there is no light flash.
Each lifted demo prefixes every id, class, SVG marker, and DOM lookup with a unique tag (this lesson uses d05_, d07_, d08_, d09_, d10_, d15_, d19_). That is what lets five or seven independent demos coexist on one page without a single collision.
How does a topic actually become a finished course? Click through this deck for the shape of it in two minutes — one idea per slide. Then the next two demos let you watch the pipeline run and drive a single lesson through it.
A slide deck is the right demo type when the job is "grasp the shape of a whole topic before the detail." Each slide carries exactly one idea in large type, so the reader never juggles two thoughts at once. The engine is one go(index) function clamped to [0, n-1] that toggles the current slide, fills the progress bar, syncs the dot rail, and disables Prev/Next at the ends — arrow keys included, motion respecting prefers-reduced-motion.
Scaffold copies the template (shell intact, body a marker). Fill replaces the marker, adds demo CSS to the one CSS slot and wiring to the one JS slot. Mirror produces the pt/ twin. Verify is the Proof Gate for teaching: open the file, diff the shell, exercise the demos, resolve every link — never assert "it should work."
A deck tells you the steps; an animation shows the order. Press Play to send one lesson down the pipeline, Step to advance one beat, or Reset to start over. Watch the token travel: scaffold to fill, then a mirror fans out to the PT twin, then verify proves it before it ships.
Ready. Press Play or Step to send one lesson down the pipeline.
Five ordered phases — scaffold, fill, mirror, verify, ship — drive a vanilla-JS engine. Each step tweens the token's position with requestAnimationFrame and an ease-in-out curve; the mirror beat spawns a second token that fans down to the PT twin. There is no <video>, no GIF, no library, so it steps, plays, and resets deterministically and respects prefers-reduced-motion by snapping instead of tweening.
A still diagram answers "what is connected." This animation answers "in what order, and where does the PT twin branch off." Reach for animation only when sequence is the lesson — otherwise a labelled still costs less and reads faster.
Now you drive it. A lesson moves through a fixed set of states, and the whole point is that you cannot skip: you cannot ship a lesson that was never verified, and a page that fails verification goes back to be fixed, not forward. Press an event and watch the highlighted state move; buttons grey out the instant a move is not allowed from where you are.
The clay-filled node is where this lesson is now. Faint nodes are unreachable from here.
Current state
SCAFFOLD
A copy of the template with the shell intact and a FILL marker where the body goes. Nothing taught yet.
Allowed transitions
Event log
Everything the prototype does is driven by this table. The buttons read it to decide what to enable; pressing one looks up machine[state][event] and moves there. The illegal moves — shipping before verifying, mirroring before filling — simply do not exist in the table, so they cannot be taken. VERIFIED can only ship; a failed verify routes to NEEDSFIX, whose only way forward is back to FILLED to be re-filled and re-verified. That is the Proof Gate expressed as a state machine.
const machine = { SCAFFOLD: { fill: 'FILLED' }, FILLED: { mirror: 'MIRRORED' }, MIRRORED: { verify: 'VERIFIED', fail: 'NEEDSFIX' }, NEEDSFIX: { refill: 'FILLED' }, VERIFIED: { ship: 'SHIPPED' }, SHIPPED: {} // terminal — the course gate is satisfied };
What makes a lesson live rather than a page of text is the demo. visual-teach ships 20 ready-made demo types — little self-contained widgets you copy and re-wire. They are a palette, not a checklist: a thin idea might use one; a rich lesson (like this one) stacks seven. They fall into a handful of families by the teaching job each one does.
And here is the "tune toggles" family itself, made live — demo type 19. These are the very switches that decide what a course ships with. Flip them and watch the warnings: some choices depend on others.
Build status
For each beat of a lesson you name the teaching job in one phrase — explain how it works, compare options, show a process over time, read state, teach via failure, summarise, let them drive, tune knobs — list two or three candidate types, pick the best fit with a one-line reason, and name the runner-up you rejected. A complete course exercises most or all twenty; reusing one widget every beat is a smell.
The switches above are demo type 19. Each toggle reads a small rules table: turning off self-contained permits a CDN but breaks offline use; turning off the PT mirror orphans the language link; turning off demos drops the skills layer to knowledge-only. The panel surfaces those consequences live — exactly what this demo type teaches: a toggle is never free of side effects.
Every diagram you have seen in this course is hand-drawn as an inline SVG — vector shapes written into the page, never an image file. That is why they stay razor-sharp at any size and why they re-colour themselves when you flip to dark mode. There is a strict palette so they read on both the light ivory and the near-black background. Tap a swatch below to spotlight one rule of that palette on the worked example.
Think of an exploded-view diagram in a furniture manual: every panel and screw drawn in place with a line to its name. You don't read it — you see where each piece goes. An SVG sheet is that, but it also obeys a colour discipline so it never vanishes into a dark page.
No swatch selected dims nothing — pick one to spotlight it, or "Show all" to reset.
var(), in the SVGCSS custom properties do not resolve reliably inside SVG presentation attributes (fill="…", stroke="…") across renderers, so diagrams use the literal mid-palette hexes — clay #D97757, olive #788C5D, sky #5C7CA3, rust #B04A3F, gray #87867F. Each reads on both the ivory and the near-black surface. Boxes are fill="none" so the themed page surface shows through; the one allowed white fill is a glyph sitting on a saturated colour chip.
Every <svg> carries role="img" and an aria-label that reads the whole diagram as a sentence, so a screen-reader user gets the same content. A single arrowhead <marker> is defined once per SVG and reused. Where a diagram animates, it honours prefers-reduced-motion.
The warm-neutral look you have been reading in is not improvised per page — it is a small design system: a fixed set of named colours and sizes (the tokens) that every page draws from. Nobody writes a raw hex like #D97757 in the lesson; they write the name --clay. Change the name's value once and every button, heading, and border updates together — and that is exactly the mechanism that makes dark mode a one-line flip.
Think of a kitchen with labelled jars. Nobody scoops from an unmarked bag hoping it's sugar — they reach for the jar that says "Sugar." Tokens are the labels; the rule is always reach for the jar, never the raw bag. Where it breaks: a jar's contents are fixed, but a token's value is swapped wholesale by theme — the same label, a different sugar in the dark.
Now make it concrete. Pick an intent and a size — the preview button is styled only from tokens, and the code readout shows the exact tokens in play. This is precisely how a token-driven component behaves: swap the values, the component re-renders, no new CSS.
Intent
Size
.btn { }
Two layers matter. Primitive tokens are raw values (--clay: #D97757). Semantic tokens alias them by role (--btn-bg: var(--clay)). Components consume only the semantic ones, so re-skinning means re-pointing an alias, never touching the component. The preview button carries no per-intent class — each control writes the semantic custom properties onto its inline style, and one .d05_dsbtn rule reads them with var().
/* primitive scale */ --clay: #D97757; --clay-d: #B85C3E; --olive: #788C5D; --rust: #B04A3F; /* dark mode redefines the SAME names → every var() flips */ :root[data-theme="dark"] { --clay: #E08A6B; --ivory: #1A1917; /* … */ }
A single lesson has to serve two very different readers: someone meeting the idea for the first time, and someone who wants the exact command and edge case. visual-teach does not pick one — it layers both. The Simple layer is always visible and must tell the whole story on its own. The Technical layer is folded behind a toggle, so the precise detail is one click away for the reader who opts in — and invisible to the one who does not. Every "Show the technical detail" button on this page is that mechanism. (There is also an "Expand all" control at the top that opens them together.)
Think of museum labels. The big wall text gives everyone the story in a sentence; the small card beside the piece adds the date, medium, and provenance for those who want it. Nobody is forced to read the small card, and nobody who wants it is denied it. Where it breaks: a museum prints both statically; here the small card is collapsible, so the casual reader isn't even distracted by it.
The rule the engine enforces: hide every technical panel and the Simple layer must still make sense and reach the lesson's one win. If it doesn't, the Simple layer is incomplete. Introduce the term after the idea — "the thing that decides where your request goes … that's called a load balancer" — so jargon is earned, not assumed. Short sentences, one idea each, second person, present tense.
Each toggle is a <button class="tech-toggle" aria-expanded> whose next sibling is a .technical panel; clicking flips aria-expanded and toggles .open. The page-level #expandAll opens or closes all of them at once and stays in sync. That wiring lives in the shared JS, so every lesson gets it for free — this lesson did not write a line of it.
Pulling the threads together, here is the contract every visual-teach course meets without anyone asking. It opens from a double-click with no internet. It carries the byte-identical shell on every page. Dark mode works and remembers your choice. It ships English and Brazilian Portuguese together — never English with dead PT links. Every diagram is dark-safe vector. Every lesson leads with the Simple layer and shows real code or commands with a way to reach them. And there is no AI attribution anywhere — the artifact stands on its own.
Think of a car's standard safety kit. You don't tick a box for seatbelts, airbags, and mirrors — they're fitted by law on every model. These defaults are visual-teach's standard kit: not optional extras you remember to add, but the baseline a course cannot ship without.
None of these choices are decoration. visual-teach is built on a specific theory of how people actually learn, and three ideas drive almost every decision on the page.
First, learning needs three different things: knowledge (facts, drawn from trustworthy sources, never made up), skills (built only by doing — which is why the demos exist), and wisdom (judgment, earned from real practice in a community). A lesson weights these differently depending on the topic.
Second, there is a difference between fluency and storage strength. Re-reading something makes it feel familiar — that's fluency, and it fades fast. Durable memory — storage strength — is built by retrieval (recalling from a blank page), spacing (revisiting over time), and interleaving (mixing related ideas). That is the whole reason this course teaches each core idea several ways — an analogy, a diagram, a live demo, a worked example, and a check — and re-tests it.
Third, the zone of proximal development: meet the reader just past what they already know — not so easy it's boring, not so hard it overwhelms. For pure knowledge, difficulty is the enemy (it eats the working memory you need to understand); for skills, a little difficulty is the tool that makes it stick.
Think of learning to drive. Reading the manual is knowledge; it feels like progress but you can't drive from it. Skill comes only from time behind the wheel with instant feedback — drift over the line, the instructor speaks up now, not next week. And a good instructor keeps you just past comfortable: today's lesson is slightly harder than yesterday's, never a motorway on day one.
So here is the retrieval practice itself — demo type 15's quick check. Recall first, then reveal. Pick the answer you believe before you click; the feedback is immediate. (Every option is the same length, so the formatting gives no tell.)
Q1 Why does the course teach one idea several different ways?
Q2 What is the Simple layer required to do entirely on its own?
Q3 For pure knowledge (not skill), difficulty during learning is…
Mini-glossary
Every option in a quiz is the same word count — ideally the same character count — so the longest, most-qualified option never gives the answer away. Distractors are plausible and match a real misconception, which teaches more than an obviously-wrong option. The feedback is immediate (the tight loop skills need), and "Try again" lets the reader space the retrieval.
The split matters: in the knowledge layer, difficulty is removed (clear prose, one idea per sentence) because working memory is tiny and you want it spent on understanding. In the skills layer — the demos and quiz — a little desirable difficulty (recall before reveal, drive the machine yourself) is exactly what converts fluency into storage strength.
Everything in this lesson came from a handful of real files. Here is where they live and how to open them, so the engine is not a black box.
~/.claude/skills/visual-teach/ — the engine
# the one shell every page copies, byte-for-byte assets/lesson-template.html # BEGIN/END SHARED SHELL + two fill slots assets/index-template.html # the hub, grouped by Module # the 20 copyable demo exemplars (lift markup + CSS + JS) assets/demos/05-design-system.html assets/demos/07-prototype-animation.html assets/demos/08-prototype-interaction.html assets/demos/09-slide-deck.html assets/demos/10-svg-illustrations.html assets/demos/19-editor-feature-flags.html assets/demos/15-research-concept-explainer.html # the four reference files that govern the build references/build-guide.md # shell, tokens, nav, i18n, the verify checklist references/demo-catalog.md # the 20 types + the debate procedure references/svg-patterns.md # dark-safe inline-SVG rules references/teaching-language.md # Simple-layer + analogy + quiz design references/pedagogy.md # knowledge/skills/wisdom · fluency vs storage · ZPD
# every reference and demo exemplar ls ~/.claude/skills/visual-teach/references/ ls ~/.claude/skills/visual-teach/assets/demos/ # the two fill slots in the shared shell grep -n "LESSON-SPECIFIC" ~/.claude/skills/visual-teach/assets/lesson-template.html
# the hub and a lesson — open from file://, no server needed open ~/courses/loop-engineering/index.html open ~/courses/loop-engineering/lessons/0013-visual-teach.html # confirm zero external requests (no http/https/cdn references) grep -nE "https?://(?!.*w3\.org)" ~/courses/loop-engineering/lessons/0013-visual-teach.html || echo "self-contained ✓"
Scaffold from lesson-template.html (shell intact, body a <!-- FILL --> marker), replace the marker with the content, drop each lifted demo's CSS into the one LESSON-SPECIFIC CSS slot and its wiring into the one LESSON-SPECIFIC JS slot, namespace every id/class/marker per demo, then mirror into pt/ and verify by opening both. That is precisely the pipeline you watched and drove above.