Various bug fixes and improvements.
This commit is contained in:
@@ -541,7 +541,7 @@ export function BattlePhase({ view, send, step, setStep }: Props) {
|
||||
<div className={`deck-peek deck-peek-${peek.dir}`} style={style}>
|
||||
<div className="deck-peek-label">
|
||||
{peek.seat === youSeat ? 'Your' : 'Opponent’s'} deck · {lineup.length} card
|
||||
{lineup.length !== 1 ? 's' : ''} (top first)
|
||||
{lineup.length !== 1 ? 's' : ''} (first on the right)
|
||||
</div>
|
||||
<div className="deck-peek-cards">
|
||||
{lineup.map((c, i) => (
|
||||
|
||||
@@ -206,19 +206,19 @@ export function CardView({
|
||||
onMouseLeave={preview ? undefined : () => setHover(null)}
|
||||
>
|
||||
{previewEl}
|
||||
{/* Power sits in a spiky burst badge in the top-left corner (pets only),
|
||||
with any battle damage marker beside it. It's absolutely placed so it
|
||||
doesn't eat into the room the name and ability text need. */}
|
||||
<div className="card-top">
|
||||
<span className="card-tier">{card.tier ? `T${card.tier}` : '·'}</span>
|
||||
{card.suit && <span className={`suit-dot suit-${card.suit}`} title={`${card.suit} suit`} />}
|
||||
</div>
|
||||
{/* Power sits in a spiky burst badge on its own centered row (pets only),
|
||||
with any battle damage marker beside it, so it never overlaps the art,
|
||||
name, or ability text. */}
|
||||
{card.kind === 'pet' && (
|
||||
<div className="card-combat">
|
||||
<span className={`card-power ${bonus > 0 ? 'is-buffed' : ''}`}>{power}</span>
|
||||
{damage > 0 && !dead && <span className="card-damage">−{damage}</span>}
|
||||
</div>
|
||||
)}
|
||||
<div className="card-top">
|
||||
<span className="card-tier">{card.tier ? `T${card.tier}` : '·'}</span>
|
||||
{card.suit && <span className={`suit-dot suit-${card.suit}`} title={`${card.suit} suit`} />}
|
||||
</div>
|
||||
<div className="card-art" aria-hidden>
|
||||
{artFor(card.name)}
|
||||
</div>
|
||||
|
||||
@@ -73,6 +73,7 @@ export function ShopPhase({ view, you, send }: Props) {
|
||||
const [useAvocado, setUseAvocado] = useState(false)
|
||||
const myTurn = view.turn === view.youSeat && !you.ready
|
||||
const avocados = you.avocados ?? 0
|
||||
const trumpets = you.trumpets ?? 0
|
||||
const freeBuy = !!you.firstBuyFree // Manta Ray: next buy costs no gold
|
||||
const canBuy = myTurn && (you.coins > 0 || avocados > 0 || freeBuy)
|
||||
// Nudge the player to pass once there's nothing left to buy.
|
||||
@@ -376,6 +377,11 @@ export function ShopPhase({ view, you, send }: Props) {
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
{trumpets > 0 && (
|
||||
<div className="trumpet-indicator" title="Trumpets banked for your next battle">
|
||||
🎺 ×{trumpets}
|
||||
</div>
|
||||
)}
|
||||
</section>
|
||||
|
||||
{/* Actions */}
|
||||
|
||||
@@ -224,7 +224,7 @@ export function Table({ session, onLeave }: { session: Session; onLeave: () => v
|
||||
>
|
||||
<div className="deck-peek-label">
|
||||
{oppName}’s deck last round · {lineup.length} card
|
||||
{lineup.length !== 1 ? 's' : ''} (top first)
|
||||
{lineup.length !== 1 ? 's' : ''} (first on the right)
|
||||
</div>
|
||||
<div className="deck-peek-cards">
|
||||
{lineup.map((c, i) => (
|
||||
|
||||
+27
-8
@@ -983,9 +983,8 @@ h3 {
|
||||
.card-top {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
/* The power badge now floats over the top-left corner, so tier + suit sit
|
||||
together at the top-right. */
|
||||
justify-content: flex-end;
|
||||
/* Tier sits at the top-left, suit dot at the top-right. */
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
font-size: 0.72rem;
|
||||
@@ -993,16 +992,15 @@ h3 {
|
||||
min-height: 14px;
|
||||
}
|
||||
|
||||
/* Combat stats (power badge + battle damage marker) pinned to the top-left
|
||||
corner. Absolute so they don't push the name and ability text down. */
|
||||
/* Combat stats (power badge + battle damage marker) get their own centered
|
||||
row just under the tier/suit line, so they never overlap the art or text. */
|
||||
.card-combat {
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
left: 5px;
|
||||
z-index: 2;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 4px;
|
||||
margin: 2px 0 1px;
|
||||
}
|
||||
|
||||
.card-tier {
|
||||
@@ -1290,6 +1288,19 @@ h3 {
|
||||
inset 0 0 0 1px rgba(246, 201, 78, 0.06);
|
||||
}
|
||||
|
||||
/* Trumpets banked for the next battle, shown as a pill under the deck. */
|
||||
.trumpet-indicator {
|
||||
margin: 12px auto 0;
|
||||
width: fit-content;
|
||||
font-family: var(--font-display);
|
||||
font-size: 1.05rem;
|
||||
padding: 5px 14px;
|
||||
border-radius: 999px;
|
||||
border: 1px solid rgba(246, 201, 78, 0.3);
|
||||
background: rgba(0, 0, 0, 0.28);
|
||||
color: var(--gold);
|
||||
}
|
||||
|
||||
/* Coins shown as big golden discs above the buy row. */
|
||||
.shop-coins {
|
||||
display: flex;
|
||||
@@ -2592,6 +2603,14 @@ h3 {
|
||||
flex-wrap: wrap;
|
||||
gap: 6px;
|
||||
max-width: min(60vw, 560px);
|
||||
/* Read right-to-left like the arrangement screen: the first (top) card sits
|
||||
on the right and later pets flow left. */
|
||||
direction: rtl;
|
||||
}
|
||||
|
||||
/* Keep each card's own contents left-to-right despite the rtl row. */
|
||||
.deck-peek-cards > * {
|
||||
direction: ltr;
|
||||
}
|
||||
|
||||
/* Backdrop behind the toolbar deck-peek: any click outside dismisses it. Sits
|
||||
|
||||
@@ -32,6 +32,7 @@ export interface PlayerView {
|
||||
avocados?: number // set-aside Avocado tokens (Golden pack)
|
||||
firstBuyFree?: boolean // Manta Ray: next buy is free (self only)
|
||||
buysThisRound?: number // Blue-Ringed Octopus counter (self only)
|
||||
trumpets?: number // banked Trumpets for next battle (Bird of Paradise, self only)
|
||||
deck?: Card[]
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user