Fear wears its bubble: a breathing dashed diamond at three spaces

The dread was invisible, so a wizard legally circling at four squares
read as a rules failure (QD3S: no wizard ever actually breached the
bubble — only the monster, fixed at rev 32). Every feared player now
radiates a manhattan-3 diamond, dashed violet, breathing slowly; what
the engine refuses, the board now shows.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0138A8CjeQRpvzKxuMfz1Bqc
This commit is contained in:
Eric Wagoner
2026-08-19 21:29:31 -04:00
co-authored by Claude Fable 5
parent 0e9d482495
commit 644d651ae0
+24 -1
View File
@@ -633,6 +633,17 @@
{/if}
{/each}
{/if}
<!-- FEAR's bubble: no willing step crosses this line toward its center -->
{#each view.players.filter((p) => p.alive && view.sustained.some((e) => e.cardId === "fear" && e.targetId === p.id)) as fp (fp.id)}
{@const fx = fp.position.x * CELL + CELL / 2}
{@const fy = fp.position.y * CELL + CELL / 2}
{@const r = 3.5 * CELL}
<path
d={`M ${fx} ${fy - r} L ${fx + r} ${fy} L ${fx} ${fy + r} L ${fx - r} ${fy} Z`}
class="fear-aura"
/>
{/each}
<!-- the sight line an attack traveled, leg by leg through any warp mouth -->
{#if sightTrace}
<SightTraceOverlay from={sightTrace.from} to={sightTrace.to} trace={sightTrace.trace} />
@@ -764,6 +775,18 @@
.ghost-slot:hover { fill: rgba(122, 162, 122, 0.22); }
.fx-layer { pointer-events: none; }
.fear-aura {
fill: rgba(90, 44, 110, 0.05);
stroke: #7a4a8a;
stroke-width: 2;
stroke-dasharray: 8 6;
pointer-events: none;
animation: fear-breathe 2.4s ease-in-out infinite;
}
@keyframes fear-breathe {
0%, 100% { opacity: 0.65; }
50% { opacity: 0.3; }
}
.mover { transition: transform 260ms cubic-bezier(0.25, 0.8, 0.35, 1); }
.mover.snap { transition: none; }
@@ -789,7 +812,7 @@
50% { opacity: 0.35; }
}
@media (prefers-reduced-motion: reduce) {
.marked-cell, .marked-sector, .ghost-slot, .warp-dest { animation: none; }
.marked-cell, .marked-sector, .ghost-slot, .warp-dest, .fear-aura { animation: none; }
.fx-layer { display: none; }
:global(.token-art.ghosted) { animation: none; }
.mover { transition: none; }