/* ==========================================================================
   SoulkindAI · 前端设计系统 v4 —— 一张卡，几栏，一条线

   v4 换掉 v3 的三件事（依据用户给的参考图：多栏收件箱式工作台）：

     结构   四块浮板 + 16px 缝隙 → 一张白大卡，栏与栏之间 1px 发丝线
     色     紫 #6A4BF2 → 绿。而且分工写死：
            **绿只做色块**（选中条、AI 角标、状态胶囊、气泡底），
            **近黑做动作**（主按钮、Rail 选中方块、发送键），
            **字永远是近黑**——绿一旦当文字色，弱视用户就只剩颜色这一重线索
     卡片   「白卡靠阴影浮起」→「1px 线 + 几乎看不见的一层阴影」

   下面这段是 v3 的原始说明，结构性的判断（正圆头像、状态三重表达、
   亮暗两套令牌必须逐字一致）在 v4 里全部继续有效。
   ---------------------------------------------------------------------------
   SoulkindAI · 前端设计系统 v3 —— 浮起面板（Floating Panel）

   v2 是编辑排版：衬线标题 + 苔绿 + 去卡片化的发丝线。
   那一版的观感偏「刊物」，不像 2025 年的产品。v3 换掉三件事：

     字     衬线标题 → 几何无衬线（Inter + 中文系统字），复古感的根源在这
     色     苔绿 #284b40 → 紫 #6A4BF2 + 浅紫画布，主按钮走近黑高对比
     结构   面板从「贴边铺满」变成「在画布上浮起」，内容重新卡片化，
            靠 面/圆角/阴影 分层，而不是靠一堆 1px 灰线

   不改的：类名、DOM 结构、四个固定入口、状态的三重表达（色 + 形 + 字）。

   亮暗双主题：:root 是亮色，[data-theme="dark"] 与系统深色偏好各翻一次令牌，
   组件层一律只用令牌，不写死颜色——所以下面的组件代码亮暗共用一份。

   无障碍：正文四档文字色在亮暗两套下都过 4.5:1；状态永远配文字标签与形状记号。
   ========================================================================== */

:root {
  color-scheme: light;

  /* ---- 品牌：绿。只做色块（选中行、AI 角标、状态胶囊、AI 气泡底），
         当文字色只有 --brand 这一档站得住（白底 5.2:1），且只给正文链接用 ---- */
  --brand:      #0b7d42;
  --brand-600:  #096838;
  --brand-700:  #075229;
  --brand-400:  #2eb872;
  --brand-300:  #6fd79b;
  --brand-200:  #b4ecc8;
  --brand-100:  #d9f5e4;
  --brand-50:   #eefaf2;
  --accent:     #c3f24d;   /* 柠檬绿：只做 App 标记那一块，不进功能层 */
  --accent-50:  #f3fcdb;

  /* 主操作用近黑而不是品牌色：绿留给「状态与身份」，黑留给「这一步该点哪」 */
  --pri-bg:     #16181a;
  --pri-bg-h:   #2e3336;
  --pri-fg:     #ffffff;

  /* ---- 面 ---- */
  /* 底板保持一块安静的浅底。
     试过四团彩色光晕的 aurora 渐变（Subly 那种），在这个界面上太花——
     它的内容本身颜色就不少（状态色带、头像、胶囊），底下再铺一层彩就压不住了。 */
  --canvas:     #e7e7e5;
  --surface:    #ffffff;
  --surface-2:  #f6f6f4;
  --surface-3:  #eeeeeb;
  /* 卡片底：亮色下与面板同白，靠一条极浅的线立住；
     暗色下必须抬高一档，否则卡片和面板糊成一片 */
  --card-bg:    #ffffff;

  /* 状态色块用的底：比胶囊那档再淡一层。
     整张卡铺满时不能用胶囊的浓度，会吵。 */
  --ok-tint: #e7f5ec;   --wait-tint: #fbf3de;  --need-tint: #fcefe4;
  --block-tint: #fcebe9; --unknown-tint: #eeeafc; --info-tint: #e9f1fa;
  --off-tint: #f0f0ed;
  /* 压在饱和状态色上的字。亮色下状态色是深的，配白字；
     暗色下状态色是亮的，白字只有 2:1，必须换成深字。 */
  --on-state: #ffffff;

  /* ---- 线：只做分隔，不承载信息 ---- */
  --rule:        #e9e9e5;
  --rule-2:      #f2f2ef;
  --rule-strong: #d9d9d4;

  /* ---- 字：四档在「最深的常用底」surface-3 上也全部 ≥ 4.5:1 ----
     判据比白底更严，因为小字经常落在色块上而不是纯白上。括号是 白底 / surface-3。 */
  --ink:   #15171a;   /* 18.3 / 15.9 */
  --ink-2: #43474c;   /* 10.4 /  9.0 */
  --ink-3: #5f646a;   /*  6.4 /  5.5 */
  --ink-4: #666b71;   /*  5.7 /  4.6 */

  /* ---- 语义状态 ---- */
  --ok: #0b7d42;        --ok-bg: #e4f6ea;
  --wait: #8a6212;      --wait-bg: #faf1dc;
  --need: #a04a16;      --need-bg: #fcece0;
  --block: #b32d24;     --block-bg: #fce8e6;
  --unknown: #5a45c8;   --unknown-bg: #ebe6fc;
  --info: #2c6ba6;      --info-bg: #e6f0fa;
  --off: #5f636a;       --off-bg: #eeeeeb;

  /* ---- 头像：白字在这些底色上都过 4.5:1 ---- */
  --t-a: #3f5ae0; --t-b: #7a45ee; --t-c: #c0521f; --t-d: #0e7a66;
  --t-ai1: #6d3fe0; --t-ai2: #0b7c8c; --t-ai3: #c43c7c;
  --t-ai4: #a06a12; --t-ai5: #4757d8;

  /* ---- 形 ---- */
  --r-s: 8px; --r-m: 10px; --r-l: 12px; --r-xl: 16px; --r-panel: 24px;
  /* 旧页面的内联 style 里写死过这些名字（登录、注册、404 等 9 个页面）。
     令牌改名不能让那些页面变成没有背景色的白块，所以留一层别名指到新色。 */
  --radius: 14px; --radius-sm: 10px;
  --line: var(--rule); --line-2: var(--rule-2);
  --moss: var(--brand); --moss-700: var(--brand-600); --moss-800: var(--brand-700);
  --moss-900: var(--pri-bg); --moss-500: var(--brand); --moss-300: var(--brand-300);
  --sage: var(--brand-100); --sage-soft: var(--brand-50);

  /* 卡片专用：近处一层压住边缘，远处一层给出高度 */
  /* 白卡压在白底上，阴影是唯一的分隔，所以要比常规的重一档 */
  --shadow-card: 0 1px 2px rgba(18, 20, 23, .05);
  --shadow-card-h: 0 2px 10px rgba(18, 20, 23, .09);
  --shadow-1: 0 1px 2px rgba(18, 20, 23, .05);
  --shadow-2: 0 10px 30px rgba(18, 20, 23, .10);
  --shadow-3: 0 24px 64px rgba(18, 20, 23, .20);
  --shadow-panel: 0 1px 3px rgba(18, 20, 23, .06), 0 20px 55px rgba(18, 20, 23, .13);
  --ring: 0 0 0 3px rgba(46, 184, 114, .28);

  /* Inter 由 app.js 异步注入；拿不到就落到系统几何无衬线，观感不塌 */
  --font: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI Variable Text", "Segoe UI",
          "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Noto Sans SC", sans-serif;
  --font-display: var(--font);
  --mono: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;

  --rail-w: 58px;
  --nav-w: 280px;
  --drawer-w: 340px;
  --head-h: 64px;
  --gap: 16px;

  --measure: 42rem;
}

/* ---- 暗色令牌 ----
   下面两块是一对：一块跟随系统偏好，一块对应用户手动选择。
   ⚠️ 内容必须逐字相同。它们分处 @media 内外，没法用一个选择器覆盖，
   所以改暗色时**两块都要改**——只改一块的话，手动切暗色会拿到亮色的值，
   而且因为跟随系统那条还是对的，一眼很难看出来。 */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;

    --brand: #4ade80; --brand-600: #86efac; --brand-700: #b7f5cd;
    --brand-400: #34c46f; --brand-300: #269255; --brand-200: #1d4433;
    --brand-100: #14311f; --brand-50: #10261a;
    --accent: #d9f56e; --accent-50: #2b3312;

    --pri-bg: #eceeef; --pri-bg-h: #ffffff; --pri-fg: #16181a;

    --canvas: #0a0b0c; --surface: #15171a; --surface-2: #1b1e21; --surface-3: #2b2f33;
    /* 暗色里「抬起」＝更亮。阴影在深底上几乎看不见，所以卡片必须比它所在的面亮一档 */
    --card-bg: #212528;
    --rule: #2b2f33; --rule-2: #232629; --rule-strong: #3b4045;

    --ink: #eff1f2; --ink-2: #c2c7cc; --ink-3: #9ba1a7; --ink-4: #979da3;

    --ok: #4ade80;        --ok-bg: #113023;
    --wait: #e0b44e;      --wait-bg: #2b2314;
    --need: #f09a5f;      --need-bg: #2d1e14;
    --block: #f0736a;     --block-bg: #2e1817;
    --unknown: #a794ff;   --unknown-bg: #221d3a;
    --info: #6eaee6;      --info-bg: #14212e;
    --off: #9aa0a6;       --off-bg: #232629;

    /* 状态色块：要比卡片亮、并且带得出色相，不能比卡片还黑 */
    --ok-tint: #16342a;   --wait-tint: #38301a;  --need-tint: #3a2a1d;
    --block-tint: #3a2325; --unknown-tint: #2b2547; --info-tint: #1d2c3d;
    --off-tint: #26292c;
    /* 暗色的状态色是亮的，压白字只有 2:1，所以实心胶囊改深字 */
    --on-state: #0f1214;

    --t-a: #5d75f0; --t-b: #9169f5; --t-c: #d97440; --t-d: #2f9c85;
    /* #8a63f0 配深字只有 4.48，差一点点过不了 4.5，提亮 1% 补上 */
    --t-ai1: #8b65f0; --t-ai2: #2a9aa8; --t-ai3: #d9629a;
    --t-ai4: #c08c2e; --t-ai5: #6675e8;

    --shadow-card: 0 1px 2px rgba(0, 0, 0, .35);
    --shadow-card-h: 0 2px 10px rgba(0, 0, 0, .45);
    --shadow-1: 0 1px 2px rgba(0, 0, 0, .30);
    --shadow-2: 0 10px 30px rgba(0, 0, 0, .45);
    --shadow-3: 0 24px 64px rgba(0, 0, 0, .60);
    --shadow-panel: 0 1px 3px rgba(0, 0, 0, .40), 0 20px 55px rgba(0, 0, 0, .30);
    --ring: 0 0 0 3px rgba(74, 222, 128, .28);
  }
}

/* 同上，但不看系统偏好。内容与上面那块逐字一致。 */
:root[data-theme="dark"] {
  color-scheme: dark;

  --brand: #4ade80; --brand-600: #86efac; --brand-700: #b7f5cd;
  --brand-400: #34c46f; --brand-300: #269255; --brand-200: #1d4433;
  --brand-100: #14311f; --brand-50: #10261a;
  --accent: #d9f56e; --accent-50: #2b3312;

  --pri-bg: #eceeef; --pri-bg-h: #ffffff; --pri-fg: #16181a;

  --canvas: #0a0b0c; --surface: #15171a; --surface-2: #1b1e21; --surface-3: #2b2f33;
  /* 暗色里「抬起」＝更亮。阴影在深底上几乎看不见，所以卡片必须比它所在的面亮一档 */
  --card-bg: #212528;
  --rule: #2b2f33; --rule-2: #232629; --rule-strong: #3b4045;

  --ink: #eff1f2; --ink-2: #c2c7cc; --ink-3: #9ba1a7; --ink-4: #979da3;

  --ok: #4ade80;        --ok-bg: #113023;
  --wait: #e0b44e;      --wait-bg: #2b2314;
  --need: #f09a5f;      --need-bg: #2d1e14;
  --block: #f0736a;     --block-bg: #2e1817;
  --unknown: #a794ff;   --unknown-bg: #221d3a;
  --info: #6eaee6;      --info-bg: #14212e;
  --off: #9aa0a6;       --off-bg: #232629;

  /* 状态色块：要比卡片亮、并且带得出色相，不能比卡片还黑 */
  --ok-tint: #16342a;   --wait-tint: #38301a;  --need-tint: #3a2a1d;
  --block-tint: #3a2325; --unknown-tint: #2b2547; --info-tint: #1d2c3d;
  --off-tint: #26292c;
  /* 暗色的状态色是亮的，压白字只有 2:1，所以实心胶囊改深字 */
  --on-state: #0f1214;

  --t-a: #5d75f0; --t-b: #9169f5; --t-c: #d97440; --t-d: #2f9c85;
  /* #8a63f0 配深字只有 4.48，差一点点过不了 4.5，提亮 1% 补上 */
    --t-ai1: #8b65f0; --t-ai2: #2a9aa8; --t-ai3: #d9629a;
  --t-ai4: #c08c2e; --t-ai5: #6675e8;

  --shadow-card: 0 1px 2px rgba(0, 0, 0, .35);
  --shadow-card-h: 0 2px 10px rgba(0, 0, 0, .45);
  --shadow-1: 0 1px 2px rgba(0, 0, 0, .30);
  --shadow-2: 0 10px 30px rgba(0, 0, 0, .45);
  --shadow-3: 0 24px 64px rgba(0, 0, 0, .60);
  --shadow-panel: 0 1px 3px rgba(0, 0, 0, .40), 0 20px 55px rgba(0, 0, 0, .30);
  --ring: 0 0 0 3px rgba(74, 222, 128, .28);
}

/* ==========================================================================
   基础
   ========================================================================== */

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; height: 100%; }
body {
  /* 画布只从 body 的内边距露出来那一圈。.shell 自己就是那张白卡，
     所以卡的圆角、阴影都在 .shell 上，body 只负责留白。 */
  margin: 0; height: 100%; padding: var(--gap);
  background: var(--canvas); color: var(--ink);
  font: 14.5px/1.65 var(--font);
  font-feature-settings: "cv11", "ss01";
  -webkit-font-smoothing: antialiased;
  overflow: hidden;
}
a { color: var(--brand); text-decoration: none; transition: color .16s ease; }
a:hover { color: var(--brand-600); }
b, strong { font-weight: 600; color: var(--ink); }
h1, h2, h3, h4 { margin: 0; font-weight: 600; letter-spacing: -.011em; }
p { margin: 0; }
dl, dd, dt, ul, ol { margin: 0; padding: 0; }
li { list-style: none; }
button { font: inherit; color: inherit; cursor: pointer; background: none; border: 0; padding: 0; }
input, textarea, select { font: inherit; color: inherit; }
:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; border-radius: 6px; }

.mono { font-family: var(--mono); font-size: .87em; color: var(--ink-2); }
.skip {
  position: absolute; left: -9999px; top: 8px; z-index: 200;
  background: var(--pri-bg); color: var(--pri-fg); padding: 9px 15px; border-radius: var(--r-m);
}
.skip:focus { left: 12px; }

