Redesign dashboard: single neutral theme, urgency-ordered layout

Replaces the five novelty themes with one professional dark theme built
on a shared token set (surfaces, 6-step type scale, semantic colours,
44px tap target) used across dashboard, login and settings.

Layout now matches the cache tiers in app.py: a "Right now" strip with
live streams, the download queue and array usage sits above the fold,
with library, discovery, requests and watch insights below. Previously
the page opened on rarely-actionable disk stats and buried active
streams under twenty recommendation rows.

Also from the design review:
- Discover lists show 5 with a Show more toggle instead of 10 each
- RT descriptions render inline and clamped, not hover-only tooltips
  that touch devices could never reach
- Adding a title is now two-step (tap to arm, tap to confirm) since it
  queues a real download
- role=alert on errors, aria-live on polled regions, semantic dl/dt/dd
  stats, labelled search inputs
- every text/surface pair verified at >= 5:1 contrast

Drops the dead delete-modal JS, which threw a TypeError on every load,
and the stale root-level template copies that Flask never rendered.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Barely Removable 2026-08-26 08:12:41 -07:00
parent 951914dd69
commit 339b9f3310
8 changed files with 1484 additions and 4828 deletions

6
app.py
View file

@ -1001,7 +1001,6 @@ def dashboard():
s = load_settings()
timezone = s.get("timezone", "America/New_York")
theme = s.get("theme", "community")
# Public-facing URLs for card header links (via NPM reverse proxy)
arr_host_public = f"https://hippofam.com"
service_urls = {
@ -1020,7 +1019,6 @@ def dashboard():
rt_movies=rt_movies, rt_tv=rt_tv,
sonarr_titles=sonarr_titles, radarr_titles=radarr_titles,
timezone=timezone,
theme=theme,
service_urls=service_urls,
)
@ -1243,7 +1241,6 @@ def settings_page():
prowlarr_api_key=PROWLARR_API_KEY,
ombi_api_key=OMBI_API_KEY,
arr_host=os.environ.get("ARR_HOST", ""),
theme=s.get("theme", "community"),
)
@ -1252,7 +1249,7 @@ def settings_page():
def api_save_settings():
data = request.get_json()
allowed = {"timezone", "sonarr_api_key", "radarr_api_key", "sabnzbd_api_key",
"tautulli_api_key", "prowlarr_api_key", "ombi_api_key", "arr_host", "theme"}
"tautulli_api_key", "prowlarr_api_key", "ombi_api_key", "arr_host"}
filtered = {k: v for k, v in data.items() if k in allowed}
save_settings(filtered)
return jsonify({"success": True})
@ -1264,7 +1261,6 @@ def api_get_settings():
s = load_settings()
return jsonify({
"timezone": s.get("timezone", "America/New_York"),
"theme": s.get("theme", "community"),
})