Speak this phrase into your other device (good for 10 minutes, one use):
{net.transferCode.code}
(net.transferCode = null)}>dismiss
{/if}
{#if local.setup}
{#if !local.active && net.missedMoves > 0}
You missed {net.missedMoves} move{net.missedMoves === 1 ? "" : "s"}.
net.requestCatchUp()}>▶ Watch what happened
net.markSeen()}>skip
{/if}
{#if view.phase === "finished"}
🏆 {view.winner} wins!
{:else if youMustRespond}
{#if view.stack?.defenderId === view.you}
Under attack — respond by your hand.
{:else}
Your spell is countered — respond by your hand.
{/if}
{:else if view.stack}
Waiting on {view.stack.waitingOn}…
{:else if view.outOfTurnWindow?.playerId === view.you}
Your interruption — cast now, or waste it
{:else if isYourTurn}
Your turn — round {view.turn.round}.
{view.turn.movementAllowance - view.turn.movementUsed} moves left{view.turn.attackUsed ? " · attack spent" : ""}
{:else}
{view.activePlayerId} is taking their turn…
{/if}
{#each idleCreatures as c (c.id)}
{@const moves = c.movesPerTurn - c.movementUsed}
🜲 {c.controllerId === view.you ? "Your" : "The"} {cardDef(c.kind).name} awaits orders —
{#if moves > 0}{moves} move{moves === 1 ? "" : "s"}{/if}{#if moves > 0 && !c.attackUsed && !c.justCreated} · {/if}{#if !c.attackUsed && !c.justCreated}attack ready{/if}.
Tap its token to command it.
{/each}
{#if view.yourAmbushes.length > 0}
{#each view.yourAmbushes as a (a.id)}
🗡 {cardDef(a.spell.cardId).name} waits —
{a.trigger.kind === "los" ? "when seen" : a.trigger.kind === "near" ? "when approached" : "when treasure is grabbed"}
{#if isYourTurn}
dispatch({ type: "cancelAmbush", ambushId: a.id })}>disarm
{/if}
{/each}
{/if}
life-points
{#each view.players as p (p.id)}
{p.id}{p.id === view.you ? " (you)" : ""}
{p.life}
{p.handCount} cards{#if p.lostTurns > 0} · dazed {p.lostTurns}{/if}{#if p.carriedTreasureId} · 💰{/if}
{@const spellsOn = view.sustained.filter((e) => e.targetId === p.id)}
{#if p.displayed.length > 0 || spellsOn.length > 0}
{#each p.displayed as c (c.instanceId)}
(peekCard = peekCard?.instanceId === c.instanceId ? null : c)}>
{cardDef(c.cardId).name}{#if view.wandCharges[c.instanceId] != null} · {"●".repeat(view.wandCharges[c.instanceId]!)}{/if}
{/each}
{#each spellsOn as e (e.id)}
{
peekCard = { instanceId: `peek-${e.id}`, cardId: e.cardId };
peekCreatureId = null;
}}>
✦ {cardDef(e.cardId).name} · {e.remainingTurns}
{/each}
{/if}
{/each}
draw pile {view.deckCount} · discards {view.discardCount}
{#each (local.active ? local.log : net.log).slice(-60) as line, i (i)}
{line}
{/each}
{#if ambushVia}
{cardDef(ambushVia.cardId).name} — set an ambush
{#if !ambushTrigger}
springs when an opponent…
(ambushTrigger = "los")}>enters my sight
(ambushTrigger = "near")}>comes beside me
(ambushTrigger = "treasure")}>grabs a treasure
{:else if !ambushSpell}
— now tap the attack card to commit
{:else}
{cardDef(ambushSpell.cardId).name}{attachedNumber ? ` with a ${numberTotal}` : " (tap a number to power it)"}
Arm the ambush
{/if}
cancel
{/if}
{#if youMustRespond || selectedDef || selectedCreature || youMustDiscard || discardMode || discardSelection.size > 0}
{#if selectedCreature && !selectedDef}
{@const sc = view.creatures.find((c) => c.id === selectedCreature)}
{#if sc}
Commanding {cardDef(sc.kind).name} — {creatureStats(sc)}.
Tap a square beside it to march, a target in its square to attack.
{ selectedCreature = null; peekCard = null; peekCreatureId = null; }}>done
{/if}
{/if}
{#if youMustRespond && view.stack}
{#if view.stack.defenderId === view.you}
{view.stack.attackerId} attacks with
{view.stack.attackCard ? cardDef(view.stack.attackCard.cardId).name : "a punch"} —
tap a counteraction card, or
{:else}
{view.stack.waitingOn === view.you ? "They counter your spell — counter back, or" : ""}
{/if}
let it resolve
{/if}
{#if youMustDiscard}
Hand over the limit — mark cards and discard.
{:else if discardMode && discardSelection.size === 0}
Mark the cards to throw away, then confirm.
{/if}
{#if discardSelection.size > 0}
Discard {discardSelection.size} marked
{/if}
{#if discardMode || (discardSelection.size > 0 && !youMustDiscard)}
never mind
{/if}
{#if selectedDef}
{selectedDef.name}
{#if edgeSelectMode}— click a wall line {/if}
{#if selectedDef.cardType === "attack" && !edgeSelectMode && !cellSelectMode}
— click a target{attachedNumber ? ` (powered by a ${numberTotal})` : " (tap a number card to power it)"}
{/if}
{#if attachedMods.length > 0}
[+ {attachedMods.map((m) => cardDef(m.cardId).name).join(", ")}]
{/if}
{#if selectedCard?.cardId === "boobytrap"}
— place 4 tokens ({trapCells.length}/4; the first is real)
{/if}
{#if selectedCard && TWO_CELL_CARDS.has(selectedCard.cardId)}
{tradeFrom ? "— now the second square" : "— click the first square"}
{/if}
{#if selectedCard?.cardId === "rotate-sector"}
clockwise
— click the sector
{/if}
{#if selectedCard?.cardId === "relocate-sector"}
{pendingSectorFrom ? "— now the destination area" : "— click the sector to move"}
{/if}
{#if selectedCard && NAMED_CARDS.has(selectedCard.cardId)}
name
{#each nameSuggestions as n (n)} {/each}
{#if selectedCard.cardId === "deja-vu"}
{
const id = nameToCardId(nameInput);
if (id && selectedCard) {
dispatch({ type: "cast", instanceId: selectedCard.instanceId, params: { cardId: id } });
clearSelection();
}
}}>Retrieve
{:else}
— then click the target
{/if}
{/if}
{#if selectedCard?.cardId === "waterbolt"}
damage
(knockback {numberTotal - wbDamage})
{/if}
{#if selectedCard?.cardId === "power-run"}
life to trade
Run!
{/if}
{#if selectedCard && CONFIRM_CAST.has(selectedCard.cardId)}
Cast{attachedNumber ? ` with the ${numberTotal}` : ""}
{/if}
{#if selectedCard && isMovableObject(selectedCard.cardId) && isYourTurn}
{
if (selectedCard) dispatch({ type: "dropObject", instanceId: selectedCard.instanceId });
clearSelection();
}}>Drop it here
{/if}
{#if selectedCard && isNumberCard(selectedCard.cardId)}
Play for +{cardDef(selectedCard.cardId).value} movement{view.turn.numberPlayedForMovement ? " (uses your Add)" : ""}
{/if}
cancel
{/if}
{/if}
{#if isYourTurn && onWarpToken}
dispatch({ type: "warpStep" })}>Step through the warp
{/if}
{#if isYourTurn}
Pick up treasure
Drop treasure
{#each objectsHere as obj (obj.instanceId)}
dispatch({ type: "pickUpObject", instanceId: obj.instanceId })}>
Pick up {cardDef(obj.cardId).name}
{/each}
Discard cards…
draw
0
1
2
End turn
{/if}
{#if selectedCard && !inspectorHidden}
(inspectorHidden = true)} aria-label="hide enlarged card">×
{/if}
{#if view.phase === "finished" && view.revealedHands}
The hands, face-up
{#each view.players as p (p.id)}
{p.id === view.winner ? "🏆 " : ""}{p.id}
{#if !p.alive}as they fell {/if}
{#each view.revealedHands[p.id] ?? [] as card (card.instanceId)}
(peekCard = card)} />
{/each}
{#if (view.revealedHands[p.id] ?? []).length === 0}
empty-handed
{/if}
{/each}
{/if}
{#each view.phase === "finished" ? [] : view.yourHand as card (card.instanceId)}
m.instanceId === card.instanceId)}
marked={discardSelection.has(card.instanceId)}
displayed={view.players.find((p) => p.id === view.you)?.displayed.some((c) => c.instanceId === card.instanceId) ?? false}
charges={view.wandCharges[card.instanceId] ?? null}
onclick={() => selectCard(card)}
/>
{/each}
{/if}