Design pass: the client becomes Eric's table
The design system is the physical set itself, taken from the scans: card-stock cream, warm ink, and the six wizard marker colors, laid on a dark leather tabletop. Cards in your hand are now the actual cards — vertical corner rails (ATTACK / L.O.S. / ADJACENT), condensed gothic titles, brown body text on cream, number cards as big bordered numerals with per-value border styles; selecting lifts a card from the fan. The board matches the physical tiles: ink-outlined white brick walls on cracked flagstone, plank doors, eight-point home stars in each wizard's color, swirled treasure discs, warp arrows. The sidebar is paper: a turn slip, the rulebook's own hand-scrawled life-points score sheet (Caveat over ruled lines), and a typewritten chronicle that scrolls itself. The lobby is the box lid. Type: Oswald condensed display / Archivo Narrow body / Courier Prime log. Buttons are ink stamps. Board height-caps so board, actions, and the full hand share one screen; responsive stack below 900px; reduced motion respected. Verified with live screenshots at 1440x900. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
c9524a37db
commit
9501a85be4
@@ -91,17 +91,28 @@
|
||||
|
||||
<!-- homes & treasure spaces -->
|
||||
{#each view.players as p (p.id)}
|
||||
<text
|
||||
x={p.home.x * CELL + CELL / 2} y={p.home.y * CELL + CELL / 2 + 2}
|
||||
class="home" fill={playerColor(p.id)}
|
||||
>✦</text>
|
||||
{@const hx = p.home.x * CELL + CELL / 2}
|
||||
{@const hy = p.home.y * CELL + CELL / 2}
|
||||
{@const R = CELL * 0.36}
|
||||
{@const r = CELL * 0.14}
|
||||
<polygon
|
||||
points={Array.from({ length: 16 }, (_, i) => {
|
||||
const rad = (Math.PI / 8) * i - Math.PI / 2;
|
||||
const len = i % 2 === 0 ? R : r;
|
||||
return `${hx + Math.cos(rad) * len},${hy + Math.sin(rad) * len}`;
|
||||
}).join(" ")}
|
||||
class="home-star" fill={playerColor(p.id)}
|
||||
/>
|
||||
{/each}
|
||||
{#each view.treasures as t (t.id)}
|
||||
{#if t.position}
|
||||
<circle
|
||||
cx={t.position.x * CELL + CELL / 2} cy={t.position.y * CELL + CELL * 0.72}
|
||||
r={7} class="treasure" fill={playerColor(t.owner)}
|
||||
/>
|
||||
{@const tx = t.position.x * CELL + CELL / 2}
|
||||
{@const ty = t.position.y * CELL + CELL * 0.72}
|
||||
<g class="treasure-g">
|
||||
<circle cx={tx} cy={ty} r={8} class="treasure" fill={playerColor(t.owner)} />
|
||||
<circle cx={tx} cy={ty} r={4.5} class="treasure-swirl" />
|
||||
<circle cx={tx} cy={ty} r={1.6} class="treasure-core" />
|
||||
</g>
|
||||
{/if}
|
||||
{/each}
|
||||
|
||||
@@ -210,7 +221,7 @@
|
||||
onkeydown={() => {}}
|
||||
class="wizard"
|
||||
>
|
||||
<circle {cx} {cy} r={12} fill={playerColor(p.id)} stroke="#111" stroke-width="1.5" />
|
||||
<circle {cx} {cy} r={12} fill={playerColor(p.id)} stroke="#2b2218" stroke-width="2" />
|
||||
<text x={cx} y={cy + 4} class="wizard-label">{p.id[0]?.toUpperCase()}</text>
|
||||
{#if p.carriedTreasureId}
|
||||
<circle cx={cx + 9} cy={cy + 9} r={5} class="carried" />
|
||||
@@ -256,21 +267,38 @@
|
||||
<style>
|
||||
.board {
|
||||
width: 100%;
|
||||
max-width: 640px;
|
||||
background: #d8d2c4;
|
||||
border: 3px solid #4a4438;
|
||||
border-radius: 4px;
|
||||
max-width: 680px;
|
||||
background: #e3dcc7;
|
||||
border: 7px solid #2b2218;
|
||||
border-radius: 3px;
|
||||
box-shadow:
|
||||
0 0 0 2px #b7ad92,
|
||||
0 12px 34px rgba(0, 0, 0, 0.6);
|
||||
}
|
||||
.floor {
|
||||
fill: #e8e2d4;
|
||||
stroke: #b8b0a0;
|
||||
stroke-width: 1;
|
||||
fill: #e3dcc7;
|
||||
stroke: #b7ad92;
|
||||
stroke-width: 1.1;
|
||||
stroke-dasharray: 4 2.5;
|
||||
cursor: pointer;
|
||||
}
|
||||
.floor:hover { fill: #f2ecda; }
|
||||
.wall { fill: #4a4438; }
|
||||
.door { fill: #8b5a2b; }
|
||||
.firewall { fill: #e0442a; }
|
||||
.floor:hover { fill: #efe8d2; }
|
||||
.wall {
|
||||
fill: #f2ecd8;
|
||||
stroke: #2b2218;
|
||||
stroke-width: 1.6;
|
||||
}
|
||||
.door {
|
||||
fill: #8b5a2b;
|
||||
stroke: #2b2218;
|
||||
stroke-width: 1.4;
|
||||
rx: 2;
|
||||
}
|
||||
.firewall {
|
||||
fill: #d0342c;
|
||||
stroke: #7c1a14;
|
||||
stroke-width: 1.2;
|
||||
}
|
||||
.stone { fill: #6a6458; stroke: #3a362e; stroke-width: 2; }
|
||||
.bush { fill: #2e7d32; stroke: #1b4d1e; stroke-width: 2; }
|
||||
.rose { fill: #2e7d32; stroke: #b0245a; stroke-width: 3; }
|
||||
@@ -289,12 +317,15 @@
|
||||
.creature-body { fill: #3b3428; stroke-width: 2.5; }
|
||||
.creature-body.selected { fill: #6b5a34; }
|
||||
.creature-label { font-size: 11px; font-weight: bold; fill: #f4ead2; text-anchor: middle; pointer-events: none; }
|
||||
.home { font-size: 26px; text-anchor: middle; dominant-baseline: middle; opacity: 0.85; }
|
||||
.treasure { stroke: #111; stroke-width: 1.2; }
|
||||
.warp { font-size: 13px; text-anchor: middle; fill: #6a5f4b; font-weight: bold; }
|
||||
.home-star { stroke: #2b2218; stroke-width: 1.4; opacity: 0.92; }
|
||||
.treasure { stroke: #2b2218; stroke-width: 1.3; }
|
||||
.treasure-swirl { fill: none; stroke: #2b2218; stroke-width: 1.2; stroke-dasharray: 5 2.2; }
|
||||
.treasure-core { fill: #2b2218; }
|
||||
.warp { font-size: 14px; text-anchor: middle; fill: #2b2218; font-weight: bold; opacity: 0.65; }
|
||||
.wizard { cursor: pointer; }
|
||||
.wizard-label {
|
||||
font-size: 13px; font-weight: bold; fill: white;
|
||||
font-family: "Oswald", sans-serif;
|
||||
font-size: 13px; font-weight: 600; fill: #f4ead2;
|
||||
text-anchor: middle; pointer-events: none;
|
||||
}
|
||||
.carried { fill: gold; stroke: #111; stroke-width: 1; }
|
||||
|
||||
Reference in New Issue
Block a user