Stage 17 docs: round-4 UI (inline profile, double-tap/drag recall, hover-zoom, animated shuffle, lines-off board)
CI / changes (pull_request) Successful in 1s
CI / unit (pull_request) Successful in 8s
CI / integration (pull_request) Successful in 11s
CI / ui (pull_request) Successful in 29s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 41s

- UI_DESIGN: double-tap recall vs zoom, hover-hold drag auto-zoom, placing & recall
  rules, grid-lines toggle (gapless checkerboard default), animated shuffle; fix the
  stale MakeMove/Reset description (direct  button + ↩️ Reset tab, no popover).
- FUNCTIONAL (+ru): optional trailing '.' in display names; profile edited inline.
- PLAN: robot early band [1,5]→[3,10] (#14); round-4 refinements + deferred #2/#16.
This commit is contained in:
Ilia Denisov
2026-06-06 14:55:17 +02:00
parent 71b054227a
commit 3856b34f8a
4 changed files with 49 additions and 24 deletions
+15 -3
View File
@@ -1224,9 +1224,9 @@ provided cert) at the contour caddy; prod VPN; rollback.
across restarts). `Pick(variant)` is variant-aware: a Russian game draws Russian names with ≤ ~20% across restarts). `Pick(variant)` is variant-aware: a Russian game draws Russian names with ≤ ~20%
Latin, an English game the Latin pool. Robot identities are keyed `robot-<lang>-<index>`. Latin, an English game the Latin pool. Robot identities are keyed `robot-<lang>-<index>`.
- **Robot timing** (#4, interview): the fixed `2 + 88·u^3.5` move delay became move-number-aware — the - **Robot timing** (#4, interview): the fixed `2 + 88·u^3.5` move delay became move-number-aware — the
band interpolates from [1,5] min at the first move to [10,90] min by ~28 moves, right-skewed by k=4, band interpolates from [3,10] min at the first move (raised from [1,5] in round 4, #14) to [10,90] min
so early moves are quick and the endgame can be long. A daytime nudge pulls the reply toward the by ~28 moves, right-skewed by k=4, so early moves are quick and the endgame can be long. A daytime
move's lower band. nudge pulls the reply toward the move's lower band.
- **Multi-device push** (#7, interview): `emitMove` no longer skips the acting seat, so the mover's own - **Multi-device push** (#7, interview): `emitMove` no longer skips the acting seat, so the mover's own
other devices (and their lobby) refresh. `opponent_moved` stays in-app only (no out-of-app push to the other devices (and their lobby) refresh. `opponent_moved` stays in-app only (no out-of-app push to the
actor), and the gateway already fans each event out to all of a user's live streams. actor), and the gateway already fans each event out to all of a user's live streams.
@@ -1269,6 +1269,18 @@ provided cert) at the contour caddy; prod VPN; rollback.
pops; the make-move popover became a direct **✅** with a tab-bar **↩️ Reset**; the hint pops; the make-move popover became a direct **✅** with a tab-bar **↩️ Reset**; the hint
button disables at zero hints; plus **board-only vertical scroll** (#9) and a button disables at zero hints; plus **board-only vertical scroll** (#9) and a
**keyboard-overlay** check-word dialog (#10). **keyboard-overlay** check-word dialog (#10).
- **Contour-verification follow-ups** (round 4, from live testing): the robot early-move band was raised
[1,5] → [3,10] min so openings are less hasty (#14); the **profile** is edited inline (the Edit/Cancel
toggle is gone, the form is always shown for durable accounts, hint balance stays read-only) and a
single trailing "." is allowed in display names (#5/#6); a pending tile now recalls by **double-tap**
or by **dragging it back onto the rack** (single-tap recall removed), and **holding a dragged tile over
a cell ~1 s auto-zooms** there (#3/#10); **🔀 Shuffle is animated** — tiles hop along a low parabola to
their new slots, duration scaled by distance, with a haptic shake (#9); a **lines-off board** Settings
toggle (default off) renders a gapless checkerboard with rounded, right-shadowed tiles, reclaiming
~14px of width (#12). **Deferred (discussed):** board **pinch zoom** (#2) — it fights both the native
scroll and the new one-finger drag-back, so it stays dropped in favour of double-tap + hover-hold zoom;
**robot win% in the admin game detail** (#16) — needs the seed-derived play-to-win decision exposed
across the game/robot package boundary, to be picked up when that seam is added.
## Deferred TODOs (cross-stage) ## Deferred TODOs (cross-stage)
+4 -3
View File
@@ -109,9 +109,10 @@ even disguised. Nudge the player whose turn is awaited at most once per hour (th
nudge is part of the game chat); the out-of-app push is delivered via the platform. nudge is part of the game chat); the out-of-app push is delivered via the platform.
### Profile & settings *(Stage 4 / 8)* ### Profile & settings *(Stage 4 / 8)*
Edit the display name (letters joined by single space / "." / "_" separators, up to Edit the display name (letters joined by a single space / "." / "_" separator, with an
32 characters), the timezone (chosen as a UTC offset), the daily away window (on a optional trailing ".", up to 32 characters), the timezone (chosen as a UTC offset), the
10-minute grid, at most 12 hours, wrapping midnight) and the block toggles. Linking daily away window (on a 10-minute grid, at most 12 hours, wrapping midnight) and the
block toggles. The profile form is edited inline (no separate edit mode). Linking
an email or Telegram and merging accounts are covered under "Accounts, linking & an email or Telegram and merging accounts are covered under "Accounts, linking &
merge" (Stage 11). merge" (Stage 11).
+6 -5
View File
@@ -112,11 +112,12 @@ Mini App** авторизует по подписанным `initData` плат
push доставляется через платформу. push доставляется через платформу.
### Профиль и настройки *(Stage 4 / 8)* ### Профиль и настройки *(Stage 4 / 8)*
Редактирование отображаемого имени (буквы, разделённые одиночными пробелом / «.» / Редактирование отображаемого имени (буквы, разделённые одиночным пробелом / «.» /
«_», до 32 символов), таймзоны (выбор смещения от UTC), суточного окна отсутствия «_», с необязательной завершающей «.», до 32 символов), таймзоны (выбор смещения от
(away; сетка по 10 минут, не более 12 часов, с переходом через полночь) и UTC), суточного окна отсутствия (away; сетка по 10 минут, не более 12 часов, с
переключателей блокировок. Привязка email и Telegram, а также слияние аккаунтов переходом через полночь) и переключателей блокировок. Форма профиля редактируется
вынесены в раздел «Аккаунты, привязка и слияние» (Stage 11). сразу (без отдельного режима редактирования). Привязка email и Telegram, а также
слияние аккаунтов вынесены в раздел «Аккаунты, привязка и слияние» (Stage 11).
### История и статистика *(Stage 3 / 8)* ### История и статистика *(Stage 3 / 8)*
Завершённые партии архивируются в независимом от словаря виде и экспортируются Завершённые партии архивируются в независимом от словаря виде и экспортируются
+24 -13
View File
@@ -62,10 +62,17 @@ Login uses `Screen`.
that works consistently across browsers; no `transform`, which broke scrolling that works consistently across browsers; no `transform`, which broke scrolling
differently in Safari/Chrome). Labels are sized in `cqw` against the fixed viewport, so differently in Safari/Chrome). Labels are sized in `cqw` against the fixed viewport, so
they stay a constant size as the cells grow (relatively smaller at higher zoom). they stay a constant size as the cells grow (relatively smaller at higher zoom).
**Double-tap** toggles zoom and, on touch, placing a tile auto-zooms in centred on the **Double-tap** an empty/filled cell toggles zoom centred on it; double-tap a **pending**
target; the custom pinch and swipe-to-open-history gestures were dropped because they tile recalls it. On touch, placing a tile auto-zooms in centred on the target, and
fight native scroll — history opens from the menu or a tap on the players plaque (below). **holding a dragged tile over a cell for ~1 s** auto-zooms there (Stage 17). The custom
A **hint** auto-zooms centred on the hint's placement, not the top-left (Stage 17). pinch and swipe-to-open-history gestures stay dropped — they fight both native scroll and
the one-finger drag-back gesture; history opens from the menu or a tap on the players
plaque (below). A **hint** auto-zooms centred on the hint's placement, not the top-left.
- **Placing & recall** (`Game.svelte`): a rack tile is placed by tap-then-tap or by
dragging it onto a cell; a pending tile is taken back by a **double-tap** or by **dragging
it back onto the rack** (unzoomed board only — when zoomed the one-finger gesture scrolls).
A single tap no longer recalls (too easy to trigger); a recalled tile returns to its
original rack slot (Stage 17).
- **Players plaque & history** (`Game.svelte`, Stage 17): the seats above the board share - **Players plaque & history** (`Game.svelte`, Stage 17): the seats above the board share
the width evenly; the seat whose turn it is is **raised** (a drop shadow on its sides) the width evenly; the seat whose turn it is is **raised** (a drop shadow on its sides)
while the others read **sunk in** (an inset shadow). A tap anywhere on the plaque toggles while the others read **sunk in** (an inset shadow). A tap anywhere on the plaque toggles
@@ -86,20 +93,24 @@ Login uses `Screen`.
- **Bonus-square labels** — a Settings choice (`boardlabels.ts`): `beginner` shows a - **Bonus-square labels** — a Settings choice (`boardlabels.ts`): `beginner` shows a
split `3×` / `word` (localized слово/буква), `classic` a single `3W` / `3С`, `none` split `3×` / `word` (localized слово/буква), `classic` a single `3W` / `3С`, `none`
nothing. Default **beginner**. nothing. Default **beginner**.
- **Grid lines**: the inter-cell gap shows a contrasting `--cell-line` (darker in light, - **Grid lines** — a Settings toggle, **default off** (Stage 17). Off: a **gapless
lighter in dark) to avoid a wavy-line optical illusion. checkerboard** — plain cells alternate two shades, and tiles get rounded corners with a
soft right-side shadow so adjacent gapless tiles still read apart, reclaiming ~14px of
board width. On: the classic lined grid, where the inter-cell gap shows a contrasting
`--cell-line` (darker in light, lighter in dark) to avoid a wavy-line optical illusion.
## Controls ## Controls
- **HoldConfirm** (`components/HoldConfirm.svelte`): the shared press-and-hold control. A - **HoldConfirm** (`components/HoldConfirm.svelte`): the shared press-and-hold control. A
short tap opens a small popover above the button; a ~0.7 s hold runs the primary action short tap opens a small popover above the button; a ~0.7 s hold runs the primary action
immediately. Reused by: immediately. Used by the **Skip** and **Hint** tabs (each confirmed by an **Ok ✅** popover).
- **MakeMove** (appears when ≥1 tile is pending; the rack collapses its used slots and - **MakeMove / Reset** (Stage 17): when ≥1 tile is pending the rack collapses its used slots
shifts left to free room): a **🏁** button whose popover offers **Make move ✅** / and shifts left, a direct **** button beside the rack commits the move (no popover), and
**Reset ❌**. the 🔀 Shuffle tab is replaced by a **↩️ Reset** tab.
- **Game tab bar**: 🔄 Draw (disabled when the bag is empty), 🥺 Skip, 🛟 Hint (with a - **Game tab bar**: 🔄 Draw (disabled when the bag is empty), 🥺 Skip, 🛟 Hint (with a
remaining-count badge) — each confirmed by an **Ok ✅** popover; 🔀 Shuffle has no remaining-count badge, disabled at zero); 🔀 Shuffle (no label, no confirm), which
label and no confirm. The under-board slot shows the **Scores: N** preview. **animates** — tiles hop along a low parabola to their new slots (duration scaled by the
distance) with a short haptic shake. The under-board slot shows the **Scores: N** preview.
## Announcement banner (`components/AdBanner.svelte`, `lib/banner.ts`) ## Announcement banner (`components/AdBanner.svelte`, `lib/banner.ts`)