Skip to main content
Nine patterns, one for each thing an author actually wants a slide to do. Every one is adapted from the two decks decktalk init writes, so each is markup the runtime already accepts. Each recipe is three things: the markup for one slide, the cues.json rows that give its moments a second, and one sentence saying what the pattern costs to measure. That last sentence matters, because a reveal DeckTalk cannot measure is usually a reveal a viewer cannot see either.

Before you start

The recipes are slides of one scene numbered 4, which neither packaged deck uses. A project that followed Your first deck already has a section 4, so give the recipe the next free number instead, in the scene, the slide ids, the cues.json key and the section alike. To add one to a project:
  1. Paste the <template> inside a <div data-scene="4" data-name="…"> in the page’s <body>.
  2. Paste the recipe’s <style> rules into the page’s own <style> block.
  3. Paste the cues.json rows into "4": { "cues": [ … ] } inside sections.
  4. Add a [[section]] with number = 4, the page path and scene = "4" to decktalk.toml, and a ## 4. … section to script.md that speaks each phrase.
A moment inside <template data-slide="4.1"> is qualified with that slide id, so data-in="title" is the cue id 4.1:title and that is what cues.json carries. The recipes use the starter’s own custom properties, such as --ink and --accent, and its .eyebrow class. The recipes are laid out on the wide canvas, 1920 by 1080. For a square or vertical project, write their widths and left edges against --dt-width, as the starter does: var(--span) for 1680px and var(--margin) for 120px.

A title that arrives on its word

The heading and the bar under it are one element with one cue, so the whole block lands together.
deck/index.html
cues.json
What it costs to measure. A line of type is a few hundred pixels of ink, which is well under the 0.1 percent floor on its own. The 1000 by 12 accent bar arriving with it is 12,000 pixels, about 0.6 percent of the frame, and that is what carries the cue past CUE_THIN_CHANGE.

A list that staggers

One cue, and the container’s children arrive one step apart.
deck/index.html
cues.json
What it costs to measure. The whole spread is the step times the children after the first, plus the entrance, so this one is 0.04 × 3 + 0.24, which is 0.36 seconds. Anything at or above 0.5 seconds is PAGE_STAGGER_OVERRUN, and the arithmetic that says so is exact, so the finding is an error.

A figure that swaps for another

The card that leaves and the card that arrives share one cue. data-swaps holds the leaving card in place until its replacement has arrived, so the two read as one thing changing.
deck/index.html
cues.json
What it costs to measure. A swap is between one thing and one other thing. Zero elements leaving on the arrival cue, or two, is PAGE_SWAP_AMBIGUOUS and an error, and two halves landing far enough apart to read as unrelated is PAGE_SWAP_APART and a warning, which is why both cards here share a box.

An element that steps back while a second comes to the front

data-back dims an element to 45 percent and data-front brings it back. Neither is a second reveal, so neither needs a second element.
deck/index.html
cues.json
What it costs to measure. The step back takes 0.28 seconds and the return 0.20 seconds, both well under the ceiling. Attention only registers as a change when the element is large, because dimming a label to 45 percent moves too few pixels to clear the floor, so step back a whole panel rather than a line.

A line shown word by word on the voice

data-words matches the element’s own text against the section’s spoken words and reveals it one word at a time, each word whole by the second the voice reaches it.
deck/index.html
cues.json
What it costs to measure. One word lighting up is far under the change floor, so the runtime reports the line through its own telemetry instead of through pixels, and the band fading in on the cue is what the frame comparison sees. The text has to be the words the narration really says, or the line earns PAGE_WORDS_NOT_FOUND. data-words defaults to highlight, which starts every word dim. data-words="appear" starts them absent and is limited to eight words, above which it earns PAGE_APPEAR_TOO_LONG.

A number that counts up

data-count="last" grows the last number in the text from zero when the element arrives, and data-count="first" grows the first one, so the figure the voice says and the figure on screen land together.
deck/index.html
cues.json
What it costs to measure. The count runs 0.44 seconds, which ties with the draw entrance as the longest span the contract declares and stays under the 0.5 second ceiling with a frame to spare. The digits alone are a slow, thin change, and the filled band arriving underneath them is what the cue is measured on. The script writes the figure in words, because a cue phrase is matched against spoken words.

A formula typeset with KaTeX

data-tex holds the TeX and the element’s own text is the readable fallback. data-tex-display makes it a display equation on its own line.
deck/index.html
cues.json
What it costs to measure. Typeset glyphs are thin, so the equation sits in a filled panel that arrives with it and carries the change. Write the fallback text as correct, fully parenthesised mathematics that reads well out loud, because it is what shows if KaTeX never loads, it is what the transcript prints, and it is what a screen reader reads. In markup a backslash is written once. KaTeX refusing the TeX is PAGE_KATEX_ERROR and the element falls back to that text, and a page with no KaTeX at all is PAGE_KATEX_MISSING.

A class change the page’s own stylesheet animates

data-class adds a class at a cue, written as cue:class pairs. It is how a page makes a change the contract has no word for.
deck/index.html
cues.json
What it costs to measure. This is the one span the contract cannot bound in advance, so DeckTalk lays the slide out, adds each class and reads the longest transition the stylesheet gives it. Keep it under half a second. Each class needs its description in data-describe-class or the change earns PAGE_CLASS_UNDESCRIBED, and the stylesheet must drop the motion under .dt-reduced or a reduced build earns PAGE_CLASS_NOT_REDUCED.

A cue only a handler serves

A cue that no moment attribute names has to be listed in data-owns, which is how a slide declares a cue it draws with script of its own.
deck/index.html
cues.json
What it costs to measure. Nothing in the contract bounds a handler, so the length and the size of the change are yours to keep honest: hold the motion under half a second and move something large enough to clear the change floor, or the cue reads as CUE_NO_CHANGE. A cue named in data-owns that the deck never declares is PAGE_CUE_UNKNOWN, and a handler that throws is PAGE_HANDLER_THREW, which leaves that moment doing nothing rather than failing the page.

Next