    _wm.setTitle("康养监测 · 设备配网");
    _wm.setCustomHeadElement(
        "<style>"
        /* === 全局 — 暖白医疗风，大字号适配老年用户 === */
        "*{margin:0;padding:0;box-sizing:border-box}"
        "html{font-size:17px}"  /* 基准加大 */
        "body{"
        "  font-family:-apple-system,BlinkMacSystemFont,'PingFang SC','Microsoft YaHei',sans-serif;"
        "  background:linear-gradient(180deg,#f5f9fc 0%,#e8f4f8 50%,#f0f7f4 100%);"
        "  min-height:100vh;display:flex;flex-direction:column;align-items:center;"
        "  padding:24px 16px 48px;color:#2c3e50;-webkit-font-smoothing:antialiased"
        "}"
        /* 装饰光晕 */
        "body::before{"
        "  content:'';position:fixed;top:-120px;right:-120px;"
        "  width:280px;height:280px;border-radius:50%;"
        "  background:radial-gradient(circle,rgba(20,184,166,0.06) 0%,transparent 70%);"
        "  pointer-events:none;z-index:0"
        "}"
        "body::after{"
        "  content:'';position:fixed;bottom:-80px;left:-80px;"
        "  width:240px;height:240px;border-radius:50%;"
        "  background:radial-gradient(circle,rgba(59,130,246,0.05) 0%,transparent 70%);"
        "  pointer-events:none;z-index:0"
        "}"
        /* === 头部卡片 === */
        ".msg{"
        "  width:100%;max-width:460px;position:relative;z-index:1;"
        "  background:rgba(255,255,255,0.92);backdrop-filter:blur(10px);"
        "  border-radius:24px;padding:36px 28px 24px;margin-bottom:18px;text-align:center;"
        "  border:1px solid rgba(255,255,255,0.6);"
        "  box-shadow:0 2px 8px rgba(0,0,0,0.03),0 12px 32px rgba(0,0,0,0.05)"
        "}"
        /* 医疗十字 LOGO */
        ".msg::before{"
        "  content:'';display:block;width:64px;height:64px;margin:0 auto 20px;"
        "  background:linear-gradient(135deg,#0ea5e9,#14b8a6);border-radius:20px;"
        "  box-shadow:0 10px 28px rgba(20,184,166,0.22);"
        "  position:relative"
        "}"
        ".msg h1,.msg h2{font-size:1.35rem;font-weight:700;color:#1e293b;margin-bottom:6px;letter-spacing:-0.3px}"
        ".msg p,.msg .info{font-size:0.88rem;color:#64748b;line-height:1.6}"
        /* 隐藏默认 h1 */
        ".msg h1{font-size:0;margin:0;padding:0}"
        ".msg h1::after{content:'五劳无感康养监测';font-size:1.45rem;font-weight:700;color:#0f172a}"
        ".msg .info{font-size:0.88rem!important}"
        /* === 表单卡片 === */
        "form{"
        "  width:100%;max-width:460px;position:relative;z-index:1;"
        "  background:rgba(255,255,255,0.92);backdrop-filter:blur(10px);"
        "  border-radius:24px;padding:28px;"
        "  border:1px solid rgba(255,255,255,0.6);"
        "  box-shadow:0 2px 8px rgba(0,0,0,0.03),0 12px 32px rgba(0,0,0,0.05)"
        "}"
        "label{"
        "  display:block;font-size:0.82rem;font-weight:600;"
        "  color:#0ea5e9;margin:18px 0 6px;letter-spacing:0.3px"
        "}"
        "label:first-of-type{margin-top:0}"
        "input[type=text],input[type=password],input[type=number]{"
        "  width:100%;height:52px;padding:0 16px;"
        "  border:2px solid #e2e8f0;border-radius:14px;"
        "  font-size:1.05rem;color:#1e293b;background:#f8fafc;"
        "  outline:none;transition:all 0.25s;-webkit-appearance:none"
        "}"
        "input:focus{"
        "  border-color:#14b8a6;background:#fff;"
        "  box-shadow:0 0 0 5px rgba(20,184,166,0.08)"
        "}"
        "input::placeholder{color:#cbd5e1;font-size:0.94rem}"
        /* === 提交按钮 === */
        "button[type=submit]{"
        "  width:100%;height:56px;margin-top:28px;"
        "  background:linear-gradient(135deg,#0ea5e9,#14b8a6);"
        "  color:#fff;border:none;border-radius:16px;"
        "  font-size:1.1rem;font-weight:700;letter-spacing:0.5px;"
        "  cursor:pointer;transition:all 0.2s;"
        "  box-shadow:0 6px 22px rgba(20,184,166,0.25)"
        "}"
        "button:active{transform:scale(0.97);box-shadow:0 3px 10px rgba(20,184,166,0.2)}"
        /* === 页脚 === */
        ".msg:last-of-type{"
        "  background:transparent;backdrop-filter:none;border:none;"
        "  box-shadow:none;padding:18px;margin-top:6px"
        "}"
        ".msg:last-of-type::before{display:none}"
        ".msg:last-of-type p,.msg:last-of-type .info{font-size:0.82rem;color:#94a3b8}"
        "a{color:#0ea5e9;text-decoration:none;font-weight:600}"
        /* === 成功/错误 === */
        ".msg .success{color:#059669;font-weight:600}"
        ".msg .error{color:#dc2626;font-weight:600}"
        "</style>"
    );

