diff --git a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/app.js b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/app.js
index 4a6c391..a73fe61 100644
--- a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/app.js
+++ b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/app.js
@@ -1364,6 +1364,12 @@ function renderRdsOverlays() {
evt.stopPropagation();
copyRdsPsToClipboard(entry.rds, entry.freq_hz);
});
+ el.addEventListener("mouseenter", () => {
+ el.style.zIndex = String(entries.length + 10);
+ });
+ el.addEventListener("mouseleave", () => {
+ if (el.dataset.defaultZ) el.style.zIndex = el.dataset.defaultZ;
+ });
rdsPsOverlay.appendChild(el);
rdsOverlayEntries.push({ ...entry, el, stackIdx: idx });
});
@@ -1386,6 +1392,10 @@ function positionRdsOverlays() {
const count = rdsOverlayEntries.length;
const mid = (count - 1) / 2;
const stackStepPx = 26;
+ // Assign z-indices: sort by frequency ascending so higher-frequency layers
+ // sit on top of lower-frequency ones in the default (non-hover) state.
+ const sortedByFreq = [...rdsOverlayEntries].sort((a, b) => a.freq_hz - b.freq_hz);
+ const freqZMap = new Map(sortedByFreq.map((e, i) => [e.id, i + 1]));
rdsOverlayEntries.forEach((entry, idx) => {
const el = entry.el;
if (!el) return;
@@ -1399,6 +1409,9 @@ function positionRdsOverlays() {
const offsetPx = Math.round((idx - mid) * stackStepPx);
el.style.left = `${clamped * width}px`;
el.style.top = `calc(50% + ${offsetPx}px)`;
+ const z = String(freqZMap.get(entry.id) ?? (idx + 1));
+ el.style.zIndex = z;
+ el.dataset.defaultZ = z;
});
}
diff --git a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/index.html b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/index.html
index bc716b1..131338e 100644
--- a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/index.html
+++ b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/index.html
@@ -262,7 +262,6 @@
Signal
diff --git a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/plugins/vchan.js b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/plugins/vchan.js
index c3ea228..3e64708 100644
--- a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/plugins/vchan.js
+++ b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/plugins/vchan.js
@@ -49,50 +49,6 @@ function vchanHandleChannels(data) {
}
}
-function vchanRenderLayers() {
- const container = document.getElementById("vchan-freq-layers");
- if (!container) return;
- container.innerHTML = "";
-
- if (vchanChannels.length === 0) {
- container.style.height = "0";
- return;
- }
-
- // Sort by frequency ascending so higher-frequency channels get higher z-index.
- const sorted = [...vchanChannels].sort((a, b) => a.freq_hz - b.freq_hz);
-
- const LAYER_H_PX = 32;
- const STEP_PX = 11; // vertical offset between layers so each peeks below the next
- const totalH = LAYER_H_PX + (sorted.length - 1) * STEP_PX;
- container.style.height = totalH + "px";
-
- sorted.forEach((ch, i) => {
- const layer = document.createElement("div");
- layer.className = "vchan-freq-layer";
- if (ch.id === vchanActiveId) layer.classList.add("active");
-
- layer.style.top = (i * STEP_PX) + "px";
- // Higher frequency → higher index → higher z-index (sits on top by default).
- const defaultZ = i + 1;
- layer.style.zIndex = defaultZ;
-
- layer.textContent = `${ch.index}: ${vchanFmtFreq(ch.freq_hz)} ${ch.mode}`;
- layer.title = `Ch ${ch.index}: ${vchanFmtFreq(ch.freq_hz)} ${ch.mode} · ${ch.subscribers} subscriber${ch.subscribers !== 1 ? "s" : ""}`;
-
- // Bring hovered layer to the front; restore on leave.
- const maxZ = sorted.length + 10;
- layer.addEventListener("mouseenter", () => { layer.style.zIndex = maxZ; });
- layer.addEventListener("mouseleave", () => { layer.style.zIndex = defaultZ; });
-
- layer.addEventListener("click", () => {
- if (ch.id !== vchanActiveId) vchanSubscribe(ch.id);
- });
-
- container.appendChild(layer);
- });
-}
-
function vchanRender() {
const picker = document.getElementById("vchan-picker");
if (!picker) return;
@@ -137,7 +93,6 @@ function vchanRender() {
addBtn.addEventListener("click", vchanAllocate);
picker.appendChild(addBtn);
- vchanRenderLayers();
vchanSyncAccentUI();
}
diff --git a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/style.css b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/style.css
index 5696ca2..81c8e7f 100644
--- a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/style.css
+++ b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/style.css
@@ -392,44 +392,6 @@ input.status-input, select.status-input { width: 100%; padding: 0.45rem 0.5rem;
border-color: var(--vchan-color);
box-shadow: inset 3px 0 0 var(--vchan-color);
}
-/* Frequency layers: absolutely-positioned channel strips stacked by frequency */
-.vchan-freq-layers {
- position: relative;
- margin-top: 0.5rem;
- /* height is set dynamically by vchanRenderLayers() */
-}
-.vchan-freq-layer {
- position: absolute;
- left: 0;
- right: 0;
- height: 2rem;
- display: flex;
- align-items: center;
- padding: 0 0.6rem;
- border-radius: 6px;
- background: var(--input-bg);
- border: 1px solid var(--border-light);
- font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
- font-size: 0.82rem;
- color: var(--text-muted);
- cursor: pointer;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
- transition: border-color 0.12s, box-shadow 0.12s;
-}
-.vchan-freq-layer:hover {
- border-color: var(--vchan-color);
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.35);
- color: var(--text);
-}
-.vchan-freq-layer.active {
- background: var(--btn-bg);
- color: var(--text);
- font-weight: 600;
- border-color: var(--vchan-color);
- box-shadow: inset 3px 0 0 var(--vchan-color);
-}
/* Applied to #freq and #spectrum-bw-input when on a virtual channel */
.vchan-ch-active {
border-color: var(--vchan-color) !important;