99b5dd4eb2030759d675c48a7096c5304af0aa7b
33
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
99b5dd4eb2 |
CRYONOVA Schritt 3: Feldfokus, Blickfaenge, Testkorrekturen
Der Feldfokus zeigt jetzt den Ion-Rand und den weichen Schein, den das
Design-System auf Seite 15 verlangt. Er fehlte, weil der allgemeine
Tastaturring seinen dunklen Innenring darueberlegte: Dessen Selektor hat
Spezifitaet 0,3,0, die Feldregel nur 0,2,1 -- und Spezifitaet schlaegt
Reihenfolge, egal wie weit unten die Regel steht. Eingabefelder sind
jetzt vom Innenring ausgenommen; sie brauchen ihn nicht, weil sie selbst
eine dunkle Flaeche sind. Der Aqua-Umriss bleibt fuer alle erhalten.
Die zwei Blickfang-Motive stehen jetzt auch wirklich auf einer Seite:
das Wappen auf "Ueber mich", direkt nach dem Absatz ueber die Herkunft
des Namens, der Monolith auf "Portfolio" zwischen Einleitung und den
echten Projekten. Beide als Zierbild ausgezeichnet -- ihre Aussage steht
schon im Text daneben. Auf dem Handy laedt automatisch die kleine
Fassung.
Vier Fehler steckten in der Pruefung selbst, nicht im Stilblatt:
- Sie griff das erste "input" der Anfrageseite. Das sind aber sechs
optisch versteckte Auswahl-Radios, kein Textfeld.
- Sie mass ohne Fensterfokus. Ein Browser wendet :focus nur an, wenn das
Fenster selbst den Fokus hat -- das DOM meldet trotzdem brav
matches(":focus") === true, die Farbe bleibt die alte.
- Sie mass mitten im Uebergang, bevor die Animation stand.
- Und sie zaehlte Schattenebenen an "),", einem Muster, das in keinem
Schattenwert je vorkommt. Geprueft wird jetzt die Anforderung selbst:
Ion-Farbe und ein Weichzeichner ueber 0.
Geprueft: 334 Pruefungen gruen (CRYONOVA 53, Blickfang 13, Abmelden 16,
Angebot 54, Abbruch 42, System 5, Automatik 55, Angebote 56, Kette 40).
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
e92daed103 |
CRYONOVA Schritt 2: Bildwelt, Materialien, Rangsystem, Status
Setzt die restlichen Kapitel des Design-Systems um (Seiten 7, 14, 16, 19, 24-29). Wie Schritt 1 ausschliesslich Farbe, Material und Licht -- Aufbau, Navigation, Texte und Funktionen bleiben unangetastet. BILDWELT (Seiten 24-29) Die Motive sind jetzt echte Seitenhintergruende: Ring auf Startseite und Portal, Kristallwelt an der Zugangswand. Ueber jedem Motiv liegt eine Navy-Glasflaeche -- das System fordert auf Seite 31 ausdruecklich, dass bei Bedarf "eine Navy- oder Frost-Glasflaeche zwischen Bild und Inhalt" liegt. Ohne sie waere Text auf den hellen Kristallspitzen nicht sicher lesbar, und genau dort macht ein schoenes Bild eine Seite unbrauchbar. Von 2,5 MB auf 96-229 KB (WebP), auf dem Handy 30-73 KB. Das System nennt fuer Mobile ausdruecklich Ladezeit als Kriterium. DAS LOGO IM BILD -- eine Entscheidung gegen die woertliche Vorgabe Zwei der drei Motive zeigen das Dogfather-Logo gross in der Mitte. Als Seitenhintergrund waere das ein zweites Logo neben dem echten in der Kopfzeile: zwei Marken, die um dieselbe Aufmerksamkeit ringen. Beim ersten Versuch schien es an der Zugangswand hinter den Karten durch (gemessen 15,9 % helle Flaeche im Logobereich). Die Zugangswand nutzt deshalb jetzt einen Ausschnitt der linken Bildhaelfte -- dieselbe Kristallwelt, dasselbe Licht, nur ohne Wappen. Die Logo-Motive bleiben als Blickfang-Klasse erhalten, dort wo sie fuer sich stehen duerfen. MATERIALIEN (Seite 7) Optic Glass, Frosted Ice, Prism Edge und Void Navy als Klassen. "Hell" heisst auf einer dunklen Seite aufgehelltes Navy, nicht Weiss -- echtes Weiss waere ein Loch im Bildschirm, und das System verbietet weisse Vollflaechen ausdruecklich. RANGSYSTEM (Seite 14) Drei Stufen fehlten: Premium (Indigo), VIP (Champagne), Gefahr (Coral). Wenn jeder Knopf gleich laut ist, ist keiner mehr laut. Zwei bewusste Abweichungen von der naheliegenden Loesung: - Indigo steht als FLAECHE unter hellem Text, nie als Schriftfarbe. Es erreicht als Text nirgends 4,5:1 (gemessen 3,25-4,29). Der Test haelt das dauerhaft fest. - Gefahr ist NICHT vollflaechig rot. Ein voll gefuellter roter Knopf zieht den Blick staerker an als die Hauptaktion und wird dadurch versehentlich gedrueckt. Kritische Aktionen sollen auffindbar sein, nicht verlockend. FOKUSRING (Seite 19) Doppelter Aqua-Ring: 2 px Aqua aussen, dunkler Innenring. Kein Schmuck -- ein einfacher heller Ring verschwindet auf hellen Flaechen, ein dunkler auf dunklen. Die Kombination ist auf JEDEM Untergrund sichtbar. STATUS-SPEKTRUM (Seite 16) Acht Zustaende. Die Klasse faerbt nur -- den Text liefert immer das Markup. Es gibt bewusst keine Variante, die nur einen farbigen Punkt zeigt: Wer Farben nicht unterscheiden kann, saehe dann gar nichts. Der Test prueft, dass keine Statusmarke ohne Text existiert. Dabei einen eigenen Fehler gefunden und behoben: Ich hatte beim Bauen des Premium-Knopfes selbst einen losen Hex-Wert eingesetzt -- genau das, was Token-Regel 05 verbietet und was der Test dann meldete. Geprueft: 43 (CRYONOVA, von 24 erweitert) + 0 Fundstellen (WCAG ueber 12 Seiten x 5 Sprachen, jetzt MIT Bildhintergruenden) + 55 + 40 + 69 + 54 + 42 + 16 + 5 + 20 + 64 + 58 -- alles gruen. |
||
|
|
de8819f1fd |
CRYONOVA: Farb- und Lichtsystem nach dem Design-System umgesetzt
Umsetzung des Design-Systems "Baby Blue Optical Luxury" (Edition 2.0), Schritt 1 von mehreren: die zentrale Farbquelle. Nach der Kernregel auf Seite 3 ist das ausdrücklich ein Farb- und Licht-Redesign — Aufbau, Navigation, Texte und Funktionen bleiben unangetastet. FARBEN Grundflächen auf die vier Tiefenebenen des Systems (Void, Midnight, Obsidian, Deep Glass). Palette nach Seite 5: Signature Baby, Ion Blue, Hyper Aqua, Aurora Violet, Prism Indigo, Liquid Gold, Signal Coral, Chrome Silver. Die Variablen behalten ihre alten NAMEN (--wd-blau statt --cryo-baby). Ein Umbenennen hätte über 155 Fundstellen anfassen müssen — viel Bewegung ohne sichtbaren Nutzen, mit der realen Gefahr, eine Stelle zu übersehen und danach zwei fast gleiche Blautöne zu haben. Entscheidend ist die Rolle, nicht der Name; die Systembezeichnungen stehen als Kommentar daneben. EIN FEHLER IM DESIGN-SYSTEM, DER BEWUSST NICHT ÜBERNOMMEN WURDE Die Token-Liste auf Seite 20 ist um eine Zeile verrutscht — Namen und Hex-Werte passen dort nicht zusammen. Am folgenreichsten: --cryo-baby stünde auf #0C2740, einem fast schwarzen Navy, und ist laut Seite 21 zugleich die Standard-Lumenfarbe. Das Mauslicht wäre damit praktisch unsichtbar geworden — ausgerechnet der Effekt, den das System auf fünf Seiten als unantastbar schützt. Maßgeblich ist deshalb die Palette auf Seite 5 und die Lumen-Logik auf Seite 9, die untereinander stimmig sind. MAUSLICHT Der bestehende Effekt bleibt vollständig erhalten (Systemauflage) und bekommt eine Farbvariable pro Kachel: --wd-lumen. Vorher war die Farbe im Verlauf fest verdrahtet, und jede weitere Kachelfarbe hätte zwei neue Blöcke gebraucht (Fläche + leuchtende Kante). Bei sechs Lumen-Rollen wären das zwölf fast gleiche Blöcke gewesen, die beim nächsten Feinschliff zwangsläufig auseinanderlaufen. Jetzt setzt die Kachel nur ihre Farbe, der Verlauf steht einmal da — genau das meint Token-Regel 02 mit "Kachelfarbe steuert Lumenfarbe". 38 lose Hex-Codes durch Token ersetzt (Token-Regel 05). Drei davon (#3d9dbd, #7c5cd6, #a8873a) waren noch die ALTEN Markenfarben und hätten still neben den neuen weitergelebt — genau der Mechanismus, durch den Oberflächen mit der Zeit zwei fast gleiche Töne bekommen. KONTRASTE NACHGERECHNET Die Palette ist auf dunklem Grund durchweg stark (9,7 bis 19,8:1) — mit einer Ausnahme: Prism Indigo erreicht auf keiner Fläche 4,5:1 (nur 3,25 bis 4,29). Es ist deshalb ausschließlich für Kanten, Verläufe und große Premium-Flächen zugelassen, nie für Fließtext. Das System sieht Indigo ohnehin nur für "Premium-Momente" vor — die Rechnung bestätigt die Regel, statt ihr zu widersprechen. NEUER TEST: pruef-cryonova.mjs (24 Prüfungen) Palette, Grundflächen, Mauslicht-Erhalt, echte Zeigerbewegung, keine losen Hex-Codes, Kontraste und die Frage, ob alle 12 Seiten wirklich aus derselben Quelle schöpfen. Dabei drei Fehlalarme im eigenen Test gefunden und behoben — jeder davon hätte dauerhaft rote Zeilen erzeugt und irgendwann dazu geführt, dass man eine echte Meldung übersieht: - Halbtransparente Flächen müssen über ihren Untergrund gerechnet werden. Der aktive Reiter kam sonst auf 1:1 statt echter 8,25–10,23:1. - Text auf Farbverläufen liefert rgba(0,0,0,0) als Hintergrund; der Hauptknopf kam so auf 1:1 statt rund 11:1. - Die Maus muss mit Zwischenschritten bewegt werden, sonst feuert pointermove nicht. Eine Direktmessung bestätigte: Das Licht folgt einwandfrei (30px → 723px, Deckkraft 1). pruef-system.mjs auf den neuen Markenton gesetzt. Dass er dort zunächst "0 von 1804 Elementen" meldete, war kein Fehler, sondern der Beweis, dass der alte Ton nirgends mehr vorkommt. Geprüft: 24 (CRYONOVA) + 0 Fundstellen (Design/WCAG über 12 Seiten × 5 Sprachen) + 40 + 56 + 69 + 54 + 42 + 55 + 5 + 16 — alles grün. |
||
|
|
305920d872 | Cache-Version fuer die Portal-Korrektur (Countdown vor Anzahlung) | ||
|
|
8726110035 |
Angebote in der Oberflaeche: schicken und im Portal zusagen
VERWALTUNG
Der Angebotsbereich steht in der Anfrage-Detailansicht ueber dem
direkten Annehmen. Der uebliche Weg ist: Angebot raus, Kunde sagt zu,
Projekt entsteht -- direkt anzunehmen ist der Sonderfall (man hat schon
telefoniert). Stuende der Sonderfall oben, waere er der naheliegende
Griff, und man verschenkte den Beleg, den eine Zusage im Portal erzeugt.
Vorbelegt sind Paket, Preis, Anzahlung, Laufzeit, Ablaufdatum und der
komplette Leistungstext. Zu tun bleibt: Paket bestaetigen, Preis
bestaetigen. Der Leistungstext ist eingeklappt statt die Seite zu
fluten, aber aenderbar.
Ein Paketwechsel laedt ALLES neu -- auch den Leistungstext. Ein
stehengebliebener Text vom vorigen Paket waere der schlimmste Fall: Er
ginge unbemerkt hinaus, und im Angebot staende etwas, das zum Preis
nicht passt. Genau das prueft der Test.
PORTAL
Die Angebotskarte steht ganz oben, vor allen Projekten: Ein Angebot ist
das Einzige im Portal, das eine ENTSCHEIDUNG verlangt -- alles andere
ist Auskunft. Der eingefrorene Leistungstext wird lesbar aufbereitet
(Zwischenueberschriften, Punkte), nicht als Textblock hingeworfen.
Vor der Zusage wird gefragt, und die Frage nennt die Folgen ('verbindlich',
'Anzahlung'). Nicht aus Foermlichkeit: Hier entsteht ein Vertrag, und ein
Knopf, der beim Danebentippen einen Auftrag ausloest, waere eine Falle.
Beim Ablehnen wird NICHT gefragt -- das ist folgenlos.
ZWEI FEHLER GEFUNDEN, BEIDE IM NORMALFALL
- Die Angebotskarten standen im Zweig 'es gibt Projekte'. Ein Kunde mit
offenem Angebot hat aber typischerweise noch KEIN Projekt -- genau der
Normalfall -- und saeh damit nichts. Der Server lieferte das Angebot,
die Seite zeichnete es nur nie. Nur im Browsertest sichtbar.
- Eine Antwort ohne 'nachrichten' liess das Postfach werfen, und weil der
Fehler den Aufbau abbrach, erschien danach GAR NICHTS mehr -- auch nicht
das Angebot, das ueber allem stehen sollte. Dieselbe Sorte wie zuvor im
Cockpit: Ein halber Server ist ein realistischer Fall.
Neun Sprachschluessel in fuenf Sprachen ergaenzt.
Geprueft mit 54 Pruefungen auf Computer und Handy, die messen, was
tatsaechlich an den Server geht. Alle bestehenden weiter gruen.
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
658febb6c5 |
Abbruch-Dialog und Farbunterscheidung meins/beim Kunden
ABBRECHEN IN DER OBERFLAECHE Der Server konnte es seit gestern, die Knoepfe fehlten. Jetzt steht am Ende der Projektansicht ein zurueckhaltender Knopf -- bewusst nicht zwischen den anderen: Es ist die seltenste und endgueltigste Handlung an einem Projekt, und ein gleich lauter Knopf daneben laedt zum Verwechseln ein. Beim Aufklappen rechnet die Seite vor: wie viele Schritte erledigt sind, wie viel gezahlt wurde, wie viel davon verdient ist, und was sich daraus als Erstattung ergibt. Der Betrag steht als Vorschlag im Feld und ist aenderbar -- geprueft wird, dass der GEAENDERTE Wert hinausgeht und nicht der vorgeschlagene, sonst waere das Feld eine Attrappe. Gerechnet wird erst beim Aufklappen, nicht beim Oeffnen der Projektansicht: Dazwischen kann man Punkte abgehakt haben, und die Zahlen sollen den Stand von JETZT zeigen. Faellt die Vorschau aus, laesst sich der Betrag von Hand eintragen -- ein ausgefallener Rechendienst darf kein Projekt in der Liste festhalten. Ein bereits abgebrochenes Projekt bekommt keinen Knopf mehr, sondern einen Kasten mit Datum, Grund, wer abgebrochen hat und was zu erstatten war. MEINS ODER SEINS Wunsch: 'ich will dass die kunden sachen auch in der verwaltungs seite von kacheln eine andere farbe haben wie meine damit ich sie gut unterscheide.' Was bei mir liegt, bleibt im Markenblau. Was beim Kunden liegt, bekommt Lila. Gemessen: rgb(127,208,232) gegen rgb(183,157,255). Bewusst NICHT ueber Rot/Gruen: Die Warnstufen sind an das ALTER vergeben und muessen frei bleiben. Eine Kachel, die gleichzeitig 'beim Kunden' und 'seit acht Tagen ueberfaellig' faerben muesste, koennte nur eine der beiden Aussagen zeigen -- und die Frist ist die wichtigere. Dazu eine 3px-Kante links auf beiden Seiten. Farbe allein traegt die Aussage nicht: Wer sie nicht unterscheiden kann, saehe sonst zwei gleich aussehende Bloecke (WCAG 1.4.1). Die Kante ist ein Gegensatz, keine Markierung einer Gruppe -- meins blau, seins lila. Geprueft mit 42 Pruefungen auf Computer und Handy, die messen, was tatsaechlich an den Server geht und welche Farben wirklich berechnet werden. Alle bestehenden Pruefungen weiter gruen. Co-Authored-By: Claude Opus 5 <[email protected]> |
||
|
|
65b98ace89 |
Die Uhr laeuft erst, wenn die Anzahlung da ist
Bisher begann der Liefertermin mit der Annahme. Das ist unfair in beide Richtungen: Wer zehn Tage bis zur Zahlung braucht, verbraucht zehn Tage der zugesagten Zeit, ohne dass ein Handschlag Arbeit passiert waere -- und ich stehe am Ende als der da, der seinen Termin reisst. Ein Projekt hat jetzt drei Abschnitte statt zwei: 1. angenommen, wartet auf Anzahlung -> Uhr steht 2. Anzahlung da -> Uhr laeuft, Termin ab HEUTE neu 3. uebergeben oder abgebrochen -> Uhr steht wieder Der Zahlungseingang loest alles Weitere von selbst aus: Uhr starten, Termin neu rechnen, Status von briefing auf design, 'wer ist am Zug' auf mich, Benachrichtigung in der Verwaltung. Der bei der Annahme genannte Termin bleibt als termin_geplant_am erhalten, und die Meldung nennt BEIDE -- so sieht man, dass sich etwas verschoben hat, ohne nachrechnen zu muessen. Eingehaengt an der Stelle, an der beide Wege zusammenlaufen (PayPals Meldung UND das Vermerken von Hand). Nur am Webhook haenge sich die Seite verschieden verhalten, je nachdem WIE das Geld ankam -- eine von Hand verbuchte Zahlung startete die Uhr nie. Zwei Grundsaetze fuer die Automatik: Sie setzt Dinge in Gang, nimmt aber nie eine Entscheidung zurueck, die ein Mensch getroffen hat (ein von Hand pausiertes Projekt wird nicht kommentarlos wieder gestartet). Und jeder Schritt hinterlaesst eine Spur im Verlauf UND als Meldung -- eine Automatik, die stillschweigend arbeitet, ist kein Helfer, sondern ein Raetsel. ABBRECHEN Ein angenommener Auftrag bleibt abbrechbar: Der Kunde zahlt nicht, meldet sich nicht, springt ab. Vorschau und Ausfuehrung sind getrennt -- die Seite rechnet aus dem Aufgabenfortschritt vor, wie viel Leistung erbracht wurde, und schlaegt daraus einen Erstattungsbetrag vor. Der Betrag ist ein VORSCHLAG: Ob im Einzelfall mehr oder weniger angemessen ist, haengt an Dingen, die keine Tabelle kennt. Offene Rechnungen werden storniert (eine Zahlungsaufforderung ohne Gegenleistung), bezahlte bleiben unangetastet, und die Rueckzahlung loest die Seite bewusst NICHT selbst aus -- PayPal-Rueckzahlungen sind nicht umkehrbar. BENACHRICHTIGUNGEN Eigene Tabelle statt im Verlauf: Der Verlauf haelt fest, WAS geschehen ist -- vollstaendig, zum Nachschlagen. Eine Benachrichtigung ist ein Anstupsen, das gelesen und weggelegt wird. Beides in einer Tabelle hiesse: entweder ein Verlauf voller Rauschen oder Meldungen, die man nicht wegklicken kann. Wegklicken markiert nur als gelesen, loescht nichts. Dazu die Liste der Projekte, die seit ueber einer Woche auf ihre Anzahlung warten. Sie stehen in keiner anderen Zahl, weil ihre Uhr nie zu laufen begann -- ohne diesen Hinweis vergisst man sie. Geprueft: 44 gegen eine echte Datenbank. Darunter der Kern -- die Annahme wird zehn Tage zurueckdatiert, und der Termin muss danach trotzdem volle 20 Werktage entfernt liegen. Beim Bauen des Tests selbst ein Fehler gefunden: Die erste Fassung datierte nur die Annahme zurueck, nicht den damals errechneten Termin, und bildete damit genau den Fall nicht ab, um den es geht. Co-Authored-By: Claude Opus 5 <[email protected]> |
||
|
|
6b818fd6f6 |
Abmelden meldet jetzt wirklich ab
Rueckmeldung: 'der abmelde button klappt auch nicht auf dem handy'. Die Ursache war nicht das Handy -- der Fehler war auf beiden Geraeten derselbe, auf dem Handy sieht man das kurze Aufblitzen nur eher. Der Knopf beendete die Team-Sitzung, loeschte den Schluessel und lud neu. Das Merkmal der Zugangswand blieb dabei im Browser stehen. Beim Neuladen holt sich die Seite damit sofort wieder einen Ausweis -- man war nach einer Zehntelsekunde erneut angemeldet, und der Knopf schien nichts zu tun. Jetzt werden BEIDE Sitzungen beendet (der Endpunkt dafuer gab es laengst, die Verwaltung rief ihn nur nie auf), und man landet an der Zugangswand statt in einer Codeeingabe. Das ist auch die ehrliche Bedeutung des Wortes: Wer sich abmeldet, will draussen sein. Beide Aufrufe sind einzeln abgesichert -- faellt einer aus, laeuft der andere trotzdem. Ein halbes Abmelden waere schlimmer als keins: Man hielte sich fuer abgemeldet und waere es nicht. Geprueft mit 16 Pruefungen auf Computer und Handy, die messen, was tatsaechlich hinausgeht statt ob sich etwas auf dem Schirm bewegt. Dabei ein Artefakt im eigenen Test gefunden und behoben: Das Vorbereitungsskript lief bei jeder Navigation und setzte den Schluessel auf der Zugangswand gleich wieder -- zwei Pruefungen massen also sich selbst. Co-Authored-By: Claude Opus 5 <[email protected]> |
||
|
|
2ae77fc54f |
Verwaltung: eine Suche ueber alles, mit Tastatur bedienbar
Bisher gab es genau ein Suchfeld, und es durchsuchte nur die Anfragenliste. Wer den Namen eines Kunden im Kopf hatte, musste raten, in welchem Reiter er nachsehen muss: War das eine Anfrage, ein laufendes Projekt, eine offene Rechnung? Bei drei Vorgaengen merkt man sich das, bei dreissig nicht mehr. Jetzt: Strg+K von ueberall, auf dem Handy der Lupenknopf oben. Ein Aufruf durchsucht Anfragen, Kunden, Projekte und Zahlungen; jeder Treffer traegt seinen Zusammenhang (Nummer, Kunde, Betrag, Liefertermin) und fuehrt per Enter in den passenden Reiter, bei einer Anfrage direkt in die Detailansicht. Gebaut nach dem ARIA-Muster 'Combobox mit Listbox-Popup' aus den W3C Authoring Practices -- nachgeschlagen, nicht aus dem Gedaechtnis: role=combobox am Eingabefeld, aria-expanded, aria-controls, aria-activedescendant, role=listbox, role=option mit aria-selected. Der Fokus bleibt dabei im Eingabefeld, damit man weitertippen kann; die Auswahl wandert ueber aria-activedescendant. Ohne diese Auszeichnung waere ein Feld, das Vorschlaege einblendet, fuer einen Screenreader stumm -- das sieht man beim Testen mit den Augen nie. Vier Fallen ausdruecklich behandelt: - Nicht bei jedem Tastendruck suchen (180 ms Wartezeit): 'Musterbau' haette sonst neun Abfragen ausgeloest, acht davon veraltet. - Das Wettrennen der Antworten: Jede Abfrage bekommt eine laufende Nummer, nur die neueste darf zeichnen. Sonst ueberschreibt eine spaet eintreffende alte Antwort die neue. - Leer, laedt und Fehler sind eigene Zustaende. Ein Kasten, der bei einem Serverfehler leer bleibt, sieht aus wie 'nichts gefunden'. - LIKE-Sonderzeichen: '%' waere ein Platzhalter, '_' ein beliebiges Zeichen -- und Unterstriche stehen regelmaessig in E-Mail-Adressen. Der Fehler ist tueckisch, weil die Suche trotzdem Treffer liefert, nur die falschen. Ausserdem zum dritten Mal dieselbe Spezifitaetsfalle gefunden: '.wd p' schlug die eigene Regel, der Tastaturhinweis erschien in 17,9px statt 11,5px -- so gross wie der Inhalt, den er erklaert. Jetzt festgenagelt durch eine Pruefung, die Groessenverhaeltnisse vergleicht. Geprueft: 28 gegen eine echte Datenbank (darunter alle LIKE-Sonderzeichen), 64 im Browser auf Computer und Handy inkl. der ARIA-Vorgaben, des Wettrennens und des Fehlerzustands. Co-Authored-By: Claude Opus 5 <[email protected]> |
||
|
|
659a1ee9ce |
Verwaltung fragt nicht mehr grundlos nach dem Zugangscode
Zwei Ursachen, die zusammenwirkten. 1. Nach einem Neuladen war die HERKUNFT des Schluessels vergessen. Der Code speicherte nur den Schluessel selbst, nicht ob er aus einer Codeeingabe oder aus dem Ausweis der Zugangswand stammt. 2. Weil die Herkunft fehlte, wurde vorsichtshalber 'code' angenommen. Als Vorsicht gedacht, mit unangenehmer Kehrseite: Ein Ausweis gilt nur 15 Minuten. Als 'code' behandelt wurde er nie erneuert -- nach einer Viertelstunde kam der erste 401, und man landete in der Codeeingabe, obwohl alles in Ordnung war. Der Schutz 'eine Code-Sitzung wird nie durch einen Ausweis ersetzt' war damit ab dem ersten Neuladen ohnehin wirkungslos. Die Herkunft steht jetzt neben dem Schluessel und ueberlebt ein Neuladen. Fehlt sie -- etwa aus einer aelteren Sitzung --, bleibt es bei der vorsichtigen Annahme 'code'. Das behebt die Haelfte des Problems. Die andere Haelfte ist eine Einstellung auf dem Server: Die beiden Dienste benutzen nicht dasselbe WEBDESIGN_API_SECRET, weshalb jeder Ausweis abgelehnt wird. Der Kommentar in server/.env.example sagt ausdruecklich, dass beide Werte exakt gleich sein muessen. Das kann nur Filipe angleichen -- /home/dogiintern/ ist fuer claudian gesperrt. Co-Authored-By: Claude Opus 5 <[email protected]> |
||
|
|
131bc8a755 |
Anfragen annehmen und ablehnen — mit laufender Zeit bis zur Übergabe
Annehmen war bisher nur ein Etikett: Man stellte den Status um, und es passierte nichts. Kunde, Projekt, Aufgabenliste, Termin und Zugang musste man danach von Hand in fünf Schritten nachbauen. Der alte Code gab das im Kommentar selbst zu -- schlug der zweite von zwei Aufrufen fehl, stand der Kunde schon in der Datenbank und man durfte es nicht noch einmal versuchen. Jetzt macht das EIN Aufruf, ganz oder gar nicht: Kunde finden oder anlegen, Projekt anlegen, die komplette Aufgabenliste des Pakets einsetzen, Liefertermin berechnen, Einladungslink erzeugen. Der Kunde verfolgt ab diesem Moment alles in seinem Portal. Die Zeit läuft wirklich: - Eigenes Datumsfeld (termin_am) neben dem freien Text. Aus 'Mitte Oktober' kann man keine verbleibenden Tage rechnen. - Werktage statt Kalendertage, inklusive luxemburgischer Feiertage. Die beweglichen werden über die Osterformel berechnet statt gepflegt -- eine Liste ist im übernächsten Jahr lautlos falsch. - Vorschlag je Paket (Onepager 10, Website 20, Shop 30 Werktage), überschreibbar vor dem Bestätigen. - Verbleibende Zeit wird SERVERSEITIG gerechnet. Der Browser kennt die Feiertage nicht; zwei verschiedene Zahlen für denselben Termin wären schlimmer als gar keine. Ablehnen mit Grund und vorbereiteter Absage in fünf Sprachen, Text serverseitig erzeugt und vor dem Abschicken lesbar. Ein laufendes Projekt lässt sich nicht nachträglich als Anfrage ablehnen. Sechs Fehler dabei gefunden: - Ein unbekanntes Paket hätte GAR KEINEN Termin bekommen statt des Ersatzwerts. Zwei Funktionen lasen dieselbe Tabelle, nur eine hatte einen Rückfallwert. Eine fehlende Zahl fällt nirgends auf. - wd_anfragen hat keine Spalte 'firma' -- better-sqlite3 weist undefined ab, die ganze Annahme wäre gescheitert. - Migrationen stehen in einer ausdrücklichen Liste; 0015 fehlte darin. - datumKurz() wurde aufgerufen, gab es aber nicht. Der Fehler wäre erst NACH dem Anlegen aufgetreten. - Der Installations-Hinweis lag fest über dem Annehmen-Knopf und machte ihn auf dem Handy untreffbar. Die Seite reserviert jetzt Platz dafür. - 'richttermin' ist freier Text, lief aber durch einen Datumsformatierer: Der Kunde las 'Invalid Date' an der wichtigsten Stelle seines Projekts. Geprüft: 49 Prüfungen der Terminrechnung gegen nachschlagbare Osterdaten und Wochentage, 70 gegen eine echte Datenbank (darunter: zweiter Klick legt nichts doppelt an, Abbruch mittendrin lässt NICHTS zurück, gesperrter Kunde wird nicht still entsperrt), 42 im Browser auf Computer und Handy, 40 im Portal. Alle bestehenden Prüfungen weiter grün. Co-Authored-By: Claude Opus 5 <[email protected]> |
||
|
|
37f1b4a8f5 |
Handy: Sicherheitsabstaende, Wisch-Reiter, zweispaltige Uebersicht
Der wichtigste Fund: env(safe-area-inset-*) stand bereits im CSS, lieferte aber immer null -- viewport-fit=cover fehlte auf allen dreizehn Seiten. Der Code sah richtig aus und tat nichts. Zusammen mit apple-mobile-web-app-status-bar-style=black-translucent (schon gesetzt) hiess das: installiert lag die Kopfzeile auf einem iPhone hinter Uhr und Akkuanzeige. Behoben: - viewport-fit=cover auf allen 13 Seiten. - Vier Sicherheitsabstaende zentral benannt statt an jeder Stelle einzeln geschrieben. Kopfzeile weicht der Statusleiste, Container dem seitlichen Notch im Querformat, Fusszeile der Gestenleiste. - Der 'Ueberspringen'-Knopf des Vorspanns lag mit bottom:2rem praktisch AUF dem Entsperr-Strich (34px). Man haette die App verlassen statt uebersprungen. - Eigener Zweig fuer den installierten Betrieb: kein Gummiband- Nachfedern (sieht in einer App nach einem Fehler aus), kein Installations-Hinweis. - Die vier Sprungmarken auf der Rechtsseite waren 39px hoch -- fuenf unter dem Daumenmass. Ausgerechnet dort muss man zum Widerrufsrecht springen koennen. - 'Waehle links einen Verlauf aus': Auf dem Handy gibt es kein links, die Liste steht darueber. Richtungswort entfernt. - Sechs Reiter brauchten auf dem Handy drei Zeilen. Jetzt ein Wischstreifen mit Einrasten und Auslauf am Rand; der aktive Reiter wird herangeholt, wenn man ueber eine Kachel springt. - Uebersicht zweispaltig statt zwoelf Zeilen untereinander: 2635px -> 1924px. Eine Uebersicht, an der man vorbeiwischen muss, ist keine. Geprueft mit 55 neuen Handy-Pruefungen auf iPhone 14 Pro, Pixel 7 und 320px Breite, jeweils im Browser und im installierten Zweig. Drei Fehlalarme der eigenen Pruefung wurden begruendet ausgenommen (Honigtopf bei left:-9999px, Eingabefeld in einer Beschriftung, Inline-Link im Fliesstext -- WCAG 2.5.8 nimmt letztere ausdruecklich aus). Zwei Selbstkorrekturen an der Pruefung dokumentiert: Die Emulation von display-mode wirkt nicht (Chromium nimmt den Befehl an und ignoriert ihn) -- ohne das waeren die zwoelf 'installiert'-Zeilen ein zweiter Browser-Durchgang gewesen. Und die Messung gegen die Systemleisten mass zuerst die Kastenkante statt der Inhaltskante und meldete elf korrekte Seiten als fehlerhaft. Eine Selbstpruefung mit einem absichtlich falsch gesetzten Knopf belegt jetzt, dass die Messung echte Fehler findet. Co-Authored-By: Claude Opus 5 <[email protected]> |
||
|
|
c1cb51884f |
Verwaltung: Übersicht als Startansicht, Reiter unter den Titel
Die Reiter standen neben dem Titel. Das las sich wie eine einzige lange
Zeile, in der der Titel nur der erste von sechs Knöpfen zu sein schien --
man sah nicht auf einen Blick, in welchem Bereich man war. Jetzt zwei
Zeilen: oben WO man ist, darunter WOHIN man kann.
Die Verwaltung öffnete bisher mit der Anfragenliste. Eine Liste ist eine
Ablage: Sie zeigt, WAS es gibt, nicht was zu TUN ist. Neu ist ein
Cockpit, das in drei Stufen antwortet -- was auf mich wartet, was beim
Kunden liegt, wie es ums Geld steht -- und dann laufende Projekte mit
Fortschritt sowie den Verlauf.
Zwei Grundsätze machen die Zahlen brauchbar: Getrennt nach 'wartet auf
mich' und 'wartet auf den Kunden' (zwölf offene Punkte sind entspannt,
wenn elf beim Kunden liegen). Und das ALTER färbt, nicht die Menge --
vier neue Anfragen sind kein Problem, eine seit sechs Tagen liegende
schon. Ein offener Widerruf ist immer rot, weil eine gesetzliche Frist
läuft.
Jede Kachel ist ein echter <button> und führt in den passenden Reiter.
Farbe ist nie der einzige Träger: Neben jedem farbigen Zustand steht der
Text ('älteste seit 8 Tagen').
Drei Fehler dabei gefunden und behoben:
- Der Titel wurde nur beim Klicken gesetzt. Frisch geladen zeigte die
Seite das Cockpit, während darüber noch 'Projektanfragen' stand. Die
Zuordnung Reiter->Titel liegt jetzt ausserhalb des Klick-Zuhörers.
- '.wd h2' überstimmte '.vw-ub-h': 44px Überschrift über 33px Zahl, die
Seite las sich wie ein Plakat. Dieselbe Spezifitätsfalle wie früher
bei '.wd a'.
- Eine Antwort mit ok:true aber ohne Inhalt riss die ganze Verwaltung
mit. Wird jetzt abgefangen -- ein halber Server ist ein realistischer
Fall.
Geprüft: 22 Serverprüfungen gegen eine echte Datenbank (inkl. vier
Fällen, die belegen, dass die Rechteprüfung wirklich greift), 56 im
Browser auf Computer und Handy, 69 im bestehenden Verwaltungstest,
0 Fundstellen im Design-/WCAG-Test, 5 im Farbsystemtest.
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
4fe66e1e0e |
"Preise & Zeit" entfernt -- Inhalte in die Leistungen uebernommen
"leistungen und preis&zeit ist ja das gleiche, nimm die kategorie
preise&zeit komplett weg"
Stimmt bei den Paketen und Preisen: Beide Seiten zeigten dieselben
Zahlen. Zwei Orte fuer dieselbe Zahl sind eine Einladung, dass sie
irgendwann auseinanderlaufen -- und dann steht ein falscher Preis auf
der Seite, ohne dass es jemand merkt.
NICHT ALLES WAR DOPPELT
Vor dem Loeschen nachgesehen statt einfach geloescht. Zwei Abschnitte
gab es NUR dort:
"Was den Preis bewegt" -- beantwortet die Frage, die nach jeder
Preisliste kommt: Warum kostet es bei mir mehr oder weniger?
Ohne sie ist eine Preisspanne eine Behauptung.
"Wie bezahlt wird" -- Angebot, 30 % Anzahlung, Restbetrag, Betreuung.
Rechtlich relevant und aus den AGB verlinkt.
Beide sind in die Leistungen umgezogen, samt ihrer 24 Textbausteine in
allen fuenf Sprachen. Waeren sie mitgeloescht worden, haette es niemand
sofort bemerkt -- und die Seite haette ab dann Preise genannt, ohne sie
zu erklaeren.
WEITERLEITUNG STATT 404
Die Adresse /webdesign/preise.html bleibt bedient und fuehrt auf die
Leistungen. Lesezeichen, alte Links aus Nachrichten und die installierte
App zeigen sonst ins Leere, und ein 404 auf einer Preisseite ist der
denkbar schlechteste erste Eindruck.
302 statt 301: Eine dauerhafte Weiterleitung merken sich Browser
hartnaeckig; sollte die Seite je zurueckkehren, muesste jeder Besucher
seinen Zwischenspeicher leeren.
EIN FEHLER BEIM EINBAU
Die Weiterleitung stand zuerst weiter unten in der Schranke, bei den
ohne Code erreichbaren Seiten. Dort haette sie nur fuer NICHT angemeldete
Besucher gegriffen -- wer angemeldet ist, passiert die Schranke vorher
mit next() und haette einen 404 auf die geloeschte Datei bekommen.
Genau die Person also, die die Seite am ehesten im Lesezeichen hat.
Jetzt steht sie ganz vorne, vor jeder Zugangspruefung.
GEPRUEFT: 10 Pruefungen -- beide uebernommenen Abschnitte erscheinen in
allen fuenf Sprachen, kein unuebersetzter Schluessel sichtbar. Kein
Verweis auf die alte Seite blieb irgendwo stehen (ablauf.html hatte
einen, der ist umgebogen). Gestaltung 0 Befunde, Textkodierung sauber,
Designsystem 5.
Versionsstempel und Cache auf v20.
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
d6e75ce56a |
Kacheln: Licht folgt dem Zeiger, Rand glueht mit
"ich will das die kacheln richtig speziell sind und modern ... dass viel mehr auffaellt und doch modern und profissionell" Die Kacheln hatten Verlaufsrand, Verlaufsflaeche, Schatten und Lichtkante -- alles richtig, alles STATISCH. Was fehlte, war das Gefuehl von Material: eine Flaeche, die auf Licht reagiert. ZWEI EBENEN Ein weicher Lichtfleck folgt dem Zeiger ueber die Flaeche. Und -- der Teil, der wirklich auffaellt -- der RAND glueht an derselben Stelle auf und verlaeuft nach beiden Seiten aus. Das geht ohne zusaetzliches Element: Die Kachel hat bereits zwei Hintergrundebenen (Flaeche padding-box, Verlaufsrand border-box). Beim Ueberfahren bekommt die Randebene einen Lichtpunkt an der Zeigerstelle. Der Rand ist nur einen Pixel breit -- genau dort laesst sich Licht am staerksten zeigen, ohne kitschig zu werden. Ein Lichtfleck OHNE mitleuchtende Kante wirkt wie ein Fleck AUF der Kachel; mit ihr wirkt die ganze Kachel beleuchtet. Die Flaeche selbst bleibt beim Ueberfahren unveraendert -- sonst wuerde der Text flackern. VIER ENTSCHEIDUNGEN GEGEN BILLIGE OPTIK Die Farbe folgt der Kachel: blaue leuchten blau, lila lila. Sonst braeche der Effekt die Farbordnung, die ueberall sonst Bedeutung traegt. Nur bei echtem Zeiger (hover: hover, pointer: fine). Auf dem Handy gibt es keinen; dort bliebe der Lichtfleck an einer zufaelligen Stelle kleben. Aus bei prefers-reduced-motion. Auch wenn sich nichts bewegt: Etwas, das dem Zeiger folgt, ist Bewegung. Erste Fassung war mit 13 % zu zurueckhaltend -- am Screenshot geprueft und auf 22 % angehoben. "Man soll es spueren" ist richtig, aber es muss auch ankommen. SPARSAM GEBAUT EIN Zuhoerer am Dokument statt einem je Kachel -- sonst muesste jede nachgeladene Kachel einzeln nachgeruestet werden. Geschrieben wird erst im naechsten Bildaufbau: Der Zeiger meldet sich bis zu tausendmal je Sekunde, der Bildschirm zeichnet sechzigmal; ohne Drosselung rechnet der Browser neunhundertmal umsonst. Der Inhalt bekommt z-index 1. Ohne das legt sich der absolut gesetzte Lichtfleck ueber den Text -- absolut positionierte Elemente malen ueber Fluss-Inhalt, auch wenn sie im Quelltext davor stehen. Das Ergebnis waere ein Schleier auf der Schrift, den man erst beim Vergleich zweier Kacheln bemerkt. Eigens geprueft. GEPRUEFT: 7 Pruefungen fuer den Effekt selbst -- unsichtbar im Ruhezustand, erscheint beim Ueberfahren, folgt dem Zeiger auf 6 Pixel genau, Inhalt liegt darueber, lila Kacheln leuchten lila, bei Bewegungsempfindlichkeit vollstaendig abgeschaltet. Gestaltung 0 Befunde, Designsystem 5, Verwaltung 69, Portal 32. Versionsstempel und Cache auf v19. Co-Authored-By: Claude Opus 5 <[email protected]> |
||
|
|
e495542fe5 |
Typografie: Lesebreite begrenzt -- 105 zu breite Absaetze behoben
Gemessen ueber alle Seiten: 105 von 200 Textabsaetzen waren zu breit, der schlimmste mit 151 Zeichen pro Zeile. WARUM DAS ZAEHLT Beim Zeilensprung muss das Auge zurueck an den Zeilenanfang finden. Je laenger die Zeile, desto haeufiger landet es in der falschen -- man liest eine Zeile doppelt oder ueberspringt eine und merkt es erst zwei Saetze spaeter. Der Text ist dann nicht "schwer", er ist schlecht gesetzt. Bewaehrt sind 45 bis 75 Zeichen. Das ist der aelteste und bestbelegte Grundsatz der Typografie ueberhaupt -- jedes ordentlich gesetzte Buch haelt sich daran. Jetzt 68 Zeichen fuer Fliesstext, 60 fuer Kleingedrucktes. Die Einheit ist ch statt Pixel: Damit haengt die Breite an der SCHRIFTGROESSE. Kleingedrucktes bekommt automatisch einen schmaleren Block, grosse Schrift einen breiteren -- beide landen bei aehnlich vielen Zeichen. max-width macht nie etwas breiter. In schmalen Karten und Spalten aendert sich also nichts; die Regel greift nur dort, wo eine Zeile wirklich ueber das Lesbare hinauswaechst. Ergebnis: von 105 auf 0. DREI FEHLER BEIM EINBAU, ALLE VON DER MESSUNG GEFUNDEN 1. Zentrierter Text stand ploetzlich links. Eine Breitenbegrenzung zentriert den KASTEN nicht mit -- die Schrift war mittig, ihr Kasten klebte am linken Rand, mit 384 Pixeln Luft rechts und null links. Gefunden, weil die Pruefung den Abstand links mit dem rechts VERGLEICHT, statt nur zu zaehlen, ob zentriert ist. 2. Meine erste Regel deckte nur den Fall ab, dass das ELTERNELEMENT zentriert -- nicht den, dass der Absatz es selbst tut. 3. Und dann blieb einer uebrig, bei dem beides stimmte. Ursache: ein Inline-Stil "margin:1.2rem 0 0". Die Kurzschreibweise setzt links und rechts hart auf 0 und schlaegt jede Stilvorlage. 11 solche Stellen ueber fuenf Seiten auf margin-top umgestellt -- gemeint war ohnehin immer nur der Abstand nach oben. Ausnahmen bewusst gesetzt: Nachrichtenblasen tragen ihre Breite schon selbst, Tabellenzellen und Beschreibungslisten richten sich nach ihrer Spalte, die Fusszeile ist mehrspaltig und ohnehin schmal. ALLES GRUEN: Gestaltung 0 Befunde, Designsystem 5, Verwaltung 69, Portal 32, Widerruf 58, Anfragedetail 20. Versionsstempel und Cache auf v18. Co-Authored-By: Claude Opus 5 <[email protected]> |
||
|
|
10a075cc33 |
Gestaltung: Hoehensystem -- mehrschichtige Schatten und Lichtkante
Bis hierher trug jede Karte EINEN Schatten. Das ist solide und genau der Grund, warum eine Oberflaeche "ordentlich" statt "teuer" wirkt. Echtes Licht erzeugt zwei Dinge gleichzeitig: einen engen, dunklen Kontaktschatten an der Kante -- er sagt dem Auge, dass etwas AUFLIEGT -- und einen weiten, weichen Umgebungsschatten, der sagt, wie HOCH es darueber schwebt. Nur einen von beiden zu setzen sieht aus wie ein Aufkleber; beide zusammen ergeben einen Gegenstand. Dazu die LICHTKANTE: eine 1 Pixel hohe, sehr schwache weisse Linie an der Oberkante. Sie tut so, als kaeme das Licht von oben und braeche sich an der Kante. Das ist das meistuebersehene Detail in dunklen Oberflaechen und dasjenige mit der groessten Wirkung -- ohne sie wirkt eine Karte wie ein Loch im Hintergrund, mit ihr wie ein Stueck Material. Drei Stufen, mehr braucht es nicht: ruhende Flaechen, hervorgehobene Flaechen, Schwebendes. Dazu eine vierte, umgekehrte fuer Eingabefelder: Die liegen nicht AUF der Flaeche, sie sind hineingeschnitten -- oben dunkel, unten hell. Weil es die gemeinsamen Bausteine sind, wirkt es sofort auf allen 13 Seiten: Hauptseite, Portal und Verwaltung. Dazu Feinheiten, die einzeln niemand bemerkt und in Summe den Unterschied machen: Uebergaenge auf 160-180 ms verkuerzt (alles darueber wirkt beim Ueberfahren traege), eigene Rueckmeldung beim Druecken, optische Laufweitenkorrektur fuer grosse Ueberschriften (-.028em bei h1; das Auge sieht bei 48px mehr Weissraum zwischen Buchstaben als bei 16px), text-wrap: balance gegen einzelne Woerter in der letzten Zeile. EIN FEHLER BEIM EINBAU, GEMESSEN STATT UEBERSEHEN Nach dem ersten Durchgang hatten die Karten ihre Lichtkante, der Hauptknopf nicht. Grund: Die Grundregel lautet ".wd .wd-btn--haupt, .wd-btn--haupt" -- der erste Teil zaehlt ZWEI Klassen. Mein Nachtrag zaehlte eine und verlor, obwohl er spaeter steht. Dieselbe Falle wie am 22.08.2026 bei ".wd a" gegen ".wd-btn--haupt". Aufgefallen nur, weil die Pruefung die Lichtkanten ZAEHLT. PRUEFWERKZEUGE ANGEPASST diagnose.html ist jetzt ausgenommen. Sie traegt bewusst alles fest in sich -- eigene Farben, keine Uebersetzung -- weil sie funktionieren muss, wenn genau das kaputt ist, was sie untersucht. Sie an den Regeln der eigentlichen Seite zu messen erzeugte zwei Meldungen, die man auf Dauer wegsieht. Und irgendwann sieht man dann auch eine echte weg. ALLES GRUEN: Gestaltung 0 Befunde (12 Seiten x 5 Sprachen gegen WCAG 2.2 AA), Designsystem 5, Verwaltung 69, Portal 32. Versionsstempel und Cache auf v17. Co-Authored-By: Claude Opus 5 <[email protected]> |
||
|
|
a964a078f0 |
Zahlungen: Verwaltung sticht Serverdatei -- der Schalter wirkt jetzt
Filipes Bildschirm zeigte alles, was noetig war, um es zu erkennen:
Betriebsart: hinterlegt (auf dem Server) . 7 Zeichen
Client ID: hinterlegt . 82 Zeichen
Secret: hinterlegt . 80 Zeichen
Fehler: "PayPal hat die Anmeldung abgelehnt."
7 Zeichen sind "sandbox". Der Wert kam aus der .env, und die hatte
Vorrang. Sein Klick auf "Echtbetrieb" blieb wirkungslos -- seine echten
Zugangsdaten wurden gegen den TESTSERVER von PayPal geprueft, der sie
zwangslaeufig ablehnt.
Die Fehlermeldung zeigte dabei auf die Zugangsdaten ("stimmen Client ID
und Secret nicht zusammen") und damit in die voellig falsche Richtung.
DER ENTWURFSFEHLER
Ich hatte der .env bewusst Vorrang gegeben, damit ein Fehlgriff im
Formular keine funktionierende Servereinstellung aushebelt. Das klingt
vorsichtig und war falsch:
Ein Formular mit Schaltern, die nichts bewirken, ist schlimmer als gar
kein Formular. Es behauptet eine Wirkung, die es nicht hat, und schickt
bei der Fehlersuche in die Irre.
Der Sinn dieser Ablage ist gerade, dass die Werte OHNE SSH gesetzt
werden koennen. Dann muss das, was dort steht, auch gelten.
Ungefaehrlich, weil diese Werte ausschliesslich der Webdesign-Bereich
liest. Das DogiCrew-Supporter-Abo hat sein eigenes Modul und liest
weiter direkt aus der Umgebung -- ein Eintrag hier kann es nicht
abschalten. Eigens geprueft.
AUCH DIE ANZEIGE WAR UNEHRLICH
Sie sagte nur "hinterlegt (auf dem Server)" und verschwieg, dass genau
dieser Wert die eigene Eingabe ueberstimmt. Jetzt steht dort, welche
Quelle GILT -- "aus der Serverdatei" oder "hier eingetragen" -- und bei
doppelter Belegung zusaetzlich "Serverwert wird nicht benutzt".
GEPRUEFT: 16 Pruefungen auf dem Server, alle bestanden. Darunter der
genaue Fall: Serverdatei sagt sandbox, Formular sagt live -> istLive()
wird WAHR. Und der Rueckweg: Feld leeren -> Serverwert greift wieder.
Beim Testen noch ein Werkzeugfehler behoben: Der Absturz von
better-sqlite3 beim Beenden verschluckte die gesamte gepufferte
Ausgabe -- der Test lief durch und sah aus, als waere er nie gestartet.
Jetzt schreibt er unumgepuffert.
Versionsstempel und Cache auf v16.
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
d870a9c1d7 |
PayPal: falsche Angabe zur Webhook-ID berichtigt, Abo-Plan-Weg ergaenzt
Filipe: "webhook id faengt bei mir nicht mit w an und wo finde ich plan fuer betreung" Er hat recht, ich hatte unrecht. An der Quelle nachgeprueft: Webhook-ID: 0NH55953DH663215D -- OHNE Vorsilbe, ~17 Zeichen Ereignis-ID: WH-3F562076HD293871E-... -- DIE beginnt mit WH- Meine Anleitung und der Hinweistext im Formular behaupteten beide "beginnt mit WH-". Wer sich daran haelt, sucht an der falschen Stelle oder traegt eine Ereignis-Kennung ein -- und die Signaturpruefung scheitert dann bei der ersten echten Zahlung, mit einer Meldung, die nicht auf die Ursache zeigt. Beide Stellen berichtigt, in der Anleitung mit ausdruecklichem Hinweis, dass dort vorher etwas Falsches stand. Wer sie schon gelesen hat, soll den Widerspruch erklaert bekommen und nicht stillschweigend eine andere Fassung vorfinden. ABO-PLAN: Der Grund fuer die Frage ist ein echter Stolperstein -- Abo-Plaene werden NICHT im Entwicklerbereich angelegt, sondern im normalen Geschaeftskonto. Unter developer.paypal.com sucht man vergeblich. Jetzt mit direkter Adresse (paypal.com/billing/plans), dem Weg ueber das Menue und dem Schritt, den man am ehesten vergisst: den Plan nach dem Speichern auch AKTIVIEREN. Ein gespeicherter, aber nicht aktivierter Plan sieht fertig aus und funktioniert nicht. Ausserdem klargestellt, dass dieser ganze Schritt entfaellt, wenn kein monatliches Abo verkauft wird -- Anzahlung und Restbetrag laufen ohne. Versionsstempel und Cache auf v15. Co-Authored-By: Claude Opus 5 <[email protected]> |
||
|
|
9421bd5cfe |
Verwaltung: Endlosschleife bei abgewiesenem Ausweis behoben
DIE URSACHE FUER "die ganze seite haengt"
In ladeAnfragen stand seit Tagen dieser Code:
if (!ausweisVersucht) {
ausweisVersucht = true;
var frisch = await ausweisHolen();
if (frisch) {
token = frisch; tokenSchreiben(token);
ausweisVersucht = false; // <-- VOR dem Neuversuch geloest
return ladeAnfragen(); // <-- und ruft sich selbst auf
}
}
Die Sperre wird zurueckgesetzt, BEVOR der neue Versuch laeuft. Solange
der Ausweis akzeptiert wurde, fiel das nie auf. Weist der Server ihn
dagegen ab, dreht es sich unbegrenzt: Ausweis holen, 401, Ausweis holen,
401 -- ohne Fehlermeldung, ohne Anmeldemaske, nur ein Ladehinweis, der
zehn Minuten stehen bleibt. Die schlimmste Sorte Fehler: Sie sieht aus
wie Langsamkeit.
WARUM DER AUSWEIS ABGEWIESEN WIRD
Die Diagnose mit echtem Ausweis zeigte es eindeutig:
Ausweis erhalten in 23 ms
Einstellungen abrufen -> 401, {"ok":false,"error":"Kein Zugriff."}
Die Zugangswand stellt also aus, der interne Dienst lehnt ab. Beide
benutzen nicht dasselbe WEBDESIGN_API_SECRET. Auf dem oeffentlichen
Server ist es gesetzt (Fingerabdruck e7d63573174f661a); der interne ist
fuer mich nicht lesbar -- Filipe prueft das mit einem Befehl, der nur
den Fingerabdruck ausgibt, nie den Wert.
UND EIN FEHLER, DEN ICH SELBST EINGEBAUT HATTE
Die Erneuerung aus v12/v13 ersetzte bei jedem 401 den Schluessel durch
einen Ausweis -- auch dann, wenn er aus der Anmeldung mit dem
Zugangscode stammte. Bei untauglichem Ausweis wurde daraus ein
Totalausfall: Alle zehn Minuten ersetzte sie eine FUNKTIONIERENDE
Sitzung durch eine kaputte.
Eine Reparatur, die den Normalfall verschlechtert, ist keine.
Jetzt fuehrt die Seite mit, WOHER der Schluessel stammt. Eine
Code-Sitzung wird nie durch einen Ausweis ersetzt, und die vorsorgliche
Erneuerung laeuft fuer sie gar nicht erst. Nach einem Neuladen gilt ein
vorhandener Schluessel vorsichtshalber als Code-Sitzung -- lieber einmal
zu viel nach dem Code fragen als eine laufende Sitzung zerstoeren.
Die Erneuerung sitzt jetzt an EINER Stelle (api()) mit genau einem
Neuversuch. Die zweite, aeltere Fassung in ladeAnfragen ist raus; zwei
Mechanismen, die sich gegenseitig den Schluessel ueberschreiben, waren
ein Teil des Problems.
GEPRUEFT mit genau dieser Lage -- Zugangswand stellt aus, interner
Dienst lehnt ab:
2 Ausweis-Abrufe in 3 Sekunden statt unbegrenzt
abgewiesener Ausweis fuehrt zur Codeeingabe statt zum Haengen
Anmeldung mit Code oeffnet die Verwaltung
sechs Reiterwechsel, null Rauswuerfe, null Ausweis-Abrufe
Zahlungen-Kasten zeigt Inhalt
Verwaltung weiterhin 69 von 69. Versionsstempel und Cache auf v14.
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
2ec935ccc6 |
Verwaltung: Ausweis vorsorglich erneuern statt erst nach dem Fehlschlag
"wenn ich von postfach auf projekte oder so gehe da werd ich immer wieder mien zugangscode gefragt ... ich will nur den zugangscode anfrage wenn ich auf die seite will und fertig" Die Wiederholung bei 401 (v12) rettet zwar jeden Fall, greift aber erst, NACHDEM eine Anfrage abgewiesen wurde: ein unnoetiger Umlauf, und solange steht ein Ladehinweis auf dem Schirm. Jetzt laeuft der Ausweis gar nicht erst ab. Er gilt 15 Minuten, erneuert wird alle 10 -- mit Abstand, damit ein langsamer Netzzugang nicht ins Zeitfenster hineinlaeuft. Im Hintergrund pausiert die Erneuerung, das waere Verschwendung. Dazu beim Zurueckkommen ins Fenster: War der Rechner zwischendurch zu, ist der Ausweis mit Sicherheit abgelaufen. Dann soll der erste Klick sofort sitzen statt ueber einen Fehlschlag zu gehen. Beim schnellen Hin- und Herwechseln zwischen zwei Fenstern passiert nichts -- unter einer Minute wird nicht erneuert. Die Codeeingabe erscheint jetzt nur noch in genau zwei Faellen: beim ersten Betreten der Seite und wenn die Zugangssitzung wirklich abgelaufen ist (8 Stunden oder Seite geschlossen). Genau so war es gewuenscht. GEPRUEFT: sieben Reiterwechsel hintereinander -- postfach, projekte, kunden, zahlungen, anfragen, postfach, zahlungen -- und vor JEDEM wurde der Ausweis kuenstlich fuer ungueltig erklaert. Null Codeabfragen, die Verwaltung blieb offen, der Inhalt erschien. Verwaltung weiterhin 69 von 69. Versionsstempel und Cache-Name auf v13. Co-Authored-By: Claude Opus 5 <[email protected]> |
||
|
|
bd9051bfb7 |
Verwaltung: Ausweis erneuert sich selbst statt nach dem Code zu fragen
Rueckmeldung: "wieso werd ich auch immer meinen zugangscode gefragt wenn ich die kategorie wechseln tue das ist schwachsin." Er hat recht, und es war ein echter Fehler. DIE URSACHE Der Ausweis fuer die interne Schnittstelle (/webdesign/api-ausweis) gilt 15 Minuten. Danach antwortete jede Anfrage mit 401, und die Verwaltung tat das Haerteste, was moeglich ist: Token verwerfen und Codeeingabe zeigen -- beim blossen Wechsel eines Reiters. Doppelt falsch: Die ZUGANGSSITZUNG selbst gilt 8 Stunden. Der Code war also gar nicht noetig; ein frischer Ausweis haette genuegt und war jederzeit abrufbar. Ein Rauswurf mitten in der Arbeit ist die haerteste denkbare Reaktion auf ein Problem, das sich unsichtbar loesen laesst. Wer gerade ein Angebot beziffert hat, verliert damit seinen Platz. DIE LOESUNG Bei 401 wird EINMAL ein neuer Ausweis geholt und die Anfrage wiederholt. Nur wenn auch das scheitert, kommt die Codeeingabe -- dann ist die Sitzung wirklich abgelaufen. Das Wiederholen ist auch bei Absendungen unbedenklich: Eine mit 401 abgewiesene Anfrage hat serverseitig nichts bewirkt. Alle gleichzeitig wartenden Aufrufe teilen sich EINEN Erneuerungsversuch. Ohne das holt beim Oeffnen eines Reiters mit drei Abfragen jede ihren eigenen Ausweis -- drei statt einem. GEPRUEFT: 5 Pruefungen mit kuenstlich abgelaufenem Ausweis. Der Reiterwechsel fragt NICHT mehr nach dem Code, der Inhalt erscheint trotzdem, genau EIN neuer Ausweis wird geholt, und der naechste Wechsel laeuft ebenfalls durch. Ist dagegen die Zugangssitzung selbst abgelaufen, erscheint die Codeeingabe weiterhin -- das soll sie dann auch. Verwaltung weiterhin 69 von 69. Versionsstempel und Cache-Name auf v12. Co-Authored-By: Claude Opus 5 <[email protected]> |
||
|
|
d68d10d002 |
Zahlungen: Ladefehler sichtbar machen statt ewig "Wird geladen"
Rueckmeldung 23.08.2026: "da steht das aber passiert nichts" -- der
Reiter Zahlungen zeigte in beiden Kaesten dauerhaft "Wird geladen...".
Geprueft statt vermutet: Der Server antwortet (401 auf unangemeldete
Anfragen, Webhook 400), die ausgelieferte Seite enthaelt die Funktion,
und lokal nachgestellt laeuft der Ablauf sauber durch. Die Anfrage
bricht nach 15 Sekunden von selbst ab.
Der eigentliche Mangel liegt woanders und ist meiner: Ein Ladehinweis
ohne Ende ist die schlechteste aller Rueckmeldungen. Er sieht aus wie
Arbeit und ist doch nur Stillstand -- man kann nicht unterscheiden, ob
die Anfrage laeuft, fehlgeschlagen ist oder das Skript gar nicht
angesprungen ist. Und wenn der Fehler dann kommt, verschwindet er in
einer Meldung am Bildschirmrand.
DREI AENDERUNGEN
Jeder Fehler wird im Kasten selbst angezeigt, mit STATUSNUMMER im
Klartext ("Konnte nicht geladen werden (Status 403)"). Die kann Filipe
mir nennen, ohne die Entwicklerwerkzeuge zu oeffnen -- 403 heisst etwas
voellig anderes als 500 oder "keine Verbindung", und ohne diese Zahl
raet man.
Dazu ein Knopf "Nochmal versuchen". Bei einem Aussetzer im Mobilfunk ist
das der ganze Unterschied zwischen "geht nicht" und "geht doch".
Die statischen "Wird geladen..."-Texte im HTML sind raus. Der Kasten ist
jetzt leer, bis das Skript ihn fuellt -- und die Ladetexte lauten anders
als vorher. Bleibt spaeter der alte Text stehen, weiss man sofort: Die
Funktion ist nie angelaufen. Das ist eine Aussage, "Wird geladen" war
keine.
Auch die Zahlungsliste verschluckt ihren Fehler nicht mehr. Sie leerte
den Kasten stillschweigend -- ein leerer Bereich ohne Erklaerung ist
nicht weniger verwirrend als ein haengender Ladehinweis.
GEPRUEFT: alle vier Zustaende im Browser nachgestellt -- Serverfehler
500, kein Zugriff 403, Netzausfall und Erfolgsfall. In den ersten drei
erscheint Klartext samt Wiederholen-Knopf, im vierten der normale
Inhalt. Verwaltung weiterhin 69 von 69.
Versionsstempel und Cache-Name auf v11.
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
6a2aa13dd8 |
PayPal ohne Konsole einrichten -- Formular in der Verwaltung
Auf die Frage "soll ich das Secret hier reinschicken?" ist die Antwort nein: Es stuende dauerhaft im Gespraechsverlauf, und schreiben koennte ich es trotzdem nicht (kein Zugriff auf /home/dogiintern, sudo nur fuer apt/systemctl/docker). Risiko ohne Nutzen. Der Fehler lag aber bei mir: Ich hatte SSH-Befehle als Loesung angeboten. Filipe soll gar nicht in die Konsole. Jetzt traegt er die Werte in seiner Verwaltung ein. AUFBAU lib/webdesign-geheimnisse.js legt die Werte verschluesselt in app_settings ab -- derselbe AES-GCM-Weg wie fuer die Zugangscodes des Universe. Wer die Datenbankdatei in die Haende bekommt, etwa ueber eine alte Sicherung, hat damit nichts. Die .env behaelt VORRANG. Sonst koennte ein Fehlgriff im Formular stillschweigend eine funktionierende Servereinstellung aushebeln und laufenden Zahlungsverkehr umleiten. Die Datenbank ergaenzt, was dort fehlt -- sie konkurriert nicht. Kein Neustart noetig: Nach jedem Speichern werden die Werte neu geladen. DER KNIFF MIT DEM SYNCHRONEN ZUGRIFF Entschluesseln ist asynchron, die Pruefungen des PayPal-Moduls (istLive, istEingerichtet, fehlendeEinstellungen) sind synchron und werden an einem Dutzend Stellen aufgerufen, teils mitten im Aufbau einer Antwort. Sie alle auf async umzustellen waere ein Eingriff quer durch den Bezahlvorgang gewesen -- viel Flaeche fuer Fehler genau dort, wo Fehler Geld kosten. Stattdessen werden die Werte einmal beim Start entschluesselt und danach synchron gelesen. Alle 12 Zugriffe auf process.env.PAYPAL* im Modul laufen jetzt ueber einen einzigen Zugriffspunkt. WERTE KOMMEN NIE ZURUECK Es gibt keinen Weg, ein gespeichertes Geheimnis wieder auszulesen. Die Anzeige zeigt nur: ob etwas da ist, woher es stammt, wie lang es ist, wann es zuletzt geaendert wurde. Das Formular leert sich nach dem Speichern selbst -- ein Secret soll nicht stehen bleiben, wenn jemand anders auf den Bildschirm schaut. Ein leeres Feld bedeutet "nicht anfassen", nicht "loeschen". Sonst wuerde das Nachtragen eines einzelnen Werts alle anderen leeren. Nach jeder Aenderung wird das gemerkte PayPal-Zugangstoken vergessen -- sonst liefe die naechste Zahlung noch ueber die alten Zugangsdaten oder scheiterte mit "invalid client". "Verbindung testen" meldet sich probeweise bei PayPal an. Erst das beweist, dass die Werte stimmen: "gesetzt" heisst nur, dass etwas dasteht. Es fliesst dabei kein Geld. GEPRUEFT: 23 Pruefungen auf dem Server, alle bestanden. Darunter die wichtigsten Verneinungen: In der Datenbank steht kein Klartext, auch kein Teil davon. Der Stand enthaelt das Geheimnis nicht. Ein fremder Schluessel wird abgewiesen. Und: Ein gewechselter ENCRYPTION_KEY bringt den Dienst NICHT zum Stehen -- der Wert gilt dann als nicht vorhanden, die Seite laeuft weiter. Verwaltung 69, Gestaltung 0 Befunde, Designsystem 5 -- unveraendert gruen. Versionsstempel und Cache-Name auf v10. Co-Authored-By: Claude Opus 5 <[email protected]> |
||
|
|
be3599239d |
Designsystem: eine Quelle je Farbe, Radien auf eine Skala
Diese Runde ging eine Ebene tiefer als "sieht es gut aus": Ist das
System, aus dem das Aussehen entsteht, ueberhaupt eines?
DIE MESSUNG VORWEG
Markenfarben ausgeschrieben im Quelltext: 155 Stellen
davon Blau 74, Gold 33, Lila 22, Gruen 16, Rot 10
verschiedene Eckenradien: 12
darunter 5px, 7px, 9px, 11px
Die Farben gab es laengst als Variablen. Sie standen trotzdem ueberall
ausgeschrieben da, weil halbdurchsichtige Toene -- Raender, Leuchten,
sanfte Flaechen -- einen Alphawert brauchen, und das mit einer fertigen
Farbvariablen nicht geht: rgba(127, 208, 232, .16).
Die Folge waere beim ersten Farbwechsel sichtbar geworden: Man findet
150 Stellen, uebersieht fuenf, und die Seite hat danach zwei Blautoene,
die sich um eine Nuance unterscheiden. Genau das ist der Unterschied
zwischen einer gewachsenen und einer gestalteten Oberflaeche.
WAS GEAENDERT WURDE
Kanalvariablen (--wd-blau-rgb: 127 208 232) neben den fertigen Farben.
Damit schreibt man rgb(var(--wd-blau-rgb) / .16), und eine Aenderung
wirkt ueberall. 164 Stellen umgestellt, verteilt ueber CSS und neun
Seiten.
Auch die abgeleiteten Farben zeigen jetzt auf die Kanaele statt eigene
Werte zu fuehren -- und die vier Prozessfarben (--wd-p1 bis p4) sind
keine eigenen Farben mehr, sondern Rollen: --wd-p1: var(--wd-blau).
Sonst haette man vier weitere Stellen, die beim naechsten Farbwechsel
stillschweigend zurueckbleiben.
Ergebnis: Jede Markenfarbe hat genau EINE Quelle. Ausgeschriebene
Markenfarben im Quelltext: 0.
Radien auf vier Stufen plus Pillenform: 6 / 10 / 14 / 20 / 999. Kein
Wert wurde um mehr als 2px verschoben, optisch aendert sich also nichts
Spuerbares -- 12 verschiedene Werte sind auf 3 tatsaechlich verwendete
zusammengeschmolzen. Zwischenwerte wie 7px oder 11px entstehen nicht aus
Absicht, sondern weil man beim Bauen einer neuen Kachel nicht nachschaut,
was nebenan schon gilt.
DER BEWEIS, DASS ES EIN SYSTEM IST
Neue Pruefung pruef-system.mjs. Sie behauptet nicht, sie STELLT UM: Die
Markenfarbe wird von Babyblau auf kraeftiges Orange gesetzt und dann
nachgezaehlt, ob irgendwo der alte Ton stehen bleibt.
658 von 1975 sichtbaren Elementen tragen die Markenfarbe
0 bleiben nach der Umstellung beim alten Ton
Prozessfarben folgen nachweislich mit
Radien: 3 Stufen
UND DIE WICHTIGSTE ERKENNTNIS -- ueber das Messen selbst
Der erste Anlauf meldete 110 haengengebliebene Elemente, alle in Kopf-
und Fusszeile. Die naheliegende Erklaerung waere gewesen: "da steht die
Farbe noch ausgeschrieben". Sie war falsch.
Nachgewiesen ueber die DevTools-Schnittstelle: Auf diese Elemente wirkt
die Regel ".wd a:not(.wd-btn) -> var(--wd-blau)", und --wd-blau
resolviert an genau dieser Stelle korrekt zum neuen Orange. Trotzdem
blieb die berechnete Textfarbe alt -- auch nach erzwungener
Neuberechnung.
Der Unterschied: Kopf- und Fusszeile werden von wd-core.js per innerHTML
eingefuegt. Chromium erneuert solche Teilbaeume nicht zuverlaessig, wenn
man eine Variable NACHTRAEGLICH umstellt. Laedt man dieselbe Seite mit
bereits geaenderter Variable, sind sie orange -- gegengeprueft mit einem
Minimalbeispiel, in dem derselbe Mechanismus einwandfrei funktioniert.
Das Pruefverfahren wurde deshalb umgestellt: Die Variable wird VOR dem
Laden ueberschrieben. Das entspricht genau dem, was eine Aenderung in der
CSS-Datei bewirkt -- also dem Fall, um den es wirklich geht.
Haette ich der ersten Messung geglaubt, haette ich 110 einwandfreie
Stellen "repariert" und dabei das gerade aufgebaute System wieder
zerlegt. Es ist der siebte Fehlalarm in eigener Messtechnik innerhalb
von zwei Runden -- und der subtilste.
ALLE PRUEFUNGEN GRUEN: Gestaltung 0 Befunde (13 Seiten x 5 Sprachen
gegen WCAG 2.2 AA), Anfragedetail 20, Verwaltung 69, Portal 32,
Widerruf 58, Textkodierung 55 Kombinationen, Designsystem 5.
Versionsstempel und Cache-Name auf v9.
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
3ca9f0b0cd |
Gestaltung: WCAG-Messung ueber alle Seiten, alle Befunde behoben
"Sieht gut aus" ist Geschmack und laesst sich nicht pruefen. Handwerkliche
Qualitaet laesst sich pruefen -- und bei einer WEBDESIGN-Seite ist sie
zugleich das Verkaufsargument: Wer selbst schludert, kann schlecht
Sorgfalt verkaufen.
Neues Werkzeug pruef-design.mjs misst 13 Seiten x 5 Sprachen auf
Handy-Breite gegen WCAG 2.2 AA -- denselben Standard, auf den auch das
Barrierefreiheitsstaerkungsgesetz verweist. Der Browser rechnet, es wird
nichts geschaetzt.
ERGEBNIS: 0 Befunde. Kontrast, Klickflaechen, Tastaturfokus,
Ueberschriftenstruktur, Bildalternativen, Feldbeschriftungen,
lang-Attribut, Schriftgroessen.
ECHTE BEFUNDE, DIE BEHOBEN WURDEN
1. 23 Schriftgroessen unter 12px (bis hinunter zu 10,9px), verteilt ueber
CSS und sieben Seiten. Betroffen waren durchweg gesperrte
Grossbuchstaben-Beschriftungen -- also genau die Textsorte, die klein
ohnehin am schlechtesten lesbar ist. Alle auf mindestens 12px, die
gesperrten auf 12,8px. Das ist zugleich die Dauervorgabe
"augenschonend" ernst genommen.
2. Ueberschriftensprung h2 -> h4 in der Fusszeile, auf ALLEN 13 Seiten in
allen 5 Sprachen (42 Stellen). Wer sich mit einem Screenreader durch
die Ueberschriften bewegt, hoert dadurch eine Gliederung, die es nicht
gibt, und vermutet uebersprungene Abschnitte. Jetzt h2 mit
Gestaltungsklasse: Die Ebene sagt etwas ueber die STRUKTUR, die
Groesse ueber die GEWICHTUNG -- zwei verschiedene Dinge.
3. code-Auszeichnung auf der Rechtsseite rutschte durch relative
Groessenangabe auf 11,2px. Jetzt mit Untergrenze abgesichert.
SECHS FEHLALARME IM WERKZEUG -- ALLE GEFUNDEN UND BESEITIGT
Der erste Lauf meldete 302 Fundstellen. Fast alle waren falsch. Haette
ich sie "repariert", haette ich funktionierende Gestaltung zerstoert.
Jeder Fehlalarm hatte eine eigene, nicht offensichtliche Ursache:
* Farbverlaeufe: getComputedStyle().backgroundColor liefert bei einer
reinen Verlaufsflaeche "rgba(0,0,0,0)". Die Suche lief an der hellen
Knopfflaeche VORBEI bis zum dunklen Seitengrund und verglich dunkle
Schrift mit dunklem Grund -- Ergebnis 1:1 fuer 60 einwandfreie
Knoepfe. Jetzt werden die Farbstopps ausgelesen und der
unguenstigste Fall gerechnet.
* MEHRERE Hintergrundebenen: Die Karten nutzen den bekannten Kniff
"Flaeche padding-box, Rahmenverlauf border-box". Der helle
Rahmenverlauf ist im Textbereich gar nicht sichtbar. Alle Ebenen
zusammenzurechnen ergab 820 Meldungen mit Werten wie "3,45:1" fuer
Text, der in Wahrheit ueber 7:1 liegt. CSS malt die ERSTE Ebene oben
-- nur die zaehlt. Das Trennen an Kommas muss dabei die Kommas
INNERHALB der Verlaufsklammern respektieren.
* Verlaufsschrift (background-clip:text): Dort ist die Schriftfarbe
durchsichtig und der Verlauf IST der Text. Farbe gegen Hintergrund zu
vergleichen ergibt zwangslaeufig 1:1.
* Verlaufsstopps mit wenig Deckkraft (9 % und 4 % Gold in den
Hinweiskaesten) wurden verworfen statt auf den Untergrund gerechnet.
Uebrig blieb "nicht messbar" fuer 72 Textstellen. Ein Pruefwerkzeug,
das bei allem passt, prueft nichts.
* Laufende Ueberblendungen: getComputedStyle liefert waehrend einer
Ueberblendung den ZWISCHENWERT. Nach blur() verblasst der Fokusring
ueber 0,16 s -- misst man sofort, sieht man ihn noch, und "vorher"
ist identisch mit "nachher". Das Codefeld der Verwaltung wurde
dadurch als "ohne sichtbaren Fokus" gemeldet. Nachgewiesen mit
el.matches(":focus") === false bei gleichzeitig sichtbarem Schatten.
Loesung: Ueberblendungen fuer die Messung abschalten.
* Ausgeblendete Abschnitte: Eine Ueberschrift in einem versteckten
Bereich hat selbst weiterhin display:block. Im Portal wurden dadurch
drei h1 gezaehlt, obwohl immer nur eine sichtbar ist. Jetzt
getClientRects().
Dazu zwei bekannte Muster, die das Werkzeug jetzt kennt: der Sprunglink
(absichtlich aus dem Bild geschoben) und die winzigen Auswahlfelder
hinter den Kacheln (die Kachel IST die Klickflaeche).
ALLE UEBRIGEN PRUEFUNGEN WEITERHIN GRUEN nach den Aenderungen:
Anfragedetail 20, Verwaltung 69, Portal 32, Widerruf 58, Textkodierung
55 Seiten-Sprach-Kombinationen.
Versionsstempel und Cache-Name auf v8.
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
14ad108c87 |
Rechtliches: elektronische Widerrufsfunktion (§ 356a BGB), Impressum, AGB,
Widerrufsbelehrung und Datenschutz
RECHERCHIERT, NICHT AUS DEM GEDAECHTNIS
Der Webdesign-Bereich hatte KEINE eigene Rechtsseite -- obwohl dort
Vertraege geschlossen und Zahlungen ausgeloest werden. Die Fusszeile
verwies auf die Kontaktseite des Universe, die ein Content-Projekt
beschreibt, kein Dienstleistungsgeschaeft.
Die Web-Recherche hat eine Pflicht zutage gefoerdert, die seit zwei
Monaten gilt und die die Seite nicht erfuellt hat:
§ 356a BGB -- elektronische Widerrufsfunktion, in Kraft seit
19.06.2026. Sie gilt fuer ALLE Fernabsatzvertraege, die ueber eine
Online-Benutzeroberflaeche geschlossen werden, nicht nur fuer
Finanzdienstleistungen.
WARUM DAS HIER GILT: Im Kundenportal nimmt der Kunde Zusatzangebote per
Klick VERBINDLICH an ("Damit nimmst du das Zusatzangebot verbindlich
an"). Das ist ein Vertragsschluss ueber eine Online-Benutzeroberflaeche.
Fuer die geplanten PayPal-Zahlungen gilt dasselbe.
Der Anbieter sitzt in Luxemburg. Fuer Verbraucher mit gewoehnlichem
Aufenthalt in Deutschland gilt nach Art. 6 Rom-I-VO trotzdem das
deutsche zwingende Verbraucherrecht, weil die Seite sich erkennbar an den
deutschsprachigen Markt richtet. Deshalb wurde der STRENGERE Standard
umgesetzt, nicht der bequemere.
WAS GEBAUT WURDE
webdesign/widerruf.html -- die Widerrufsfunktion, genau nach dem
Wortlaut der Vorschrift:
* Beschriftung "Vertrag widerrufen" (gesetzlich vorgegeben)
* ZWEITE Schaltflaeche "Widerruf bestaetigen" (ebenfalls vorgegeben --
ein einstufiges Formular wuerde die Vorschrift nicht erfuellen)
* unverzuegliche Eingangsbestaetigung mit Nummer, ZEITPUNKT (nicht nur
Datum), Empfaenger und dem Wortlaut der Erklaerung
* Link in der Fusszeile JEDER Seite -- "staendig verfuegbar,
hervorgehoben platziert, leicht zugaenglich" heisst nicht "in den AGB
versteckt"
Drei Entscheidungen, die unmittelbar aus dem Sinn der Vorschrift folgen:
KEINE ANMELDUNG. Die Seite ist von der Zugangswand ausgenommen. Wer
seinen Code verlegt hat, wuerde sonst seine Frist verlieren --
Fristverlust durch eine selbstgebaute Huerde ist der schlimmste
denkbare Fall.
KEINE MENGENBEGRENZUNG. Ueberall sonst richtig, hier ein
Rechtsverlust: Wer in der letzten Stunde seiner Frist wegen eines
hakenden Netzes dreimal klickt, darf nicht abgewiesen werden.
KEIN ZWISCHENSPEICHER. Beim Anfrageformular ein Segen, hier eine
Falle: Auf einem geteilten Rechner laege der halb ausgefuellte Widerruf
des einen im Browser des naechsten.
webdesign/rechtliches.html -- Impressum, AGB, Widerrufsbelehrung samt
Muster-Widerrufsformular, Datenschutzerklaerung. Alle Betreiberangaben
sind aus den bestehenden Seiten UEBERNOMMEN, nichts erfunden: Anschrift
in Mondercange, Kleinunternehmerregelung nach Art. 57 TVA-Gesetz LU und
Richtlinie (EU) 2020/285, netcup/Cloudflare, PayPal Luxemburg.
Migration 0014: wd_widerrufe (der dauerhafte Datentraeger und der
Nachweis, wird nie geleert) und wd_zustimmungen. Letztere speichert nicht
nur den Haken, sondern den WORTLAUT, den der Kunde gesehen hat -- die
Beweislast fuer die Zustimmung zum vorzeitigen Leistungsbeginn liegt beim
Unternehmer (§ 356 Abs. 4 BGB), und im Streit zaehlt, WAS bestaetigt
wurde. Bewusst OHNE Fremdschluessel: CASCADE wuerde den Nachweis mit dem
Kunden mitloeschen, RESTRICT wuerde eine DSGVO-Loeschung blockieren.
Druckansicht: Die Eingangsbestaetigung ist ein Rechtsnachweis. Auf Papier
schwarz auf weiss, ohne Navigation und Knoepfe -- ein Nachweis, den
niemand ausdruckt, weil er eine halbe Patrone kostet, erfuellt seinen
Zweck nicht.
ZWEI ECHTE FEHLER GEFUNDEN
1. Die Pflicht-Sternchen verschwanden nach der Uebersetzung. Ursache:
data-i18n stand auf dem <label> selbst und ersetzte dessen ganzen
Inhalt -- samt <span class="wd-pflicht">. Das Anfrageformular macht es
laengst richtig (data-i18n auf einem INNEREN span); die neue Seite
hatte das Muster nicht uebernommen. Aufgefallen ist es nur, weil der
Test die Pflichtfelder GEZAEHLT hat statt sie vorauszusetzen.
2. window.WD.sprache() gibt es nicht, die Funktion heisst getSprache().
Dadurch brach der Uebergang zur zweiten Stufe stumm ab.
GEPRUEFT: 58 Pruefungen, alle bestanden. Darunter die gesetzlich
vorgegebenen Beschriftungen in allen FUENF Sprachen, "kein Grund noetig",
genau drei Pflichtfelder, Datum UND Uhrzeit in der Bestaetigung, und die
Druckansicht.
WAS FILIPE NOCH PRUEFEN LASSEN MUSS: Diese Texte sind sorgfaeltig
recherchiert, aber ich bin keine Rechtsanwaeltin. Vor dem oeffentlichen
Start gehoert das Ganze einmal zu einer im luxemburgischen Recht
qualifizierten Fachperson -- besonders die grenzueberschreitende Lage
(Sitz LU, Kunden in DE/CH/FR/PT) und die Frage, ob die Seite in
Franzoesisch und Portugiesisch aktiv verkaufen soll. Dann muessen die
Rechtstexte auch dorthin uebersetzt werden, und zwar fachlich.
Versionsstempel und Cache-Name auf v7.
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
98fc04c666 |
Verwaltung: Projektstand aendern, Wuensche beziffern, im Projekt antworten
Drei Server-Funktionen existierten seit Tagen und hatten KEINE Oberflaeche.
Erst im Vergleich "was kann der Server" gegen "was ruft die Seite auf"
ist es aufgefallen:
POST /admin/projekte/:id projektAendern
POST /admin/aenderungen/:id/beziffern
POST /admin/projekt-nachricht
Jede davon schliesst einen Kreis, der bisher offen war.
1. DIE SCHMERZHAFTESTE LUECKE: DER STAND
Der Kunde sieht in seinem Portal GANZ OBEN die Phasenleiste und den
"naechsten Schritt". Beides liess sich nirgends aendern. Ein Projekt blieb
also fuer immer im Briefing stehen, egal wie weit es wirklich war -- und
der prominenteste Text im ganzen Kundenportal war dauerhaft leer.
Jetzt: sieben Phasen als Knoepfe (plus Pausiert/Abgebrochen daneben, denn
das sind keine Phasen, sondern Zustaende), "wer ist am Zug", naechster
Schritt, Richttermin, Zahlungsstand, Portfolio-Freigabe.
Phase und "wer ist am Zug" speichern SOFORT ohne Speichern-Knopf: Es ist
ein Klick auf genau einen Wert, ein zweiter Klick waere Zeremonie. Die
Textfelder haben einen Knopf, weil man beim Tippen zwischendurch nicht
speichern will.
2. AENDERUNGSWUENSCHE
Der Kunde konnte Ideen einreichen, seit es das Portal gibt. Beziffern ging
serverseitig auch -- nur gab es keine Oberflaeche. Der Kreis war offen: Er
schickt etwas los und hoert nie wieder davon.
Jetzt stehen alle Wuensche im Projekt, offene mit Feldern fuer Preis,
Dauer und einer kurzen Erklaerung. Ohne Preis geht nichts raus (geprueft)
-- ohne Preis kann der Kunde nicht entscheiden, und ein "Angebot" ohne
Zahl ist keins.
3. NACHRICHTEN ZUM PROJEKT
Getrennt vom allgemeinen Postfach, weil sie zum Projekt gehoeren und im
Portal auch dort erscheinen. Sie hier nicht zu haben hiess: Der Kunde
schreibt im Projekt, und ich kann ihm nur woanders antworten.
AUFBAU
Neuer Endpunkt /admin/projekte/:id/alles liefert Projekt, Aufgaben,
Fortschritt, Aenderungswuensche und Nachrichten in EINER Antwort. Fuenf
Anfragen hintereinander wuerden die Ansicht sichtbar ruckelnd aufbauen.
Dieselbe Aufteilung wie in der Anfrageansicht -- links die Arbeit
(Aufgaben), rechts das Steuern. Wer zwischen beiden Ansichten wechselt,
muss nicht umdenken.
GEPRUEFT: 69 Pruefungen, Computer und Handy, alle bestanden.
Die neuen Pruefungen schauen nicht darauf, ob sich ein Knopf einfaerbt --
das beweist nichts. Sie schneiden mit, was die Seite TATSAECHLICH an den
Server schickt: {"status":"entwicklung"}, {"restBezahlt":true},
{"preisEuro":250,"dauer":"3 Tage"}. Und sie pruefen den Fall, in dem
nichts rausgehen darf: Ohne Preis bleibt die Mitschrift leer.
Ein Fehler im Test selbst behoben: Die Nachrichtenzaehlung war
document-weit und zaehlte die Nachrichten der geschlossenen Projektansicht
mit -- geschlossen heisst nicht aus dem Dokument entfernt. Jetzt auf den
Postfach-Verlauf eingegrenzt.
Versionsstempel und Cache-Name auf v6.
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
469a6c195f |
Portal: Aufgabenliste und Postfach fuer den Kunden
Schritt 4 von 4 -- damit sind beide Wuensche vom 22.08.2026 vollstaendig:
"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".
AUFGABENLISTE IM PROJEKT
Bisher sah der Kunde nur die Phase ("Design . 3/7") -- eine Zahl ohne
Inhalt. Sie beantwortet die eigentliche Frage nicht: WAS ist denn fertig?
Die Liste steht GANZ OBEN, direkt nach dem Projektkopf, noch vor
Zahlungen und Dateien. Die sind wichtig, aber sie sind nicht der Grund
fuer den Klick.
Zwei Entscheidungen praegen die Ansicht:
1. Offene Kundenpunkte stehen in einem EIGENEN Kasten ganz oben ("Das
brauche ich noch von dir"), nicht nur farblich markiert irgendwo
mittendrin. Wer eine lange Liste sieht, liest sie als Bericht ueber
fremde Arbeit und ueberliest seinen eigenen Teil -- genau daraus
entstehen die meisten Verzoegerungen. Ist nichts offen, steht das
auch da: "Von dir wird gerade nichts gebraucht." Eine gute Nachricht
darf ausgesprochen werden.
2. Der Kunde hakt seine eigenen Punkte selbst ab. Nur diese haben einen
Knopf; bei fremden Punkten ist das Zeichen reine Anzeige. Ein Knopf,
der nichts tut, laesst die Seite kaputt wirken. Geprueft: 4 Knoepfe
bei 2 offenen eigenen Punkten (sie erscheinen zweimal), 5 feste.
Grosse Zahl statt Prozent: "2 von 6 erledigt" ist greifbar, "33 %" ist
eine Rechnung, die niemand fuehlt. Der Balken traegt die vier
Prozessfarben -- dieselben wie auf der Ablaufseite und in der Verwaltung.
Der Ton ist bewusst gewaehlt. Der Kunde liest die Liste, wenn er unsicher
ist -- also im Zweifel schon angespannt. "Wir warten auf dich" waere
Druck, "Das brauche ich noch von dir" ist eine Bitte.
POSTFACH AUF DER UEBERSICHT
Bewusst auf der Uebersicht, nicht im Projekt: Wer kein Projekt hat -- oder
eine Frage, die zu keinem gehoert -- konnte vorher gar nicht schreiben und
musste zur E-Mail greifen. Damit war der Verlauf weg, sobald man ihn
brauchte.
Niedrigschwellig: kein Betreff, kein Pflichtfeld, der Projektbezug ist
freiwillig. Wer glaubt, eine Nachricht muesse eine "richtige" Anfrage
sein, schreibt gar nicht erst -- und genau die kurzen Fragen sollen hier
landen. Wird nachgeladen, damit die Uebersicht sofort dasteht.
Projekt- und Aufgabendaten werden gleichzeitig angefordert statt
nacheinander -- sonst waere die Wartezeit die Summe beider Anfragen. Die
Aufgabenliste darf dabei fehlschlagen, ohne die Seite mitzureissen: Wer
wegen einer leeren Liste seine Zahlungen nicht mehr saehe, waere
schlechter dran als vorher.
EIN SICHTBARER FEHLER GEFUNDEN
Auf dem Screenshot stand "Ideen &amp; Aenderungswuensche". Ursache ist
eine Falle mit zwei Wegen: Texte ueber data-i18n landen als HTML in der
Seite, dort ist "&" richtig. Derselbe Text im JavaScript laeuft aber
durch die Absicherung und wird ein zweites Mal kodiert. Derselbe Baustein
ist also je nach Verwendungsort richtig oder falsch.
Das kann man nicht im Kopf behalten -- deshalb neu pruef-texte.mjs mit
ZWEI Pruefungen:
Anzeige: alle 11 Seiten x 5 Sprachen = 55 Kombinationen, sichtbarer
Text darf keine Kodierungsreste enthalten.
Quelltext: welcher Baustein mit "&" wird irgendwo abgesichert
eingesetzt?
Beide sind noetig. Gegengeprueft: Die Anzeigepruefung allein haette den
Fehler NICHT gefunden, weil die Ideen-Karte erst nach einer Anmeldung
erscheint. Die Quelltextpruefung findet ihn ohne Anzeige.
Auch die Quelltextpruefung selbst wurde zweimal gegengeprueft: Zuerst
meldete sie zusaetzlich po_senden ("Senden", voellig harmlos) -- ihre
Blockerkennung lief bis zum naechsten Schluessel und schluckte dabei
einen Kommentar mit "&". Jetzt zaehlt sie geschweifte Klammern. Ein
Fehlalarm im Pruefwerkzeug ist fast so schaedlich wie ein uebersehener
Fehler: Man gewoehnt sich daran, ihn wegzusehen.
GEPRUEFT
32 Pruefungen im Portal (Computer und Handy), alle bestanden. Darunter:
114 Texte in allen fuenf Sprachen vollstaendig, Kundenpunkte stehen vor
der langen Liste, Aufgaben vor den Zahlungen, Abhaken meldet den
richtigen Punkt, alle Kaestchen mindestens 24 px, keine Fehler im
Protokoll. Dazu 55 Seiten-Sprach-Kombinationen ohne Kodierungsreste.
Ein Fehler im Test selbst gefunden und behoben: Die Adressabfrage prueft
jetzt den PFAD statt der ganzen Adresse. Der API-Server heisst
"postfach.dogfather-universe.com" -- ein includes("/postfach") traf den
HOSTNAMEN und damit jede Anfrage, auch die Uebersicht.
Versionsstempel und Cache-Name auf v5.
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
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]>
|
||
|
|
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]> |
||
|
|
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]> |
||
|
|
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]> |