/* ============================================================
 * NetOps Console — theme.css（两档皮肤 + 四层宇宙元素）
 *
 * 体系（计划 §3，2026-10-08 老板调整）：
 *   一套骨架 token 两档共享，差异只在"装饰层与动效强度"，
 *   由 <html data-skin="legacy|tech-max"> 一处开关。
 *   （克制档 tech-lite 已取消——风格差异不够明显；老皮肤保留严格专业提示语，
 *     满配保留温暖俏皮提示语 + 戴森球网状链接动画）
 *
 * 三条硬规则：
 *   1. 皮肤档只换 token 与装饰强度，不换布局结构（两档同一套 HTML）
 *   2. 皮肤档位 ≠ 信息页分档：S8 的资产/RAG/V2 装饰固定 A 档，色板跟随所选皮肤
 *   3. 移动端 / prefers-reduced-motion 强制降强度（js 设 html[data-deco="lite"]）
 *
 * 字体：只用本机已有（决策 6），不引用任何外部 CDN。
 * ============================================================ */

/* ===== 0. Reset + 共享骨架 ===== */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

html {
  font-size: 14px;
  -webkit-text-size-adjust: 100%;
}

body {
  min-height: 100vh;
  font-family: var(--font-sans);
  background: var(--bg);
  color: var(--text);
  line-height: 1.6;
  overflow-x: hidden;
}

img { max-width: 100%; height: auto; }
button { font-family: inherit; cursor: pointer; }
input, textarea { font-family: inherit; }

:root {
  --font-sans: "Noto Sans SC", "Segoe UI", "Microsoft YaHei", system-ui, sans-serif;
  --font-mono: "Consolas", "JetBrains Mono", ui-monospace, monospace;

  /* z-index 层级（C5 · 2026-10-17）：新增层一律用变量，别再写魔法数字。
     原 .toast(95) 被 .subtitle-bar(96) 压住 —— 两者都是底部居中的 fixed 层。 */
  --z-bg: 0;          /* 背景装饰 */
  --z-content: 1;     /* 常规内容 / 卡片 */
  --z-topbar: 40;     /* 顶栏 */
  --z-overlay: 60;    /* 局部浮层（弹层遮罩等） */
  --z-modal: 80;      /* 模态框 */
  --z-subtitle: 96;   /* 底部字幕条 */
  --z-toast: 97;      /* 瞬时提示：必须在字幕条之上 */
  --z-sticky: 300;    /* 全屏/专注层 */
  --z-alert: 1200;    /* 最顶层警示（受限横幅等） */

  --r-card: 12px;
  --r-ctrl: 8px;
  --topbar-h: 60px;
  --gap: 16px;

  /* 切角轮廓（戴森球六边形感）：削右上与左下 */
  --cut: polygon(0 0, calc(100% - 16px) 0, 100% 16px, 100% 100%, 16px 100%, 0 calc(100% - 16px));

  --t-fast: 150ms cubic-bezier(.4, 0, .2, 1);
  --t-norm: 220ms cubic-bezier(.4, 0, .2, 1);
}

/* ===== 1. 皮肤档：老皮肤（NetKB 极简风，决策 30）===== */
/* 源自 network-knowledge-base\app\static\core.css，2026-10-08 逐行提取 */
[data-skin="legacy"] {
  --bg: #f8fafc;
  --surface: #ffffff;
  --surface-2: #f1f5f9;
  --surface-3: #e2e8f0;
  --line: #e2e8f0;
  --line-strong: #cbd5e1;
  --text: #0f172a;
  --dim: #475569;
  --dim-2: #64748b;           /* 2.6:1 → 4.8:1 */

  --accent: #3b82f6;
  --accent-2: #2563eb;
  --accent-light: #eff6ff;
  --brand-gradient: linear-gradient(135deg, #3b82f6 0%, #8b5cf6 100%);
  --warn: #b45309;            /* 2026-10-11 审计 #15：白底 2.1:1 → 4.6:1（WCAG AA）*/
  --ok: #047857;              /* 2.5:1 → 5.2:1；夜间档在下方 dark 块回填亮色 */
  --danger: #ef4444;
  --danger-ink: #b91c1c;          /* V2-35③：危险按钮文字色（白底 5.9:1，原 #ef4444 只有 3.43）*/

  --shadow: 0 1px 3px rgba(0, 0, 0, .1), 0 1px 2px rgba(0, 0, 0, .06);
  --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, .1), 0 4px 6px -4px rgba(0, 0, 0, .1);
  --glow: 0 0 0 rgba(0, 0, 0, 0);   /* 审计 #15：none 拼进 box-shadow 逗号列表会整条 IACVT 失效 */
  --topbar-bg: rgba(255, 255, 255, .92);

  /* 装饰层全部关闭 */
  --deco-grid: 0;
  --deco-nebula: 0;
  --deco-stars: 0;
  --deco-canvas: 0;
  --deco-cut: 0;
  --deco-bracket: 0;
  --deco-orbit: 0;
  --deco-orbit-spin: 0s;
  --deco-radar: 0;
  --deco-scan: 0;
  --deco-hud: 0;
  --deco-breathe: 0;

  --card-radius: var(--r-card);
}

/* 老皮肤自带的深色变体（原项目 [data-theme="dark"]） */
[data-skin="legacy"][data-theme="dark"] {
  /* 夜间回填亮色（浅色块加深前的原值，深底上可读性更好） */
  --warn: #f59e0b;
  --ok: #10b981;
  --bg: #0f172a;
  --surface: #1e293b;
  --surface-2: #334155;
  --surface-3: #475569;
  --line: #334155;
  --line-strong: #475569;
  --text: #f1f5f9;
  --dim: #94a3b8;
  --dim-2: #64748b;
  --accent-light: #1e3a5f;
  --shadow: 0 1px 2px rgba(0, 0, 0, .2), 0 1px 3px rgba(0, 0, 0, .3);
  --shadow-lg: 0 10px 15px rgba(0, 0, 0, .3);
  --topbar-bg: rgba(30, 41, 59, .94);
}

/* ===== 2. 皮肤档：科技·满配（tech-max）=====
   2026-10-08 老板指令加强：原"纯黑对比度不够" → 面板提亮、线条加亮、
   文字提纯、辉光加强；克制档已取消，本块即满配专属。 */
