diff --git a/onchain_scout_gate/static/app.js b/onchain_scout_gate/static/app.js
index 9d2d4eb..d0315ad 100644
--- a/onchain_scout_gate/static/app.js
+++ b/onchain_scout_gate/static/app.js
@@ -430,7 +430,14 @@ async function saveDailyReportSettings() {
}
}
+function isPanelFolded(foldId) {
+ const panel = document.querySelector(`.matrix-panel-fold[data-fold-id="${foldId}"]`);
+ return !!(panel && panel.classList.contains("is-folded"));
+}
+
async function refresh() {
+ if (document.visibilityState !== "visible") return;
+ const mobileLite = isMobileLite();
try {
const funnelWindowH = getFunnelWindowHours();
const [status, alerts, logs, config, funnel, dailyReport] = await Promise.all([
@@ -445,8 +452,16 @@ async function refresh() {
const statusPre = document.getElementById("status");
const cf = document.getElementById("config");
- if (statusPre) statusPre.textContent = pretty(status);
- if (cf) cf.textContent = pretty(config);
+ if (!mobileLite) {
+ if (statusPre) {
+ const st = pretty(status);
+ if (statusPre.textContent !== st) statusPre.textContent = st;
+ }
+ if (cf) {
+ const cfgTxt = pretty(config);
+ if (cf.textContent !== cfgTxt) cf.textContent = cfgTxt;
+ }
+ }
const runState = (status && status.state) || {};
const funnelWindowApplied =
@@ -497,7 +512,8 @@ async function refresh() {
const watchRows = allAlerts.filter((a) => (a.details && a.details.signal_level) === "WATCH");
const triggerRows = allAlerts.filter((a) => (a.details && a.details.signal_level) === "TRIGGER");
- renderItems("watchAlerts", watchRows, (a) => `
+ if (!mobileLite || !isPanelFolded("scan-layers")) {
+ renderItems("watchAlerts", watchRows, (a) => `
${a.symbol} ${escapeHtml(a.chain || "")}
级别: ${(a.details && a.details.signal_level) || "N/A"}
信号: ${(a.trigger_types || []).join(" · ")}
@@ -523,11 +539,14 @@ async function refresh() {
${formatIsoToBeijing(a.created_at)}
`);
}
+ }
- renderItems("logs", logs.items || [], (l) => `
+ if (!mobileLite || !isPanelFolded("runtime-logs")) {
+ renderItems("logs", logs.items || [], (l) => `
[${l.level}] ${escapeHtml(l.message)}
${formatIsoToBeijing(l.created_at)}
`);
+ }
} catch (error) {
console.error("refresh failed", error);
setText("hudLink", "ERR");
@@ -536,8 +555,25 @@ async function refresh() {
}
}
-/** 轻量 Canvas 代码雨(仅 dashboard 有 canvas) */
+/** 手机 / 触控:关闭重动画与代码雨,减轻闪屏与发热 */
+function isMobileLite() {
+ return (
+ document.documentElement.classList.contains("matrix-lite") ||
+ window.matchMedia("(max-width: 640px), (hover: none) and (pointer: coarse)").matches
+ );
+}
+
+function applyMobileLiteClass() {
+ if (isMobileLite()) {
+ document.documentElement.classList.add("matrix-lite");
+ document.body.classList.add("matrix-lite");
+ }
+}
+
+/** 轻量 Canvas 代码雨(仅 dashboard 有 canvas;手机端不启动) */
function initMatrixRain() {
+ applyMobileLiteClass();
+ if (isMobileLite()) return;
const canvas = document.getElementById("matrixRain");
if (!canvas || !canvas.getContext) return;
const ctx = canvas.getContext("2d");
@@ -843,7 +879,8 @@ initMatrixRain();
initFunnelWindowControls();
initPanelFolds();
refresh();
-setInterval(refresh, 4000);
+const REFRESH_MS = isMobileLite() ? 10000 : 4000;
+setInterval(refresh, REFRESH_MS);
document.addEventListener("visibilitychange", () => {
if (document.visibilityState === "visible") refresh();
});
diff --git a/onchain_scout_gate/static/style.css b/onchain_scout_gate/static/style.css
index 36cff7e..d6ae676 100644
--- a/onchain_scout_gate/static/style.css
+++ b/onchain_scout_gate/static/style.css
@@ -1647,12 +1647,60 @@ body.matrix-theme {
}
.matrix-rain-canvas {
- opacity: 0.3;
+ display: none !important;
}
.matrix-scanlines,
- .matrix-noise {
- opacity: 0.45;
+ .matrix-noise,
+ .matrix-aurora {
+ display: none !important;
+ }
+
+ .matrix-vignette {
+ opacity: 0.35;
+ background: radial-gradient(ellipse at center, transparent 40%, rgba(0, 0, 0, 0.55) 100%);
+ }
+
+ .matrix-hero-radar,
+ .matrix-radar-header {
+ display: none !important;
+ }
+
+ .matrix-panel-chrome::before,
+ .matrix-hud-block::after,
+ .matrix-card::before {
+ display: none !important;
+ }
+
+ .matrix-glitch-c,
+ .matrix-glitch-m {
+ display: none !important;
+ }
+
+ .matrix-glitch-base {
+ text-shadow: 0 0 12px rgba(0, 255, 213, 0.35);
+ }
+
+ .matrix-hud-dot {
+ animation: none !important;
+ }
+
+ .matrix-tagline-glow,
+ .matrix-btn-pulse,
+ .matrix-chip-magenta,
+ .matrix-card::before,
+ .matrix-panel-chrome::before,
+ .matrix-hud-block::after,
+ .matrix-hero-radar-sweep,
+ .matrix-radar-h-sweep,
+ .matrix-bar {
+ animation: none !important;
+ }
+
+ .matrix-chrome,
+ .matrix-main,
+ .matrix-panel {
+ transform: translateZ(0);
}
.matrix-table {
@@ -1670,16 +1718,66 @@ body.matrix-theme {
}
}
+/* 手机轻量模式(head 内联脚本提前打标 + 触控设备) */
+html.matrix-lite .matrix-rain-canvas,
+html.matrix-lite .matrix-scanlines,
+html.matrix-lite .matrix-noise,
+html.matrix-lite .matrix-aurora {
+ display: none !important;
+}
+
+html.matrix-lite .matrix-hero-radar,
+html.matrix-lite .matrix-radar-header,
+html.matrix-lite .matrix-panel-chrome::before,
+html.matrix-lite .matrix-hud-block::after,
+html.matrix-lite .matrix-card::before,
+html.matrix-lite .matrix-glitch-c,
+html.matrix-lite .matrix-glitch-m {
+ display: none !important;
+}
+
+html.matrix-lite .matrix-glitch-base {
+ text-shadow: 0 0 12px rgba(0, 255, 213, 0.35);
+}
+
+html.matrix-lite .matrix-hud-dot,
+html.matrix-lite .matrix-tagline-glow,
+html.matrix-lite .matrix-btn-pulse,
+html.matrix-lite .matrix-chip-magenta,
+html.matrix-lite .matrix-hero-radar-sweep,
+html.matrix-lite .matrix-radar-h-sweep,
+html.matrix-lite .matrix-bar,
+html.matrix-lite .matrix-glitch-c,
+html.matrix-lite .matrix-glitch-m {
+ animation: none !important;
+}
+
+html.matrix-lite body.matrix-theme {
+ background: #020806;
+}
+
@media (prefers-reduced-motion: reduce) {
.matrix-rain-canvas {
- display: none;
+ display: none !important;
+ }
+
+ .matrix-scanlines,
+ .matrix-noise,
+ .matrix-aurora {
+ display: none !important;
}
.matrix-glitch-c,
.matrix-glitch-m,
.matrix-tagline-glow,
.matrix-btn-pulse,
- .matrix-chip-magenta {
+ .matrix-chip-magenta,
+ .matrix-hud-dot,
+ .matrix-panel-chrome::before,
+ .matrix-hud-block::after,
+ .matrix-card::before,
+ .matrix-hero-radar-sweep,
+ .matrix-radar-h-sweep {
animation: none !important;
}
}
diff --git a/onchain_scout_gate/templates/dashboard.html b/onchain_scout_gate/templates/dashboard.html
index 6b0ec27..6c74bfc 100644
--- a/onchain_scout_gate/templates/dashboard.html
+++ b/onchain_scout_gate/templates/dashboard.html
@@ -3,6 +3,12 @@
+
MATRIX · FUNNEL
diff --git a/onchain_scout_gate/templates/login.html b/onchain_scout_gate/templates/login.html
index a396ea6..e7e47af 100644
--- a/onchain_scout_gate/templates/login.html
+++ b/onchain_scout_gate/templates/login.html
@@ -3,6 +3,13 @@
+
MATRIX · 接入