Hold the battle arena at a fixed height.

The play area grew and shrank as cards entered and left play. Two slots
were sized independently of the cards that fill them: the pet zone
reserved 150px for a 162px battle card, and the empty-deck placeholder
kept its desktop 84x116 on phones where the face-down card is 56x78. So
each faint/reveal moved the arena 12px per side on desktop, and a deck
running dry moved it 38px per side on a phone.

Every arena slot now derives from one set of --unit-*/--deck-* metrics on
.battle, and holds that size whether or not a card occupies it. Measured
across a battle's states (no pets, both revealed, one fainted, fans of
apples, decks dry), the arena height spread goes from 24px desktop /
76px phone to 0.

Also hide the arena's horizontal scrollbar: a wide apple fan made it
appear and vanish mid-battle, and with a content-driven height that alone
jumped the arena by the scrollbar's thickness. Touch, trackpad and
shift+wheel still scroll it.
This commit is contained in:
Greyson Parrelli
2026-07-27 16:24:52 -04:00
parent b5a143d059
commit a2024229ff
2 changed files with 49 additions and 29 deletions
+4 -4
View File
@@ -295,10 +295,10 @@ export function BattlePhase({ view, send, step, setStep }: Props) {
// The result dialog pops when the replay ends. "Not yet" dismisses it so the
// battle can be rewatched; a toolbar button then remains to advance the round.
const [resultDismissed, setResultDismissed] = useState(false)
// The deck-peek popover lives inside .battlefield, which sets overflow-x
// (and thus overflow-y) to auto — so an absolutely-positioned popover gets
// clipped to the battlefield. We anchor it to the hovered stack's viewport
// rect and portal it to <body> so it floats over the whole window instead.
// The deck-peek popover lives inside .battlefield, which scrolls on one axis
// and hides the other — so an absolutely-positioned popover gets clipped to
// the battlefield. We anchor it to the hovered stack's viewport rect and
// portal it to <body> so it floats over the whole window instead.
const [peek, setPeek] = useState<{ seat: number; pos: 'top' | 'bottom'; rect: DOMRect } | null>(
null,
)