From 359758a01a5ece4baa24204a9966771072097d35 Mon Sep 17 00:00:00 2001 From: Ilia Denisov Date: Fri, 12 Jun 2026 12:31:39 +0200 Subject: [PATCH] feat(ui): tint last-word letters for the recent highlight; lift dark bonus contrast MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Dark theme: the 2x/3x bonus-square pairs were too close to tell apart. Soften the 2x squares (sky blue #4a779b, rose #a8636b) and deepen the 3x squares (#2c527a, #9c3f34) so each pair reads as two distinct steps. Light theme is unchanged. Last-word highlight (both themes): stop tinting the tile background — the tile keeps its normal fill, and instead the placed letters (not the point values) are drawn in the recent-move colour. The opponent-just-moved flash now pulses the letter between its normal colour and the recent colour, with no background animation and no white peak. Reconcile the explicit [data-theme=dark] --tile-recent with the OS-dark value so the highlight reads the same however dark is selected, and darken --tile-recent a step in every theme. Update docs/UI_DESIGN.md. --- docs/UI_DESIGN.md | 8 +++++--- ui/src/app.css | 24 +++++++++++++----------- ui/src/game/Board.svelte | 27 ++++++++++++++------------- 3 files changed, 32 insertions(+), 27 deletions(-) diff --git a/docs/UI_DESIGN.md b/docs/UI_DESIGN.md index 435c525..a4ddd69 100644 --- a/docs/UI_DESIGN.md +++ b/docs/UI_DESIGN.md @@ -123,9 +123,11 @@ Login uses `Screen`. overlays the empty area below, so the layout doesn't resize/jank; other modals stay keyboard-aware (they size to the area above the keyboard). - **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. + last completed word keeps the normal tile background; instead its letters — not the point + values — are drawn in the recent-move colour, in both themes. It is static while it is the + opponent's turn (our word), and a 1 s flash (the letter pulses between its normal colour + and the recent-move colour) 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**. diff --git a/ui/src/app.css b/ui/src/app.css index de3930f..f92322f 100644 --- a/ui/src/app.css +++ b/ui/src/app.css @@ -29,7 +29,7 @@ --tile-edge: #d8c190; --tile-text: #2a2113; --tile-pending: #f2cf73; - --tile-recent: #c8a85c; + --tile-recent: #a8884a; --prem-tw: #e06a5b; /* triple word */ --prem-dw: #efa6a0; /* double word + centre */ --prem-tl: #4f8fd6; /* triple letter */ @@ -75,11 +75,11 @@ --tile-edge: #b6a473; --tile-text: #20190d; --tile-pending: #d8b75e; - --tile-recent: #7a6638; - --prem-tw: #b1493d; - --prem-dw: #8c5450; - --prem-tl: #34608f; - --prem-dl: #3b5a72; + --tile-recent: #6c5a30; + --prem-tw: #9c3f34; /* 3x word: a touch darker red */ + --prem-dw: #a8636b; /* 2x word: softer, pinker */ + --prem-tl: #2c527a; /* 3x letter: a touch darker blue */ + --prem-dl: #4a779b; /* 2x letter: softer, sky blue */ --prem-text: #e7eaf0; } } @@ -106,11 +106,13 @@ --tile-edge: #b6a473; --tile-text: #20190d; --tile-pending: #f0d98f; - --tile-recent: #4a4636; - --prem-tw: #b1493d; - --prem-dw: #8c5450; - --prem-tl: #34608f; - --prem-dl: #3b5a72; + /* Last-word highlight letter colour; matches the OS-dark value so the highlight reads the + same whether dark is chosen in Settings or via prefers-color-scheme. */ + --tile-recent: #6c5a30; + --prem-tw: #9c3f34; /* 3x word: a touch darker red */ + --prem-dw: #a8636b; /* 2x word: softer, pinker */ + --prem-tl: #2c527a; /* 3x letter: a touch darker blue */ + --prem-dl: #4a779b; /* 2x letter: softer, sky blue */ --prem-text: #e7eaf0; } diff --git a/ui/src/game/Board.svelte b/ui/src/game/Board.svelte index ffb2e89..9c33563 100644 --- a/ui/src/game/Board.svelte +++ b/ui/src/game/Board.svelte @@ -314,25 +314,26 @@ box-shadow: inset 0 0 0 2px var(--accent); background: color-mix(in srgb, var(--accent) 18%, var(--cell-bg)); } - .cell.hl { - background: var(--tile-recent); - /* The bottom edge goes darker than the highlighted fill (not lighter, as the plain - --tile-edge would), so the tile still reads as raised. */ - box-shadow: inset 0 -2px 0 rgba(0, 0, 0, 0.32); + /* Last-word highlight: the tile keeps its normal fill (same as every other placed tile); + instead the letter glyph — not the point value — is drawn in the recent-move colour, in + both themes. */ + .cell.hl .letter, + .cell.flash .letter { + color: var(--tile-recent); } - .cell.flash { - /* Two flashes to draw the eye, then settle back to normal so it does not distract. */ - animation: tileflash 1s ease-in-out 2; + .cell.flash .letter { + /* When the opponent just moved and it is now our turn, the highlighted letter pulses + twice between its normal colour and the recent-move colour to draw the eye, then + settles on the recent colour (matching .hl). The tile background never animates. */ + animation: letterflash 1s ease-in-out 2; } - @keyframes tileflash { + @keyframes letterflash { 0%, 100% { - background: var(--tile-bg); - box-shadow: inset 0 -2px 0 var(--tile-edge); + color: var(--tile-recent); } 50% { - background: var(--tile-recent); - box-shadow: inset 0 -2px 0 rgba(0, 0, 0, 0.32); + color: var(--tile-text); } } /* cqw fonts are sized against the fixed viewport, so labels stay a constant size as