# Sxo Persona

> Erstellt ein Persona-Feedback-Dashboard als HTML-Datei auf Basis eines SXO-Analyzer Reports und/oder einer SXO Page. Kann auch standalone mit URL + Keyword arbeiten (fuehrt dann intern eine SERP-Analyse durch, ohne HTML-Report zu erzeugen). Leitet 4-7 Personas aus Intent-Signalen ab (Related Searches, PAA, User Story, Gap-Analyse), generiert Flat-Illustration-Avatare via Nano Banana MCP mit lokalem Bild-Cache, bewertet die Zielseite aus jeder Persona-Perspektive (Score 1-100) und gibt konkrete Verbesserungsvorschlaege. Supports German and English. Use when user says "SXO Persona", "Persona Dashboard", "Persona Analyse", "Persona erstellen", "create personas", "persona feedback", "Nutzer-Feedback", "user feedback dashboard", "Zielgruppen-Analyse", "audience analysis", "Persona aus Report", "personas from report", "wer sucht das", "who is searching for this", or "SXO Persona Dashboard". Do NOT use for: marketing personas without SXO context, buyer personas for ads, UX research interviews, or general user resear

- Skill: `tools-enerix/sxo-persona` (Agent Skill, multi-file: 6 files)
- Install (CLI): `npx skillmds@latest add tools-enerix/sxo-persona`
- Raw SKILL.md: https://api.skillmd.com/api/skills/tools-enerix/sxo-persona/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Marketing & Growth
- Author: tools-enerix (https://skillmd.com/u/tools-enerix)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/tools-enerix/sxo-persona

---


# SXO-Persona -- Persona-Feedback-Dashboard aus SXO-Report

Der SXO-Persona Skill erzeugt ein visuelles **Persona-Feedback-Dashboard**, das zeigt:

> **Wer sucht dieses Keyword, was erwartet jede Person -- und wie gut liefert die Seite?**

Logik: **SERP-Signale -> Intent-Cluster -> Personas -> Scoring gegen Zielseite -> Handlungsempfehlungen**

---

## Schritt 0: Inputs erkennen und validieren

### 0a -- Inputs erkennen (4 Modi)

```
Suche mit Glob im aktuellen Arbeitsverzeichnis nach:

1. SXO-Report:  sxo-report-*.html   (aus /sxo-analyze)
2. SXO-Page:    sxo-page-*.html     (aus /sxo-page)
3. Argumente:   URL und/oder Keyword als Argument

Bestimme den Modus:

MODUS A -- Report gefunden:
  -> Zeige gefundene Datei(en)
  -> Falls mehrere Reports: User waehlen lassen
  -> Lies den Report mit Read-Tool
  -> IF zusaetzlich SXO-Page gefunden:
       -> Nutze die Page fuer praeziseres Scoring
       -> Hinweis: "SXO-Page gefunden -- Scoring basiert auf tatsaechlichem Seiteninhalt"
  -> Weiter mit Schritt 1 (Daten aus Report extrahieren)

MODUS B -- Kein Report, aber URL + Keyword als Argumente:
  -> Standalone-Modus: Fuehre interne SERP-Analyse durch (siehe Schritt 0c)
  -> Hinweis: "Standalone-Modus: Fuehre SERP-Analyse fuer '[KEYWORD]' durch..."
  -> Weiter mit Schritt 0c

MODUS C -- Kein Report, nur URL (ohne Keyword):
  -> Frage den User nach dem Fokus-Keyword:
     "Fuer die Persona-Analyse brauche ich ein Fokus-Keyword.
      Welches Keyword soll ich analysieren?"
  -> Warte auf Antwort
  -> Dann weiter wie Modus B (Standalone mit URL + Keyword)

MODUS D -- Weder Report noch URL:
  -> Fehler: "Ich brauche mindestens einen SXO-Report oder eine URL + Keyword."
  -> "Option 1: /sxo-analyze [keyword] [url]  (vollstaendiger Report)"
  -> "Option 2: /sxo-persona [keyword] [url]   (Standalone-Analyse)"
```

### 0b -- Spracherkennung

Erkenne die Dashboard-Sprache automatisch:

1. **Aus SXO-Report:** `<html lang="de">` -> Deutsch, `<html lang="en">` -> Englisch
2. **Aus URL-TLD:** `.de/.at/.ch` -> Deutsch, `.com/.co.uk/.io` -> Englisch
3. **Aus Keyword:** Deutsche Begriffe -> Deutsch, englische -> Englisch

```
IF Sprache = Englisch:
  -> Verwende CSS aus assets/persona-template-en.html
  -> Schreibe ALLE Texte auf Englisch
  -> Englische Labels (Search Motive, Expectation, Improvements, etc.)
ELSE:
  -> Verwende CSS aus assets/persona-template.html
  -> Deutsche Labels (Suchmotiv, Erwartung, Verbesserungen, etc.)
```

### 0c -- Standalone-Modus (SERP-Analyse ohne Report)

Wenn Modus B oder C aktiv ist, fuehre die SERP-Analyse intern durch.
Ziel: Dieselben Datenfelder wie in Schritt 1 erzeugen, aber aus Live-SERP-Daten statt aus einem HTML-Report.

**WICHTIG:** Es wird KEIN HTML-Report erzeugt. Alle Daten bleiben im Arbeitskontext.

```
SCHRITT 0c-1: SERP-Daten holen (ein einzelner API-Call)

  Rufe auf: mcp__dataforseo__serp_organic_live_advanced
    keyword:       KEYWORD
    location_code: 2276 (Deutschland) bzw. passend zur Sprache
    language_code: "de" bzw. "en"
    depth:         30

  Dieser Call liefert:
    - Organic Top-10/30 Ergebnisse
    - Related Searches (item_types: "related_searches")
    - People Also Ask (item_types: "people_also_ask")
    - Featured Snippets (item_types: "featured_snippet")
    - Google Ads (item_types: "paid")
    - AI Overview (item_types: "ai_overview")

SCHRITT 0c-2: Daten in Report-Format mappen

  Aus den SERP-Daten extrahiere:

  RELATED_SEARCHES:
    -> Fuer jedes Related-Search-Item:
       SUCHBEGRIFF: title
       INTENT_BADGE: Leite Intent ab (Informational/Commercial/Transactional/Local/DIY)
       Nutze mcp__dataforseo__dataforseo_labs_search_intent fuer praezise Intent-Klassifikation

  PAA_FRAGEN:
    -> Fuer jedes People-Also-Ask-Item:
       PAA_FRAGE: title
       PAA_ANTWORT: description (falls vorhanden)

  ADS_SIGNALE:
    -> Fuer jedes Paid-Item:
       ADS_TITLE: title
       ADS_DESCRIPTION: description
       ADS_URL: url
    -> Interpretation: Welche Botschaften werden getestet? Preispunkte?

  TOP_10_ERGEBNISSE:
    -> Fuer jedes Organic-Item (Position 1-10):
       TITLE, URL, DESCRIPTION
    -> Analyse: Welche Themen dominieren? Content-Typen?

SCHRITT 0c-3: User Story ableiten

  Aus den gesammelten SERP-Signalen leite die User Story ab:

  1. WISSENSSTAND: Aus Komplexitaet der PAA-Fragen
     - Einfache Fragen ("Was ist...?") -> Einsteiger
     - Vergleichsfragen ("Was ist besser...?") -> Fortgeschritten
     - Detailfragen ("Wie konfiguriere ich...?") -> Experte

  2. JOURNEY_PHASE: Aus Intent-Verteilung
     - Ueberwiegend Informational -> Recherche
     - Gemischt Info+Commercial -> Vergleich
     - Ueberwiegend Commercial/Transactional -> Entscheidung

  3. EMOTIONALE_LAGE: Aus Tonalitaet der Suchanfragen
     - "Lohnt sich...?" -> Unsicherheit
     - "Beste/Top..." -> Optimismus
     - "Problem/Fehler..." -> Frustration

  4. BARRIEREN: Aus PAA-Fragen und Related Searches
     - Preisfragen -> Kostenbarriere
     - "Erfahrungen" -> Vertrauensbarriere
     - "Nachteile/Risiken" -> Risikobarriere

  5. PRIMAERES_ZIEL + SEKUNDAERES_ZIEL: Aus dominantem Intent

  6. USER_STORY_STATEMENT: Formuliere als:
     "Als [Rolle] mit [Wissensstand] moechte ich [Ziel],
      damit ich [Nutzen]. Meine groesste Sorge ist [Barriere]."

SCHRITT 0c-4: Seiteninhalte holen (fuer Scoring)

  -> Hole die Zielseite via WebFetch (URL aus Argument)
  -> Extrahiere: Headline, Meta-Description, Hauptinhalt, Trust-Signale
  -> Scoring-Modus: "Basierend auf Live-URL (Standalone)"

SCHRITT 0c-5: Gap-Analyse ableiten

  Vergleiche SERP-Erwartungen mit Seiteninhalt:
  -> Fuer jedes SERP-Signal (Related Search, PAA, Ads-Botschaft):
     Pruefe ob die Zielseite dieses Thema abdeckt
  -> Erstelle Gap-Items mit Prioritaet:
     - SERP-Signal stark + Seite fehlt = high
     - SERP-Signal mittel + Seite schwach = medium
     - SERP-Signal schwach + Seite fehlt = low

SCHRITT 0c-6: Above-the-Fold Screenshot (parallel zu 0c-4)

  -> Lies references/screenshot-capture.md fuer Capture-Befehl und Fehlerbehandlung
  -> npx playwright screenshot "{{URL}}" /tmp/sxo-screenshot.png --viewport-size "1280,800" --timeout 15000
  -> Konvertiere zu Base64:
     SCREENSHOT_BASE64=$(base64 -w 0 /tmp/sxo-screenshot.png 2>/dev/null || openssl base64 -A -in /tmp/sxo-screenshot.png)
  -> rm -f /tmp/sxo-screenshot.png
  -> IF Screenshot fehlschlaegt: weglassen, Workflow NICHT abbrechen

Danach: Weiter mit Schritt 2 (Personas ableiten).
Die Daten aus 0c-2/0c-3/0c-5 ersetzen die Report-Daten aus Schritt 1.
```

---

## Schritt 1: Daten aus SXO-Report extrahieren

Lies den SXO-Report und extrahiere diese Datenfelder. Die HTML-Struktur des Reports folgt einem festen Schema:

### 1a -- Metadaten

```
Aus dem <header class="report-header">:
  KEYWORD:    Text aus <h1> (nach "SXO-Analyse: " bzw. "SXO Analysis: ")
  URL:        href aus .meta-value a
  DATUM:      Text aus .meta-value (Datum/Date Feld)
```

### 1b -- Related Searches / Autocomplete (Section 1a)

```
Aus der Tabelle in "Autocomplete / Related Searches":
  Fuer jede <tr> in <tbody>:
    SUCHBEGRIFF:  Text aus erster <td>
    INTENT_BADGE: Text aus <span class="badge ...">

  -> Ergibt eine Liste von (Suchbegriff, Intent-Typ) Paaren
  -> Jeder Intent-Typ ist ein Persona-Kandidat

Aus dem Interpretations-Absatz (<p> nach "Interpretation"):
  AUTOCOMPLETE_INTERPRETATION: Freitext mit Cluster-Analyse
```

### 1c -- PAA-Fragen (Section 1d)

```
Aus der <ol> in "People Also Ask" / "Aehnliche Fragen":
  Fuer jedes <li>:
    PAA_FRAGE:  Text (inklusive Preise, Details)
    HAT_AI_OVERVIEW: true wenn <span class="badge badge-info">AI Overview</span>

Aus dem Interpretations-Absatz:
  PAA_INTERPRETATION: Freitext
```

### 1d -- Google Ads Signale (Section 1b)

```
Aus "Google Ads / Shopping-Signale" bzw. "Google Ads Messages":
  ADS_BEOBACHTUNG:    Freitext (Beobachtung/Observation)
  ADS_INTERPRETATION: Freitext
  -> Extrahiere: Preispunkte, A/B-getestete Botschaften, kommerzielle Signale
```

### 1e -- User Story (Section 2)

```
Aus der Tabelle "Identifizierte Elemente":
  Fuer jede <tr> in <tbody>:
    ELEMENT: Text aus erster <td> (z.B. "Wissensstand", "Journey-Phase", "Barrieren")
    WERT:    Text aus zweiter <td>

  -> Besonders wichtig fuer Persona-Ableitung:
     - Wissensstand / Knowledge Level
     - Journey-Phase / Journey Phase
     - Emotionale Lage / Emotional State
     - Barrieren / Barriers
     - Primaeres Ziel / Primary Goal
     - Sekundaeres Ziel / Secondary Goal

Aus .user-story-quote:
  USER_STORY_STATEMENT: Volltext
```

### 1f -- Gap-Analyse (Section 3b)

```
Aus "User Story Coverage (Gap-Analyse)":
  Fuer jedes <div class="gap-item gap-{priority}">:
    GAP_NAME:      Text aus <h4>
    GAP_PRIORITY:  high | medium | low (aus Klasse)
    GAP_SERP:      Text aus div mit .gd-label "SERP-Signal"
    GAP_ZIELSEITE: Text aus div mit .gd-label "Zielseite"
    GAP_TEXT:       Text aus div mit .gd-label "Gap"

  -> Jeder High-Priority-Gap kann eine eigene Persona rechtfertigen
```

### 1g -- First Screen Check (Section 3a)

```
Aus "First Screen Check":
  Fuer jede <tr> in <tbody>:
    ELEMENT:    Text aus erster <td>
    STATUS:     pass | warn | fail (aus badge-Klasse)
    BEWERTUNG:  Text aus dritter <td>
```

### 1h -- Gesamturteil (Section 3c)

```
Aus .verdict:
  VERDICT_CLASS: verdict-good | verdict-partial | verdict-bad
  VERDICT_TEXT:  Freitext
```

### 1i -- Above-the-Fold Screenshot (wenn URL verfuegbar)

```
IF URL aus Report-Metadaten (Schritt 1a) vorhanden:
  -> Lies references/screenshot-capture.md fuer Capture-Befehl und Fehlerbehandlung
  -> npx playwright screenshot "{{URL}}" /tmp/sxo-screenshot.png --viewport-size "1280,800" --timeout 15000
  -> Konvertiere zu Base64 und speichere als SCREENSHOT_BASE64
  -> rm -f /tmp/sxo-screenshot.png
  -> IF Screenshot fehlschlaegt: weglassen, Workflow NICHT abbrechen
```

---

## Schritt 2: Personas ableiten

Lies die Referenzdatei `references/persona-derivation.md` fuer die vollstaendigen Ableitungsregeln.

### 2a -- Intent-Cluster bilden

```
WICHTIG: Alle Personas suchen dasselbe Fokus-Keyword!
Related Searches und PAA-Fragen zeigen NICHT, dass Personas
andere Keywords tippen, sondern welche ERWARTUNGEN und HINTERGRUENDE
verschiedene Menschen mitbringen, wenn sie das Fokus-Keyword eingeben.

Beispiel: Keyword "Photovoltaikanlage"
  -> Related "Photovoltaikanlage Kosten" zeigt: Manche Suchende
     haben primaer Kosten im Kopf, wenn sie "Photovoltaikanlage" tippen
  -> PAA "Lohnt sich PV noch?" zeigt: Manche Suchende sind skeptisch
  -> ABER: Alle tippen "Photovoltaikanlage" in Google ein!

1. Gruppiere Related Searches und PAA-Fragen nach Erwartungs-Cluster:
   - Welche VERBORGENEN BEDUERFNISSE stecken hinter dem Fokus-Keyword?
   - Gleicher Bedarf-Typ = gleicher Cluster (z.B. alle Preis-bezogenen = 1 Cluster)
   - ABER: Unterscheide innerhalb eines Clusters, wenn der Hintergrund
     sich grundlegend unterscheidet (z.B. Preis-Optimierer vs. ROI-Skeptiker)

2. Ordne PAA-Fragen den Clustern zu:
   - Preisbezogene PAA -> Kosten-Erwartungs-Cluster
   - Qualitaetsfragen -> Qualitaets-Erwartungs-Cluster
   - Grundsatzfragen ("Lohnt es sich?") -> Unsicherheits-Cluster

3. Pruefe Gap-Analyse auf unabgedeckte Cluster:
   - High-Priority-Gap ohne passenden Cluster -> neuer Cluster

4. User Story als Basis-Persona:
   - Die User Story beschreibt den "typischen" Suchenden
   - Daraus wird die Haupt-Persona abgeleitet
   - Weitere Personas sind Varianten mit anderem Hintergrund und Fokus
   - Alle suchen dasselbe Keyword, aber mit unterschiedlicher Erwartung
```

### 2b -- Persona-Anzahl bestimmen

```
Ziel: 4-7 Personas

IF weniger als 4 unterscheidbare Cluster:
  -> Teile den groessten Cluster in Sub-Personas auf
  -> Z.B. "Preis" -> "Sparfuchs" (billigste Option) + "Qualitaetsbewusster" (bestes P/L)
  -> Minimum: 4 Personas

IF mehr als 7 Cluster:
  -> Merge die aehnlichsten Cluster
  -> Priorisiere Cluster mit High-Priority-Gaps
  -> Maximum: 7 Personas
```

### 2c -- Persona-Details ausarbeiten

Fuer JEDE Persona erstelle:

```
1. NAME + DEMOGRAFIE
   - Alliterativer Vorname + Nachname-Initial oder Spitzname
   - Alter, Beruf, 1 relevantes Detail
   - MUSS zur Branche passen (nicht generisch!)
   - Deutsch: "Preisbewusste Petra, 34, Studentin"
   - English: "Budget-Conscious Ben, 28, Graduate Student"

2. SUCHMOTIV & INTENT
   - WICHTIG: Die Persona sucht IMMER das Fokus-Keyword, NICHT ein anderes Keyword!
   - Beschreibe den HINTERGRUND und die MOTIVATION hinter der Suche
   - Was hat diese Person dazu bewogen, genau jetzt "{{KEYWORD}}" zu googeln?
   - Was ist der konkrete Ausloser? (Event, Problem, Vergleich, Lebenssituation)
   - Intent-Typ: Informational / Transaktional / Commercial / Navigational / Lokal / DIY
   - Welcher Related-Search oder PAA-Eintrag spiegelt die Erwartung dieser Persona wider?
   - Beispiel: Keyword "Photovoltaikanlage"
     RICHTIG: "Sucht 'Photovoltaikanlage'. Hintergrund: Will wissen, was eine Anlage
              fuer sein Einfamilienhaus kostet und ob sich die Investition lohnt."
     FALSCH:  "Sucht 'Photovoltaikanlage Kosten'."

   SPRECHBLASE (Ich-Perspektive):
   - Zusaetzlich zum Suchmotiv-Text: Schreibe 2-3 Saetze in der ICH-Form
   - Diese Saetze erscheinen in einer visuellen Sprechblase neben dem Avatar
   - Die Sprechblase macht die Persona lebendig und greifbar
   - Formuliere natuerlich, wie ein echter Mensch reden wuerde
   - Beispiel DE: "Mein iPhone-Display ist gesprungen und ich brauche schnell
     eine Reparatur. Am liebsten haette ich einen guenstigen Anbieter in meiner Naehe."
   - Beispiel EN: "My phone screen just cracked and I need it fixed fast.
     I'm looking for a reliable shop nearby that won't charge a fortune."

3. ERWARTUNG AN DIE SEITE
   - 2-3 Saetze: Was will diese Person KONKRET finden?
   - Welche Fragen muessen beantwortet werden?
   - Welches Format erwartet sie? (Tabelle, Rechner, Text, Video)

4. SCORE (1-100) -- nur wenn Page/URL verfuegbar
   - Berechnung: siehe Schritt 3
   - ODER: "Projiziert" basierend auf Gap-Analyse

5. VERBESSERUNGSVORSCHLAEGE (2-4 Punkte)
   - Konkret und umsetzbar
   - Aus der Perspektive dieser Persona formuliert
   - Referenz auf Gap-Analyse oder First-Screen-Check

6. ARCHETYPE (fuer Avatar-Bild)
   - Ordne jeder Persona einen Archetype-Key zu (siehe references/persona-images.md)
   - Mapping: Intent-Cluster -> Archetype-Key
     Preis -> price-conscious | Qualitaet -> quality-focused
     Lokal -> local-seeker | DIY -> diy-maker
     Anbieter -> provider-comparer | Angst/Unsicherheit -> anxious-decider
     Spezialfall -> special-case | Dringlichkeit -> urgent-user
     Informational -> knowledge-seeker | Commercial -> ready-buyer
   - Die Hauptpersona (aus User Story) bekommt immer "main-planner"
   - WICHTIG: Keine zwei Personas duerfen denselben Archetype haben!
     Bei Kollision: sekundaeren Archetype verwenden (trust-seeker,
     expert-user, beginner, emotional-seeker, roi-calculator)
```

---

## Schritt 3: Scoring (wenn Seite verfuegbar)

### 3a -- Scoring-Quelle bestimmen

```
IF SXO-Page vorhanden (sxo-page-*.html):
  -> Lies die Page mit Read-Tool
  -> Score basiert auf tatsaechlichem Seiteninhalt
  -> Scoring-Modus: "Basierend auf SXO-Page"

ELIF URL als Argument UND Report vorhanden:
  -> Hole Seite via WebFetch
  -> Score basiert auf Live-Seite
  -> Scoring-Modus: "Basierend auf Live-URL"

ELIF nur Report vorhanden (kein Page, keine URL):
  -> Score basiert auf Gap-Analyse + First-Screen-Check aus dem Report
  -> Scoring-Modus: "Projiziert aus SXO-Report"
  -> Hinweis im Dashboard: "Scores sind projiziert -- fuer praezisere Bewertung
     SXO-Page erstellen oder URL angeben"
```

### 3b -- Scoring-Dimensionen (4 Dimensionen, je 25 Punkte)

Fuer JEDE Persona, bewerte:

```
DIMENSION 1: First-Screen-Relevanz (0-25 Punkte)
  "Wird das Suchmotiv dieser Persona im First Screen adressiert?"

  25: Headline + Hero sprechen genau diesen Intent an
  20: Intent ist erkennbar, aber nicht dominant
  15: Intent ist vorhanden, aber erst nach Scrollen
  10: Intent wird nur indirekt angesprochen
   5: Intent ist auf der Seite, aber versteckt
   0: Intent wird nicht adressiert

DIMENSION 2: Erwartungserfuellung (0-35 Punkte)
  "Findet diese Persona, was sie konkret sucht?"

  35: Alle erwarteten Inhalte in passendem Format vorhanden
  28: Meiste Inhalte da, aber Format nicht optimal
  21: Kerninhalte vorhanden, aber unvollstaendig
  14: Nur teilweise abgedeckt, wichtige Elemente fehlen
   7: Nur am Rande erwaehnt
   0: Nicht abgedeckt

DIMENSION 3: Barriereabbau (0-25 Punkte)
  "Werden die spezifischen Bedenken/Barrieren dieser Persona adressiert?"

  25: Alle Barrieren proaktiv entschaerft (Trust, Preis, Risiko)
  20: Meiste Barrieren adressiert
  15: Einige Barrieren adressiert, andere ignoriert
  10: Nur die offensichtlichsten Barrieren
   5: Minimal
   0: Keine Barrieren adressiert

DIMENSION 4: Trust-Signale (0-15 Punkte)
  "Gibt es passende Vertrauenssignale fuer diese Persona?"

  15: Bewertungen, Zertifikate, Social Proof -- passend zum Persona-Kontext
  12: Gute Trust-Signale, aber nicht persona-spezifisch
   9: Basis-Trust vorhanden (Impressum, SSL)
   6: Wenige Trust-Signale
   3: Kaum Trust
   0: Keine Trust-Signale

GESAMTSCORE = Dim1 + Dim2 + Dim3 + Dim4 (max. 100)
```

### 3c -- Scoring bei projiziertem Modus (nur Report)

```
IF Scoring-Modus = "Projiziert aus SXO-Report":

  Dim 1 (First-Screen): Leite aus First-Screen-Check ab
    - Alle 5 Checks "pass" -> 25
    - Gemischt -> anteilig
    - Passe an: Ist der Check fuer DIESE Persona relevant?

  Dim 2 (Erwartung): Leite aus Gap-Analyse ab
    - Persona hat relevanten Gap mit Prio "high" -> max 14
    - Persona hat relevanten Gap mit Prio "medium" -> max 21
    - Persona hat keinen relevanten Gap -> 28-35

  Dim 3 (Barrieren): Leite aus User Story "Barrieren" ab
    - Pruefe ob Gap-Analyse die Persona-spezifischen Barrieren adressiert

  Dim 4 (Trust): Leite aus First-Screen "Vertrauenssignale" ab
    - pass -> 12-15, warn -> 6-9, fail -> 0-3
```

---

## Schritt 4: Dashboard-Zusammenfassung berechnen

```
1. DURCHSCHNITT = Summe aller Persona-Scores / Anzahl Personas (gerundet)

2. SCHWAECHSTE_PERSONA = Persona mit niedrigstem Score
   -> Name + Score + 1-Satz-Erklaerung

3. STAERKSTE_PERSONA = Persona mit hoechstem Score
   -> Name + Score + 1-Satz-Erklaerung

4. TOP_HANDLUNGSFELDER (max 5):
   -> Sammle alle Verbesserungsvorschlaege aller Personas
   -> Dedupliziere aehnliche Vorschlaege
   -> Sortiere nach: Anzahl betroffener Personas (absteigend)
   -> Jedes Handlungsfeld zeigt: Beschreibung + betroffene Personas

5. SCORING_MODUS:
   -> "Basierend auf SXO-Page" | "Basierend auf Live-URL" | "Projiziert aus SXO-Report"
```

### 4b -- Persona-Bilder generieren (mit Cache)

Lies die Referenzdatei `references/persona-images.md` fuer Archetype-Prompts und Cache-Logik.

```
Fuer JEDE Persona:

1. ARCHETYPE_KEY = Persona.archetype (aus Schritt 2c)
2. LANG = "de" oder "en" (aus Schritt 0b)
3. CACHE_KEY = "{ARCHETYPE_KEY}-{LANG}.png"
4. CACHE_PATH = ~/.sxo-persona/image-cache/{CACHE_KEY}

5. Pruefe Cache:
   IF Datei existiert UND Dateigroesse > 0:
     -> Log: "Cache-Hit: {CACHE_KEY}"
     -> Lies Bild als base64 via Bash:
        base64_data=$(base64 -w 0 {CACHE_PATH})
     -> PERSONA_IMG_SRC = "data:image/png;base64,${base64_data}"

   ELSE (Cache-Miss):
     -> Log: "Cache-Miss: {CACHE_KEY} -- generiere Bild..."
     -> Erstelle Cache-Verzeichnis: mkdir -p ~/.sxo-persona/image-cache/
     -> Bestimme BG_COLOR aus Persona-Score:
        Score 0-29:  #fce4ec (soft coral)
        Score 30-49: #fff3e0 (soft peach)
        Score 50-69: #fffde7 (soft warm yellow)
        Score 70-89: #e3f2fd (soft sky blue)
        Score 90-100: #e8f5e9 (soft mint)
     -> Baue Prompt = BASIS_PROMPT + ARCHETYPE_ERWEITERUNG
        (siehe references/persona-images.md)
     -> Rufe gemini_generate_image auf (1:1, 512px -- wird als 120px Avatar angezeigt)
     -> Kopiere generiertes Bild in Cache:
        cp ~/Documents/nanobanana_generated/<generated-file> {CACHE_PATH}
     -> Lies als base64
     -> PERSONA_IMG_SRC = "data:image/png;base64,${base64_data}"

6. Falls Bildgenerierung fehlschlaegt:
   -> Verwende Fallback: persona-avatar-placeholder (CSS-Klasse mit Emoji)
   -> Log: "Warnung: Bild fuer {CACHE_KEY} konnte nicht generiert werden"
   -> Dashboard trotzdem erstellen (Bild ist optional)
```

---

## Schritt 5: HTML-Dashboard generieren

### 5a -- CSS laden

```
1. Bestimme die Dashboard-Sprache (siehe Schritt 0b)
2. Lies das passende Template fuer den CSS-Block:
   - Deutsch:  assets/persona-template.html
   - English:  assets/persona-template-en.html
3. Kopiere den <style> Block woertlich
4. Generiere den <body> Inhalt direkt als HTML
```

### 5b -- HTML-Struktur generieren

Generiere den Body-Inhalt in dieser Reihenfolge.

**WICHTIG: Laienverstaendliche Sprache!** Alle Labels und Texte so formulieren,
dass ein Nicht-SEO-Experte (z.B. ein Geschaeftsfuehrer oder Marketing-Mitarbeiter)
das Dashboard sofort versteht. Keine Fachbegriffe ohne Erklaerung.

```html
<!-- HEADER -->
<header class="report-header">
  <div class="label">SXO Persona-Dashboard</div>  <!-- bzw. "SXO Persona Dashboard" EN -->
  <h1>Persona-Feedback: <span>{{KEYWORD}}</span></h1>
  <div class="meta-grid">
    <!-- Zielseite, Datum, Bewertungsmethode, Anzahl Personas -->
  </div>
</header>

<!-- ZUSAMMENFASSUNG -->
<div class="section">
  <div class="section-header">
    <div class="section-icon">&#128202;</div>
    <h2>Auf einen Blick</h2>  <!-- bzw. "At a Glance" EN -->
  </div>
  <div class="summary-card">
    <!-- Durchschnitts-Score (grosser SVG-Kreis, 150px) -->
    <!-- Schwaechste Persona + Staerkste Persona -->
    <!-- Bewertungsmethode-Hinweis -->
  </div>
</div>

<!-- ABOVE-THE-FOLD SCREENSHOT (nur wenn SCREENSHOT_BASE64 vorhanden) -->
<!-- IF SCREENSHOT_BASE64 vorhanden: -->
<div class="screenshot-card">
  <div class="sub-label">Above-the-Fold Ansicht</div>  <!-- bzw. "Above-the-Fold View" EN -->
  <img class="screenshot-img" src="data:image/png;base64,{{SCREENSHOT_BASE64}}" alt="Above-the-Fold Screenshot: {{URL}}">
  <p class="fs-13 text-muted mt-8">Viewport: 1280 &times; 800px (Desktop)</p>
</div>
<!-- ENDIF -->

<!-- USER STORY -->
<div class="section">
  <div class="section-header">
    <div class="section-icon">&#128172;</div>
    <h2>Die typische Suche</h2>  <!-- bzw. "The Typical Search" EN -->
  </div>
  <div class="card">
    <div class="user-story-quote">{{USER_STORY_STATEMENT}}</div>
  </div>
</div>

<!-- PERSONA CARDS (Einzelspalte fuer mehr Platz pro Persona) -->
<div class="section">
  <div class="section-header">
    <div class="section-icon">&#128101;</div>
    <h2>So unterschiedlich suchen Menschen</h2>  <!-- bzw. "How People Search Differently" EN -->
  </div>
  <div class="persona-list">
    <!-- 4-7 Persona-Cards, je eine pro Persona -->
    <!-- Reihenfolge: nach Score aufsteigend (schwaechste zuerst = groesster Handlungsbedarf) -->
    <!-- Jede Persona-Card: grosses Avatar-Bild + Sprechblase + Details -->
  </div>
</div>

<!-- HANDLUNGSEMPFEHLUNGEN -->
<div class="section">
  <div class="section-header">
    <div class="section-icon">&#9889;</div>
    <h2>Das sollten Sie als N&auml;chstes tun</h2>  <!-- bzw. "What You Should Do Next" EN -->
  </div>
  <div class="card">
    <!-- Nummerierte Liste, max 5 Eintraege -->
    <!-- Jeder Eintrag: Beschreibung + betroffene Personas als Tags -->
  </div>
</div>

<!-- FOOTER -->
<footer class="report-footer">
  SXO Persona-Dashboard erstellt mit Claude Code &middot; sxo-persona Skill &middot; {{DATUM}}
</footer>
```

### 5c -- Persona-Card Struktur (mit Sprechblase)

Jede Persona-Card hat 3 Bereiche:
1. **Profil-Kopf**: Grosses Avatar-Bild (120px) + Name + Score-Kreis
2. **Sprechblase**: Suchmotiv in Ich-Perspektive (macht die Persona lebendig)
3. **Details**: Erwartung, Score-Balken, Verbesserungstipps

```html
<div class="persona-card" style="--persona-color: {{COLOR}}">
  <!-- Farbiger Akzentstreifen oben -->
  <div class="persona-topbar"></div>

  <!-- PROFIL-KOPF: Grosses Bild + Name + Score -->
  <div class="persona-profile">
    <!-- Avatar (120px, aus Schritt 4b) -->
    <!-- IF Bild vorhanden: -->
    <img class="persona-avatar" src="{{PERSONA_IMG_SRC}}" alt="{{PERSONA_NAME}}">
    <!-- ELSE (Fallback): -->
    <!-- <div class="persona-avatar-placeholder">&#128100;</div> -->

    <div class="persona-identity">
      <h3>{{PERSONA_NAME}}</h3>
      <div class="persona-demo">{{DEMOGRAFIE}}</div>
      <span class="badge {{INTENT_BADGE_CLASS}}">{{INTENT_TYP}}</span>
    </div>
    <div class="score-circle" data-score="{{SCORE}}">
      <svg viewBox="0 0 120 120">
        <circle class="score-bg" cx="60" cy="60" r="54"/>
        <circle class="score-fill" cx="60" cy="60" r="54"
          stroke-dasharray="{{FILLED}} {{REMAINING}}"
          stroke-dashoffset="85"/>
      </svg>
      <div class="score-value">{{SCORE}}</div>
    </div>
  </div>

  <!-- SPRECHBLASE: Suchmotiv in Ich-Perspektive -->
  <div class="speech-bubble-wrap">
    <div class="speech-bubble">
      <span class="speech-keyword">&bdquo;{{KEYWORD}}&ldquo;</span> &mdash;
      {{SPRECHBLASE_ICH_PERSPEKTIVE}}
      <!-- 2-3 Saetze in der Ich-Form, natuerlich formuliert -->
      <!-- Beispiel: "Mein Display ist kaputt gegangen und ich suche jetzt
           eine guenstige Reparatur. Am besten in meiner Naehe, damit ich
           das Handy noch heute abgeben kann." -->
    </div>
  </div>

  <!-- DETAILS: Erwartung + Score + Tipps -->
  <div class="persona-body">
    <div class="persona-columns">
      <!-- Linke Spalte: Erwartung + Score-Balken -->
      <div>
        <div class="persona-field">
          <div class="pf-label"><span class="pf-icon">&#127919;</span> Was erwartet diese Person?</div>
          <!-- bzw. "What does this person expect?" EN -->
          <p>{{ERWARTUNG}}</p>
        </div>

        <div class="persona-field">
          <div class="pf-label"><span class="pf-icon">&#128200;</span> Bewertung im Detail</div>
          <!-- bzw. "Score Details" EN -->
          <div class="score-breakdown">
            <div class="sb-row">
              <span>Erster Eindruck</span>  <!-- bzw. "First Impression" EN -->
              <div class="sb-bar"><div class="sb-fill" style="width: {{DIM1_PCT}}%"></div></div>
              <span>{{DIM1}}/25</span>
            </div>
            <div class="sb-row">
              <span>Inhalte gefunden</span>  <!-- bzw. "Content Found" EN -->
              <div class="sb-bar"><div class="sb-fill" style="width: {{DIM2_PCT}}%"></div></div>
              <span>{{DIM2}}/35</span>
            </div>
            <div class="sb-row">
              <span>Bedenken gekl&auml;rt</span>  <!-- bzw. "Concerns Addressed" EN -->
              <div class="sb-bar"><div class="sb-fill" style="width: {{DIM3_PCT}}%"></div></div>
              <span>{{DIM3}}/25</span>
            </div>
            <div class="sb-row">
              <span>Vertrauen</span>  <!-- bzw. "Trust" EN -->
              <div class="sb-bar"><div class="sb-fill" style="width: {{DIM4_PCT}}%"></div></div>
              <span>{{DIM4}}/15</span>
            </div>
          </div>
        </div>
      </div>

      <!-- Rechte Spalte: Verbesserungstipps -->
      <div>
        <div class="persona-field">
          <div class="pf-label"><span class="pf-icon">&#128161;</span> Das k&ouml;nnen Sie tun</div>
          <!-- bzw. "What You Can Do" EN -->
          <ul class="tip-list">
            <li>{{VERBESSERUNG_1}}</li>
            <li>{{VERBESSERUNG_2}}</li>
            <!-- 2-4 Punkte -->
          </ul>
        </div>
      </div>
    </div>
  </div>
</div>
```

### 5d -- Score-Kreis berechnen (SVG)

```
Persona-Score-Kreis (80px Anzeige, viewBox 120):
  Umfang = 2 * PI * 54 = 339.29
  FILLED = (SCORE / 100) * 339.29
  REMAINING = 339.29 - FILLED

Summary-Score-Kreis (150px Anzeige, viewBox 120):
  Gleiche Formel wie oben (SVG skaliert automatisch)
```

### 5e -- Farbzuordnung

```
Score  0-29:  --persona-color: #ef4444  (Rot / Kritisch)
Score 30-49:  --persona-color: #f97316  (Orange / Schwach)
Score 50-69:  --persona-color: #eab308  (Amber / Teilweise)
Score 70-89:  --persona-color: #4f6ef7  (Blau / Gut)
Score 90-100: --persona-color: #22c55e  (Gruen / Exzellent)
```

### 5f -- Dateiname

```
Dateiname: sxo-persona-[KEYWORD-SLUG].html

KEYWORD-SLUG: Keyword in Kleinbuchstaben, Leerzeichen -> Bindestriche, Umlaute -> ae/oe/ue/ss
Beispiel: "iPhone 13 Display Reparatur" -> "iphone-13-display-reparatur"
```

---

## Schritt 6: Ausgabe und Zusammenfassung

Nach dem Speichern der HTML-Datei, gib eine kurze Zusammenfassung aus:

```
Zeige:
1. Dateiname + Pfad
2. Anzahl Personas
3. Durchschnitts-Score
4. Schwaechste Persona (Name + Score)
5. Wichtigstes Handlungsfeld (1 Satz)
6. Scoring-Modus
```

---

## Qualitaetsregeln

### Persona-Qualitaet

```
REGEL 0: Alle Personas suchen dasselbe Fokus-Keyword!
  -> Jede Persona tippt EXAKT das Fokus-Keyword in Google ein
  -> Die Differenzierung liegt im HINTERGRUND, INTENT und ERWARTUNG
  -> Related Searches und PAA zeigen verborgene Beduerfnisse, NICHT andere Suchbegriffe
  -> RICHTIG: "Sucht 'Photovoltaikanlage'. Hintergrund: Will vor allem wissen,
              was die Anlage kostet und ob sich die Investition lohnt."
  -> FALSCH: "Sucht 'Photovoltaikanlage Kosten'."
  -> FALSCH: "Sucht 'Photovoltaikanlage Balkon'."
  -> Das Ziel ist die bestmoegliche Seite fuer das EINE Fokus-Keyword

REGEL 1: Jede Persona MUSS sich klar von den anderen unterscheiden
  -> Nicht: 2x "will guenstigen Preis" mit anderem Namen
  -> Sondern: "will billigsten Preis" vs. "will bestes Preis-Leistungs-Verhaeltnis"
  -> Unterscheidung ueber: Lebenssituation, Wissensstand, Motivation, Barrieren

REGEL 2: Namen muessen branchenspezifisch sein
  -> Nicht: "User A", "Persona 1", "Max Mustermann"
  -> Sondern: "Altbau-Andreas, 52" (Solarbranche), "Studentin Lena, 23" (Handy-Reparatur)

REGEL 3: Verbesserungsvorschlaege muessen umsetzbar sein
  -> Nicht: "Seite verbessern", "mehr Trust aufbauen"
  -> Sondern: "Preisvergleichstabelle (Anbieter vs. Apple vs. MediaMarkt) above-the-fold"

REGEL 4: Score-Begruendungen muessen nachvollziehbar sein
  -> Referenziere konkrete Seiteninhalte oder Gaps
  -> Nicht: "Die Seite ist mittelmassig"
  -> Sondern: "Preis sichtbar (119,90 EUR), aber ohne Einordnung gegenueber Apple (489 EUR)"

REGEL 5: Alliterative Namen sind OPTIONAL, nicht erzwungen
  -> Wenn ein passender alliterativer Name existiert: verwenden
  -> Wenn nicht: normaler Name ist besser als erzwungene Alliteration
```

### HTML-Qualitaet

```
REGEL 6: Selbststaendige Datei
  -> Kein externes CSS, kein externes JavaScript
  -> Alle Styles inline im <style> Block
  -> SVG direkt im HTML (kein externer Verweis)

REGEL 7: Responsive Design
  -> Persona-Liste: Einzelspalte (volle Breite pro Persona)
  -> Persona-Body: 2 Spalten Desktop, 1 Spalte Mobile (persona-columns)
  -> Avatar: 120px Durchmesser, Score-Kreis: 80px
  -> Sprechblase: volle Breite mit Pfeil nach oben
  -> Lesbar auf 360px Breite

REGEL 8: Barrierefreiheit
  -> Farbkontrast: WCAG AA (4.5:1 fuer Text)
  -> Score-Kreise: Zahl ZUSAETZLICH zum Kreis (nicht nur visuell)
  -> Sinnvolle Ueberschriften-Hierarchie (h1 > h2 > h3)

REGEL 9: Print-Freundlich
  -> Print-Styles inkludieren (wie bei sxo-report Template)
  -> Score-Kreise muessen auch in Schwarz-Weiss lesbar sein
```

### Bild-Qualitaet

```
REGEL 10: Cache immer nutzen
  -> Niemals ein Bild generieren, wenn es bereits im Cache liegt
  -> Cache-Verzeichnis: ~/.sxo-persona/image-cache/
  -> Cache-Key: {archetype}-{lang}.png

REGEL 11: Bilder sind optional
  -> Dashboard MUSS auch ohne Bilder funktionieren
  -> Bei Fehler: persona-avatar-placeholder CSS-Klasse mit Emoji verwenden
  -> Niemals den gesamten Workflow abbrechen wegen eines Bildfehlers

REGEL 12: Archetype-Eindeutigkeit
  -> Keine zwei Personas im selben Dashboard duerfen denselben Archetype haben
  -> Bei Kollision: sekundaeren Archetype verwenden
  -> 16 Archetypes verfuegbar (siehe references/persona-images.md)

REGEL 13: Bildformat konsistent
  -> Alle Bilder als base64 inline im HTML (data:image/png;base64,...)
  -> Keine externen Bildverweise
  -> 120x120px Anzeige (CSS), 512px Quellaufloesung

REGEL 14: Sprechblase pflicht
  -> Jede Persona-Card MUSS eine Sprechblase mit Ich-Perspektive-Text haben
  -> Die Sprechblase macht die Persona greifbar und menschlich
  -> Formulierung: natuerlich, wie ein echter Mensch reden wuerde
  -> Keine Fachbegriffe in der Sprechblase
```

---

## Sprachspezifische Labels (Laienverstaendlich)

**Prinzip:** Alle Labels so formulieren, dass ein Nicht-SEO-Experte sie sofort versteht.
Keine Fachbegriffe wie "First-Screen-Relevanz" oder "Barriereabbau".

| Bereich | Deutsch | English |
|---|---|---|
| Header-Label | SXO Persona-Dashboard | SXO Persona Dashboard |
| Zusammenfassung | Auf einen Blick | At a Glance |
| Durchschnitts-Score | Durchschnitts-Score | Average Score |
| Schwaechste Persona | Groesster Handlungsbedarf | Needs Most Work |
| Staerkste Persona | Am besten bedient | Best Served |
| Bewertungsmethode | Bewertungsmethode | Scoring Method |
| User Story Section | Die typische Suche | The Typical Search |
| Personas Section | So unterschiedlich suchen Menschen | How People Search Differently |
| Erwartung | Was erwartet diese Person? | What does this person expect? |
| Score-Detail | Bewertung im Detail | Score Details |
| Verbesserungen | Das k&ouml;nnen Sie tun | What You Can Do |
| Handlungsfelder | Das sollten Sie als N&auml;chstes tun | What You Should Do Next |
| Betrifft | Betrifft | Affects |
| Projiziert | Gesch&auml;tzt aus SXO-Report | Estimated from SXO Report |
| Dim 1 | Erster Eindruck | First Impression |
| Dim 2 | Inhalte gefunden | Content Found |
| Dim 3 | Bedenken gekl&auml;rt | Concerns Addressed |
| Dim 4 | Vertrauen | Trust |
| Footer | SXO Persona-Dashboard erstellt mit Claude Code | SXO Persona Dashboard generated with Claude Code |

---

## Wichtig

- Schreibe echtes HTML, keine Markdown-Reste
- Kopiere NUR das CSS aus dem Template -- generiere den Body direkt
- Versuche NICHT, die `{{PLATZHALTER}}` im Template zu ersetzen
- Alle Texte in der erkannten Sprache
- Verwende `&mdash;` fuer Gedankenstriche, `&euro;` fuer Euro, `&amp;` fuer &
- Nutze HTML-Entities fuer Umlaute im HTML oder UTF-8 direkt
- Score-Kreise: Verwende SVG `stroke-dasharray` fuer den Fortschrittskreis
- Persona-Cards sortieren: schwaechster Score zuerst (= groesster Handlungsbedarf oben)
- Verwende `persona-list` (Einzelspalte), NICHT `persona-grid` (2-Spalten)
- Verwende `section-icon` fuer Section-Header, NICHT `section-number`
- Jede Persona-Card hat: persona-topbar, persona-profile, speech-bubble-wrap, persona-body
- Die Sprechblase (speech-bubble) enthaelt Ich-Perspektive-Text der Persona
- Alle Labels laienverstaendlich (siehe Labels-Tabelle)

