/* ══════════════════════════════════════════════════════════════════
   colleagues.css —— 「AI同事管理」站（顶栏第 9 站 · 新增真站，2026-09-26）
   用户原话：「在中台那，加一个AI同事管理-专门配置采集机和绑定采集机，
             通过AI同事编号，后端确认绑定，就可以正常上下行，
             后续增加新机，编码随机生成，后端绑定确认」

   数据口径：`backend/app/routes/colleagues.py`（8 个端点，MOD_VERSION 0.1.1）
             `GET  /colleagues`                    台账 + 派生绑定态 + 可绑账号 + 参数 schema
             `GET  /colleagues/<machine_id>`       单机详情
             `POST /colleagues/<machine_id>/bind`  ★确认绑定（人工动作）
             `POST /colleagues/<machine_id>/unbind` 解绑（保留行与编号 + 吊销令牌）
             `POST /colleagues/<machine_id>/revoke` 停用 / 启用
             `POST /colleagues/<machine_id>/token`  ★签发令牌（明文只回一次）
             `GET  /colleagues/<machine_id>/config` 取参数（采集机轮询）
             `PUT  /colleagues/<machine_id>/config` 改参数 ⇒ rev 自增

   结构范式：app/css/xiaoe.css（站头 44px 通栏 + 视图条 + 内容层 + 窄窗兜底）。
   四条纪律（引前已机械核过，命令见交付回报）：
     1. 本文件**不得出现字面色值**，一律 var() 令牌；且只用**四主题齐备**的令牌
        （`tokens.css` 里出现 4 次的那些）。★ 刻意**不用** `--warn`（它只在 :root 一处
        有定义，chatlog.css 头注已记过这条）；风险色一律 `--danger*`、次级用 `--amber*`。
        —— 另核过：`--ok*` 系列在本仓**不存在**，故"已绑好"这个**正向**态也不用绿色，
          改用 `--accent*`（本仓 accent 就是"正常/激活"的语义色，四主题都齐）。
     2. 类名一律 `cm-` 前缀 + 内容层 `#cmbody`；`.cm-` / `#cmbody` / `data-cm*` 在
        本仓**引前 0 命中**（R58 同族：命名撞车必须提前查）。
     3. ★★ **「忙」与「空」必须是两个类**（xiaoe.css 头注那条教训的原话）：
        `.cm-busy`（取数中）/ `.cm-empty`（取到了、结果就是空）/ `.cm-err`（取数失败，
        **带原因**）—— 三者**分开**，合成一个会让出图/判据的等待条件退化（偶发假绿）。
        ★ 本文件**多一个**：`.cm-na`（无法判）—— 采集机的 `bind_state=unknown`
          是"这台机从没跟中台联系过"，**不是**"没有机器"（那是 `.cm-empty`）。
     4. ★ 正文大量来自**服务端下发的字段**（机器名 / 短号 / 绑定人备注 / 参数 label）
        ⇒ 渲染层一律 `esc`（XSS 面在 js 侧守）。参数 `label` 是**上屏文字**，
          机械键（`poll_sec` 那类）**永不上屏**（v12 稿硬口径，见 colleagues.py 头注）。
   ══════════════════════════════════════════════════════════════════ */
.cm{display:none;flex:1 1 auto;min-width:0;min-height:0;flex-direction:column;
  background:var(--e2)}
.app.cmmode > .list,
.app.cmmode > .chat,
.app.cmmode > .side,
.app.cmmode > .spl{display:none}
.app.cmmode > #cmbody{display:flex}

/* ══ ★★ `#cmmain` = `render()` 加的主体包装层。
   ⚠⚠ 裸 div 会**吃断 flex 链**，且**全程不报错**（xiaoe.css 实测过同一条，2026-09-23）：
      `.cm-body` 是全站唯一纵向滚动容器，它的定高完全依赖父级是 flex 容器 + 自己是 flex 子项。
      包装层若默认 `display:block` ⇒ `.cm-body` 的 `flex` 整条失效 ⇒ `overflow:auto` 拿到
      "无限高" ⇒ **永远不出滚动条**，而祖先 `.app{overflow:hidden}` 把溢出部分直接裁掉
      ⇒ 现象 =「列表滑不动、下面的机器够不着」。
   ⇒ 这层**必须原样透传 flex 上下文**（grow + min-height:0 + 纵向列）。 */
#cmmain{flex:1 1 auto;min-height:0;display:flex;flex-direction:column}

/* ── 站头（44px，与其余 7 站同量；顶栏总高 120px 是全局约束，这里只管站内这一段）── */
.cm-hd{display:flex;align-items:center;gap:9px;flex:none;height:44px;padding:0 14px;
  border-bottom:1px solid var(--line);background:var(--e1)}
.cm-ico{flex:none;width:26px;height:26px;border-radius:var(--r-sm);
  background:var(--accent-wash);border:1px solid var(--accent-line);color:var(--accent-text);
  display:flex;align-items:center;justify-content:center}
