A Vite + React presentation app for markdown and HTML slides with theme packs, charts (Recharts), Mermaid diagrams, multi-column layouts, and optional per-slide working areas.
Install Bun, then from this directory:
bun install| Command | Description |
|---|---|
bun run dev |
Start the Vite dev server |
bun run build |
Production build to dist/ |
bun run deck:create --id deck01 --title "Deck 01" [--subtitle "…"] |
Scaffold a new deck |
bun run deck:export --id deck01 --out ./deck01.zip |
Export one deck to zip |
bun run deck:import --zip ./deck01.zip |
Import deck zip into decks/ |
Restart the dev server after adding new files under decks/ or themes/ so Vite's glob imports pick them up.
markdown-slider/
├── decks/
│ ├── sample-deck/ # Tracked sample deck
│ │ ├── metadata.md # Deck metadata frontmatter
│ │ └── slide01/
│ │ ├── slide.md
│ │ ├── slide.html
│ │ └── working-area/
│ │ ├── slide.md
│ │ ├── slide.html
│ │ ├── style.css
│ │ └── script.js
│ └── <your-local-decks>/ # Usually gitignored
├── themes/
│ ├── palettes/ # Color tokens (`*.yaml`); `_*.yaml` ignored
│ └── fonts/ # Typography tokens (`*.yaml`)
├── src/
└── scripts/deck-cli.mjs
- App starts on a deck picker screen.
- A deck is discovered from
decks/<deckId>/with at least oneslideNN/slide.mdorslide.html. - Deck metadata comes from
decks/<deckId>/metadata.md. - Slide folders are naturally sorted (
slide01,slide02, ...,slide10). - If both
slide.mdandslide.htmlexist in one slide folder,slide.mdwins.
---
title: Team Update
subtitle: DECK MODE
author: Jane Doe
date: 2026-03-31
defaultPalette: default
defaultFont: libre-baskerville-franklin
description: Weekly roadmap sync
tags:
- weekly
- roadmap
---subtitle is the small line under the deck title in the app header (deck mode). defaultPalette and defaultFont set the slide look when a slide omits palette / font (and optional legacy theme:). You can still use defaultTheme alone as a shorthand for a named bundle; see themes/README.md.
While viewing a deck, use Edit deck metadata (pencil in the header) to change title, subtitle, and related fields; those edits are stored in the browser. Use Copy YAML there to paste into metadata.md if you want the repo file to match.
- If
decks/<deckId>/slideNN/working-area/slide.mdorslide.htmlexists, that slide has a working area. - Use the header control or F to flip between main slide and working area.
- For HTML working areas, optional
style.cssandscript.jsare inlined at build time.
Slide appearance merges a palette (themes/palettes/*.yaml) and a font pack (themes/fonts/*.yaml). Example pairings: default palette + libre-baskerville-franklin; watermelon-sorbet + lora-manrope; rustic-charm + montserrat-nunito; monochrome-red + oswald-montserrat; cherry-blossom + lusitana-raleway; fiery-ocean + ovo-mulish.
Mix and match in frontmatter:
palette: monochrome-red
font: lora-manropeLegacy bundle shorthand (same pairs as before):
theme: monochrome-redIf palette / font are missing on a slide, deck defaults apply (see Deck metadata), then the default bundle.
layout |
What you see |
|---|---|
content |
(default) Header with title and optional subtitle; markdown body scrolls below. |
cover |
Only frontmatter title and subtitle (and optional backgroundImage: for full-bleed). Text after the closing --- is not rendered—put all visible copy in YAML. |
infographic |
Strong header with title only (subtitle hidden); body for compact KPIs or one diagram. |
image |
Centered figure from a markdown image in the body; optional caption, imageWidth, imageHeight in frontmatter. |
quote |
Quote body (e.g. blockquote); subtitle works well as attribution. |
Examples: decks/sample-deck/slide05 (content), slide07 / slide51 (cover), slide06 (infographic), slide08 (image), slide59 (quote).
-
Create a deck with one starter slide:
bun run deck:create --id deck01 --title "Deck 01" --subtitle "Optional tagline" --author "You" --default-palette default --default-font libre-baskerville-franklin
-
Export a deck:
bun run deck:export --id deck01 --out ./deck01.zip
-
Import a deck:
bun run deck:import --zip ./deck01.zip
Deck id collisions are auto-resolved by suffixing (-2, -3, ...).
- Deck picker: choose a deck from the list and Open deck, or fill Create new deck and copy the generated
deck:createcommand. Primary actions use the app design tokens (src/styles/theme.css); light/dark mode toggles both the chrome and the documentdarkclass so colors stay consistent. - Navigation: side arrows, footer dots, and keyboard shortcuts (see footer hint).
- Theme toggle (T): sun/moon switches light vs dark mode for the shell.
- Flip (F): switches to working area when available.
- Add Slide / Add Working Area: footer buttons (session-only); they use the shared shadcn
Buttonstyling with the same outline treatment as other chrome controls. - Per-slide source (E): code button edits raw
slide.md/slide.htmlin-memory. - Presentation (P): fullscreen slide view; Esc exits.
- Go to slide (G): jump by slide number.
- Edit deck metadata: pencil in the header opens the dialog (browser-stored overrides; see Deck metadata above).
themes/README.mdfor theme authoringdecks/sample-deck/for the tracked example deck