From 8616636212142f64b681db1a8630b9afd96788b1 Mon Sep 17 00:00:00 2001 From: JoshHeaps Date: Wed, 2 Sep 2026 09:36:51 -0600 Subject: [PATCH] Make hidden mean hidden, and check that it does MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three rounds inside the money, so this one was a look at the thing. On a desktop screenshot of a table mid-session there is a small empty box under the bank check: 21 pixels wide, 44 tall, no text, no purpose. It is the "Take $600 from 3 players" button from three rounds ago, which sets `hidden` when there is nothing to record — and `hidden` was losing. The attribute carries its `display: none` from the browser's own stylesheet, which is the weakest rule in the cascade, so any class that sets a display beats it. Every button class here sets `inline-flex`. This is not a new discovery in this file either: seven overlays already carry their own `[hidden] { display: none }`, each one presumably found the same way. One global rule now covers all of them, so there is no ninth. The audit had been telling me. Its touch check reported the box as "could not be probed (drawn 21x44)" — in the warnings, which my sweeps printed only sometimes and never failed on. So the check now says the plainer thing: an element that claims to be hidden and is drawn anyway is a fault, not a note. It is in runAll with the rest, and the bug was put back by hand to confirm it fires. The same warning stream had a second thing in it: the waiting list's Add button was 43px wide. Three letters, one pixel under the rule, and a thumb doesn't know the word is short. 182 audits across 13 viewports, both input kinds, every overlay and a table with a rake, a cash-out, a waiting list and six logged hands on it: clean, and the only note left is the one that says the 44px rule stood itself down on a mouse. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_015bnp7xKUPFFSpwkYNFaPgb --- JoshHeaps.Net/wwwroot/css/casino/holdem.css | 17 +++++++++++++++++ tests/holdem/uiAudit.js | 21 +++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/JoshHeaps.Net/wwwroot/css/casino/holdem.css b/JoshHeaps.Net/wwwroot/css/casino/holdem.css index 5c28d01..99a20dc 100644 --- a/JoshHeaps.Net/wwwroot/css/casino/holdem.css +++ b/JoshHeaps.Net/wwwroot/css/casino/holdem.css @@ -318,6 +318,20 @@ button, margin-top: 1rem; } +/* `hidden` means hidden. + + The attribute only carries `display: none` from the browser's own stylesheet, which + is the weakest rule there is: any class that sets a display — and every button here + sets `inline-flex` — beats it. That is not a hypothetical. Seven overlays in this + file already carry their own `[hidden] { display: none }` because each one was found + the hard way, and the eighth was a button that shipped as a 21x44 empty box under the + bank check on every table that didn't need it. + + One rule, for everything, so there is no ninth. */ +[hidden] { + display: none !important; +} + /* ---------- Poker table ---------- */ #pokerTableWrap { @@ -2338,6 +2352,9 @@ body.hasActionBar #holdemSidebar { .waitingAdd .holdemBtn { flex: none; min-height: 44px; + /* "Add" is three letters, which came out 43px wide — one pixel under the rule, and + the audit called it. A thumb doesn't know the word is short. */ + min-width: 56px; } .waitingList { diff --git a/tests/holdem/uiAudit.js b/tests/holdem/uiAudit.js index ab5dd96..4a9adb1 100644 --- a/tests/holdem/uiAudit.js +++ b/tests/holdem/uiAudit.js @@ -719,6 +719,26 @@ const LayoutAudit = { return { name: "the felt shows one dealer button", offenders }; }, + // Anything that says it is hidden and is drawn anyway. + // + // `hidden` gets its `display: none` from the browser's own stylesheet, the weakest + // rule in the cascade, so any class that sets a display beats it — and in this tool + // every button class does. The result is an element the code believes is gone, + // sitting on the screen: found as a 21x44 empty box under the bank check, and this + // file's own touch check had been calling it "could not be probed" rather than + // saying the plainer thing, which is that it should not be there at all. + hiddenButPainted() { + const offenders = [...document.querySelectorAll("[hidden]")] + .filter(el => { + const rect = el.getBoundingClientRect(); + if (rect.width === 0 || rect.height === 0) return false; + const style = getComputedStyle(el); + return style.display !== "none" && style.visibility !== "hidden"; + }) + .map(el => `${this.describe(el)} :: hidden, but drawn ${Math.round(el.getBoundingClientRect().width)}x${Math.round(el.getBoundingClientRect().height)}`); + return { name: "hidden means hidden", offenders }; + }, + // ---- Runner ---- // Every check this file knows how to make, every time. @@ -747,6 +767,7 @@ const LayoutAudit = { this.fieldFontSize(), this.seatOwnership(), this.oneDealerButton(), + this.hiddenButPainted(), this.contrast(options.contrast), this.touchTargets(options.minimumTarget, options.touchTargets), ];