<!--
  Dieser Skill ist eine der Arbeitsanweisungen, mit denen die Filme auf
  caligatus.eu entstanden sind. Er liegt hier so, wie er im Einsatz ist — bis
  auf Pfade und Zugangsdaten, die durch Platzhalter ersetzt wurden.

  Ablage: ~/.claude/skills/<name>/SKILL.md
  Zugang: die Umgebungsvariable KIE_API_KEY muss gesetzt sein.
-->

---
name: whiteboard
description: >
  Whiteboard-Animationen erzeugen, also Filme, in denen eine echte Hand die
  Zeichnung vor der Kamera Strich für Strich malt und zwischen zwei Bildern mit
  der flachen Hand wieder wegwischt. Aus jeder Strichzeichnung werden dabei
  automatisch die Zeichenpfade gewonnen. Nutzen bei: "Whiteboard", "Whiteboard-
  Video", "Whiteboard-Animation", "Scribble-Video", "zeichnende Hand", "Hand
  malt", "Erklärvideo im Whiteboard-Stil", "VideoScribe", "Doodly". Auch für
  einzelne Szenen innerhalb einer größeren Produktion — der Skill liefert dann
  die Animation, während Sprache, Musik und Schnitt beim `schulung`-Skill
  bleiben.
---

# /whiteboard — Zeichnende Hand für Erklärvideos

Erzeugt aus Strichzeichnungen ein HyperFrames-Projekt, in dem eine
fotorealistische Hand die Zeichnung malt. Der Ton läuft weiterhin über
`media-skill` und kie.ai, dieser Skill liefert nur die Animation — dafür aber
**zeitgenau**, damit sie zu den gemessenen Sprechabschnitten passt.

**Über Videomodelle geht das nicht.** Seedance und Verwandte erzeugen jedes Bild
neu und können nicht garantieren, dass ein gezogener Strich stehen bleibt. Genau
darauf beruht der Stil.

## Voraussetzungen

Einmalig eine Python-Umgebung anlegen (Skelettierung braucht numpy und
scikit-image, beides ist nicht im System-Python):

```bash
python3 -m venv ~/.claude/venvs/whiteboard
~/.claude/venvs/whiteboard/bin/pip install numpy scikit-image pillow
```

Alle Skripte hier werden mit diesem Python aufgerufen:
`~/.claude/venvs/whiteboard/bin/python`.

Dazu HyperFrames (`npx hyperframes`, wird bei Bedarf geladen) und für neue
Motive ein Zugang zu einem Bildmodell.

## Der Ablauf

### 1. Motive erzeugen

Ein Bild je Szene, über `media-skill` mit `gpt-image-2-text-to-image`, 10 Credits
je Bild in 2K. Den erprobten Prompt-Baukasten dafür in
`references/prompts.md` verwenden.

**Die Vorlage muss eine reine Strichzeichnung sein.** Alle Tonwerte aus offener
Schraffur mit weißen Zwischenräumen, **keine gefüllten schwarzen Flächen, keine
Graustufen, keine Verläufe**. Flächen ergeben beim Skelettieren Astwerk statt
Linien und sehen im Film aus wie ein Kurzschluss.

### 2. Sprechtext vertonen und messen

Wie immer über `media-skill`. **Erst vertonen, dann die Längen setzen** — die
Dauer je Szene kommt aus dem gemessenen Abschnitt, nicht aus einer Schätzung.

### 3. Szenenliste schreiben

```json
{
  "name": "erklaervideo-xy",
  "szenen": [
    {"motiv": "bilder/01.png", "dauer": 12.4},
    {"motiv": "bilder/02.png", "dauer": 8.1, "wischen": false},
    {"motiv": "bilder/03.png", "dauer": 9.0, "hoehe": 700}
  ]
}
```

`dauer` ist die **volle Länge der Szene**, einschließlich Hand herein, Zeichnen,
Hand hinaus und Wischen. Die Summe aller Dauern ist damit die Filmlänge, und die
Werte lassen sich direkt aus den Sprechabschnitten übernehmen.

