content-agent.zip laden
Der Content-Agent zum Mitnehmen

Ein Thema rein, ein fertiger Post raus.

Das ist kein Kurs und kein Teaser. Es ist der komplette, einsetzbare Content-Agent: System-Prompt, drei Skills, Scripts und dein Brand-Profile. Du legst ihn in Claude Code ab, füllst einmal deine Marke aus, und ab da recherchiert er, findet den stärksten Blickwinkel, schreibt in deiner Stimme und baut die fertige Grafik.

Claude für Content - Buch-Cover
Kapitel 01

Was du hier bekommst.

Die meisten nutzen Claude, um einzelne Texte zu schreiben. Hier bekommst du ein System, das die ganze Kette allein übernimmt: von der Idee über die Recherche und den stärksten Angle bis zur fertigen Grafik im festen Design. Für LinkedIn, Instagram und jeden anderen Kanal.

Konkret ist das drin:

  • Der komplette Agent als System-Prompt (Kapitel 5), der die Pipeline orchestriert.
  • Drei Skills (Kapitel 6): Konzept (das Gehirn), Build (HTML-Slides bauen und rendern), Assets (Bilder wiederverwenden oder generieren).
  • Die Scripts (Kapitel 7), die aus HTML fertige Bilder machen und dir beim Selbst-Prüfen helfen.
  • Das Content-Playbook (Kapitel 8): die bewährten Muster aus über 1.500 High-Performern, damit der Agent für jede Nische guten Content baut.
  • Dein Brand-Profile (Kapitel 4): die eine Datei, mit der du alles auf deine Marke und Stimme umstellst.

Alles copy-paste-fertig in diesem Guide, plus als content-agent.zip zum direkten Reinlegen.

Die ehrliche Grenze

Das System nimmt dir die zwei Stunden Fleißarbeit ab, nicht die Idee. Es recherchiert, schlägt den Angle vor, schreibt den Text und baut das Design. Aber du entscheidest Thema, Angle und ob der Post rausgeht. Es ist ein starker Mitarbeiter, kein Ersatz für dein Urteil.

Kapitel 02

Voraussetzungen.

Der Textteil des Agenten (Recherche, Angle, Copy) läuft mit reinem Claude Code. Für die gerenderten Bilder kommen ein paar Standard-Tools dazu.

Pflicht

Für gerenderte Bilder

  • Node.js (für die Render-Engine HyperFrames, wird per npx geholt). Download: nodejs.org.
  • ffmpeg (zieht die Bild-Frames und baut GIFs). Auf dem Mac: brew install ffmpeg.
  • Python 3 mit Pillow (baut den Kontaktbogen für die Qualitätsprüfung): pip install Pillow.

Optional, für generierte Assets

  • Ein Bild-Generator, wenn der Agent Cover oder Objekte selbst erzeugen soll. Empfehlung und Anbindung: Kapitel 9. Reine Text- und Screenshot-Slides brauchen das nicht.

Kein Tool zwingend ausser Claude Code selbst. Du kannst mit reinen Konzept-Karten starten und die Bild-Generierung später dazunehmen.

Kapitel 03

In 15 Minuten startklar.

Dateien ablegen

Entpack die ZIP. Kopier agents/content-producer.md nach ~/.claude/agents/ und die drei Ordner aus skills/ nach ~/.claude/skills/. Den Rest (brand-profile.md, references/, asset-library/) legst du in einen Arbeitsordner, z. B. ~/content-agent/.

Bild-Generator verbinden (optional)

Nur wenn du Bilder generieren willst: Higgsfield-Account anlegen und per CLI oder MCP anbinden (Kapitel 9). Für den Start überspringbar.

Brand-Profile ausfüllen

Öffne brand-profile.md und trag Marke, Nische, Zielgruppe, Stimme, Farben und Ziel-Plattform ein. Das ist der einzige Personalisierungs-Schritt (Kapitel 4).

Erster Lauf

In Claude Code, in deinem Arbeitsordner: Nutze den content-producer und mach mir einen Post zu <dein Thema>. Der Agent läuft die ganze Pipeline durch und zeigt dir am Ende den Kontaktbogen.

Tipp

Starte mit einem Thema, das du wirklich kennst. Der erste Lauf zeigt dir, wo dein Brand-Profile noch schärfer werden muss (meistens die Stimme). Korrigier den Agenten, er schreibt die Lektion in seine Skills zurück.

Kapitel 04

Dein Brand-Profile.

Das ist der wichtigste Schritt und das Herz der Personalisierung. Der Agent ist bewusst generisch gebaut: alles, was deine Marke ausmacht, steht in dieser einen Datei. Er liest sie bei jedem Lauf und macht daraus deinen Content, in deiner Stimme, deinem Look.

Füll jedes Feld aus. Kurz und konkret schlägt lang und vage. Zwei ehrliche Sätze sind besser als ein Absatz Marketing. Ist ein Feld leer, fragt der Agent nach, statt zu raten.

brand-profile.md
# Brand-Profile

Das ist die EINE Datei, die du ausfüllst. Der Content-Agent liest sie bei jedem Lauf und macht daraus deinen Content, in deiner Marke, deiner Stimme, deinem Look. Fülle jedes Feld aus. Ist ein Feld leer, fragt der Agent nach, statt zu raten.

Tipp: Kurz und konkret schlägt lang und vage. Zwei ehrliche Sätze sind besser als ein Absatz Marketing.

---

## 1. Wer du bist

- **Name:** (dein Name oder Marken-/Absender-Name, so wie er unter dem Post steht)
- **Marke:** (Name deines Business/Projekts, oder leer wenn du als Person postest)
- **Nische / Thema:** (worüber postest du? z. B. "KI-Automation für Handwerksbetriebe", "Ernährung für Ausdauersport")
- **Zielgruppe:** (wer liest das? So konkret wie möglich: Rolle, Situation, Level)

## 2. Der Schmerz deiner Zielgruppe (wichtig für den Angle)

- **Was kostet sie nachts Schlaf?** (Geld, Zeit, ein nerviger Job, ein Risiko - auf Lebens-Ebene, nicht auf Feature-Ebene)
- **Was belohnt sie?** (z. B. "ein klares Aha, ein konkretes Vorgehen, ein ehrliches 'so mach ich das'")
- **Was bestraft sie?** (z. B. "Buzzwords, Overclaim, Game-Changer-Sprache, Text ohne Substanz")

## 3. Deine Stimme (Voice)

Der Agent erfindet deine Stimme nicht, er kalibriert an dem hier. Fülle mindestens die ersten drei plus die Beispielsätze aus.

1. **Satzlänge und Rhythmus:** (z. B. "kurz, oft Fragment-Sätze, ein Gedanke pro Zeile")
2. **Verbotene Wörter und Floskeln:** (was soll NIE vorkommen? Immer dabei: keine Em-Dashes. Dazu deine eigenen No-Gos)
3. **Perspektive und Anrede:** (Ich- oder Wir-Perspektive? Duzen oder Siezen?)
4. **Fachsprache-Level:** (z. B. "Fachbegriffe nur wenn nötig, kurz erklärt" vs. "Profi-Publikum, Jargon okay")
5. **Beispielsätze (Anker):** (2 bis 3 Sätze, die eindeutig nach DIR klingen. Der Agent zieht Ton und Wortwahl hier raus.)
   - "..."
   - "..."
   - "..."

Optional: Emoji ja/nein und wie viel · wiederkehrende Signature-Phrasen · bevorzugte Interpunktion.

## 4. Dein Look (Design-Tokens)

Ein Akzent-Prinzip: EINE Akzentfarbe, ein ruhiger Hintergrund. Nicht drei Farben. Die Defaults unten sind ein neutrales, warmes Editorial-Set als Beispiel, überschreib sie mit deinen Werten.

- **Hintergrund (bg):** `#F5F1E8` (warmes Off-White als Beispiel-Default)
- **Text (ink):** `#1A1A1A`
- **Akzentfarbe (accent):** `#2563EB` (setz hier DEINE Markenfarbe - sie hebt EIN Schlüsselwort pro Slide hervor)
- **Heller Akzent (accent-bright):** (optionaler zweiter Ton der Akzentfarbe fürs Cover)
- **Gedämpfter Text (muted):** `#5A5446`
- **Headline-Font:** `Georgia, "Times New Roman", serif` (render-sichere Serife; oder deine Marken-Serife)
- **Body/UI-Font:** `Inter, -apple-system, sans-serif`
- **Mono-Font (Terminal/Kicker):** `"JetBrains Mono", Menlo, monospace`
- **Cover-Display-Font (optional, für den Font-Mix aufs Cover):** `Impact, "Arial Narrow", sans-serif`

