The screen does what you tell it — three Display items, and a fourth declined
Reviewed with Jesse out of TODO.md's Display section. Stays in the unshipped v0.7.9. #17 (hiding the Division map) was DECLINED, and the reason is that its premise had already died. Gitea#18 replaced the wrapped layout with a single row, and the reason to fold the map away was that it GREW — a horseshoe of three or a square of four pushed the board off the screen. One row is boardH = PAD * 2 + CH + 30: 150px, fixed, at every seat count. That is not worth a control, three states and a persisted preference. It was a sixth member of the drawing pass that got closed with Gitea#18 and stayed open only because it reads as a control question rather than a drawing one — recorded in TODO.md as an explicit decision, with the design that had already been worked out kept, and with the one thing that would justify reopening it: the map growing again. #16 THE OFFICE AREA'S AUTO-HIDE COULD NOT REACH EVERY STATE. One button cycling auto -> pinned -> auto, where the pin was `open ? 'closed' : 'open'` and `open` is what auto is doing AT THAT MOMENT. So the pin a press offered depended on the phase, and going from always-show to always-hide meant clicking back to auto, waiting for the phase to turn over, and clicking again. Three controls now, one per mode. The labels still say what pressing DOES, which was an earlier deliberate fix; what the cycle could not do was report the state it was in, and aria-pressed carries that now. They are addressed by id rather than queried off the container, and that is testability rather than style: the stub DOM the web suite runs against only models markup the page WROTE, so a child query finds nothing and the control would have shipped green and unexercised. The test presses always-show to always-hide directly — the transition the cycle could not make. #23 THE HISTORY READS NEWEST FIRST. Jesse: "the top line is the most recent and the further down you go, the older the entry." The phase headings now trail the lines they announce, ruled acceptable rather than overlooked: "stage changes will be beneath (prior to / older than) the following events. That is OK." Reading down is reading backwards. Grouping by phase and reversing the groups was offered and declined as more machinery than the complaint needs. replays.ts keeps its oldest-first log deliberately — it is paired with a frame stepper, where newest-first would fight the stepping. The slice(-60) cap is untouched and stays open. #28 THE SETTINGS MOVED INTO A CARD. The top line carried six things and now carries four: Revenue, the objective, the collision counts and the game code. The rest is a This Game card at the foot of the right-hand column, folded by default. Nothing new travels for it — configFromFrame already existed and main.ts already called it three times, so rulesListHtml(configFromFrame(f), ...) needed no refactor, and the card draws from the same renderer as the lobby's join preview so the two cannot drift. THE COLLISION COUNTS ARE NEW ON THE BOARD, NOT MOVED. The Frame has carried collisionsToday and collisionsTotal since v0.7.0 and nothing drew them, so the one victory condition that ends a game EARLY ran invisibly — the second time this release that the Frame had the answer and the view never asked (see #43's actingPlayer). They stay on the top line while the limits go in the card: a limit is agreed to once, "2 of 3 today" changes how you play the next Stage. One stub gap closed to get here: none of the five element factories in test/web.test.ts had setAttribute, so the first render threw and any control reporting state through ARIA was untestable. WHAT IS NOT VERIFIED: the layout. There is no browser on this box, so nothing has confirmed the segmented control, the card or the reversed panel look right on screen. The logic is tested; the appearance is not, and wants the next play session. 881 tests pass, fourteen new. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YTaNBL1jVxNqgFdjHkHoo3
This commit is contained in:
co-authored by
Claude Opus 5
parent
31b942cc38
commit
d267f89a82
+88
-1
@@ -254,6 +254,93 @@ and the line reads "resumed" when it is.
|
||||
Both halves are pinned, including that a brand-new game does *not* claim to be a resume — an
|
||||
announcement that fires either way says nothing.
|
||||
|
||||
### The screen does what you tell it — three items off `TODO.md`
|
||||
|
||||
Reviewed with Jesse 2026-08-30 out of the Display section. A fourth, #17 (hiding the Division map),
|
||||
was **declined** in the same pass: its premise died with Gitea#18 and nobody had connected the two.
|
||||
The map used to grow a row at a time and was worth folding away at three or four seats; a single row
|
||||
is `boardH = PAD * 2 + CH + 30` — 150px, fixed, at every seat count — and that is not worth a
|
||||
control, three states and a persisted preference.
|
||||
|
||||
#### The Office Area's auto-hide could not reach every state (#16)
|
||||
|
||||
One button cycling `auto -> pinned -> auto`, where the pin it reached was
|
||||
`open ? 'closed' : 'open'` — and `open` is what auto is doing **at that moment**,
|
||||
`FOCUS_PHASES.has(f.phaseKey)`. So which pin a press offered depended on the phase: "always hidden"
|
||||
during Local Operations and Cargo, "always showing" everywhere else. Getting from one pin to the
|
||||
other meant clicking back to auto, waiting for the phase to turn over, and clicking again. That is
|
||||
why it never read as a setting — it was not one.
|
||||
|
||||
Three controls now, one per mode, and every mode is one press from every other. The labels still say
|
||||
what pressing **does** rather than what the panel is doing, which was an earlier deliberate fix; what
|
||||
the cycle could not do was report the state it was in, and `aria-pressed` on the lit button carries
|
||||
that instead of the label.
|
||||
|
||||
**Addressed by id (`#dm-auto`/`#dm-open`/`#dm-closed`) rather than by querying the container's
|
||||
children**, and that is a testability decision rather than a style one. The page never writes this
|
||||
markup, so a child query finds nothing in the stubbed DOM the web suite runs against — the control
|
||||
would have shipped green and completely unexercised. The test that now pins it presses
|
||||
always-show → always-hide directly, which is precisely the transition the cycle could not make.
|
||||
|
||||
#### The history reads newest first (#23)
|
||||
|
||||
Jesse: "it should be reversed so the top line is the most recent and the further down you go, the
|
||||
older the entry." The panel ran oldest-first and scrolled itself to the bottom, so the thing that had
|
||||
just happened was the one line you had to go and find.
|
||||
|
||||
**The phase headings now trail their lines, and that is accepted rather than overlooked.** A
|
||||
`t-phase` line reads forwards — it introduces what follows it — so reversing puts each one below the
|
||||
events it announced. Jesse ruled on it directly: "stage changes will be beneath (prior to / older
|
||||
than) the following events. That is OK." Reading down the panel is reading backwards in time, and a
|
||||
heading under its own lines is what backwards looks like. Grouping by phase and reversing the groups
|
||||
was the alternative and was declined as more machinery than the complaint needs. The
|
||||
"— the game began —" marker moves by the same logic: it is the oldest thing on screen, so it goes
|
||||
last.
|
||||
|
||||
`replays.ts` keeps its own oldest-first log deliberately. It is paired with a frame stepper, where
|
||||
"what just happened" is the step you have this moment clicked, so newest-first would fight the
|
||||
stepping rather than help it.
|
||||
|
||||
#### The settings moved into a card, and the collision counts came out of hiding (#28)
|
||||
|
||||
Jesse, 2026-08-23: "the game-specific information in the very top line should probably be a card like
|
||||
Facilities, timetable or blocked… we can give complete information about all the game options and not
|
||||
take up valuable real estate at the top of the screen." And on when it is read: "To go, 'Oh wait, what
|
||||
did we set that to?'"
|
||||
|
||||
The top line carried six things and now carries four: **Revenue, the objective, the collision counts,
|
||||
and the game code**. The seed or seat, the game type and the abbreviated house rules moved into a
|
||||
**This Game** card at the foot of the right-hand column, folded by default and persisted with the
|
||||
other display preferences.
|
||||
|
||||
**Nothing new travels for it.** `configFromFrame` already turns the Frame's copy of the config back
|
||||
into a `GameConfig`, and `rulesListHtml` is the renderer the lobby's join preview and seating screen
|
||||
already draw — so what a player agreed to before the deal and what they read mid-game come from one
|
||||
implementation and cannot drift. The card adds only the half `rulesListHtml` has no notion of: which
|
||||
seed or seat this is, and what the game is called.
|
||||
|
||||
**The collision counts are new on the board, not merely moved.** The Frame has carried
|
||||
`collisionsToday` and `collisionsTotal` since v0.7.0 and nothing drew them, so the one victory
|
||||
condition that ends a game EARLY ran invisibly — which v0.7.9 made reachable in solitaire too, and
|
||||
that is what made them worth having. They stay on the top line while the limits go in the card,
|
||||
because the two are different kinds of thing: a limit is a setting agreed to once, "2 of 3 today" is
|
||||
a number that changes how you play the next Stage. A limit of `0` is off, and an off half is left out
|
||||
rather than shown as "1 of 0"; with both off the chip is empty and collapses.
|
||||
|
||||
In solitaire the game-code span is empty, so its tooltip — which still carries the type, the blurb and
|
||||
the victory conditions — is unreachable. Not a hole: the card's summary line is on screen whether the
|
||||
card is open or shut and opens with the type, "Solitaire · 5 Days · floor 15 · 3 cards · 4/2/1".
|
||||
|
||||
**One gap in the test stubs was closed to get here.** None of the five element factories in the web
|
||||
suite had `setAttribute`, so the first render threw `b.setAttribute is not a function` — meaning any
|
||||
control that reports its state through ARIA could not be tested at all. They carry an attribute bag
|
||||
now, and the segmented control's test reads `aria-pressed` through it.
|
||||
|
||||
**What is verified and what is not.** The logic is covered by three new tests and the two that used to
|
||||
read `#houserules`/`#gametype` were rewritten to open the card rather than deleted. **The layout is
|
||||
not verified** — there is no browser on this box, so nothing has confirmed the segmented control, the
|
||||
card, or the reversed panel actually look right on screen. That wants a play session.
|
||||
|
||||
### Three wording and layout fixes
|
||||
|
||||
- **The collision entries** on all three screens now read "The game ends immediately and results in
|
||||
@@ -268,7 +355,7 @@ announcement that fires either way says nothing.
|
||||
cost, not a danger, and red would outrank the actual rules above it. The buttons say **Continue
|
||||
Existing Saved Game** and **Deal New Game** rather than "Continue saved game" and "Deal".
|
||||
|
||||
878 tests pass, eleven of them new; one existing test asserted the opposite of the collision ruling
|
||||
881 tests pass, fourteen of them new; one existing test asserted the opposite of the collision ruling
|
||||
above and says so where it was reversed.
|
||||
|
||||
---
|
||||
|
||||
Reference in New Issue
Block a user