Files
trx-rs/docs/Spectrum-Controls-Rework.md
sjg 06971ff65c
CI / lint (push) Successful in 2m17s
CI / test (push) Successful in 8m28s
CI / frontend (push) Successful in 4m10s
CI / reuse (push) Successful in 3s
[style](trx-frontend-http): make the spectrum control strip one strip
The row of controls under the plot held four different control heights,
units as loose text beside the field they belonged to, and a quarter of
its width as a hole in the middle.  Between about 1100 and 1400 px it
came apart: the bandwidth cluster wrapped to two lines while the level
cluster stayed on one, so the two sat at heights that matched neither
each other nor anything else on the page.

Every control stays, in its order, with its name and its behaviour.
This is the styling and the layout.

A field is now one box -- name, value and unit inside a single border --
so a number cannot be read apart from the unit it is in.  Fields,
buttons, the peak-hold select and the contrast slider are one height,
border-box so a button's own border cannot add two pixels to it, and
2.4rem under a coarse pointer where a fingertip needs the room.  The
contrast readout holds a fixed, tabular slot, so the row no longer
twitches between 1.0 and 0.9.

The container wraps and a cluster does not: a cluster that will not fit
drops whole to the next line and starts it left-aligned.  The slack
goes to a spacer rather than to `space-between`, which is what opened
the hole.

Two things this turned up.  The select carries `status-input` for other
layouts' sake, which drew a box inside the field's box.  And the narrow
-screen rules lived in a media query earlier in the file than the rules
they override -- identical specificity, so the later one won and the
phone layout had been overflowing sideways rather than stacking.  The
narrow rules now sit directly after what they override.

The layout test measures the strip at three widths: one height across
every control, no overflow, inside the plot, and clusters either
sharing a line or each having one -- never one floating against the
middle of the other.

docs/Spectrum-Controls-Rework.md records what was wrong and what was
deliberately left alone: the two different Autos, the settings that do
not persist, the one-shot buttons, and Sweet-spot's silence while it
retunes the SDR.  Those are behaviour, and are for another day.

Signed-off-by: Stan Grams <sjg@haxx.space>
2026-08-06 01:10:26 +02:00

117 lines
5.1 KiB
Markdown

# Spectrum Controls — Visual Rework
The strip between the spectrum and the radio controls (`#spectrum-controls`)
holds eight controls in two groups. This proposes how it should *look*.
Every control stays, in its current order, with its current name and its
current behaviour. Nothing here changes what a button does, what commits when,
or what is stored. It is a styling and layout change.
*Status: implemented. Kept as the record of what was changed and why.*
---
## What it looks like now
```
Bandwidth [ 12 ] kHz [Set] [Auto BW] [Sweet-spot] Peak Hold [2 s] Floor [-115] dB Range [90] dB [Auto] Contrast [——●——] 1.0
```
Four problems, all of them visual:
**1. Four different control heights on one line.** The bare number inputs, the
buttons, the `select` and the range slider are each sized by their own rule, so
nothing shares a baseline and the row reads as a pile rather than a strip.
**2. Units are loose text.** `kHz`, `dB`, `dB` and the contrast value `1.0` are
text nodes sitting outside the control they belong to, separated from it by a
gap the same size as the gap between unrelated controls. The eye has to work
out which number owns which unit.
**3. A quarter of the strip is a hole.** `justify-content: space-between` puts
about 250 px of nothing in the middle at 1600 px, and the two groups read as
two unrelated things because the only thing between them is emptiness.
**4. The groups stagger between 1100 and 1400 px.** The bandwidth group wraps
to two lines while the level group stays on one, so the level group floats at a
height of its own, aligned with neither line of the group beside it. This is
the worst of it, and it happens at a common window width.
Two smaller things: 24 px controls are below any touch-target guideline, and
the contrast readout has no fixed width, so the row twitches as the value
changes between `1.0` and `0.9`.
## Proposed
**One control height, units inside their field, and a rule where the clusters
meet.**
- **A field is one box.** Label, value and unit share a single bordered box —
`Bandwidth │ 12.0 │ kHz` — so a number and its unit can never be read apart.
Fields, buttons, the peak-hold select and the contrast slider are all 1.7 rem
tall, on 44 px targets under a coarse pointer.
- **A rule, not a hole.** The two clusters are separated by a thin vertical
rule with normal spacing either side. The slack goes to a flexible spacer, so
the strip is left-aligned rather than pushed apart.
- **A cluster never splits.** Each cluster is `nowrap`; the container wraps. If
a cluster does not fit on the line it drops whole to the next one,
left-aligned with the one above. No staggering, at any width.
- **Rules fall away at line starts.** A cluster that begins a line has no rule
hanging off its left edge.
- **The contrast readout gets a fixed, tabular slot**, so the row is still.
Below the existing mobile breakpoint the strip already stacks; the same field
component applies there, which is most of what makes it look deliberate.
## What this does not change
`Set` stays. `Auto BW` and `Auto` keep their names, even though they mean
different things — that is a naming question, not a styling one. Sweet-spot
stays where it is and keeps its behaviour. Nothing gains or loses persistence.
Nothing moves into a popover, and no control is hidden behind a click.
Those are all worth arguing about separately; a note of them is at the end of
this file so the arguments are not lost.
## Implementation
One pass, no behaviour touched:
1. `.spectrum-field` and `.spectrum-btn` in `style.css`, replacing the six
per-id rules (`#spectrum-bw-input`, `#spectrum-floor-input`,
`#spectrum-range-input`, `#spectrum-bw-label`, `#spectrum-floor-label`,
`#spectrum-range-label`) that currently repeat the same declarations.
2. Markup in `index.html`: the loose `kHz` / `dB` text nodes move inside their
label, which keeps every id and every event handler exactly where it is.
3. `#spectrum-controls` becomes a wrapping flex row with a spacer;
`#spectrum-bw-row` and `#spectrum-level-row` become `nowrap` clusters with a
left rule.
4. The mobile block in the media query drops the rules it no longer needs.
`app.ts` is not touched. Every id survives, so the existing handlers, the
`spectrum-layout.mjs` geometry test and the broadcast-layout highlight all keep
working.
### Tests
Extend `spectrum-layout.mjs`, which already measures this area:
- Every control in the strip shares one height, at 1600, 1200 and 900 px.
- No two clusters sit at different vertical offsets on the same line — the
staggering bug, asserted directly.
- The strip never overflows its container and never overlaps the hint line.
---
## Noted for later, not proposed here
Behavioural observations from reading the code, kept so they are not lost:
- `Auto BW` (filter) and `Auto` (display scaling) are both called Auto, 600 px
apart.
- `Floor`, `Range` and `Contrast` are not persisted; `Peak Hold` is.
- `Auto` and `Auto BW` are one-shot: no state, nothing to turn off.
- `Sweet-spot` retunes the SDR and waits up to 1.4 s per candidate centre, with
no busy indication.
- Contrast resets on a double-click that nothing advertises.