Optional je Szene:

| Feld | Vorgabe | Wirkung |
|---|---|---|
| `wischen` | `true` | bei `false` bleibt die vorige Zeichnung stehen und die neue entsteht darüber |
| `zeichnen` | `true` | bei `false` steht die Zeichnung **sofort** vollständig da, ohne Hand |
| `hoehe` | 900 | Motivhöhe im Bild, von 1080 |
| `breite` | 1100 | Arbeitsbreite beim Vektorisieren; kleiner heißt weniger Details, aber auch stärkere Skalierung — als Tempobremse nur bedingt geeignet |

**`zeichnen: false` ist mehr als eine Abkürzung.** Es ist das dramaturgische
Gegenstück zum Whiteboard: ein Bild, das eben nicht entsteht, sondern einfach
dasteht. Wer beides hintereinander zeigt, lässt den Zuschauer den Unterschied
erleben, statt ihn zu behaupten. Ein Erklärfilm über Whiteboard-Animation sollte
genau damit anfangen.

### 4. Projekt bauen

```bash
~/.claude/venvs/whiteboard/bin/python ~/.claude/skills/whiteboard/scripts/bauen.py \
  szenen.json projekt
```

Das Skript gewinnt die Pfade, setzt die Hände ein, rechnet die Zeiten aus und
schreibt ein fertiges HyperFrames-Projekt. Es meldet je Szene das Zeichentempo.

### 5. Prüfen und rendern

```bash
cd projekt && npm run check && npm run render
```

**Vor dem Rendern immer Einzelbilder ansehen**, mindestens eines mittendrin:

```bash
npx hyperframes snapshot . --at 3,8,13
```

## Das Zeichentempo ist die Planungsgröße

Tempo ist Pfadlänge mal Skalierung, geteilt durch die Zeichenzeit.

**⚠ Die Skalierung gehört zwingend in die Rechnung.** Die Pfade entstehen im
Arbeitsmaßstab (`breite`, Vorgabe 1100) und werden fürs Video vergrößert. Wer
nur die Arbeitspixel misst, unterschätzt das sichtbare Tempo um genau diesen
Faktor. Bei einer klein abgetasteten Vorlage sind das schnell drei Fach.

| Sichtbares Tempo | Wirkung |
|---|---|
| um **1400 px/s** | angenehm, der Strich ist gut zu verfolgen |
| bis 3000 px/s | zügig, trägt noch; ein fertiger Film liegt stellenweise bei 2960 |
| über **3000 px/s** | die Hand rast, Schraffuren entstehen in Zuckungen |

Gewarnt wird ab 2500, damit noch Luft bleibt. Die Warnung ist ein Hinweis zum
Hinsehen, kein Verbot.

**Bei einer Warnung das Motiv vereinfachen, nicht das Tempo senken.** Die
Szenendauer steht fest, sie kommt aus dem Sprechtext. Das Skript nennt die
angemessene Strichlänge.

**⚠ Die Arbeitsbreite zu senken hilft nur begrenzt.** Es fallen zwar Details
weg, gleichzeitig steigt aber die Skalierung, weil dasselbe Bild aus weniger
Pixeln aufgeblasen wird. Bei einem gemessenen Rückgang von 39.600 auf 9.600
blieb sichtbar nur ein Drittel Ersparnis übrig statt der vermeintlichen drei
Viertel. Das eigentliche Mittel ist ein einfacheres Motiv: „only the outer
contour, no hatching" im Prompt.

## Die Hände sind fertig und kosten nichts

In `assets/` liegen beide freigestellt, in `assets/haende.json` stehen ihre
gemessenen Kennwerte. **Nicht neu erzeugen**, außer es wird ausdrücklich eine
andere Hand gewünscht — das kostet Credits und bricht die Einheitlichkeit über
mehrere Filme.

Wenn doch: Bild über `media-skill` erzeugen (Prompts in `references/prompts.md`),
dann

