Files
wizwar6e/packages/web/src/EdgeGlyph.svelte
T
Eric WagonerandClaude Fable 5 6adcbe23b5 Credibility pass: the accretion sanded smooth
Blind reviews over d2b40ec..HEAD (engine / web / server+deploy). Orphaned
doc comments rejoined their functions; the swap-meet tradables collapsed
from four pasted deriveds to one (killing the "the's treasure" label);
FEAR's aura and banner now share the engine's own dreadDistance; the
long-press peek got one home; rulebook.ts stopped wearing JSON quotes;
process-named tests and war-story comments now state the constraints they
pin; the protocol doc caught up to its handlers; verify-ledgers.sh can
actually count failures; the runbook learned about the determinism gate
and the nightly backups. No behavior changes — 255 tests and all 48
production ledgers replay identically.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-21 10:58:08 -04:00

72 lines
2.5 KiB
Svelte

<script lang="ts" module>
/** The color states a door can wear (a wall wears none). */
export type LockState = "removed" | "jammed" | "held" | "ajar";
</script>
<script lang="ts">
import { holdToPeek } from "./peek";
// A wall or door on an edge, exactly as the board draws it. Wall-segment
// effects (locks picked, jammed, removed; doors held) are color states of
// this one glyph — the game has never used tokens for them.
let { x, y, kind, state, lock = null, title = null, damage = 0, onpeek }: {
x: number; y: number; kind: "V" | "H";
state: "wall" | "door";
lock?: LockState | null;
title?: string | null;
/** Battle damage taken so far (walls fall at 20, doors at 15). */
damage?: number;
/** Press-and-hold (touch has no hover): report the tooltip's text. */
onpeek?: (tip: string) => void;
} = $props();
const CELL = 48;
const WALL = 7;
const cls = $derived(state === "door" ? `door${lock ? ` ${lock}` : ""}` : "wall");
// Every segment tells its points — the game's own word: "A wall takes 20
// points of damage to destroy; a door takes 15."
const needed = $derived(state === "door" ? 15 : 20);
const hp = $derived(damage > 0
? `${Math.max(0, needed - damage)} of ${needed} points left`
: `${needed} points to destroy`);
const tip = $derived(`${title ?? (state === "door" ? "a locked door" : "a wall")}${hp}`);
const { press, release } = holdToPeek(() => onpeek?.(tip));
</script>
{#if kind === "V"}
<rect
x={(x + 1) * CELL - WALL / 2} y={y * CELL - WALL / 2}
width={WALL} height={CELL + WALL}
class={cls}
role="img" onpointerdown={press} onpointerup={release} onpointerleave={release}
><title>{tip}</title></rect>
{:else}
<rect
x={x * CELL - WALL / 2} y={(y + 1) * CELL - WALL / 2}
width={CELL + WALL} height={WALL}
class={cls}
role="img" onpointerdown={press} onpointerup={release} onpointerleave={release}
><title>{tip}</title></rect>
{/if}
<style>
.wall {
fill: #f2ecd8;
stroke: #2b2218;
stroke-width: 1.6;
}
.door {
fill: #8b5a2b;
stroke: #2b2218;
stroke-width: 1.4;
rx: 2;
}
/* Lock removed: pale, an open doorway forever. */
.door.removed { fill: #d4bd8e; }
/* Lock jammed: near-black, sealed. */
.door.jammed { fill: #3a2a18; stroke: #14100b; }
/* Picked or keyed open until end of turn. */
.door.ajar { fill: #d4bd8e; stroke-dasharray: 5 3; }
/* Held open: a wizard stands propping it. */
.door.held { fill: #d4bd8e; stroke: #2e7d32; }
</style>