Skip to content

Improve the Web UI design and UX #60

Description

@angeloINTJ

What

Redesign or improve the embedded Web UI — the browser interface served directly from the Pico W.

Why

The current Web UI is functional and was given a design pass in v2.2.0-beta (measured light/dark palette, --ok/--warn/--track tokens, theme-aware graph and login). There is still room in layout, mobile ergonomics, forms and error states.

⚠️ Resource constraints (corrected — read carefully)

Measured on main @ 217e28a (v2.2.14-beta, release build, 2026-08-19) Bytes
Flash used 1,006,076 of 1,044,480 (96.3%)
Flash headroom 38,404

Numbers here age with every release — an earlier revision said 50,268 B; h5g (v2.2.11), HA Discovery + /metrics (v2.2.13) and syslog (v2.2.14) consumed the difference. Re-measure before budgeting: arm-none-eabi-size -A on the release ELF, formula in docs/ANALISE_FLASH_RAM.md (the PlatformIO % lies). The practical budget is unchanged: a few KB of gzipped growth is affordable, a framework is not.

  • No frameworks. No React, Vue, Tailwind, or npm. Static HTML/CSS/JS only.
  • RP2040: 264 KB SRAM, dual-core at 133 MHz. The web server shares the chip with sensor polling, display rendering, WiFi and telemetry. Heavy JS or large DOM trees will OOM the device.
  • Browser target: modern Chrome, Firefox, Safari, Edge. Mobile-first (most users arrive from a phone).
  • i18n ceiling (the hidden cost). Every new visible string ships in BOTH .lng packs, and language_es-ES.lng is at 97% of its 32,768 B ceiling (723 B free). Overflow is invisible at runtime — python3 tools/check_lang_packs.py is the only guard. Prefer reusing existing visible labels (e.g. aria-labelledby) over minting new strings; text-heavy improvements (error messages) need a pack diet first.

How the pipeline actually works (corrected)

WebUI.h is the source (currently 452,625 B of raw-string HTML/CSS/JS). It is not shipped as-is:

  1. tools/build_webui_gz.py runs as a pre-build hook — it minifies each page, gzips it, and writes src/WebUI_GZ.h.
  2. The minifier is a stateful scanner, not a regex, because the regex predecessor silently ate JS inside string literals. It is guarded by tools/test_webui_minify.pyrun it after any edit; a page that stops being literal-equivalent fails the gate.
  3. custom_fs_pages can move a page out of flash and into LittleFS, but build_webui_gz.py refuses that option for shipping environments — it is a bench-only diet lever and is not a way to buy space for a UI change.

So the loop is: edit WebUI.hpython3 tools/test_webui_minify.pypio run -e pico_w_release → read the gzipped size delta out of the build.

What you can improve — pick ONE

  • Dashboard cards — temperature/humidity as cards instead of raw tables
  • Mobile-first responsive — touch-friendly controls, no horizontal scroll at 375px
  • Settings form UX — grouping, validation, save/cancel patterns
  • Loading states — CSS-only spinner, skeleton screens
  • Accessibility — ARIA labels, keyboard nav, focus management
  • Error states — friendly messages, retry buttons, offline indicators
  • Login page — modern and branded, under 1 KB of added CSS

Already done, do not pick: dark mode. It shipped in v2.2.0-beta as a full light/dark palette chosen by measured contrast, not a toggle bolted on top.

Acceptance

  • UI improvement submitted as changes to WebUI.h
  • Works on mobile (375px) and desktop
  • python3 tools/test_webui_minify.py passes
  • Builds with pio run -e pico_w_release (zero warnings)
  • Gzipped size change measured and documented (before/after)
  • Flash headroom reported and still positive
  • python3 tools/check_lang_packs.py still passes (both packs under the 32 KB ceiling)
  • Before/after screenshots attached

References

  • WebUI.h — UI source
  • tools/build_webui_gz.py — minify + gzip pre-build hook
  • tools/test_webui_minify.py — equivalence gate
  • src/WebManager_*.cpp — server-side handlers

Metadata

Metadata

Assignees

No one assigned

    Labels

    designVisual design, UI/UX, themes, logos, and graphic assetsenhancementNew feature or requestgood first issueGood for newcomers

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions