Commit Graph
100 Commits
Author SHA1 Message Date
DogFatherGitandClaude Opus 5 b7c333fca3 Verwaltung: Aufgabenlisten abhaken und Postfach
Schritt 3 von 4 zu den zwei Wuenschen vom 22.08.2026. Die Datenbank und
die Server-Routen standen schon; das hier ist die Seite, auf der ICH
arbeite. Was hier passiert, sieht der Kunde unmittelbar in seinem Portal
(Schritt 4).

ZWEI NEUE REITER

"Projekte" -- bisher gab es Projekte nur als Zahl neben dem Kunden
("3 Proj."), man konnte kein einzelnes oeffnen. Man denkt aber in
Projekten, nicht in Kunden. Neuer Endpunkt projekteListe liefert die
flache Liste samt Aufgabenzahlen; die einzeln nachzufragen haette bei
zwanzig Projekten einundzwanzig Anfragen bedeutet.

"Postfach" -- mit Abzeichen fuer Ungelesenes. Steht nichts an, ist das
Abzeichen GANZ weg statt eine 0 zu zeigen: Eine Null, die man taeglich
sieht, wird zu Rauschen, und irgendwann uebersieht man auch die 3.

Die Reiterumschaltung war vorher ein Ja/Nein zwischen zwei Ansichten. Mit
vier Reitern haette jede neue Ansicht eine weitere "hidden = ..."-Zeile
gebraucht -- und beim naechsten Reiter vergisst man eine, dann liegen zwei
Ansichten uebereinander. Jetzt eine Zuordnung Reiter -> Kasten, die sich
selbst aufraeumt.

AUFGABENLISTE

Vier Abschnitte in den vier Prozessfarben -- dieselben wie im Portal und
auf der Ablaufseite. Das ist der Punkt: Eine Farbe bedeutet ueberall
dasselbe, sonst waere sie Deko.

Ein Klick aufs Kaestchen schaltet weiter: offen -> in Arbeit -> erledigt.
Drei Zustaende ueber einen Knopf statt eines Auswahlfeldes -- beim
Abarbeiten einer Liste zaehlt jeder gesparte Klick.

Punkte, die auf den KUNDEN warten, sind golden hinterlegt und tragen eine
Marke. Ohne diese Unterscheidung liest man die Liste als reinen
Fortschrittsbericht und uebersieht, dass man selbst gar nicht am Zug ist.
Der goldene Grund verschwindet, sobald der Punkt erledigt ist -- er
braucht dann keine Aufmerksamkeit mehr.

Abhaken faerbt die Zeile sofort um, ohne auf den Server zu warten. Bei
zehn Punkten hintereinander waere ein Neuaufbau nach jedem Klick zaeh, und
man verliert die Stelle. Geht es schief, wird die Liste neu geholt und der
Zustand ist wieder ehrlich.

POSTFACH

Links Verlaeufe, rechts das Gespraech. Nicht aus Nachahmung, sondern weil
man ein Gespraech abarbeitet und nicht eine Zeile: Man will sehen, was
vorher besprochen wurde, waehrend man antwortet. Kunde links, eigene
Nachrichten rechts -- man erkennt den Absender an der Seite, bevor man den
Namen liest.

Der Schalter "Nur interne Notiz" faerbt das ganze Schreibfeld um. Ein
Haekchen allein uebersieht man, und eine interne Bemerkung, die beim
Kunden landet, ist der peinlichste Fehler, den dieses System machen kann.
Interne Notizen im Verlauf sind gestrichelt umrandet und golden -- sie
duerfen nicht wie etwas Gesendetes aussehen.

Strg+Enter sendet, Enter allein nicht: In einem mehrzeiligen Feld will man
Absaetze machen koennen, ohne dass die halbe Nachricht rausgeht.

EIN FEHLER, DEN DIE TESTS NICHT GEFUNDEN HABEN

Der erste Lauf meldete 37 von 37 gruen -- und jede Aufgabenzeile war
sichtbar falsch herum gebaut: Kaestchen, dann die kleinen Knoepfe, Titel
ganz rechts. Aufgefallen ist es erst am Screenshot.

Ursache: Das Raster platziert zuerst alle Elemente mit FESTGELEGTER Zeile
und erst danach die freien. Kaestchen und Knopfgruppe hatten beide
"grid-row: 1 / span 2" und wurden deshalb zusammen nach vorne gesetzt; der
Titel landete als letzter in der dritten Spalte. Jetzt bekommt jedes Kind
Zeile UND Spalte ausdruecklich.

Die eigentliche Lehre steckt im Test: Alle 37 Pruefungen betrafen
Bestandteile (Farben, Anzahl, Durchgestrichenes), keine einzige die
ANORDNUNG. Wer eine Anordnung baut, muss die Anordnung pruefen. Drei neue
Pruefungen vergleichen jetzt die tatsaechlichen Bildschirmpositionen --
und sie wurden gegengeprueft: Mit dem alten Zustand schlagen sie fehl,
mit dem neuen nicht. Ein Test, der nie fehlschlaegt, ist wertlos.

GEPRUEFT: 43 Pruefungen, Computer und Handy, alle bestanden. Darunter:
alle Touch-Ziele mindestens 24 px, interne Notiz sieht anders aus als eine
gesendete, Verlauf springt ans Ende, keine Fehler im Protokoll.

Versionsstempel und Cache-Name auf v4.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-22 23:30:11 +02:00
DogFatherGitandClaude Opus 5 9186d4cc1a Verwaltung uebersichtlicher, Bildlaufleiste dunkel
Rueckmeldung 22.08.2026 zur Anfrage-Detailansicht: "das ganze soll viel
uebersichtlicher sein und nicht so durcheinander" und "die leiste rechts
zum hoch und runter, kannst du die mal geil aussehen lassen anstatt
einfach so kake weiss."

1. DAS DURCHEINANDER HATTE EINE URSACHE

Die Kaesten standen in "columns: 2" -- Zeitungsspalten. Die fuellen sich
von selbst: erst Spalte eins bis oben voll, dann Spalte zwei. Wo ein
Kasten landet, haengt allein davon ab, wie lang die vor ihm sind. Bei
einer Anfrage stand "Interne Notizen" oben rechts, bei der naechsten
unten links. Es gab schlicht keine Ordnung, der man haette folgen koennen.

Jetzt ein festes Raster mit einer Aussage:
  LINKS  = was der Kunde geschickt hat   (lesen)
  RECHTS = was du damit machst           (handeln)

Immer gleich. Nach der zweiten Anfrage weiss man, wo man hinschaut, ohne
zu suchen. Rechts ist schmaler (Knoepfe brauchen weniger Platz als
laufender Text) und klebt beim Scrollen mit -- die Handlungen sind der
Grund, warum man die Ansicht oeffnet, sie duerfen nicht aus dem Bild
wandern.

Reihenfolge rechts korrigiert: "Anfrage uebernehmen" steht jetzt oben.
Es ist der Knopf, den man bei einer neuen Anfrage druecken WILL -- er
stand unter den Notizen und damit ausserhalb des sichtbaren Bereichs.

2. "KEINE ANGABE" WAR DIE HALBE ANSICHT

Jede fehlende Angabe bekam eine eigene Zeile. Der Kasten "Umfang"
enthielt zweimal nichts und war trotzdem so gross wie einer mit Inhalt.

Leere Felder sind aber keine Information, sondern deren Fehlen. Sie
stehen jetzt als EINE leise Zeile am Fuss: "Ohne Angabe: Bereiche,
Funktionen". Aus sechs Zeilen wird eine. Weggelassen werden sie nicht --
man muss sehen, wonach gefragt wurde und was unbeantwortet blieb, genau
daraus entstehen die Rueckfragen.

Neu darueber: "Auf einen Blick" mit Paket, Budget, Wunschtermin und
Alter. Die vier Fragen, die man immer zuerst hat, standen vorher auf drei
Kaesten verteilt. Das Alter als "vor 3 Tagen" statt als Datum -- die
Frage ist nie "welcher Tag war das", sondern "wie lange liegt das schon
hier", und die beantwortet ein Datum erst nach Kopfrechnen.

3. BILDLAUFLEISTE -- und ein Fehler, der fast durchgegangen waere

Auf einer durchgehend dunklen Seite ist eine weisse Bildlaufleiste der
einzige grelle Streifen im Bild. Sie zieht den Blick dorthin, wo nichts
Wichtiges steht, und blendet. Verstoesst gegen die Dauervorgabe
"augenschonend".

Zwei Wege noetig, weil kein Browser beide versteht: color-scheme: dark
fuer Firefox/Safari (wirkt zusaetzlich auf Auswahl- und Datumsfelder, die
sonst weiss aufblitzen), ::-webkit-scrollbar fuer Chrome/Edge.
scrollbar-width/-color bewusst NICHT gesetzt -- sobald es dasteht,
ignoriert Chrome die feineren ::-webkit-Regeln.

Beim ersten Versuch stand dort nur ".wd ::-webkit-scrollbar" -- MIT
Leerzeichen. Das trifft nur Elemente INNERHALB der Seite, nicht den body
selbst. Alle Messungen sahen gut aus; an der einen Leiste, ueber die sich
jemand beschwert hatte, haette sich nichts geaendert. Jetzt beide
Fassungen, mit einem Warnhinweis im CSS.

GEPRUEFT

Neue Datei pruef-detail.mjs: echter Browser, 1440x900 und 390x844, mit
einer absichtlich sehr knappen Anfrage -- genau die sah vorher schlecht
aus. 20 Pruefungen, alle bestanden: Spalten nebeneinander bzw. auf dem
Handy untereinander, rechte schmaler als linke, keine Ueberlappung, kein
waagerechtes Schieben, nichts ragt aus dem Fenster, keine einzelne
"keine Angabe"-Zeile mehr, keine Fehler im Protokoll.

Die Bildlaufleiste liess sich nur in einem ECHTEN Browserfenster pruefen:
Headless-Chromium blendet Leisten grundsaetzlich ueber dem Inhalt ein und
meldet deshalb immer 0 px Breite. Mit sichtbarem Fenster gemessen: 12 px,
alle sechs Regeln vom Browser akzeptiert.

Versionsstempel auf allen 11 Seiten und Cache-Name des Service Workers
auf v3 -- sonst liefert der eigene Zwischenspeicher beim ersten Laden
weiter die alte Fassung aus.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-22 23:05:47 +02:00
DogFatherGit 60c1e7be94 Test: Absturz beim Beenden vermeiden (better-sqlite3) 2026-08-22 22:57:59 +02:00
DogFatherGit 38bc741660 Aufraeumen: versehentlich mitcommittete Dateien entfernt
Ein 'git add -A' hat 13 Bild-Sicherungskopien (.bak-*, zusammen 2,6 MB),
den lokalen Testserver und eine erzeugte package-lock.json mitgenommen.

Die package-lock.json war der schaedlichste Teil: Auf dem Server existiert
eine eigene, dort erzeugte Fassung. Eine versionierte Datei gleichen Namens
laesst 'git pull' abbrechen -- der Deploy stand sofort still.

Alle drei Muster stehen jetzt in .gitignore.
2026-08-22 22:57:26 +02:00
DogFatherGit 4ce51c127e WIP: Aufgaben- und Postfach-Routen (Test folgt auf dem Server) 2026-08-22 22:56:59 +02:00
DogFatherGitandClaude Opus 5 548ec6bc00 Aufgabenlisten und allgemeines Postfach: Datenbank und Vorlagen
Erster von vier Schritten fuer zwei Wuensche vom 22.08.2026:
"wenn sie drauf druecken sollen sie auch sehen was ich schon gemacht habe
von dem was im plan war" und "die kunden sollen mir auch nachrichten
hinterlassen koennen".

DATENBANK (3 neue Tabellen, jetzt 18 insgesamt, Fremdschluessel geprueft)

wd_aufgaben -- die Punkte je Projekt. Drei Entscheidungen darin:
  * "wer_dran" ist eine eigene Spalte, kein Text. Manche Punkte warten
    auf den KUNDEN ("Texte liefern"), und genau die muessen ihm ins Auge
    springen. Ohne diese Unterscheidung liest er die Liste als reinen
    Fortschrittsbericht und uebersieht seinen eigenen Teil -- der
    haeufigste Grund fuer Verzoegerungen ueberhaupt.
  * "nicht_enthalten" bildet ab, was NICHT zum Umfang gehoert. Das ist
    die haeufigste Streitfrage in jedem Projekt ("ich dachte, das ist
    dabei"). Vorher sichtbar aufgeschrieben kostet es nichts, hinterher
    kostet es Geld oder den Kunden.
  * "kategorie" nutzt dieselben vier Abschnitte wie die Farben im Portal.
    Damit bedeutet eine Farbe ueberall dasselbe statt nur huebsch zu sein.

wd_postfach -- Nachrichten OHNE Projektbezug. Bewusst eine EIGENE Tabelle:
wd_nachrichten hat projekt_id als NOT NULL, und SQLite kann das nicht
lockern, ohne die ganze Tabelle zu kopieren -- ein unnoetiges Risiko bei
echten Kundennachrichten. Die neue Tabelle hat ohnehin andere
Anforderungen (Anhaenge, Lesestatus in BEIDE Richtungen, optionaler Bezug
auf eine Aufgabe). Zwei klar getrennte Tabellen sind ehrlicher als eine,
die beides halb kann.

VORLAGEN (56 Punkte ueber 5 Pakete, davon 20 beim Kunden)

Bei jedem Projekt fuenfzehn Punkte von Hand einzutippen fuehrt
zuverlaessig dazu, dass es irgendwann niemand mehr macht -- und dann
steht der Kunde wieder vor der leeren Liste, die der Ausloeser war.

Die Punkte sind in der Sprache formuliert, in der ein KUNDE denkt:
"Aufbau der Seiten festlegen" statt "Informationsarchitektur", "Auf dem
Handy durchtesten" statt "Responsive QA". Er liest diese Liste -- sie
muss ihm etwas sagen, nicht mir.

Die Vorlagen wandern beim ersten Start in die Datenbank und sind ab dann
dort aenderbar. Bereits vorhandene werden NIE ueberschrieben: sonst waeren
von Hand angepasste Vorlagen nach dem naechsten Neustart weg, und niemand
kaeme auf die Idee, dass der Neustart schuld war.

Naechste Schritte: Server-Routen, Verwaltung, Portal.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-22 22:48:39 +02:00
DogFatherGitandClaude Opus 5 71b9fc09c1 Anfrage-Detail: zentriertes Fenster statt seitlicher Leiste
Rueckmeldung 22.08.2026 mit Bildschirmfoto: "ich will das nicht so ich
will es viel viel viel besser und uebersichtlicher und schoener zentriert
in der mitte."

Berechtigt, und aus mehreren Gruenden. Eine seitlich eingeschobene Leiste
ist fuer so viel Inhalt das falsche Format:
  * Der Blick springt beim Oeffnen nach rechts.
  * Die Liste dahinter bleibt halb sichtbar und lenkt ab.
  * Alles muss sich in eine schmale Spalte quetschen -- auf dem
    Bildschirmfoto stand "keine Angabe" dadurch achtmal untereinander,
    und die Abwesenheit von Information nahm mehr Platz ein als die
    Information selbst.

Jetzt: mittig, 940px breit, zweispaltig ab Tablet. Der Blick bleibt, wo
er ist, und zusammengehoerende Angaben stehen nebeneinander.

Weitere Entscheidungen:
* Mauerwerk-Umbruch (columns) statt Raster. Die Abschnitte sind
  unterschiedlich hoch; ein Raster haette grosse Luecken gerissen.
* Jeder Abschnitt bekommt eine eigene Flaeche statt nur einer Trennlinie.
* Die Kopfzeile klebt beim Scrollen oben fest. Bei einer langen Anfrage
  weiss man sonst nach dem Scrollen nicht mehr, wessen Daten man liest.
* "keine Angabe" wird kleiner und blasser dargestellt. Es ist die
  ABWESENHEIT einer Information und darf nicht aussehen wie eine.
* Die Oeffnen-Animation skaliert dezent aus der Mitte statt von rechts
  hereinzufahren, und ist bei prefers-reduced-motion ganz aus.

9/9 Tests weiterhin gruen.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-22 22:28:09 +02:00
DogFatherGitandClaude Opus 5 2539fdea8d Zahlenkreise repariert und vier Prozessfarben durchgaengig
"wieso sehen die zahlen immer noch so scheisse aus?" -- zu Recht, und die
Ursache war nicht Geschmack, sondern ein Fehler. Nachgemessen sass die
Ziffer 15px NEBEN der Kreismitte.

Ursache: ".po-leer-punkt span" (fuer den Beschreibungstext) trifft auch
den Zahlen-Span und ist spezifischer (Klasse + Element) als
".po-leer-nr" (nur Klasse). Sie erzwang display:block, 14,4px Schrift und
23px Zeilenhoehe -- exakt die gemessenen Werte. Meine eigene
"line-height: 1"-Regel kam gar nicht zum Zug.

Das ist derselbe Spezifitaets-Fehler wie zuvor beim Hauptknopf (blaue
Schrift auf blauem Grund) und bei den Namen auf der Zugangswand. Dreimal
dieselbe Falle, deshalb steht die Begruendung jetzt ausfuehrlich im Code.

Behoben ueber :not(.po-leer-nr) an beiden Textregeln. Nachgemessen:
  Versatz waagerecht  -15px -> 0px
  Versatz senkrecht    -8px -> -1,3px
  display             block -> grid
  Schrift/Zeile   14,4/23px -> 18,4/18,4px

Zweite Rueckmeldung: "es soll 4 farben geben wie 4 kategorien zum
prozess". Sehr gute Idee -- sie macht das System erst schluessig. Die
sieben Phasen sind in Wahrheit vier Abschnitte, und die vier
Merkmalskacheln trugen ohnehin schon vier Farben. Jetzt bedeuten diese
Farben ueberall dasselbe:

  1  Blau   Start        Briefing, Angebot
  2  Lila   Gestaltung   Design
  3  Gruen  Umsetzung    Entwicklung, Tests
  4  Gold   Abschluss    Abnahme, Uebergabe

Die Phasenleiste faerbt erledigte Abschnitte in IHRER Farbe statt
pauschal gruen -- man sieht dadurch, wie weit man ist, nicht nur DASS
etwas fertig ist. Die Vorschau laeuft in denselben Farben durch. Die
Legende nennt die vier Abschnitte beim Namen, damit Farbe nicht geraten
werden muss: Farbe allein ist nie Information.

45/45 Handy-Abnahme, i18n vollstaendig.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-22 22:26:04 +02:00
DogFatherGitandClaude Opus 5 c597753abf Portal: Zahlenkreise, Typografie und eine echte Farblogik fuer Phasen
Drei Rueckmeldungen vom 22.08.2026, alle drei berechtigt.

1) "die kisten sollen auch eine spezielle farbe bekommen wenn sie fertig
   sind" -- das war inhaltlich der wichtigste Punkt. Vorher sahen
   erledigte und gerade laufende Phase fast gleich blau aus. Damit ging
   die einzige Aussage verloren, die die Leiste ueberhaupt traegt:
   naemlich WO man steht. Jetzt drei klar getrennte Zustaende:
     erledigt     gruen, ruhig
     laeuft grad  leuchtendes Blau mit langsamem Puls
     kommt noch   gedaempft
   Die Vorschau erklaert die Logik gleich mit: ihre Leiste wandert von
   blau nach gruen, statt nur an- und auszugehen.
   Dazu eine Legende in Worten. Farbe allein ist nie Information -- wer
   sie nicht unterscheiden kann, liest hier trotzdem, was sie bedeutet.

2) "die zahlen sollen besser im kreis sein" -- vorher ein flacher Kreis
   mit Zahl. Jetzt ein doppelter Ring: aussen ein Farbverlauf als Rand,
   innen die dunkle Flaeche, dazu ein weicher Schein. Derselbe Kniff wie
   bei den Karten (Verlauf ueber border-box); der Kreis wirkt dadurch
   plastisch statt aufgemalt. Jede der vier Kacheln hat ihre eigene
   Farbe -- vier gleiche Kacheln wirken wie eine Aufzaehlung, vier
   unterscheidbare wie ein System.

3) "schrift soll spezieller sein" -- die Kachel-Ueberschrift war so gross
   wie der Text darunter und ging unter. Jetzt groesser, in der
   Headline-Schrift, enger gesetzt mit leicht negativer Laufweite. Die
   Ueberschrift "Gleich geht es los" bekommt einen Farbverlauf.

45/45 Handy-Abnahme, i18n vollstaendig, prefers-reduced-motion beachtet.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-22 22:14:00 +02:00
DogFatherGitandClaude Opus 5 ad58ab99d3 Leeres Portal: zeigen statt erzaehlen
Rueckmeldung 22.08.2026 mit Bildschirmfoto: "dass muss noch viel
spezieller, krasser und geiler sein, nicht so einfach".

Der Kern des Problems war nicht die Optik, sondern die Haltung: Die Seite
BESCHRIEB, was hier bald stehen wird ("Eine Leiste zeigt dir, in welcher
Phase dein Projekt ist"). Beschreibungen sind schwach -- man muss sie
lesen und sich dann etwas vorstellen.

Jetzt steht dort eine echte, als Vorschau gekennzeichnete Projektkarte:
Projektnummer, Titel, eine Phasenleiste, die langsam durchlaeuft, die
Marke "Dogfather ist dran" und ein naechster Schritt. Man sieht in zwei
Sekunden, was drei Saetze nicht erklaeren.

Die Karte ist bewusst als Vorschau erkennbar -- gestrichelter Rand,
Etikett oben rechts, gedaempfte Schrift, Nummer P-0000-0000. Sie darf nie
mit einem echten Projekt verwechselt werden.

Dazu ein sehr langsamer Lichtstreifen, der einmal durchwandert. Er sagt
ohne Worte "hier passiert gleich etwas", ohne zu blinken oder zu zappeln
-- augenschonend bleibt Dauervorgabe.

Bei prefers-reduced-motion laeuft nichts, aber die Phasenleiste zeigt
trotzdem drei erledigte Phasen. Ohne das staende dort eine leere graue
Reihe und die Vorschau erklaerte gar nichts mehr -- ein abgeschaltetes
Element muss trotzdem noch seine Aussage transportieren.

45/45 Handy-Abnahme, i18n vollstaendig.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-22 22:07:06 +02:00
DogFatherGitandClaude Opus 5 96458b58aa Anfrage mit einem Klick zu Kunde und Projektraum machen
Der wichtigste Handgriff im ganzen Bereich -- und der Weg, den man bei
JEDEM echten Kunden geht. Bisher haette man Name, E-Mail, Paket und
Wunschtermin von Hand in die Kundenmaske abgetippt: vier Gelegenheiten
fuer einen Tippfehler, und einer davon ist spaeter nicht mehr
korrigierbar, weil die E-Mail gleichzeitig der Anmeldename ist.

Jetzt steht in der Anfrage-Detailansicht eine Uebernahme mit Vorschau
(Kunde, E-Mail, Projekttitel, Sprache) und einem optionalen Preisfeld,
das die 30 % Anzahlung beim Tippen mitrechnet. Ein Klick legt an:
  * den Kundenzugang, freigeschaltet, in der Sprache der Anfrage
  * das Projekt, verknuepft mit der Anfrage, mit Wunschtermin und
    "Briefing-Termin vereinbaren" als erstem sichtbaren Schritt
  * die Anfrage wechselt automatisch auf "angenommen"
Danach springt die Ansicht auf "Kunden" und zeigt sofort den
Einladungslink -- den einzigen Weg, wie der Kunde an sein Passwort kommt.

Die beiden Schritte laufen bewusst nacheinander, nicht parallel: das
Projekt braucht die Kunden-Kennung. Schlaegt der zweite fehl, existiert
der Kunde trotzdem schon. Genau das sagt die Fehlermeldung dann auch
ausdruecklich -- sonst versucht man es blind noch einmal und scheitert an
der doppelten E-Mail-Adresse, ohne zu verstehen warum.

Ist aus einer Anfrage bereits ein Kunde geworden, erscheint statt der
Uebernahme ein Hinweis darauf. Zweimal denselben Kunden anzulegen soll
gar nicht erst angeboten werden.

Dabei denselben Anfuehrungszeichen-Fehler wie schon einmal gemacht und
behoben: das gerade " in „Kunden" beendet die JavaScript-Zeichenkette.
Typografisch richtig ist ohnehin das schliessende " -- beides in einem Zug.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-22 21:48:07 +02:00
DogFatherGitandClaude Opus 5 77674cb801 Kennzahlen der Verwaltung: aus stillen Zahlen werden Werkzeuge
Rueckmeldung 22.08.2026: "mach es noch krasser noch detaillierter noch
viel besser und perfekter und auch die kacheln viel geiler."

Die Kacheln waren eine Reihe stiller Zahlen. Zahlen, die man nur anschauen
kann, sind Dekoration. Jetzt:

* Jede Kachel FILTERT die Liste darunter beim Antippen. Als echter
  <button>, nicht als div mit Klickzuhoerer -- sonst ist sie mit der
  Tastatur nicht erreichbar und ein Screenreader kuendigt sie nicht als
  Bedienelement an.
* Jede Kachel sagt, was zu TUN ist, nicht nur wie viele es sind:
  "warten auf dich" / "du bist dran" / "Kunde ist dran" /
  "Projekt anlegen".
* Neue Kachel: der aelteste unbearbeitete Vorgang in Tagen. Das ist die
  ehrlichste Kennzahl ueberhaupt -- sie sagt nicht, wie viel man
  geschafft hat, sondern wie lange jemand schon auf Antwort wartet.
  Genau daran misst ein Kunde Zuverlaessigkeit. Ab sieben Tagen rot.
  Diese eine Kachel filtert bewusst NICHT und ist deshalb auch kein
  Knopf: sie zeigt einen Zustand, keinen Status.
* Eine Null wird gedaempft dargestellt. Sonst konkurriert "0 abgelehnt"
  optisch mit "3 neu" -- und genau die Drei ist die, auf die man schauen
  soll. Was nichts zu tun gibt, soll auch nicht leuchten.
* Gold bleibt ausschliesslich dem echten Handlungsbedarf vorbehalten.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-22 21:44:37 +02:00
DogFatherGitandClaude Opus 5 d93625439a Verwaltung: mehr Information pro Zeile statt leerer Flaeche
Rueckmeldung 22.08.2026 mit Bildschirmfoto: die Anfragenliste wirkte blass
und leer. Zu Recht -- sie zeigte Nummer, Name, Paket, Status, Datum. Das
ist korrekt, beantwortet aber nicht die Fragen, die man beim Draufschauen
WIRKLICH hat.

Jetzt steht in jeder Zeile:
* E-Mail direkt sichtbar (vorher musste man die Anfrage dafuer oeffnen)
* Paket, Budgetrahmen, Wunschtermin als eigene Marken
* Sprache, falls es NICHT Deutsch ist -- dann antwortet man auch in der
  richtigen Sprache
* ob daraus schon ein Kunde geworden ist

Statt eines Datums steht dort "vor 3 Tagen". Beim Datum muss man selbst
rechnen, wie lange jemand schon wartet -- und genau das ist die Frage,
die zaehlt. Ab sieben Tagen ohne Bearbeitung wird die Angabe rot: eine
Anfrage, die eine Woche liegt, ist ein verlorener Kunde.

Ein farbiger Streifen links codiert den Status zusaetzlich zur Textmarke.
Farbe ALLEIN waere fuer farbfehlsichtige Menschen keine Information --
zusammen mit dem Text ist sie ein schneller Anker beim Ueberfliegen.

Der leere Zustand stellt nicht mehr nur fest, dass nichts da ist, sondern
erklaert, WO Anfragen herkommen, und legt den Link zum Formular gleich
daneben.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-22 21:42:15 +02:00
DogFatherGitandClaude Opus 5 097e80b845 Projekte anlegen und ein leerer Zustand, der fuehrt statt zu enttaeuschen
Rueckmeldung 22.08.2026 mit Bildschirmfoto aus dem eigenen Testzugang:
"die seite soll jetzt schon bitte richtig krass sein und hoch profissionel,
auch sehr detailliert."

Zwei Luecken, beide geschlossen:

1) Projekte liessen sich nur ueber die Schnittstelle anlegen. Jetzt in der
   Verwaltung: pro Kunde ein "+ Projekt" mit Titel, Paket, Preis,
   Richttermin und naechstem Schritt. Bewusst als Einblendung direkt bei
   der Kundenzeile statt als eigene Seite -- man legt ein Projekt IMMER
   fuer einen bestimmten Kunden an, nie im luftleeren Raum. Der Kundenname
   steht deshalb gross im Formular, damit es nicht versehentlich dem
   Falschen angehaengt wird.
   Die 30 % Anzahlung wird beim Tippen live mitgerechnet. Sie wird zwar
   serverseitig berechnet, aber wer sie beim Eintippen sieht, merkt eine
   falsche Null sofort -- und nicht erst, wenn der Kunde ueberweisen soll.

2) Der leere Zustand im Portal war ein einziger Satz. Das ist eine
   verpasste Gelegenheit: Wer dort zum ersten Mal landet, hat gerade sein
   Passwort gesetzt und weiss noch nicht, was ihn erwartet -- genau dann
   entscheidet sich, ob die Seite souveraen wirkt oder unfertig. Jetzt
   zeigt er in vier Punkten, WAS gleich hier stehen wird (Projektstand,
   wer am Zug ist, Dateien und Nachrichten, Ideen jederzeit) und schliesst
   mit der Zusicherung, dass nichts zu tun ist. Fuenfsprachig.

45/45 Handy-Abnahme, i18n vollstaendig.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-22 21:40:27 +02:00
DogFatherGitandClaude Opus 5 74091590b8 Verwaltung: nur noch EINMAL den Code eingeben
Rueckmeldung 22.08.2026: "ich hab auf der verwaltungs seite 2 mal dass ich
den zugangscode eingeben muss und vanvan auch, ich will es nur einmal
eingeben muessen." Berechtigt.

Die Zugangswand hat serverseitig laengst geprueft, WER da ist -- Dogfather
oder VanVan, laut Masterplan S.4 beide gleichberechtigte
Volladministratoren. Ein zweites Passwort danach bringt keinen
zusaetzlichen Schutz, es kostet nur jedes Mal Zeit.

Warum es nicht einfach "Cookie mitschicken" ist: Die Verwaltungsdaten
liegen hinter postfach.dogfather-universe.com, einem ANDEREN Rechnernamen.
Das Sitzungs-Cookie gilt dort nicht -- so sind Cookies gebaut, und das ist
gut so.

Loesung: Die Zugangswand stellt unter /webdesign/api-ausweis einen
kurzlebigen, signierten Ausweis aus, den die interne API anerkennt.
  - 15 Minuten gueltig, die Seite holt bei Bedarf still einen neuen
  - traegt bereich="wd-admin", damit ein Sitzungs-Token der Zugangswand
    hier NICHT durchgeht und umgekehrt
  - nur mit gueltiger Zugangssitzung zu bekommen
  - gilt AUSSCHLIESSLICH fuer die /webdesign-Endpunkte. Postfach,
    Bewerbungen, Supporter und Teamverwaltung bleiben unberuehrt

Fehlt WEBDESIGN_API_SECRET auf einer der beiden Seiten, gilt kein Ausweis
und die Verwaltung fragt wie bisher nach dem Team-Code. Ein fehlender
Konfigurationswert darf niemals eine Tuer oeffnen -- nur eine schliessen.
Genau das prueft der letzte Testfall.

Bei einem 401 wird EINMAL still ein neuer Ausweis geholt und die Anfrage
wiederholt, statt jemanden mitten im Arbeiten rauszuwerfen.

10/10 Tests, darunter: gefaelschte Signatur, fremdes Geheimnis,
abgelaufen, falscher Bereich, erfundene Rolle.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-22 21:36:11 +02:00
DogFatherGitandClaude Opus 5 2542a2598e Kunden und Projekte in der Verwaltung anlegen, inklusive Testzugang
Wunsch 22.08.2026: "ich will einen provisorischen zugang fuer mich".
Der richtige Weg dahin war ohnehin ueberfaellig -- Kundenzugaenge
entstehen ausschliesslich hier, es gibt bewusst keine Selbstregistrierung.

Neu:
* Kundenzugang anlegen (Name, E-Mail, Firma, Sprache, sofort freischalten
  ja/nein) mit Einladungslink
* "Testzugang fuer mich" -- ein Klick, legt einen als Test erkennbaren
  Zugang mit Datumsstempel an. Bewusst NICHT die echte Geschaeftsadresse:
  die E-Mail ist gleichzeitig der Anmeldename und laesst sich aus gutem
  Grund nicht mehr aendern, ein Test wuerde also spaeter mit einem echten
  Kundenkonto kollidieren.
* Zugaenge auflisten, freischalten, sperren, neuen Einladungslink erzeugen
* Projekte anlegen und aendern, Aenderungswuensche beziffern, Nachrichten

Entscheidungen:
* Der Einladungslink geht EINMAL im Klartext raus, direkt beim Anlegen.
  In der Datenbank liegt nur sein Hash. Wer ihn verliert, bekommt einen
  neuen -- das ist sicherer, als ihn dauerhaft abrufbar zu halten. Die
  Oberflaeche sagt das auch klar dazu, sonst klickt man ihn weg und
  wundert sich.
* Ein neuer Link entwertet alle offenen alten. Sonst sammeln sich mehrere
  gueltige Generalschluessel fuer dasselbe Konto an.
* "Sofort freischalten" ist eine bewusste Handlung. Ohne Haekchen wird der
  Zugang angelegt, kommt aber noch nicht hinein -- Masterplan S.12
  verlangt, dass Projektkauf oder Betreuung VOR der Freischaltung geprueft
  werden.
* Sperren beendet laufende Sitzungen sofort, nicht erst nach Ablauf.
* Die 30 % Anzahlung werden aus dem Preis BERECHNET, nicht eingetippt.
  Ein Tippfehler in der Anzahlung faellt sonst erst beim Geldeingang auf.
* Preise kommen als Euro herein und werden sofort in Cent umgerechnet
  (Math.round, damit 49.99 nicht zu 4998 wird). Ab da nie wieder Komma.
* Vier klar unterscheidbare Zustaende in der Liste. Wichtig vor allem
  "Einladung offen": freigeschaltet, aber noch kein Passwort gesetzt --
  der Kunde war also noch nie drin.
* Kopieren faellt auf Markieren zurueck, wenn die Zwischenablage
  blockiert ist. Eine Fehlermeldung waere dort nutzlos.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-22 21:23:15 +02:00
DogFatherGitandClaude Opus 5 1b432f456f Kundenportal: Oberflaeche (Masterplan S.12)
Vier Ansichten in einer Seite: Anmeldung, Passwort festlegen ueber den
Einladungslink, Uebersicht, Projektdetail. 71 Textbausteine in fuenf
Sprachen.

Korrektur an einer frueheren Entscheidung: Ich hatte das Portal als "nur
Deutsch" eingestuft wie die Verwaltung. Denkfehler -- die Verwaltung
nutzen Dogfather und VanVan, das PORTAL nutzen Kunden, und die koennen
Franzosen oder Portugiesen sein. Jetzt fuenfsprachig, und die Sprache des
Kunden wird bei der Anmeldung automatisch uebernommen.

Gestaltungsentscheidungen:
* Eine Phasenleiste zeigt auf einen Blick, wo das Projekt steht. Das ist
  die haeufigste Frage ueberhaupt und der Grund, warum Kunden anrufen.
  Bei pausierten oder abgebrochenen Projekten wird KEINE Leiste gezeigt --
  ein Fortschrittsbalken waere dort irrefuehrend.
* Eine Marke sagt, wer gerade am Zug ist ("Wir warten auf dich" /
  "Dogfather ist dran"). Das beendet die haeufigste Unklarheit im
  Projektverlauf.
* Offene Zahlungen stehen ganz oben und in Gold -- das Einzige, was den
  Kunden wirklich zum Handeln auffordert.
* Rueckfrage nur beim ANNEHMEN eines Zusatzangebots, nicht beim Ablehnen.
  Annehmen erzeugt eine Zahlungspflicht, Ablehnen ist folgenlos.
* Abgelaufene Sitzung fuehrt zur Anmeldung mit klarer Ansage statt zu
  einer leeren Seite, die wie "du hast keine Projekte" aussaehe.
* Der Einladungslink wird nach Gebrauch aus der Adresszeile entfernt --
  er ist verbraucht und hat in der Chronik nichts verloren.
* Die Zahlungsknoepfe sagen ehrlich, dass PayPal noch eingerichtet wird,
  statt so zu tun als wuerde etwas passieren.

Pruefskript zweimal geschaerft, beide Male waren es Fehlalarme:
* Die Heuristik fuer Nachschlagetabellen hielt gewoehnliche Woerter wie
  "abnahme" und "uebergeben" fuer Woerterbuch-Schluessel. Jetzt muss ein
  Unterstrich im Namen sein, so wie bei allen echten Schluesseln.
* Eine Ueberschrift gilt jetzt auch als uebersetzt, wenn die Uebersetzung
  INNEN sitzt (fester Teil + dynamischer Teil).

i18n vollstaendig, 45/45 Handy-Abnahme.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-22 21:17:22 +02:00
DogFatherGitandClaude Opus 5 04a1af1253 Kundenportal: Server-Seite mit strikter Mandantentrennung
Masterplan S.12. Anmeldung, Uebersicht, Projektdetail, Aenderungswuensche,
Zusatzangebote annehmen/ablehnen, Nachrichten, Profil.

DIE ZENTRALE ENTSCHEIDUNG: Die Trennung zwischen Kunden sitzt NICHT in der
Oberflaeche, sondern in jeder einzelnen Abfrage. Ueberall steht
"WHERE id = ? AND kunde_id = ?" statt "WHERE id = ?", wobei die kunde_id
IMMER aus der Sitzung kommt, nie aus der Anfrage. Wer eine fremde
Projektkennung errät, bekommt dadurch "nicht gefunden" statt Daten. Die
Oberflaeche liegt im Browser des Kunden und ist beliebig manipulierbar --
sie kann diese Aufgabe grundsaetzlich nicht uebernehmen.

Weitere bewusste Entscheidungen:
* KEINE Selbstregistrierung. Masterplan S.12 verlangt, dass Projektkauf
  oder Betreuung VOR der Freischaltung geprueft werden. Ein Portal, in das
  sich jeder selbst eintraegt, waere das Gegenteil. Kunden werden in der
  Verwaltung angelegt und bekommen einen Einladungslink.
* Passwoerter mit scrypt (in Node eingebaut, kein Zusatzpaket). Ein
  SHA-256 ueber ein Passwort ist milliardenfach pro Sekunde durchprobierbar;
  scrypt ist absichtlich langsam UND speicherhungrig.
* Mindestanforderung ist LAENGE, nicht Zeichenklassen. "Hund1234!" erfuellt
  jede Klassenregel und ist trotzdem schlecht; "mein blauer stuhl steht
  krumm" erfuellt keine und ist ausgezeichnet.
* Gleiche Fehlermeldung bei unbekannter Adresse und falschem Passwort --
  sonst lassen sich Kundenadressen durchprobieren.
* Die Anmeldesperre haengt an der E-Mail, nicht an der IP. Eine IP-Sperre
  wuerde mehrere Kunden hinter demselben Firmenanschluss gemeinsam
  aussperren -- genau der Fehler, der im Universe am 19.08.2026 auftrat.
* Sperre und Passwortwechsel beenden laufende Sitzungen SOFORT, nicht erst
  nach zwoelf Stunden.
* Ein Zusatzangebot laesst sich nur annehmen, wenn es beziffert ist --
  sonst entstuende eine Zahlungspflicht ohne Preis.

Dazu der wichtigste Test des Bereichs (test-webdesign-portal.mjs): zwei
echte Kunden, und Kunde B versucht systematisch mit Kunde As echten
Kennungen an dessen Projekt, Nachrichten, Dateien und Zusatzangebote zu
kommen. Prueft ausserdem, dass interne Notizen und interne Arbeitsdateien
auch dem BERECHTIGTEN Kunden verborgen bleiben.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-22 19:12:56 +02:00
DogFatherGitandClaude Opus 5 ae9878cb4c Sprungmarken auf breiten Bildschirmen alle in einer Reihe
Rueckmeldung 22.08.2026: "alle neben einander bitte". Vorher passten vier
in die Zeile und die fuenfte rutschte allein darunter -- das sieht aus wie
ein Versehen, nicht wie eine Gestaltung.

