The Token Workshop: every token, twice, at /?tokens
All 45 tokens in both arts — the photographed physical set beside the hand-drawn contingency — grouped (wizards, treasures, monsters, terrain, objects & markers), each at board size and close-up. The drawn column renders through TokenArt, so it previews exactly as the board inlines it. Cross-linked with the flourish workshop. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0138A8CjeQRpvzKxuMfz1Bqc
This commit is contained in:
co-authored by
Claude Fable 5
parent
ed7a58a698
commit
e1aeeaabff
@@ -7,6 +7,7 @@
|
||||
import Help from "./Help.svelte";
|
||||
import Replay from "./Replay.svelte";
|
||||
import FxGallery from "./FxGallery.svelte";
|
||||
import TokenGallery from "./TokenGallery.svelte";
|
||||
import { scheduleFx, type BoardFx } from "./fx";
|
||||
import { CREATURE_ART, objectArt, TERRAIN_ART, tokenArt } from "./art";
|
||||
import { local } from "./local.svelte";
|
||||
@@ -38,6 +39,7 @@
|
||||
}
|
||||
/** Which pending attack the player has already acknowledged (modal dismissed). */
|
||||
const fxWorkshop = new URLSearchParams(location.search).has("fx");
|
||||
const tokenWorkshop = new URLSearchParams(location.search).has("tokens");
|
||||
let attackNoticeSeen = $state<string | null>(null);
|
||||
/** The interruption fanfare, dismissed once per window. */
|
||||
let momentSeen = $state(false);
|
||||
@@ -1082,7 +1084,9 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if fxWorkshop}
|
||||
{#if tokenWorkshop}
|
||||
<TokenGallery />
|
||||
{:else if fxWorkshop}
|
||||
<FxGallery />
|
||||
{:else}
|
||||
<div class="table">
|
||||
|
||||
@@ -57,6 +57,7 @@
|
||||
<p class="sub">
|
||||
Every effect replays each beat. Edit a file in <code>src/fx-sprites/</code>
|
||||
and it hot-reloads here.
|
||||
<a class="cross" href="/?tokens">→ the token workshop</a>
|
||||
</p>
|
||||
<div class="grid">
|
||||
{#each SAMPLES as fx (fx.kind)}
|
||||
@@ -162,6 +163,7 @@
|
||||
}
|
||||
.demo-wall { fill: #4d4438; }
|
||||
.sub code { color: #c9a72a; }
|
||||
.sub .cross { color: #c9a72a; }
|
||||
.grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
<script lang="ts">
|
||||
// The token workshop: every token in both arts, side by side — the
|
||||
// photographed physical set and the hand-drawn SVG contingency. Open
|
||||
// with /?tokens under `npm run dev`; edits to public/tokens-svg/*.svg
|
||||
// show on the next refresh. Board size and close-up for each.
|
||||
import TokenArt from "./TokenArt.svelte";
|
||||
|
||||
const GROUPS: { title: string; files: string[] }[] = [
|
||||
{ title: "Wizards", files: ["wizard-0", "wizard-1", "wizard-2", "wizard-3", "wizard-4", "wizard-5"] },
|
||||
{ title: "Treasures", files: ["treasure-0", "treasure-1", "treasure-2", "treasure-3", "treasure-4", "treasure-5"] },
|
||||
{
|
||||
title: "Monsters",
|
||||
files: ["troll", "skeleton", "wraith", "fire-imp", "democratic-monster", "shadow", "alter-ego"],
|
||||
},
|
||||
{
|
||||
title: "Terrain",
|
||||
files: [
|
||||
"solid-stone", "thorn-bush", "rosebush", "killer-ooze", "slime", "dustcloud",
|
||||
"tacks", "pit", "safe", "fire-wall", "illusion-wall", "wall", "wall-2", "door",
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Objects & markers",
|
||||
files: [
|
||||
"dagger", "rock", "magic-stone", "magic-wand", "master-key", "boobytrap",
|
||||
"dimensional-warp", "redirection-a", "redirection-b", "destroy-wall",
|
||||
"jam-lock", "lock-gone",
|
||||
],
|
||||
},
|
||||
];
|
||||
</script>
|
||||
|
||||
<div class="gallery">
|
||||
<h1>The Token Workshop</h1>
|
||||
<p class="sub">
|
||||
Every token, twice: the photographed physical set beside the hand-drawn
|
||||
contingency. Edit <code>public/tokens-svg/</code> and refresh. Small is
|
||||
board size; large is the close-up the peek modal shows.
|
||||
<a href="/?fx">→ the flourish workshop</a>
|
||||
</p>
|
||||
{#each GROUPS as group (group.title)}
|
||||
<h2>{group.title}</h2>
|
||||
<div class="grid">
|
||||
{#each group.files as f (f)}
|
||||
<figure>
|
||||
<div class="pair">
|
||||
<div class="col">
|
||||
<img class="big" src={`/tokens/${f}.png`} alt={`${f} (photo)`} />
|
||||
<img class="small" src={`/tokens/${f}.png`} alt="" />
|
||||
<span class="tag">photo</span>
|
||||
</div>
|
||||
<div class="col">
|
||||
<svg viewBox="0 0 96 96" class="big">
|
||||
<TokenArt href={`/tokens-svg/${f}.svg`} x={0} y={0} width={96} height={96} />
|
||||
</svg>
|
||||
<svg viewBox="0 0 28 28" class="small">
|
||||
<TokenArt href={`/tokens-svg/${f}.svg`} x={0} y={0} width={28} height={28} />
|
||||
</svg>
|
||||
<span class="tag">drawn</span>
|
||||
</div>
|
||||
</div>
|
||||
<figcaption>{f}</figcaption>
|
||||
</figure>
|
||||
{/each}
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.gallery {
|
||||
min-height: 100vh;
|
||||
background: #171a20;
|
||||
color: #d8d2c0;
|
||||
font-family: "Archivo Narrow", system-ui, sans-serif;
|
||||
padding: 1.5rem;
|
||||
}
|
||||
h1, h2 {
|
||||
font-family: "Oswald", sans-serif;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.14em;
|
||||
color: #e9e1cb;
|
||||
margin: 0 0 0.2rem;
|
||||
}
|
||||
h1 { font-size: 1.2rem; }
|
||||
h2 { font-size: 0.95rem; margin-top: 1.4rem; }
|
||||
.sub { color: #8d8672; margin: 0 0 1rem; }
|
||||
.sub code { color: #c9a72a; }
|
||||
.sub a { color: #c9a72a; }
|
||||
.grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
|
||||
gap: 0.9rem;
|
||||
}
|
||||
figure {
|
||||
margin: 0;
|
||||
background: #efe8d4;
|
||||
border-radius: 4px;
|
||||
padding: 0.5rem;
|
||||
}
|
||||
.pair { display: flex; gap: 0.6rem; justify-content: center; }
|
||||
.col { display: flex; flex-direction: column; align-items: center; gap: 0.25rem; }
|
||||
.big { width: 72px; height: 72px; display: block; }
|
||||
.small { width: 28px; height: 28px; display: block; }
|
||||
img.big, img.small { object-fit: cover; border-radius: 3px; }
|
||||
.tag {
|
||||
font-family: "Courier Prime", monospace;
|
||||
font-size: 0.6rem;
|
||||
color: #8a7a5e;
|
||||
}
|
||||
figcaption {
|
||||
font-family: "Courier Prime", monospace;
|
||||
font-size: 0.72rem;
|
||||
color: #43331f;
|
||||
text-align: center;
|
||||
padding-top: 0.35rem;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user