Splits /tools/verfahrensablauf persisted state into two namespaces:
URL params (timeline kind — paste-able, shareable, refresh-resistant):
proceeding, side, target, trigger_date
localStorage `paliad.verfahrensablauf.scenario.*` (per-user tweaks
that should never leak into a shared link):
event_choices, court_id, ccr, inf_amend, rev_amend, rev_cci,
show_hidden
Hydration order: URL wins. localStorage fills the rest. A shared link
reproduces the timeline kind but each user sees their own scenario
state.
Added trigger_date and proceeding to URL (previously DOM-only — a
refresh lost the date and the proceeding tile). Moved event_choices
and show_hidden from URL to localStorage (verbose, per-user). Added
court_id + flag persistence to localStorage (previously DOM-only).
New pure module `views/verfahrensablauf-state.ts` owns the URL +
localStorage contract: URL parsers + encoder (`applyFiltersToSearch`),
scenario read/write helpers, and a `hydrate()` orchestrator that
documents the URL→localStorage order. 31 unit tests pin the contract,
including the "shared link doesn't leak scenario state" invariant.
Anti-patterns explicitly avoided:
- No ?appellant= resurrection (#132 removed it; engine reads from
the single side picker for role-swap proceedings).
- trigger_date in URL not localStorage (a shared link must reproduce
the same dated timeline).
- URL→localStorage hydration order is contract; localStorage never
overrides an explicit URL value.
Project-driven side-fill chip (?project=<id>) still overrides as
before — parseSideFromSearch is called before the project's our_side
is applied so an explicit ?side= still wins.
Build clean: `bun run build`, `bun test` (240 pass / 594 expect calls),
`go test ./...`, `go vet ./...`.