Claude: changes for issue #74 #82

Merged
Grandiras merged 1 commit from claude/issue-74 into main 2026-08-14 14:07:02 +00:00
Collaborator

Closes #74.

Closes #74.
Give the reconnect dialog the app's own face, and one stylesheet
All checks were successful
CI / build (pull_request) Successful in 31s
1b364a8e90
The scheduling half of this landed with #36: ReconnectModal.razor.js holds
the dialog back so a reconnect that lands inside the grace window — every
return to a backgrounded PWA — shows nothing at all. Two things were still
undone.

The dialog was still the framework's. Styling for it existed in app.css and
never reached the screen: the component shipped with the template's scoped
ReconnectModal.razor.css beside it, and a scoped selector carries an extra
attribute, so `#components-reconnect-modal[b-…]` outranked
`#components-reconnect-modal` no matter which file loaded last. What members
got was a white box, a #6b9ed2 button and blue expanding rings in *both*
themes — in dark that is --fg on hard white, i.e. a dialog you cannot read,
on the one screen that only appears when something has already gone wrong.
So the scoped file is gone and app.css is the single home: --bg-1 on
--radius, the app's .btn-primary pill, the board's own .spinner (two brand
bars drifting like the streamlines in the mark), no backdrop blur below
600px for .modal-backdrop's reason, and no UA focus ring drawn as a black
rectangle across the rounded corners.

And that stylesheet was quietly cancelling the scheduling. blazor.web.js
marks its progress with classes on the <dialog> as well as with the events
the script listens to, and the template turned two of them —
components-reconnect-retrying and components-reconnect-failed — into
`display: block` on the dialog itself, which overrides the UA's
`display: none` for a dialog nobody opened. The second reconnect attempt
therefore painted the dialog into the top of the page, outside the top layer,
with no backdrop and no focus, while the script was deliberately keeping it
off screen; `showModal()` was never called, so no test in the file could see
it. (It also carried `transition: display 0.5s allow-discrete`, which keeps a
closed dialog painted for a beat after close() — the same flash from the
other end.) Nothing in CSS decides whether that dialog is on screen any more;
the state classes only choose which line an open one shows.

Two new tests come at it from the side showModal-counting cannot reach: one
puts each state class on a closed dialog and asserts it stays off screen, and
one compares the painted surface and button against what --bg-1 and --brand
resolve to in each theme, so retuning the palette is not a failing test. Both
fail on the code they replace.
Author
Collaborator

🤖 Reviewing this PR — follow along in the action run; the reply will link the full session transcript.

📜 Live transcript — updating every ~5 minutes while the task runs.

🤖 Reviewing this PR — follow along in [the action run](https://git.grandiras.net/Grandiras/claude-bot/actions/runs/221); the reply will link the full session transcript. 📜 [Live transcript](https://git.grandiras.net/Grandiras/claude-bot/src/branch/claude-logs/transcripts/Grandiras/Ponente/pr-82/run-221.md) — updating every ~5 minutes while the task runs.
claude-reviewer left a comment

Verdict: approve — no blocking issues found.

Solid fix and well-verified. The root cause is real and the diagnosis checks out: the template's ReconnectModal.razor.css was a CSS-isolated (scoped) stylesheet, so its selectors carried an extra [b-xxxxx] attribute and outranked the identical-looking #components-reconnect-modal rules already sitting unused in app.css — meaning the framework's default white/blue styling (unreadable in dark theme) was what actually rendered, and worse, the template's display: block rules on the <dialog> itself (keyed to the same state classes blazor.web.js toggles) could paint the dialog outside the top layer even when showModal() was never called, defeating the deferred-show logic in ReconnectModal.razor.js.

The replacement in app.css correctly avoids repeating that mistake: no rule anywhere sets display on #components-reconnect-modal itself conditioned on a state class — only on its children (.components-reconnect-container > *), so the UA's dialog:not([open]) { display: none } still governs whether the dialog is visible at all, and only showModal()/close() decide that. Button-specific inline-flex overrides correctly win via an added button type selector for higher specificity. .btn-primary (existing, unmodified) uses a solid background: var(--brand), so the new visual-regression test comparing computed backgroundColor against a --brand token probe is valid and not flaky-by-construction. The reused .spinner class is self-contained (uses ::before/::after, fixed dimensions) and already has a prefers-reduced-motion rule elsewhere in app.css, so no gap there. No stale references to the deleted ReconnectModal.razor.css remain.

One very minor, non-blocking note: #components-reconnect-modal:focus/:focus-visible { outline: none } removes the browser's default focus ring on the dialog with no visible replacement, which is a mild accessibility regression in isolation — but the accompanying comment gives a deliberate rationale (nothing interactive to focus in most states), so I'd leave this as a judgment call rather than a blocker.


⏱ 1m 19s · 6 turns · tokens: 62.6k in / 6.6k out (+436.9k cache-read)
📜 Full session transcript

✅ **Verdict: approve** — no blocking issues found. Solid fix and well-verified. The root cause is real and the diagnosis checks out: the template's `ReconnectModal.razor.css` was a CSS-isolated (scoped) stylesheet, so its selectors carried an extra `[b-xxxxx]` attribute and outranked the identical-looking `#components-reconnect-modal` rules already sitting unused in `app.css` — meaning the framework's default white/blue styling (unreadable in dark theme) was what actually rendered, and worse, the template's `display: block` rules on the `<dialog>` itself (keyed to the same state classes `blazor.web.js` toggles) could paint the dialog outside the top layer even when `showModal()` was never called, defeating the deferred-show logic in `ReconnectModal.razor.js`. The replacement in `app.css` correctly avoids repeating that mistake: no rule anywhere sets `display` on `#components-reconnect-modal` itself conditioned on a state class — only on its children (`.components-reconnect-container > *`), so the UA's `dialog:not([open]) { display: none }` still governs whether the dialog is visible at all, and only `showModal()`/`close()` decide that. Button-specific `inline-flex` overrides correctly win via an added `button` type selector for higher specificity. `.btn-primary` (existing, unmodified) uses a solid `background: var(--brand)`, so the new visual-regression test comparing computed `backgroundColor` against a `--brand` token probe is valid and not flaky-by-construction. The reused `.spinner` class is self-contained (uses `::before`/`::after`, fixed dimensions) and already has a `prefers-reduced-motion` rule elsewhere in `app.css`, so no gap there. No stale references to the deleted `ReconnectModal.razor.css` remain. One very minor, non-blocking note: `#components-reconnect-modal:focus/:focus-visible { outline: none }` removes the browser's default focus ring on the dialog with no visible replacement, which is a mild accessibility regression in isolation — but the accompanying comment gives a deliberate rationale (nothing interactive to focus in most states), so I'd leave this as a judgment call rather than a blocker. --- ⏱ 1m 19s · 6 turns · tokens: 62.6k in / 6.6k out (+436.9k cache-read) 📜 [Full session transcript](https://git.grandiras.net/Grandiras/claude-bot/src/branch/claude-logs/transcripts/Grandiras/Ponente/pr-82/run-221.md) <!-- claude-verdict:approve --> <!-- claude-reviewed-head:1b364a8e90365780af26d1e7d7aaf2d323c6a34c -->
Grandiras deleted branch claude/issue-74 2026-08-14 14:07:02 +00:00
Grandiras referenced this pull request from a commit 2026-08-14 14:07:02 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Grandiras/Ponente!82
No description provided.