diff --git a/server/pruef-chat-optik.mjs b/server/pruef-chat-optik.mjs
index d8e015ca..95e4249f 100644
--- a/server/pruef-chat-optik.mjs
+++ b/server/pruef-chat-optik.mjs
@@ -92,7 +92,13 @@ const pw = await import("file:///C:/Users/qciga/Documents/Obelix/Analyse/node_mo
const browser = await pw.chromium.launch();
async function alsRolle(rolle, code, wohin = "chat.html", breite = 1280) {
- const ctx = await browser.newContext({ viewport: { width: breite, height: 900 } });
+ /* MIT FINGER, WENN ES SCHMAL IST. Playwright schaltet
+ `pointer: coarse` nur ein, wenn der Zusammenhang Beruehrung kennt
+ -- ohne das misst man den Rechner und glaubt, es sei das Handy.
+ Genau daran ist mir am 23.09. eine Messung danebengegangen. */
+ const ctx = await browser.newContext({
+ viewport: { width: breite, height: 900 },
+ hasTouch: breite < 900, isMobile: breite < 900 });
const seite = await ctx.newPage();
await seite.goto(BASIS + "/workspace/", { waitUntil: "networkidle" });
await seite.click(`.rolle[data-rolle="${rolle}"]`);
@@ -671,6 +677,145 @@ melde("\n=== Antworten quetscht das Schreibfeld nicht ===");
}
}
+/* =======================================================================
+ DIE SCHREIBZEILE AUF DEM HANDY (23.09.2026)
+
+ Filipe schreibt vom Handy. In dieser einen Zeile stehen inzwischen
+ SECHS Dinge: Bueroklammer, Mikrofon, GIF, Emoji, Schreibfeld,
+ Senden -- die letzten drei sind in der Nacht zum 23.09. dazu-
+ bzw. umgekommen.
+
+ WARUM DAS GEFAEHRLICH IST, steht in den Hausregeln: Am 06.09.2026
+ kam ein sechstes Element in die Kopfleiste, und bei 412 px lag ein
+ Knopf ueber dem anderen -- wer auf "Meine Sicht" tippte, landete im
+ Chat, auf zwoelf Seiten.
+
+ GEMESSEN AM 23.09., VOR DEM UMBAU:
+ 320 px Feld 164
+ 390 px Feld 130 -- und "Senden" ALLEIN auf einer eigenen Zeile
+ 412 px Feld 151 -- dito
+
+ Das Feld lag auf seiner Untergrenze, und der Knopf, der die
+ Nachricht wegschickt, war weiter vom Text entfernt als die
+ Bueroklammer. Kaputt war nichts; benutzbar war es auch nicht.
+
+ NACH DEM UMBAU (zwei Gruppen: Werkzeuge / Schreiben):
+ 320 px Feld 214 390 px Feld 278
+ 412 px Feld 299 1280 px Feld 560
+
+ Diese Pruefung haelt beides fest: dass das Feld breit genug bleibt,
+ und dass Senden dabei steht.
+ ======================================================================= */
+melde("\n=== Die Schreibzeile auf dem Handy ===");
+{
+ /* ==== MIT JEMANDEM, DER ALLE VIER WERKZEUGE HAT =================
+
+ Der erste Anlauf mass mit einem Scout -- und der bekommt Mikrofon
+ und GIF gar nicht zu sehen (nur Team Dogi und DogFather duerfen
+ Sprachnachrichten und GIFs schicken). Gemessen wurde damit eine
+ Zeile mit ZWEI Dingen darin, waehrend der gefaehrliche Fall der
+ mit VIER ist.
+
+ Aufgefallen ist es erst in der Gegenprobe: Mit der alten Fassung
+ kam das Feld auf 178 px statt der 130, die ich am selben Tag von
+ Hand gemessen hatte. Zwei verschiedene Zahlen fuer dieselbe
+ Sache -- das war der Hinweis.
+
+ Jetzt DogFather im Treff: vier Werkzeuge, und der Raum ist
+ sicher da. */
+ const handy = await alsRolle("admin", "CODE-DOGI-0001", "chat.html?raum=treff", 390);
+ try {
+ await handy.seite.waitForSelector("#schreiben:not([hidden])", { timeout: 8000 });
+ await handy.seite.waitForTimeout(900);
+ const zeile = await handy.seite.evaluate(() => {
+ const f = document.getElementById("text");
+ const senden = document.getElementById("senden");
+ const werk = document.querySelector(".chat__werkzeuge");
+ const r = (e) => { const x = e?.getBoundingClientRect();
+ return x ? { b: Math.round(x.width), h: Math.round(x.height),
+ y: Math.round(x.top), x: Math.round(x.left), re: Math.round(x.right) } : null; };
+ /* Ueberlappt irgendetwas in der Zeile? Genau das ist am 06.09.
+ passiert -- und man merkt es erst, wenn man danebentippt. */
+ const stuecke = [...document.querySelectorAll(
+ "#schreiben button, #schreiben textarea")]
+ .filter((e) => { const x = e.getBoundingClientRect(); return x.width > 1 && x.height > 1; })
+ .map((e) => ({ was: e.id || e.className.toString().split(" ")[0], ...r(e) }));
+ const drueber = [];
+ for (let i = 0; i < stuecke.length; i++) {
+ for (let j = i + 1; j < stuecke.length; j++) {
+ const a2 = stuecke[i], b2 = stuecke[j];
+ const ux = Math.min(a2.re, b2.re) - Math.max(a2.x, b2.x);
+ const uy = Math.min(a2.y + a2.h, b2.y + b2.h) - Math.max(a2.y, b2.y);
+ if (ux > 2 && uy > 2) drueber.push(`${a2.was} / ${b2.was}`);
+ }
+ }
+ return {
+ feld: r(f), senden: r(senden), werkzeuge: r(werk),
+ klein: stuecke.filter((t) => t.b < 38 || t.h < 38).map((t) => `${t.was} ${t.b}x${t.h}`),
+ drueber,
+ quer: document.documentElement.scrollWidth - window.innerWidth,
+ werkzeugZahl: werk ? werk.querySelectorAll("button").length : 0,
+ };
+ });
+
+ /* DIE ZAHL GEHOERT IN DIE BEDINGUNG -- ohne Feld waere alles
+ darunter gruen, ohne etwas angesehen zu haben. */
+ ok(!!zeile.feld && !!zeile.senden, "Schreibfeld und Senden sind da");
+ /* 220 px, und die Zahl ist der gemessene Ist-Wert minus Luft:
+ Gemessen sind 278. Vor dem Umbau waren es 130 -- die Pruefung
+ waere damals rot geworden, und genau das soll sie wieder, wenn
+ jemand einen siebten Knopf dazustellt. */
+ ok((zeile.feld?.b || 0) >= 220,
+ `das Schreibfeld ist ${zeile.feld?.b} px breit (mindestens 220)`);
+ /* SENDEN STEHT BEIM FELD. Vorher lag es eine Zeile tiefer, unten
+ links -- weiter vom Text entfernt als die Bueroklammer. */
+ ok(Math.abs((zeile.senden?.y || 0) - (zeile.feld?.y || 0)) <= 6,
+ `und "Senden" steht daneben, nicht darunter (y ${zeile.senden?.y} zu ${zeile.feld?.y})`);
+ ok(zeile.drueber.length === 0,
+ `nichts liegt uebereinander (${zeile.drueber.join(", ") || "nichts"})`);
+ ok(zeile.klein.length === 0,
+ `alle Bedienelemente sind am Daumen treffbar (${zeile.klein.join(", ") || "alle gross genug"})`);
+ ok(zeile.quer <= 1, `die Seite scrollt nicht waagerecht (${zeile.quer})`);
+
+ /* GEGENPROBE ZUR MESSUNG: Die Werkzeuge muessen auf einem Handy
+ in einer ANDEREN Zeile stehen als das Feld -- sonst hiesse
+ "Senden steht daneben" nur, dass alles in einer Zeile liegt
+ und die Messung gar nicht unterscheiden kann. */
+ ok(zeile.werkzeugZahl === 4,
+ `die vier Werkzeuge stehen in einer Gruppe (${zeile.werkzeugZahl})`);
+ /* `!!zeile.werkzeuge` GEHOERT IN DIE BEDINGUNG, und das ist kein
+ Zierrat: In der Gegenprobe gab es die Gruppe nicht, `y` war
+ `undefined`, und `(undefined || 0) < 834` ist wahr -- die Zeile
+ stand gruen da, ohne etwas angesehen zu haben. Genau die Sorte
+ gruener Haken, vor der die Hausregeln warnen, und sie ist mir
+ hier selbst passiert. */
+ ok(!!zeile.werkzeuge && !!zeile.feld
+ && zeile.werkzeuge.y < zeile.feld.y - 10,
+ `und auf dem Handy in einer eigenen Zeile darueber (y ${zeile.werkzeuge?.y} zu ${zeile.feld?.y})`);
+ } finally { await handy.ctx.close(); }
+
+ /* UND AM RECHNER PASST ALLES IN EINE ZEILE. Ohne diese Zeile waere
+ "die Werkzeuge stehen darueber" eine Regel, die auch dort gaelte,
+ wo reichlich Platz ist -- und die Zeile waere unnoetig hoch. */
+ const laptop = await alsRolle("admin", "CODE-DOGI-0001", "chat.html?raum=treff", 1280);
+ try {
+ await laptop.seite.waitForSelector("#schreiben:not([hidden])", { timeout: 8000 });
+ await laptop.seite.waitForTimeout(800);
+ const weit = await laptop.seite.evaluate(() => {
+ const f = document.getElementById("text")?.getBoundingClientRect();
+ const w = document.querySelector(".chat__werkzeuge")?.getBoundingClientRect();
+ const se = document.getElementById("senden")?.getBoundingClientRect();
+ return { feld: Math.round(f?.width || 0),
+ gleicheZeile: !!f && !!w && Math.abs(f.top - w.top) <= 12,
+ sendenDaneben: !!f && !!se && Math.abs(f.top - se.top) <= 6 };
+ });
+ ok(weit.feld >= 400, `am Rechner ist das Feld ${weit.feld} px breit`);
+ ok(weit.gleicheZeile,
+ "und die Werkzeuge stehen daneben statt darueber — dort ist Platz");
+ ok(weit.sendenDaneben, "Senden steht auch dort beim Feld");
+ } finally { await laptop.ctx.close(); }
+}
+
await browser.close();
try { rmSync(ordner, { recursive: true, force: true }); } catch { /* egal */ }
diff --git a/workspace/anruf-probe.html b/workspace/anruf-probe.html
index 8ba25171..9e6fa05d 100644
--- a/workspace/anruf-probe.html
+++ b/workspace/anruf-probe.html
@@ -16,15 +16,15 @@
verdeckt. Gefunden hat es pruef-struktur.
Richtig sind `gate.css` (die Farbwerte des Hauses) und `haus.css`. -->
-
-
+
+
-
+