From e3066ec3e5a9b54145c841e7b1f465cbd07bb4a0 Mon Sep 17 00:00:00 2001 From: Marcel Raddatz Date: Thu, 9 Apr 2026 16:31:14 +0200 Subject: [PATCH] docs(specs): add C3 variety page rework mockups and V1 implementation spec Three mockup variations (c3-variety-rework.html) for /planner/variety page, plus detailed implementation spec for the chosen V1 "Erweiterte Karten" approach: recipe names + swap links inside warning cards, minimal layout changes. Co-Authored-By: Claude Sonnet 4.6 --- specs/frontend/c3-variety-rework-v1-spec.html | 625 ++++++++++++++ specs/frontend/c3-variety-rework.html | 790 ++++++++++++++++++ 2 files changed, 1415 insertions(+) create mode 100644 specs/frontend/c3-variety-rework-v1-spec.html create mode 100644 specs/frontend/c3-variety-rework.html diff --git a/specs/frontend/c3-variety-rework-v1-spec.html b/specs/frontend/c3-variety-rework-v1-spec.html new file mode 100644 index 0000000..bc80f9e --- /dev/null +++ b/specs/frontend/c3-variety-rework-v1-spec.html @@ -0,0 +1,625 @@ + + + + + + Recipe App — C3 Abwechslungs-Analyse · Implementierungsspezifikation V1 + + + + +
+ + +
+
+

C3 — Abwechslungs-Analyse · Implementierungsspezifikation

+

Recipe App · Variation V1 "Erweiterte Karten" · Rezeptnamen + Tausch-Links in Warnkarten

+
+
+ Final
+ Erstellt: 2026-04
+ Screen: C3
+ Bezug: c3-variety-rework.html +
+
+ + + +
+ +

Die Seite /planner/variety zeigt derzeit Warnkarten mit technischen Tages-Codes (MON, WED — erwäge einen Tausch). Der Planer muss manuell nachschlagen, welches Gericht an diesen Tagen eingeplant ist, und dann zurück zum Planer navigieren um es zu tauschen.

+

V1 "Erweiterte Karten" löst dies mit minimalem Umbauaufwand: Die Warnkarten erhalten eine strukturierte Zeile pro betroffenem Tag — mit Wochentag-Abkürzung, Rezeptname und direktem "Tauschen →" Link. Score-Hero, Bewertungsdetails und das Gesamt-Layout bleiben unverändert.

+ +
+
Scope
+
    +
  • Kein neues Backend-Endpoint — alle nötigen Daten sind bereits im weekPlan-Load vorhanden
  • +
  • Kein Layout-Umbau — nur VarietyWarningCards.svelte und die Datenvorbereitung in +page.svelte ändern sich
  • +
  • Protein-Grid und EffortBar bleiben wie bisher (Desktop)
  • +
+
+
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ElementAktuellSoll (V1)
Warnkarte Inhalttitle + explanation (String)Strukturierte Zeilen: Wochentag · Rezeptname · Tauschen-Link
Tages-AngabeAPI-Code MON, WEDAbkürzung Mo, Mi
RezeptnameFehltAus weekPlan.slots[].recipe.name
Tausch-NavigationFehlt — Nutzer verlässt die Seite manuell/planner?week={weekStart}&swap={slotId}
DatenbasiscomputeWarnings() aus variety.tsInline $derived.by() in +page.svelte, direkt aus API-Daten
+
+ + + +
+ + +

Alle nötigen Daten werden bereits im Server-Load geladen. Kein neuer API-Call erforderlich.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
QuelleFeldVerwendung
weekPlan.slots[]{ id, dayOfWeek, recipe: { id, name } }Aufbau der slotsByDay-Map: DayCode → { slotId, recipeName }
varietyScore.tagRepeats[]{ tagType, tagName, days: string[] }Warnkarten für wiederholte Tags (Protein, Cuisine). days[] enthält API-Codes: "MON", "TUE" …
varietyScore.ingredientOverlaps[]{ ingredientName, days: string[] }Warnkarten für Zutaten-Überschneidungen
varietyScore.duplicatesInPlan[]string[] (Rezeptnamen)Warnkarte: "X doppelt geplant". Alle Slots mit diesem Rezeptnamen liefern die Items.
data.weekStartstring (YYYY-MM-DD)Swap-URL-Parameter
+ +

Tag-Code → Abkürzung Mapping (konstant):

