# 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 mobile-app feel: the screen is a full-height flex column where the **nav bar grows** to absorb spare vertical space (its buttons stay top-aligned) and everything else — the announcement strip, the content, and the optional bottom tab bar — **pins to the bottom**, the strip directly above the content. Tall content scrolls within the content region. 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) via `transform: scale()` on an inner layer inside a **fixed-size viewport** (the page never reflows; the viewport scrolls when zoomed), with a smooth transition. Cell/tile **text lives in a counter-scaled layer** (`scale(1/z)`) sized in `cqw`, so labels stay a constant size (relatively smaller at higher zoom). On touch, attempting to place a tile auto-zooms in centred on the target; double-tap and pinch toggle. - **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 3–4-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).