From e2c413d9971c0d92a3ccac884acf4b774d68472a Mon Sep 17 00:00:00 2001 From: rope Date: Sat, 1 Aug 2026 13:32:26 +0100 Subject: [PATCH] quickshell: derive surfaces from base00, fix status colours Stylix base01/base02 come off the wallpaper and land off-hue (purple card over a slate bar). Tint base00 instead: #1c1f26 -> #2f3440 -> #434a5b. base08-base0C collapse to the same cyan on monochrome wallpapers, so warning and critical were indistinguishable. Replace with fixed err/warn/ ok/info/alt tokens; base0D stays the themed accent. Also fixes Theme.base06, which was referenced but never declared. Co-Authored-By: Claude Opus 5 --- settings/quickshell.nix | 102 +++++++++++++++++++++++----------------- 1 file changed, 59 insertions(+), 43 deletions(-) diff --git a/settings/quickshell.nix b/settings/quickshell.nix index 6fdfdb2..b7ee0c0 100644 --- a/settings/quickshell.nix +++ b/settings/quickshell.nix @@ -265,26 +265,42 @@ in import QtQuick QtObject { + // ── Surfaces: one hue, three steps. base01/base02 are tints of + // base00 rather than stylix's own base01/base02, which come + // straight off the wallpaper and routinely land off-hue — a + // purple card floating over a slate bar. Tinting keeps + // bar → card → hover reading as one stack. Two numbers, and + // they are the whole surface ladder. readonly property color base00: "#${c.base00}" - readonly property color base01: "#${c.base01}" - readonly property color base02: "#${c.base02}" + readonly property color base01: Qt.lighter(base00, 1.7) // card + readonly property color base02: Qt.lighter(base00, 2.4) // hover / chip / track + // ── Ink, wallpaper-derived: base05 primary, base04 muted, + // base03 disabled (also the border colour). readonly property color base03: "#${c.base03}" readonly property color base04: "#${c.base04}" readonly property color base05: "#${c.base05}" - readonly property color base08: "#${c.base08}" - readonly property color base09: "#${c.base09}" - readonly property color base0A: "#${c.base0A}" - readonly property color base0B: "#${c.base0B}" - readonly property color base0C: "#${c.base0C}" + // The one themed accent: active, focused, selected, filled. readonly property color base0D: "#${c.base0D}" - readonly property color barBg: "#B3${c.base00}" + + // ── Status colours, deliberately NOT wallpaper-derived. + // stylix's base08-base0F all collapse to near-identical values + // on a monochrome wallpaper, which leaves "battery critical" + // and "battery low" the same colour. Status has to stay legible + // whatever is on the desktop, so these are fixed. + readonly property color err: "#e0525f" // critical: temp ≥85, batt ≤15, auth failed + readonly property color warn: "#e0a44b" // caution: temp ≥70, batt ≤30 + readonly property color ok: "#68c17c" // connected / active / net down + readonly property color info: "#5aa6e0" // memory + readonly property color alt: "#b98ce0" // net up + + readonly property color barBg: Qt.rgba(base00.r, base00.g, base00.b, 0.70) // Card surfaces are translucent so the compositor's bar-layer // blur shows through — a lessened blur over the panel tint. - readonly property color cardBg: "#CC${c.base01}" + readonly property color cardBg: Qt.rgba(base01.r, base01.g, base01.b, 0.80) // Transparent base02: hover highlights fade to/from this so the // colour animation stays in-hue instead of dipping through // transparent *black* (which reads as an extra flash colour). - readonly property color base02t: "#00${c.base02}" + readonly property color base02t: Qt.rgba(base02.r, base02.g, base02.b, 0) readonly property string fontFamily: "${sansFont}" // Ligature-based icon font: text "wifi-high" renders the icon readonly property string iconFont: "lucide" @@ -445,7 +461,7 @@ in color: Theme.cardBg border.width: Theme.borderWidth border.color: pam.active ? Theme.base0D - : root.failed ? Theme.base08 + : root.failed ? Theme.err : Theme.base03 Behavior on border.color { ColorAnimation { duration: Theme.animFade } } @@ -465,7 +481,7 @@ in anchors.centerIn: parent visible: pwInput.text === "" && root.failed text: "wrong password" - color: Theme.base08 + color: Theme.err font.family: Theme.fontFamily font.pixelSize: 13 } @@ -662,7 +678,7 @@ in text: modelData[0] font.family: Theme.fontFamily font.pixelSize: 13 - color: Theme.base0A + color: Theme.base0D } Text { text: modelData[1] @@ -1140,7 +1156,7 @@ in radius: parent.knobD / 2 anchors.verticalCenter: parent.verticalCenter x: Math.max(0, Math.min(parent.width - parent.knobD, parent.value * parent.width - parent.knobD / 2)) - color: Theme.base06 + color: Theme.base05 Behavior on x { NumberAnimation { duration: 80 } } } MouseArea { @@ -1216,7 +1232,7 @@ in width: parent.width - nlTempLabel.width - 8 anchors.verticalCenter: parent.verticalCenter value: _nlc.nl.warmth - fillColor: Theme.base09 + fillColor: Theme.warn onMoved: (v) => bar.shellRoot.setNightlight(_nlc.nl.autoOn, v) } SText { @@ -2179,24 +2195,24 @@ in value: srvWidget.connected && srvWidget.memTotal > 0 ? Math.round(100 * srvWidget.memUsed / srvWidget.memTotal) + "%" : "--" caption: "ram" - valueColor: srvWidget.connected ? Theme.base0C : Theme.base03 + valueColor: srvWidget.connected ? Theme.info : Theme.base03 } GlanceStat { value: srvWidget.connected && srvWidget.tempC >= 0 ? srvWidget.tempC + "°" : "--" caption: "temp" valueColor: !srvWidget.connected || srvWidget.tempC < 0 ? Theme.base03 - : srvWidget.tempC >= 85 ? Theme.base08 - : srvWidget.tempC >= 70 ? Theme.base0A : Theme.base05 + : srvWidget.tempC >= 85 ? Theme.err + : srvWidget.tempC >= 70 ? Theme.warn : Theme.base05 } GlanceStat { value: srvWidget.connected ? srvWidget.rateVal(srvWidget.rxBps) : "--" caption: "↓ " + srvWidget.rateUnit(srvWidget.rxBps) - valueColor: srvWidget.connected ? Theme.base0B : Theme.base03 + valueColor: srvWidget.connected ? Theme.ok : Theme.base03 } GlanceStat { value: srvWidget.connected ? srvWidget.rateVal(srvWidget.txBps) : "--" caption: "↑ " + srvWidget.rateUnit(srvWidget.txBps) - valueColor: srvWidget.connected ? Theme.base09 : Theme.base03 + valueColor: srvWidget.connected ? Theme.alt : Theme.base03 } GlanceStat { value: srvWidget.pingMs < 0 ? "--" @@ -2520,8 +2536,8 @@ in id: batteryIconText anchors.horizontalCenter: parent.horizontalCenter text: batteryWidget.batteryIcon - color: batteryWidget.batteryLevel <= 15 ? Theme.base08 - : batteryWidget.batteryLevel <= 30 ? Theme.base0A + color: batteryWidget.batteryLevel <= 15 ? Theme.err + : batteryWidget.batteryLevel <= 30 ? Theme.warn : Theme.base05 font.pixelSize: 18 } @@ -2530,8 +2546,8 @@ in id: batteryText anchors.horizontalCenter: parent.horizontalCenter text: batteryWidget.batteryLevel - color: batteryWidget.batteryLevel <= 15 ? Theme.base08 - : batteryWidget.batteryLevel <= 30 ? Theme.base0A + color: batteryWidget.batteryLevel <= 15 ? Theme.err + : batteryWidget.batteryLevel <= 30 ? Theme.warn : Theme.base05 font.pixelSize: 10 } @@ -2697,7 +2713,7 @@ in SIcon { anchors.centerIn: parent text: "power" - color: powerMa.containsMouse || sessionMenu.open ? Theme.base08 : Theme.base05 + color: powerMa.containsMouse || sessionMenu.open ? Theme.err : Theme.base05 font.pixelSize: 18 Behavior on color { ColorAnimation { duration: Theme.animFade } } } @@ -3148,7 +3164,7 @@ in SIcon { anchors.verticalCenter: parent.verticalCenter text: "server" - color: srvWidget.connected ? Theme.base0B : Theme.base08 + color: srvWidget.connected ? Theme.ok : Theme.err } SText { anchors.verticalCenter: parent.verticalCenter @@ -3163,7 +3179,7 @@ in ? "up " + srvWidget.uptime + " • load " + srvWidget.load : "unreachable" font.pixelSize: 12 - color: srvWidget.connected ? Theme.base04 : Theme.base08 + color: srvWidget.connected ? Theme.base04 : Theme.err elide: Text.ElideRight } @@ -3175,7 +3191,7 @@ in width: parent.width - 42 - 76 - 20 anchors.verticalCenter: parent.verticalCenter value: srvWidget.cpu / 100 - fillColor: srvWidget.cpu >= 90 ? Theme.base08 : Theme.base0D + fillColor: srvWidget.cpu >= 90 ? Theme.err : Theme.base0D } SText { width: 76 @@ -3194,7 +3210,7 @@ in width: parent.width - 42 - 76 - 20 anchors.verticalCenter: parent.verticalCenter value: srvWidget.memTotal > 0 ? srvWidget.memUsed / srvWidget.memTotal : 0 - fillColor: Theme.base0C + fillColor: Theme.info } SText { width: 76 @@ -3213,8 +3229,8 @@ in text: srvWidget.tempC < 0 ? "--" : srvWidget.tempC + "°C" font.weight: Font.Medium color: srvWidget.tempC < 0 ? Theme.base03 - : srvWidget.tempC >= 85 ? Theme.base08 - : srvWidget.tempC >= 70 ? Theme.base0A : Theme.base05 + : srvWidget.tempC >= 85 ? Theme.err + : srvWidget.tempC >= 70 ? Theme.warn : Theme.base05 } } @@ -3226,7 +3242,7 @@ in spacing: 14 Row { spacing: 4 - SIcon { text: "arrow-down"; font.pixelSize: 14; color: Theme.base0B; anchors.verticalCenter: parent.verticalCenter } + SIcon { text: "arrow-down"; font.pixelSize: 14; color: Theme.ok; anchors.verticalCenter: parent.verticalCenter } SText { text: srvWidget.fmtRate(srvWidget.rxBps) font.weight: Font.Medium @@ -3235,7 +3251,7 @@ in } Row { spacing: 4 - SIcon { text: "arrow-up"; font.pixelSize: 14; color: Theme.base09; anchors.verticalCenter: parent.verticalCenter } + SIcon { text: "arrow-up"; font.pixelSize: 14; color: Theme.alt; anchors.verticalCenter: parent.verticalCenter } SText { text: srvWidget.fmtRate(srvWidget.txBps) font.weight: Font.Medium @@ -3298,8 +3314,8 @@ in width: 56 text: modelData.cpu.toFixed(1) horizontalAlignment: Text.AlignRight - color: modelData.cpu >= 100 ? Theme.base08 - : modelData.cpu >= 25 ? Theme.base0A : Theme.base05 + color: modelData.cpu >= 100 ? Theme.err + : modelData.cpu >= 25 ? Theme.warn : Theme.base05 anchors.verticalCenter: parent.verticalCenter } SText { @@ -3550,7 +3566,7 @@ in height: 16 trackH: 4 value: modelData.audio ? Math.min(1, modelData.audio.volume) : 0 - fillColor: modelData.audio && modelData.audio.muted ? Theme.base03 : Theme.base0C + fillColor: modelData.audio && modelData.audio.muted ? Theme.base03 : Theme.base0D onMoved: (v) => { if (modelData.audio) modelData.audio.volume = v; } } @@ -3626,7 +3642,7 @@ in SText { anchors.centerIn: parent text: "Disconnect" - color: Theme.base08 + color: Theme.err font.pixelSize: 12 } } @@ -3677,14 +3693,14 @@ in if (s >= 40) return "wifi-low"; return "wifi-zero"; } - color: modelData.active ? Theme.base0B : Theme.base04 + color: modelData.active ? Theme.ok : Theme.base04 font.pixelSize: 16 anchors.verticalCenter: parent.verticalCenter } SText { text: modelData.ssid - color: modelData.active ? Theme.base0B : Theme.base05 + color: modelData.active ? Theme.ok : Theme.base05 font.pixelSize: 12 elide: Text.ElideRight width: 140 @@ -4222,7 +4238,7 @@ in SIcon { anchors.horizontalCenter: parent.horizontalCenter text: calPopup.weatherGlyph(modelData.code) - color: Theme.base0C + color: Theme.base0D font.pixelSize: 16 } SText { @@ -4344,7 +4360,7 @@ in width: 3 radius: 1.5 height: 3 + lvl * 13 - color: Theme.base0C + color: Theme.base0D opacity: 0.35 + lvl * 0.65 x: vinyl.width / 2 - width / 2 y: vinyl.height / 2 - vinyl.ringR - height @@ -4588,7 +4604,7 @@ in height: 16 trackH: 4 value: mediaCard.pwNode && mediaCard.pwNode.audio ? Math.min(1, mediaCard.pwNode.audio.volume) : 0 - fillColor: mediaCard.pwNode && mediaCard.pwNode.audio && mediaCard.pwNode.audio.muted ? Theme.base03 : Theme.base0C + fillColor: mediaCard.pwNode && mediaCard.pwNode.audio && mediaCard.pwNode.audio.muted ? Theme.base03 : Theme.base0D onMoved: (v) => { if (mediaCard.pwNode && mediaCard.pwNode.audio) mediaCard.pwNode.audio.volume = v; } } @@ -4782,7 +4798,7 @@ in Connections { target: bar.shellRoot function onOsdBrightness(icon, value) { - osdItem.show(icon, value, Theme.base0A); + osdItem.show(icon, value, Theme.base0D); } }