Per-cadence preview budgets, coverage-gap detection, literal-comma encoding
- All four two-cadence tools (forecast, historical, marine, ensemble) now bound their inline preview to one shared budget per cadence on both the canvas and canvas-less branch — the canvas branch previously reconstructed the preview from spillover()'s concatenated head, which could leave daily empty on a wide hourly window (#36), and ensemble previously measured each cadence against the whole budget separately, doubling its inline ceiling (#35)
- A regional ensemble model queried outside its coverage area now fails on the first attempt as a non-retryable input error naming the coverage gap, instead of retrying three times into a false transient-outage report (#33)
- Comma-joined list parameters (models, hourly, daily, elevation coordinates) go on the wire with a literal comma instead of a percent-encoded one, so an upstream rejection names only the offending value instead of the whole requested list; the local climate-model isolation workaround this made redundant is removed (#34)