942b9c2161
The waste fan x-offset was computed two ways: the renderer used tableau_col_step * 0.224 while the hit-test hard-coded card_size.x * 0.28. These coincide on desktop (col_step = 1.25*cw) but drift on Android, where tighter column spacing (H_GAP_DIVISOR=32, col_step ~= 1.03*cw) makes the renderer fan at ~0.231*cw. The top fanned waste card's sprite then sits ~14px left of its click target, so dragging the visible top card grabs the card beneath it. Extract waste_fan_step() and tableau_col_step() as the single source for both the renderer (card_plugin::card_positions) and the hit-test (input_plugin::card_position) so they can no longer diverge. Add a regression test that simulates Android-tight spacing and asserts the hit target tracks the renderer. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>