From 8b0e20f5bfdf5e101394becd5db9960185df2b46 Mon Sep 17 00:00:00 2001 From: johndoe6345789 Date: Thu, 19 Mar 2026 03:47:59 +0000 Subject: [PATCH] =?UTF-8?q?fix(qt6):=20light=20mode=20overhaul=20=E2=80=94?= =?UTF-8?q?=20softer=20palette,=20theme-aware=20CAppBar,=20persist=20theme?= =?UTF-8?q?=20on=20startup?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Change default primary from green (#10a37f) to indigo (#6366f1/#4f46e5) - Light theme: soft off-white (#f0f0f3) background instead of blinding #ffffff - CAppBar now uses Theme.paper background instead of native ToolBar styling - App.qml calls Theme.setTheme() on startup + on currentTheme change - FrontPage uses isDark flag for all surface/border colors (works both modes) Co-Authored-By: Claude Opus 4.6 (1M context) --- frontends/qt6/App.qml | 12 ++++++++++++ frontends/qt6/FrontPage.qml | 18 ++++++++++-------- qml/components/surfaces/CAppBar.qml | 17 +++++++++++++++++ qml/components/theming/Theme.qml | 6 +++--- 4 files changed, 42 insertions(+), 11 deletions(-) diff --git a/frontends/qt6/App.qml b/frontends/qt6/App.qml index 084b3a382..9adf22360 100644 --- a/frontends/qt6/App.qml +++ b/frontends/qt6/App.qml @@ -335,8 +335,20 @@ ApplicationWindow { property alias authToken: appWindow.authToken } + // ── Restore persisted theme ── + onCurrentThemeChanged: { + if (typeof Theme.setTheme === "function") { + Theme.setTheme(currentTheme) + } + } + // ── Auto-login with persisted token ── Component.onCompleted: { + // Apply saved theme on startup + if (typeof Theme.setTheme === "function") { + Theme.setTheme(currentTheme) + } + if (authToken !== "") { dbalProvider.authToken = authToken dbalProvider.execute("core/auth/validate", { token: authToken }, function(result, error) { diff --git a/frontends/qt6/FrontPage.qml b/frontends/qt6/FrontPage.qml index 6e72e8ef1..380f858b6 100644 --- a/frontends/qt6/FrontPage.qml +++ b/frontends/qt6/FrontPage.qml @@ -37,15 +37,17 @@ Rectangle { Component.onCompleted: loadPlatformStatus() - // ── Palette — cool/techy, no golf ── + // ── Palette — cool/techy, theme-aware ── readonly property color accentBlue: "#6366F1" // indigo-500 readonly property color accentCyan: "#06B6D4" // cyan-500 readonly property color accentViolet: "#8B5CF6" // violet-500 readonly property color accentAmber: "#F59E0B" // amber-500 readonly property color accentRose: "#F43F5E" // rose-500 - readonly property color subtleText: Qt.rgba(1, 1, 1, 0.45) - readonly property color subtleBorder: Qt.rgba(1, 1, 1, 0.08) - readonly property color cardBg: Qt.rgba(1, 1, 1, 0.03) + // Theme-aware surface colors (work in both light and dark) + readonly property bool isDark: Theme.mode === "dark" + readonly property color subtleText: isDark ? Qt.rgba(1, 1, 1, 0.45) : Qt.rgba(0, 0, 0, 0.45) + readonly property color subtleBorder: isDark ? Qt.rgba(1, 1, 1, 0.08) : Qt.rgba(0, 0, 0, 0.08) + readonly property color cardBg: isDark ? Qt.rgba(1, 1, 1, 0.03) : Qt.rgba(0, 0, 0, 0.02) // ── Level definitions ── property var levels: [ @@ -115,14 +117,14 @@ Rectangle { Layout.preferredHeight: 360 color: "transparent" - // Subtle gradient — indigo → transparent → violet + // Subtle gradient — uses accent colors, theme-aware Rectangle { anchors.fill: parent gradient: Gradient { orientation: Gradient.Horizontal - GradientStop { position: 0.0; color: Qt.rgba(0.39, 0.4, 0.95, 0.06) } + GradientStop { position: 0.0; color: Qt.rgba(accentBlue.r, accentBlue.g, accentBlue.b, 0.06) } GradientStop { position: 0.5; color: "transparent" } - GradientStop { position: 1.0; color: Qt.rgba(0.55, 0.36, 0.96, 0.04) } + GradientStop { position: 1.0; color: Qt.rgba(accentViolet.r, accentViolet.g, accentViolet.b, 0.04) } } } @@ -597,7 +599,7 @@ Rectangle { Layout.fillWidth: true Layout.preferredHeight: 56 radius: 6 - color: credMA2.containsMouse ? Qt.rgba(0.39, 0.4, 0.95, 0.06) : cardBg + color: credMA2.containsMouse ? Qt.rgba(accentBlue.r, accentBlue.g, accentBlue.b, 0.06) : cardBg border.color: credMA2.containsMouse ? modelData.accent : subtleBorder border.width: 1 diff --git a/qml/components/surfaces/CAppBar.qml b/qml/components/surfaces/CAppBar.qml index b2b8a0fd7..05005539e 100644 --- a/qml/components/surfaces/CAppBar.qml +++ b/qml/components/surfaces/CAppBar.qml @@ -1,8 +1,25 @@ import QtQuick import QtQuick.Controls import QtQuick.Layouts +import QmlComponents 1.0 ToolBar { id: appbar + + background: Rectangle { + color: Theme.paper + border.color: Theme.border + border.width: 1 + + // Bottom border only + Rectangle { + anchors.bottom: parent.bottom + anchors.left: parent.left + anchors.right: parent.right + height: 1 + color: Theme.border + } + } + RowLayout { anchors.fill: parent } } diff --git a/qml/components/theming/Theme.qml b/qml/components/theming/Theme.qml index 4ef8096bc..726af85fb 100644 --- a/qml/components/theming/Theme.qml +++ b/qml/components/theming/Theme.qml @@ -30,9 +30,9 @@ QtObject { // Theme definitions - matches React themes.js readonly property var themes: ({ - system: { name: "System", mode: "dark", primary: "#10a37f", background: "#0d0d0d", paper: "#1a1a1a", surface: "#242424", text: "#ffffff", textSecondary: "#a0a0a0", border: "#333333", error: "#ef4444", warning: "#f59e0b", success: "#22c55e", info: "#3b82f6" }, - dark: { name: "Dark", mode: "dark", primary: "#10a37f", background: "#0d0d0d", paper: "#1a1a1a", surface: "#242424", text: "#ffffff", textSecondary: "#a0a0a0", border: "#333333", error: "#ef4444", warning: "#f59e0b", success: "#22c55e", info: "#3b82f6" }, - light: { name: "Light", mode: "light", primary: "#10a37f", background: "#ffffff", paper: "#f7f7f8", surface: "#eeeeee", text: "#1a1a1a", textSecondary: "#6e6e80", border: "#e0e0e0", error: "#d32f2f", warning: "#ed6c02", success: "#2e7d32", info: "#0288d1" }, + system: { name: "System", mode: "dark", primary: "#6366f1", background: "#0d0d0d", paper: "#1a1a1a", surface: "#242424", text: "#ffffff", textSecondary: "#a0a0a0", border: "#333333", error: "#ef4444", warning: "#f59e0b", success: "#22c55e", info: "#3b82f6" }, + dark: { name: "Dark", mode: "dark", primary: "#6366f1", background: "#0d0d0d", paper: "#1a1a1a", surface: "#242424", text: "#ffffff", textSecondary: "#a0a0a0", border: "#333333", error: "#ef4444", warning: "#f59e0b", success: "#22c55e", info: "#3b82f6" }, + light: { name: "Light", mode: "light", primary: "#4f46e5", background: "#f0f0f3", paper: "#e8e8ec", surface: "#dddde2", text: "#1a1a2e", textSecondary: "#5a5a72", border: "#c8c8d4", error: "#d32f2f", warning: "#ed6c02", success: "#2e7d32", info: "#0288d1" }, midnight: { name: "Midnight", mode: "dark", primary: "#6366f1", background: "#0f172a", paper: "#1e293b", surface: "#334155", text: "#f1f5f9", textSecondary: "#94a3b8", border: "#334155", error: "#ef4444", warning: "#f59e0b", success: "#22c55e", info: "#3b82f6" }, forest: { name: "Forest", mode: "dark", primary: "#22c55e", background: "#0a1f0a", paper: "#14331a", surface: "#1a4d23", text: "#ecfdf5", textSecondary: "#a7f3d0", border: "#166534", error: "#ef4444", warning: "#f59e0b", success: "#22c55e", info: "#3b82f6" }, ocean: { name: "Ocean", mode: "dark", primary: "#0ea5e9", background: "#0c1929", paper: "#132f4c", surface: "#1e4976", text: "#e0f2fe", textSecondary: "#7dd3fc", border: "#0369a1", error: "#ef4444", warning: "#f59e0b", success: "#22c55e", info: "#0ea5e9" },