Files
hermes-sync/skills/creative/manim-video/references/production-quality.md

5.8 KiB
Raw Blame History

Production Quality Checklist

Standards and checks for ensuring animation output is publication-ready.

Pre-Code Checklist

Before writing any Manim code:

  • Narration script written with visual beats marked
  • Scene list with purpose, duration, and layout for each
  • Color palette defined with meaning assignments (PRIMARY = main concept, etc.)
  • MONO = "Menlo" set as the font constant
  • Target resolution and aspect ratio decided

Text Quality

Overlap prevention

# RULE: buff >= 0.5 for edge text
label.to_edge(DOWN, buff=0.5)     # GOOD
label.to_edge(DOWN, buff=0.3)     # BAD — may clip

# RULE: FadeOut previous before adding new at same position
self.play(ReplacementTransform(note1, note2))  # GOOD
self.play(Write(note2))                          # BAD — overlaps note1

# RULE: Reduce font size for dense scenes
# When > 4 text elements visible, use font_size=20 not 28

Width enforcement

Long text strings overflow the frame:

# RULE: Set max width for any text that might be long
text = Text("This is a potentially long description", font_size=22, font=MONO)
if text.width > config.frame_width - 1.0:
    text.set_width(config.frame_width - 1.0)

Font consistency

# RULE: Define MONO once, use everywhere
MONO = "Menlo"

# WRONG: mixing fonts
Text("Title", font="Helvetica")
Text("Label", font="Arial")
Text("Code", font="Courier")

# RIGHT: one font
Text("Title", font=MONO, weight=BOLD, font_size=48)
Text("Label", font=MONO, font_size=20)
Text("Code", font=MONO, font_size=18)

Spatial Layout

The coordinate budget

The visible frame is approximately 14.2 wide × 8.0 tall (default 16:9). With mandatory margins:

Usable area: x ∈ [-6.5, 6.5], y ∈ [-3.5, 3.5]
Top title zone: y ∈ [2.5, 3.5]
Bottom note zone: y ∈ [-3.5, -2.5]
Main content: y ∈ [-2.5, 2.5], x ∈ [-6.0, 6.0]

Fill the frame

Empty scenes look unfinished. If the main content is small, add context:

  • A dimmed grid/axes behind the content
  • A title/subtitle at the top
  • A source citation at the bottom
  • Decorative geometry at low opacity

Maximum simultaneous elements

Hard limit: 6 actively visible elements. Beyond that, the viewer can't track everything. If you need more:

  • Dim old elements to opacity 0.3
  • Remove elements that have served their purpose
  • Split into two scenes

Animation Quality

Variety audit

Check that no two consecutive scenes use the exact same:

  • Animation type (if Scene 3 uses Write for everything, Scene 4 should use FadeIn or Create)
  • Color emphasis (rotate through palette colors)
  • Layout (center, left-right, grid — alternate)
  • Pacing (if Scene 2 was slow and deliberate, Scene 3 can be faster)

Tempo curve

A good video follows a tempo curve:

Slow ──→ Medium ──→ FAST (climax) ──→ Slow (conclusion)

Scene 1: Slow (introduction, setup)
Scene 2: Medium (building understanding)
Scene 3: Medium-Fast (core content, lots of animation)
Scene 4: FAST (montage of applications/results)
Scene 5: Slow (conclusion, key takeaway)

Transition quality

Between scenes:

  • Clean exit: self.play(FadeOut(Group(*self.mobjects)), run_time=0.5)
  • Brief pause: self.wait(0.3) after fadeout, before next scene's first animation
  • Never hard-cut: always animate the transition

Color Quality

Dimming on dark backgrounds

Colors that look vibrant on white look muddy on dark backgrounds (#0D1117, #1C1C1C). Test your palette:

# Colors that work well on dark backgrounds:
# Bright and saturated: #58C4DD, #83C167, #FFFF00, #FF6B6B
# Colors that DON'T work: #666666 (invisible), #2244AA (too dark)

# RULE: Structural elements (axes, grids) at opacity 0.15
# Context elements at 0.3-0.4
# Primary elements at 1.0

Color meaning consistency

Once a color is assigned a meaning, it keeps that meaning for the entire video:

# If PRIMARY (#58C4DD) means "the model" in Scene 1,
# it means "the model" in every scene.
# Never reuse PRIMARY for a different concept later.

Data Visualization Quality

Minimum requirements for charts

  • Axis labels on every axis
  • Y-axis range starts at 0 (or has a clear break indicator)
  • Bar/line colors match the legend
  • Numbers on notable data points (at least the maximum and the comparison point)

Animated counters

When showing a number changing:

# GOOD: DecimalNumber with smooth animation
counter = DecimalNumber(0, font_size=48, num_decimal_places=0, font="Menlo")
self.play(counter.animate.set_value(1000), run_time=3, rate_func=rush_from)

# BAD: Text that jumps between values

Pre-Render Checklist

Before running manim -qh:

  • All scenes render without errors at -ql
  • Preview stills at -qm for text-heavy scenes (check kerning)
  • Background color set in every scene (self.camera.background_color = BG)
  • add_subcaption() or subcaption= on every significant animation
  • No text smaller than font_size=18
  • No text using proportional fonts (use monospace)
  • buff >= 0.5 on all .to_edge() calls
  • Clean exit (FadeOut all) at end of every scene
  • self.wait() after every reveal
  • Color constants used (no hardcoded hex strings in scene code)
  • All scenes use the same quality flag (don't mix -ql and -qh)

Post-Render Checklist

After stitching the final video:

  • Watch the complete video at 1x speed — does it feel rushed anywhere?
  • Is there a moment where two things animate simultaneously and it's confusing?
  • Does every text label have enough time to be read?
  • Are transitions between scenes smooth (no black frames, no jarring cuts)?
  • Is the audio in sync with the visuals (if using voiceover)?
  • Is the Gibbs-like "first impression" good? The first 5 seconds determine if someone keeps watching