Skip to main content
Choreography is where courses go from “slides with voiceover” to “narrated film.” The screen should never be static while narration is playing.

The Density Rule

Every sentence must have at least one trigger. Many sentences need two or three.
A paragraph with no triggers is a bug. Fix it by adding a focus shift, a zoom change, an annotation, or a show/hide.

Why Density Matters

Triggers fire at their word position. TTS speaks the narration. The listener’s eyes track what’s changing on screen. If nothing changes, the listener’s attention drifts. If the visual changes align perfectly with the spoken words, the listener is locked in. This is Mayer’s temporal contiguity principle taken to the extreme: not just “narration and visuals at the same time” but “narration and visuals synchronized at the word level.”

Minimum Trigger Density

Paragraph typeMinimum triggersTypical triggers
Introducing a block1 (show)1-2 (show + focus)
Walking through code2 (focus + annotate)2-3 (focus + zoom + annotate)
Comparing two things2 (focus left + focus right)3-4
Making a point1 (zoom or annotate)1-2
Transitioning1 (clear or unsplit)1-2 (clear + show)
Concluding a section1 (zoom reset or focus none)1-2

Animation Selection

Which Animation for What

SituationEffectDurationEasingExample
First code revealtypewriter1.5-2slinear{{show: hash-fn typewriter 2s linear}}
New concept replaces oldslide0.3-0.5sease-out{{show: solution slide 0.3s}}
Result or conclusionslide-up0.3sease-out{{show: result slide-up 0.3s}}
Focal element appearinggrow0.4-0.5sspring{{show: diagram grow 0.5s spring}}
Data structure snapping ingrow0.3-0.5sspring{{show: tree grow 0.4s spring}}
Preview alongside codeslide0.5sspring{{show: preview slide 0.5s spring}}
Reference materialnone{{show: table none}}
Hiding somethingfade0.3sease-out{{hide: old-code fade 0.3s}}
Scene breakslide{{clear: slide}}

Duration Guidelines

  • Micro-interactions (focus shifts, annotations): instant state changes, no duration
  • Content transitions (show/hide): 0.3-0.5s—fast enough to not feel sluggish, slow enough to register
  • Typewriter reveals: 1.5-2s for 10-20 lines. Aim for ~100ms per line
  • Scene clears: use the default
Never exceed 400ms for product UI interactions. Only typewriter (a deliberate slow reveal) goes longer.

Typewriter Choreography

Typewriter makes code appear line by line, creating a “live coding” feel.

When to Use

  • The FIRST time a code block appears in a step
  • When you want the audience to absorb code incrementally
  • When the code is the star of the scene (not a supporting element)

When NOT to Use

  • Re-showing a block that was visible earlier (use slide or fade)
  • Supporting code that accompanies a primary visualization
  • Blocks over 40 lines (pacing breaks down)
  • Quick reference or boilerplate code

Duration Formula

duration = lines * 0.1s is a reasonable starting point:
  • 10 lines → 1s
  • 15 lines → 1.5s
  • 20 lines → 2s
Don’t go faster than 50ms/line (too glitchy) or slower than 150ms/line (too tedious).

Narration During Typewriter

Start narrating while lines are still appearing—the audience reads ahead naturally. Don’t wait for the typewriter to finish before speaking.
{{show: dijkstra typewriter 2s linear}} Here's Dijkstra's algorithm in code.

{{focus: init}} {{zoom: 1.3x}} Set every distance to infinity except the start.

Zoom Choreography

Zoom is the most underused and most impactful tool. It controls what the learner can actually read.

The 15-Line Rule

Any code block over 15 lines MUST have zoom choreography. At normal scale (1x), the bottom of a 20+ line block is below the viewport. The learner sees a focus highlight but can’t read the code. This is a failure.

The Zoom Pattern

1x          Show full block for context
  ↓ focus
1.2x-1.3x  Zoom in on focused region
  ↓ explain
1x          Reset before jumping to a distant region
  ↓ focus
1.2x-1.3x  Zoom in on new region
  ↓ explain
1x          Reset to show full picture

Zoom Scales and Their Purpose

ScalePurposeWhen
0.8xZoom out to show more contextRarely. Only for very wide diagrams.
1xNormal. Full block visible.Reset between focus jumps. End of section.
1.1xSlight emphasis. Current context.Gentle nudge: “look at this area.”
1.2xStandard zoom. Key insight.Most common zoom level for code walkthrough.
1.3xDramatic. Critical moment.Factorial growth, key formula, the aha moment.
1.5x+Extreme. Single line emphasis.Rare. Only for very important single lines.

Zoom + Focus + Annotate (The Triple)

The most powerful choreography pattern combines all three:
{{focus: pick}} Now the key step. {{zoom: 1.2x}} Pick the unvisited node with the smallest known distance. {{annotate: pick "Greedy choice"}}
  1. Focus fires → region highlighted, everything else dimmed
  2. “Now the key step” → builds anticipation
  3. Zoom fires → region enlarged, legible
  4. Explanation follows while zoomed in
  5. Annotation fires → concept labeled
This triple is the workhorse of code walkthroughs.

Zoom Transitions

Always reset to 1x before jumping to a distant region:
{{zoom: 1x}} {{focus: return-val}} {{zoom: 1.2x}} Down at the bottom, the return value.
If you jump from 1.3x on line 3 to 1.3x on line 18, the viewport snaps violently. Resetting to 1x first shows the full block, then zooms into the new target smoothly.

