Produktkarte statt direkt unter dem Banner
Auf den anderen Seitentypen (Kategorie, Sale) stand die Zahl schon immer direkt
über dem Produkt-Grid. Auf den Unterkategorie-Seiten (Charakter-Familien wie
Glasperlenarmbänder, Kuh, Wal, ...) saß sie dagegen in einem eigenen Container
direkt unter dem Banner-Bild, mit teils viel Abstand zur ersten echten Karte
(z.B. wenn vorher noch eine Charakter-Story-Box kommt). Jetzt wird sie direkt
in der Sektion angezeigt, die auch wirklich die erste Produktkarte enthält —
in allen 4 Sprachen (de/en/fr/ch).
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Auf den drei anderen Seitentypen (Kategorie, Sale) stand die Anzahl bereits korrekt unter dem
Banner — nur auf den Unterkategorie-Seiten (z.B. /shop/modeschmuck-accessoires/
glasperlenarmbaender/) landete sie versehentlich VOR dem Bannerbild, direkt nach der Breadcrumb.
Jetzt hinter das Banner verschoben, in allen 4 Sprachen.
Bisher zeigte nur /shop/ (die Hauptübersicht) an, wie viele Produkte gerade zu sehen sind. Auf
ausdrücklichen Wunsch jetzt auch auf: Kategorie-Seiten, Unterkategorie-Seiten (Gesamtzahl aus
Charakter-Karten + "weitere Modelle", ohne reine Platzhalterkarten) und der Sale-Seite — jeweils
in allen 4 Sprachen. Server-seitig fest berechnet (kein Filter-JS wie im Haupt-Shop nötig, da
diese Seiten keine Live-Filterung haben), gleiche Optik/Wortlaut wie im Shop-Filter
(t.shop.resultCount), neue gemeinsame CSS-Klasse .result-count-static für den Abstand vor dem
Grid. Nur sichtbar, wenn tatsächlich Produkte da sind (bei leeren Kategorien bleibt der bisherige
Hinweistext ohne zusätzliche "0 Produkte"-Zeile).
Per Build + Browsertest über alle drei Seitentypen verifiziert.
Neues Kästchen "🔥 Nur Bestseller (Top 6)" im Shop-Filter (alle 4 Sprachen) — zeigt beim Anhaken
genau die 6 Produkte mit den meisten echten Verkäufen. Keine manuelle Pflege nötig: neuer
öffentlicher Endpunkt GET /api/bestseller berechnet die Rangliste live per SQL-Aggregation aus
den echten Bestelldaten (order_items JOIN orders, GROUP BY Produkt-Slug, SUM der Menge), NICHT
die manuell im Admin-Bereich setzbare "Bestseller"-Auszeichnung.
Zählweise: stornierte und noch nicht bezahlte (zahlungOffen) Bestellungen zählen nicht mit (sonst
würden Fehlbestellungen/nie eingegangene Zahlungen die Rangliste verfälschen), ebenso wenig
kostenlose Positionen wie der Abo-Teddy (kein echtes Kaufinteresse). Liefert ausschließlich
Produkt-Slugs zurück, keinerlei Bestell-/Kundendaten — bleiben weiterhin nur in /api/verwaltung/*.
Verifiziert: SQL-Aggregation mit Testdaten geprüft (korrekte Rangfolge, korrekter Ausschluss von
storniert/zahlungOffen/gratis, LIMIT 6 exakt). Frontend-Verdrahtung (Checkbox -> fetch -> Filter)
per echtem Browsertest mit vorgetäuschter API-Antwort bestätigt (checken zeigt genau die
vorgegebenen Produkte, abwählen zeigt wieder alle).
Beide <script>-Blöcke am Ende von shop/index.astro (+en/ch/fr) liefen bisher direkt beim Parsen,
statt wie in Layout.astro etabliert in "astro:page-load" gekapselt zu sein. Da <ClientRouter
fallback="swap" /> Inline-Skripte bei einem clientseitigen Seitenwechsel nicht erneut ausführt,
wurden die Klick-Listener der beiden eigenen Dropdowns nie angehängt, wenn man per Link (statt
Direktaufruf) auf /shop/ navigiert ist — Preis-Regler/Checkbox blieben unbemerkt funktionsfähig,
weil das natives Browser-Verhalten ohne JS ist.
Auf ausdrücklichen Wunsch: oben auf jeder Produktseite jetzt ein "← Zurück"-Button vor dem
Breadcrumb. Nutzt den Browser-Verlauf (history.back()) statt fest zur Kategorieseite zu
springen — landet man z.B. von der Startseite, einer Suche oder "Das könnte dir gefallen" auf
einer Produktseite, kommt man genau dahin zurück. Fällt sauber auf einen normalen Link zur
Kategorieseite zurück, wenn kein echter vorheriger Seitenaufruf im Verlauf existiert (Direkt-
aufruf, neuer Tab, Suchmaschine). In allen 4 Sprachversionen (de/en/ch/fr) umgesetzt.
Nebenbei behoben: t.common.skipToContent (Skip-Link aus der BFSG-Barrierefreiheits-Arbeit vom
04.08.) war nur für "de" gepflegt und dadurch auf den en/ch/fr-Seiten leer — jetzt für alle
4 Sprachen ergänzt (gleicher Commit, da hier ohnehin dieselbe common-Sektion bearbeitet wurde).
Lokal mit wrangler pages dev end-to-end getestet (Login, echtes Produkt, Button + Skript im
gerenderten HTML bestätigt).
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Auf ausdrücklichen Wunsch: statt der vagen Ersatzformulierung "Teddy aus einer früheren
Einlösung" zeigt die Liste "Diese Teddys hast du schon bekommen" jetzt fuer JEDEN Eintrag
den echten Produktnamen + eine kleine Vorschau — auch fuer Einloesungen von vor diesem
Feature, bei denen kein Name gespeichert war. Das geht zuverlaessig, weil es je Groesse
aktuell nur EIN konfiguriertes Teddy-Produkt gibt (aboEinstellungen.kleinTeddySlug/
grossTeddySlug) — es gibt also keine Mehrdeutigkeit, welcher Teddy es war.
Mini-Foto: echtes Produktfoto, sobald VanVan eins im Adminbereich hochlaedt (automatisch,
ohne Code-Aenderung) — bis dahin ein gestalteter Platzhalter statt eines kaputten Bildes,
da beide Teddy-Produkte aktuell noch kein Foto hinterlegt haben.
Dabei einen echten Datenfehler gefunden und behoben: der KLEINE Teddy trug auf Englisch
"Large Teddy" und auf Schweizerdeutsch "Grosse Teddy" (Kopierfehler vom grossen Teddy) —
war nicht nur in dieser Liste sichtbar, sondern auch auf der Produktseite selbst in allen
nicht-deutschen Sprachen. Jetzt korrekt "Small Teddy" / "Chliine Teddy" / "Petit ours en peluche".
Getestet (Browser): genau der Fall aus der Rückmeldung nachgestellt (2 alte Einlösungen ohne
Namensverlauf) — zeigt jetzt Name + Link statt "unbekannt". Gemischter Fall (echter + alter
Eintrag) korrekt sortiert. Vorhandenes Foto ersetzt den Platzhalter automatisch. Korrigierte
Produktnamen in allen 4 Sprachen bestätigt.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Auf ausdrücklichen Wunsch: die PayPal-Zahlungsoption ist jetzt eine "besondere" Kachel statt
der schlichten Icon-Zeile — exakt in der Mitte horizontal geteilt, obere Hälfte PayPal-
Markenverlauf mit Logo + zweifarbiger Wortmarke, untere Hälfte die Visa-/Mastercard-Hinweise.
Animierter Verlaufsrand, leuchtender Mittelsteg, Glanzeffekt und Glitzer-Akzente — dieselbe
Formsprache wie die anderen "besonderen" Karten der Seite (z.B. .account-head). Alle 4 Sprachen.
Feste Höhe (statt min-height) auf der Kachel, damit die Trennlinie IMMER exakt mittig sitzt,
unabhängig vom Inhalt jeder Hälfte — mit auto-Höhe hätte der Flex-Container sich sonst am
längeren Inhalt orientiert und die Linie wäre verrutscht (nachgemessen: vorher 106,6px oben vs.
141px unten, jetzt 109px/109px exakt).
Dabei zwei echte Bugs gefunden und behoben:
1. Eine generische Farb-Regel (".pay-card:has(input:checked) .pay-option span:not(.pay-icon)")
hätte die neue zweifarbige Wortmarke und den Kartenhinweis auf die einfarbige Markenfarbe
umgefärbt und auf dem blauen Verlaufshintergrund fast unlesbar gemacht — mit gezielt
spezifischeren Regeln überschrieben.
2. Die Radio-Markierung überlappte bei bestimmten Fensterbreiten (ca. 800–1000px) die
Mastercard-Karte, weil zwei VERSCHACHTELTE Zweispalten-Layouts (.checkout-layout und
.checkout-split) bei ZU ÄHNLICHEN Umbruchpunkten (800px bzw. 760px) gleichzeitig aktiv
blieben und die Zahlungsspalte auf ca. 90px zusammenquetschten — ein vorbestehender
Layout-Fehler, der die ganze Zahlungsspalte betraf, nicht nur die neue Kachel. Behoben,
indem die innere Spalte jetzt deutlich früher umbricht (1024px statt 760px), lange bevor
die äußere Spalte eng wird.
Getestet (Browser, alle 4 Sprachen): Kontrastprüfung im markierten Zustand, Geometrie der
Trennlinie, Breiten-Sweep von 390px bis 1600px ohne Überlappung mehr, Mobil-Ansicht.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Auf ausdrücklichen Wunsch: der Knopf war bisher unter allen aktuellen Bestellungen platziert.
Jetzt steht er direkt unter der Überschrift "Meine Bestellungen", noch vor der neuesten
Bestellung — beim Aufklappen erscheinen Suchfeld und ältere Bestellungen also ganz oben,
noch vor der aktuellen Liste. Alle 4 Sprachen.
Rein eine Markup-Verschiebung (das <div class="order-archive"> wandert vor <div id="order-list">
im DOM) — die JavaScript-Logik, die ältere Karten per appendChild() in den Aufklappbereich
verschiebt, funktioniert unabhängig von der Position weiter, da sie über getElementById auf
beide Container zugreift. CSS entsprechend angepasst: margin-top wurde zu margin-bottom, weil
der Abstand jetzt VOR der ersten Bestellkarte gebraucht wird statt danach.
Getestet (Browser): DOM-Reihenfolge in allen 4 Sprachen bestätigt (order-archive vor
order-list), Auf-/Zuklappen weiterhin funktionsfähig, Karten wandern korrekt in den
Archiv-Bereich und wieder zurück, Sichtprüfung per Screenshot.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Statt "Bereits erhalten: 1x kleiner Teddy, 1x grosser Teddy" steht im Abo-Bereich jetzt eine
Liste mit dem tatsaechlichen Teddy-Namen, dem Einloesedatum und einem Link zum Produkt —
damit Kundinnen sehen, welchen Teddy sie schon besitzen, und keinen doppelt waehlen.
Dafuer haelt das Konto beim Einloesen fest, WELCHER Teddy vergeben wurde (neues Feld
abo.erhalteneTeddys mit Slug, Name und Datum). Bewusst als Verlauf gespeichert statt aus der
aktuellen Abo-Einstellung abgeleitet: VanVan kann die hinterlegten Teddy-Produkte jederzeit im
Adminbereich austauschen — eine nachtraeglich berechnete Liste wuerde dann einen Teddy
anzeigen, den die Kundin nie bekommen hat. Die Anzeige nimmt den aktuellen, uebersetzten
Produktnamen und faellt auf den gespeicherten Namen zurueck, falls das Produkt spaeter
umbenannt oder entfernt wird.
Nebenbei behoben: Beim Einloesen wanderte der Teddy in den Warenkorb, BEVOR geprueft wurde, ob
ueberhaupt eine Praemie offen ist. Bei einem zweiten Klick landete er dadurch erneut gratis im
Warenkorb, ohne im Konto gezaehlt zu werden. Jetzt wird zuerst geprueft.
Ausserdem sichert getAccount() nun auch die Listenfelder gegen kaputte Speicherwerte ab.
Getestet (Browser): Leerzustand, Einloesen beider Arten, Speicherung im Konto, zweiter Klick
ohne offene Praemie, Altkonto ohne Namensliste (ehrlicher Ersatztext) und entferntes Produkt
(gespeicherter Name greift). Beschriftungen in allen 4 Sprachen geprueft.
Co-Authored-By: Claude Opus 5 <[email protected]>
Im Kundenbereich stehen jetzt nur noch Bestellungen aus dem letzten Monat direkt in der Liste.
Aeltere werden gebuendelt hinter einem kleinen Knopf "Aeltere Bestellungen (N)" gezeigt und
lassen sich dort nach Bestellnummer, Artikel oder Datum durchsuchen. Alle 4 Sprachen.
Die Monatsgrenze wird bewusst ERST IM BROWSER berechnet (echte Kalendermonate, nicht "30 Tage"):
Die Seite ist statisch vorgebaut, eine schon beim Bauen gezogene Grenze waere ab dem naechsten
Tag falsch. Bestelldatum steht dafuer jetzt als ISO-Datum in den Daten, die Anzeige wird daraus
abgeleitet — nur noch eine Quelle fuers Datum.
Nebenbei gefunden und behoben: getAccount() hat gespeicherte Kontodaten reind flach mit den
Standardwerten zusammengefuehrt. Stand im Speicher ein kaputtes/fehlendes abo-Objekt (null),
hat das den Standardwert ueberschrieben und jeder Zugriff wie a.abo.bezahltBisDatum warf einen
Fehler, der das GESAMTE Konto-Dashboard lahmgelegt hat (keine Bestellungen, keine Tabs mehr).
Das verschachtelte abo-Objekt wird jetzt ausdruecklich mit Standardwerten aufgefuellt.
Getestet (Browser, alle Faelle): Aufteilung nach Datum, Auf-/Zuklappen, Suche nach Artikel und
nach Bestellnummer, Suche ohne Treffer, Zusammenspiel mit den Tabs "Offene Sendungen"/
"Bestellungen", sowie Markup und Uebersetzungen in allen 4 Sprachen.
Co-Authored-By: Claude Opus 5 <[email protected]>
Kundenkonten sind jetzt genauso echt wie die PayPal-Zahlung: server-geprüftes OAuth 2.0 mit
PKCE für Google und "Log in with PayPal" (functions/_shared/oauth.js, oauth-handlers.js),
neue D1-Tabelle "customers" (bewusst ohne Passwort-Feld), eigene von der Zugangscode-Schranke
getrennte Sitzungs-Logik (customer-auth.js). Echte DSGVO-Rechte direkt im Kontobereich:
Daten herunterladen (Art. 15/20) und Konto unwiderruflich löschen (Art. 17), Bestellungen
bleiben aus gesetzlichen Gründen erhalten. Datenschutzerklärung entsprechend ergänzt.
Ohne echte Google-/PayPal-Zugangsdaten zeigt der Login-Button ehrlich einen
"noch nicht eingerichtet"-Hinweis statt eine Anmeldung vorzutäuschen.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Auf ausdrücklichen Wunsch, mit Fokus auf rechtliche Absicherung:
- Klarna komplett entfernt (hätte eigene Händlerprüfung + Bonitätsprüfungs-
Pflichten nach der neuen EU-Verbraucherkreditrichtlinie vorausgesetzt).
- Eigene Kreditkarten-Eingabemaske komplett entfernt (wäre PCI-DSS-pflichtig
gewesen — für einen kleinen Shop praktisch nicht stemmbar). Kartenzahlung
bleibt möglich: PayPals eigener, PCI-zertifizierter Gast-Checkout bietet
Kredit-/Debitkarte an, ohne dass Kartendaten je unsere Seite berühren.
- PayPal ist jetzt ECHT server-seitig verifiziert statt dem Browser blind zu
vertrauen: eigener Cloudflare-Function-Flow (functions/_shared/paypal.js +
functions/api/paypal/) legt die PayPal-Bestellung server-seitig an, zieht
die Zahlung nach Bestätigung server-seitig ein und prüft den eingezogenen
Betrag gegen die Bestellsumme — die Bestellung wird ausschließlich bei
bestätigter, betragsgleicher Zahlung angelegt. /api/orders lehnt direkte
PayPal-Bestellungen jetzt ausdrücklich ab (verhindert vorgetäuschte
"bezahlte" Bestellungen ohne echte Zahlung).
- Neuer, ehrlicherer Bestellstatus "zahlungOffen": Überweisungs-Bestellungen
starten jetzt so (Geld noch nicht da) statt fälschlich sofort "bezahlt" zu
heißen — Schutz vor Warenversand, bevor das Geld wirklich angekommen ist.
Eigene Kachel/Filter/Badge-Farbe in der Verwaltung, Umsatz-/Auswertungs-
Zahlen zählen "zahlungOffen" bewusst nicht mit.
- Rechtstexte (AGB, Datenschutzerklärung, FAQ, Versand & Zahlung) auf allen
4 Sprachen aktualisiert: nur noch PayPal + Überweisung erwähnt, inkl. DSGVO-
Hinweis zur internationalen Datenübertragung an PayPal (Data Privacy
Framework-Zertifizierung).
- D1-Migration 0003: neue Spalte paypal_order_id (Zahlungsbeleg) + erweiterter
Status-Wertebereich, auf Live-Datenbank angewendet, bestehende Daten intakt.
Mit echten Testbestellungen lokal verifiziert: Überweisung legt korrekt
"zahlungOffen" an, direkter PayPal-Bypass-Versuch an /api/orders wird
abgelehnt, PayPal-Route meldet sauber "noch nicht eingerichtet" ohne
Zugangsdaten. Checkout-UI zeigt nur noch 2 Zahlungsarten, Bestellknopf ist bei
PayPal ausgeblendet (Zahlung läuft exklusiv über den echten PayPal-Button).
Für den echten Zahlungseingang fehlt noch VanVans eigenes PayPal-Business-
Konto (Client-ID + Secret) — Details in der Vault-Dokumentation.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Auf ausdrücklichen Wunsch: "Mit Apple anmelden" raus aus allen 4 Sprachversionen
der Kontoseite (Buttons, Übersetzungsstrings, Kommentare). Bleiben: Google +
PayPal, beide ohne laufende Kosten nutzbar — anders als Apple, das zwingend das
kostenpflichtige Apple Developer Program (99 $/Jahr) fürs Web-Login voraussetzt.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
1) Gutscheincodes können jetzt im Adminbereich auf "nur einmal pro Person einlösbar"
gestellt werden. Wird serverseitig durchgesetzt (neue Spalte orders.gutschein_code +
Prüfung in functions/api/orders.js gegen die echte Bestelldatenbank, case-insensitiv
nach E-Mail-Adresse) — kann also NICHT durch Löschen von localStorage/einen anderen
Browser umgangen werden, anders als die bisherige rein clientseitige Rabattlogik.
Stornierte Bestellungen zählen nicht als "schon benutzt". Ausführlich getestet: echter
Browser-Checkout mit Einmal-Code funktioniert beim ersten Versuch, wird beim zweiten
Versuch (gleiche E-Mail) korrekt mit klarer Fehlermeldung abgelehnt, mit anderer E-Mail
weiterhin nutzbar.
2) Bestell-E-Mail-Benachrichtigung an [email protected]: recherchiert und
vorbereitet (existierte vorher nirgends im Code). Läuft über Resend (kostenlos bis
3.000 E-Mails/Monat), im Hintergrund per context.waitUntil() nach jeder neuen
Bestellung — verzögert nie die Antwort an die Kundschaft und kann eine Bestellung
niemals zum Scheitern bringen, selbst wenn der Versand fehlschlägt (mit ungültigem
Testschlüssel verifiziert: Bestellung bleibt trotzdem erfolgreich gespeichert). Wird
automatisch aktiv, sobald ein RESEND_API_KEY als Secret hinterlegt wird.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
1) Versandkostenfreigrenze ist jetzt länderabhängig statt einer einzigen Zahl für alle:
Deutschland 75 €, Österreich/Luxemburg 85 €, Schweiz 100 € (im Adminbereich unter
"Versandkosten-Staffel" änderbar). Betrifft Warenkorb (live je nach gewähltem Land),
Checkout-Berechnung, sowie alle Text-Hinweise (Topbar, FAQ, AGB) in allen 4 Sprachen.
2) Neues Feld "USt-IdNr." im Impressum (optional, admin-editierbar) — erscheint nur, wenn
ausgefüllt.
3) Impressum, AGB, Datenschutzerklärung, Widerrufsbelehrung und FAQ sind jetzt vollständig
im Adminbereich editierbar (neue Collection "⚖️ Rechtstexte & FAQ") statt fest im Code zu
stehen. Jede Rechtsseite besteht aus frei bearbeitbaren Abschnitten (Überschrift + Text) —
VanVan kann selbst Abschnitte ergänzen, ändern oder löschen. Freitext wird beim Anzeigen
sicher escaped (kein kaputtes HTML durch Tippfehler möglich) und nackte Links automatisch
klickbar gemacht. FAQ bleibt dabei weiterhin in allen 4 Sprachen separat pflegbar.
Ausführlich getestet: Freigrenze pro Land im echten Warenkorb verifiziert (Puppeteer,
84€ Warenwert -> DE kostenlos, AT/LU "noch 1€", CH "noch 16€"), Rechtstexte/FAQ/USt-ID
gegen den fertigen Build geprüft, EU-Streitschlichtung-Link-Bug (Satzzeichen wurde
mitverlinkt) gefunden und behoben.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Ersetzt die Phase-1-Beispieldaten in /verwaltung/ durch ein echtes, funktionierendes
Bestellsystem:
- Neue D1-Datenbank (vans-diy-bastelbedarf-db) mit orders/order_items-Tabellen,
an das Pages-Projekt gebunden (wrangler.toml).
- Neue API-Routen (Pages Functions): POST /api/orders legt beim Checkout eine echte
Bestellung an (mit Validierung); GET/PATCH /api/verwaltung/orders(/:id) listen bzw.
ändern Bestellungen — beide zusätzlich zur Middleware nochmal eigenständig gegen die
Zugangscode-Sitzung geprüft (Verteidigung in der Tiefe). Gemeinsame Auth-Logik aus
_middleware.js nach functions/_shared/auth.js ausgelagert.
- Checkout (4 Sprachen) sendet beim Absenden die echte Bestellung an die API, zeigt bei
einem Fehler eine klare Meldung statt einfach auf die Danke-Seite weiterzuleiten.
- /verwaltung/ lädt Bestellungen jetzt live per fetch(), mit Lade-/Fehlerzustand, und
erlaubt direktes Ändern des Bestellstatus per Dropdown (sofort in der Datenbank
gespeichert). Neuer Status "storniert" (zählt nicht in Umsatz/Auswertung mit).
Vollständig lokal end-to-end getestet (wrangler pages dev + lokale D1): echter
Browser-Checkout -> Bestellung landet in der Datenbank -> erscheint sofort in der
Verwaltung -> Status ändern bleibt nach Neuladen bestehen.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Die Treuebonus-Karte im Konto zeigte bisher nur einen nackten Fortschrittsbalken
mit einem Satz Text. Jetzt: (1) zehn Meilenstein-Striche direkt im Balken plus
Geschenk-Symbol am Ziel, (2) vier Kennzahl-Kacheln im gleichen Stil wie beim Abo-
Status (Gesammelt, Noch nötig, Bonus bei Ziel, Bisher eingelöst), (3) ein neues
Datenfeld "wie oft insgesamt schon eingelöst + wann zuletzt" (account.ts), das in
einer eigenen, gold→grün abgewandelten "Bonus bereit"-Karte mit Glow-Effekt landet
statt eines einfachen Links, (4) eine kurze Icon-Liste mit den Sammelregeln statt
einem einzelnen Erklärsatz. Alles in 4 Sprachen, mit echten Vorschau-Zuständen
(Fortschritt/bereit/gesperrt) per Screenshot verifiziert.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Treuebonus-Kiste im Konto-Dashboard bekam bisher das normale kleine ✨ wie
Bestellungen/Sendungen/Wunschliste. Jetzt nutzt sie denselben großen, kräftig
pulsierenden 🌟-Stern wie die Abo-Kiste (4 Sprachen). Die CSS-Regel dafür gilt
jetzt für beide Kisten gemeinsam und färbt den Glanz automatisch in der jeweils
eigenen --nav-color ein (Abo = Gold, Treuebonus = Grün) statt eines fest codierten
Goldtons — Stil bleibt identisch, nur die Farbe unterscheidet die beiden klar.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Die kleinen ✨-Sternchen oben rechts in den Kontobereich-Kacheln waren
bisher überall neutral-gelb, unabhängig von der Kistenfarbe. Jetzt bekommt
jedes Funkeln einen farbigen Schein passend zur eigenen Akzentfarbe der
Kiste (Lila/Teal/Pink/Grün/Gold).
Das Abo-Funkeln sticht zusätzlich klar heraus: eigener goldener Stern (🌟
statt ✨), größer, kräftiger und schneller leuchtend — soll dem Premium-
Charakter des Abos gerecht werden und auf den ersten Blick auffallen.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Plan-Karten: eigenes Icon je Stufe (🌱/🌿/👑), Rabatt als farbiger Chip statt
reinem Fließtext, Prämien-Intervalle als eigene Chips (aus den admin-
konfigurierten Werten berechnet), Preis mit Farbverlauf, sanft pulsierender
Rahmen für die aktuell gebuchte Stufe.
Abo-Status: Tabelle durch ein Stat-Kachel-Raster ersetzt (Icon + Label + Wert
pro Kennzahl, Rabatt farblich hervorgehoben), echte Fortschrittsbalken statt
Text für den Weg zum nächsten Teddy (Prozent aus dem admin-konfigurierten
Intervall berechnet), "Bereits erhalten" als Badge-Chip, verfügbare Prämien
als eigene, leicht glühende Karten statt schlichter Buttons.
Benachrichtigungen: farbiger Icon-Kreis pro Ereignistyp (Erfolg/Prämie/
Warnung/Abbruch/Info) statt einheitlicher grauer Liste — auf einen Blick
erkennbar, worum es bei jedem Eintrag geht.
Alles in 4 Sprachen (DE/EN/CH/FR), neues i18n-Template aboRewardEveryLabel
für die Prämien-Intervall-Chips.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Der Treuebonus (10 Bestellungen → 20% Rabatt) sammelt jetzt nur noch, solange
ein aktives, bezahltes Abo besteht — ohne Abo bleibt der Fortschritt einfach
stehen, statt weiterzuzählen (account.ts: registriereAbgeschlosseneBestellung()).
Ebenso greift ein bereits freigeschalteter Rabatt im Warenkorb/Checkout nur,
solange das Abo aktiv ist (cart.ts: treuebonusDiscount()).
Im Kundenkonto wird die Treuebonus-Karte ohne aktives Abo nicht einfach
ausgeblendet, sondern zeigt bewusst einen einladenden gesperrten Zustand
("🔒 Nur mit aktivem Abo verfügbar" + Button "Zum Abo →") statt der üblichen
Fortschrittsanzeige — soll als klarer Anreiz fürs Abo wirken, nicht als totes
Feature. Dieselbe Sperre greift auch im Warenkorb: das Auswahl-Radio/Badge für
den Treuebonus-Artikel erscheint nur noch bei tatsächlich aktivem Abo, damit
nie ein Rabatt suggeriert wird, der beim Checkout dann doch nicht greift.
Alles in 4 Sprachen (DE/EN/CH/FR).
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Der "Mein Abo verwalten"-Button in der Kopfkarte fällt wieder weg — der
Zugriff aufs Abo läuft ab jetzt nur noch über die eigene "Mein Abo"-Nav-
Kachel. Stattdessen wandert "Meine Daten" aus der Schnellnavigation direkt
in die Kopfkarte: ein neuer, gleich premium gestylter Button (Teal/Lila statt
Gold, gleiches wanderndes Glanzlicht) unten rechts in der Karte, der zum
Profil-Bereich springt.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Bisher waren nur Preis, Rabatt-% und ein paar Verhaltensregeln im CMS
editierbar — Namen, Vorteilstexte und die Teddy-Vergabe-Intervalle steckten
fest im Code. Jetzt ist pro Abo-Stufe (Klein/Mittel/Groß) direkt im
Adminbereich einstellbar:
- Name & Vorteilstext der Stufe, in allen 4 Sprachen einzeln
- Ob die Stufe aktuell überhaupt neu buchbar ist (bestehende Abonnent:innen
behalten ihre Vorteile trotzdem, im Kundenkonto wird die Stufe nur für neue
Buchungen ausgegraut mit "Derzeit nicht buchbar")
- Nach wie vielen Monaten es den kleinen/großen Teddy gibt (ersetzt die vorher
fest verankerten 6-/12-Monats-Abstände)
- Welches Produkt als "kleiner"/"großer" Teddy für die Prämien-Einlösung
verwendet wird (Produktauswahl statt festem Slug im Code)
Alle Berechnungen (Meilensteine, Fortschrittsanzeige) laufen jetzt komplett
über diese Admin-Werte statt über Konstanten im Code. Konto-Plan-Karten in
allen 4 Sprachen zeigen die admin-gepflegten Texte live an.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Drei Mitgliedschaftsstufen (Klein 4,99€/5%, Mittel 9,99€/10%, Groß 19,99€/20%)
mit automatischem Bestellrabatt und Teddy-Prämien nach Meilensteinen (12-Monats-
Rhythmus bzw. 6+12 bei Groß). Preise/Rabatte und alle Admin-Regeln (Kombinier-
barkeit mit anderen Rabatten, Fortsetzung bei Wiederanmeldung, Monate über
Stufen zusammenzählen, kostenloser Versand bei Prämie) sind über Decap CMS
einstellbar (src/content/abo-einstellungen.json).
Neuer "Mein Abo"-Bereich im Kundenkonto (6. Nav-Kachel) mit Plan-Vergleich,
Live-Status (Laufzeit, nächste Zahlung, Rabatt, Fortschritt bis zur nächsten
Prämie), Einlösen-Buttons für freigeschaltete Teddys, Kündigen/Wechseln sowie
einer übersetzten Benachrichtigungsliste. Dazu ein extra hervorgehobener
"Mein Abo verwalten"-Button neben Abmelden in der Kopfkarte.
Warenkorb/Checkout rechnen den Abo-Rabatt korrekt in die Summe ein und stellen
eingelöste Teddys als 0€-Gratisposition dar. Alles in 4 Sprachen (DE/EN/CH/FR).
Unterwegs zwei echte Bugs gefunden und behoben: addMonateISO() vermischte
lokale Zeit mit toISOString() (UTC) und verlor dadurch bei jeder Monats-
verlängerung reproduzierbar einen Tag; die Checkout-Positionsliste zeigte für
Gratis-Prämien fälschlich den vollen Preis statt 0€.
Wie beim Treuebonus gilt: Speicherung aktuell im localStorage des Geräts
(Phase 1) statt einer echten geräteübergreifenden Datenbank — folgt mit der
Zahlungsanbindung in Phase 2.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Neue eigene Kiste "Treuebonus" im Kundenkonto (5. Nav-Tab, grüner Akzent)
zeigt den Fortschritt ("X von 10 Bestellungen") mit Fortschrittsbalken und
Restanzahl-Hinweis, nach Freischaltung eine Erfolgsmeldung mit Link zum
Warenkorb. Es zählen ausschließlich erfolgreich abgeschickte, bezahlte
Bestellungen (in Phase 1: jede erfolgreich abgeschlossene Demo-Bestellung
im Checkout) — abgebrochene Bestellungen zählen nie mit.
Sobald der Bonus aktiv ist, erscheint im Warenkorb ein Hinweis-Banner und
bei jedem Artikel eine Auswahl ("Für 20% Treuebonus auswählen") — es kann
immer nur EIN Artikel gewählt werden (Radiobutton-Verhalten über alle
Positionen hinweg). Der Rabatt fließt automatisch in Warenkorb- und
Checkout-Summe ein (neue treuebonusDiscount()-Funktion in scripts/cart.ts,
in totalDiscount() eingerechnet). Nach erfolgreichem Bestellabschluss wird
die Belohnung als eingelöst markiert und der Fortschrittszähler beginnt
wieder bei 0 — beides dauerhaft im Konto (localStorage, Phase 1) gespeichert
und eindeutig diesem Kundenkonto zugeordnet.
Neue Funktionen in scripts/account.ts: registriereAbgeschlosseneBestellung(),
setTreuebonusArtikel(), treuebonusEinloesen(), treueFortschritt(). Beide
Zustandsübergänge (Fortschritt zählen vs. Belohnung einlösen) end-to-end
über den echten Checkout-Ablauf getestet und verifiziert.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Neuer Button lädt die Rechnung als echte PDF-Datei herunter — komplett
clientseitig mit jsPDF + jspdf-autotable (beide MIT-lizenziert, per
dynamic import erst beim Klick nachgeladen, kein Einfluss auf die normale
Seitenladezeit). Zeigt exakt dieselben Daten wie der "Rechnung ansehen"-
Dialog (Rechnungsnummer/-datum, Verkäufer, Empfänger, Artikeltabelle,
Gesamtbetrag, §19-UStG-Hinweis), sauber formatiert mit Kopfzeile, zwei
Spalten für Verkäufer/Empfänger und einer echten Tabelle. Datei heißt
"Rechnung-<Bestellnummer>.pdf". Mit Node-Testskript verifiziert, dass die
PDF-Erzeugung fehlerfrei ein valides PDF mit korrekten Umlauten liefert.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Größeres Profilbild in der "Mein Konto"-Karte. Alle vier Navigations-
Knöpfe (Bestellungen/Offene Sendungen/Wunschliste/Meine Daten) haben jetzt
denselben besonderen Stil wie vorher nur "Meine Daten": wanderndes Verlaufs-
licht in der eigenen Akzentfarbe, pulsierender Glanzrand, funkelndes
Sternchen und Farbverlauf-Text — nur die Farbe unterscheidet sich pro
Knopf. Der "Meine Daten"-Inhaltsbereich (Profilkarte) bekommt dieselbe
"mega besondere" Behandlung wie die Begrüßungs-Karte (wandernder Verlaufs-
rand, Farbschein, Glanz-Sweep, Sternchen). Bestellkarten bekommen einen
passenden dezenten Glanz-Sweep und pulsierenden Schein in ihrer Status-
farbe für ein stimmigeres Gesamtbild.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Die Zahl im "Bestellungen"-Kasten zeigte bisher alle Bestellungen, obwohl
der Tab selbst nur die angekommenen anzeigt. Jetzt stimmen Zahl und Liste
überein. "Offene Sendungen" zählt entsprechend alles, was noch nicht
abgeschlossen ist (nicht nur "versendet"), passend zum Tab-Filter.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Der bisherige "Rechnung (PDF)"-Knopf war ein toter Link (href="#"). Jetzt
öffnet "Rechnung ansehen" pro Bestellung ein natives Dialog-Fenster direkt
auf der Seite mit vollständiger Rechnung: Rechnungsnummer/-datum,
Verkäufer, Rechnungsempfänger (live mit dem aktuellen Kontonamen befüllt),
Artikeltabelle mit Einzel-/Gesamtpreisen und dem §19-UStG-Hinweis — kein
Herunterladen nötig, schließbar per Kreuz, Schließen-Knopf oder Klick auf
den abgedunkelten Hintergrund.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Wandernder Mehrfarb-Verlaufsrand, sanfter Farbschein im Hintergrund, ein
Glanz-Sweep, der regelmäßig durchläuft, ein pulsierender Leucht-Ring um
den Avatar und zwei funkelnde ✨-Sternchen — dieselbe Formsprache wie beim
"Meine Daten"-Knopf, nur größer und ruhiger für gute Lesbarkeit.
Respektiert prefers-reduced-motion.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Bisher zeigte der Bestellungen-Tab ALLE Bestellungen (Überschneidung mit
"Offene Sendungen"). Jetzt ist es eine echte Trennung: "Bestellungen"
zeigt nur bereits angekommene/abgeschlossene, "Offene Sendungen" nur die
noch nicht angekommenen. Eigene Leermeldung, falls noch keine Bestellung
angekommen ist.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Der echte Name war bisher versehentlich ebenfalls editierbar. Jetzt steht
er als reine Anzeige in derselben Tabelle wie E-Mail und Lieferadresse —
änderbar bleibt ausschließlich der optionale Benutzername (Spitzname).
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Sanft wanderndes Mehrfarb-Verlaufslicht im Hintergrund, pulsierender
Glanzrand, funkelndes ✨-Sternchen und ein Farbverlauf-Text — hebt sich
jetzt deutlich von den anderen drei Knöpfen ab, ohne kitschig zu wirken.
Respektiert prefers-reduced-motion.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Bisher war "Bestellungen" beim Öffnen der Seite automatisch aktiv. Jetzt
ist standardmäßig KEIN Knopf gedrückt — man muss selbst auswählen, was man
sehen möchte. Solange nichts angeklickt ist, steht direkt "Zuletzt
angesehen" da. "Meine Daten" ist jetzt ein vierter, gleichwertiger Tab-
Knopf (👤, goldener Akzent) statt permanent sichtbar — genau wie
Bestellungen/Wunschliste/Offene Sendungen erscheint das Profilformular
erst nach Klick.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Die Schnellnav-Leiste sprang bisher nur zum Abschnitt (der Rest blieb
sichtbar). Jetzt sind es echte Filter-Tabs: Klick auf "Bestellungen" /
"Wunschliste" / "Offene Sendungen" blendet alle anderen Bereiche komplett
aus und zeigt nur den ausgewählten. "Offene Sendungen" filtert zusätzlich
innerhalb der Bestellungen auf noch nicht abgeschlossene. Der aktive Tab
bleibt farbig hinterlegt und unterstrichen erkennbar. Start-Ansicht:
Bestellungen-Tab aktiv.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Die drei losen "Bestellungen/Wunschliste/Offene Sendungen"-Kästchen waren
nur Zahlen ohne Verbindung zu den Abschnitten weiter unten. Jetzt sind sie
eine zusammenhängende Leiste direkt über "Meine Bestellungen" — jedes
Segment ist ein echter Sprunglink zum passenden Abschnitt (📦 Bestellungen,
🩵 Wunschliste, 🚚 Offene Sendungen), mit eigener Akzentfarbe je Segment und
einem Hover-Unterstrich, der die Klickbarkeit deutlich macht.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Bisher unterschied sich der Status nur durch eine kleine, ähnlich gefärbte
Pille — auf einen Blick kaum zu erkennen. Jetzt bekommt jede Bestellkarte
einen eigenen farbigen Rand plus dezenten Farbschein passend zum Status
(Blau = versendet/unterwegs, Grün = abgeschlossen/angekommen, Gold = in
Bearbeitung/Versand wird vorbereitet, Violett = bezahlt), zusätzlich ein
Icon direkt in der Status-Pille (🚚 unterwegs, ✅ angekommen, usw.) — genau
wie schon bei den Zahlungskarten im Checkout.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Bisher gab es nur ein "Benutzername"-Feld, das überall (Begrüßung, Header,
Rezensionen) angezeigt wurde. Jetzt gibt es zwei getrennte Felder: einen
festen "Name" (Pflichtangabe, z.B. für Bestellungen) und einen optionalen
"Benutzername (Spitzname)" als Bonus, falls man lieber mit einem Spitznamen
statt dem echten Namen angezeigt werden möchte.
Überall, wo bisher nur der Benutzername angezeigt wurde (Header-Konto-Menü,
Begrüßung im Dashboard, Rezensions-Autorenname, "angemeldet als"-Hinweis),
gilt jetzt: Spitzname bevorzugt, sonst echter Name als Rückfalloption
(neue anzeigeName()-Hilfsfunktion in scripts/account.ts).
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Jede Zahlungsart-Karte hat jetzt einen deutlich sichtbaren Farbschein in
der jeweiligen Markenfarbe (auch im Ruhezustand, nicht erst bei Hover),
einen feinen Farbstreifen am oberen Rand und einen dezenten Glanz-Sweep
beim Hover — wirkt hochwertiger/"geiler", bleibt aber gedeckt genug fürs
dunkle Gesamtdesign. Kreditkarte (Visa/Mastercard) bekommt einen eigenen
Gold-Akzent statt der bisherigen, kaum sichtbaren Farbe.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Nach Recherche zu den Markenrichtlinien von PayPal, Klarna, Visa und
Mastercard: Zahlungsoptionen im Checkout zeigen jetzt echte Markenlogos in
den offiziellen Farben (PayPal- und Klarna-Icon, Visa-Wortmarke auf Weiß,
Mastercard-Kreise in Rot/Orange unverändert nebeneinander) statt grober
Buchstaben-/Emoji-Platzhalter — genau die Verwendung, die die jeweiligen
Markenrichtlinien für die Kennzeichnung akzeptierter Zahlungsarten
vorsehen. Dieselbe PayPal-Grafik jetzt auch beim Social-Login auf der
Anmeldeseite statt eines schlichten "P".
Zusätzlich: Ein Vorschau-Link auf der Anmeldeseite meldet mit einem Demo-
Konto an und führt direkt zum Kundenbereich-Dashboard — bleibt dauerhaft
erreichbar, damit VanVan und wir jederzeit sehen können, wie der Bereich
für angemeldete Kund:innen aussieht, ohne das Formular jedes Mal
auszufüllen.
Der Phase-1-Demo-Hinweis auf Checkout- und Anmeldeseite steht jetzt am
Ende der Seite statt direkt unter der Überschrift, damit zuerst der
fertige, professionelle Eindruck zählt.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Nach Recherche zu üblichen Anmelde-Standards bei deutschen Online-Shops:
Ergänzt Social-Login-Buttons für Google, Apple und PayPal (PayPal explizit
wegen seiner Marktdominanz bei Zahlungen in DE/DACH), da Social Login
Registrierung/Login deutlich beschleunigt und laut Studien die Conversion
spürbar erhöht. Die Buttons sind noch nicht funktional (kein OAuth ohne
eigenes Backend) — ein Klick zeigt stattdessen ehrlich einen Phase-2-
Hinweis, statt eine Anmeldung vorzutäuschen.
Zusätzlich: Passwort-Sichtbarkeits-Toggle (Augen-Icon, eine der
wirkungsvollsten Login-UX-Verbesserungen laut UX-Recherche), "Angemeldet
bleiben"-Checkbox, sowie ein DSGVO-konformer Hinweis mit Link zur
Datenschutzerklärung unterhalb des Formulars. Gastbestellung ("Neu hier?")
war als gleichwertige Alternative schon vorhanden und bleibt bestehen —
Gastbestellung gilt laut EDPB-Empfehlung als Standard neben der freiwilligen
Registrierung.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Beim Einbau der Kundenbewertungen in den Shop-Filter (voriger Commit) landete
ein "import" mitten in einem define:vars-Skript, das aber gar keine Module
unterstützt. Dadurch brach das komplette Filter-Skript auf allen 4 Sprachen
mit einem SyntaxError ab, sobald es geladen wurde – Kategorie-Dropdown,
Mindestbewertung-Dropdown und Sortierung reagierten dadurch gar nicht mehr
auf Klicks. Die lokal gespeicherten Kundenbewertungen werden jetzt in einem
eigenen, echten Modul-Skript direkt danach eingerechnet.
Zusätzlich: horizontaler Scrollbalken im Dropdown-Menü entfernt (nur noch
vertikal scrollbar), wie gewünscht.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Bisher musste VanVan Bewertungen manuell im CMS eintragen. Jetzt können
angemeldete Kund:innen Rezensionen direkt auf der Produktseite abgeben
(inkl. Herzen-Sternebewertung und Text). Die Durchschnittsbewertung wird
automatisch berechnet und überall live eingebunden: Produktkarten
(shop-weit), Produktdetailseite, Shop-Filter/Sortierung nach Bewertung
und die Kundenstimmen-Sektion auf der Startseite.
Neu dazu: ein Kontobereich fürs Login (Demo-Login per E-Mail), Profilfoto-
Upload, wählbarer Benutzername, und ein Header-Kontomenü, das nur bei
Anmeldung erscheint. Jede Bestellung im Konto-Dashboard hat einen
"Rezension schreiben"-Link, der direkt zur Produktseite führt und dort
per Bestellnummer verknüpft wird; im Profil ist dann sofort sichtbar,
welche Bestellungen schon bewertet wurden.
Technisch als reines Frontend/localStorage-System umgesetzt (kein Backend
in dieser Phase), analog zum bestehenden Warenkorb-Muster. Admin-CMS-Feld
für manuelle Bewertungen entfernt, da Rezensionen jetzt ausschließlich von
Kund:innen kommen (auch aus rechtlichen Gründen: keine Fake-Bewertungen).
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Im Filter "Mindestbewertung" wurden bisher schlichte 🩵-Emojis angezeigt. Grund:
das war ein natives <select>, und in der browsereigenen Auswahlliste lassen
sich weder Farbverlaeufe noch eigene Grafiken darstellen - der Browser rendert
dort nur das System-Emoji in seiner festen hellblauen Farbe.
Ersetzt durch dasselbe eigene Dropdown, das schon der Kategorie-Filter nutzt.
Dadurch erscheinen jetzt die echten HeartRating-Herzen mit dem Marken-Verlauf
von Lila (--c-purple-glow) nach Babyblau (--c-accent) - auch im geschlossenen
Knopf, sobald eine Bewertung gewaehlt ist. Der Verlauf bekam zusaetzlich einen
weichen Zwischenton, damit er im kleinen Herz-Format nicht hart umschlaegt,
sondern wirklich wie eine Mischung beider Farben wirkt.
Die Dropdown-Logik ist dabei fuer BEIDE Filter zu einem gemeinsamen Code
zusammengefasst worden (statt zweimal fast dasselbe): beide verhalten sich
identisch, oeffnen sich gegenseitig zu, schliessen bei Klick daneben und bei
Escape - nur noch eine Stelle zum Pflegen.
Im Browser funktional geprueft: 5 Optionen, oeffnet/schliesst korrekt, 10
Verlaufsherzen in der Liste, Auswahl setzt den Filterwert und uebernimmt die
Herzen in den Knopf, gegenseitiges Schliessen funktioniert. Gilt fuer alle 4
Sprachen.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
1. Neue Seite /konto/angemeldet/ (alle 4 Sprachen): zeigt, was Kund:innen nach
dem Anmelden sehen - Begruessung, Kennzahlen, Bestellhistorie mit farbigem
Bestellstatus, Sendungsverfolgung (echter DHL-Link), Rechnung/Nochmal-
bestellen, Wunschliste, "Zuletzt angesehen" und Profildaten. Klar als
Vorschau gekennzeichnet: es gibt noch kein echtes Login und keine Datenbank
(Phase 2), die Bestellungen sind Beispieldaten fuer die Gestaltung. Von der
Login-Seite aus verlinkt, damit die Ansicht ueberhaupt erreichbar ist.
2. "Ueber die Kreative": der erste Abschnitt ihrer Geschichte ("Meine Reise
begann mit einer einzigen Masche") steht jetzt direkt neben dem Foto statt
darunter. Foto bleibt beim Lesen sichtbar (sticky), die restlichen
Abschnitte folgen wie bisher darunter.
3. Kategorie-Seiten: der farbige Kreis um das Emoji bei "Hauptkategorie" ist
entfernt, das Emoji steht jetzt frei neben der Ueberschrift.
Dabei gefundener und behobener eigener Fehler: das noetige "align-items: start"
fuer das neue Nebeneinander-Layout hat im gestapelten Handy-Layout die
Grid-Zeile zu niedrig berechnet, wodurch das Foto 80px in den Text darunter
ragte (per Messung im Browser nachgewiesen, nicht nur per Screenshot geraten).
Jetzt sauber auf Bildschirme ab 901px begrenzt - Handy misst 24px Abstand.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Neue HeartRating-Komponente (Herzen statt Sterne, Lila-Babyblau-Verlauf wie
der Rest der Markenoptik) + komplettes Rezensions-System:
- Produktkarten: Bewertungszeile (Herzen + Anzahl) unter dem Titel, nur wenn
Bewertungen vorhanden sind.
- Produktseite: volle "Kundenrezensionen"-Sektion mit Durchschnitt und
einzelnen Rezensionen (Name, Herzen, Datum, Text) bzw. "Noch keine
Bewertungen"-Hinweis.
- Shop-Filter: neuer "Mindestbewertung"-Filter im Filter-Sidebar + neue
Sortierung "Beste Bewertung".
- Startseite: "Was unsere Kund:innen sagen"-Sektion mit Gesamtbewertung und
den 3 neuesten Rezensionen - erscheint automatisch, sobald die erste echte
Bewertung existiert.
- Adminbereich: neues Feld "Bewertungen" pro Produkt (Name/Herzen/Text/Datum),
mit deutlichem Hinweis, dass hier nur echte Kundenrueckmeldungen eingetragen
werden duerfen - erfundene Bewertungen sind in Deutschland/der EU gesetzlich
verboten (UWG). Deshalb bewusst OHNE Beispiel-Bewertungen im Code: alle
Bereiche starten leer und blenden sich automatisch ein, sobald VanVan die
erste echte Rezension eintraegt.
Mit temporaeren Testdaten end-to-end durchgetestet (Herzen-Darstellung,
Rezensions-Section, Filter, Startseiten-Sektion) und vor dem Commit wieder
aus den echten Produktdaten entfernt. Gilt fuer alle 4 Sprachen.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Die zwei ueberlappenden Kreise (Visa/Mastercard-Anmutung) beim
Kreditkarte-Zahlungsoption wirkten wie ein fremdes Marken-Logo statt einem
neutralen eigenen Icon. Ersetzt durch ein schlichtes SVG-Kartensymbol, im
gleichen Stil wie die anderen Zahlungsarten-Icons (PayPal/Klarna).
Co-Authored-By: Claude Sonnet 5 <[email protected]>