Add HTML rulebook page with always-available Rules link

New /#/rules route renders the full rulebook transcribed from
"Rats with Gats beta.pdf" (intro, character creation, gameplay,
obstacle charts, challenge resolution, example of play, and setting
info), with an in-page table of contents. A fixed corner link in
App.svelte opens it in a new tab from every page, and the splash
page's previously broken /rules link now points at the new route.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-06-12 01:30:00 -07:00
parent ed7900656d
commit 69e7d24e10
6 changed files with 1375 additions and 2 deletions

View File

@@ -4,15 +4,18 @@
import Join from './pages/Join.svelte';
import Dashboard from './pages/Dashboard.svelte';
import Admin from './pages/Admin.svelte';
import Rules from './pages/Rules.svelte';
const routes = {
'/': Home,
'/game/:id/join': Join,
'/game/:id/player/:pid': Dashboard,
'/game/:id/admin': Admin,
'/rules': Rules,
};
</script>
<main>
<Router {routes} />
<a class="rules-corner-link" href="#/rules" target="_blank" rel="noopener" title="Open the rulebook in a new tab">📖 Rules</a>
</main>

View File

@@ -9,3 +9,4 @@
@import './assets/css/card.css';
@import './assets/css/upkeep.css';
@import './assets/css/admin.css';
@import './assets/css/rules.css';

View File

@@ -0,0 +1,242 @@
/* --- Rules Page --- */
.rules-page {
max-width: 860px;
margin: 0 auto;
padding: 2rem 1rem 4rem;
display: flex;
flex-direction: column;
gap: 1.5rem;
}
.rules-page .glass-panel {
padding: 1.5rem 2rem;
}
.rules-header {
text-align: center;
}
.rules-header h1 {
font-family: var(--font-heading);
color: var(--gold);
font-size: 2.4rem;
margin-bottom: 0.25rem;
}
.rules-subtitle {
color: var(--text-primary);
font-size: 1.15rem;
margin-bottom: 0.75rem;
}
.rules-credits {
color: var(--text-muted);
font-size: 0.85rem;
margin-bottom: 0.5rem;
}
.rules-credits a {
color: var(--neon-cyan);
}
.playtest-note {
margin-top: 0.75rem;
padding: 0.5rem 1rem;
border: 1px dashed var(--glass-border);
border-radius: 8px;
color: var(--gold);
font-size: 0.9rem;
}
.rules-toc h2 {
font-family: var(--font-heading);
color: var(--gold);
margin-bottom: 0.75rem;
}
.rules-toc ul {
list-style: none;
padding-left: 0;
}
.rules-toc ul ul {
padding-left: 1.5rem;
}
.rules-toc li {
margin: 0.2rem 0;
}
.rules-toc button {
background: none;
border: none;
color: var(--neon-cyan);
cursor: pointer;
font-family: var(--font-body);
font-size: 1rem;
padding: 0;
text-align: left;
}
.rules-toc button:hover {
text-decoration: underline;
}
.rules-body {
display: flex;
flex-direction: column;
gap: 1.5rem;
}
.rules-body section {
scroll-margin-top: 1rem;
}
.rules-body h2 {
font-family: var(--font-heading);
color: var(--gold);
font-size: 1.8rem;
margin-bottom: 1rem;
border-bottom: 1px solid var(--glass-border);
padding-bottom: 0.5rem;
}
.rules-body h3 {
font-family: var(--font-heading);
color: var(--text-primary);
font-size: 1.35rem;
margin: 1.5rem 0 0.75rem;
scroll-margin-top: 1rem;
}
.rules-body h4 {
color: var(--gold);
font-size: 1.1rem;
margin: 1.25rem 0 0.5rem;
}
.rules-body h5 {
color: var(--text-primary);
font-size: 1rem;
margin: 1rem 0 0.5rem;
}
.objective-note {
color: var(--text-muted);
font-weight: normal;
font-style: italic;
font-size: 0.9em;
}
.rules-body p {
margin-bottom: 0.75rem;
}
.rules-body ul,
.rules-body ol {
margin: 0 0 0.75rem 1.5rem;
}
.rules-body li {
margin-bottom: 0.35rem;
}
.rules-body .aside {
color: var(--text-muted);
font-style: italic;
font-size: 0.95em;
}
.technique-examples {
list-style: none;
margin-left: 0.5rem;
}
.rules-body table {
width: 100%;
border-collapse: collapse;
margin: 0.75rem 0 1rem;
background: rgba(7, 11, 18, 0.5);
border: 1px solid var(--glass-border);
border-radius: 8px;
}
.rules-body th,
.rules-body td {
padding: 0.5rem 0.75rem;
border-bottom: 1px solid rgba(212, 175, 55, 0.1);
text-align: left;
vertical-align: top;
}
.rules-body thead th {
color: var(--gold);
font-family: var(--font-heading);
}
.obstacle-chart th {
width: 2.5rem;
text-align: center;
color: var(--gold);
font-family: var(--font-heading);
}
.suit-ways th {
width: 7.5rem;
white-space: nowrap;
}
.suit-red {
color: var(--red-suit);
}
.suit-black {
color: var(--black-suit);
}
.rules-body details {
border: 1px solid var(--glass-border);
border-radius: 8px;
padding: 0.75rem 1rem;
}
.rules-body details summary {
cursor: pointer;
color: var(--neon-cyan);
font-weight: 600;
padding: 0.25rem 0;
}
.rules-body details[open] summary {
margin-bottom: 0.75rem;
}
.signature {
color: var(--gold);
font-style: italic;
}
.back-to-top {
text-align: center;
}
/* --- Always-available rules corner link (rendered by App.svelte) --- */
.rules-corner-link {
position: fixed;
top: 12px;
left: 16px;
z-index: 1001;
padding: 6px 14px;
border-radius: 16px;
background: rgba(10, 15, 25, 0.9);
border: 1px solid var(--glass-border-focus);
color: var(--neon-cyan);
font-size: 0.85rem;
font-weight: 700;
text-decoration: none;
font-family: var(--font-heading);
}
.rules-corner-link:hover {
background: rgba(0, 242, 254, 0.1);
}

View File

@@ -56,6 +56,6 @@
</div>
<div class="links mt-4">
<a href="/rules" class="text-muted">Read the Rules</a>
<a href="#/rules" class="text-muted">Read the Rules</a>
</div>
</div>

File diff suppressed because it is too large Load Diff