The board's furniture and the reel's fists, painted as cels
The last of the inked look. Walls carry stone joints and highlights, doors their grain, hinges, and a brass lock plate whose keyhole turns to a cross when jammed; battle scars fracture and branch with the damage; illusion walls drift as tapered wisps with breathing glints; the wall of fire burns in flat three-tone flames on a stepped flicker; warp mouths and destinations are painted curls. Through a wizard's eyes the punch is a three-tone hand with an ink contour and a hand-cut POW, the same on every platform where the emoji glyph was not, and the incoming fist no longer reverses late in its travel. The inked stand-ins for missing conjuration files match. Goldens re-blessed: every board frame, and the web's third ring. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
8dfd0e0c29
commit
34b621b5cb
@@ -6,6 +6,7 @@
|
||||
import type { BoardFx } from "./fx";
|
||||
import { colorIndexOf as sharedColorIndex, wizardColor } from "./colors";
|
||||
import { CREATURE_ART, objectArt, TERRAIN_ART, tokenArt } from "./art";
|
||||
import { edgeScar, edgeWisps, webThreads, warpCurls } from "./boardArt";
|
||||
import EdgeGlyph, { type LockState } from "./EdgeGlyph.svelte";
|
||||
import FirewallEdge from "./FirewallEdge.svelte";
|
||||
import IllusionShimmer from "./IllusionShimmer.svelte";
|
||||
@@ -464,11 +465,13 @@
|
||||
{@const wy = Number(key.split(":")[1]?.split(",")[1])}
|
||||
{@const frac = Math.min(1, dmg / 20)}
|
||||
{#if kind === "V"}
|
||||
<line x1={(wx + 1) * CELL} y1={wy * CELL + 3} x2={(wx + 1) * CELL} y2={(wy + 1) * CELL - 3}
|
||||
class="crack" style:opacity={0.35 + frac * 0.65}><title>battle-scarred — {dmg} damage taken</title></line>
|
||||
<path d={edgeScar((wx+1)*CELL, wy*CELL+3, (wx+1)*CELL, (wy+1)*CELL-3, frac)} class="crack-shadow" style:opacity={0.35 + frac * 0.65} />
|
||||
<path d={edgeScar((wx+1)*CELL, wy*CELL+3, (wx+1)*CELL, (wy+1)*CELL-3, frac)}
|
||||
class="crack" style:opacity={0.35 + frac * 0.65}><title>battle-scarred — {dmg} damage taken</title></path>
|
||||
{:else}
|
||||
<line x1={wx * CELL + 3} y1={(wy + 1) * CELL} x2={(wx + 1) * CELL - 3} y2={(wy + 1) * CELL}
|
||||
class="crack" style:opacity={0.35 + frac * 0.65}><title>battle-scarred — {dmg} damage taken</title></line>
|
||||
<path d={edgeScar(wx*CELL+3, (wy+1)*CELL, (wx+1)*CELL-3, (wy+1)*CELL, frac)} class="crack-shadow" style:opacity={0.35 + frac * 0.65} />
|
||||
<path d={edgeScar(wx*CELL+3, (wy+1)*CELL, (wx+1)*CELL-3, (wy+1)*CELL, frac)}
|
||||
class="crack" style:opacity={0.35 + frac * 0.65}><title>battle-scarred — {dmg} damage taken</title></path>
|
||||
{/if}
|
||||
{/each}
|
||||
|
||||
@@ -478,9 +481,9 @@
|
||||
{@const ix = Number(key.split(":")[1]?.split(",")[0])}
|
||||
{@const iy = Number(key.split(":")[1]?.split(",")[1])}
|
||||
{#if kind === "V"}
|
||||
<line x1={(ix + 1) * CELL} y1={iy * CELL} x2={(ix + 1) * CELL} y2={(iy + 1) * CELL} class="illusion"><title>an illusion — your eyes see through it</title></line>
|
||||
<path d={edgeWisps((ix+1)*CELL, iy*CELL, (ix+1)*CELL, (iy+1)*CELL)} class="illusion"><title>an illusion — your eyes see through it</title></path>
|
||||
{:else}
|
||||
<line x1={ix * CELL} y1={(iy + 1) * CELL} x2={(ix + 1) * CELL} y2={(iy + 1) * CELL} class="illusion"><title>an illusion — your eyes see through it</title></line>
|
||||
<path d={edgeWisps(ix*CELL, (iy+1)*CELL, (ix+1)*CELL, (iy+1)*CELL)} class="illusion"><title>an illusion — your eyes see through it</title></path>
|
||||
{/if}
|
||||
{/each}
|
||||
|
||||
@@ -523,10 +526,7 @@
|
||||
</g>
|
||||
{#if standing}
|
||||
<!-- show where this opening leads -->
|
||||
<circle
|
||||
cx={w.to.cell.x * CELL + CELL / 2} cy={w.to.cell.y * CELL + CELL / 2}
|
||||
r={CELL * 0.42} class="warp-dest"
|
||||
/>
|
||||
<path d={warpCurls(w.to.cell.x*CELL+CELL/2, w.to.cell.y*CELL+CELL/2, CELL*.42)} class="warp-dest" />
|
||||
{/if}
|
||||
{/each}
|
||||
|
||||
@@ -592,9 +592,7 @@
|
||||
/>
|
||||
{#if hasSpell(p.id, "sticky-web")}
|
||||
<g class="webbing">
|
||||
<line x1={-half} y1={-half * 0.4} x2={half} y2={half * 0.5} />
|
||||
<line x1={-half * 0.6} y1={half} x2={half * 0.7} y2={-half} />
|
||||
<line x1={-half} y1={half * 0.7} x2={half} y2={-half * 0.2} />
|
||||
<path d={webThreads(half)} />
|
||||
</g>
|
||||
{/if}
|
||||
{:else}
|
||||
@@ -796,7 +794,7 @@
|
||||
}
|
||||
.creature-ring.selected { stroke-width: 4; stroke-dasharray: 5 3; }
|
||||
.ground-object { fill: #a6812e; stroke: #4a3a10; stroke-width: 1; }
|
||||
.illusion { stroke: #7a6f9a; stroke-width: 4; stroke-dasharray: 6 5; opacity: 0.7; }
|
||||
.illusion { fill: #7a6f9a; stroke: none; opacity: 0.7; pointer-events: none; }
|
||||
.creature { cursor: pointer; }
|
||||
.creature-body { fill: #3b3428; stroke-width: 2.5; }
|
||||
.creature-body.selected { fill: #6b5a34; }
|
||||
@@ -914,7 +912,7 @@
|
||||
fill: rgba(90, 44, 110, 0.05);
|
||||
stroke: #7a4a8a;
|
||||
stroke-width: 2;
|
||||
stroke-dasharray: 8 6;
|
||||
stroke-dasharray: 15 5 3 5;
|
||||
pointer-events: none;
|
||||
animation: fear-breathe 2.4s ease-in-out infinite;
|
||||
}
|
||||
@@ -929,16 +927,19 @@
|
||||
:global(.token-art.ghosted) { opacity: 0.4; animation: ghost-breathe 2.6s ease-in-out infinite; }
|
||||
@keyframes -global-ghost-breathe { 50% { opacity: 0.22; } }
|
||||
:global(.token-art.stone-gazed) { filter: grayscale(0.9) brightness(0.8); }
|
||||
.webbing line {
|
||||
stroke: rgba(220, 218, 205, 0.85);
|
||||
stroke-width: 1.6;
|
||||
.webbing { pointer-events: none; }
|
||||
.webbing path {
|
||||
fill: none;
|
||||
stroke: rgba(240, 231, 209, 0.9);
|
||||
stroke-width: 1.25;
|
||||
stroke-linecap: round;
|
||||
pointer-events: none;
|
||||
}
|
||||
.warp-dest {
|
||||
fill: none;
|
||||
stroke: #2e7d32;
|
||||
stroke-width: 2.5;
|
||||
stroke-dasharray: 7 4;
|
||||
stroke-linecap: round;
|
||||
pointer-events: none;
|
||||
animation: warp-pulse 1.6s ease-in-out infinite;
|
||||
}
|
||||
@@ -947,7 +948,8 @@
|
||||
50% { opacity: 0.35; }
|
||||
}
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.marked-cell, .marked-sector, .ghost-slot, .warp-dest, .fear-aura { animation: none; }
|
||||
.marked-cell, .marked-sector, .ghost-slot, .warp-dest, .fear-aura,
|
||||
.spot-cell, .sight-corner, .sight-pierced { animation: none; }
|
||||
.fx-layer { display: none; }
|
||||
:global(.token-art.ghosted) { animation: none; }
|
||||
.mover { transition: none; }
|
||||
@@ -963,10 +965,12 @@
|
||||
filter: drop-shadow(0.5px 1px 1px rgba(0, 0, 0, 0.55));
|
||||
pointer-events: none;
|
||||
}
|
||||
.crack-shadow { fill: none; stroke: #6e5a3d; stroke-width: 2.8; stroke-linejoin: bevel; stroke-linecap: round; pointer-events: none; }
|
||||
.crack {
|
||||
fill: none;
|
||||
stroke: #efe8d4;
|
||||
stroke-width: 2;
|
||||
stroke-dasharray: 3 5;
|
||||
stroke-width: 1.4;
|
||||
stroke-linejoin: bevel;
|
||||
stroke-linecap: round;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user