Ab 700px teilen sich jetzt alle fuenf den Platz zu gleichen Teilen
("flex: 1 1 0" statt "auto"). Mit "auto" waere "Preise & Zahlung" schmal
und "Inhalte & Zusammenarbeit" breit gewesen -- ungleiche Kacheln in einer
Reihe, also genau das, was hier schon einmal bemaengelt wurde.
"min-width: 0" ist dabei noetig, weil Flex-Elemente sonst nicht unter ihre
Inhaltsbreite schrumpfen und die Reihe trotzdem umbrechen wuerde.

Nachgemessen bei 700 / 900 / 1280 / 1440px: 5 Knoepfe, 1 Reihe, alle
gleich breit UND gleich hoch. Unter 700px bleibt der Umbruch -- fuenf
Spalten waeren auf einem Handy unlesbar schmal.

45/45 Handy-Abnahme weiterhin sauber.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-22 19:08:47 +02:00
DogFatherGitandClaude Opus 5 9f74167f84 Sprungmarken brechen um statt zu scrollen, keine Silbentrennung in Ueberschriften
Rueckmeldung 22.08.2026: "ich will nicht dass man die hin und her
schieben muss man soll die alle sehen aber nicht schieben muessen."

Richtig, und aus zwei Gruenden: Eine Wischleiste verbirgt, DASS es noch
mehr gibt -- was rechts aus dem Bild ragt, existiert fuer die meisten
Menschen schlicht nicht. Dazu kam ein haesslicher Scrollbalken quer ueber
die Seite. Jetzt brechen die Knoepfe um, alle fuenf sind auf einen Blick
da, auch bei 320px.

Der Text in den Knoepfen darf dabei mitbrechen (white-space: normal) --
ohne das sprengt ein langer Name wie "Buchhaltungs- &
Steuerverwaltungsseiten" auf schmalen Bildschirmen die Zeile und der
waagerechte Ueberlauf waere durch die Hintertuer zurueck.

Dabei mitgefunden: "hyphens: auto" auf Ueberschriften. Auf dem Handy
stand dadurch "Alles, was vorher ge-klaert sein sollte". Der Browser
trennt damit nach Silben, auch wenn ueberhaupt kein Platzproblem
besteht. In Fliesstext ist das ein Gewinn, in grossen Ueberschriften
sieht es billig aus -- und genau die sind das Erste, was jemand sieht.
overflow-wrap: break-word bleibt und faengt echte Ueberlaeufe weiterhin ab.

Pruefskript: die Sprungmarken-Leisten waren als "absichtlich scrollbar"
von der Ueberlaufpruefung ausgenommen. Diese Ausnahme ist raus -- sonst
wuerde ein zurueckkehrender Ueberlauf dort nie auffallen. 45/45 weiterhin
sauber.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-22 19:03:30 +02:00
DogFatherGitandClaude Opus 5 de4a90362e Verwaltungsbereich fuer Projektanfragen
Masterplan S.13. Anfragen ansehen, filtern, durchsuchen, Status aendern,
interne Notizen, archivieren. 9/9 Sicherheitstests.

Bewusste Entscheidungen:

* NUR AUF DEUTSCH. Der oeffentliche Teil laeuft in fuenf Sprachen, weil
  dort Kunden landen. Hier landen ausschliesslich Dogfather und VanVan --
  fuenf Sprachen waeren fuenffache Pflege und fuenffache Fehlerflaeche
  ohne einen einzigen Nutzer, der sie braucht. Genau wie der bestehende
  interne Bereich des Universe.

* Anmeldung ueber die BESTEHENDE Team-Anmeldung (/auth/login) statt einer
  zweiten eigenen. Zwei Anmeldungen fuer dieselben zwei Personen waeren
  doppelte Pflege und ein zweiter Ort, an dem ein Zugang vergessen werden
  kann. Der Code der Zugangswand gilt hier ausdruecklich NICHT --
  die Verwaltung steckt hinter zwei getrennten Tueren.

* Sitzungstoken im sessionStorage, nicht localStorage: es verschwindet
  beim Schliessen, dieselbe Regel wie an der Zugangswand. Der Test prueft
  das ausdruecklich.

* Bei abgelaufener Sitzung geht es zurueck zur Anmeldung statt zu einer
  leeren Liste. Eine leere Liste sieht aus wie "keine Anfragen" und ist
  damit eine stille Falschaussage.

* Gold nur beim Status "neu" -- also genau dort, wo wirklich etwas zu tun
  ist. Wuerde alles leuchten, leuchtet nichts.

* Archivieren statt Loeschen, und die Oberflaeche sagt das auch dazu.

Pruefskript: kennt jetzt bewusst einsprachige Seiten (verwaltung, portal)
und prueft dort nur die Struktur, statt ein fehlendes Woerterbuch zu
melden.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-22 18:54:58 +02:00
DogFatherGitandClaude Opus 5 eaeaec6b56 Anfrageformular fertig - vier Schritte, Zwischenspeicherung, echte Absendung
Masterplan S.10 "Projektanfrage ohne Informationsverlust" umgesetzt.
End-to-End gegen die echte Datenbank belegt: Anfrage A-2608-0002 liegt drin.
38/38 Browsertests, 45/45 Handy-Abnahme.

Aufbau: 4 Schritte + Zusammenfassung + Dankeseite.
- Zwischenspeicherung nach jedem Tastendruck. Geschlossener Tab, leerer
  Akku oder versehentliches Zurueck kosten keine Arbeit. Entwuerfe
  verfallen nach 30 Tagen -- ein halbes Jahr alter Entwurf verwirrt mehr
  als er hilft.
- Folgefragen erscheinen nur passend zur Auswahl und werden beim
  Zurueckwechseln NICHT mitgeschickt, sonst landen alte Shop-Antworten in
  einer Onepager-Anfrage.
- Die Zusammenfassung wird aus den Feldern gelesen, nicht aus einem
  nebenher gepflegten Objekt -- sie kann dadurch nie etwas anderes
  behaupten als das, was tatsaechlich abgeschickt wird.
- Telefon wird zur Pflicht, sobald "Per Telefon" gewaehlt ist. Ein Wunsch,
  der nicht erfuellbar ist, ist schlimmer als eine Pflichtangabe.

Drei Fehler, die erst der Test gefunden hat:
1. Der "Zurueck"-Knopf stand auch auf Schritt 1 da. Ursache: das
   hidden-Attribut wird nur ueber "display:none" umgesetzt und verliert
   gegen jedes eigene display -- und Knoepfe sind inline-flex. Zentral
   behoben ueber ".wd [hidden] { display:none !important }".
2. Nach erfolgreichem Absenden legte zeigeSeite() den geloeschten Entwurf
   sofort wieder an. Beim naechsten Besuch haette eine bereits gesendete
   Anfrage erneut im Formular gestanden.
3. Der Server meldet bei Spamverdacht bewusst Erfolg ohne Nummer. Ein
   echter Mensch, der zufaellig sehr schnell war, haette eine Dankeseite
   mit "—" gesehen und auf eine Antwort gewartet, die nie kommt. Jetzt
   ein ehrlicher Hinweis mit zweitem Weg, und der Entwurf bleibt erhalten.

Pruefskripte geschaerft:
- i18n-Pruefung liest jetzt auch assets/js/wd-<seite>.js, sonst meldet sie
  reihenweise "unbenutzt" fuer Schluessel, die aus dem Seitenskript kommen.
- Handy-Abnahme ueberspringt absichtlich unsichtbare Eingabefelder
  (Auswahlkacheln, Honigtopf). Fehlalarme sind das Ende jeder Pruefung,
  weil man sie irgendwann pauschal ignoriert.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-22 18:47:45 +02:00
DogFatherGitandClaude Opus 5 8ace955740 Service Worker lieferte alte Stilvorlagen aus - Korrekturen blieben unsichtbar
Gemeldet 22.08.2026 mit Bildschirmfoto: "immer noch so" -- das Logo im
Marken-Intro stand weiterhin hochkant gestreckt da, obwohl die Korrektur
(height:auto gegen die height-Attribute) laengst live war.

Ursache war NICHT die Korrektur, sondern mein eigener Service Worker. Er
lief fuer /assets/ als "stale-while-revalidate": die gespeicherte Fassung
geht sofort raus, im Hintergrund wird eine frische geholt. Das ist schnell
-- bedeutet aber, dass jede Aenderung an CSS oder JavaScript beim ersten
Aufruf unsichtbar bleibt und erst beim zweiten wirkt. Ein behobener Fehler
sieht dadurch aus wie ein nicht behobener. Die unangenehmste Sorte.

Nachgemessen ist das Logo jetzt 160x161px bei einem natuerlichen
Verhaeltnis von 472x476 -- also unverzerrt. Vorher erzwang das Attribut
height="476" bei 160px Breite ein Verhaeltnis von 0,34 statt 0,99, genau
das lange Gesicht auf dem Bildschirmfoto.

Behoben:
- Stilvorlagen und Skripte laufen jetzt "Netz zuerst", Zwischenspeicher
  nur als Notfallnetz. Richtigkeit vor Millisekunden.
- Bilder und Symbole bleiben beim schnellen Weg -- die aendern sich
  praktisch nie und bekaemen sonst einen neuen Dateinamen.
- CACHE_NAME auf v2 gesetzt, damit der alte Speicher beim naechsten Start
  vollstaendig weggeworfen wird.
- Versionsnummer an allen CSS/JS-Verweisen hochgesetzt, damit es sich auch
  ohne Service Worker sofort selbst heilt.

Ausserdem: Woerterbuch fuer das Anfrageformular, 101 Textbausteine in fuenf
Sprachen (vier Schritte, Zusammenfassung, Fehlermeldungen).

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-22 18:34:15 +02:00
DogFatherGitandClaude Opus 5 29a054c359 Bilder waren hochkant gestreckt und ungleich hoch, Abstaende halbiert
Rueckmeldung 22.08.2026 per Bildschirmfoto: "die sollen alle gleich
aussehen und nicht einer groesser oder kleiner" und "ich will nicht soooo
viel abstand".

1) Verzerrte, ungleich hohe Projektbilder
   Nachgemessen: 576px breit, aber 750px bzw. 696px hoch -- also hochkant
   gestreckt und unterschiedlich, obwohl im CSS sauber "aspect-ratio:
   16/10" stand. Ursache: die width/height-Attribute im HTML (die dort
   bewusst stehen, damit der Browser vor dem Laden den Platz reserviert
   und die Seite nicht springt) wirken wie eine CSS-Hoehe und schlagen
   aspect-ratio. Fix zentral ueber ".wd img[width][height] { height:
   auto }" statt in jeder einzelnen Regel -- so kann es bei einem neuen
   Bild nicht vergessen werden.
   Jetzt beide 576x360, Karten beide 853px hoch.

2) Zu viel Leerraum
   .wd-abschnitt hatte 100,8px oben UND unten, also gut 200px zwischen
   zwei Abschnitten. Halbiert auf 57,6px, Hero von 78svh auf 68svh.
   Seitenlaenge dadurch 8798px -> 7089px bei gleichem Inhalt.

3) Zwei neue Dauerpruefungen in pruefe-webdesign-handy.mjs, damit genau
   diese beiden Fehlerarten nicht wieder per Bildschirmfoto auffallen
   muessen:
   - verzerrte Bilder (gewuenschtes vs. tatsaechlich gerendertes
     Seitenverhaeltnis, 2 % Toleranz)
   - ungleich hohe Karten innerhalb EINER Rasterzeile

40/40 Abnahme weiterhin sauber.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-22 18:26:07 +02:00
DogFatherGitandClaude Opus 5 356bb974b8 Knopf war unlesbar, und der Code wird jetzt bei jedem Schliessen neu verlangt
Zwei Rueckmeldungen vom 22.08.2026, beide behoben und mit Tests abgesichert.

1) "das sieht nicht gut aus" (Bildschirmfoto des Hauptknopfs)
   Ursache: ".wd a" ist Klasse+Element und damit spezifischer als die reine
   Knopfklasse ".wd-btn--haupt". Die Textfarbe des Knopfs wurde dadurch
   ueberstimmt -- hellblaue Schrift auf hellblauem Grund, praktisch
   unlesbar. Derselbe Spezifitaetsfehler wie zuvor bei den Namen auf der
   Zugangswand. Fix: ".wd a:not(.wd-btn)" plus zweistufig geschriebene
   Knopfregeln, damit das nicht wieder passieren kann.

2) "das sieht lang gezogen aus"
   Die Pillenform (border-radius 999px) laesst breite Knoepfe
   auseinandergezogen wirken, weil der Radius optisch mit der Breite
   mitwaechst. Jetzt fester Radius von 14px -- gleiche Form bei jeder
   Breite, ruhiger und hochwertiger.

3) "ich will das ich jedes mal den code gefragt werde wenn man die seite
   zu macht"
   Das Sitzungs-Cookie allein reicht dafuer nicht: Browser stellen genau
   solche Cookies beim Wiederherstellen von Tabs zurueck ("Dort
   fortfahren, wo du aufgehoert hast"), man landet dann ohne Codeabfrage
   wieder mitten in der Seite. Zusaetzlich jetzt eine Sitzungsmarke im
   sessionStorage, die beim echten Schliessen verschwindet. Fehlt sie bei
   vorhandenem Cookie, wird die Sitzung serverseitig beendet und zur
   Zugangswand geleitet. Token-Notbremse von 24 auf 8 Stunden gesenkt.
   13/13 Tests im echten Browser, inklusive Schutz vor Endlosschleife.

DEPLOY.md: zwei Checkouts auf dem Server dokumentiert (/home/dogiweb und
/home/dogiintern) und der Vorfall, dass /webdesign nach dem Pull kurz ohne
Zugangsschutz erreichbar war, weil der Dienstneustart fehlte.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-22 18:20:34 +02:00
DogFatherGitandClaude Opus 5 4b3ec450d5 Webdesign-Bereich: Fundament, oeffentliche Seiten, Zugangsschutz, PayPal
Umsetzung des "Website Masterplan" (16 Seiten) unter /webdesign.

Zugangsschutz mit EIGENER Schranke (server/webdesign-gate.js) statt gate.js:
gate.js laesst seit dem oeffentlichen Start am 21.08.2026 jeden durch, weil
die Pruefung auf SITE_PUBLIC_LAUNCH_AT als allererste Zeile steht. Haette man
/webdesign dahintergehaengt, waere der ausdruecklich nicht-oeffentliche Bereich
inklusive Preisen und spaeteren Kundendaten ab der ersten Sekunde fuer jeden
lesbar gewesen. Eigenes Sitzungs-Cookie, bereich="webdesign" im Token, damit
ein gueltiges Universe-Cookie hier NICHT gilt. 37/37 Tests.

Sieben oeffentliche Seiten in fuenf Sprachen (de, de-CH mit echtem Dialekt, en,
fr, pt). Preise, Zeitrahmen, Paketnamen und die 30-%-Regel stehen an genau
EINER Stelle in wd-core.js -- der Masterplan verlangt "ueberall
widerspruchsfrei", und vier Kopien laufen bei der ersten Preisaenderung
auseinander.

Als App installierbar auf Handy und PC. Der Service Worker speichert bewusst
KEINE HTML-Seite zwischen: nach dem Abmelden wuerden sonst geschuetzte Seiten
weiter ausgeliefert, ohne dass der Server je gefragt wird. 18/18 Tests.

Handy-Abnahme ueber alle Seiten in fuenf Breiten (320-1440) und fuenf Sprachen:
40/40. Der Test fand 35 echte Fehler (Touch-Ziele unter 44px), behoben im
Designsystem statt einzeln pro Seite.

PayPal (Wunsch 22.08.2026 "sofort auf meinem paypal"): Orders API mit
intent=CAPTURE, also sofortiger Einzug statt blosser Reservierung. Gebuehr und
Nettobetrag getrennt gespeichert. Betraege durchgehend als Ganzzahl in Cent.
Gefaelschte Webhooks werden abgewiesen. Fail closed solange Zugangsdaten
fehlen. 28/28 Tests gegen einen nachgebauten PayPal-Server.

Datenbank: 15 Tabellen mit Praefix wd_, fachlich vollstaendig vom Universe
getrennt.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-22 18:06:52 +02:00
DogFatherGitandClaude Opus 5 2010b5ec33 Live benutzte Hintergrundbilder + Stimmen-Avatare in die Ablage aufgenommen
Beim Abgleich zwischen Rechner und Netcup-Server am 22.08.2026 aufgefallen:
20 Bilddateien wurden live von mehreren Seiten benutzt (bewerben-modi.html,
links.html, medien-casper.html, medien-hasidog.html, supporter.html,
stimmen.html u.a.), lagen aber in keiner Git-Ablage -- nur auf diesem
Rechner und auf dem Server. Waeren beide verloren gegangen, waeren diese
Seiten ohne Hintergrund/Avatare dagestanden.

Vor dem Hinzufuegen jede Datei per Pruefsumme gegen den Server abgeglichen
-- alle identisch, kein abweichender Stand wird hier verdeckt.

dogfather-universe-app.ico ist aktuell nirgends verlinkt (vermutlich ein
nie eingebauter Favicon-Entwurf), trotzdem mit gesichert statt verworfen.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-22 15:47:38 +02:00
DogFatherGitandClaude Opus 5 541a91d9e2 DEPLOY.md korrigiert: echte Seite laeuft auf Netcup, nicht auf Cloudflare
Die Anleitung nannte als Deploy-Weg weiterhin "npx wrangler deploy". Das ist
seit dem oeffentlichen Start (21.08.2026) falsch und aktiv gefaehrlich: der
Befehl laeuft fehlerfrei durch und meldet Erfolg, erreicht aber nur noch
...workers.dev. Die echte Domain wird von Caddy auf dem Netcup-Server
ausgeliefert (dogiweb.service, localhost:4100). Genau darauf bin ich heute
beim Sprachfenster-Fix hereingefallen -- Deploy "erfolgreich", auf dem Handy
aber unveraendert kaputt.

Neu dokumentiert: der einzige gueltige Weg (commit -> push gitea master:main
-> git pull auf dem Server), die Zweig-Falle master/main, die Pflichtpruefung
gegen die echte Domain statt gegen die Deploy-Meldung, warum die
wrangler-Fehlermeldung "externally managed DNS records" erwuenscht ist, und
als offener Punkt: mehrere live benutzte Hintergrundbilder liegen in keiner
Git-Ablage.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-22 15:27:08 +02:00
DogFatherGitandClaude Opus 5 e5d55137d4 Zwei Server-Reparaturen zurueckgeholt, die es nur auf dem Server gab
Beim Abgleich der beiden Staende (Rechner vs. Netcup-Server) gefunden --
beide Aenderungen liefen bereits live, waren aber nirgends gespeichert und
haetten beim naechsten Deploy vom Rechner aus verloren gehen koennen:

1. gate.html: autofocus im Dogi-Feld entfernt (21.08.2026, Rueckmeldung von
   Diene -- der Cursor sprang nach dem Laden zurueck nach oben, die eigene
   Kachel scrollte dabei aus dem Bild).
2. verwaltung.html: "Oeffnen"-Knoepfe wurden auf dem Handy vom
   overflow:hidden der Karte abgeschnitten (22.08.2026); jetzt
   overflow:visible plus etwas mehr Unterabstand.

Inhalt unveraendert vom Server uebernommen, nur hier nachgetragen.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-22 15:24:35 +02:00
DogFatherGitandClaude Opus 5 3f9997456a Handy: Sprachfenster (DE) klappte halb aus dem Bild auf
Nutzer-Report per Foto: beim Tippen auf "DE" im Handy-Menue erschien das
Sprachfenster halb links ausserhalb des Bildschirms, man konnte keine
Sprache mehr lesen oder treffen.

Ursache: Die Handy-Regel, die alle Aufklapp-Fenster auf statische Position
und volle Breite umstellt, hat den Sprachschalter nicht erreicht -- seine
Desktop-Regel (.sprach-schalter .nav-dropdown, 0-2-0) ist spezifischer,
und eine @media-Abfrage erhoeht die Spezifitaet nicht. Dadurch lief die
Desktop-Animation "sprach-dropdown-in" weiter, die per fill-mode:both
dauerhaft transform: translateX(-50%) setzt. Auf dem Desktop korrekt
(schmales Fenster mittig unter dem Knopf), im Handy-Menue aber toedlich:
das Fenster ist dort bildschirmbreit und wurde um seine halbe Breite nach
links geschoben (gemessen live: x = -148px bei 390px Viewport).

Fix: dieselben Handy-Regeln erneut mit ausreichender Spezifitaet fuer den
Sprachschalter, samt Kommentar zur Begruendung.

Geprueft mit Playwright (echter Browser): 390x844, 360x640, Querformat
844x390 und Tablet 768x1024 -> Fenster jeweils vollstaendig im Bild, alle
5 Sprachen sichtbar; Desktop 1920 unveraendert schmal und zentriert;
Sprachwechsel (English) funktioniert weiterhin.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-22 11:27:22 +02:00
DogFatherGitandClaude Sonnet 5 adb1042915 Namenskorrektur Cigdem (statt Cidgem) auch lokal + in allen 5 Sprachen nachgezogen
War beim Server-Deploy schon als Konflikt aufgefallen (Diene/das Team hatte
die richtige Schreibweise bereits korrigiert) -- hier fehlte die Korrektur
noch in i18n-zeitreise.js (alle 5 Sprachen) sowie in der HTML-Fallback-
Version, weil mein ursprünglicher Fix von heute Nachmittag ("Cidem" ->
"Cidgem") selbst schon falsch war.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-08-21 23:39:29 +02:00
DogFatherGitandClaude Sonnet 5 1f0ec994a9 Drei Handy-Nachbesserungen: Trio-Bild hinter dem Text, auffälliger Menü-Knopf, abgeschnittener Öffnen-Knopf
Nutzer-Report mit drei Bildern vom Handy:

1. HERO-BILD SASS NICHT MEHR HINTER DEM TEXT (index.html)
   .hero-artwork hat "inset:0" -- füllt also die GESAMTE Höhe von
   .hero-cinematic, und diese Sektion umschließt nicht nur die Überschrift,
   sondern auch die 3 Welt-Kacheln darunter. Auf dem Handy wird die Sektion
   durch den 4-zeilig umbrechenden Titel + Kacheln riesig (~1570px bei
   390px Breite) -- das Trio-Bild (16:9, contain-skaliert an die Breite)
   wurde dadurch nur ~220px hoch und mittig in dieser riesigen Fläche
   zentriert, landete also als schmaler Streifen zwischen den Buttons und
   den Welt-Kacheln statt hinter der Überschrift.
   Fix: eigenes festes Seitenverhältnis (4:3) für die Bildbox auf dem
   Handy, von OBEN verankert statt zentriert, background-size auf "cover"
   -- Verlauf eigens für die neue, kürzere Box abgestimmt (die
   Desktop-Version wäre zu abrupt gewesen). Über 6 Breiten (320-768px)
   mit Playwright gegengeprüft.

2. MENÜ-KNOPF ZU UNAUFFÄLLIG (main.js + main.css, alle Seiten)
   "da soll auch menü stehen und die 3 striche" + "die kiste soll auch
   leicht eine andere farbe haben so dass sie auffällt, eine leicht blau
   tönung". Sichtbares "Menü" neben den drei Strichen ergänzt (neuer i18n-
   Schlüssel nav_toggle_label, alle 5 Sprachen) + dezente Babyblau-Tönung
   (8% Deckkraft, passend zur Markenfarbe --accent). Dabei einen
   unabhängigen, zweiten Bug gefunden und mitbehoben: durch die neue
   Knopfbreite/-höhe wurde ein Rechenfehler im geschlossenen Mobilmenü
   sichtbar -- "translateY(-110%)" reicht nur, wenn das Panel mindestens
   10x so hoch ist wie der Kopfbereich; war das nicht der Fall, ragte die
   Unterkante (der Sprachschalter) ein paar Pixel sichtbar ins Bild.
   Robusterer Ersatz: -100% + fester 200px-Puffer, unabhängig von Panel-
   und Kopfbereichshöhe. Über 3 Breiten gegengeprüft (Panel unsichtbar UND
   öffnet weiterhin normal).

