655dfde736
Players were recycling the stock blind — there's no in-world indicator of how many cards are left before the recycle. A small "·N" chip now sits at the top-right corner of the stock pile, showing the remaining count. The badge is a top-level world entity whose Transform.translation is recomputed each tick from the live LayoutResource (so window resizes and theme switches don't strand it), parented to neither the PileMarker nor any card. update_stock_count_badge spawns the entity on the first frame, then on every subsequent frame reads the stock pile's card count, writes the formatted text into the child Text2d, and toggles Visibility::Hidden when the count drops to zero — the same state where StockEmptyLabel's existing ↺ icon takes over, so the two never co-render. Z_STOCK_BADGE = 30 sits above stock cards (z ≈ 1) and below Z_DROP_OVERLAY = 50, so the badge stays visible during normal play but green drop-target washes still cover it while a card is being dragged. Card drop shadows live at negative local z relative to each card and don't compete with the badge plane. Tokens (STOCK_BADGE_BG, STOCK_BADGE_FG, Z_STOCK_BADGE) were already present in ui_theme from prior work; this commit only wires them up. The chip itself is 28×16 px, rendered with TYPE_CAPTION text in ACCENT_PRIMARY against BG_ELEVATED_HI. Four new tests pin the contract: badge shows "·24" on a fresh deal, hides when the stock empties, updates as the count drops, and the stock_card_count helper reports 0 when the pile is missing. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>