Refresh the scene dashboard around a crew bubble column

Replace the roster banner and the standalone character-sheet panel with
a left-hand column of crew bubbles. Each bubble shows the player's role
icon, name, rank, current hand size, and a 🛞 for the Captain; clicking
one pops out that player's character sheet as a modal.

- New CrewColumn.svelte: bubbles (Pi-Rats first, Deep last) + an
  Objectives button that opens a crew-objectives popup.
- CharacterSheet.svelte is now a target-driven modal: description,
  likes/hates, and personal objectives for anyone; secret J/Q/K only on
  your own sheet; the Duel UI (no "Challenge whom?" — target is fixed)
  only when a living Pi-Rat views another living Pi-Rat.
- ScenePhase.svelte → 3-column layout (crew | obstacles | hand/deep);
  crew column collapses to a horizontal strip on narrow screens.
- Shared .modal-backdrop/.modal-box/.modal-close moved into components.css;
  removed the now-dead roster-banner and captain-badge styles.

Backend unchanged — the state blob already carries hands, roles, ranks,
objectives, and the captain.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-14 20:03:41 -07:00
parent 8614a6c820
commit 2ea91c066a
6 changed files with 367 additions and 236 deletions

View File

@@ -398,25 +398,6 @@
color: var(--ghost);
}
.captain-badge {
background: color-mix(in srgb, var(--accent) 14%, transparent);
border: 1px solid var(--accent);
color: var(--accent);
padding: 0.4rem 1rem;
border-radius: 20px;
font-size: 1rem;
font-weight: 700;
font-family: var(--font-heading);
display: inline-flex;
align-items: center;
gap: 0.5rem;
}
.captain-badge.vacant {
background: color-mix(in srgb, var(--text) 4%, transparent);
border: 1px dashed var(--edge);
color: var(--text-muted);
}
/* --- Waiting indicator --- */
.waiting-box, .waiting-indicator {
@@ -428,3 +409,56 @@
gap: 0.75rem;
}
/* --- Modal overlay (shared by popups) --- */
.modal-backdrop {
position: fixed;
inset: 0;
z-index: 2000;
display: flex;
align-items: center;
justify-content: center;
padding: 20px;
background: color-mix(in srgb, var(--bg-deep) 70%, transparent);
backdrop-filter: blur(6px);
}
.modal-box {
position: relative;
max-width: 440px;
width: 100%;
max-height: 88vh;
overflow-y: auto;
padding: 1.75rem;
border: 1px solid var(--edge);
border-radius: var(--radius-md);
box-shadow: var(--shadow-deep);
}
.modal-box h3 {
margin-top: 0;
}
.modal-box.sheet-modal {
max-width: 520px;
text-align: left;
}
.modal-close {
position: absolute;
top: 0.6rem;
right: 0.75rem;
background: transparent;
border: none;
color: var(--text-muted);
font-size: 1.6rem;
line-height: 1;
cursor: pointer;
padding: 0.1rem 0.4rem;
border-radius: var(--radius-sm);
}
.modal-close:hover {
color: var(--text);
background: color-mix(in srgb, var(--text) 10%, transparent);
}