diff --git a/.claude/commands/think-in-html.md b/.claude/commands/think-in-html.md
index 9313fee..8528b4a 100644
--- a/.claude/commands/think-in-html.md
+++ b/.claude/commands/think-in-html.md
@@ -1,43 +1,71 @@
# /think-in-html
-Generate an interactive HTML explainer from code, thinking transcripts, or text. The output is a single self-contained `.html` file that anyone can open in a browser — no server, no dependencies.
+Generate an interactive HTML explainer from code, thinking transcripts, or text. The output is a single self-contained `.html` file that anyone can open in a browser — no server, no dependencies. **Every explainer is authored fresh — a different design and a different interactive model each time.**
## Arguments
-$ARGUMENTS — the target to analyze. Can be a file path, folder path, or a description of what to analyze. Optionally prefix with `--mode code|thinking|text` (defaults to `code`).
+$ARGUMENTS — the target to analyze (a file path, folder, or a description of what to explain).
+Optional flags:
+- `--mode code|thinking|text` — the kind of input (default `code`).
+- `--blocks` — use the legacy template engine (schema-validated teaching blocks + preset skins) instead of freeform. Use only when the user explicitly wants the templated output.
+- `-o ` — output file (default `output.html`).
-## Steps
+## Default flow — Freeform (author the whole page on the fly)
-1. **Determine mode.** Parse `$ARGUMENTS` for `--mode`. Default to `code` if not specified.
+This is the default. You design and build a complete, bespoke, interactive HTML file for
+THIS subject — its own layout, its own visual system, its own interactive logic. **No two
+outputs should look alike, and the interactive part must be driven by the subject's real
+logic**, not decoration.
-2. **Read the instructions.** Read these files from the project root (or from wherever `core/` lives):
- - `core/instructions/ANALYZE.md` — how to think like a teacher and compose a lesson
- - `core/instructions/mode-{mode}.md` — mode-specific guidance
+1. **Read the instructions.** Read `core/instructions/FREEFORM.md` (the quality rubric,
+ the "make the core mechanic tangible" mandate, the variety requirement, and the hard
+ self-contained safety constraints). Also read `core/instructions/mode-{mode}.md` for
+ input-type guidance.
-3. **Read the schema.** Read `core/schema/analysis.schema.json` to understand the block contract (`schemaVersion: 2`).
+2. **Read the target thoroughly.** Understand the real logic, constants, names, and edge
+ cases. If it's a folder, pick the single most teachable flow — don't try to cover
+ everything.
-4. **Think like a teacher, then compose.** Don't pour the code into a fixed template. Decide
- the best way to teach THIS subject — pick a real-world analogy if one helps — and compose an
- ordered list of teaching blocks (`hook`, `analogy`, `flow`, `steps`, `concept`, `code`,
- `compare`, `aha`, `quiz`, `recap`, `glossary`) that fits. Every lesson should feel bespoke.
+3. **Pick the core mechanic to make tangible.** Decide the one dynamic the reader should
+ be able to *play with*, and design a small working model of it that reimplements the
+ subject's real rule (same formula/thresholds/states).
-5. **Emit analysis JSON.** Write valid JSON to `analysis.json` in the project root. It MUST
- conform to the schema (a non-empty `blocks` array; every block has a known `type`). You may
- set a default `meta.skin`, but the viewer can switch skins live regardless.
+4. **Choose a bespoke design direction** from the domain — palette, layout, type, and a
+ recurring motif — deliberately different from anything you've produced before.
-6. **Build the HTML.** Run:
+5. **Write the single `.html`** to the output path with everything inline (CSS + JS), the
+ required CSP ``, system fonts, and any imagery as inline SVG / `data:` URIs.
+ Escape anything echoed verbatim from the source. No network at runtime.
+
+6. **Validate self-containment:**
```
- node core/build/inline.mjs analysis.json -o output.html
+ node core/build/check-html.mjs output.html
```
+ Fix every error it reports and re-check until it passes.
+
+7. **Report.** Tell the user where the file is and, in one line, what the interactive
+ centerpiece lets them do.
+
+## Legacy flow — Blocks (`--blocks`)
+
+Only when the user explicitly asks for the templated engine:
-7. **Report.** Tell the user where the output file is, and that they can switch the visual skin
- (Aurora / Storybook / Blueprint / Terminal, plus 🎲 Surprise me) live in the top-right.
+1. Read `core/instructions/ANALYZE.md` and `core/schema/analysis.schema.json`.
+2. Compose an ordered `blocks` array (`hook`, `analogy`, `flow`, `steps`, `concept`,
+ `code`, `compare`, `aha`, `quiz`, `recap`, `glossary`) and an optional bespoke `design`
+ theme (ANALYZE.md → *Step 3*).
+3. Write `analysis.json`, then `node core/build/inline.mjs analysis.json -o output.html`.
+4. Report the output path; the reader can switch skins live in the 🎨 picker.
## Important
-- The JSON must pass schema validation. If `inline.mjs` reports errors, fix the JSON and rebuild.
-- Use `textContent`-safe strings — never include raw HTML in `plain` or `technical` fields.
-- The `plain` field is teacher voice: explain like the reader has never seen code before.
-- `technical` is optional — only include it when there's meaningful extra detail.
-- Keep the walkthrough linear and narrated — each step should feel like "and then..."
-- Quiz questions test understanding, not trivia. Always explain the answer.
+- **Freeform must pass `check-html.mjs`** — if it flags an external resource, inline it (or
+ use a `data:` URI) and re-check. The file must work fully offline.
+- **Different every time.** If your draft resembles a hero + card grid you've used before,
+ choose a different structure. Let the subject pick the shape.
+- **Real logic, not a cartoon.** The interactive model must reflect the source's actual
+ behavior — read the code and use its real constants and names.
+- **Teacher voice.** Explain like the reader is smart but new to this; gloss jargon in
+ plain English.
+- A worked reference at the intended quality bar:
+ `examples/novus-pricing-desk.freeform.html`. Study it, then build something different.
diff --git a/.gitignore b/.gitignore
index 6712eed..3c5cc84 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,3 +15,6 @@ output/
/*.analysis.json
.vii/
+
+# Local-only planning docs (not pushed)
+/LANDING-PLAN.md
diff --git a/CLAUDE.md b/CLAUDE.md
index aec0248..368ff17 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -2,34 +2,62 @@
A tool-agnostic engine that turns code, AI thinking transcripts, or text into self-contained interactive HTML explainers.
-## Architecture
+There are two generation modes. **Freeform is the default.**
+
+### Freeform mode (default) — the AI authors the whole page on the fly
+
+```
+target input → AI reads core/instructions/FREEFORM.md → writes a bespoke output.html → check-html.mjs validates self-containment
+```
+
+The AI designs and builds a complete, unique, interactive HTML explainer per subject —
+its own layout, visual system, and an interactive model of the subject's core mechanic.
+No two outputs look alike. The only hard invariant is that the file is a single
+self-contained artifact that works offline.
+
+- `core/instructions/FREEFORM.md` — the rubric: "make the core mechanic tangible", the
+ variety mandate, and the hard self-contained safety constraints.
+- `core/build/check-html.mjs` — zero-dep validator that rejects any external resource
+ load (external `
+