fix: keep the see-through bubble readable on light backgrounds

Solid dark tracks looked like black holes and the muted text faded out when the 60% background sat over a light window. Tracks are now tints over the background, a faint edge traces the outline, and text gets a soft halo.
This commit is contained in:
tiennm99 committed 2026-10-27 15:15:27 +07:00
1 parent c7af9ed0ac
commit 3aaf963841
3 files changed
+28 -8

No files matched your search

+20 -8
View File
@@ -1,21 +1,27 @@
/* Bubble palette. Accent and fill colours come from the payload. */
:root[data-theme='dark'] {
/* 60% opaque, so the desktop shows through; text and bars stay solid. */
/* 60% opaque, so the desktop shows through. Tracks and the edge are
tints over it, so they keep the same contrast step on a light or dark
desktop; the text halo keeps text readable on either. */
--bg: rgb(31 31 31 / 60%);
--track: #2c2c2c;
--time-track: #404040;
--track: rgb(0 0 0 / 28%);
--time-track: rgb(255 255 255 / 14%);
--time-fill: #b0b0b0;
--edge: rgb(255 255 255 / 22%);
--text: #eaeaea;
--muted: #a8a8a8;
--muted: #c4c4c4;
--halo: 0 0 2px rgb(0 0 0 / 75%);
}
:root[data-theme='light'] {
--bg: rgb(243 243 243 / 60%);
--track: #e2e2e2;
--time-track: #e0e0e0;
--track: rgb(0 0 0 / 10%);
--time-track: rgb(0 0 0 / 8%);
--time-fill: #666666;
--edge: rgb(0 0 0 / 18%);
--text: #1f1f1f;
--muted: #5e5e5e;
--muted: #4a4a4a;
--halo: 0 0 2px rgb(255 255 255 / 85%);
}
html,
@@ -56,10 +62,15 @@ body {
height: 100%;
}
.rings circle {
.rings circle,
.edge {
fill: none;
}
.edge {
stroke: var(--edge);
}
.ring-track {
stroke: var(--track);
}
@@ -82,6 +93,7 @@ body {
margin: 0;
white-space: nowrap;
color: var(--text);
text-shadow: var(--halo);
}
.head-label {
+1
View File
@@ -9,6 +9,7 @@
<body>
<div class="pill" id="pill">
<svg class="rings" id="rings" aria-hidden="true">
<path class="edge" id="edge"></path>
<circle class="ring-track" id="ring-track"></circle>
<circle class="ring-arc" id="ring-arc"></circle>
<circle class="time-ring-track" id="time-ring-track"></circle>
+7
View File
@@ -59,6 +59,8 @@ const FONT_STACK = '"Segoe UI", system-ui, sans-serif';
/** Weight text is measured at when the caller names none (regular). */
const MEASURE_WEIGHT = 400;
const HEAD_LABEL_WEIGHT = 600;
/** Outline stroke in CSS px; the clip keeps the inner half. */
const EDGE_STROKE = 2;
const slug = windowLabel.replace(/^bubble-/, '');
@@ -80,6 +82,8 @@ function byId(id) {
const pill = byId('pill');
/** @type {SVGSVGElement} */
const rings = byId('rings');
/** @type {SVGPathElement} */
const edge = byId('edge');
/** @type {SVGCircleElement} */
const ringTrack = byId('ring-track');
/** @type {SVGCircleElement} */
@@ -221,6 +225,9 @@ function relayout(p) {
const outline = outlinePath(cssPx(p.canvasW, p.dpi), cssPx(p.canvasH, p.dpi));
pill.style.clipPath = `path('${outline}')`;
rings.setAttribute('viewBox', `0 0 ${p.canvasW} ${p.canvasH}`);
// Half the stroke falls outside the clip, leaving a 1 px edge.
edge.setAttribute('d', outlinePath(p.canvasW, p.canvasH));
edge.setAttribute('stroke-width', String((EDGE_STROKE * p.dpi) / BASE_DPI));
placeCircle(ringTrack, head.ringCx, head.ringCy, head.ringRadius, head.ringStroke);
placeCircle(ringArc, head.ringCx, head.ringCy, head.ringRadius, head.ringStroke);
placeCircle(timeRingTrack, head.ringCx, head.ringCy, head.timeRingRadius, head.timeRingStroke);