feat: settings become five groups that state their own answer
The panel was one open block of everything in two columns. That reads fine at four games and stops working at eighteen: the game list alone is eighteen rows of four controls each, and it sat above the checkbox somebody had scrolled down here to tick. Nothing was findable and everything was in the way. Collapsing it into groups is only half an answer, though — a group showing nothing but its name turns "what is my region set to?" into a click, which trades one kind of friction for another. So each summary carries its group's current state: "Europe · Dark", "17 of 18 on · A–Z", "plus finished, not started". Closed, the panel is a five-line report of how the app is configured; opening one is for changing an answer rather than reading it. The states are derived from `prefs` at render, never stored, so they cannot drift from the controls they describe. Native `<details>`, for the reason the reorder arrows are ordinary buttons: keyboard and screen reader reach it with no second implementation. `summary` is not an `a`, `button` or `[tabindex]`, so it needed its own focus-visible rule — the shared one does not reach it. Two things fell out along the way. The region and appearance rows had no accessible name at all, so a screen reader read six unlabelled buttons in a row; they and the board's split pills are one `PillGroup` now, with the `role="group"` the board's own controls already carry. And the empty states that point at "Show events that haven't started" now name the group holding it, which is what makes shipping the groups closed safe. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
14f6f2f0dc
commit
fb390c1af8
8 files changed
+498
-215
No files matched your search
@@ -423,6 +423,45 @@ body {
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
/* ---- Settings: collapsible groups -------------------------------------- */
|
||||
/*
|
||||
* Native `<details>`, so the disclosure is keyboard- and screen-reader-reachable
|
||||
* without a second implementation of the same interaction — the argument the
|
||||
* game-order arrows already make. Only three things need CSS. The browser's own
|
||||
* marker cannot be placed and differs between engines, so it goes and the
|
||||
* summary draws its own chevron; and `summary` is not an `a`, a `button` or a
|
||||
* `[tabindex]`, so the focus rule above does not reach it and the one control
|
||||
* that opens a group would have no visible focus at all.
|
||||
*/
|
||||
.settings-group > summary {
|
||||
list-style: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.settings-group > summary::-webkit-details-marker {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.settings-group > summary:focus-visible {
|
||||
outline: 2px solid var(--color-near);
|
||||
outline-offset: 2px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.settings-chevron {
|
||||
transition: transform 150ms ease;
|
||||
}
|
||||
|
||||
.settings-group[open] > summary .settings-chevron {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.settings-chevron {
|
||||
transition: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* Horizontal scrollers keep their gutter but hide the bar chrome. */
|
||||
.scroll-x {
|
||||
overflow-x: auto;
|
||||
|
||||
Reference in new issue
Block a user