diff --git a/skills/creative/manim-video/SKILL.md b/skills/creative/manim-video/SKILL.md index 34e6f7e67..15bc3d386 100644 --- a/skills/creative/manim-video/SKILL.md +++ b/skills/creative/manim-video/SKILL.md @@ -108,14 +108,18 @@ project-name/ ### Fonts -Always specify fonts explicitly — the default renders poorly. See `references/visual-design.md` for full recommendations. +**Use monospace fonts for all text.** Manim's Pango renderer produces broken kerning with proportional fonts at all sizes. See `references/visual-design.md` for full recommendations. ```python -Text("Title", font_size=48, font="Inter", weight=BOLD) # body text -Text("code()", font_size=24, font="JetBrains Mono") # monospaced -MathTex(r"\nabla L") # math (uses LaTeX) +MONO = "Menlo" # define once at top of file + +Text("Fourier Series", font_size=48, font=MONO, weight=BOLD) # titles +Text("n=1: sin(x)", font_size=20, font=MONO) # labels +MathTex(r"\nabla L") # math (uses LaTeX) ``` +Minimum `font_size=18` for readability. + ### Per-Scene Variation Never use identical config for all scenes. For each scene: @@ -141,11 +145,12 @@ BG = "#1C1C1C" PRIMARY = "#58C4DD" SECONDARY = "#83C167" ACCENT = "#FFFF00" +MONO = "Menlo" class Scene1_Introduction(Scene): def construct(self): self.camera.background_color = BG - title = Text("Why Does This Work?", font_size=48, color=PRIMARY) + title = Text("Why Does This Work?", font_size=48, color=PRIMARY, weight=BOLD, font=MONO) self.add_subcaption("Why does this work?", duration=2) self.play(Write(title), run_time=1.5) self.wait(1.0) diff --git a/skills/creative/manim-video/references/visual-design.md b/skills/creative/manim-video/references/visual-design.md index e8dc09fe3..e7dcec01a 100644 --- a/skills/creative/manim-video/references/visual-design.md +++ b/skills/creative/manim-video/references/visual-design.md @@ -60,35 +60,40 @@ BG="#0A0A0A"; PRIMARY="#00F5FF"; SECONDARY="#FF00FF"; ACCENT="#39FF14" ## Font Selection -Manim's default `Text()` uses the system's default sans-serif font, which often renders with poor kerning. Always specify a font explicitly. +**Use monospace fonts for all text.** Manim's Pango text renderer produces broken kerning with proportional fonts (Helvetica, Inter, SF Pro, Arial) at all sizes and resolutions. Characters overlap and spacing is inconsistent. This is a fundamental Pango limitation, not a Manim bug. + +Monospace fonts have fixed character widths — zero kerning issues by design. ### Recommended Fonts | Use case | Font | Fallback | |----------|------|----------| -| Body text, titles | `"Inter"`, `"SF Pro Display"` | `"Helvetica Neue"`, `"Arial"` | -| Code, terminal | `"JetBrains Mono"`, `"SF Mono"` | `"Menlo"`, `"Courier New"` | -| Math labels | Use `MathTex` (renders via LaTeX, not system fonts) | — | +| **All text (default)** | `"Menlo"` | `"Courier New"`, `"DejaVu Sans Mono"` | +| Code, labels | `"JetBrains Mono"`, `"SF Mono"` | `"Menlo"` | +| Math | Use `MathTex` (renders via LaTeX, not Pango) | — | ```python -# Clean body text -title = Text("Gradient Descent", font_size=48, font="Inter", weight=BOLD) +MONO = "Menlo" # define once at top of file -# Monospaced code -code_label = Text("loss.backward()", font_size=24, font="JetBrains Mono") +title = Text("Fourier Series", font_size=48, color=PRIMARY, weight=BOLD, font=MONO) +label = Text("n=1: (4/pi) sin(x)", font_size=20, color=BLUE, font=MONO) +note = Text("Convergence at discontinuities", font_size=18, color=DIM, font=MONO) # Math — always use MathTex, not Text equation = MathTex(r"\nabla L = \frac{\partial L}{\partial w}") ``` +### When Proportional Fonts Are Acceptable + +Large title text (font_size >= 48) with short strings (1-3 words) can use proportional fonts without visible kerning issues. For anything else — labels, descriptions, multi-word text, small sizes — use monospace. + ### Font Availability -Not all fonts are installed on all systems. Manim falls back silently to a default if the font is missing. Use widely available fonts: -- **macOS**: SF Pro Display, SF Mono, Menlo, Helvetica Neue -- **Linux**: DejaVu Sans, Liberation Sans, Ubuntu, Noto Sans -- **Cross-platform**: Inter (install via Google Fonts), JetBrains Mono (install from jetbrains.com) +- **macOS**: Menlo (pre-installed), SF Mono +- **Linux**: DejaVu Sans Mono (pre-installed), Liberation Mono +- **Cross-platform**: JetBrains Mono (install from jetbrains.com) -For maximum portability, use `"Helvetica Neue"` (body) and `"Menlo"` (code) — both available on macOS and have Linux equivalents. +`"Menlo"` is the safest default — pre-installed on macOS, and Linux systems fall back to DejaVu Sans Mono. ### Fine-Grained Text Control @@ -99,15 +104,15 @@ For maximum portability, use `"Helvetica Neue"` (body) and `"Menlo"` (code) — MarkupText('HERMES', font_size=18, font="Menlo") # Bold specific words -MarkupText('This is important', font_size=24) +MarkupText('This is important', font_size=24, font="Menlo") # Color specific words -MarkupText('Red warning', font_size=24) +MarkupText('Red warning', font_size=24, font="Menlo") ``` -### Text Rendering Quality +### Minimum Font Size -Manim's text rendering quality depends heavily on output resolution. At `-ql` (480p), text kerning looks noticeably poor. Always preview text-heavy scenes at `-qm` (720p) or higher. See `references/rendering.md` for quality preset guidance. +`font_size=18` is the minimum for readable text at any resolution. Below 18, characters become blurry at `-ql` and barely readable even at `-qh`. ## Visual Hierarchy Checklist