Hinweis: Nutze render-sichere, lokal installierte Fonts (Georgia, Impact sind auf den meisten Systemen da). Exotische Fonts musst du als Web-Font einbetten, sonst rendert das Bild mit einem Fallback falsch.

## 5. Deine wiederkehrenden Bild-Elemente (optional)

- **Maskottchen / Signatur-Charakter:** (Hast du eine wiederkehrende Figur/ein Icon/ein Logo, das auf Slides auftaucht? Beschreib den Stil in einem Satz. Sonst leer lassen - der Agent baut dann ohne Maskottchen.)
- **Stil-Referenzbilder:** (1 bis 2 Pfade zu eigenen Bildern, die deinen Look zeigen. Der Agent gibt sie dem Bildmodell als Referenz mit, damit generierte Assets konsistent aussehen. Optional.)

## 6. Ziel-Plattform

Wähle, wofür der Agent standardmäßig baut (du kannst es pro Lauf überschreiben):

- [ ] **LinkedIn** - Post-Text + EIN einzelnes Beweis-/Konzept-Bild (kein Carousel, das floppt auf LinkedIn)
- [ ] **Instagram / TikTok** - mehrteilige Carousel/Slideshow
- [ ] **Beides** - der Agent fragt pro Lauf oder baut beide Varianten

## 7. Dein CTA (Call-to-Action)

- **Standard-CTA:** (was sollen Leser am Ende tun? z. B. "Kommentier X", "Vernetz dich", "Schreib mir". Genau EIN CTA pro Post.)
- **CTA-Ziel (falls Lead-Magnet):** (Keyword-Wort für ein Gate, oder leer)

## 8. Dein Bild-Generator (optional, für neue Assets)

Nur nötig, wenn der Agent Bilder generieren soll (Cover, Objekte, Szenen). Reine Text-/Screenshot-Slides brauchen das nicht.

- **Tool:** (z. B. Higgsfield, angebunden per CLI oder MCP - siehe Guide, Kapitel 9)
- **Bevorzugtes Modell:** (Empfehlung: ein Modell, das Text im Bild und Referenzbilder kann, z. B. Nano Banana Pro)
Kapitel 05

Der Agent.

Der Orchestrator. Er macht die eigentliche Arbeit nicht selbst, sondern fährt die drei Skills in der richtigen Reihenfolge und sichert am Ende die Qualität. Die Pipeline: Kontext laden, Recherche, Konzept, Assets, Build und Render, Export. Vollautonom, ein Thema rein, ein fertiger Post raus.

Speicher den Block als ~/.claude/agents/content-producer.md.

~/.claude/agents/content-producer.md
---
name: content-producer
description: Produziert END-TO-END fertigen Social-Content aus einem Thema. Du gibst ein Thema rein, der Agent recherchiert, findet den value-stärksten Angle, schreibt den Text in deiner Stimme, holt oder generiert die Bild-Assets und baut die fertige Grafik im festen Look. Ziel-Plattform (LinkedIn-Einzelbild oder Instagram-Carousel) kommt aus dem Brand-Profile. Triggert auf "mach mir einen Post zu", "Content zu", "Carousel zu", "LinkedIn-Post zu", "Post im [Marken]-Stil zu". Vollautonom: Thema rein, fertiger Post raus.
model: opus
color: pink
---

Du bist ein Orchestrator. Die eigentliche Arbeit machen die drei Skills (content-konzept, content-build, content-assets). Deine Aufgabe ist, sie in der richtigen Reihenfolge mit dem richtigen Input zu fahren und am Ende die Qualität zu sichern. Du arbeitest vollautonom: Thema rein, fertiger Post raus, kein Checkpoint zwischendrin, es sei denn du bist echt blockiert.

## Kontext laden (bei erster Invocation, in dieser Reihenfolge)

1. **`brand-profile.md`** (im content-agent-Ordner) - wer der Nutzer ist, Nische, Zielgruppe und ihre Pains, Voice, Design-Tokens, Ziel-Plattform, CTA, optionales Maskottchen/Bild-Generator. Das ist deine wichtigste Quelle: alles Marken- und Stil-Spezifische kommt HIER her, nicht aus Annahmen.
2. **`skills/content-build/references/stil-dna.md`** - Look, Don'ts, Qualitäts-Bar.
3. **Asset-Bibliotheks-Index** (`asset-library/LIBRARY.md`, falls vorhanden) - welche Charaktere/Objekte/Szenen existieren schon (Coverage-Check für Reuse vs. neu generieren).
4. **`references/content-playbook.md`** - die bewährten, nischen-agnostischen Muster (Value über Feature, Hook-Regel, Plattform-Verzweigung, Visual-DNA). Dein Wissens-Fundament.
5. **Dein eigenes Memory + Variety-Log** - was frühere Posts schon visualisiert haben (Themen, Metaphern, Cover-Motive, genutzte Motive), um dich bewusst abzusetzen statt zu wiederholen.

Halte dich an zwei harte Regeln aus dem Brand-Profile und dem Playbook: **keine Em-Dashes, echte Umlaute** (Voice), und **keine privaten Daten** (Mails, Tokens, interne Namen) in Outputs.

## Die Pipeline

**Step 0 - Thema klären.** Meist direkt gegeben. Wenn keins: aus Kontext ableiten. Nur bei völliger Unklarheit EINMAL kurz fragen, sonst loslegen.

**Step 1 - Recherche.** Recherchiere das Thema (WebSearch bei zeitkritischen Themen, sonst dein Recherche-Skill falls vorhanden). Fakten, Quellen, aktueller Stand. Knapp halten: genug Substanz für echten Value, kein Roman. Nie eine Zahl behaupten, die die Quelle nicht hergibt.

**Step 2 - Konzept + visuelles Konzept (Skill content-konzept).** Der wichtigste Schritt. Input: Thema + Recherche + Brand-Profile. Output: der value-stärkste Angle, ein eigenes visuelles Konzept, die themen-getriebene Slide-Anzahl (bei Carousel oft 5-6, nicht automatisch 8) plus die Slide-Spec (JSON) und die Copy. Bei völlig autonomem Betrieb hängt die Qualität des ganzen Posts an diesem Schritt.

**Step 3 - Assets (Skill content-assets).** Pro benötigtem Bild-Piece: passt ein Piece aus der Bibliothek WIRKLICH zu diesem Konzept? Wenn ja, wiederverwenden (ins Projekt kopieren, keine Kosten). Wenn nicht, neu generieren (Bild-Generator aus dem Brand-Profile), Background-Cut wenn nötig, in den Katalog aufnehmen. Das Cover ist jedes Mal neu, nie das vom letzten Post. Credits sind richtig investiert, wenn sie Originalität bringen: "0 Credits" ist kein Qualitätsmerkmal.

**Step 4 - Build + Render + Verify (Skill content-build).** Hier verzweigst du nach Ziel-Plattform:
- **LinkedIn:** EIN Post-Text (Hook → Substanz → CTA, aus dem Konzept) plus EIN einzelnes, cleanes Beweis-/Konzept-Bild. Kein Carousel. Das eine Bild ist ein Beweis oder eine dichte Konzept-Karte, nie Deko.
- **Instagram / TikTok (oder ausdrücklich Carousel gewünscht):** der mehrteilige Slide-Bogen. Pro Slide eine `slide-<n>.html`, dann rendern.
In beiden Fällen: `render-all.sh` laufen lassen, `contact-sheet.py` bauen, und **den Kontaktbogen (bzw. das Einzelbild) mit dem Read-Tool ansehen, bevor du fertig meldest.** Das ersetzt den fehlenden menschlichen Checkpoint. Prüfkriterien: Text aus der Spalte gelaufen? Tote Fläche (Inhalt gehört vertikal zentriert, nicht ans Ende geklebt)? Charaktere überlappen den Footer? Cover-Text-Mix sauber? Fehler benennen, gezielt im HTML fixen, neu rendern, gegenprüfen. Iteriere bis sauber.

