diff --git a/pruef-wahl-scrollen.mjs b/pruef-wahl-scrollen.mjs
new file mode 100644
index 00000000..acce694e
--- /dev/null
+++ b/pruef-wahl-scrollen.mjs
@@ -0,0 +1,143 @@
+/* ===================================================================
+ pruef-wahl-scrollen.mjs — die Namensliste bleibt beim Scrollen offen.
+
+ ANLASS (Filipe, 04.09.2026, mit Bildschirmfoto der Personenauswahl):
+ "wenn ich da scollen will geht das immer zu"
+
+ Er hatte recht, und die Ursache war eine einzige Stelle in
+ assets/js/wahl.js:
+
+ addEventListener('scroll', schliessen, true);
+
+ Das dritte Argument bedeutet "in der Einfangphase lauschen" -- und
+ damit auf JEDES Scroll-Ereignis im ganzen Dokument, auch auf das in
+ der Liste selbst. Wer die Namensliste herunterrollen wollte, schloss
+ sie im selben Moment. Bei acht Eintraegen faellt das kaum auf; beim
+ ganzen Manager- und Scout-Team ist die Liste unbedienbar.
+
+ Zumachen MUSS sie trotzdem, wenn die Seite scrollt: Sie haengt an
+ position:fixed und schwaemme sonst neben ihrem Knopf davon. Deshalb
+ pruefen hier beide Haelften -- eine Reparatur, die nur die eine
+ Richtung sichert, waere die naechste Ueberraschung:
+
+ scrollt die LISTE -> bleibt offen
+ scrollt die SEITE -> geht zu
+
+ Geprueft wird im echten Browser am ECHTEN wahl.js und gate.css, nicht
+ an einer Nachbildung. Eine Nachbildung haette genau die Zeile nicht
+ gehabt, um die es geht.
+
+ Aufruf: node pruef-wahl-scrollen.mjs
+ =================================================================== */
+import { chromium } from "playwright";
+import { readFileSync } from "node:fs";
+import { dirname, join } from "node:path";
+import { fileURLToPath } from "node:url";
+
+const HIER = dirname(fileURLToPath(import.meta.url));
+const JS = join(HIER, "workspace", "assets", "js", "wahl.js");
+/* ALLE Stylesheets, die eine Arbeitsplatz-Seite laedt -- nicht nur gate.css.
+ Beim ersten Lauf war nur gate.css eingebunden: Die Eintraege bekamen dadurch
+ weder Schriftgroesse noch Innenabstand, 30 Namen waren zusammen 243 Pixel hoch,
+ und die Liste konnte gar nicht scrollen. Die Pruefung hat das gemeldet, statt
+ gruen zu behaupten, sie haette das Scrollen geprueft. */
+const CSS_DATEIEN = ["gate.css", "start.css", "aufgaben.css"]
+ .map((n) => join(HIER, "workspace", "assets", "css", n));
+
+let gut = 0;
+const schlecht = [];
+const pruefe = (name, bedingung, zusatz = "") => {
+ if (bedingung) { gut++; console.log(" ok " + name); }
+ else { schlecht.push(name); console.log(" FEHLER " + name + (zusatz ? " — " + zusatz : "")); }
+};
+
+/* Genug Eintraege, damit die Liste ueberhaupt scrollen KANN -- mit fuenf
+ Namen gaebe es nichts zu rollen, und die Pruefung waere gruen, ohne
+ etwas gemessen zu haben. Die Namen sind die aus Filipes Bild. */
+const NAMEN = [
+ "Dogfather (admin)", "VanVan (admin)", "Cigdem (manager)", "Drouwn (manager)",
+ "Schulle (manager)", "BananaStift (scout)", "Patrick (scout)", "Tili (scout)",
+ ...Array.from({ length: 22 }, (_, i) => `Weitere Person ${i + 9} (scout)`),
+];
+
+const browser = await chromium.launch();
+/* Ein NIEDRIGES Fenster, wie auf Filipes Bildschirmfoto. Beim ersten Lauf stand hier
+ 700 Pixel Hoehe -- da passte die ganze Liste hinein, es gab nichts zu scrollen, und
+ "bleibt beim Scrollen offen" waere eine leere Aussage gewesen. Die Pruefung hat das
+ selbst gemeldet, statt gruen zu behaupten, was sie nicht gemessen hatte. */
+const seite = await browser.newPage({ viewport: { width: 1280, height: 420 } });
+
+/* Die Seite ist absichtlich hoch: Ohne Scrollweg liesse sich die zweite
+ Haelfte ("die Seite scrollt -> Liste geht zu") gar nicht pruefen. */
+await seite.setContent(`
+
+
+
+
+ `);
+for (const datei of CSS_DATEIEN) await seite.addStyleTag({ content: readFileSync(datei, "utf8") });
+await seite.addScriptTag({ content: readFileSync(JS, "utf8") });
+await seite.waitForTimeout(150);
+
+console.log("\n--- Die Liste laesst sich ueberhaupt oeffnen ---");
+const knopf = seite.locator(".wahl2__knopf").first();
+pruefe("Das Auswahlfeld wurde eingepackt", await knopf.count() > 0);
+await knopf.click();
+await seite.waitForTimeout(120);
+const liste = seite.locator(".wahl2__liste").first();
+pruefe("Die Liste ist offen", await liste.count() > 0);
+
+/* DIE LISTE MUSS SCROLLEN KOENNEN, sonst ist alles Weitere wertlos: Eine Liste, die
+ gar nicht rollt, bleibt beim Scrollen selbstverstaendlich offen.
+
+ Die Hoehe wird hier ausdruecklich klein gesetzt, statt sie aus dem Seitenaufbau
+ entstehen zu lassen. Grund: Geaendert wurde die JavaScript-Logik (welches Scrollen
+ schliesst die Liste), nicht die Gestaltung. Ein Aufbau, der erst die echte
+ Schriftgroesse, Zeilenhoehe und Fensterhoehe nachbaut, prueft am Ende die
+ Stylesheets -- und beim ersten Versuch genau daran vorbei: 30 Namen waren
+ zusammen 243 Pixel hoch, es gab nichts zu rollen, und die Pruefung hat das
+ gemeldet, statt gruen zu behaupten, sie haette gescrollt.
+
+ Wie gross die Liste im Betrieb wird, entscheidet gate.css (max-height aus dem
+ Platz unter dem Knopf) -- das ist eine andere Frage als diese hier. */
+await liste.evaluate((el) => { el.style.maxHeight = "150px"; });
+await seite.waitForTimeout(80);
+const scrollbar = await liste.evaluate((el) => el.scrollHeight > el.clientHeight + 4);
+pruefe("Und sie ist laenger als ihr Fenster — es gibt wirklich etwas zu scrollen", scrollbar);
+
+console.log("\n--- DER FALL: in der Liste scrollen ---");
+/* Gerollt wird ueber scrollTop, nicht ueber das Mausrad. Grund: Beim ersten Versuch
+ stand hier hover() + mouse.wheel() -- die Liste blieb offen, aber scrollTop war 0.
+ Das Rad hatte gar nichts bewegt, es war also nie ein Scroll-Ereignis unterwegs, und
+ "bleibt offen" haette nichts bewiesen. Eine Zuweisung an scrollTop loest dasselbe
+ Ereignis aus wie das Rad, nur zuverlaessig. */
+await liste.evaluate((el) => { el.scrollTop = 60; });
+await seite.waitForTimeout(200);
+pruefe("Die Liste ist nach dem Scrollen NOCH OFFEN", await seite.locator(".wahl2__liste").count() > 0);
+const versatz = await seite.locator(".wahl2__liste").first()
+ .evaluate((el) => el.scrollTop).catch(() => 0);
+pruefe("Und sie ist wirklich gerollt — nicht nur stehen geblieben", versatz > 0, `scrollTop = ${versatz}`);
+
+console.log("\n--- GEGENPROBE: die SEITE scrollen ---");
+/* Die andere Haelfte der Zusage. Ohne sie waere "bleibt offen" auch mit
+ einem ersatzlos entfernten Zuhoerer gruen -- und die Liste stuende beim
+ Scrollen der Seite irgendwo im Nichts. */
+await seite.mouse.move(20, 20);
+await seite.mouse.wheel(0, 400);
+await seite.waitForTimeout(200);
+pruefe("Beim Scrollen der Seite geht sie zu", await seite.locator(".wahl2__liste").count() === 0);
+
+console.log("\n--- Und danach laesst sie sich wieder oeffnen ---");
+await seite.evaluate(() => window.scrollTo(0, 0));
+await seite.waitForTimeout(100);
+await seite.locator(".wahl2__knopf").first().click();
+await seite.waitForTimeout(120);
+pruefe("Erneutes Oeffnen geht", await seite.locator(".wahl2__liste").count() > 0);
+
+await browser.close();
+
+console.log("");
+console.log("=".repeat(60));
+if (schlecht.length === 0) console.log(`Alle ${gut} Pruefungen bestanden.`);
+else { console.log(`${gut} bestanden, ${schlecht.length} fehlgeschlagen:`); schlecht.forEach((s) => console.log(" - " + s)); }
+process.exit(schlecht.length ? 1 : 0);
diff --git a/workspace/assets/css/gate.css b/workspace/assets/css/gate.css
index a56b8cc6..ee15d3a6 100644
--- a/workspace/assets/css/gate.css
+++ b/workspace/assets/css/gate.css
@@ -774,6 +774,10 @@ body.suche-offen { overflow: hidden; }
position: fixed; z-index: 90;
min-width: 180px; max-width: min(420px, calc(100vw - 24px));
overflow-y: auto; padding: 5px;
+ /* Am Ende der Liste NICHT weiterrollen: Ohne das gibt der Browser das Scrollen an
+ die Seite weiter (Scroll-Verkettung), die Seite bewegt sich -- und genau daran
+ schliesst die Liste zu Recht. Damit waere der Fehler von oben zur Haelfte zurueck. */
+ overscroll-behavior: contain;
background: #0d1420;
border: 1px solid rgba(63, 189, 245, .3);
border-radius: 11px;
diff --git a/workspace/assets/js/wahl.js b/workspace/assets/js/wahl.js
index 3ca81b6c..7cde6ef4 100644
--- a/workspace/assets/js/wahl.js
+++ b/workspace/assets/js/wahl.js
@@ -338,7 +338,26 @@
schliessen();
});
addEventListener('resize', schliessen);
- addEventListener('scroll', schliessen, true);
+
+ /* SCROLLEN IN DER LISTE DARF SIE NICHT SCHLIESSEN (04.09.2026, von Filipe gemeldet:
+ "wenn ich da scollen will geht das immer zu").
+
+ Hier stand `addEventListener('scroll', schliessen, true)`. Das dritte Argument
+ bedeutet: in der EINFANGPHASE lauschen -- und damit auf JEDES Scrollen im ganzen
+ Dokument, auch auf das in der Liste selbst. Wer die Namensliste herunterrollen
+ wollte, schloss sie damit im selben Moment. Bei acht Eintraegen faellt das kaum
+ auf, beim ganzen Team ist die Liste unbedienbar.
+
+ Zumachen muss sie trotzdem, wenn die SEITE scrollt: Sie haengt position:fixed am
+ Knopf und schwaemme sonst davon. Deshalb wird jetzt unterschieden, WO gescrollt
+ wurde. Ein Scroll-Ereignis der Seite hat document als Ziel -- das ist nicht in der
+ Liste enthalten, also schliesst sie wie bisher. */
+ addEventListener('scroll', (e) => {
+ if (!aktiv) return;
+ const ziel = e.target;
+ if (ziel instanceof Node && aktiv.liste?.contains(ziel)) return;
+ schliessen();
+ }, true);
/* Ein Formular-reset() leert das