diff --git a/modules/Bar.qml b/modules/Bar.qml index 6e28c3a..bc80690 100644 --- a/modules/Bar.qml +++ b/modules/Bar.qml @@ -40,39 +40,68 @@ PanelWindow { ctx.clearRect(0, 0, w, h); - // Horizontal gradient for the border + // Opaque backing behind the stroke + ctx.fillStyle = M.Theme.base00.toString(); + ctx.beginPath(); + if (r > lw) { + ctx.moveTo(0, r); + ctx.arc(r, r, r, Math.PI, -Math.PI / 2); + ctx.lineTo(w - r, 0); + ctx.arc(w - r, r, r, -Math.PI / 2, 0); + ctx.lineTo(w, lw); + ctx.lineTo(0, lw); + } else { + ctx.rect(0, 0, w, lw); + } + ctx.fill(); + + // Glow below the stroke — fades from gradient color to transparent + const glowH = h - lw; + if (glowH > 0) { + const glowGrad = ctx.createLinearGradient(0, lw, 0, h); + glowGrad.addColorStop(0, "rgba(255,255,255,0.06)"); + glowGrad.addColorStop(1, "transparent"); + + // Use the horizontal gradient as a mask via compositing + const hGrad = ctx.createLinearGradient(0, 0, w, 0); + hGrad.addColorStop(0, M.Theme.base0C.toString()); + hGrad.addColorStop(1, M.Theme.base09.toString()); + + // Draw vertical fade strip + ctx.globalAlpha = 0.12; + ctx.fillStyle = hGrad; + ctx.fillRect(0, lw, w, glowH); + + // Erase bottom portion with transparent fade + ctx.globalAlpha = 1; + ctx.globalCompositeOperation = "destination-out"; + const eraseGrad = ctx.createLinearGradient(0, lw, 0, h); + eraseGrad.addColorStop(0, "transparent"); + eraseGrad.addColorStop(1, "black"); + ctx.fillStyle = eraseGrad; + ctx.fillRect(0, lw, w, glowH); + ctx.globalCompositeOperation = "source-over"; + } + + // Gradient stroke + ctx.globalAlpha = 1; const grad = ctx.createLinearGradient(0, 0, w, 0); grad.addColorStop(0, M.Theme.base0C.toString()); grad.addColorStop(1, M.Theme.base09.toString()); ctx.strokeStyle = grad; ctx.lineWidth = lw; - // Stroke: top + left side + right side (open bottom) - // Left side down, curve, across top, curve, right side down ctx.beginPath(); if (r > lw) { - ctx.moveTo(hw, h); - ctx.lineTo(hw, r); + ctx.moveTo(0, r); ctx.arc(r, r, r - hw, Math.PI, -Math.PI / 2); ctx.lineTo(w - r, hw); ctx.arc(w - r, r, r - hw, -Math.PI / 2, 0); - ctx.lineTo(w - hw, h); } else { - ctx.moveTo(hw, h); - ctx.lineTo(hw, hw); - ctx.lineTo(w - hw, hw); - ctx.lineTo(w - hw, h); + ctx.moveTo(0, hw); + ctx.lineTo(w, hw); } ctx.stroke(); - - // Fade out the bottom of the side borders - ctx.globalCompositeOperation = "destination-out"; - const fadeGrad = ctx.createLinearGradient(0, h * 0.5, 0, h); - fadeGrad.addColorStop(0, "transparent"); - fadeGrad.addColorStop(1, "black"); - ctx.fillStyle = fadeGrad; - ctx.fillRect(0, h * 0.5, w, h * 0.5); - ctx.globalCompositeOperation = "source-over"; } }