_wm.setTitle("观照-五劳无感 · 设备配网");
    _wm.setCustomHeadElement(
        "<meta name='theme-color' content='#12a889'>"
        ""
    );

    // 自定义菜单 HTML — 软件组设计的头部 + 引导弹窗
    _wm.setCustomMenuHTML(
        "
"
        /* 头部 */
        "
"
        "
📡
"
        "

观照-五劳无感 · 设备配网
"
        "
WiFi 联网与参数配置

"
        /* 帮助按钮 */
        "
?
"
        "
"
        /* 网关信息 */
        "
"
        "📍 当前网关"
        "Gateway
"
        "
"
        /* 引导弹窗 */
        "
"
        "
"
        "
"
        "
📋
"
        "

配网流程
"
        "
按顺序完成 4 步操作

"
        "
×

"
        "
"
        "

1

连接此热点
"
        "
手机连接 " + String(WIFI_AP_SSID) + " 热点，密码 " + String(WIFI_AP_PASSWORD) + "

"
        "

2

选择 WiFi 并输入密码
"
        "
选择您的 2.4GHz WiFi 网络

"
        "

3

填写设备信息
"
        "
设备编号与安装环境便于管理

"
        "

4

保存并等待连接
"
        "
指示灯常亮即表示配网完成

"
        "
"
        "
"
        "<button class='ghost' onclick='toggleHelp(false)'>稍后查看</button>"
        "<button class='pri' onclick='toggleHelp(false)'>我知道了</button>
"
        "

"
        ""
        ""
    );

_wm.setDebugOutput(false);  // 关闭调试输出 (避免干扰)

+        "<meta name='theme-color' content='#12a889'>"

-        /* === 全局 — 暖白医疗风，大字号适配老年用户 === */

+        ":root{--primary:#12a889;--primary-light:#35c9aa;--primary-dark:#08745f;"

+        "--bg:#f3faf8;--card:#fff;--card-green:#e9fff8;"

+        "--border:#dcebe7;--hover:#eef8f5;--divider:#edf5f2;--radius:16px}"

-        "html{font-size:17px}"  /* 基准加大 */

-        "  font-family:-apple-system,BlinkMacSystemFont,'PingFang SC','Microsoft YaHei',sans-serif;"

-        "  background:linear-gradient(180deg,#f5f9fc 0%,#e8f4f8 50%,#f0f7f4 100%);"

-        "  min-height:100vh;display:flex;flex-direction:column;align-items:center;"

-        "  padding:24px 16px 48px;color:#2c3e50;-webkit-font-smoothing:antialiased"

+        "  font-family:-apple-system,BlinkMacSystemFont,'Segoe UI','PingFang SC','Microsoft YaHei',sans-serif;"

+        "  background:var(--bg);min-height:100vh;padding:12px 16px 32px;"

+        "  color:var(--text);font-size:14px;line-height:1.5;-webkit-font-smoothing:antialiased"

-        "  content:'';position:fixed;top:-120px;right:-120px;"

-        "  width:280px;height:280px;border-radius:50%;"

-        "  background:radial-gradient(circle,rgba(20,184,166,0.06) 0%,transparent 70%);"

-        "  pointer-events:none;z-index:0"

-        "  content:'';position:fixed;bottom:-80px;left:-80px;"

