diff --git a/SHA256SUMS b/SHA256SUMS
index 0c93842..6cd5134 100644
--- a/SHA256SUMS
+++ b/SHA256SUMS
@@ -7,5 +7,5 @@ e83c52906953a723fc79208aecf08372a875e0bc2f74b4283329a475744f8984 README.md
3da8b5d94e2206bffc19e1c4fa493b31880c9a90fd6a02546461fe54a7255dbd config/pigway-pi-control.conf
20c584762cae3a50a498df25e11272c3c191a62c9ce823e63f8224d14637b1d4 systemd/pigway-pi-control-api.service
35ec68e1c3040e7affad43961fbb77e9e29f3474b92aed1005502629f9acb549 systemd/pigway-pi-control.service
-3cdb7ce120c137f2665c58ea8121fd680757407085c49d0c097c60b4dc919519 web/index.html
+51ffc5a0f92ef926791352c4dbb6d23b3e610340bb0d0b666696f0af329c4d02 web/index.html
73b7922be93bf57169589755137dc5ec7ec7c8059c85c2bf2ee53a344e534d7e docs/HARDWARE_PLUGIN_API.md
diff --git a/web/index.html b/web/index.html
index bbba7dc..b91fbc7 100644
--- a/web/index.html
+++ b/web/index.html
@@ -15,10 +15,11 @@
#mainSavebar{display:flex;align-items:center;gap:16px;flex-wrap:wrap}
.action-row,.savebar,.plugin-actions{display:flex;align-items:center;gap:16px;flex-wrap:wrap}.action-row>button{flex-shrink:0}.bulk-tools{column-gap:16px}.group-head{column-gap:16px}
.language-preference{position:relative}.language-preference .language-icon{position:absolute;left:10px;width:16px;height:16px;pointer-events:none;color:var(--text)}.language-preference select{padding-left:34px;min-width:110px}
+.theme-preference{position:relative}.theme-preference .preference-icon{position:absolute;left:10px;width:16px;height:16px;display:flex;align-items:center;justify-content:center;pointer-events:none;color:var(--text);font-size:16px;line-height:1}.theme-preference select{padding-left:34px}
-PIGWay Pi Control
正在连接树莓派…
+PIGWay Pi Control
正在连接树莓派…
事件日志
查询 systemd journal 中仍在保留的全部硬件 Agent 事件。
@@ -50,7 +51,7 @@ Object.assign(EN,{'硬件插件':'Hardware plugins','配置按用途分组。监
Object.assign(EN,{'机器管理':'Machine management','恢复设备默认值':'Restore device defaults','本机':'Local host'});
const ZH=Object.fromEntries(Object.entries(EN).map(([zh,en])=>[en,zh])),tr=s=>LANG==='en'?(EN[s]||s):(ZH[s]||s);
function translateNode(root=document){const map=LANG==='en'?EN:ZH,translate=value=>{const trim=value.trim();return trim&&map[trim]?value.replace(trim,map[trim]):value};const walker=document.createTreeWalker(root,NodeFilter.SHOW_TEXT);let n;while(n=walker.nextNode())n.nodeValue=translate(n.nodeValue);root.querySelectorAll?.('[placeholder],[title],[aria-label]').forEach(e=>['placeholder','title','aria-label'].forEach(a=>{const v=e.getAttribute(a);if(v)e.setAttribute(a,translate(v))}))}
-function applyTheme(value){const resolved=value==='auto'?(matchMedia('(prefers-color-scheme: dark)').matches?'dark':'light'):value;document.documentElement.dataset.theme=resolved}
+function applyTheme(value){$('themeIcon').textContent=({auto:"◐",light:"☀",dark:"☾"})[value]||"◐";const resolved=value==='auto'?(matchMedia('(prefers-color-scheme: dark)').matches?'dark':'light'):value;document.documentElement.dataset.theme=resolved}
const $=id=>document.getElementById(id),tabs=[...document.querySelectorAll('nav button')];let original={},fleetHosts=[],currentConfigHost='';const esc=s=>String(s??'').replace(/[&<>"']/g,c=>({'&':'&','<':'<','>':'>','"':'"',"'":'''}[c]));
const sectionMeta={plugins:['硬件插件','独立安装,按实际能力提供风扇、屏幕或灯光控制'],hardware:['硬件插件','可选 Yahboom 散热板;未安装时保持关闭'],device:['设备标识','自定义本机显示名称和稳定标识'],hosts:['机器列表','登记需要聚合监控的其他节点'],led:['灯光设置','正常灯效与告警颜色'],alerts:['告警阈值','处理器、内存、温度、磁盘和 Wi-Fi'],fan:['风扇温控','温度档位与降档回差'],timing:['刷新周期','传感器、屏幕、网络和健康检查'],display:['屏幕布局','OLED 四行文字位置'],dark_mode:['板载指示灯','树莓派电源灯与活动灯'],services:['服务监控','监控 systemd 服务'],processes:['进程监控','监控普通进程关键字'],api:['Web 与 API','监听地址、端口和日志数量'],bulk_sync:['批量同步','从当前配置机器复制所选配置项到目标机器']};
const labels={'hardware.cooling_hat_enabled':'启用散热板(OLED、风扇、RGB)','led.alert_mode':'告警灯效模式','led.custom_min_hold_ms':'自定义闪烁最小保持时间','led.normal_mode':'正常状态灯效','led.normal_r':'红色通道','led.normal_g':'绿色通道','led.normal_b':'蓝色通道','led.normal_flash_on_ms':'亮灯时间','led.normal_flash_off_ms':'灭灯时间','led.normal_effect_speed':'内置效果速度','led.normal_effect_color':'内置效果颜色','led.warning_flash_on_ms':'普通告警亮灯','led.warning_flash_off_ms':'普通告警灭灯','led.critical_flash_on_ms':'严重告警亮灯','led.critical_flash_off_ms':'严重告警灭灯','led.emergency_flash_on_ms':'紧急告警亮灯','led.emergency_flash_off_ms':'紧急告警灭灯','led.write_delay_ms':'RGB 寄存器写入间隔','alerts.cpu_high':'处理器高负载阈值','alerts.cpu_recover':'处理器恢复阈值','alerts.cpu_high_seconds':'处理器持续时间','alerts.memory_high':'内存高占用阈值','alerts.memory_recover':'内存恢复阈值','alerts.memory_high_seconds':'内存持续时间','alerts.temp_high':'高温告警阈值','alerts.temp_critical':'严重高温阈值','alerts.disk_high':'磁盘高占用阈值','alerts.disk_critical':'磁盘严重阈值','alerts.wifi_weak':'Wi-Fi 弱信号阈值','alerts.wifi_recover':'Wi-Fi 恢复阈值','alerts.wifi_weak_seconds':'弱信号持续时间','fan.start':'风扇启动温度','fan.level2':'二档起始温度','fan.level3':'三档起始温度','fan.level4':'四档起始温度','fan.max':'全速起始温度','fan.hysteresis':'降档温度回差','timing.sensor_interval':'传感器采样周期','timing.oled_refresh_interval':'OLED 刷新周期','timing.page_interval':'OLED 页面轮播周期','timing.network_interval':'网络检查周期','timing.service_interval':'服务检查周期','timing.health_interval':'健康检查周期','display.row1_y':'第一行纵坐标','display.row2_y':'第二行纵坐标','display.row3_y':'第三行纵坐标','display.row4_y':'第四行纵坐标','dark_mode.pi_pwr_led':'树莓派电源灯','dark_mode.pi_act_led':'树莓派活动灯','api.bind':'监听地址','api.port':'监听端口','api.log_limit':'默认日志条数','device.identifier':'机器标识','device.name':'显示名称'};