Creating a talk with the itenium theme

Start a deck, pick layouts, copy snippets. Every layout links to the live slide.

Start a new talk

Each talk is its own repo; the theme comes in as a git submodule.

  1. Create the repo and add the theme

    mkdir my-talk && cd my-talk && git init
    git submodule add https://github.com/itenium-be/Presentations.git presentation/theme
  2. Scaffold: creates presentation/slides.md from the starter deck, package.json, .gitignore and ElevatorPitch.md

    bun run presentation/theme/scripts/scaffold.ts
    cd presentation && bun install
    bun run dev       # http://localhost:3030 · /presenter for notes + timer
  3. Fill in the headmatter of presentation/slides.md. The site reads it for the talk card.

    ---
    theme: ./theme
    title: Talk Title
    subTitle: A brief subtitle
    transition: fade
    session-time: 60min
    track: Architecture          # category on the site
    type: Theoretical            # or Practical, Workshop, ...
    first: 2026-01-01            # first presentation date
    lastUpdate: 2026-06-01       # optional, shown instead of first
    aspectRatio: 16/10           # 16/10 laptop, 16/9 projector
    ---
  4. Write the abstract in ElevatorPitch.md: the ## Abstract section becomes the card description.

Update the theme later with cd presentation/theme && git pull.

Publish to this site

List the repo in talks.yaml of the theme repo and push.

Export the pptx copy from presentation/:

bun run export    # ../<repo>.pptx

The talk repo needs, in its root:

  • <repo>.pptx
  • ElevatorPitch.md
  • presentation/images/cover-art.{png,jpg,webp}: the card image (2:3, 1024×1536)

Then add it to talks.yaml in the theme repo:

- repo: itenium-be/my-talk
  published: true

# a second deck in the same repo: presentation/guardrails.md
- repo: itenium-be/my-talk
  entry: guardrails.md
  published: true

The site deploys on every push to the theme repo’s main. To pick up changes in a talk repo only, run the Deploy Presentations Site workflow manually.

Edit these docs

This page, Showcase and Rosetta all hot reload locally.

From the theme repo:

bun run dev:creators
What URL Source
Docs http://localhost:4321/Presentations/creators/ site/src/content/creators/**/*.md
Showcase http://localhost:3030 talks/showcase/slides.md
Rosetta http://localhost:3031 talks/rosetta/slides.md

A doc links to its live slide via live: { deck, slide } in its frontmatter, matching a routeAlias: on that slide. bun test fails when a layout has no doc or a live link points nowhere.

Reference decks

Click through every layout and feature, as an audience would see it.

Layouts

Set with layout: in the slide frontmatter.

cover Title slide

::image::

Orange background, logo top-left, image on the right via the image slot. Use as the first slide; the headmatter goes on top.

# Title
# Subtitle

::image::

![](./images/cover-art.jpg)

conf-intro Conference opener

itenium photo collage, three title lines (cyan / white / orange), logo bottom-right. Put it first in a conference deck.

---
layout: conf-intro
---

# Your
# Title
# Etc

default Content slide

textSize: xxl…xsh1/h2 decorations

White background, dot decorations, footer with slide number. Font size auto-scales with the bullet count; force it with textSize.

---
layout: default
---

# Title

- Bullet
- Bullet

default-aside Content + round image

textSizeimage-position: top-right | middle-right::image::

Content slide with a circular image (orange border, square-cropped). Text wraps around it.

---
layout: default-aside
image-position: middle-right
textSize: sm
---

# Title

- Bullet that wraps around the image

::image::

![](./images/headshot.jpg)

section Section divider

background::subtitle::

Full-bleed photo with a 45% dark overlay, white title near the top. Override the photo with background: (a file in presentation/images/).

---
layout: section
background: prompt-lint-demo.png
---

# Section Title

::subtitle::

Optional subtitle text

agenda Agenda

itemstextSize: lg…xs

Numbered items next to a photo. Items come from the frontmatter.

---
layout: agenda
textSize: sm
items:
  - First Topic
  - Second Topic
  - Third Topic
---

comparison Two cards side by side

.cols.col

Two-column card layout with .cols and .col divs.

---
layout: comparison
---

# Title

<div class="cols">
<div class="col">

### Left Card

- Point one

</div>
<div class="col">

### Right Card

- Point one

</div>
</div>

two-col-image-text Image left, text right

textSize: lg…xs::image::::content::

Title centered above both columns, columns vertically centered.

---
layout: two-col-image-text
---

# Title

::image::

![](./images/photo.jpg)

::content::

- Content here

quote Quote / transition

Orange background with dot decorations.

---
layout: quote
---

# Quote text here

quote-image Quote with image

::image::::author::

Green background, quote with an image and an attribution line.

---
layout: quote-image
---

# The quote

::image::

![](./images/photo.jpg)

::author::

**Name Surname**

statement Bold one-liner

textSize: xl…xsimage-position::author::::image::

Green background, big quote mark, attribution and an optional round image. More weight than quote.

---
layout: statement
textSize: lg
---

# The bold claim that anchors the talk

::author::

**Name Surname** — Title, Org

::image::

![](./images/headshot.jpg)

break Break with countdown

orientation: vertical::timer::::image::

Break slide with a <Timer> and an image. orientation: vertical stacks them.

---
layout: break
---

# ☕ Break

::timer::

