More random UI fixes.
This commit is contained in:
@@ -537,13 +537,19 @@ export function BattlePhase({ view, send, step, setStep }: Props) {
|
||||
? { left: peek.rect.left }
|
||||
: { right: window.innerWidth - peek.rect.right }),
|
||||
}
|
||||
// Your deck sits on the left of the board and fights from its right
|
||||
// edge; the rival's sits on the right and fights from its left edge.
|
||||
// Order each peek to match, so "first" always points toward the clash.
|
||||
const mine = peek.seat === youSeat
|
||||
const firstSide = mine ? 'right' : 'left'
|
||||
return createPortal(
|
||||
<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' : ''} (first on the right)
|
||||
{mine ? 'Your' : 'Opponent’s'} deck · {lineup.length} card
|
||||
{lineup.length !== 1 ? 's' : ''} (first on the {firstSide})
|
||||
</div>
|
||||
<div className="deck-peek-cards">
|
||||
<div className={`deck-peek-cards first-${firstSide}`}>
|
||||
<div className="deck-peek-first">⚔️ first</div>
|
||||
{lineup.map((c, i) => (
|
||||
<CardView key={c.id || i} card={c} size="sm" />
|
||||
))}
|
||||
|
||||
@@ -62,7 +62,7 @@ const TRIGGER_GLOSS: Record<string, string> = {
|
||||
Hurt: 'when it survives taking damage',
|
||||
Sell: 'when you sell it in the shop',
|
||||
Buy: 'when you buy it',
|
||||
Triple: 'when traded in as one of three',
|
||||
Triple: 'when tripled as one of three same-suit pets',
|
||||
'After Attacking': 'right after it attacks in a clash',
|
||||
'Battle Prep': 'as the battle is arranged',
|
||||
'Shop start': 'when the shop opens each round',
|
||||
|
||||
@@ -227,7 +227,7 @@ export function ShopPhase({ view, you, send }: Props) {
|
||||
<div className="shop-status">
|
||||
{pending && !myPending ? (
|
||||
<span className="muted">
|
||||
{opponent?.name ?? 'Opponent'} is trading up a tier…
|
||||
{opponent?.name ?? 'Opponent'} is tripling up a tier…
|
||||
</span>
|
||||
) : you.ready ? (
|
||||
<span className="muted">
|
||||
@@ -239,7 +239,7 @@ export function ShopPhase({ view, you, send }: Props) {
|
||||
Too many pets! Sell down to {view.maxPets} before you can pass 🍎
|
||||
</span>
|
||||
) : myTurn ? (
|
||||
<span className="status-hot">Your turn — buy, sell, trade, or pass</span>
|
||||
<span className="shop-status-pill">Your turn — buy, sell, triple, or pass</span>
|
||||
) : (
|
||||
<span className="muted">
|
||||
{view.players[view.turn]?.name ?? 'Opponent'}’s turn…
|
||||
@@ -305,7 +305,7 @@ export function ShopPhase({ view, you, send }: Props) {
|
||||
? 'Tap a card to buy it for 1 🪙 — selling and trading are free'
|
||||
: avocados > 0
|
||||
? 'No coins — tap a card to buy it by discarding an Avocado 🥑'
|
||||
: 'No coins left — you can still sell, trade, or pass'}
|
||||
: 'No coins left — you can still sell, triple, or pass'}
|
||||
</div>
|
||||
)}
|
||||
</section>
|
||||
@@ -398,9 +398,9 @@ export function ShopPhase({ view, you, send }: Props) {
|
||||
className="btn btn-secondary"
|
||||
disabled={!myTurn || !sameSuit || view.round >= view.maxRounds}
|
||||
onClick={() => act({ type: 'trade', cards: selected })}
|
||||
title="Trade 3 same-suit pets for a pick from the next tier — free"
|
||||
title="Triple 3 same-suit pets for a pick from the next tier — free"
|
||||
>
|
||||
Trade 3{' '}
|
||||
Triple 3{' '}
|
||||
{sameSuit && selectedCards[0].suit ? (
|
||||
<span className={`suit-dot suit-${selectedCards[0].suit}`} />
|
||||
) : (
|
||||
@@ -455,7 +455,7 @@ export function ShopPhase({ view, you, send }: Props) {
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Trade picker */}
|
||||
{/* Triple picker */}
|
||||
{myPending && pending && (
|
||||
<div className="modal-backdrop">
|
||||
<div className="modal">
|
||||
|
||||
@@ -36,8 +36,8 @@ export function Table({ session, onLeave }: { session: Session; onLeave: () => v
|
||||
})
|
||||
|
||||
// A shop-phase peek at an opponent's deck from the previous round's battle
|
||||
// (its arranged lineup is already public). Anchored under the clicked button.
|
||||
const [deckPeek, setDeckPeek] = useState<{ seat: number; rect: DOMRect } | null>(null)
|
||||
// (its arranged lineup is already public). Shown as a centered modal.
|
||||
const [deckPeek, setDeckPeek] = useState<{ seat: number } | null>(null)
|
||||
|
||||
// The battle outcome is known before the replay plays out, so we hold its
|
||||
// "result" log entry back: it's dropped from the persistent list during the
|
||||
@@ -158,10 +158,9 @@ export function Table({ session, onLeave }: { session: Session; onLeave: () => v
|
||||
<button
|
||||
className={`chip chip-btn ${deckPeek?.seat === p.seat ? 'is-active' : ''}`}
|
||||
title="See their deck from last round's battle"
|
||||
onClick={(e) => {
|
||||
const rect = e.currentTarget.getBoundingClientRect()
|
||||
setDeckPeek((cur) => (cur?.seat === p.seat ? null : { seat: p.seat, rect }))
|
||||
}}
|
||||
onClick={() =>
|
||||
setDeckPeek((cur) => (cur?.seat === p.seat ? null : { seat: p.seat }))
|
||||
}
|
||||
>
|
||||
👁 deck
|
||||
</button>
|
||||
@@ -214,25 +213,26 @@ export function Table({ session, onLeave }: { session: Session; onLeave: () => v
|
||||
const lineup = view.battle?.lineups?.[deckPeek.seat] ?? []
|
||||
if (!lineup.length) return null
|
||||
const oppName = view.players.find((p) => p.seat === deckPeek.seat)?.name ?? 'Opponent'
|
||||
const left = Math.max(8, Math.min(deckPeek.rect.left, window.innerWidth - 380))
|
||||
return createPortal(
|
||||
<>
|
||||
<div className="deck-peek-backdrop" onClick={() => setDeckPeek(null)} />
|
||||
<div className="modal-backdrop" onClick={() => setDeckPeek(null)}>
|
||||
<div
|
||||
className="deck-peek deck-peek-toolbar"
|
||||
style={{ top: deckPeek.rect.bottom + 8, left }}
|
||||
className="modal deck-peek-modal"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
<div className="deck-peek-label">
|
||||
{oppName}’s deck last round · {lineup.length} card
|
||||
{lineup.length !== 1 ? 's' : ''} (first on the right)
|
||||
{oppName}’s deck from last round’s battle · {lineup.length} card
|
||||
{lineup.length !== 1 ? 's' : ''} (first on the left)
|
||||
</div>
|
||||
<div className="deck-peek-cards">
|
||||
{/* The rival battles on your right, so their first pet faces you
|
||||
on the left — order the peek to match, first card on the left. */}
|
||||
<div className="deck-peek-cards first-left">
|
||||
<div className="deck-peek-first">⚔️ first</div>
|
||||
{lineup.map((c, i) => (
|
||||
<CardView key={c.id || i} card={c} size="sm" />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</>,
|
||||
</div>,
|
||||
document.body,
|
||||
)
|
||||
})()}
|
||||
|
||||
Reference in New Issue
Block a user