This commit is contained in:
2026-07-27 16:42:04 +02:00
parent 45a7704ea6
commit 018b751723
23 changed files with 2327 additions and 635 deletions

View File

@@ -0,0 +1,417 @@
# GreenLens — Copy-Audit: Onboarding & Paywall
> **Status: umgesetzt am 27.07.2026.** Alle Empfehlungen aus diesem Dokument sind im Code implementiert
> (DE/EN/ES). TypeScript-Check läuft fehlerfrei. Offene Punkte stehen in Abschnitt 6.
>
> Alle 6 echten App-Store-Bewertungen sind in `constants/socialProof.ts` hinterlegt.
> Confidence-Werte im Worked Example spiegeln echtes Produktverhalten; die Kalibrierung im
> Health-Prompt (`server/lib/openai.js`) wurde dafür ergänzt (Abschnitt 6.2).
**Audit:** 26.07.2026 · **Umsetzung:** 27.07.2026
**Grundlage:** Deep Research Report, Avatar Sheet (Emma / "Anxious Beginner"), Offer Brief, Necessary Beliefs Doc
**Geprüfte Screens:** `app/onboarding.tsx`, `app/onboarding/slides.tsx`, `source.tsx`, `health-check.tsx`, `personalizing.tsx`, `customize.tsx`, `app/profile/billing.tsx` (Paywall + Cancel-Flow), `components/OutOfCreditsSheet.tsx`, `utils/translations.ts`
---
## 0. Executive Summary
Der Flow ist handwerklich sauber gebaut (Progress, Analytics, 3 Sprachen, Chat-Interaktion). **Das Problem ist nicht die Ausführung, sondern das Argument.**
Drei Befunde, alles andere ist Detail:
1. **Der gesamte Flow verkauft Identifikation. Das Produkt verkauft Triage.**
Offer Brief, wörtlich: *"Start the pitch after identification, never on identification."* Der aktuelle Flow tut exakt das Gegenteil — Screen 1 bis 3 heißen „Pflanzen-Scanner", „Scanne jede Pflanze", „Monstera · 98%". Das ist genau das, was Google Lens gratis kann. Damit wird **Belief 5** („Ein Abo ist mir mehr wert als weiter googeln") nie adressiert — sie wird sogar aktiv widerlegt.
2. **Es gibt keinen einzigen Satz über Emmas Schmerz.**
Der Avatar kommt mit einem *akuten Symptom*, Schuldgefühl und Angst („I'll be so discouraged if I kill another one"). Im gesamten Onboarding fällt kein Wort über gelbe Blätter, braune Spitzen, hängende Triebe oder „hab ich zu viel gegossen?". Der Flow ist Feature-Tour, nicht Argument. *Pain is the pitch* — der Pitch fehlt.
3. **Die Paywall kommt nach null erlebtem Wert.**
`personalizing.tsx` → direkt `billing?view=paywall`. Der Nutzer hat zu diesem Zeitpunkt keinen Scan gemacht, keine Ausgabe gesehen, kein Symptom eingegeben. Offer Brief benennt das als **den einzelnen höchsten Hebel überhaupt**: *"A meaningful preview of the triage output before the paywall."*
Dazu kommen **fünf akute Credibility-Risiken** (Abschnitt 2), von denen mindestens zwei rechtlich und App-Store-relevant sind.
---
## 1. Belief-Coverage-Matrix
Wo im Flow wird welcher der sechs notwendigen Beliefs bearbeitet?
### Vorher
| # | Notwendiger Belief | Wo adressiert? | Status |
|---|---|---|---|
| 1 | Ein Foto kann die Ursache genug eingrenzen | nirgends | fehlt |
| 2 | Die App sagt mir konkret, was zu prüfen und zu tun ist (**Anker**) | nur health-check, als UI-Tutorial | schwach |
| 3 | Die App sagt ehrlich, wenn sie unsicher ist | nirgends — „98%" behauptet Sicherheit | kontraproduktiv |
| 4 | Die Empfehlung gilt für *meine* Pflanze | behauptet, nie belegt | schwach |
| 5 | Abo > weiter googeln | nirgends | fehlt |
| 6 | Preis, Verlängerung, Kündigung vorab klar | Preis + „Jederzeit kündbar" | erfüllt |
### Nachher — alle sechs bedient
| # | Belief | Umgesetzt in | Konkret |
|---|---|---|---|
| 1 | Foto grenzt ein | `slides.tsx` Slide 1, `health-check.tsx` | „GreenLens gewichtet die wahrscheinlichsten Ursachen und sagt dir, was du prüfen sollst, um sie zu bestätigen oder auszuschließen." + Ursachen-Ranking im Beispiel |
| 2 | Konkret prüfen & tun | `health-check.tsx`, `slides.tsx`, Paywall-Bullets | Worked Example mit „Prüfe zuerst" (3 Schritte) und „Tu jetzt" (eine Handlung) |
| 3 | Ehrlich bei Unsicherheit | `slides.tsx` Slide 3, `health-check.tsx` limitNote, Paywall-Bullet 1 | Eigener Slide „Wir sagen dir auch, wenn wir unsicher sind" + graue Confidence-Stufen statt Prozentzahl |
| 4 | Gilt für *meine* Pflanze | `slides.tsx` Slide 2, `personalizing.tsx` | „Ein konkreter Plan. Für diese Pflanze." + Rückspiegelung der eigenen Chat-Antworten als Chips |
| 5 | Besser als googeln | Welcome-Variante B, **Paywall `paywallCompare`** | „Kostenlose Tools sagen dir, wie deine Pflanze heißt. Sie sagen dir nicht, was zu prüfen ist, was zu tun ist oder ob es gewirkt hat." — bewusst auch auf der Paywall, damit der Belief unabhängig von der A/B-Variante greift |
| 6 | Preis & Kündigung vorab | `billing.tsx` | Monatsäquivalent des Jahrespreises, Trial-Erinnerung 2 Tage vorher, konkreter Kündigungsweg — alles vor dem CTA |
Der Anker-Belief (2) war ursprünglich an *einer* Stelle bedient — dort als Wegbeschreibung getarnt („Wo ist der Health-Scan?") statt als Kaufargument. Dieser Screen ist jetzt das Worked Example und trägt drei Beliefs gleichzeitig.
---
## 2. Akute Credibility- und Compliance-Risiken
**Diese fünf Punkte vor allen Copy-Verbesserungen klären.**
### 2.1 Testimonials ohne belegte Herkunft — `onboarding.tsx:23`, `personalizing.tsx:17`
```
„Endlich überleben meine Pflanzen! Absolute Empfehlung." — Anna M.
„GreenLens hat meine Geigenfeige gerettet..." — Elena R.
```
Wenn diese Zitate nicht von realen, dokumentierten Nutzern stammen: UWG-Verstoß (§5 Irreführung), App-Store-Guideline-Risiko, und im Schadensfall genau die Vertrauensfrage, auf der die gesamte Positionierung ruht. **Entweder belegen oder entfernen.** Es gibt starke Alternativen ohne Testimonial (siehe 3.1).
### 2.2 „4,8 APP-STORE-BEWERTUNG" hardcoded — `personalizing.tsx:19`
Der Deep Research Report stellt fest, dass das App-Store-Listing **keine Reviews** hat. Eine fest einprogrammierte Sternebewertung, die nicht aus einer realen Quelle stammt, ist derselbe Tatbestand wie 2.1 — nur prominenter platziert.
### 2.3 „Monstera · 98%" — `slides.tsx:30`
Offer Brief, Verbotsliste: *"Not a specific accuracy percentage — self-reported figures read as marketing noise and are unverifiable."* Zusätzlich zerstört diese Zahl aktiv **Belief 3** (Ehrlichkeit über Unsicherheit), der die gesamte Differenzierung gegenüber „App XY hat mir selbstbewusst was Falsches gesagt" trägt.
### 2.4 Direkter Widerspruch auf der Paywall — `billing.tsx:156159`
```
Headline: „Unbegrenzter Zugriff"
Sub: „Unbegrenzte Scans, Health-Checks…"
Card-Body: „…, 100 Credits/Monat"
```
„Unbegrenzt" und „100 Credits/Monat" stehen auf demselben Screen, drei Zeilen auseinander. Für einen Avatar, dessen dokumentierte Kernangst *Abo-Intransparenz* ist, ist das der schlimmstmögliche Fehler an der schlimmstmöglichen Stelle. Er zerstört den einzigen Belief, der aktuell erfüllt ist (Nr. 6).
### 2.5 Datenschutz-Aussage prüfen — `translations.ts:254`
```
„Deine Daten bleiben privat und lokal auf deinem Gerät."
```
Laut Architektur gehen Scans an OpenAI und Bilder an MinIO/S3. Diese Aussage ist dann **sachlich falsch**. Bitte durch etwas Wahres ersetzen, z. B.: *„Deine Fotos werden nur zur Analyse verarbeitet und nicht weiterverkauft."* (nur wenn zutreffend).
**Nebenbefund — Umlaute:** In `health-check.tsx` (DE) steht durchgängig ASCII-Ersatz: „Spaeter", „oeffnen", „Ausfuehrliche", „Sofortmassnahmen", „Wo ist der Health-Scan?" mit „Donde" statt „Dónde" im ES. Auf einem Screen, auf dem Zahlungsbereitschaft entsteht, liest sich das als unfertiges Produkt.
---
## 3. Screen für Screen — Diagnose & Rewrite
### 3.1 Welcome — `app/onboarding.tsx`
**Aktuell**
> Willkommen bei GreenLens!
> Pflanzen erkennen, verstehen und pflegen — ganz einfach.
> „Endlich überleben meine Pflanzen!" — Anna M.
> [Los geht's]
**Diagnose**
- „Willkommen bei GreenLens!" ist eine Begrüßung, keine Headline. Sie kostet den wertvollsten Platz im gesamten Produkt und sagt nichts.
- „ganz einfach" ist ein subjektives Adjektiv ohne Beleg — *point, don't talk*.
- Die Subline ist eine Kategoriebeschreibung, die auf jede der zwölf Konkurrenz-Apps passt. Keine Pattern Interruption.
- One-Mississippi-Test: nach zwei Sekunden weiß der Nutzer, dass es um Pflanzen geht. Sonst nichts.
**Rewrite A — Symptom-Einstieg (empfohlen, adressiert Belief 1+2+5)**
> **Gelbe Blätter. Und jetzt?**
> GreenLens sagt dir die wahrscheinlichsten Ursachen, was du selbst prüfen sollst und die eine sichere Sache, die du jetzt tun kannst.
> [Meine Pflanze prüfen] · Schon dabei? Anmelden
**Rewrite B — Abgrenzung zur Gratis-Alternative (adressiert Belief 5 frontal)**
> **Andere Apps sagen dir, wie deine Pflanze heißt.**
> **GreenLens sagt dir, was mit ihr los ist.**
> Wahrscheinliche Ursache, was du prüfen sollst, was du als Nächstes tust — und ein Check, ob es gewirkt hat.
> [Pflanze prüfen]
Beide ersetzen das Testimonial durch Argument. Wenn belegte Testimonials existieren, gehören sie *nach* das Argument, nicht davor.
---
### 3.2 Slides — `app/onboarding/slides.tsx`
**Aktuell:** „Scanne jede Pflanze" → „Health Check & Pflegeplan" → „Nie mehr Gießen vergessen"
**Diagnose**
- **Falsche Reihenfolge.** Slide 1 ist die Gratis-Funktion. Slide 2 ist das Produkt. Der stärkste Grund zu zahlen steht an Position 2 von 3 — und der Nutzer, der nach Slide 1 aussteigt, hat ihn nie gesehen.
- „Nie mehr Gießen vergessen" verkauft an einen anderen Avatar (den organisierten Sammler). Emma hat kein Erinnerungsproblem, sie hat ein *Diagnoseproblem*. Slide 3 wechselt mitten im Flow das Publikum.
- „Monstera · 98%" → siehe 2.3.
- Slide 2 ist inhaltlich richtig, aber unterspezifiziert: „erkennt Probleme früh und erstellt deinen Rettungsplan" — was steht in dem Plan? Genau das weiß `health-check.tsx` bereits sehr gut. Der Text existiert schon, nur am falschen Screen.
**Rewrite — 3 Slides, neu geordnet**
**Slide 1 (war 2) — das Produkt**
> **Was ist mit meiner Pflanze los?**
> Fotografiere das Symptom. GreenLens rankt die wahrscheinlichsten Ursachen und sagt dir, was du prüfen sollst, um sie zu bestätigen oder auszuschließen.
> *Visual-Chip:* „Wahrscheinlichste Ursache: Überwässerung · Prüfe: Erde 3 cm tief, Blattunterseiten"
**Slide 2 — der Plan (Belief 2 + 4)**
> **Ein konkreter Plan. Für diese Pflanze.**
> Sofortmaßnahme, 7-Tage-Plan, und nach 7 Tagen die Frage: Hat es gewirkt? Wenn nicht, geht es weiter.
**Slide 3 — Ehrlichkeit als Feature (Belief 3 — aktuell komplett unbesetzt)**
> **Wir sagen dir auch, wenn wir unsicher sind.**
> Ein Foto zeigt keine Wurzeln, keine Erdfeuchte, keine Vorgeschichte. Deshalb bekommst du Wahrscheinlichkeiten und Prüfschritte — keine erfundene Gewissheit.
Slide 3 ist der Screen, den keine Konkurrenz-App hat. Er beantwortet „Eine andere App hat mir selbstbewusst was Falsches gesagt" — laut Offer Brief eine der Top-Einwände.
---
### 3.3 Chat-Flow — `app/onboarding/source.tsx`
**Aktuell:** Monstera-Bot → „Wie hast du von GreenLens gehört?" → Ziel → Erfahrung → Licht
**Diagnose**
- **Die erste Frage dient dir, nicht ihm.** Attribution („Wie hast du von GreenLens gehört?") ist eine Marketing-Frage an der Stelle mit der höchsten Abbruchgefahr. Sie signalisiert dem Nutzer: dieses Gespräch ist für die Firma. Verschieben — nach dem ersten Erfolgserlebnis oder in die Profil-Settings.
- **Die Fiktion kollidiert mit der Positionierung.** „Hi! Ich bin deine neue Monstera 🌿" ist charmant, aber der Nutzer hat evtl. gar keine Monstera — und die gesamte Differenzierung basiert auf *Ehrlichkeit und Nüchternheit*. Eine sprechende Pflanze an der Stelle, an der Vertrauen entstehen soll, arbeitet gegen Belief 3.
- **Es wird nie nach dem Symptom gefragt** — der einzigen Information, die für Emmas Job-to-be-done tatsächlich zählt.
- Positiv: Die Lichtfrage ist gut motiviert („damit ich glücklich bleibe"). Genau dieses Muster — *warum ich das frage* — fehlt bei allen anderen Fragen.
**Rewrite — Fragenreihenfolge**
| # | Frage | Warum |
|---|---|---|
| 1 | „Hat gerade eine deiner Pflanzen ein Problem?" (Ja, akut / Ja, schleichend / Nein, vorbeugend) | Sofortige Relevanz, segmentiert Emma vs. Sammler |
| 2 | „Was siehst du?" (Gelbe Blätter · Braune Spitzen · Hängt · Flecken/Belag · Krabbeltiere · Etwas anderes) | Das ist der P.I.G.-Moment. Hier erkennt sie sich wieder. |
| 3 | „Wie viel Licht bekommt sie?" | bleibt — gut gemacht |
| 4 | „Wie sicher fühlst du dich bei Pflanzenpflege?" | bleibt |
| — | „Wie hast du von uns gehört?" | **raus aus dem Flow** |
Jede Frage mit einem Halbsatz begründen, warum sie gestellt wird — so wie es die Lichtfrage bereits tut.
Wenn der Monstera-Charakter bleiben soll: als *Beispielpflanze zur Demo* rahmen, nicht als Persona, die vorgibt, die Pflanze des Nutzers zu sein.
---
### 3.4 Health-Check-Screen — `app/onboarding/health-check.tsx`
**Das ist der stärkste Screen im Flow — und er ist als Bedienungsanleitung verkleidet.**
Diese vier Zeilen sind das gesamte Verkaufsargument:
> Gesundheits-Score mit Status: stabil, beobachten oder kritisch.
> Ausführliche Analyse mit sichtbaren Hinweisen **und Unsicherheit**.
> Wahrscheinlichste Ursachen **mit Confidence-Werten**.
> Sofortmaßnahmen plus konkreter 7-Tage-Pflegeplan.
Das bedient Belief 1, 2, 3 und 4 gleichzeitig. Es steht aber unter der Überschrift **„Wo ist der Health-Scan?"** — also unter einer Wegbeschreibung, an Position 5 von 6, kurz vor der Paywall.
**Empfehlung:** Inhalt hochziehen (Slides 1+2, siehe 3.2). Den Screen selbst zu einem **konkreten Beispiel** umbauen — laut Offer Brief *"the single highest-leverage proof asset available today"*:
> **So sieht eine Antwort aus**
>
> *Symptom:* Gelbe untere Blätter, Erde feucht
> **Wahrscheinlichste Ursache: Überwässerung** (hoch)
> Weniger wahrscheinlich: Nährstoffmangel (mittel) · Lichtmangel (niedrig)
>
> **Prüfe zuerst:** Erde 3 cm tief · Abzugslöcher im Topf · Blattunterseiten
> **Tu jetzt:** Nicht gießen. In 5 Tagen erneut prüfen.
> **In 7 Tagen:** Wir fragen nach, ob es besser wird.
>
> *Ein Foto zeigt keine Wurzeln. Deshalb Wahrscheinlichkeiten statt Diagnose.*
Ein echtes Beispiel schlägt jede Behauptung. Und es beantwortet den Einwand „Die Tipps sind eh generisch" ohne ein einziges Adjektiv.
---
### 3.5 Personalizing — `app/onboarding/personalizing.tsx`
**Diagnose**
- Loading-Screens, die Arbeit simulieren, sind branchenüblich — aber „Antworten werden analysiert / Pflegeplan wird erstellt / Scan-Credits werden vorbereitet / Plan wird finalisiert" beschreibt **deine** Prozesse, nicht ihren Nutzen. Es ist Wartezeit ohne Überzeugungsarbeit an der Stelle direkt vor der Kaufentscheidung.
- Testimonial + „4,8 App-Store-Bewertung": siehe 2.1 / 2.2.
- „Scan-Credits werden vorbereitet" führt einen Begriff ein, der nie erklärt wurde — und der zwei Screens später zum Widerspruch mit „unbegrenzt" führt.
**Rewrite — Schritte auf ihren Nutzen umschreiben**
> Deine Antworten werden ausgewertet
> Passende Ursachen für dein Symptom werden gewichtet
> Prüfschritte für deine Lichtsituation werden ausgewählt
> Dein 7-Tage-Plan steht
Statt Testimonial an dieser Stelle: die **Zusammenfassung ihrer eigenen Angaben** einblenden („Wenig Licht · Gelbe Blätter · Anfängerin"). Das beweist Belief 4 (*es geht um meine Pflanze*) durch Demonstration statt Behauptung.
---
### 3.6 Paywall — `app/profile/billing.tsx`
**Aktuell**
> GREENLENS PRO
> **Unbegrenzter Zugriff**
> Unbegrenzte Scans, Health-Checks und dein persönlicher Pflegeplan.
> GreenLens Pro — Unbegrenzte KI-Scans, Gesundheitsdiagnose, 7-Tage-Rettungspläne, 100 Credits/Monat
> 7 Tage gratis, dann 39,99 €/Jahr · [Gratis testen] · Jederzeit kündbar
**Diagnose**
1. **„Unbegrenzter Zugriff" vs. „100 Credits/Monat"** — siehe 2.4. Muss weg, unabhängig von allem anderen.
2. **Headline verkauft Menge, nicht Ergebnis.** „Unbegrenzt" ist eine Mengenaussage. Emma will kein Volumen, sie will *wissen, was zu tun ist*. Value Equation: Der Traumzustand wird nicht benannt.
3. **„Gesundheitsdiagnose"** — laut Offer Brief explizit nicht versprechbar („Not a guaranteed or lab-grade diagnosis"). Wording: *Ursachen-Analyse* oder *Triage*.
4. **Kein Risk Reversal jenseits von „Jederzeit kündbar".** Was honest garantierbar ist: transparente Abrechnung + klarer Kündigungsweg. Beides gehört *sichtbar auf den Screen*, nicht in eine Fußnote.
5. **Kein Preisanker.** 39,99 €/Jahr steht allein im Raum. Vergleich fehlt (eine ersetzte Pflanze; ein Nursery-Besuch).
6. **Nichts erinnert an den Schmerz.** Zwischen Symptomfrage und Kaufentscheidung liegen drei Screens, auf denen ihr Problem nie wieder erwähnt wurde.
**Rewrite**
> **GREENLENS PRO**
> ## Nicht mehr raten, was deiner Pflanze fehlt.
> Bei jedem Symptom: wahrscheinlichste Ursache, was du prüfen sollst, was du jetzt tust — und ein Check nach 7 Tagen, ob es gewirkt hat.
>
> ✓ Ursachen-Ranking statt einer Behauptung — inklusive dem, was unsicher ist
> ✓ Konkrete Prüfschritte, keine allgemeinen Pflegetexte
> ✓ 7-Tage-Plan pro Problem, plus Nachfrage, ob es besser wurde
> ✓ 100 Scans & Nachfragen im Monat *(Pro-Modell)*
> ✓ Deine komplette Pflanzen-Historie
>
> **7 Tage gratis. Danach 39,99 €/Jahr (3,33 €/Monat).**
> Wir erinnern dich 2 Tage vor Ablauf. Kündigen in 2 Taps in den iOS-Einstellungen — Anleitung in der App.
>
> [7 Tage gratis testen]
> *Heute fällig: 0,00 € · Erste Abbuchung am 2. August*
Änderungen im Detail:
- „Unbegrenzt" ersatzlos gestrichen → interner Widerspruch aufgelöst
- Headline benennt den Zustand, nicht die Menge
- „Gesundheitsdiagnose" → „Ursachen-Ranking" (compliant mit Offer Brief)
- Unsicherheits-Bullet als **Feature** → Belief 3 zum ersten Mal im ganzen Flow bedient
- Trial-Erinnerung + konkreter Kündigungsweg → Belief 6 von „erfüllt" auf „übererfüllt"
- Monatsäquivalent des Jahrespreises sichtbar (3,33 €) → senkt die wahrgenommene Hürde bei einem preissensiblen Avatar
**Zusätzlich, höchster Hebel:** Vor die Paywall einen echten Scan setzen. Ein Foto, ein Ergebnis, dann Paywall. Der Offer Brief nennt das die wirksamste verfügbare Einzelmaßnahme — und der aktuelle Flow ist genau eine `router.replace`-Zeile davon entfernt (`personalizing.tsx:75`).
---
### 3.7 Out-of-Credits Sheet — `components/OutOfCreditsSheet.tsx`
**Aktuell**
> Deine Gratis-Scans sind aufgebraucht.
> Hol dir Pro für unbegrenztes Scannen und deinen 7-Tage-Rettungsplan.
**Diagnose:** Reine Verlustmeldung. Der Nutzer wollte gerade etwas tun und wird blockiert. Das ist der Moment mit der höchsten *Intention* im ganzen Produkt und er wird mit einer Fehlermeldung eröffnet. Außerdem wieder „unbegrenzt" (siehe 2.4).
**Rewrite**
> **Diese Pflanze schauen wir uns noch an.**
> Mit Pro läuft dein Scan sofort — plus Ursachen-Ranking, Prüfschritte und dein 7-Tage-Plan.
> [Diesen Scan mit Pro starten] · [Einzelne Credits kaufen] · Später
Der CTA soll **die angefangene Aufgabe zu Ende bringen**, nicht ein Abo verkaufen. Der Kauf ist das Mittel, nicht das Angebot.
---
### 3.8 Cancel-Flow — `billing.tsx:141150`
**Gut gemacht:** Grund vor Angebot abfragen, gestaffeltes Save-Offer, klarer Abbruchweg. Struktur stimmt.
**Zwei Verbesserungen**
- „Schade, dass du gehst" / „Ein Geschenk für dich!" — der Ton ist unternehmensseitig („wir sind traurig"). Besser nutzerseitig: *„Bevor du gehst — was hat nicht gepasst?"*
- Das Save-Offer ist grundsegmentiert falsch: Wer „Ich nutze die App zu selten" wählt, bekommt einen Rabatt, obwohl der Preis nicht sein Problem ist. Bei *zu selten* wäre die passende Antwort **Pause statt Rabatt** („Abo für 3 Monate pausieren") — und das rettet die Beziehung, ohne Marge zu verschenken.
---
## 4. Umsetzungsstand
### Erledigt (27.07.2026)
| # | Maßnahme | Datei |
|---|---|---|
| 1 | Erfundene Testimonials entfernt, echte Store-Zitate als einzige Quelle | `constants/socialProof.ts` (neu), `onboarding.tsx`, `personalizing.tsx` |
| 2 | Rating auf belegbare **5,0 · 6 Bewertungen** — Wert und Anzahl immer gemeinsam | `constants/socialProof.ts`, `onboarding.tsx` |
| 3 | „Unbegrenzt / unlimited / ilimitado" überall entfernt, wo Credits limitiert sind | `billing.tsx`, `OutOfCreditsSheet.tsx` |
| 4 | „98%" ersetzt durch Ursachen-Ranking mit hoch/mittel/niedrig | `slides.tsx`, `health-check.tsx` |
| 5 | Datenschutz-Aussage korrigiert (kein „bleibt lokal auf deinem Gerät" mehr) | `translations.ts` (DE/EN/ES) |
| 6 | Umlaute und Akzente in `health-check.tsx` korrigiert | `health-check.tsx` |
| 7 | Welcome-Rewrite mit A/B-Test (Symptom vs. Abgrenzung) | `onboarding.tsx`, `services/experiments.ts` (neu) |
| 8 | Slides neu geordnet: Triage → Plan → Unsicherheit | `slides.tsx` |
| 9 | Chat: Attributionsfrage ans Ende, Symptomfrage nach vorn | `source.tsx` |
| 10 | Health-Check-Screen zum Worked Example umgebaut | `health-check.tsx` |
| 11 | Personalizing: Nutzensprache + Rückspiegelung der eigenen Antworten | `personalizing.tsx` |
| 12 | Paywall-Rewrite inkl. Bullets, Vergleich, Monatsäquivalent, Trial-Erinnerung, Kündigungsweg | `billing.tsx` |
| 13 | Out-of-Credits als „Aufgabe zu Ende bringen" reframed | `OutOfCreditsSheet.tsx` |
| 14 | Cancel-Flow: Pause statt Rabatt bei „nutze zu selten" | `billing.tsx` |
| 15 | „Pro scans with GPT-5.4" entfernt — Modellname ist kein Nutzen | `billing.tsx` |
| 16 | Hardcodierte englische Fragen-Überschriften im Chat lokalisiert | `source.tsx` |
**Verifikation:** `npx tsc --noEmit` → 0 Fehler. Grep-Gegenprobe auf „unbegrenzt/unlimited/ilimitado", „Anna M.", „Elena R.", „4,8", „98%", „GPT-5" → keine Treffer außer erklärenden Kommentaren.
### Neue Dateien
- **`constants/socialProof.ts`** — einzige Quelle für Sterne, Anzahl und Zitate. Regel im Kopf der Datei: nur was im Store nachweisbar ist. Solange `TESTIMONIALS` leer ist, rendert das UI Argument-Copy statt eines Zitats.
- **`services/experiments.ts`** — lokale, persistierte 50/50-Zuweisung. Siehe Abschnitt 5.
---
## 5. A/B-Test: wie er funktioniert und wie du ihn auswertest
**Warum nicht PostHog Feature Flags:** Der PostHog-Client läuft bewusst ohne Provider (`services/analytics.ts` — die Provider-Variante hat früher den App-Start zerlegt). Flags wären erst nach einem Netzwerk-Roundtrip da, der Welcome-Screen rendert aber sofort. Die Zuweisung passiert deshalb lokal, wird in AsyncStorage persistiert und an PostHog gemeldet.
**Was passiert:**
1. Beim ersten Öffnen des Welcome-Screens wird 50/50 gewürfelt: `symptom` oder `contrast`.
2. Die Variante wird persistiert — derselbe Nutzer sieht immer dieselbe.
3. `experiment_assigned` wird gefeuert, plus `register()` auf dem PostHog-Client. Dadurch hängt `experiment_welcome_headline_v1` **an jedem folgenden Event** dieses Nutzers.
**Auswertung in PostHog:** Funnel bauen über `onboarding_welcome_viewed``onboarding_started``onboarding_chat_completed``paywall_opened``subscription_started`/`trial_started`, dann *Breakdown by* `experiment_welcome_headline_v1`. Kein Backend-Umbau nötig — die Property liegt auf allen Events.
**Aussagekraft:** Bei 6 Bewertungen im Store bist du noch in einer Größenordnung, in der ein Headline-Test lange braucht, um signifikant zu werden. Bis dahin ist der Test vor allem eine saubere Infrastruktur — die Entscheidung darüber, welche Variante gewinnt, sollte nicht auf den ersten 50 Nutzern getroffen werden.
**QA:** `forceVariant('welcome_headline_v1', 'contrast')` erzwingt eine Variante zum Testen.
---
## 6. Offene Punkte
### 6.1 Store-Bewertungen — eingetragen ✅
Alle 6 echten Bewertungen liegen in `constants/socialProof.ts`, Wortlaut und Anzeigename unverändert. Jede hat ein `priority`-Feld — die Auswahl im UI richtet sich danach, wie stark eine Bewertung die Positionierung stützt, nicht nach Reihenfolge.
**Priorität 1 ist „Exactly what I needed" (Chrispetersssss, EN)** und die ist ein Glücksfall: *"Snap a photo and it tells you what's wrong and how to fix it - no more guessing why the leaves are turning yellow."* Das ist die Triage-Positionierung, formuliert von einem echten Nutzer — inklusive „gelbe Blätter", also exakt dem Symptom aus der Welcome-Variante A. Diese Bewertung ist wertvoller als jede Headline, die wir selbst schreiben könnten.
Priorität 2 („Die Pflanzenanalyse toppt echt jede andere App") stützt Belief 5, Priorität 3 („weil ich keinen grünen Daumen habe") trifft den Avatar wörtlich.
Alle Bewertungen haben freigegebene Übersetzungen für die jeweils anderen Sprachen. Spanische Nutzer sehen die englische Top-Bewertung übersetzt — mit sichtbarem „Traducido"-Hinweis, weil ein fremdsprachiges Original nie unkommentiert als muttersprachlich ausgegeben werden darf.
**Pflege:** `APP_STORE_RATING` bei jeder Listing-Änderung nachziehen; `verifiedOn` dokumentiert die letzte Gegenprüfung.
### 6.2 Belief 3 — gedeckt, nach einem Fund im Backend-Prompt ✅
Bei der Gegenprüfung in `server/lib/openai.js` sind zwei Dinge aufgefallen, die die Copy betroffen hätten.
**Fund 1: Die Confidence-Skala galt nur für die Arterkennung.**
`buildScanPrompt` (Arterkennung) hatte eine saubere Kalibrierung:
```
0.850.95 Art klar erkennbar
0.650.84 sehr wahrscheinlich, einzelne Merkmale verdeckt
0.400.64 mehrdeutig, mehrere Arten passen
< 0.40 überwiegend geraten
```
`buildHealthPrompt` (die Ursachen — also genau das, was das Worked Example zeigt) hatte **keine**. Dort stand nur: `"confidence": float 0.050.99 reflecting visual certainty`. Eine freie Zahl ohne definierte Bedeutung. Die App zeigt sie aber als Prozentwert an, und die neue Copy verspricht, dass wir Unsicherheit ehrlich ausweisen — dieses Versprechen hing damit an einem uncalibrierten Wert.
**Behoben:** Dieselbe Skala ist jetzt auch im Health-Prompt hinterlegt, plus die explizite Anweisung *"Do not inflate confidence to appear decisive. If the photo cannot settle it, a value below 0.65 is the correct and expected answer."* Damit ist Belief 3 nicht nur Copy, sondern Modellverhalten.
**Die Schwelle liegt bei 65 %, nicht 70 %.** Deine Einschätzung war der Sache nach richtig — 6584 % ist der „sehr wahrscheinlich"-Bereich, darunter wird es mehrdeutig. Die exakte Kante liegt aber bei 0,65. Die Beispiel-Notiz sagt jetzt „Unter 65 %" und stimmt damit mit dem Prompt überein. Wenn du die Schwelle im Prompt änderst, ist die Copy in `health-check.tsx` (`confidenceNote`, alle drei Sprachen) mitzuziehen.
**Fund 2: Die Beispielwerte hätten ein Verhalten gezeigt, das das Produkt nicht hat.**
Meine ersten Zahlen waren 58 / 27 / 11 — das summiert sich auf ~96 % und liest sich damit als Wahrscheinlichkeitsverteilung. Das Produkt liefert aber **unabhängige** Sicherheiten je Ursache; zwei Ursachen können beide bei 0,8 liegen. Ein Nutzer, der das Beispiel gesehen hat und dann echte Werte bekommt, die sich auf 140 % addieren, hätte zu Recht das Gefühl, dass etwas nicht stimmt.
**Geändert auf 64 / 41 / 22.** Summiert sich bewusst nicht auf 100, spiegelt echtes Verhalten und behält den entscheidenden Punkt: der Spitzenwert liegt knapp unter der Sicherheitsschwelle, das Beispiel zeigt also einen ehrlich unsicheren Fall. Im Prompt steht die Nicht-Summierung jetzt ebenfalls explizit (`these are NOT probabilities and must NOT sum to 1`), damit das Modell es nicht selbst normalisiert.
**Warum das der stärkere Beweis ist:** Ein Beispiel mit 94 % würde aussehen wie jede Konkurrenz-App, der die Nutzer nicht mehr glauben. 64 % plus „unter 65 % sagen wir das deutlich" beweist die Behauptung im selben Atemzug, in dem sie aufgestellt wird — und macht die Prüfschritte zur logischen Konsequenz statt zum Beiwerk.
**Abgrenzung zum entfernten „98 %":** Der Offer Brief verbietet *Accuracy-Claims* über das Produkt insgesamt („zu 98 % genau") — eine unbelegbare Marketing-Zahl. Ein *fallbezogener Confidence-Wert* im Ergebnis ist das Gegenteil: keine Werbeaussage, sondern eine Auskunft über die Grenzen dieser einen Einschätzung. Das alte „Monstera · 98 %" war Ersteres, die 64 % im Beispiel sind Letzteres.
**Noch zu beobachten:** Der Prompt ist geändert, aber noch nicht gegen echte Scans validiert. Nach dem nächsten Deploy ein paar Health-Scans mit uneindeutigen Fotos laufen lassen und prüfen, ob die Werte tatsächlich in den unteren Bereich fallen — ein Modell, das trotz Anweisung durchgehend 0,9 ausgibt, wäre wieder eine Produkt-, keine Copy-Lücke.
### 6.3 Scan vor der Paywall
Du hast angemerkt, dass der Demo-Scan auf dem Welcome-Screen bereits existiert. Er ist jetzt als **„Erst ausprobieren — ohne Konto"** formuliert und wird mit `onboarding_demo_scan_started` getrackt.
Der Flow bleibt bewusst unverändert: `personalizing.tsx` → Paywall. Grund: Wer den Demo-Scan nimmt, umgeht das Onboarding komplett und landet nie bei der Paywall — wer das Onboarding durchläuft, sieht keinen Scan. Beide Wege haben eine Lücke, und das Zusammenführen berührt Credits- und Auth-Logik, nicht Copy.
**Empfehlung als eigener Schritt:** Nach `personalizing.tsx` auf den Scanner leiten („Deine erste Analyse ist inklusive"), Paywall erst nach dem ersten Ergebnis. Der Offer Brief nennt das den höchsten verfügbaren Einzelhebel. In PostHog lässt sich vorher vergleichen, wie die Demo-Scan-Nutzer gegen die Onboarding-Nutzer konvertieren — die Daten dafür laufen ab jetzt.
### 6.4 Cancel-Flow: Pause technisch umsetzen
Die Pause-Option ist in der UI umgesetzt und wird als `cancel_save_offer_accepted` mit `offer: 'pause_3_months'` getrackt. Die tatsächliche Umsetzung am Store-Abo steht noch aus — im Code als `TODO(billing)` markiert. Aktuell zeigt sie einen Mock-Alert, genau wie der Rabatt vorher auch.
### 6.5 Symptom-Antwort in die Personalisierung führen
`situation` und `symptom` aus dem Chat werden jetzt gespeichert (`PreAuthOnboardingService`) und auf dem Personalizing-Screen zurückgespiegelt. Sie fließen aber noch nicht in den tatsächlich generierten Plan ein. Das wäre der nächste Schritt, damit Belief 4 nicht nur demonstriert, sondern eingelöst wird.