::-webkit-scrollbar { width: 11px; height: 11px; }
::-webkit-scrollbar-thumb {
  background: var(--rule-strong); border-radius: 8px;
  border: 3px solid transparent; background-clip: content-box;
}
::-webkit-scrollbar-thumb:hover { background: var(--ink-4); background-clip: content-box; }
::-webkit-scrollbar-track { background: transparent; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ==========================================================================
   骨架｜一张白大卡，切成几栏，栏与栏之间是一条发丝线

   v3 是四块面板浮在画布上，靠 16px 缝隙分区。那样每块都自带阴影，
   界面读起来是「四张纸并排」，而不是「一个应用」。
   v4 收成一张卡：外面只剩一圈画布留白 + 一层阴影，
   里面的分栏交给 1px 的线。色块留给状态，线只管分隔——这两件事分工不换。
   ========================================================================== */

.shell {
  display: flex; height: 100%; overflow: hidden;
  gap: 0; padding: 0;
  background: var(--surface);
  border-radius: var(--r-panel);
  box-shadow: var(--shadow-panel);
}
.rail, .nav, .main, .drawer { background: transparent; border-radius: 0; box-shadow: none; }
/* 分栏线。Rail 与 Navigator 右侧各一条，抽屉左侧一条；
   主区两边不再画线，它的边界就是邻居的线。 */
.rail { border-right: 1px solid var(--rule); }
.nav { border-right: 1px solid var(--rule); }
.drawer { border-left: 1px solid var(--rule); }

/* ---- Rail：四个固定入口 ---- */
.rail {
  width: var(--rail-w); flex: 0 0 var(--rail-w);
  display: flex; flex-direction: column; align-items: center;
  padding: 14px 0 12px; gap: 8px; z-index: 30;
  color: var(--ink-3);
}
/* App 标：柠檬绿的一块方糖。全站唯一一处高饱和的亮色，
   放在最左上角当锚点，别处不再出现。 */
.rail .appmark {
  width: 34px; height: 34px; border-radius: 11px;
  color: var(--pri-bg); display: grid; place-items: center; margin-bottom: 12px;
  background: var(--accent);
}
.rail .appmark svg { width: 21px; height: 21px; }
/* Rail 只放图标。名字留在 DOM 里给读屏与 title，视觉上收掉——
   四个入口全站固定不变，图标本身就是它们的形状记号。 */
.rail-btn {
  width: 40px; height: 40px; border-radius: var(--r-l);
  display: grid; place-items: center;
  color: var(--ink-3); position: relative;
  transition: color .16s ease, background .16s ease;
}
.rail-btn:hover { background: var(--surface-3); color: var(--ink); }
/* 选中态是一块实心近黑的方糖，不是一条色带。
   参考图里当前所在的位置就是这么标的——面积够大，扫一眼就找得到。 */
/* 选中＝品牌绿的圆角方块（2026-09-12 照绿色 Inbox 参考图；之前是近黑） */
.rail-btn.on { background: var(--brand); color: #fff; box-shadow: 0 6px 14px -6px rgba(11,125,66,.55); }
.rail-btn.on:hover { background: var(--brand-600); color: #fff; }
.rail-btn svg { width: 20px; height: 20px; }
.rail-btn .lb {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}
.rail-btn .bdg {
  position: absolute; top: -2px; right: -2px; min-width: 18px; height: 18px; padding: 0 4px;
  /* 字色必须走 --on-state：亮色下 --block 是深红配白字，
     暗色下 --block 变成亮红，白字只有 2.85，得翻成深字。 */
  background: var(--block); color: var(--on-state); border-radius: 9px;
  /* ⚠️ 全站 `box-sizing: border-box`，height **连边框一起算**。
     原来 height:15px ＋ border:2px ⇒ 内容盒只剩 11px，
     行高却按 15px 排 —— 数字被挤得偏下，9.5px 的字号又本来就到极限，
     两件叠在一起就是「红圈里的数字看不清」。
     行高必须等于 height 减掉上下边框（18 − 2×2 = 14）。 */
  font-size: 11px; line-height: 14px; text-align: center; font-weight: 700;
  font-variant-numeric: tabular-nums; border: 2px solid var(--surface);
}
.rail .sp { flex: 1 1 auto; }

/* ---- Rail 下段：偶尔才动的那几个 ----

   和上段之间有一条线。分开不是为了好看：上段是「我现在在跟谁说话」，
   下段是「我要去改点设置」——两类混在一列里，每次找都要从头看一遍。 */
.rail-tail {
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  padding-top: 10px; width: 100%;
  border-top: 1px solid var(--rule);
}
/* 下段的图标淡一档：它们在那儿，但不争注意力。

   ⚠️ **选中态不在这里改颜色。**
   `.rail-btn.on` 的底是 `--pri-bg`（深色），字是 `--pri-fg`（白）。
   这里原本写了 `.rail-tail .rail-btn.on { color: var(--ink) }`，
   它比上面那条晚出现、权重也更高，于是把白字盖回了深字 ——
   **深底配深字，选中的那一个图标就整个消失了**（只剩一块黑方块）。
   淡一档只对「没选中」的时候说。 */
.rail-tail .rail-btn:not(.on) { color: var(--ink-4, var(--ink-3)); }
.rail-tail .rail-btn:not(.on):hover { color: var(--ink); }

/* 左二里的「＋」：加好友、建群。放在分组标题那一行的右端，
   而不是列表末尾——列表长了之后，末尾那个按钮会被滚出视野。 */
.nav-add {
  min-width: 20px; height: 20px; padding: 0 6px; border-radius: 6px; display: grid; place-items: center;
  color: var(--ink-3); font-size: 12px; line-height: 1; text-decoration: none; text-transform: none; letter-spacing: 0;
  margin-left: 4px;
}
.nav-add:hover { background: var(--surface-3); color: var(--ink); }

/* 一栏里什么都没有的时候，说一句为什么，而不是留一片白。 */
.nav-empty {
  margin: 2px 10px 6px; padding: 8px 10px;
  font-size: 12px; line-height: 1.55; color: var(--ink-3);
  background: var(--surface-2); border-radius: 8px;
}
.rail-me {
  width: 36px; height: 36px; border-radius: 50%; margin-top: 8px;
  display: grid; place-items: center;
  box-shadow: 0 0 0 2px var(--surface), 0 0 0 3.5px var(--rule);
}
.rail-me:hover { box-shadow: 0 0 0 2px var(--surface), 0 0 0 3.5px var(--brand-300); }

/* 主题分段控件：注入在 Navigator 底部，对应参考图 4 左下角那个 Light / Dark */
.theme-seg {
  flex: 0 0 auto; display: flex; gap: 3px; margin: 0 10px 8px; padding: 4px;
  background: var(--surface-3); border-radius: 999px;
}
.theme-seg button {
  flex: 1 1 0; display: flex; align-items: center; justify-content: center; gap: 6px;
  height: 30px; border-radius: 999px; font-size: 12.5px; font-weight: 500;
  color: var(--ink-3); transition: background .16s ease, color .16s ease, box-shadow .16s ease;
}
.theme-seg button svg { width: 15px; height: 15px; }
.theme-seg button:hover { color: var(--ink); }
.theme-seg button.on {
  background: var(--card-bg); color: var(--ink); font-weight: 600; box-shadow: var(--shadow-card);
}
/* 分段控件挂在 Navigator 上，而 Navigator 在窄屏会整个收起，
   所以窄屏改用 Rail 上那颗图标按钮——两者永远只出现一个 */
@media (max-width: 620px) { .theme-seg { display: none; } }

/* 主题开关（app.js 注入） */
.theme-btn {
  width: 36px; height: 36px; border-radius: 50%; margin-top: 4px;
  display: grid; place-items: center; color: var(--ink-3);
  transition: background .16s ease, color .16s ease;
}
.rail .theme-btn { display: none; }
@media (max-width: 620px) { .rail .theme-btn { display: grid; } }
.theme-btn:hover { background: var(--surface-3); color: var(--ink); }
.theme-btn svg { width: 18px; height: 18px; }
.theme-btn.float {
  position: fixed; top: 16px; right: 16px; z-index: 80;
  background: var(--surface); box-shadow: var(--shadow-2);
}

/* ---- Context Navigator ---- */
.nav {
  width: var(--nav-w); flex: 0 0 var(--nav-w);
  display: flex; flex-direction: column; overflow: hidden; z-index: 20;
}
.nav-head {
  flex: 0 0 auto; padding: 20px 18px 12px;
  display: flex; align-items: flex-start; gap: 8px;
}
.nav-head .t {
  flex: 1 1 auto; min-width: 0;
  font-size: 16px; font-weight: 600; letter-spacing: -.015em;
  line-height: 1.35; color: var(--ink);
}
.nav-head .t small {
  display: block; font-size: 11.5px; font-weight: 400;
  color: var(--ink-4); letter-spacing: 0; margin-top: 2px;
}
.nav-body { flex: 1 1 auto; overflow-y: auto; padding: 2px 10px 20px; }
.nav-group { margin-top: 18px; }
.nav-group:first-child { margin-top: 2px; }
.nav-label {
  display: flex; align-items: center; white-space: nowrap;
  font-size: 10.5px; font-weight: 600; letter-spacing: .11em; text-transform: uppercase;
  color: var(--ink-4); padding: 0 8px 7px;
}
.nav-item {
  display: flex; align-items: center; gap: 9px;
  padding: 7px 10px; border-radius: var(--r-m);
  color: var(--ink-2); font-size: 13.8px; line-height: 1.5;
  transition: color .16s ease, background .16s ease;
}
.nav-item:hover { background: var(--surface-3); color: var(--ink); }
/* 选中＝薄荷底 + 左端一条绿。字仍然是近黑：
   绿在这套里只做色块，一旦拿去当文字色，弱视用户就只剩「颜色」这一重线索。 */
.nav-item.on {
  color: var(--ink); font-weight: 600;
  background: var(--brand-50); box-shadow: none; position: relative;
}
.nav-item.on::before {
  content: ""; position: absolute; left: 0; top: 6px; bottom: 6px;
  width: 3px; border-radius: 0 3px 3px 0; background: var(--brand-400);
}
/* 图标由 app.js 按目标页注入——170 个静态页的 markup 里没有图标，
   在 CSS 里按 href 一条条写选择器会写成一面墙，交给运行时更好维护。 */
.nav-item .ni {
  flex: 0 0 auto; width: 18px; height: 18px; display: grid; place-items: center;
  color: var(--ink-4); transition: color .16s ease;
}
.nav-item .ni svg { width: 17px; height: 17px; display: block; }
.nav-item:hover .ni { color: var(--ink-3); }
.nav-item.on .ni { color: var(--brand); }
.nav-item .nm { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nav-item .n { font-size: 11.5px; color: var(--ink-4); font-variant-numeric: tabular-nums; }
.nav-item.on .n { color: var(--brand); }
/* 未读计数：中性的近黑小圆点，不是红色。
   红留给「出事了」（.chip.stop、Rail 上的待处理角标）；
   「有 3 条没看」只是一个数量，不该和告警长得一样。 */
.nav-item .unread, .conv .unread {
  min-width: 18px; height: 18px; padding: 0 5px; border-radius: 9px;
  background: var(--brand); color: #fff; font-size: 10px; line-height: 18px;
  text-align: center; font-weight: 600; font-variant-numeric: tabular-nums;
  display: inline-block;
}

/* 抽屉底下那句「关闭这个抽屉不会改变任何业务状态」：一行小字就够，不占一张卡 */
.drawer .note:last-child, .drawer .drawer-note { background: none; border: 0; padding: 6px 0 0; font-size: 12px; color: var(--ink-4); box-shadow: none; }

/* 通讯录一行：头像在左，右端「发消息 ›」（2026-09-12） */
.row.contact { align-items: center; gap: 12px; }
.row.contact .rt { color: var(--brand); font-size: 12.5px; white-space: nowrap; }
.row.contact .t .chip { margin-left: 8px; }

/* 左栏顶上的搜索格（2026-09-12，参照微信/Inbox） */
/* 通讯录的首字母分组标题（微信那一行小灰字「A」） */
.nav-letter { font-size: 11px; color: var(--ink-3); padding: 8px 10px 2px; letter-spacing: .04em; }
.nav-search { padding: 0 2px 10px; }
.nav-search .input {
  width: 100%; box-sizing: border-box; height: 32px; padding: 0 10px 0 30px; font-size: 13px;
  border-radius: 999px; border: 1px solid var(--rule); background: var(--surface-2) no-repeat 10px center;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none' stroke='%23888' stroke-width='1.6' stroke-linecap='round'><circle cx='9' cy='9' r='5.5'/><path d='M13.2 13.2 16.5 16.5'/></svg>");
  background-size: 14px 14px;
}
.nav-search .input:focus { outline: none; border-color: var(--brand-300); background-color: var(--surface); box-shadow: var(--ring); }
.conv.is-hidden { display: none; }

.conv {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 10px; border-radius: var(--r-l); color: var(--ink-2);
  transition: background .16s ease;
}
.conv:hover { background: var(--surface-2); }
/* 会话行选中：和导航项同一套记号（薄荷底 + 左端绿条），
   两栏的「你在这里」长得一样，不用各记一套。 */
.conv.on { background: var(--brand-50); box-shadow: none; position: relative; }
.conv.on::before {
  content: ""; position: absolute; left: 0; top: 7px; bottom: 7px;
  width: 3px; border-radius: 0 3px 3px 0; background: var(--brand-400);
}
.conv .bd { flex: 1 1 auto; min-width: 0; }
.conv .t1, .conv .t2 { display: block; }
.conv .t1 {
  font-size: 13.5px; font-weight: 500; color: var(--ink);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.conv.on .t1 { color: var(--ink); font-weight: 600; }
.conv .t2 {
  font-size: 11.5px; color: var(--ink-3); margin-top: 2px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.conv .rt { flex: 0 0 auto; display: flex; flex-direction: column; align-items: flex-end; gap: 4px; }
.conv .rt .tm { font-size: 11px; color: var(--ink-4); }

/* `.nav-foot` 那一条（搜索 Ctrl K ｜ 页面总览）2026-09-01 去掉了。
   样式一并删 —— 留着一条没有元素用得上的规则，
   下一个人要花时间确认它到底还生不生效。

   ⚠️ 顺带记一笔：亮/暗切换控件原本是 `insertBefore(.nav-foot)` 插进来的，
   删掉那个锚点之后它掉到了容器底边外面，看起来像坏了。
   现在它直接 append，靠 `.nav-body { flex: 1 }` 把自己顶到底部。 */

/* ---- Primary Work Surface ---- */
.main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; overflow: hidden; }

.main-head {
  flex: 0 0 auto; padding: 18px 28px 14px;
  display: flex; align-items: flex-start; gap: 20px;
  border-bottom: 1px solid var(--rule-2);
}
.main-head .hl { min-width: 0; flex: 1 1 auto; }
.crumb {
  font-size: 12px; font-weight: 500; letter-spacing: .02em;
  color: var(--ink-4); display: flex; align-items: center; gap: 7px; flex-wrap: wrap;
  margin-bottom: 7px;
}
.crumb .sep { color: var(--rule-strong); }
.crumb:empty { display: none; }
.title {
  font-size: 26px; font-weight: 600; line-height: 1.24; letter-spacing: -.022em;
  color: var(--ink);
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
}
.head-actions { flex: 0 0 auto; display: flex; align-items: center; gap: 8px; padding-top: 4px; }

.tabs {
  flex: 0 0 auto; align-self: flex-start; max-width: calc(100% - 64px);
  display: flex; gap: 3px; margin: 0 32px 16px; padding: 4px;
  background: var(--surface-3); border-radius: 999px;
  overflow-x: auto; scrollbar-width: none;
}
.tabs::-webkit-scrollbar { display: none; }
.tab {
  padding: 6px 15px; font-size: 13.5px; color: var(--ink-3);
  border-radius: 999px; white-space: nowrap; font-weight: 500;
  transition: color .16s ease, background .16s ease, box-shadow .16s ease;
}
.tab:hover { color: var(--ink); }
.tab.on {
  color: var(--brand-700); font-weight: 600;
  background: var(--card-bg); box-shadow: var(--shadow-card);
}
.tab .n { color: var(--ink-4); font-size: 12px; font-variant-numeric: tabular-nums; }
.tab.on .n { color: var(--brand); }

.main-body { flex: 1 1 auto; overflow-y: auto; }
.pad { padding: 4px 32px 64px; max-width: 64rem; }
.pad.narrow { max-width: 48rem; }
.pad.wide { max-width: none; }

/* ---- Context Drawer ---- */
.drawer {
  width: var(--drawer-w); flex: 0 0 var(--drawer-w);
  display: flex; flex-direction: column; overflow: hidden;
}
.drawer-head {
  min-height: var(--head-h); flex: 0 0 auto; padding: 20px 20px 12px;
  display: flex; align-items: flex-start; gap: 10px;
}
.drawer-head .t {
  flex: 1 1 auto; min-width: 0;
  font-size: 16px; font-weight: 600; letter-spacing: -.015em;
}
.drawer-head .t small {
  display: block; font-size: 11.5px; font-weight: 400;
  color: var(--ink-3); margin-top: 3px;
}
.drawer-body { flex: 1 1 auto; overflow-y: auto; padding: 0 20px 28px; }
.drawer-note {
  font-size: 12px; color: var(--ink-3); line-height: 1.65;
  background: var(--surface-2); border: 1px solid var(--rule); border-radius: var(--r-l);
  padding: 12px 14px; margin-top: 20px;
}

/* 抽屉里的属性行：每行一枚淡彩小方块 + 标签，行与行之间一条极浅的线。
   参考图右栏就是这个节奏——五个颜色轮着来，块本身不携带信息，
   它只是让一长串「标签：值」不至于糊成一坨。
   颜色直接复用五个状态的 tint 令牌，暗色会自己跟着翻，不另立一套。 */
.drawer .kv > dt {
  display: flex; align-items: center; gap: 9px;
  padding: 13px 0 0; border-top: 1px solid var(--rule-2);
  --tone: var(--ok); --tone-bg: var(--ok-tint);
}
.drawer .kv > dt:first-of-type { border-top: 0; }
.drawer .kv > dt::before {
  content: ""; flex: 0 0 22px; width: 22px; height: 22px; border-radius: 7px;
  background:
    radial-gradient(circle at 50% 50%, var(--tone) 0 3.2px, transparent 3.4px),
    var(--tone-bg);
}
.drawer .kv > dt:nth-of-type(5n+2) { --tone: var(--unknown); --tone-bg: var(--unknown-tint); }
.drawer .kv > dt:nth-of-type(5n+3) { --tone: var(--block);   --tone-bg: var(--block-tint); }
.drawer .kv > dt:nth-of-type(5n+4) { --tone: var(--wait);    --tone-bg: var(--wait-tint); }
.drawer .kv > dt:nth-of-type(5n+5) { --tone: var(--info);    --tone-bg: var(--info-tint); }
.drawer .kv > dd { padding-left: 31px; }

/* ==========================================================================
   排版件
   ========================================================================== */

.lede {
  font-size: 16px; line-height: 1.7; color: var(--ink-2);
  max-width: var(--measure); margin: 2px 0 28px;
}
.lede b { color: var(--ink); font-weight: 600; }

.sec { margin-bottom: 36px; }
.sec > h2 {
  display: flex; align-items: center; gap: 10px;
  font-size: 13px; font-weight: 600; letter-spacing: -.006em;
  color: var(--ink); margin-bottom: 12px;
}
/* 标题前一枚短色条：把「一段」和「一段」在视觉上分开，页面不再是一片平的字（2026-09-12） */
.sec > h2::before { content: ""; width: 3px; height: 14px; border-radius: 2px; background: var(--brand-400); flex: 0 0 auto; }
/* 计数收进一颗小色块，比「标题 + 一条横线 + 右端数字」安静得多 */
.sec > h2 .n {
  order: 2; font-size: 11.5px; letter-spacing: 0; color: var(--ink-3);
  background: var(--surface-3); border-radius: 999px; padding: 2px 8px;
  font-variant-numeric: tabular-nums; font-weight: 600;
}
.sec > h2 .sp2 { order: 3; flex: 1 1 auto; }
.sec > h2 .sp { order: 3; flex: 1 1 auto; }
.sec > h2 a {
  order: 4; font-size: 12.5px; font-weight: 500; letter-spacing: 0; text-transform: none;
  color: var(--brand);
}
.sec-desc { font-size: 14px; color: var(--ink-3); max-width: var(--measure); margin: -8px 0 18px; line-height: 1.7; }

/* 分区之间的保底留白：.sec 只有下边距，前面若是 .grid2 / .btn-row 这类
   自己没有下边距的块，两块会贴在一起。折叠规则保证不会叠成两倍。 */
.pad > * + .sec { margin-top: 32px; }
/* 裸用的小标题（不在 .split / .spine 里的 .sh）本来没有任何边距，
   会同时贴住上面的列表和下面的自己那一组。 */
.pad > .sh, .sec > .sh { margin-bottom: 10px; }
.pad > * + .sh, .sec > * + .sh { margin-top: 26px; }
/* 行没有裹在 .rows 里时，拿不到那里的 gap:8，会贴成一整块 */
.pad > .row + .row, .sec > .row + .row { margin-top: 8px; }

/* 内容块大多只管自己内部的排版，不带外边距；两块直接相邻时就会贴在一起
   （卡片底边紧挨说明块、列表紧挨键值表）。这里给相邻的两块一个保底间距，
   前一块自己已经有 margin-bottom 的，折叠后取较大的那个，不会变成两倍。 */
:is(.pad, .sec) > :is(.card, .hcard, .rows, .kv, .facts, .picks, .field, .grid2, .grid3, .split, .steps, .spine, .note, .btn-row, .tabs)
  + :is(.card, .rows, .kv, .facts, .picks, .field, .grid2, .grid3, .split, .steps, .spine, .note) {
  margin-top: 20px;
}
/* 一叠卡片是一组，保持原来更紧的节奏 */
:is(.pad, .sec) > .card + .card { margin-top: 12px; }
.muted { color: var(--ink-3); }
.small { font-size: 13px; }

/* ---- 说明块：软底色 + 左侧色条 ---- */
.note {
  background: var(--surface-2); box-shadow: none; border: 1px solid var(--rule);
  border-radius: var(--r-xl);
  padding: 15px 18px; margin: 0 0 20px;
  font-size: 14px; color: var(--ink-2); line-height: 1.7;
  max-width: var(--measure);
}
/* 说明块前面保底留白：前一块（.grid2 / .card / .rows 这类）自己没有下边距时，
   紧贴着的说明块会顶到卡片底边上。这里的 margin-top 会和前一块自己的
   margin-bottom 折叠，所以已经留够空的地方不会被叠成两倍。 */
.note:not(:first-child) { margin-top: 20px; }
.sec > h2 + .note, .sec > .sec-desc + .note { margin-top: 0; }
.note .h {
  display: block; font-weight: 600; color: var(--ink); margin-bottom: 4px;
  font-size: 14px;
}
/* 收起的说明：一枚 ? 加一句标题，点开才是正文（2026-09-12）。 */
details.note.hint { padding: 0; background: transparent; border: 0; box-shadow: none; }
details.note.hint > summary {
  list-style: none; cursor: pointer; display: inline-flex; align-items: center; gap: 8px;
  font-size: 13px; color: var(--ink-3); padding: 4px 10px 4px 4px; border-radius: 999px;
  border: 1px solid transparent; user-select: none;
}
details.note.hint > summary::-webkit-details-marker { display: none; }
details.note.hint > summary:hover { color: var(--ink-2); background: var(--surface-2); border-color: var(--rule); }
details.note.hint > summary .q {
  display: inline-flex; align-items: center; justify-content: center;
  width: 20px; height: 20px; border-radius: 50%; font-size: 12px; font-weight: 700;
  background: var(--brand-50); color: var(--brand); border: 1px solid var(--brand-100, var(--rule));
}
details.note.hint[open] > summary { color: var(--ink); }
details.note.hint > .hint-body {
  margin-top: 8px; padding: 13px 16px; border-radius: var(--r-xl);
  background: var(--surface-2); border: 1px solid var(--rule);
}
.note.warn { background: var(--wait-tint); }
.note.stop { background: var(--block-tint); }
.note.unknown { background: var(--unknown-tint); }
.note.ok { background: var(--ok-tint); }
.note.warn .h { color: var(--wait); }
.note.stop .h { color: var(--block); }
.note.unknown .h { color: var(--unknown); }
.note.ok .h { color: var(--ok); }
.note.warn, .note.stop, .note.unknown, .note.ok { color: var(--ink-2); }

/* ==========================================================================
   状态胶囊｜色 + 形 + 字，三重
   ========================================================================== */

.chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 10px; border-radius: 999px;
  background: var(--surface-3); color: var(--ink-3);
  font-size: 11.5px; font-weight: 600; letter-spacing: .005em;
  white-space: nowrap; line-height: 1.5;
}
.chip::before {
  content: ""; width: 6px; height: 6px; border-radius: 50%;
  background: currentColor; flex: 0 0 6px;
}
.chip.plain { color: var(--ink-4); font-weight: 500; background: transparent; padding: 3px 0; }
.chip.plain::before { display: none; }
.chip.ok      { color: var(--ok);      background: var(--ok-bg); }
.chip.wait    { color: var(--wait);    background: var(--wait-bg); }
.chip.need    { color: var(--need);    background: var(--need-bg); }
.chip.stop    { color: var(--block);   background: var(--block-bg); }
.chip.unknown { color: var(--unknown); background: var(--unknown-bg); }
.chip.info    { color: var(--info);    background: var(--info-bg); }
.chip.off     { color: var(--off);     background: var(--off-bg); }
/* 形状记号：颜色之外的第二重区分 */
.chip.wait::before    { border-radius: 1px; transform: rotate(45deg); }
.chip.need::before    { border-radius: 1px; }
.chip.stop::before    { clip-path: polygon(50% 0, 100% 100%, 0 100%); border-radius: 0; }
.chip.unknown::before { background: none; box-shadow: inset 0 0 0 2px currentColor; }
.chip.off::before     { background: none; box-shadow: inset 0 0 0 1.5px currentColor; }

.title .chip { font-size: 12px; }

.kind {
  display: inline-block; font-size: 9.5px; font-weight: 700; letter-spacing: .09em;
  padding: 2px 6px; border-radius: 5px; vertical-align: 1px; text-transform: uppercase;
}
.kind.ai { background: var(--brand); color: var(--on-state); }
/* 这句话是谁产的：内核 / 模型直连 / 替身（title 里是原始 produced_by） */
.kind.src { background: var(--brand-50); color: var(--brand); border: 1px solid var(--brand-100); }
.kind.human { background: var(--surface-3); color: var(--ink-3); }

/* ==========================================================================
   操作
   ========================================================================== */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  height: 36px; padding: 0 15px; border-radius: var(--r-m);
  border: 1px solid transparent; background: var(--surface-3);
  font-size: 13.8px; font-weight: 500; color: var(--ink-2); cursor: pointer;
  white-space: nowrap; flex: 0 0 auto;
  transition: background .16s ease, border-color .16s ease, color .16s ease, box-shadow .16s ease;
}
.btn:hover { background: var(--rule); color: var(--ink); }
/* 主操作改成品牌绿（2026-09-12 老板：「色彩偏我们主题色」）；之前是近黑。
   绿仍然只做「这一步该点哪」与状态两件事，不进正文文字色。 */
.btn.pri {
  background: var(--brand); border-color: var(--brand); color: #fff; font-weight: 600;
  box-shadow: 0 6px 14px -8px rgba(11,125,66,.6);
}
.btn.pri:hover { background: var(--brand-600); border-color: var(--brand-600); color: #fff; }
.btn.brand { background: var(--brand); border-color: var(--brand); color: var(--on-state); }
.btn.brand:hover { background: var(--brand-600); border-color: var(--brand-600); color: var(--on-state); }
.btn.danger { color: var(--block); background: var(--block-tint); }
.btn.danger:hover { background: var(--block-bg); color: var(--block); }
.btn.ghost { border-color: transparent; background: transparent; color: var(--ink-3); padding: 0 11px; }
.btn.ghost:hover { background: var(--surface-3); color: var(--ink); }
.btn.sm { height: 30px; padding: 0 12px; font-size: 13px; border-radius: var(--r-s); }
.btn.lg { height: 44px; padding: 0 22px; font-size: 15px; border-radius: var(--r-l); }
.btn.block { width: 100%; }
.btn[disabled], .btn.off {
  opacity: 1; cursor: not-allowed; background: transparent;
  border-color: var(--rule-strong); color: var(--ink-4); border-style: dashed; box-shadow: none;
}
.btn[disabled]:hover, .btn.off:hover { background: transparent; color: var(--ink-4); border-color: var(--rule-strong); }
.btn-row { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; margin-top: 20px; }
.btn-row .sp { flex: 1 1 auto; }
/* 被禁用的操作，紧跟着必须说明「为什么」 */
.why-off {
  font-size: 13px; color: var(--ink-3); margin-top: 10px; line-height: 1.65;
  max-width: var(--measure);
}

.icon-btn {
  width: 34px; height: 34px; border-radius: var(--r-m);
  display: grid; place-items: center; color: var(--ink-3); border: 1px solid transparent;
  cursor: pointer; transition: background .16s ease, color .16s ease;
}
.icon-btn:hover { background: var(--surface-3); color: var(--ink); }
.icon-btn svg { width: 18px; height: 18px; }

/* ==========================================================================
   内容块｜重新卡片化：面 + 圆角 + 极浅的线
   ========================================================================== */

/* v4：卡片重新用线。
   v3 是「白卡压白面、靠阴影浮起」，一列卡片下来阴影叠阴影，整页发灰。
   参考图的做法是 1px 线 + 一层几乎看不见的阴影——边界是清楚的，
   但没有任何一块在「浮」。 */
/* ---- 数字方块（2026-09-12，参照 Smartpro）：淡底 + 左侧色条 + 右上图标 ---- */
.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 12px; margin: 0 0 20px; }
.stat {
  position: relative; display: grid; grid-template-columns: 1fr auto; grid-template-areas: "l ic" "v ic" "s ic";
  align-content: start; row-gap: 2px; padding: 14px 16px 14px 18px;
  border-radius: var(--r-xl); border: 1px solid transparent; color: var(--ink); text-decoration: none;
  transition: transform .16s ease, box-shadow .16s ease;
}
.stat::before { content: ""; position: absolute; left: 0; top: 12px; bottom: 12px; width: 3px; border-radius: 0 3px 3px 0; background: var(--stat-c); }
a.stat:hover { transform: translateY(-1px); box-shadow: var(--shadow-card); }
.stat .stat-l { grid-area: l; font-size: 12.5px; color: var(--ink-3); font-weight: 500; }
.stat .stat-v { grid-area: v; font-size: 24px; font-weight: 700; letter-spacing: -.02em; line-height: 1.2; font-variant-numeric: tabular-nums; }
.stat .stat-s { grid-area: s; font-size: 12px; color: var(--ink-3); margin-top: 2px; }
.stat .stat-ic { grid-area: ic; align-self: start; width: 34px; height: 34px; border-radius: 10px; display: grid; place-items: center; background: var(--stat-ic-bg); color: var(--stat-c); }
.stat .stat-ic svg { width: 18px; height: 18px; }
.stat.green  { background: var(--brand-50);  --stat-c: var(--brand);   --stat-ic-bg: var(--brand-100); }
.stat.blue   { background: #eaf1fb;          --stat-c: #2563a8;        --stat-ic-bg: #d8e6f8; }
.stat.violet { background: #efeafb;          --stat-c: #6b46c1;        --stat-ic-bg: #e2d8f7; }
.stat.orange { background: #fdf0e4;          --stat-c: #c2620e;        --stat-ic-bg: #f9dfc4; }
:root[data-theme="dark"] .stat.blue   { background: #17263a; --stat-ic-bg: #1f3654; --stat-c: #8ab8f0; }
:root[data-theme="dark"] .stat.violet { background: #241c3d; --stat-ic-bg: #33285a; --stat-c: #b9a3ef; }
:root[data-theme="dark"] .stat.orange { background: #3a2614; --stat-ic-bg: #52351c; --stat-c: #f0b078; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .stat.blue   { background: #17263a; --stat-ic-bg: #1f3654; --stat-c: #8ab8f0; }
  :root:not([data-theme="light"]) .stat.violet { background: #241c3d; --stat-ic-bg: #33285a; --stat-c: #b9a3ef; }
  :root:not([data-theme="light"]) .stat.orange { background: #3a2614; --stat-ic-bg: #52351c; --stat-c: #f0b078; }
}

.card {
  background: var(--card-bg); border: 1px solid var(--rule); box-shadow: 0 1px 2px rgba(18,20,23,.05), 0 8px 24px -18px rgba(18,20,23,.25);
  border-radius: var(--r-xl); padding: 18px 20px; margin: 0;
  transition: box-shadow .16s ease, border-color .16s ease;
}
.card:hover { border-color: var(--rule-strong); }
.card + .card { margin-top: 12px; }
.sec > .card:first-of-type { padding-top: 18px; }
/* 次级块：不抬起，往下沉一层。
   用 surface-3 而不是 surface-2——它既可能嵌在白卡里，也可能直接落在
   已经是 surface-2 的主面板上；只有再深一档才能两种场合都看得见。 */
.card.sub { background: var(--surface-3); box-shadow: none; }
.card-h { display: flex; align-items: center; gap: 12px; margin-bottom: 7px; }
.card-h .t {
  font-size: 16px; font-weight: 600; letter-spacing: -.015em;
  flex: 1 1 auto; min-width: 0; color: var(--ink);
}
.card-h .sp { flex: 1 1 auto; }
.card-d { font-size: 14px; color: var(--ink-2); line-height: 1.7; max-width: var(--measure); }

/* Home 卡：色带没了，整张卡就是一张安静的白卡。
   顶上那条铺满卡宽的淡色带比标题还重，一屏三四张下来整页发黄发紫；
   现在元信息收成标题上方一行小字，状态只剩右端那一颗胶囊。
   状态仍是三重表达：胶囊的色 ＋ 胶囊的形状记号 ＋ 胶囊的字。 */
.hcard {
  background: var(--card-bg); border: 1px solid var(--rule); box-shadow: var(--shadow-card);
  border-radius: var(--r-xl); padding: 16px 20px 17px;
  margin: 0 0 12px; position: relative;
  transition: box-shadow .16s ease, border-color .16s ease;
}
.hcard:hover { box-shadow: var(--shadow-card-h); border-color: var(--rule-strong); }
.hcard .ct, .hcard .cw, .hcard .ca { margin-left: 0; margin-right: 0; }
/* 元信息行：左边一行小字说这是什么，右边一颗胶囊说它现在什么状态 */
.hcard .c1 {
  display: flex; align-items: center; gap: 12px;
  background: none; padding: 0; margin-bottom: 8px;
  font-size: 12px; font-weight: 500; letter-spacing: .01em;
  color: var(--ink-3);
}
/* 真正要你现在做决定的那张用实心胶囊——一屏里最多几处高饱和；
   其余（建议 / 等待 / 进行中 / 结果未知）用全站通用的淡底胶囊。 */
.hcard .c1 .chip.need { background: var(--need); color: var(--on-state); padding: 4px 11px; }
.hcard .c1 .chip.plain { background: transparent; color: var(--ink-3); }
.hcard .c1 .sp { flex: 1 1 auto; }
.hcard .ct {
  font-size: 17px; font-weight: 600;
  line-height: 1.4; letter-spacing: -.018em; color: var(--ink); max-width: var(--measure);
}
.hcard .cw { font-size: 14px; color: var(--ink-2); margin-top: 7px; line-height: 1.7; max-width: var(--measure); }
.hcard .ca { display: flex; gap: 10px; align-items: center; margin-top: 15px; flex-wrap: wrap; }
.hcard .ca .sp { flex: 1 1 auto; }
/* v4 取消了「事件卡主操作用品牌色」这条例外。
   现在全站一条规矩：动作是近黑，状态是绿。
   事件卡的状态已经由胶囊说清楚了，按钮不必再上一次色。 */
/* 一屏十几张卡，每张都顶一颗深色实心按钮就是一列黑块，
   而且「现在就得做」和「知道一下」看起来一样重。
   只有胶囊是 need 的那几张保留实心，其余降为描边。 */
.hcard:not(:has(.c1 .chip.need)) .ca .btn.pri {
  background: transparent; border-color: var(--rule-strong);
  color: var(--ink); box-shadow: none;
}
.hcard:not(:has(.c1 .chip.need)) .ca .btn.pri:hover {
  background: var(--surface-2); border-color: var(--ink-4); color: var(--ink);
}

/* 行列表 */
.rows {
  border: 0; border-radius: 0; background: none; overflow: visible;
  display: flex; flex-direction: column; gap: 8px;
}
.row {
  display: flex; align-items: flex-start; gap: 18px; width: 100%; text-align: left;
  padding: 14px 18px; border: 1px solid var(--rule); border-radius: var(--r-l);
  background: var(--card-bg); box-shadow: none; color: inherit;
  transition: background .16s ease, border-color .16s ease;
}
.row:hover { background: var(--brand-50); border-color: var(--brand-200); }
.row .bd { flex: 1 1 auto; min-width: 0; }
.row .t {
  font-size: 14.5px; font-weight: 500; color: var(--ink);
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap; line-height: 1.5;
}
.row .d { display: block; font-size: 13px; color: var(--ink-3); margin-top: 4px; line-height: 1.6; }
.row .rt { flex: 0 0 auto; display: flex; align-items: center; gap: 10px; color: var(--ink-4); font-size: 12.5px; }
.row .av { align-self: flex-start; }

/* 键值表 */
.kv { display: block; }
.kv > dt {
  font-size: 11.5px; font-weight: 600; letter-spacing: .02em;
  color: var(--ink-4); padding: 14px 0 0;
}
.kv > dd {
  font-size: 14.5px; color: var(--ink); line-height: 1.6;
  padding: 3px 0 0; max-width: var(--measure);
}
.kv > dd .sub { display: block; font-size: 13px; color: var(--ink-3); margin-top: 5px; line-height: 1.6; }

.grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 12px 20px; }
.grid3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px 16px; }

/* 两件必须分开显示的事 */
.split {
  display: grid; grid-template-columns: 1fr 1fr; gap: 12px;
  background: none; border: 0; border-radius: 0; overflow: visible;
}
.split > div {
  padding: 16px 18px; background: var(--card-bg); box-shadow: var(--shadow-card);
  border: 1px solid var(--rule); border-radius: var(--r-xl);
}
.split .sh {
  font-size: 11px; font-weight: 600; letter-spacing: .11em; text-transform: uppercase;
  color: var(--ink-4); margin-bottom: 9px;
}

/* 事实清单 */
.facts { display: flex; flex-direction: column; gap: 9px; max-width: var(--measure); }
.facts li { display: flex; gap: 11px; font-size: 14px; line-height: 1.7; color: var(--ink-2); }
.facts li::before { content: "—"; color: var(--rule-strong); flex: 0 0 auto; }
.facts.check li::before { content: "✓"; color: var(--ok); font-weight: 700; }
.facts.cross li::before { content: "✕"; color: var(--block); font-weight: 700; }
.facts.q li::before { content: "?"; color: var(--unknown); font-weight: 700; }

/* ---- 头像 ---- */
/* 正圆。四张参考图里的人像全是圆的——方角头像会让「人」看起来像「文件」。 */
.av {
  flex: 0 0 auto; border-radius: 50%; display: grid; place-items: center;
  color: var(--on-state); font-weight: 600; background: var(--t-a);
  width: 34px; height: 34px; font-size: 13px; position: relative;
  letter-spacing: 0;
}
.av.s { width: 26px; height: 26px; font-size: 11px; }
.av.l { width: 58px; height: 58px; font-size: 21px; }
.av.tone-a { background: var(--t-a); } .av.tone-b { background: var(--t-b); }
.av.tone-c { background: var(--t-c); } .av.tone-d { background: var(--t-d); }
.av.tone-ai1 { background: var(--t-ai1); } .av.tone-ai2 { background: var(--t-ai2); }
.av.tone-ai3 { background: var(--t-ai3); } .av.tone-ai4 { background: var(--t-ai4); }
.av.tone-ai5 { background: var(--t-ai5); }
/* AI 头像加实心角标：不靠颜色也能认出「这是 AI」。
   角标是品牌绿，头像色调里没有绿，所以两者不会糊在一起；
   白环仍然留着——头像色深浅不一，没有环的话角标会陷进去。 */
.av.is-ai::after {
  content: ""; position: absolute; right: -3px; bottom: -3px;
  width: 13px; height: 13px; border-radius: 4px; background: var(--brand-400);
  border: 2px solid var(--surface);
  /* 角标里是一个小火花图标（老板 2026-09-15：AI 加个 icon），白色，随角标缩放 */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='white'%3E%3Cpath d='M12 2l1.8 5.7L19.5 9.5l-5.7 1.8L12 17l-1.8-5.7L4.5 9.5l5.7-1.8z'/%3E%3Ccircle cx='19' cy='18' r='2'/%3E%3C/svg%3E");
  background-size: 80% 80%; background-position: center; background-repeat: no-repeat;
}
.row .av { margin-right: 2px; }
.av.s.is-ai::after { width: 9px; height: 9px; border-radius: 3px; border-width: 1.5px; }
.av.l.is-ai::after { width: 16px; height: 16px; border-radius: 5px; border-width: 3px; }

.who { display: flex; align-items: center; gap: 10px; }
.who .nm { font-weight: 600; }
.who .hd { color: var(--ink-3); font-size: 13px; }
/* 整块 .who 常常本身就是一个 <a>。名字得跟正文同色，
   否则「头像＋名字」会整条变成品牌紫，看着像状态而不像人。 */
a.who .nm { color: var(--ink); transition: color .16s ease; }
a.who:hover .nm { color: var(--brand); }

/* ==========================================================================
   会话｜气泡
   ========================================================================== */

/* ⚠️ 这里原来还有一层 `max-width: 60rem`。
   行长早就由气泡自己管着（`.msg .mb` 是 `max-width: var(--measure)` = 42rem），
   所以这一层不解决可读性，只制造死区：窗口一宽，主区比 960px 宽出来的部分
   全是空白，而**自己的消息靠右之后贴的是那条看不见的 960px 线，不是右边缘**。
   去掉之后 head / stream / composer 三者左右边界对齐，气泡照旧 42rem。 */
.stream { padding: 18px 28px 12px; display: flex; flex-direction: column; gap: 14px; }
.daysep {
  align-self: center; color: var(--ink-3);
  font-size: 11.5px; font-weight: 500; letter-spacing: .01em; margin: 4px 0;
  background: var(--surface-2); border-radius: 999px; padding: 4px 12px;
}

.msg { display: flex; gap: 12px; }
.msg .bd { min-width: 0; flex: 1 1 auto; }
.msg .mh { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; margin-bottom: 5px; }
.msg .mh .nm { font-weight: 600; font-size: 13.5px; color: var(--ink); }
.msg .mh .tm { font-size: 11.5px; color: var(--ink-4); font-variant-numeric: tabular-nums; }
/* 气泡：人说的话是白底 + 一圈线，AI 说的话是薄荷底、无线。
   两种底 + 两种边界，加上 AI 头像角标与 kind 标签，一共三重区分。 */
.msg .mb {
  font-size: 14px; line-height: 1.65; color: var(--ink); max-width: var(--measure);
  background: var(--brand-50); border: 1px solid transparent;
  border-radius: 4px 16px 16px 16px;
  padding: 10px 14px; display: inline-block;
}
.msg .mb p + p { margin-top: 9px; }
.msg:has(.kind.ai) .mb { background: var(--brand-50); border-color: var(--brand-100); }
/* ---- 自己说的话靠右 ----

   `row-reverse` 一次把三样都翻过去：头像到右边、名字与时间贴右、
   气泡靠右。气泡里的**正文仍然左对齐** —— `.bd` 是 flex 列，
   只把盒子推到右端，没有动 text-align，所以多行文字不会变成右对齐的碎行。
   气泡缺角也跟着镜像：别人的缺左上角，自己的缺右上角。 */
.msg.me { flex-direction: row-reverse; }
.msg.me .mh { flex-direction: row-reverse; }
.msg.me .bd { display: flex; flex-direction: column; align-items: flex-end; }
.msg.me .mb { border-radius: 16px 4px 16px 16px; background: var(--surface-2); border-color: var(--rule); }

.msg.sys {
  background: none; border: 0; border-left: 3px solid var(--rule);
  border-radius: 0; padding: 2px 0 2px 16px; margin-left: 46px;
}
.msg.sys .mb { font-size: 13px; color: var(--ink-3); background: none; padding: 0; }
/* 对方（AI）正在想：三个点跳动。它不是消息，回话一到就被真消息顶掉。 */
.msg.typing .mb { color: var(--ink-3); font-size: 13px; }
.msg.typing .dots span { display: inline-block; width: 5px; height: 5px; margin: 0 1px; border-radius: 50%; background: var(--brand); opacity: .35; animation: skai-dot 1.2s infinite; }
.msg.typing .dots span:nth-child(2) { animation-delay: .2s; }
.msg.typing .dots span:nth-child(3) { animation-delay: .4s; }
@keyframes skai-dot { 0%, 80%, 100% { opacity: .35; transform: translateY(0); } 40% { opacity: 1; transform: translateY(-3px); } }

/* 会话流里的对象卡 */
.inline-card {
  border: 1px solid var(--rule); border-radius: var(--r-xl);
  background: var(--card-bg); box-shadow: var(--shadow-card);
  padding: 15px 17px; margin-top: 12px; max-width: var(--measure);
}
.inline-card.need { background: var(--need-tint); }
.inline-card.unknown { background: var(--unknown-tint); }
.inline-card .ih {
  font-size: 10.5px; font-weight: 600; letter-spacing: .1em; text-transform: uppercase;
  color: var(--ink-4); margin-bottom: 6px;
}
.inline-card .it {
  font-size: 15px; font-weight: 600; letter-spacing: -.012em;
  color: var(--ink); line-height: 1.45;
}
.inline-card .id { font-size: 13.5px; color: var(--ink-2); margin-top: 5px; line-height: 1.65; }
.inline-card .ia { margin-top: 12px; display: flex; gap: 8px; flex-wrap: wrap; }

.composer { flex: 0 0 auto; padding: 10px 28px 18px; }
.composer .box {
  border: 1px solid var(--rule); border-radius: 18px; background: var(--surface-2);
  padding: 12px 16px 10px; display: flex; flex-direction: column; gap: 6px;
  transition: border-color .16s ease, box-shadow .16s ease, background .16s ease;
}
.composer .box:hover { border-color: var(--rule-strong); }
/* @ 名单：贴在输入框上方弹出，最多显示 6 行，其余滚动 */
.composer .box { position: relative; }
.mention-pop {
  position: absolute; left: 12px; bottom: calc(100% + 6px); min-width: 240px; max-width: 360px; max-height: 264px; overflow: auto;
  background: var(--card-bg); border: 1px solid var(--rule); border-radius: 12px; box-shadow: 0 8px 24px rgba(0,0,0,.08);
  padding: 6px; z-index: 30; display: flex; flex-direction: column; gap: 2px;
}
.mention-row {
  display: flex; align-items: center; gap: 10px; width: 100%; text-align: left; border: 0; background: none;
  padding: 8px 10px; border-radius: 8px; color: var(--ink); font: inherit; cursor: pointer;
}
.mention-row:hover, .mention-row.on { background: var(--brand-50); }
.mention-row .mn { font-size: 14px; font-weight: 500; }
.mention-row .mh { font-size: 12.5px; color: var(--ink-4); margin-left: auto; white-space: nowrap; }
/* 静止时是一块安静的面，落焦点才亮出品牌色描边——
   描边只在「你正在输入」这一刻存在，平时页面上不多一条线。 */
.composer .box:focus-within {
  background: var(--surface); border-color: var(--brand); box-shadow: var(--ring);
}
.composer textarea {
  border: 0; outline: 0; resize: none; width: 100%; min-height: 24px;
  font-size: 14.5px; line-height: 1.7; background: none;
}
.composer .cbar { display: flex; align-items: center; gap: 10px; padding-top: 2px; }
.composer .cbar .sp { flex: 1 1 auto; }
.composer .hint { font-size: 12px; color: var(--ink-3); line-height: 1.6; }
/* 发送键：近黑的圆键，和参考图右下角那颗一样。
   全站主操作都是近黑，绿留给状态——发送不是状态，是动作。 */
.composer .cbar .btn.pri {
  border-radius: 999px; min-width: 64px;
  background: var(--pri-bg); border-color: var(--pri-bg); color: var(--pri-fg);
  border-radius: 999px; height: 36px; padding: 0 20px;
}
.composer .cbar .btn.pri:hover { background: var(--pri-bg-h); border-color: var(--pri-bg-h); }
/* 关闭态：留在原位、置灰、写明原因 */
.composer.closed .box {
  border-style: dashed; border-color: var(--rule-strong);
  background: transparent; box-shadow: none;
}
.composer.closed textarea { color: var(--ink-4); }

/* ==========================================================================
   流程
   ========================================================================== */

.steps {
  display: flex; gap: 10px; margin-bottom: 32px;
  border: 0; border-radius: 0; background: none; overflow: visible;
}
.step {
  flex: 1 1 0; padding: 14px 16px; min-width: 0; position: relative;
  background: var(--card-bg); box-shadow: var(--shadow-card); border-radius: var(--r-l);
}
.step .sn {
  font-size: 10.5px; font-weight: 600; letter-spacing: .1em; color: var(--ink-4);
  text-transform: uppercase;
}
.step .st { font-size: 13.5px; font-weight: 500; color: var(--ink-3); margin-top: 4px; line-height: 1.45; }
.step.done { background: var(--ok-tint); }
.step.done .sn { color: var(--ok); }
.step.done .st { color: var(--ink-2); }
.step.on { background: var(--brand-100); }
/* 压在 --brand-100 色块上要用 -600 而不是 --brand：
   --brand 在这个底上只有 4.29，差一点点到 4.5。-600 在亮色更深、暗色更亮，两边都拉开。 */
.step.on .sn { color: var(--brand-600); }
.step.on .st { color: var(--ink); font-weight: 600; }

/* 竖排阶段 */
.spine {
  border-left: 1px solid var(--rule); margin-left: 5px; padding-left: 26px;
  display: flex; flex-direction: column; gap: 24px;
}
.spine > li { position: relative; }
.spine > li::before {
  content: ""; position: absolute; left: -31px; top: 6px;
  width: 11px; height: 11px; border-radius: 50%;
  background: var(--surface); border: 1px solid var(--rule-strong);
}
.spine > li.done::before { background: var(--ok); border-color: var(--ok); }
.spine > li.on::before { background: var(--brand); border-color: var(--brand); box-shadow: 0 0 0 5px var(--brand-50); }
.spine > li.stop::before { background: var(--block); border-color: var(--block); }
.spine > li.unknown::before { background: var(--surface); border-color: var(--unknown); border-style: dashed; }
.spine .sh {
  font-size: 15.5px; font-weight: 600; letter-spacing: -.015em;
  color: var(--ink); display: flex; align-items: center; gap: 11px; flex-wrap: wrap; line-height: 1.4;
}
.spine .sd { font-size: 14px; color: var(--ink-2); margin-top: 6px; line-height: 1.7; max-width: var(--measure); }
.spine .sm { font-size: 12px; color: var(--ink-4); margin-top: 6px; font-variant-numeric: tabular-nums; }

/* ==========================================================================
   表单
   ========================================================================== */

.field { margin-bottom: 20px; max-width: var(--measure); }
.field > label {
  display: block; font-size: 12px; font-weight: 600; letter-spacing: .04em;
  color: var(--ink-2); margin-bottom: 7px; text-transform: none;
}
.field .hint { font-size: 13px; color: var(--ink-3); margin-top: 7px; line-height: 1.65; }
.input, .field input[type="text"], .field input[type="email"], .field input[type="password"],
.field textarea, .field select {
  width: 100%; border: 1.5px solid transparent; border-radius: var(--r-l);
  padding: 11px 14px; font-size: 14.5px; background: var(--surface-2); outline: 0;
  transition: border-color .16s ease, box-shadow .16s ease, background .16s ease;
}
.input::placeholder, .field textarea::placeholder { color: var(--ink-4); }
.input:focus, .field input:focus, .field textarea:focus, .field select:focus {
  border-color: var(--brand); background: var(--surface); box-shadow: var(--ring);
}
.field textarea { min-height: 88px; resize: vertical; line-height: 1.7; }

.picks { display: flex; flex-direction: column; gap: 8px; max-width: var(--measure); }
.pick {
  display: flex; align-items: flex-start; gap: 13px; text-align: left; width: 100%;
  border: 1.5px solid transparent; border-radius: var(--r-l);
  padding: 14px 16px 14px 40px; background: var(--card-bg); box-shadow: var(--shadow-card);
  position: relative;
  transition: background .16s ease, border-color .16s ease, box-shadow .16s ease;
}
.pick::before {
  content: ""; position: absolute; left: 16px; top: 18px;
  width: 14px; height: 14px; border-radius: 50%; border: 1.5px solid var(--rule-strong);
  background: var(--surface); transition: border-color .16s ease, border-width .16s ease;
}
.pick:hover { box-shadow: var(--shadow-card-h); }
/* 真的能选的那种 pick 里有一个 radio。它自己不显示 —— 显示的是
   ::before 那颗点。选中态两条并列：`.on` 是渲染时就定下的，
   `:has(:checked)` 是用户点过之后的，两者说的是同一件事。 */
.pick-in { position: absolute; opacity: 0; width: 0; height: 0; pointer-events: none; }
.pick:has(.pick-in) { cursor: pointer; }
/* 勾几个和几选一长得不一样 —— 圆点是「只能选一个」，方块是「可以多选」。
   这不是装饰，是在说这个字段收一个还是收一组。 */
.pick:has(.pick-in[type="checkbox"])::before { border-radius: 5px; }
.pick.on, .pick:has(.pick-in:checked) { border-color: var(--brand); background: var(--brand-50); box-shadow: var(--ring); }
/* 选中态：圆圈/方块整个填成品牌色，里面一枚白色对号（老板 2026-09-17：「圆圈缩小一点，里面加个对号，不要只是圆圈亮」）。
   `::after` 画对号——一条旋转 45° 的 L 形白边。 */
.pick.on::before, .pick:has(.pick-in:checked)::before { border-color: var(--brand); background: var(--brand); border-width: 1.5px; }
.pick.on::after, .pick:has(.pick-in:checked)::after {
  content: ""; position: absolute; left: 21px; top: 21px; width: 3.5px; height: 7px;
  border: solid #fff; border-width: 0 2px 2px 0; transform: rotate(45deg); pointer-events: none;
}
.pick:has(.pick-in:focus-visible) { outline: 2px solid var(--brand); outline-offset: 2px; }
/* 「点一下填进去」的那种 pick（`[data-fill-field]`，见 live.js 的 wireFill）：
   它不是一个 radio 组，里面没有 `.pick-in`，所以吃不到上面那条 cursor。
   一个点得动却不显示手型的东西，很多人根本不会去点它。 */
.pick[data-fill-field] { cursor: pointer; }
.pick .bd { flex: 1 1 auto; min-width: 0; }
.pick .t { font-size: 14.5px; font-weight: 500; color: var(--ink); display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
.pick .d { font-size: 13px; color: var(--ink-3); margin-top: 4px; line-height: 1.65; }
.pick.on .t, .pick:has(.pick-in:checked) .t { font-weight: 600; }
.pick[disabled], .pick.off {
  cursor: not-allowed; background: transparent;
  border-style: dashed; border-color: var(--rule-strong);
}
.pick.off::before { border-style: dashed; }
.pick.off .t, .pick.off .d { color: var(--ink-4); }
.pick[disabled]:hover, .pick.off:hover { background: transparent; border-color: var(--rule-strong); box-shadow: none; }

/* 表格 */
.tbl { width: 100%; border-collapse: separate; border-spacing: 0; font-size: 14px; }
.tbl th {
  text-align: left; font-size: 11px; font-weight: 600; letter-spacing: .09em; text-transform: uppercase;
  color: var(--ink-3); background: var(--surface-3); padding: 11px 16px;
  white-space: nowrap;
}
.tbl th:first-child { border-top-left-radius: var(--r-l); }
.tbl th:last-child { border-top-right-radius: var(--r-l); }
.tbl td { padding: 13px 16px; vertical-align: top; }
/* 隔行填色代替横线：同样能把长表格切开，但页面上少了几十条线 */
.tbl tbody tr:nth-child(even) td { background: var(--surface-2); }
.tbl-wrap {
  overflow-x: auto; border: 0; border-radius: var(--r-l);
  background: var(--card-bg); box-shadow: var(--shadow-card);
}

/* 空态 */
.empty {
  border: 0; border-radius: var(--r-xl);
  padding: 20px 22px; text-align: left; max-width: var(--measure);
  background: var(--card-bg); box-shadow: var(--shadow-card);
}
.empty .t { font-size: 14.5px; font-weight: 600; color: var(--ink-2); }
.empty .d { font-size: 13.5px; color: var(--ink-3); margin-top: 6px; line-height: 1.7; }

/* 拦截屏：Route 不等于 Visibility */
.guard { max-width: 44rem; margin: 56px auto; padding: 0 32px; }
.guard .gt {
  display: inline-flex; align-items: center; gap: 7px;
  font-size: 11px; font-weight: 600; letter-spacing: .11em; text-transform: uppercase;
  color: var(--block); background: var(--block-bg);
  padding: 5px 11px; border-radius: 999px; margin-bottom: 18px;
}
.guard.info-tone .gt { color: var(--info); background: var(--info-bg); }
.guard h1 {
  font-size: 28px; font-weight: 600;
  letter-spacing: -.024em; line-height: 1.26; margin-bottom: 16px;
}
.guard p { font-size: 15px; color: var(--ink-2); line-height: 1.75; margin-bottom: 14px; }

/* ==========================================================================
   浮层
   ========================================================================== */

.scrim {
  position: fixed; inset: 0; background: rgba(15, 12, 30, .38);
  z-index: 90; opacity: 0; pointer-events: none; transition: opacity .2s ease;
  backdrop-filter: blur(2px);
}
.scrim.on { opacity: 1; pointer-events: auto; }

.searchbox {
  position: fixed; top: 13vh; left: 50%; transform: translateX(-50%) translateY(-6px);
  width: min(640px, calc(100vw - 32px)); z-index: 100;
  background: var(--surface); border: 0;
  border-radius: var(--r-panel); box-shadow: var(--shadow-3);
  opacity: 0; pointer-events: none; transition: opacity .2s ease, transform .2s ease;
  display: flex; flex-direction: column; max-height: 70vh; overflow: hidden;
}
.searchbox.on { opacity: 1; pointer-events: auto; transform: translateX(-50%) translateY(0); }
.searchbox .sb-in { display: flex; align-items: center; gap: 12px; padding: 16px 20px; }
.searchbox .sb-in input { flex: 1 1 auto; border: 0; outline: 0; font-size: 16px; background: none; }
.searchbox .sb-list { overflow-y: auto; padding: 8px; }
.searchbox .sb-foot {
  padding: 12px 20px; font-size: 12px;
  color: var(--ink-3); line-height: 1.6; background: var(--surface-2);
}
kbd {
  font: 600 11px/1 var(--mono); background: var(--surface-3); color: var(--ink-3);
  border: 0; border-radius: 6px; padding: 5px 7px;
}

/* ==========================================================================
   响应式
   ========================================================================== */

.nav-close, .drawer-open { display: none; }

@media (max-width: 1360px) {
  .main-head, .tabs, .composer, .pad, .stream, .guard {
    padding-left: 26px; padding-right: 26px;
  }
}

/* ---- 宽屏：抽屉收得起来 ----

   ≤1240px 时抽屉是浮层，× 关的是浮层，一切正常。
   **宽屏上那个 × 原来点了毫无反应** —— 抽屉是 flex 里的一列，
   `closeAll()` 摘掉的 `.open` 在这个宽度下没有任何规则用到。
   于是它恒占 340px，而会话页的抽屉常常只有一两行字（实测 65 个字符），
   右边就空掉一大块。

   状态放在 `.shell` 上而不是 `.drawer` 上：这样同一个状态既能藏抽屉，
   又能把「重新打开」那颗按钮显出来（CSS 没法从 .drawer 反选到 head 里的按钮）。
   整段只在宽屏生效，窄屏拿到这个 class 也不受影响。 */
@media (min-width: 1241px) {
  .shell.drawer-shut .drawer { display: none; }
  .shell.drawer-shut .drawer-open { display: grid; }
}

@media (max-width: 1240px) {
  /* 抽屉从卡里抽出来变成浮层。它在卡里时是透明的（底由卡提供），
     一旦 fixed 就没人给它底了——所以这里要把面、圆角、阴影补回来。 */
  .drawer {
    position: fixed; top: var(--gap); right: var(--gap); bottom: var(--gap); z-index: 95;
    background: var(--surface); border-left: 0; border-radius: var(--r-panel);
    box-shadow: var(--shadow-3); transform: translateX(calc(100% + var(--gap) * 2));
    transition: transform .22s ease;
  }
  .drawer.open { transform: none; }
  .drawer-open { display: grid; }
}

@media (max-width: 960px) {
  :root { --gap: 8px; }
  .nav {
    position: fixed; top: var(--gap); bottom: var(--gap);
    left: calc(var(--rail-w) + var(--gap) * 2); z-index: 92;
    background: var(--surface); border-right: 0; border-radius: var(--r-panel);
    box-shadow: var(--shadow-3);
    transform: translateX(calc(-100% - var(--rail-w) - var(--gap) * 3));
    transition: transform .22s ease;
  }
  .nav.open { transform: none; }
  .nav-close { display: grid; }
  .main-head { padding: 18px 20px 12px; }
  .tabs, .composer, .stream { padding-left: 20px; padding-right: 20px; }
  .pad { padding: 4px 20px 56px; }
  .guard { margin: 32px auto; padding: 0 20px; }
  .title { font-size: 23px; }
  .grid2, .grid3 { grid-template-columns: 1fr; }
  .split { grid-template-columns: 1fr; }
  .steps { flex-wrap: wrap; }
  .step { flex: 1 1 44%; }
}

@media (max-width: 620px) {
  :root { --rail-w: 100%; --gap: 8px; }
  /* 手机上让卡铺满屏：留白和圆角在 375 宽里只会吃掉本来就不够的正文宽度 */
  body { font-size: 15px; padding: 0; }
  .shell { border-radius: 0; box-shadow: none; }
  .shell { flex-direction: column-reverse; padding: 0; }
  /* 竖屏把 Rail 放到底部当 tab bar。分栏线从右边换到上边。 */
  .rail {
    flex-direction: row; height: 58px; width: 100%; flex: 0 0 58px;
    padding: 0 4px; justify-content: space-around;
    border-right: 0; border-top: 1px solid var(--rule);
  }
  .rail .appmark, .rail .sp { display: none; }
  .rail-btn { width: 44px; height: 44px; flex: 0 0 auto; margin: 0; }
  .rail-me { margin: 0; width: 32px; height: 32px; align-self: center; }
  .theme-btn { margin: 0; width: 32px; height: 32px; align-self: center; }
  .nav { left: var(--gap); top: var(--gap); bottom: 74px; width: min(310px, 86vw); transform: translateX(calc(-100% - var(--gap) * 2)); }
  .drawer { bottom: 74px; }
  .main-head { padding: 16px 16px 10px; }
  .pad { padding: 4px 16px 48px; }
  .tabs, .composer, .stream { padding-left: 16px; padding-right: 16px; }
  .guard { padding: 0 16px; }
  .title { font-size: 21px; }
  .guard h1 { font-size: 24px; }
  .lede { font-size: 15.5px; margin-bottom: 24px; }
  .hcard .ct { font-size: 16px; }
  .sec { margin-bottom: 28px; }
  .msg.sys { margin-left: 0; }
  /* 时间戳这类右侧元信息是定宽的（完整 ISO 时间要 150px 左右），
     在 375 下它会把正文挤成一百来像素的窄条，一句话断成四行。
     窄屏让它整条换到下面去，正文吃满整行。 */
  .row { padding: 13px 14px; flex-wrap: wrap; row-gap: 6px; }
  .row .rt { flex: 1 0 100%; font-size: 12px; }
  .card { padding-left: 16px; padding-right: 16px; }
  .hcard .ct, .hcard .cw, .hcard .ca { margin-left: 16px; margin-right: 16px; }
  .hcard .c1 { padding-left: 16px; padding-right: 16px; }

}

/* ==========================================================================
   触摸命中区
   手指的可靠命中区约 44px。桌面上 30px 的小按钮用鼠标没问题，
   到了手机就变成「要点两次才中」。

   条件写成「窄屏 或 粗指针」两条，缺一不可：
   只写 max-width 会漏掉平板——iPad 竖屏 768、横屏 1024，都比 620 宽，
   但一样是手指在点；只写 pointer: coarse 会漏掉桌面上被拖窄的窗口。
   鼠标设备的宽屏两条都不满足，密度一点不变。
   ========================================================================== */
@media (max-width: 620px), (pointer: coarse) {
  .btn { height: 44px; }
  .btn.sm { height: 44px; padding: 0 16px; font-size: 14px; }
  .icon-btn { width: 44px; height: 44px; flex: 0 0 auto; }
  /* 区块标题右侧的「全部…」是独立入口，不是句子里的行内链接，
     只有 21px 高。往上下各撑一点，命中区够手指，视觉位置不变。 */
  .sec > h2 a { display: inline-flex; align-items: center; min-height: 44px; }
  /* 搜索框的 input 无边框、高度只有一个行高，
     外面 .sb-in 的内边距并不接收点击，得让 input 自己撑满。 */
  .searchbox .sb-in input { min-height: 44px; }
  /* 导航项按桌面密度只有 35px 高。手机上导航是最常点的东西，
     不能是全站最难点中的东西。 */
  .nav-item, .conv { min-height: 44px; }
  /* 发送键的高度写在 .composer .cbar .btn.pri 上，特异性比 .btn.sm 高，
     不在这里再写一遍的话，上面那条 44px 压不动它。 */
  .composer .cbar .btn.pri { height: 44px; }
  .rail-me, .theme-btn { width: 44px; height: 44px; }
  .skip { padding-top: 11px; padding-bottom: 11px; }
}


/* Voice / Representation Badge —— AI 以自己的名义说话 ≠ 代表别人说话
   依据 SKAI-GOV-IMPACT-LEDGER-00 IMPACT-044 / IMPACT-045
   复用既有状态令牌，亮暗两套主题自动跟随，不另立一份颜色。 */
.chip.voice          { margin-left: 7px; vertical-align: middle; }
.chip.voice.own      { color: var(--info); background: var(--info-bg); }
.chip.voice.delegated{ color: var(--wait); background: var(--wait-bg); }


/* ---- 开一段子对话 ----

   输入框和按钮在一行：题目是必填的，所以它们是**一件事**，
   不该看起来像「先填一个可选的，再点一个按钮」。 */
.subchat-open { display: flex; gap: 6px; align-items: center; margin-top: 8px; }
.subchat-topic {
  flex: 1 1 auto; min-width: 0;
  padding: 6px 9px; font: inherit; font-size: 13px;
  border: 1px solid var(--rule); border-radius: 8px;
  background: var(--surface); color: var(--ink);
}
.subchat-topic::placeholder { color: var(--ink-3); }
.subchat-topic:focus { outline: 2px solid var(--accent); outline-offset: -1px; }

/* 消息动作（悬停出现）· 引用块 · 转发标 · 表情行 · 转发选会话 · 提示条 */
.msg .bd { position: relative; }
.msg .macts { display: none; position: absolute; right: 0; top: -22px; gap: 2px; background: var(--card-bg); border: 1px solid var(--rule); border-radius: 8px; padding: 2px 4px; box-shadow: 0 2px 8px rgba(0,0,0,.06); z-index: 5; }
.msg.me .macts { right: auto; left: 0; }
.msg:hover .macts { display: flex; }
.mact { border: 0; background: none; font: inherit; font-size: 12px; color: var(--ink-3); padding: 2px 6px; border-radius: 6px; cursor: pointer; }
.mact:hover { background: var(--brand-50); color: var(--ink); }
.msg .quote { display: flex; gap: 6px; align-items: baseline; font-size: 12.5px; color: var(--ink-3); border-left: 3px solid var(--rule-strong); padding: 2px 8px; margin: 0 0 6px; background: var(--surface-2); border-radius: 0 8px 8px 0; max-width: var(--measure); }
.msg .quote .qn { font-weight: 600; white-space: nowrap; }
.msg .quote .qx { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.msg .fwd { font-size: 11.5px; color: var(--ink-4); margin-bottom: 4px; }
.msg.sys.recalled .mb { color: var(--ink-4); font-size: 12.5px; }
.reacts { display: flex; gap: 6px; margin-top: 6px; flex-wrap: wrap; }
.react { border: 1px solid var(--rule); background: var(--card-bg); border-radius: 999px; padding: 1px 9px; font: inherit; font-size: 12.5px; cursor: pointer; color: var(--ink-2); }
.react.on { border-color: var(--brand); background: var(--brand-50); color: var(--brand); }
.composer .quoting { display: flex; align-items: center; gap: 8px; font-size: 12.5px; color: var(--ink-3); border-left: 3px solid var(--brand); padding: 2px 8px; margin-bottom: 6px; background: var(--surface-2); border-radius: 0 8px 8px 0; }
.composer .quoting .qt { flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.composer .quoting .qx { border: 0; background: none; font-size: 15px; cursor: pointer; color: var(--ink-4); }
.fwd-pop { position: fixed; left: 50%; top: 50%; transform: translate(-50%,-50%); width: 320px; max-height: 60vh; overflow: auto; background: var(--card-bg); border: 1px solid var(--rule); border-radius: 14px; box-shadow: 0 12px 40px rgba(0,0,0,.14); padding: 10px; z-index: 60; display: flex; flex-direction: column; gap: 4px; }
.fwd-pop .fh { font-size: 13px; font-weight: 600; color: var(--ink-3); padding: 4px 8px 8px; }
.fwd-pop .fr { border: 0; background: none; text-align: left; font: inherit; font-size: 14px; padding: 9px 10px; border-radius: 8px; cursor: pointer; color: var(--ink); }
.fwd-pop .fr:hover { background: var(--brand-50); }
.fwd-pop .fr.cancel { color: var(--ink-4); margin-top: 6px; }
.toast { position: fixed; left: 50%; bottom: 40px; transform: translateX(-50%); background: var(--ink); color: #fff; padding: 8px 14px; border-radius: 10px; font-size: 13px; z-index: 70; box-shadow: 0 6px 20px rgba(0,0,0,.18); }

/* ---- AI 广场（2026-09-17）：名片网格 ---- */
.square { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 14px; margin-top: 18px; }
.ai-card {
  display: flex; flex-direction: column; align-items: center; text-align: center; gap: 6px;
  padding: 22px 16px 16px; border-radius: var(--radius); background: var(--card-bg); box-shadow: var(--shadow-card);
  border: 1px solid var(--line);
}
.ai-card .av.l { width: 64px; height: 64px; font-size: 26px; margin-bottom: 4px; border-radius: 20px; object-fit: cover; }
.ai-card .ac-name { font-weight: 600; font-size: 15px; color: var(--ink); display: flex; align-items: center; gap: 6px; }
.ai-card .ac-handle { font-size: 12px; color: var(--ink-4); }
.ai-card .ac-bio { font-size: 13px; color: var(--ink-3); line-height: 1.5; min-height: 2.9em; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.ai-card .ac-meta { display: flex; gap: 10px; font-size: 12px; color: var(--ink-4); margin-top: 2px; }
.ai-card .ac-act { margin-top: 8px; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; justify-content: center; min-height: 32px; }
@media (max-width: 640px) { .square { grid-template-columns: repeat(2, 1fr); gap: 10px; } .ai-card { padding: 16px 10px 12px; } }

/* ---- 群二维码 / 扫一扫 / 按群号预览（2026-09-17） ---- */
.qr-box { margin: 10px 0 4px; display: flex; flex-direction: column; align-items: flex-start; gap: 6px; }
.qr-canvas { width: 168px; height: 168px; border-radius: var(--radius-sm); background: #fff; border: 1px solid var(--line); padding: 6px; box-sizing: border-box; display: flex; flex-direction: column; align-items: center; }
.qr-canvas svg { width: 100%; height: 100%; display: block; }
.qr-canvas .qr-link { display: none; }
.qr-cap { font-size: 12px; color: var(--ink-4); }
.join-row { display: flex; gap: 8px; align-items: center; }
.join-row .input { flex: 1; }
.join-preview { margin: 4px 0 18px; }
.jp-card { padding: 14px 16px; border-radius: var(--radius-sm); background: var(--card-bg); border: 1px solid var(--line); box-shadow: var(--shadow-card); }
.jp-title { font-weight: 600; color: var(--ink); }
.jp-intro { font-size: 13px; color: var(--ink-3); margin-top: 4px; }
.jp-meta { font-size: 12px; color: var(--ink-4); margin-top: 6px; }
.jp-none { font-size: 13px; color: var(--warn, #b45309); }
.qr-scan { position: fixed; inset: 0; z-index: 9000; background: #000; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 12px; }
.qr-scan video { width: min(92vw, 480px); border-radius: 12px; }
.cand[hidden] { display: none; }

/* ---- 图片 / 语音 / 文件消息（2026-09-17） ---- */
.cbar .cbtn { background: transparent; border: 0; cursor: pointer; font-size: 16px; line-height: 1; padding: 4px 6px; border-radius: 8px; color: var(--ink-3); }
.cbar .cbtn:hover { background: var(--surface-3); }
.cbar .cbtn.rec { background: #fee2e2; color: #b91c1c; font-size: 12px; font-weight: 600; padding: 6px 8px; }
.pending-atts { display: flex; flex-wrap: wrap; gap: 6px; padding: 8px 10px 0; }
.patt { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; padding: 4px 8px; border-radius: 999px; background: var(--surface-3); color: var(--ink-2); max-width: 260px; }
.patt.up { color: var(--ink-4); }
.patt .px { border: 0; background: transparent; cursor: pointer; color: var(--ink-4); font-size: 14px; line-height: 1; padding: 0 2px; }
.atts { display: flex; flex-wrap: wrap; gap: 6px; margin: 2px 0 4px; }
.att.img { display: block; max-width: 260px; border-radius: 10px; overflow: hidden; background: var(--surface-3); min-width: 80px; min-height: 48px; }
.att.img img { display: block; max-width: 260px; max-height: 320px; width: auto; height: auto; }
.att.img.broken { padding: 10px; font-size: 12px; color: var(--ink-4); }
.att.voice { display: inline-flex; align-items: center; gap: 8px; min-width: 120px; padding: 6px 12px; border-radius: 999px; background: var(--brand-50); color: var(--brand); border: 1px solid var(--brand-100); }
.att.voice .vplay { border: 0; background: transparent; color: inherit; cursor: pointer; font-size: 13px; padding: 0; }
.att.voice .vbar { flex: 1; height: 3px; border-radius: 2px; background: currentColor; opacity: .35; min-width: 40px; }
.att.voice.playing .vbar { opacity: .9; }
.att.voice .vlen { font-size: 12px; }
.att.voice audio { display: none; }
.att.video video { max-width: 280px; border-radius: 10px; }
.att.file { display: flex; align-items: center; gap: 10px; padding: 10px 12px; border-radius: 10px; background: var(--card-bg); border: 1px solid var(--line); color: var(--ink); text-decoration: none; min-width: 200px; max-width: 320px; }
.att.file .ficon { font-size: 22px; }
.att.file .fbody { display: flex; flex-direction: column; min-width: 0; }
.att.file .fname { font-size: 13px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.att.file .fsize { font-size: 11px; color: var(--ink-4); }

/* ---- 搜索聊天记录（2026-09-17） ---- */
.msearch { margin: 8px 0 16px; }
/* 「只搜这一个会话 · 搜全部」在输入框底下：.sec-desc 全局的 -8px 负上边距是给标题用的，
   在这里会把它拉到输入框上面（老板 2026-09-19 截图：框跟文字重叠）。 */
.msearch .sec-desc { margin: 8px 0 0; }
.msr-group { margin-top: 16px; }
.msr-title { font-weight: 600; font-size: 13px; color: var(--ink-2); margin-bottom: 6px; display: flex; align-items: center; gap: 6px; }
.msr-n { font-size: 11px; color: var(--ink-4); background: var(--surface-3); border-radius: 999px; padding: 1px 7px; }
.msr-hit { display: grid; grid-template-columns: 96px 1fr auto; gap: 10px; padding: 10px 12px; border-radius: 10px; background: var(--card-bg); border: 1px solid var(--line); text-decoration: none; color: var(--ink); margin-bottom: 6px; align-items: baseline; }
.msr-hit:hover { background: var(--surface-2, var(--surface-3)); }
.msr-from { font-size: 12px; color: var(--ink-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.msr-body { font-size: 13px; }
.msr-body mark { background: #fef08a; color: inherit; padding: 0 1px; border-radius: 2px; }
.msr-att { color: var(--ink-4); font-size: 12px; }
.msr-at { font-size: 11px; color: var(--ink-4); white-space: nowrap; }
@media (max-width: 640px) { .msr-hit { grid-template-columns: 1fr; gap: 2px; } }
.msg.hit { outline: 2px solid var(--brand); outline-offset: 4px; border-radius: 10px; transition: outline-color .6s; }

/* ---- 群公告（2026-09-17）：聊天区顶部横幅 + 右栏卡片 ---- */
.ann-bar { margin: 8px 16px 0; border-radius: 10px; background: #fffbeb; border: 1px solid #fde68a; color: #78350f; font-size: 13px; }
.ann-bar summary { cursor: pointer; padding: 8px 12px; font-weight: 600; display: flex; gap: 8px; align-items: center; list-style: none; }
.ann-bar summary::-webkit-details-marker { display: none; }
.ann-bar .ann-peek { font-weight: 400; flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; opacity: .8; }
.ann-bar[open] .ann-peek { display: none; }
.ann-bar .ann-full { padding: 0 12px 10px; white-space: pre-wrap; line-height: 1.55; }
.ann-card { margin: 0 0 12px; padding: 10px 12px; border-radius: 10px; background: #fffbeb; border: 1px solid #fde68a; color: #78350f; }
.ann-card .ann-head { font-weight: 600; font-size: 12px; margin-bottom: 4px; }
.ann-card .ann-body { font-size: 13px; white-space: pre-wrap; line-height: 1.5; }

/* ---- 抽屉里的快捷动作（免打扰 / 删好友 / 退群）与免打扰标记（2026-09-17） ---- */
.drawer-acts { display: flex; flex-wrap: wrap; gap: 8px; margin: 4px 0 14px; }
.btn.danger { color: #b91c1c; background: #fef2f2; border-color: #fecaca; }
.btn.danger:hover { background: #fee2e2; }
.conv .mute-ic { font-size: 11px; opacity: .6; margin-right: 4px; }
.conv .unread.dot { min-width: 8px; width: 8px; height: 8px; padding: 0; border-radius: 50%; font-size: 0; }

/* ---- 带动作条的行（群管理成员 / 添加成员，2026-09-17）：行 + 动作条合成一张卡 ---- */
.row-with-acts { display: flex; flex-direction: column; border: 1px solid var(--rule); border-radius: var(--r-l); background: var(--card-bg); overflow: hidden; }
.row-with-acts > .row { border: 0; border-radius: 0; }
.row-with-acts > .btn-row.acts { margin: 0; padding: 10px 18px 12px; border-top: 1px solid var(--rule); background: var(--surface-2, var(--surface)); display: flex; flex-wrap: wrap; gap: 8px; }
/* 单个动作键的行：键放右边，同一行，不另起动作栏（老板 2026-09-21） */
.row-with-acts.inline { flex-direction: row; align-items: center; }
.row-with-acts.inline > .row { flex: 1 1 auto; min-width: 0; }
.row-with-acts.inline > .btn-row.acts { flex: 0 0 auto; border-top: 0; background: transparent; padding: 0 16px 0 0; }
.row-plain { display: contents; }
.ai-card .ac-declined { font-size: 12px; color: #b45309; margin-bottom: 4px; width: 100%; }
.cbar .sent-hint { font-size: 12px; color: var(--ink-4); margin-right: 8px; }
.qr-box.small .qr-canvas { width: 132px; height: 132px; }
.qr-box.small { margin: 0 0 14px; }

/* ---- 头像：图片 / 群九宫格 / 更多默认底色（2026-09-17） ---- */
:root { --t-e: #7c3aed; --t-f: #0891b2; --t-g: #db2777; --t-h: #65a30d; }
.av.tone-e { background: var(--t-e); } .av.tone-f { background: var(--t-f); }
.av.tone-g { background: var(--t-g); } .av.tone-h { background: var(--t-h); }
.av.tone-ai6 { background: #0d9488; }
.av.has-img { position: relative; overflow: hidden; }
.av.has-img img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.av.grp { display: grid; gap: 1px; padding: 2px; background: var(--surface-3); overflow: hidden; }
.av.grp .cell { display: flex; align-items: center; justify-content: center; color: #fff; font-size: 9px; font-weight: 600; border-radius: 3px; overflow: hidden; position: relative; }
.av.grp .cell img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.av.grp.n1 { grid-template-columns: 1fr; }
.av.grp.n2 { grid-template-columns: 1fr 1fr; align-items: stretch; }
.av.grp.n3, .av.grp.n4 { grid-template-columns: 1fr 1fr; grid-template-rows: 1fr 1fr; }
.av.grp.n3 .cell:first-child { grid-column: 1 / span 2; }
.av.grp .cell.tone-a { background: var(--t-a); } .av.grp .cell.tone-b { background: var(--t-b); }
.av.grp .cell.tone-c { background: var(--t-c); } .av.grp .cell.tone-d { background: var(--t-d); }
.av.grp .cell.tone-e { background: var(--t-e); } .av.grp .cell.tone-f { background: var(--t-f); }
.av.grp .cell.tone-g { background: var(--t-g); } .av.grp .cell.tone-h { background: var(--t-h); }
.av.grp .cell[class*="tone-ai"] { background: var(--t-ai1); }


/* ==========================================================================
   v5 · 层次（2026-09-19，老板：「整个 UI 样式升级优化，有层次感，有设计感」）

   v4 把界面收成「一张白卡，几栏，一条线」——结构对，但截图看下来整站是
   **一张平铺的白纸**：Rail、左栏、主区、右抽屉同一个白、同一层级，卡片、输入框、
   按钮全靠 1px 线立着，没有一样东西在「浮」。「毛坯房」的感觉来自这里，不是缺组件。

   v5 不换语言（仍是白卡 + 发丝线 + 绿；字永远近黑；绿只做色块与主操作），
   只补三件事：

     面     三层：底（冷灰，带一丝品牌色的光）→ 整张应用卡（大而软的影）→ 卡内
            左栏微微上色、主区纯白、右抽屉向左投一层影。眼睛一扫就知道谁在谁上面。
     件     卡片 / 行 / 输入框 / 气泡 / 输入区都有自己的一层影，悬停上浮 1px；
            主按钮是一条绿色微渐变 + 内高光，按下去会沉。
     字     标题收紧字距、面包屑改小号大写，段落节奏不变。

   全部写成对 v4 规则的**覆盖**，类名与 DOM 一个都不动——三套判据脚本
   （browser-smoke / site-sweep / verify-flow-boss）查的都是类名与结构。
   暗色两块令牌仍然逐字一致（见 v4 那段注释里的原因）。
   ========================================================================== */

:root {
  --canvas: #eceef1;
  --canvas-glow: rgba(11, 125, 66, .07);
  --surface-2: #f4f6f8;
  --surface-3: #eceff2;
  --body-bg: #fafbfc;
  --stream-bg: #f3f5f7;
  --rule: #e6e8eb;
  --rule-2: #eff1f3;
  --rule-strong: #d5d9de;

  --shadow-card: 0 1px 2px rgba(16, 24, 40, .04), 0 6px 20px -14px rgba(16, 24, 40, .16);
  --shadow-card-h: 0 2px 4px rgba(16, 24, 40, .05), 0 14px 32px -16px rgba(16, 24, 40, .22);
  --shadow-1: 0 1px 2px rgba(16, 24, 40, .05);
  --shadow-2: 0 12px 32px -12px rgba(16, 24, 40, .18);
  --shadow-3: 0 28px 72px -20px rgba(16, 24, 40, .32);
  --shadow-panel: 0 0 0 1px rgba(16, 24, 40, .05), 0 1px 2px rgba(16, 24, 40, .04), 0 32px 80px -32px rgba(16, 24, 40, .28);
  --shadow-drawer: -16px 0 40px -32px rgba(16, 24, 40, .35);
  --shadow-inset: inset 0 1px 2px rgba(16, 24, 40, .04);
  --pri-grad: linear-gradient(180deg, #14934f 0%, #0b7d42 100%);
  --pri-grad-h: linear-gradient(180deg, #1a9f58 0%, #0d8a49 100%);
  --pri-shadow: 0 1px 2px rgba(11, 125, 66, .28), 0 10px 22px -12px rgba(11, 125, 66, .65);
  --mine-grad: linear-gradient(135deg, #e3f7ea 0%, #d3f1de 100%);
  --av-sheen: linear-gradient(145deg, rgba(255, 255, 255, .22), rgba(255, 255, 255, 0) 58%);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --canvas: #0a0c0f;
    --canvas-glow: rgba(74, 222, 128, .06);
    --surface: #14171b; --surface-2: #181c21; --surface-3: #22272d;
    --body-bg: #121518; --stream-bg: #101316;
    --card-bg: #1b2026;
    --rule: #262b31; --rule-2: #1f2429; --rule-strong: #353b43;

    --shadow-card: 0 1px 2px rgba(0, 0, 0, .35), 0 8px 24px -14px rgba(0, 0, 0, .6);
    --shadow-card-h: 0 2px 4px rgba(0, 0, 0, .4), 0 16px 36px -16px rgba(0, 0, 0, .7);
    --shadow-1: 0 1px 2px rgba(0, 0, 0, .35);
    --shadow-2: 0 12px 32px -12px rgba(0, 0, 0, .6);
    --shadow-3: 0 28px 72px -20px rgba(0, 0, 0, .75);
    --shadow-panel: 0 0 0 1px rgba(255, 255, 255, .05), 0 1px 2px rgba(0, 0, 0, .5), 0 32px 80px -32px rgba(0, 0, 0, .8);
    --shadow-drawer: -16px 0 40px -32px rgba(0, 0, 0, .8);
    --shadow-inset: inset 0 1px 2px rgba(0, 0, 0, .3);
    --pri-grad: linear-gradient(180deg, #5ce691 0%, #3fcf76 100%);
    --pri-grad-h: linear-gradient(180deg, #6feea0 0%, #4bd984 100%);
    --pri-shadow: 0 1px 2px rgba(0, 0, 0, .4), 0 10px 22px -12px rgba(74, 222, 128, .45);
    --mine-grad: linear-gradient(135deg, #17392a 0%, #123324 100%);
    --av-sheen: linear-gradient(145deg, rgba(255, 255, 255, .16), rgba(255, 255, 255, 0) 58%);
  }
}

:root[data-theme="dark"] {
  --canvas: #0a0c0f;
  --canvas-glow: rgba(74, 222, 128, .06);
  --surface: #14171b; --surface-2: #181c21; --surface-3: #22272d;
  --body-bg: #121518; --stream-bg: #101316;
  --card-bg: #1b2026;
  --rule: #262b31; --rule-2: #1f2429; --rule-strong: #353b43;

  --shadow-card: 0 1px 2px rgba(0, 0, 0, .35), 0 8px 24px -14px rgba(0, 0, 0, .6);
  --shadow-card-h: 0 2px 4px rgba(0, 0, 0, .4), 0 16px 36px -16px rgba(0, 0, 0, .7);
  --shadow-1: 0 1px 2px rgba(0, 0, 0, .35);
  --shadow-2: 0 12px 32px -12px rgba(0, 0, 0, .6);
  --shadow-3: 0 28px 72px -20px rgba(0, 0, 0, .75);
  --shadow-panel: 0 0 0 1px rgba(255, 255, 255, .05), 0 1px 2px rgba(0, 0, 0, .5), 0 32px 80px -32px rgba(0, 0, 0, .8);
  --shadow-drawer: -16px 0 40px -32px rgba(0, 0, 0, .8);
  --shadow-inset: inset 0 1px 2px rgba(0, 0, 0, .3);
  --pri-grad: linear-gradient(180deg, #5ce691 0%, #3fcf76 100%);
  --pri-grad-h: linear-gradient(180deg, #6feea0 0%, #4bd984 100%);
  --pri-shadow: 0 1px 2px rgba(0, 0, 0, .4), 0 10px 22px -12px rgba(74, 222, 128, .45);
  --mine-grad: linear-gradient(135deg, #17392a 0%, #123324 100%);
  --av-sheen: linear-gradient(145deg, rgba(255, 255, 255, .16), rgba(255, 255, 255, 0) 58%);
}

/* ---- 面：底 → 应用卡 → 栏 ---- */
body {
  background:
    radial-gradient(1100px 520px at 12% -8%, var(--canvas-glow) 0%, transparent 62%),
    var(--canvas);
}
.shell { box-shadow: var(--shadow-panel); }
.rail { background: linear-gradient(180deg, var(--surface-2) 0%, var(--surface) 100%); }
.nav { background: var(--surface-2); }
.main { background: var(--surface); }
.drawer { background: var(--surface); box-shadow: var(--shadow-drawer); position: relative; z-index: 25; }

/* 左栏顶部：标题带与列表之间一条极浅的分界 */
.nav-head { padding-bottom: 14px; }
.nav-search .input {
  background-color: var(--surface); border-color: var(--rule);
  box-shadow: var(--shadow-inset);
}

/* 主区标题带：固定在顶部，下面一条发丝线，内容从它底下滑过 */
.main-head {
  padding: 20px 28px 16px;
  background: var(--surface); border-bottom: 1px solid var(--rule);
  box-shadow: 0 10px 24px -22px rgba(16, 24, 40, .28);
  position: relative; z-index: 5;
}
.crumb { font-size: 11px; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-4); margin-bottom: 6px; }
.crumb .sep { color: var(--rule-strong); }
.crumb:empty { display: none; }
.title { font-size: 24px; letter-spacing: -.024em; }
.main-body { background: var(--body-bg); }
/* 聊天流的底再深一档：白卡气泡、绿气泡、日期胶囊都从这层底上跳出来 */
.main-body:has(> .stream), .main-body:has(> .thread) { background: var(--stream-bg); }
.composer { background: var(--surface); border-top: 1px solid var(--rule-2); }
/* 分区标题：稍大一号，色条粗一点 */
.sec > h2 { font-size: 14px; }
.sec > h2::before { width: 4px; height: 16px; border-radius: 3px; }
.nav-head .t { font-size: 17px; }

/* 抽屉标题与内容之间同一条线 */
.drawer-head { border-bottom: 1px solid var(--rule); padding-bottom: 14px; margin-bottom: 14px; }
.drawer-note { background: var(--surface-2); box-shadow: var(--shadow-inset); }

/* ---- 件：能浮起来的都浮起来 ---- */
.card, .hcard, .row, .empty, .step, .split > div, .inline-card, .tbl-wrap, .ai-card, .stat, .jp-card {
  box-shadow: var(--shadow-card);
  border: 1px solid var(--rule);
  transition: transform .16s ease, box-shadow .16s ease, border-color .16s ease, background .16s ease;
}
.card:hover, .hcard:hover, .ai-card:hover, a.stat:hover, .row:hover {
  transform: translateY(-1px); box-shadow: var(--shadow-card-h); border-color: var(--rule-strong);
}
.row:hover { background: var(--card-bg); }
.rows { gap: 10px; }
.card.sub { box-shadow: var(--shadow-inset); border-color: var(--rule); }
.card.sub:hover { transform: none; box-shadow: var(--shadow-inset); }
.empty {
  background: var(--surface-2); border: 1px dashed var(--rule-strong); box-shadow: none;
}
.empty .t { color: var(--ink); }

/* 左栏选中项：淡绿底 + 左侧绿条（v4 就有），补一层极浅的内影让它「按下去」 */
.nav-item.on, .conv.on { box-shadow: inset 0 0 0 1px var(--brand-100); }
.nav-item:hover, .conv:hover { background: var(--surface-3); }
.nav-item.on:hover, .conv.on:hover { background: var(--brand-50); }
.conv { padding: 9px 10px; }
.conv .av { box-shadow: 0 0 0 2px var(--surface-2); }
.conv.on .av { box-shadow: 0 0 0 2px var(--brand-50); }

/* ---- 头像：一层高光，圆不再是平的 ---- */
.av, .av[class*="tone-"] { background-image: var(--av-sheen); box-shadow: 0 1px 2px rgba(16, 24, 40, .16), inset 0 0 0 1px rgba(255, 255, 255, .12); }
.av.has-img, .av.has-img[class*="tone-"] { background-image: none; }
.av.grp { background-image: none; box-shadow: 0 1px 2px rgba(16, 24, 40, .16); }
.rail-me { box-shadow: 0 0 0 2px var(--surface), 0 0 0 3.5px var(--rule), 0 4px 10px -6px rgba(16, 24, 40, .4); }
.rail-me:hover { box-shadow: 0 0 0 2px var(--surface), 0 0 0 3.5px var(--brand-300), 0 4px 10px -6px rgba(16, 24, 40, .4); }
.rail-btn.on { background: var(--pri-grad); box-shadow: var(--pri-shadow), inset 0 1px 0 rgba(255, 255, 255, .18); color: var(--on-state); }
.rail-btn.on:hover { background: var(--pri-grad-h); color: var(--on-state); }

/* ---- 操作 ---- */
.btn {
  background: var(--surface); border-color: var(--rule-strong); color: var(--ink);
  box-shadow: var(--shadow-1);
  transition: background .16s ease, border-color .16s ease, color .16s ease, box-shadow .16s ease, transform .1s ease;
}
.btn:hover { background: var(--surface-2); border-color: var(--ink-4); color: var(--ink); }
.btn:active { transform: translateY(1px); box-shadow: none; }
.btn.pri, .btn.brand, .composer .cbar .btn.pri {
  background: var(--pri-grad); border-color: transparent; color: var(--on-state);
  box-shadow: var(--pri-shadow), inset 0 1px 0 rgba(255, 255, 255, .22);
}
.btn.pri:hover, .btn.brand:hover, .composer .cbar .btn.pri:hover {
  background: var(--pri-grad-h); border-color: transparent; color: var(--on-state);
  box-shadow: var(--pri-shadow), inset 0 1px 0 rgba(255, 255, 255, .22);
}
.btn.pri:active, .btn.brand:active { transform: translateY(1px); box-shadow: inset 0 1px 2px rgba(0, 0, 0, .18); }
.btn.danger { background: var(--block-tint); border-color: transparent; box-shadow: none; }
.btn.ghost { background: transparent; border-color: transparent; box-shadow: none; color: var(--ink-3); }
.btn.ghost:hover { background: var(--surface-3); border-color: transparent; }
.btn[disabled], .btn.off { box-shadow: none; background: transparent; }
.hcard:not(:has(.c1 .chip.need)) .ca .btn.pri {
  background: var(--surface); border-color: var(--rule-strong); color: var(--ink); box-shadow: var(--shadow-1);
}
.hcard:not(:has(.c1 .chip.need)) .ca .btn.pri:hover { background: var(--surface-2); border-color: var(--ink-4); }
.icon-btn { transition: background .16s ease, color .16s ease, transform .1s ease; }
.icon-btn:active { transform: translateY(1px); }
.tab.on { box-shadow: var(--shadow-card); }
.theme-seg { background: var(--surface-3); box-shadow: var(--shadow-inset); }
.theme-seg button.on { box-shadow: var(--shadow-card); }

/* ---- 表单：白底 + 发丝边 + 内影；落焦点才亮绿环 ---- */
.input, .field input[type="text"], .field input[type="email"], .field input[type="password"],
.field textarea, .field select {
  background: var(--surface); border: 1px solid var(--rule-strong); box-shadow: var(--shadow-inset);
}
.input:hover, .field input:hover, .field textarea:hover, .field select:hover { border-color: var(--ink-4); }
.input:focus, .field input:focus, .field textarea:focus, .field select:focus {
  border-color: var(--brand); box-shadow: var(--ring), var(--shadow-inset);
}
.field > label { font-size: 12.5px; letter-spacing: .02em; color: var(--ink); }
.pick { box-shadow: var(--shadow-1); }

/* ---- 会话 ---- */
.stream { gap: 16px; padding-top: 22px; }
.daysep { background: var(--surface); border: 1px solid var(--rule); box-shadow: var(--shadow-1); color: var(--ink-3); }
.msg .mb {
  background: var(--card-bg); border: 1px solid var(--rule); box-shadow: var(--shadow-card);
  border-radius: 6px 18px 18px 18px; padding: 11px 15px;
}
.msg:has(.kind.ai) .mb { background: var(--card-bg); border-color: var(--rule); }
.msg.me .mb {
  background: var(--mine-grad); border-color: var(--brand-200); border-radius: 18px 6px 18px 18px;
  box-shadow: 0 1px 2px rgba(11, 125, 66, .08), 0 6px 20px -14px rgba(11, 125, 66, .35);
}
.msg.sys { border-left-color: var(--rule-strong); }
.msg .macts { box-shadow: var(--shadow-2); border: 1px solid var(--rule); background: var(--card-bg); }
/* 刚发出去的那一句、「正在想」那一条：淡入上浮。只动这两种——整页重画时别让全部气泡一起闪。 */
.msg.local, .msg.typing { animation: skai-msg-in .22s ease-out both; }
@keyframes skai-msg-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

.composer { padding-top: 12px; }
.composer .box {
  background: var(--card-bg); border: 1px solid var(--rule); border-radius: 20px;
  box-shadow: 0 1px 2px rgba(16, 24, 40, .04), 0 16px 40px -24px rgba(16, 24, 40, .35);
  padding: 14px 18px 12px;
}
.composer .box:hover { border-color: var(--rule-strong); }
.composer .box:focus-within { background: var(--card-bg); border-color: var(--brand); box-shadow: var(--ring), 0 16px 40px -24px rgba(16, 24, 40, .35); }
.composer .cbar .btn.pri { border-radius: 999px; height: 36px; padding: 0 20px; }
.cbar .cbtn { border-radius: 8px; transition: background .16s ease, color .16s ease; }
.cbar .cbtn:hover { background: var(--surface-3); }
.mention-pop, .fwd-pop { box-shadow: var(--shadow-2); }
.inline-card { margin-top: 12px; }

/* ---- 数字方块 / 状态 ---- */
.stat { border-color: transparent; }
.chip { box-shadow: inset 0 0 0 1px rgba(16, 24, 40, .04); }
.kind.ai { box-shadow: 0 1px 2px rgba(11, 125, 66, .25); }

/* ---- 说明块：左侧一条极细的色条，把「这是说明」从正文里分出来 ---- */
.note { box-shadow: var(--shadow-inset); border-color: var(--rule); }
details.note.hint > .hint-body { box-shadow: var(--shadow-inset); }

/* ---- 表格 / 空态 / 拦截屏 ---- */
.tbl-wrap { border: 1px solid var(--rule); }
.searchbox { box-shadow: var(--shadow-3), 0 0 0 1px rgba(16, 24, 40, .06); }
.toast { box-shadow: var(--shadow-2); }

/* ==========================================================================
   v6 · 圆润 / 彩色 / 会话感（2026-09-21，老板：「UI 还要升级，重点参考 Teamily / muse」）

   v5 之后有层次了，但和参考图并排一看还差一档「产品感」。参考图（Teamily 桌面端四张、
   muse 一张）抽出来的五条，每一条都是**形**而不是新组件：

     圆     卡片 16–20px、气泡 18px、按钮胶囊、头像正圆。v4 的 10–12px 圆角在大面积白卡上
            读起来仍是「面板」，圆角放大一档，卡片才像「一张张」。
     色     头像从「饱和底 + 白字」换成 **柔和彩底 + 同色深字**（Teamily 每个 agent 一个
            淡彩圆）。饱和圆在会话列表里一排下来太重，柔彩才让名字成为主角。
     底     聊天流铺一层**极淡的绿灰**，AI 白卡气泡、我的绿气泡、日期胶囊全从这层底上跳出来
            （微信 / Teamily 都是这么分「对话区」和「其他区」的）。
     件     输入区是一张**独立的大圆卡**：字在上，工具条在下，发送是绿色胶囊；
            工具条图标从 emoji 换成描边线条；Rail 图标同样换描边，选中态改淡绿底 + 绿图标
            （实心绿块太像「按钮被按住」）。
     引     刚开始的 AI 私聊里放一张「试试这样开头」的引导卡（三行、可点、填进输入框）——
            空态不再是一句「这里还没有人说过话」。

   仍然全部是对 v4/v5 的**覆盖**：类名与 DOM 不动（三套判据脚本查的是类名与结构），
   暗色两块令牌逐字一致。绿仍然只做色块与主操作，字永远近黑。
   ========================================================================== */

:root {
  --r-m: 12px; --r-l: 14px; --r-xl: 18px; --radius: 18px; --radius-sm: 12px;
  --stream-bg: #f1f7f2;
  --body-bg: #f6f8f9;
  --daysep-bg: rgba(16, 24, 40, .07);
  --mine-grad: linear-gradient(135deg, #ddf7e3 0%, #cdefd7 100%);
  --bubble-shadow: 0 1px 2px rgba(16, 24, 40, .05), 0 6px 18px -12px rgba(16, 24, 40, .22);
  /* 柔彩头像：底是该色相的淡彩，字是该色相的深色（白底上字色对比 ≥ 5:1，淡彩上 ≥ 4.5:1） */
  --t-a-bg: #e2e8ff; --t-a-fg: #2e45c4;
  --t-b-bg: #ece3ff; --t-b-fg: #6132d0;
  --t-c-bg: #ffe6d8; --t-c-fg: #a8421a;
  --t-d-bg: #d7f2ec; --t-d-fg: #0b6553;
  --t-ai1-bg: #e9e1ff; --t-ai1-fg: #5a2fc9;
  --t-ai2-bg: #d8f0f4; --t-ai2-fg: #0a6776;
  --t-ai3-bg: #fde1ed; --t-ai3-fg: #ab2f69;
  --t-ai4-bg: #fbecd0; --t-ai4-fg: #85570d;
  --t-ai5-bg: #e3e6ff; --t-ai5-fg: #3846bd;
  /* 人的默认头像后端按法位哈希到 a–h 八种，v4 只画了 a–d（e–h 全掉回默认蓝）；补齐后四种 */
  --t-e-bg: #fde3e6; --t-e-fg: #b0303f;
  --t-f-bg: #fdefd0; --t-f-fg: #8a5a06;
  --t-g-bg: #dbeefc; --t-g-fg: #1f5f9e;
  --t-h-bg: #dff5e3; --t-h-fg: #17683a;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --t-e-bg: #5a2130; --t-e-fg: #ffc9d1;
    --t-f-bg: #4f3a0c; --t-f-fg: #f7e0a6;
    --t-g-bg: #173a5a; --t-g-fg: #bfe0ff;
    --t-h-bg: #14402a; --t-h-fg: #b9f0cb;
    --stream-bg: #0e1411;
    --body-bg: #121518;
    --daysep-bg: rgba(255, 255, 255, .08);
    --mine-grad: linear-gradient(135deg, #1a3f2c 0%, #153524 100%);
    --bubble-shadow: 0 1px 2px rgba(0, 0, 0, .35), 0 8px 22px -14px rgba(0, 0, 0, .6);
    --t-a-bg: #26307a; --t-a-fg: #c9d2ff;
    --t-b-bg: #3a2a74; --t-b-fg: #dccdff;
    --t-c-bg: #5c2e18; --t-c-fg: #ffd3bf;
    --t-d-bg: #12433a; --t-d-fg: #bdeee2;
    --t-ai1-bg: #362470; --t-ai1-fg: #d8c9ff;
    --t-ai2-bg: #123f47; --t-ai2-fg: #bfe8ef;
    --t-ai3-bg: #5a1f3d; --t-ai3-fg: #ffcbe0;
    --t-ai4-bg: #4d3610; --t-ai4-fg: #f6dfa8;
    --t-ai5-bg: #262f7a; --t-ai5-fg: #cbd1ff;
  }
}

:root[data-theme="dark"] {
  --t-e-bg: #5a2130; --t-e-fg: #ffc9d1;
  --t-f-bg: #4f3a0c; --t-f-fg: #f7e0a6;
  --t-g-bg: #173a5a; --t-g-fg: #bfe0ff;
  --t-h-bg: #14402a; --t-h-fg: #b9f0cb;
  --stream-bg: #0e1411;
  --body-bg: #121518;
  --daysep-bg: rgba(255, 255, 255, .08);
  --mine-grad: linear-gradient(135deg, #1a3f2c 0%, #153524 100%);
  --bubble-shadow: 0 1px 2px rgba(0, 0, 0, .35), 0 8px 22px -14px rgba(0, 0, 0, .6);
  --t-a-bg: #26307a; --t-a-fg: #c9d2ff;
  --t-b-bg: #3a2a74; --t-b-fg: #dccdff;
  --t-c-bg: #5c2e18; --t-c-fg: #ffd3bf;
  --t-d-bg: #12433a; --t-d-fg: #bdeee2;
  --t-ai1-bg: #362470; --t-ai1-fg: #d8c9ff;
  --t-ai2-bg: #123f47; --t-ai2-fg: #bfe8ef;
  --t-ai3-bg: #5a1f3d; --t-ai3-fg: #ffcbe0;
  --t-ai4-bg: #4d3610; --t-ai4-fg: #f6dfa8;
  --t-ai5-bg: #262f7a; --t-ai5-fg: #cbd1ff;
}

/* ---- Rail：白底、圆 App 标、描边图标、淡绿选中 ---- */
.rail { background: var(--surface); padding-top: 16px; gap: 6px; }
.rail .appmark {
  width: 38px; height: 38px; border-radius: 50%; margin-bottom: 14px;
  background: var(--pri-grad); color: #fff;
  box-shadow: 0 6px 16px -8px rgba(11, 125, 66, .7), inset 0 1px 0 rgba(255, 255, 255, .25);
}
.rail .appmark svg { width: 22px; height: 22px; }
.rail-btn { width: 44px; height: 44px; border-radius: 14px; color: var(--ink-3); }
.rail-btn svg { width: 22px; height: 22px; }
.rail-btn:hover { background: var(--surface-3); color: var(--ink); }
.rail-btn.on, .rail-btn.on:hover {
  background: var(--brand-100); color: var(--brand); box-shadow: none;
}
.rail-tail .rail-btn.on { background: var(--brand-100); color: var(--brand); }
.rail-btn .bdg { top: 2px; right: 2px; }
.rail-me { width: 38px; height: 38px; margin-top: 10px; }

/* ---- 左栏：胶囊搜索、大头像会话行、圆角选中卡 ---- */
.nav { background: var(--surface); }
.nav-search .input {
  height: 36px; border-radius: 999px; border-color: transparent;
  background-color: var(--surface-3); box-shadow: none; padding-left: 34px; font-size: 13.5px;
}
.nav-search .input:hover { background-color: var(--surface-3); border-color: var(--rule-strong); }
.nav-search .input:focus { background-color: var(--surface); border-color: var(--brand-300); box-shadow: var(--ring); }
.nav-item { border-radius: 12px; }
.nav-item.on::before { display: none; }
.nav-item.on { box-shadow: none; background: var(--brand-50); }
.conv { border-radius: 16px; padding: 10px 12px; gap: 12px; }
.conv .av { width: 46px; height: 46px; font-size: 17px; box-shadow: none; }
.conv.on .av { box-shadow: none; }
.conv.on { background: var(--brand-50); box-shadow: none; }
.conv.on::before { display: none; }
.conv .t1 { font-size: 14.5px; }
.conv .t2 { font-size: 12.5px; }
.conv .rt .tm { font-size: 11.5px; }
.conv .unread, .nav-item .unread { background: var(--brand); color: var(--on-state); }

/* ---- 头像：柔彩底 + 同色深字，正圆；AI 角标改成实心绿圆 ---- */
.av, .av[class*="tone-"] {
  background-image: none; font-weight: 700;
  box-shadow: inset 0 0 0 1px rgba(16, 24, 40, .06);
}
.av, .av.tone-a { background-color: var(--t-a-bg); color: var(--t-a-fg); }
.av.tone-b { background-color: var(--t-b-bg); color: var(--t-b-fg); }
.av.tone-c { background-color: var(--t-c-bg); color: var(--t-c-fg); }
.av.tone-d { background-color: var(--t-d-bg); color: var(--t-d-fg); }
.av.tone-e { background-color: var(--t-e-bg); color: var(--t-e-fg); }
.av.tone-f { background-color: var(--t-f-bg); color: var(--t-f-fg); }
.av.tone-g { background-color: var(--t-g-bg); color: var(--t-g-fg); }
.av.tone-h { background-color: var(--t-h-bg); color: var(--t-h-fg); }
.av.tone-ai1 { background-color: var(--t-ai1-bg); color: var(--t-ai1-fg); }
.av.tone-ai2 { background-color: var(--t-ai2-bg); color: var(--t-ai2-fg); }
.av.tone-ai3 { background-color: var(--t-ai3-bg); color: var(--t-ai3-fg); }
.av.tone-ai4 { background-color: var(--t-ai4-bg); color: var(--t-ai4-fg); }
.av.tone-ai5 { background-color: var(--t-ai5-bg); color: var(--t-ai5-fg); }
.av.has-img, .av.has-img[class*="tone-"] { box-shadow: 0 1px 2px rgba(16, 24, 40, .16); }
.av.grp { box-shadow: 0 1px 2px rgba(16, 24, 40, .12); }
.av.is-ai::after { border-radius: 50%; background-color: var(--brand); border-color: var(--surface); }
.av.l.is-ai::after { width: 18px; height: 18px; border-width: 2.5px; right: -1px; bottom: -1px; }
/* 九宫格里的小格子也换柔彩 */
.av.grp .cell.tone-a { background: var(--t-a-bg); color: var(--t-a-fg); }
.av.grp .cell.tone-b { background: var(--t-b-bg); color: var(--t-b-fg); }
.av.grp .cell.tone-c { background: var(--t-c-bg); color: var(--t-c-fg); }
.av.grp .cell.tone-d { background: var(--t-d-bg); color: var(--t-d-fg); }
.av.grp .cell.tone-e { background: var(--t-e-bg); color: var(--t-e-fg); }
.av.grp .cell.tone-f { background: var(--t-f-bg); color: var(--t-f-fg); }
.av.grp .cell.tone-g { background: var(--t-g-bg); color: var(--t-g-fg); }
.av.grp .cell.tone-h { background: var(--t-h-bg); color: var(--t-h-fg); }
.av.grp .cell.tone-ai1 { background: var(--t-ai1-bg); color: var(--t-ai1-fg); }
.av.grp .cell.tone-ai2 { background: var(--t-ai2-bg); color: var(--t-ai2-fg); }
.av.grp .cell.tone-ai3 { background: var(--t-ai3-bg); color: var(--t-ai3-fg); }
.av.grp .cell.tone-ai4 { background: var(--t-ai4-bg); color: var(--t-ai4-fg); }
.av.grp .cell.tone-ai5 { background: var(--t-ai5-bg); color: var(--t-ai5-fg); }

/* ---- 主区：标题带更轻，正文底更淡 ---- */
.main-head { padding: 16px 24px 14px; box-shadow: none; }
.title { font-size: 22px; }
.main-head .title .chip { font-size: 12px; }
.head-actions .btn { border-radius: 999px; height: 34px; }

/* ---- 聊天流：淡绿底、白卡气泡、绿气泡、胶囊日期 ---- */
.stream { gap: 14px; padding: 20px 24px 14px; }
.msg { gap: 10px; }
.msg .av { width: 36px; height: 36px; font-size: 14px; }
.msg .mh { margin-bottom: 4px; gap: 7px; }
.msg .mh .nm { font-size: 13px; color: var(--ink-2); }
.msg .mh .tm { font-size: 11px; }
.msg .mb {
  border: 0; border-radius: 4px 18px 18px 18px; padding: 11px 15px;
  background: var(--card-bg); box-shadow: var(--bubble-shadow); font-size: 14.5px; line-height: 1.65;
}
.msg:has(.kind.ai) .mb { background: var(--card-bg); }
.msg.me .mb {
  background: var(--mine-grad); border: 0; border-radius: 18px 4px 18px 18px;
  box-shadow: 0 1px 2px rgba(11, 125, 66, .08), 0 6px 18px -12px rgba(11, 125, 66, .35);
}
.msg.me .mh .nm { display: none; }
.msg.sys .mb { box-shadow: none; }
.msg.sys.recalled .mb, .msg.sys .mb { background: none; }
.daysep { border: 0; background: var(--daysep-bg); box-shadow: none; border-radius: 999px; font-size: 12px; padding: 4px 12px; }
.kind.ai { border-radius: 6px; box-shadow: none; font-size: 10.5px; }
.kind.src { border-radius: 6px; }

/* 引导卡（新 AI 私聊） */
.starter {
  align-self: flex-start; width: min(560px, 100%); margin-left: 46px;
  background: var(--card-bg); border-radius: 20px; padding: 16px 14px 10px;
  box-shadow: var(--bubble-shadow);
}
.starter-t { font-weight: 600; font-size: 14px; color: var(--ink); padding: 0 4px 6px; }
.starter-row {
  display: flex; align-items: center; gap: 12px; width: 100%; text-align: left;
  border: 1px solid var(--rule); background: var(--surface); border-radius: 14px;
  padding: 11px 12px 11px 12px; margin: 0 0 8px; cursor: pointer; font: inherit; color: var(--ink);
  transition: transform .16s ease, box-shadow .16s ease, border-color .16s ease;
}
.starter-row:hover { border-color: var(--brand-300); transform: translateY(-1px); box-shadow: var(--shadow-card-h); }
.starter-row:active { transform: none; }
.starter-ic { flex: 0 0 auto; width: 32px; height: 32px; border-radius: 10px; background: var(--brand-50); display: grid; place-items: center; font-size: 15px; }
.starter-q { flex: 1 1 auto; font-size: 14px; }
.starter-go {
  flex: 0 0 auto; width: 28px; height: 28px; border-radius: 50%;
  background: var(--pri-grad); color: var(--on-state); display: grid; place-items: center; font-size: 14px; font-weight: 700;
}
@media (max-width: 640px) { .starter { margin-left: 0; } }

/* ---- 输入区：一张独立的大圆卡，坐在聊天流的底色上 ---- */
.composer { padding: 8px 24px 20px; background: var(--stream-bg); border-top: 0; }
.composer .box {
  border-radius: 22px; border: 1px solid var(--rule); padding: 14px 16px 10px 18px;
  box-shadow: 0 2px 6px rgba(16, 24, 40, .04), 0 18px 44px -26px rgba(16, 24, 40, .38);
}
.composer .box:focus-within { border-color: var(--brand-300); box-shadow: var(--ring), 0 18px 44px -26px rgba(16, 24, 40, .38); }
.composer textarea { font-size: 14.5px; }
.composer .cbar { gap: 4px; padding-top: 6px; }
.cbar .cbtn {
  width: 34px; height: 34px; border-radius: 10px; display: inline-grid; place-items: center;
  color: var(--ink-3); font-size: 15px; font-weight: 600; cursor: pointer; border: 0; background: transparent;
}
.cbar .cbtn .ci { width: 20px; height: 20px; display: block; }
.cbar .cbtn:hover { background: var(--brand-50); color: var(--brand); }
.composer .hint { margin-left: 8px; font-size: 11.5px; color: var(--ink-4); }
.composer .cbar .btn.pri { border-radius: 999px; height: 38px; padding: 0 22px; font-weight: 600; font-size: 14px; }
.composer.closed .box { box-shadow: none; background: var(--surface-2); }

/* ---- 卡片 / 按钮：圆角放大一档，主按钮胶囊 ---- */
.card, .hcard, .inline-card, .empty, .step, .tbl-wrap, .stat, .jp-card { border-radius: 16px; }
.row { border-radius: 14px; }
.btn { border-radius: 12px; }
.btn.pri, .btn.brand { border-radius: 999px; }
.btn.sm { border-radius: 999px; }
.tab { border-radius: 999px; }
.drawer-note, .note { border-radius: 14px; }

/* ---- AI 广场：大圆头像、胶囊按钮、圆卡 ---- */
.square { gap: 16px; }
.ai-card { border-radius: 20px; padding: 24px 16px 18px; border-color: var(--rule); }
.ai-card .av.l { width: 72px; height: 72px; font-size: 28px; border-radius: 50%; margin-bottom: 6px; }
.ai-card .ac-name { font-size: 15.5px; }
.ai-card .ac-act .btn { border-radius: 999px; }

/* ---- 老板 9-21 截图：「这里不要一层一层的，很不协调」——输入区外面不再套白带（上面已改成
   单张卡坐在聊天底色上），右侧抽屉也不再压一道投影当「另一层」，改成一条发丝线与主区平接；
   抽屉里的说明块同样去掉内影，整栏只有一个白。 ---- */
.drawer { box-shadow: none; border-left: 1px solid var(--rule); }
.drawer-note { box-shadow: none; background: var(--surface-2); }
.composer .box { box-shadow: 0 1px 2px rgba(16, 24, 40, .04), 0 8px 24px -18px rgba(16, 24, 40, .25); }
.main-body:has(> .stream), .main-body:has(> .thread) { border-bottom: 0; }

/* ==========================================================================
   v7 · Inbox 风（2026-09-21 中午，老板发来第二张参考图：「按这个风格来，我们的布局不变，
   就是模块颜色、风格、icon 等等按这个来」；并指着抽屉：「按图 2 重新排版，点击状态也太僵硬了，
   最下面的小话也可以去掉」）

   这张参考图和上午那套 Teamily 走的是两个方向，v7 覆盖 v6 里冲突的部分：

     底     全白。聊天流不再铺绿底，栏与栏之间只有发丝线，卡片没有投影。
     色     近黑做主操作（主按钮、发送键、Rail 选中块、未读数），**亮绿只做点缀**
            （Rail 选中块里的图标、在线点、选中行左侧的细条、对方气泡的淡绿底）。
     形     圆角收回 8–12px，头像正圆，色块是「浅灰圆角行」而不是白卡。
     气泡   对方（含 AI）＝淡绿底，我的＝浅灰底，都没有边框和影。
     按钮   点下去不再位移、不再变影，只是底色深一档（老板：「点击状态太僵硬」）。
     抽屉   头像＋名字一行 → 一排动作（主动作近黑）→ 浅灰信息行 → 「设置」列表；
            默认那句「关闭这个抽屉不会改变任何业务状态」不再画。

   v6 里保留的：柔彩头像、描边图标、引导卡、独立输入卡（改成白底细边）。
   仍是覆盖层：类名与 DOM 不动，暗色两块令牌逐字一致。
   ========================================================================== */

:root {
  --accent-g: #22c55e;
  --accent-g-bg: #e9f8ee;
  --accent-ring: rgba(34, 197, 94, .22);
  --rail-on-bg: #16181a;
  --stream-bg: #ffffff;
  --body-bg: #ffffff;
  --canvas: #eef0f2;
  --canvas-glow: transparent;
  --mine-bg: #f3f4f6;
  --daysep-bg: #f3f4f6;
  --r-m: 10px; --r-l: 10px; --r-xl: 12px; --radius: 12px; --radius-sm: 8px;
  --shadow-card: none; --shadow-card-h: none; --shadow-1: none; --shadow-inset: none;
  --shadow-drawer: none; --bubble-shadow: none; --pri-shadow: none;
  --shadow-panel: 0 0 0 1px rgba(16, 24, 40, .06), 0 16px 48px -32px rgba(16, 24, 40, .22);
  --pri-grad: var(--pri-bg); --pri-grad-h: var(--pri-bg-h);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --accent-g: #4ade80;
    --accent-g-bg: #14311f;
    --accent-ring: rgba(74, 222, 128, .22);
    --rail-on-bg: #2a2f36;
    --stream-bg: #14171b;
    --body-bg: #14171b;
    --canvas: #0a0c0f;
    --mine-bg: #1f2429;
    --daysep-bg: #1f2429;
    --shadow-panel: 0 0 0 1px rgba(255, 255, 255, .06), 0 16px 48px -32px rgba(0, 0, 0, .6);
  }
}

:root[data-theme="dark"] {
  --accent-g: #4ade80;
  --accent-g-bg: #14311f;
  --accent-ring: rgba(74, 222, 128, .22);
  --rail-on-bg: #2a2f36;
  --stream-bg: #14171b;
  --body-bg: #14171b;
  --canvas: #0a0c0f;
  --mine-bg: #1f2429;
  --daysep-bg: #1f2429;
  --shadow-panel: 0 0 0 1px rgba(255, 255, 255, .06), 0 16px 48px -32px rgba(0, 0, 0, .6);
}

/* ---- 面：全白，只剩线 ---- */
body { background: var(--canvas); }
.shell { box-shadow: var(--shadow-panel); }
.rail, .nav, .main, .drawer { background: var(--surface); }
.main-body { background: var(--body-bg); }
.main-body:has(> .stream), .main-body:has(> .thread) { background: var(--stream-bg); }
.main-head { padding: 14px 22px 12px; }
.title { font-size: 19px; letter-spacing: -.01em; }
.crumb { margin-bottom: 4px; }

/* ---- Rail：绿色 App 标、近黑选中块里一枚绿图标 ---- */
.rail { padding-top: 14px; gap: 4px; }
.rail .appmark { background: transparent; color: var(--accent-g); box-shadow: none; width: 36px; height: 36px; margin-bottom: 10px; }
.rail .appmark svg { width: 24px; height: 24px; }
.rail-btn { width: 38px; height: 38px; border-radius: 10px; color: var(--ink-2); }
.rail-btn svg { width: 20px; height: 20px; }
.rail-btn:hover { background: var(--surface-3); color: var(--ink); }
.rail-btn.on, .rail-btn.on:hover, .rail-tail .rail-btn.on { background: var(--rail-on-bg); color: var(--accent-g); box-shadow: none; }
.rail-btn .bdg { top: -3px; right: -3px; background: var(--block); }
.rail-me { width: 32px; height: 32px; box-shadow: 0 0 0 2px var(--surface), 0 0 0 3px var(--rule); }

/* ---- 左栏：灰底搜索框、行之间发丝线、选中＝淡绿底＋左侧细绿条 ---- */
.nav-search .input { height: 34px; border-radius: 8px; border: 1px solid var(--rule); background-color: var(--surface-2); font-size: 13px; }
.nav-search .input:focus { background-color: var(--surface); border-color: var(--accent-g); box-shadow: 0 0 0 3px var(--accent-ring); }
.nav-item { border-radius: 8px; }
.nav-item.on { background: var(--accent-g-bg); color: var(--ink); }
.nav-item.on .ni, .nav-item.on .n { color: var(--ink); }
.conv { border-radius: 8px; padding: 9px 10px; gap: 10px; }
.conv .av { width: 38px; height: 38px; font-size: 14px; }
.conv.on { background: var(--accent-g-bg); }
.conv.on::before { display: block; top: 6px; bottom: 6px; width: 3px; border-radius: 0 3px 3px 0; background: var(--accent-g); }
.conv .t1 { font-size: 13.5px; }
.conv .t2 { font-size: 12px; }
.conv .unread, .nav-item .unread { background: var(--pri-bg); color: var(--pri-fg); }
.theme-seg { box-shadow: none; background: var(--surface-2); }
.theme-seg button.on { box-shadow: none; border: 1px solid var(--rule); }

/* ---- 头像：AI 角标用亮绿 ---- */
.av.is-ai::after { background-color: var(--accent-g); }
.av, .av[class*="tone-"] { box-shadow: none; }

/* ---- 聊天流：白底；对方淡绿、我的浅灰；都无边无影 ---- */
.stream { gap: 12px; padding: 18px 22px 12px; }
.msg .av { width: 32px; height: 32px; font-size: 13px; }
.msg .mh .nm { font-size: 12.5px; color: var(--ink); font-weight: 600; }
.msg .mb {
  background: var(--accent-g-bg); border: 0; border-radius: 10px; padding: 10px 14px;
  box-shadow: none; font-size: 14px; line-height: 1.6;
}
.msg:has(.kind.ai) .mb { background: var(--accent-g-bg); }
.msg.me .mb { background: var(--mine-bg); border: 0; border-radius: 10px; box-shadow: none; }
.msg.sys .mb, .msg.sys.recalled .mb { background: none; }
.daysep { background: var(--daysep-bg); color: var(--ink-3); border: 0; box-shadow: none; border-radius: 8px; }
.kind.ai { background: var(--pri-bg); color: var(--pri-fg); box-shadow: none; border-radius: 5px; }
.kind.src { background: var(--surface-2); color: var(--ink-3); border-color: var(--rule); border-radius: 5px; }
.msg .macts { box-shadow: 0 6px 18px -10px rgba(16, 24, 40, .3); }

/* 引导卡：白卡细边，箭头是「黑圆绿箭」（和发送键一家） */
.starter { box-shadow: none; border: 1px solid var(--rule); border-radius: 12px; margin-left: 42px; }
.starter-row { border-radius: 10px; }
.starter-row:hover { transform: none; box-shadow: none; border-color: var(--accent-g); background: var(--surface-2); }
.starter-ic { background: var(--surface-2); border-radius: 8px; }
.starter-go { background: var(--pri-bg); color: var(--accent-g); }

/* ---- 输入区：白底细边的一行卡，发送键是近黑方块 ---- */
.composer { background: var(--surface); border-top: 1px solid var(--rule); padding: 12px 22px 16px; }
.composer .box {
  border-radius: 12px; border: 1px solid var(--rule-strong); box-shadow: none;
  padding: 10px 12px 8px 14px; background: var(--surface);
}
.composer .box:hover { border-color: var(--ink-4); }
.composer .box:focus-within { border-color: var(--accent-g); box-shadow: 0 0 0 3px var(--accent-ring); }
.composer textarea { font-size: 14px; }
.cbar .cbtn { width: 32px; height: 32px; border-radius: 8px; color: var(--ink-3); }
.cbar .cbtn .ci { width: 19px; height: 19px; }
.cbar .cbtn:hover { background: var(--surface-2); color: var(--ink); }
.composer .cbar .btn.pri {
  background: var(--pri-bg); color: var(--pri-fg); border-color: var(--pri-bg);
  border-radius: 10px; height: 38px; padding: 0 18px; box-shadow: none; font-weight: 600;
}
.composer .cbar .btn.pri:hover { background: var(--pri-bg-h); border-color: var(--pri-bg-h); color: var(--pri-fg); box-shadow: none; }
.composer.closed .box { background: var(--surface-2); border-color: var(--rule); }

/* ---- 按钮：点下去只变底色，不位移、不变影（老板：「点击状态太僵硬」） ---- */
.btn {
  border-radius: 10px; box-shadow: none; background: var(--surface); border: 1px solid var(--rule-strong); color: var(--ink);
  transition: background .15s ease, border-color .15s ease, color .15s ease;
}
.btn:hover { background: var(--surface-2); border-color: var(--rule-strong); color: var(--ink); }
.btn:active { transform: none; box-shadow: none; background: var(--surface-3); }
.btn.pri, .btn.brand { background: var(--pri-bg); color: var(--pri-fg); border-color: var(--pri-bg); border-radius: 10px; box-shadow: none; }
.btn.pri:hover, .btn.brand:hover { background: var(--pri-bg-h); border-color: var(--pri-bg-h); color: var(--pri-fg); box-shadow: none; }
.btn.pri:active, .btn.brand:active { transform: none; box-shadow: none; background: var(--pri-bg-h); }
.btn.sm { border-radius: 8px; }
.btn.danger { background: var(--surface); color: var(--block); border-color: var(--rule-strong); }
.btn.danger:hover { background: var(--block-tint); border-color: var(--block-tint); }
.btn.ghost { border-color: transparent; background: transparent; }
.btn[disabled], .btn.off { background: var(--surface-2); color: var(--ink-4); border-color: var(--rule); }
.icon-btn:active { transform: none; }
.hcard:not(:has(.c1 .chip.need)) .ca .btn.pri { background: var(--surface); color: var(--ink); border-color: var(--rule-strong); box-shadow: none; }
.hcard:not(:has(.c1 .chip.need)) .ca .btn.pri:hover { background: var(--surface-2); }
.head-actions .btn { border-radius: 10px; }
.tab { border-radius: 8px; }
.tab.on { box-shadow: none; border: 1px solid var(--rule); }

/* ---- 卡片 / 行：细边圆角，不浮 ---- */
.card, .hcard, .row, .empty, .step, .split > div, .inline-card, .tbl-wrap, .ai-card, .stat, .jp-card {
  box-shadow: none; border-radius: 12px; border: 1px solid var(--rule);
}
.card:hover, .hcard:hover, .ai-card:hover, a.stat:hover, .row:hover { transform: none; box-shadow: none; border-color: var(--rule-strong); }
.card.sub { box-shadow: none; background: var(--surface-2); border-color: transparent; }
.card.sub:hover { box-shadow: none; }
.note, .drawer-note, details.note.hint > .hint-body { box-shadow: none; border-radius: 10px; background: var(--surface-2); }
.input, .field input[type="text"], .field input[type="email"], .field input[type="password"], .field textarea, .field select {
  box-shadow: none; border-radius: 10px;
}
.input:focus, .field input:focus, .field textarea:focus, .field select:focus { border-color: var(--accent-g); box-shadow: 0 0 0 3px var(--accent-ring); }
.pick { box-shadow: none; }
.chip { box-shadow: none; }

/* ---- AI 广场 ---- */
.square { gap: 12px; }
.ai-card { border-radius: 12px; padding: 20px 14px 16px; }
.ai-card .av.l { width: 64px; height: 64px; font-size: 24px; }
.ai-card .ac-act .btn { border-radius: 10px; }

/* ---- 抽屉：头像行 → 动作 → 浅灰信息行 → 设置列表 ---- */
.drawer { border-left: 1px solid var(--rule); box-shadow: none; }
.drawer-head { border-bottom: 1px solid var(--rule); padding-bottom: 12px; margin-bottom: 14px; }
.dr-head { display: flex; align-items: center; gap: 12px; margin-bottom: 12px; }
.dr-head .av.l { width: 48px; height: 48px; font-size: 18px; }
.dr-id { min-width: 0; }
.dr-name { font-weight: 700; font-size: 15px; color: var(--ink); }
.dr-handle { font-size: 12.5px; color: var(--ink-3); margin-top: 2px; }
.dr-bio { font-size: 13.5px; color: var(--ink-2); line-height: 1.6; margin: 0 0 14px; }
.dr-acts { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 16px; }
.dr-acts .btn.pri { flex: 1 1 auto; }
.dr-stats { display: flex; flex-direction: column; gap: 8px; margin-bottom: 18px; }
.dr-stat {
  display: flex; align-items: center; gap: 10px;
  background: var(--surface-2); border-radius: 10px; padding: 8px 12px 8px 8px; font-size: 13.5px;
}
.dr-ic {
  flex: 0 0 auto; width: 28px; height: 28px; border-radius: 8px;
  background: var(--surface); border: 1px solid var(--rule); color: var(--ink-3);
  display: grid; place-items: center;
}
.dr-ic .ci { width: 15px; height: 15px; }
.dr-stat .k { color: var(--ink-2); font-weight: 600; }
.dr-stat .v { margin-left: auto; color: var(--ink); display: inline-flex; align-items: center; gap: 6px; }
.dot.ok { width: 7px; height: 7px; border-radius: 50%; background: var(--accent-g); display: inline-block; }
.dr-sec { font-size: 12px; font-weight: 700; color: var(--ink-2); margin: 4px 0 6px; }
.dr-list { display: flex; flex-direction: column; gap: 2px; }
.dr-list .btn {
  justify-content: flex-start; width: 100%; background: transparent; border: 0;
  border-radius: 8px; height: 40px; padding: 0 10px; font-size: 13.5px; color: var(--ink); font-weight: 500;
}
.dr-list .btn:hover { background: var(--surface-2); }
.dr-list .btn.danger { color: var(--block); background: transparent; }
.dr-list .btn.danger:hover { background: var(--block-tint); }
.starter-ic .ci { width: 17px; height: 17px; }
.dr-list a.btn { text-decoration: none; }
.dr-list .btn.sm { height: 40px; border-radius: 8px; }

/* ---- 群聊右栏照微信（老板 2026-09-21）：搜索 → 成员九宫格 → 信息行 → 开关 → 危险动作 ---- */
.dr-search { padding: 0 0 12px; }
.dr-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px 6px; margin: 0 0 6px; }
.dr-grid .dr-m {
  display: flex; flex-direction: column; align-items: center; gap: 6px; min-width: 0;
  text-decoration: none; color: var(--ink-2); font-size: 12px; border-radius: 8px; padding: 4px 2px;
}
.dr-grid .dr-m:hover { background: var(--surface-2); color: var(--ink); }
.dr-grid .dr-m .av { width: 44px; height: 44px; font-size: 16px; border-radius: 10px; }
.dr-grid .dr-m .av.is-ai::after { width: 14px; height: 14px; border-radius: 4px; }
.dr-grid .dr-mn { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; text-align: center; line-height: 1.3; }
.dr-grid .dr-plus {
  width: 44px; height: 44px; border-radius: 10px; border: 1px dashed var(--rule-strong, var(--rule));
  display: grid; place-items: center; color: var(--ink-3); background: var(--surface);
}
.dr-grid .dr-plus .ci { width: 20px; height: 20px; }
/* 三行之外的成员折起来；「查看更多」展开，或者搜索的时候全部参与 */
.dr-grid .dr-m.more { display: none; }
.dr-grid.open .dr-m.more, .dr-grid.searching .dr-m.more { display: flex; }
.dr-grid .dr-m.is-hidden { display: none; }
.dr-grid.searching .dr-add { display: none; }
.dr-more {
  display: flex; align-items: center; justify-content: center; gap: 4px; width: 100%;
  height: 32px; border: 0; background: transparent; color: var(--ink-3); font-size: 12.5px; cursor: pointer;
  border-radius: 8px; margin: 0 0 8px;
}
.dr-more:hover { background: var(--surface-2); color: var(--ink); }
.dr-more .ci { width: 14px; height: 14px; }
.dr-grid.open + .dr-more { display: none; }

.dr-kvs { display: flex; flex-direction: column; margin: 8px 0 0; padding: 4px 0; border-top: 1px solid var(--rule); }
.dr-kvs > .dr-kv, .dr-kvs > .btn.sw, .dr-kvs > .btn.row {
  display: flex; align-items: center; gap: 10px; min-height: 44px; padding: 8px 6px;
  text-decoration: none; color: var(--ink); font-size: 13.5px; font-weight: 500; border-radius: 8px;
}
.dr-kvs > a.dr-kv:hover, .dr-kvs > .btn.sw:hover, .dr-kvs > .btn.row:hover { background: var(--surface-2); }
.dr-kv .k { flex: 0 0 auto; color: var(--ink); }
.dr-kv .v {
  flex: 1 1 auto; min-width: 0; text-align: right; color: var(--ink-3); font-weight: 400;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.dr-kv .v.chev { display: inline-flex; justify-content: flex-end; }
.dr-kv .v.chev .ci { width: 16px; height: 16px; }
/* 群号那一行点开是二维码 */
.dr-kvs > details.dr-kv { display: block; padding: 0; }
details.dr-kv > summary { display: flex; align-items: center; gap: 10px; min-height: 44px; padding: 8px 6px; cursor: pointer; list-style: none; border-radius: 8px; }
details.dr-kv > summary::-webkit-details-marker { display: none; }
details.dr-kv > summary:hover { background: var(--surface-2); }
details.dr-kv > .qr-box, details.dr-kv > .qr-cap { margin: 4px 6px 12px; }
details.dr-kv > .qr-cap { font-size: 12px; color: var(--ink-3); }
/* 整行开关：文字在左，右边一枚滑块。整行都是那颗按钮。 */
.dr-kvs > .btn.sw {
  position: relative; width: 100%; height: auto; justify-content: flex-start; border: 0; background: transparent;
  padding-right: 54px; font-size: 13.5px; font-weight: 500; color: var(--ink);
}
.dr-kvs > .btn.sw::after {
  content: ""; position: absolute; right: 8px; top: 50%; transform: translateY(-50%);
  width: 38px; height: 22px; border-radius: 11px; background: var(--ink-5, #c9ccd1);
  transition: background .16s ease;
}
.dr-kvs > .btn.sw::before {
  content: ""; position: absolute; right: 8px; top: 50%; z-index: 1;
  width: 18px; height: 18px; border-radius: 50%; background: #fff; box-shadow: 0 1px 2px rgba(0,0,0,.25);
  transform: translate(-18px, -50%); transition: transform .16s ease;
}
.dr-kvs > .btn.sw.on::after { background: var(--brand-400); }
.dr-kvs > .btn.sw.on::before { transform: translate(-2px, -50%); }
/* 危险动作：一整行、红字、居中（微信「退出群聊」） */
.dr-kvs > .btn.row { width: 100%; height: auto; border: 0; background: transparent; justify-content: center; }
.dr-kvs > .btn.row.danger { color: var(--block); }
.dr-kvs > .btn.row.danger:hover { background: var(--block-tint); }

/* ---- 「聊天」没选中任何会话时的中间区域（微信留白）---- */
.chat-empty {
  min-height: 60vh; display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 10px; text-align: center; padding: 40px 24px; color: var(--ink-3);
}
.chat-empty .ce-ic { width: 56px; height: 56px; border-radius: 16px; background: var(--surface-2); display: grid; place-items: center; color: var(--ink-4); margin-bottom: 4px; }
.chat-empty .ce-ic .ci { width: 26px; height: 26px; }
.chat-empty .ce-t { font-size: 15px; font-weight: 600; color: var(--ink-2); }
.chat-empty .ce-d { max-width: 30rem; font-size: 13.5px; line-height: 1.7; margin: 0; }
.chat-empty .btn-row { justify-content: center; margin-top: 8px; }

/* ---- 群右栏 9-22：就地加人 / 就地改 ---- */
.dr-grid button.dr-m { border: 0; background: transparent; font: inherit; cursor: pointer; }
.dr-grid.open + .dr-more { display: none; }
.dr-picker { display: none; margin: 4px 0 10px; padding: 8px 10px 6px; border: 1px solid var(--rule); border-radius: 10px; background: var(--surface-2); }
.dr-picker.open { display: block; }
.dr-picker .dr-sec { margin: 0 0 6px; }
.dr-picker .dr-hint { font-size: 12.5px; color: var(--ink-3); line-height: 1.6; margin: 0 0 4px; }
.dr-cand { display: flex; align-items: center; gap: 10px; padding: 6px 0; }
.dr-cand + .dr-cand { border-top: 1px solid var(--rule); }
.dr-cand .bd { flex: 1 1 auto; min-width: 0; }
.dr-cand .t { display: block; font-size: 13.5px; font-weight: 500; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dr-cand .d { display: block; font-size: 12px; color: var(--ink-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dr-cand .btn.sm { height: 30px; padding: 0 12px; }
/* 点一行展开就地改：输入框 + 一颗保存 */
.dr-kvs > details.dr-edit > summary .chev { flex: 0 0 auto; display: inline-flex; color: var(--ink-4); transition: transform .16s ease; }
.dr-kvs > details.dr-edit > summary .chev .ci { width: 16px; height: 16px; }
.dr-kvs > details.dr-edit[open] > summary .chev { transform: rotate(90deg); }
.dr-kvs > details.dr-edit > summary .v { flex: 1 1 auto; }
.dr-kvs > details.dr-kv > summary .chev { flex: 0 0 auto; display: inline-flex; color: var(--ink-4); }
.dr-kvs > details.dr-kv > summary .chev .ci { width: 16px; height: 16px; }
.dr-edit-body { display: flex; flex-direction: column; gap: 8px; padding: 2px 6px 12px; }
.dr-edit-body .input { width: 100%; box-sizing: border-box; font-size: 13.5px; }
.dr-edit-body textarea.input { resize: vertical; min-height: 64px; }
.dr-edit-body .btn { align-self: flex-end; }
.dr-edit-body .dr-full { margin: 0; font-size: 13px; line-height: 1.6; color: var(--ink-2); white-space: pre-wrap; }

/* ---- 通讯录中间那块：名片（微信）---- */
.contact-card { max-width: 40rem; padding-top: 28px; }
.cc-head { display: flex; align-items: flex-start; gap: 18px; margin-bottom: 22px; }
.cc-head .av.l { width: 72px; height: 72px; font-size: 26px; border-radius: 16px; }
.cc-id { min-width: 0; padding-top: 4px; }
.cc-name { font-size: 20px; font-weight: 700; color: var(--ink); display: flex; align-items: center; gap: 8px; }
.cc-handle { font-size: 13.5px; color: var(--ink-3); margin-top: 4px; }
.cc-bio { font-size: 13.5px; color: var(--ink-2); line-height: 1.6; margin-top: 8px; }
.cc-kvs { border-top: 1px solid var(--rule); border-bottom: 1px solid var(--rule); padding: 6px 0; margin-bottom: 22px; }
.cc-kv { display: flex; gap: 16px; min-height: 40px; align-items: center; font-size: 13.5px; }
.cc-kv .k { flex: 0 0 8em; color: var(--ink-3); }
.cc-kv .v { flex: 1 1 auto; min-width: 0; color: var(--ink); }
.cc-acts { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }
.cc-acts.center { justify-content: center; margin-top: 26px; }
.cc-acts .btn.pri { min-width: 120px; }
.cg-title { font-size: 18px; font-weight: 700; color: var(--ink); margin: 0 0 22px; }
.cg-title .cg-n { font-weight: 500; color: var(--ink-3); }
.contact-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(84px, 1fr)); gap: 18px 8px; }
.contact-grid .dr-m {
  display: flex; flex-direction: column; align-items: center; gap: 8px; min-width: 0;
  text-decoration: none; color: var(--ink-2); font-size: 12.5px; border-radius: 10px; padding: 6px 2px;
}
.contact-grid .dr-m:hover { background: var(--surface-2); color: var(--ink); }
.contact-grid .dr-m .av { width: 52px; height: 52px; font-size: 19px; border-radius: 12px; }
.contact-grid .dr-mn { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; text-align: center; }