.cm-ttl{font-size:var(--fs-h3);color:var(--t1);font-weight:600;letter-spacing:.2px}
.cm-sub{font-size:var(--fs-caption);color:var(--t3)}
.cm-sp{flex:1 1 auto;min-width:8px}
/* 站头右上读数：机器台数 / 已绑 / 等确认 —— 一条读数三格，**不藏进二级页**。 */
.cm-kpis{display:flex;align-items:center;gap:10px}
.cm-kpi{display:flex;align-items:baseline;gap:4px;font-size:var(--fs-caption);color:var(--t3)}
.cm-kpi b{font-size:var(--fs-num);color:var(--t1);font-weight:600;font-variant-numeric:tabular-nums}
.cm-kpi.on b{color:var(--accent-text)}
.cm-kpi.pd b{color:var(--amber)}

/* ── 视图条（36px）—— 三个视图，与 xiaoe 站的 `viewsHtml()` 同形 ── */
.cm-views{display:flex;align-items:center;gap:2px;flex:none;height:36px;padding:0 12px;
  border-bottom:1px solid var(--line);background:var(--e1)}
.cm-v{padding:4px 11px;border-radius:var(--r-sm);font-size:var(--fs-small);color:var(--t2);
  cursor:pointer;border:1px solid transparent;user-select:none}
.cm-v:hover{color:var(--t1);background:var(--e3)}
.cm-v.on{color:var(--accent-text);background:var(--accent-wash);border-color:var(--accent-line)}
.cm-vn{margin-left:5px;font-size:var(--fs-micro);color:var(--t3);font-variant-numeric:tabular-nums}
.cm-v.on .cm-vn{color:var(--accent-text)}

/* ── 内容层（唯一纵向滚动容器）── */
.cm-body{flex:1 1 auto;min-height:0;overflow:auto;padding:14px}
.cm-wrap{max-width:1080px;margin:0 auto}

/* ── 三态 + 第四态（互斥、四个类）── */
.cm-busy,.cm-empty,.cm-err,.cm-na{padding:34px 18px;text-align:center;
  font-size:var(--fs-small);color:var(--t3)}
.cm-err{color:var(--danger-text)}
.cm-err .cm-err-c{display:block;margin-top:5px;font-size:var(--fs-micro);color:var(--t3)}
.cm-empty .cm-empty-t,.cm-busy .cm-busy-t{display:block;color:var(--t2);margin-bottom:4px}
.cm-empty .cm-empty-s,.cm-busy .cm-busy-s{font-size:var(--fs-micro);color:var(--t3)}
.cm-na{color:var(--amber)}

/* ── 区块标题 ── */
.cm-h2{display:flex;align-items:center;gap:8px;margin:0 0 9px;font-size:var(--fs-small);
  color:var(--t2);font-weight:600}
.cm-h2 .cm-h2n{font-size:var(--fs-micro);color:var(--t3);font-weight:400}
.cm-h2 + .cm-h2hint{font-size:var(--fs-micro);color:var(--t3);margin:-5px 0 10px}
.cm-sec{margin-bottom:20px}
/* ★ 2026-10-03（用户令「绑定教练-绑定AI同事流程完善」）：绑定视图里「负责教练」行。
   已指派 = 正文强调；未指派/读不到 = 弱化（同 `.cm-h2hint` 的口吻，不吓人）。 */
.cm-owner{font-size:var(--fs-small);color:var(--t1);font-weight:600}
.cm-owner.none{font-weight:400;color:var(--t3)}
/* 负责教练那行的「读值 + 去指派按钮」并排（2026-10-03 合并批加） */
.cm-ownrow{display:flex;align-items:center;gap:10px}

/* ── 机器卡（台账一行）── */
.cm-list{display:flex;flex-direction:column;gap:9px}
.cm-card{border:1px solid var(--line);border-radius:var(--r-md);background:var(--e1);
  padding:11px 13px;display:flex;flex-direction:column;gap:9px;
  transition:border-color .14s,box-shadow .14s}
.cm-card:hover{border-color:var(--line-strong)}
.cm-card.sel{border-color:var(--accent-line);box-shadow:0 0 0 1px var(--accent-line) inset}
.cm-crow{display:flex;align-items:center;gap:10px}
/* 头像位：圆角方块 + 短号首段字符（可读、可截图辨认；不用 emoji、不用随机色） */
.cm-av{flex:none;width:34px;height:34px;border-radius:var(--r-sm);display:flex;
  align-items:center;justify-content:center;font-size:var(--fs-caption);font-weight:700;
  background:var(--e3);border:1px solid var(--line);color:var(--t2);letter-spacing:.4px}