```bash
~/.claude/venvs/whiteboard/bin/python ~/.claude/skills/whiteboard/scripts/hand.py \
  roh.png hand-neu.png --art zeichnen
```

Das Skript stellt frei, holt den Stift zurück, misst den Ankerpunkt und gibt den
fertigen Eintrag für `haende.json` aus.

## Die Fallen, die kein Werkzeug meldet

**⚠ Nicht alle Striche in einen Pfad legen.** Der Gedanke liegt nahe: ein
`<path>` mit allen Teilstücken, ein wachsender `stroke-dashoffset`, fertig. SVG
startet das Strichmuster aber **bei jedem Teilstück neu**. Ergebnis: Die
Zeichnung steht sofort vollständig da und die Hand fährt sie nur noch nach. Der
Fehler ist tückisch, weil die Handführung dabei völlig richtig aussieht. Richtig
ist ein Element je Strich; die Vorlage macht das bereits.

**⚠ Der Ankerpunkt ist nicht der oberste dunkle Punkt.** Bei schräg liegendem
Stift trifft das die Oberkante des Schafts, im erprobten Bild 168 Pixel neben der
Spitze — und dann scheint die Farbe aus der Hand zu kommen. Richtig ist der
Extrempunkt entlang der Stiftachse. `hand.py` macht das.

**⚠ Das Freistellen verliert den Stift.** `hyperframes remove-background` nutzt
ein Modell für menschliche Silhouetten und schneidet den Stift weg, sobald der
Arm dominiert. `hand.py` vereinigt die Maske deshalb mit einer Dunkelheitsmaske
aus dem Original.

**⚠ Ein Pfad mit vollem `stroke-dashoffset` ist nicht unsichtbar.** Die runde
Strichkappe bleibt als Punkt stehen. Deshalb wird jeder Strich zusätzlich
ausgeblendet, bis er an der Reihe ist.

**⚠ Die Zeitleiste muss so lang sein wie die Komposition.** Sonst bleibt
`tl.time()` nach dem letzten Tween stehen und das Zittern friert ein. Die
Vorlage hängt dafür einen Platzhalter ans Ende.

**⚠ Das Zittern gehört auf die Hand, nicht auf das Gemalte.** Ein Strich, der
einmal steht, liegt fest. Seine Unregelmäßigkeit steckt in der Form des Pfades.
Bewegen darf sich nur die Hand, und zwar als Drehung um die Stiftspitze, damit
der Ansatzpunkt steht und der Arm wandert.

## Beides ist im Standbild unsichtbar — so wird es geprüft

Ob das Gemalte steht und die Hand sich bewegt, sieht man nur im Vergleich:

```bash
ffmpeg -ss 10.5 -i film.mp4 -frames:v 1 -y a.png
ffmpeg -ss 10.6 -i film.mp4 -frames:v 1 -y b.png
md5 -q a.png b.png
```

Drei Bilder aus der Standzeit am Ende, wenn die Hand aus dem Bild ist, müssen
**gleiche** Prüfsummen haben. Drei Bilder aus einer Zeichenpause, in der die Hand
nicht geführt wird, müssen **verschiedene** haben.

## Was der Skill nicht macht

Sprache, Musik, Schnitt, Untertitel und die Kennzeichnung als KI-generiert. Das
läuft über `schulung` und `media-skill`. **Jedes fertige Video wird
gekennzeichnet**, auch ein reines Whiteboard-Video:

```bash
python3 ~/.claude/skills/schulung/scripts/kennzeichnung.py fertig.mp4
```

## Kosten

Die Hände sind bezahlt und liegen bei. Es bleiben **10 Credits je Motiv**, rund
4 Cent. Vektorisieren, Animation und Rendern kosten nichts.

## Verwandt

- `media-skill` — Bilder, Sprache, Musik über kie.ai
- `schulung` — die Gesamtproduktion, Whiteboard ist dort ein möglicher Stil
- Vault: `Whiteboard-Animation mit HyperFrames`
