From 34ded6b4413df26e905f18df36c29f1e75aaa6b3 Mon Sep 17 00:00:00 2001 From: DanS Date: Sat, 4 Jul 2026 14:07:36 -0500 Subject: [PATCH] feat(ui): shutdown-screen consistency polish (Phase 3) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The two Phase 3 "bespoke overlays" aren't content modals: the send-error is an in-tab glass banner (already consistent — left as-is), and the shutdown screen is a teardown screen where a blur backdrop would be semantically wrong (should read as "closing") + risky on the teardown path. Per that finding, apply minor consistency polish to the shutdown screen only: - Share the overlay-scrim tone via a new material::OverlayScrimColor(opacity), used by both the dialog scrim and the shutdown scrim (was a slightly different hardcoded 0.06/0.06/0.08 → now the 0.04/0.04/0.06 dialog base). - "Shutting Down" title → theme Warning() amber (was hardcoded gold). - Force-Quit confirm destructive button → theme Error() (alpha-varied) instead of hardcoded reds. No behavior change; the shutdown scrim stays opaque (no blur). Co-Authored-By: Claude Opus 4.8 (1M context) --- src/app.cpp | 13 ++++++++----- src/ui/material/draw_helpers.h | 6 +++++- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/app.cpp b/src/app.cpp index e0aaae4..a7a08b2 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -3425,7 +3425,9 @@ void App::renderShutdownScreen() ImGui::SetNextWindowPos(vp_pos); ImGui::SetNextWindowSize(vp_size); ImGui::SetNextWindowFocus(); - ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(0.06f, 0.06f, 0.08f, 0.92f)); + // Shared overlay-scrim tone (matches dialog backdrops); the shutdown screen stays an opaque + // scrim (no blur) so it reads as "closing", not a modal over your work. + ImGui::PushStyleColor(ImGuiCol_WindowBg, OverlayScrimColor(0.92f)); ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f); ImGuiWindowFlags shutdownFlags = @@ -3464,7 +3466,7 @@ void App::renderShutdownScreen() ImGui::PushFont(Type().h5()); ImVec2 ts = ImGui::CalcTextSize(title); ImGui::SetCursorPosX(cx - ts.x * 0.5f); - ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 0.85f, 0.0f, 1.0f)); + ImGui::PushStyleColor(ImGuiCol_Text, ImGui::ColorConvertU32ToFloat4(Warning())); // theme amber ImGui::TextUnformatted(title); ImGui::PopStyleColor(); ImGui::PopFont(); @@ -3578,9 +3580,10 @@ void App::renderShutdownScreen() ImGui::CloseCurrentPopup(); } ImGui::SameLine(); - ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.6f, 0.15f, 0.15f, 0.9f)); - ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.75f, 0.2f, 0.2f, 1.0f)); - ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0.5f, 0.1f, 0.1f, 1.0f)); + // Destructive action — theme error color (alpha-varied for hover/active) instead of hardcoded red. + ImGui::PushStyleColor(ImGuiCol_Button, ImGui::ColorConvertU32ToFloat4(WithAlpha(Error(), 210))); + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImGui::ColorConvertU32ToFloat4(Error())); + ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImGui::ColorConvertU32ToFloat4(WithAlpha(Error(), 160))); if (ImGui::Button(TR("force_quit_yes"), ImVec2(btnW, 0))) { DEBUG_LOGF("Force quit confirmed by user after %.0fs\n", shutdown_timer_); shutdown_complete_ = true; diff --git a/src/ui/material/draw_helpers.h b/src/ui/material/draw_helpers.h index f285f13..9325b92 100644 --- a/src/ui/material/draw_helpers.h +++ b/src/ui/material/draw_helpers.h @@ -1129,6 +1129,10 @@ inline int SegmentedControl(ImDrawList* dl, ImVec2 origin, float totalW, float h inline std::unordered_map g_overlayCardHeights; inline std::string g_overlayCurrentKey; +// The dark base color for any full-window overlay backdrop (dialog scrims + the shutdown screen), +// so every overlay shares one backdrop tone. `opacity` is the alpha (dialogs vary it per call). +inline ImVec4 OverlayScrimColor(float opacity) { return ImVec4(0.04f, 0.04f, 0.06f, opacity); } + // Style of an overlay dialog. GlassCard = the classic scrim + glass card + boxed title bar. // BlurFloat = the "Manage Portfolio" look: live-blur backdrop + floating content + plain heading. enum class OverlayStyle { GlassCard, BlurFloat }; @@ -1173,7 +1177,7 @@ inline bool BeginOverlayDialog(const OverlayDialogSpec& spec) if (!overlayPopupOpen) ImGui::SetNextWindowFocus(); // Blur overlays draw their own backdrop, so the window itself is transparent. ImGui::PushStyleColor(ImGuiCol_WindowBg, - blur ? ImVec4(0, 0, 0, 0) : ImVec4(0.04f, 0.04f, 0.06f, spec.scrimOpacity)); + blur ? ImVec4(0, 0, 0, 0) : OverlayScrimColor(spec.scrimOpacity)); ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f); ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0));