Files
scrabble-game/docs/UI_DESIGN.md
T
Ilia Denisov 52a0e3160d
Tests · UI / test (push) Successful in 12s
Tests · Go / test (pull_request) Successful in 6s
Tests · Integration / integration (pull_request) Successful in 11s
Tests · UI / test (pull_request) Successful in 11s
Stage 7 polish (round 2): layout/zoom/tab-bar/hint/check fixes
- 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
2026-06-03 14:54:41 +02:00

85 lines
4.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Scrabble Game — UI design system
Visual and interaction conventions for the `ui` client. Behaviour lives in
[`FUNCTIONAL.md`](FUNCTIONAL.md); cross-service architecture (including the global
points this doc references) lives in [`ARCHITECTURE.md`](ARCHITECTURE.md). The client
is **pure HTML5/CSS + Unicode** — no image/font/SVG assets; icons are CSS shapes or
emoji glyphs. Tokens are CSS custom properties (`ui/src/app.css`), light/dark via
`prefers-color-scheme` or an explicit Settings choice, and **Telegram-themeParams-ready**
(the tokens can be overridden at runtime).
## Layout shell (`components/Screen.svelte`)
A full-height flex column: the nav bar, the announcement strip, the content, and an
optional bottom tab bar (the tab bar always sits at the screen bottom). On most screens
the nav is minimal and the **content fills** between nav and tab bar. **Only in the
game** (`growNav`) does the nav bar grow to absorb spare height (buttons top-aligned),
pinning the board and controls to the **bottom** for thumb reach. Every screen except
Login uses `Screen`.
## Navigation
- **Back**: a thin, compact `<` drawn from two rotated CSS borders (`Header.svelte`
`.chev`) — lighter than a glyph.
- **Hamburger**: a CSS three-bar (`Menu.svelte`), deliberately larger; opens a dropdown
of items (lobby: Profile/Settings/About; game: History/Chat/Check word/Drop game).
- **Tab bar** (`TabBar.svelte`): square, borderless, evenly distributed buttons — a large
emoji icon over a tiny truncated label. A press highlights a rounded **square** behind
the icon (slightly larger than it) until release; spacing keeps adjacent labels from
touching. No text selection on nav / tab-bar / buttons (`user-select: none`).
## Tiles & board
- **Tiles**: the letter sits in the **top-left** corner (offset a touch more than the
value), the point value bottom-right; blanks show no value.
- **Board zoom** (`Board.svelte`): a two-state zoom (full 15×15 ↔ ~9 cells) by **growing
the board's width** inside a fixed-size viewport (a real layout change → native scroll
that works consistently across browsers; no `transform`, which broke scrolling
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).
**Double-tap** toggles zoom and, on touch, placing a tile auto-zooms in centred on the
target; the custom pinch and swipe-to-open-history gestures were dropped because they
fight native scroll — history opens from the menu.
- **Highlights**: pending tiles use a slightly darker tile background (no outline). The
last completed word gets a dark tile background — static while it is the opponent's
turn (our word), and a 1 s flash when it is our turn (their word). While placing, only
the pending tiles are highlighted.
- **Bonus-square labels** — a Settings choice (`boardlabels.ts`): `beginner` shows a
split `3×` / `word` (localized слово/буква), `classic` a single `3W` / `3С`, `none`
nothing. Default **beginner**.
- **Grid lines**: the inter-cell gap shows a contrasting `--cell-line` (darker in light,
lighter in dark) to avoid a wavy-line optical illusion.
## Controls
- **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
immediately. Reused by:
- **MakeMove** (appears when ≥1 tile is pending; the rack collapses its used slots and
shifts left to free room): a **🏁** button whose popover offers **Make move ✅** /
**Reset ❌**.
- **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
label and no confirm. The under-board slot shows the **Scores: N** preview.
## Announcement banner (`components/AdBanner.svelte`, `lib/banner.ts`)
A one-line inset strip under the nav bar. Content is minimal markdown (text + links,
escaped + linkified). A parameterised **rotator** drives messages: a fitting message
holds `holdMs` (default 60 s) then cross-fades to the next; a message wider than the strip
pauses (`edgePauseMs`), scrolls to its right edge at `scrollPxPerSec`, pauses, and repeats
until the cycle exceeds `holdMs`. Today a **mock** provider rotates a long and a short
message; the source becomes a server-driven channel later (see ARCHITECTURE).
## Result / status iconography (`lib/result.ts`)
Lobby rows show two lines (opponents, then result + score) with a large place-based emoji
on the right: Victory 🏆 / Defeat 🥈 / Draw 🏅, and for 34-player games II 🥈 / III 🥉 /
IV 🏅; active games show Your move 🟢 / Opponent's move ⏳; invitations use 💌.
## Caveat
Emoji are rendered by the platform's system emoji font, so their exact look varies across
OSes — acceptable for the MVP, and consistent with the no-asset rule (no glyphs are
downloaded).