- weather_detail: scrollable hourly forecast (time, temp, description,
rain probability), data logic ported from old weather_detail_screen.cpp
- calendar_detail: scrollable list of all 10 events (summary + formatted
date/all_day), ported from old calendar_detail_screen.cpp
- mvg: scrollable departures list (line badge U/S colored, destination,
time/delay, cancellation), 1-minute refresh timer ported from old
mvg_screen.cpp
- all three use back_button widget (fixed bottom-left)
- main.cpp: Screen controller, navigates between screens via callbacks,
5-minute inactivity timeout -> home, per-screen tick() for refresh
- tile_button: large touch tile with accent bg + title + icon + value,
fires LV_EVENT_CLICKED (for home screen tiles)
- back_button: fixed bottom-left Zurueck button (LV_SYMBOL_LEFT),
large touch target, reused on all detail screens
- screen_base.h: Screen struct with create/show/hide/refresh/tick
lifecycle around an lv_obj_t root (replaces old ScreenId-only header)
- lv_conf.h: enable Montserrat 16/20/24 fonts used by the widgets
Fetch weather/calendar/departures once in setup() after WiFi and dump
parsed fields to Serial, so JSON parsing against the three real
endpoints can be verified on hardware independently of the UI. API
layer itself unchanged (1:1 from m5stack-dashboard).
http_client/weather_api/calendar_api/departures_api are hardware-
independent (HTTP GET + ArduinoJson parsing, same endpoints, same
JSON). Kept verbatim per PLAN.md migration strategy; only changed
#include "../../include/secrets.h" -> #include <secrets.h> to match
the PlatformIO include/ layout (no functional change).