From 57bd0364171efdba1f9253b65afc405c6a37d36c Mon Sep 17 00:00:00 2001 From: Eric Wagoner Date: Sun, 16 Aug 2026 10:17:57 -0400 Subject: [PATCH] The first square of a two-square spell now shows on the board MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Dimensional Warp, Trader, Redirection, and Relocate Sector all take two clicks, but only the hint bar acknowledged the first — the board itself sat unchanged until the second click landed. The first chosen square now wears a pulsing amber dashed ring (same rhythm as the warp destination ring, still under prefers-reduced-motion) until the spell completes or is cancelled. Co-Authored-By: Claude Fable 5 --- packages/web/src/App.svelte | 1 + packages/web/src/Board.svelte | 30 +++++++++++++++++++++++++++++- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/packages/web/src/App.svelte b/packages/web/src/App.svelte index 2b5ee88..03f12be 100644 --- a/packages/web/src/App.svelte +++ b/packages/web/src/App.svelte @@ -760,6 +760,7 @@ onPlayerClick={clickPlayer} onCreatureClick={clickCreature} onWarpClick={clickWarp} + markedCell={tradeFrom ?? pendingSectorFrom} /> diff --git a/packages/web/src/Board.svelte b/packages/web/src/Board.svelte index 6f1b319..5358349 100644 --- a/packages/web/src/Board.svelte +++ b/packages/web/src/Board.svelte @@ -14,6 +14,7 @@ onPlayerClick, onCreatureClick, onWarpClick, + markedCell = null, }: { view: GameView; edgeSelectMode?: boolean; @@ -23,6 +24,8 @@ onPlayerClick?: (playerId: string) => void; onCreatureClick?: (creatureId: string) => void; onWarpClick?: (cell: { x: number; y: number }, side: Side) => void; + /** First square of a two-square spell: marked so the click reads as taken. */ + markedCell?: { x: number; y: number } | null; } = $props(); const PLAYER_COLORS = ["#1a9c46", "#d3352b", "#c9308f", "#3a3ac0", "#2ab0c9", "#c9a72a"]; @@ -326,6 +329,15 @@ {/if} {/each} + + {#if markedCell} + + {/if} + {#each [...wizardsByCell.entries()] as [key, group] (key)} {#each group as p, i (p.id)} @@ -507,6 +519,14 @@ fill: #6a5c44; pointer-events: none; } + .marked-cell { + fill: rgba(211, 133, 43, 0.18); + stroke: #d3852b; + stroke-width: 2.5; + stroke-dasharray: 7 4; + pointer-events: none; + animation: warp-pulse 1.6s ease-in-out infinite; + } .warp-dest { fill: none; stroke: #2e7d32; @@ -520,7 +540,15 @@ 50% { opacity: 0.35; } } @media (prefers-reduced-motion: reduce) { - .warp-dest { animation: none; } + .marked-cell { + fill: rgba(211, 133, 43, 0.18); + stroke: #d3852b; + stroke-width: 2.5; + stroke-dasharray: 7 4; + pointer-events: none; + animation: warp-pulse 1.6s ease-in-out infinite; + } + .warp-dest { animation: none; } } .wizard { cursor: pointer; } .wizard-label {