MulmoCast Slide DSL
Overview
The MulmoCast Slide DSL describes presentation slides in JSON. Pipeline: JSON -> Tailwind HTML -> Puppeteer PNG.
- •Schema definitions:
src/slide/schema.ts - •HTML generation:
src/slide/render.ts - •Layout implementations:
src/slide/layouts/ - •Content blocks:
src/slide/blocks.ts - •Plugin integration:
src/utils/image_plugins/slide.ts
MulmoScript Beat Structure
Recommended: Set theme once with slideParams
Use slideParams.theme to specify the default theme, then only write image.slide in each beat.
{
"$mulmocast": { "version": "1.1" },
"lang": "en",
"title": "Presentation Title",
"slideParams": {
"theme": {
"colors": { "bg": "0F172A", "bgCard": "1E293B", "bgCardAlt": "334155", "text": "F8FAFC", "textMuted": "CBD5E1", "textDim": "64748B", "primary": "3B82F6", "accent": "8B5CF6", "success": "22C55E", "warning": "F59E0B", "danger": "EF4444", "info": "14B8A6", "highlight": "EC4899" },
"fonts": { "title": "Georgia", "body": "Calibri", "mono": "Consolas" }
}
},
"beats": [
{
"text": "Title slide narration",
"image": {
"type": "slide",
"slide": { "layout": "title", "title": "Main Title", "subtitle": "Subtitle" }
}
},
{
"text": "Three-column comparison",
"image": {
"type": "slide",
"slide": {
"layout": "columns",
"title": "Comparison",
"columns": [
{ "title": "Plan A", "accentColor": "primary", "content": [{ "type": "bullets", "items": ["Feature 1", "Feature 2"] }] },
{ "title": "Plan B", "accentColor": "accent", "content": [{ "type": "bullets", "items": ["Feature 3", "Feature 4"] }] }
]
}
}
}
]
}
Theme Resolution Priority
- •If
beat.image.themeexists, use it (beat-level override) - •Otherwise fall back to
slideParams.theme - •If neither exists, throw an error
To use a different theme for a specific beat, set beat.image.theme.
Theme
Colors (13 keys)
| Key | Purpose |
|---|---|
bg | Background color |
bgCard | Card background |
bgCardAlt | Alternative card background |
text | Primary text color |
textMuted | Secondary text color |
textDim | Dimmed text color |
primary | Main accent color |
accent | Secondary accent color |
success | Positive / success |
warning | Warning / caution |
danger | Error / danger |
info | Informational |
highlight | Highlight |
Values are 6-digit hex without #. Example: "3B82F6"
Fonts (3 keys)
| Key | Purpose |
|---|---|
title | Titles and headings |
body | Body text |
mono | Code blocks |
Preset Themes (6 variants)
Theme JSON files are stored in assets/slide_themes/. Read the appropriate file and set its content as slideParams.theme.
| File | Name | Style | Best for |
|---|---|---|---|
assets/slide_themes/dark.json | dark | Dark Professional | Tech talks, developer presentations, evening events |
assets/slide_themes/pop.json | pop | Bright and Energetic | Marketing, product launches, creative pitches |
assets/slide_themes/warm.json | warm | Warm and Welcoming | Education, workshops, community events |
assets/slide_themes/creative.json | creative | Bold and Modern | Design reviews, startup pitches, creative showcases |
assets/slide_themes/minimal.json | minimal | Clean and Fresh | Academic, research, data-focused presentations |
assets/slide_themes/corporate.json | corporate | Professional and Trustworthy | Business reports, client presentations, formal meetings |
Using a theme
Read the theme JSON file and embed it in slideParams.theme:
{
"slideParams": {
"theme": { /* contents of assets/slide_themes/dark.json */ }
}
}
Using a presentation style (recommended)
Pre-built presentation style files are available in assets/styles/slide_*.json. These include $mulmocast, slideParams.theme, and canvasSize (1280x720).
| Style file | Theme |
|---|---|
assets/styles/slide_dark.json | dark |
assets/styles/slide_pop.json | pop |
assets/styles/slide_warm.json | warm |
assets/styles/slide_creative.json | creative |
assets/styles/slide_minimal.json | minimal |
assets/styles/slide_corporate.json | corporate |
Apply via -s option:
yarn cli tool complete beats.json -s slide_dark -o presentation.json
Layouts (11 types)
title - Title Slide
{ "layout": "title", "title": "...", "subtitle?": "...", "author?": "...", "note?": "..." }
columns - Column Layout
{
"layout": "columns", "title": "...", "subtitle?": "...", "stepLabel?": "...",
"columns": [{ "title": "...", "accentColor?": "primary", "content?": [...], "footer?": "...", "label?": "...", "num?": 1, "icon?": "..." }],
"showArrows?": true, "callout?": {...}, "bottomText?": "..."
}
comparison - Side-by-Side Comparison
{
"layout": "comparison", "title": "...", "subtitle?": "...", "stepLabel?": "...",
"left": { "title": "...", "accentColor?": "danger", "content?": [...], "footer?": "..." },
"right": { "title": "...", "accentColor?": "success", "content?": [...], "footer?": "..." },
"callout?": {...}
}
grid - Grid Layout
{
"layout": "grid", "title": "...", "subtitle?": "...", "gridColumns?": 3,
"items": [{ "title": "...", "description?": "...", "accentColor?": "primary", "num?": 1, "icon?": "...", "content?": [...] }],
"footer?": "..."
}
bigQuote - Quote Slide
{ "layout": "bigQuote", "quote": "...", "author?": "...", "role?": "..." }
stats - Statistics / KPIs
{
"layout": "stats", "title": "...", "subtitle?": "...", "stepLabel?": "...",
"stats": [{ "value": "99.9%", "label": "Uptime", "color?": "success", "change?": "+0.1%" }],
"callout?": {...}
}
timeline - Timeline
{
"layout": "timeline", "title": "...", "subtitle?": "...", "stepLabel?": "...",
"items": [{ "date": "Q1 2026", "title": "...", "description?": "...", "color?": "success", "done?": true }]
}
split - Split Panels
{
"layout": "split",
"left?": { "title?": "...", "subtitle?": "...", "label?": "...", "accentColor?": "primary", "content?": [...], "dark?": true, "ratio?": 60 },
"right?": { "title?": "...", "subtitle?": "...", "content?": [...], "ratio?": 40 }
}
matrix - Matrix (2x2 etc.)
{
"layout": "matrix", "title": "...", "subtitle?": "...", "stepLabel?": "...",
"rows?": 2, "cols?": 2,
"xAxis?": { "low?": "...", "high?": "...", "label?": "..." },
"yAxis?": { "low?": "...", "high?": "...", "label?": "..." },
"cells": [{ "label": "...", "items?": ["..."], "content?": [...], "accentColor?": "success" }]
}
table - Table
{
"layout": "table", "title": "...", "subtitle?": "...", "stepLabel?": "...",
"headers": ["Col1", "Col2"],
"rows": [["val1", { "text": "val2", "color?": "success", "bold?": true }]],
"rowHeaders?": true, "striped?": true, "callout?": {...}
}
funnel - Funnel
{
"layout": "funnel", "title": "...", "subtitle?": "...", "stepLabel?": "...",
"stages": [{ "label": "...", "value?": "1000", "description?": "...", "color?": "info" }],
"callout?": {...}
}
Common Fields (all layouts)
- •
accentColor?:"primary" | "accent" | "success" | "warning" | "danger" | "info" | "highlight" - •
style?:{ "bgColor?": "hex", "decorations?": boolean, "bgOpacity?": number, "footer?": "..." }
Content Blocks (7 types)
Used in the content array of layouts such as columns, comparison, grid, split, and matrix.
text
{ "type": "text", "value": "...", "align?": "left|center|right", "bold?": true, "dim?": true, "fontSize?": 24, "color?": "primary" }
bullets
{ "type": "bullets", "items": ["Item 1", "Item 2"], "ordered?": true, "icon?": ">" }
code
{ "type": "code", "code": "const x = 1;", "language?": "typescript" }
callout
{ "type": "callout", "text": "...", "label?": "Note", "color?": "warning", "style?": "quote|info|warning" }
metric
{ "type": "metric", "value": "99.9%", "label": "Uptime", "color?": "success", "change?": "+0.1%" }
divider
{ "type": "divider", "color?": "primary" }
image
{ "type": "image", "src": "photo.png", "alt?": "Description", "fit?": "contain|cover" }
Shared Components
card (used in columns, grid)
{ "title": "...", "accentColor?": "primary", "content?": [...], "footer?": "...", "label?": "...", "num?": 1, "icon?": "..." }
calloutBar (used in columns, comparison, stats, table, funnel)
{ "text": "...", "label?": "...", "color?": "primary", "align?": "left|center", "leftBar?": true }
slideStyle (available on all layouts)
{ "bgColor?": "hex value", "decorations?": true, "bgOpacity?": 0.8, "footer?": "Page footer" }
Design Principles
- •Theme consistency: Use one theme per presentation. Set it once with
slideParams.theme - •Color usage: Apply semantic colors via
accentColoron cards, stats, timeline items, etc. Use all 7 accent colors purposefully - •Typography:
font-titlefor headings,font-bodyfor body text,font-monofor code are applied automatically - •Layout selection guide:
- •Opening / closing ->
title - •Steps / process ->
columns(showArrows: true) - •Compare / contrast ->
comparison - •Categories / overview ->
grid - •Quotes / key messages ->
bigQuote - •Numbers / KPIs ->
stats - •Chronological ->
timeline - •Two-pane detail ->
split - •2x2 analysis ->
matrix - •Data tables ->
table - •Conversion / pipeline ->
funnel
- •Opening / closing ->
- •Content density: Avoid cramming too much into one slide. 3-5 bullet points per slide is ideal
Workflow
# 1. Create a beats-only JSON (Claude generates this) # 2. Convert to complete MulmoScript (with presentation style) yarn cli tool complete beats.json -s slide_dark -o presentation.json # 3. Generate slide images yarn cli image presentation.json -o output/ # 4. Preview a specific beat yarn cli image presentation.json -o output/ --beat 0