Put "design one bin" where someone looking for it would look - #11
Put "design one bin" where someone looking for it would look#11Oliver-Johnson wants to merge 1 commit into
Conversation
bc5b8ae to
750ab9b
Compare
The two ways in were the bottom of panel 03 -- which only appears with nothing selected -- and a button under the drawer map. Both sit below a large panel about laying out a whole drawer, so someone who arrived wanting one bin that fits one thing had to read past the thing they were not doing to find the thing they were. It goes under the nav rather than in it. The nav is a row of page links and carries the layout across them; an action sitting in that row reads like a fourth page, and it is a mode switch rather than a destination. The markup is in the bins template, so chrome.js -- which runs on the baseplates page and every guide page too -- is untouched. A case pins that the baseplates page did not sprout a control for a mode it does not have. Wired through the loop the other two entry points already share rather than a third copy of the handler, so a change to what starting a loose bin means cannot reach two of the three. Hidden once you are already in the mode, by the class that hides everything else focus takes away. The way in is noise from inside; the way out is what the focus bar is for. The sentence beside the button is desktop only. At 390 px it wrapped to three lines of 11.5 px text, which broke two existing cases at once: the 375 px audit refuses any element owning text under 12 px, and the extra height pushed the drawer map down until only 97 px of it were above the fold, against the 120 px on-screen.spec.js requires. Both were caught by CI and not by me, because I ran the new spec rather than the suite. The button says what it does; the gloss is what goes. Both older entry points are left alone. Three ways in is arguably one too many now, but which of them to drop is a taste question and not mine to answer. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
750ab9b to
b5a25ec
Compare
Oliver-Johnson
left a comment
There was a problem hiding this comment.
Verdict: looks good — nits only. The cleanest of the four.
Independent review; I did not write this.
The judgement calls are all right, and they are the ones that would have been easy to get wrong:
- Under the nav rather than in it. A mode switch in a row of page links that carry state via
data-carrywould have been a genuine confusion, and the reasoning for keeping it out is stated where the next person will find it. - Markup in
src/bins/template.html,chrome.jsuntouched. Right call, and case 4 pins it rather than trusting it. - Reusing the existing handler loop instead of a third copy — the same instinct the handover records as having cost three bugs when it was not followed.
- Hidden via the
body.binfocusCSS list, not JS assignments, which is the project's stated convention for exactly this. - Owning the CI regression in the PR body, including why it happened (ran the new spec, not the suite). That is more useful than a clean history.
All four ablations reproduce
Ran them rather than trusting the table:
| ablation | result |
|---|---|
drop scratchBinTop from the handler loop |
2 failed (opens the same loose bin, gets out of the way), 2 passed |
remove body.binfocus header .quickstart{display:none} |
1 failed (gets out of the way), 3 passed |
| neither | 4 passed |
Exactly as the body claims. Note the build stays green under the first ablation — the id audit checks that every $('id') exists in the template, not that every button is wired — so case 2 is carrying real weight there.
Nits, none blocking
-
Two buttons now read "Design one bin on its own", verbatim.
#scratchBinTop(template.html:52) and#scratchBin(template.html:245). Anyone navigating by a screen reader's button list gets two identical entries with no way to tell them apart. You have already flagged that three entry points is one too many and left the decision to Oliver — that is the right call, but if all three survive, the two survivors should at least not share a label.#scratchBin's in-panel copy could become something like "…or design one bin on its own". -
The gloss disappears below 980px, not below ~400px. The regression it was fixing was at 375–390px, but
@media(max-width:980px)also covers tablets and any half-screen desktop window, where there is plenty of room for it. Following the stylesheet's existing breakpoint rather than inventing one is defensible and I would not block on it — but a narrower query, or shrinking themax-width: 52chinstead of hiding, would keep the sentence where it still fits. -
Comment style. Two of the new lines use ASCII
--where this codebase uses em dashes (src/shared-ui/style.cssonmain: 26—against 2--;src/bins/template.html: 50 against 0). Cosmetic, but the prose voice here is clearly deliberate.
Merge order
Issue #6 suggested landing this after #4 so the single-bin page's controls get designed once. Worth knowing that is no longer forced: I merged all four PRs together and they auto-merge with node build.js --check clean on the result, so the generated pages stay in sync either way. Order is now a UI-design question rather than a mechanical one — with both landed, the page gains a header button and a layer picker plus "Add a layer on top" in the focus bar, which is worth one look together before shipping.
Reviewed independently; I am not the approver.
| like a fourth page. Plenty of people arrive wanting one bin that fits one thing, | ||
| and the way in was the bottom of a panel about laying out a whole drawer. --> | ||
| <div class="quickstart" id="quickstart"> | ||
| <button type="button" class="act" id="scratchBinTop">Design one bin on its own</button> |
There was a problem hiding this comment.
This label is verbatim identical to #scratchBin at line 245. With both entry points surviving, a screen reader's button list shows two entries reading "Design one bin on its own" with nothing to distinguish them.
If all three ways in stay (your call to leave that to Oliver is right), giving the in-panel one different copy — "…or design one bin on its own" — costs nothing and removes the ambiguity.
| it wrapped to three lines of 11.5px text, which failed the 12px floor this block | ||
| exists to enforce AND pushed the drawer map below the fold -- the exact regression | ||
| on-screen.spec.js was written to catch. The way in stays; only the gloss goes. */ | ||
| header .quickstart span{display:none} |
There was a problem hiding this comment.
The regression this fixes was at 375–390px, but @media(max-width:980px) also swallows tablets and half-screen desktop windows, where the sentence still fits comfortably.
Following the stylesheet's existing breakpoint rather than inventing one is a reasonable trade and I would not block on it — but a narrower query, or letting max-width: 52ch shrink instead of hiding outright, would keep the gloss where there is room for it.
Closes #6.
The two ways into "design one bin" were the bottom of panel 03 — which only appears with nothing selected — and a button under the drawer map. Both sit below a large panel about laying out a whole drawer. Someone who arrives wanting one bin that fits one thing has to read past the thing they are not doing to find the thing they are.
Where it went, and why not in the nav
A prominent control now sits directly beneath the nav, in the header, above every panel.
Not inside the nav, deliberately. The nav is a row of page links, and it carries the working layout across them via
data-carry. An action sitting in that row reads like a fourth page, and this is a mode switch rather than a destination — different mechanism, different meaning.Kept off the shared furniture
The header is shared furniture:
chrome.jsruns on the Baseplates page and every guide page too. So the markup lives insrc/bins/template.htmlandchrome.jsis untouched — the cheapest way to keep a bins-only control off pages that have no such mode. There's a case pinning that the Baseplates page didn't sprout a button for a mode it doesn't have.Wired through the existing loop
for (const id of ['scratchBin', 'scratchBinMap', 'scratchBinTop'])— the loop the other two entry points already share, rather than a third copy of the handler. A change to what starting a loose bin means can't now reach two of the three.Hidden from inside the mode
Once you're designing one bin, the way in is noise — the way out is what the focus bar is for. It's hidden by
body.binfocus, the same class that hides everything else focus takes away, so it follows the project's convention that what focus hides is a CSS list rather than JS assignments.What I did not do
Both older entry points are left in place. Three ways in is arguably one too many now, and I raised that in #6 — but which to drop is a taste question about your own UI, not one I should answer while you're asleep. Say the word and I'll remove one.
Verification
Four new cases in
test/ui/entry-point.spec.js, proven to bite:body.binfocushide rule removedThe first case (position in the header, above the bin panel) passes under both ablations by design — it's about placement, which neither ablation touches.
build.js --checkclean; the id audit rose 145→147 present.node build.js.style.cssis embedded in every page, so all five outputs change.🤖 Generated with Claude Code
Update: a regression CI caught and I did not
The first push of this branch broke two existing cases at 375–390 px, and it was a real regression, not flakiness:
on-screen.spec.js:115— the drawer map must keep ≥120 px above the fold at 390 px wide. This block pushed it to 97 px. That case exists precisely to stop the map being shoved down a phone screen.export.spec.js:290— the 375 px audit refuses any element owning text below 12 px. The sentence beside the button wasfont-size:11.5px.Cause: I ran the new spec locally rather than the suite, so CI found it instead of me.
Fix, following the pattern already in the stylesheet rather than inventing one: there is an existing
@media(max-width:980px)block that lifts text to 12 px and controls to 40 px tap targets. The explanatory span sat outside it. It is now hidden there — the button label carries the meaning and the gloss is a desktop luxury. That removes the sub-12 px text from the audit and returns the height to the map.Re-verified: 170 passed, 0 failed at
--workers=2locally, plusbuild.js --checkclean and all eight headless suites green.Rebase note
Rebased onto
c88f512(post-#7). No conflicts — #7 changed exactly one line ofindex.htmlas an in-place substitution, in a different region from this branch'sstyle.cssedits, so nothing shifted.build.js --checkconfirms the committed pages match what the sources generate.