Modes off has no curve (no forecast is read, no house profile kept), so dayview._levels() never ran there and tomorrow's legs were drawn from the bound. homeview.trade_runs(ahead=f) now reads each leg at f(name, kind, start), as mode_runs() does: no give while the emptiest battery is at the floor, each share sized from that level. dayview._counted() gives a give the level by Home's own count (the level now, plus what the blocks before it put in, less what they take out); a charge is read from the floor, because a full battery covers the house before the cheap hour. The battery line says a give is planned when one is and the battery has no give block, also with modes off. test_ux54.py: the modes-on walk no longer relabels a GIVE role at the floor; it asks control's own discharge envelope (packshare.envelope()) with each pack's cut-out at the floor. The peak-guard 20 % case asserts the curve is at the floor at the 17:00 give start. A modes-off walk on a cloudy day (arbitrage.decide() with the cycle's inputs, the packs moved by what control does and by the house), cases A-D: control charges and gives in exactly the quarters the tab has a block. trade_runs(ahead=f) unit check. _stops() ends a give block where the level the tab shows is at the floor (LEVEL_DP). No decision, command, timing or option key changes. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Bdqr7PiaHcBnzPituu2yTC