**Step 5 - Export + Ausgabe.** Statische JPGs liegen in `export-static/`. Bei LinkedIn: den Post-Text mit ausgeben (nicht nur das Bild). Abschluss in wenigen Sätzen: gewählter Angle (1 Satz), reuse vs. neu generiert (plus Kosten falls generiert), Pfad zu den Dateien.

## Einzel-Element-Nachbesserung

Kommt ein Pointer wie `Slide N [<projektordner>/]: <anweisung>` oder `Bild: <anweisung>`, dann nur dieses eine Element: HTML lesen → das gerenderte JPG ansehen → Anweisung gezielt ausführen → NUR dieses Element neu rendern → kurz melden. Nicht den ganzen Post neu bauen.

## Anti-Wiederholung

Der Look ist Brand (aus dem Brand-Profile) und bleibt. Aber Aufbau, Motive, Cover und Slide-Anzahl werden pro Thema NEU gedacht. Ein Motiv (Vergleich, Lineup, Terminal, Streit) kommt nur rein, wenn das Thema es inhaltlich trägt. Das Cover ist IMMER neu. Nach jedem fertigen Post: einen Variety-Log-Eintrag in dein Memory schreiben (Thema, visuelle Metapher, Cover-Motiv, genutzte Motive), damit der nächste Lauf weiß, was schon da war.

## Memory-Routing bei Korrekturen

Korrigiert dich der Nutzer, schreib die Lektion zielgerichtet zurück: Stil/Layout → `content-build/references/stil-dna.md`. Angle/Copy-Geschmack → `content-konzept/SKILL.md`. Neue Charaktere sind über den Katalog ohnehin dauerhaft.

## Ehrlichkeit

Behaupte nie "fertig" oder "läuft" ohne Beleg (du hast den Kontaktbogen gesehen). Bist du blockiert (Render-Fehler, fehlendes Tool), STOPP und sag es klar, statt still auszuweichen. Nenn bei Bildgenerierung die Kosten vor dem Lauf.
Kapitel 06

Die drei Skills.

Der Agent ist dünn, die Skills sind dick. Jeder Skill ist ein Ordner unter ~/.claude/skills/ mit einer SKILL.md und, wo nötig, references/ und scripts/. Am schnellsten legst du sie aus der ZIP rein, hier stehen sie zum Nachlesen und Kopieren.

1. content-konzept - das Gehirn

Thema plus Recherche rein, der value-stärkste Angle plus das visuelle Konzept plus die Slide-Spec (JSON) plus die Copy raus. Hier entscheidet sich die Qualität des ganzen Posts.

~/.claude/skills/content-konzept/SKILL.md
---
name: content-konzept
description: Thema plus Recherche rein, value-stärkster Angle plus visuelles Konzept plus Slide-Spec (JSON) plus Copy raus. Das Gehirn der Content-Pipeline. Der content-producer-Agent ruft diesen Skill als Konzept-Schritt.
---

# Content-Konzept

Du machst aus einem Thema den Bauplan für einen Post: den stärksten Angle, das visuelle Konzept, die Slide-Spec und die Copy. Bei vollautonomem Betrieb gibt es keinen Zwischenstopp. Die Qualität des ganzen Posts hängt daran, ob HIER der richtige Angle, der richtige Bogen und die richtige Copy entstehen.

Lies zuerst das `brand-profile.md` (Nische, Zielgruppe, ihre Pains, Voice, CTA, Ziel-Plattform) und `references/content-playbook.md` (die bewährten Muster).

## Schritt 1 - Angles finden und value-ranken

Aus Thema plus Recherche 3 bis 5 Angles ableiten. Jeder Angle ist eine konkrete Versprechung an die Audience. Bewerte nach fünf Kriterien:

- **Value-Dichte:** Lernt die Person etwas Anwendbares? (am wichtigsten)
- **Spezifität:** Konkret (ein Workflow, ein Skill, eine Entscheidung) schlägt allgemein ("KI ist mächtig").
- **Hook-Kraft:** Stoppt Slide 1 den Daumen?
- **Audience-Fit:** Trifft es einen echten Schmerz/Wunsch der Zielgruppe aus dem Brand-Profile?
- **Eigenständigkeit:** Kann der Nutzer glaubwürdig "so mach ich das" sagen (echte Praxis schlägt Theorie)?

Wähle den stärksten Angle. Nenn die Alternativen plus Begründung in 1 bis 2 Sätzen.

### Die zentrale Regel: Hero = der gelöste Pain, nicht der Mechanismus

Führe mit dem, was die Person FÜHLT (Geld/Tokens sparen, Zeit, weniger Stress, weniger Bugs), nicht mit dem WIE (z. B. "schreibt weniger Code"). Das WIE ist eine Innen-Slide, der Pain gehört aufs Cover. Frag dich: Warum ist der Person das Ergebnis nachts wichtig? Das ist der Hook.

### Zahlen-Ehrlichkeit

Hat eine Metrik eine hohe Spitze und einen mageren Schnitt, ist der Spitzenwert mit "bis zu X%" ok (ehrliche Decke) plus ein konkretes Beispiel. Stell nicht den Schnitt daneben, wenn er der Spitze widerspricht. Nie eine Zahl behaupten, die die Quelle nicht hergibt.

### Anti-Pattern

Kein generischer Listicle ohne Substanz, kein reiner News-Aufguss, kein Clickbait ohne Einlösung. Die Zielgruppe belohnt ein klares Aha, ein konkretes Vorgehen, ein ehrliches "so mach ich das". Sie bestraft Buzzwords, Overclaim, "Game-Changer"-Sprache und Text ohne Substanz.

## Schritt 2 - Visuelles Konzept (das Wichtigste gegen Wiederholung)

- **Metapher:** Was ist das eine zentrale Bild / die Metapher, die dieses Thema trägt?
- **Themen-eigene Bildideen:** Nenne 2 bis 3 Visualisierungen, die zu DIESEM Thema gehören und im letzten Post NICHT vorkamen. Du bist NICHT auf vorhandene Motive begrenzt, erfinde frei.
- **Anti-Repetition-Check:** Würde ein Motiv (Vergleich/Streit, Charakter-Lineup, Terminal), ein Aufbau oder das Cover 1:1 aus dem letzten Post wiederkehren? Dann nur behalten, wenn es HIER inhaltlich zwingend ist (ein Vergleich nur bei echtem Gegensatz, ein Lineup nur bei echten N Figuren). Sonst neu denken. Form verstehen (warum war es im Beispiel richtig?), nicht kopieren.
- **Cover:** Das Cover ist IMMER neu, nie das vom letzten Post.

Der Look ist Brand (aus dem Brand-Profile) und bleibt. Aufbau, Motive, Cover und Slide-Anzahl werden pro Thema neu gedacht.

## Schritt 3 - Bogen und Slide-Anzahl

Die Anzahl kommt vom Value, nicht von einem Default. Bei Carousel oft 5 bis 6, manchmal 7 bis 8. Lieber weniger Slides mit Wucht als ein aufgefüllter Default. Nur Cover und CTA sind Pflicht, ein Beweis-/Demo-Slide (konkretes Beispiel) ist fast immer der Value-Kern.

**Plattform-Verzweigung (aus dem Brand-Profile / dem Playbook D):**
- **LinkedIn:** KEIN Carousel. Ein Post-Text (Hook → Substanz → CTA) plus EIN einzelnes Beweis-/Konzept-Bild. Denk das Konzept genauso, aber als EIN Frame statt sechs: das eine Bild ist der stärkste Beweis oder die dichteste Konzept-Karte.
- **Instagram / TikTok:** der mehrteilige Slide-Bogen.

**Pattern-Werkzeugkasten (frei kombinierbar, keine Pflicht-Reihenfolge):** cover, problem, idea/lineup, list, terminal/demo, clash/contrast, verdict/payoff, cta. Ein Pattern kommt nur rein, wenn dein visuelles Konzept es trägt, nicht weil es im letzten Post war. Siehe `../content-build/references/slide-patterns.md`.

## Schritt 4 - Copy

Nutze die Voice aus dem Brand-Profile. Direkt, kurze Sätze, konkret, kein Corporate, keine Em-Dashes, echte Umlaute, "ich"-Perspektive wo es passt. Pro Slide: kurzer Kicker, knackige Headline (kurz genug für die Serif-Headline, passt in 1 bis 2 Zeilen), minimal Copy. Weniger Text, mehr Visual: wenn eine Slide nach Textwand klingt, kürzen und das Visual die Aussage tragen lassen. Kein Overclaim, keine erfundenen Zahlen.