3. "ÖFFNEN"-KNOPF AUF DER ZUGANGSSEITE ABGESCHNITTEN (gate.html)
   .gate-card trägt "flex: 1 1 220px" für die Desktop-Reihe (220px als
   BREITE gedacht). Sobald @media max-width:480px auf flex-direction:column
   umschaltet, gilt dieselbe Zahl als HÖHE -- die Karte wurde auf genau
   220px Höhe gequetscht. overflow:hidden setzt zusätzlich das normale
   Mindestmaß (min-height:auto) auf 0 herunter, wodurch nichts das
   Zusammenquetschen verhinderte -- der "Öffnen"-Knopf wurde unten
   abgeschnitten. Fix: flex:none in genau diesem Media-Block, Breite bleibt
   weiterhin über width:100%/max-width geregelt. An 4 Breiten x 3 Kacheln
   (Dogi/VanVan/Diene) gegengeprüft: Karten jetzt 258px statt 220px hoch,
   Knopf komplett sichtbar.

Vollständiger Regressionslauf: alle 34 Seiten bei 390px (kein Überlauf,
Menü-Knopf überall erreichbar und beschriftet), Desktop bei 1920px
unverändert (Hamburger weiterhin nur unter der bestehenden 1650px-
Schwelle sichtbar).

Cache-Busting-Version auf 20260821t erhöht.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-08-21 23:37:14 +02:00
DogFatherGitandClaude Sonnet 5 57966e24d0 Automatischer öffentlicher Start um 21 Uhr + Countdown auf der Zugangsseite
Nutzer-Wunsch 21.08.2026: "ich will dass du auch ein countdown zu der
seite hinzufügst wo wir den zugangscode eingeben müssen. den um 21h heute
abend geht die seite live. kannst du das sogar so anpassen dass es
automatisch läuft?"

server/gate.js:
- Neue Einstellung SITE_PUBLIC_LAUNCH_AT (ISO-Zeitstempel mit Zeitzone).
  Ab diesem Moment lässt gateMiddleware ausnahmslos jeden durch -- ganz
  ohne Neustart oder manuellen Eingriff, weil jede Anfrage die aktuelle
  Serverzeit live neu prüft. Die Freischaltung "passiert" also von selbst
  in der Sekunde, in der die Uhrzeit erreicht wird. Vorher bleiben die
  Zugangscodes unverändert nötig, damit das Team schon vorher rein kann.
  Fail-safe statt fail-open geprüft: ein kaputter/unparsbarer Zeitwert
  (z.B. Tippfehler in der .env) lässt die Schranke aktiv, statt die Seite
  versehentlich für alle zu öffnen.
- Neuer öffentlicher Endpunkt GET /gate-launch-info (immer erreichbar,
  auch ohne gültige Sitzung) liefert launchAt/isLive/serverTime für die
  Countdown-Anzeige im Frontend.

gate.html:
- Neue Countdown-Box zwischen Titel-Karte und den Zugangscode-Kacheln
  (bleibt unsichtbar, solange kein Starttermin konfiguriert ist). Rechnet
  auf der SERVERZEIT statt der eigenen Uhr (einmaliger Zeit-Abgleich beim
  Laden), damit eine falsch gehende Besucher-Uhr weder zu früh noch zu
  spät zählt. Bei Erreichen von Null folgt ein letzter Abgleich mit dem
  Server, bevor automatisch zur Zielseite weitergeleitet wird -- kein
  Klick, kein Neuladen nötig.
- Zugangscode-Kacheln (Dogi/VanVan/Diene) bleiben während des Countdowns
  unverändert nutzbar.

Getestet: 18 Middleware-Tests (inkl. Fail-safe bei kaputtem Zeitwert,
weiterhin funktionierender Zugangscode vor dem Start) + 10 Playwright-
Tests der Countdown-Oberfläche (Anzeige, Format, automatischer Sprung bei
Ablauf, sofortige Weiterleitung falls schon live, stiller Fallback bei
Netzwerkfehler). Zusätzlich alle 32 echten Seiten auf PC-Installierbarkeit
geprüft (Manifest, Icons, Service Worker, Install-Knopf, echter
Install-Klick-Ablauf simuliert) -- keine Probleme gefunden.

