Every game we ship runs in an iframe on its own page. On a desktop that frame is a sensible box with the game inside it. On a phone we had it hold the game's declared aspect ratio, which seemed obviously right.
So we measured all 70 bundles at 390×844 with Chrome's mobile emulation, and the headline is this:
A game shrunk into an aspect-ratio box is not a smaller game. It is a wrong one.
What was actually broken
Nine of 51 canvases were drawn stretched. Not scaled down — distorted.
max-width: 100% and max-height: 100% on a canvas do not preserve aspect
ratio once both constraints bind. Checkers' squares were rectangles and its
pieces were ellipses, 60 per cent off. Drift Arena's track rendered as a 36-pixel
strip, 337 per cent off. Fleet Hunt drew a square board into a 334×104 box.
These are not subtle. They were shipping.
Another nine games pushed controls outside the box — and because the bundles
are overflow: hidden, there was nothing to scroll to. Hearts lost six of its
eight controls. Not hidden behind a fold. Gone.
Median board area was 21 per cent of the viewport. Four fifths of a phone screen spent on not-the-game.
The measurement that turned a wish-list into an ordering
We had a list of candidate fixes and no way to rank them. So we re-ran the entire measurement with the frame removed — games opening full-screen on phones — and compared:
| boxed | full screen | |
|---|---|---|
| Distorted canvases | 9 | 0 |
| Unreachable controls | 9 | 0 |
| Board area (median) | 21% | 42% |
| Undersized tap targets | 89% | 88% |
That last row is the useful one. Auto-fullscreen is a complete fix for two correctness bugs and essentially no fix at all for tap-target size. Which means they are two independent pieces of work — and we now know that rather than assuming it.
Always re-run the whole measurement under the candidate fix. The deltas rank the work for you, and they tell you which problems your fix does not touch.
Reading the code was worth about 40 per cent
Before measuring we made five predictions from reading the CSS. Three were wrong:
- The frame will be below the fold on phones. No — above it on 70 of 70.
- The fullscreen button will be below the fold. No — visible on 70 of 70.
- The drag-based games will scroll-jack. Backwards. The drag games all set
touch-action: noneand behave perfectly. It is the tap games that pan the page under your finger.
We would have built a rotate hint and a layout reorder for problems that did not exist, and missed the one that did.
One emulation detail, because it invalidates the whole exercise if you get it
wrong: you must enable isMobile and hasTouch. Without them
(pointer: coarse) never matches, none of the mobile CSS applies, and you have
carefully measured a page no human ever sees.
The fix that broke the thing it was fixing
The tap-target work needed a pass that grows controls across every bundle at once. On its first run it distorted five boards — by taking height from the canvas to give to the buttons. The exact defect the whole project existed to remove, reintroduced by the fix for a different defect.
So the pass now snapshots the board geometry, applies its changes, re-measures, and backs off — width adjustments first, then everything — if the canvas skewed, shrank, or anything overflowed. Undersized controls went from 89 per cent to 16 per cent with zero regressions on any safety metric.
A fix that reaches every game at once must prove it did no harm in the same run that applies it. Not in a later test. In the same run, with the ability to undo itself.
Telling a board from a toolbar
The naive version of the tap-target fix is button { min-height: 44px }. It
bursts every board it means to help — Sudoku's digit pad, Mahjong's 144 tiles and
Word Weave's letter cells are all <button> elements in a grid.
Class names cannot separate them. .btn, .key, .cell and .card are all
used both ways across the catalogue.
Arrangement can. Count interactive siblings per parent node; six or more means you are looking at a board, not a toolbar. One subtlety that cost us a round: keying on the parent's tag plus class merged three separate segmented control rows into one eight-strong group, which the rule then classified as a board and skipped. Only node identity works.
And the guard has to classify the world the same way the fix does, or it is asserting something the fix never attempted.
Four measurement tools that lied to us
documentElement.scrollWidthcannot see a bundle overflowing. Every bundle pinshtmlto the viewport, so it reported zero overflow on 70 of 70 while Carrom was clipping 262 pixels of board off the edge. Readdocument.body.getBoundingClientRectcounts a closed<details>as visible — Chrome gives its contents a layout box. Useel.checkVisibility()with the opacity, CSS and content-visibility options set.- Budget a size, not a count. Our piece-size assertion was flaky within a single sitting because Dominoes deals a different number of tiles each run. How small the layout draws a piece is a property of the layout; how many it deals is a property of the shuffle. Assert the first.
- Our own branding bar renders nothing inside our own iframe, so a harness loading bundles standalone counts one control per game that no player ever sees.
And: verify the guard fails on purpose. Reverting Carrom's media query is caught. A guard that cannot fail is decoration.
Two features that measurement killed
A rotate hint for the nine games declaring landscape orientation. Six of the nine are the same or worse rotated (0.94–1.02× board area), and of the three that gain, two collect more undersized controls than they shed. The manifest field does not predict which games play better sideways — the bundles already adapt.
Reordering the frame above the heading on phones. The frame was already fully above the fold on 70 of 70.
Both were on the roadmap. Neither was real.
What is still wrong
Mahjong Solitaire draws its 144 tiles at 22 pixels — the worst remaining mobile defect in the catalogue — followed by TriPeaks Solitaire at 37 and Daily Word at 29. No shared pass reaches these. Each needs its own board given more of the screen, one game at a time.
They are recorded in a minimum-piece-size table, so they cannot quietly get worse while we get to them.
Everything above is measurable on your own phone right now, because all 76 games are free, browser-based and need no account: browse the catalogue.