Component gallery
Every interactive lesson component with its Storybook-style demo states. All data is simulated — no model connected yet.
<Duel />
Before running
The starting state: brief, editor, live token count, and the locked model lane.
Get the model to answer “Canberra.” using as few prompt tokens as you can. Politeness is expensive.
After the learner runs (win)
A passing, cheaper attempt: one-sentence verdict, gap number, both receipts, quiet delta.
Get the model to answer “Canberra.” using as few prompt tokens as you can. Politeness is expensive.
The reveal (open)
The teaching peak: the annotated optimal attempt, spans focusable, notes in a live region.
Get the model to answer “Canberra.” using as few prompt tokens as you can. Politeness is expensive.
Checker failed (kindly)
The attempt missed the requirement; the receipt explains what, not just a red mark.
Get the model to answer “Canberra.” using as few prompt tokens as you can. Politeness is expensive.
Cold-start — excluded
A cold-start receipt is flagged excluded; it doesn’t enter the ledger or the verdict.
Get the model to answer “Canberra.” using as few prompt tokens as you can. Politeness is expensive.
Capability missing → replay
The connected model lacks a required capability, so the attempt runs from a replay fixture.
Get the model to answer “Canberra.” using as few prompt tokens as you can. Politeness is expensive.
This lesson needs capabilities the connected model lacks — running your attempt from a replay fixture.
No model connected
Without a client the learner can write but not run; the state says so honestly.
Get the model to answer “Canberra.” using as few prompt tokens as you can. Politeness is expensive.
No model connected — connect one to run your attempt.
<Duel · authored fixture />
Authored fixture — m1-l2 (revealed)
The real m1-l2 token-economics duel task, seeded to a completed attempt with the reveal open — the annotations are the fixture’s own.
Get the model to translate “The train is late.” into French. It must contain “retard”. Then do it again spending fewer tokens than the model’s optimal prompt.
<ReceiptHistory />
Converging history
Six duels trending from model-wins to learner-wins, with a baseline shift where the model was upgraded.
Your convergence
Token gap to the model, duel by duel. Below the line, you’re cheaper than the model.
Empty state
Before any duel — the empty state sells what the chart will become.
Your convergence
Token gap to the model, duel by duel. Below the line, you’re cheaper than the model.
No duels yet
Run your first duel and this chart starts drawing itself — one point per attempt, tracing how your gap to the model closes as you learn the mechanism.
<Receipt />
Plain usage receipt
The lightweight form Playground and ParamCompare show — tokens in/out only, no model or latency to report.
Duel receipt — pass
A full duel receipt: pass badge, verdict, reason, model + version, generation latency, expandable.
passYour attempt:14 input · 20 output tokens— You win by 12 tokensDetails ▾
Duel receipt — fail (kindly)
The checker did not pass; the reason explains what was missing, never just a red mark.
failYour attempt:9 input · 5 output tokensDetails ▾
Cold-start — excluded
A cold-start receipt is visibly flagged and excluded from the ledger and the verdict (ADR-027).
Model attempt:14 input · 18 output tokensDetails ▾
With projected commercial cost
Local inference is free; a commercial figure appears only as a labeled projection beside it, never blended in.
Model attempt:512 input · 256 output tokensDetails ▾
<Playground />
Empty chat
Fresh playground with parameter controls, simulated replies.
Seeded conversation
Starts mid-conversation with a system prompt and a turn limit of 3.
Without parameter controls
Minimal chat surface for early lessons.
Usage receipt & live counter
Prefilled prompt, live token estimate while typing, usage receipt after each reply, exercise goal.
- Rewrite the prompt to ≤ 15 tokens
💡 The counter under the input is your judge.
<TokenizerViz />
Empty
Starts blank — skeleton while the tokenizer loads, live count as you type.
English sentence
Editable text, ids visible, leading spaces shown as ␣ — the default lesson configuration.
Long German compound
A single German compound word shatters into sub-word tokens; compared against its English translation with the count delta.
💡 Same meaning, wildly different token counts.
Emoji
Emoji are encoded as UTF-8 byte pieces — one glyph can cost several tokens, and partial bytes render as �.
💡 The family emoji is several code points joined by invisible zero-width joiners — count them.
JSON payload
Structured data is token-dense: every bracket, quote and key costs tokens.
With evaluated goals
Goals are checked live against the input and latch once met; all met shows the pass state.
- ☐One word ≥ 5 tokens
- ☐≥ 20 characters ≤ 2 tokens
Pre-computed tokens
Renders tokens supplied by the lesson author — no tokenizer is loaded at all.
<ContextMeter />
Plenty of room
A short conversation in a 128k window.
Nearly full
An 8k window at 92% — the warning state.
Context nearly full — oldest history will be truncated soon.
Overflow
More tokens than the window holds — the error state.
Context window exceeded!
<ParamCompare />
Temperature spread
Same prompt at temperature 0, 0.8 and 1.5.
Describe rain in one sentence.
Rain is water falling from clouds in drops.
Rain drums softly on rooftops, turning streets into mirrors.
Rain: the sky rehearsing its silver piano across a city of umbrellas.
Prompt cost comparison
Per-variant prompts compared by usage receipt instead of output.
The capital of Australia is Canberra.
Canberra.
💡 Same question, same answer — compare the input tokens.
Two-way comparison
Two variants side by side, with top-p shown.
Name a plausible startup idea.
A scheduling tool for small dental practices.
Subscription greenhouses that text you when your tomatoes are lonely.
<ToolCallDemo />
Single tool call
The classic weather example: question → call → result → answer.
- User
What is the weather in Hamburg?
Chained tool calls
Two dependent calls: fetch weather, then convert units.
- User
Weather in Berlin, in Fahrenheit please.
- Assistant calls get_weather({"city":"Berlin"})
- get_weather returns: {"tempC": 22}
- Assistant calls convert_units({"value":22,"to":"F"})
- convert_units returns: {"value": 71.6}
- Assistant
Berlin is currently at 71.6 °F (22 °C).
<Terminal />
Read-only transcript
Shows a finished session, e.g. an API call with curl.
Interactive with canned commands
Learner can type; a small command table answers. Try "tokens --count 'hello world'".
<Quiz />
Token basics quiz
Two questions with explanations on every choice.
What does a language model actually process?
Single question
The smallest possible quiz — one question inline in a lesson.
Higher temperature means…