diff --git a/server/mess-support-runde.mjs b/server/mess-support-runde.mjs
index 220d62a0..dbedf9b2 100644
--- a/server/mess-support-runde.mjs
+++ b/server/mess-support-runde.mjs
@@ -118,6 +118,41 @@ const anfrage = (pfad, art, koerper, keks) => new Promise((fertig, schief) => {
if (koerper) a.write(JSON.stringify(koerper));
a.end();
});
+/** Eine Rueckmeldung des Melders -- UEBER DEN KOPF, nicht als JSON.
+ *
+ * ==== DIESE MESSUNG HAT ZWEI TAGE LANG NICHTS GEMESSEN ===========
+ *
+ * Am 02.10.2026 ist `/rueckmeldung` auf den Weg umgestellt worden,
+ * den auch das Melden nimmt: Urteil und Text reisen im KOPF
+ * (`x-geht`, `x-text`, prozentkodiert), der Rumpf ist fuer die
+ * Bilder da. Diese Datei schickte weiter JSON -- der Server fand
+ * also kein Urteil und keinen Text und antwortete mit 400.
+ *
+ * GEMERKT HAT ES NIEMAND, weil die Messung keine Rueckgabewerte
+ * prueft: Sie macht Bilder. Auf dem Bild stand danach eine Runde
+ * statt vier, und das sieht aus wie ein Ergebnis. Aufgefallen ist
+ * es erst, als die Bilder vier Rundenfarben zeigen sollten.
+ *
+ * Eine Messung, die nach einem Umbau stillschweigend etwas anderes
+ * misst, ist schlimmer als keine -- man glaubt ihr. */
+const rueckmelden = (id, geht, satz, keks) => new Promise((fertig, schief) => {
+ const a = httpAnfrage({
+ host: "127.0.0.1", port: PORT, path: `/workspace/api/support/${id}/rueckmeldung`,
+ method: "POST",
+ headers: {
+ Host: CREW, Cookie: keks,
+ "Content-Type": "application/octet-stream",
+ "x-geht": geht ? "ja" : "nein",
+ "x-text": encodeURIComponent(satz || ""),
+ },
+ }, (r) => {
+ let t = ""; r.on("data", (x) => { t += x; });
+ r.on("end", () => fertig({ code: r.statusCode, text: t }));
+ });
+ a.on("error", schief);
+ a.end();
+});
+
const anmelden = async (rolle, code) => {
const an = await anfrage("/workspace/api/anmelden", "POST", { rolle, code });
if (an.code !== 200) { console.log(`ABBRUCH: Anmeldung ${rolle} ${an.code}`); process.exit(2); }
@@ -200,12 +235,34 @@ try {
await blicken("melder-handy", kModi, 412, 915);
/* --- Runde 2: „noch nicht", dann behoben, dann bestaetigt --------- */
- await anfrage(`/workspace/api/support/${dran}/rueckmeldung`, "POST",
- { geht: false, text: "Der Knopf ja – aber jetzt springt die Seite nach oben." }, kModi);
+ const r2 = await rueckmelden(dran, false,
+ "Der Knopf ja – aber jetzt springt die Seite nach oben.", kModi);
+ if (r2.code !== 200) console.log(` !! Rueckmeldung ging nicht: ${r2.code} ${r2.text}`);
await anfrage(`/workspace/api/support/${dran}`, "PATCH",
{ stand: "erledigt", antwort: "Das Springen kam vom Nachladen. Ist raus." }, kHand);
await blicken("melder-runde2", kModi, 1280, 1000);
+ /* ==== VIER RUNDEN -- WEIL ES VIER FARBEN SIND (03.10.2026) =======
+
+ Filipe: „jede runde soll auch immer eine spezielle farbe haben …
+ damit man einen viel besseren und krasseren ueberblick hat."
+
+ Mit zwei Runden sieht man zwei Toene und kann nicht sagen, ob es
+ eine Reihe ist. Vier ist die Zahl, nach der sich die Farben
+ wiederholen (siehe `rundenTon` in support.js) -- also genau die
+ Zahl, bei der man die Regel sieht statt sie zu glauben. */
+ for (const [wort, satz] of [
+ ["Jetzt laedt die Liste nicht mehr nach.", "Und jetzt ist der Knopf doppelt."],
+ ["Der doppelte Knopf ist raus.", "Jetzt stimmt die Reihenfolge nicht."],
+ ]) {
+ const rr = await rueckmelden(dran, false, satz, kModi);
+ if (rr.code !== 200) console.log(` !! Rueckmeldung ging nicht: ${rr.code} ${rr.text}`);
+ await anfrage(`/workspace/api/support/${dran}`, "PATCH",
+ { stand: "erledigt", antwort: wort }, kHand);
+ }
+ await blicken("melder-vierrunden", kModi, 1280, 1100);
+ await blicken("melder-vierrunden-handy", kModi, 412, 915);
+
console.log(`\n(Die offene Meldung #${offen} bleibt unangetastet stehen –`
+ " so sieht man beide Sorten nebeneinander.)");
} finally {
diff --git a/server/pruef-support-bilder.mjs b/server/pruef-support-bilder.mjs
index 2e67a482..b44ae93b 100644
--- a/server/pruef-support-bilder.mjs
+++ b/server/pruef-support-bilder.mjs
@@ -489,6 +489,146 @@ melde("\n=== Die zweite Spalte nur mit eigenem Bild ===");
await kontext.close();
}
+/* =====================================================================
+ 6. DER VERLAUF: EINE FARBE JE RUNDE (03.10.2026)
+ =====================================================================
+
+ Filipe: „ich will diese komplette seite vom support viel
+ uebersichtlicher, profissioneller, jede runde soll auch immer eine
+ spezielle farbe haben und anders aufgestellt aufgeteilt sein damit
+ man einen viel besseren und krasseren ueberblick hat."
+
+ WARUM DAS GEPRUEFT WERDEN MUSS und nicht nur auf einem Bild steht:
+ Die Farbe kommt aus einer Rechnung (`rundenTon` in support.js) und
+ wird im CSS zu `hsl()`. Zwischen diesen beiden Stellen kann sie
+ verlorengehen, ohne dass etwas abstuerzt -- dann sind alle Runden
+ gleich grau, und auf dem Bildschirm sieht das aus wie Absicht.
+
+ GEMESSEN WIRD DIE ANGEZEIGTE FARBE, nicht die Zahl: `--ton` kann
+ gesetzt sein und das CSS sie trotzdem nicht benutzen.
+ ===================================================================== */
+melde("\n=== Eine Farbe je Runde ===");
+{
+ /* Eine Meldung mit VIER Runden -- so viele, wie es Toene gibt.
+ Mit zwei saehe man zwei Farben und wueste nicht, ob es eine
+ Reihe ist. */
+ /* UEBER `fetch` MIT KEKS -- diese Datei hat keinen `hol`-Helfer wie
+ pruef-support.mjs. Mein erster Anlauf rief ihn trotzdem auf und
+ stuerzte ab; die Pruefung hat es in derselben Minute gesagt. */
+ const ruf = (pfad, keks, o = {}) => fetch(BASIS + pfad,
+ { ...o, headers: { cookie: keks, ...(o.headers || {}) } });
+ const neu = await ruf("/workspace/api/support", keksModi, {
+ method: "POST", headers: { "Content-Type": "text/plain",
+ "x-text": encodeURIComponent("Probe fuer die Rundenfarben.") },
+ });
+ const vId = (await neu.json())?.meldung?.id;
+ for (let i = 0; i < 4; i++) {
+ await ruf(`/workspace/api/support/${vId}`, keksHand, {
+ method: "PATCH", headers: { "Content-Type": "application/json" },
+ body: JSON.stringify({ stand: "erledigt", antwort: `Versuch ${i + 1}.` }),
+ });
+ await ruf(`/workspace/api/support/${vId}/rueckmeldung`, keksModi, {
+ method: "POST",
+ headers: { "x-geht": "nein",
+ "x-text": encodeURIComponent(`Ging noch nicht, Versuch ${i + 1}.`) },
+ });
+ }
+ /* Noch einmal zurueckgeben, damit die letzte Runde eine Antwort
+ hat und der Melder wieder dran ist. */
+ await ruf(`/workspace/api/support/${vId}`, keksHand, {
+ method: "PATCH", headers: { "Content-Type": "application/json" },
+ body: JSON.stringify({ stand: "erledigt", antwort: "Jetzt aber." }),
+ });
+
+ const { kontext, seite } = await neueSeite(1280, keksModi);
+ const karte = `#meldung-${vId}`;
+ await seite.locator(karte).waitFor({ timeout: 8000 });
+
+ const bild = await seite.evaluate((wahl) => {
+ const k = document.querySelector(wahl);
+ const punkte = [...k.querySelectorAll(".s-rundenleiste__punkt")];
+ const offen = [...k.querySelectorAll(".s-runde")];
+ const farbe = (e) => getComputedStyle(e).backgroundColor;
+ return {
+ punkte: punkte.length,
+ punktFarben: punkte.map((p) => farbe(p)),
+ nummern: punkte.map((p) => p.textContent.trim()),
+ /* Die Farbe der Rundennummer -- sie muss sich mit der Runde
+ aendern, sonst ist die Achse farbig und die Schrift nicht. */
+ nrFarben: offen.map((r) =>
+ getComputedStyle(r.querySelector(".s-runde__nr")).color),
+ offene: offen.length,
+ mehr: (k.querySelector(".s-verlauf__mehr")?.innerText || "")
+ .replace(/\s+/g, " ").trim(),
+ /* Zwei Sprechrichtungen: Wer geantwortet hat und was daraus
+ wurde, muessen verschieden aussehen. */
+ schilder: [...k.querySelectorAll(".s-schritt__schild")]
+ .map((x) => x.textContent.trim()),
+ hoch: Math.round(k.getBoundingClientRect().height),
+ };
+ }, karte);
+
+ ok(bild.punkte === 5, `die Leiste zeigt jede Runde (${bild.punkte} Punkte)`);
+ ok(bild.nummern.join(",") === "1,2,3,4,5",
+ `mit ihrer Nummer (${bild.nummern.join(", ")})`);
+ /* DER EIGENTLICHE PUNKT: vier verschiedene Farben. Die fuenfte
+ wiederholt die erste -- so ist die Formel gebaut, und das steht
+ hier als Aussage, damit es niemand fuer einen Fehler haelt. */
+ const verschieden = new Set(bild.punktFarben.slice(0, 4)).size;
+ ok(verschieden === 4,
+ `die ersten vier Runden haben vier verschiedene Farben (${verschieden})`);
+ ok(bild.punktFarben[4] === bild.punktFarben[0],
+ "und die fuenfte faengt die Reihe wieder von vorn an — so ist die Formel");
+ /* GEGENPROBE: Waere `--ton` nicht angekommen, waeren ALLE gleich.
+ Diese Zeile unterscheidet „vier Farben" von „viermal dieselbe". */
+ ok(new Set(bild.punktFarben).size > 1,
+ `Gegenprobe: sie sind nicht alle gleich (${new Set(bild.punktFarben).size} Farben)`);
+
+ ok(new Set(bild.nrFarben).size === bild.offene,
+ `auch die Rundennummern tragen ihre Farbe (${new Set(bild.nrFarben).size} `
+ + `von ${bild.offene})`);
+
+ ok(bild.offene === 2, `offen stehen die letzten zwei Runden (${bild.offene})`);
+ ok(/3 frühere Runden/.test(bild.mehr),
+ `und die aelteren sind einen Griff entfernt („${bild.mehr}")`);
+
+ ok(bild.schilder.includes("Geantwortet")
+ && bild.schilder.some((t) => /Ging noch nicht|Wartet/.test(t)),
+ `jede Runde zeigt beide Seiten (${[...new Set(bild.schilder)].join(" / ")})`);
+
+ /* AUFKLAPPEN UND WIEDER ZU. */
+ await seite.locator(`${karte} .s-verlauf__mehr`).click();
+ await seite.waitForTimeout(400);
+ const ganz = await seite.evaluate((wahl) => ({
+ offene: document.querySelectorAll(`${wahl} .s-runde`).length,
+ mehr: (document.querySelector(`${wahl} .s-verlauf__mehr`)?.innerText || "")
+ .replace(/\s+/g, " ").trim(),
+ }), karte);
+ ok(ganz.offene === 5, `aufgeklappt stehen alle da (${ganz.offene})`);
+ await seite.locator(`${karte} .s-verlauf__mehr`).click();
+ await seite.waitForTimeout(400);
+ ok(await seite.locator(`${karte} .s-runde`).count() === 2,
+ "und wieder zu — der Knopf geht in beide Richtungen");
+
+ /* UND NICHTS RAGT HERAUS, auch nicht auf dem Handy. */
+ await kontext.close();
+ const h = await neueSeite(390, keksModi);
+ await h.seite.locator(karte).waitFor({ timeout: 8000 });
+ const ueber = await h.seite.evaluate(() =>
+ document.documentElement.scrollWidth - document.documentElement.clientWidth);
+ ok(ueber <= 0, `auf 390 px ragt nichts heraus (${ueber} px)`);
+ /* GEGENPROBE ZUR LEISTE: Bei EINER Runde gibt es sie nicht -- ein
+ Punkt neben keinem Punkt sagt nichts. */
+ const einzeln = await h.seite.evaluate(() => {
+ const k = [...document.querySelectorAll(".s-karte")]
+ .find((x) => x.querySelectorAll(".s-runde").length === 1);
+ return k ? k.querySelectorAll(".s-rundenleiste").length : -1;
+ });
+ ok(einzeln === 0 || einzeln === -1,
+ `bei einer einzigen Runde gibt es keine Leiste (${einzeln})`);
+ await h.kontext.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 aad7469b..265cf93e 100644
--- a/workspace/anruf-probe.html
+++ b/workspace/anruf-probe.html
@@ -16,8 +16,8 @@
verdeckt. Gefunden hat es pruef-struktur.
Richtig sind `gate.css` (die Farbwerte des Hauses) und `haus.css`. -->
-
-
+
+
-
+