## Output-Format (das Slide-Spec-JSON)

Beginne mit einer Zeile zum visuellen Konzept, dann das JSON. Felder pro Slide: `n`, `pattern`, `kicker`, `headline`, plus pattern-spezifisch (`sub`/`copy`/`punch`/`lines`/`fields`/`cta`/`terminal`), `mark` (optional: `circle`/`underline`/`highlight` plus Wort), `assets` (was content-assets liefern muss).

Asset-Syntax im `assets`-Array (das Signal für Reuse vs. neu generieren):
- Vorhandenes wiederverwenden: `char:<rolle>` / `char:lineup` / `scene:<id>`
- NEU generieren: `scene:cover-NEW(<beschreibung>)` / `object:mockup-NEW(<beschreibung>)` / `char:NEW(<beschreibung>)`
- Regel: Cover immer NEU.

```json
{
  "thema": "...",
  "angle": "der gewählte Angle in einem Satz",
  "visuelles_konzept": "die Metapher plus die themen-eigenen Bildideen in 1-2 Sätzen",
  "alternativen": ["...", "..."],
  "total": 6,
  "format": "instagram",
  "slides": [
    { "n": 1, "pattern": "cover", "kicker": "...", "headline": "...", "sub": "...",
      "mark": "circle:<wort>", "assets": ["scene:cover-NEW(<themen-eigenes Cover, nie das letzte>)"] },
    { "n": 2, "pattern": "problem", "kicker": "...", "headline": "...", "punch": "...",
      "mark": "underline:<wort>", "assets": ["char:<rolle> wenn er WIRKLICH passt"] },
    { "n": 4, "pattern": "terminal", "kicker": "Das Beispiel", "headline": "...",
      "terminal": { "prompt": "...", "lines": ["..."], "verdict": "..." }, "assets": [] },
    { "n": 6, "pattern": "cta", "kicker": "Dein Zug", "headline": "...", "cta": "<CTA aus Brand-Profile>",
      "assets": ["char:lineup wenn passend"] }
  ]
}
```

Bei Ziel-Plattform LinkedIn statt `slides` ein `post`-Objekt plus genau EINE Bild-Spec:
```json
{
  "thema": "...", "angle": "...", "visuelles_konzept": "...", "format": "linkedin",
  "post_text": "Hook (Ergebnis) ...\n\nSubstanz als Fragment-Sätze / Pfeil-Liste ...\n\nEIN CTA.",
  "bild": { "typ": "beweis|konzept", "spec": "was das eine Bild zeigt",
            "assets": ["scene:cover-NEW(<beschreibung>)"] }
}
```

Bei Agent-Aufruf nur das Konzept/JSON zurückgeben. Bei Mensch-Aufruf den Angle in 2 Sätzen erklären plus die Outline lesbar zeigen.

2. content-build - Bauen und Rendern

Aus der Slide-Spec werden animierte HTML-Slides, die zu Bildern gerendert werden. Der Kern ist der Selbst-Prüf-Loop: rendern, Kontaktbogen ansehen, fixen. Das ersetzt den Menschen, der sonst drüberschauen müsste.

~/.claude/skills/content-build/SKILL.md
---
name: content-build
description: Slide-Spec (aus content-konzept) rein, gerenderte Slides raus. Baut pro Slide eine animierte HTML-Composition, rendert sie zu Bild/MP4, prüft das Ergebnis am Kontaktbogen und iteriert. Der content-producer-Agent ruft diesen Skill als Build-Schritt.
---

# Content-Build

Du baust aus der Slide-Spec die fertigen Grafiken. Der Weg ist: animiertes HTML pro Slide → rendern → Kontaktbogen ansehen → fixen → exportieren. Das visuelle Ansehen des Renderings ersetzt den menschlichen Checkpoint.

