diff --git a/pkg/service/soundtouchweb/static/css/app.css b/pkg/service/soundtouchweb/static/css/app.css
index 23518c6..6c8f673 100644
--- a/pkg/service/soundtouchweb/static/css/app.css
+++ b/pkg/service/soundtouchweb/static/css/app.css
@@ -274,7 +274,10 @@ img { display: block; max-width: 100%; }
font-size: 1.1rem;
padding: .25rem .4rem;
border-radius: 4px;
- line-height: 1;
+ line-height: 0;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
transition: opacity .15s;
}
.btn-icon:hover { opacity: .7; }
@@ -422,6 +425,10 @@ img { display: block; max-width: 100%; }
border: 1px solid var(--border);
background: var(--surface);
color: var(--text);
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ line-height: 1;
transition: background .12s;
}
.ctrl-btn:hover { background: var(--bg); }
@@ -429,7 +436,7 @@ img { display: block; max-width: 100%; }
.ctrl-btn.active { background: var(--accent); color: var(--accent-fg); border-color: var(--accent); }
.volume-row { display: flex; align-items: center; gap: .75rem; }
-.volume-icon { font-size: 1rem; }
+.volume-icon { display: flex; align-items: center; }
.volume-slider { flex: 1; accent-color: var(--accent); }
.volume-value { font-size: .8rem; color: var(--text-dim); min-width: 2.5ch; text-align: right; }
diff --git a/pkg/service/soundtouchweb/static/js/app.js b/pkg/service/soundtouchweb/static/js/app.js
index 910a280..f2507cd 100644
--- a/pkg/service/soundtouchweb/static/js/app.js
+++ b/pkg/service/soundtouchweb/static/js/app.js
@@ -31,7 +31,12 @@ function DeviceDetail({ deviceId, devices, onBack }) {
<${NowPlaying} nowPlaying=${device.status?.nowPlaying} deviceId=${deviceId} presets=${device.status?.presets} />
<${Controls} deviceId=${deviceId} status=${device.status} />
diff --git a/pkg/service/soundtouchweb/static/js/components/Controls.js b/pkg/service/soundtouchweb/static/js/components/Controls.js
index cacbd52..0b103c0 100644
--- a/pkg/service/soundtouchweb/static/js/components/Controls.js
+++ b/pkg/service/soundtouchweb/static/js/components/Controls.js
@@ -5,6 +5,44 @@ import { api } from '../api.js';
const html = htm.bind(h);
+// Flat SVG icons using stroke/fill="currentColor" so they automatically
+// follow the button's text colour in light mode, dark mode, and in the
+// accent-inverted active state — no CSS filter needed.
+
+function IconVolume({ muted = false, size = 20 }) {
+ if (muted) {
+ return html`
`;
+ }
+ return html`
`;
+}
+
+function IconShuffle() {
+ return html`
`;
+}
+
+function IconRepeat({ one = false }) {
+ return html`
`;
+}
+
export function Controls({ deviceId, status }) {
const np = status?.nowPlaying;
const isPlaying = np?.PlayStatus === 'PLAY_STATE';
@@ -45,8 +83,6 @@ export function Controls({ deviceId, status }) {
else send('REPEAT_OFF');
}
- const repeatIcon = repeat === 'REPEAT_ONE' ? '🔂' : '🔁';
-
return html`
@@ -56,13 +92,17 @@ export function Controls({ deviceId, status }) {
+
+
-
-
- 🔈
+ ${IconVolume({ size: 16 })}
${localVolume}
@@ -77,4 +117,4 @@ export function Controls({ deviceId, status }) {
`}
`;
-}
\ No newline at end of file
+}