+
// Day code → German short label +const DAY_SHORT: Record<string, string> = { + MON: 'Mo', TUE: 'Di', WED: 'Mi', + THU: 'Do', FRI: 'Fr', SAT: 'Sa', SUN: 'So' +};
+
+ + + +
+ + +

Die bestehende VarietyWarningCards.svelte definiert bereits die korrekten Interfaces. Diese bleiben unverändert:

+ +
// In VarietyWarningCards.svelte (bereits vorhanden, nicht ändern) +interface WarningItem { + dayShort: string; // 'Mo', 'Di', … + recipeName: string; // aus weekPlan.slots[].recipe.name + slotId: number; // für Swap-Link +} + +interface ActionWarning { + title: string; // z.B. "Tofu mehrfach diese Woche" + items: WarningItem[]; // eine Zeile pro betroffenem Tag +}
+ +

Die alte Warning-Schnittstelle aus variety.ts ({ title, explanation }) wird nicht mehr verwendet.

+
+ + + +
+ + +

Es gibt drei Änderungen:

+ + +
+
+
5.1
+
+page.svelte — slotsByDay Map aufbauen
+
+
+

Füge direkt nach den bestehenden $derived-Deklarationen hinzu:

+
const DAY_SHORT: Record<string, string> = { + MON: 'Mo', TUE: 'Di', WED: 'Mi', + THU: 'Do', FRI: 'Fr', SAT: 'Sa', SUN: 'So' +}; + +// dayOfWeek (API code) → { slotId, recipeName } +let slotsByDay = $derived.by(() => { + const map: Record<string, { slotId: number; recipeName: string }> = {}; + for (const slot of weekPlan?.slots ?? []) { + if (slot.dayOfWeek && slot.recipe?.name && slot.id) { + map[slot.dayOfWeek] = { slotId: slot.id, recipeName: slot.recipe.name }; + } + } + return map; +});
+
+
+ + +
+
+
5.2
+
+page.svelte — actionWarnings ersetzen computeWarnings()
+
+
+

Ersetze den bestehenden let warnings = $derived.by(() => computeWarnings(…))-Block vollständig:

