The map's filter bar picked up a few things that read as mistakes.
The prose hint. "All bands visible by default" (and "All sources visible — click to filter") were appended into the chip row, wedged between the chips and the Rig group. An All chip replaces both: lit when nothing is selected, and clicking it clears a selection.
Dimmed chips with no filter set. Every band chip came up at 62% opacity at the exact moment all of them were showing — only sources had the neutral default style. Both kinds now use it, and chips carry aria-pressed.
The path toggles. "TRX Paths On" / "Contact Paths On" cost most of a row and only repeated what their own highlight said. They are now TRX and Contact under the Paths label, with state in aria-pressed and the tooltip.
The divider by Fullscreen / Hide Filters. It is drawn on the button block's edge, and the panel centred that block: against a two-row bar it floated as a 42px stub in a 90px space. The block now stretches, so the rule runs the height of the bar. Stacked (mobile) it becomes a rule across the panel instead of down the left of a block that sits underneath.
Rows that did not line up. Labels sat at their natural widths, so row one's first control began at x=131 and row two's at x=121; and the two pairs of phase buttons differ in width, so the groups after them missed each other by 4px. One 3.5rem gutter for every label ("Filter by" → "Filter" so it fits the gutter rather than sets it) and one min-width for both button pairs. Search moved last, capped at 26rem, so it takes what the fixed-width groups leave — and first in the stacked layout, where the panel scrolls.
Costs worth naming: the label gutter adds ~70px, which is free down to 1100px (the bar stays two rows / 106px) but tips the bar to three rows at 1024px. Only the first column is guaranteed to align at every width; below 1280px the rows break at different groups, so interior columns depend on the wrap point.
Testing
spectrum-layout.mjs now feeds the map FT8 decodes on three bands and asserts: no prose in the chip row, All lit with nothing dimmed, picking 20m selects only it and dims the rest, All clears it; the actions block is no more than 1px shorter than the filters beside it; every row's leading control shares one x. Checked at 1600px and 1200px.
Full frontend suite green: 39 unit tests, browser-smoke, decode-flow, spectrum-layout, lint, typecheck. Layout verified by screenshot at 1600, 1440, 1280, 1200, 1100, 1024 and 480px.
The map's filter bar picked up a few things that read as mistakes.
**The prose hint.** "All bands visible by default" (and "All sources visible — click to filter") were appended into the chip row, wedged between the chips and the Rig group. An **All** chip replaces both: lit when nothing is selected, and clicking it clears a selection.
**Dimmed chips with no filter set.** Every band chip came up at 62% opacity at the exact moment all of them were showing — only sources had the neutral default style. Both kinds now use it, and chips carry `aria-pressed`.
**The path toggles.** "TRX Paths On" / "Contact Paths On" cost most of a row and only repeated what their own highlight said. They are now **TRX** and **Contact** under the Paths label, with state in `aria-pressed` and the tooltip.
**The divider by Fullscreen / Hide Filters.** It is drawn on the button block's edge, and the panel centred that block: against a two-row bar it floated as a 42px stub in a 90px space. The block now stretches, so the rule runs the height of the bar. Stacked (mobile) it becomes a rule across the panel instead of down the left of a block that sits underneath.
**Rows that did not line up.** Labels sat at their natural widths, so row one's first control began at x=131 and row two's at x=121; and the two pairs of phase buttons differ in width, so the groups after them missed each other by 4px. One 3.5rem gutter for every label ("Filter by" → "Filter" so it fits the gutter rather than sets it) and one `min-width` for both button pairs. Search moved last, capped at 26rem, so it takes what the fixed-width groups leave — and first in the stacked layout, where the panel scrolls.
Costs worth naming: the label gutter adds ~70px, which is free down to 1100px (the bar stays two rows / 106px) but tips the bar to three rows at 1024px. Only the first column is guaranteed to align at every width; below 1280px the rows break at different groups, so interior columns depend on the wrap point.
## Testing
`spectrum-layout.mjs` now feeds the map FT8 decodes on three bands and asserts: no prose in the chip row, All lit with nothing dimmed, picking 20m selects only it and dims the rest, All clears it; the actions block is no more than 1px shorter than the filters beside it; every row's leading control shares one x. Checked at 1600px and 1200px.
Full frontend suite green: 39 unit tests, `browser-smoke`, `decode-flow`, `spectrum-layout`, lint, typecheck. Layout verified by screenshot at 1600, 1440, 1280, 1200, 1100, 1024 and 480px.
The bar explained itself in prose: "All bands visible by default" sat
between the chips and the next group, taking width the bar could not
spare and reading as a stray line of text. An "All" chip says the same
thing in a chip's width and gives the selection somewhere to be undone.
Band chips also came up dimmed at the very moment every band was on the
map -- an empty selection is no filter at all, so nothing is dimmed
until something is picked. The path toggles drop their "On"/"Off"
suffix, which cost most of a row and only repeated what their own
highlight already said; state moves to aria-pressed and the tooltip.
The rest is alignment. The rule dividing the buttons from the filters
is drawn on the button block's edge, and a centred block left it
floating as a stub beside a two-row bar; stacked, it lay down the left
of a block that sits underneath. The labels sat at their natural
widths, so each row's first control started somewhere different, and
the two pairs of phase buttons differed in width, so the groups after
them missed each other by four pixels. One gutter for every label, one
width for both pairs, and the search field moved last where it can take
the room the fixed-width groups leave.
The map layout test now covers the chips, the divider's height and the
rows' shared start.
Signed-off-by: Stan Grams <sjg@haxx.space>
sjg
merged commit 09634eb851 into main2026-08-05 21:44:31 +02:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
The map's filter bar picked up a few things that read as mistakes.
The prose hint. "All bands visible by default" (and "All sources visible — click to filter") were appended into the chip row, wedged between the chips and the Rig group. An All chip replaces both: lit when nothing is selected, and clicking it clears a selection.
Dimmed chips with no filter set. Every band chip came up at 62% opacity at the exact moment all of them were showing — only sources had the neutral default style. Both kinds now use it, and chips carry
aria-pressed.The path toggles. "TRX Paths On" / "Contact Paths On" cost most of a row and only repeated what their own highlight said. They are now TRX and Contact under the Paths label, with state in
aria-pressedand the tooltip.The divider by Fullscreen / Hide Filters. It is drawn on the button block's edge, and the panel centred that block: against a two-row bar it floated as a 42px stub in a 90px space. The block now stretches, so the rule runs the height of the bar. Stacked (mobile) it becomes a rule across the panel instead of down the left of a block that sits underneath.
Rows that did not line up. Labels sat at their natural widths, so row one's first control began at x=131 and row two's at x=121; and the two pairs of phase buttons differ in width, so the groups after them missed each other by 4px. One 3.5rem gutter for every label ("Filter by" → "Filter" so it fits the gutter rather than sets it) and one
min-widthfor both button pairs. Search moved last, capped at 26rem, so it takes what the fixed-width groups leave — and first in the stacked layout, where the panel scrolls.Costs worth naming: the label gutter adds ~70px, which is free down to 1100px (the bar stays two rows / 106px) but tips the bar to three rows at 1024px. Only the first column is guaranteed to align at every width; below 1280px the rows break at different groups, so interior columns depend on the wrap point.
Testing
spectrum-layout.mjsnow feeds the map FT8 decodes on three bands and asserts: no prose in the chip row, All lit with nothing dimmed, picking 20m selects only it and dims the rest, All clears it; the actions block is no more than 1px shorter than the filters beside it; every row's leading control shares one x. Checked at 1600px and 1200px.Full frontend suite green: 39 unit tests,
browser-smoke,decode-flow,spectrum-layout, lint, typecheck. Layout verified by screenshot at 1600, 1440, 1280, 1200, 1100, 1024 and 480px.