Nothing in this firmware ever mounted internal flash storage: apps, lib, settings and
themes all live on the SD card. The Arduino default table still reserved 1408K for
spiffs, so a custom table hands that to the OTA slots instead, taking each from 1280K
to 1984K. The 64K tail the slots cannot use goes to coredump, which otherwise logs a
missing-partition error on every boot. Changing the table shifts app0, so the next
flash must be a full one.
The ESP32 has no battery-backed clock, so time is 1970 on every power-up. net.cpp
seeds it from the build timestamp -- the device cannot predate its own firmware, and
certificate validity checks need a plausible clock before SNTP can answer -- then
starts SNTP on each join and latches a synced flag from the notification callback.
sntp_get_sync_status() only reports COMPLETED briefly before resetting for the next
cycle, so polling it would make the clock flap.
sys.clockSynced() is the only new binding a clock UI needs; Lua's os.date() already
reads the same system clock. The launcher shows it, in UTC for now.