Hustler-Pixelwelt T13: Kopf-Symbole ruhen bei Pause, Warnrot #c8372d, Prüfstand-Befunde sind jetzt harte Prüfungen (0 Verstöße)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ClaudeandClaude Opus 5.5 committed 2026-10-22 09:52:04 +00:00
1 parent 5e6698f5e0
commit 75ed38e68d
4 files changed
+19 -6

No files matched your search

+4 -4
View File
@@ -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 }) 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, // 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) // 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 shoot(lp, 'c-handy-quer-detail.png')
await landscape.context.close() 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: 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) 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')) 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 stempel(page, 'Als Mensch antworten').tap()
await page.locator('.hk-feld-antwort textarea').waitFor() await page.locator('.hk-feld-antwort textarea').waitFor()
await sleep(300) 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 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')) 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 }) 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() await zeilen(page).first().tap()
const akte = page.getByRole('dialog', { name: 'Akte Praxis Dr. Lindner', exact: true }) const akte = page.getByRole('dialog', { name: 'Akte Praxis Dr. Lindner', exact: true })
await akte.waitFor() await akte.waitFor()
@@ -1489,7 +1489,7 @@ async function handyPultKeller(browser, base) {
const aktLink = badReach(await reachOf(page, '.hk-akte-link')) 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: 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 }) 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 page.getByRole('button', { name: 'Schließen', exact: true }).tap()
await akte.waitFor({ state: 'detached' }) await akte.waitFor({ state: 'detached' })
// der Eintrag mit dem langen Namen und dem langen Grund ohne Umbruchstellen // der Eintrag mit dem langen Namen und dem langen Grund ohne Umbruchstellen
@@ -143,7 +143,8 @@ export default function HochhausKopf({ api, isAdmin, state, error, refresh, onGa
return ( return (
<> <>
<div className="hk-kopf"> {/* Angehalten: die Symbole der Kopfzeile ruhen wie die Welt (die Budget-Warnung blinkt weiter) */}
<div className={paused ? 'hk-kopf hk-kopf-steht' : 'hk-kopf'}>
<div className="hk-kopf-zeile"> <div className="hk-kopf-zeile">
<section className="hk-panel hk-kopf-geld" aria-label="Geld"> <section className="hk-panel hk-kopf-geld" aria-label="Geld">
<div className="hk-kopf-wert" title={hud.einnahmen.titel}> <div className="hk-kopf-wert" title={hud.einnahmen.titel}>
+4 -1
View File
@@ -71,7 +71,7 @@
.hk-hochhaus .hk-meldung-angehalten { --hk-ton: #ffd25a; } .hk-hochhaus .hk-meldung-angehalten { --hk-ton: #ffd25a; }
.hk-hochhaus .hk-meldung-angehalten::before { content: 'II'; font-size: 10px; } .hk-hochhaus .hk-meldung-angehalten::before { content: 'II'; font-size: 10px; }
.hk-hochhaus .hk-meldung-umschalten, .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-umschalten::before,
.hk-hochhaus .hk-meldung-notbremse::before { color: #ffffff; } .hk-hochhaus .hk-meldung-notbremse::before { color: #ffffff; }
.hk-hochhaus .hk-meldung-verbindung { --hk-ton: #ff9f43; } .hk-hochhaus .hk-meldung-verbindung { --hk-ton: #ff9f43; }
@@ -126,3 +126,6 @@
@media (prefers-reduced-motion: reduce) { @media (prefers-reduced-motion: reduce) {
.hk-hochhaus .hk-api-warn { animation: none; color: #ffb86b; } .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; }
+9
View File
@@ -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]) const z = Number((regel[1].match(/z-index:\s*(\d+)/) || [])[1])
assert.ok(Number.isInteger(z) && z <= 9, `z-index ${z}`) 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/)
})