Mark played-card outcomes with corner checks and crosses

This commit is contained in:
2026-09-04 19:34:26 -07:00
parent 22880cc466
commit 811a80a4c9
6 changed files with 48 additions and 20 deletions
+1 -1
View File
@@ -3,7 +3,7 @@
- [x] Add an online indicator that displays if a player is connected - [x] Add an online indicator that displays if a player is connected
- [x] PvP challenges should linger in the UI after completion so that players can see the result - [x] PvP challenges should linger in the UI after completion so that players can see the result
- [x] Add hat/gun icons next to player names on the player list to indicate if they're the captain and/or have a gat - [x] Add hat/gun icons next to player names on the player list to indicate if they're the captain and/or have a gat
- [ ] Replace red/green borders of successful/failed cards with checks and crosses in the upper corner of the card. - [x] Replace red/green borders of successful/failed cards with checks and crosses in the upper corner of the card.
- [ ] Add a note taking area to store game state between sessions - [ ] Add a note taking area to store game state between sessions
## Polish ## Polish
+33 -4
View File
@@ -46,12 +46,41 @@
margin: 0 4px; margin: 0 4px;
} }
.card-mini.success { .card-mini.success, .card-mini.failure {
box-shadow: 0 0 0 2px var(--success); box-shadow: none;
} }
.card-mini.failure { /* Remains visible in the exposed top strip of overlapping played cards. */
box-shadow: 0 0 0 2px var(--danger); .card-result {
position: absolute;
top: 3px;
right: 4px;
display: grid;
place-items: center;
width: 1.1rem;
height: 1.1rem;
border-radius: 50%;
background: var(--card-face);
color: var(--card-ink-black);
font-size: 1rem;
font-weight: 900;
line-height: 1;
}
.card-mini .card-result {
top: 1px;
right: 1px;
width: 0.7rem;
height: 0.7rem;
font-size: 0.65rem;
}
.card-mini.rotated .card-result {
top: auto;
right: auto;
bottom: 1px;
left: 1px;
transform: rotate(-90deg);
} }
.card-mini .val { .card-mini .val {
+2 -10
View File
@@ -264,8 +264,8 @@
/* Overlapping card column for an Obstacle. Cards stack with a heavy negative /* Overlapping card column for an Obstacle. Cards stack with a heavy negative
margin so each earlier card shows only its top strip (rank + suit); the most margin so each earlier card shows only its top strip (rank + suit); the most
recent play sits fully visible at the bottom. Rings: accent = the original recent play sits fully visible at the bottom. The original has an accent ring;
card, green/red = a play that did / didn't beat the difficulty. */ played cards show a result mark in the exposed upper corner. */
.obstacle-stack { .obstacle-stack {
--peek: 34px; /* visible strip of each earlier card */ --peek: 34px; /* visible strip of each earlier card */
--card-h: 112px; /* medium card height (card.css) */ --card-h: 112px; /* medium card height (card.css) */
@@ -290,14 +290,6 @@
box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent) 55%, transparent); box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent) 55%, transparent);
} }
.stack-card.is-success {
box-shadow: 0 0 0 2px var(--success);
}
.stack-card.is-failure {
box-shadow: 0 0 0 2px var(--danger);
}
.suit-badge { .suit-badge {
font-weight: 900; font-weight: 900;
font-size: 1.1rem; font-size: 1.1rem;
+8 -2
View File
@@ -6,7 +6,7 @@
export let size = 'large'; // 'large' | 'medium' | 'mini' export let size = 'large'; // 'large' | 'medium' | 'mini'
export let draggable = false; export let draggable = false;
export let rotated = false; // mini: rendered as a played (rotated) column card export let rotated = false; // mini: rendered as a played (rotated) column card
export let success = null; // mini: true/false adds success/failure styling export let success = null; // true/false displays a success/failure corner mark
export let owner = ''; // mini: short label of who played the card export let owner = ''; // mini: short label of who played the card
export let title = ''; // explicit override; otherwise the card describes itself export let title = ''; // explicit override; otherwise the card describes itself
export let techs = null; // large: {J, Q, K} technique names for the face-card overlay export let techs = null; // large: {J, Q, K} technique names for the face-card overlay
@@ -21,7 +21,7 @@
// tooltip describing the card itself (suit theme + Obstacle meaning), which // tooltip describing the card itself (suit theme + Obstacle meaning), which
// recomputes once the obstacle table loads. // recomputes once the obstacle table loads.
$: tipContent = title ? title : { html: cardTooltipHtml(card, $obstacleTable) }; $: tipContent = title ? title : { html: cardTooltipHtml(card, $obstacleTable) };
$: ariaLabel = title || cardTooltip(card, $obstacleTable); $: ariaLabel = (title || cardTooltip(card, $obstacleTable)) + (success === true ? ' — Success' : success === false ? ' — Failure' : '');
</script> </script>
{#if size === 'mini'} {#if size === 'mini'}
@@ -29,6 +29,9 @@
use:tooltip={tipContent} aria-label={ariaLabel}> use:tooltip={tipContent} aria-label={ariaLabel}>
<span class="val">{val}</span> <span class="val">{val}</span>
<span class="suit">{suit}</span> <span class="suit">{suit}</span>
{#if success !== null}
<span class="card-result" aria-hidden="true">{success ? '✓' : '✕'}</span>
{/if}
{#if owner}<span class="owner">{owner}</span>{/if} {#if owner}<span class="owner">{owner}</span>{/if}
</div> </div>
{:else} {:else}
@@ -39,6 +42,9 @@
<span class="val">{val}</span> <span class="val">{val}</span>
<span class="suit">{suit}</span> <span class="suit">{suit}</span>
</div> </div>
{#if success !== null}
<span class="card-result" aria-hidden="true">{success ? '✓' : '✕'}</span>
{/if}
<div class="card-center"> <div class="card-center">
{#if joker} {#if joker}
🃏 🃏
@@ -80,10 +80,10 @@
<Card card={obs.original_card} size="medium" /> <Card card={obs.original_card} size="medium" />
</div> </div>
{#each column_cards as pc, i (i)} {#each column_cards as pc, i (i)}
<div class="stack-card {pc.success ? 'is-success' : 'is-failure'}" <div class="stack-card"
class:is-latest={i === column_cards.length - 1} class:is-latest={i === column_cards.length - 1}
use:tooltip={`${pc.player_name} played this — ${pc.success ? 'success' : 'no success'}.`}> use:tooltip={`${pc.player_name} played this — ${pc.success ? 'success' : 'no success'}.`}>
<Card card={pc.card} size="medium" /> <Card card={pc.card} size="medium" success={pc.success} />
</div> </div>
{/each} {/each}
</div> </div>
+2 -1
View File
@@ -6,10 +6,11 @@
// - Add a CHANGELOG entry only when a commit changes something players can // - Add a CHANGELOG entry only when a commit changes something players can
// see. Skip refactors, tests, and tooling. Keep wording player-facing. // see. Skip refactors, tests, and tooling. Keep wording player-facing.
export const VERSION = 39; export const VERSION = 40;
// Newest first. Each entry: { version, date: 'YYYY-MM-DD', changes: [string, ...] }. // Newest first. Each entry: { version, date: 'YYYY-MM-DD', changes: [string, ...] }.
export const CHANGELOG = [ export const CHANGELOG = [
{ version: 40, date: '2026-09-04', changes: ['Played cards show a check or cross in the upper corner instead of a green or red outline, so results remain clear in stacked cards.'] },
{ version: 39, date: '2026-09-04', changes: ['Completed duels stay visible for the rest of the scene, showing the winner, both cards, and how the defense resolved.'] }, { version: 39, date: '2026-09-04', changes: ['Completed duels stay visible for the rest of the scene, showing the winner, both cards, and how the defense resolved.'] },
{ version: 38, date: '2026-09-04', changes: ['The crew roster shows who is online, with hat and gun icons for the Captain and Pi-Rats who have a Gat.'] }, { version: 38, date: '2026-09-04', changes: ['The crew roster shows who is online, with hat and gun icons for the Captain and Pi-Rats who have a Gat.'] },
{ version: 37, date: '2026-09-04', changes: ['Color-match replacement cards arrive after the Deep resolves a Challenge. Each applied Obstacle accepts one card per Challenge, and each assistant can contribute one card.'] }, { version: 37, date: '2026-09-04', changes: ['Color-match replacement cards arrive after the Deep resolves a Challenge. Each applied Obstacle accepts one card per Challenge, and each assistant can contribute one card.'] },