Re-theme the app: token-based CSS and a full face lift

CSS refactor: every color, font, radius, and shadow is now defined once
in theme.css; all other styles derive translucent variants with
color-mix(), so re-theming means editing one file. Removed the
duplicate core.css/style.css import chains, dead styles, and the
Bootstrap/Tailwind orphan classes that were silently unstyled
(the main reason the splash page looked broken).

New "Lantern & Brine" look: brass and parchment on a lantern-lit
ink-navy night, Pirata One wordmark with Alegreya SC/Sans body fonts
(self-hosted via fontsource — they were previously referenced but
never loaded), parchment-faced playing cards, and a rebuilt splash
page. Inline color styles in components were replaced with semantic
classes (prompt-box, notice-banner, status chips, etc.), the rulebook's
embedded palette was updated to match, and the leftover Vite favicon
and "frontend" page title were replaced.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-06-12 06:50:00 -07:00
parent ba6bf35579
commit 0744893e7b
36 changed files with 1442 additions and 1185 deletions

View File

@@ -55,32 +55,32 @@
{/if}
{#if state.player.is_dead}
<div class="sheet-group prompt-box" style="background: rgba(255, 42, 95, 0.1); border: 1px dashed var(--red-suit); padding: 1rem; border-radius: 8px; margin-bottom: 1rem; text-align: center;">
<h4 style="color: var(--red-suit); margin-top: 0; font-family: var(--font-heading); font-size: 1.1rem; font-weight: 700;">💀 You have Died / Retired!</h4>
<div class="prompt-box danger text-center">
<h4>💀 You have Died / Retired!</h4>
<p class="info-text" style="margin-bottom: 0; font-size: 0.9rem;">Your story arc is complete. You will choose to become a Ghost or roll a new character during the upkeep phase between scenes.</p>
</div>
{/if}
{#if state.player.is_ghost}
<div class="sheet-group prompt-box" style="background: rgba(120, 150, 180, 0.1); border: 1px dashed #7890a8; padding: 1rem; border-radius: 8px; margin-bottom: 1rem; text-align: center;">
<h4 style="color: #a0b0c0; margin-top: 0; font-family: var(--font-heading); font-size: 1.1rem; font-weight: 700;">👻 Playing as a Ghost</h4>
<div class="prompt-box ghostly text-center">
<h4>👻 Playing as a Ghost</h4>
<p class="info-text" style="margin-bottom: 0; font-size: 0.9rem;">You are in the Ghost World (grayscale view). You cannot interact well with the living but you can still help them resolve challenges!</p>
</div>
{/if}
{#if state.player.needs_name}
<div class="sheet-group prompt-box" style="background: rgba(212, 175, 55, 0.1); border: 1px dashed var(--gold); padding: 1rem; border-radius: 8px; margin-bottom: 1rem;">
<h4 style="color: var(--gold); margin-top: 0;">🏴‍☠️ You Earned a Name!</h4>
<div class="prompt-box accent">
<h4>🏴‍☠️ You Earned a Name!</h4>
<p class="info-text" style="margin-bottom: 0.5rem;">You completed your second objective and ranked up! What is your new Pirate Name?</p>
<div style="display: flex; gap: 0.5rem;">
<input type="text" bind:value={newNameInput} class="form-control" placeholder="Enter new name...">
<div class="input-row">
<input type="text" bind:value={newNameInput} class="input-field" placeholder="Enter new name...">
<button class="btn btn-gold" on:click={submitNewName} disabled={!newNameInput.trim()}>Claim Name</button>
</div>
</div>
{/if}
{#if state.player.tax_banned}
<div class="sheet-group prompt-box" style="background: rgba(255, 42, 95, 0.08); border: 1px dashed var(--red-suit); padding: 0.75rem; border-radius: 8px; margin-bottom: 1rem; text-align: center;">
<div class="prompt-box danger text-center">
<p class="info-text" style="margin: 0; font-size: 0.9rem;">🚫 You failed a refused Tax — no more Gat/Name Taxes for you this scene.</p>
</div>
{/if}
@@ -104,7 +104,7 @@
<!-- Duel another Pi-Rat -->
{#if !state.player.is_dead && duelTargets.length > 0}
<div class="sheet-group margin-top">
<h4 style="color: var(--gold);">⚔️ Duel a Pi-Rat</h4>
<h4>⚔️ Duel a Pi-Rat</h4>
<p class="info-text" style="font-size: 0.85rem;">Challenge a crewmate (e.g. for the Captaincy)! Your card becomes a temporary Obstacle they must beat. Both cards are discarded afterwards.</p>
<select class="select-field" bind:value={pvpOpponentId} style="width: 100%; margin-bottom: 0.5rem;">
<option value="">Challenge whom?</option>
@@ -123,7 +123,7 @@
{/if}
<div class="sheet-group margin-top">
<h4 style="color: var(--gold);">Crew Objectives</h4>
<h4>Crew Objectives</h4>
<div class="objectives-checklist">
<label class="checkbox-label">
<input type="checkbox" checked={state.game.completed_crew_1} disabled>
@@ -141,7 +141,7 @@
</div>
<div class="sheet-group margin-top">
<h4 style="color: var(--gold);">Personal Objectives</h4>
<h4>Personal Objectives</h4>
<div class="objectives-checklist">
<label class="checkbox-label">
<input type="checkbox" checked={state.player.completed_personal_1} disabled>