miro-board — lesson presentations on Miro
When to use
- User asks to "build lesson N presentation" / "slides for lesson" / "workshop presentation"
- Need to prepare a visual layout for recording a video lesson (face-cam right, content left)
- Goal: 6 frames 1920x1080 on Miro board, ready for Convert to Slides in Miro UI
Architecture of one presentation
Lesson anatomy: Cover + 5 steps = 6 frames 1920x1080.
y=200 Cover (Lesson · Topic)
y=1380 Step 1 (eyebrow / title / content)
y=2560 Step 2
y=3740 Step 3
y=4920 Step 4
y=6100 Step 5
Frames in a vertical column, gap=100 between them. x=200 for all (board origin).
Layout inside a frame:
- Left half (x=500..1280, w=780): all text
- Right half (x=1280..2120, ~840px): empty — for face-cam during recording
x=500 is the absolute coordinate on the board (frame.x=200 + offset 300).
Style system
| Color | HEX | Where |
|---|---|---|
| Graphite (background) | #0f0e0b |
fill of all frames |
| Gold (accents) | #c8a24a |
eyebrows, mono labels, pin quotes, arrows |
| Warm white | #fcfaf7 |
titles, main labels |
| Dim grey | #8a8275 |
subtitles, secondary, descriptions |
Miro fonts:
eb_garamond— serif titles (size 58-80 on cover, 28-64 on steps)plex_mono— eyebrows (UPPERCASE), code-like labels (size 18-24)plex_sans— bullets, descriptions (size 18-24)plex_serif— italic pin quotes in frame footer (size 18-22)
Full typographic scale: references/02-style-system.md.
Key rule — coordinates
This is the most common pitfall. Always read references/04-coordinate-rules.md before the first layout_create.
In brief:
layout_createwithoutmoveToWidget→ x/y are ABSOLUTE on the board, even if DSL hasparent=<frame_url>. Parent in DSL — logical grouping only, coordinates are not recalculated.layout_createwithmoveToWidget=<frame_id>→ x/y are relative to frame top-left (frame top-left = 0,0). Must be withinframe.w / frame.h.image_createbehaves the same: withmoveToWidget— relative, without — board-absolute.
Recipe for building a lesson
Full step-by-step process in references/03-create-lesson.md. Short version:
Step 0 — fetch lesson content
Fetch from your data source (database, markdown, etc.) the lesson title, duration, and step descriptions.
Step 1 — find/create board
mcp__miro__board_search_boards query="<course name>"
If none — board_create.
Step 2 — create 6 frames with one layout_create
Without moveToWidget, board-absolute coordinates.
mcp__miro__layout_create miro_url=<board>
dsl=
f1 FRAME x=200 y=200 w=1920 h=1080 fill=#0f0e0b "Lesson N · Cover"
f2 FRAME x=200 y=1380 w=1920 h=1080 fill=#0f0e0b "Lesson N · Step 1 — ..."
f3 FRAME x=200 y=2560 w=1920 h=1080 fill=#0f0e0b "Lesson N · Step 2 — ..."
f4 FRAME x=200 y=3740 w=1920 h=1080 fill=#0f0e0b "Lesson N · Step 3 — ..."
f5 FRAME x=200 y=4920 w=1920 h=1080 fill=#0f0e0b "Lesson N · Step 4 — ..."
f6 FRAME x=200 y=6100 w=1920 h=1080 fill=#0f0e0b "Lesson N · Step 5 — ..."
The response includes frame URLs with ?moveToWidget=<frame_id>. Save them.
Step 3 — fill TEXT inside each frame
Here coordinates are relative to the frame (important!). Separate layout_create per frame with moveToWidget=<frame_id>.
Cover template (10 elements):
eb TEXT x=300 y=140 w=780 align=left font=plex_mono size=22 color=#c8a24a "LESSON N · MM MIN"
t TEXT x=300 y=300 w=780 align=left font=eb_garamond size=80 color=#fcfaf7 "<Lesson title>"
sub TEXT x=300 y=480 w=780 align=left font=plex_sans size=24 color=#8a8275 "<Short description (1-2 sentences)>"
h TEXT x=300 y=640 w=780 align=left font=plex_mono size=18 color=#c8a24a "WHAT WE COVER"
b1 TEXT x=300 y=720 w=780 align=left font=plex_sans size=22 color=#fcfaf7 "— <step 1>"
b2 TEXT x=300 y=765 w=780 align=left font=plex_sans size=22 color=#fcfaf7 "— <step 2>"
b3 TEXT x=300 y=810 w=780 align=left font=plex_sans size=22 color=#fcfaf7 "— <step 3>"
b4 TEXT x=300 y=855 w=780 align=left font=plex_sans size=22 color=#fcfaf7 "— <step 4>"
b5 TEXT x=300 y=900 w=780 align=left font=plex_sans size=22 color=#fcfaf7 "— <step 5>"
ft TEXT x=300 y=1020 w=780 align=left font=plex_mono size=14 color=#8a8275 "<your-domain> · course name · N / TOTAL"
Step template (10-14 elements): eyebrow + title + subtitle + content blocks + pin. Full templates in references/03-create-lesson.md.
Note: x=300 in relative-frame coordinates = x=500 on board (frame.x=200 + 300). This gives the left half for text.
Step 4 — manual Convert to Slides
This is done by the user, not the agent. In Miro UI: right-click on frame → "Convert to Slides". After conversion texts inside frames are preserved as editable slides.
Note: after Convert to Slides, API access to those frames partially breaks. Make all edits before Convert to Slides.
Pitfalls (read before first build)
Bulk limit: 14+ TEXT items in one
layout_createfail withHTTP 400. Split into groups of 9-12.Parallel calls on one frame = race → fail. Finish frame A, then start frame B. Only different frames can be parallelized.
Symbol
✕(U+2715) breaks the API → HTTP 400. Alternatives:—,x,X. Safe:→,?, numbers.Image widgets in frames for Convert to Slides — Miro does not pick them up correctly in slide mode. Let the user drag and drop images manually.
HARD RULE: right half of frame = ONLY face-cam. ALWAYS single column: relative
x=300 w=780(= board absolute x=500..1280, left half). NEVER make a second column atx=980— it overlaps the face-cam zone.
Content: visual schemes as images vs text
| Scheme | Method |
|---|---|
| Anatomy diagrams (4-block) | TEXT in frame (editable, readable in Convert to Slides) |
| Before/After comparison | TEXT in frame |
| Few-shot pattern | TEXT in frame with → arrows |
| Antipatterns grid 2x3 | TEXT in frame |
| Decorative covers | Image generated externally, placed as separate image-widget |
On-demand references
references/01-architecture.md— board coordinate grid, frame layout, how to add 7th/8th stepreferences/02-style-system.md— full typographic scale, padding, gap, sizesreferences/03-create-lesson.md— step-by-step recipe, full DSL templates cover/stepreferences/04-coordinate-rules.md— relative vs absolute coordinates in Miro DSLreferences/05-api-gotchas.md— bulk limit, frame race, symbol escape, prevention checklistreferences/06-fetch-content.md— how to fetch lesson content from your data source (Supabase, etc.)