dojocodinglabs/instructional-design-toolkit · Archived

workbook-generate

Interactive course workbook design system — turns a course's text classes into one standalone, accessible, interactive HTML explainer (a navigable document chunked by module, Articulate-Rise lesson model; stepped mode for screen-recording). Defines the curated component kit, the content-shape -> component mapping rules, the accessibility contract, and the consumer-spec (instruction-bundle-spec.yaml) consumption + graceful-degrade rules. Consumer plugins own the brand tokens and the component vo…

First seen Jun 17, 2026

Installation

$ npx skills add dojocodinglabs/instructional-design-toolkit --skill workbook-generate

Stronger alternatives

This repository is archived — consider an actively maintained alternative.

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Repository health

Stars 1
License LICENSE
Default branch main
Open issues 1
Status Archived

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 21,983 B
  • docs SUMMARY.md 602 B

History

  1. First seen on skills.sh
  2. First recorded snapshot · 1 installs

SKILL.md

Interactive Workbook Design Knowledge Base

This skill encodes the design system for interactive course workbooks — a single, standalone, self-contained HTML artifact that renders a whole course's text classes (text-*.md) as an interactive explainer the learner scrolls or steps through.

It is the student-facing sibling of course-visualize (which produces an instructor-facing analytics view of the same course). Where slides-generate turns a video brief into a deck for live teaching, workbook-generate turns the reading classes into a self-study / screen-share artifact.

The philosophy is borrowed from interactive-HTML explainers: a concept should recover its natural shape. A process becomes a navigable flow, a comparison becomes a side-by-side, code becomes annotated-and-copyable, and "do you follow?" becomes a reveal + a check question. Interaction is felt, not described — but it is delivered through a curated, tested component kit, not freeform per-concept JavaScript.

What this skill is NOT

  • It is not a slide system (slide-design / slides-generate own that).
  • It is not a persistence layer. V1 holds all learner answers **in memory

only** — refresh resets. No localStorage, no postMessage, no parent-frame communication, no backend. (Those are deliberately deferred.)

  • It does not ship brand tokens. Palette / typography / voice come from the

consumer's instruction-bundle-spec.yaml. This knowledge base is voice-neutral and must stay that way (the "would this help an instructor in Argentina shipping a Python course on Moodle?" test).

The artifact (per-course by default)

One workbook-{course-slug}.html covering all modules of a course, with:

  • a module-chunked navigable flow (default, scroll_behavior: doc): one

module ("lesson") shows at a time — the Articulate-Rise model, not one endless scroll. A stepped flow (one screen at a time, for screen-recording) is the alternative. No scroll-snap — plain smooth scroll within a lesson.

  • a table of contents that switches the active module — a **sticky sidebar

on desktop, a collapsible "Contents" menu on mobile** (a slim sticky bar + toggle, never a wall of links pushing content down);

  • a progress indicator (module-based) and, at each module's end, an **arc

indicator ("Module N of M") + a forward-hook** Next control;

  • interactive blocks chosen to match each piece of content's shape (see the

mapping rules below).

Light-touch storytelling (structure here, voice in the overlay)

The base ships the slots that give a course narrative momentum, voice-neutral: the arc indicator (where you are), and a forward-hook on the Next control — a primary action line (Next: {title} →) plus an optional teaser line that is a voice slot. Leave the teaser empty in the base draft (it hides via :empty, so a generic consumer just sees Next: {title} →); the consumer's voice overlay fills it with momentum copy (the L3 "momentum endings" concern). Richer beats (transition/closure cards, connective lesson intros) are a deliberate future addition, not in the base today.

An optional --scope module narrows generation to a single module (workbook-{module-slug}.html under that module).

The curated component kit

Each component is a documented, theme-variable-driven, accessible-by-construction block. This catalog is owned by IDT base — the canonical, voice-neutral vocabulary of what an interactive workbook can contain. The base template ships the HTML/CSS/JS for all of them; the command composes a workbook by selecting and filling them. A consumer MAY narrow, extend, or set options on this catalog via an optional workbooks.components override in their spec; absent that override, the full catalog is available with sensible defaults. The library itself never lives in the consumer spec — only brand theming and thin preferences do.

What interactivity is FOR here. The artifact's job is to **display rich
information**. Per the source thesis, interactivity earns its place in exactly
two ways: (a) felt understanding — drag/click and see the effect
(knobs, diagrams, simulations); or (b) closing the loop — hand the learner
something to take back to Claude or a mentor (export / copy-as-prompt).
It does NOT capture answers. Because V1 persists nothing, a widget that
records a learner's input and does nothing with it (an ungraded quiz to
nowhere, a reflection box that evaporates on refresh) is an anti-pattern.
Self-check belongs in predict-and-reveal (immediate, no capture); taking
work forward belongs in export.