.cm-card.bound .cm-av{background:var(--accent-wash);border-color:var(--accent-line);color:var(--accent-text)}
.cm-card.pending .cm-av{background:var(--amber-bg);border-color:var(--amber-line);color:var(--amber)}
.cm-card.revoked .cm-av{opacity:.5}
.cm-nm{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;gap:2px}
.cm-nm .cm-n1{display:flex;align-items:center;gap:7px;min-width:0}
.cm-name{font-size:var(--fs-small);color:var(--t1);font-weight:600;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* 短号：等宽数字 + 字距，因为要**口头报读 / 贴标签 / 截图辨认** */
.cm-no{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:var(--fs-caption);
  letter-spacing:.6px;color:var(--t2);background:var(--e3);border:1px solid var(--line);
  border-radius:var(--r-xs);padding:1px 6px;cursor:pointer;user-select:all}
.cm-no:hover{color:var(--t1);border-color:var(--line-strong)}
.cm-no.none{color:var(--t3);border-style:dashed;cursor:default}
.cm-n2{font-size:var(--fs-micro);color:var(--t3);overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap}
.cm-n2 code{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;letter-spacing:.3px}

/* ── 绑定态标（四档，互斥）── */
.cm-st{flex:none;display:flex;align-items:center;gap:5px;font-size:var(--fs-micro);
  padding:3px 9px;border-radius:var(--r-full);border:1px solid var(--line);
  background:var(--e3);color:var(--t2);white-space:nowrap}
.cm-st i{width:6px;height:6px;border-radius:50%;background:var(--t3);flex:none}
.cm-st.bound{color:var(--accent-text);background:var(--accent-wash);border-color:var(--accent-line)}
.cm-st.bound i{background:var(--accent)}
.cm-st.pending{color:var(--amber);background:var(--amber-bg);border-color:var(--amber-line)}
.cm-st.pending i{background:var(--amber)}
.cm-st.revoked{color:var(--t3);opacity:.75}
.cm-st.unknown{color:var(--t3);border-style:dashed}

/* ══ ★ 抖店飞鸽 worker 运行状态（2026-10-10）══════════════════════════
   ⚠ 与上面 `.cm-st` 的那些**并列而不复用**：机器卡的 `bound/pending/revoked`
     答的是「绑定态」，这里的 `running/offline/stopped` 答的是「它此刻在干什么」
     —— 两个不同的问题（见 `colleagues.js` 2026-10-04 那段注释）。
   ⚠ **颜色只表达"要不要人管"**，不表达具体状态；状态**以文字为准**
     （颜色不是数据 —— 色弱/深浅主题下都可能读错）。
   ⚠ 全部复用 `tokens.css` 既有变量，**不新增色值**（色值唯一点）。 */

/* 分节标题左侧一道细线，标明它与上面的机器列表**不是同一类东西** */
.fg-sec{margin-top:18px;padding-top:14px;border-top:1px solid var(--line)}

/* 五档：running 最轻（正常态不上眼）／offline 最重（真的要去查机器） */
.cm-st.fg-running{color:var(--accent-text);background:var(--accent-wash);border-color:var(--accent-line)}
.cm-st.fg-running i{background:var(--accent)}
.cm-st.fg-stopped{color:var(--t3);border-style:dashed}          /* 人停的：中性，不是故障 */
.cm-st.fg-stopping{color:var(--amber);background:var(--amber-bg);border-color:var(--amber-line)}
.cm-st.fg-stopping i{background:var(--amber)}
.cm-st.fg-offline{color:var(--danger-text);background:var(--danger-bg);border-color:var(--danger-line)}
.cm-st.fg-offline i{background:var(--danger)}
.cm-st.fg-unknown{color:var(--t3);border-style:dashed}
.cm-st.fg-offline.bad,.cm-st.fg-unknown.bad,.cm-st.fg-stopping.bad{font-weight:600}

/* 计数与「上膛」：上膛=会真发消息 ⇒ 必须显眼（不上膛只打字不提交） */
.cm-fg-nums{flex:none;font-size:var(--fs-micro);color:var(--t3);white-space:nowrap;
  font-variant-numeric:tabular-nums}
.cm-fg-err{margin-top:6px;font-size:var(--fs-micro);color:var(--t2);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.cm-fg-err.none{color:var(--t3);opacity:.7}

/* ── 键值行（机器元信息）── */
.cm-kvs{display:flex;flex-wrap:wrap;gap:4px 18px;font-size:var(--fs-micro);color:var(--t3)}
.cm-kv{display:flex;gap:5px;align-items:baseline;min-width:0}
.cm-kv b{color:var(--t2);font-weight:500}
.cm-kv .cm-v1{color:var(--t1);font-variant-numeric:tabular-nums}
.cm-kv .cm-dash{color:var(--t3)}

/* ── 「四条路」（2026-09-26）────────────────────────────────────────────────
   用户 09-26 定的正题：抖店只发 / 微信收发 / 抖音只发 / 小鹅通只采。
   ★ 为什么单独一块、不复用上面那排 `kv`：上面那排是"这台机的属性"（横向铺满、可换行），
     这块是"这台机在干什么" —— **四条固定、每条一行**，横排成网格，一眼扫完。
   ★ 令牌只用四主题齐备的那几个（`--line` / `--e1` / `--t1..3` / `--amber*` /
     `--danger*`）—— 别用 `--ok*`（本仓不存在，见本文件头注）。
   ★ 「还没开通」「这台机没装」走 `--amber` 那一档（**要人看一眼**），
     而不是红色 —— 它们不是故障，是"本来就没开"。 */
.cm-roads{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));
  gap:3px 14px;margin:6px 0 2px;font-size:var(--fs-micro);color:var(--t3)}
.cm-roads-h{grid-column:1/-1;color:var(--t3)}
/* ★ 2026-10-04：标题右侧的「N 条」—— 条数是**现算的**（`rs.length`），
   所以标题本身不含数字（名字里带条数 ⇒ 加一条路名字就变假话）。
   ⚠ 这个 `-n` 有两种落点：`.none` 时是**整块**那一句（要独占一行，见下），
     平时是**标题里的一格**（跟标题并排）。两者形态不同 ⇒ 两条规则都要在。 */
