The help becomes a reference desk: searchable, linkable, and it remembers its place
The rules tab is one body — the condensed rules, the rulebook, the expansion, and the FAQ — with a contents list, a search that labels each hit by source, and a link on every section. The rulebook's emphasis renders, and the (6E: …) notes are set apart from the original words. The card library gains filters for set, type, and target, ranks an exact name first, counts its results, and says so when there are none; a card opens as an entry: the card itself beside reading-size text with the printed wording, deck counts, the official FAQ, this table's rulings, and links to the cards it names. The house rulings are organized by card, in the present tense, with the revision history kept off the page. Every page and card has a link (/?help=rules/…, /?card=…) that opens the desk to it, and the desk reopens on the tab, search, and scroll position it was closed at. About leads with the worn box and the friends, shows the workshops as a small gallery with a direct link to the demo reel, and says plainly what an online ledger keeps and what a passed-around device keeps to itself. The tally leads with finished games, treasure and combat wins, and hours played, and explains that wizards are counted by name and table time by the clock between moves. Escape closes only the foremost layer and returns focus to the card that opened it; the tabs wrap on a phone instead of clipping. 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
4c2a253723
commit
9dee01d393
@@ -9,6 +9,7 @@
|
||||
import Faq from "./Faq.svelte";
|
||||
import Card from "./Card.svelte";
|
||||
import Help from "./Help.svelte";
|
||||
import type { HelpTab } from "./help-state";
|
||||
import Replay from "./Replay.svelte";
|
||||
import FxGallery from "./FxGallery.svelte";
|
||||
import TokenGallery from "./TokenGallery.svelte";
|
||||
@@ -257,7 +258,39 @@
|
||||
let faqCardId = $state<string | null>(null);
|
||||
/** A discard-pile card enlarged above the pile. */
|
||||
let discardPeek = $state<CardInstance | null>(null);
|
||||
let helpTab = $state<"play" | "rules" | "cards" | "rulings" | "about" | "tally">("play");
|
||||
/** The help's opening tab; null reopens it where the reader left off. */
|
||||
let helpTab = $state<HelpTab | null>(null);
|
||||
let helpAnchor = $state<string | null>(null);
|
||||
let helpCard = $state<string | null>(null);
|
||||
// A link into the reference — /?help=rules/rulebook-line-of-sight or
|
||||
// /?card=force-field — opens the desk to that page.
|
||||
{
|
||||
const q = new URLSearchParams(location.search);
|
||||
const card = q.get("card");
|
||||
const help = q.get("help");
|
||||
const tabs: HelpTab[] = ["play", "rules", "cards", "rulings", "about", "tally"];
|
||||
if (card) { helpCard = card; showHelp = true; }
|
||||
else if (help) {
|
||||
const [t, ...rest] = help.split("/");
|
||||
if (tabs.includes(t as HelpTab)) { helpTab = t as HelpTab; helpAnchor = rest.join("/") || null; showHelp = true; }
|
||||
}
|
||||
}
|
||||
/** The address bar follows the reader through the help, so any page is a link. */
|
||||
function helpNavigate(tab: HelpTab, anchor: string | null, card: string | null) {
|
||||
const u = new URL(location.href);
|
||||
u.searchParams.delete("help"); u.searchParams.delete("card");
|
||||
if (card) u.searchParams.set("card", card);
|
||||
else u.searchParams.set("help", anchor ? `${tab}/${anchor}` : tab);
|
||||
// The slash stays a slash: /?help=rules/the-cards reads as a path should.
|
||||
u.search = u.searchParams.toString().replace(/%2F/g, "/");
|
||||
history.replaceState(null, "", u);
|
||||
}
|
||||
function helpClose() {
|
||||
showHelp = false; helpAnchor = null; helpCard = null; helpTab = null;
|
||||
const u = new URL(location.href);
|
||||
u.searchParams.delete("help"); u.searchParams.delete("card");
|
||||
history.replaceState(null, "", u);
|
||||
}
|
||||
let hotseatCount = $state(2);
|
||||
let setupName = $state("");
|
||||
let setupColor = $state(0);
|
||||
@@ -1695,7 +1728,7 @@
|
||||
<button class="mast-leave" title="something behaved unexpectedly? tell the wizards"
|
||||
onclick={() => (feedbackOpen = true)}>🐞 report</button>
|
||||
{/if}
|
||||
<button class="mast-leave" class:mast-help-solo={!net.roomId} onclick={() => { helpTab = "play"; showHelp = true; }}>
|
||||
<button class="mast-leave" class:mast-help-solo={!net.roomId} onclick={() => { helpTab = null; showHelp = true; }}>
|
||||
help & rules
|
||||
</button>
|
||||
<span class="mast-status" class:offline={net.status !== "connected"}>
|
||||
@@ -1969,7 +2002,8 @@
|
||||
{/if}
|
||||
|
||||
{#if showHelp}
|
||||
<Help initialTab={helpTab} stats={net.stats} onstats={() => net.requestStats()} onclose={() => (showHelp = false)} />
|
||||
<Help initialTab={helpTab} initialAnchor={helpAnchor} initialCard={helpCard} stats={net.stats}
|
||||
onstats={() => net.requestStats()} onnavigate={helpNavigate} onclose={helpClose} />
|
||||
{/if}
|
||||
|
||||
{#if view?.phase === "finished" && view.winner && victoryCurtain && !victorySeen}
|
||||
|
||||
Reference in New Issue
Block a user