diff --git a/server/pruef-handy.mjs b/server/pruef-handy.mjs index 54faa231..8378b390 100644 --- a/server/pruef-handy.mjs +++ b/server/pruef-handy.mjs @@ -89,6 +89,12 @@ function anlegen(name, rolle, code) { const idDogi = anlegen("Filipe", "admin", "CODE-DOGI-0001"); const idScout = anlegen("Patrick-Maximilian", "scout", "CODE-SCOU-0001"); const idTili = anlegen("Tili", "creator", "CODE-ANNA-0001"); +/* Die beiden fehlenden Rollen -- gebraucht fuer die Mittenpruefung ganz + unten. Filipe: "das soll bei jedem und jeder rolle verbessert + werden", und eine Pruefung an drei von fuenf Rollen haette genau + diese Aussage nicht belegen koennen. */ +const idSpicy = anlegen("Cigdem", "spicy", "CODE-SPIC-0001"); +const idMgr = anlegen("Mara", "manager", "CODE-MANA-0001"); d.prepare("INSERT INTO betreuung (creator_id, betreuer_id, seit) VALUES (?,?,?)").run(idTili, idScout, jetzt); const LANG = "Ein sehr langer Eintrag ohne Leerzeichenumbruch fuer die Handypruefung"; @@ -425,6 +431,59 @@ console.log("\n=== Kein Licht ohne Zeiger"); await kontext.close(); } +/* --------------------------------------------------------------------- + RING UND UHR STEHEN IN DER MITTE -- bei jeder Rolle (09.09.2026) + + Filipe, mit Bildschirmfoto: "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 war es bei allen fuenf Rollen und beiden Breiten dieselbe + Zahl: Ring 31 px nach links, Uhr 31 px nach rechts. Ursache war + `justify-content: center` auf einer Reihe, in der neben dem + Instrument noch ein Knopf steht -- zentriert wurde der Block aus + beiden. 62 px Knopfbreite (`--instrument-knoepfe`), halbiert, macht + genau die 31. + + Warum das hier ALLE Rollen durchgeht, obwohl die Ursache eine einzige + CSS-Regel ist: Weil genau das die Behauptung war, die geprueft + gehoert. Eine Regel kann von einer rollenabhaengigen ueberschrieben + werden, und dann faellt es nur bei einer auf. + --------------------------------------------------------------------- */ +console.log("\n=== Ring und Uhr stehen mittig (alle Rollen)"); +for (const [breite, hoehe] of [[390, 844], [412, 915]]) { + for (const [rolle, code] of [["admin", "CODE-DOGI-0001"], ["spicy", "CODE-SPIC-0001"], + ["manager", "CODE-MANA-0001"], ["scout", "CODE-SCOU-0001"], ["creator", "CODE-ANNA-0001"]]) { + const kontext = await browser.newContext({ viewport: { width: breite, height: hoehe } }); + const seite = await kontext.newPage(); + await seite.goto(BASIS + "/workspace/", { waitUntil: "domcontentloaded" }); + await seite.click(`.rolle[data-rolle="${rolle}"]`); + await seite.fill("#code", code); + await seite.click("button[type=submit]"); + await seite.waitForURL("**/start.html", { timeout: 15000 }); + await seite.waitForTimeout(1500); + const m = await seite.evaluate(() => { + const ab = (w) => { + const e = document.querySelector(w); + if (!e) return null; + const r = e.getBoundingClientRect(); + if (r.width < 4) return null; + return Math.round((r.left + r.right) / 2 - window.innerWidth / 2); + }; + return { ring: ab("#zring"), uhr: ab(".uhr"), + ueber: document.documentElement.scrollWidth - document.documentElement.clientWidth }; + }); + /* 3 px Nachsicht: Ein ungerader Rest bei ungerader Breite ist kein + Befund. 31 px waren einer. */ + const gut = m.ring !== null && m.uhr !== null + && Math.abs(m.ring) <= 3 && Math.abs(m.uhr) <= 3 && m.ueber <= 1; + ok(gut, `${breite}px ${rolle.padEnd(8)} Ring ${m.ring} px, Uhr ${m.uhr} px von der Mitte` + + (m.ueber > 1 ? `, Ueberstand ${m.ueber}` : "")); + await kontext.close(); + } +} + await browser.close(); try { rmSync(ordner, { recursive: true, force: true }); } catch { /* egal */ } console.log(fehler ? `\n${fehler} Prüfung(en) fehlgeschlagen.` : "\nAlles in Ordnung."); diff --git a/server/pruef-personen-kachel.mjs b/server/pruef-personen-kachel.mjs index 6769c739..6fa33483 100644 --- a/server/pruef-personen-kachel.mjs +++ b/server/pruef-personen-kachel.mjs @@ -371,6 +371,13 @@ melde("\n=== 5. Lesbarkeit ==="); ["Anzahl", '.gruppe[data-rolle="scout"] .gruppe__zahl'], ["Namenszeichen", '.gruppe[data-rolle="scout"] .gruppe__kopf-zeichen'], ["Namenszeichen (Creator, hellste Rolle)", '.gruppe[data-rolle="creator"] .gruppe__kopf-zeichen'], + /* DogFather steht ausdruecklich dabei: Sein Babyblau wurde am + 09.09.2026 saettiger gemacht (#9ed3f4 -> #5fbdff) und dabei + dunkler. Von 12,49:1 auf 9,75:1 gegen den Grund gerechnet -- eine + Rechnung ist aber keine Messung, und gemessen wird hier gegen die + Flaeche, die wirklich dahinter liegt. */ + ["Anzahl (DogFather)", '.gruppe[data-rolle="admin"] .gruppe__zahl'], + ["Namenszeichen (DogFather)", '.gruppe[data-rolle="admin"] .gruppe__kopf-zeichen'], ["Anzahl (Creator)", '.gruppe[data-rolle="creator"] .gruppe__zahl'], ["Name offen", '.gruppe[data-rolle="manager"] .gruppe__name'], ]) { diff --git a/server/pruef-sicht.mjs b/server/pruef-sicht.mjs index 672b6daf..a8f523bb 100644 --- a/server/pruef-sicht.mjs +++ b/server/pruef-sicht.mjs @@ -80,6 +80,17 @@ function anlegen(name, rolle, code) { return d.prepare("SELECT last_insert_rowid() AS id").get().id; } const idDogi = anlegen("Filipe", "admin", "CODE-DOGI-0001"); +/* SPICY MEDIA GEHOERT DAZU (09.09.2026). + + Filipe: "ich will da auch noch die spicy rolle sehen und die leute in + der rolle wie die anderen." + + Der Umschalter fuehrte eine EIGENE Rollenliste -- vier Eintraege, und + Spicy Media fehlte. Ohne eine Spicy-Person in diesen Testdaten waere + das nie aufgefallen: Eine Rolle ohne Leute wird ohnehin weggelassen, + und die Pruefung darunter haette weiter brav "Manager, Scouts, + Creator" bestaetigt. */ +const idSpicy = anlegen("Cigdem", "spicy", "CODE-SPIC-0001"); const idMgr = anlegen("Mara", "manager", "CODE-MANA-0001"); const idPat = anlegen("Patrick", "scout", "CODE-SCOU-0001"); const idBen = anlegen("Ben", "scout", "CODE-SCOB-0001"); @@ -338,10 +349,34 @@ const wahl = await bDogi.seite.evaluate(() => { anzahl: s.querySelectorAll("option").length, erste: s.querySelector("option")?.textContent, ichDrin: [...s.querySelectorAll("option")].some((o) => o.textContent === "Filipe"), + namen: [...s.querySelectorAll("optgroup option")].map((o) => o.textContent), }; }); -ok(wahl.gruppen.join(", ") === "Manager, Scouts, Creator", +/* Die Reihenfolge ist die des Hauses (window.Bereiche.ROLLENFOLGE): + Spicy Media, DogFather, Manager, Scout, Creator. DogFather faellt + weg, weil dort nur Filipe selbst steht. */ +ok(wahl.gruppen.join(", ") === "Spicy Media, Manager, Scouts, Creator", `nach Rollen gruppiert: ${wahl.gruppen.join(", ")}`); +ok(wahl.gruppen.includes("Spicy Media"), + "Spicy Media steht mit dabei — nicht mehr nur vier von fuenf Rollen"); + +/* GEGENPROBE: Die Liste kommt wirklich aus der zentralen Reihenfolge + und ist nicht wieder abgeschrieben. Waere sie es, koennte sie beim + naechsten Mal genauso stehenbleiben. */ +const ausZentral = await bDogi.seite.evaluate(() => { + const folge = window.Bereiche?.ROLLENFOLGE || []; + const namen = window.Bereiche?.ROLLEN_GRUPPE || {}; + const s = document.getElementById("sicht-feld"); + const da = [...s.querySelectorAll("optgroup")].map((g) => g.label); + const erwartet = folge.map((r) => namen[r]).filter((n) => da.includes(n)); + return { gleich: erwartet.join(", ") === da.join(", "), erwartet, da }; +}); +ok(ausZentral.gleich, + `die Reihenfolge folgt der zentralen Liste (${ausZentral.erwartet.join(", ")})`); + +/* Und die PERSON steht drin, nicht nur die Ueberschrift. */ +ok([...(wahl.namen || [])].includes("Cigdem"), + `die Spicy-Media-Person steht in ihrer Gruppe (${(wahl.namen || []).join(", ")})`); ok(/meine Sicht/i.test(wahl.erste || ""), `der Rueckweg steht ganz oben ("${wahl.erste}")`); ok(!wahl.ichDrin, "DogFather selbst steht nicht in der Liste – das waere derselbe Zustand"); diff --git a/workspace/assets/css/gate.css b/workspace/assets/css/gate.css index e4421c2a..22d1d5dc 100644 --- a/workspace/assets/css/gate.css +++ b/workspace/assets/css/gate.css @@ -160,9 +160,43 @@ Silber bleibt es durch die HELLIGKEIT, blau wird es durch den Kanalabstand. Beides zugleich geht nur so; ein saettigeres Blau waere Farbe statt Material. */ - --dogi-haupt: #9ed3f4; - --dogi-zweit: #6dc2f2; - --dogi-tief: #35506b; + /* --------------------------------------------------------------- + DRITTER SCHRITT, 09.09.2026. Filipe: "die rolle dogfather soll + eine uebertrieben geile babyblau haben." + + Zweimal habe ich hier den ABSTAND zwischen Rot- und Blaukanal + erhoeht (45 Stufen -> 86) und zweimal war es zu wenig. Diesmal + erst gemessen, was am Bildschirm ankommt, statt den Hexwert + anzusehen: + + Die DogFather-Zeile traegt 98,7 % farbige Bildpunkte -- MEHR als + jede andere Rolle. An der Menge lag es also nie. + Ihr Mittelwert war aber rgb(43,62,78): zwischen Rot und Blau + liegen 35 Stufen, und das ist Stahlgrau, kein Babyblau. + + Die richtige Groesse ist die SAETTIGUNG, nicht der Kanalabstand im + Hexwert. In OKLab gemessen hatte #9ed3f4 eine Buntheit von 0,0718 + -- der blasseste Wert aller fuenf Rollen. #5fbdff hat 0,1303, also + 81 Prozent mehr, und die Zeile kommt damit auf rgb(28,55,76): + 48 Stufen zwischen Rot und Blau statt 28. + + Was dabei NICHT verlorengeht, nachgerechnet: + * Kontrast auf dem Grund 9,75:1 (vorher 12,49) -- weit ueber den + 4,5, die fuer Text gelten, und ueber den 7 fuer AAA. + * Abstand zur naechsten Rollenfarbe (Scout) 0,1608 in OKLab, + vorher 0,1466. Die Hausgrenze liegt bei 0,0973 -- DogFather + ist also SICHERER unterscheidbar als vorher, nicht weniger. + + Silber bleibt es durch die Helligkeit des Spitzlichts auf der + Schiene (#f2f8ff an ihrem oberen Ende) -- das ist die Stelle, an + der Metall entsteht. Die Flaeche darunter darf Farbe sein. */ + --dogi-haupt: #5fbdff; + /* Der Begleitton geht mit: Er traegt die untere Haelfte der Schiene. + Bliebe er auf #6dc2f2, waere die Schiene oben satter als unten -- + ein Verlauf, der in die falsche Richtung laeuft. */ + --dogi-zweit: #2fa9f2; + /* Und die Tiefe wird ein echtes Blau statt eines Schiefergraus. */ + --dogi-tief: #14496f; /* MANAGER — lila, bleibt (Wunsch: "manager bleibt lila"). */ --manager-haupt: #8a76ff; diff --git a/workspace/assets/css/heim.css b/workspace/assets/css/heim.css index 26e79047..87dc45e9 100644 --- a/workspace/assets/css/heim.css +++ b/workspace/assets/css/heim.css @@ -679,9 +679,46 @@ steht das Ausschalten dort, wo die Spalte verschwindet, die es begruendet. Wer die Spalten wieder anfasst, sieht es. */ .willkommen__rechts::before { display: none; } + + /* ==== DIE UHR STEHT IN DER MITTE, NICHT DIE REIHE ==================== + Filipe, mit Bildschirmfoto vom Handy: "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." + + 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 -- das ist eine Ursache, nicht + zwei. + + `justify-content: center` zentriert den INHALT der Reihe, und in + der Reihe steht neben dem Instrument noch der Knopf. Zentriert wird + also [Knopf + Abstand + Uhr] als Block; die Uhr rutscht dabei um + die halbe Knopfbreite zur Seite. Die Knopfbreite steht seit jeher + als `--instrument-knoepfe: 62px` in dieser Datei -- 62 / 2 = 31. + Die gemessene Zahl war also von Anfang an aufgeschrieben, nur an + einer anderen Stelle. + + Der Knopf zaehlt deshalb nicht mehr mit: Er wird aus dem Fluss + genommen und neben die zentrierte Uhr gehaengt. Kein Verschieben um + 31 px -- das waere dieselbe Zahl ein zweites Mal, und beim + naechsten Knopf waere sie falsch. So folgt seine Lage der Uhr, + wie gross die auch ist. */ + .willkommen__rechts > .glocke-platz { + position: absolute; top: 50%; transform: translateY(-50%); + right: calc(50% + var(--instrument) / 2 + 14px); + } + .willkommen__rechts > .uhr { margin-inline: auto; } } @media (max-width: 780px) { .willkommen { --instrument: 196px; } + + /* Und dasselbe fuer den Ring: Erst HIER faellt die zweite Spalte weg, + vorher steht er neben dem Text und soll gar nicht mittig sein. */ + .willkommen__links > .glocke-platz--links { + position: absolute; top: 50%; transform: translateY(-50%); + left: calc(50% + var(--instrument) / 2 + 14px); + } + .willkommen__links > .zring { margin-inline: auto; } .willkommen__reihe { grid-template-columns: minmax(0, 1fr); gap: 20px; } /* Jetzt faellt auch die zweite Spalte weg -- ab hier trennt die linke Nut ebenfalls nichts mehr. Bis hierher blieb sie richtig: Ring und diff --git a/workspace/assets/js/kopf.js b/workspace/assets/js/kopf.js index 198f5a43..6167aa69 100644 --- a/workspace/assets/js/kopf.js +++ b/workspace/assets/js/kopf.js @@ -1060,12 +1060,32 @@ return k; }; - const ROLLE_GRUPPE = [ - ['manager', 'Manager'], - ['scout', 'Scouts'], - ['creator', 'Creator'], - ['admin', 'DogFather'], - ]; + /* DIE REIHENFOLGE KOMMT AUS DER ZENTRALEN LISTE (09.09.2026). + + Hier stand eine eigene: manager, scout, creator, admin. Also VIER + Rollen -- und Spicy Media fehlte. Wer eine Spicy-Media-Person + ansehen wollte, fand sie im Umschalter nicht, obwohl der Server sie + mitliefert. Filipe hat es gemeldet: "ich will da auch noch die + spicy rolle sehen und die leute in der rolle wie die anderen." + + Es ist 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. Jedes + Mal wurde die zentrale Fassung gepflegt und die Kopie vergessen. + + Deshalb steht hier keine Liste mehr, sondern eine Ableitung: + `ROLLENFOLGE` gibt die Reihenfolge, `ROLLEN_GRUPPE` die + Ueberschrift. Kommt morgen eine sechste Rolle dazu, ist sie hier + ohne eine Zeile Arbeit dabei. + + ERST BEIM BAUEN GELESEN, nicht beim Laden dieser Datei. bereiche.js + steht auf allen achtzehn Seiten davor und beide tragen `defer`, die + Reihenfolge stimmt also -- aber eine Liste, die beim Laden + stillschweigend leer bliebe, waere ein Ausfall, den niemand sieht. + Zum Zeitpunkt des Bauens ist die Seite fertig geladen. */ + const rollenGruppen = () => (window.Bereiche?.ROLLENFOLGE || []) + .map((r) => [r, window.Bereiche?.ROLLEN_GRUPPE?.[r] || r]); /* EIN WETTLAUF, den es wirklich gab: Auf profil.html rufen zwei Dateien werZeigen() auf (profil.js und steckbrief.js). Beide kamen an der @@ -1126,7 +1146,7 @@ nichts und machte den Knopf so breit, dass am Handy nichts anderes mehr danebenpasste. */ s.append(new Option('Meine Sicht', '')); - for (const [rolle, name] of ROLLE_GRUPPE) { + for (const [rolle, name] of rollenGruppen()) { const drin = personen.filter((p) => p.rolle === rolle && p.id !== ich.id && p.aktiv !== false); if (!drin.length) continue; const g = document.createElement('optgroup'); diff --git a/workspace/aufgaben.html b/workspace/aufgaben.html index a573fc3c..9f78cdd1 100644 --- a/workspace/aufgaben.html +++ b/workspace/aufgaben.html @@ -14,10 +14,10 @@ - - - - + + + +
@@ -231,10 +231,10 @@ - - - - - + + + + +