zoom multiplies the baseline instead of being swallowed by it

The 2x cap flattened the panel's zoom control into doing nothing, and the
reason is worth writing down: `fit` is the SAME NUMBER at every zoom level.
CSS `zoom` takes off `offsetWidth` exactly what it adds to the pixel ratio, so
the fit is zoom-invariant by construction — and capping it therefore caps every
zoom level to the same size.

So the cap applies to the baseline, the size at 100%, and zoom multiplies what
comes out. 100% stays exactly where it is; zooming in goes past 2x again.

Quarter steps now go all the way down rather than whole numbers under 2x. With
whole numbers, zooming out from a 2x baseline fell straight to 1x and halved
the board in one press. Cells stay whole at every quarter — 20px at 1.25x —
which was always the property that mattered, not the size of the step.

The resulting ladder over the panel's 70-160% range: 1.25, 1.5, 1.75, 2.0,
2.0, 2.25, 2.5, 2.75, 3.0, 3.0. Eight of the ten presses move it; two land on
the same quarter, which is the price of keeping the grid even.

Also `overflow-hidden` on the box, so zooming past what the panel holds clips
rather than shoving the status line out of the way.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Officer-Session: de3ed4e6-f88a-429c-94e6-a760336ba83b
This commit is contained in:
2026-08-23 22:41:14 +00:00
co-authored by Claude Opus 5
parent 48cbb24c4c
commit e5a7c5ffff
2 changed files with 36 additions and 25 deletions
+13 -8
View File
@@ -90,15 +90,20 @@ resizing the panel, and the surround is teal (`-solid`) rather than the root's b
**The stage is small because the panel scales it by whole numbers.** Pixel art at a fractional scale gets
uneven cells — some three screen pixels wide, their neighbours two — which reads as "not quite right"
rather than as blur, and `image-rendering: pixelated` does not help because unevenness is not blur. So the
panel snaps the scale, in DEVICE pixels, to whole numbers below 2x and QUARTER steps above it. Quarters are
safe because the unit that has to stay regular is the CELL: the board is a 16px grid, so at 2.25x a cell is
exactly 36 screen pixels, as even as at 2x, and only sub-cell pixels alternate. They are quarters rather
than halves because coarse steps overshoot — with halves this jumped 2x to 2.5x, too small to too large
with nothing in between.
panel snaps the scale, in DEVICE pixels, to QUARTER steps. Quarters are safe because the unit that has to
stay regular is the CELL: the board is a 16px grid, so every quarter step gives a whole cell — 20px at
1.25x, 36px at 2.25x — and only sub-cell pixels alternate. Quarters rather than halves because coarse steps
overshoot, and quarters all the way down rather than whole numbers under 2x because otherwise zooming out
from a 2x baseline falls straight to 1x and halves the board in one press.
The scale is then CAPPED at 2x. Fitting the panel is not the same as looking right, and past 2x this stops
reading as a window on a desktop. That is a default, not a verdict — the panel header has a zoom control,
and `MAX_SCALE` is one constant.
The BASELINE — the size at 100% — is capped at 2x. Fitting the panel is not the same as looking right, and
past 2x this stops reading as a window on a desktop.
The panel's own zoom control then multiplies that, so zooming in still goes past 2x and zooming out still
shrinks. This needs saying because it is not automatic: `fit` is the same number at every zoom level, since
CSS `zoom` takes off `offsetWidth` exactly what it adds to the pixel ratio. A cap applied to the result
rather than the baseline therefore flattens the zoom control into doing nothing, which is how the first
version of it shipped.
Two things the scale has to know about that are easy to miss. `devicePixelRatio` is not the whole story:
the panel header has its own CSS `zoom`, so the effective ratio is `devicePixelRatio × zoom`, read as