Cache-Busting-Version auf 20260821s erhöht.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-08-21 19:25:12 +02:00
DogFatherGitandClaude Opus 5 41faf22614 Handy: vollständige Prüfung von Inhalten, Knöpfen und allen Systemen
Nachtrag auf Nachfrage ("hast du alles geprüft oder nur die menü
leisten?") -- vorher hatte ich nur Navigation, Seitenbreite, Tippflächen
und Hoch/Querformat geprüft. Jetzt zusätzlich Bilder, Texte, Knöpfe und
die kompletten Abläufe.

Geprüft über alle 35 Seiten bei 393px:
- Bilder: kein einziges kaputtes Bild, keine fehlenden alt-Texte
- Dateien: keine 404er
- Knöpfe/Links: alle beschriftet (keine namenlosen Bedienelemente)
- Text: nichts wird abgeschnitten. Die zunächst gemeldeten "Überläufe"
  bei .btn/.card waren Fehlalarme -- sie stammen von den dekorativen
  Leucht-Ebenen (::before mit negativem inset), echter Text ragt
  nirgends heraus (einzeln gegengeprüft).

Zwei echte Funde behoben:
1. Marken-Unterzeile war mit 8,96px zu klein zum Lesen (hatte ich beim
   Handy-Fix selbst so verkleinert). Jetzt 11px -- Platz ist da, seit der
   Menü-Knopf eigenständig rechts sitzt. Über acht Breiten gegengeprüft,
   Kopfleiste bleibt überall stabil.
2. "Aktiv"-Ankreuzfelder in der Verwaltung waren 22px. Jetzt 26px, die
   ganze Beschriftungszeile ist 44px hoch und schaltet mit um.

Abläufe am Handy durchgespielt (echte Fingertipps, Fake-Backend):
- Registrierung über alle drei Schritte inkl. falschem Code
- Login mit falschem und richtigem Zugangscode
- Abmelden auf supporter.html
- Stimme einreichen inkl. Profilbild-Auswahl
- Verwaltung: Team-Mitglied anlegen, Stimme freigeben, alle Bereiche
  sichtbar, kein Überlauf

Cache-Busting-Version auf 20260821r erhöht.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-21 18:33:52 +02:00
DogFatherGitandClaude Opus 5 6910112d97 Stimmen: nur noch die zwei Originalfiguren + eigenes Bild hochladen
Nutzer-Wunsch 21.08.2026: "benutz da bitte nur die originalen husky und
hasen. mach nur die zwei. und die auswahl wo die leute selbst ein bild
rein setzen können."

- Auswahl von acht auf zwei reduziert (DogFather-Husky, HasiDog). Die
  übrigen Bilddateien bleiben liegen, falls sie je zurücksollen -- es
  genügt, die Zeile in data-stimmen-avatare.js und die Id in
  ERLAUBTE_AVATARE wieder zu ergänzen.
- Neue Kachel "eigenes Bild" (gestrichelter Rand + Plus), die den
  Dateidialog öffnet, das Bild sofort hochlädt und als Vorschau in der
  Kachel zeigt.

Bereits freigegebene Stimmen mit einer der entfernten Figuren zeigen
wieder den Anfangsbuchstaben statt eines kaputten Bildes -- die
Auflösung unbekannter Ids liefert null, das war schon so vorgesehen.

Sicherheit des öffentlichen Uploads (bisher war Hochladen bewusst nur
der Verwaltung erlaubt):
- Gleiche multer-Härtung wie der Verwaltungs-Upload: nur JPG/PNG/WebP,
  max. 5 MB, zufälliger UUID-Dateiname (kein Originalname).
- Der Server nimmt im Avatar-Feld weiterhin NUR bekannte Ids an oder
  eine Adresse, die exakt auf den eigenen Upload-Ordner zeigt und danach
  nur aus UUID + Bildendung besteht. Gegengetestet: fremde Domains,
  "../"-Ausbruch, .svg/.html, javascript:, angehängte Skripte und http
  statt https werden alle abgelehnt.
- Missbrauchsbremse gegen Vollschreiben der Festplatte: max. 10 Uploads
  pro Stunde und IP.
- Sichtbar wird ein Bild ohnehin erst, wenn die Stimme freigegeben wird.

Mit Playwright end-to-end geprüft (10 Tests) plus 9 Sicherheitsfälle.

Cache-Busting-Version auf 20260821q erhöht.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-21 18:23:17 +02:00
DogFatherGitandClaude Opus 5 e2bd436084 Arbeit der parallelen Session gesichert (Profilbilder für Stimmen, Diene-Zugang)
Wie beim vorherigen Mal lag das nur als Arbeitskopie auf dem Server, nicht
in git. Unverändert übernommen, bevor darauf aufgebaut wird:
- Profilbild-Auswahl für die Stimmen (data-stimmen-avatare.js neu,
  stimmen.js, i18n-stimmen.js, stimmen.html, verwaltung.html, main.css)
- Dritte Zugangs-Kachel für Diene (gate.html, server/gate.js)

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-21 18:17:47 +02:00
DogFatherGitandClaude Opus 5 d0613f86c1 Handy: Navigation war komplett unerreichbar — behoben, plus Tippflächen überall
Nutzer-Report 21.08.2026 mit Screenshot: "auf dem handy kann ich oben
nicht aussehen in welche seite ich will welche kategorie welche sprache
garnichts". Drei echte, per Playwright reproduzierte Fehler:

1. MENÜ-KNOPF AUSSERHALB DES BILDSCHIRMS (Hauptproblem)
   .brand stand auf flex-shrink:0, war bei 390px aber 352px breit. Mit
   Abstand + Knopf brauchte die Leiste 423px bei 367px Platz -- der
   Menü-Knopf landete bei x=396px, also komplett außerhalb. Damit war auf
   dem Handy die GESAMTE Navigation unerreichbar (keine Seiten, keine
   Kategorien, kein Sprachwechsel).
   Fix: Knopf per margin-left:auto immer an die rechte Kante; Marke darf
   unter 620px schrumpfen (inkl. min-width:0, sonst greift flex-shrink
   nicht); unter 400px entfällt die reine Deko-Unterzeile.

2. MENÜ IM QUERFORMAT NICHT ZU ÖFFNEN
   Das zugeklappte Panel wird um -110% SEINER EIGENEN Höhe verschoben. Quer
   (568x320) ist es nur 258px hoch, die Unterkante lag dadurch bei y=36px --
   also unsichtbar genau über dem Menü-Knopf (y=11..55) und hat jede
   Berührung abgefangen. Fix: pointer-events:none im geschlossenen Zustand.

3. MENÜPUNKTE AUF KURZEN BILDSCHIRMEN ZUSAMMENGEQUETSCHT
   .nav-links ist ein Flex-Container fester Höhe; passte der Inhalt nicht,
   schrumpfte Flexbox die Einträge (iPhone SE: 59px -> 29px, Knöpfe 21px).
   Fix: flex-shrink:0 auf die Kinder, der Bereich scrollt stattdessen
   (overflow-y:auto war bereits gesetzt).

Zusätzlich: Fußzeilen- und Impressum/AGB-Links auf Handys als echte
Tippziele (44px statt 17-20px) -- 18 dicht stehende Links, mit dem Finger
vorher kaum zu treffen. Menü-Trennlinien begradigt (folgten dem
Desktop-Pillenradius und sahen aus wie Schüsseln).

Ergebnis: alle 31 Seiten ohne Überlauf, Menü auf 320-768px, hoch UND quer
nutzbar, kleinster Menüpunkt 46px. Verbleibende kleine Ziele sind reine
Fließtext-Links im Satz (dürfen laut Standard klein bleiben).
Desktop per Regressionstest unverändert geprüft.

Cache-Busting-Version auf 20260821p erhöht.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-21 18:13:03 +02:00
DogFatherGitandClaude Opus 5 5a5912636d Registrierung: E-Mail-Bestätigung per Einmalcode vor dem Zugangscode
Nutzer-Wunsch 21.08.2026: "bei der ersten registrierung sollen die eine
email bekommen mit einem einmaligen code damit wir auch wissen dass
email stimmt und danach wenn sie den code eingegeben haben sollen die
erst ihren zugangscode auswählen/eintippen können."

Damit wird eine echte Lücke geschlossen: registerSupporter() hat bisher
`email_verified = 1` gesetzt, OHNE dass irgendetwas geprüft wurde -- man
konnte sich mit einer fremden oder erfundenen Adresse registrieren und
kam sofort rein.

Neuer Ablauf in drei Schritten:
1. Name/TikTok/E-Mail -> Konto wird als UNBESTÄTIGT angelegt
   (email_verified = 0, noch kein Zugangscode). Es kommt bewusst KEIN
   Session-Token zurück -- eingeloggt ist man hier noch nicht.
2. Einmalcode aus der E-Mail eingeben -> verify-email bestätigt und
   loggt ein. Die Willkommens-Mail wandert hierher, sie ging vorher an
   eine noch ungeprüfte Adresse.
3. Erst jetzt den eigenen Zugangscode festlegen.

Serverseitig abgesichert: setSupporterAccessCode() lehnt ab, solange die
E-Mail nicht bestätigt ist -- der Schritt ist damit nicht nur im
Formular versteckt, sondern auch per Direktaufruf nicht überspringbar.

Wiederverwendet wird die bereits vorhandene Mechanik (issueAuthCode/
verifyAuthCode mit Zweck "verify_email", sendVerifyEmailCode, die Panels
#panel-code und #panel-neuer-code) -- der "Code vergessen?"-Weg nutzt
dieselbe Code-Eingabe und bleibt unverändert; eine neue Variable
codeZweck unterscheidet, welcher Endpunkt aufgerufen wird.

Mit Playwright end-to-end geprüft (14 Tests): Reihenfolge der Aufrufe,
kein Token vor der Bestätigung, falscher Code kommt nicht weiter,
Zugangscode-Feld erst im letzten Schritt, "Code vergessen?" unberührt.

Cache-Busting-Version auf 20260821o erhöht.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-21 17:48:08 +02:00
DogFatherGitandClaude Opus 5 5d0ea11570 Arbeit der parallelen Session in git gesichert (war nur auf dem Server)
Diese Änderungen liefen bereits live auf dem Server, lagen dort aber
ausschließlich als nicht eingecheckte Arbeitskopie — bei jedem Deploy
(stash/pull/pop) und bei jedem Serverproblem wären sie verloren gewesen.
Deshalb hier unverändert in git übernommen, bevor darauf aufgebaut wird.

Enthalten (nicht von mir gebaut, nur gesichert):
- Supporter: eigener fester Zugangscode statt Einmalcode-Login
  (Migration 0009, lib/crypto.js scrypt-Hash, routes/supporter.js,
  abonnieren.html, supporter.html, i18n-abonnieren/-supporter)
- Stimmen: Profilbilder (Migration 0010, routes/testimonials.js)
- Event-Bild-Upload: voller Pfad statt relativem (routes/events.js)
- Neue/überarbeitete Hintergrundbilder für viele Seiten
- Teilen-Funktion (streamplan.js, i18n-index/-streamplan, main.css)

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-21 17:35:14 +02:00
DogFatherGitandClaude Sonnet 5 4b294f6c6b Startseite: die vier Personen-Kacheln unter "Team Dogi" entfernt
Nutzer-Wunsch 21.08.2026: "die 4 kacheln da sollen da weg bitte."
Überschrift, Beschreibungstext und der Knopf zum Modi-Team bleiben --
dadurch kommt das "Team Dogi"-Hintergrundbild dieser Sektion jetzt
unverdeckt zur Geltung. Der zugehörige Render-Code ist ebenfalls raus;
data-modis.js/data-scouts.js bleiben eingebunden, weil die
Statistik-Zeile weiter oben sie weiterhin auszählt (geprüft: zeigt
weiterhin korrekt "8+"). Die Profile selbst gibt es unverändert
vollständig auf team-modis.html.

Cache-Busting-Version auf 20260821n erhöht.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-08-21 16:53:56 +02:00
DogFatherGitandClaude Sonnet 5 d0f3edb079 bewerben.html: Überschrift-Umbruch verbessert (kein einsames letztes Wort mehr)
Nutzer-Wunsch 21.08.2026: "Weg" stand auf manchen Bildschirmbreiten
allein in einer eigenen Zeile, sah unruhig aus. Non-breaking-Space
zwischen den letzten zwei Wörtern in allen 5 Sprachen -- bricht die
Zeile jetzt nie mehr genau zwischen ihnen um.

Cache-Busting-Version auf 20260821m erhöht.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-08-21 16:51:00 +02:00
DogFatherGitandClaude Sonnet 5 76f70ffcf2 Zeitreise: Namen "Cidem" zu "Cidgem" korrigiert (Creator Cup)
Nutzer-Wunsch 21.08.2026: Tippfehler beim Namen des Kooperationspartners
beim Creator Cup korrigiert, in allen 5 Sprachen plus dem
HTML-Fallbacktext.

Cache-Busting-Version auf 20260821l erhöht.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-08-21 12:58:29 +02:00
DogFatherGitandClaude Sonnet 5 971c5ea3f6 Bugfix: Team-Foto-Upload lieferte relativen statt vollen Pfad zurück
Gleicher Fehler wie in routes/events.js/uploadEventImage (dort gerade
direkt auf dem Server gefunden und gefixt, siehe git stash auf
dogiintern): die Verwaltung und die echte Website laufen auf
dogfather-universe.com (dogiweb), hochgeladene Fotos liegen aber unter
postfach.dogfather-universe.com (dogiintern). Ein relativer Pfad wurde
vom Browser also gegen die falsche Domain aufgelöst -> kaputtes
Bild-Symbol für jedes über die Team-Verwaltung hochgeladene Foto.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-08-21 04:37:04 +02:00
DogFatherGitandClaude Sonnet 5 81f55d67db Team-Verwaltung Runde 2: bestehende Mitglieder importieren + Kategorien/Seitentitel editierbar
Nutzer-Wunsch 21.08.2026: "wenn ich eine änderung mache ist es auch für
jeden für die die schon da sind und die neuen" + "ich will ich titel
und namen von kategorien und seiten ändern können in der verwaltung".

Backend (braucht Filipes manuellen Deploy):
- Migration 0008: team_members bekommt intro/bioHtml/extraCta-Spalten
  -- volle Feld-Parität mit den von Hand gepflegten Profilen (Diene/
  Patrick/Bananenstift/Marina nutzen diese Felder).
- routes/team.js: neue importLegacyMember()-Funktion -- übernimmt ein
  bestehendes Profil 1:1 in die Datenbank, OHNE erneut zu übersetzen
  (die vorhandenen, von Hand geschriebenen Übersetzungen bleiben
  erhalten). Idempotent: mehrfacher Import erzeugt keine Duplikate.
- routes/site-texts.js (neu): admin-editierbare Kategorie-Namen und
  Seitentitel, generischer key->{de,...}-Override über app_settings
  (wie "Event des Jahres"), fester Schlüssel-Katalog aus
  Sicherheitsgründen. Leeres Feld setzt auf den Standardtext zurück.
- 27 Tests in isolierter Testumgebung geprüft (kein better-sqlite3
  lokal kompilierbar).

Frontend:
- window.dogiTeamZusammenfuehren() (main.js): admin-Mitglieder
  ÜBERSCHREIBEN jetzt gleichnamige statische Einträge (per slug) statt
  sie zu duplizieren -- eine Bearbeitung wirkt dadurch für alle.
- window.dogiSiteTexteLaden() + applyTranslations() erweitert um
  data-site-text-key -- Kategorie-Seitentitel (team-modis.html/
  team-scouts.html/creator.html/manager.html) sind jetzt live editierbar.
- Verwaltung: "📥 Bestehende Mitglieder importieren"-Knopf (holt VanVan/
  Diene/Funny/Miss/Marina/Ghost/Patrick/Bananenstift aus den data-*.js-
  Dateien, VanVan bewusst ausgenommen -- eigene Sonderkarte + Seite),
  erweitertes Formular (Intro/ausführliche Vorstellung/zweiter Button,
  eingeklappt unter "Erweitert"), neue Sektion "Kategorien &
  Seitentitel" (4 Karten, sofort wirksam auf Website UND Verwaltung).

Beim Testen einen echten UX-Bug gefunden und gefixt: die "Gespeichert"-
Meldung nach dem Speichern eines Mitglieds wurde von der direkt
anschließenden Formular-Zurücksetzung sofort wieder überschrieben und
war nie sichtbar.

Cache-Busting-Version auf 20260821k erhöht.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-08-21 03:47:51 +02:00
DogFatherGitandClaude Sonnet 5 7060a4a6ae Verwaltungsseite perfektioniert: Team-Verwaltung für Modis/Scouts/Creator/Manager
Nutzer-Wunsch 21.08.2026: "überall wo Modis sind oder Scouts oder
Manager, oder Creator, will ich dass ich die easy über meine
Verwaltungsseite hinzufüge und die automatisch in der Website
hinzugefügt werden ... auch mit Fotos und TikTok Link."

Backend (server-internal, braucht Filipes manuellen Deploy):
- Neue Tabelle team_members (Migration 0007) für alle vier Kategorien
  gemeinsam -- ergänzt, überschreibt NIE die von Hand gepflegten
  Einträge in data-modis.js/data-scouts.js/data-creator.js.
- routes/team.js: öffentliches Lesen (nur aktive Mitglieder, optional
  nach Kategorie gefiltert), TEAM_MANAGE-geschütztes Anlegen/Bearbeiten/
  Löschen, Foto-Upload (gleiches Muster wie "Event des Jahres"),
  automatische Übersetzung von Rolle/Bio/Zitat wie bei anderen
  admin-gepflegten Texten. Slug global eindeutig (mit automatischer
  Kollisionsauflösung), TikTok-Kurzname wird zu voller URL ergänzt.
  27 Tests in isolierter Testumgebung geprüft (kein better-sqlite3
  lokal kompilierbar).

Frontend:
- window.dogiTeamLaden() in main.js: holt admin-gepflegte Mitglieder
  einer (oder aller) Kategorien und bringt sie in exakt dieselbe Form
  wie die bestehenden data-*.js-Einträge.
- team-scouts.html/team-modis.html/creator.html hängen das Ergebnis
  einfach an ihre bestehenden Arrays an und rendern erneut -- exakt
  derselbe Look wie die schon bestehenden Profile (Foto/Avatar-Initiale,
  Rolle, Zitat, TikTok-Button). creator.html hatte bisher ein "return"
  bei leerem CREATORS-Array, wodurch admin-Creator NIE geladen worden
  wären -- gefixt. team-modis.html berücksichtigt Rang/Rang-Bezeichnung
  für die Pyramide.
- Neue Sektion "Weitere Manager" auf manager.html, komplett unsichtbar
  bis der erste Manager angelegt wird (data-manager.js neu, wie
  data-creator.js aktuell leer).
- profil.html sucht jetzt kategorieübergreifend auch in admin-gepflegten
  Profilen, inkl. korrektem Theme/Zurück-Link auch für Manager.

Verwaltung: neue Sektion "Team verwalten" (TEAM_MANAGE-Berechtigung) --
ein Formular für alle vier Kategorien mit Foto-Sofort-Upload,
TikTok-Feld, Bio/Zitat, bedingten Rang-Feldern (nur Modi), Kategorie-
Filterleiste und Bearbeiten/Löschen pro Eintrag.

Beim Testen mit Playwright einen echten Syntaxfehler gefunden und
gefixt (ASCII-Anführungszeichen statt schließendem „" in einem
Statustext), der das GESAMTE Verwaltungs-Skript und damit die komplette
Seite lahmgelegt hätte.

Cache-Busting-Version auf 20260821j erhöht.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-08-21 03:06:21 +02:00
DogFatherGitandClaude Sonnet 5 8ead1b750b KRITISCH: echten Ursprung der "rohen Übersetzungs-Schlüssel"-Bugs gefunden und behoben
Beide heutigen Meldungen ("pr_quote_open...", "ts_profil_ansehen") waren
KEIN Caching-Problem, sondern ein echter Bug in main.js: nach Klick auf
einen internen Link und dann "Zurück" (oder generell jede zweite Seite
innerhalb einer Browser-Sitzung) wurde die seiteneigene i18n-*.js-Datei
nie erneut ausgeführt -> window.I18N_PAGE blieb auf null -> jede
Übersetzung fiel auf den rohen Schlüsselnamen zurück.

Ursache: skripteUebernehmen() erkennt i18n-Dateien am Muster ".js$"
(String-Ende). Seit die Cache-Busting-Version ("?v=...") an jede
Skript-URL angehängt wird, endet der echte src-Wert aber nie mehr auf
".js", sondern auf ".js?v=...". Der Test schlug seitdem für JEDE
i18n-Datei fehl und sie wurde wie eine normale, schon geladene Datei
behandelt und beim nächsten Seitenwechsel übersprungen.

Mit Playwright reproduziert (Klick auf Profil-Kachel + Zurück-Button)
und nach dem Fix erneut verifiziert -- betraf praktisch jede Seite mit
eigenem i18n-*.js beim Navigieren per Klick, nicht nur team-scouts.html.

Cache-Busting-Version auf 20260821i erhöht.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-08-21 02:12:24 +02:00
DogFatherGitandClaude Sonnet 5 fbd11b7be4 "Was gerade läuft"-Aktionen-Teaser von der Startseite entfernt
Nutzer-Wunsch 21.08.2026: Überschrift + Button "Alle Aktionen & Projekte"
auf index.html weg. data-aktionen.js-Script-Tag (nur noch dafür gebraucht)
und die zugehörigen JS-Renderzeilen ebenfalls entfernt, dazugehörige
i18n-Keys (idx_aktionen_h2/idx_aktionen_btn) aus i18n-index.js aufgeräumt.
aktion-detail.html und data-aktionen.js selbst bleiben unangetastet.

Cache-Busting-Version auf 20260821h erhöht.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-08-21 02:04:43 +02:00
DogFatherGitandClaude Sonnet 5 ca5793e79f Patricks Profil-Abschluss um "Scout von Dogfather" ergänzt (wie Bananenstift)
Nutzer-Wunsch 21.08.2026: Patricks Bio endete nur mit "- euer Patrick",
Bananenstift hat zusätzlich eine zweite Zeile "Scout von Dogfather".
Für Konsistenz zwischen beiden Scout-Profilen in allen 5 Sprachen ergänzt.

Cache-Busting-Version auf 20260821g erhöht.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-08-21 01:53:57 +02:00
DogFatherGitandClaude Sonnet 5 c7904ccd62 TikTok-Buttons auf Patrick- und Bananenstift-Scout-Profilen ergänzt
Nutzer-Wunsch 21.08.2026: unter dem Namen/Rolle-Text je ein TikTok-Button
(@patrick180585 bzw. @bananenstift009). Beide nutzen den bereits
bestehenden social-Mechanismus in profil.html (social.tiktok -> echter
.btn-tiktok-Button), kein neuer Code nötig.

Cache-Busting-Version auf 20260821f erhöht (data-scouts.js ist .js und
damit von Cloudflares erzwungenem Edge-Cache betroffen).

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-08-21 01:49:00 +02:00
DogFatherGitandClaude Sonnet 5 ac01a74d08 Zeitreise: neue Station "Erstes Fan-Treffen: Team TiliDog" (25. Juli 2026)
Nutzer-Wunsch 21.08.2026: erstes Fan-Treffen von Dogi & Tili (Team
TiliDog) in Wuppertal ergänzt -- gleichzeitig das erste persönliche
Aufeinandertreffen von DogFather und Tili. Als Meilenstein markiert und
chronologisch korrekt zwischen "Juli 2026 — Start als Manager" und
"27. Juli bis 2. August 2026 — Creator Cup" einsortiert.

Cache-Busting-Version auf 20260821e erhöht.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-08-21 01:39:47 +02:00
DogFatherGitandClaude Sonnet 5 360f19a52d Echtes Foto von Filipe in der Intro-Sektion auf streamer.html ergänzt
Nutzer-Wunsch 21.08.2026: "füge das foto was ich am ende mitschicke
neben den text im screen1". Sektion von einspaltigem Fließtext auf
grid-2 umgebaut, Foto (assets/img/streamer-filipe-portrait.jpg, aus
Pictures/Filipe, auf 1000x1500 verkleinert) rechts daneben mit
frame-gold-Rahmen für Abwechslung zur Casper-Sektion (frame-lila).

Cache-Busting-Version auf 20260821d erhöht.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-08-21 01:29:03 +02:00
DogFatherGitandClaude Sonnet 5 6106cf9f03 Modi-Gang TikTok-Button von streamer.html nach team-modis.html verschoben
Der Button gehört thematisch besser zum Modi-Team als zur Casper-Sektion
auf streamer.html (Nutzer-Wunsch 21.08.2026: "den knopf da weg bitte und
in die modie seite zu den modis hinzufügen und perfekt in die seite
anpassen"). Jetzt im Hero von team-modis.html, unter dem Lead-Text,
zentriert im bestehenden btn-row-Muster der Seite.

Cache-Busting-Version auf 20260821c erhöht.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-08-21 01:24:43 +02:00
DogFatherGitandClaude Sonnet 5 ed9b373a74 Husky-Bild auf streamer.html an Texthöhe angepasst statt fixem Mini-Deckel
Vorheriger max-height-Deckel (460px) fürs sehr hochkantige
streamer-mascot.jpg (900x2812) war zu knapp und ließ eine sichtbare
Lücke neben dem längeren Text ("die größe vom bild vom husky soll dem
text rechts nebendran angepasst werden"). Deckel auf 720px erhöht
(orientiert an der typischen Texthöhe in diesem Abschnitt), Grid-Stretch-
Ansatz ausprobiert und wegen Rückkopplung mit dem extremen
Seitenverhältnis verworfen (siehe Kommentare in main.css/streamer.html).

Cache-Busting-Version auf 20260821b erhöht (Cloudflare cached CSS/JS
sonst bis zu 4h am Edge).

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-08-21 01:21:31 +02:00
DogFatherGitandClaude Opus 5 1f87b54351 Nav umbenannt/umsortiert + Stimmen-Kachel und Zitat-Karten aufgewertet
Nutzer-Wuensche 20.08.2026 (2. Runde):
- Kategorie "DogFather" -> "Filipe", Kategorie "HasiDog" -> "Dogi&Hasi".
- Unterpunkt "Streamer" (streamer.html) aus "Filipe" heraus nach
  "Dogi&Hasi" verschoben, dort GANZ NACH OBEN (ueber "HasiDog") und in
  "DogFather" umbenannt.
- Unterpunkt "HasiDog-Welt" -> "HasiDog".
- Fusszeile zieht mit: Spaltenueberschrift nutzt jetzt dieselbe
  Kategorie-Bezeichnung wie die Nav ("Filipe" / "Dogi&Hasi & Manager"),
  streamer.html steht dort ebenfalls in der Dogi&Hasi-Spalte ganz oben.
  Die internen Schluesselnamen (nav_dogfather...) bleiben bewusst
  unveraendert -- reine Bezeichner, ein Umbenennen waere nur Fehlerquelle.

- "die kachel soll noch spezieller und geiler aussehen": Einreich-Kachel
  auf stimmen.html deutlich aufgewertet -- wandernder Farbverlauf-Rahmen
  (Zwei-Ebenen-/background-position-Technik, KEIN rotierender Ring: siehe
  dokumentierte Projekt-Lektion zu Verzerrungen auf eckigen Flaechen),
  schwebende Herz-Partikel, Medaillon statt nacktem Emoji,
  Farbverlauf-Ueberschrift, aufleuchtende Eingabefelder.
- "und auch die die danach kommen ... sollen viel geiler sein": freigegebene
  Stimmen sind jetzt echte Praesentationskarten -- farbige Akzentlinie oben,
  grosses Anfuehrungszeichen als Wasserzeichen, Avatar-Medaillon mit
  Anfangsbuchstabe, TikTok-Handle als eigener Chip, sanftes Anheben beim
  Ueberfahren.

Alles augenschonend gehalten (gedeckte Toene, langsame Bewegungen,
vollstaendiger Stillstand bei prefers-reduced-motion) und per Playwright
visuell geprueft, keine JS-Fehler.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-21 01:02:36 +02:00
DogFatherGitandClaude Opus 5 5146cef164 TikTok-Knoepfe fuer HasiDog + Modi-Gang, Zeitreise-Reihenfolge, Bildgroesse
Nutzer-Wuensche 20.08.2026:
- hasidog.html: TikTok-Knopf direkt unter der grossen Ueberschrift,
  Account @hasidog0804 (alle 5 Sprachen uebersetzt).
- streamer.html: TikTok-Knopf unter "Casper - mein treuer Begleiter",
  Account @dogis.modi.gang (alle 5 Sprachen uebersetzt).
- zeitreise.html: die beiden letzten Karten getauscht -- der Website-Start
  (21.08.2026, konkretes Datum) steht jetzt VOR der Teddy-Kooperation
  ("Datum folgt"), damit die Zeitleiste durchgehend chronologisch bleibt.
- streamer.html Bildgroesse gefixt ("der soll bissl kleiner sein und nicht
  so riesig"): streamer-mascot.jpg ist 900x2812 px und lief mit
  aspect-ratio:auto + height:auto in voller natuerlicher Hoehe -- rund
  dreimal so hoch wie die Textspalte daneben. Neue Klasse
  .collage-photo-kompakt deckelt die Hoehe auf 460px und laesst den Rahmen
  eng am Bild sitzen (width:fit-content), die ganze Figur bleibt sichtbar.
  Regel steht bewusst NACH ".collage-photo img" -- gleiche Spezifitaet,
  die spaetere gewinnt, sonst haette width:100%/height:100% sie aufgehoben.

Alles per Playwright verifiziert (beide Knoepfe mit korrekten Links,
Bildhoehe 460px statt ~1780px, neue Zeitreise-Reihenfolge), keine JS-Fehler.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-20 23:46:04 +02:00
DogFatherGitandClaude Opus 5 399260b805 "Stimmen" verwandelt: Fans reichen selbst Testimonials ein
Nutzer-Wunsch 20.08.2026: "eine richtig geile kachel ... wo die leute mit
namen und tiktok namen mir eine nachricht schreiben können die ich in die
verwaltung kriege, und dann kann ich die ausgewählten über die
verwaltungsseite auf die website hinzufügen ... das wird mega persoenlich
zu den fans, bitte wirklich krass geil speziell."

- Neue, augenschonend gestaltete Einreich-Kachel auf stimmen.html: Name,
  TikTok-Name (optional), Nachricht -- landet NIE automatisch oeffentlich,
  sondern immer erst als Entwurf in der Verwaltung.
  Warmer Babyblau/Rosé-Farbverlauf, wandernder Lichtschein, pulsierendes
  Herz -- ersetzt die 3 ewigen "Hier steht bald..."-Platzhalterkarten.
- Neue Verwaltungs-Sektion "💬 Stimmen verwalten": Warteschlange (offene
  zuerst), Freigeben/Ablehnen/Löschen pro Eintrag.
- Freigegebene Stimmen erscheinen automatisch in einer neuen, spezielleren
  Zitat-Kartenoptik (großes Anführungszeichen, Name + TikTok-Chip) --
  Abschnitt bleibt komplett unsichtbar, solange keine einzige freigegeben
  wurde.
- Backend: neue Tabelle `testimonials` (Migration 0006), routes/
  testimonials.js (oeffentliches Einreichen + Lesen freigegebener,
  admin-Warteschlange + Status/Loeschen mit neuer TESTIMONIALS_MANAGE-
  Berechtigung). 18 automatisierte Tests gegen eine Fake-DB bestanden.
- Alles per Playwright visuell durchgespielt: leerer Zustand, Einreichen
  -> Erfolgsmeldung, freigegebene Stimmen-Anzeige, Verwaltungs-Warteschlange
  mit allen Aktionen.

Backend-Teil (server-internal/, cloudflare-worker/migrations/) noch ohne
Deploy-Zugriff -- Dogi muss ihn manuell auf dogiintern ausrollen.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-20 23:37:31 +02:00
DogFatherGitandClaude Opus 5 519e209bce Zweite Live-Uhr fuer "spezielles Live-Event" + mehr Farbe im Radar
Nutzer-Wunsch 20.08.2026: "wuensch mir nur noch bissl farbe und sehr
wichtig ist dass ich auch spezielle live events da auch eintragen kann
in der verwaltungsseite so dass da eine zweite uhr erscheint wo die zeit
dann fuer dieses spezielle event laeuft."

- Neue Verwaltungs-Sektion "Spezielles Live-Event": Titel (Deutsch, wird
  automatisch uebersetzt), echtes Datum+Uhrzeit, optionaler Link, Aktiv-
  Schalter -- nur mit Titel + Zukunftsdatum aktivierbar.
- Zweite Uhr auf streamplan.html (Magenta/Violett statt Cyan/Gold, direkt
  neben der bestehenden), nur sichtbar wenn ein Event aktiviert ist und
  das Zieldatum noch nicht vorbei ist. Echter Countdown inkl. Tage (z.B.
  "2T 03:14:59"), "Jetzt"-Zeiger zeigt wie bei Uhr 1 die tatsaechliche
  Uhrzeit, der magentafarbene Fixpunkt markiert die Tageszeit des Events.
  Zieldatum wird als UTC gespeichert -- jede besuchende Person sieht den
  exakt richtigen Countdown in ihrer eigenen Zeitzone.
- "Bissl Farbe": bunter Farbverlauf (Cyan/Violett/Gold) auf dem aeusseren
  Ring statt reinem Grauton, kraeftigerer Sweep-Farbschein.
- Backend: neue routes/special-event.js (getSpecialEventPublic nur bei
  aktiv+zukuenftig, getSpecialEventAdmin fuer Entwuerfe, saveSpecialEvent
  mit Validierung), 13 automatisierte Tests gegen eine Fake-DB bestanden.
- Bugfix unterwegs gefunden (Playwright-Screenshot, wiederholtes Muster
  auf dieser Seite): .stream-radar-wrap blieb trotz [hidden]-Attribut
  sichtbar (display:block ueberschreibt die eingebaute [hidden]-Regel bei
  gleicher Spezifitaet) -- explizite Regel ergaenzt, per Playwright erneut
  verifiziert (display:none bestaetigt).

Backend-Teil (server-internal/) noch ohne Deploy-Zugriff -- Dogi muss ihn
manuell auf dogiintern ausrollen, sonst bleibt die zweite Uhr unsichtbar.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-20 23:24:17 +02:00
DogFatherGitandClaude Opus 5 7fdceadb9e Fix: Sprachschalter-Menue nicht mittig wie die Kategorie-Menues
Nutzer-Report per Screenshot-Vergleich: "Medien"-Kategorie ist mittig
unter dem Knopf, der Sprachschalter (DE/CH/EN/FR/PT) aber rechtsbuendig --
war bewusst so gebaut, als der Schalter noch ganz am rechten Rand sass.
Seit DogiCrew-/Bewerben-Knopf daneben stehen, ist genug Platz fuer
dieselbe zentrierte Ausrichtung wie ueberall sonst -- macht die Optik
konsistent und behebt nebenbei einen Detail-Fehler: der Verbindungspfeil
zeigte schon immer mittig, waehrend die Box selbst rechts daneben sass.
Per Playwright verifiziert: Dropdown jetzt exakt unter dem Knopf zentriert,
laeuft bei keiner getesteten Breite ueber den Rand.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-20 23:10:27 +02:00
DogFatherGitandClaude Opus 5 7dadd84cbb Neue Hintergrundbilder: Startseite (Trio) + Streamplan
Nutzer-Wunsch 20.08.2026: Startseiten-Hero (universe-trio.jpg) und
Streamplan-Hero (bg-streamplan.jpg/-mobile.jpg) durch neu bereitgestellte
Bilder ersetzt. Blur-Variante fuer die Startseite neu aus dem frischen
Bild erzeugt (Gaussian Blur, passend zur bestehenden Cover-Verlauf-Technik).
Mobile-Ausschnitt fuer Streamplan mehrfach nachjustiert, damit der
"STREAMPLAN"-Schriftzug im schmalen Hochformat-Crop komplett sichtbar
bleibt. Alte Bilder als .bak-20-08-2026 gesichert (nicht eingecheckt).
Referenzen mit Versions-Stempel (?v=) versehen, damit der neue Stand
sofort sichtbar ist statt bis zu 4 Std im Cache zu haengen.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-20 23:07:33 +02:00
DogFatherGitandClaude Opus 5 19636a25ec Fix: per Klick geoeffnetes Nav-Kategorie-Menue schloss sich nicht von selbst
Nutzer-Report per Screenshot: Klick auf eine Kategorie (z.B. "DogFather")
liess das Untermenue offen stehen, bis irgendwo anders hingeklickt wurde --
verliess man es einfach mit der Maus, blieb es haengen. Jetzt schliesst
sich ein per Klick geoeffnetes Menue automatisch, sobald die Maus die
Kategorie (Knopf + Untermenue) verlaesst -- nur auf echten Maus-Geraeten
(hover:hover + pointer:fine), auf Touch/Tablet aendert sich nichts, dort
gibt es kein "mit der Maus verlassen". Per Playwright verifiziert: Klick
oeffnet, Mausbewegung weg schliesst.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-20 22:56:49 +02:00
DogFatherGitandClaude Opus 5 a5615331aa Streamplan-Seite: interaktives Live-Radar statt schlichter Textkarten
Nutzer-Wunsch 20.08.2026: "diese seite vom streamplan soll viel geiler
und spezieller sein, ueberrasch mich."

Neues Herzstueck: ein 24-Stunden-Ziffernblatt (reines SVG, keine
Bild-Assets), das den festen 20-Uhr-Termin als dauerhaft leuchtenden
Fixpunkt zeigt (goldener Puls) und einen "Jetzt"-Zeiger in Echtzeit mit
der tatsaechlichen Uhrzeit der besuchenden Person mitbewegt (Babyblau,
DogFather-Markenfarbe). Nutzt denselben /live-status-Endpunkt wie die
Startseite:
- Offline: echter Sekunden-Countdown zum naechsten lokalen 20-Uhr-Termin.
- Live: komplettes Radar schaltet auf Rot/Puls um, zeigt den Stream-Titel
  und einen "Jetzt anschauen"-Knopf direkt zu TikTok.
Sanft rotierender Lichtschein fuer Atmosphaere, komplett augenschonend
(gedeckte Farben, respektiert prefers-reduced-motion vollstaendig).

Bugfix unterwegs gefunden (Playwright-Screenshot, dritte Wiederholung
desselben Musters heute): der "Jetzt anschauen"-Knopf blieb trotz
[hidden]-Attribut sichtbar, weil .btn selbst "display" setzt und damit
gleiche Spezifitaet wie die eingebaute [hidden]-Regel hat -- explizite
Regel ergaenzt.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-20 22:50:49 +02:00
DogFatherGitandClaude Opus 5 b3e191d3ca "Event des Jahres": Aktivieren-Schalter, leer bis befuellt, Detail-Fenster
Nutzer-Wunsch 20.08.2026: "diese zwei kisten sollen leer sein solang wie
ich nichts rein setze, am besten sollen die sogar immer nur erscheinen
wenn ich was rein setze und sie aktiviere ... wen ich drauf druecke dass
dann ein kleines fenster aufgeht wo das bild bissl groesser ist mit einem
groesseren text und beschreibung, und mit einem link ... die kacheln
sollen auch bissl spezieller sein."

- Kein hartkodierter Standardinhalt mehr auf der Startseite -- die Kachel
  UND der ganze Abschnitt bleiben komplett unsichtbar, bis mindestens ein
  Event in der Verwaltung ausgefuellt UND ueber einen neuen "Aktiv"-Schalter
  freigeschaltet ist. Genau 1 aktives Event -> zentrierte Einzelkachel
  statt halbleerem Zwei-Spalten-Raster.
- Klick auf eine Kachel oeffnet jetzt ein Detail-Fenster (groesseres Bild,
  groesserer Titel/Text, optionaler direkter Link) statt sofort
  wegzunavigieren.
- Kacheln bekommen einen goldenen Trophaeen-Akzent + dezenten wandernden
  Lichtschimmer statt der neutralen Standardkarten-Optik.
- Bugfix unterwegs gefunden (Playwright-Screenshot): .jahres-event-card
  blieb trotz [hidden]-Attribut sichtbar (dieselbe Ursache wie der
  frühere .jahres-event-bild-Bug: display:block ueberschreibt die
  eingebaute [hidden]-Regel bei gleicher Spezifitaet) -- explizite
  [hidden]-Regel ergaenzt.
- Backend: server-internal/routes/events.js liefert oeffentlich NUR noch
  aktivierte Slots aus (getEventsPublic), neuer authentifizierter Endpunkt
  getEventsAdmin liefert der Verwaltung auch Entwuerfe zum Vorausfuellen.
  10 automatisierte Tests gegen eine Fake-DB bestanden.

Backend-Teil (server-internal/) noch ohne Deploy-Zugriff -- Dogi muss ihn
manuell auf dogiintern ausrollen, sonst bleibt die Startseite beim alten
Verhalten (immer beide Slots zeigen, kein Aktiv-Schalter in der Verwaltung).

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-20 22:43:28 +02:00
DogFatherGitandClaude Opus 5 208b5ba4ed Fix: gemeinsame Navigationsleiste war auf der Verwaltungsseite ~16% groesser
Endlich gefunden (Screenshot-Vergleich Haupt-/Verwaltungsseite Seite an
Seite, exakt gleiche Fensterbreite): verwaltung.html setzt bewusst
`html { font-size: 18.5px }` fuer ihr eigenes "Jewelen-Tresor"-Design
(statt der normalen 16px) -- das ist eine GLOBALE rem-Basis und vergroesserte
dadurch ungewollt auch die gemeinsame, aus main.css/main.js kommende
Navigationsleiste um denselben Faktor (~16%). Dieselbe Leiste brauchte
dadurch spuerbar mehr Breite als auf jeder anderen Seite und lief bei
Fensterbreiten ueber, bei denen sie ueberall sonst laengst gut passte --
kein Cache-Problem, ein echter CSS-Bug, der die ganze vorherige
Fehlersuche erklaert.

Fix: die Navigationsleiste bekommt in verwaltung.html ihre Masse fest in
Pixel zurueck (exakt die Werte, die bei 16px-Basis herauskaemen) statt in
rem -- dadurch bleibt sie unabhaengig von der Basis-Schriftgroesse dieser
Seite exakt so gross wie ueberall sonst. Lokal verifiziert: beide Seiten
liefern jetzt bei identischer Fensterbreite exakt dieselbe Leisten-Breite
(1560px).

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-20 22:22:45 +02:00
DogFatherGitandClaude Opus 5 fece1dad56 Revert: Hamburger-Schwelle zurueck auf 1650px
Die Erhoehung auf 1900px eben war ein Fehlgriff -- der Nutzer sah dadurch
bei seiner eigentlichen Fensterbreite (die volle Desktop-Nav laengst
gepasst haette, zweifach live bestaetigt) nur noch die schmale Menue-
Ansicht statt der gewohnten vollen Leiste. 1650px war die korrekte,
bereits bestaetigte Schwelle -- das eigentliche Problem war durchgehend
Browser-/CDN-Caching, nicht die Schwelle selbst.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-20 20:06:18 +02:00
DogFatherGitandClaude Opus 5 0b0e7a2eb9 Nav-Sicherheitsabstand nochmal deutlich vergroessert (Hamburger bis 1900px)
Nutzer meldet weiterhin Ueberlauf trotz zweifach bestaetigtem Live-Test
(exakt seine Fensterbreite 1993x931 gegen den echten Server, 0 Ueberlauf,
mehrfach reproduziert) -- Ursache vermutlich hartnaeckiger lokaler Cache
im jeweiligen Browserprofil, nicht mehr abschliessend ferndiagnostizierbar.
Statt weiter zu diskutieren: Sicherheitsabstand brachial vergroessert,
unabhaengig von der genauen Ursache. Hamburger-Schwelle 1650px -> 1900px --
deckt praktisch jede Laptop-/Desktop-Fensterbreite ab, echte Desktop-Nav
zeigt sich jetzt erst ab sehr breiten Fenstern (>1900px), dort mit viel
Luft (min(1560px, 94vw)).

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-20 20:00:07 +02:00
DogFatherGitandClaude Opus 5 7099d80491 Sichtbarer "App installieren"-Knopf statt versteckter Browser-Funktion
Nutzer-Report: "ich kann sie immer noch nicht runter laden" -- Manifest +
Service Worker reichen technisch fuer Installierbarkeit, aber ohne
sichtbaren Knopf muss man wissen, dass Chrome/Edge das Adressleisten-
Symbol/3-Punkte-Meny dafuer versteckt. Jetzt: echter Knopf im Footer
("Als App installieren", jede Seite) und in der Verwaltung-Session-Leiste
("Als eigene App installieren"), nutzt beforeinstallprompt + prompt() --
loest pro Seite automatisch mit GENAU dem Manifest aus, das diese Seite
selbst verlinkt (index.html -> manifest.json, verwaltung.html ->
manifest-verwaltung.json), kein Sonderfall-Code noetig. Bleibt unsichtbar,
wenn der Browser das nicht unterstuetzt (Safari/iOS) oder die Seite schon
als App laeuft.

Ausserdem: eigener apple-mobile-web-app-title fuer verwaltung.html
("DogiCrew-Verwaltung" statt generisch "DogFather" beim iOS-Home-Bildschirm).

Cache-Busting-Version (?v=) erneut hochgezaehlt (20260820 -> 20260820b),
da main.js sich durch diese Aenderung erneut geaendert hat.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-20 19:30:42 +02:00
DogFatherGitandClaude Opus 5 4173e43c78 Cache-Busting fuer CSS/JS auf allen Seiten (?v=20260820)
Zusammen mit dem no-cache-Header-Fix in server/index.js: Cloudflare (die
Seite laeuft hinter einem orange-cloud-Proxy) liefert fuer .css/.js einen
eigenen festen Standard-Cache (Browser Cache TTL 4 Std) aus, UNABHAENGIG
vom Origin-Cache-Control -- der no-cache-Header allein reichte deshalb
nicht (per curl bestaetigt: main.css zeigte weiterhin max-age=14400 direkt
nach dem Deploy). Robuste, von Cloudflare-Zoneneinstellungen unabhaengige
Loesung: jede lokale CSS/JS-Referenz auf allen 34 Seiten bekommt einen
Versions-Query-String (?v=20260820) -- fuer Browser/CDN ist das eine neue
URL, alte gecachte Kopien werden dadurch nie mehr faelschlich weiterverwendet.

WICHTIG fuer kuenftige Aenderungen an main.css/main.js: das Datum in ?v=
muss bei der naechsten inhaltlichen Aenderung an einer dieser Dateien
wieder hochgezaehlt werden, sonst greift der Cache-Bust nicht erneut.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-20 19:26:11 +02:00
DogFatherGitandClaude Opus 5 6dad6a5af5 Fix: Deploys blieben bei Besuchern bis zu 4 Std im Browser-Cache haengen
Nutzer-Report: sah den Nav-Fix und die neue installierbare Verwaltungsseite
trotz erfolgreichem Deploy nicht. Ursache: Express schickt standardmaessig
KEIN Cache-Control mit -- da die Seite hinter Cloudflare (orange-cloud)
liegt, sprang Cloudflare dafuer mit seinem eigenen Standardwert ein
(Browser Cache TTL 4 Std, per curl bestaetigt: max-age=14400). Ein frischer
Deploy war dadurch bis zu 4 Std lang im eigenen Browser-Cache jedes/jeder
Besuchers unsichtbar. Cloudflare respektiert ein vom Origin gesetztes
Cache-Control -- jetzt explizit "no-cache" gesetzt (erzwingt Revalidierung
per ETag bei jedem Laden, kein Performance-Verlust durch schnelle
304-Antworten bei unveraendertem Inhalt).

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-20 19:23:42 +02:00
DogFatherGitandClaude Opus 5 2c5e04e433 Fix: manifest-verwaltung.json wurde von der Zugangsschranke blockiert
Die site-weite Zugangsschranke (server/gate.js) laesst bislang nur den
exakten Pfad /manifest.json unauthentifiziert durch (fuer die
PWA-Installierbarkeit der Haupt-Website noetig) -- das neue
manifest-verwaltung.json fiel dadurch nicht unter die Ausnahme und wurde
zur Login-Seite umgeleitet statt als JSON ausgeliefert zu werden. Neuen
Pfad zur Ausnahmeliste hinzugefuegt.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-20 16:43:23 +02:00
DogFatherGitandClaude Opus 5 aecf6db509 Verwaltungsseite als eigene, separat installierbare App
Nutzer-Wunsch 20.08.2026: "ich will die Verwaltungsseite auch herunter
laden koennen, so dass ich die originale website und die verwaltungsseite
2 mal getrennt installieren kann, auf dem pc und handy."

- Eigenes manifest-verwaltung.json (eigene "id"/"scope" nur fuer
  verwaltung.html, eigener Name "DogiCrew-Verwaltung", eigenes
  Icon-Set) statt des site-weiten manifest.json (scope "/") -- macht sie
  zu einer technisch eigenstaendigen App-Identitaet, installierbar
  parallel zur Haupt-Website, auf Desktop und Handy.
- Neue Icons: bestehendes Husky-Logo mit Violett/Gold-Verlauf statt
  Babyblau (passend zum "Jewelen-Tresor"-Look der Verwaltungsseite),
  damit beide installierten Apps auch optisch klar unterscheidbar sind.
- Kein zweiter Service Worker noetig -- /sw.js laeuft bereits site-weit
  auf Scope "/" und deckt verwaltung.html automatisch mit ab.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-20 16:42:20 +02:00
DogFatherGitandClaude Opus 5 94182cc6ab Fix: Desktop-Nav lief ab ~1500px Fensterbreite ueber den Rand hinaus
Nutzer-Report per Screenshot: "DogiCrew"-Knopf/"BALD"-Badge rechts
abgeschnitten. Ursache: die Hamburger-Schwelle (1480px) und der
Nav-Bar-Breiten-Deckel (1440px) wurden schon zweimal knapp nachgezogen,
reichten aber nicht mehr, seit die Nav um den "DogiCrew"-Knopf + "BALD"-
Badge gewachsen ist (braucht jetzt real ~1491px). Ergebnis: bei JEDER
Fensterbreite ab ca. 1500px (nicht nur in einer schmalen Uebergangszone)
lief die Nav dauerhaft ~50px ueber den Rand.

Diesmal mit echtem Sicherheitsabstand statt wieder nur knapp behoben:
Schwelle 1480px -> 1650px, Deckel 1440px -> 1560px. Per Playwright ueber
den kompletten Bereich 1024-2560px nachgeprueft, keine Ueberlaeufe mehr.
Header ist site-weit eine gemeinsame Vorlage (main.js/main.css), Fix gilt
damit automatisch fuer alle Seiten.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-20 16:38:46 +02:00
DogFatherGitandClaude Opus 5 bda3198c76 Neue Funktion: Supporter-Abstimmungen (Verwaltung + DogiCrew-Bereich)
Naechste "Ausbaustufe" aus Dogfather_VanVan_Supporter_Abo.odt Abschnitt 20
(siehe Supporter-Abo-System.md), auf Nutzerwunsch "perfektioniere meine
Verwaltungsseite": Dogi/VanVan koennen in verwaltung.html eine Frage mit
2-6 Antwortoptionen auf Deutsch erstellen, automatische Uebersetzung beim
Speichern (gleiches Muster wie "Event des Jahres"). Jede aktive DogiCrew-
Person sieht die Abstimmung in ihrem Supporter-Bereich, stimmt genau einmal
ab (UNIQUE-Constraint in der DB, nicht nur Anwendungslogik), sieht danach
die Live-Ergebnisse. Admin-Seite zeigt Ergebnisbalken live, kann schliessen/
wiedereroeffnen/loeschen.

- Neue Migration 0005_supporter_polls.sql (supporter_polls,
  supporter_poll_votes), neue Berechtigung POLLS_MANAGE.
- server-internal/routes/polls.js: 30 End-to-End-Tests gegen eine
  Fake-DB bestanden (better-sqlite3 laesst sich lokal nicht kompilieren).
- verwaltung.html: neue "Abstimmungen"-Kiste im bestehenden
  vw-overview-box-Stil (violett/pink Ergebnisbalken).
- supporter.html: neue "Aktuelle Abstimmung"-Karte im bestehenden
  Gold-Look, Optionen -> Stimme -> Ergebnisbalken, alle 5 Sprachen.

Backend-Teil (server-internal/, cloudflare-worker/migrations/) noch ohne
Deploy-Zugriff -- Dogi muss ihn manuell auf dogiintern ausrollen.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-20 16:07:51 +02:00
DogFatherGitandClaude Opus 5 189b72ec73 Vorschau-Umschalter (Theatermasken-Symbol) vor dem oeffentlichen Start deaktiviert
Nutzer-Wunsch 20.08.2026, vor morgigem oeffentlichem Start: "die leute
sollen das ja nicht selbst auswaehlen koennen". Der Schalter erkannte
Dogi/VanVan bisher nur ueber das rein client-seitig lesbare dogi_role-
Cookie (bewusst NICHT das echte HttpOnly-Sicherheits-Cookie) -- technisch
liesse sich dieses Cookie per Browser-Konsole selbst setzen. Echte Daten
waeren dadurch nie einsehbar (nur eigene Beispieldaten-Vorschau), aber
"soll weg fuer die Oeffentlichkeit" heisst hier bewusst ganz weg, nicht
nur sicherer.

Nur der Aufruf beim Seitenaufbau ist auskommentiert, renderVorschauSchalter()
selbst bleibt unangetastet fuer ein spaeteres internes Testen.

Per Playwright verifiziert: Widget erscheint weder bei normalem Besuch
noch mit manuell gesetztem dogi_role-Cookie.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-20 15:16:01 +02:00
DogFatherGitandClaude Opus 5 f86b96a22f "Event des Jahres" jetzt in der Verwaltung pflegbar (Bild, Text, Link)
Nutzer-Wunsch 20.08.2026: "will ich in der admin seite das selbst
gestalten können, mit bild und text und am besten auch einen link." Auf
Rueckfrage entschieden: Titel/Text nur auf Deutsch eingeben, die anderen
4 Sprachen werden beim Speichern automatisch uebersetzt (MyMemory, 0€,
kein API-Key) -- bewusste Ausnahme von der sonst geltenden "immer echte
Uebersetzung"-Regel, klar dokumentiert und im Admin-UI selbst als Hinweis
sichtbar. de-CH bekommt denselben deutschen Text (Dialekt ist keine von
Uebersetzungs-APIs unterstuetzte Zielsprache).

Backend (server-internal):
- routes/events.js: getEventsPublic (oeffentlich, keine Session),
  saveEvent + uploadEventImage (beide hinter neuer EVENTS_MANAGE-
  Berechtigung, Owner immer erlaubt). Speichert in der bereits
  bestehenden app_settings-Tabelle (2 feste Slots) statt einer neuen
  Tabelle -- es gibt nie mehr als genau 2 Events.
- lib/translate.js: MyMemory-Anbindung mit "fail closed auf Deutsch"
  pro Sprache, falls der Dienst mal nicht antwortet.
- Bild-Upload per multer, zufaelliger Dateiname (crypto.randomUUID,
  verhindert Path-Traversal ueber den Originalnamen komplett), 5 MB
  Limit, nur jpeg/png/webp, Ablage unter /var/lib/dogfather-internal/
  uploads/events (NICHT im Git-Ordner -- uebersteht Deploys), oeffentlich
  ausgeliefert unter /uploads.
- Neue Berechtigung EVENTS_MANAGE im Katalog (Gruppe "Startseite").

Frontend:
- index.html: laedt /events-of-year beim Aufruf, ueberschreibt pro Slot
  Datum/Titel/Text/Bild/Link NUR wenn dort tatsaechlich etwas gespeichert
  ist -- bleibt der Abruf aus oder ist ein Slot leer, bleibt der bisherige
  fest eingebaute Standardinhalt (dieselben zwei echten Events) stehen.
  Kein Blocker, kein sichtbarer Fehler bei Ausfall.
- verwaltung.html: neue Sektion "🏆 Event des Jahres" (nur mit
  EVENTS_MANAGE sichtbar), 2 Karten mit Bild-Upload+Vorschau, Datum,
  Titel, Text, Link, eigenem Speichern-Knopf pro Event.

Ausfuehrlich getestet, weil server-internal wegen fehlender Visual-
Studio-Build-Tools auf dieser Windows-Maschine nicht lokal mit echtem
better-sqlite3 laufen kann: routes/events.js komplett isoliert gegen eine
Fake-DB getestet (11 Szenarien: oeffentlicher Abruf, fehlende Session,
Session ohne Recht, Owner, Rolle MIT EVENTS_MANAGE, alle Validierungen,
Bild-Upload inkl. falscher Dateityp, Abruf des hochgeladenen Bilds).
index.html per Playwright mit echtem Netzwerk-Mocking gegen zwei
Szenarien getestet (API nicht erreichbar -> Standardinhalt bleibt; API
liefert echte Daten -> nur der befuellte Slot wird ueberschrieben, der
leere bleibt Standard). Dabei einen echten CSS-Bug gefunden und behoben
(display:block auf .jahres-event-bild überschrieb die [hidden]-Regel des
Browsers, leeres Bild waere immer sichtbar gewesen). verwaltung.html per
Playwright mit gemocktem Login+API end-to-end getestet: Formular wird
korrekt vorbefuellt, Bild-Upload + Speichern senden die richtigen Daten.

WICHTIG: server-internal laeuft unter einem eigenen Systembenutzer
(dogiintern), auf den ich (claudian) bewusst KEINEN Zugriff habe -- diese
Aenderung kann ich anders als sonst nicht selbst bis auf den Server
bringen. Dogi muss den Deploy-Schritt fuer server-internal selbst
ausfuehren (git pull + npm install + Neustart des dogiintern-Dienstes).

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-20 15:09:54 +02:00
DogFatherGitandClaude Opus 5 3f3ba835a9 Patricks Zitat ergaenzt
Nutzer-Wunsch 20.08.2026: "Wege entstehen dadurch, dass man sie geht."
(alle 5 Sprachen). Ersetzt "Zitat folgt" auf der Scout-Karte.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-20 14:28:11 +02:00
DogFatherGitandClaude Opus 5 f8f3e65603 Streamer-gesucht-Seite: neues Hero-Bild (Spicy Media, rot)
Nutzer-Wunsch 20.08.2026: bg-bewerben-creator.jpg + -mobile.jpg (bisher
unscharfes Selfie mit pinker Sonnenbrille) ersetzt durch das vom Nutzer
gelieferte Motiv (Spicy-Media-Look, rot, Silhouette + Logo). Alte Version
lokal gesichert (*.jpg.bak-20-08-2026, nicht eingecheckt).

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-20 14:22:01 +02:00
DogFatherGitandClaude Opus 5 f6cbaec132 Zeitreise: Karte "Das Manager-Team wächst" entfernt
Nutzer-Wunsch 20.08.2026. Karte (Juli 2026) samt zugehoeriger i18n-Keys
(zr_ev8_date/_h3/_p, alle 5 Sprachen) entfernt. 16 -> 15 Karten.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-20 13:16:32 +02:00
DogFatherGitandClaude Opus 5 5c5accd12c Neues Links-Hero-Bild + echtes Community-Foto statt Platzhalter
Nutzer-Wunsch 20.08.2026:
- links.html: neues, vom Nutzer geliefertes "aus dem Universum"-Motiv
  (Weltraum-Szene mit TikTok/Instagram/Snapchat/Discord/Merch-Icons um ein
  "LINKS"-Portal) ersetzt bg-links.jpg + -mobile.jpg. Alte Version lokal
  gesichert (*.jpg.bak-20-08-2026, nicht eingecheckt).
- community.html, Abschnitt "Mehr als Follower": echtes Team-Foto
  (Diene, Ghost, VanVan, Dogi bei einem gemeinsamen Treffen, "TEAM DOGI")
  ersetzt den "Foto folgt"-Platzhalter. Gleiches Muster wie vanvan.html
  (.collage-photo, aspect-ratio:3/4 statt der alten 4/3-Platzhalterbox,
  da das echte Foto Hochformat ist). Jetzt ungenutzte i18n-Keys
  com_bild_platzhalter/com_foto_folgt entfernt.

Per Playwright verifiziert: beide Seiten laden fehlerfrei, keine
fehlgeschlagenen Requests, keine Konsolenfehler.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-20 12:54:53 +02:00
DogFatherGitandClaude Opus 5 071f3d0382 Startseite: neue "Event des Jahres"-Kachel unter den 3 Welt-Kacheln
Nutzer-Wunsch 20.08.2026: volle Breite wie die 3 Welt-Kacheln zusammen,
zeigt immer genau zwei Events. Erste Belegung mit zwei bereits auf
zeitreise.html dokumentierten echten Events (28-Stunden-Stream 7. März
2026, Creator Cup 27. Juli - 2. August 2026) statt Platzhaltertext --
Texte sind gekuerzte, inhaltlich unveraenderte Fassungen der bestehenden
Zeitreise-Beschreibungen, beide Karten verlinken auf zeitreise.html. Alle
5 Sprachen gepflegt. Gleiche Karten-/Tag-Optik wie die Welt-Kacheln, damit
es wie ein natuerlicher vierter Baustein wirkt statt wie ein fremdes
Element.

Per Playwright verifiziert: exakt gleiche Breite wie .hero-grid (1180px),
2 Karten, kein horizontales Scrollen auf Mobil, keine Konsolenfehler.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-20 12:51:17 +02:00
DogFatherGitandClaude Opus 5 9adebd9bc4 KRITISCH: Server-Quellcode + kompletter Git-Verlauf waren oeffentlich abrufbar
Sicherheits-Audit vor dem geplanten oeffentlichen Start morgen (21.08.2026,
Nutzer-Anfrage: "duerfen die leute keinen zugriff auf veraenderungen haben").
SITE_DIR ist der GESAMTE Repo-Ordner (join(__dirname, "..")), express.static
lieferte daher nicht nur die Website aus, sondern auch:
- server/ (inkl. gate.js, das komplette Sicherheitskonzept im Klartext)
- server-internal/ (Admin-/Supporter-Backend-Quellcode)
- cloudflare-worker/ (altes Backend)
- .git/ (VOLLSTAENDIGE Commit-Historie, rekonstruierbar per Git-Dump)
- CLAUDE.md, DEPLOY.md, wrangler.toml, netlify.toml, gate-worker.js,
  gate.html.bak-07-08-2026 (Alt-Backup-Datei einer frueheren Session)

Live nachgewiesen (mit gueltigem Zugangscode -- morgen faellt die Schranke
fuer ALLE weg): /server/gate.js und /.git/config lieferten HTTP 200.
Ursache: serve-static blockt per Default nur Dateien, deren EIGENER Name
mit einem Punkt beginnt (server/.env -> zufaellig schon 404), aber NICHT
rekursiv -- .git/config wird trotzdem ausgeliefert, weil "config" selbst
nicht mit einem Punkt beginnt, nur der Ordner davor.

Fix: eigene Sperr-Middleware VOR express.static, unabhaengig von
gateMiddleware (bleibt also auch nach dem Entfernen der Zugangsschranke
wirksam). Blockt ganze Ordner (server/, server-internal/,
cloudflare-worker/) + versteckte Ordner/Dateien rekursiv (jedes
Pfadsegment, das mit "." beginnt, ausser .well-known) + eine feste Liste
an Alt-Dateien + jedes *.bak-Muster, damit auch kuenftige Backup-Reste
automatisch mitgeschuetzt sind.

Lokal mit echtem Express-Server verifiziert (gateMiddleware absichtlich
deaktiviert, um exakt den morgigen "oeffentlich"-Zustand zu simulieren):
alle vorher gefundenen Luecken jetzt 404, alle echten Seiten/Assets
(index.html, main.css, main.js, manifest.json, robots.txt, favicon)
weiterhin 200.

Getrennt prooft: server-internal/ (eigener Dienst unter
postfach.dogfather-universe.com, Port 4200) hat sein EIGENES,
unabhaengiges Session-System -- jede /admin/*-Route ist einzeln per
requireTeamSession-Middleware abgesichert (in index.js durchgezaehlt,
keine Ausnahme gefunden), live mit einer unauthentifizierten Anfrage
gegen /admin/users/list bestaetigt (401). Dieser Dienst war nie vom
Website-Gate abhaengig und ist von diesem Fund nicht betroffen.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-20 12:47:36 +02:00
DogFatherGitandClaude Opus 5 1d28d8db2b Kooperation-Seite: Hero-Bild nochmal ausgetauscht (verfeinerte Version)
Nutzer-Wunsch 20.08.2026 (zweite Runde): neues, verfeinertes Motiv (DogFather-
Logo oben, Filipe sitzend mit HasiDog + Husky, "INTERESSE AN EINER
KOOPERATION? JETZT KONTAKT AUFNEHMEN") ersetzt die Version vom selben Tag.
Theme bleibt dogfather/babyblau (passt weiterhin). Alte Version lokal
gesichert (*.jpg.bak-20-08-2026-v2, nicht eingecheckt).

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-20 12:26:59 +02:00
DogFatherGitandClaude Opus 5 7a69f896bc Dienes Profiltext: Alter durch Geburtsmonat ersetzt
Nutzer-Wunsch 20.08.2026: "Ich bin 37 Jahre alt" -> "Ich bin im August 1988
geboren" (und analog in allen 5 Sprachen), Rest des Satzes (verheiratet,
Mutter von zwei Kindern) unveraendert. Betrifft nur bioHtml.de/de-CH/en/
fr/pt in data-modis.js, keine anderen Vorkommen von "37" im Text.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-20 12:06:48 +02:00
DogFatherGitandClaude Opus 5 bfcf35aafa Kooperation-Seite: neues Hero-Bild + Theme Rot -> Blau
Nutzer-Wunsch 20.08.2026: Hintergrundbild von bewerben-kooperation.html
(bg-bewerben.jpg + -mobile.jpg, beide bisher identisch zum alten roten
Spicy-Media-Motiv "WERDE TEIL VON SPICY MEDIA") ersetzt durch das vom
Nutzer geschickte neue Motiv (HasiDog/DogFather/Husky, "EINE KOOPERATION
WOLLEN? DANN HIER MELDEN", bereits babyblau statt rot). Passend dazu
data-theme von "spicymedia" (Rot/Orange) auf "dogfather" (Babyblau/Lila)
umgestellt -- keine hartkodierten Rot-Werte im HTML, daher genuegt die
Theme-Umstellung fuer Knopf-/Link-/Eyebrow-Farben komplett.

Bild aus PNG-Quelle konvertiert (quality=90, optimize+progressive), Seiten-
verhaeltnis/Aufloesung unveraendert uebernommen (kein Hochskalieren). Alte
Bilder lokal gesichert (*.jpg.bak-20-08-2026, nicht eingecheckt).

Per Playwright verifiziert: data-theme=dogfather, --accent=#8fd9ea, keine
fehlgeschlagenen Requests, keine Konsolenfehler, Formular/Footer sehen im
echten (nicht-fullPage-)Screenshot nach dem Scrollen korrekt dunkel aus --
ein zunaechst gefundener "weisser Kasten" war ein reines Playwright-
fullPage-Screenshot-Artefakt (position:fixed-Hintergrund kachelt beim
kuenstlich verlaengerten Full-Page-Screenshot nicht mit), kein echter Bug,
per echtem gescrolltem Viewport-Screenshot gegengeprueft und ausgeschlossen.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-20 12:04:05 +02:00
DogFatherGitandClaude Opus 5 02f9509042 Zeitreise-Finale-Punkt-Bug + Preis aus dem Abonnieren-Hero-Bild entfernt
1) Nutzer-Report 20.08.2026 ("wieso dieser Punkt da in der Mitte"):
.zeit-node (der leuchtende Zeitleisten-Punkt) ist bei normalen Karten
position:absolute; left:50%; top:50% relativ zu .zeit-ast -- korrekt, weil
die Karte dort nur die halbe Breite einnimmt. Die Finale-Karte
(.zeit-final) wird aber auf fast volle Breite gestreckt und zentriert,
der Knoten landete dadurch mitten im Zitat-Text. Die Verbindungslinie
(::before) wurde dafuer schon frueher ausgeblendet, der Knoten selbst
wurde dabei uebersehen -- jetzt nachgezogen (display:none fuer
.zeit-final .zeit-node).

2) Nutzer-Wunsch 20.08.2026: der Preis "FÜR 4,99 € MONATLICH" stand fest
ins Hero-Bild von abonnieren.html eingebrannt (bg-abonnieren.jpg +
-mobile.jpg, beide Dateien waren identisch) -- per CSS/Text nicht
erreichbar, siehe bereits dokumentierter Fund vom selben Tag. Per Pillow
sauber herausretuschiert (Clone-Stamp aus einem textfreien Bereich
derselben Schaltflaeche, exakt auf die Zeilenhoehe inkl. Ü-Umlautpunkte
skaliert, Nahtstellen weich gezeichnet, mit numpy-Helligkeitsanalyse
zeilenweise gegengeprueft bis keine Text-Reste mehr uebrig waren) --
"ABONNIEREN" bleibt als eigenstaendiger Button stehen, keine sichtbare
Lücke/Leerstelle. Qualitaet/Dateigroesse an das Original angepasst
(quality=90, optimize+progressive, exakt vergleichbare Groesse). Original
lokal gesichert (bg-abonnieren.jpg.bak-20-08-2026, nicht eingecheckt).

Beide Fixes per Playwright verifiziert: Knoten-Punkt display:none bei der
Finale-Karte, Hero-Bild laedt fehlerfrei ohne fehlgeschlagene Requests,
keine Konsolenfehler.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-20 11:49:26 +02:00
DogFatherGitandClaude Opus 5 7e369c72ae Zeitreise: echte Daten fuer "Team Dogi entsteht" + "geht online"
Nutzer-Wunsch 20.08.2026:
- "Team Dogi entsteht": "Datum folgt" -> "Anfang 2025" (neuer Key
  zr_ev2_date, alle 5 Sprachen). Bleibt an ihrer Stelle -- liegt weiterhin
  chronologisch vor "Ostern 2025".
- "DOGFATHER UNIVERSE geht online": "2026 - Datum folgt" -> "21. August
  2026, 21 Uhr" (morgen, live). Bleibt ebenfalls an ihrer Stelle.

Per Playwright komplette Reihenfolge erneut gegengeprueft: weiterhin
chronologisch korrekt, keine Konsolenfehler.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-20 11:36:47 +02:00
DogFatherGitandClaude Opus 5 895f04c524 Zeitreise: echtes Datum fuer "Start als Content Creator" (24.10.2023)
Nutzer-Wunsch 20.08.2026. Neuer i18n-Key zr_ev1_date (alle 5 Sprachen),
Karte bleibt weiterhin an erster Stelle, da 2023 das fruehste Datum der
gesamten Zeitleiste ist. Per Playwright die komplette Reihenfolge erneut
durchgezaehlt: weiterhin korrekt, keine Konsolenfehler.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-20 11:33:55 +02:00
DogFatherGitandClaude Opus 5 f750fe9dfd Zeitreise: echte Daten fuer Buch + Spotify, chronologisch einsortiert
Nutzer-Wunsch 20.08.2026: "Das Buch HasiDog & Casper" (November 2025) und
"HasiDog startet auf Spotify" (1. Januar 2026) hatten bisher "Datum folgt"
und lagen dadurch weit hinten in der Zeitleiste, obwohl beide zeitlich vor
dem 28-Stunden-Stream (7. März 2026) liegen. Neue i18n-Keys zr_ev13_date/
zr_ev14_date (alle 5 Sprachen) ergaenzt, beide Karten an die chronologisch
richtige Stelle verschoben: Ostern 2025 -> November 2025 (Buch) ->
1. Januar 2026 (Spotify) -> 7. März 2026 (28-Stunden-Stream) -> ...

"Kooperation mit VanVan Teddys" bleibt bewusst unveraendert bei "Datum
folgt", da dafuer noch kein Datum genannt wurde.

Per Playwright die komplette Reihenfolge alle 16 Karten durchgezaehlt und
gegengeprueft: chronologisch korrekt, keine Konsolenfehler.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-20 11:26:19 +02:00
DogFatherGitandClaude Opus 5 9cb4e177ee Zeitreise: 4 Ereignisse entfernt + einladender "wächst noch"-Hinweis
Nutzer-Wunsch 20.08.2026: vier Zeitleisten-Karten sollten komplett weg
("Ein neues Kapitel beginnt" / Mai 2026, "Die ersten betreuten Creator",
"Weitere Scouts und Manager kommen hinzu", "Das erste Community-Treffen") --
entfernt aus zeitreise.html samt der zugehoerigen, jetzt ungenutzten
i18n-Keys (zr_ev5_*, zr_ev16_*, zr_ev17_*, zr_ev18_*). 20 -> 16 Karten.

Zusaetzlich: gleich am Seitenanfang soll auffallen, dass diese Zeitreise
noch nicht fertig ist. Bewusst NICHT die alte .todo-note-Optik reaktiviert
(die war fuer Entwickler gedacht und wurde am 31.07.2026 sitewide bewusst
unsichtbar gemacht) -- stattdessen ein neuer, fuer Besucher gestalteter
Hinweis (.zeit-baustelle), der zum Wachstums-Baum-Thema der Seite passt
(🌱 "Der Anfang" oben, 🌳 "...wächst weiter" unten): "Diese Zeitreise
wächst noch", babyblauer Glow-Rahmen, leicht wiegendes Setzlings-Icon.
Alle 5 Sprachen gepflegt.

Per Playwright verifiziert: alle 4 Karten wirklich weg (Text-Suche),
16 statt 20 .zeit-ast-Elemente, Hinweisbox sichtbar mit korrektem Text,
keine Konsolenfehler.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-20 11:23:38 +02:00
DogFatherGitandClaude Opus 5 c4fa132244 DogiCrew-Sperre: auch die Registrierungsfelder selbst nicht mehr eintippbar
Nutzer-Feedback 20.08.2026 (direkte Nachpruefung): "ich kann immer nur was
rein tippen, soll garnicht möglich sein bitte" -- der Registrieren-Knopf
war gesperrt, aber Name/TikTok/E-Mail-Feld ließen sich weiterhin normal
beschreiben. Jetzt disabled, exakt wie das E-Mail-Feld im Login-Panel
(voriger Commit). Per Playwright verifiziert: echter Tippversuch in allen
drei Feldern hinterlässt keinen Wert mehr.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-20 11:10:26 +02:00
DogFatherGitandClaude Opus 5 d98133faba DogiCrew-Sperre vervollstaendigt: Login-Einstieg, E-Mail-Feld, Preis
Nutzer-Feedback 20.08.2026 (Nachpruefung des vorherigen Commits): der
Registrieren-Knopf war gesperrt, aber drei Luecken blieben offen --

1. "Schon Supporter? Hier einloggen" fuehrte zu einem VOLL FUNKTIONSFAEHIGEN
   Login-Code-Anfordern-Knopf. E-Mail-Feld jetzt disabled (nicht eintippbar,
   wie gewuenscht) und btn-login-request auf denselben .btn-gold-locked-Stil
   wie der Registrieren-Knopf umgestellt (natives disabled-Attribut).
2. Dritte, bislang uebersehene Luecke: "Mit Google anmelden" waere ein
   weiterer Weg gewesen, trotz gesperrter Knoepfe ein echtes Konto anzulegen,
   falls GOOGLE_CLIENT_ID serverseitig konfiguriert ist. initGoogleConsent()
   wird jetzt nicht mehr aufgerufen, solange die Registrierung gesperrt ist --
   ein Kommentar markiert genau die Stelle zum spaeteren Reaktivieren.
3. Der Preis (4,99 €) durfte laut Nutzer noch nicht sichtbar sein -- war aber
   an zwei Stellen zu sehen: der grossen Preis-Zahl in der Box (jetzt
   "Coming soon…" im selben Gold-Schimmer-Stil wie der gesperrte Knopf) und
   im Fliesstext (ab_text2, alle 5 Sprachen: "Für 4,99 € im Monat" ->
   "Mit deinem/dim/your/ta/sua monatlichen Beitrag", nur die erste Teilphrase
   geaendert, Rest jeder Uebersetzung unangetastet).

Betrifft ausschliesslich den oeffentlichen Anmelde-Einstieg -- bereits
eingeloggte Supporter (Dogi/VanVan als Test-Accounts) sind ueber ihren
gespeicherten Token/supporter.html unveraendert erreichbar.

Bekannter, NICHT in diesem Commit geloester Rest: der grosse Hero-Banner
oben auf der Seite (assets/img/bg-abonnieren(-mobile).jpg) zeigt den Preis
ebenfalls fest ins Bild eingebrannt ("ABONNIEREN FÜR 4,99 € MONATLICH") --
das ist Bildmaterial, keine Text-/CSS-Aenderung, braucht Ruecksprache mit
Dogi bevor daran gearbeitet wird.

Vor dem Commit per Playwright verifiziert: Preis-Box zeigt nur noch
"Coming soon…", Login-E-Mail-Feld nimmt keine Eingabe an, Klick auf den
gesperrten Login-Knopf loest keinen /supporter/login-request-Aufruf aus,
Google-Bereich bleibt hidden, keine Konsolenfehler.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-20 11:07:24 +02:00
DogFatherGitandClaude Opus 5 5cd473e71a DogiCrew-Registrierung: "Coming Soon"-Sperre + Bald-Badge im Nav-Knopf
Nutzer-Wunsch 20.08.2026: DogiCrew ist "das geilste Bonus" -- der Registrieren-
Knopf soll noch nicht bedienbar sein (Dogis PayPal-Business-Zugangsdaten fehlen
noch, siehe DogFather Website - Offene Punkte.md), aber Besucher sollen ueber
den Nav-Knopf trotzdem ganz normal auf die Seite kommen und die Vorschau sehen
duerfen -- "soll alles bleiben" ausser dem einen Knopf.

- Nav-Knopf (DogiCrew/Abo aktivieren, main.js renderAboButton): neues kleines
  Schimmer-Badge "Bald" direkt in der Pille (main.css .nav-cta-soon, reine
  Wiederverwendung von .btn-silver-text/-spark in kleinerem Massstab). Nur auf
  den drei Zielen, die zur (noch gesperrten) Registrierung fuehren -- NICHT auf
  supporter.html, das ist der echte, bereits funktionierende Bereich fuer
  Dogi/VanVan als Test-Supporter.
- abonnieren.html: Registrieren-Knopf ersetzt durch neue .btn-gold-locked-
  Komponente -- eigener Gold/Schloss-Stil (nicht das schon anderswo auf dieser
  Seite vergebene .btn-silver), natives disabled-Attribut (kein JS noetig,
  disabled-Buttons feuern keine Click-Events -- der bestehende Listener bleibt
  unveraendert und inert). Formularfelder bleiben normal ausfuellbar (Teaser),
  nur der Absende-Knopf ist gesperrt.

Bug waehrend der Umsetzung gefunden UND behoben, nicht nur uebersehen: die
rotierende Conic-Gradient-Randmaske von .btn-silver/.btn-legendary (copy-paste
als erster Versuch) verzieht sich auf diesem sehr langgestreckten 100%-Breite-
Knopf zu einer krummen Schlaufe -- exakt die dokumentierte Lektion in
Projektregeln.md Punkt 14 (03.08.2026, TikTok-Button-Bug), die beim ersten
Entwurf übersehen wurde. Per Playwright-Screenshots über mehrere Animations-
Frames nachgewiesen (nicht nur vermutet) und auch am bereits LIVE laufenden
.btn-silver auf dieser Seite reproduziert, um auszuschliessen, dass es an der
neuen Komponente statt an der Technik selbst liegt. Fix: derselbe sichere
Zwei-Layer-Background-Trick wie bei .abo-google-frame (gleiche Datei) --
Bewegung nur ueber background-position, bleibt geometrieunabhaengig exakt an
der Kontur. Nach dem Fix erneut ueber mehrere Frames verifiziert, sauber.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-20 10:51:34 +02:00
DogFatherGitandClaude Opus 5 0223fcf9cd Mobil-Menü: schwebende Eck-Knöpfe blockierten Sprachschalter + Bewerben-Button
Nutzer-Report 20.08.2026: "auf dem Handy... passt nicht immer alles". Per echter
Mobil-Emulation (iPhone 15 Pro + Pixel 8, Playwright) nachgestellt statt geraten:
Die schwebenden Eck-Knöpfe (Musik-Widget unten rechts, Vorschau-Umschalter fuer
Dogi/VanVan unten links) sind absichtlich immer sichtbar (position:fixed, direkte
<body>-Kinder). Beim aufgeklappten Mobil-Hamburger-Menü lagen sie dadurch sichtbar
UEBER den untersten Menuepunkten (Sprachschalter "DE" + "Bewerben"-Knopf) und
verdeckten sie -- auf Screenshots klar zu sehen, betrifft jede der ueber 30 Seiten,
da das Menü ueberall gleich ist. Genau die Art Bug, die im Browser (Adressleiste
noch da, man kann drumrum navigieren) kaum auffaellt, aber in der installierten
Vollbild-App voll durchschlaegt.

Fix: :has()-Selektor blendet beide Widgets aus, solange .nav-links.open ist --
kein gemeinsamer Elternknoten mit dem Menue vorhanden, daher CSS statt weiterer
main.js-Logik. Nach dem Fix per Regressionstest ueber 6 Seiten x 2 Geraete erneut
verifiziert: Widgets erscheinen normal wieder, sobald das Menue schliesst, keine
neuen Konsolenfehler, kein horizontales Scrollen.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-20 10:28:22 +02:00
DogFatherGit 44086b0407 Manager-Seite: TikTok-Button zur Spicy-Media-Agentur ergänzt
Bei der Spicy-Media-Agentur-Sektion auf manager.html einen TikTok-Button
(gleicher .btn-tiktok-Stil wie bei Dogi/den Modis) hinzugefügt, der direkt
zum Agentur-Profil @spicymediaagentur verlinkt, damit Besucher von dort
sofort weiterklicken können.
2026-08-20 10:13:15 +02:00
DogFatherGitandClaude Opus 5 50371d5404 Zugangs-Sperre traf ALLE Besucher gleichzeitig statt nur den Verursacher
Nutzer-Report 19.08.2026: "ich komme auf der .com nicht rein" -- der RICHTIGE Zugangscode
wurde mit "Falscher Zugangscode" abgewiesen.

Ursache: gateClientKey() nutzte req.ip. Das ist hier NICHT die IP des Besuchers, sondern
die des Cloudflare-Knotens (Kette Besucher -> Cloudflare -> Caddy -> Express; bei
trust proxy: 1 bleibt genau Cloudflare uebrig). Damit teilten sich alle Besucher EINEN
Fehlversuchs-Zaehler -- fuenf Vertipper von irgendwem sperrten die Seite fuer jeden,
15 Minuten lang.

Live nachgewiesen, nicht vermutet: derselbe richtige Code wurde ueber
dogfather-universe.com abgelehnt und im selben Moment ueber www.dogfather-universe.com
akzeptiert -- zwei Namen, zwei Cloudflare-Knoten, zwei getrennte Zaehler.

Fix 1 -- echte Besucher-IP aus CF-Connecting-IP. Dieser Header war am 05.08.2026 bewusst
verworfen worden, weil er faelschbar war, solange der Server auch direkt unter seiner IP
erreichbar war. Diese Voraussetzung gilt nicht mehr: die Firewall laesst 80/443 nur noch
aus den Cloudflare-Netzen zu. Vor der Umstellung von aussen gegengeprueft -- Direktzugriff
auf beide Ports kommt gar nicht mehr zustande, der Header kann also nur von Cloudflare
stammen. Abhaengigkeit im Code vermerkt: wird der Direktzugriff je wieder geoeffnet, muss
diese Stelle zurueckgebaut werden. Ungueltige Header-Werte fallen sauber auf req.ip zurueck.

Fix 2 -- ehrliche Meldung bei Sperre (429 statt 401), mit Restzeit in Minuten. Die bisher
absichtlich identische Meldung sollte Angreifern nichts verraten, hat aber in der Praxis
den Besitzer der Seite selbst ratlos gemacht: richtiger Code, Anzeige "Falscher
Zugangscode", keine Chance zu erkennen dass nur eine Wartezeit laeuft. Die Sperre bleibt
in voller Laenge bestehen, der Code wird dadurch nicht leichter erratbar.

Fix 3 -- abgelaufene Eintraege werden aufgeraeumt. Pro echter Besucher-IP kann die Map
sonst unbegrenzt wachsen (vorher gab es nur eine Handvoll Cloudflare-Knoten).

Regressionstest ergaenzt (server/test-gate.mjs, 12 Pruefungen). Gegen den ALTEN Code
laufen gezielt 5 davon auf Fehler -- darunter "Dogi kommt trotz fremder Sperre rein" --,
gegen den neuen alle gruen. Der Test faengt also wirklich diesen Bug.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-19 20:21:46 +02:00
DogFatherGitandClaude Opus 5 80dbfc9367 Handy-App reparieren: Zugangsseite war nicht installierbar + Knopf ohne Rueckmeldung
Nutzer-Report 19.08.2026: "komm auf dem Handy nicht rein, hab es installiert und
klappt nicht" / "er nimmt meinen Code nicht an".

Hauptursache war ein veralteter Zugangscode (nur Doku, kein Code) -- beim Nachpruefen
kamen aber drei echte Fehler auf der Zugangsseite zutage, alle nur auf dem Handy spuerbar:

1. gate.html war NICHT installierbar. Ohne gueltige Sitzung leitet gate.js jeden Aufruf
   hierher um -- es ist also der Bildschirm, von dem aus man die App installiert. Genau
   dort fehlten Manifest-Verweis und Service-Worker-Registrierung, die Chrome fuer eine
   echte App verlangt (index.html hatte beides laengst, gate.html laedt main.js bewusst
   nicht). Wer vor dem ersten Login installierte, bekam nur eine leere Verknuepfung.
   Exakt derselbe Fehler wie am 07.08.2026 in VanVans Shop, hier nie aufgefallen.

2. Der "Oeffnen"-Knopf gab keinerlei Rueckmeldung und die Anfrage hatte kein Zeitlimit.
   Bleibt im Mobilfunknetz eine Antwort aus, haengt fetch() unbegrenzt -- es sieht aus,
   als sei der Tap nicht angekommen. Jetzt: Knopf sperrt sich sofort und zeigt "Wird
   geprueft...", Abbruch nach 10s mit klarer Meldung (AbortController), Doppel-Tap
   ignoriert. Letzteres ist hier besonders wichtig, weil server/gate.js nach 5
   Fehlversuchen die IP fuer 15 Minuten sperrt -- Doppel-Taps zaehlten bisher mit.

3. apple-touch-icon fehlte im GESAMTEN Projekt. iOS ignoriert das Manifest fuer das
   Startbildschirm-Symbol und liest nur dieses Tag -- auf dem iPhone gab es deshalb einen
   unscharfen Seiten-Screenshot statt des Logos. Neu erzeugt (180x180, vollflaechig ohne
   Alpha: iOS faerbt Transparenz schwarz, und icon-512.png hat nachgemessen transparente
   Ecken). Zentral ueber main.js in alle 34 Seiten eingehaengt statt 34x kopiert;
   gate.html hat es statisch, da ohne main.js.

Zusaetzlich maskable-Icons ergaenzt: Android beschneidet das Startsymbol auf einen Kreis.
Per Simulation der Sicherheitszone nachgemessen -- das bisherige Icon haette 19,87% des
Logos verloren (Husky-Ohren + Schriftzug). Die neuen Varianten (60%/59% Fuellgrad) liegen
bei exakt 0 abgeschnittenen Pixeln, Fuellgrad dafuer schrittweise eingemessen statt geraten.

Markenfarbe #8FD9EA aus dem vorhandenen Icon ausgelesen, keine neue Farbe erfunden.
Validiert: node --check, Manifest-JSON, Tag-Balance, alle 8 Pflicht-Zutaten vorhanden.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-19 20:13:10 +02:00
DogFatherGit fed6a1f7c7 Impressum auf Luxemburg-Recht korrigiert + Zugangsseite auf 2 Kacheln umgebaut
- kontakt.html: Anbieterkennzeichnung zitierte faelschlich deutsches Recht
  (§5 TMG) trotz Sitz in Luxemburg. Jetzt korrekt Art. 5 der loi modifiee
  du 14 aout 2000 relative au commerce electronique. Telefonnummer ergaenzt
  (in Luxemburg fuer die Anbieterkennzeichnung ueblich, in Deutschland nicht
  zwingend noetig - dort galt bislang keine). Veraltete "§55 Abs.2 RStV"-Zeile
  entfernt: gilt inhaltlich wie rechtlich nicht (deutsches Landesmedienrecht,
  Sitzlandprinzip, zudem kein journalistisch-redaktionelles Angebot). EU-OS-
  Streitschlichtungslink + VSBG-Erklaerung ergaenzt (fehlten bisher, bei
  bezahltem Supporter-Abo EU-weit vorgeschrieben).
- gate.html: gemeinsame Zugangs-Box fuer Dogi/VanVan durch 2 getrennte
  Kacheln ersetzt (gleiches Muster wie bereits in verwaltung.html), nur die
  Kacheln selbst neu - Hintergrund/Logo/Buehne unveraendert. Beide Formulare
  rufen weiterhin denselben /gate-auth-Endpunkt auf, Rollen-Erkennung bleibt
  serverseitig ueber die Zugangscodes (server/gate.js unveraendert).
2026-08-07 12:53:54 +02:00
DogFatherGit d6489f787a Sicherheits- und Stabilitaetskorrekturen nach vollstaendiger Pruefung
- Login-Sperre war umgehbar: clientKey() vertraute dem Header CF-Connecting-IP.
  Bei Cloudflare war das sicher (CF ueberschreibt ihn), auf dem eigenen Server nicht:
  der Ursprungsserver ist auch direkt unter seiner IP erreichbar, dort konnte der
  Header frei gesetzt und die 5-Versuche-Sperre komplett ausgehebelt werden
  (nachgewiesen). Jetzt req.ip hinter trust proxy.
- Absturzsicherheit: Express 4 faengt Fehler aus async-Handlern nicht ab, eine
  einzige fehlerhafte Anfrage konnte den ganzen Dienst beenden. wrap() um alle
  Handler, zentraler Fehler-Handler, unhandledRejection/uncaughtException-Netz.
- Sicherheits-Header (X-Content-Type-Options, X-Frame-Options, Referrer-Policy,
  Permissions-Policy, HSTS) wurden bisher nur ueber die Datei _headers gesetzt,
  die auf dem eigenen Server wirkungslos ist. Jetzt im Express-Server.
- x-powered-by abgeschaltet.
- Datenschutzerklaerung/AGB: nannten Cloudflare als Hoster und eine Cloudflare-D1-
  Datenbank. Jetzt korrekt netcup (Rechenzentrum Nuernberg) als Hoster, Cloudflare
  als vorgeschaltetes CDN mit Drittlandhinweis.
2026-08-05 22:33:31 +02:00
DogFatherGit 61729d4f12 Zugangs-Sperre: Code wird nach dem Schliessen des Browsers wieder gefragt
Sitzungs-Cookie ohne maxAge/expires statt 90-Tage-Cookie; zusaetzlich
Notbremse von 12 Stunden im signierten Token, falls ein Browser sehr
lange offen bleibt.
2026-08-05 20:00:15 +02:00
DogFatherGit 59343b459c Frontend auf den neuen eigenen Postfach-Server umgestellt
API_BASE_URL/API_BASE zeigen jetzt auf https://postfach.dogfather-universe.com
(eigener Server-internal-Dienst) statt auf den Cloudflare Worker
dogfather-universe-postfach.dogfather1608.workers.dev.
2026-08-05 19:15:25 +02:00
DogFatherGit e87aca3019 Postfach/Team-Verwaltung/Supporter-Abo als Node.js/Express-Server portiert
Vollständiger 1:1-Port des cloudflare-worker/ (dogfather-universe-postfach)
auf server-internal/: Bewerbungs-Postfach mit Rollen/Rechten, Team-
Zugangsverwaltung (verschlüsselte Owner-only-Codes), DogiCrew-Supporter-Abo
(PayPal Subscriptions, Google-Login, Resend-E-Mail, 30-Monats-Prämienzyklus)
und automatische TikTok-Live-Erkennung. D1 -> better-sqlite3, Cloudflare-
Cron -> node-cron. Läuft ohne gesetzte Secrets weiter (PayPal/Google/Resend/
Ticketanizer/Discord bleiben "nicht konfiguriert" statt kaputt), bis die
echten Zugangsdaten eingetragen werden.
2026-08-05 18:57:19 +02:00