From a95938d611c9cbce9ad1152270a050f50de67b74 Mon Sep 17 00:00:00 2001 From: tiennm99 Date: Mon, 21 Sep 2026 16:59:19 +0700 Subject: [PATCH] feat(web): make the rejection row's suggestion and report real touch targets The suggestion and report pills sat at 2px padding on 0.8rem text, under WCAG's 24px minimum, on the two taps most worth making under a running clock. They move onto their own line at a 36px floor, and the suggestion reads as primary weight since it is almost certainly the word the player meant. The fill-only behaviour and the field's uncontrolled-input invariant are unchanged. --- web/src/lib/components/WordInput.svelte | 95 ++++++++++++++++++------- 1 file changed, 71 insertions(+), 24 deletions(-) diff --git a/web/src/lib/components/WordInput.svelte b/web/src/lib/components/WordInput.svelte index f2a3938..b959d43 100644 --- a/web/src/lib/components/WordInput.svelte +++ b/web/src/lib/components/WordInput.svelte @@ -223,17 +223,26 @@ clock, with nothing to compare against. --> + {#if game.state.rejection.suggestion || game.state.rejection.reason === RejectReason.NOT_IN_DICTIONARY} + +
+ {#if game.state.rejection.suggestion} + + + {/if} + {#if game.state.rejection.reason === RejectReason.NOT_IN_DICTIONARY} + + {/if} +
+ {/if} {/if} {#if game.state.reportConfirmation} @@ -251,13 +260,13 @@ input { flex: 1; min-width: 0; - padding: 14px; + padding: var(--space-4); border: 1px solid var(--border-strong); border-radius: var(--radius-sm); background: var(--surface); /* 16px or larger stops iOS Safari zooming the page on focus, which on a phone hides half the board behind the keyboard. */ - font-size: var(--text-6); + font-size: var(--text-3); /* Whatever does not fit ends in an ellipsis rather than against the edge of the box. */ text-overflow: ellipsis; @@ -275,12 +284,21 @@ } button { - padding: 14px var(--space-5); + padding: var(--space-4) var(--space-5); border: 0; border-radius: var(--radius-sm); background: var(--accent); color: var(--accent-text); font-weight: 600; + transition: background-color 150ms ease-out; + } + + button:hover:not(:disabled) { + background: var(--accent-hover); + } + + button:active:not(:disabled) { + background: var(--accent-pressed); } button:disabled { @@ -294,34 +312,63 @@ align-items: baseline; gap: 4px var(--space-2); margin: var(--space-2) 0 0; - padding: 10px var(--space-3); + padding: var(--space-3) var(--space-3); border-radius: var(--radius-sm); background: var(--danger-soft); color: var(--danger); - font-size: var(--text-5); + font-size: var(--text-2); } .rejection strong { font-weight: 600; } - .suggestion, - .report { - padding: 2px var(--space-2); - border: 1px solid currentColor; + .fixes { + display: flex; + flex-direction: column; + gap: var(--space-2); + margin-top: var(--space-2); + } + + .fix { + min-height: 36px; + padding: var(--space-1) var(--space-3); + border: 1px solid var(--border-strong); border-radius: var(--radius-pill); - background: none; - color: inherit; - font-size: var(--text-3); + background: var(--surface); + color: var(--text); + font-size: var(--text-2); font-weight: 600; + text-align: left; + transition: background-color 150ms ease-out; + } + + .fix:hover { + background: var(--surface-alt); + } + + /* Primary weight: of the two, this is the one tap that almost certainly + finishes the turn. */ + .fix.suggestion { + border-color: transparent; + background: var(--accent); + color: var(--accent-text); + } + + .fix.suggestion:hover { + background: var(--accent-hover); + } + + .fix.suggestion:active { + background: var(--accent-pressed); } .report-confirmation { margin: var(--space-2) 0 0; - padding: 10px var(--space-3); + padding: var(--space-3) var(--space-3); border-radius: var(--radius-sm); background: var(--accent-soft); color: var(--text); - font-size: var(--text-5); + font-size: var(--text-2); }