Lock the polish branch's behaviour so a future UI edit surfaces as a failing
assertion to re-agree or fix.
Unit (vitest, node env):
- placement: recallIndex, cellOccupied/isBlankSlot, non-linear direction, the
single-tile submit default, and placementFromHint blank-fallback / rack-exhausted.
- banner: the marquee scroll-cycle repeat-then-advance, stop(), root-relative and
multiple links.
- client.GatewayError. Extract the check-word constraints out of Game.svelte into a
pure lib/checkword.ts (sanitize + canCheck) and cover them.
E2E (playwright mock, Chromium + WebKit):
- commit via the 🏁 control, history slide-down + close, the exchange dialog,
check-word input sanitising + verdict, resign-to-finished, and the Settings
board-label mode changing the on-board labels.
- AdBanner: move the side inset onto the scrolling track so the long message
scrolls to its very end; pin body text-size-adjust:100% so iOS/Safari stops
inflating the long marquee text.
- Game: do not zoom on drag start (the player may change their mind) — zoom and
centre happen on drop, in attemptPlace; a stray tap on an occupied cell no
longer cancels the rack selection (wait for an empty cell).
- Board: centre the focus cell after the zoom width transition finishes (was
clamping to top-left mid-transition); compute the cell from the rendered
scrollWidth.
- nav bar grows ONLY in game (other screens: minimal nav, content fills); tab bar always bottom
- tab bar: tighter icon/label spacing, bigger icons, hint badge on the icon corner
- board zoom reworked to width-based (real native scroll, fixes Safari/Chrome) + constant cqw labels; pinch & swipe-to-history dropped (conflict), double-tap kept, history via menu
- beginner bonus labels shrunk to fit cells
- Draw opens exchange directly (no confirm); confirm popovers restyled like the hamburger dropdown (vertical); removed the floating direction toggle
- pending tiles darker bg (no outline); last-word dark-tile highlight (static / 1s flash)
- check button disabled for <2/>15 chars, already-checked, or 5s cooldown
- global user-select:none (inputs exempt); docs updated; TODO-4 alphabet-on-wire