From 813d111bbd00181c72ae383d3e0611092bb12268 Mon Sep 17 00:00:00 2001 From: Eric Wagoner Date: Sun, 27 Sep 2026 20:40:39 -0400 Subject: [PATCH] The about panel is a dialog of tabs, as Wiz-War's is, not a wall of text MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit "About this game — a labor of love" opens a dialog with the game, the tally, more games and a way to send word each on a tab of its own (About.svelte, shared through the kit), instead of one long fold at the foot of the hall. Arrow keys walk the tabs; Escape or a click outside closes it; a link to #about opens it. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG --- CONVENTIONS.md | 4 +- template/src/lib/components/About.svelte | 148 +++++++++++++++++++++++ template/src/lib/components/Hall.svelte | 49 ++++---- 3 files changed, 178 insertions(+), 23 deletions(-) create mode 100644 template/src/lib/components/About.svelte diff --git a/CONVENTIONS.md b/CONVENTIONS.md index 1d78167..a7c4f68 100644 --- a/CONVENTIONS.md +++ b/CONVENTIONS.md @@ -11,7 +11,9 @@ README. *Open a table*, *or join one* with a four-letter code, then *your games* (the ledger of tables this browser holds a seat at, with whose move it is and unread talk), *your reports to the keeper*, and *about this game — - a labor of love*. + a labor of love*, which opens the about panel: a dialog of tabs (The + game, The tally, More games, Send word; a game may add its own, as Dip's + Playing here), `About.svelte`, with each game's words in its hall. - **A table** is a room. Its code is four letters or digits from an alphabet with no look-alikes, and its link is `/join/CODE`. The masthead button reads *invite friends · room CODE* and copies the link. Whoever opened diff --git a/template/src/lib/components/About.svelte b/template/src/lib/components/About.svelte new file mode 100644 index 0000000..505b7ab --- /dev/null +++ b/template/src/lib/components/About.svelte @@ -0,0 +1,148 @@ + + + + + + +{#if open} + +{/if} + + diff --git a/template/src/lib/components/Hall.svelte b/template/src/lib/components/Hall.svelte index 7758164..578a7db 100644 --- a/template/src/lib/components/Hall.svelte +++ b/template/src/lib/components/Hall.svelte @@ -4,6 +4,7 @@ // about panel with the rules, the guide and a way to reach the keeper. import { goto } from '$app/navigation'; import { loadFamily, type FamilyGame } from '$lib/family'; + import About from './About.svelte'; import Preferences from './Preferences.svelte'; import { prefs, setPref } from '$lib/prefs.svelte'; import { allSeats, doubtSeat, forgetSeat, rememberSeat, ServerError, trustSeat } from '$lib/net/client'; @@ -25,6 +26,9 @@ let seats = $state(allSeats()); let games = $state | null>>({}); let aboutOpen = $state(false); + $effect(() => { + if (location.hash === '#about') aboutOpen = true; + }); /** The ledgers' tally, fetched when the about panel opens. */ let tally = $state(null); $effect(() => { @@ -260,16 +264,18 @@ {/if} -
- about this game + + {#snippet aboutGame()}

Where the game comes from, who made the original and when, and how the keeper of this page first met it.

What this version keeps and what it changes. Where the rules text it follows lives (the rules page), and any borrowed art or text with its notice.

It is free and keeps no accounts. A game between people lives on a small server as an append-only ledger of moves, so it can be replayed from its first move, and each player is shown only what the rules let them see.

-

Send word

-

A rule read wrong, a bug, a game you would like to tell of: write to eric@ericwagoner.com, @kestrelsnest.social on Bluesky, or @eric@toots.kestrelsnest.social on Mastodon. The keeper of this hall roosts at kestrelsnest.social.

+
+ {/snippet} + {#snippet aboutTally()} +
{#if tally} -

The tally

+
{tally.gamesFinished}
{tally.gamesFinished === 1 ? 'game' : 'games'} played to a finish, of {tally.gamesBegun} begun at {tally.tablesOpened} {tally.tablesOpened === 1 ? 'table' : 'tables'}
{tally.namesSeated}
{tally.namesSeated === 1 ? 'name has' : 'names have'} taken a seat
@@ -284,8 +290,13 @@ {#if tally.firstGameAt}The first game began {new Date(tally.firstGameAt).toLocaleDateString(undefined, { year: 'numeric', month: 'long', day: 'numeric' })}.{/if} Names are counted, not people: one player under two names is two here. Table time counts only the minutes between moves, so a game left open overnight adds nothing for the night.

+ {:else} +

Counting…

{/if} - {#if family.length} +
+ {/snippet} + {#snippet aboutFamily()} +
{#if family.length}

More games in {#if hall}Kestrel's Hall{:else}Kestrel's Hall{/if}

    {#each family as g (g.slug)} @@ -299,7 +310,13 @@

    __NAME__ is its designer's. This page was made by Eric and a very enthusiastic AI, 2026.

-
+ {/snippet} + {#snippet aboutWord()} +
+

A rule read wrong, a bug, a game you would like to tell of: write to eric@ericwagoner.com, @kestrelsnest.social on Bluesky, or @eric@toots.kestrelsnest.social on Mastodon. The keeper of this hall roosts at kestrelsnest.social.

+
+ {/snippet} +