Skip to content
Education
Skill

/slide-craft

The design law of a slide page — canvas geometry, the text height table, the type scale, contrast pairs, spacing rhythm, and which element type carries which content. Load it when patching slide elements one at a time, when a fix is about colour or contrast, when text has to

From plugin
openmaic
43k25 skills

Claude Code

$ npx -y skills add thu-maic/openmaic --skill slide-craft --agent claude-code

SKILL.md

slide-craft.SKILL.md
name: slide-craft
title: "页面设计"
description: The design law of a slide page — canvas geometry, the text height table, the type scale, contrast pairs, spacing rhythm, and which element type carries which content. Load it when patching slide elements one at a time, when a fix is about colour or contrast, when text has to grow or shrink inside a box, when a page feels crowded or empty, or when replacement content needs real rich-text structure. It is the standard `page-clone` and `pro-editing` edit against, not a procedure of its own — those two decide which pages to touch and in what order, this one decides what a good page looks like when you put it back.

The design law of a slide page

Every slide in this runtime was drawn under a long set of rules — the canvas, the height table, the type scale, the spacing standards. The generator that drew the page had all of them in front of it. When you patch one element, you have the page's numbers and nothing else, and the rules are the only way to tell a repair from a dent.

This is that rule set, restated for editing. It is about the page, not the process: which numbers a change has to stay consistent with, and which fields actually reach the screen.

The canvas you are editing inside

The canvas is **1000 × 562.5**. All elements respect a **50px margin**, so the live area is `left ∈ [50, 950]`, `top ∈ [50, 512.5]`, and an element's right edge (`left + width`) stays ≤ 950, its bottom edge ≤ 512.5.

The page's own alignment grid, which existing elements are already on:

  • Left-aligned content sits at `left = 60` or `left = 80`.
  • Centred content is `left = (1000 - width) / 2` — recomputed, never guessed.
  • Right-aligned content is `left = 1000 - width - 60`.

Changing `width` on centred content changes `left` too, and they are two separate writes. Read the neighbours' boxes first and land on the column they are already using; a lone element 8px off the shared left edge reads as a mistake even though nothing overflows.

**There is no alignment operation.** Every position is an explicit number you write to that element's own `left` / `top` / `width` / `height`, one path per call, computed from the neighbours you read. Aligning a row means giving each element the number the row already uses — not asking the page to tidy itself.

Text is sized by table, not by eye

A text element has **10px padding on all four sides**, so its usable area is `(width - 20) × (height - 20)`, and heights come from one table (line-height 1.5, padding included):

| Font size | 1 line | 2 lines | 3 lines | 4 lines | 5 lines | | --------- | ------ | ------- | ------- | ------- | ------- | | 14px | 43 | 64 | 85 | 106 | 127 | | 16px | 46 | 70 | 94 | 118 | 142 | | 18px | 49 | 76 | 103 | 130 | 157 | | 20px | 52 | 82 | 112 | 142 | 172 | | 24px | 58 | 94 | 130 | 166 | 202 | | 28px | 64 | 106 | 148 | 190 | 232 | | 32px | 70 | 118 | 166 | 214 | 262 | | 36px | 76 | 130 | 184 | 238 | 292 |

When you replace an element's words, re-derive its height instead of keeping the old one:

1. `characters_per_line = (width - 20) / font_size`. Keep the longest line at **≤ 75%** of that; past 100% the text wraps and takes a row you did not budget. 2. Count the lines your new content needs — one per `<p>`, plus a wrap for every paragraph over `characters_per_line` — then add ~0.8 of a line of slack and round up. 3. Look the height up against the **largest font size present in the content**, not the average.

Height is a container, not a clamp: overflowing text spills past the box rather than shrinking, and the page shows the spill. The fix order is **shorten the words, then step to the next table row, then widen the box** — in that order, because a slide that needs a bigger box usually needs fewer words.

The type scale

| Content | Size | | ----------- | ------- | | Main title | 32-36px | | Subtitle | 24-28px | | Key points | 18-20px | | Body | 16-18px | | Caption | 14-16px |

Levels stay 2-4px apart and everything at one level uses one size. When you touch an element, take its size from the siblings that share its role on that page rather than from this table fresh — the page's own scale wins, and this table is how you recognise which level an element belongs to.

**Size lives in the content HTML**, as inline `font-size` on the `<p>` — there is no font-size field to write. So changing a size means writing the whole content string back, which means you have to know the markup you are replacing.

What the renderer really does with your HTML

The `content` of a text element is an HTML string, and this page's CSS resets most tag semantics. Four consequences decide how you write rich text:

  • **`<ul>` / `<ol>` render without markers.** The stylesheet's reset strips

`list-style` and the indent, and the rule that puts them back is scoped to the browser editor — not to classroom playback. A list sent as `<ul><li>…</li></ul>` comes out as bare unindented lines. Write bullets the way the deck itself does: **one `<p>` per item with the marker in the text**, `<p style="font-size:18px;">• First point</p>`.

  • **`<h1>`–`<h6>` are inert.** The reset sets `font-size: inherit` and

`font-weight: inherit` on them, so a heading tag is a `<p>` with extra characters. Size and weight come from inline `font-size` and `<strong>`, which do work.

  • **Stacked `<p>` tags have no gap between them** in a text element — only

line-height separates them. If two lines need air between them, raise the element's `lineHeight` or split them into two elements; do not expect an empty `<p>`, whose height still costs you a table row.

  • **A newline in plain text is not a line break.** Plain text is wrapped in a

single `<p>` and the newline collapses to a

Read more
@thu-maic
Ships withopenmaic

Open Multi-Agent Interactive Classroom — Get an immersive, multi-agent learning experience in just one click

Stars on GitHub

Momentum

stars in total
43.2k
Star history of thu-maic/openmaic on GitHub, a chart by star-history.com

Other skills on openmaic.

build-personal-skill

build-personal-skill

Evidence-based creation of a reusable personal course-making Skill from the user's own classroom and chat history. Use when the…

@thu-maic@thu-maicInstall Skill
curriculum-planner

curriculum-planner

Multi-stage series — a request for several classrooms that belong together, like 「7 天学 Python」, a four-week onboarding track, a…

@thu-maic@thu-maicInstall Skill
deep-interactive

deep-interactive

Deep Interactive courses. Plans the course so the learner manipulates something on most pages — simulations, diagrams they…

@thu-maic@thu-maicInstall Skill
deep-research

deep-research

Courses whose content rests on current, external or real-world facts that must be verified against live sources before being…

@thu-maic@thu-maicInstall Skill
fact-check

fact-check

Improve factual reliability while creating or reviewing a course or supplied content. Use when the user asks to fact-check,…

@thu-maic@thu-maicInstall Skill
feynman-learning

feynman-learning

Turn any concept, lesson, slide deck, or source material into a Feynman learning cycle in which learners explain first, expose…

@thu-maic@thu-maicInstall Skill

More skills from other plugins.

lesson-quiz

lesson-quiz

Test a learner on a single Claude Code tutorial lesson (01-10) with 10 questions, scoring answers and flagging weak spots. Use…

@luongnv89@luongnv89Install Skill

Questions about slide-craft.

Which coding agents can use slide-craft?
slide-craft installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.