Baseline (always available)

Component Purpose
step / section A unit of the flow. Each H2 of a reading is typically one step.
lede A one-line lead paragraph (.wb-lede) that frames a step before the body. Bigger, muted; sets up what the step is about.
statement / callout A bordered emphasis block for a load-bearing sentence; key words in <strong> render in the accent.
quote A pull-quote (.wb-quote <blockquote> + optional <cite>) for a memorable/authoritative line.
progress bar Course-level and per-module completion %. Updates as the learner advances.
completion event Fired (not persisted) when the learner reaches the end. A hook point for V2.

Progressive disclosure

Component Purpose
accordion Collapsible detail blocks. Scaffolds complexity — TL;DR open, depth on demand.
tabs Parallel variants on one surface (e.g. "Python / JS / Go", "before / after").
reveal Hide content until the learner asks for it.
predict-and-reveal A "think about this first" prompt + a hidden model answer / expert take. The self-check pattern — pedagogy via retrieval + immediate feedback, with no capture and no grading. Replaces ungraded quizzes/input boxes.

Loop-closer (the "stay in the loop" move)

Component Purpose
export / copy-as-prompt A button that copies a ready-made prompt (or the learner's notes) to the clipboard so they can paste it into Claude or send it to a mentor. The only way interaction leaves a no-persistence artifact — turns passive display into two-way. Clipboard has a file:// fallback.

Inline SVG (restores the spatial dimension)

Component Purpose
flow diagram A process / pipeline as clickable, ordered steps.
comparison diagram Two or more options laid out spatially for contrast.
chart A small bar / line chart. Hand-rendered SVG with precomputed coordinates (no runtime scale fn) and the single salient datum recolored to the accent (.is-peak) while the rest stay neutral — the highlight is itself a teaching move. No library.
annotated figure An SVG figure with callout labels.

Annotated code

Component Purpose
code block Syntax-styled code with a copy button (with a file:// clipboard fallback) and optional margin annotations / line callouts. High value for a coding curriculum. Syntax highlighting is dependency-free: wrap tokens by role in <span>s — kw (keyword), str (string), num (number), fn (function/type), cmt (comment). Fixed legible hues on the dark code surface (not brand tokens).
code diff A before -> after variant of the code block: removed lines (.diff-del, struck through) and added lines (.diff-add) banded inline. Teaches the change, not just the result — the core move of teaching code.

Parametric knob (the reliable "felt" interaction)

Component Purpose
knob A slider whose value writes a CSS custom property (--knob) that a preview element consumes and a readout mirrors. Lets a learner drag and watch the effect — the felt interactivity of the reference site's simulations, delivered through a fixed, tested component rather than bespoke per-concept JS. In-memory only.
knob (split-bar) The is-split preview variant: a full-width A-vs-B bar where the value portion is the accent and the remainder is --wb-accent-2, with a 2-item legend. Use when the value is one side of a split (e.g. P(1) vs P(0)) so the bar matches a caption that names both outcomes. Same --knob wiring — no extra JS.

Course navigation

Component Purpose
module chapter A titled chapter grouping a module's reading steps.
table of contents Jump-to navigation across modules; reflects progress.

Stretch tier (only when a concept truly needs it — add deliberately, test it)

Component Purpose
live simulation A measured simulation — state array -> recompute -> diff-vs-previous -> re-render, with a readout that prints the lesson's key metric live (e.g. "25% of keys moved"). The most powerful pattern in the reference, but the most expensive to generate/QA — reach for the knob first.
state visualizer A small interactive state machine / structure (e.g. add/remove nodes) for a concept best understood by manipulation.

These are the most fragile to generate and the most expensive to QA. Prefer a baseline or disclosure component unless manipulation is the point of the lesson.

Semantic color language

Color carries consistent meaning across every component (and is always paired with text or an icon — never color alone, per the accessibility contract):

  • accent (--wb-accent) = the current / focal / interactive thing — the

active step, a selected tab, the salient datum on a chart, an interactive control, a key term.

  • good (--wb-good) = success / done / favourable — a completed step, the

favourable side of a comparison, added lines in a diff.

  • bad (--wb-bad) = removed / unfavourable — the weak side of a

comparison, removed lines in a diff.

This mirrors the reference site's clay / olive / rust roles. Consumers retheme the hexes via the spec's design.palette; the roles stay fixed so the visual grammar is stable across a course (stable grammar = lower cognitive load).

Content-shape -> component mapping (the pedagogical core)

Read the reading's prose and promote it into the component whose shape fits. These are heuristics — starting points, not a lookup table. Don't map mechanically (every table → the same chart). Pick the representation that best illuminates this concept, and deliberately vary across a course: if three sections each hold a comparison, they should not become three identical diagrams — find the angle each one needs. Monotony (every workbook the same shell with swapped text) is a failure mode, not a success criterion. With that framing, the heuristics:

  • Course -> module chapters (ordered by module directory), with a

table of contents and course-level progress.

  • **Each text-*.md** -> a run of steps inside its module chapter.
  • Each H2 -> a step / section.
  • A table -> a comparison diagram, tabs, or a chart (pick by

whether the table contrasts options, shows variants, or holds numbers).

  • An ordered "step 1 / 2 / 3" list or a described process -> a **flow

diagram** or a stepper.

  • A fenced code block -> an annotated code block; if it shows an edit

(old vs new), use the code diff variant.

  • A small dataset with a standout value -> a chart, recoloring the peak.
  • A tunable relationship ("as X grows, Y...") -> a knob so the learner

drags X and watches Y; reach for a live simulation only if measuring the outcome is the lesson.

  • A quotable / load-bearing sentence -> a statement / callout.
  • A digression or optional depth -> an accordion.
  • Parallel alternatives (languages, approaches) -> tabs.
  • End of each major section -> an optional predict-and-reveal self-check

(a "think about it first" question + a revealed model answer) — not a graded quiz. Sibling quiz-*.md files become predict-and-reveal checks.

  • Something the learner would want to take further (a parameter they tuned,

a reflection, a topic to go deeper on) -> an export / copy-as-prompt so it leaves the page as a prompt for Claude or a mentor.

  • Course intro -> a hero step; course end -> a recap + the

completion event.

Density guidance: not every paragraph needs a widget. Interactivity should earn its place — one well-chosen interactive block per concept beats five decorative ones. Long readings get chaptered and made collapsible so the single-file artifact stays navigable.

Invariant frame vs. creative payload (where the latitude is)

The base constrains the frame, not the ideas. Keep one set of things identical across every workbook; let the other set differ freely per concept and course:

  • Invariant (always the same): brand tokens (palette/typography), the

accessibility contract, the navigation/flow shell (TOC, progress, module chunking), and the standalone / no-CDN technical rules. Consistency here is the point — don't reinvent it.

  • Creative (should differ — make it differ): the prose and explanations, the

analogies and examples, what each diagram actually depicts, which components appear and how they're composed, chart data, comparison axes, knob parameters, simulation design. Two different courses should produce visibly different workbooks — not the same skeleton with the text swapped.

The kit is a floor, not a ceiling

The component kit is the reliable, tested baseline — not the limit of what you may build. The biggest creative surface is inline SVG: the kit gives you the styling shell (.wb-figure, brand colors, arrow markers), but what the figure depicts — a hashing ring, a token-bucket, a state machine, a spatial layout unique to the concept — is yours to author. When a concept needs a visualization the kit doesn't have, author it directly with inline SVG/CSS, honoring the design tokens + accessibility contract. Bespoke static / SVG / CSS visualization is encouraged. The only thing to avoid is fragile, untested stateful JS widgets — those should be added to the kit deliberately (and tested), not improvised per page.

Generation at scale: per-module fan-out (orchestration)

A per-course workbook can span many modules × text classes — more than one context window composes well in a single pass. So generation is size-gated:

  • Small course (≈ 2 modules or fewer) → compose linearly in one pass.
  • Larger course → map → reduce: dispatch one workbook-module-composer

subagent per module (in parallel, via the standard Task/Agent tool — never a session-specific orchestration tool; the command must stay portable), then the orchestrator assembles the returned fragments into the single self-contained workbook.

This is also a quiet win for variety: independent per-module composition resists the "I already used a chart, reuse it" monotony a single pass can fall into.

The fragment contract (what binds it together)

Each composer returns a MANIFEST ({ moduleId, title, steps[], components_used }) plus a FRAGMENT: one <div class="wb-module" id="mod-{N}"> of namespaced .wb-steps and kit components — not a full document. Rules:

  • ID & attribute namespacing: every id / aria-controls /

aria-labelledby / label for / form-control name is prefixed m{N}- (module index) so fragments concatenate without id collisions, broken label associations, or cross-module radio-group bleed.

  • Fragment only: no <html>/<head>/<style>/<script>, no .wb-progress, no

.wb-nav, no .wb-module__nav footer. Those are global and the orchestrator owns them — the footer is added at assembly so the "Module N of M" arc is correct.

  • No hardcoded brand: consume design tokens (var(--wb-accent), …), never

literal hex/fonts. Voice-neutral; the forward-hook teaser stays an overlay slot.

Why it stays consistent (no stitched-together feel)

The shared instruction-bundle-spec.yaml (brand / a11y / kit) is the binding contract handed to every composer, so fragments are visually uniform by construction. The assembler then runs a normalization pass — verify each fragment uses only allowed components, IDs are namespaced + globally unique, a11y roles are present — and runs the variety/fit self-check on the assembled whole. Drift is bounded by the frame, not left to chance.

Consuming the consumer spec (instruction-bundle-spec.yaml)

The workbook's brand + structural vocabulary comes from the consumer's instruction-bundle-spec.yaml (see the command for resolution order). This skill reads:

  • design (top level) -> palette, typography, voice, spacing,

components. Inlined into the generated HTML as CSS custom properties.

  • workbooks.scroll_behavior -> doc (navigable, module-chunked; default)

or stepped (one screen at a time, for recording). No scroll-snap.

  • workbooks.navigation -> TOC layout (sidebar desktop / collapsible mobile),

arc indicator, and the forward-hook on the Next control (teaser = voice slot).

  • workbooks.animation -> onenter transition + reducedmotion policy.
  • workbooks.step_patterns -> the available step layouts (hero, content,

quiz, branch, progress, ...).

  • workbooks.components (OPTIONAL) -> a consumer override layer on top

of IDT's built-in catalog (the vocabulary above, owned by IDT base). When present, it may enable/disable components, set options, or opt into the stretch tier. When absent, the full IDT catalog is available with sensible defaults — the workbook is fully rich, not plainer. The consumer spec never defines the library; it only themes and tunes it.

Validate before generating

Fail fast (with a clear, path-pointing error) when required keys are missing: design.palette.accent, design.typography.family.body, workbooks.step_patterns. Do not emit a half-themed artifact.

Graceful degrade (never crash)

If instruction-bundle-spec.yaml cannot be resolved from any source, emit the workbook anyway with neutral defaults (system-ui typography, a single monochrome accent, a generic stepped layout) and a visible WARNING — both to the user (stderr / chat) and as an HTML comment at the top of the generated file. Never silently produce a neutral artifact as if the spec said so, and never crash.

Standalone HTML contract

  • No CDN runtime dependencies. Corporate / school networks block them.

Fonts are the one allowed exception — a Google Fonts <link> with a system-ui fallback in the font stack.

  • No build step, no framework. Inline <style> and inline vanilla

<script>. The file opens in any browser by double-clicking it.

  • Design CSS inlined at generation time from the design palette/type.
  • Self-contained assets. Any image is inlined (e.g. base64) or referenced

relative to the file; nothing fetched at runtime.

Accessibility contract (not optional)

  • Full keyboard operation: Tab order follows reading order; **Enter / arrow

keys advance** steps; all interactive controls are focusable.

  • Landmark roles: each step is a role="region" with an aria-label; the

nav layer is a <nav>; progress uses role="progressbar" with aria-valuenow.

  • prefers-reduced-motion: reduce disables enter animations and smooth-scroll.
  • Color contrast meets WCAG AA for text on the chosen background (verify the

consumer's palette; the neutral defaults already pass).

  • State conveyed by text + icon, not color alone (e.g. diff add/del, comparison).

Anti-patterns

  • Hardcoding any brand token, copy, or "Dojo"-ism in this skill or the base

template. Brand lives in the consumer spec.

  • Hardcoding the component catalog or step patterns here instead of reading

them from the spec.

  • Fragile, untested stateful JS widgets improvised per page. Compose

stateful interactivity from the tested kit, and extend the kit deliberately (with tests) when a concept truly needs a new interaction. (This is not a ban on creative static / SVG / CSS visualization — author those freely; see "The kit is a floor, not a ceiling.")

  • Monotony. Mapping every content type to the same component so every

workbook is one shell with swapped text. Vary the representation to fit each concept; two different courses should look visibly different.

  • Decorative interactivity. Every widget must teach something the prose alone

could not convey as well.

  • Capture-to-nowhere widgets. Do not add inputs that record a learner's

answer and do nothing with it (ungraded quiz, reflection box). With no persistence they are dead ends. Use predict-and-reveal for self-check and export to take work forward.

  • Persisting state in V1. The completion event is a fire-only hook; nothing

else is stored.