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:
2
TODO.md
2
TODO.md
@@ -10,7 +10,7 @@
|
||||
|
||||
- [x] **Incomplete admin page.**: The Admin page should include links for players to re-join the game.
|
||||
- [x] **Less intrusive link copied notification.** When you copy a join link from the lobby page, it pops up an alert() to let you know the link was copied. I'd prefer something more subtle, and more importantly not modal.
|
||||
- [ ] **Rules endpoint** Make a nicely formatted HTML version of the rulebook. It should probably also be linked from a help menu somewhere that's always available, rather than only being surfaced on the splash page of the site (which joining players don't even see). Work from "Rats with Gats beta.pdf" rather than "RULEBOOK.md", which is a low fidelity AI summary of the former.
|
||||
- [x] **Rules endpoint** Make a nicely formatted HTML version of the rulebook. It should probably also be linked from a help menu somewhere that's always available, rather than only being surfaced on the splash page of the site (which joining players don't even see). Work from "Rats with Gats beta.pdf" rather than "RULEBOOK.md", which is a low fidelity AI summary of the former.
|
||||
|
||||
## Cosmetic
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -9,3 +9,4 @@
|
||||
@import './assets/css/card.css';
|
||||
@import './assets/css/upkeep.css';
|
||||
@import './assets/css/admin.css';
|
||||
@import './assets/css/rules.css';
|
||||
|
||||
242
frontend/src/assets/css/rules.css
Normal file
242
frontend/src/assets/css/rules.css
Normal 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);
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
1127
frontend/src/pages/Rules.svelte
Normal file
1127
frontend/src/pages/Rules.svelte
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user