Focus Choreography

Focus is your primary attention tool. Default to focused.

Always Focus After Showing

An unfocused 20-line code block is overwhelming. The listener doesn’t know where to look.
{{show: hash-fn typewriter 2s linear}} Here's our hash function.

{{focus: signature}} It takes a string and returns a number.
Show → establish context → focus immediately on the first thing you’ll explain.

Walk Regions Top to Bottom

Read code in reading order. Focus shifts should follow the natural flow:
{{focus: signature}} The function signature.
{{focus: init}} Initialize the accumulator.
{{focus: loop}} The loop processes each character.
{{focus: return-val}} Return the result.
Jumping from line 15 to line 2 to line 20 is disorienting. If you must jump, reset focus and zoom first.

focus: none

Use none to clear focus in two situations:
  1. Show the whole picture: “Step back and look at the whole function.”
  2. Before clearing: Reset before {{clear}} so the transition feels clean.
{{focus: none}} {{zoom: 1x}} That's the whole algorithm. Every step justified.

{{clear: slide}}

Split Choreography

Split mode shows two blocks side by side.

Entry Pattern

{{split}} {{show: source slide 0.3s}} {{show: preview slide 0.5s spring}} Here's the code and what it produces.
  • split enables multi-panel mode
  • Left panel enters first (0.3s)
  • Right panel enters slightly delayed (0.5s) with a playful spring
  • Narration begins after both are visible

Convention: Left = Code, Right = Visual

The explanation/source is on the left. The result/preview/diagram is on the right. This convention means the learner always knows where to look.

Working in Split Mode

While split, you can focus on either panel’s regions:
{{focus: signature}} On the left, the function signature.

{{focus: button-text}} On the right, see how it renders.
Focus works across panels—the system finds which block contains the region.

Exit Patterns

Unsplit (keep one):
{{unsplit}} Now just the code.
Keeps the last-shown block. The other panel exits. Clear (fresh start):
{{focus: none}} {{unsplit}} {{clear: slide}}
Clean exit: unfocus, unsplit, clear. Complete reset.
Never use more than two panels. Three-panel layouts are too cramped and confuse the eye.

Clear Choreography

Clear is a scene break. Use it between conceptual sections.

Transition Types

TransitionFeelUse when
slideDirectional, progressiveMoving to the next concept (default)
fadeGentle, connectedBridging related ideas
instantHard reset, no ceremonyStarting a completely new section

Clear Frequency

2-3 clears per step is typical. More than 4 means your step has too many concepts—split it.

What Clear Resets

Everything. After clear:
  • Slots: empty
  • Focus: none
  • Annotations: gone
  • Zoom: 1x
You must {{show: ...}} something new after every clear. A clear followed by narration with no show means the audience hears narration while looking at nothing.

Pre-Clear Cleanup

Before clearing, clean up the scene:
{{zoom: 1x}} {{focus: none}} That's the complete picture.

{{clear: slide}}

{{show: next-thing}} Now let's look at...
This feels intentional. Resetting zoom and focus → brief pause with full view → clean transition → new content.

Transform Choreography

Transform morphs one data block into another. Nodes with the same ID slide smoothly from old to new positions.

The Transform Pattern

Every algorithmic operation follows a three-beat rhythm:
  1. Setup — focus the region about to change
  2. Trigger{{transform: v0->v1}} fires the structural change
  3. Resolve — narrate what just happened while the animation plays

Tree Operations

Insert into BST:
{{focus: leaf-parent}} We compare with six. {{transform: tree-v0->tree-v1}} Four goes left. The new node slides in from its parent's position.
Rotation (AVL/Red-Black):
{{annotate: unbalanced "bf=2"}} This node is unbalanced.
{{transform: avl-v0->avl-v1}} A right rotation fixes it. Watch the nodes slide to their new positions.
Rotations are the most visually dramatic transform—three nodes rearrange simultaneously. Keep narration short so the viewer watches the movement.

Hash Map Operations

Insert with hash computation:
{{annotate: input "h(key)=3"}} Hash of the key lands in bucket three.
{{focus: bucket-3}} That's this bucket.
{{transform: hm-v0->hm-v1}} The new entry appends to the chain.

Transform Timing

OperationRecommended pauseWhy
Single node insert/delete0s (narrate immediately)Simple, viewer grasps instantly
Rotation1-2s pauseThree nodes moving simultaneously
Split (B-tree)1-2s pauseComplex structural change
Consolidation step0.5-1sRepetitive, keep pace up
Path compression1sMultiple edges changing at once
Recoloring0sSubtle, narrate over it

The Storyboard Test

Before writing narration, sketch the sequence of screens your step will produce. Each screen = one scene. A scene is: which blocks are visible + which region is focused + any annotations + zoom level.
Scene 0:  [empty]
Scene 1:  [hash-fn] — typewriter reveal
Scene 2:  [hash-fn, focus: signature, zoom: 1.3x, annotate: "The API"]
Scene 3:  [hash-fn, focus: loop, zoom: 1.2x]
Scene 4:  [hash-fn, focus: return-val]
Scene 5:  [hash-fn, focus: none, zoom: 1x]
Scene 6:  [clear: slide]
Scene 7:  [buckets] — enter from right
...
If the storyboard feels choppy, rethink the sequence. If there are big jumps between scenes, add intermediate steps. If three scenes in a row look the same, you’re not using focus/zoom/annotate enough.

Build docs developers (and LLMs) love