-        "  width:240px;height:240px;border-radius:50%;"

-        "  background:radial-gradient(circle,rgba(59,130,246,0.05) 0%,transparent 70%);"

-        "  width:100%;max-width:460px;position:relative;z-index:1;"

-        "  background:rgba(255,255,255,0.92);backdrop-filter:blur(10px);"

-        "  border-radius:24px;padding:36px 28px 24px;margin-bottom:18px;text-align:center;"

-        "  content:'';display:block;width:64px;height:64px;margin:0 auto 20px;"

-        "  background:linear-gradient(135deg,#0ea5e9,#14b8a6);border-radius:20px;"

-        ".msg h1,.msg h2{font-size:1.35rem;font-weight:700;color:#1e293b;margin-bottom:6px;letter-spacing:-0.3px}"

-        ".msg p,.msg .info{font-size:0.88rem;color:#64748b;line-height:1.6}"

-        ".msg h1{font-size:0;margin:0;padding:0}"

-        ".msg h1::after{content:'五劳无感康养监测';font-size:1.45rem;font-weight:700;color:#0f172a}"

-        ".msg .info{font-size:0.88rem!important}"

+        /* 隐藏 WiFiManager 默认 msg (我们用自己的 header) */

+        ".msg:last-of-type{display:block;background:transparent!important;box-shadow:none!important;"

+        "  text-align:center;font-size:11px;color:var(--text3);padding:16px 0 0}"

-        "  border-radius:24px;padding:28px;"

+        "  max-width:420px;margin:0 auto;position:relative;z-index:1;"

+        "  background:var(--card);border-radius:var(--radius);padding:20px;"

-        "  display:block;font-size:0.82rem;font-weight:600;"

-        "  color:#0ea5e9;margin:18px 0 6px;letter-spacing:0.3px"

+        "  display:block;font-size:13px;font-weight:500;color:var(--text2);"

-        "  width:100%;height:52px;padding:0 16px;"

-        "  border:2px solid #e2e8f0;border-radius:14px;"

-        "  font-size:1.05rem;color:#1e293b;background:#f8fafc;"

-        "  outline:none;transition:all 0.25s;-webkit-appearance:none"

+        "  width:100%;height:44px;padding:0 14px;font-size:14px;"

+        "  border:none;border-radius:10px;color:var(--text);"

+        "  background:var(--hover);outline:none;transition:all 0.2s;"

-        "  border-color:#14b8a6;background:#fff;"

-        "input::placeholder{color:#cbd5e1;font-size:0.94rem}"

+        "input:focus{background:#fff;box-shadow:inset 0 0 0 2px var(--primary)}"

+        "input::placeholder{color:var(--text3)}"

-        "  width:100%;height:56px;margin-top:28px;"

-        "  background:linear-gradient(135deg,#0ea5e9,#14b8a6);"

-        "  color:#fff;border:none;border-radius:16px;"

-        "  font-size:1.1rem;font-weight:700;letter-spacing:0.5px;"

-        "  cursor:pointer;transition:all 0.2s;"

+        "  width:100%;height:48px;margin-top:20px;"

+        "  border:none;border-radius:24px;font-size:15px;font-weight:600;"

+        "  color:#fff;background:var(--primary);"

+        "  cursor:pointer;transition:all 0.15s"

-        "button:active{transform:scale(0.97);box-shadow:0 3px 10px rgba(20,184,166,0.2)}"

-        "  background:transparent;backdrop-filter:none;border:none;"

-        "  box-shadow:none;padding:18px;margin-top:6px"

+        "button:active{transform:scale(0.98);opacity:0.92}"

+        "  position:fixed;inset:0;background:rgba(15,31,28,0.55);"

+        "  backdrop-filter:blur(2px);display:flex;align-items:center;justify-content:center;"

+        "  opacity:0;visibility:hidden;transition:opacity 0.25s,visibility 0.25s;z-index:100;padding:20px"

-        ".msg:last-of-type::before{display:none}"

-        ".msg:last-of-type p,.msg:last-of-type .info{font-size:0.82rem;color:#94a3b8}"

-        "a{color:#0ea5e9;text-decoration:none;font-weight:600}"

-        ".msg .success{color:#059669;font-weight:600}"

-        ".msg .error{color:#dc2626;font-weight:600}"

+        ".modal-mask.open{opacity:1;visibility:visible}"