[data-skin="tech-max"] {
  --bg: #0a0d13;
  --surface: #171d27;
  --surface-2: #1e2531;
  --surface-3: #272f3d;
  --line: #333d4d;
  --line-strong: #4a5668;
  --text: #f2f6fc;
  --dim: #9fa9b8;
  --dim-2: #7c8799;

  --accent: #7c8cff;          /* 电光蓝紫，决策 A */
  --accent-2: #8b7bff;
  --accent-light: rgba(124, 140, 255, .12);
  --brand-gradient: linear-gradient(135deg, #7c8cff 0%, #8b7bff 100%);
  --warn: #ffa94d;            /* 琥珀橙：仅警告/临界 */
  --ok: #5bc98a;
  --danger: #ff5c5c;
  --danger-ink: #ff9a9a;          /* V2-35③：深色底上更亮一档（8.5:1）*/

  --shadow: 0 1px 2px rgba(0, 0, 0, .5);
  --shadow-lg: 0 12px 32px rgba(0, 0, 0, .55);
  --glow: 0 0 24px rgba(124, 140, 255, .38);
  --star: rgba(255, 255, 255, .72);
  --topbar-bg: rgba(10, 13, 19, .93);

  /* 满配基础装饰（强度档再叠 nebula/canvas/radar/scan） */
  --deco-grid: 1;
  --deco-nebula: 0;
  --deco-stars: 1;
  --deco-canvas: 0;
  --deco-cut: 1;
  --deco-bracket: 1;
  --deco-orbit: 1;
  --deco-orbit-spin: 0s;
  --deco-radar: 0;
  --deco-scan: 0;
  --deco-hud: 1;
  --deco-breathe: 0;

  --card-radius: 12px;
}

/* ===== 3. 皮肤档：科技·满配（tech-max）===== */
[data-skin="tech-max"] {
  --deco-nebula: 1;
  --deco-canvas: 1;
  --deco-orbit-spin: 22s;
  --deco-radar: 1;
  --deco-scan: 1;
  --deco-breathe: 1;
}

/* 移动端 / 减弱动效 / 手动低动效：强制降为克制强度（js 设 data-deco="lite"）
   2026-10-11 老板：ToDesk 远程访问时页面一直闪烁 —— 远程是把每帧画面当视频传，
   任何"持续变化"都会让编码器一直出块（全屏 canvas 重绘、无限循环动画、
   backdrop-filter 模糊的每帧重采样）。lite 档除了下面的变量，还要把动画与模糊整体停掉。 */
[data-deco="lite"] {
  --deco-nebula: 0;
  --deco-canvas: 0;
  --deco-orbit-spin: 0s;
  --deco-radar: 0;
  --deco-scan: 0;
  --deco-breathe: 0;
}

/* 低动效：停掉所有动画/过渡（与上方无障碍降级同一套写法）——远程下画面近乎静止，不再闪 */
[data-deco="lite"] *, [data-deco="lite"] *::before, [data-deco="lite"] *::after {
  animation-duration: .001ms !important;
  animation-iteration-count: 1 !important;
  transition-duration: .001ms !important;
}
/* 低动效：去掉 backdrop-filter 模糊（远程/无 GPU 合成时它每帧重采样，是闪烁的头号嫌疑）
   覆盖全站 5 处模糊：.topbar / .mem-legend / .modal / .subtitle-bar / .focus-scenes */
[data-deco="lite"] .topbar,
[data-deco="lite"] .mem-legend,
[data-deco="lite"] .modal,
[data-deco="lite"] .subtitle-bar,
[data-deco="lite"] .focus-scenes {
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
}

/* ===== 3b. 皮肤档：科技·日（tech-max + data-theme="light"，2026-10-09 老板指令：两种皮肤都带日夜）=====
   浅色底保留科技网格/切角/括号装饰，发光减淡、星空关闭（星空仅科技·夜）；
   变量名与 tech-max 全对齐，靠更高特异性覆盖，不动夜里任何规则。 */
[data-skin="tech-max"][data-theme="light"] {
  --bg: #f2f4fa;
  --surface: #ffffff;
  --surface-2: #edf0f8;
  --surface-3: #e2e7f3;
  --line: #d8deec;
  --line-strong: #b7c0d8;
  --text: #17203a;
  --dim: #4a5570;
  --dim-2: #566079;           /* 审计 #15：浅底加深到 4.6:1 */

  --accent: #4d5ce8;          /* 浅底对比度加强的蓝紫 */
  --accent-2: #6f5df2;
  --accent-light: rgba(77, 92, 232, .10);
  --brand-gradient: linear-gradient(135deg, #4d5ce8 0%, #6f5df2 100%);
  --warn: #b45309;            /* 审计 #15：浅底 2.9:1 → 4.6:1 */
  --ok: #047857;              /* 3.0:1 → 5.0:1 */
  --danger: #e5484d;
  --danger-ink: #b3261e;          /* V2-35③：浅底加深（6.1:1）*/

  --shadow: 0 1px 2px rgba(23, 32, 58, .07), 0 2px 8px rgba(23, 32, 58, .05);
  --shadow-lg: 0 12px 30px rgba(23, 32, 58, .12);
  --glow: 0 0 0 rgba(0, 0, 0, 0);   /* 审计 #15：同 legacy——弹窗阴影整条失效的根 */
  --star: rgba(90, 105, 220, .4);
  --topbar-bg: rgba(255, 255, 255, .93);

  --deco-stars: 1;            /* 2026-10-10 老板：日间也要戴森球元素 → 全开 */
  --deco-canvas: 1;
  --deco-nebula: 1;
  --card-radius: 12px;
}

/* ===== 3b-lite 叠加：日间 × 降级的关断（2026-10-13）=====
   上面 3b 日间块选择器特异性 0-2-0，把 --deco-canvas / --deco-nebula 提回 1，
   压过了下面 [data-deco="lite"]（0-1-0）的 0 —— 结果**日间+降级时星野 canvas 与星云没关**
   （夜间档 tech-max 与 lite 同为 0-1-0、靠位置在后才正常）。这里用三属性（0-3-0）写回关断。
   只修 3b 引入的这两个：--deco-stars 日间夜间本就都是 1、lite 档从不关它，不动。 */
[data-skin="tech-max"][data-theme="light"][data-deco="lite"] {
  --deco-canvas: 0;
  --deco-nebula: 0;
}

/* 科技·日 图形元素与夜间同框（浓度按浅底重调，对 11.6 满配强化块更高特异性覆盖） */
[data-skin="tech-max"][data-theme="light"] body::before { opacity: .55; }
[data-skin="tech-max"][data-theme="light"] body::after {
  background:                              /* 浅底星云：同色相、低浓度不压内容 */
    radial-gradient(900px 500px at 15% -8%, rgba(99, 116, 255, .15), transparent 60%),
    radial-gradient(760px 420px at 88% 4%, rgba(139, 123, 255, .13), transparent 62%),
    radial-gradient(900px 560px at 62% 112%, rgba(77, 92, 232, .11), transparent 60%);
  opacity: .9;
}

/* 科技·日 标题可读性：白渐变字在浅底隐形 → 深色渐变 */
[data-skin="tech-max"][data-theme="light"] .section-title h2 {
  background: linear-gradient(90deg, #17203a, #3d4bb8);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
[data-skin="tech-max"][data-theme="light"] .section-title .idx {
  color: var(--accent);
  text-shadow: none;
}
[data-skin="tech-max"][data-theme="light"] .section-title .rule {
  background: linear-gradient(90deg, rgba(77, 92, 232, .55), rgba(77, 92, 232, .06));
}

/* ===== 4. 背景装饰层（四层分色原则：低对比、低饱和、低频动）===== */
body::before {           /* 背景层①：细网格 */
  content: "";
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image:
    linear-gradient(var(--line) 1px, transparent 1px),
    linear-gradient(90deg, var(--line) 1px, transparent 1px);
  background-size: 56px 56px;
  opacity: calc(var(--deco-grid) * .55);
}

body::after {            /* 背景层②：星云（仅满配，静态多层渐变不逐帧画） */
  content: "";
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background:
    radial-gradient(900px 500px at 15% -8%, rgba(124, 140, 255, .16), transparent 60%),
    radial-gradient(760px 420px at 88% 4%, rgba(139, 123, 255, .12), transparent 62%),
    radial-gradient(900px 560px at 62% 112%, rgba(124, 140, 255, .10), transparent 60%);
  opacity: var(--deco-nebula);
}

#scene {               /* 背景层②.5：戴森球场景（恒星/球壳/能量流/太阳帆/火箭，scene.js） */
  display: none;        /* 默认关：仅科技档渲染（传统档零元素） */
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
}
[data-skin="tech-max"] #scene { display: block; }
[data-skin="tech-max"][data-deco="lite"] #scene { display: none; }   /* 移动端关（JS 双守卫） */

#stars {                 /* 背景层③：canvas 星空（仅满配，js 控制开销） */
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: var(--deco-canvas);
  transition: opacity var(--t-norm);
}

.starfield {             /* 背景层④：CSS 星点（克制档也有的低成本星点） */
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: calc(var(--deco-stars) * .9);
  background-image:
    radial-gradient(1.4px 1.4px at 12% 18%, var(--star), transparent),
    radial-gradient(1.2px 1.2px at 78% 12%, var(--star), transparent),
    radial-gradient(1.6px 1.6px at 34% 64%, var(--star), transparent),
    radial-gradient(1.2px 1.2px at 88% 72%, var(--star), transparent),
    radial-gradient(1.3px 1.3px at 55% 36%, var(--star), transparent),
    radial-gradient(1.1px 1.1px at 6% 82%, var(--star), transparent),
    radial-gradient(1.5px 1.5px at 66% 88%, var(--star), transparent),
    radial-gradient(1.2px 1.2px at 24% 44%, var(--star), transparent);
  animation: drift 90s linear infinite alternate;
}

@keyframes drift { to { transform: translate3d(-18px, -12px, 0); } }
@keyframes spin { to { transform: rotate(360deg); } }
@keyframes breathe { 0%, 100% { opacity: 1; box-shadow: 0 0 8px currentColor; } 50% { opacity: .55; box-shadow: 0 0 18px currentColor; } }
@keyframes hud-in { from { opacity: 0; transform: translate3d(0, 14px, 0); } to { opacity: 1; transform: none; } }
@keyframes scan-sweep { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
@keyframes topbar-glint {
  0% { background-position: -90px 0; }
  100% { background-position: calc(100% + 90px) 0; }
}

/* ===== 5. 布局（三档共用同一套结构）===== */
.stage {
  position: relative;
  z-index: 1;
  max-width: 1360px;
  margin: 0 auto;
  padding: 22px 20px 64px;
}

.topbar {
  position: sticky;
  top: 0;
  z-index: 40;
  display: flex;
  align-items: center;
  gap: 14px;
  min-height: var(--topbar-h);
  padding: 8px 20px;
  background: var(--topbar-bg);
  border-bottom: 1px solid var(--line);
  backdrop-filter: blur(12px);
  overflow: visible;   /* 时统下拉面板不能被裁；扫光改用 background-position 扫动实现 */
}

.topbar::after {         /* 强调层：顶栏细扫光（仅满配） */
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 90px;
  height: 100%;
  background: linear-gradient(90deg, transparent, rgba(124, 140, 255, .16), transparent) no-repeat -90px 0;
  pointer-events: none;
  opacity: var(--deco-scan);
}
[data-skin="tech-max"] .topbar::after { animation: topbar-glint 7s ease-in-out infinite; }

.brand { display: flex; align-items: center; gap: 10px; margin-right: auto; min-width: 0; }
.brand-mark {
  width: 30px; height: 30px;
  display: grid; place-items: center;
  background: var(--brand-gradient);
  color: #fff;
  font-size: 15px;
  /* 六边形标识（戴森球元素·结构层） */
  clip-path: polygon(50% 0, 93% 25%, 93% 75%, 50% 100%, 7% 75%, 7% 25%);
  flex-shrink: 0;
}
.brand-title { font-size: 15px; font-weight: 600; letter-spacing: .01em; white-space: nowrap; }

/* 后端离线横幅（2026-10-11 审计 P1：防"服务挂了页面假装正常"） */
.offline-bar {
  position: sticky; top: var(--topbar-h); z-index: 39;
  margin: 4px 0 10px;
  padding: 9px 16px; border-radius: 10px;
  background: linear-gradient(90deg, rgba(248,113,113,.18), rgba(248,113,113,.08));
  border: 1px solid rgba(248,113,113,.55);
  color: #fca5a5; font-size: 12.5px; font-weight: 600;
  text-align: center; letter-spacing: .02em;
  animation: offline-pulse 1.6s ease-in-out infinite;
}
.offline-bar[hidden] { display: none; }
@keyframes offline-pulse { 50% { border-color: rgba(248,113,113,.9); box-shadow: 0 0 14px rgba(248,113,113,.25); } }
/* 专注+记忆固定顶栏正中央（2026-10-10 老板） */
.topbar-center {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  display: flex; gap: 10px; align-items: center; z-index: 2;
}

/* ===== SNTP 时统（顶栏校正时间 + 偏移徽章 + 详情下拉） ===== */
.clockbox { position: relative; flex-shrink: 0; }
.clock-face {
  display: flex;
  flex-direction: column;      /* 两行：时间行 + 农历·节气·天气行（2026-10-09） */
  align-items: flex-start;
  gap: 2px;
  padding: 5px 11px;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--r-ctrl);
  cursor: pointer;
  transition: border-color var(--t-fast), box-shadow var(--t-fast);
}
.clock-face:hover,
.clock-face[aria-expanded="true"] { border-color: var(--accent); box-shadow: var(--glow); }
.clock-row1 { display: flex; align-items: baseline; gap: 9px; }
/* 2026-10-11 老板（二次）：时间块字体/字号彻底统一——
   整块都用主字体 var(--font-sans)（此前误写 var(--font)，变量不存在导致声明失效；
   且时间数字走 Consolas，与日期数字字形不一）；数字靠 tabular-nums 保持等宽不抖；
   层级固定为「时间 16px / 毫秒与两条副行 11px」，两条副行同字重同色 */
.clock-date {
  font-family: var(--font-sans); font-size: 10.5px; font-weight: 400;
  color: var(--dim); white-space: nowrap; font-variant-numeric: tabular-nums;
}
.clock-lunar {
  font-family: var(--font-sans); font-size: 10.5px; font-weight: 400;
  color: var(--dim); white-space: nowrap;
}
.clock-main {
  font-family: var(--font-sans);
  /* 2026-10-20 老板：字号调小、不要加粗 */
  font-size: 14px;
  font-weight: 400;
  color: var(--text);
  font-variant-numeric: tabular-nums;
  letter-spacing: .01em;
  line-height: 1;
}
.clock-ms {
  font-size: 10.5px; font-weight: 400; color: var(--dim);
  margin-left: 1px; font-variant-numeric: tabular-nums;
}

.ntp-badge {
  font-family: var(--font-mono);
  font-size: 11.5px;
  font-weight: 600;
  padding: 2.5px 7px;
  border-radius: 999px;
  border: 1px solid var(--dim-2);
  color: var(--dim);
  white-space: nowrap;
  letter-spacing: .02em;
}
.ntp-badge.is-pending { border-style: dashed; animation: ntp-pulse 1.4s ease-in-out infinite; }
.ntp-badge.q-ok   { color: var(--ok);     border-color: var(--ok); }
.ntp-badge.q-mid  { color: var(--warn);   border-color: var(--warn); }
.ntp-badge.q-bad  { color: var(--danger); border-color: var(--danger); }
[data-skin="tech-max"] .ntp-badge.q-ok { box-shadow: 0 0 8px rgba(16, 185, 129, .35); }
[data-skin="tech-max"] .ntp-badge.q-bad { box-shadow: 0 0 8px rgba(239, 68, 68, .35); }
@keyframes ntp-pulse { 0%, 100% { opacity: 1; } 50% { opacity: .45; } }

.ntp-pop {
  position: absolute;
  top: calc(100% + 9px);
  right: 0;
  z-index: 60;
  width: min(446px, calc(100vw - 24px));
  max-height: min(78vh, 720px);
  overflow: auto;
  padding: 14px 16px;
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-lg);
}
[data-skin="tech-max"] .ntp-pop { box-shadow: var(--shadow-lg), var(--glow); }
.ntp-pop[hidden] { display: none; }

.ntp-pop-head { display: flex; align-items: center; gap: 9px; padding-bottom: 11px; border-bottom: 1px solid var(--line); }
.ntp-pop-head b { font-size: 13.5px; white-space: nowrap; }
.ntp-ver { font-family: var(--font-mono); font-size: 11.5px; color: var(--dim-2); flex: 1;
  min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ntp-pop-actions { display: flex; gap: 6px; }

.ntp-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 9px 14px; padding: 12px 0 2px; }
.ntp-cell { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.ntp-cell span { font-size: 11.5px; color: var(--dim-2); letter-spacing: .03em; }
.ntp-cell b {
  font-family: var(--font-mono);
  font-size: 12.5px;
  font-weight: 600;
  color: var(--text);
  font-variant-numeric: tabular-nums;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ntp-cell b.q-ok  { color: var(--ok); }
.ntp-cell b.q-mid { color: var(--warn); }
.ntp-cell b.q-bad { color: var(--danger); }

/* ===== NTP 来源表（2026-10-09 多源：全探偏移 + 选优/指定同步） ===== */
.ntp-src { margin-top: 11px; padding-top: 11px; border-top: 1px solid var(--line); }
.ns-head { display: flex; align-items: baseline; gap: 10px; min-width: 0; font-size: 11.5px; }
.ns-head b { font-size: 11.5px; color: var(--text); flex-shrink: 0; }
.ns-hint {
  flex: 1; min-width: 0;                  /* 必须可收缩，否则撑宽弹层出横向滚动条 */
  color: var(--dim-2); font-size: 11.5px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ns-rows { display: flex; flex-direction: column; gap: 6px; margin-top: 7px; }
.ns-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 62px 54px 36px 50px 20px auto;
  gap: 6px;
  align-items: center;
  padding: 6px 8px;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: 8px;
  font-size: 11.5px;
}
.ns-row.is-used { border-color: var(--accent); }
.ns-name {
  display: flex; align-items: center; gap: 6px; min-width: 0;
  font-family: var(--font-mono); font-size: 11.5px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ns-tag { font-style: normal; font-size: 11.5px; padding: 1px 5px; border-radius: 999px; flex-shrink: 0; }
.ns-tag.is-used { color: #fff; background: var(--accent); }
.ns-tag.is-best { color: var(--accent); border: 1px solid var(--accent); }
.ns-off { font-family: var(--font-mono); text-align: right; color: var(--text); }
.ns-delay { font-family: var(--font-mono); text-align: right; color: var(--dim); }
.ns-st { text-align: center; color: var(--dim-2); font-family: var(--font-mono); }
.ns-row .btn { padding: 3px 7px; font-size: 11.5px; min-height: 0; }
[data-skin="tech-max"] .ns-row.is-used { box-shadow: 0 0 10px rgba(124, 140, 255, .3); }

.ntp-hist { margin-top: 11px; padding-top: 11px; border-top: 1px solid var(--line); }
.ntp-hist-head { display: flex; justify-content: space-between; gap: 10px; font-size: 11.5px; color: var(--dim-2); }
.ntp-hist-head span { white-space: nowrap; flex-shrink: 0; }
.ntp-hist-head b {
  font-family: var(--font-mono); font-weight: 500; color: var(--dim);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  min-width: 0; text-align: right;
}
.ntp-hist svg { display: block; width: 100%; height: 44px; margin-top: 5px; }
.ntp-hist svg .zero { stroke: var(--dim-2); stroke-width: .6; stroke-dasharray: 3 4; opacity: .55; }
.ntp-hist svg .line { fill: none; stroke: var(--accent); stroke-width: 1.6; vector-effect: non-scaling-stroke; }

.ntp-sys { margin-top: 11px; padding-top: 11px; border-top: 1px solid var(--line); }
.ntp-sys-head { font-size: 11.5px; color: var(--dim-2); letter-spacing: .03em; margin-bottom: 4px; }
.ntp-sys-body { font-family: var(--font-mono); font-size: 11.5px; color: var(--dim); line-height: 1.65; word-break: break-all; }
.ntp-sys.is-warn .ntp-sys-body,
.ntp-sys.is-warn #nt-sys { color: var(--warn); }
.ntp-err {
  margin-top: 9px;
  padding-top: 9px;
  border-top: 1px solid var(--line);
  font-family: var(--font-mono);
  font-size: 11.5px;
  color: var(--danger);
  line-height: 1.6;
  word-break: break-all;
}
.ntp-err[hidden] { display: none; }

/* 分段皮肤切换器 */
.seg {
  display: inline-flex;
  flex-shrink: 0;
  gap: 2px;
  padding: 3px;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--r-ctrl);
}
.seg button {
  border: 0;
  background: transparent;
  color: var(--dim);
  font-size: 12px;
  padding: 5px 11px;
  border-radius: 6px;
  transition: background var(--t-fast), color var(--t-fast);
}
.seg button:hover { color: var(--text); }
.seg button[aria-pressed="true"] {
  background: var(--accent);
  color: #fff;
  box-shadow: var(--glow);
}

.btn {
  border: 1px solid var(--line-strong);
  background: var(--surface-2);
  color: var(--text);
  font-size: 12.5px;
  padding: 7px 14px;
  border-radius: var(--r-ctrl);
  white-space: nowrap;
  transition: all var(--t-fast);
}
.btn:hover { border-color: var(--accent); color: var(--accent); }
.btn-primary { background: var(--accent); border-color: var(--accent); color: #fff; }
.btn-primary:hover { background: var(--accent-2); color: #fff; box-shadow: var(--glow); }

/* S3 启停按钮：绿=启动 琥珀=重启 红=停止（hover 才显色，保持卡片克制） */
.btn-ok:hover { border-color: var(--ok); color: var(--ok); box-shadow: 0 0 12px rgba(91, 201, 138, .4); }
.btn-warn:hover { border-color: var(--warn); color: var(--warn); box-shadow: 0 0 12px rgba(255, 169, 77, .35); }
/* V2-35③（2026-10-19）：原 color: var(--danger) 在深色底只有 3.43:1（WCAG AA 要 4.5）。
   改用各主题的 --danger-ink（白底 5.9:1 / 深底 8.5:1）。 */
.btn-danger { color: var(--danger-ink); border-color: color-mix(in srgb, var(--danger-ink) 45%, transparent); }
/* V2-35⑧（2026-10-19）：按钮按下态（原来没有任何 :active 反馈） */
.btn:active:not(:disabled), .btn-mini:active:not(:disabled) { transform: translateY(1px); box-shadow: none; }
@media (prefers-reduced-motion: reduce) { .btn:active:not(:disabled), .btn-mini:active:not(:disabled) { transform: none; } }
.btn-danger:hover { border-color: var(--danger-ink); color: var(--danger-ink); box-shadow: 0 0 12px color-mix(in srgb, var(--danger-ink) 35%, transparent); }

/* ===== 6. 卡片（结构层：切角 + 四角 HUD 括号）===== */
.grid {
  display: grid;
  /* 2026-10-09 老板指令：卡片做大（300→400 起步，1280 视口 3 列变 2 列，按钮不挤） */
  grid-template-columns: repeat(auto-fill, minmax(400px, 1fr));
  gap: var(--gap);
}

.card {
  position: relative;
  padding: calc(var(--deco-cut) * 1px);   /* tech: 1px 描边内衬；legacy: 0 */
  background: var(--line);
  border-radius: var(--card-radius);
  clip-path: polygon(0 0, calc(100% - var(--cut-size, 16px)) 0, 100% var(--cut-size, 16px), 100% 100%, var(--cut-size, 16px) 100%, 0 calc(100% - var(--cut-size, 16px)));
}
[data-skin="legacy"] .card {
  --cut-size: 0px;
  padding: 0;
  background: var(--surface);
  border: 1px solid var(--line);
  clip-path: none;
  box-shadow: var(--shadow);
  transition: box-shadow var(--t-fast), transform var(--t-fast);
}
[data-skin="legacy"] .card:hover { box-shadow: var(--shadow-lg); transform: translateY(-2px); }

.card-body {
  position: relative;
  height: 100%;
  padding: 15px 16px;
  background: var(--surface);
  border-radius: calc(var(--card-radius) - var(--deco-cut) * 4px);
  clip-path: polygon(0 0, calc(100% - var(--cut-size, 16px) + 1px) 0, 100% calc(var(--cut-size, 16px) - 1px), 100% 100%, calc(var(--cut-size, 16px) - 1px) 100%, 0 calc(100% - var(--cut-size, 16px) + 1px));
  transition: background var(--t-fast);
}
.card:hover .card-body { background: var(--surface-2); }
[data-skin="legacy"] .card-body { clip-path: none; border-radius: 9px; }

/* 四角 HUD 括号（结构层，仅科技档） */
.card-body::before,
.card-body::after {
  content: "";
  position: absolute;
  width: 13px;
  height: 13px;
  border: 2px solid var(--accent);
  opacity: calc(var(--deco-bracket) * .6);
  pointer-events: none;
  transition: opacity var(--t-fast);
}
.card-body::before { top: 9px; left: 9px; border-right: 0; border-bottom: 0; }
.card-body::after { bottom: 9px; right: 9px; border-left: 0; border-top: 0; }
.card:hover .card-body::before,
.card:hover .card-body::after { opacity: calc(var(--deco-bracket) * 1); }

.card-head { display: flex; align-items: center; gap: 9px; margin-bottom: 12px; }
.card-name { font-size: 13.5px; font-weight: 600; line-height: 1.25; }
.card-meta { font-size: 11.5px; color: var(--dim-2); font-family: var(--font-mono); }
.card-actions { margin-left: auto; display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 7px; }

/* ===== 7. 状态灯（雷达扫描仅满配）===== */
.lamp-wrap { position: relative; width: 11px; height: 11px; flex-shrink: 0; color: var(--dim-2); }
.lamp-wrap:has(.lamp[data-state="up"])   { color: var(--ok); }
.lamp-wrap:has(.lamp[data-state="warn"]) { color: var(--warn); }
.lamp-wrap:has(.lamp[data-state="err"])  { color: var(--danger); }
.lamp {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: currentColor;
  box-shadow: 0 0 9px currentColor;
}
.lamp[data-state="up"]   { color: var(--ok); }
.lamp[data-state="down"] { color: var(--dim-2); opacity: .55; box-shadow: none; }
.lamp[data-state="warn"] { color: var(--warn); }
.lamp[data-state="err"]  { color: var(--danger); }
[data-skin="tech-max"] .lamp[data-state="up"] { animation: breathe 2.6s ease-in-out infinite; }
/* 雷达扫描圈：颜色取自 lamp-wrap（由 :has 按状态着色） */
[data-skin="tech-max"] .lamp-wrap::after {
  content: "";
  position: absolute;
  inset: -7px;
  border-radius: 50%;
  background: conic-gradient(from 0deg, transparent 0 68%, currentColor 94%, transparent 100%);
  opacity: calc(var(--deco-radar) * .55);
  animation: scan-sweep 2.8s linear infinite;
  pointer-events: none;
}

/* ===== 8. 遥测读数（内容层：Consolas + 单位 + sparkline）===== */
.tel-row { display: flex; gap: 18px; margin-bottom: 12px; }
.tel { display: flex; flex-direction: column; gap: 2px; }
.tel-label { font-size: 11.5px; color: var(--dim-2); letter-spacing: .06em; text-transform: uppercase; }
.tel-value {
  font-family: var(--font-mono);
  font-size: 19px;
  font-weight: 600;
  color: var(--text);
  font-variant-numeric: tabular-nums;
  line-height: 1.15;
}
.tel-unit { font-size: 11.5px; color: var(--dim-2); font-weight: 400; margin-left: 2px; }
.tel-value.is-warn { color: var(--warn); }
.tel-value.is-ok { color: var(--ok); }

.spark { display: block; width: 100%; height: 30px; overflow: visible; }
.spark .area { fill: rgba(124, 140, 255, .12); stroke: none; }
.spark .line { fill: none; stroke: var(--accent); stroke-width: 1.6; stroke-linejoin: round; stroke-linecap: round; }
[data-skin="legacy"] .spark .area { fill: rgba(59, 130, 246, .12); }
[data-skin="legacy"] .spark .line { stroke: var(--accent); }

.tag {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 11.5px;
  font-family: var(--font-mono);
  padding: 2px 7px;
  border: 1px solid var(--line);
  border-radius: 999px;
  color: var(--dim);
  background: var(--surface-2);
}
.tag.is-live { color: var(--ok); border-color: rgba(91, 201, 138, .4); }
.tag.is-off  { color: var(--dim-2); }
.tag.is-warn { color: var(--warn); border-color: rgba(255, 169, 77, .4); }
.tag.is-danger { color: var(--danger); border-color: rgba(239,68,68,.5); }

/* ===== 9. 条形图 / 进度（全局资源）===== */
.meter { margin-bottom: 11px; }
.meter-top { display: flex; justify-content: space-between; font-size: 11.5px; color: var(--dim); margin-bottom: 5px; }
.meter-top b { font-family: var(--font-mono); color: var(--text); font-variant-numeric: tabular-nums; }
/* 科技风曲线图（2026-10-10 老板：全局资源条形改曲线）——发光描边+底部渐变由 canvas 绘制 */
.curve { display: block; width: 100%; height: 52px; margin-top: 2px; }
/* 纳管状态分布 chips（与卡片 status_note 五色徽章同源） */
.svc-states { display: flex; flex-wrap: wrap; gap: 8px 14px; align-items: center; margin: 2px 2px 12px; font-size: 11.5px; color: var(--dim); }
.svc-states .ss { display: inline-flex; align-items: center; gap: 5px; }
.svc-states .ss i { width: 7px; height: 7px; border-radius: 50%; background: var(--dim); box-shadow: 0 0 6px currentColor; }
.svc-states .ss.is-live i { background: #34d399; color: #34d399; }
.svc-states .ss.is-dev i { background: #60a5fa; color: #60a5fa; }
.svc-states .ss.is-test i { background: #fbbf24; color: #fbbf24; }
.svc-states .ss.is-hold i { background: #94a3b8; color: #94a3b8; }
.svc-states .ss.is-bad i { background: #f87171; color: #f87171; }

/* ===== 10. 轨道环（强调层：单点使用，仅顶栏统计区与 eNSP 卡）===== */
.orbit-box { position: relative; overflow: hidden; }
.orbit {
  position: absolute;
  width: 190px;
  height: 190px;
  right: -46px;
  top: -58px;
  border: 1px dashed var(--accent);
  border-radius: 50%;
  opacity: calc(var(--deco-orbit) * .32);
  animation: spin var(--deco-orbit-spin) linear infinite;
  pointer-events: none;
}
.orbit::after {
  content: "";
  position: absolute;
  top: -3.5px;
  left: 50%;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 10px var(--accent);
}
.orbit.orbit-2 { width: 128px; height: 128px; right: -20px; top: -30px; opacity: calc(var(--deco-orbit) * .2); animation-duration: calc(var(--deco-orbit-spin) * .62); }

/* ===== 11. 其他组件 ===== */
.section-title {
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin: 26px 0 13px;
}
.section-title h2 { font-size: 14.5px; font-weight: 600; }
.section-title .idx {
  font-family: var(--font-mono);
  font-size: 11.5px;
  color: var(--accent);
  letter-spacing: .1em;
}
.section-title .rule { flex: 1; height: 1px; background: var(--line); }

.panel {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  padding: 16px;
}
[data-skin="tech-max"] .panel { border-color: var(--line); box-shadow: var(--shadow); }
[data-skin="legacy"] .panel { box-shadow: var(--shadow); }

table { width: 100%; border-collapse: collapse; font-size: 12.5px; }
th, td { text-align: left; padding: 9px 8px; border-bottom: 1px solid var(--line); }
th { font-size: 11.5px; color: var(--dim-2); font-weight: 600; text-transform: uppercase; letter-spacing: .05em; }
tbody tr:hover { background: var(--surface-2); }
td.mono { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.agent-hint { font-size: 11.5px; color: var(--dim-2); margin-top: 9px; }

/* ===== 11.5 第一排：运行状态条（WorkBuddy 式状态 + 滚动提示语 + 网状链接） ===== */
.status-banner {
  position: relative;
  display: flex;
  flex-wrap: wrap;                 /* V2-43②：让星语条能独占一行 */
  align-items: center;
  gap: 10px 16px;
  min-height: 54px;
  margin: 4px 0 20px;
  padding: 11px 16px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  overflow: hidden;
}
[data-skin="tech-max"] .status-banner {
  border-color: rgba(124, 140, 255, .42);
  background:
    linear-gradient(180deg, rgba(124, 140, 255, .08), rgba(124, 140, 255, 0) 60%),
    var(--surface);
  box-shadow: var(--shadow), 0 0 26px rgba(124, 140, 255, .16), inset 0 0 32px rgba(124, 140, 255, .05);
}
[data-skin="tech-max"] .status-banner::before,
[data-skin="tech-max"] .status-banner::after {
  content: "";
  position: absolute;
  width: 14px; height: 14px;
  border: 2px solid var(--accent);
  opacity: .75;
  pointer-events: none;
}
[data-skin="tech-max"] .status-banner::before { top: 6px; left: 6px; border-right: 0; border-bottom: 0; }
[data-skin="tech-max"] .status-banner::after { bottom: 6px; right: 6px; border-left: 0; border-top: 0; }

.banner-mesh {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
  pointer-events: none;
  opacity: calc(var(--deco-canvas) * .95);
}
.banner-run {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
  padding-right: 14px;
  border-right: 1px solid var(--line);
}
.run-dot {
  width: 9px; height: 9px;
  border-radius: 50%;
  flex-shrink: 0;
  background: var(--ok);
  box-shadow: 0 0 9px var(--ok);
}
[data-skin="tech-max"] .run-dot { animation: breathe 2.4s ease-in-out infinite; }
.run-text { font-size: 13px; font-weight: 700; letter-spacing: .06em; color: var(--text); }
[data-skin="tech-max"] .run-text { color: var(--ok); text-shadow: 0 0 12px rgba(91, 201, 138, .55); }
.run-sub { font-family: var(--font-mono); font-size: 11.5px; color: var(--dim-2); white-space: nowrap; }

/* V2-43②（2026-10-19 老板："星语独立节点"）：星语条原来挤在「运行中」与「监听/网段」之间，
   桌面被两边挤成一小段、窄屏直接看不到。现在独立成行（整行宽度、上方虚线分隔）。 */
.banner-ticker {
  position: relative;
  z-index: 1;
  /* 2026-10-20 老板：「运行中」和星语放同一栏（桌面一行）；手机端再按视窗上下分栏 */
  flex: 1 1 auto;
  order: 0;
  min-width: 0;
  margin-top: 0;
  padding-top: 0;
  border-top: 0;
  overflow: hidden;
  display: flex;
  align-items: center;
  perspective: 520px;              /* 3D 翻牌视距 */
}
.ticker-seg {
  display: block;
  flex: 1;
  min-width: 0;
  font-size: 12.5px;
  color: var(--dim);
  letter-spacing: .01em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  transform-origin: 50% 50%;
  backface-visibility: hidden;
  will-change: transform, opacity;
}
[data-skin="tech-max"] .ticker-seg { color: var(--text); text-shadow: 0 0 10px rgba(124, 140, 255, .25); }

/* 翻转播放（2026-10-08 老板指令：横滚太快 → 一屏一条翻牌切换） */
.ticker-seg.flip-out { animation: seg-flip-out .26s ease-in forwards; }
.ticker-seg.flip-in { animation: seg-flip-in .34s cubic-bezier(.2, .7, .3, 1); }
@keyframes seg-flip-out {
  from { transform: rotateX(0deg); opacity: 1; }
  to { transform: rotateX(-88deg); opacity: .12; }
}
@keyframes seg-flip-in {
  from { transform: rotateX(88deg); opacity: .12; }
  to { transform: rotateX(0deg); opacity: 1; }
}

.banner-params {
  position: relative;
  z-index: 1;
  display: flex;
  gap: 12px;
  flex-shrink: 0;
}
.bp { font-family: var(--font-mono); font-size: 11.5px; color: var(--dim-2); white-space: nowrap; }
.bp b { color: var(--accent); font-weight: 600; font-variant-numeric: tabular-nums; }
[data-skin="tech-max"] .bp b { text-shadow: 0 0 9px rgba(124, 140, 255, .55); }
.bp b.q-ok  { color: var(--ok);     text-shadow: 0 0 9px rgba(91, 201, 138, .5); }
.bp b.q-mid { color: var(--warn);   text-shadow: 0 0 9px rgba(255, 169, 77, .5); }
.bp b.q-bad { color: var(--danger); text-shadow: 0 0 9px rgba(255, 92, 92, .5); }

/* ===== 11.6 满配强化（老板：对比度、元素、炫酷度都要拉起来） ===== */
[data-skin="tech-max"] body::before { opacity: .9; }   /* 背景网格更亮 */
[data-skin="tech-max"] body::after {                   /* 星云更浓 */
  background:
    radial-gradient(900px 500px at 15% -8%, rgba(124, 140, 255, .26), transparent 60%),
    radial-gradient(760px 420px at 88% 4%, rgba(139, 123, 255, .22), transparent 62%),
    radial-gradient(900px 560px at 62% 112%, rgba(124, 140, 255, .16), transparent 60%);
}
[data-skin="tech-max"] .orbit { opacity: calc(var(--deco-orbit) * .5); }
[data-skin="tech-max"] .orbit.orbit-2 { opacity: calc(var(--deco-orbit) * .34); }

[data-skin="tech-max"] .section-title .idx {
  font-weight: 700;
  text-shadow: 0 0 12px rgba(124, 140, 255, .85);
}
[data-skin="tech-max"] .section-title h2 {
  background: linear-gradient(90deg, #ffffff, #b9c2ff);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
[data-skin="tech-max"] .section-title .rule {
  background: linear-gradient(90deg, rgba(124, 140, 255, .65), rgba(124, 140, 255, .06));
}
[data-skin="tech-max"] .card { transition: transform var(--t-fast); }
[data-skin="tech-max"] .card:hover { transform: translateY(-2px); }
[data-skin="tech-max"] .card:hover .card-body {
  box-shadow: inset 0 0 0 1px rgba(124, 140, 255, .55), inset 0 0 26px rgba(124, 140, 255, .07);
}
[data-skin="tech-max"] .lamp { box-shadow: 0 0 14px currentColor; }
[data-skin="tech-max"] .tel-value { text-shadow: 0 0 14px rgba(124, 140, 255, .45); }
[data-skin="tech-max"] .btn:hover { box-shadow: 0 0 14px rgba(124, 140, 255, .4); }
[data-skin="tech-max"] .tag.is-live { box-shadow: 0 0 8px rgba(91, 201, 138, .3); }

/* ===== 11.7 语音（指令台：麦克风 / 波形 / 播报开关 / 接入方案） ===== */
.btn-mic {
  min-width: 42px;
  font-size: 15px;
  padding: 7px 11px;
}
.btn-mic:hover { border-color: var(--accent); color: var(--accent); box-shadow: var(--glow); }
/* V2-29（2026-10-18）：STT 未就绪时**置灰而不是隐藏** —— 用户要看得到功能存在。
   （旧的 `display:none !important` 是 10-09 语音暂缓遗留，V2-20 解封时漏删，实测按钮 0×0。） */
.btn-mic:disabled {
  opacity: .42;
  cursor: not-allowed;
  filter: grayscale(.55);
}
.btn-mic:disabled:hover { border-color: var(--line); color: inherit; box-shadow: none; }

.btn-mic.is-rec {
  color: var(--danger);
  border-color: var(--danger);
  animation: mic-pulse 1s ease-in-out infinite;
}
@keyframes mic-pulse {
  0%, 100% { box-shadow: 0 0 0 rgba(255, 92, 92, .25); }
  50% { box-shadow: 0 0 16px rgba(255, 92, 92, .85); }
}

/* ===== 「开发中」标注（2026-10-19 老板指令：语音暂停开发，页面如实标注） ===== */
.dev-note {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin-top: 12px;
  padding: 7px 10px;
  font-size: 11.5px;
  color: var(--dim);
  background: var(--surface-2);
  border: 1px dashed var(--line-strong);
  border-radius: var(--r-ctrl);
}
.dev-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-family: var(--font-mono);
  font-size: 11.5px;
  padding: 2px 7px;
  border-radius: 999px;
  color: var(--warn);
  border: 1px solid rgba(255, 169, 77, .45);
  background: rgba(255, 169, 77, .1);
  white-space: nowrap;
}
.dev-note .dev-text b { color: var(--text); }

/* 登录入口按钮（2026-10-19）：常显；已登录时描边高亮 */
.btn-login { border-color: var(--line-strong); }
.btn-login.is-in { color: var(--accent); border-color: var(--accent); }

/* ===== 账号控制（2026-10-19 老板："账号控制…UI上我没看见"） ===== */
.acc-group .cfg-group-title { display: flex; justify-content: space-between; align-items: center; }
.acc-who { font-family: var(--font-mono); font-size: 11.5px; font-weight: 400; color: var(--dim); }
.acc-hint { font-size: 11.5px; color: var(--dim); line-height: 1.75; margin: 4px 0 10px; }
.acc-hint b { color: var(--text); }
.acc-table { width: 100%; border-collapse: collapse; font-size: 12px; }
.acc-table th, .acc-table td {
  text-align: left; padding: 6px 8px; border-bottom: 1px solid var(--line); vertical-align: middle;
}
.acc-table th { color: var(--dim); font-weight: 500; font-size: 11.5px; }
.acc-table .acc-name { font-family: var(--font-mono); color: var(--text); }
.acc-table .acc-note { color: var(--dim); font-size: 11.5px; }
.acc-table .btn-mini { margin-right: 6px; }
.acc-table .acc-role { min-width: 108px; }
.acc-empty { font-size: 12px; color: var(--dim); padding: 6px 0 10px; }
.acc-add { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-top: 12px; }
.acc-add .cfg-input { width: auto; min-width: 132px; flex: 0 1 auto; }

/* 受限入口（2026-10-19）：可见但点不动，点了给明确文案（未登录 / 权限不足） */
.is-locked { opacity: .5; cursor: not-allowed; }

/* 对话页签的"对话即调度"标签（原 chat/agent 模式开关已删） */
.ac-tag {
  font-family: var(--font-mono);
  font-size: 11.5px;
  padding: 2px 8px;
  border-radius: 999px;
  color: var(--accent);
  border: 1px solid var(--line-strong);
  background: var(--surface-2);
  white-space: nowrap;
}

.voice-wave {
  display: block;
  width: 100%;
  height: 46px;
  margin-top: 10px;
  background: linear-gradient(180deg, rgba(124, 140, 255, .06), transparent);
  border: 1px solid var(--line);
  border-radius: var(--r-ctrl);
}
.voice-wave[hidden] { display: none; }

.voice-row {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-top: 12px;
  flex-wrap: wrap;
}
.voice-switch {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
  font-size: 12px;
  color: var(--dim);
  user-select: none;
}
.voice-switch input { position: absolute; opacity: 0; pointer-events: none; }
.vs-track {
  position: relative;
  width: 32px; height: 18px;
  border-radius: 999px;
  background: var(--surface-3);
  border: 1px solid var(--line-strong);
  transition: all var(--t-fast);
  flex-shrink: 0;
}
.vs-track::after {
  content: "";
  position: absolute;
  top: 2px; left: 2px;
  width: 12px; height: 12px;
  border-radius: 50%;
  background: var(--dim);
  transition: all var(--t-fast);
}
.voice-switch input:checked + .vs-track {
  background: var(--accent-light);
  border-color: var(--accent);
}
.voice-switch input:checked + .vs-track::after {
  left: 16px;
  background: var(--accent);
  box-shadow: 0 0 8px var(--accent);
}
.voice-state {
  font-family: var(--font-mono);
  font-size: 11.5px;
  color: var(--ok);
  white-space: nowrap;
}
.voice-state.is-warn { color: var(--warn); }
.btn-ghost {
  background: transparent;
  border-style: dashed;
  color: var(--dim);
  font-size: 11.5px;
}

.voice-help { padding: 6px 17px 12px; overflow: auto; }
.vh-block {
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  padding: 13px 15px;
  margin-top: 12px;
}
.vh-block.is-ok { border-color: rgba(91, 201, 138, .45); }
.vh-block > b { font-size: 13px; display: block; }
.vh-block > p { font-size: 12px; color: var(--dim); line-height: 1.75; margin-top: 6px; }
.vh-block code {
  font-family: var(--font-mono);
  font-size: 11.5px;
  background: var(--surface-2);
  padding: 1px 6px;
  border-radius: 4px;
  color: var(--accent);
}
.vh-opt {
  display: flex;
  flex-direction: column;
  gap: 5px;
  align-items: flex-start;
  padding: 11px 13px;
  margin-top: 10px;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--r-ctrl);
}
.vh-opt b { font-size: 12.5px; }
.vh-opt code { word-break: break-all; }
.vh-opt > span:last-child { font-size: 11.5px; color: var(--dim-2); }

.port-cands { display: flex; flex-wrap: wrap; gap: 8px; padding: 10px 17px 0; }
.port-cands:empty { display: none; }

/* ===== 12.2 场景（S3 一键编排） ===== */
.scene-body { padding: 6px 17px 14px; overflow: auto; }
.scene-list { display: flex; flex-direction: column; gap: 8px; margin-top: 10px; }
.scene-list:empty { display: none; }
.scene-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 12px;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--r-ctrl);
}
.scene-item b { font-size: 13px; white-space: nowrap; }
.scene-item .si-meta {
  flex: 1;
  font-size: 11.5px;
  color: var(--dim-2);
  font-family: var(--font-mono);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.scene-new { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--line); }
.scene-new > label { display: flex; align-items: center; gap: 9px; font-size: 12px; color: var(--dim); }
.scene-new input {
  flex: 1;
  padding: 8px 11px;
  background: var(--surface-2);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-ctrl);
  color: var(--text);
  font-size: 13px;
  outline: none;
}
.scene-new input:focus { border-color: var(--accent); box-shadow: var(--glow); }
.scene-picks {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 16px;
  margin: 11px 0;
  max-height: 148px;
  overflow: auto;
}
.scene-new .btn { margin-top: 4px; }
.scene-result {
  margin-top: 13px;
  padding-top: 11px;
  border-top: 1px solid var(--line);
  font-family: var(--font-mono);
  font-size: 11.5px;
  line-height: 1.85;
}
.scene-result[hidden] { display: none; }
.sr-ok { color: var(--ok); }
.sr-skip { color: var(--dim-2); }
.sr-fail { color: var(--danger); }

/* HUD 入场（仅满配）——2026-10-09 全局化：由"加载时一次性"改为"滚动触发"
   （js IntersectionObserver 见 app.js，区块滚入视口时加 .is-in）；JS 未跑时
   区块停在初始态的问题不存在：observer 首轮回调即对可见区块补 class。 */
[data-skin="tech-max"] .stage > .enter {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity .55s cubic-bezier(.2, .8, .3, 1), transform .55s cubic-bezier(.2, .8, .3, 1);
}
[data-skin="tech-max"] .stage > .enter.is-in { opacity: 1; transform: none; }
[data-skin="tech-max"] .stage > .enter:nth-child(2) { transition-delay: .06s; }
[data-skin="tech-max"] .stage > .enter:nth-child(3) { transition-delay: .12s; }

/* ===== 12.1 记忆（思维导图 / 图谱） ===== */

/* 显示设置面板（防隐私泄露：分组/正文/路径开关） */
.mem-opts {
  position: relative;
  z-index: 5;
  margin: 0 15px;
  padding: 12px 15px;
  background: var(--surface-2);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-ctrl);
}
.mem-opts[hidden] { display: none; }
.mo-head { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.mo-head b { font-size: 13px; }
.mo-head span { font-size: 11.5px; color: var(--dim-2); }
.mo-head b + span b { color: var(--accent); }
.mo-groups {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 16px;
  margin-top: 10px;
  max-height: 132px;
  overflow: auto;
}
.mo-rows { display: flex; gap: 18px; margin-top: 10px; flex-wrap: wrap; }
.mo-row {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: 12px;
  color: var(--dim);
  cursor: pointer;
  user-select: none;
}
.mo-row input { accent-color: var(--accent); width: 14px; height: 14px; cursor: pointer; }
.mo-row i { font-style: normal; color: var(--dim-2); font-size: 11.5px; font-family: var(--font-mono); }
.mo-actions {
  display: flex;
  align-items: center;
  gap: 9px;
  margin-top: 11px;
  flex-wrap: wrap;
}
.mo-tip { font-size: 11.5px; color: var(--dim-2); }
.mem-excerpt.is-hidden,
.mem-content { word-break: break-all; }
.mem-excerpt.is-hidden { color: var(--dim-2); font-style: italic; }

.btn-memory {
  border: 1px solid var(--accent);
  background: var(--accent-light);
  color: var(--accent);
  font-weight: 600;
  letter-spacing: .12em;
  /* V2-43③（2026-10-19）：专注按钮与标签栏贴在一起，间距/高度对齐 */
  padding: 8px 18px;
  min-height: 40px;
  border-radius: 999px;
  box-shadow: var(--glow);
  margin: 0 6px 0 14px;
}
.btn-memory:hover { background: var(--accent); color: #fff; box-shadow: var(--glow); }
.modal-card.memory-card { width: min(1360px, 100%); height: min(94vh, 980px); }
/* 2026-10-20 老板：记忆回到独立弹层（与专注同组按钮打开）→ 按弹层口径给尺寸，
   不再按 section 的高度算（否则套进 .modal 会顶出视口）。 */
.modal-memory { padding: 18px; }
.modal-memory .memory-card {
  width: min(1360px, 100%);
  height: min(94vh, 980px);
  min-height: 420px;
}
@media (max-width: 900px) {
  .modal-memory .memory-card { height: calc(100vh - 120px); }
}
/* 顶栏「专注 / 记忆」同组按钮（2026-10-20 老板：记忆和专注放一起） */
.focus-mem { display: inline-flex; align-items: center; gap: 6px; }
.focus-mem .btn-memory { margin: 0; }

.mem-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
  padding: 11px 17px;
  border-bottom: 1px solid var(--line);
  max-height: 96px;
  overflow-y: auto;
}
.chip-btn {
  border: 1px solid var(--line-strong);
  background: var(--surface-2);
  color: var(--dim);
  font-size: 11.5px;
  padding: 4px 10px;
  border-radius: 999px;
  transition: all var(--t-fast);
}
.chip-btn i { font-style: normal; color: var(--dim-2); margin-left: 3px; font-size: 11.5px; }
.chip-btn:hover { border-color: var(--accent); color: var(--accent); }
.chip-btn.is-on { background: var(--accent); border-color: var(--accent); color: #fff; box-shadow: var(--glow); }
.chip-btn.is-on i { color: rgba(255, 255, 255, .8); }

.mem-body {
  flex: 1;
  display: flex;
  min-height: 0;
  gap: 0;
}
.mem-canvas-wrap {
  position: relative;
  flex: 1;
  min-width: 0;
  background:
    radial-gradient(700px 420px at 50% 46%, rgba(124, 140, 255, .07), transparent 70%),
    var(--bg);
  overflow: hidden;
}
#mem-canvas { display: block; width: 100%; height: 100%; cursor: grab; touch-action: none; }
#mem-canvas:active { cursor: grabbing; }

.mem-legend {
  position: absolute;
  left: 13px;
  bottom: 11px;
  display: flex;
  gap: 13px;
  font-size: 11.5px;
  color: var(--dim-2);
  background: color-mix(in srgb, var(--surface) 82%, transparent);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 5px 13px;
  backdrop-filter: blur(6px);
  pointer-events: none;
}
.mem-legend .dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: 5px; vertical-align: -1px; }
.mem-legend .dot-root { background: var(--accent); }
.mem-legend .dot-group { background: var(--accent); opacity: .7; }
.mem-legend .dot-note { background: var(--text); }
.mem-legend .line { display: inline-block; width: 14px; height: 0; border-top: 2px solid; margin-right: 5px; vertical-align: 3px; }
.mem-legend .line-link { border-color: var(--ok); }
.mem-legend .line-tag { border-color: var(--accent); border-top-style: dashed; }

.mem-side {
  width: 322px;
  flex-shrink: 0;
  border-left: 1px solid var(--line);
  background: var(--surface);
  overflow-y: auto;
  padding: 15px 16px;
}
.mem-empty { font-size: 12px; color: var(--dim-2); line-height: 2.1; padding-top: 8px; }
.mem-empty b { color: var(--accent); font-weight: 600; }

.mem-detail .mem-h {
  font-size: 14.5px;
  font-weight: 600;
  line-height: 1.45;
  margin-bottom: 9px;
  color: var(--text);
}
.mem-badge {
  display: inline-block;
  margin-left: 7px;
  padding: 1px 8px;
  border-radius: 999px;
  background: var(--accent-light);
  color: var(--accent);
  font-size: 11.5px;
  font-weight: 600;
}
.mem-row {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  font-size: 11.5px;
  padding: 5px 0;
  border-bottom: 1px dashed var(--line);
}
.mem-row span { color: var(--dim-2); flex-shrink: 0; }
.mem-row b { color: var(--text); font-weight: 500; text-align: right; word-break: break-all; }
.mem-tags-line { display: flex; flex-wrap: wrap; gap: 6px; margin: 11px 0; }
.mem-excerpt {
  font-size: 12px;
  line-height: 1.75;
  color: var(--dim);
  background: var(--surface-2);
  border-left: 2px solid var(--accent);
  padding: 8px 11px;
  border-radius: 0 7px 7px 0;
  margin-bottom: 9px;
}
.mem-path {
  font-family: var(--font-mono);
  font-size: 11.5px;
  color: var(--dim-2);
  word-break: break-all;
  margin-bottom: 9px;
}
.mem-content {
  font-family: var(--font-mono);
  font-size: 11.5px;
  line-height: 1.7;
  color: var(--text);
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 10px 12px;
  white-space: pre-wrap;
  word-break: break-word;
  max-height: 46vh;
  overflow-y: auto;
}
.mem-dim { color: var(--dim-2); font-size: 11.5px; line-height: 1.7; }
.mem-list { display: flex; flex-direction: column; gap: 5px; margin-top: 11px; }
.mem-item {
  text-align: left;
  border: 1px solid var(--line);
  background: var(--surface-2);
  color: var(--dim);
  font-size: 12px;
  padding: 7px 10px;
  border-radius: 7px;
  transition: all var(--t-fast);
}
.mem-item:hover { border-color: var(--accent); color: var(--accent); }

@media (max-width: 860px) {
  .mem-body { flex-direction: column; }
  .mem-side { width: auto; max-height: 40%; border-left: 0; border-top: 1px solid var(--line); }
  .memory-card { height: 96vh; }
  .modal-head { flex-wrap: wrap; }
}

/* ===== 12. 模态框 / 日志视图 / 新增表单 / toast ===== */
.modal {
  position: fixed;
  inset: 0;
  z-index: 80;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  background: rgba(0, 0, 0, .55);
  backdrop-filter: blur(3px);
}
.modal[hidden] { display: none; }

.modal-card {
  width: min(620px, 100%);
  max-height: min(86vh, 900px);
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
}
.modal-wide { width: min(880px, 100%); }
[data-skin="tech-max"] .modal-card { box-shadow: var(--shadow-lg), var(--glow); }

.modal-head {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 15px 17px;
  border-bottom: 1px solid var(--line);
}
.modal-title { font-size: 14.5px; font-weight: 600; }
.modal-foot {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 17px;
  border-top: 1px solid var(--line);
  background: var(--surface-2);
}

.log-view {
  flex: 1;
  min-height: 240px;
  margin: 0;
  padding: 13px 16px;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-mono);
  font-size: 12px;
  line-height: 1.65;
  overflow: auto;
  white-space: pre-wrap;
  word-break: break-all;
}

.add-row { display: flex; gap: 9px; padding: 15px 17px 0; }
.add-row input {
  flex: 1;
  padding: 9px 12px;
  background: var(--surface-2);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-ctrl);
  color: var(--text);
  font-family: var(--font-mono);
  font-size: 12.5px;
  outline: none;
}
.add-row input:focus { border-color: var(--accent); box-shadow: var(--glow); }

.add-hint { padding: 8px 17px 0; font-size: 11.5px; color: var(--dim-2); line-height: 1.6; }
.add-hint.is-ok { color: var(--ok); }
.add-hint.is-err { color: var(--danger); }

.add-cands { display: flex; flex-wrap: wrap; gap: 8px; padding: 12px 17px 0; }
.cand {
  border: 1px solid var(--line-strong);
  background: var(--surface-2);
  color: var(--text);
  font-size: 12px;
  padding: 7px 12px;
  border-radius: var(--r-ctrl);
  transition: all var(--t-fast);
}
.cand:hover { border-color: var(--accent); color: var(--accent); }
.cand.is-on { background: var(--accent); border-color: var(--accent); color: #fff; box-shadow: var(--glow); }
.cand.is-muted { opacity: .6; }
.cand.is-muted.is-on { opacity: 1; }

.add-form {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 11px 14px;
  padding: 15px 17px;
  overflow-y: auto;
}
.add-form label {
  display: flex;
  flex-direction: column;
  gap: 5px;
  font-size: 11.5px;
  color: var(--dim);
}
.add-form label.wide { grid-column: 1 / -1; }
.add-form input,
.add-form select {
  padding: 8px 10px;
  background: var(--surface-2);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-ctrl);
  color: var(--text);
  font-size: 13px;
  outline: none;
}
.add-form input:focus,
.add-form select:focus { border-color: var(--accent); box-shadow: var(--glow); }

.btn:disabled { opacity: .45; cursor: not-allowed; }
.btn:disabled:hover { border-color: var(--line-strong); color: var(--text); }

.toast {
  position: fixed;
  left: 50%;
  bottom: 34px;
  transform: translateX(-50%);
  z-index: var(--z-toast);      /* C5：95 → 97，别被字幕条(96)压住 */
  padding: 11px 20px;
  background: var(--surface);
  border: 1px solid var(--accent);
  border-radius: var(--r-ctrl);
  color: var(--text);
  font-size: 13px;
  box-shadow: var(--shadow-lg), var(--glow);
  max-width: min(90vw, 620px);
  animation: hud-in .25s ease-out both;
}
.toast[hidden] { display: none; }
.toast.is-err { border-color: var(--danger); box-shadow: var(--shadow-lg); }

/* ===== 13. 响应式（移动端自动降为克制强度，js 设 data-deco="lite"）===== */
@media (max-width: 900px) {
  .grid { grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); }
  .clock-date { display: none; }   /* 平板/手机只藏公历日期；农历·节气·天气保留（老板 2026-10-20） */
}

@media (max-width: 640px) {
  html { font-size: 15px; }
  .stage { padding: 16px 13px 52px; }
  .topbar { flex-wrap: wrap; gap: 10px; padding: 10px 13px; }
  .topbar-center { position: static; transform: none; }
  .grid { grid-template-columns: 1fr; }
  .btn, .seg button { min-height: 40px; }   /* 触摸友好 */
  .tel-value { font-size: 21px; }
  .clock-date { display: none; }            /* 手机上只留时分秒 + 徽章 */
  .clock-main { font-size: 13px; }
  .ntp-pop { right: auto; left: 0; }
  .ntp-grid { grid-template-columns: 1fr; }
  .status-banner { flex-wrap: wrap; gap: 8px 12px; padding: 10px 12px; }
  .banner-run { border-right: 0; padding-right: 0; }
  /* 手机：运行中与监听一行，星语按视窗宽度换到下一行（上下分栏） */
  .banner-ticker { order: 3; flex: 1 1 100%; margin-top: 2px; padding-top: 9px;
    border-top: 1px dashed var(--line); -webkit-mask-image: none; mask-image: none; }
  .banner-params { margin-left: auto; }
}

/* ===== 14. 无障碍：减弱动效全局降级 ===== */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
}

/* ===== 15. 访问观测（S4 入站流水 + 白名单） ===== */
.acc-head-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.acc-body { display: flex; flex-direction: column; gap: 12px; }

.acc-note {
  padding: 9px 12px; border: 1px solid var(--line); background: var(--surface-2);
  border-radius: 8px; font-size: 12.5px; color: var(--text);
}
.acc-note.is-monitor { border-style: dashed; opacity: .8; }
.acc-note.is-ok { border-color: rgba(91, 201, 138, .45); color: var(--ok); }
.acc-note.is-bad { border-color: rgba(239, 68, 68, .55); background: rgba(239, 68, 68, .08); }
.acc-note.is-bad b { color: var(--danger); }

.acc-allow {
  border: 1px solid var(--line); background: var(--surface-2);
  border-radius: 10px; padding: 10px 12px;
}
.acc-allow-head { font-size: 12px; opacity: .7; margin-bottom: 8px; line-height: 1.6; }
.acc-allow-list { display: flex; flex-wrap: wrap; gap: 7px 16px; margin-bottom: 10px; }
.acc-allow-item { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; cursor: pointer; }
.acc-allow-item input { accent-color: var(--accent); width: 14px; height: 14px; cursor: pointer; }
.acc-allow-item code { font-size: 11.5px; opacity: .75; }

.acc-table-wrap { max-height: 42vh; overflow: auto; border: 1px solid var(--line); border-radius: 10px; }
.acc-table { width: 100%; min-width: 820px; border-collapse: collapse; font-size: 12.5px; }
.acc-table th {
  position: sticky; top: 0; z-index: 1; background: var(--surface-2);
  font-weight: 600; font-size: 11.5px; padding: 8px 10px; text-align: left;
  border-bottom: 1px solid var(--line); white-space: nowrap; opacity: .75;
}
.acc-table td {
  padding: 7px 10px; border-bottom: 1px solid var(--line);
  white-space: nowrap; font-variant-numeric: tabular-nums;
}
.acc-table tr:last-child td { border-bottom: 0; }
.acc-table code { font-family: Consolas, "Courier New", monospace; font-size: 12px; background: none; padding: 0; }
.acc-table i.acc-pid { font-style: normal; opacity: .5; font-size: 11.5px; }
.acc-row-bad td { background: rgba(239, 68, 68, .08); }
.acc-empty { color: var(--text); opacity: .55; text-align: center; padding: 20px 8px !important; white-space: normal !important; }
.acc-unknown { opacity: .5; }

.acc-badge {
  display: inline-block; padding: 2px 8px; border-radius: 999px;
  border: 1px solid var(--line); font-size: 11.5px; line-height: 1.5;
}
.acc-badge.is-ok { color: var(--ok); border-color: rgba(91, 201, 138, .5); }
.acc-badge.is-warn { color: var(--warn); border-color: rgba(255, 169, 77, .5); }
.acc-badge.is-danger {
  color: var(--danger); border-color: rgba(239, 68, 68, .55);
  background: rgba(239, 68, 68, .12); font-weight: 600;
}
.acc-badge.is-mute { opacity: .6; }
.acc-badge.is-lan { color: var(--accent); border-color: var(--accent); }

.acc-arp { border-top: 1px dashed var(--line); padding-top: 10px; }
.acc-arp-head { font-size: 12px; opacity: .7; margin-bottom: 7px; }
.acc-arp-list { display: flex; flex-direction: column; gap: 6px; max-height: 16vh; overflow: auto; }
.acc-iface { display: flex; flex-wrap: wrap; gap: 5px 12px; align-items: baseline; }
.acc-iface b {
  font-size: 11.5px; color: var(--accent); font-family: Consolas, monospace;
  min-width: 100px; font-weight: 600;
}
.acc-arp-item {
  font-size: 11.5px; font-family: Consolas, monospace; opacity: .65; cursor: default;
}
.acc-arp-item:hover { opacity: 1; }

a.btn#acc-export { text-decoration: none; display: inline-flex; align-items: center; }

@media (max-width: 900px) {
  .acc-table-wrap { max-height: 46vh; }
  .acc-head-actions { width: 100%; justify-content: flex-start; }
}

/* ===== 16. 指令台（S5 agent 指令流 + 大脑） ===== */
.agent-log {
  margin-top: 10px;
  max-height: 240px;
  min-height: 72px;
  overflow-y: auto;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--surface-2);
  padding: 8px 11px;
  font-family: Consolas, "Courier New", monospace;
  font-size: 12.5px;
  line-height: 1.65;
}
.al-row { white-space: pre-wrap; word-break: break-word; padding: 2px 0; }
.al-you { color: var(--accent); }
.al-you::before { content: ""; }
/* 每条回答的指标行（首字延迟/token 速率，口径同 ai-monitor 账本）：比正文小一号、更淡 */

/* 本机 AI 基线一行（数据来自 ai-monitor 账本，agent 面板对照用） */
.agent-base {
  margin-top: 7px;
  font-size: 12px;
  color: var(--text);
  opacity: .6;
  padding: 5px 9px;
  border: 1px dashed var(--line);
  border-radius: 6px;
  background: var(--surface-2);
}

.agent-tools {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 9px;
  flex-wrap: wrap;
}
.agent-tools .add-hint { flex: 1; min-width: 200px; }

#m-brain .add-row input { font-family: Consolas, monospace; letter-spacing: .04em; }

/* ===== 17. 局域网共享（S7）+ 登录层 ===== */
.acc-share {
  border-top: 1px dashed var(--line);
  padding-top: 10px;
}
.acc-share-row {
  display: flex;
  align-items: center;
  gap: 9px;
  flex-wrap: wrap;
}
.acc-share-row input {
  background: var(--surface-2);
  border: 1px solid var(--line-strong);
  border-radius: 7px;
  color: var(--text);
  padding: 6px 9px;
  font-size: 12.5px;
}
.acc-share-row input:focus { border-color: var(--accent); box-shadow: var(--glow); }
.acc-lan-log {
  margin-top: 9px;
  max-height: 110px;
  overflow-y: auto;
  font-family: Consolas, monospace;
  font-size: 11.5px;
  line-height: 1.7;
}
.acc-lan-row { border-bottom: 1px dashed var(--line); padding: 2px 0; }
.acc-lan-row:last-child { border-bottom: 0; }

/* 公网入口（2026-10-12）：来源白名单 / 拉黑名单 并排的两个小输入框 */
.acc-pub-cols { display: flex; gap: 12px; margin: 8px 0; flex-wrap: wrap; }
.acc-pub-cols label { flex: 1 1 220px; display: flex; flex-direction: column; gap: 4px; font-size: 12px; }
.acc-pub-cols textarea {
  font-family: var(--font-mono); font-size: 12px; line-height: 1.5; resize: vertical;
  background: var(--surface-2); color: var(--text);
  border: 1px solid var(--line-strong); border-radius: 8px; padding: 6px 8px;
}
#acc-pub { border-left: 2px solid var(--accent); }

#m-login .add-row input {
  width: 100%;
  background: var(--surface-2);
  border: 1px solid var(--line-strong);
  border-radius: 8px;
  color: var(--text);
  padding: 9px 11px;
}
#login-err { color: var(--danger); }

/* ===== 18. 字幕条（语音识别 + TTS 播报双向上屏） ===== */
.subtitle-bar {
  position: fixed;
  left: 50%;
  bottom: 30px;
  transform: translateX(-50%) translateY(16px);
  z-index: var(--z-subtitle);
  max-width: min(880px, 92vw);
  display: flex;
  gap: 11px;
  align-items: baseline;
  padding: 12px 20px;
  border-radius: 13px;
  background: color-mix(in srgb, var(--surface) 88%, transparent);
  backdrop-filter: blur(9px);
  -webkit-backdrop-filter: blur(9px);
  border: 1px solid var(--line-strong);
  box-shadow: 0 10px 36px rgba(0, 0, 0, .38);
  opacity: 0;
  pointer-events: none;
  transition: opacity .38s ease, transform .38s ease;
}
.subtitle-bar.is-show {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}
.subtitle-bar.is-hide {
  opacity: 0;
  transform: translateX(-50%) translateY(16px);
}
.sub-who {
  flex-shrink: 0;
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: .1em;
  color: var(--accent);
  white-space: nowrap;
}
.sub-text {
  font-size: 16.5px;
  line-height: 1.55;
  color: var(--text);
  word-break: break-word;
}
[data-skin="tech-max"] .subtitle-bar {
  border-color: rgba(124, 140, 255, .5);
  box-shadow: 0 12px 44px rgba(0, 0, 0, .55), 0 0 26px rgba(124, 140, 255, .2);
}
[data-skin="tech-max"] .sub-text { text-shadow: 0 0 14px rgba(124, 140, 255, .4); }
[data-skin="tech-max"] .sub-who { text-shadow: 0 0 10px rgba(124, 140, 255, .5); }

/* V2-32（2026-10-18）：标签栏漏了触控尺寸 —— 项目自己在 640 断点给 .btn / .seg button
   定了 min-height:40px，唯独 .tab-btn 没跟上（实测 22px，手机上按不准）。
   900 断点覆盖手机与平板竖屏；顺带让顶栏在窄屏换行，5 个标签挤一行会互相压。 */
@media (max-width: 900px) {
  .tab-btn { min-height: 40px; padding: 9px 12px; }
  .topbar, .topbar-center, .topbar-tabs { flex-wrap: wrap; }
  .topbar-tabs { row-gap: 6px; }
}

@media (max-width: 900px) {
  /* V2-35⑤（2026-10-19）：顶栏右侧按钮条（… Harness 系统配置 使用文档）在手机上溢出，
     实测把 "Harness" 截成 "Harnes"。允许换行 + 允许子项收缩。 */
  .topbar > * { min-width: 0; }
  .topbar-right, .topbar-actions, .brand-status { flex-wrap: wrap; max-width: 100%; }
  .brand-status { row-gap: 4px; }
}

@media (max-width: 720px) {
  /* V2-35④（2026-10-19）：手机窄屏时 section 标题被挤成一列一个字（「02 服务」竖排）。 */
  .section-title { flex-wrap: wrap; row-gap: 4px; }
  .section-title h2 { white-space: nowrap; font-size: 15px; }
  .section-title .tag { white-space: nowrap; }
}

@media (max-width: 640px) {
  .subtitle-bar { bottom: 18px; padding: 10px 14px; max-width: 94vw; }
  .sub-text { font-size: 14.5px; }
}

/* ===== 20. 顶栏时间块去 NTP 偏移（2026-10-09 老板指令）：只正常显示时间 ===== */
.ntp-badge { display: none !important; }

/* ===== 21. 状态备注徽标（2026-10-09：卡片一眼看出是否实际可用） ===== */
.status-chip {
  display: inline-block;
  margin-left: 7px;
  padding: 1px 9px;
  border-radius: 999px;
  font-size: 11.5px;
  font-weight: 700;
  line-height: 1.7;
  vertical-align: middle;
  border: 1px solid transparent;
  letter-spacing: .02em;
}
.status-chip.sc-use {
  color: var(--ok);
  border-color: color-mix(in srgb, var(--ok) 55%, transparent);
  background: color-mix(in srgb, var(--ok) 13%, transparent);
}
.status-chip.sc-dev {
  color: var(--accent);
  border-color: color-mix(in srgb, var(--accent) 55%, transparent);
  background: color-mix(in srgb, var(--accent) 13%, transparent);
}
.status-chip.sc-test {
  color: var(--warn);
  border-color: color-mix(in srgb, var(--warn) 60%, transparent);
  background: color-mix(in srgb, var(--warn) 15%, transparent);
}
.status-chip.sc-hold {
  color: var(--dim);
  border-color: var(--line-strong);
  background: var(--surface-3);
}
.status-chip.sc-bad {
  color: var(--danger);
  border-color: color-mix(in srgb, var(--danger) 60%, transparent);
  background: color-mix(in srgb, var(--danger) 13%, transparent);
}

/* ===== 21b. 服务卡片状态分组标题（2026-10-21 老板：开发中/测试中/使用中区分开） =====
 * 跨列独占一行（grid-column: 1/-1），左侧状态色点 + 名称 + 数量 + 渐隐横线。 */
.svc-group {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 8px 2px 0;
  line-height: 1.6;
}
.svc-group:first-child { margin-top: 0; }
.svc-group i {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--dim); flex: none;
}
.svc-group b {
  font-size: 13px; font-weight: 700; color: var(--text);
  letter-spacing: .02em;
}
.svc-group span {
  font-size: 11px; color: var(--dim);
  font-variant-numeric: tabular-nums;
}
.svc-group em {
  flex: 1; height: 1px;
  background: linear-gradient(90deg, var(--line-strong), transparent);
}
.svc-group.sc-dev i {
  background: var(--accent);
  box-shadow: 0 0 8px color-mix(in srgb, var(--accent) 55%, transparent);
}
.svc-group.sc-test i {
  background: var(--warn);
  box-shadow: 0 0 8px color-mix(in srgb, var(--warn) 55%, transparent);
}
.svc-group.sc-use i {
  background: var(--ok);
  box-shadow: 0 0 8px color-mix(in srgb, var(--ok) 55%, transparent);
}
.svc-group.sc-hold i { background: var(--dim); }
.svc-group.sc-bad i {
  background: var(--danger);
  box-shadow: 0 0 8px color-mix(in srgb, var(--danger) 55%, transparent);
}

/* ===== 22. 设置 · 自定义 API（2026-10-09） ===== */
.set-apis { display: flex; flex-direction: column; gap: 7px; margin-top: 13px; }
.set-row {
  display: grid;
  grid-template-columns: 110px minmax(0, 1fr) 78px 120px auto;
  gap: 8px;
  align-items: center;
  padding: 8px 10px;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: 8px;
  font-size: 12px;
}
.set-name { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.set-url {
  font-family: var(--font-mono); font-size: 11.5px; color: var(--dim);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.set-key, .set-model { font-family: var(--font-mono); font-size: 11.5px; color: var(--dim-2);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.set-actions { display: flex; gap: 5px; }
.set-actions .btn { padding: 3px 8px; font-size: 11.5px; min-height: 0; }
.set-test-result { grid-column: 1 / -1; font-family: var(--font-mono); font-size: 11.5px; color: var(--dim); }
.set-test-result.is-ok { color: var(--ok); }
.set-test-result.is-err { color: var(--danger); }
.set-form { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--line); }
.set-form-title { font-size: 12.5px; font-weight: 600; margin-bottom: 8px; color: var(--text); }
.set-form-actions { display: flex; gap: 8px; align-items: center; margin-top: 10px; flex-wrap: wrap; }

/* ===== 23. 全局化科技质感（2026-10-09 老板："第一屏有感觉，下滑就普通换色 → 改成全局化"）=====
   把首屏已有的科技语言铺满整页组件：渐变描边 / 对角 HUD 括号 / 流光标题线 / 表格扫描 /
   按钮带电 / 指令台终端化 / 弹层描边。全部限定 tech-max（传统档零影响）；
   颜色走 var(--accent)，日夜自动适配；发光在日间块减弱。 */

/* 23.1 面板族（01 全局资源 / 03 安全监控 / 04 agent中心）：渐变描边 + 对角括号 */
[data-skin="tech-max"] .panel {
  position: relative;
  border: 1px solid transparent;
  background:
    linear-gradient(var(--surface), var(--surface)) padding-box,
    linear-gradient(135deg,
      color-mix(in srgb, var(--accent) 75%, transparent),
      color-mix(in srgb, var(--accent) 16%, transparent) 42%,
      color-mix(in srgb, var(--accent) 16%, transparent) 58%,
      color-mix(in srgb, var(--accent-2, var(--accent)) 62%, transparent)) border-box;
  box-shadow: var(--shadow), inset 0 0 26px color-mix(in srgb, var(--accent) 5%, transparent);
}
[data-skin="tech-max"] .panel::before,
[data-skin="tech-max"] .panel::after {
  content: "";
  position: absolute;
  width: 13px;
  height: 13px;
  border: 2px solid var(--accent);
  opacity: .5;
  pointer-events: none;
  transition: opacity var(--t-fast);
}
[data-skin="tech-max"] .panel::before { top: 7px; left: 7px; border-right: 0; border-bottom: 0; }
[data-skin="tech-max"] .panel::after { bottom: 7px; right: 7px; border-left: 0; border-top: 0; }
[data-skin="tech-max"] .panel:hover::before,
[data-skin="tech-max"] .panel:hover::after { opacity: 1; }
/* 贴顶表格的面板豁免括号（03 表格 padding-top 仅 4px，括号会叠表头字） */
[data-skin="tech-max"] .panel:has(table)::before,
[data-skin="tech-max"] .panel:has(table)::after { content: none; }

/* 23.2 卡片常态能量描边（02 纳管卡外层 1px 由灰线换渐变，常态就带电） */
[data-skin="tech-max"] .card {
  background: linear-gradient(135deg,
    color-mix(in srgb, var(--accent) 60%, transparent),
    color-mix(in srgb, var(--accent) 20%, transparent) 45%,
    color-mix(in srgb, var(--accent-2, var(--accent)) 52%, transparent));
}
[data-skin="tech-max"] .card:hover { filter: brightness(1.05); }

/* 23.3 标题线流光（能量沿线流动，滚动全程可见的"活"元素） */
[data-skin="tech-max"] .section-title .rule {
  background: linear-gradient(90deg,
    color-mix(in srgb, var(--accent) 88%, transparent) 0%,
    color-mix(in srgb, var(--accent) 45%, transparent) 28%,
    color-mix(in srgb, var(--accent) 12%, transparent) 70%,
    transparent 100%);
  background-size: 240% 100%;
  animation: rule-flow 6.5s linear infinite;
}
[data-skin="tech-max"][data-theme="light"] .section-title .rule {
  background: linear-gradient(90deg,
    rgba(77, 92, 232, .75) 0%, rgba(111, 93, 242, .42) 30%,
    rgba(77, 92, 232, .12) 72%, transparent 100%);
  background-size: 240% 100%;
  animation: rule-flow 6.5s linear infinite;
}
@keyframes rule-flow { from { background-position: 240% 0; } to { background-position: -240% 0; } }
[data-deco="lite"] .section-title .rule { animation: none; }   /* 移动端关流动省电 */

/* 23.4 表格（03 入站流水 + 访问详情 / 白名单 / 设置等弹层表全吃） */
[data-skin="tech-max"] th {
  background: linear-gradient(180deg,
    color-mix(in srgb, var(--accent) 12%, transparent),
    color-mix(in srgb, var(--accent) 3%, transparent));
  color: var(--dim);
  letter-spacing: .08em;
  border-bottom: 1px solid color-mix(in srgb, var(--accent) 42%, transparent);
}
[data-skin="tech-max"] tbody tr {
  transition: background var(--t-fast), box-shadow var(--t-fast);
}
[data-skin="tech-max"] tbody tr:hover {
  background: color-mix(in srgb, var(--accent) 8%, transparent);
  box-shadow: inset 2px 0 0 var(--accent);
}

/* 23.5 按钮常态带电（primary 是实底按钮，只加常驻光晕不叠底纹） */
[data-skin="tech-max"] .btn:not(.btn-primary) {
  border-color: color-mix(in srgb, var(--accent) 40%, transparent);
  background-image: linear-gradient(180deg,
    color-mix(in srgb, var(--accent) 8%, transparent),
    color-mix(in srgb, var(--accent) 0%, transparent));
}
[data-skin="tech-max"] .btn:not(.btn-primary):hover {
  border-color: var(--accent);
  background-image: linear-gradient(180deg,
    color-mix(in srgb, var(--accent) 15%, transparent),
    color-mix(in srgb, var(--accent) 3%, transparent));
}
[data-skin="tech-max"] .btn-primary {
  box-shadow: 0 0 16px color-mix(in srgb, var(--accent) 32%, transparent);
}

/* 23.6 指令台日志终端化（夜：深底 + 发光边；日间保持浅底只留描边） */
[data-skin="tech-max"] .agent-log {
  background: linear-gradient(180deg, rgba(16, 20, 28, .97), rgba(12, 15, 22, .99));
  border-color: color-mix(in srgb, var(--accent) 35%, transparent);
  box-shadow: inset 0 0 22px color-mix(in srgb, var(--accent) 6%, transparent);
}

/* 23.7 弹层卡片渐变描边（与面板同语言，阴影 glow 由 1345 段保留） */
[data-skin="tech-max"] .modal-card {
  border: 1px solid transparent;
  background:
    linear-gradient(var(--surface), var(--surface)) padding-box,
    linear-gradient(135deg,
      color-mix(in srgb, var(--accent) 68%, transparent),
      color-mix(in srgb, var(--accent) 15%, transparent) 46%,
      color-mix(in srgb, var(--accent-2, var(--accent)) 55%, transparent)) border-box;
}

/* 23.8 日间减弱（浅底发光易显脏 → 光晕降档、终端深底回浅、hover 提亮关） */
[data-skin="tech-max"][data-theme="light"] .btn-primary {
  box-shadow: 0 2px 12px rgba(77, 92, 232, .28);
}
[data-skin="tech-max"][data-theme="light"] .agent-log {
  background: var(--surface-2);
  box-shadow: inset 0 0 18px color-mix(in srgb, var(--accent) 6%, transparent);
}
[data-skin="tech-max"][data-theme="light"] .card:hover { filter: none; }

/* ===== 24. 戴森球轨道环组（2026-10-09 老板："背景基本一大块空白，星环旋转图形再多一些"）=====
   仅科技档：fixed 全屏五环交错倾斜（虚线环 + 行星亮点沿轨运行），滚动全程可见；
   纯 CSS 零 canvas 零依赖（行星动画 GPU 合成）；日间降透、lite 移动端关、传统档不渲染。 */
.orbits { display: none; }
[data-skin="tech-max"] .orbits {
  display: block;
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  overflow: hidden;
}
[data-skin="tech-max"] .orbits i {
  position: absolute;
  border: 1.5px dashed color-mix(in srgb, var(--accent) 45%, transparent);
  border-radius: 50%;
  opacity: .42;
}
[data-skin="tech-max"] .orbits i::after {           /* 行星亮点：贴合倾斜轨道面运行 */
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: 7px;
  height: 7px;
  margin: -3.5px 0 0 -3.5px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 10px color-mix(in srgb, var(--accent) 85%, transparent),
              0 0 3px color-mix(in srgb, var(--accent) 100%, transparent);
  animation: orb-moon var(--dur, 46s) linear infinite;
  animation-direction: var(--dir, normal);
}
@keyframes orb-moon {
  to { transform: rotate(360deg) translateX(var(--r, 160px)); }
}
/* 五环分布：尺寸 / 锚位 / 倾角与椭圆朝向 / 行星轨半径 / 周期与方向 */
[data-skin="tech-max"] .orbits i:nth-child(1) {   /* 右上大环 */
  width: 520px; height: 520px; right: -130px; top: 7vh;
  transform: rotateX(64deg) rotateZ(10deg);
  --r: 252px; --dur: 46s;
}
[data-skin="tech-max"] .orbits i:nth-child(2) {   /* 左中环（反向） */
  width: 360px; height: 360px; left: -90px; top: 36vh;
  transform: rotateX(58deg) rotateZ(-20deg);
  --r: 172px; --dur: 36s; --dir: reverse;
}
[data-skin="tech-max"] .orbits i:nth-child(3) {   /* 右下环 */
  width: 430px; height: 430px; right: -70px; bottom: -110px;
  transform: rotateX(66deg) rotateZ(26deg);
  --r: 207px; --dur: 54s;
}
[data-skin="tech-max"] .orbits i:nth-child(4) {   /* 左下小环（快、反向） */
  width: 250px; height: 250px; left: 7vw; bottom: 5vh;
  transform: rotateX(54deg) rotateZ(-6deg);
  --r: 117px; --dur: 30s; --dir: reverse;
}
[data-skin="tech-max"] .orbits i:nth-child(5) {   /* 中左超大淡环（慢速压场） */
  width: 660px; height: 660px; left: 16vw; top: -190px;
  transform: rotateX(70deg) rotateZ(-8deg);
  opacity: .26;
  --r: 322px; --dur: 78s;
}
/* 2026-10-10 老板：日间也要绚丽 → 轨道环日夜同强度（不再降透缩光） */
/* 移动端 lite：关整组（视觉噪音 + 动画开销） */
[data-deco="lite"] .orbits { display: none; }

/* ===== 25. 扫描已运行服务（2026-10-10：一键纳管 / 停止进程） ===== */
.scan-list { max-height: 48vh; overflow-y: auto; padding-right: 2px; }
.scan-filter {
  display: flex;
  align-items: center;
  gap: 7px;
  flex-wrap: wrap;
  margin-bottom: 10px;
}
.sf-lab { font-size: 11.5px; color: var(--dim-2); }
.fmini {
  font-size: 11.5px;
  color: var(--dim);
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 3px 10px;
  cursor: pointer;
  transition: color var(--t-fast), border-color var(--t-fast);
}
.fmini:hover { color: var(--text); border-color: var(--line-strong); }
.fmini.is-on {
  color: var(--accent);
  border-color: var(--accent);
  background: var(--accent-light);
}
.scan-pid-in {
  width: 130px;
  padding: 3px 9px;
  font-family: var(--font-mono);
  font-size: 11.5px;
  color: var(--text);
  background: var(--surface-2);
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  outline: none;
}
.scan-pid-in:focus { border-color: var(--accent); }
.sf-count { margin-left: auto; font-size: 11.5px; color: var(--dim-2); }
.scan-proc { display: flex; align-items: center; gap: 7px; min-width: 0; }
.bind-tag {
  font-family: var(--font-mono);
  font-size: 11.5px;
  padding: 1px 6px;
  border-radius: 999px;
  border: 1px solid var(--line);
  color: var(--dim-2);
  background: var(--surface-3);
  white-space: nowrap;
  max-width: 108px;
  overflow: hidden;
  text-overflow: ellipsis;
  flex-shrink: 0;
}
.bind-tag.is-loop { color: var(--ok); border-color: rgba(91, 201, 138, .35); }
.bind-tag.is-warn,
.bind-tag.is-wild { color: var(--warn); border-color: rgba(255, 169, 77, .4); }
.scan-row {
  display: grid;
  grid-template-columns: 86px minmax(110px, 1fr) 86px minmax(0, 1.7fr) auto;
  gap: 9px;
  align-items: center;
  padding: 8px 10px;
  margin-bottom: 7px;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: 8px;
  font-size: 12px;
  transition: border-color var(--t-fast);
}
.scan-row.is-managed { opacity: .55; }
.scan-port { font-family: var(--font-mono); font-weight: 600; color: var(--accent); }
.scan-pid { font-family: var(--font-mono); font-size: 11.5px; color: var(--dim-2); }
.scan-path {
  font-family: var(--font-mono);
  font-size: 11.5px;
  color: var(--dim);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.scan-acts { display: flex; gap: 6px; align-items: center; }
.scan-acts .btn { padding: 3px 9px; min-height: 0; font-size: 11.5px; }
.scan-empty { padding: 18px 10px; color: var(--dim-2); font-size: 12.5px; }
[data-skin="tech-max"] .scan-row:hover {
  border-color: color-mix(in srgb, var(--accent) 45%, transparent);
}

/* ===== 26.5 顶栏融合轮播 + 标题栏微装饰（2026-10-10 老板：星环/戴森球战斗/流浪地球三幕） ===== */
/* 2026-10-20 老板：顶栏戴森球动效已去掉（#topbar-scene 画布与 scene.js 第二幕一并移除） */
/* 区块标题 / 弹层头部微装饰：渐变底 + 漂浮小轨道环（静态语言与顶栏呼应） */
[data-skin="tech-max"] .section-title {
  position: relative;
  background: linear-gradient(90deg,
    color-mix(in srgb, var(--accent) 7%, transparent),
    transparent 62%);
  border-radius: 8px;
}
[data-skin="tech-max"] .section-title::after {
  content: "";
  position: absolute;
  right: 118px; top: 50%;
  width: 14px; height: 14px;
  margin-top: -9px;
  border: 1.4px dashed color-mix(in srgb, var(--accent) 55%, transparent);
  border-radius: 50%;
  transform: rotateX(58deg);
  opacity: .55;
  pointer-events: none;
}
[data-skin="tech-max"] .modal-card .modal-head {
  position: relative;
  background: linear-gradient(90deg,
    color-mix(in srgb, var(--accent) 8%, transparent),
    transparent 55%);
}
[data-skin="tech-max"] .modal-card .modal-head::after {
  content: "";
  position: absolute;
  right: 96px; top: 50%;
  width: 12px; height: 12px;
  margin-top: -8px;
  border: 1.3px dashed color-mix(in srgb, var(--accent) 55%, transparent);
  border-radius: 50%;
  transform: rotateX(58deg);
  opacity: .5;
  pointer-events: none;
}
[data-deco="lite"] .section-title::after,
[data-deco="lite"] .modal-card .modal-head::after { display: none; }

/* ===== 26. 专注模式（2026-10-10：全屏场景 + 太空人 + 计时；黑洞特有） ===== */
/* 固定深空底（专注=沉浸，不分日夜），z 在弹层之上 */
.focus-wrap {
  position: fixed;
  inset: 0;
  z-index: 300;
  background: radial-gradient(1200px 700px at 50% 30%, #0a0f1e 0%, #04060c 70%);
}
.focus-wrap[hidden] { display: none; }
#focus-canvas { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 1; pointer-events: none; }
.focus-hud {
  position: absolute;
  top: 0; left: 0; right: 0;
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 10px 16px;
  background: linear-gradient(180deg, rgba(4, 6, 12, .92), rgba(4, 6, 12, .55) 80%, transparent);
  flex-wrap: wrap;
}
/* 场景切换：左上角 ◀ 名称 ▶ 紧凑菜单（2026-10-10 老板：不再全部摊开） */
.focus-scenes {
  display: flex; align-items: center; gap: 6px;
  background: rgba(14, 18, 32, .78); border: 1px solid #2a3450;
  border-radius: 999px; padding: 3px 6px;
  backdrop-filter: blur(6px);
}
.fnav {
  width: 26px; height: 26px; border-radius: 50%;
  border: 1px solid transparent; background: transparent;
  color: #9fa9b8; font-size: 12px; cursor: pointer; line-height: 1;
  transition: color var(--t-fast), border-color var(--t-fast), box-shadow var(--t-fast);
}
.fnav:hover { color: #fff; border-color: #7c8cff; box-shadow: 0 0 10px rgba(124, 140, 255, .35); }
.fname {
  min-width: 112px; text-align: center;
  font-size: 12.5px; color: #dfe6ff; letter-spacing: .04em;
}
/* 专注计时：整个屏幕最上方居中（2026-10-11 老板四改："挪到整个屏幕的最上方中间"；
   原版在 canvas 上跟随太空人头顶，已迁到 DOM 以获得稳定层级） */
.focus-timer {
  position: absolute;
  left: 50%; top: 6px;
  transform: translateX(-50%);
  z-index: 9;                                    /* 顶层：不被 canvas/hud/tip 覆盖 */
  text-align: center;
  pointer-events: none;
  user-select: none;
  -webkit-user-select: none;
}
.focus-timer .ft-label {
  font-size: 11.5px;
  letter-spacing: .62em; text-indent: .62em;
  color: rgba(198, 210, 255, .6);
  margin-bottom: 1px;
  text-shadow: 0 1px 8px rgba(2, 4, 10, .95);
}
.focus-timer .ft-time {
  font-family: Consolas, "Courier New", monospace;
  font-size: clamp(22px, 3.4vw, 54px);
  font-weight: 600;
  letter-spacing: .06em;
  line-height: 1.05;
  color: #e2e9ff;
  text-shadow:
    0 0 18px rgba(140, 160, 255, .5),
    0 2px 12px rgba(2, 4, 10, .95),
    0 0 44px rgba(120, 140, 255, .3);
}
#m-focus[data-scene="hole"] .focus-timer .ft-time {
  color: #ffd9a8;
  text-shadow:
    0 0 20px rgba(255, 170, 80, .55),
    0 2px 12px rgba(2, 4, 10, .95),
    0 0 46px rgba(255, 150, 60, .3);
}
#m-focus[data-scene="hole"] .focus-timer .ft-label { color: rgba(255, 205, 150, .64); }
/* 小屏：HUD 顶栏会换行 → 计时块让到 HUD 下方 */
@media (max-width: 720px) {
  .focus-timer { top: 54px; }
}
.focus-ctrl { display: flex; gap: 7px; margin-left: auto; }
/* 2026-10-11 老板：暂停/退出在深空底上原为浅色主题文字，看不清 —— 固定亮字 + 亮边 */
.focus-ctrl .btn {
  background: rgba(19, 26, 44, .82);
  border-color: rgba(128, 144, 255, .5);
  color: #e8eeff;
  font-size: 13px;
  padding: 8px 16px;
  text-shadow: 0 1px 6px rgba(0, 0, 0, .65);
}
.focus-ctrl .btn:hover {
  background: rgba(32, 42, 70, .92);
  border-color: #9db0ff;
  color: #fff;
  box-shadow: 0 0 14px rgba(124, 140, 255, .45);
}
.focus-ctrl #focus-close:hover {
  border-color: #ff9a9a;
  color: #ffd2d2;
  box-shadow: 0 0 14px rgba(255, 110, 110, .4);
}
/* 底部提示语：加大字号 + 可点击切下一句（2026-10-11 老板） */
.focus-tip {
  position: absolute;
  bottom: 24px; left: 50%;
  transform: translateX(-50%);
  max-width: min(92vw, 1180px);
  padding: 9px 26px;
  border-radius: 999px;
  text-align: center;
  font-size: 19px;
  letter-spacing: .08em;
  color: rgba(226, 233, 255, .95);
  background: rgba(8, 12, 24, .35);
  border: 1px solid rgba(124, 140, 255, .18);
  text-shadow: 0 0 16px rgba(110, 130, 220, .5), 0 2px 10px rgba(0, 0, 0, .85);
  cursor: pointer;
  transition: opacity .42s ease, border-color .2s ease, color .2s ease;
}
.focus-tip:hover, .focus-tip:focus-visible {
  border-color: rgba(155, 172, 255, .5);
  color: #fff;
  outline: none;
}
/* 进入全屏后的弹出提示（4 秒淡出） */
.focus-fs-tip {
  position: absolute;
  left: 50%; top: 11%;
  transform: translateX(-50%);
  z-index: 8;
  padding: 10px 22px;
  border-radius: 999px;
  background: rgba(10, 16, 32, .85);
  border: 1px solid rgba(128, 144, 255, .55);
  color: #e8eeff;
  font-size: 14.5px;
  letter-spacing: .06em;
  white-space: nowrap;
  box-shadow: 0 0 26px rgba(90, 110, 220, .35);
  pointer-events: none;
  opacity: 0;
  transition: opacity .5s ease;
}
.focus-fs-tip[hidden] { display: none; }
.focus-fs-tip.show { opacity: 1; }

/* ============================================================
   section 24 —— 公网只读视图（2026-10-11）
   后端 NOS_PUBLIC=1 且访客不在管理员网段时，<html data-readonly="1">，
   界面同步摘掉所有操作入口，避免出现一按就 403 的按钮。
   ============================================================ */
[data-readonly="1"] .card-actions,
[data-readonly="1"] #btn-add,
[data-readonly="1"] #btn-scan,
[data-readonly="1"] #btn-exe,
[data-readonly="1"] #btn-scenes,
[data-readonly="1"] #btn-settings,
[data-readonly="1"] #btn-access-detail,
[data-readonly="1"] #btn-memory,
[data-readonly="1"] #sec-access,
[data-readonly="1"] #sec-agent {
  display: none !important;
}

.ro-banner {
  margin: 0 auto 12px;
  padding: 7px 14px;
  border-radius: 8px;
  font-size: 13px;
  text-align: center;
  color: inherit;
  background: rgba(186, 117, 23, .14);
  border: .5px solid rgba(186, 117, 23, .45);
}

/* ===== section 27：卡片级二次验证（2026-10-11 老板指令） ===== */
.tag.is-gate {
  color: var(--warn, #d97706);
  border-color: rgba(217, 119, 6, .5);
  background: rgba(217, 119, 6, .12);
}
.gate-clear-row {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12.5px;
  color: var(--dim-2, #8b93a7);
}
.gate-clear-row input[type="checkbox"] {
  width: auto;
  accent-color: var(--accent, #5a69dc);
}
.add-hint.wide { grid-column: 1 / -1; }

/* ===== section 28：顶栏「帮助」入口（2026-10-11）—— /help 独立文档页，新标签打开 ===== */
a.btn-help {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  text-decoration: none;
  cursor: pointer;
}
a.btn-help:hover { text-decoration: none; }
[data-skin="tech-max"] a.btn-help {
  background: linear-gradient(180deg, rgba(94, 231, 255, .10), rgba(94, 231, 255, .02));
}

/* ===== section 29：版本说明（2026-10-12 老板）—— logo 右侧版本徽章 + 改动流水弹层 ===== */
/* 2026-10-20 老板：上下结构 —— 开发时间轴 / 版本号 / 小字持续开发 */
.brand-ver {
  margin-left: 2px;
  padding: 2px 9px 3px;
  display: inline-flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 1px;
  font-family: var(--font-mono);
  letter-spacing: .02em;
  color: var(--dim-2);
  background: transparent;
  border: 1px solid var(--line-strong);
  border-radius: 9px;
  cursor: pointer;
  white-space: nowrap;
  transition: color var(--t-fast), border-color var(--t-fast);
}
.brand-ver .bv-name { font-size: 11.5px; line-height: 1.25; color: var(--dim); }
.brand-ver .bv-ver { font-size: 12.5px; line-height: 1.2; font-weight: 600; color: var(--text); }
.brand-ver .brand-status { margin-top: 1px; }
.brand-ver .brand-dev, .brand-ver .brand-dev em { font-size: 10px; line-height: 1.2; }
.brand-ver .brand-dev { gap: 4px; }
.brand-ver:hover, .brand-ver:focus-visible { color: var(--accent); border-color: var(--accent); }

/* ---- 持续开发状态 + 最近更新框（2026-10-13 老板：版本号位置写"正在持续开发"，
        右侧加最近一次版本更新框，让人感觉项目一直在开发中） ---- */
/* 持续开发状态 + 最近更新（2026-10-13 老板：改成上下两行，避免侵占顶栏其他显示空间） */
.brand-status {
  display: inline-flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 3px;
  vertical-align: middle;
}
/* 自定义 display 会盖掉 [hidden] 的 UA 规则 —— 首帧空状态块就是这么冒出来的
   （F14 · 2026-10-16 审计；项目第三次踩这个坑）。同类已排查：.add-form / .subtitle-bar。 */
.brand-status[hidden] { display: none; }
.add-form[hidden] { display: none; }
.subtitle-bar[hidden] { display: none; }
.brand-dev {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 11.5px;
  color: var(--dim-2);
  white-space: nowrap;
}
.brand-dev em {
  font-style: normal;
  font-family: var(--font-mono);
  font-size: 11.5px;
  color: var(--dim);
}
.live-dot {
  display: inline-block;
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--ok);
  flex-shrink: 0;
  animation: live-pulse 1.8s ease-in-out infinite;
}
@keyframes live-pulse {
  0%, 100% { opacity: 1; box-shadow: 0 0 0 0 color-mix(in srgb, var(--ok) 45%, transparent); }
  50% { opacity: .55; box-shadow: 0 0 0 4px color-mix(in srgb, var(--ok) 0%, transparent); }
}
.bl-text { overflow: hidden; text-overflow: ellipsis; }

/* 溢出长文本慢速滑动（2026-10-13 老板：行太长显示不够就滑动显示，速度要慢）——
   JS（app.js mxSync）检测内容真的放不下时给元素加 .mx-live，用 scrollLeft 往返
   （内容动、元素不动）；滑动中右端硬切（clip），低动效（lite）回落省略号 */
.mx-live { text-overflow: clip; }
[data-deco="lite"] .mx-live { text-overflow: ellipsis; }

.modal-card.modal-ver { width: min(760px, 100%); }
.ver-body { overflow: auto; padding: 2px 0 8px; }
.ver-empty { padding: 26px 17px; color: var(--dim-2); font-size: 12.5px; }

/* ---- 开发调用数据（2026-10-13 老板：token 消耗/调用次数放时间轴） ---- */
.ver-usage {
  margin: 8px 17px 6px;
  padding: 9px 12px;
  background: color-mix(in srgb, var(--accent) 6%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent) 22%, transparent);
  border-radius: var(--r-ctrl);
  font-size: 12px;
  line-height: 1.65;
}
.vu-head { font-weight: 600; color: var(--text); }
.vu-head em { font-style: normal; font-weight: 400; font-size: 11.5px; color: var(--dim-2); margin-left: 6px; }
.vu-nums { color: var(--dim); }
.vu-nums b { font-family: var(--font-mono); color: var(--accent); font-weight: 700; }
.vu-days { font-size: 11.5px; color: var(--dim-2); font-family: var(--font-mono); }

/* ---- 竖排时间轴（2026-10-12 老板：改竖排、只留时间轴；轴上不放时间、放版本号，逐条直显内容） ---- */
.ver-tl { position: relative; padding: 6px 0 2px; }
.ver-tl::before {          /* 竖轴：贯穿全表；顶（最新）亮 → 底（最早）灰 */
  content: "";
  position: absolute;
  left: 25px; top: 26px; bottom: 23px;
  width: 2px; margin-left: -1px;
  background: linear-gradient(180deg, var(--accent), var(--line-strong));
  border-radius: 1px;
}
.ver-tl-row, .ver-tl-sep {
  position: relative;
  display: grid;
  grid-template-columns: 52px minmax(0, 1fr);
}
.ver-tl-line { position: relative; display: block; }
.ver-tl-line::after {      /* 大版本节点：空心圆（轴心 x=26） */
  content: "";
  position: absolute;
  left: 26px; top: 20px;
  width: 12px; height: 12px;
  margin: -6px 0 0 -6px;
  border-radius: 50%;
  background: var(--surface);
  border: 2px solid var(--accent);
  box-sizing: border-box;
  z-index: 1;
}
.ver-tl-row.is-minor .ver-tl-line::after {   /* 修订版节点：小实心点 */
  top: 15px;
  width: 7px; height: 7px;
  margin: -3.5px 0 0 -3.5px;
  border: 0;
  background: var(--dim-2);
  opacity: .75;
}
.ver-tl-row.is-top .ver-tl-line::after {     /* 当前版本：实心 + 光环 */
  background: var(--accent);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent) 22%, transparent);
  opacity: 1;
}
.ver-tl-main {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 2px 10px;
  padding: 11px 17px 11px 8px;
}
.ver-tl-row.is-minor .ver-tl-main { padding: 6px 17px 6px 8px; }
.ver-tl-v {
  flex-shrink: 0;
  min-width: 56px;
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--accent);
  white-space: nowrap;
}
.ver-tl-row.is-minor .ver-tl-v { font-weight: 400; font-size: 11.5px; color: var(--dim-2); }
.ver-tl-ts {              /* 刻度时间：某日某时某分（2026-10-13 老板） */
  flex-shrink: 0;
  min-width: 106px;
  font-family: var(--font-mono);
  font-size: 11.5px;
  color: var(--dim-2);
  white-space: nowrap;
}
.ver-tl-row.is-minor .ver-tl-ts { font-size: 11.5px; }
.ver-tl-meta {            /* 逐版本耗时与 token（2026-10-13 老板）：独占一行小字 */
  flex-basis: 100%;
  font-family: var(--font-mono);
  font-size: 11.5px;
  color: var(--dim-2);
}
.ver-tl-t { font-size: 12.5px; line-height: 1.55; color: var(--text); }
.ver-tl-row.is-minor .ver-tl-t { font-size: 12px; color: var(--dim); }
.ver-tl-row:hover .ver-tl-main { background: color-mix(in srgb, var(--accent) 5%, transparent); }
.ver-tl-row.is-top .ver-tl-main { background: color-mix(in srgb, var(--accent) 8%, transparent); }
.ver-tl-row.is-top .ver-tl-v { font-weight: 700; }
.ver-tl-sep .ver-tl-line::after {           /* 分界记号：小菱形（公网上线） */
  content: "";
  position: absolute;
  left: 26px; top: 50%;
  width: 8px; height: 8px;
  margin: -4px 0 0 -4px;
  background: var(--accent);
  border: 0;
  border-radius: 1px;
  transform: rotate(45deg);
  opacity: 1;
}
.ver-tl-sep-t {
  align-self: center;
  padding: 7px 17px 7px 8px;
  font-size: 11.5px;
  letter-spacing: .12em;
  color: var(--dim-2);
}

@media (max-width: 640px) {
  .brand-ver { font-size: 11.5px; padding: 2px 7px; }
  .ver-tl-main { padding-right: 12px; }
  .ver-tl-v { min-width: 48px; font-size: 11.5px; }
  .ver-tl-t { font-size: 12px; }
}

/* 顶栏变窄时收起「持续开发状态 + 最近更新框」（1920 设计稿下完整显示） */
@media (max-width: 1200px) {
  .brand-status { display: none; }
}

/* ===== section 30：DNS 解析检测 + IP 识别（2026-10-12 老板）——
   「全局资源 · 云资源探测」里新增两块：DNS 结果 chips 复用 .tag，
   这里只补输入框、IP 识别结果条与只读隐藏 ===== */
.cp-inp {
  font-family: var(--font-mono);
  font-size: 11.5px;
  color: var(--text);
  background: var(--surface-2);
  border: 1px solid var(--line, rgba(148, 163, 184, .35));
  border-radius: 7px;
  padding: 3px 8px;
  width: 172px;
  outline: none;
}
.cp-inp:focus { border-color: var(--accent); box-shadow: var(--glow, none); }
.cp-inp::placeholder { color: var(--dim-2); }

.cp-ip-result {
  margin-top: 8px;
  padding: 7px 11px;
  border-radius: 8px;
  font-size: 12.5px;
  line-height: 1.55;
  color: var(--dim);
  background: var(--surface-2);
  border: 1px solid var(--line, rgba(148, 163, 184, .35));
  word-break: break-all;
}
.cp-ip-result b { color: var(--text); font-family: var(--font-mono); letter-spacing: .02em; }
.cp-ip-result.is-pub { border-color: rgba(52, 211, 153, .5); }
.cp-ip-result.is-priv { border-color: rgba(122, 168, 255, .5); }
.cp-ip-result.is-err { border-color: rgba(217, 119, 6, .55); color: var(--warn, #d97706); }
.cp-src { display: block; margin-top: 3px; font-size: 11.5px; color: var(--dim-2); }

/* 公网只读视图：DNS 检测与 IP 识别的写入口一并摘掉（后端同样 403 兜底） */
[data-readonly="1"] #cp-dns-run,
[data-readonly="1"] #cp-ip-run { display: none !important; }
/* F13（2026-10-16 审计）：只读视图禁用 agent 输入框（否则打字全 403、一片红色报错） */
[data-readonly="1"] #agent-input,
[data-readonly="1"] #agent-send { opacity: .55; cursor: not-allowed; }

/* ===== section 31：公网来源归属地（2026-10-12 老板："公网 IP 来访问的直接识别出来"）——
   03 安全监控「公网入口」表格新增归属列 + 首页小表 IP 下小字；后端 core/pubgate.py
   为每条来源 IP 附 iplook.brief_geo（只读缓存、未命中后台补，不阻塞轮询） ===== */
.acc-geo {
  font-size: 11.5px;
  color: var(--dim-2);
  line-height: 1.35;
}

/* ===== section 32：可疑来源受限视图 + 访问留言（2026-10-12 老板批复）=====
   三态（允许/可疑/拒绝）：可疑来源登录后只能看主页 —— 顶部横幅 + 拦截警告 +
   留言出口；老板侧 03 详情「访问留言」处理三选。样式与既有 acc-* 体系配套。 */
.rs-banner {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 1200;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  padding: 9px 16px;
  font-size: 14px;
  color: #7c2d12;
  background: linear-gradient(90deg, #fef3c7, #fde68a, #fef3c7);
  border-bottom: 1px solid rgba(180, 83, 9, .45);
  box-shadow: 0 2px 14px rgba(180, 83, 9, .18);
}
[data-theme="dark"] .rs-banner {
  color: #fde68a;
  background: linear-gradient(90deg, rgba(120, 53, 15, .92), rgba(146, 64, 14, .92));
  border-bottom-color: rgba(251, 191, 36, .5);
}
/* 关键：自定义 display 会盖掉 [hidden] 的 UA 规则 —— 必须显式配一条，
   否则横幅 hidden=true 也永远显示（2026-10-12 实测踩坑） */
.rs-banner[hidden] { display: none; }
.rs-banner .rs-ico { font-size: 16px; }
.rs-banner .rs-note-btn { border-color: currentColor; color: inherit; }
[data-restricted="1"] body { padding-top: 48px; }
[data-restricted="1"] .btn { opacity: .55; cursor: not-allowed; }
[data-restricted="1"] .rs-banner .btn,
[data-restricted="1"] #m-rs-note .btn,
[data-restricted="1"] #m-rs-warn .btn { opacity: 1; cursor: pointer; }
.rs-warn-text { margin: 14px 0 6px; font-size: 15.5px; font-weight: 600; color: var(--text); }
.rs-warn-sub { margin: 0 0 4px; font-size: 12px; color: var(--dim-2); }

/* 访问留言（老板侧） */
.acc-note-row {
  padding: 9px 10px;
  margin: 6px 0;
  border: 1px solid var(--line, rgba(148, 163, 184, .35));
  border-radius: 9px;
  background: var(--surface-2);
}
.acc-note-head { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; }
.acc-note-text { margin: 6px 0 7px; font-size: 13px; color: var(--text); white-space: pre-wrap; }
.acc-note-acts { display: flex; gap: 6px; flex-wrap: wrap; }

/* 最近事件：全量请求下的判定标色（违规/可疑行左侧色条） */
.acc-lan-row.is-ev-bad { border-left: 3px solid rgba(220, 38, 38, .75); padding-left: 7px; }
.acc-lan-row.is-ev-warn { border-left: 3px solid rgba(217, 119, 6, .7); padding-left: 7px; }
.acc-lan-row.is-ev-susp { border-left: 3px solid rgba(250, 204, 21, .8); padding-left: 7px; }

/* 「全部请求」视图里的轮询/静态行：弱化显示，别跟动作抢眼（2026-10-13） */
.acc-lan-row.is-ev-poll { opacity: .62; }
.acc-ev-all {
  display: inline-flex; align-items: center; gap: 4px;
  margin-left: 10px; font-size: 12px; color: var(--dim-2); cursor: pointer;
  user-select: none; white-space: nowrap;
}
.acc-ev-all input { vertical-align: -1px; cursor: pointer; }

/* ===== section 33：agent 对话气泡（2026-10-12 老板："做的更像主流大模型对话"）=====
   原先是终端行式；这里把 #agent-log 改成聊天气泡流：老板的话靠右（主色气泡），
   agent 回复靠左（浅底气泡），指标行/系统提示做无框小字。四组合皮肤通用。 */
#agent-log {
  display: flex;
  flex-direction: column;
  gap: 7px;
  align-items: flex-start;
  max-height: 320px;
  padding: 12px;
}
#agent-log .al-row {
  width: auto;
  max-width: 88%;
  padding: 7px 12px;
  border-radius: 13px 13px 13px 4px;
  background: var(--surface);
  border: 1px solid var(--line);
  box-shadow: 0 1px 2px rgba(15, 23, 42, .05);
}
#agent-log .al-you {
  align-self: flex-end;
  background: var(--accent);
  border-color: transparent;
  color: #fff;
  border-radius: 13px 13px 4px 13px;
}
#agent-log [data-audit] {
  border: 1px dashed var(--line);
  background: var(--surface-2);
  padding: 7px 11px;
  border-radius: 10px;
  max-width: 100%;
}

/* ===== section 30b：域名访问提示条（2026-10-13 老板：顶层标题栏下、提示语功能之间）=====
   三态由 app.js 控制内容：宽限期倒计时 / 已到期（IP 已跳域名）/ 未启用整体隐藏。 */
.dom-banner {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 6px 14px;
  margin: 10px 0 4px;
  padding: 9px 16px;
  font-size: 13.5px;
  line-height: 1.5;
  color: #0c4a6e;
  background: linear-gradient(90deg, rgba(224, 242, 254, .96),
              rgba(219, 234, 254, .96), rgba(224, 242, 254, .96));
  border: 1px solid rgba(56, 189, 248, .55);
  border-radius: 10px;
  box-shadow: 0 2px 10px rgba(56, 189, 248, .16);
}
/* 自定义 display 会盖掉 [hidden] 的 UA 规则 —— 必须显式配一条（rs-banner 踩过） */
.dom-banner[hidden] { display: none; }
.dom-banner b { font-weight: 700; letter-spacing: .02em; }
.dom-banner .db-url {
  font-family: Consolas, "Courier New", monospace;
  font-weight: 700;
  color: #0369a1;
  text-decoration: underline;
  text-underline-offset: 3px;
}
.dom-banner .db-url:hover { color: #075985; }
.dom-banner .db-note { color: #0369a1; opacity: .88; }
[data-theme="dark"] .dom-banner {
  color: #bae6fd;
  background: linear-gradient(90deg, rgba(12, 74, 110, .92),
              rgba(30, 64, 175, .72), rgba(12, 74, 110, .92));
  border-color: rgba(56, 189, 248, .5);
  box-shadow: 0 2px 12px rgba(56, 189, 248, .22);
}
[data-theme="dark"] .dom-banner .db-url { color: #7dd3fc; }
[data-theme="dark"] .dom-banner .db-url:hover { color: #a5f3fc; }
[data-theme="dark"] .dom-banner .db-note { color: #bae6fd; }

/* ============ 记忆弹层 · 底部语库轮播（2026-10-14 扩池） ============ */
.mem-tip {
  padding: 7px 16px 9px;
  text-align: center;
  min-height: 1.4em;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--dim-2);
  border-bottom: 1px solid var(--line);
  transition: opacity .4s ease;
  user-select: none;
}
.mem-tip.fade { opacity: 0; }

/* ============ 专注模式 · 戴森球场景发射计数板（2026-10-14 老板：右侧计数板） ============
   绝对定位到画面右侧中部：恒星居中偏左、右侧空旷，计数板落右侧既符合"右侧"要求，
   又不遮挡中央的恒星与星轨；顶栏/计时数字都在上方，三者分处不同区域互不打架。 */
.focus-dyson {
  position: absolute;
  right: 26px;
  top: 50%;
  transform: translateY(-50%);
  margin-top: 34px;   /* 避让顶部 HUD（暂停/退出按钮行），否则首行被裁 */
  z-index: 8;
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 10px 15px 11px;
  min-width: 186px;
  background: rgba(10, 14, 28, .78);
  border: 1px solid rgba(140, 158, 255, .34);
  border-radius: 11px;
  backdrop-filter: blur(7px);
  box-shadow: 0 6px 26px rgba(0, 0, 0, .45);
  text-shadow: 0 1px 6px rgba(0, 0, 0, .8);
}
.focus-dyson[hidden] { display: none; }
.focus-dyson .fd-head {
  font-size: 11.5px;
  letter-spacing: .14em;
  color: rgba(198, 210, 255, .62);
  padding-bottom: 3px;
  border-bottom: 1px solid rgba(140, 158, 255, .2);
}
.focus-dyson .fd-row {
  display: flex;
  align-items: baseline;
  gap: 6px;
  font-size: 12px;
  color: #b9c4e6;
}
.focus-dyson .fd-k { min-width: 52px; color: rgba(185, 196, 230, .8); }
.focus-dyson .fd-v {
  font-family: Consolas, "Courier New", monospace;
  font-size: 15px;
  font-weight: 600;
  color: #ffe6b0;
  text-shadow: 0 0 10px rgba(255, 200, 110, .45);
  margin-left: auto;
  text-align: right;
}
.focus-dyson .fd-u { font-size: 11.5px; color: rgba(185, 196, 230, .6); min-width: 34px; }
.focus-dyson .fd-foot {
  margin-top: 3px;
  padding-top: 4px;
  border-top: 1px solid rgba(140, 158, 255, .2);
  font-size: 11.5px;
  line-height: 1.5;
  color: rgba(170, 184, 224, .62);
}
/* 窄屏：右侧改到底部居中偏上，避免压住画面主体 */
@media (max-width: 860px) {
  .focus-dyson {
    right: 50%;
    top: auto;
    bottom: 78px;
    transform: translateX(50%);
    min-width: 0;
  }
}

/* ===== section 34：可用性探测（3.2 · 2026-10-17）=====
   Statuspage 形态：总览横幅 → 组件行（胶囊 + uptime% + 90 天逐日条）→ 事件时间线。
   三态 + 未知四色；未知（灰）绝不显示成"正常"。 */
.up-banner {
  display: flex; align-items: center; gap: 10px;
  padding: 11px 14px; margin-bottom: 12px;
  border: 1px solid var(--line); border-radius: 11px;
  background: var(--surface-2);
}
.up-banner-dot { width: 10px; height: 10px; border-radius: 50%; flex: none; background: var(--dim-2); }
.up-banner[data-state="up"] .up-banner-dot { background: var(--ok); box-shadow: 0 0 8px var(--ok); }
.up-banner[data-state="degraded"] .up-banner-dot { background: var(--warn, #d97706); box-shadow: 0 0 8px var(--warn, #d97706); }
.up-banner[data-state="down"] .up-banner-dot { background: var(--danger); box-shadow: 0 0 8px var(--danger); }
.up-banner b { font-size: 14px; }
.up-banner-meta { font-size: 11.5px; color: var(--dim-2); margin-left: auto; }

/* 2026-10-20 老板：「可用性探测那边也改成竖着显示」→ 和 DNS 检测同一套竖排卡片：
   卡内自上而下 = 组件名 → 状态胶囊/可用率 → 逐日采样条 → 采样数；多列网格铺开。 */
.up-rows { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
.up-row {
  display: flex; flex-direction: column; gap: 6px;
  padding: 9px 11px; border: 1px solid var(--line); border-radius: 10px;
  background: var(--surface-2); min-width: 0;
}
.up-name { font-size: 10.5px; font-weight: 600; letter-spacing: .08em; text-transform: uppercase;
  color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.up-head { display: flex; align-items: center; gap: 8px; }
.up-pill {
  font-size: 11.5px; text-align: center; padding: 2px 8px; border-radius: 999px;
  border: 1px solid var(--line-strong); color: var(--dim); flex: 0 0 auto;
}
.up-pill.is-up { color: var(--ok); border-color: color-mix(in srgb, var(--ok) 55%, transparent); }
.up-pill.is-degraded { color: var(--warn, #d97706); border-color: color-mix(in srgb, var(--warn, #d97706) 55%, transparent); }
.up-pill.is-down { color: var(--danger); border-color: color-mix(in srgb, var(--danger) 55%, transparent); }
.up-pill.is-unknown { color: var(--dim-2); }
.up-pct { font-size: 12.5px; font-family: var(--font-mono); text-align: right; color: var(--text);
  margin-left: auto; white-space: nowrap; }
/* 2026-10-20 老板：「可用性显示怎么那么大的色块，搞成跟 dns 一样」→ 细竖条平铺，不拉伸填满 */
.up-bars { display: flex; gap: 2px; align-items: center; overflow: hidden; min-width: 0; }
.up-bar { width: 6px; height: 12px; border-radius: 2px; flex: 0 0 auto; background: var(--line-strong); }
.up-bar.is-up { background: var(--ok); }
.up-bar.is-degraded { background: var(--warn, #d97706); }
.up-bar.is-down { background: var(--danger); }
.up-bar.is-unknown { background: var(--line-strong); opacity: .45; }
.up-samples { font-size: 11px; color: var(--dim-2); text-align: right; }

.up-events { margin-top: 14px; }
.up-events-head { display: flex; align-items: baseline; gap: 8px; margin-bottom: 6px; }
.up-events-head b { font-size: 13px; }
.up-events-list { display: flex; flex-direction: column; gap: 5px; max-height: 190px; overflow-y: auto; }
.up-ev { display: flex; gap: 10px; font-size: 12px; align-items: baseline; }
.up-ev-ts { color: var(--dim-2); font-family: var(--font-mono); font-size: 11.5px; flex: none; }
.up-ev-name { color: var(--text); min-width: 130px; }
.up-ev-flow b.is-up { color: var(--ok); }
.up-ev-flow b.is-degraded { color: var(--warn, #d97706); }
.up-ev-flow b.is-down { color: var(--danger); }
.up-ev-flow b.is-unknown { color: var(--dim-2); }
.up-hint { font-size: 11.5px; color: var(--dim-2); }
.up-empty { font-size: 12.5px; color: var(--dim-2); padding: 6px 0; }
/* 2026-10-21：订阅 API 明细（与组件行同款竖排卡片；说明单行截断，悬停看全文） */
.up-apis { margin-top: 14px; }
.up-apis .up-samples { text-align: left; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
[data-readonly="1"] #sec-uptime .up-events { display: none; }

@media (max-width: 980px) { .up-rows { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 640px) { .up-rows { grid-template-columns: 1fr; } }

/* ===== section 35：DNS 矩阵（3.3 · 2026-10-17）=====
   行=解析器（名称+IP）｜时延条｜ms｜TTL｜解析结果｜差异标记。 */

.cp-dns-mx .mx-bar.is-live { background: var(--ok); }
.cp-dns-mx .mx-bar.is-warn { background: var(--warn, #d97706); }
.cp-dns-mx .mx-bar.is-off { background: var(--line-strong); }
@media (max-width: 900px) {
  .cp-dns-mx .mxc { grid-template-columns: 118px 1fr 46px; }
}

/* 3.3 NTP 来源表加 reach/jitter 两列（ntpq -p 风格 · 2026-10-17） */
.ns-reach, .ns-jit { font-family: var(--font-mono); text-align: right; color: var(--dim); font-size: 11.5px; }
.ns-act { display: flex; justify-content: flex-end; }
.ns-head-row { background: none; border-color: transparent; padding: 0 8px; color: var(--dim-2); font-size: 11.5px; }
.ns-head-row .ns-off, .ns-head-row .ns-delay, .ns-head-row .ns-reach,
.ns-head-row .ns-jit, .ns-head-row .ns-st { color: var(--dim-2); }
@media (max-width: 900px) {
  .ns-row { grid-template-columns: minmax(0, 1fr) 66px 56px 40px auto; }
  .ns-jit, .ns-head-row .ns-jit { display: none; }
}

/* ===== section 36：星图拓扑弹层（3.5 · 2026-10-17）===== */
.modal-topo { width: min(1000px, 92vw); }
#topo-canvas { display: block; width: 100%; height: min(58vh, 560px); border-radius: 10px;
  background: radial-gradient(ellipse at 50% 45%, #0b1424 0%, #070b14 70%, #05080f 100%);
  border: 1px solid var(--line); }
[data-skin="legacy"] #topo-canvas { background: #0e1219; }

/* ===== section 37：下载通道弹层（D4 · 2026-10-17）===== */
.dl-lines { display: flex; flex-direction: column; gap: 9px; margin-top: 10px; }
.dl-line { border: 1px solid var(--line); border-radius: 10px; padding: 9px 11px; background: var(--surface-2); }
.dl-head { display: flex; align-items: center; gap: 8px; margin-bottom: 5px; }
.dl-badge { font-size: 11.5px; padding: 1px 8px; border-radius: 999px; border: 1px solid var(--line-strong); }
.dl-badge.is-ok { color: var(--ok); border-color: color-mix(in srgb, var(--ok) 55%, transparent); }
.dl-badge.is-bad { color: var(--danger); border-color: color-mix(in srgb, var(--danger) 55%, transparent); }
.dl-url { display: block; font-family: var(--font-mono); font-size: 11.5px; color: var(--dim);
  word-break: break-all; margin-bottom: 7px; }
.dl-acts { display: flex; gap: 7px; }

/* ===== section 38：多机同步卡片（V2-11 · 2026-10-17）===== */
/* 平台级状态卡片：不属任何一条纳管条目。2026-10-20 搬进顶栏「同步」弹层 */
.sync-card { grid-column: 1 / -1; }
.modal-sync #sync-modal-body { max-height: 74vh; }
.modal-sync .sync-card { border: 0; background: transparent; box-shadow: none; padding: 0; }
.modal-sync .card-head { flex-wrap: wrap; row-gap: 8px; }
.sync-folders { margin-top: 10px; display: flex; flex-direction: column; gap: 6px;
  max-height: 208px; overflow-y: auto; }   /* 2026-10-20：folder 多时把首屏服务卡挤下去，限高可滚 */
.sync-folder { display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  border: 1px solid var(--line); border-radius: 9px; padding: 6px 10px; background: var(--surface-2); }
.sync-folder-name { font-weight: 600; font-size: 12.5px; }
.sync-folder-num { margin-left: auto; font-family: var(--font-mono); font-size: 11.5px; color: var(--dim); }
.sync-products { margin-top: 10px; font-size: 12px; color: var(--dim);
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.btn-mini { padding: 2px 8px; font-size: 11.5px; }
.modal-body { max-height: 60vh; overflow: auto; }
.sync-policy-table { width: 100%; border-collapse: collapse; font-size: 12.5px; margin-top: 8px; }
.sync-policy-table th, .sync-policy-table td {
  text-align: left; padding: 6px 8px; border-bottom: 1px solid var(--line); vertical-align: top; }
.sync-policy-table th { color: var(--dim); font-weight: 600; }
.sync-policy-table code { font-family: var(--font-mono); font-size: 11.5px; word-break: break-all; }

/* ===== V2-44②（2026-10-19）：统一的加载中（骨架屏）/ 错误态 / 空态 ===== */
.skel-wrap { display: flex; flex-direction: column; gap: 9px; padding: 6px 0; }
.skel-line {
  height: 12px;
  border-radius: 6px;
  background: linear-gradient(90deg, var(--surface-2) 0%, var(--surface-3) 45%, var(--surface-2) 100%);
  background-size: 220% 100%;
  animation: skel-shine 1.4s ease-in-out infinite;
}
@keyframes skel-shine {
  from { background-position: 120% 0; }
  to { background-position: -20% 0; }
}
/* 低动效 / 系统"减少动画"：骨架屏只留静态底色，不闪 */
[data-deco="lite"] .skel-line, .deco-lite .skel-line { animation: none; }
@media (prefers-reduced-motion: reduce) { .skel-line { animation: none; } }

.errbar {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 9px 12px;
  font-size: 11.5px; color: var(--text);
  background: color-mix(in srgb, var(--danger-ink) 10%, transparent);
  border: 1px solid color-mix(in srgb, var(--danger-ink) 40%, transparent);
  border-radius: var(--r-ctrl);
}
.errbar-ic { color: var(--danger-ink); }
.errbar-msg { flex: 1; min-width: 0; color: var(--dim); }
.emptybox {
  padding: 14px 4px; text-align: center; font-size: 11.5px; color: var(--dim);
  border: 1px dashed var(--line); border-radius: var(--r-ctrl);
}

/* ===== V2-38（2026-10-19）：辅助文字下限 11.5px =====
   审计 U-7：服务页 97 处 <11px 的小字，老板 1440 屏 zoom 0.75 后实际只剩 7.9px，读不动。
   全域把 9.5/10/10.5/11px 一律提到 11.5px（与既有 11.5px 档统一）。 */

/* ===== V2-35②（2026-10-19）：全站键盘焦点环 =====
   深色皮肤原先没有焦点色（浏览器默认 outline 在 tech-max 上近黑，实测看不见）——
   这里统一 2px accent 焦点环；弹层 focus trap / Esc 属行为层，见 V2-44。 */
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* 这几个输入框原先把 :focus 的 outline 压成 none（只留边框变色），键盘焦点要还给它们 */
.cfg-row .cfg-input:focus-visible, .add-row input:focus-visible,
.ac-input textarea:focus-visible, .acc-add .cfg-input:focus-visible,
.set-form input:focus-visible, .login-input:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 1px;
}

/* ===== section 39：主视图标签栏（V2-03/06/07 · 2026-10-17）===== */
/* V2-43④（2026-10-19）：监控页二级锚点条 */
.sub-nav { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 12px; }
.sub-nav .chip-btn { min-height: 30px; }

.topbar-tabs { display: flex; gap: 2px; align-items: center; padding: 2px;
  border-radius: 999px; border: 1px solid var(--line);
  background: color-mix(in srgb, var(--surface-2) 85%, transparent); }
.tab-btn { appearance: none; border: 0; background: transparent; color: var(--dim);
  font: inherit; font-size: 13.5px; line-height: 1; padding: 8px 12px; border-radius: 999px;
  min-height: 40px; display: inline-flex; align-items: center;     /* V2-35⑥⑨：桌面 22px→40px、字号 12.5→13.5 */
  cursor: pointer; white-space: nowrap; transition: color var(--t-fast), background var(--t-fast); }
.tab-btn:hover { color: var(--text); }
.tab-btn.is-active { color: var(--text);
  background: color-mix(in srgb, var(--accent) 20%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 45%, transparent); }

/* 标签切换靠 hidden 控制显隐；.enter 自带 display，必须显式压掉，否则 hidden 失效
   （本项目第 4 次踩「[hidden] 被 display 压过」，前面已修过 rs-banner/dom-banner 等） */
[data-tab][hidden] { display: none !important; }

/* 窄屏：标签栏与专注并排时空间紧张，缩小内边距 */
@media (max-width: 1400px) {
  .tab-btn { padding: 7px 9px; font-size: 12.5px; }
  .topbar-tabs { gap: 0; }
}

/* ===== section 40：审计四分类（V2-07 · 2026-10-17）===== */
.audit-panel { margin-top: 12px; padding: 10px 16px 8px; }
.audit-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 8px; }
.audit-head b { font-size: 13px; }
.audit-tabs { display: flex; gap: 2px; padding: 2px; border-radius: 999px;
  border: 1px solid var(--line); background: color-mix(in srgb, var(--surface-2) 85%, transparent); }
.audit-list { max-height: 320px; overflow: auto; font-family: var(--font-mono); font-size: 11.5px; }
.audit-row { display: grid; grid-template-columns: 132px 150px minmax(90px, 170px) 1fr;
  gap: 8px; padding: 4px 6px; border-bottom: 1px solid var(--line); align-items: baseline; }
.audit-row.is-bad { color: var(--danger); }
.audit-row.is-local { opacity: .55; }   /* 本机回环轮询：降权，别淹没真实外部访问 */
.audit-ts { color: var(--dim); }
.audit-kind, .audit-target, .audit-detail {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.audit-kind { color: var(--text); }
.audit-target, .audit-detail { color: var(--dim); }
.audit-empty { color: var(--dim); padding: 10px 6px; }
@media (max-width: 1100px) {
  .audit-row { grid-template-columns: 118px 1fr; }
  .audit-target, .audit-detail { display: none; }
}

/* ===== section 41：系统配置总览（V2-10 骨架 · 2026-10-17）===== */
.cfg-group { margin-bottom: 14px; }
.cfg-group-title { font-size: 12.5px; font-weight: 700; color: var(--dim);
  padding: 4px 0 6px; border-bottom: 1px solid var(--line-strong); margin-bottom: 4px; }
.cfg-row { display: grid; grid-template-columns: 150px minmax(120px, 1.2fr) minmax(110px, 1fr) 150px;
  gap: 10px; padding: 5px 4px; border-bottom: 1px dashed var(--line);
  font-size: 12.5px; align-items: baseline; }
.cfg-row.is-risk .cfg-label { color: var(--danger); }
.cfg-label { font-weight: 600; }
.cfg-label .tag { margin-left: 6px; font-size: 11.5px; }
.cfg-value { color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cfg-edit { color: var(--dim); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cfg-file { color: var(--dim); font-family: var(--font-mono); font-size: 11.5px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@media (max-width: 1100px) {
  .cfg-row { grid-template-columns: 130px 1fr; }
  .cfg-edit, .cfg-file { display: none; }
}
/* V2-36（2026-10-19）：可写项渲染成真控件 —— 数字 / 文本 / 下拉 / 勾选 / 密码 */
.cfg-row.is-writable { padding: 3px 4px; }
.cfg-ctl { display: inline-flex; align-items: center; gap: 6px; min-width: 0; }
.cfg-ctl input[type="checkbox"] { width: 15px; height: 15px; accent-color: var(--accent); cursor: pointer; }
.cfg-row .cfg-input {
  width: 100%; min-width: 0; box-sizing: border-box;
  padding: 3px 7px; font-family: var(--font-mono); font-size: 12px;
  color: var(--text); background: var(--surface-2);
  border: 1px solid var(--line-strong); border-radius: 6px;
}
.cfg-row .cfg-input:focus { outline: none; border-color: var(--accent); }
.cfg-row .cfg-input:invalid { border-color: var(--danger); }
.cfg-row select.cfg-input { font-family: inherit; cursor: pointer; }
.cfg-ctl .btn-mini { flex: 0 0 auto; }

/* ===== section 42：AI 用量（V2-13 · 2026-10-17 → 2026-10-20 ZCode 用量版式）=====
   老板："AI 用量那一块，做成 ZCode 这边的使用统计的样式"——
   顶部一排 KPI、两张并列图表（近 14 天双柱 / 今日 24 小时）、两个排行、token 分布表。 */
.aiu-panel { padding: 12px 16px 14px; }
.aiu-head { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; margin-bottom: 10px; }
.aiu-title { font-size: 13.5px; }
.aiu-kpis {
  display: grid; gap: 10px; margin-bottom: 12px;
  grid-template-columns: repeat(auto-fit, minmax(148px, 1fr));
}
.aiu-kpi { border: 1px solid var(--line); border-radius: 10px; padding: 8px 12px; background: var(--surface-2); }
.aiu-kl { font-size: 11.5px; color: var(--dim); }
.aiu-km { font-size: 21px; font-weight: 700; margin: 2px 0; font-variant-numeric: tabular-nums; }
.aiu-ks { font-size: 11px; color: var(--dim); line-height: 1.5; }
.aiu-unit { font-size: 11.5px; color: var(--dim); margin-left: 3px; font-weight: 400; }
.aiu-grid { display: grid; grid-template-columns: 1.35fr 1fr; gap: 12px; margin-bottom: 12px; }
.aiu-card { border: 1px solid var(--line); border-radius: 10px; padding: 10px 12px 8px; background: var(--surface-2); min-width: 0; }
.aiu-ct { font-size: 12px; color: var(--dim); margin-bottom: 6px; }
.aiu-legend { display: flex; align-items: center; gap: 6px; font-size: 11px; color: var(--dim); margin-top: 4px; }
.aiu-dot { width: 8px; height: 8px; border-radius: 2px; display: inline-block; margin-left: 6px; }
.aiu-dot.is-model, .aiu-pair i.is-model { background: var(--accent); }
.aiu-dot.is-tool, .aiu-pair i.is-tool { background: color-mix(in srgb, var(--accent) 38%, transparent); }
.aiu-dot:first-child { margin-left: 0; }
.aiu-bars { display: flex; align-items: flex-end; gap: 4px; height: 92px; }
.aiu-bcol { flex: 1; display: flex; flex-direction: column; justify-content: flex-end;
  align-items: center; gap: 3px; min-width: 0; }
.aiu-pair { display: flex; align-items: flex-end; justify-content: center; gap: 2px; width: 100%; }
.aiu-pair i { display: block; width: 44%; max-width: 9px; border-radius: 2px 2px 0 0; min-height: 0; }
.aiu-bcol em { font-size: 10px; color: var(--dim); font-style: normal; white-space: nowrap;
  transform: scale(.92); }
.aiu-chart.is-hours { height: 92px; }
.aiu-hbars { display: flex; align-items: flex-end; gap: 1px; height: 100%; }
.aiu-hcol { flex: 1; display: flex; flex-direction: column; justify-content: flex-end;
  align-items: center; gap: 3px; min-width: 0; }
.aiu-hcol i { display: block; width: 100%; background: color-mix(in srgb, var(--accent) 62%, transparent);
  border-radius: 2px 2px 0 0; }
.aiu-hcol i.is-zero { height: 2px; background: var(--line); }
.aiu-hcol em { font-size: 10px; color: var(--dim); font-style: normal; height: 12px; }
.aiu-list { display: flex; flex-direction: column; gap: 4px; }
.aiu-mrow { display: grid; grid-template-columns: minmax(90px, 46%) 1fr 54px minmax(0, 40%);
  gap: 8px; align-items: center; font-size: 12px; }
.aiu-mname { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.aiu-bar { height: 6px; border-radius: 3px; background: var(--line); overflow: hidden; }
.aiu-bar i { display: block; height: 100%; background: var(--accent); }
.aiu-mnum { text-align: right; color: var(--text); font-family: var(--font-mono); font-size: 11.5px; }
.aiu-msub { color: var(--dim); font-size: 11px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.aiu-sec { font-size: 12px; color: var(--dim); margin: 12px 0 4px; }
@media (max-width: 1100px) { .aiu-grid { grid-template-columns: 1fr; } }
@media (max-width: 640px) {
  .aiu-mrow { grid-template-columns: minmax(70px, 40%) 1fr 46px; }
  .aiu-msub { display: none; }
  .aiu-km { font-size: 19px; }
}

/* ===== section 43：探测面（V2-18 · 2026-10-17）===== */
.probe-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(340px, 1fr)); gap: 12px; grid-auto-flow: dense; }
/* 2026-10-20 UI 巡检：行内值被挤成"一字一行"（未发现 / 2核4GB / 541/3723MB）。
   值元素不参与收缩、不换行；只有末尾备注允许省略。 */
.probe-row > * { flex: 0 0 auto; }
.probe-row .tag, .probe-row b, .probe-row code { white-space: nowrap; }
.probe-row .probe-note { flex: 1 1 auto; min-width: 60px; }
.probe-block { border: 1px solid var(--line); border-radius: 10px; padding: 8px 12px; background: var(--surface-2); }
.probe-sec { font-size: 12px; color: var(--dim); margin-bottom: 6px; }
.probe-row { display: flex; align-items: center; gap: 8px; padding: 3px 0; font-size: 12.5px; }
.probe-name { min-width: 96px; }
/* V2-40（2026-10-19）：探测面按天历史条 */
.probe-days { display: flex; flex-wrap: wrap; gap: 4px; margin: 6px 0 4px; }
.probe-day {
  width: 14px; height: 14px; border-radius: 4px;
  border: 1px solid var(--line-strong);
  background: var(--surface-2);
}
.probe-day.is-ok { background: color-mix(in srgb, var(--ok) 65%, transparent); border-color: var(--ok); }
.probe-day.is-warn { background: color-mix(in srgb, var(--warn) 70%, transparent); border-color: var(--warn); }

.probe-note { color: var(--dim); font-size: 11.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ===== section 44：记忆星图（V2-19 · 2026-10-17 · 老板批复的「星核 + 星座」表达）=====
   画布之上的 DOM 层：星团标签 / 扇形条目 / 面包屑 / KPI。
   层本身 pointer-events:none（滚轮与拖拽落到底下画布），只有卡片与条目行吃点击。
   配色固定为深空金（星团浮在自己的一片夜空上），不跟随皮肤变量。 */
.mem-stage { position: absolute; inset: 0; z-index: 2; pointer-events: none; overflow: hidden; }
.mem-legend { z-index: 3; }                       /* 图例压在星图层之上（旧规则只定了位置） */

.mem-crumbs {
  position: absolute; left: 0; top: 0; max-width: 100%;
  display: flex; align-items: center; gap: 7px; flex-wrap: wrap;
  padding: 9px 14px; font-size: 12px; color: #8d97b8;
}
.mem-crumbs button {
  pointer-events: auto; cursor: pointer;
  background: rgba(10, 14, 28, .62); border: 1px solid rgba(232, 200, 132, .22);
  color: #e8ecf8; border-radius: 999px; padding: 3px 10px; font-size: 12px;
  transition: border-color .15s, color .15s;
}
.mem-crumbs button:hover { border-color: rgba(232, 200, 132, .58); color: #fff3d2; }
.mem-crumbs .crumb-back { padding: 2px 9px; font-size: 14px; line-height: 1; }
.mem-crumbs .crumb em { font-style: normal; color: #b9a271; margin-left: 5px; font-size: 11.5px; }
.mem-crumbs .crumb.is-cur { border-color: rgba(232, 200, 132, .5); color: #fff3d2; }
.mem-crumbs b { color: #e8ecf8; font-weight: 600; }

/* 星团标签卡片：hub 贴着星座朝外；module 在左侧列队（宽度由 .is-hub 区分） */
.mem-cl {
  position: absolute; left: 0; top: 0; width: 152px; box-sizing: border-box;
  display: flex; flex-direction: column; gap: 2px; text-align: left;
  padding: 7px 10px 8px; border-radius: 10px; cursor: pointer; pointer-events: auto;
  background: linear-gradient(180deg, rgba(12, 17, 34, .84), rgba(8, 11, 22, .74));
  border: 1px solid rgba(160, 176, 224, .20);
  box-shadow: 0 4px 18px rgba(0, 0, 0, .35);
  color: #e8ecf8; font-size: 12px;
  transition: border-color .18s, box-shadow .18s;
  will-change: transform, opacity;
}
.mem-cl:hover { border-color: rgba(232, 200, 132, .55); box-shadow: 0 6px 22px rgba(0, 0, 0, .45); }
.mem-cl.is-sel { border-color: rgba(232, 200, 132, .78); box-shadow: 0 0 0 1px rgba(232, 200, 132, .22), 0 8px 26px rgba(0, 0, 0, .5); }
.mem-cl .mc-top { display: flex; align-items: center; gap: 6px; }
.mem-cl .mc-dot { width: 7px; height: 7px; border-radius: 50%; flex: none; background: #e8c884; box-shadow: 0 0 8px rgba(232, 200, 132, .85); }
.mem-cl .mc-top b { font-family: var(--font-mono); font-size: 14px; color: #fff3d2; }
.mem-cl .mc-top em { font-style: normal; font-size: 11.5px; color: #b9a271; margin-left: auto; letter-spacing: .4px; }
.mem-cl .mc-name { font-weight: 600; font-size: 12.5px; }
.mem-cl .mc-sub { font-size: 11.5px; color: #8d97b8; }
.mem-cl .mc-meta { font-size: 11.5px; color: #6f7a9a; }
.mem-cl:not(.is-hub) { width: 172px; }
.mem-cl:not(.is-hub) .mc-sub { display: none; }

/* 扇形条目行（选中星团 → 一排，逐条点亮） */
.mem-fan-item {
  position: absolute; left: 0; top: 0; width: 300px; box-sizing: border-box;
  display: flex; flex-direction: column; gap: 1px; text-align: left;
  padding: 5px 10px 6px; border-radius: 9px; cursor: pointer; pointer-events: auto;
  background: rgba(10, 14, 28, .74); border: 1px solid rgba(160, 176, 224, .16);
  color: #e8ecf8; will-change: transform, opacity;
  transition: border-color .15s, background .15s;
}
.mem-fan-item:hover { border-color: rgba(232, 200, 132, .5); background: rgba(16, 22, 42, .86); }
.mem-fan-item.is-sel { border-color: rgba(232, 200, 132, .82); background: rgba(24, 28, 48, .9); }
.mem-fan-item .fi-title { font-size: 12.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mem-fan-item .fi-meta { font-size: 11.5px; color: #8d97b8; }
.mem-fan-item.is-more {
  align-items: center; justify-content: center; font-size: 11.5px;
  color: #b9a271; border-style: dashed; background: rgba(10, 14, 28, .5);
}

/* 右上 KPI（hub） */
.mem-kpis {
  position: absolute; right: 14px; top: 12px; display: flex; gap: 6px;
  padding: 7px 12px; border-radius: 10px; color: #e8ecf8;
  background: rgba(10, 14, 28, .55); border: 1px solid rgba(160, 176, 224, .16);
}
.mem-kpi { display: flex; flex-direction: column; align-items: center; min-width: 42px; }
.mem-kpi span { font-size: 11.5px; color: #8d97b8; }
.mem-kpi b { font-size: 14px; color: #fff3d2; }

/* 侧栏「关联」块（出向 / 入向 / 共标签） */
.mem-rel { margin-top: 10px; }
.mem-rel-t { display: block; font-size: 11.5px; color: var(--dim); margin-bottom: 4px; }
.mem-rel-t i { font-style: normal; color: var(--accent); }
.mem-rel-list { display: flex; flex-wrap: wrap; gap: 4px; }
.mem-rel-list .mem-item { padding: 3px 8px; font-size: 11.5px; border-radius: 6px; }

/* 标签筛选条（V2-44① · 2026-10-19）：默认 Top10 + 搜索框，不让 35 个标签铺满三行 */
.mem-tags { max-height: 96px; overflow-y: auto; overflow-x: hidden; }
.mem-tag-search {
  flex: 0 0 150px;
  min-height: 26px;
  padding: 3px 9px;
  font: inherit;
  font-size: 11.5px;
  color: var(--text);
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: 999px;
}
.mem-tag-search:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.mem-tag-chips { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.mem-tag-more { border-style: dashed; }

/* ===== section 43：Agent 中心（V2-08 重写 · 2026-10-19）=====
   左窄栏会话列表 + 右侧消息流；输入区贴底。高度用 min() 兜住窄屏，不给整页撑出滚动条。 */
.ac-wrap { display: grid; grid-template-columns: 236px 1fr; gap: 14px;
  height: min(70vh, 720px); min-height: 420px; }
.ac-side { display: flex; flex-direction: column; gap: 8px; min-height: 0; }
.ac-list { flex: 1; min-height: 0; overflow-y: auto; border: 1px solid var(--line);
  border-radius: 10px; background: var(--surface-2); padding: 6px; }
.ac-side-empty { color: var(--dim); font-size: 12px; padding: 10px 8px; line-height: 1.7; }
.ac-item { border-radius: 8px; padding: 7px 8px; cursor: pointer; border: 1px solid transparent; }
.ac-item:hover { background: var(--surface); }
.ac-item.on { border-color: var(--accent); background: var(--surface); }
.ac-item-top { display: flex; align-items: center; gap: 6px; }
.ac-item-title { flex: 1; font-size: 12.5px; font-weight: 600; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
/* 2026-10-20：原来悬停才显（opacity:0→1），触屏根本看不到，而老板反馈"点了没反应"；
   改成常显，悬停时提亮。 */
.ac-item-act { display: flex; gap: 2px; opacity: .55; transition: opacity .15s; }
.ac-item:hover .ac-item-act, .ac-item.on .ac-item-act { opacity: 1; }
.ac-x { border: 0; background: transparent; color: var(--dim); cursor: pointer;
  font-size: 12px; padding: 0 3px; line-height: 1.4; }
.ac-x:hover { color: var(--accent); }
.ac-item-sub { color: var(--dim); font-size: 11.5px; margin-top: 2px; }
.ac-item-prev { color: var(--dim); font-size: 11.5px; margin-top: 3px; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
.ac-main { display: flex; flex-direction: column; min-height: 0; }
.ac-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 0 2px 8px; border-bottom: 1px solid var(--line); }
.ac-title { flex: 1; font-weight: 700; font-size: 13.5px; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
.ac-head-right { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.ac-pool-note { font-size: 11.5px; color: var(--warn, #b8860b); padding: 6px 2px;
  line-height: 1.7; }
/* 消息流容器：**必须用 #agent-log 选择器**——旧气泡样式（section 36）用的是
   `#agent-log .al-row` 这类 ID 选择器，优先级高于 .ac-log，不这么写会被它压住
   （实测：用户气泡贴左边、整片被限高 320px）。 */
#agent-log { flex: 1; min-height: 0; max-height: none; overflow-y: auto;
  padding: 12px 4px 4px; display: flex; flex-direction: column; gap: 12px;
  align-items: flex-start; }
.ac-foot { display: flex; align-items: center; gap: 10px; padding-top: 6px;
  color: var(--dim); font-size: 11.5px; }
.ac-foot-hint { margin-left: auto; }
/* 消息行：沿用 .al-row 类名（旧样式与旧验收脚本都按它找行）。
   行本身**不再当气泡**（旧样式的行既是容器又是气泡），这里把它重置成容器，
   气泡交给里面的 .ac-bub —— 否则会出现"双层边框 + 头像被塞进气泡"。 */
#agent-log .al-row { display: flex; gap: 10px; width: auto; max-width: 100%;
  padding: 0; border: 0; border-radius: 0; background: transparent; box-shadow: none; }
.ac-ava { flex: 0 0 28px; width: 28px; height: 28px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center; font-size: 11.5px;
  background: var(--surface-2); border: 1px solid var(--line-strong); color: var(--dim); }
.ac-bub { max-width: min(760px, 82%); background: var(--surface-2);
  border: 1px solid var(--line); border-radius: 10px; padding: 8px 11px; min-width: 0; }
.ac-who { font-size: 11.5px; color: var(--dim); margin-bottom: 4px; display: flex; gap: 8px; }
.ac-ts { margin-left: auto; font-family: var(--font-mono); }
.ac-body { font-size: 12.8px; line-height: 1.75; word-break: break-word; }
.ac-body .ac-p { margin: 3px 0; }
.ac-body .ac-h1, .ac-body .ac-h2, .ac-body .ac-h3, .ac-body .ac-h4 {
  font-weight: 700; margin: 8px 0 4px; }
.ac-body .ac-h1 { font-size: 15px; }
.ac-body .ac-h2 { font-size: 14px; }
.ac-body .ac-li { margin: 2px 0 2px 4px; }
.ac-body .ac-quote { border-left: 3px solid var(--line-strong); padding-left: 8px;
  color: var(--dim); margin: 4px 0; }
.ac-body .ac-ic { font-family: var(--font-mono); font-size: .94em; padding: 1px 5px;
  border-radius: 4px; background: var(--surface); border: 1px solid var(--line); }
.ac-code { margin: 6px 0; border: 1px solid var(--line-strong); border-radius: 8px;
  overflow: hidden; background: var(--surface); }
.ac-code-head { display: flex; align-items: center; gap: 8px; padding: 4px 8px;
  border-bottom: 1px solid var(--line); color: var(--dim); font-size: 11.5px;
  font-family: var(--font-mono); }
.ac-code-head .btn-mini { margin-left: auto; }
.ac-code pre { margin: 0; padding: 8px 10px; overflow-x: auto; }
.ac-code code { font-family: var(--font-mono); font-size: 12px; line-height: 1.6;
  white-space: pre; }
.ac-kw { color: #c678dd; font-style: normal; }
.ac-str { color: #98c379; font-style: normal; }
.ac-cmt { color: var(--dim); font-style: italic; }
.ac-num { color: #d19a66; font-style: normal; }
.ac-usage { margin-top: 5px; font-size: 11.5px; color: var(--dim);
  font-family: var(--font-mono); }
#agent-log .ac-err .ac-bub { border-color: var(--danger); }
.ac-empty { color: var(--dim); font-size: 12.5px; line-height: 1.9; padding: 10px 4px; }
.ac-empty h4 { color: var(--text); font-size: 13.5px; margin: 0 0 6px; }
.ac-chips { display: flex; flex-wrap: wrap; gap: 6px; margin: 8px 0; }
.ac-chip { border: 1px solid var(--line-strong); background: var(--surface-2);
  color: var(--text); border-radius: 999px; padding: 4px 11px; font-size: 12px; cursor: pointer; }
.ac-chip:hover { border-color: var(--accent); }
.ac-input { display: flex; align-items: flex-end; gap: 8px; padding-top: 8px;
  border-top: 1px solid var(--line); }
.ac-input textarea { flex: 1; resize: none; min-height: 34px; max-height: 160px;
  padding: 7px 10px; font-family: inherit; font-size: 12.8px; line-height: 1.6;
  color: var(--text); background: var(--surface-2); border: 1px solid var(--line-strong);
  border-radius: 8px; }
.ac-input textarea:focus { outline: none; border-color: var(--accent); }
@media (max-width: 900px) {
  .ac-wrap { grid-template-columns: 1fr; height: auto; min-height: 0; }
  .ac-list { max-height: 168px; }
  .ac-log { min-height: 240px; }
}

/* 设置面板：用途徽章 + 免费池预置条（V2-46） */
.set-pool { margin-left: 6px; font-size: 11.5px; padding: 1px 6px; border-radius: 999px;
  background: var(--surface-2); border: 1px solid var(--line-strong); color: var(--dim);
  white-space: nowrap; }
.set-presets { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.set-presets-label { font-size: 11.5px; color: var(--dim); }
.set-presets-hint { font-size: 11.5px; color: var(--dim); margin-left: 4px; }

/* 终端指纹：本机身份行 + 设备 id 小字（V2-24 第二版） */
.device-self { padding: 6px 10px; margin-bottom: 8px; border: 1px solid var(--line);
  border-radius: 8px; background: var(--surface-2); font-size: 12.5px; }
.device-self code { font-family: var(--font-mono); font-size: 12px; }
.dev-id { color: var(--dim); font-family: var(--font-mono); font-size: 11.5px; }
/* 终端指纹表：10 列在 1920 下会被挤成两三行 —— 给个最小宽度 + 横向滚动，别让"访问"这类表头断字 */
#device-list { overflow-x: auto; }
#device-list table { min-width: 1240px; }

/* ===== section 42：窄屏版式修复（2026-10-20 · 决赛前 UI 巡检）=====
   实测 390 宽：安全页表格被压成"一字一行"并撑宽 71px；对话页侧栏 236px 固定列
   把整页撑宽 249px。这里把表格放进可横滚容器、对话在手机上改单列。 */
.table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.acc-live { min-width: 560px; }
.acc-live th, .acc-live td { white-space: nowrap; }

@media (max-width: 720px) {
  /* 1fr 的最小宽度是 auto（min-content），会话列表会把整列撑到 600+ px；
     必须 minmax(0,1fr) + 内部 min-width:0 才能真正收缩。 */
  .ac-wrap { grid-template-columns: minmax(0, 1fr); gap: 10px; }
  .ac-side, .ac-main, .ac-list, .ac-item, .ac-item-top,
  .ac-item-title, .ac-item-sub, .ac-item-prev { min-width: 0; }
  .ac-side { max-height: 172px; }
  .ac-list { max-height: 118px; }
  .acc-live { min-width: 520px; }
}
/* ===== section 43：顶栏特效开关（2026-10-20 · 从监控页搬来）===== */
.btn-deco { display: inline-flex; align-items: center; gap: 6px; }
.btn-deco .deco-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--ok, #22c55e);
  box-shadow: 0 0 6px color-mix(in srgb, var(--ok, #22c55e) 70%, transparent); }
.btn-deco.is-warn { color: var(--warn, #d97706);
  border-color: color-mix(in srgb, var(--warn, #d97706) 55%, transparent); }
.btn-deco.is-warn .deco-dot { background: var(--warn, #d97706);
  box-shadow: 0 0 6px color-mix(in srgb, var(--warn, #d97706) 70%, transparent); }
.btn-deco.is-off { opacity: .62; }
.btn-deco.is-off .deco-dot { background: var(--dim); box-shadow: none; }
/* ===== section 44：顶栏密度（2026-10-20 · 加特效按钮后 1920 下挤到重叠）===== */
.topbar { gap: 10px; padding: 8px 14px; }
.topbar .btn { padding: 6px 10px; }
.topbar .seg .btn { padding: 5px 9px; }
.topbar .tab-btn { padding: 7px 11px; }
@media (max-width: 1500px) {
  .topbar { gap: 8px; padding: 8px 12px; }
  .topbar .btn { padding: 5px 8px; font-size: 12px; }
  .topbar .tab-btn { padding: 6px 9px; }
  /* 窄屏优先保入口、不保装饰：徽章只留版本号（农历/节气/天气按老板要求始终显示） */
  .brand-ver .bv-name { display: none; }
  /* 关键：标签栏原来是 absolute 居中（不占流），加特效按钮后两侧挤到中心就重叠。
     窄屏把它放回 flex 流，宁可不绝对居中，也不能叠在一起。 */
  .topbar-center { position: static; transform: none; margin: 0 auto; }
}
/* 窄屏用缩写，避免顶栏挤到重叠（2026-10-20） */
.lbl-abbr { display: none; }
@media (max-width: 1500px) {
  .lbl-full { display: none; }
  .lbl-abbr { display: inline; }
}

/* ===== 顶栏身份菜单（2026-10-20 老板：「未登录 / 用户名」+ 改密码、退出） =====
   fixed 定位由 JS 算到按钮下方；层级在顶栏之上、模态框之下。 */
.user-menu {
  position: fixed;
  z-index: var(--z-overlay);
  min-width: 176px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 6px;
  background: var(--surface-2);
  border: 1px solid var(--line-strong);
  border-radius: 10px;
  box-shadow: 0 14px 34px rgba(0, 0, 0, .38);
}
.user-menu[hidden] { display: none; }   /* 坑：带 hidden 又设 display 的元素必须补这条 */
.user-menu-head {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 6px 9px 9px;
  margin-bottom: 4px;
  border-bottom: 1px solid var(--line);
}
.user-menu-name {
  font-family: var(--font-mono);
  font-size: 12.5px;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.user-menu-role { font-size: 10.5px; color: var(--dim); }
.user-menu-item {
  appearance: none;
  border: 0;
  background: transparent;
  color: var(--text);
  text-align: left;
  padding: 7px 9px;
  border-radius: 7px;
  font: inherit;
  font-size: 12.5px;
  cursor: pointer;
}
.user-menu-item:hover,
.user-menu-item:focus-visible {
  background: rgba(127, 127, 127, .16);
  outline: none;
}
.user-menu-item[data-um="logout"]:hover { color: var(--warn, var(--text)); }

/* ===== 折叠说明（2026-10-20）：控制台只留结论，口径/原理默认收起 ===== */
.fold { margin: 8px 0 2px; }
.fold > summary {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 11.5px; line-height: 1.7; color: var(--dim-2, var(--dim));
  cursor: pointer; user-select: none; list-style: none;
  padding: 1px 9px; border-radius: 999px;
  border: 1px dashed var(--line-strong, var(--line));
}
.fold > summary::-webkit-details-marker { display: none; }
.fold > summary::before { content: "ⓘ"; font-size: 11px; opacity: .8; }
.fold[open] > summary { color: var(--text); border-style: solid; }
.fold > summary:hover { color: var(--text); border-color: var(--line-strong, var(--line)); }
.fold > .agent-hint { margin: 8px 0 0; }

/* ===== DNS 可用性（2026-10-20 老板：不要平铺，改成 status.deepseek 那种可用性风格；
   同日再改：每个解析器竖排成卡片，并按 2 行 × 3 列铺开——横着排一行只放一个，白占整幅宽度）=====
   卡片内自上而下：名称+IP → 状态标签/延迟 → 可用率 → 解析结果 → 近 40 次历史方块。
   固定 3 列（解析器多于一页时按行往下长，而不是每格被挤窄）；窄屏逐级降到 2 列 / 1 列。 */
.dns-avail { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
.dns-row { display: flex; flex-direction: column; gap: 5px;
  border: 1px solid var(--line); border-radius: 10px; padding: 9px 11px; background: var(--surface-2); min-width: 0; }
.dns-name { display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap;
  font-weight: 600; font-size: 10.5px; letter-spacing: .08em; text-transform: uppercase; color: var(--text); }
.dns-name em { font-style: normal; color: var(--dim); font-size: 11px; font-family: var(--font-mono);
  letter-spacing: 0; text-transform: none; }
/* 状态行：左侧大号可用性标签，右侧可用率 */
.dns-stat { display: flex; align-items: center; gap: 8px; min-width: 0; }
.dns-stat .tag { flex: 0 0 auto; }
.dns-rate { margin-left: auto; color: var(--dim); font-size: 11.5px; font-variant-numeric: tabular-nums;
  white-space: nowrap; }
.dns-ans { color: var(--dim); font-family: var(--font-mono); font-size: 11.5px; line-height: 1.45;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dns-sqs { display: flex; gap: 2px; margin-top: 1px; }
.dns-sq { width: 6px; height: 12px; border-radius: 2px; display: inline-block;
  background: var(--line); border: 0; }
.dns-sq.is-ok { background: color-mix(in srgb, var(--ok) 72%, transparent); }
.dns-sq.is-warn { background: color-mix(in srgb, var(--warn) 78%, transparent); }
.dns-sq.is-bad { background: color-mix(in srgb, var(--danger, #ef4444) 78%, transparent); }
.dns-sq.is-none { background: var(--line-strong); }
.dns-row.is-used { border-color: var(--accent); }
[data-skin="tech-max"] .dns-row.is-used { box-shadow: 0 0 10px rgba(124, 140, 255, .3); }
@media (max-width: 980px) { .dns-avail { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 640px) { .dns-avail { grid-template-columns: 1fr; } }

/* 2026-10-20：磁盘利用率是"占用率"，用满高条显示（与百分比读数同义，曲线表达不了量级）；
   网络吞吐仍是折线（发/收曲线同款）。 */

/* ===== 全局资源六指标网格（2026-10-20 老板：3 列 × 2 行，单格做窄）=====
   原来沿用 .grid（minmax(400px,1fr)）→ 现在独立网格，窄屏自动降列。 */
.g-meters {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 10px 16px;
  margin: 6px 0 4px;
}
.g-meters .meter { margin-bottom: 0; min-width: 0; }
.g-meters .meter-top { font-size: 11px; gap: 8px; }
.g-meters .meter-top span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.g-meters .curve { height: 40px; }        /* 单格变窄 → 曲线也压矮，六格一屏放得下 */

@media (max-width: 760px) { .g-meters { grid-template-columns: 1fr; } }

/* ===== 发布 · 打包与下载（2026-10-20）=====
   弹层内分三块：全部服务打包 / 下载目录 / exe 比对（折叠）。 */
.pack-sec { margin-top: 14px; }
.pack-sec:first-of-type { margin-top: 4px; }
.pack-sec-head {
  display: flex; align-items: center; gap: 10px; margin-bottom: 7px;
}
.pack-sec-head b { font-size: 13px; color: var(--text); letter-spacing: .02em; }
.pack-sec-head b::before {
  content: ""; display: inline-block; width: 3px; height: 12px; margin-right: 7px;
  vertical-align: -1px; border-radius: 2px; background: var(--brand-gradient, linear-gradient(135deg,#7c8cff,#8b7bff));
}
.pack-sec-head .add-hint { margin-left: auto; text-align: right; }
#m-exe .modal-card { width: min(980px, 96vw); }
.pack-sec .acc-table-wrap { max-height: 38vh; }
.pack-sec .acc-table { min-width: 720px; }
.pack-sec .acc-table th:first-child,
.pack-sec .acc-table td:first-child { width: 26%; }
.pack-sec .acc-table td { white-space: nowrap; }
.pack-sec .acc-table td .acc-note { white-space: normal; }
.pack-fold { margin-top: 16px; border-top: 1px dashed var(--line); padding-top: 10px; }
.pack-fold > summary {
  cursor: pointer; font-size: 12.5px; color: var(--dim); list-style: none;
  padding: 4px 0; user-select: none;
}
.pack-fold > summary::-webkit-details-marker { display: none; }
.pack-fold > summary::before { content: "▸ "; }
.pack-fold[open] > summary::before { content: "▾ "; }
.pack-fold > summary:hover { color: var(--text); }
.pack-fold-body { margin-top: 8px; }
.pack-fold .modal-foot { margin-top: 10px; display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }

/* ===== 页脚备案信息（2026-10-23）=====
   放在 <main> 之后，不参与 stage 的布局网格；低对比度、小字号，
   只承担"备案号可见且可点"的合规职责，不抢正文注意力。 */
.legal-foot {
  position: relative;
  z-index: 1;
  padding: 14px 16px 18px;
  text-align: center;
  font-size: 12px;
  color: var(--dim-2);
}
.legal-foot a {
  color: var(--dim-2);
  text-decoration: none;
  border-bottom: 1px dotted transparent;
}
.legal-foot a:hover { color: var(--accent); border-bottom-color: var(--accent); }
.legal-foot .lf-sep { margin: 0 8px; opacity: .5; }

/* ===== 纯背景模式（2026-10-23）=====
   把界面整层隐掉，只留 #scene / #stars / .starfield / .orbits 这些背景装饰。
   用 opacity 而不是 display:none —— 后者会让 stage 的滚动高度瞬间塌陷、
   fixed 背景重排一次，切换时画面会抖。pointer-events 一并断掉，防误点。 */
.bg-toggle {
  position: fixed; right: 18px; bottom: 18px; z-index: 70;
  width: 38px; height: 38px; padding: 0;
  display: grid; place-items: center;
  border-radius: 50%; cursor: pointer;
  color: var(--dim);
  background: var(--surface);
  border: 1px solid var(--line);
  box-shadow: var(--shadow);
  opacity: .45;
  transition: opacity .2s ease, transform .2s ease, color .2s ease, border-color .2s ease;
}
.bg-toggle:hover {
  opacity: 1; transform: translateY(-1px);
  color: var(--accent); border-color: var(--accent);
}
.bg-toggle svg {
  width: 17px; height: 17px;
  stroke: currentColor; fill: none;
  stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round;
}

.topbar, .stage, .legal-foot, .rs-banner, .offline-bar,
.subtitle-bar, .modal, .focus-wrap, .toast {
  transition: opacity .55s ease;
}
/* 界面只是 opacity:0 仍在文档流里（避免切换时布局塌陷抖动），
   所以必须显式锁滚动，否则右侧会留一条滚动条、还能把背景滚走。 */
body.bg-only { overflow: hidden !important; }

body.bg-only .topbar,
body.bg-only .stage,
body.bg-only .legal-foot,
body.bg-only .rs-banner,
body.bg-only .offline-bar,
body.bg-only .subtitle-bar,
body.bg-only .modal,
body.bg-only .focus-wrap,
body.bg-only .toast,
body.bg-only .bg-toggle {
  opacity: 0 !important;
  pointer-events: none !important;
}

/* 退出提示：进来自动出现，3 秒后淡出，不挡观赏 */
.bg-exit-hint {
  position: fixed; left: 50%; bottom: 34px;
  transform: translateX(-50%) translateY(6px);
  z-index: 71; padding: 8px 16px;
  font-size: 12.5px; letter-spacing: .03em; color: var(--dim);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 999px;
  box-shadow: var(--shadow);
  opacity: 0; pointer-events: none;
  transition: opacity .5s ease, transform .5s ease;
}
body.bg-only .bg-exit-hint { opacity: .92; transform: translateX(-50%) translateY(0); }
body.bg-only .bg-exit-hint.is-faded { opacity: 0; }
