clang-format had no config here, so adopting the submodule's puts both repos
on the same pointer alignment. .editorconfig is what lua-language-server reads
on save, which is why the Lua tree had drifted between tabs and two widths.
The launcher clock read UTC and sat next to the title because the toolkit could only
stack children from the start of an axis. justify adds the CSS main-axis modes that
had a caller -- start, end, center, between -- so a header keeps its title left and
its clock right without any app doing arithmetic.
Timezones are stored as POSIX TZ rules rather than offsets, so newlib applies DST
changeovers and os.date() in Lua reports local time with no binding of its own.
/lib/timezones.lua is only the picker list: a zone missing from it still works if its
rule is written into settings, the same split themes already use.
settings_calibration.lua now finds rows by label. Adding the timezone row shifted
every hardcoded y coordinate in it, which is the failure that had been predicted and
would have silently retargeted taps at the wrong control.
Every app re-declared the same black/white/accent triple, so a palette now lives in
/lib/theme.lua and ui.lua derives muted, contrast, gradients and radius from it.
Deriving rather than listing means a new component costs no theme keys, and a theme
cannot pick text that is unreadable on its own accent.
Components take the palette by inheritance, so the three apps name no colors at all;
ui.theme stays for drawing outside the tree. Settings cycles the installed themes and
stores only the name.
Adds a wifi binding over the Arduino API and a settings flow that scans, picks
the strongest AP per SSID, takes a password from an on-screen keyboard, and
reports connection state. Credentials join /settings.lua and reconnect at boot.
Settings are now written through a temp file and rename, and strings are
Lua-escaped, so a password cannot corrupt the file the firmware parses at boot.
Boots to a launcher that lists /apps/<name>/main.lua on the SD card and runs
the selected app in a vendored Lua 5.4 with gui, input, fs, sys and log
bindings. Settings persist as a Lua table in /settings.lua, covering touch
calibration and screen rotation, with a settings app to edit both. Rotation is
applied after mapping raw touch into the panel's rotation-0 frame, so turning
the UI never invalidates a calibration.