<Timer minutes="10" />

::image::

![](./images/cover-art.jpg)

code Code slide

code-size

Minimal padding, the code block fills the slide. code-size sets the maximum code font size (default 1em); it shrinks to fit the slide.

---
layout: code
code-size: 1.4em
---

# Title

## Optional subtitle

```ts {1|2|3-5|all}
function isPrime(n: number): boolean {
  if (n <= 1) return false
  for (let i = 2; i * i <= n; i++) {
    if (n % i === 0) return false
  }
  return true
}
```

code-comparison Before / after code

before-labelafter-labelcode-size::before::::after::

Two code panels side by side, red Before and green After headings.

---
layout: code-comparison
before-label: Without Skills
after-label: With Skills
code-size: 0.7em
---

# Title

::before::

```ts
function fetchUser(id) { /* ... */ }
```

::after::

```ts
async function fetchUser(id: string): Promise<User> { /* ... */ }
```

source Source + QR code

source: org/repo

Second to last slide: “Powerpoint Source”, a QR code and the GitHub link, both from source:. The scaffold fills it in.

---
layout: source
source: itenium-be/MicroServices
---

socials itenium socials

qr

Fixed slide with the itenium social accounts. qr: adds a QR code.

---
layout: socials
---

end Closing slide

Photo background with “THANK YOU!”; the slide content replaces the text.

---
layout: end
---

Recipes

The "how did I do that again?" list.

Tables Markdown tables are themed. Wrap in `<div class='dense'>` for tighter rows.

.dense
<div class="dense">

| Technique    | Example                    |
|--------------|----------------------------|
| **0px font** | Invisible to humans        |

</div>

v-click table Table that reveals rows on click. Cells accept HTML.

<VClickTable>
<VClickTable
  :headers="['Defense', 'Approach', 'Solves it?']"
  :rows="[
    ['<b>Constitutional AI</b>', 'Self-critique', 'No'],
    ['<b>Prompt Shields</b>', 'Pattern scanning', 'No'],
  ]"
  :firstVisible="1"
  size="sm"
/>
Prop Type Default Description
headers string[] required Column headers
rows string[][] required Row data (HTML allowed)
firstVisible number 1 Rows visible immediately
size lg | md | sm md sm is dense
separatorBefore number[] [] Row indices (0-based) with an orange top line

Click to reveal Wrap a list in `<v-clicks>`; `depth` includes sub-items.

<v-clicks>
<v-clicks depth="2">

- First item
- Second item
  - Sub-item

</v-clicks>

Text size & full width `textSize` frontmatter on content layouts; `full-width` breaks out of the content padding.

textSize.full-width
---
layout: default
textSize: sm
---

# My Slide

<div class="full-width text-xxl italic text-orange-400">
  A quote that spans the entire width of the slide.
</div>

Title decorations Code-style symbols around h1/h2, set in frontmatter.

h1h2
h1:
  type: braces      # dot · slashes · hash · semicolon · brackets · braces
  color: primary    # primary (orange) · muted (gray)
  position: 2       # start · end · all · 2 · 2-3 (word range, brackets/braces)

# What is UnitTesting renders as What is {UnitTesting}.

Code walkthrough Step through line ranges with `{1-4|6-10}`; `lines:true` shows numbers.

{1|2-3|all}
```ts {1-4|6-10|12-13}{lines:true,at:0}
interface User { ... }
```

Magic move Animate between versions of a code block.

magic-move
````md magic-move
```ts
const a = 1
```

```ts
const a = 1
const b = 2
```
````

Live code Editable, runnable code block.

{monaco-run}
```ts {monaco-run}
console.log(42)
```

Diagrams Mermaid code blocks render as diagrams.

mermaid
```mermaid
graph LR
  A[Kickoff] --> B[Development] --> C[Demo]
```

Speaker notes An HTML comment at the end of a slide; only visible in `/presenter`.

<!-- -->
# My Slide

Content here

<!-- Only visible in presenter mode -->

Countdown timer `<Timer>` counts down, click to start. Used by the `break` layout.

<Timer>
<Timer minutes="10" />

QR code `<QRCode>` renders any URL as an SVG QR code.

<QRCode>
<div class="w-64 h-64">
  <QRCode url="https://github.com/itenium-be/Presentations" color="#343434" />
</div>

Images Sizes, formats and compression per layout slot.

cover-artpngquant

Vite bundles images as-is; right-size them before committing.

Use Aspect Resolution File size Notes
cover slot + site card 2:3 1024×1536 <300 KB Card crops to 240×200: keep the subject centered
break slot 2:3 1024×1536 <300 KB Usually the cover image
default-aside circle 1:1 600×600 <150 KB Center the subject
agenda photo portrait 800×1200 <250 KB
section background landscape 1920×1080 <400 KB 45% black overlay: avoid busy detail
two-col-image-text flexible ≥1200 long edge <250 KB Letterboxed

PNG for screenshots/illustrations, JPG (q85) for photos, WebP for either, SVG for logos and diagrams. No GIF, no HEIC.

pngquant --quality=70-85 --strip --output cover.min.png cover.png
magick photo.jpg -quality 85 -strip photo.jpg
magick cover.png -resize 1024x1536 -quality 85 cover.webp
magick portrait.jpg -resize 600x600^ -gravity center -extent 600x600 aside.jpg