.cm-roads .cm-roads-h .cm-roads-n{margin-left:7px;color:var(--t3);opacity:.85}
.cm-roads.none .cm-roads-n{grid-column:1/-1;color:var(--t3);margin-left:0;opacity:1}
.cm-road{display:flex;align-items:center;gap:5px;min-width:0}
.cm-road i{flex:0 0 auto;width:6px;height:6px;border-radius:50%;
  background:var(--accent-text);opacity:.85}
.cm-road b{color:var(--t2);font-weight:500;white-space:nowrap;overflow:hidden;
  text-overflow:ellipsis}
.cm-road em{margin-left:auto;font-style:normal;color:var(--t3);white-space:nowrap}
.cm-road.bad i{background:var(--amber);opacity:1}
.cm-road.bad em{color:var(--amber)}
.cm-road[data-s="dead"] i,.cm-road[data-s="error"] i{background:var(--danger-text);opacity:1}
.cm-road[data-s="dead"] em,.cm-road[data-s="error"] em{color:var(--danger-text)}

/* ── 动作条 ── */
.cm-acts{display:flex;flex-wrap:wrap;gap:7px;align-items:center}
.cm-btn{appearance:none;border:1px solid var(--line);background:var(--e3);color:var(--t2);
  border-radius:var(--r-sm);padding:5px 12px;font-size:var(--fs-caption);cursor:pointer;
  transition:color .13s,border-color .13s,background .13s}
.cm-btn:hover{color:var(--t1);border-color:var(--line-strong)}
.cm-btn.pri{background:var(--accent-wash);border-color:var(--accent-line);color:var(--accent-text)}
.cm-btn.pri:hover{color:var(--t1)}
.cm-btn.dg{color:var(--danger-text);border-color:var(--danger-line);background:var(--danger-bg)}
.cm-btn.gh{background:transparent}
.cm-btn[disabled]{opacity:.45;cursor:not-allowed}
.cm-btn[disabled]:hover{color:var(--t2);border-color:var(--line)}
.cm-why{font-size:var(--fs-micro);color:var(--amber)}
.cm-toast{font-size:var(--fs-caption);color:var(--accent-text)}
.cm-toast.bad{color:var(--danger-text)}

/* ── 可绑账号选择卡 ── */
.cm-accs{display:grid;gap:8px;grid-template-columns:repeat(auto-fill,minmax(238px,1fr))}
.cm-acc{display:flex;align-items:center;gap:9px;border:1px solid var(--line);
  border-radius:var(--r-sm);background:var(--e1);padding:9px 11px;cursor:pointer;
  transition:border-color .13s,background .13s}
