When a city cannot complete a build (e.g., size < 2 for settlers),
shields were accumulating past the build cost, showing confusing
values like "60/40 shields" or negative turn counts.
- Cap shieldBox at buildCost each turn in processCity
- Clamp displayed shields to min(shieldBox, cost) in city screen
- Add tests verifying shield capping and stalled build completion
- Capture attacker/defender snapshot (id, civ, type, start position) in
combat events so the UI can reconstruct them after resolution
- Add `animateCombat()` that plays sequential lunge/retreat animations for
each combat, death flash/shrink for the loser, and optional victory glide
for unopposed winners stepping onto the cleared tile
- Add `animateUnitsAlong()` to glide AI civ units between before/after
snapshots, enabling the same "resolve now, animate after" pattern for
AI turns
- Track unit containers in `unitContainers` map for lookup by unitId
- When player unit encounters combat mid-path, animate the peaceful leg
first then play the clash
- Add `collectNewCombatEvents()` to pick up and mark consumed combat events
- Add `isTileVisible()` helper for filtering AI combat to visible tiles
- Update tests to verify advance-after-kill and combat event shape