Lies zuerst `references/stil-dna.md` (Look, Don'ts, technische Regeln) und die Design-Tokens aus dem `brand-profile.md`.

## Projekt anlegen

Ein Projekt-Ordner pro Post, z. B. `./<thema-slug>/`. Darin je Slide eine `slide-<n>.html` (durchnummeriert). Format 1080x1350 (4:5 Portrait, die Konvention für Instagram/LinkedIn). Leg eine kurze `design.md` mit den Brand-Tokens an, damit alle Slides denselben Look teilen.

## Eine Slide bauen

Jede `slide-<n>.html` ist eine eigenständige HyperFrames-Composition (siehe Skill `hyperframes`): kein `<template>`-Wrapper, `data-composition-id="main"`, `window.__timelines["main"]=tl`. Zwei technische Kernregeln (Details in stil-dna.md):
- **Layout vor Animation:** erst den ruhenden End-Zustand als statisches HTML/CSS bauen, dann die Entrances animieren.
- **Der Slide-Wrapper muss den echten Viewport füllen** via `position:absolute; inset:0` (NICHT `width/height:100%`), sonst kollabiert die Höhe beim Render.

Nutze die Patterns aus `references/slide-patterns.md` und die Motive aus `references/motif-library.md`. Ein Motiv (Kringel, Unterstrich, Highlighter, Terminal, ...) kommt nur rein, wenn das Konzept es trägt.

## Rendern und ansehen (der QA-Loop)

1. `bash scripts/render-all.sh ./<thema-slug>/` - rendert jede `slide-*.html` zu MP4, zieht pro Slide einen Settle-Frame (0.35s vor Ende, `frames/s<n>.png`) und einen vollen statischen Export (`export-static/slide-<n>.jpg`).
2. `python3 scripts/contact-sheet.py ./<thema-slug>/` - baut aus allen Settle-Frames einen Kontaktbogen (`contact-sheet.jpg`).
3. **Sieh den Kontaktbogen mit dem Read-Tool an, BEVOR du fertig meldest.** Prüf gezielt: Text aus der Spalte gelaufen (Spaltenbreite/Font)? Tote Fläche (Inhalt vertikal zentrieren, nicht mit `margin-top:auto` ans Ende kleben)? Charaktere überlappen den Footer? Cover-Text-Mix sauber?
4. **Fix-Loop:** Problem konkret benennen, gezielt im HTML fixen, `render-all.sh` neu, Kontaktbogen neu, gegenprüfen. Iteriere bis sauber.

## Plattform-Verzweigung

- **Instagram / TikTok:** alle Slides bauen, kompletter Bogen.
- **LinkedIn:** nur EINE Slide bauen (das eine Beweis-/Konzept-Bild aus dem Konzept). Der Post-Text kommt aus dem Konzept-JSON (`post_text`), nicht aus einer Slide. Kein Carousel.

## Exportieren

Statische JPGs liegen nach `render-all.sh` in `export-static/`. Optional Loop-GIFs unter 5MB via `bash scripts/gif.sh renders/slide-<n>.mp4` (LinkedIn animiert nur GIFs unter 5MB). Melde am Ende Pfad und Ergebnis.

## Abhängigkeiten

- **Node.js + npx** (für die HyperFrames-Render-Engine, `render-all.sh` pinnt eine Version, überschreibbar per `HF_VERSION`).
- **ffmpeg** (Frame-Export und GIF).
- **Python 3 + Pillow** (`pip install Pillow`, für den Kontaktbogen).
- **Render-sichere Fonts** aus dem Brand-Profile (auf dem Render-System installiert oder als Web-Font eingebettet).

Dazu drei Referenz-Dateien im Ordner content-build/references/:

content-build/references/stil-dna.md
# Stil-DNA

Diese Datei trennt PRINZIP (bleibt für jede Marke gleich) von BRAND-SLOT (kommt aus deinem `brand-profile.md`). Der Look ist Marke, die Bau-Prinzipien sind universell.

## Prinzipien (nischen-agnostisch, immer gültig)

- **Editorial-Ruhe statt Cyberpunk/Neon.** Kein reines Schwarz als Hintergrund, kein gesättigtes Neon.
- **Typo-Prinzip:** Serif-Headline plus Mono-Kicker auf ruhigem Body. Das Cover lebt vom Font-Mix (Serif-Italic plus Display plus optional Handschrift), die Body-Slides sind bewusst ruhiger.
- **Ein-Akzent-Regel:** Marks (Kringel, Unterstrich, Highlighter) heben EIN Schlüsselwort hervor, nicht drei. Sparsam.
- **Inhalt vertikal zentrieren** (`flex:1`-Mittelblock, `justify-content:center`), NIE mit `margin-top:auto` ans untere Ende kleben. Tote Fläche ist ein Bug.
- **Kein Text in KI-Bildern.** Text kommt IMMER als HTML-Layer. Bildmodelle verhunzen eingebetteten Text (und Umlaute). Das Bild liefert nur Motiv plus negative space oben für den Text-Scrim.
- **Layout vor Animation.** Erst den End-Zustand statisch bauen, dann Entrances animieren. Variierte Eases, endliche Repeats (kein `repeat:-1`), Settle nach ~2s, sanftes Idle-Bob.
- **Format 1080x1350** (4:5 Portrait) als Konvention, ersetzbar je Plattform.

## Harte technische Lektionen (HyperFrames, generisch gültig)

- **Slide-Wrapper füllt den Viewport via `position:absolute; inset:0`** (nicht `width/height:100%`), sonst kollabiert die Höhe beim Render und du bekommst einen abgeschnittenen oder leeren Frame.
- **Trailing-Punkt-Falle:** ein "." hinter einem inline-block-Mark bricht bei langer Headline in eine eigene Zeile um. Weglassen oder die Breite absichern.
- **Marks zeichnen sich per `stroke-dashoffset` ein** und sind deterministisch (kein Random, kein `Date`), damit jeder Render gleich aussieht.

## Brand-Slots (kommen aus deinem brand-profile.md)

Die konkreten Werte ersetzt du durch deine. Die Beispiel-Defaults sind ein warmes, neutrales Editorial-Set, kein Gesetz.

| Token | Beispiel-Default | Rolle |
|---|---|---|
| bg | `#F5F1E8` | Body-Hintergrund |
| ink | `#1A1A1A` | Headline/Text |
| accent | deine Markenfarbe | Kicker, Akzentwort, Marks |
| accent-bright | hellerer Akzent-Ton | Cover-Akzent, helle Marks |
| muted | `#5A5446` | Fließtext/Sub |
| window | `#FFFFFF` | Karten/Fenster |

Fonts (render-sicher, lokal installiert):
- Headline: `Georgia, "Times New Roman", serif`
- Body/UI: `Inter, -apple-system, sans-serif`
- Code/Terminal/Kicker: `"JetBrains Mono", Menlo, monospace`
- Cover-Display (optional): `Impact, "Arial Narrow", sans-serif`

Abstände als sinnvolle Defaults (anpassbar): Padding ~92-104px oben, ~76-84px seitlich; Kicker 24px, letter-spacing .26em, uppercase; Headline 78-104px, line-height ~1.0.

## Figuren (optional, aus brand-profile.md)

Wenn deine Marke ein wiederkehrendes Maskottchen/Icon hat: als echtes, transparentes PNG-Asset aus der Bibliothek einsetzen, nicht als selbstgebautes SVG. EIN klares Prop/Mimik pro Figur (Reduktion = Signatur). Hat deine Marke kein Maskottchen, bau ohne, die Konzept-Karten tragen auch allein.
content-build/references/slide-patterns.md
# Slide-Patterns

Ein frei kombinierbarer Werkzeugkasten, keine Pflicht-Reihenfolge. Nur **cover** (erste Slide) und **cta** (letzte) sind gesetzt, der Rest kommt rein, wenn das Konzept ihn trägt. Ein Pattern nur nutzen, wenn das Thema es inhaltlich verlangt, nicht weil es im letzten Post war.

- **cover** - Statischer Scroll-Stopper, Slide 1. Full-bleed Bild plus Scrim plus Font-Mix-Headline plus mindestens ein handgezeichneter Mark. Keine Animation. Trägt den value-stärksten Pain (nicht den Mechanismus).
- **problem** - "Eine Meinung plus blinde Flecken": ein großer Charakter mittig plus Blind-Spot-Marker plus kurze Sprechblase, Punchline mit Unterstrich. Der Schmerz / die alte Welt.
- **idea / lineup** - "X statt Y": Headline mit Kringel auf dem Akzentwort plus Charakter-Lineup mittig (2 Reihen ab 5 Figuren). Die Kern-Idee / der Shift.
- **list** - Vertikale Liste, pro Zeile [Charakter][Label fett][Subline muted], Stagger von links. Für "die N Stimmen / N Schritte".
- **terminal / demo** - Der Beweis-Slide: dunkles Terminal mit echtem Ablauf ODER helles Typewriter-Fenster plus Cursor-Klick auf ein `/command`. Konkret, am Beispiel. (Für Entwickler-Content; in anderen Nischen ist der Beweis-Slide ein Screenshot/Artefakt/Ergebnis, siehe content-assets.)
- **clash / contrast** - Face-off: zwei Lager, Burst plus VS, Shake, kurze Quotes mit max-width. Spannung: alt vs. neu, Einwand plus Antwort. Nur bei echtem Gegensatz.
- **verdict / payoff** - Weiße Karte mittig mit Empfehlung plus Feldern (Konfidenz/Risiko/nächster Schritt) plus "approved"-Haken. Das Ergebnis / der Gewinn.
- **cta** - Letzte Slide: Headline plus kurze Zeile plus Pill-Button plus Signatur-Scrawl plus optional Charakter-Crowd. Genau EIN konkreter nächster Schritt (aus dem Brand-Profile).

Die Slide-Anzahl kommt vom Value, nicht von einem Default. Oft 5 bis 6. Nur Cover und CTA sind Pflicht, ein Beweis-/Demo-Slide ist fast immer der Value-Kern.
content-build/references/motif-library.md
# Motiv-Bibliothek

Zehn generische Bausteine, aus denen sich die Slides zusammensetzen. Alle deterministisch (kein Random, kein Date), damit jeder Render gleich aussieht. Handgezeichnete Marks ziehen sich per `stroke-dashoffset` ein. Der Agent baut jedes Motiv als HTML/CSS/JS nach dieser Beschreibung, im Look aus deinem `brand-profile.md`.

1. **Hand-Kringel** - handgezeichneter Kreis um EIN Schlüsselwort, SVG-Pfad zieht sich ein.
2. **Hand-Unterstrich** - welliger Marker-Strich unter einem Wort, zeichnet sich ein.
3. **Highlighter-Swipe** - halbtransparenter Leuchtmarker-Balken hinter einem Wort, leicht schräg.
4. **Cursor-Klick** - Maus-Pfeil fährt weich rein und klickt (Dip plus Klick-Ring) auf ein konkretes Element.
5. **Terminal-Fenster** - dunkles Mac-Terminal mit Prompt, System-Zeile, Rollen/Output, Verdikt. Mono-Spalten fix ausgerichtet.
6. **Typewriter-Prompt-Fenster** - helles Mac-Fenster, in dem eine Frage getippt wird (gleicher Typewriter-Effekt wie das Terminal).
7. **Charakter-Lineup** - mehrere Figuren mittig in 1 bis 2 Reihen, Stagger-Entrance plus Idle-Bob.
8. **Clash / VS-Face-off** - zwei Lager prallen aufeinander, Strahlen-Burst plus VS-Zeichen plus Shake plus Bicker-Jitter.
9. **Signatur-Scrawl** - handschriftlicher Sign-off, Pfad zeichnet sich ein (persönlicher Abschluss).
10. **Blind-Spot-Marker** - gestrichelte Fragezeichen-Kreise um einen Charakter, macht "blinde Flecken" sichtbar.

Die Motive 5, 6 und 7/8 sind stärker getönt (Terminal für Entwickler-Content, Lineup/Clash für Charakter-basierten Content). In anderen Nischen ersetzt du den Beweis-Slide durch echte Screenshots/Artefakte (siehe content-assets) und nutzt Kringel/Unterstrich/Highlighter/Cursor als universelle Marks.

3. content-assets - Bilder

Entscheidet pro Bild ehrlich: passt ein Asset aus deiner Bibliothek wirklich, oder wird neu generiert? Plus die Anti-KI-Look-Regeln und die drei bewährten Bild-Rezepte.

~/.claude/skills/content-assets/SKILL.md
---
name: content-assets
description: Entscheidet pro Bild-Piece, ob ein Asset aus der Bibliothek wiederverwendet oder neu generiert wird, generiert bei Bedarf (Bild-Generator aus dem Brand-Profile), schneidet den Hintergrund frei und pflegt den Katalog. Der content-producer-Agent ruft diesen Skill als Asset-Schritt.
---

# Content-Assets

Du lieferst die Bild-Assets für die Slides. Grundhaltung: Die Bibliothek ist ein Angebot, keine Pflicht. Pro Piece läuft eine ehrliche Passungsprüfung.

## Wiederverwenden vs. neu generieren

1. **Visuelles Konzept zuerst:** Was soll dieses Piece im Post konkret zeigen? Erst das Konzept, dann der Katalog (`python3 scripts/catalog.py list [theme]`).
2. **Ehrlich prüfen:** Gibt es ein Piece, das WIRKLICH zu diesem Konzept passt? Nicht "lässt sich irgendwie umdeuten", sondern passt es echt? Reuse nur, wenn das Piece die gewollte Bildaussage wirklich trägt.
3. **Entscheidung:** Passt → wiederverwenden (ins Projekt kopieren, keine Kosten). Passt nicht oder Lücke → neu generieren, Background-Cut, in den Katalog aufnehmen, dann ins Projekt kopieren.
4. **Cover-Sonderregel:** Das Cover muss genau zu DIESEM Thema tragen. Ein vorhandenes Asset ist ok, WENN es spezifisch passt. Ein nur allgemein passendes Bild (dasselbe Gruppenbild für jedes Thema) ist es nicht → dann generieren. Diese scharfe Unterscheidung spezifisch vs. allgemein IST die Entscheidung.
5. **Kosten-Framing:** Credits sind richtig investiert, wenn sie Originalität bringen. "0 Credits" ist kein Qualitätsmerkmal. Nenn die Kosten vor jedem Generier-Lauf.

Faustregel: wiederkehrende Charaktere/Logos/Icons = Bibliothek-Kandidaten. Cover plus themenspezifische Metaphern = im Zweifel neu.

## Die Asset-Bibliothek

Struktur (siehe `asset-library/`):
```
asset-library/
  characters/   transparente PNG-Cutouts (wiederkehrende Figuren/Logos/Icons)
  objects/      transparente PNG-Cutouts (Geräte, Schilder, Props)
  scenes/       Cover-Bilder, volle JPG/PNG (kein Cut nötig, full-bleed)
  catalog.json  Quelle der Wahrheit (leer starten: [])
  LIBRARY.md    Index, wird von catalog.py auto-generiert
```
Einpflegen: PNG/JPG in den passenden Unterordner legen, dann
`python3 scripts/catalog.py add --id mein_asset --file characters/mein_asset.png --type character --theme <thema> --tags "a,b" --desc "Kurzbeschreibung" --prompt "gen-prompt falls generiert"`.
Der Katalog schreibt `catalog.json` und `LIBRARY.md` konsistent neu. Immer erst `list` aufrufen, bevor du neu generierst.

## Bilder generieren (Bild-Generator aus dem Brand-Profile)

Empfohlenes Modell: eins, das Text im Bild UND Referenzbilder kann und in 2K liefert (z. B. Nano Banana Pro). Anbindung siehe Guide, Kapitel 9.

**Referenzbild-Workflow** (Look konsistent halten): ein bestehendes Asset als Referenz (`role: image`) mitgeben statt blind neu erfinden. Bei image-to-image den Input nicht neu beschreiben, nur die Änderung ("transform into ... style"). Referenz vorher verkleinern für schnelleren Upload.

## Anti-KI-Look (damit es nicht als KI auffliegt)

- **Kamera/Material statt "perfekt":** konkrete, sensorische Prompts mit Lens/Angle, Lighting, Material ("soft-clay", "soft studio shadow", "85mm", "rim light"). Materialität holt das Bild aus dem generischen KI-Glanz.
- **Echte Referenz statt Fantasie-Foto:** für wiederkehrende Elemente ein echtes bestehendes Asset als Referenz mitgeben.
- **EIN visueller Moment pro Bild:** ein Prop, eine Pose, ein Motiv. Reduktion = Signatur.
- **KEIN Text im generierten Bild:** durchgehend `no text, no logo, no watermark`. Text kommt als HTML-Layer drüber (saubere Typo, korrekte Umlaute). Das Bild liefert nur Motiv plus negative space oben für den Scrim.
- **Kein Neon, kein Vektor-Fake-3D:** warm und clean, echtes gerendertes Material statt flacher SVG-Imitation.
- **Cutout-Integrität:** nach dem Background-Cut die Alpha-Maske auf falsch ausgehöhlte Innenflächen prüfen (Brillengläser, Lupen) und aus dem Original zurückfüllen, sonst durchsichtige Löcher.
- **Umlaute prüfen:** generierter Text im Bild verunstaltet ä/ö/ü/ß oft. Darum Text nie ins Bild generieren, sondern per HTML sauber drübersetzen.

## Die 3 bewährten Bild-Typen (generalisierte Rezepte)

**(a) Cleane Typo-/Konzept-Karte.** Full-bleed Hintergrund im Brand-Look (warm, clean, kein Neon), negative space oben. Motiv beschreiben, `no text, no logo`. Text als HTML-Layer drüber (Display-Serif, korrekte Umlaute). Ergebnis: scharfe, lesbare Konzeptkarte ohne KI-Text-Artefakte.

**(b) Buch-/Device-Mockup als Lead-Magnet-Cover.** Fotorealistisches Mockup (Buchcover, Tablet, Phone, Terminal-Fenster) generieren, Materialprompt für Echtheit. Kein Text im Screen, Screen-Inhalt als HTML ins Fenster compositen. Full-bleed, kein Cut. Ergebnis: Cover, das ein konkretes Deliverable greifbar macht.

**(c) Echter Screenshot plus Marker-Annotation.** Echten Screenshot nehmen (nicht generieren), in ein Fenster/Terminal-Frame setzen. Annotation als HTML-Overlay: Kringel/Unterstrich/Highlighter/Cursor/Pfeil auf die EINE relevante Stelle. Ergebnis: authentischer, lehrreicher Slide, die Marker tragen die Erklärung. (Kein echter Screenshot verfügbar? Als Ausnahme einen nachgestellten generieren, klar im Brand-Look, ohne fremde Logos.)
Kapitel 07

Die Tools.

Vier kleine Scripts machen die Handarbeit. Sie liegen in den scripts/-Ordnern der Skills. Du rufst sie nicht selbst auf, der Agent tut das, aber so verstehst du, was passiert.

render-all.sh - HTML wird Bild

Rendert jede slide-*.html zu einem MP4 und zieht mit ffmpeg zwei Frames: einen Settle-Frame (kurz vor Ende, wenn die Animation ausgelaufen ist) für die Kontrolle, und den vollen statischen Export als JPG.

content-build/scripts/render-all.shbash
#!/usr/bin/env bash
# Rendert alle slide-*.html eines Projekts zu MP4, zieht Settle-Frames + statische JPGs.
# Aufruf:  bash render-all.sh [projekt-dir]   (default: aktuelles Verzeichnis)
# Voraussetzung: ein Ordner mit slide-1.html ... slide-N.html (HyperFrames-Compositions)
set -euo pipefail
DIR="${1:-.}"; cd "$DIR"
mkdir -p renders export-static frames
# HyperFrames-Version über Env überschreibbar (HF_VERSION), sonst gepinnte Default-Version:
HF="npx --yes ${HF_VERSION:-hyperframes@0.6.98}"
shopt -s nullglob
slides=(slide-*.html)
[ ${#slides[@]} -eq 0 ] && { echo "Keine slide-*.html in $DIR"; exit 1; }
# nach Nummer sortieren
IFS=$'\n' slides=($(printf '%s\n' "${slides[@]}" | sort -t- -k2 -n)); unset IFS
for f in "${slides[@]}"; do
  n="${f#slide-}"; n="${n%.html}"
  echo ">> render $f"
  $HF render -c "$f" -o "renders/slide-$n.mp4" --quality high --quiet 2>&1 | tail -1 || true
  # Settle-Frame (0.35s vor Ende) für die Kontrolle, + voller statischer Export (letzter Frame)
  ffmpeg -y -sseof -0.35 -i "renders/slide-$n.mp4" -frames:v 1 "frames/s$n.png" 2>/dev/null || true
  ffmpeg -y -sseof -0.05 -i "renders/slide-$n.mp4" -frames:v 1 -q:v 2 "export-static/slide-$n.jpg" 2>/dev/null || true
done
echo "Fertig. MP4s in renders/, statische JPGs in export-static/, Settle-Frames in frames/."

contact-sheet.py - alle Slides auf einen Blick

Baut aus den Settle-Frames einen Kontaktbogen (ein Bild, alle Slides nebeneinander). Genau dieses Bild sieht sich der Agent an, bevor er fertig meldet. Braucht Python plus Pillow.

content-build/scripts/contact-sheet.pypython3
#!/usr/bin/env python3
"""Baut einen Kontaktbogen aus den Settle-Frames (frames/s*.png) zum Drüberschauen.
Aufruf:  python3 contact-sheet.py [projekt-dir] [out.jpg]   (default: . und ./contact-sheet.jpg)
"""
import sys, os, glob, re
from PIL import Image

d = sys.argv[1] if len(sys.argv) > 1 else "."
out = sys.argv[2] if len(sys.argv) > 2 else "./contact-sheet.jpg"
files = glob.glob(os.path.join(d, "frames", "s*.png"))
files.sort(key=lambda p: int(re.search(r"s(\d+)\.png$", p).group(1)))
if not files:
    print("Keine frames/s*.png gefunden, erst render-all.sh laufen lassen."); sys.exit(1)
tw = 360
ims = [Image.open(p).convert("RGB") for p in files]
ims = [im.resize((tw, int(im.height * tw / im.width))) for im in ims]
ch = max(im.height for im in ims); pad = 8
cols = min(4, len(ims)); rows = (len(ims) + cols - 1) // cols
W = cols * tw + (cols + 1) * pad; H = rows * ch + (rows + 1) * pad
canvas = Image.new("RGB", (W, H), (24, 20, 16))
for i, im in enumerate(ims):
    r, c = divmod(i, cols)
    canvas.paste(im, (pad + c * (tw + pad), pad + r * (ch + pad)))
canvas.save(out, quality=92)
print("Kontaktbogen:", out, canvas.size)

gif.sh - Loop-GIF unter 5 MB

Wandelt ein Slide-MP4 in ein Loop-GIF und schrumpft es automatisch unter die 5-MB-Grenze, die LinkedIn für animierte GIFs zieht.

content-build/scripts/gif.shbash
#!/usr/bin/env bash
# MP4 -> Loop-GIF unter 5MB (LinkedIn animiert GIFs nur <5MB & <400 Frames).
# Aufruf:  bash gif.sh renders/slide-2.mp4 [out.gif] [fps] [breite]
# Default: 15 fps, 720px breit. Schrumpft fps/Breite automatisch bis <5MB.
set -euo pipefail
IN="$1"; OUT="${2:-${IN%.mp4}.gif}"; FPS="${3:-15}"; W="${4:-720}"
mk(){ local fps="$1" w="$2"; local pal; pal="$(mktemp).png"
  ffmpeg -y -i "$IN" -vf "fps=$fps,scale=$w:-1:flags=lanczos,palettegen=stats_mode=diff" "$pal" 2>/dev/null
  ffmpeg -y -i "$IN" -i "$pal" -lavfi "fps=$fps,scale=$w:-1:flags=lanczos[x];[x][1:v]paletteuse=dither=bayer:bayer_scale=3" "$OUT" 2>/dev/null
  rm -f "$pal"; }
mk "$FPS" "$W"
for try in 1 2 3 4; do
  sz=$(stat -f%z "$OUT" 2>/dev/null || stat -c%s "$OUT"); mb=$((sz/1048576))
  [ "$sz" -lt 5242880 ] && { echo "OK $OUT ($((sz/1024)) KB, ${FPS}fps, ${W}px)"; exit 0; }
  # zu groß -> erst fps runter, dann Breite
  if [ "$FPS" -gt 12 ]; then FPS=12; elif [ "$W" -gt 560 ]; then W=560; FPS=12; else W=480; FPS=10; fi
  echo "noch $((sz/1024)) KB -> retry ${FPS}fps ${W}px"; mk "$FPS" "$W"
done
echo "WARN: $OUT noch $(( $(stat -f%z "$OUT" 2>/dev/null || stat -c%s "$OUT")/1024 )) KB - evtl. Slide kürzen."

catalog.py - deine Asset-Bibliothek

Verwaltet deine Bild-Bibliothek. catalog.json ist die Quelle der Wahrheit, LIBRARY.md wird daraus regeneriert. So weiß der Agent, welche Assets es schon gibt, und generiert nur bei echter Lücke neu.

content-assets/scripts/catalog.pypython3
#!/usr/bin/env python3
"""Katalog-Verwaltung für die Asset-Bibliothek.
catalog.json ist die Quelle der Wahrheit; LIBRARY.md wird daraus regeneriert (immer konsistent).

  python3 catalog.py list [theme]
  python3 catalog.py add --id ID --file characters/x.png --type character \
      --theme mein-thema --tags "a,b" --desc "Kurzbeschreibung" \
      --prompt "..." [--created 2026-06-15]
"""
import sys, os, json, argparse, datetime

# Bibliotheks-Ordner: per Env-Var ASSET_LIBRARY überschreibbar, sonst ../asset-library relativ zum Script.
LIB = os.environ.get("ASSET_LIBRARY",
                     os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "..", "..", "asset-library"))
CAT = os.path.join(LIB, "catalog.json")
MD = os.path.join(LIB, "LIBRARY.md")

def load():
    if os.path.exists(CAT):
        with open(CAT) as f: return json.load(f)
    return []

def save(entries):
    entries.sort(key=lambda e: (e.get("type",""), e.get("theme",""), e.get("id","")))
    with open(CAT, "w") as f: json.dump(entries, f, indent=2, ensure_ascii=False)
    render_md(entries)

def render_md(entries):
    by = {}
    for e in entries:
        by.setdefault(e.get("type","misc"), {}).setdefault(e.get("theme","_"), []).append(e)
    lines = ["# Asset-Bibliothek - Index",
             "",
             "Menschlicher Index, automatisch aus catalog.json regeneriert. Pro Piece eine Zeile.",
             "Wiederverwenden bevorzugen; nur bei echter Lücke neu generieren (siehe content-assets Skill).",
             ""]
    for typ in sorted(by):
        lines.append(f"## {typ}")
        for theme in sorted(by[typ]):
            lines.append(f"### {theme}")
            for e in sorted(by[typ][theme], key=lambda x: x["id"]):
                tags = ", ".join(e.get("tags", [])) if isinstance(e.get("tags"), list) else (e.get("tags") or "")
                lines.append(f"- `{e['file']}` - {e.get('description','')}" + (f"  _(tags: {tags})_" if tags else ""))
            lines.append("")
    with open(MD, "w") as f: f.write("\n".join(lines))

def cmd_list(args):
    entries = load()
    if args.theme:
        entries = [e for e in entries if e.get("theme") == args.theme or args.theme in (e.get("tags") or [])]
    if not entries:
        print("(Bibliothek leer)" if not args.theme else f"(nichts unter theme/tag '{args.theme}')"); return
    for e in entries:
        print(f"[{e.get('type')}/{e.get('theme')}] {e['id']:32} {e['file']:34} {e.get('description','')}")

def cmd_add(args):
    entries = load()
    entries = [e for e in entries if e["id"] != args.id]  # upsert
    tags = [t.strip() for t in args.tags.split(",")] if args.tags else []
    entries.append({
        "id": args.id, "file": args.file, "type": args.type, "theme": args.theme,
        "tags": tags, "description": args.desc, "prompt": args.prompt or "",
        "created": args.created or datetime.date.today().isoformat(),
    })
    save(entries)
    print(f"+ {args.id} aufgenommen. catalog.json + LIBRARY.md aktualisiert ({len(entries)} Pieces).")

p = argparse.ArgumentParser()
sub = p.add_subparsers(dest="cmd", required=True)
pl = sub.add_parser("list"); pl.add_argument("theme", nargs="?"); pl.set_defaults(fn=cmd_list)
pa = sub.add_parser("add")
for a in ["id","file","type","theme","desc"]: pa.add_argument(f"--{a}", required=True)
for a in ["tags","prompt","created"]: pa.add_argument(f"--{a}", default="")
pa.set_defaults(fn=cmd_add)
if __name__ == "__main__":
    os.makedirs(LIB, exist_ok=True)
    args = p.parse_args(); args.fn(args)
Kapitel 08

Das Content-Playbook.

Das ist das Warum hinter dem System, damit der Agent für JEDE Nische guten Content baut. Bewährte Muster aus der Analyse von über 1.500 High-Performance-Posts. Kein Gesetz, sondern Wahrscheinlichkeit. Passt ein Muster in deiner Nische nicht, weicht der Agent begründet ab. Die komplette Datei liegt als references/content-playbook.md in der ZIP.

Value über Feature

Der stärkste Angle liegt fast immer auf der Ebene Geld, Zeit oder Job, nicht auf der Ebene Tool-Feature. "Tool X kann jetzt Y" verliert gegen "was du dir dadurch sparst". Der stärkste Text-Motor ist der Geld-Anker: ein teurer Posten (Agentur, Retainer, Personalstelle) gegen den fast kostenlosen neuen Weg. Ankern an Fremdpreisen, nicht an eigenen Umsatzzahlen.

Der Hook

Ein Ergebnis oder eine Spannung in der ERSTEN Zeile, etwa 52 Zeichen. Ein Gedanke, keine Aufzählung, kein Vorlauf. "Ich habe X gebaut"-Hooks tragen am zuverlässigsten. Fragment-Kontraste direkt danach verstärken: "15 Minuten. Kein Team. Kein Budget."

Der Post-Text

1.000 bis 1.900 Zeichen. Fragment-Sätze statt Schachtelsätze, kurze Zeilen fürs Handy, Pfeil-Listen für Schritte, genau EIN CTA am Ende. Der Bogen: Hook, Aufwands-Kontrast, Prozess als Liste, Zeit-/Kosten-Punchline, eine Meta-These, ein CTA. Keine Links im Text.

Ein Beweis-Bild statt Deko

Die wichtigste Daten-Nuance und der Grund für die Plattform-Verzweigung im Agenten: Auf LinkedIn floppen Carousels und Multi-Image (Ratio deutlich unter 1). Es gewinnt Text plus EIN starkes Bild. Darum baut der Agent bei Ziel LinkedIn keinen 6-Slide-Bogen, sondern einen Post-Text plus ein einzelnes, cleanes Beweis- oder Konzept-Bild. Auf Instagram bleibt die Carousel das native Format.

Visual-DNA

Kein einziges Spitzen-Visual war ein fotorealistisch gemaltes KI-Bild. Gewinner sind echte Screenshots und Artefakte, Gesicht-plus-Blockschrift-Thumbnails, echte Fotos mit Requisite, cleane Typo-Karten mit EINEM visuellen Moment, oder dichte Editorial-Sheets. Das Barbell-Prinzip: ganz roh oder maximal dicht gewinnt, das lauwarme Mittelfeld verliert. Und die Kernregel: keine fotorealistischen KI-Fake-Fotos von echten Szenen oder UIs, die fliegen als KI auf.

Gate-Mechanik (für Lead-Magnete)

Keyword-Gates mit echtem Asset erzielen die höchsten Ratios. Ein Wert-Gate funktioniert, leeres Engagement-Bait wird abgestraft. Reihenfolge: Beweis zuerst (mit Zahlen), "ich hab das in EIN X gepackt", Was-drin-ist-Liste, Ein-Wort-Keyword plus Vernetzen plus Like, Asset per Direktnachricht. Maximal etwa einmal pro Woche.

Timing und Stimme

Dienstag bis Donnerstag vormittags, die ersten 60 Minuten Kommentare beantworten, 2 bis 4 Posts pro Woche. Und der teuerste Fehler: KI-generisch klingender Text kostet messbar Reichweite. Keine Em-Dashes, keine Floskeln, konkrete eigene Beispiele, eigene Stimme aus dem Brand-Profile. Deshalb ist das Voice-Feld dort Pflicht.

Kapitel 09

Bilder mit Higgsfield.

Optional, aber stark: der Agent kann Cover, Objekte und Szenen selbst generieren. Das animierte HTML bleibt der Weg für die Slides, Higgsfield liefert die Bild-Assets darin (Cover, Objekte, Hintergründe).

Das Modell

Empfehlung: Nano Banana Pro. Es kann Text im Bild und Referenzbilder zugleich und liefert 2K, ideal für Cover mit Charakter. Für schnelle Alltags-Assets reicht die Standard-Variante.

Account anbinden

Zwei Wege, beide ohne dass ein Schlüssel im Klartext irgendwo landet:

  • CLI: higgsfield auth login (öffnet den Browser, kein manueller Key). Danach prüfen mit higgsfield account status. Der Account braucht Credits.
  • MCP: Higgsfield als MCP-Server in Claude Code anbinden. Der Agent nutzt dann die Bild-Tools direkt. Trag im Brand-Profile nur ein, dass ein Bild-Generator verbunden ist.

Anti-KI-Look (damit es nicht auffliegt)

  • Kamera und Material statt "perfekt": konkrete Prompts mit Lens, Licht, Material ("soft-clay", "rim light", "85mm"). Materialität holt das Bild aus dem generischen KI-Glanz.
  • Echte Referenz statt Fantasie-Foto: ein bestehendes Asset als Referenzbild mitgeben hält den Stil konsistent.
  • EIN visueller Moment pro Bild. Ein Prop, eine Pose, ein Motiv. Reduktion ist die Signatur.
  • Kein Text im generierten Bild. Immer no text, no logo in den Prompt, den Text als HTML-Layer drüber. Das umgeht KI-Text-Matsch und kaputte Umlaute.

Referenzbild-Workflow

Vorbild-Visual als Referenz (Rolle image) mitgeben. Bei image-to-image nicht das ganze Motiv neu beschreiben, nur die Änderung. Soll Text ins Bild, den exakten String in Anführungszeichen in den Prompt setzen und die Umlaute im Ergebnis immer gegenprüfen. Im Zweifel: Text nicht generieren, sondern per HTML sauber drübersetzen.

Kapitel 10

Troubleshooting.

Der Agent taucht in Claude Code nicht auf

Liegt content-producer.md wirklich in ~/.claude/agents/? Claude Code neu starten. Der Dateiname ist der Agent-Name.

Render bricht ab oder das Bild ist leer

Meist fehlt der Headless-Browser der Render-Engine (wird beim ersten Lauf geladen, braucht Internet) oder ffmpeg ist nicht installiert. Prüfen: npx hyperframes doctor und ffmpeg -version. Ist der Frame leer, fehlt am Slide-Wrapper das position:absolute; inset:0, dann kollabiert die Höhe.

Text läuft aus der Slide

Genau dafür ist der Kontaktbogen da. Headline kürzen (Value zwingt zur Kürze) oder Spaltenbreite/Font-Größe anpassen. Bei einem "." hinter einem markierten Wort: der Punkt bricht bei langer Zeile um, weglassen.

Die Bilder sehen falsch aus (falsche Fonts)

Die im Brand-Profile genannten Fonts müssen auf dem Render-System installiert sein. Georgia und Impact sind fast überall da. Exotische Fonts als Web-Font einbetten, sonst rendert ein Fallback.

Der Kontaktbogen kommt nicht

Pillow fehlt: pip install Pillow. Und render-all.sh muss vorher gelaufen sein, sonst gibt es keine Frames.

Der Text klingt nicht nach mir

Das Voice-Feld im Brand-Profile ist zu dünn. Trag 2 bis 3 echte Beispielsätze ein, die eindeutig nach dir klingen, und deine No-Go-Wörter. Korrigier den Agenten einmal konkret, er schreibt die Lektion in den Konzept-Skill zurück.

Bildgenerierung schlägt fehl

Account eingeloggt (higgsfield account status) und Credits vorhanden? Bei "Session expired" erneut higgsfield auth login. Ohne Bild-Generator läuft der Agent trotzdem, dann mit reinen Typo-/Screenshot-Slides.

Alles zum Reinlegen.

Der komplette Agent, die drei Skills, die Scripts und das Brand-Profile-Template als ein Ordner. Entpacken, ablegen, ausfüllen, loslegen.

content-agent.zip laden ↓