.cm-acc:hover{border-color:var(--line-strong);background:var(--e3)}
.cm-acc.on{border-color:var(--accent-line);background:var(--accent-wash)}
.cm-acc .cm-av{width:28px;height:28px;font-size:var(--fs-micro)}
.cm-acc .cm-an{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;gap:1px}
.cm-acc .cm-an1{font-size:var(--fs-small);color:var(--t1);font-weight:600;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.cm-acc .cm-an2{font-size:var(--fs-micro);color:var(--t3)}
.cm-acc .cm-note{font-size:var(--fs-micro);color:var(--t3);flex:none}

/* ── 令牌明文框（★ 只显示一次，视觉必须显眼且不可忽略）── */
.cm-tk{border:1px solid var(--amber-line);background:var(--amber-bg);border-radius:var(--r-md);
  padding:11px 13px;display:flex;flex-direction:column;gap:8px}
.cm-tk .cm-tkh{display:flex;align-items:center;gap:7px;font-size:var(--fs-small);
  color:var(--amber);font-weight:600}
.cm-tk .cm-tkw{font-size:var(--fs-micro);color:var(--t2);line-height:1.55}
.cm-tk .cm-tkv{display:flex;align-items:center;gap:7px}
.cm-tk .cm-tkv code{flex:1 1 auto;min-width:0;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;
  font-size:var(--fs-caption);color:var(--t1);background:var(--e1);border:1px solid var(--line);
  border-radius:var(--r-xs);padding:6px 8px;overflow-wrap:anywhere;user-select:all}
.cm-tk .cm-tkf{font-size:var(--fs-micro);color:var(--t3)}

/* ── 参数面板（3 组 / N 行；行数由服务端 schema 决定，前端不写死）── */
.cm-grp{border:1px solid var(--line);border-radius:var(--r-md);background:var(--e1);
  margin-bottom:11px;overflow:hidden}
.cm-grph{display:flex;align-items:center;gap:8px;padding:9px 13px;background:var(--e3);
  border-bottom:1px solid var(--line);font-size:var(--fs-small);color:var(--t1);font-weight:600}
.cm-grph .cm-grpn{font-size:var(--fs-micro);color:var(--t3);font-weight:400}
.cm-row2{display:flex;align-items:center;gap:12px;padding:9px 13px;border-bottom:1px solid var(--hairline)}
.cm-row2:last-child{border-bottom:0}
.cm-rl{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;gap:2px}
.cm-rl .cm-r1{font-size:var(--fs-small);color:var(--t1)}
.cm-rl .cm-r2{font-size:var(--fs-micro);color:var(--t3)}
.cm-rr{flex:none;display:flex;align-items:center;gap:7px}
.cm-int{width:76px;background:var(--e2);border:1px solid var(--line);border-radius:var(--r-xs);
  color:var(--t1);font-size:var(--fs-caption);padding:4px 7px;text-align:right;
  font-variant-numeric:tabular-nums}
.cm-int:focus{outline:none;border-color:var(--accent-line);box-shadow:0 0 0 2px var(--ring)}
.cm-unit{font-size:var(--fs-micro);color:var(--t3);min-width:16px}
.cm-txt{width:104px;background:var(--e2);border:1px solid var(--line);border-radius:var(--r-xs);
  color:var(--t1);font-size:var(--fs-caption);padding:4px 7px;font-variant-numeric:tabular-nums}
.cm-txt:focus{outline:none;border-color:var(--accent-line);box-shadow:0 0 0 2px var(--ring)}
.cm-int.bad,.cm-txt.bad{border-color:var(--danger-line);box-shadow:0 0 0 2px var(--danger-bg)}
/* 开关（2 态）：用真实 checkbox + 自绘滑轨，键盘可达 */
.cm-sw{position:relative;width:38px;height:21px;flex:none;display:inline-block}
.cm-sw input{position:absolute;inset:0;opacity:0;margin:0;cursor:pointer;width:100%;height:100%}
.cm-sw .cm-swb{position:absolute;inset:0;border-radius:var(--r-full);background:var(--e4);
  border:1px solid var(--line);transition:background .15s,border-color .15s;pointer-events:none}
.cm-sw .cm-swb::after{content:'';position:absolute;top:2px;left:2px;width:15px;height:15px;
  border-radius:50%;background:var(--t3);transition:transform .15s,background .15s}
.cm-sw input:checked + .cm-swb{background:var(--accent-wash);border-color:var(--accent-line)}
.cm-sw input:checked + .cm-swb::after{transform:translateX(17px);background:var(--accent)}
.cm-sw input:focus-visible + .cm-swb{box-shadow:0 0 0 2px var(--ring)}
.cm-cfgf{display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  padding:11px 13px;border:1px solid var(--line);border-radius:var(--r-md);background:var(--e1)}
.cm-rev{font-size:var(--fs-micro);color:var(--t3);font-variant-numeric:tabular-nums}
.cm-rev code{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;letter-spacing:.3px}

/* ── 提示条（进站说明 / 纪律说明）── */
.cm-tip{border:1px solid var(--line);border-left:3px solid var(--accent-line);
  background:var(--e1);border-radius:var(--r-sm);padding:9px 12px;margin-bottom:13px;
  font-size:var(--fs-micro);color:var(--t2);line-height:1.6}
.cm-tip b{color:var(--t1);font-weight:600}
.cm-tip .cm-tipw{color:var(--amber)}

/* ══ ② 微信号（acctmgmt）· 2026-10-03 ═══════════════════════════════════
   用户令：「在 AI 同事那里加个微信号管理 —— 微信号-绑定采集机编号-绑定教练」。
   一行一个号 = 号名 + 采集机（编号/别名/最后在线）+ 负责教练 + 操作。
   ★ 配色纪律同文件头：**只用四主题齐备的令牌，零字面色值**。
     · 「已绑上」的编号 ⇒ `--accent*`（本仓 accent = 正常/激活，见纪律 1）
     · 「已停用」⇒ 弱化色（**不用红**：停用是正常状态，不是错误）
     · 「未绑 / 未指派」⇒ `--t3` 弱化，且与"有值"在**字重**上也能分辨（不是只靠颜色）
   ★ 候选卡片（`.cm-amp-i`）是**可点的**：有边框 + 卡片形态，不靠 hover 才知道能点
     （复杂度红线 ④）。选中态用 `--accent-wash` 而不是只换个字色。 */
.cm-amlist{display:flex;flex-direction:column;gap:8px}
.cm-amrow{border:1px solid var(--line);border-radius:var(--r-md);background:var(--e1);
  padding:11px 13px;display:flex;flex-direction:column;gap:7px}
.cm-amrow:hover{border-color:var(--line-strong)}
.cm-amrow.off{opacity:.72}
.cm-amhd{display:flex;align-items:center;gap:10px;min-width:0}
.cm-amn1{display:flex;align-items:center;gap:7px;min-width:0;flex-wrap:wrap}
.cm-amname{font-size:var(--fs-small);color:var(--t1);font-weight:600}
.cm-amid{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:var(--fs-caption);
  color:var(--t3);border:1px solid var(--line);border-radius:var(--r-sm);padding:0 5px}
.cm-amtag{font-size:var(--fs-micro);color:var(--t3);border:1px solid var(--line);
  border-radius:var(--r-sm);padding:0 5px}
.cm-ams{display:flex;align-items:baseline;gap:8px;font-size:var(--fs-small);
  min-width:0;flex-wrap:wrap}
.cm-aml{flex:none;width:62px;color:var(--t3);font-size:var(--fs-caption)}
.cm-amv{color:var(--t1);display:flex;align-items:baseline;gap:8px;flex-wrap:wrap;min-width:0}
.cm-amv b{font-weight:600}
.cm-amno{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:var(--fs-caption);
  color:var(--accent-text);border:1px solid var(--accent-line);background:var(--accent-wash);
  border-radius:var(--r-sm);padding:1px 6px;letter-spacing:.3px}
.cm-amnm{color:var(--t2);font-size:var(--fs-caption)}
.cm-amt{color:var(--t3);font-size:var(--fs-micro)}
.cm-amoff{color:var(--t3);font-size:var(--fs-micro);border:1px dashed var(--line);
  border-radius:var(--r-sm);padding:0 5px}
.cm-amw{color:var(--amber);font-size:var(--fs-micro)}
.cm-amacts{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
/* —— 候选面板（点「绑一台机 / 指派教练」就地展开）—— */
.cm-amp{border:1px solid var(--line);border-left:3px solid var(--accent-line);
  background:var(--e2);border-radius:var(--r-sm);padding:9px 11px;
  display:flex;flex-direction:column;gap:7px}
.cm-amp-h{font-size:var(--fs-micro);color:var(--t2);display:flex;gap:9px;
  flex-wrap:wrap;align-items:baseline}
.cm-amp-h b{color:var(--t1);font-weight:600}
.cm-amp-w{color:var(--amber)}
.cm-amp-l{display:flex;gap:7px;flex-wrap:wrap}
.cm-amp-i{display:flex;flex-direction:column;gap:1px;cursor:pointer;user-select:none;
  border:1px solid var(--line);border-radius:var(--r-sm);background:var(--e1);padding:6px 10px}
.cm-amp-i:hover{border-color:var(--line-strong);background:var(--e3)}
.cm-amp-i.on{border-color:var(--accent-line);background:var(--accent-wash)}
.cm-amp-i b{font-size:var(--fs-small);color:var(--t1);font-weight:600;
  font-family:ui-monospace,SFMono-Regular,Menlo,monospace;letter-spacing:.3px}
.cm-amp-i em{font-style:normal;font-size:var(--fs-caption);color:var(--t2);
  max-width:240px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.cm-amp-i i{font-style:normal;font-size:var(--fs-micro);color:var(--t3)}
.cm-amp-e{font-size:var(--fs-micro);color:var(--t3);line-height:1.6}
.cm-amp-e b{color:var(--t2)}
.cm-amf{margin-top:10px}

/* ══ 号位（1 号位 / 2 号位）＋ 热键登记 ＋ 号的增删 · 2026-10-03 用户令 ═══════
   用户令（逐字）：「增加一个添加微信号和删除微信号功能」
                 「AI同事那里，对应的AI同事，增加1号微信和2号微信绑定，并且填入热键」
                 「AI同事采集机那里，也会有同样的设置1号和2号位设置」
   ★ 配色纪律同文件头：**只用四主题齐备的令牌，零字面色值**。这里的四条口径：
     · 「号位里放了号」⇒ 正文色（`--t1`），与"空着"在**字重**上也能分辨（不只靠颜色）
     · 「空着 / 没设」⇒ `--t3` 弱化 + **虚线**（虚线 = "这格是空的"，不是"这格坏了"）
     · 「热键已登记」⇒ **中性底 + 等宽字**，**刻意不用 accent** ——
       它只是一份**登记值**，真热键在采集机的启动配置里（用户 2026-10-03 拍板）。
       画成"已生效"的绿/亮色，就等于在屏上对用户说了一句假话。
     · 「号位上的号已退役 / 停用」⇒ `--amber`（要人看一眼，但**不是错误** —— 同 `.cm-amw`）
   ★ 形态：号位块放在 `.cm-card` / `.cm-amrow` **内部** ⇒ 不要再叠一层卡片阴影
     （叠了会看起来像"卡片里嵌了另一张卡"，层级读不出来）。 */

/* 「几号位」小片 —— 紧跟在采集机编号后面。
   ★ 它是**结构信息**（这个号在哪一格），不是状态 ⇒ 中性色，不用 accent / amber。 */
.cm-ampos{font-size:var(--fs-micro);color:var(--t2);border:1px solid var(--line);
  border-radius:var(--r-sm);padding:0 5px}

/* —— 号位块（同事卡里那一段）—— */
.cm-slots{margin-top:9px;padding-top:9px;border-top:1px dashed var(--line);
  display:flex;flex-direction:column;gap:5px}
.cm-slh2{font-size:var(--fs-micro);color:var(--t2);display:flex;gap:9px;
  flex-wrap:wrap;align-items:baseline}
.cm-slhn{color:var(--t3)}
.cm-slrow{display:flex;align-items:center;gap:8px;flex-wrap:wrap;font-size:var(--fs-caption)}
.cm-slno{flex:none;width:58px;color:var(--t3);font-size:var(--fs-micro)}
.cm-slv{display:flex;align-items:center;gap:8px;flex-wrap:wrap;min-width:0;flex:1}
.cm-slv b{color:var(--t1);font-weight:600}
.cm-slhk{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:var(--fs-micro);
  color:var(--t2);border:1px solid var(--line);background:var(--e2);
  border-radius:var(--r-sm);padding:0 5px;letter-spacing:.3px}
.cm-slhk.none{color:var(--t3);border-style:dashed;background:transparent}
.cm-sloff{color:var(--amber);font-size:var(--fs-micro)}

/* —— ★ 2026-10-04「平台号位」新加的两块：平台小标题 / 号位级路况 —— */
/* 平台小标题（**只在多平台时出现**，只回微信的老服务端不显示 —— 见 `slotsHtml`）。
   ⚠ 它是**分组标题**不是行：所以要压过 `.cm-slrow` 的字号，且不能抢走视线
     （这一块的正文是各行，标题只是把它切开）。 */
.cm-slpl{font-size:var(--fs-micro);color:var(--t3);letter-spacing:.6px;
  margin-top:3px;padding-top:3px;border-top:1px dotted var(--line)}
.cm-slpl:first-child{margin-top:0;padding-top:0;border-top:0}
/* 号位级**路况**小标（= 这一位所属平台那条路的此刻状态，见 `roadOf` 的三条口径）。
   ⚠ 与 `.cm-road`（四条路那块）**形态不同、颜色口径相同**：那块是整行的
     圆点+名字+状态，这块是塞在号位行里的一个小胶囊 ⇒ 共用那套"要人看一眼=琥珀、
     坏了=红、不知道=灰虚框"的语义，但排版各自写。 */
.cm-slrd{flex:none;font-size:var(--fs-micro);color:var(--t3);
  border:1px solid var(--line);background:var(--e2);
  border-radius:var(--r-full);padding:0 7px;white-space:nowrap}
/* 三档"没有好消息"：红=有问题 / 琥珀=要你看一眼 / 灰虚框=**不知道**。
   ★ 灰与琥珀必须分开 —— 「还没上报」不是坏消息，渲染成坏消息就是造假读数。 */
.cm-slrd.none{color:var(--t3);border-style:dashed;background:transparent}
.cm-slrd.need_action,.cm-slrd.need_login,.cm-slrd.not_wired,
.cm-slrd.not_installed,.cm-slrd.bad_schema,.cm-slrd.stale,
.cm-slrd.offline,.cm-slrd.stopped{
  color:var(--amber);border-color:var(--amber-line);background:var(--amber-bg)}
.cm-slrd.dead,.cm-slrd.error{
  color:var(--danger-text);border-color:var(--danger-line);background:var(--danger-bg)}
/* 「正在干活 / 空着 / 在跑」这类**正常态**：不上色（本仓「正常态不上屏」）——
   只有它不是"正常态"时才值得把眼睛叫过去。 */
.cm-slrd.working,.cm-slrd.idle,.cm-slrd.running,.cm-slrd.paused{color:var(--t2)}

/* —— ★ 2026-10-04「整机在线」小标（同事卡右上，与「绑定态」并列）——
   ⚠ 与 `.cm-st`（绑定态）**刻意长得像但是另一件事**：绑定态答"配置好没有"，
     在线答"此刻在不在"。一个绑好的机可以掉线好几天，而绑定态一直写"已绑定"。 */
.cm-onl{flex:none;display:flex;align-items:center;gap:5px;font-size:var(--fs-micro);
  padding:3px 9px;border-radius:var(--r-full);border:1px solid var(--line);
  background:var(--e3);color:var(--t3);white-space:nowrap}
.cm-onl i{width:6px;height:6px;border-radius:50%;background:var(--t3);flex:none}
/* 在线 = **正常态** ⇒ 最不起眼（只用圆点给一点绿意，不占视觉权重） */
.cm-onl.online{color:var(--t2)}
.cm-onl.online i{background:var(--accent);opacity:.8}
/* 掉线 = 要你看一眼（但**不是**故障色 —— 也许只是下班关机了） */
.cm-onl.unreachable{color:var(--amber);background:var(--amber-bg);border-color:var(--amber-line)}
.cm-onl.unreachable i{background:var(--amber)}
/* 从没联系过 = **新机**的常态，不是坏事 ⇒ 虚框不实（与"掉线"分开） */
.cm-onl.never{color:var(--t3);border-style:dashed}
.cm-onl.none{color:var(--t3);border-style:dashed;background:transparent}

/* ── ★ 2026-10-04：新增号表单里的**平台选择条** ──────────────────────────
   故意复用 `.cm-amp-i` 的"可点的卡片"外观（本仓：可点的东西必须有边框形态，
   **不靠 hover 才知道能点**）—— 但这里它只放一个 `<b>`，所以要收掉
   候选卡那种竖排的间距。 */
.cm-plpik{display:inline-flex;gap:6px;flex-wrap:wrap}
.cm-plpik .cm-amp-i{padding:3px 10px;border-radius:var(--r-full)}
.cm-plpik .cm-amp-i b{font-size:var(--fs-caption)}
/* 已选中的那个：底色 + 边框变强调色（与 `.cm-amp-i.on` 同一套口径，
   但这里**必须自己写一条** —— `.cm-amp-i.on` 只在候选列表里被定义过，
   若哪天那一条改了，这里会静默跟着变而没人知道）。 */
.cm-plpik .cm-amp-i.on{border-color:var(--accent-line);background:var(--accent-wash);
  color:var(--accent-text)}

/* 热键 / 微信号这类**就地小表单**的输入行：标签 + 输入框。
   ⚠ 刻意**不复用参数页的 `.cm-row2`** —— 那是两栏网格（左标签右控件、等宽对齐），
     这一处是面板里的一行小表单。形态不同硬并成一个类，改一处就会动到另一处的版。 */
.cm-hkrow{display:flex;align-items:center;gap:9px;flex-wrap:wrap}
.cm-hkl{flex:none;width:58px;color:var(--t3);font-size:var(--fs-micro)}
/* 宽一点：热键（`CTRL+ALT+W`）与微信号都不是 104px 能读全的 */
.cm-hkin{width:200px;max-width:100%}
.cm-hkw{line-height:1.6}

/* 「＋ 添加微信号」那一行（**空态里也有**，见 `acctAddHtml` 的注释）：
   与上面的列表拉开距离 —— 贴太近会被读成"列表的最后一项"。 */
.cm-amactsb{margin-top:11px}
/* 号的**生死**动作单独一行：一条实线把它与"改挂靠"那一排分开 ——
   两类动作的后果面不同（一个只动收发链路、一个牵动人设/客户档案的归属），
   摆在一起会让人以为是一个量级的事。 */
.cm-amlife{margin-top:2px;padding-top:8px;border-top:1px solid var(--line)}
/* 新号表单（摊开时）—— 形态照 `.cm-amp`（面板），左边框用 accent（**不是危险动作**）。 */
.cm-amnew{border:1px solid var(--line);border-left:3px solid var(--accent-line);
  background:var(--e2);border-radius:var(--r-sm);padding:10px 12px;margin-top:11px;
  display:flex;flex-direction:column;gap:8px}
/* 删除的确认条：左边框换成 **danger**（覆盖 `.cm-amp` 的 accent）——
   一眼能看出"这一块里那个按钮是不可逆的"。 */
.cm-ampd{border-left-color:var(--danger-line)}
/* "它还占着 N 个号位"那一段（只在被 `ACCOUNT_IN_USE` 挡下后出现）：
   与上面的问句用一条虚线分开，免得两个问句读成一句。 */
.cm-ampwd{border-top:1px dashed var(--line);padding-top:7px}

/* ══ 左栏号位角标（`nav.rail`）· 2026-10-03 ══════════════════════════════════
   用户令：「左侧栏微信1和2号位置也绑定」→ 拍板「角标 + 就地改」。
   浮层与本站**共用一套类名**（`.cm-amp*` / `.cm-btn` / `.cm-toast`）⇒ 站内面板长什么样，
   左栏这一份就长什么样（两处一份样式，改一处两处都变）。

   ★ 角标画在**右下**：`.acct` 的右上已被未读数 `.acct .badge` 占着（shell.css:169）——
     两枚都挤右上就是"有一枚永远看不见"，且不报错。
     `.acct` 本身就是 `position:relative`（shell.css:160）⇒ 这里不必也不该再定一次。
   ★ 常驻可见、**不依赖 hover**（本仓纪律「不加 hover 才知道能点的」）；
     "未绑号位"画浅色虚线 `+` —— 只给已绑的画，未绑的号就没有入口（「空态没有出路」族）。
   ★ 令牌只用四主题齐备的（`tokens.css` 各出现 4 次）；本文件**零字面色值**。 */
.rail-slot{position:absolute;right:-1px;bottom:-1px;min-width:16px;height:16px;padding:0 4px;
  border:1px solid var(--accent-line);border-radius:var(--r-full);
  background:var(--accent-wash);color:var(--accent-text);
  font-size:var(--fs-micro);line-height:14px;font-weight:500;text-align:center;
  cursor:pointer;box-shadow:0 0 0 2px var(--e1)}
.rail-slot:hover{border-color:var(--accent);color:var(--t1)}
.rail-slot.none{background:transparent;border-style:dashed;border-color:var(--line-strong);
  color:var(--t3)}
.rail-slot.none:hover{color:var(--t1);border-color:var(--accent-line)}
.rail-slot:focus-visible{outline:2px solid var(--focus);outline-offset:1px}

/* 浮层：挂在 `document.body`（左栏会被 `renderRail()` 整块重写 ⇒ 挂栏内会被抹掉）。
   ★ `z-index:58` —— 高于内容层（`.dtl` 41/42 · `#scrim` 40）、低于「外观」面板(60)
     与其捕获层(59)：同屏时层序与"谁在谁上面"一致。 */
#railPop{position:fixed;left:76px;top:120px;z-index:58}
.rail-pop{width:340px;max-width:calc(100vw - 92px);
  max-height:calc(100vh - 32px);overflow:auto;
  box-shadow:0 10px 28px -12px var(--sh-2)}
/* 候选区单独封顶：机器多时（实测 11 台机 = 21 条候选）不封顶会把按钮顶出屏幕 ——
   而"按钮在屏幕外"在屏上读起来像"这个面板没有保存键"。
   ⚠ 留 4px 右内边距：macOS 的滚动条是**浮在内容上**的（且默认不显示），不留白会压住卡片右缘。
   条数由 JS 在候选区下方补一行"共 N 个可选位"（`railRenderPop`）—— 见那里为什么必须有。 */
.rail-pop .cm-amp-l{max-height:420px;overflow:auto;padding-right:4px}

/* ── 窄窗兜底（≤949）：与其余站同策略 —— 不隐藏，只让横向让位 ── */
@media (max-width:949px){
  .cm-body{padding:11px}
  .cm-kpis .cm-kpi.opt{display:none}
  .cm-accs{grid-template-columns:1fr}
}
