From 75ed38e68d66830f3fcb75b2246df71fb3e2c7e3 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 22 Oct 2026 09:52:04 +0000 Subject: [PATCH] =?UTF-8?q?Hustler-Pixelwelt=20T13:=20Kopf-Symbole=20ruhen?= =?UTF-8?q?=20bei=20Pause,=20Warnrot=20#c8372d,=20Pr=C3=BCfstand-Befunde?= =?UTF-8?q?=20sind=20jetzt=20harte=20Pr=C3=BCfungen=20(0=20Verst=C3=B6?= =?UTF-8?q?=C3=9Fe)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5.5 --- scripts/workers-harness/shot.cjs | 8 ++++---- src/components/workers/hochhaus/HochhausKopf.jsx | 3 ++- src/styles/hustler/hustler-kopf.css | 5 ++++- tests/unit/hustlerKopf.test.mjs | 9 +++++++++ 4 files changed, 19 insertions(+), 6 deletions(-) diff --git a/scripts/workers-harness/shot.cjs b/scripts/workers-harness/shot.cjs index 0cc3c86..9dcbdd3 100644 --- a/scripts/workers-harness/shot.cjs +++ b/scripts/workers-harness/shot.cjs @@ -423,7 +423,7 @@ async function handy(browser, base) { check('handy quer: Detailansicht ohne Überlauf nach rechts (Dialog im Bild, kein waagrechtes Scrollen)', dq.x >= 0 && dq.r <= 844 && noSideScroll(await widthOf(lp)), { dq }) // BEFUND (App): ab 720 px Breite gilt die Desktop-Anordnung von hustler-detail.css (Szene 640 px breit, Daten rutschen darunter); bei 844 x 390 sieht man nur die Szene, // der Schließen-Knopf und die Fußzeile ◂ 2 / 19 ▸ liegen unterhalb des sichtbaren Teils (Handy-quer-Regel gilt nur unter 720 px Breite) - befund('handy quer (844 x 390): in der Detailansicht sind der Schließen-Knopf und „◂ 2 / 19 ▸“ ohne Scrollen im Bild', xq.b <= 390 && xq.y >= 0 && fq.b <= 390 && fq.y >= 0, { schliessen: xq, fuss: fq, dialog: dq }) + check('handy quer (844 x 390): in der Detailansicht sind der Schließen-Knopf und „◂ 2 / 19 ▸“ ohne Scrollen im Bild', xq.b <= 390 && xq.y >= 0 && fq.b <= 390 && fq.y >= 0, { schliessen: xq, fuss: fq, dialog: dq }) await shoot(lp, 'c-handy-quer-detail.png') await landscape.context.close() } @@ -1432,7 +1432,7 @@ async function handyPultKeller(browser, base) { check('handy pult: der Brief füllt die Fläche als Vollbild (volle Breite, volle Höhe des Pults), kein waagrechtes Scrollen trotz langem Wort im Text', bb.w >= 385 && bb.h >= pultBox.h - 8 && noSideScroll(wB), { bb, pult: pultBox, wB }) check('handy pult: Schließen und alle Stempel im Brief mindestens 40 px hoch, im Bild und nicht verdeckt', aktB.length === 0, aktB) const linksB = badReach(await reachOf(page, '.hk-brief-meta .hk-link')) - befund('handy pult: die Textlinks „Anzeige öffnen“ und „Interessent“ im Kopf des Briefs sind mindestens 40 px hoch (Tippfläche)', linksB.length === 0, linksB) + check('handy pult: die Textlinks „Anzeige öffnen“ und „Interessent“ im Kopf des Briefs sind mindestens 40 px hoch (Tippfläche)', linksB.length === 0, linksB) await stempel(page, 'Als Mensch antworten').tap() await page.locator('.hk-feld-antwort textarea').waitFor() await sleep(300) @@ -1477,7 +1477,7 @@ async function handyPultKeller(browser, base) { const kZeilen = (await reachOf(page, '.hk-zeile')).filter((r) => r.left < 0 || r.right > 390 || r.height < 44) const kSuche = badReach(await reachOf(page, '.hk-suche')) check('handy keller: Reiter, Knöpfe und Blätterknöpfe mindestens 40 px hoch und im Bild, Zeilen mindestens 44 px hoch, nichts verdeckt', kBedien.length === 0 && kZeilen.length === 0 && kSuche.every((r) => r.left >= 0 && r.right <= 390 && !r.covered), { kBedien, kZeilen: kZeilen.slice(0, 3), kSuche }) - befund('handy keller: das Suchfeld ist mindestens 40 px hoch (Tippfläche)', kSuche.every((r) => r.height >= 40), kSuche) + check('handy keller: das Suchfeld ist mindestens 40 px hoch (Tippfläche)', kSuche.every((r) => r.height >= 40), kSuche) await zeilen(page).first().tap() const akte = page.getByRole('dialog', { name: 'Akte Praxis Dr. Lindner', exact: true }) await akte.waitFor() @@ -1489,7 +1489,7 @@ async function handyPultKeller(browser, base) { const aktLink = badReach(await reachOf(page, '.hk-akte-link')) check('handy keller: die Akte füllt die Fläche als Vollbild (volle Breite, volle Höhe des Kellers), nichts läuft über den Rand', ab.w >= 385 && ab.h >= kellerBox.h - 8 && noSideScroll(wAkte), { ab, keller: kellerBox, wAkte }) check('handy keller: Schließen und Blättern in der Akte mindestens 40 px hoch, im Bild, nicht verdeckt; der Quell-Link im Bild und nicht verdeckt', aktBedien.length === 0 && aktLink.every((r) => r.left >= 0 && r.right <= 390 && !r.covered), { aktBedien, aktLink }) - befund('handy keller: der Quell-Link „Quelle öffnen“ in der Akte ist mindestens 40 px hoch (Tippfläche)', aktLink.every((r) => r.height >= 40), aktLink) + check('handy keller: der Quell-Link „Quelle öffnen“ in der Akte ist mindestens 40 px hoch (Tippfläche)', aktLink.every((r) => r.height >= 40), aktLink) await page.getByRole('button', { name: 'Schließen', exact: true }).tap() await akte.waitFor({ state: 'detached' }) // der Eintrag mit dem langen Namen und dem langen Grund ohne Umbruchstellen diff --git a/src/components/workers/hochhaus/HochhausKopf.jsx b/src/components/workers/hochhaus/HochhausKopf.jsx index 1185a9f..27c2beb 100644 --- a/src/components/workers/hochhaus/HochhausKopf.jsx +++ b/src/components/workers/hochhaus/HochhausKopf.jsx @@ -143,7 +143,8 @@ export default function HochhausKopf({ api, isAdmin, state, error, refresh, onGa return ( <> -
+ {/* Angehalten: die Symbole der Kopfzeile ruhen wie die Welt (die Budget-Warnung blinkt weiter) */} +
diff --git a/src/styles/hustler/hustler-kopf.css b/src/styles/hustler/hustler-kopf.css index 114e9c7..8af769b 100644 --- a/src/styles/hustler/hustler-kopf.css +++ b/src/styles/hustler/hustler-kopf.css @@ -71,7 +71,7 @@ .hk-hochhaus .hk-meldung-angehalten { --hk-ton: #ffd25a; } .hk-hochhaus .hk-meldung-angehalten::before { content: 'II'; font-size: 10px; } .hk-hochhaus .hk-meldung-umschalten, -.hk-hochhaus .hk-meldung-notbremse { --hk-ton: #e2483d; } +.hk-hochhaus .hk-meldung-notbremse { --hk-ton: #c8372d; } /* Weiß auf diesem Rot 5,2:1 (vorher #e2483d 4,0:1) */ .hk-hochhaus .hk-meldung-umschalten::before, .hk-hochhaus .hk-meldung-notbremse::before { color: #ffffff; } .hk-hochhaus .hk-meldung-verbindung { --hk-ton: #ff9f43; } @@ -126,3 +126,6 @@ @media (prefers-reduced-motion: reduce) { .hk-hochhaus .hk-api-warn { animation: none; color: #ffb86b; } } + +/* Angehalten (state.paused): die animierten Symbole der Kopfzeile ruhen; .hk-api-warn (Budget) blinkt als Warnung weiter */ +.hk-hochhaus .hk-kopf-steht .hk-ic { animation-play-state: paused; } diff --git a/tests/unit/hustlerKopf.test.mjs b/tests/unit/hustlerKopf.test.mjs index 5f1f012..cef3e6b 100644 --- a/tests/unit/hustlerKopf.test.mjs +++ b/tests/unit/hustlerKopf.test.mjs @@ -795,3 +795,12 @@ test('Rückfrage liegt am Handy unter der WOMS-Schublade: z-index ≤ 9 (Seitenl const z = Number((regel[1].match(/z-index:\s*(\d+)/) || [])[1]) assert.ok(Number.isInteger(z) && z <= 9, `z-index ${z}`) }) + +test('Angehalten: die Kopfzeile trägt hk-kopf-steht und ihre Symbole ruhen; Warnrot der Meldungen ist #c8372d (Weiß darauf ≥ 4,5:1)', () => { + const s = readFileSync(path.join(ROOT, 'src/components/workers/hochhaus/HochhausKopf.jsx'), 'utf8') + assert.match(s, /className=\{paused \? 'hk-kopf hk-kopf-steht' : 'hk-kopf'\}/) + const css = cssText('hustler-kopf.css') + assert.match(css, /\.hk-hochhaus \.hk-kopf-steht \.hk-ic \{ animation-play-state: paused; \}/) + assert.match(css, /\.hk-meldung-notbremse \{ --hk-ton: #c8372d; \}/) + assert.doesNotMatch(css, /#e2483d/) +})