e4d11caeb0c1e5af1f72842d98b785a9ff012856
11
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
0d3a4b78cd |
Zwei Befunde aus dem Handy-Lauf -- und eine Regel, die ihre eigene Ausnahme nicht kannte
Filipe hat die beiden breiten Sichtpruefungen freigegeben. pruef-handy
meldete vier Fehlschlaege, pruef-lesbarkeit war gruen.
BEIDE BEFUNDE WAREN NICHT VON MEINER AENDERUNG -- gemessen, nicht
vermutet: crew-index.html laedt weder kopf.js noch erklaerung.js, und
mein Commit hat dort nur die Versionsnummer angefasst. Die betroffene
Regel steht seit dem 27.08.2026 so da.
1. ZU KLEINE SCHRIFT AUF DER ZUGANGSWAND VON TEAM DOGI
`.marke` stand auf schmalen Bildschirmen auf .68rem = 10,88 px und
damit unter der Hausuntergrenze von 11,5 px -- betroffen waren die
Woerter "DogFather" und "Team Dogi". Das ist die erste Seite, die ein
neuer Modi ueberhaupt sieht, und sie wird mit dem Daumen bedient.
Jetzt .72rem = 11,52 px, dieselbe Hebung wie seinerzeit in heim.css.
Die Grundlinie in pruef-css-klassen wird MITGEZOGEN (43 -> 42):
Sonst duerfte der Fortschritt lautlos wieder verlorengehen, und eine
Grundlinie, die nur nach oben nachgibt, ist keine.
2. DIE BERUEHRZIEL-REGEL ZITIERTE WCAG 2.5.8, ABER NICHT IHRE AUSNAHME
Gemeldet wurden die zwei Verweise im Fliesstext der Treff-Regeln
("Der Treff", "Regeln & Hilfe", je 20 px hoch). 2.5.8 nimmt genau das
aber ausdruecklich aus: "Inline: The target is in a sentence or its
size is otherwise constrained by the line-height of non-target text."
Sie auf 24 px zu bringen hiesse, die Zeilenhoehe eines Absatzes zu
sprengen -- also einen Text kaputtzumachen, um eine Regel zu
erfuellen, die diesen Text gar nicht meint. Die Ausnahme ist eng
gefasst: nur <a>, nur wirklich inline, und nur wenn im selben Absatz
auch Text steht, der nicht zum Link gehoert. Ein allein stehender
Link bleibt ein Beruehrziel.
UND DIESE DATEI HATTE BIS HEUTE GAR KEINE GEGENPROBE. Sie konnte
also nie zeigen, dass sie ein zu kleines Ziel ueberhaupt bemerkt --
erst recht nicht, seit die Regel eine Ausnahme hat. Jetzt in beide
Richtungen: ein allein stehendes 20x20-Ziel MUSS auffallen, ein
gleich grosser Verweis im Satz darf es NICHT.
PRUEFUNGEN: pruef-handy 136 -> 138 (vier Fehlschlaege behoben, zwei
Gegenproben dazu), keine einzige weniger. pruef-lesbarkeit gruen
(12 s). pruef-css-klassen, pruef-erklaerung und pruef-neue-seiten nach
der gate.css-Aenderung noch einmal gelaufen, alle gruen.
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
88e2b5cd5d |
Der Wecker: das Zeitfeld ging auf -- nur ausserhalb des Bildschirms
Filipe: "wenn ich am handy auf den wecker drücke dan sieht man nichts."
Er hat woertlich recht. Der Knopf tut, was er soll, und das Zeitfeld
klappt auf -- es steht nur nicht im Bild. Aufgeklappt gemessen, fuenf
Breiten:
320 px Feld bei -127 .. -8 komplett draussen
360 px Feld bei -107 .. 12
390 px Feld bei -92 .. 27
412 px Feld bei -81 .. 38
430 px Feld bei -72 .. 47
DER GRUND IST EIN ANKER, DER GEWANDERT IST. `.tagesruf__feld` steht mit
`right: 56px` da -- "56 px nach links vom Knopf". Am Rechner ist das
richtig: Dort sitzt der Knopf am rechten Rand einer breiten Kachel, und
links davon liegt die Luecke zwischen Text und Uhr. Auf dem Handy wird
derselbe Knopf aus dem Fluss genommen und neben die zentrierte Uhr
gehaengt -- er steht dann ganz LINKS, und 56 px weiter links ist kein
Raum mehr, sondern der Bildschirmrand.
Der Abstand stimmte also noch, der Bezugspunkt nicht mehr. Dieselbe
Sorte Fehler wie die feste Umbruchschwelle und die 62 px Kopfhoehe: eine
Zahl, die fuer eine Anordnung ausgerechnet wurde und in der zweiten
still falsch ist.
Es oeffnet jetzt auf dem Handy nach RECHTS statt nach links -- in die
Richtung, in der dort der Platz ist. Das ist keine zweite Zahl, sondern
dieselbe Regel andersherum ("ins Freie oeffnen"). Der linke Rand des
Knopfes ist nie kleiner als 0, das Feld 119 px breit, der schmalste
Bildschirm 320 -- damit liegt es auf jeder Breite im Bild, ohne dass
eine Schwelle stimmen muss. `max-width: calc(100vw - 24px)` als
Sicherung, falls das Feld je breiter wird.
Die Regel steht in heim.css direkt neben der Regel, die den Knopf
verschiebt. Sie gehoeren zusammen: Wer den Anker bewegt, sieht die
Folge in derselben Medienabfrage.
GEPRUEFT WIRD ES JETZT AUCH (pruef-handy, 99 -> 115 Pruefungen). Das
Feld wird dafuer aufgeklappt gemessen, nicht zugeklappt -- ein
verstecktes Feld hat keine brauchbare Lage, und genau die ist die
Frage. Gegenprobe ist die Messung von vorher: Mit demselben Messmittel
lag das Feld bei -92..27, die Bedingung waere rot gewesen.
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
6c48579f66 |
Die Kopfleiste bleibt auch in einer fremden Sicht in EINER Reihe
Filipe, mit Bildschirmfoto aus der installierten App: "es ist noch nicht alles in einer zeile und irgendwie funktionieren nicht alle knoepfe." DER GRUND WAR NICHT DIE BREITE SEINES GERAETS, SONDERN DER ZUSTAND. In der eigenen Sicht klappt der Umschalter auf 36 px zusammen; sobald man die Sicht einer anderen Person uebernimmt, stand der Name darin und er war 152 px breit. Gemessen waren es dann zwei Zeilen bei 320, 360, 390, 412 UND 430 px -- ausnahmslos. Auf seinem Bild stand "Miesmus..." im Umschalter und der goldene Rahmen um die Seite: er war in einer fremden Sicht. MEINE PRUEFUNGEN HABEN DEN FALSCHEN ZUSTAND GEMESSEN. pruef-handy lief ausschliesslich in der eigenen Sicht und war deshalb gruen, waehrend es beim Nutzer zweizeilig war. Ein gruener Haken sagt nur, dass die Bedingung erfuellt war -- nicht, dass sie den Zustand geprueft hat, in dem der Nutzer ist. Die Pruefung wechselt jetzt selbst in eine fremde Sicht (92 -> 99 Pruefungen). WAS SICH AENDERT - Auf dem Handy ist der Umschalter auch in fremder Sicht ein Zeichenknopf: Auge + Anfangsbuchstabe, 46-48 statt 152 px, in der ROLLENFARBE der Person, deren Sicht laeuft. Die Farbe kommt aus `data-rolle` -- dieselbe Zuordnung, die gate.css ohnehin hat, keine zweite Farbliste. - Der volle Name wandert in ein Band unter die Leiste, zusammen mit "Zurueck zu meiner Sicht" als ganzem Satz statt als 28-px-Kreuz. Er steht dort GANZ statt als "Miesmus...". Am Rechner bleibt alles wie bisher; dort ist Platz. - Der Rahmen um die Seite nimmt dieselbe Farbe an. Man sieht damit nicht nur DASS eine fremde Sicht laeuft, sondern WESSEN. - Das `:not([data-fremd="ja"])` faellt an beiden Stellen weg. Es war der ganze Fehler: eine Regel, die den wichtigeren Fall ausnahm. UND DER BLOCK FUER SCHMALE GERAETE STAND AN DER FALSCHEN STELLE Er galt bis 340 px und stand 3600 Zeilen VOR dem 560er-Block -- bei gleicher Spezifitaet verliert er damit. Gewirkt hat er nur, weil sein Selektor zufaellig ein `:not()` trug. Jetzt steht er direkt hinter dem 560er und gilt bis 400 px (34 px je Knopf, 4 px Abstand). Damit bleibt auch bei 360 px auf den UNTERSEITEN alles in einer Reihe -- dort stehen zusaetzlich der Zurueck-Knopf und die Glocke. Gemessen nach dem Umbau, eigene und fremde Sicht, Start- und Unterseite: 360, 390, 412 und 430 px alle einzeilig. Offen bleibt 320 px (iPhone SE 1. Generation bzw. Anzeige-Zoom) -- dort passt es ohne das Weglassen einer Funktion nicht, das ist eine Entscheidung und kein Handgriff. DER SICHERE BEREICH (auf Filipes Zusage) Jede der 20 Seiten sagt `viewport-fit=cover`, aber im ganzen Workspace stand kein einziges `env(safe-area-inset-*)`. Sein Android ist NICHT betroffen (im Bildschirmfoto nachgesehen), ein iPhone waere es: Von einem 36-px-Knopf blieben unter einer 47 px hohen Statusleiste rechnerisch 5 px zum Antippen. Einmal zentral benannt (gate.css) und an den vier Stellen angewandt, wo etwas am Rand klebt: Kopfleiste (oben und seitlich), Inhalt (seitlich und unten), Speichern-Leiste im Profil, Chat-Eingabe. Auf Geraeten ohne Aussparung sind alle vier Werte 0. Nebenbei: chat.js misst die Hoehe ueber der Chatflaeche jetzt einschliesslich des Bandes -- sonst stuende das Eingabefeld genau um dessen Hoehe unter dem Bildschirmrand. Derselbe Fehler wie mit den festen 62 px, nur mit einem anderen Element. Co-Authored-By: Claude Opus 5 <[email protected]> |
||
|
|
38416962b3 |
Kopfleiste am Handy: alles in einer Reihe
Filipe, mit Bildschirmfoto: "ich will dass es ueberall perfektionniert
wird. ich will dass du das richtig geil machst es soll alles in einer
reihe sein." Auf dem Bild stand "Abmelden" allein in einer zweiten
Zeile, darueber Teilen, Chat, Suche und das Profilbild.
--- GEMESSEN, BEVOR ETWAS GEAENDERT WURDE ---
Bei 390 px, alle fuenf Rollen:
verfuegbar fuer die rechte Gruppe 275 px
gebraucht als DogFather 393 px
(Sicht 150 · Teilen 38 · Chat 37 · Suche 47 · Bild 28 · Abmelden 93)
gebraucht als Scout/Manager/Spicy 243 px
gebraucht als Creator 205 px
Der Umbruch war also die richtige Antwort auf ein echtes
Platzproblem. `flex-wrap` misst und rechnet nicht -- das bleibt so.
Geaendert wird der PLATZBEDARF, nicht die Reaktion darauf. Eine
Schwelle, ab der nicht mehr umgebrochen wird, waere wieder eine
Rechnung von gestern: Beim naechsten Knopf staende alles uebereinander.
--- WAS SCHRUMPFT, UND WAS NICHT ---
Die drei Zeichen-Knoepfe waren 38, 37 und 47 px breit -- nebeneinander
sah das unruhig aus. Jetzt alle 36.
"Abmelden" wird auf schmalen Bildschirmen zum Zeichen (93 -> 36). Das
Wort bleibt im aria-label und am Rechner sichtbar: Dort ist Platz, und
ein Wort ist eindeutiger als ein Bild. Der Aufbau steht in kopf.js und
nicht in neunzehn HTML-Dateien -- neunzehn Stellen sind achtzehn
Gelegenheiten, eine zu vergessen.
Der Sicht-Umschalter wird ein Zeichen-Knopf wie die anderen (150 -> 36),
ABER NUR solange die eigene Sicht laeuft. Bei einer fremden behaelt er
den Namen, und dann darf die Leiste auch umbrechen: Dass man fremde
Zahlen ansieht, ist wichtiger als eine gerade Zeile. Das ist der
gefaehrlichste Fall dieser Funktion, und er bleibt unangetastet.
--- ZWEI DINGE, DIE ERST DIE MESSUNG GEZEIGT HAT ---
1. `max-width: 30px` am Umschalter-Kasten wirkte NICHT. Gemessen stand
da: berechnete Hoechstbreite 30 px, tatsaechliche Breite 104. Der
Knopf DARIN behielt seine Groesse und schob den Kasten wieder auf.
Wer nur den Rahmen begrenzt, begrenzt nichts -- die Breite kommt vom
Inhalt. Jetzt liegt der Knopf unsichtbar UEBER dem Auge: die ganze
Flaeche ist das Ziel, der Fokusring bleibt, die Breite ist 36.
2. Bei 360 px brach es weiter um, obwohl es rechnerisch passte. Ursache
war eine eigene Regel bei 380 px, die Marke und Bedienelemente
ausdruecklich in zwei Zeilen zwang -- richtig, solange die
Bedienelemente 243 bis 393 px brauchten, falsch seit sie 136 bis 238
brauchen. Die Schwelle liegt jetzt bei 300 px; darunter gibt es
Geraete, auf denen es wirklich nicht reicht.
--- Pruefung ---
pruef-handy, 15 neue Messungen (fuenf Rollen x 360/390/412): alle Teile
der Kopfleiste stehen in einer Reihe, Spanne 4 px.
Gemessen wird die ZEILENZAHL ueber die Oberkanten, nicht die Hoehe der
Leiste. Eine Hoehengrenze waere wieder eine Zahl von gestern -- sie
stimmt, bis jemand die Polsterung anfasst. Ob zwei Dinge in derselben
Zeile stehen, sieht man an ihrer Oberkante, und das gilt immer.
Ausserdem gruen: pruef-css-klassen.
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
9b1826721b |
Handy-Mitte, Babyblau und Spicy im Umschalter
Drei Bildschirmfotos, drei Befunde -- und alle drei waren messbar. --- SCREEN 2: RING UND UHR STANDEN SCHIEF --- Filipe: "ich will dass auf dem handy die uhr und der kreis ganz oben mit den erledigten aufgaben, schoen mittig, zentriert sind. die stehen sehr verzogen von der mitte. das soll bei jedem und jeder rolle verbessert werden." Gemessen bei 390 und 412 px, in allen fuenf Rollen, immer dieselbe Zahl: Ring 31 px nach links, Uhr 31 px nach rechts. Gleicher Betrag, entgegengesetzte Richtung -- eine Ursache, nicht zwei. `justify-content: center` zentriert den INHALT der Reihe, und in der Reihe steht neben dem Instrument noch ein Knopf (Glocke rechts vom Ring, Wecker links von der Uhr). Zentriert wurde also [Knopf + Abstand + Instrument] als Block; das Instrument rutschte um die halbe Knopfbreite zur Seite. Die Knopfbreite steht seit jeher als `--instrument-knoepfe: 62px` in derselben Datei -- 62 / 2 = 31. Die gemessene Zahl war von Anfang an aufgeschrieben, nur an anderer Stelle. Der Knopf zaehlt jetzt nicht mehr mit: aus dem Fluss genommen, neben das zentrierte Instrument gehaengt. NICHT um 31 px verschoben -- das waere dieselbe Zahl ein zweites Mal, und beim naechsten Knopf waere sie falsch. Jetzt folgt seine Lage dem Instrument, wie gross das auch ist. Nachher: 0 px Abweichung, alle fuenf Rollen, beide Breiten. --- SCREEN 3: DAS BABYBLAU WAR STAHLGRAU --- Filipe: "die rolle dogfather soll eine uebertrieben geile babyblau haben." Zum dritten Mal -- und die ersten beiden Male habe ich das Falsche vergroessert. Beide Male hatte ich den Abstand zwischen Rot- und Blaukanal im HEXWERT erhoeht (45 Stufen, dann 86). Diesmal zuerst gemessen, was am Bildschirm ankommt: Die DogFather-Zeile traegt 98,7 % farbige Bildpunkte -- MEHR als jede andere Rolle. An der Menge lag es also nie. Ihr Mittelwert war rgb(43,62,78): 35 Stufen zwischen Rot und Blau. Das ist Stahlgrau. Die richtige Groesse ist die SAETTIGUNG. In OKLab hatte #9ed3f4 eine Buntheit von 0,0718 -- der blasseste Wert aller fuenf Rollen. #5fbdff hat 0,1303, also 81 Prozent mehr. Die Zeile kommt damit auf rgb(36,60,79), und der mittlere Kanalabstand steigt von 35,2 auf 43,0. Nachgerechnet, was NICHT verlorengeht: Kontrast auf dem Grund 9,75:1 (vorher 12,49) -- weit ueber den 7 fuer AAA. Abstand zur naechsten Rollenfarbe 0,1608 in OKLab, vorher 0,1466; die Hausgrenze liegt bei 0,0973. DogFather ist also SICHERER unterscheidbar als vorher. Gemessen an der echten Flaeche: 8,84:1 und 9,60:1. --- SCREEN 4: SPICY FEHLTE IM UMSCHALTER --- Filipe: "ich will da auch noch die spicy rolle sehen und die leute in der rolle wie die anderen." Der Sicht-Umschalter fuehrte eine EIGENE Rollenliste -- vier Eintraege, Spicy Media fehlte. Zum vierten Mal derselbe Fehler: eine zweite Fassung einer Liste, die es zentral schon gibt. Vorher traf es die Leitungsliste (ein Set), die Rollennamen (ein Objekt in fuenf Skripten -- im Chat stand "UNDEFINED" ueber einem Namen) und die Personenliste. Jetzt steht dort keine Liste mehr, sondern eine Ableitung aus `ROLLENFOLGE` und `ROLLEN_GRUPPE`. Kommt eine sechste Rolle, ist sie ohne eine Zeile Arbeit dabei. --- Pruefung --- pruef-handy: zehn neue Messungen (fuenf Rollen x zwei Breiten), alle 0 px. Die beiden fehlenden Rollen sind dafuer in den Testdaten ergaenzt -- eine Pruefung an drei von fuenf haette "bei jeder Rolle" nicht belegen koennen. pruef-sicht: Cigdem als Spicy-Media-Person ergaenzt. Ohne sie waere es nie aufgefallen -- eine Rolle ohne Leute wird ohnehin weggelassen, und die alte Zusicherung "Manager, Scouts, Creator" waere weiter gruen gewesen. Dazu eine Gegenprobe, dass die Reihenfolge WIRKLICH aus der zentralen Liste kommt und nicht wieder abgeschrieben ist. pruef-personen-kachel: DogFather-Kontrast neu dabei. Ausserdem gruen: pruef-css-klassen, pruef-lesbarkeit. Co-Authored-By: Claude Opus 5 <[email protected]> |
||
|
|
233cd76d78 |
Der Handy-Durchgang: drei echte Bedienfehler, alle vom selben Ursprung
Filipe: "ich will dass du die komplette seite auf dem handy abcheckst.
ich will dass alles perfekt aussieht und bedienbar ist."
DER SCHWERSTE FUND: Auf ZWOELF Seiten war der "Meine Sicht"-Umschalter
nicht bedienbar -- wer darauf tippte, landete im Chat.
Bei 412 px (der haeufigsten Android-Breite ueberhaupt) brach die
Kopfleiste nicht um, der Umschalter wurde auf 50 px zusammengedrueckt,
sein Knopf behielt aber seine 104 px Mindestbreite und lag damit quer
ueber dem Chat-Knopf. Sichtbar war davon nichts.
Und die Ursache steht seit dem 05.09. woertlich im Kommentar daneben:
"Die Rechnung ging genau auf, solange rechts VIER Dinge standen. Mit der
Glocke sind es FUENF, und bei 320 px passte es nicht mehr." Am 06.09.
habe ich den Chat-Knopf dazugesetzt -- SECHS -- und die Schwelle bei 380
gelassen. Derselbe Fehler, eine Position weiter.
Die Lehre ist nicht "380 auf 430 erhoehen"; das waere er ein drittes
Mal, nur mit einer anderen Zahl. Eine feste Schwelle ist eine Rechnung,
die jemand einmal aufgestellt hat und die beim naechsten Knopf still
falsch wird. `flex-wrap: wrap` OHNE Schwelle rechnet nicht, sondern
misst -- es bricht genau dann um, wenn der Platz nicht reicht.
DASSELBE NOCH EINMAL, am anderen Ende: Bei 1280 px brauchte die Leiste
1235 px (Marke 375 + Bedienelemente 844 + Abstand 16) und hatte 1200.
Auch hier war der Chat-Knopf der Tropfen. Sie brach um, sobald das
Skript die Bedienelemente eingehaengt hatte, und schob die ganze Seite
52 px nach unten -- CLS 0,94. Jetzt gibt die MARKE nach (sie darf
gekuerzt werden, ein Knopf nicht), und umgebrochen wird nur noch auf
sehr schmalen Geraeten.
WEITERE ECHTE FUNDE:
* /workspace/api/chat/ungelesen wurde auf JEDER Seite ZWEIMAL geholt:
einmal beim Laden, einmal Millisekunden spaeter beim Aufgehen des
Ereignisstroms. Der 'open'-Zuhoerer war fuer Wiederverbindungen
gedacht und feuerte auch beim ersten Mal.
* Drei Kacheln teilten sich einen Farbton mit einer anderen (18 Farben
auf 21 Kacheln). Filipe wollte ausdruecklich, dass jede ihre eigene
hat. Nicht eine Farbe dazuerfunden -- der ganze Farbkreis ist mit
tools/kachel-farben.mjs neu in 21 geteilt; kleinster Abstand zweier
Nachbarn jetzt 120 Grad (vorher 106). Dabei fiel eine feste 16 in
der Mischschleife auf: Bei 18 Kacheln wurden die letzten beiden nie
mitgemischt.
* Der Agentur-Untertitel wurde auf dem Handy abgeschnitten.
* Ein zugeklappter <details>-Kasten (Kalender-Abo) verdeckte einen
Filter-Chip: Chromium versteckt dessen Inhalt ueber
`content-visibility`, nicht ueber `display` -- die Kaesten behalten
eine Groesse. Dieselbe Falle wie bei den Zeitbloecken, dieselbe
Loesung.
UND DREI PRUEFUNGEN, DIE SELBST FALSCH LAGEN:
* "achtzehn Kacheln" stand als feste Zahl im Test. Eine Pruefung, die
bei jeder neuen Kachel rot wird, erzieht dazu, ihr Rotwerden zu
ignorieren. Sie zaehlt jetzt aus bereiche.js.
* "das Licht der Kalender-Kachel (tuerkis) muss mehr Blau als Rot
haben" -- Wissen von aussen, und nach dem Neurechnen war der
Kalender rosa. Gemessen wird jetzt gegen den Ton der Kachel selbst.
* pruef-workspace-umzug meldete sein Ergebnis in eigenen Worten. Der
Gesamtlauf las daraus NULL Pruefungen und schrieb bei JEDEM Lauf ein
FEHL, obwohl alle 31 Punkte bestanden. Ein Fehlalarm, der immer
kommt, macht den einen echten unsichtbar.
Und weil "BUTTON 'Meine Sicht' verdeckt" mich eine Stunde gekostet hat,
sagen pruef-handy und pruef-tempo jetzt DAZU, was verdeckt und was
springt -- mit Elternkette und Koordinaten. Ein Befund, den man nicht
verorten kann, ist ein halber.
NEU: der Kalender zum Abonnieren (Stufe 3.2). Persoenlicher, jederzeit
widerrufbarer Link fuer Google, Apple und Outlook. 36 Pruefungen, die
das ICS ZURUECKLESEN statt es anzusehen -- entfaltet, entschluesselt,
verglichen. Wichtigster Punkt: Der Weg ohne Anmeldung darf nichts
zeigen, was der Weg mit Anmeldung nicht zeigt.
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
bede91921d |
Der sechste Bereich, und zwei Pruefungen, die den Lauf lahmgelegt haben
DER AGENTUR-BEREICH (Stufe 4 des Plans)
Kernprinzip 04 des Konzepts lautet woertlich "Die Agentur bleibt
angebunden" -- und dafuer gab es bis heute nichts. Fuenf Bereiche
standen, der sechste fehlte vollstaendig. Damit stand nirgends, welche
Kampagne laeuft, welche Schulung ansteht und wie ein Anliegen an die
Agentur ausgegangen ist. Das lief ueber private Nachrichten: nicht
auffindbar, nicht nachvollziehbar, beim naechsten Mal von vorn.
Vier Arten, und die vierte ist der Punkt: kampagne, schulung, anliegen
und ZUSTAENDIGKEIT. Die letzte ist keine Verlegenheit, sondern das, was
das Konzept ausdruecklich fordert -- Betreuung und Umsetzung sind unsere
Seite, offizielle Wege sind Agenturseite. Solange das nur im Kopf steht,
wird es bei jedem Streitfall neu verhandelt.
Der Umbau war das eigentliche Risiko, nicht der Bereich: Ein CHECK
laesst sich in SQLite nicht aendern, die Tabelle muss neu gebaut werden
-- und dabei werden ALLE vorhandenen Eintraege umgeschrieben. Deshalb
geht pruef-agentur.mjs (31 Pruefungen) den Weg wirklich: Sie baut eine
Datenbank im ALTEN Stand nach, fuellt sie mit allen fuenf Bereichen,
laesst die echte Anwendung darueberlaufen und zaehlt danach jede Zeile
UND jedes Feld nach -- auch die seltenen Spalten (hook, creator_extern),
die man beim Abschreiben des Bauplans vergisst. Wichtigste Gegenprobe:
Der CHECK muss danach noch BEISSEN. Eine Umstellung, die nebenbei die
Schranke entfernt, sieht aus wie ein Erfolg und ist der schlimmere
Ausgang.
Nebenbei drei abgeschriebene Bereichslisten beseitigt (Wochenbericht,
Suche, Report-Ziele). Im Wochenbericht waere der neue Bereich sonst
schlicht nicht vorgekommen -- ohne Fehler, ohne Luecke, einfach nicht da.
ZWEI PRUEFUNGEN, DIE DEN GESAMTLAUF ZUM STILLSTAND BRACHTEN
pruef-call-kategorien.mjs hing DREI STUNDEN. Ursache war ein Zeitzuender
in ihr selbst: Sie legte Calls auf "heute 18:00" und erwartete zwei
davon unter "Heute". Ab 18 Uhr sind die vorbei, der Server schiebt sie
nach "Protokoll fehlt", und die Oberflaeche unterteilt erst ab FUENF
anstehenden. Uebrig blieben vier, die Bloecke verschwanden, und die
Pruefung wartete auf einen Klick auf einen Block, den es nicht gab.
Genau die Sorte Fehler, vor der die Projektnotiz vom 06.09. warnt: Sie
war um 17:59 gruen und um 18:01 rot, ohne dass sich am Code etwas
geaendert hatte. Jetzt liegen alle Zeiten RELATIV zu jetzt, und die
Erwartung wird mit derselben Vorschrift gerechnet, die calls.js benutzt
-- statt Zahlen, die nur zu einer bestimmten Tageszeit stimmen.
Und der Grund, warum daraus ein Stillstand statt eines Fehlers wurde:
index.js setzt bewusst zwei Auffangnetze (uncaughtException,
unhandledRejection). Fuer den Betrieb richtig -- ein Fehler darf die
Website nicht offline nehmen. Fuer eine Pruefung fatal: Sie importiert
index.js in denselben Prozess und erbt die Netze. Ihr eigener Absturz
wird dann nur protokolliert, und der Express-Server haelt den Prozess
danach ewig am Leben. Kein Fehler, kein Ergebnis, kein Ende.
Deshalb zwei Abhilfen, die zusammengehoeren:
* server/helfer-notbremse.mjs -- haengt eigene Zuhoerer DANEBEN
(process.on ergaenzt, es ersetzt nicht) und beendet den Lauf mit
Fehler; dazu ein Wecker. In alle 42 Browserpruefungen eingebaut.
Der Betrieb bleibt unveraendert.
* tools/alles-pruefen.mjs gibt jeder Datei eine Frist von 600 s. Wer
sie reisst, wird abgebrochen und ZAEHLT ALS FEHLGESCHLAGEN, mit der
letzten Ausgabe davor als Beleg. Einzelne Dateien nachzuruesten hilft
nur bis zur naechsten ohne Notbremse -- deshalb sitzt sie dort, wo
sie fuer alle gilt, auch fuer die, die es noch nicht gibt.
AUSSERDEM: pruef-breiten.mjs pruefte 16 Seiten aus einer Liste von Hand,
chat.html und leistung.html fehlten darin. Der Chat war bei keiner
einzigen der neun Breiten je gemessen worden. Wie bei pruef-handy kommt
die Liste jetzt aus dem Verzeichnis.
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
80a8aac774 |
Der ganze Prueflauf blieb am Chat-Strom stehen -- behoben
BEFUND. Seit der Chat am 06.09. dazukam, LIEF DER GESAMTE
REGRESSIONSLAUF NICHT MEHR DURCH. Nicht "er wurde rot" -- er blieb
einfach stehen, bei Datei 3 von 62, ohne Fehlermeldung, ohne FEHL, ohne
Absturz. Nach zwoelf Minuten stand er immer noch dort. Von aussen sieht
"noch nicht fertig" genauso aus wie "haengt fuer immer"; deshalb ist
mir das gestern nicht aufgefallen, sondern erst, als ich den Lauf
gezielt beobachtet habe.
DIE URSACHE. pruef-alle-wege.mjs geht stumpf ueber ALLE 134
Schnittstellen und liest jede Antwort mit `await a.text()` aus. Der
Chat haelt seine Verbindung aber absichtlich offen und schickt neue
Nachrichten hinein, solange jemand zusieht (SSE). `text()` wartet, bis
der Server fertig ist -- und der wird nie fertig. Angemeldet als
DogFather trat der Lauf dort ein und kam nicht wieder heraus.
DIE ABHILFE, zwei Teile, die zusammengehoeren:
* Jeder Ruf hat jetzt eine Frist von 8 s. Laeuft sie ab, ist das ein
ERGEBNIS ("hing") und kein Absturz. Ein neuer Abschnitt meldet am
Ende, WELCHER Weg nicht geantwortet hat -- statt dass der Lauf
wortlos stehenbleibt.
* Bekannte Stroeme stehen in einer Liste MIT BEGRUENDUNG und werden
nicht uebersprungen, sondern anders geprueft: verbinden, Status
ablesen, abbrechen. Die Schranke wird damit genauso gemessen wie
ueberall. Zusaetzlich wird nachgemessen, dass ein eingetragener
Strom auch wirklich offen bleibt -- sonst verdeckte die Ausnahme
nur seine Inhaltspruefung.
Der "hing"-Zustand musste eigens gesammelt werden: In Abschnitt 1 haette
er ausgesehen wie "ohne Anmeldung erreichbar", in Abschnitt 2 waere er
ganz durchgefallen (`"hing" >= 500` ist false, Zeichenkette gegen Zahl).
Genau so verschwinden Befunde.
Ergebnis: 134 Schnittstellen, 532 Aufrufe, alles gruen, kein Haenger.
AUSSERDEM, gefunden beim Nachsehen:
* pruef-handy.mjs pruefte 15 Seiten -- aus einer Liste von Hand, die
veraltet war. chat.html, leistung.html und steckbrief.html standen
nicht darin: DREI von neunzehn Seiten waren nie auf einem Handy
gemessen worden, ausgerechnet der Chat. Die Liste kommt jetzt aus
dem Verzeichnis, die naechste neue Seite ist von selbst dabei.
* chat.html und leistung.html fehlte <link rel="manifest">. Auf dem
Handy heisst das: Wer die App installiert hat und ueber eine
Benachrichtigung dort landet, verlaesst den App-Rahmen -- die Seite
oeffnet im Browser, mit falscher Leistenfarbe. Ihre theme-color war
ausserdem eine andere als auf allen uebrigen Seiten. Beides behoben
UND als Pruefung in pruef-struktur nachgetragen, damit es beim
naechsten Mal nicht am Gedaechtnis haengt.
NEU: tools/wiederherstellung-proben.mjs — die Probe aufs Exempel.
Die Sicherung ausserhalb des Servers laeuft taeglich und prueft
`integrity_check`. Das sagt: die Datei ist nicht zerschossen. Es sagt
NICHT, ob die Anwendung damit startet, ob man sich anmelden kann und ob
die Daten vollstaendig sind. Eine Sicherung, die man nie zurueckgespielt
hat, ist eine Hoffnung. Das Werkzeug kopiert die juengste Sicherung in
ein Wegwerf-Verzeichnis, startet die echte Anwendung dagegen (damit
laufen alle Schemawanderungen wirklich durch), zaehlt vorher und
nachher, meldet sich an und ruft jede Seite auf. Drei Ausgaenge, nicht
zwei -- "konnte nicht nachsehen" ist weder Erfolg noch Fehler.
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
d7cf598b00 |
"Heute" war zwei Stunden lang gestern -- und vier Fehler auf Handy und PC
Auftrag: "einen grossen Check machen, ob alles klappt, auf dem Handy und
PC." Dafuer ein neuer Rundgang (pruef-grosscheck.mjs), der stumpf ueber
alles geht: 19 Workspace-Seiten mal 4 Rollen mal 2 Bildschirmgroessen
plus 33 oeffentliche Seiten, zweimal. 208 Seiten, 50 774 Elemente.
Solche Rundgaenge finden andere Fehler als gezielte Pruefungen: nicht
den falsch gerechneten Wert, sondern die Seite, die bei genau einer
Rolle ueberlaeuft.
=== DER WICHTIGSTE FUND: "heute" war in UTC gerechnet ===
Der Check lief um 01:10 Uhr. Ortszeit war der 2. September, in UTC noch
der 1. -- und in diesem Fenster rechnete die Anwendung an ZWOELF Stellen
"heute" als toISOString(), also in UTC. Server und Benutzer stehen beide
auf Europe/Berlin.
Was das im Alltag bedeutete, jede Nacht zwischen 0 und 2 Uhr:
* eine heute faellige Aufgabe galt noch nicht als faellig
* eine um Mitternacht ueberfaellig gewordene erschien erst um 2 Uhr
* der Filter "Heute faellig" zeigte den Vortag
* Datumsfelder schlugen gestern vor
* der Kalender begann seine Vorgabe einen Tag zu frueh
Also genau dann, wenn nach einem Stream gearbeitet wird.
kalender.js machte es die ganze Zeit RICHTIG -- samt Begruendung, warum
die ARITHMETIK trotzdem in UTC laufen muss (UTC-Mittag ueberlebt die
Zeitumstellung; wer lokal rechnet, verliert am 27. Oktober einen Tag).
Diese Trennung gilt jetzt ueberall, aus je einer Quelle:
RECHNEN mit Datumsangaben -> UTC-Mittag, unveraendert
WELCHER TAG IST HEUTE -> Ortszeit (heuteLokal/tagLokal im Server,
window.heuteLokal in kopf.js)
WIE ES AUFFIEL, und das ist die eigentliche Lehre: Zuerst schlugen zwei
Pruefungen fehl -- und die Ursache lag in IHNEN, sie rechneten selbst in
UTC (36 Stellen in 17 Dateien). Nach deren Reparatur schlugen sie WIEDER
fehl, und erst da zeigten sie auf die Anwendung. Wer beim ersten Mal
aufgehoert haette ("ist ja nur die Pruefung"), haette den echten Fehler
nie gesehen.
Nachtrag desselben Musters: pruef-uebersicht legte den Termin weiterhin
in UTC an, waehrend die Erwartung schon auf Ortszeit stand. Wer eine
Datumsrechnung umstellt, muss BEIDE Seiten umstellen -- die, die
schreibt, und die, die prueft.
=== VIER FEHLER AUF HANDY UND PC ===
1. Ein langer Creator-Name ("SpongBobSchwammKopf") schob die Startseite
auf dem Handy um 48 Pixel aus dem Bild -- ein Wort ohne Trennstelle,
und die Seite liess sich seitlich wegschieben. Trifft echte Namen:
Creator heissen selten "Tim".
2. Die klebende Speicherleiste verdeckte auf dem Handy ein Textfeld.
Beim Tippen sieht man die eigene Zeile nicht. Behoben mit
scroll-margin-bottom (WCAG 2.2, 2.4.11 "Focus Not Obscured").
3./4. Zwei Beschriftungen waren mit 9,6 px (Uebersicht: "ueberfaellig",
"dringend", "offen") und 9,9 px (Kalender: "heute") zu klein. Fuers
Handy gab es laengst eine Ausnahme -- nur der Rechner war vergessen
worden. Ausgerechnet die Woerter, die den Zahlen ihre Bedeutung geben.
=== WAS KEINE FEHLER WAREN ===
Der erste Durchgang meldete 19 Maengel, die keine waren. Alle einzeln im
Quelltext nachgeprueft und dem Rundgang beigebracht:
* Kacheln und Kopfzeilen "abgeschnitten" -- das Wasserzeichen ragt
ABSICHTLICH ueber den Rand (steht so im Quelltext)
* "verdeckt: wahl2__echt" -- das echte <select> liegt absichtlich
unsichtbar unter seinem Knopf
* "zurueck-knopf__text abgeschnitten" -- das uebliche Muster fuer
"nur fuer Vorleseprogramme"
* drei "zu kleine" Verweise -- WCAG 2.5.8 nimmt Verweise im Fliesstext
AUSDRUECKLICH aus. Eine Pruefung, die ihre eigene Messlatte nicht
kennt, misst nichts.
Beim vierten Punkt haette ich fast an der falschen Stelle repariert.
Und statt die Sticky-Meldung abzuschalten (dann faende sie auch echte
Ueberdeckungen nie mehr), wurde sie GENAUER: Ueberdeckt etwas Klebendes
ein Eingabefeld, ist das nur in Ordnung, wenn das Feld genug
scroll-margin-bottom hat, um darunter hervorzukommen. Aus einer vagen
Meldung wird eine pruefbare Zusage.
Vier Gegenproben belegen, dass der Rundgang ueberhaupt etwas finden
kann: ein zu breites Element, ein winziger Knopf, ein winziger Verweis
AUSSERHALB eines Satzes und ein wirklich abgeschnittenes Wort werden
alle gemeldet. Ohne diesen Nachweis waere "alles in Ordnung" wertlos.
Co-Authored-By: Claude Opus 5 <[email protected]>
|
||
|
|
1c00770ec5 |
Lesbarere Kaesten, und DogFather kann durch fremde Augen sehen
SCREEN 1 -- "die Kachel ganz leicht dunkler, so dass man den Text besser gelesen bekommt, aber nicht zu viel, so dass man den Hasen noch sieht." Die Erklaerkaesten stehen jetzt auf 88 statt 78 Prozent Deckung. Zehn Punkte sind gemessen der Unterschied zwischen muehsam und ruhig lesbar und lassen zwoelf Prozent Bild durch -- das Motiv bleibt sichtbar. "und die von wichtigen und neuen PDFs sollen auch staerker sein." Das war kein Geschmack, sondern ein Fehler: `background` ist eine Eigenschaft, keine Schicht. Die Zeile `background: rgba(232,192,125,.045)` hat die Flaeche nicht getoent, sondern ERSETZT -- uebrig blieben viereinhalb Prozent Deckung. Damit war ausgerechnet die Anleitung, die jeder lesen soll, die am schwersten lesbare der Seite. Die Toenung liegt jetzt als Schicht darueber. Gemessen: 88 % gegen 78 % bei einer gewoehnlichen. pruef-lesbarkeit.mjs misst das an ECHTEN PIXELN (Text kurz unsichtbar machen, Flaeche fotografieren, WCAG-Formel) und kennt ZWEI Grenzen -- lesbar genug UND durchsichtig genug. Mit nur einer haette sie eine schwarze Flaeche am besten gefunden, und das wollte niemand. SCREEN 2 -- "ich will alles von den Scouts und Managern einsehen koennen, auswaehlen, was und von wem. Ueberall, auf jeder Seite. NUR WIR BEIDE SOLLEN DIESE OPTION HABEN." Die naheliegende Loesung waere ein Filter je Seite gewesen -- also eine zweite Rechteregel in zwoelf Modulen, und eine Rechteregel an zwoelf Stellen stimmt irgendwann an elf. Stattdessen wird die PERSON getauscht, nicht die Regel: Waehlt DogFather einen Scout, laufen alle vorhandenen Sichtbarkeitsregeln unveraendert mit diesem Scout. Er sieht exakt dessen Arbeitsplatz -- nicht mehr, nicht weniger. Keine neue Rechteregel. Im Browser genauso: EIN Ort statt vierzehn. fetch wird einmal umgeleitet und haengt den Wert an jede lesende Abfrage an. Neue Seiten sind damit von selbst dabei; man kann es nicht vergessen. Drei Sicherungen: nur admin (auf dem SERVER geprueft, nicht in der Oberflaeche), nur lesend (geschrieben wird immer im eigenen Namen -- sonst staende im Protokoll der falsche Name), nur aktive Personen. Und ein Rahmen um die Seite, solange eine fremde Sicht laeuft. Der gefaehrlichste Fall ist nicht, dass man nicht umschalten kann, sondern dass man vergisst, dass man umgeschaltet hat -- und drei Aufgaben statt dreissig fuer den Bestand haelt. FUENF FEHLER, DIE DIE PRUEFUNGEN GEFUNDEN HABEN: 1. steckbrief.html hat die Kopfleiste NIE gefuellt -- dort stand monatelang "…" statt des eigenen Namens. Aufgefallen, weil der Umschalter dort fehlte. Jetzt zusaetzlich ein Netz darunter: Meldet sich nach kurzer Zeit niemand, holt der Kopf sich selbst, wer angemeldet ist. Die naechste neue Seite kann es nicht mehr vergessen. 2. Der Umschalter sprengte die Kopfleiste (46 px am Rechner, 117 px am Handy) und drueckte den Abmelden-Knopf hinaus. 3. Ich habe das <select> gestaltet -- wahl.js ersetzt aber jedes Auswahlfeld durch einen eigenen Knopf und schrumpft das echte Feld auf einen Pixel. Meine Regeln haben es wieder auf 20 x 44 aufgeblasen, wo es als unsichtbares Hindernis ueber dem Knopf lag. Gestaltet wird jetzt der Knopf. 4. Ein Wettlauf: Auf profil.html rufen zwei Dateien werZeigen() auf. Beide kamen an "gibt es den Umschalter schon?" vorbei, bevor eine ihn angehaengt hatte -- zwei Umschalter uebereinander. Die Sperre gehoert vor das erste await. 5. Die Handy-Pruefung bemaengelte ein Schild, das dort per display:none gar nicht erscheint. Sie sieht jetzt nur noch sichtbaren Text an -- eine Pruefung, die Unsichtbares anmahnt, gewoehnt man sich ab zu lesen. Dazu zwei Messfehler in den Pruefungen selbst: getComputedStyle liefert ein LEBENDES Objekt (die Farbe wurde gelesen, nachdem der Text unsichtbar gemacht war -- gemeldet wurden 1,17:1 fuer tadellos lesbaren Text), und ein Vergleich lief still ins Leere, weil die Vergleichsdaten fehlten. pruef-sicht.mjs stellt den MISSBRAUCH an den Anfang: Scout, Manager und Creator haengen ?sicht= an und muessen ignoriert werden; erfundene Nummern, Buchstaben und ein Einschleusversuch fallen auf die eigene Sicht zurueck; eine abgeschaltete Person liefert keine Sicht mehr; und was DogFather bei fremder Sicht anlegt, steht unter SEINEM Namen. Co-Authored-By: Claude Opus 5 <[email protected]> |
||
|
|
1fe443e59c |
Handy durchgeprueft, Lichtfarbe je Kachel, haengendes Licht behoben
DAS LICHT BLIEB HAENGEN -- vier Ursachen, jede einzeln behoben:
1. EIN WETTLAUF. Zwischen dem Anmelden eines Bildaufbaus und seinem
Ablauf konnte der Zeiger die Karte laengst verlassen haben. Dann hatte
pointerout schon aufgeraeumt, und der Bildaufbau schaltete das Licht
gleich wieder AN. Der haeufigste Fall und der unauffaelligste.
2. UEBER EINE LUECKE VERLASSEN. Wer eine Karte nicht ueber eine
Nachbarkarte verliess, sondern ueber den Zwischenraum, loeste kein
Ereignis aus, das die alte Karte kannte.
3. GESCROLLT, OHNE DIE MAUS ZU BEWEGEN. Die Karte wandert unter dem
stehenden Zeiger weg -- es kommt gar kein Zeigerereignis. Jetzt wird
beim Scrollen nachgesehen, ob die beleuchtete Karte noch unter dem
Zeiger liegt.
4. FENSTER ODER TAB VERLASSEN. Auch dort kommt nichts mehr.
Es gibt jetzt genau EINE beleuchtete Karte -- mehr kann es nicht geben,
es gibt ja nur einen Zeiger. Beim Wechsel geht die alte aus, bevor die
neue angeht.
DIE FARBE GEHOERT ZUR KACHEL. Auf der Wissensseite leuchteten alle sechs
Welten violett, weil die Farbe dort --w heisst und der ganze uebrige
Workspace --ton benutzt. Das Licht griff auf --ton zu, fand nichts und
nahm den Farbton der SEITE. Dieselbe Luecke bei den Aufgaben-Spalten
(--sfarbe), den Kalenderkarten (--afarbe) und den Kalenderzeilen
(--zfarbe). Alle vier setzen jetzt --ton mit.
Nachgewiesen an echten Bildpunkten, nicht am Quelltext: Der Zeiger wird
auf die Aufgaben-Kachel gesetzt (dort muss Rot ueberwiegen: 85 zu 22)
und auf die Kalender-Kachel (dort Blau: 71 zu 13). Ein
Zeichenkettenvergleich haette das nicht gekonnt -- der Browser rechnet
color-mix() aus und schreibt je nach Fassung rgb(), color() oder oklab()
zurueck.
DAS HANDY, komplett durchgeprueft: neue pruef-handy.mjs faehrt alle
fuenfzehn Seiten auf DREI echten Geraetegroessen ab (320 px iPhone SE,
390 px iPhone, 412 px Android) und misst fuenf Dinge, die am Rechner
unsichtbar sind. Gefunden und behoben:
* ZWEI ECHTE UEBERLAEUFE (startcheck +27 px, automation +33 px). Die
Seite liess sich waagerecht schieben -- auf einem Telefon der
schlimmste Fehler. Ursachen: zwoelf Raster mit festem Mindestmass
(minmax(280px, 1fr) kann nicht schrumpfen -> min(280px, 100%)),
zwoelf feste Mindestbreiten an Auswahlfeldern, und ein "flex: none"
an den Stufen-Knoepfen, das jedes Schrumpfen verbot. "width: 100%"
allein reichte dort nicht.
* BERUEHRZIELE unter 24 px (WCAG 2.2, Kriterium 2.5.8). Auswahlfelder
waren 18 bis 22 px hoch. Jetzt 44 px -- die Empfehlung von Apple und
Google, und der Daumen ist nun einmal breiter als ein Mauszeiger.
Nebenbei behebt die Schriftgroesse 16 px das Hineinzoomen von iOS.
* SCHRIFT unter 11,7 px an 52 Stellen. Gesucht wurden sie nicht von
Hand -- das waere ein Ratespiel gewesen und haette die Haelfte
uebersehen -- sondern durch Durchsuchen der Stildateien nach
font-size unter 0,73rem.
ZWEI FEHLER IN DEN EIGENEN PRUEFUNGEN gefunden und behoben: Die
Schriftregel griff zuerst gar nicht (start.css wird VOR den Seitenstilen
geladen, bei gleicher Staerke gewinnt die spaetere -- jetzt mit
body.start qualifiziert), und die Lichtpruefung scrollte 600 px und
stellte nicht zurueck, sodass die folgende Pruefung ins Leere zeigte.
GEGENPROBE gemacht: Mit absichtlich eingebauten Fehlern (8-px-Schrift,
500 px breiter Inhalt) meldet die Handypruefung sofort Rot. Eine
Pruefung, die immer bestaetigt, bestaetigt nichts.
Alle achtzehn Pruefungen laufen gruen.
Co-Authored-By: Claude Opus 5 <[email protected]>
|