The front page and the about page point to the other games of the Kestrel's Nest
The list is the kit's family.json, shipped as /family.json and refreshed at deploy when the kit is beside this checkout. 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
13a6fc2603
commit
9d087ccaa1
@@ -10,6 +10,7 @@
|
||||
import Card from "./Card.svelte";
|
||||
import Help from "./Help.svelte";
|
||||
import { HELP_TABS, type HelpTab } from "./help-state";
|
||||
import { otherGames, type FamilyGame } from "./family";
|
||||
import { summarizeMissed } from "./catchup";
|
||||
import Replay from "./Replay.svelte";
|
||||
import FxGallery from "./FxGallery.svelte";
|
||||
@@ -26,6 +27,11 @@
|
||||
net.startGamePolling();
|
||||
|
||||
let name = $state(prefs.wizardName);
|
||||
/** The other games of the Kestrel's Nest, for the front page. */
|
||||
let family = $state<FamilyGame[]>([]);
|
||||
$effect(() => {
|
||||
void otherGames("wizwar").then((g) => (family = g));
|
||||
});
|
||||
let joinCode = $state("");
|
||||
let claimPhrase = $state("");
|
||||
/** A /join/<CODE> recruiting link. The visitor lands looking at the
|
||||
@@ -2561,6 +2567,10 @@
|
||||
<img src="/hero.jpg" alt="Through a wizard's eyes: an ambush watches its corridor through a wormhole" />
|
||||
</a>
|
||||
<a class="about-link clips-link" href="/clips">watch clips from the labyrinth</a>
|
||||
{#if family.length}
|
||||
<p class="family-line">Also at the Kestrel's Nest:
|
||||
{#each family as g, i (g.slug)}{i > 0 ? ", " : " "}<a href={g.url} title={g.pitch}>{g.name}</a>{/each}</p>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<details class="more-ways" open={local.hasSave()}>
|
||||
@@ -4108,6 +4118,8 @@
|
||||
margin-bottom: 1.2rem;
|
||||
}
|
||||
.about-link:hover { color: #43331f; }
|
||||
.family-line { margin: 0.5rem 0 0; font-size: 0.85rem; color: #7b6a51; }
|
||||
.family-line a { color: #5a4630; }
|
||||
.clips-link { display: inline-block; margin: 0 0 0.9rem; }
|
||||
.field { display: block; text-align: left; margin-bottom: 1rem; }
|
||||
.field span {
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
// body, the card library with proper entries, the house rulings, the
|
||||
// story of the table, and the tally. Every section and card has a link
|
||||
// a player can send; the desk remembers where the reader was.
|
||||
import { otherGames, type FamilyGame } from "./family";
|
||||
import { cardDef } from "@wizwar/engine";
|
||||
import { tick } from "svelte";
|
||||
import Card from "./Card.svelte";
|
||||
@@ -127,6 +128,11 @@
|
||||
if (initialAnchor) void jumpTo(initialAnchor);
|
||||
else if (bodyEl) bodyEl.scrollTop = helpState.scroll[tab] ?? 0;
|
||||
});
|
||||
/** The other games of the Kestrel's Nest, for the about page. */
|
||||
let family = $state<FamilyGame[]>([]);
|
||||
$effect(() => {
|
||||
void otherGames("wizwar").then((g) => (family = g));
|
||||
});
|
||||
</script>
|
||||
|
||||
{#snippet section(s: RefSection, withSource: boolean)}
|
||||
@@ -311,6 +317,14 @@
|
||||
The keeper of this table roosts at
|
||||
<a href="https://kestrelsnest.social" target="_blank" rel="noreferrer">kestrelsnest.social</a>.
|
||||
</p>
|
||||
{#if family.length}
|
||||
<h3>More games at the Kestrel's Nest</h3>
|
||||
<ul class="family">
|
||||
{#each family as g (g.slug)}
|
||||
<li><a href={g.url}>{g.name}</a>: {g.pitch} <span class="family-note">{g.players} players; {g.origin}.</span></li>
|
||||
{/each}
|
||||
</ul>
|
||||
{/if}
|
||||
<p class="colophon">
|
||||
Wiz-War © Tom Jolly. Sixth edition published by Chessex, 1993.
|
||||
Built by Eric and a very enthusiastic AI, 2026.
|
||||
@@ -691,4 +705,7 @@
|
||||
.entry-card :global(.card:hover) { transform: none; }
|
||||
.contents { columns: 1; }
|
||||
}
|
||||
.family { margin: 0.4rem 0 0.8rem 1.2rem; padding: 0; }
|
||||
.family li + li { margin-top: 0.3rem; }
|
||||
.family-note { color: #7b6a51; }
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
// The other games of the Kestrel's Nest, from the family list the kit keeps
|
||||
// (family.json, one copy shipped with every game), so a player who liked one
|
||||
// table can find the next. This game is left out of its own list.
|
||||
|
||||
export interface FamilyGame {
|
||||
slug: string;
|
||||
name: string;
|
||||
url: string;
|
||||
pitch: string;
|
||||
players: string;
|
||||
origin: string;
|
||||
}
|
||||
|
||||
export async function otherGames(self: string): Promise<FamilyGame[]> {
|
||||
try {
|
||||
const res = await fetch('/family.json', { cache: 'no-cache' });
|
||||
if (!res.ok) return [];
|
||||
const data = (await res.json()) as { games?: FamilyGame[] };
|
||||
return (data.games ?? []).filter((g) => g.slug !== self);
|
||||
} catch {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user