On a phone, a reveal scrolls to what happened

The result strip comes into view with the last two ledger rows above it,
so the revealed gestures and their outcome are the first thing seen.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Eric Wagoner
2026-09-22 16:02:26 -04:00
co-authored by Claude Fable 5.1
parent 3716f49bbb
commit 0036eaf625
3 changed files with 19 additions and 2 deletions
+9 -1
View File
@@ -11,7 +11,7 @@
</script> </script>
{#if summary} {#if summary}
<section class="result" aria-label="What the last reveal did"> <section class="result" id="turn-result" aria-label="What the last reveal did">
<h2>{summary.phase === 'timestop' ? 'In the stopped moment' : `Turn ${summary.turn + 1}`}</h2> <h2>{summary.phase === 'timestop' ? 'In the stopped moment' : `Turn ${summary.turn + 1}`}</h2>
<dl> <dl>
{#each [YOU, FOE] as const as who (who)} {#each [YOU, FOE] as const as who (who)}
@@ -50,6 +50,7 @@
<style> <style>
.result { .result {
scroll-margin-top: 0.5rem;
margin: 0.5rem 0 0; margin: 0.5rem 0 0;
padding: 0.4rem 0.8rem; padding: 0.4rem 0.8rem;
background: var(--slate); background: var(--slate);
@@ -57,6 +58,13 @@
font-size: 0.9rem; font-size: 0.9rem;
} }
/* On a phone, leave the last two ledger rows in view above the result. */
@media (max-width: 860px) {
.result {
scroll-margin-top: 9.5rem;
}
}
h2 { h2 {
font-size: 0.8rem; font-size: 0.8rem;
color: var(--bone-faint); color: var(--bone-faint);
+9
View File
@@ -1,5 +1,6 @@
// Reactive wrapper around the engine for a duel of one person against the bot. // Reactive wrapper around the engine for a duel of one person against the bot.
import { tick } from 'svelte';
import { chooseBotTurn } from './bot'; import { chooseBotTurn } from './bot';
import { import {
completableIn, completableIn,
@@ -618,6 +619,14 @@ export class Duel {
if (pinned && this.planned.some((p) => p.hand === h && p.completion.spell.id === pinned)) this.pins[h] = null; if (pinned && this.planned.some((p) => p.hand === h && p.completion.spell.id === pinned)) this.pins[h] = null;
} }
this.resetDrafts(); this.resetDrafts();
// On a phone the hands sit far below the ledger; bring the result into view.
if (this.compact) {
void tick().then(() => {
const target = document.getElementById(this.state.over ? 'verdict' : 'turn-result');
const reduce = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
target?.scrollIntoView({ behavior: reduce ? 'auto' : 'smooth', block: 'start' });
});
}
} }
private resetDrafts(): void { private resetDrafts(): void {
+1 -1
View File
@@ -97,7 +97,7 @@
<TurnSummary {duel} /> <TurnSummary {duel} />
{#if outcome} {#if outcome}
<div class="verdict" class:won> <div class="verdict" id="verdict" class:won>
<h2>{won ? 'You win.' : outcome.winner === null ? 'A draw.' : 'You lose.'}</h2> <h2>{won ? 'You win.' : outcome.winner === null ? 'A draw.' : 'You lose.'}</h2>
<p>{outcome.reason}</p> <p>{outcome.reason}</p>
<button type="button" class="reveal" onclick={() => duel.newGame()}>Duel again</button> <button type="button" class="reveal" onclick={() => duel.newGame()}>Duel again</button>