From 3fd4c847076d719e4523b2fd21ea917e175e1175 Mon Sep 17 00:00:00 2001 From: librelad Date: Thu, 28 May 2026 23:46:39 +0100 Subject: [PATCH] ux(admin): give each Overview area a signature colour MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduces per-area identity hues as reusable tokens (--page-updates/backups/ ssh/system + -rgb companions) and a generic .admin-action-btn that takes its colour from --page set on the card. The Overview buttons now read in their area's hue — Updates blue, Backups emerald, SSH violet, System amber — with the icon following via currentColor; "Update now" is the filled (primary) variant. The tokens are the foundation to extend each area's identity (page headers, accents) going forward, not just these buttons. Co-Authored-By: Claude Opus 4.7 Signed-off-by: librelad --- containers/libreportal/frontend/css/admin.css | 42 +++++++++++++++++++ .../js/components/admin/admin-overview.js | 11 ++--- 2 files changed, 48 insertions(+), 5 deletions(-) diff --git a/containers/libreportal/frontend/css/admin.css b/containers/libreportal/frontend/css/admin.css index bc2f70f..00fab6d 100644 --- a/containers/libreportal/frontend/css/admin.css +++ b/containers/libreportal/frontend/css/admin.css @@ -1,6 +1,16 @@ /* Admin area — Overview board + shared admin-page chrome. Visually aligned with the backup dashboard (tile/card style) and the config page header. */ +:root { + /* Per-area identity hues. Each admin area owns one colour, reused going + forward (Overview action buttons today; page headers/accents next). + The *-rgb companions feed rgba() tints. */ + --page-updates: #4f8cff; --page-updates-rgb: 79, 140, 255; + --page-backups: #1fb88a; --page-backups-rgb: 31, 184, 138; + --page-ssh: #9b7bf0; --page-ssh-rgb: 155, 123, 240; + --page-system: #f0883e; --page-system-rgb: 240, 136, 62; +} + .admin-page { padding: 4px 2px 40px; } @@ -110,6 +120,38 @@ color: rgba(var(--text-rgb), 0.55); } +/* Per-page identity button. The card sets --page / --page-rgb inline; the + button (and its icon, via currentColor) takes the area's hue. Reusable on any + admin surface going forward — set the two vars and use .admin-action-btn. */ +.admin-action-btn { + display: inline-flex; + align-items: center; + gap: 8px; + padding: 9px 16px; + border-radius: 8px; + font-size: 0.875rem; + font-weight: 600; + cursor: pointer; + color: var(--page, var(--accent)); + background: rgba(var(--page-rgb, var(--accent-rgb)), 0.14); + border: 1px solid rgba(var(--page-rgb, var(--accent-rgb)), 0.35); + transition: background 0.12s ease, transform 0.12s ease, box-shadow 0.12s ease; +} +.admin-action-btn:hover { + background: rgba(var(--page-rgb, var(--accent-rgb)), 0.22); + transform: translateY(-1px); +} +.admin-action-btn:disabled { opacity: 0.6; cursor: default; transform: none; box-shadow: none; } +/* Primary action (e.g. Update now): filled with the area's hue. */ +.admin-action-btn.is-primary { + color: #fff; + background: var(--page, var(--accent)); + border-color: transparent; +} +.admin-action-btn.is-primary:hover { + box-shadow: 0 6px 18px rgba(var(--page-rgb, var(--accent-rgb)), 0.40); +} + /* ============================================================ Admin → System (in-depth statistics page) ============================================================ */ diff --git a/containers/libreportal/frontend/js/components/admin/admin-overview.js b/containers/libreportal/frontend/js/components/admin/admin-overview.js index 7ceb40f..b414430 100644 --- a/containers/libreportal/frontend/js/components/admin/admin-overview.js +++ b/containers/libreportal/frontend/js/components/admin/admin-overview.js @@ -170,9 +170,10 @@ class AdminOverview { if (vDisp) updBody += this.integrityLine(vDisp); // Update now takes priority when one's available; otherwise offer Verify now. + const updPage = 'style="--page:var(--page-updates);--page-rgb:var(--page-updates-rgb)"'; const updActions = (updAvail && upd.can_update) - ? `` - : ``; + ? `` + : ``; const updCard = this.card( 'Updates', @@ -194,7 +195,7 @@ class AdminOverview { this.line('Apps protected', `${protectedApps} / ${apps.length}`) + this.line('Locations', String(locs.length)) + this.line('Stored', this.bytes(totalSize)), - `` + `` ); // SSH & Security @@ -209,7 +210,7 @@ class AdminOverview { this.line('Password login', pwOn ? 'On' : 'Key-only') + this.line('Authorized keys', String(keyCount)) + this.line('Login user', s.user || '—'), - `` + `` ); // System health @@ -226,7 +227,7 @@ class AdminOverview { ? `${this.gb(mem.used)} / ${this.gb(mem.total)} (${Math.round(mem.percent) || 0}%)` : (mem.text || '—')) + this.line('Uptime', this.shortUptime(info.uptime)), - `` + `` ); root.innerHTML = `