Images, media & embeds

Images, video, audio, charts, tables, sandboxed embeds, themed widgets, and inline SVG.


Images

Use ![alt](src){ … }. Local paths are inlined into the output, so a built deck is one portable file. The brace is optional. It mixes tokens in any order:

Token Meaning
#id an element id. The same id on the next slide morphs into it, with transition: morph
.class .round (circular), .cover (fill and crop), .shadow
width=170px / height=… explicit size. Units allowed, no quotes
anchor: "x% y% w% h%" absolute placement in the slot. Quoted, colon form
![Paul](paul.jpg){.round width=170px}
![bg](hero.jpg){ anchor: "0% 0% 100% 100%" }

Video and audio

Use the image syntax with a media file extension.

  • Video (.mp4, .webm, .mov, .m4v, .ogv): ![](clip.mp4){ poster=cover.jpg width=60% } becomes a <video controls>. Add .autoplay for a muted, looping background clip.
  • Audio (.mp3, .wav, .ogg, .m4a): ![](track.mp3) becomes an <audio controls>.

In a PDF, media cannot play. Video falls back to its poster frame, so always supply one. Audio is dropped. Local media is inlined up to about 6 MB. Larger files are referenced by path, so keep them next to the built HTML.

Charts

Two fenced types render to theme-colored vector charts. They work in the web deck, PDF, PNG, and PPTX. slaide build bakes them to static SVG, so the final file has no chart engine in it.

  • ```mermaid for diagrams. Flowchart, sequence, state, ER, gantt. Match the shape to the slot. flowchart TD is tall, LR is wide.
  • ```echart for data charts. Write an ECharts option as JSON or YAML. A bad option warns and falls back to a code block. Series colors come from the master’s --chart-colors.
```echart
{ "xAxis": { "type": "category", "data": ["A","B","C"] },
  "yAxis": { "type": "value" },
  "series": [{ "type": "bar", "data": [5,9,7] }] }
```

Put a chart in a slot that has height. Use a 1fr row, not an auto row. Otherwise the chart collapses to a default shape.

Tables

Use standard Markdown pipe tables. The master styles them. For emphasis on a cell, use an inline [cell]{.class} span.

Safe dynamic embeds

For interactive content, rendered safely. It never runs inside the deck document.

  • ```embed takes one URL and renders a sandboxed <iframe>. Charts, maps, YouTube, Figma, Observable.
  • ```widget takes inline HTML and JS. It runs in a sandbox="allow-scripts" iframe with no same-origin access. The deck’s theme tokens (--color-*, --font-*) are injected, so a widget matches the theme.
```widget
<canvas id="c" width="600" height="300"></canvas>
<script>
  const x = document.getElementById('c').getContext('2d');
  x.fillStyle = getComputedStyle(document.documentElement).getPropertyValue('--color-accent');
  x.fillRect(20, 20, 200, 120);
</script>
```

Both degrade to a static “open the web deck” note in a PDF.

Inline SVG

A fence tagged svg renders as a vector, not as code. It inherits the theme color through currentColor.

```svg
<svg viewBox="0 0 96 40" width="96" height="40" fill="none" stroke="currentColor" stroke-width="2">
  <path d="M2 35 L17 6 L32 35"/>
</svg>
```

Always give the SVG an explicit width and height. A zero-size SVG in a centered slot collapses and vanishes with no warning.