+
interface WarningItem { dayShort: string; recipeName: string; slotId: number; } +interface ActionWarning { title: string; items: WarningItem[]; } + +let actionWarnings = $derived.by((): ActionWarning[] => { + const result: ActionWarning[] = []; + const vs = varietyScore; + if (!vs) return result; + + // Tag repeats (protein, cuisine, …) + for (const repeat of vs.tagRepeats ?? []) { + if ((repeat.days?.length ?? 0) < 2) continue; + const items: WarningItem[] = (repeat.days ?? []) + .map((day) => { + const slot = slotsByDay[day]; + return slot + ? { dayShort: DAY_SHORT[day] ?? day, recipeName: slot.recipeName, slotId: slot.slotId } + : null; + }) + .filter((x): x is WarningItem => x !== null); + if (items.length > 0) { + result.push({ title: `${repeat.tagName} mehrfach diese Woche`, items }); + } + } + + // Ingredient overlaps + for (const overlap of vs.ingredientOverlaps ?? []) { + if ((overlap.days?.length ?? 0) < 2) continue; + const items: WarningItem[] = (overlap.days ?? []) + .map((day) => { + const slot = slotsByDay[day]; + return slot + ? { dayShort: DAY_SHORT[day] ?? day, recipeName: slot.recipeName, slotId: slot.slotId } + : null; + }) + .filter((x): x is WarningItem => x !== null); + if (items.length > 0) { + result.push({ title: `${overlap.ingredientName} in mehreren Gerichten`, items }); + } + } + + // Duplicate recipes — find all slots with that recipe name + for (const name of vs.duplicatesInPlan ?? []) { + const items: WarningItem[] = Object.entries(slotsByDay) + .filter(([, s]) => s.recipeName === name) + .map(([day, s]) => ({ dayShort: DAY_SHORT[day] ?? day, recipeName: s.recipeName, slotId: s.slotId })); + if (items.length > 0) { + result.push({ title: `${name} doppelt geplant`, items }); + } + } + + return result; +});
+
+
+ + +
+
+
5.3
+
+page.svelte — Template: warnings → actionWarnings, weekStart übergeben
+
+
+

An beiden Stellen im Template (Mobile + Desktop) ersetzen:

+
+
+page.svelte (Mobile, ~Zeile 110 / Desktop, ~Zeile 222)
+
- {#if warnings.length > 0} +- <VarietyWarningCards {warnings} /> ++ {#if actionWarnings.length > 0} ++ <VarietyWarningCards warnings={actionWarnings} {weekStart} />
+
+

Achtung: weekStart ist für die Swap-URL erforderlich und muss explizit übergeben werden.

+
+
+ + +
+
+
5.4
+
+page.svelte — Import aufräumen
+
+
+

Entferne den nicht mehr genutzten Import:

+
+
+page.svelte (Script-Block, oben)
+
- import { computeSubScores, computeWarnings } from '$lib/planner/variety'; ++ import { computeSubScores } from '$lib/planner/variety';
+
+

computeSubScores wird noch für die Score-Breakdown-Anzeige genutzt.

+
+
+
+ + + +
+ + +

Die Komponente wurde bereits auf das neue ActionWarning-Format aktualisiert. Keine Änderung erforderlich. Zur Referenz die erwartete Props-Schnittstelle:

+ +
// Props (bereits implementiert) +let { warnings, weekStart }: { + warnings: ActionWarning[]; + weekStart: string; +} = $props();
+ +

Die Komponente rendert für jede Warnung:

+
    +
  • Gelbe Karte (border: yellow-light, bg: yellow-tint) mit Header-Zeile (Titel)
  • +
  • Pro Item: Zeile mit Wochentag-Abkürzung (W=20px, fixed) · Rezeptname (truncate) · "Tauschen →" Link (rechts)
  • +
  • Swap-URL: /planner?week={weekStart}&swap={item.slotId}
  • +
+ + +
+
+
Warnkarte · Referenz-Darstellung
+
+
+
Tofu mehrfach diese Woche
+
+
MoTofu-Gemüse-Pfanne
+ Tauschen → +
+
+
MiTofu-Curry mit Reis
+ Tauschen → +
+
+
+
Paprika in mehreren Gerichten
+
+
DiPaprika-Linsen-Eintopf
+ Tauschen → +
+
+
MiTofu-Curry mit Reis
+ Tauschen → +
+
+
+
+
+
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FallVerhalten
Tag im tagRepeat hat keinen SlotFilter-Schritt (.filter(x => x !== null)) entfernt das Item. Warnkarte erscheint nur wenn ≥1 Item vorhanden.
weekPlan hat keine Slots (leere Woche)slotsByDay ist {}, actionWarnings ist []. Keine Warnkarten sichtbar.
varietyScore ist nullBestehende {#if !varietyScore}-Guard greift — actionWarnings wird nie gerendert.
Slot hat kein Rezept (slot.recipe === null)slot.recipe?.name ist undefined → Slot wird nicht in slotsByDay aufgenommen.
duplicatesInPlan: Rezeptname kommt in slotsByDay nicht voritems ist leer → Warnkarte wird nicht gepusht.
Unbekannter Tag-Code (z.B. zukünftige API-Erweiterung)DAY_SHORT[day] ?? day — Fallback auf den rohen Code.
Sehr langer RezeptnameCSS truncate auf .wcard-recipe — kein Überlauf, Swap-Link bleibt sichtbar.
+
+ + + +
+ + +
+
Acceptance Criteria
+
    +
  • AC-1: Warnkarte zeigt pro betroffenem Tag eine eigene Zeile (nicht mehr einen langen Erklärungstext)
  • +
  • AC-2: Jede Zeile enthält die deutsche Wochentag-Abkürzung (Mo, Di, Mi, Do, Fr, Sa, So)
  • +
  • AC-3: Jede Zeile enthält den Namen des eingeplanten Rezepts
  • +
  • AC-4: Jede Zeile enthält einen "Tauschen →" Link, der zu /planner?week={weekStart}&swap={slotId} führt
  • +
  • AC-5: Tags mit nur einem betroffenen Tag (days.length < 2) erzeugen keine Warnkarte
  • +
  • AC-6: Score-Hero, Bewertungsdetails und Protein-Grid (Desktop) bleiben unverändert
  • +
  • AC-7: Wenn varietyScore null ist, werden keine Warnkarten gerendert (leere-Woche-State bleibt)
  • +
  • AC-8: Der Import von computeWarnings ist entfernt, TypeScript kompiliert fehlerfrei
  • +
  • AC-9: Auf Mobilgerät sind Tausch-Links touch-freundlich (mind. 44px Zeilenhöhe)
  • +
+
+ +
+
Nicht in Scope
+
    +
  • Neues Backend-Endpoint — alle Daten kommen aus dem bestehenden Load
  • +
  • Layout-Umbau der Seite — Score bleibt oben, Warnungen unten wie bisher
  • +
  • Protein-Grid oder EffortBar Änderungen
  • +
  • computeSubScores aus variety.ts — bleibt unverändert
  • +
  • Entfernen von computeWarnings aus variety.ts (Funktion bleibt, wird nur nicht mehr aufgerufen)
  • +
+
+
+ + + +
+ + + + + + + + + + + + + + + + + + +
DateiÄnderung
frontend/src/routes/(app)/planner/variety/+page.svelteDAY_SHORT-Konstante, slotsByDay-Derived, actionWarnings-Derived, Template-Update (2×), Import-Bereinigung
frontend/src/lib/planner/VarietyWarningCards.svelteKeine — bereits auf ActionWarning-Format aktualisiert
frontend/src/lib/planner/variety.tsKeine — computeWarnings bleibt (ungenutzt, aber nicht entfernen um Regressions-Risiko zu vermeiden)
+
+ + + +
+ +

Dieser Abschnitt enthält maschinenlesbare Regeln für einen KI-Agenten der die Implementierung durchführt.

+ +
SCREEN: C3 /planner/variety +VARIATION: V1 "Erweiterte Karten" +STATUS: Final spec — ready for implementation + +FILES TO MODIFY: + frontend/src/routes/(app)/planner/variety/+page.svelte + +FILES NOT TO MODIFY: + frontend/src/lib/planner/VarietyWarningCards.svelte (already correct) + frontend/src/lib/planner/variety.ts (keep computeWarnings, remove only import) + +STEP 1 — Add DAY_SHORT constant (in <script> block, after imports): + const DAY_SHORT: Record<string, string> = { + MON: 'Mo', TUE: 'Di', WED: 'Mi', + THU: 'Do', FRI: 'Fr', SAT: 'Sa', SUN: 'So' + }; + +STEP 2 — Add slotsByDay derived (after $derived declarations for weekPlan, etc.): + let slotsByDay = $derived.by(() => { + const map: Record<string, { slotId: number; recipeName: string }> = {}; + for (const slot of weekPlan?.slots ?? []) { + if (slot.dayOfWeek && slot.recipe?.name && slot.id) { + map[slot.dayOfWeek] = { slotId: slot.id, recipeName: slot.recipe.name }; + } + } + return map; + }); + +STEP 3 — Define inline interfaces + actionWarnings derived: + interface WarningItem { dayShort: string; recipeName: string; slotId: number; } + interface ActionWarning { title: string; items: WarningItem[]; } + + let actionWarnings = $derived.by((): ActionWarning[] => { + const result: ActionWarning[] = []; + const vs = varietyScore; + if (!vs) return result; + + for (const repeat of vs.tagRepeats ?? []) { + if ((repeat.days?.length ?? 0) < 2) continue; + const items: WarningItem[] = (repeat.days ?? []) + .map((day) => { + const slot = slotsByDay[day]; + return slot ? { dayShort: DAY_SHORT[day] ?? day, recipeName: slot.recipeName, slotId: slot.slotId } : null; + }) + .filter((x): x is WarningItem => x !== null); + if (items.length > 0) result.push({ title: `${repeat.tagName} mehrfach diese Woche`, items }); + } + + for (const overlap of vs.ingredientOverlaps ?? []) { + if ((overlap.days?.length ?? 0) < 2) continue; + const items: WarningItem[] = (overlap.days ?? []) + .map((day) => { + const slot = slotsByDay[day]; + return slot ? { dayShort: DAY_SHORT[day] ?? day, recipeName: slot.recipeName, slotId: slot.slotId } : null; + }) + .filter((x): x is WarningItem => x !== null); + if (items.length > 0) result.push({ title: `${overlap.ingredientName} in mehreren Gerichten`, items }); + } + + for (const name of vs.duplicatesInPlan ?? []) { + const items: WarningItem[] = Object.entries(slotsByDay) + .filter(([, s]) => s.recipeName === name) + .map(([day, s]) => ({ dayShort: DAY_SHORT[day] ?? day, recipeName: s.recipeName, slotId: s.slotId })); + if (items.length > 0) result.push({ title: `${name} doppelt geplant`, items }); + } + + return result; + }); + +STEP 4 — Replace template occurrences (both mobile and desktop sections): + OLD: {#if warnings.length > 0} / <VarietyWarningCards {warnings} /> + NEW: {#if actionWarnings.length > 0} / <VarietyWarningCards warnings={actionWarnings} {weekStart} /> + +STEP 5 — Fix import: + OLD: import { computeSubScores, computeWarnings } from '$lib/planner/variety'; + NEW: import { computeSubScores } from '$lib/planner/variety'; + +INVARIANTS (do not change): + - VarietyScoreHero, ScoreBreakdownList, EffortBar remain untouched + - Desktop protein grid (proteinByDay) remains untouched + - Layout structure (score top, warnings bottom) stays identical + - No new server load or API calls
+
+ +
+ + diff --git a/specs/frontend/c3-variety-rework.html b/specs/frontend/c3-variety-rework.html new file mode 100644 index 0000000..cc51098 --- /dev/null +++ b/specs/frontend/c3-variety-rework.html @@ -0,0 +1,790 @@ + + + + + + Recipe App — C3 Abwechslungs-Analyse · 3 Mockup-Variationen + + + + +
+ + +
+
+

C3 — Abwechslungs-Analyse · Rework

+

Recipe App · 3 Mockup-Variationen · Aktuell: technische Tages-Codes, keine Rezeptnamen, kein direkter Tausch

+
+
+ Entwurf
+ Erstellt: 2026-04
+ Variationen: 3
+ Screen: C3 +
+
+ + +
+ +

Die aktuelle Seite zeigt Warnungen wie "MON, WED — erwäge einen Tausch". Der Planer muss selbst nachschlagen, welches Gericht an Montag und Mittwoch geplant ist, und dann manuell zum Planer navigieren um zu tauschen. Zwei Probleme:

+

1. Keine Rezeptnamen — Tag-Codes statt echter Gerichte. 2. Kein direkter Tausch — der Planer muss die Seite verlassen, zurück zum Planer, das richtige Gericht suchen und dann tauschen.

+
+ + + +
+
+
V1
+
+
Variation 1
+
Erweiterte Karten
+
Minimale Änderung: bestehende gelbe Karten bleiben, aber der Text wird durch strukturierte Zeilen ersetzt — eine pro betroffenem Gericht, mit Wochentag, Rezeptname und "Tauschen →" Link. Score-Bereich und Layout bleiben unverändert.
+
+
+ +
+ + +
+
Mobile · 320px
+
+
9:41●●●
+ +
+
+
Abwechslungs-Analyse
+
+
+ + +
+
+ 5.8 + / 10 + Verbesserbar +
+
+
+ + +
+
Bewertung im Detail
+
Quellen-Vielfalt4 / 10
+
Zutaten-Überschneidung7 / 10
+
Aufwandsbalance8 / 10
+
+ + +
Hinweise
+ +
+
Tofu mehrfach diese Woche
+
+
MoTofu-Gemüse-Pfanne
+ Tauschen → +
+
+
MiTofu-Curry mit Reis
+ Tauschen → +
+
+ +
+
Paprika in mehreren Gerichten
+
+
DiPaprika-Linsen-Eintopf
+ Tauschen → +
+
+
MiTofu-Curry mit Reis
+ Tauschen → +
+
+ +
+
+
📅
Plan
+
🛒
Einkauf
+
🍳
Rezepte
+
📊
Analyse
+
+
+
+ + +
+
Desktop · 1040px
+
+
+ +
+
Planung
+
📅 Wochenplan
+
🛒 Einkaufsliste
+
🍳 Rezepte
+
Haushalt
+
⚙️ Einstellungen
+
+
+
+
+ Planer / + Abwechslungs-Analyse +
+
+ +
+ +
+
+ 5.8 + / 10 + Verbesserbar +
+
+
+
Bewertung im Detail
+
Quellen-Vielfalt4 / 10
+
Zutaten-Überschneidung7 / 10
+
Aufwandsbalance8 / 10
+
+
+ +
+
Hinweise
+
+
Tofu mehrfach diese Woche
+
+
MoTofu-Gemüse-Pfanne
+ Tauschen → +
+
+
MiTofu-Curry mit Reis
+ Tauschen → +
+
+
+
Paprika in mehreren Gerichten
+
+
DiPaprika-Linsen-Eintopf
+ Tauschen → +
+
+
MiTofu-Curry mit Reis
+ Tauschen → +
+
+
+
+
+
+
+
+
+ +
+
Design-Notizen V1
+
    +
  • Geringster Umbauaufwand — nur VarietyWarningCards.svelte ändert sich, keine Layout-Umstrukturierung.
  • +
  • Behält die bekannte Score-Hierarchie bei: Zahl oben, dann Detail, dann Hinweise.
  • +
  • Schwachstelle: Hinweise sind trotzdem am Ende der Seite versteckt — auf kurzen Telefon-Bildschirmen muss gescrollt werden, bevor der Planer die Tausch-Links sieht.
  • +
  • Die Sub-Scores bleiben immer sichtbar, auch wenn der Planer nur die Tausch-Aktionen braucht.
  • +
+
+
+ +
+ + + +
+
+
V2
+
+
Variation 2 · Empfohlen
+
Aktions-Liste
+
Hinweise rücken nach oben — direkt unter dem Score. Der Planer sieht sofort, was zu tun ist. Sub-Scores wandern in ein ausklappbares "Bewertung im Detail" (native <details>, kein JS). Kompakterer Score-Hero gibt Hinweisen mehr Raum.
+
+
+ +
+ + +
+
Mobile · 320px
+
+
9:41●●●
+
+
+
Abwechslungs-Analyse
+
+
+ + +
+
+ 5.8 + / 10 +
+
+
Verbesserbar
+
+
+
+ + +
2 Hinweise
+ +
+
Tofu mehrfach diese Woche
+
+
MoTofu-Gemüse-Pfanne
+ Tauschen → +
+
+
MiTofu-Curry mit Reis
+ Tauschen → +
+
+ +
+
Paprika in mehreren Gerichten
+
+
DiPaprika-Linsen-Eintopf
+ Tauschen → +
+
+
MiTofu-Curry mit Reis
+ Tauschen → +
+
+ + +
+ Bewertung im Detail +
+
Quellen-Vielfalt4 / 10
+
Zutaten-Überschneidung7 / 10
+
Aufwandsbalance8 / 10
+
+
+ +
+
+
📅
Plan
+
🛒
Einkauf
+
🍳
Rezepte
+
📊
Analyse
+
+
+
+ + +
+
Desktop · 1040px
+
+
+ +
+
Planung
+
📅 Wochenplan
+
🛒 Einkaufsliste
+
🍳 Rezepte
+
Haushalt
+
⚙️ Einstellungen
+
+
+
+
+ Planer / + Abwechslungs-Analyse +
+
+ +
+
+ 5.8 + / 10 +
+
+
Verbesserbar — 2 Hinweise
+
+
+ +
+
+
4
+
Quellen
+
+
+
7
+
Zutaten
+
+
+
8
+
Aufwand
+
+
+
+ +
Hinweise
+
+
+
Tofu mehrfach diese Woche
+
+
MoTofu-Gemüse-Pfanne
+ Tauschen → +
+
+
MiTofu-Curry mit Reis
+ Tauschen → +
+
+
+
Paprika in mehreren Gerichten
+
+
DiPaprika-Linsen-Eintopf
+ Tauschen → +
+
+
MiTofu-Curry mit Reis
+ Tauschen → +
+
+
+
+
+
+
+
+ +
+
Design-Notizen V2
+
    +
  • Hinweise erscheinen direkt unter dem Score — kein Scrollen nötig auf typischen Telefon-Bildschirmen.
  • +
  • Kompakter Score-Strip auf Mobile spart ~80px gegenüber dem aktuellen großen Hero — mehr Raum für die eigentlichen Tausch-Aktionen.
  • +
  • Desktop: Sub-Scores werden als kompakte Zahlen-Spalte in die Score-Leiste integriert — kein separater Abschnitt mehr nötig.
  • +
  • Native <details> auf Mobile braucht kein JavaScript; funktioniert auch ohne hydration.
  • +
  • "2 Hinweise" im Score-Strip auf Desktop gibt dem Planer sofort Kontext, ohne zu scrollen.
  • +
+
+
+ +
+ + + +
+
+
V3
+
+
Variation 3
+
Hinweise zuerst
+
Invertiertes Layout: die Seite öffnet mit den konkreten Problem-Karten — groß und klar. Score und Breakdown erscheinen darunter als unterstützende Information. Jede Warnung ist eine eigenständige "Aufgaben-Karte" mit prominentem Tausch-Button statt Link.
+
+
+ +
+ + +
+
Mobile · 320px
+
+
9:41●●●
+
+
+
Abwechslungs-Analyse
+
+
+ + +
Was zu tun ist
+ + +
+
+
Quellen-Wiederholung
+
Tofu an 2 Tagen
+
+ +
+
+
Montag
+
Tofu-Gemüse-Pfanne
+
+ Tauschen +
+ +
+
+
Mittwoch
+
Tofu-Curry mit Reis
+
+ Tauschen +
+
+ + +
+
+
Zutaten-Überschneidung
+
Paprika an 2 aufeinanderfolgenden Tagen
+
+
+
+
Dienstag
+
Paprika-Linsen-Eintopf
+
+ Tauschen +
+
+
+
Mittwoch
+
Tofu-Curry mit Reis
+
+ Tauschen +
+
+ + +
+
Gesamt-Score
+
+ 5.8 + / 10 · Verbesserbar +
+
+
+
+ Aufschlüsselung anzeigen +
+
Quellen-Vielfalt4 / 10
+
Zutaten-Überschneidung7 / 10
+
Aufwandsbalance8 / 10
+
+
+
+
+ +
+
+
📅
Plan
+
🛒
Einkauf
+
🍳
Rezepte
+
📊
Analyse
+
+
+
+ + +
+
Desktop · 1040px
+
+
+ +
+
Planung
+
📅 Wochenplan
+
🛒 Einkaufsliste
+
🍳 Rezepte
+
Haushalt
+
⚙️ Einstellungen
+
+
+
+
+ Planer / + Abwechslungs-Analyse +
+
+
+ +
+
Was zu tun ist
+ +
+
+
Quellen-Wiederholung
+
Tofu an 2 Tagen
+
+
+
+ Montag + Tofu-Gemüse-Pfanne +
+ Tauschen +
+
+
+ Mittwoch + Tofu-Curry mit Reis +
+ Tauschen +
+
+ +
+
+
Zutaten-Überschneidung
+
Paprika an 2 aufeinanderfolgenden Tagen
+
+
+
+ Dienstag + Paprika-Linsen-Eintopf +
+ Tauschen +
+
+
+ Mittwoch + Tofu-Curry mit Reis +
+ Tauschen +
+
+
+ + +
+
+
Score
+
+ 5.8 + / 10 +
+
Verbesserbar
+
+
+
+
Aufschlüsselung
+
Quellen4 / 10
+
Zutaten7 / 10
+
Aufwand8 / 10
+
+
+
+
+
+
+
+
+ +
+
Design-Notizen V3
+
    +
  • Klarer Fokus: Das erste, was der Planer sieht, ist "Was zu tun ist" — keine Score-Hierarchie die von der Aktion ablenkt.
  • +
  • Prominente "Tauschen"-Buttons (gefüllt, dunkelgelb) statt Links — erhöht die Tipp-Fläche auf Mobile und macht die Aktion offensichtlicher.
  • +
  • Voller Wochentag ("Montag" statt "Mo") — lesbarer, besonders auf Desktop.
  • +
  • Schwachstelle: Wenn es keine Hinweise gibt (Score ≥ 9), wirkt die Seite leer — der Score müsste dann nach oben rücken. Erfordert einen separaten Empty-State.
  • +
  • Höherer Umbauaufwand gegenüber V1 und V2 — die Page-Struktur ändert sich grundlegend.
  • +
+
+
+ +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
KriteriumV1 Erweiterte KartenV2 Aktions-Liste ★V3 Hinweise zuerst
Rezeptnamen sichtbar✓ Ja✓ Ja✓ Ja, prominent
Direkter TauschLinkLinkButton (größere Tap-Fläche)
Hinweise sichtbar ohne ScrollenNein (Score + Breakdown zuerst)Ja (direkt unter kompaktem Score)Ja (ganz oben)
UmbauaufwandNiedrigMittelHoch
Layout-ÄnderungKeineScore kompakter, Details kollabierbarGrundlegende Umstrukturierung
EmpfehlungWenn schnelle Lieferung PrioEmpfohlen ★Wenn Aktions-Fokus Prio
+
+ +
+ +