Add display blocks, sandbox mode, column layout, and test coverage
The TUI was pretty monotonous — everything rendered as flat markdown. Now
the DM can use fenced blocks (```map, ```aside, ```item) that render as
styled Rich Panels in a 2/3 + 1/3 column layout. Maps get heavy green
borders, asides get soft rounded yellow, items get double magenta. Narrow
blocks float in the right column alongside narrative text, wide blocks
(big city maps) center full-width. Text always stays in the 2/3 column
for comfortable reading width.
A StreamClassifier state machine handles the streaming — it detects
fenced block boundaries as chunks arrive, shows live previews while
blocks are being drawn, and classifies everything into typed parts that
build_display() arranges into the grid layout.
The DM now knows its column widths (read dynamically from the terminal
each turn) so it can size blocks to fit the right column. All three
prompts (dm-system, planner, world-seed) encourage using display blocks
generously when establishing and enriching entities.
Also adds `storied play --sandbox` for throwaway sessions — no character,
no world state, temp directory cleaned up on exit. Helpful for iterating
on display stuff and also just fun to mess around in.
Extracted display logic from cli.py into display.py so it's testable.
Added pytest-cov reporting (branch coverage, term-missing, 48% threshold)
and tests for display, character formatting, and session management.
216 tests at 51% coverage.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>