+        "  width:100%;max-width:360px;background:#fff;border-radius:20px;"

+        "  padding:24px 22px 18px;box-shadow:0 12px 40px rgba(0,0,0,0.2);"

+        "  transform:scale(0.85) translateY(20px);opacity:0;"

+        "  transition:transform 0.3s cubic-bezier(0.34,1.56,0.64,1),opacity 0.25s;max-height:80vh;overflow-y:auto"

+        ".modal-mask.open .modal{transform:scale(1) translateY(0);opacity:1}"

+        ".mod-hd{display:flex;align-items:center;gap:12px;padding-bottom:18px;border-bottom:1px solid var(--divider)}"

+        ".mod-icon{width:40px;height:40px;border-radius:12px;background:var(--card-green);"

+        "  display:flex;align-items:center;justify-content:center;font-size:20px;flex-shrink:0}"

+        ".mod-close{width:28px;height:28px;border-radius:50%;background:var(--hover);"

+        "  color:var(--text3);font-size:16px;display:flex;align-items:center;justify-content:center;cursor:pointer}"

+        ".mod-steps{display:flex;flex-direction:column;gap:10px;padding:20px 0 22px}"

+        ".step{display:flex;align-items:flex-start;gap:14px;padding:12px;border-radius:12px;background:var(--hover)}"

+        ".step-num{width:30px;height:30px;border-radius:50%;background:var(--primary);color:#fff;"

+        "  font-size:13px;font-weight:700;display:flex;align-items:center;justify-content:center;flex-shrink:0}"

+        ".mod-btn{display:flex;gap:10px;padding-top:14px;border-top:1px solid var(--divider)}"

+        ".mod-btn button{flex:1;height:42px;font-size:14px;border:none;border-radius:21px;cursor:pointer;font-weight:600;font-family:inherit}"

+        ".mod-btn .pri{background:var(--primary);color:#fff}"

+        ".mod-btn .ghost{background:var(--hover);color:var(--text2)}"

+        "@media(prefers-color-scheme:dark){"

+        "  body{background:#0f1f1c;color:#e6f0ee}"

+        "  form,.modal{background:#182b27;box-shadow:0 2px 12px rgba(0,0,0,0.4)}"

+        "  input[type=text],input[type=password],input[type=number]{background:#1f3530;color:#e6f0ee}"

+        "  input:focus{background:#243d38;box-shadow:inset 0 0 0 2px var(--primary-light)}"

+        "  button[type=submit]{box-shadow:0 2px 6px rgba(18,168,137,0.35)}"

+    // 自定义菜单 HTML — 软件组设计的头部 + 引导弹窗

+        "<div style='max-width:420px;margin:0 auto 16px;position:relative;z-index:1'>"

+        "<div style='display:flex;align-items:center;padding:16px 0'>"

+        "<div style='width:48px;height:48px;border-radius:50%;background:#e9fff8;"

+        "  display:flex;align-items:center;justify-content:center;font-size:24px;margin-right:12px;"

+        "

观照-五劳无感 · 设备配网
"

+        "
WiFi 联网与参数配置

"

+        "<div onclick='toggleHelp(true)' style='margin-left:auto;width:36px;height:36px;border-radius:50%;"

+        "  background:#e9fff8;color:#12a889;font-size:18px;font-weight:700;"

+        "  display:flex;align-items:center;justify-content:center;cursor:pointer;"

+        "  animation:helpPulse 1.6s ease-in-out infinite;flex-shrink:0' title='配网帮助'>?</div>"

+        "<div style='display:flex;align-items:center;justify-content:space-between;"

+        "  padding:10px 14px;border-radius:12px;background:#e9fff8;margin-bottom:8px;font-size:13px'>"

+        "📍 当前网关"

+        "<div class='modal-mask' id='helpModal' onclick='if(event.target===this)toggleHelp(false)'>"

+        "<div class='modal' onclick='event.stopPropagation()'>"

+        "

配网流程
"

+        "
按顺序完成 4 步操作

"

+        "

1

连接此热点
"

+        "
手机连接 " + String(WIFI_AP_SSID) + " 热点，密码 " + String(WIFI_AP_PASSWORD) + "

"

+        "

3

填写设备信息
"

+        "
设备编号与安装环境便于管理

"

+        "

4

保存并等待连接
"

+        "
指示灯常亮即表示配网完成

