Replace the free-text Timezone box with a select of curated IANA zones,
an "API host local time" choice that clears the zone, and an "Other IANA
zone…" choice that opens a text entry for any other zone. A saved zone
outside the list opens in that entry on load. Helper text states this is
the application timezone and the source of local time for the panel,
scheduler and admin app. Saving still patches only changed fields, so a
timezone change sends exactly {"timezone": ...}; nothing is written on
load and the browser zone is never read.
API tests add invalid-zone 422 cases, a non-admin timezone PATCH refusal,
and a lone timezone PATCH sticking on a fresh database.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>