From 5f4f8f2ea70dfc01f905dcad08c597c5902f8c06 Mon Sep 17 00:00:00 2001 From: Thomas Faour Date: Fri, 31 Jul 2026 10:34:28 +0000 Subject: [PATCH] Add a curated theme system for "modern" style widgets, inspired by Tesserae Frame.theme (7 presets in app/theme_tokens.py) drives font family, corner radius, drop shadow, and an accent hue for every modern-style widget's header/accent region. Rich accent colors (not just the 6 flat panel inks) are approximated via denser Bayer stippling confined to just that region (html_render.ordered_dither_regions), so icon/text content elsewhere stays exactly as crisp as it is today -- verified directly against real Chromium renders, both in unit tests and via run-server. "classic" is a byte-identical no-visual-change default: weather's header keeps its original fixed blue gradient, tasks/calendar keep their flat THEME_* ink. Themes are purely stylistic -- battery's charge-level color, calendar/ tasks' per-owner event chips, and text's own per-widget font choice are never touched. --- docs/widgets.md | 64 ++++++ server/app/calendar_html_render.py | 116 ++++++---- server/app/html_render.py | 137 ++++++++---- server/app/migration.py | 10 + server/app/models.py | 5 + server/app/routers/api_frames.py | 5 +- server/app/routers/api_widgets.py | 13 +- server/app/routers/frame_pages.py | 3 +- server/app/static/frame_config.js | 18 ++ server/app/templates/frame_config.html | 17 ++ .../templates/widget_html/battery.html.jinja | 6 +- .../widget_html/calendar_agenda.html.jinja | 8 +- .../widget_html/calendar_month.html.jinja | 8 +- .../calendar_today_tomorrow.html.jinja | 8 +- .../calendar_week_horizontal.html.jinja | 8 +- .../widget_html/framed_image.html.jinja | 2 +- .../templates/widget_html/tasks.html.jinja | 8 +- .../widget_html/weather_current.html.jinja | 6 +- .../widget_html/weather_daily.html.jinja | 8 +- server/app/theme_tokens.py | 202 ++++++++++++++++++ server/app/widgets/battery.py | 2 +- server/app/widgets/calendar.py | 1 + server/app/widgets/static_image.py | 2 +- server/app/widgets/tasks.py | 2 +- server/app/widgets/text.py | 89 ++------ server/app/widgets/weather.py | 2 +- server/app/widgets/whiteboard.py | 3 +- server/tests/test_html_render.py | 65 ++++++ server/tests/test_theme_tokens.py | 92 ++++++++ server/tests/test_widgets_calendar.py | 32 +++ server/tests/test_widgets_tasks.py | 30 +++ server/tests/test_widgets_weather.py | 31 +++ 32 files changed, 808 insertions(+), 195 deletions(-) create mode 100644 server/app/theme_tokens.py create mode 100644 server/tests/test_html_render.py create mode 100644 server/tests/test_theme_tokens.py diff --git a/docs/widgets.md b/docs/widgets.md index 9c48461..82e7f1d 100644 --- a/docs/widgets.md +++ b/docs/widgets.md @@ -212,6 +212,70 @@ Per-widget-type notes: (`framed_image.html.jinja`, shared between the two) wrapping the already-composed image. +### Themes for modern-style widgets + +`Frame.theme` (String, default `"classic"`, one Advanced Configuration +` + {% for key, t in themes.items() %} + + {% endfor %} + + + + +
Photos configuration

Palette and dithering used only by diff --git a/server/app/templates/widget_html/battery.html.jinja b/server/app/templates/widget_html/battery.html.jinja index 2cfca71..513ee13 100644 --- a/server/app/templates/widget_html/battery.html.jinja +++ b/server/app/templates/widget_html/battery.html.jinja @@ -1,8 +1,8 @@