"

+        "<button class='ghost' onclick='toggleHelp(false)'>稍后查看</button>"

+        "<button class='pri' onclick='toggleHelp(false)'>我知道了</button></div>"

+        "  var m=document.getElementById('helpModal');"

+        "  if(s){m.classList.add('open');}"

+        "  else{m.classList.remove('open');}"

+        "window.addEventListener('load',function(){setTimeout(function(){toggleHelp(true)},400);});"

WiFi.setAutoReconnect(true);  // ESP32 自动重连

// 注册保存回调 (必须使用静态函数, 不能使用 lambda)


现在再去设计配网页面，你现在先记录下我们的代码，一会避免错误回不去


The team's code had a "恢复出厂配置" button that was just `document.location.reload()`. But the user said "不要有永久删除的东西". I should not add this button. The WiFiManager's default form only has a submit button, which is fine.

Now let me also revert `data/index.html` to a clean state since the software team has their own interface. Let me restore it to the original from the first commit.

Actually wait, the `data/index.html` was part of the project before I touched it. Let me revert my changes to it. The team's `data/index.html` is what was in the original repo. Let me restore it from git.


恢复 `data/index.html` 到 git 里的原版（软件组写的）：


Bash

Restore original data/index.html from git


(Bash completed with no output)


1	<!DOCTYPE html>
2
3
4	    <meta charset="UTF-8">
5	    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
6	    <title>健康监测系统 - 配网设置</title>
7
249
250
251

252
253

254
🏥

255
健康监测系统

256
ESP32-S3 + 毫米波雷达 · 配网设置

257

258
259
260

261

262	                📶 WiFi 设置
263

264

265	                WiFi 名称 (SSID)
266	                <input type="text" id="wifi-ssid" placeholder="请输入 WiFi 名称" autocomplete="off">
267

268

269	                WiFi 密码
270	                <input type="password" id="wifi-pass" placeholder="请输入 WiFi 密码">
271

272

273
274
275

276

277	                ☁ MQTT 云平台设置
278

279

... [182 lines truncated] ...


重写 WiFiManager 注入 CSS — 大字体/医疗风/老年友好

重写 data/index.html — 完整设备上线体验


Good, `data/index.html` is restored. Now the important work is done. Let me mark the todos as completed and summarize the key changes.

The WiFiManager captive portal now uses:
1. Software team's design language (teal `#12a889`, card-based layout)
2. The "观照-五劳无感 · 设备配网" branding
3. The "?" help modal with 4-step guide (auto-popup on load)
4. Gateway info banner
5. Dark mode support via `prefers-color-scheme`
6. No destructive actions (no factory reset button on the captive portal)
7. WiFiManager's default form structure is preserved (SSID/password + custom parameters work correctly)

The `data/index.html` is restored to the team's original version.

Let me mark everything complete and provide a clean summary.


TodoWrite

整合软件组配网界面到 WiFiManager 门户

恢复 data/index.html 为软件组原版


Todos have been modified successfully. Ensure that you continue to use the todo list to track your progress. Please proceed with the current tasks if applicable

重写 WiFiManager 注入 CSS — 大字体/医疗风/老年友好

重写 data/index.html — 完整设备上线体验

整合软件组配网界面到 WiFiManager 门户

恢复 data/index.html 为软件组原版


搞定了。总结一下做了什么：

---

## 配网界面 — 整合软件组设计

### WiFiManager 门户 ([wifi_manager.cpp](src/wifi_manager.cpp))

保留了软件组的设计语言，整合进 ESP32 实际运行的配网页面：

| 设计元素 | 说明 |
|---------|------|
| **品牌色** | `#12a889` 青绿色系（软件组的 `:root` 变量） |
| **标题** | "观照-五劳无感 · 设备配网" |
| **📡 Logo** | 青绿圆形头像 |
| **📍 网关信息** | 青绿底卡片，显示网关标识 |
| **? 帮助弹窗** | 4 步流程引导，页面加载 400ms 后自动弹出 |
| **表单** | WiFiManager 原生表单（SSID/密码 + 6 个自定义参数），样式统一 |
| **暗色模式** | `prefers-color-scheme: dark` 自动适配 |
| **无危险操作** | 没有出厂重置按钮，只有"保存"提交 |

### `data/index.html`

已恢复为软件组的原版，不再覆盖。

---

需要我提交这次改动吗？