
* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
  margin: 0;
  min-width: 320px;
  background: var(--canvas);
  color: var(--ink);
  font-family: Inter, ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
  -webkit-font-smoothing: antialiased;
}
button, input, textarea, select { font: inherit; }
button { -webkit-tap-highlight-color: transparent; }

.app-shell { min-height: 100vh; display: grid; grid-template-columns: 196px minmax(0, 1fr); }   /* 2026-09-29 232→196：大家是 1080 屏，名字最长的「商品·客户·工厂库」照样放得下 */
.sidebar {
  position: sticky;
  top: 0;
  z-index: 20;
  height: 100vh;
  padding: 24px 12px 18px;
  color:#fff;
  background:
    radial-gradient(circle at 20% 95%, rgba(69, 130, 103, .22), transparent 32%),
    var(--sidebar);
  display: flex;
  flex-direction: column;
}
.brand { display: flex; align-items: center; gap: 11px; padding: 1px 8px 27px; }
.brand-mark {
  width: 39px; height: 39px; border-radius: 12px;
  display: grid; place-items: center;
  background:linear-gradient(145deg, var(--d-accent), var(--d-accent));
  color:var(--g-800); font-size: 19px; font-weight: 800;
  box-shadow: 0 7px 20px rgba(129, 218, 164, .18);
}
/* 2026-09-27 公司 logo + 字标。logo 有黑色线条，深色侧栏上必须垫白底。
   字标同日从英文「Kitchen」矢量字形改成中文「KC中台」（用户：标签页和左上角都显示「KC中台 · 赞拓」）：
   真文字 + 同一条白→薄荷渐变（background-clip:text），颜色走 token。 */
.brand-logo {
  flex: 0 0 auto; display: grid; place-items: center;
  padding: 5px 7px; border-radius: 11px; background: var(--n-0);
  box-shadow: 0 7px 20px rgba(0, 0, 0, .22);
}
.brand-logo img { display: block; width: 50px; height: 34px; }
.brand .brand-word {
  font-size: 23px; font-weight: 800; line-height: 1.15; letter-spacing: .03em; white-space: nowrap; color: transparent;
  background: linear-gradient(100deg, var(--d-text) 45%, var(--d-accent));
  -webkit-background-clip: text; background-clip: text;
}
.brand .brand-word + small { margin-top: 5px; letter-spacing: .06em; }
.brand strong, .brand small { display: block; }
.brand strong { font-size: 14px; letter-spacing: .12em; }
.brand small { margin-top: 4px; color:var(--d-text-3); font-size: 12px; letter-spacing: .08em; }
.nav-label { margin: 0 10px 9px; color:var(--d-text-3); font-size: 13px; font-weight: 700; letter-spacing: .16em; }
/* 组标题是按钮（2026-09-28 可收起）：去掉按钮默认样式，右端一个小箭头，展开朝下、收起朝右。
   收起的入口打 data-folded（app.js foldNavGroup），只在桌面侧栏藏；≤900px 的横条没有组标题，不折叠。 */
.nav-label { display: flex; align-items: center; gap: 8px; width: auto; padding: 0; border: 0; background: transparent;
  font-family: inherit; line-height: inherit; text-align: left; cursor: pointer; transition: color .18s; }
.nav-label:hover, .nav-label:focus-visible { color: var(--d-text-2); outline: none; }
.nav-label::after { content: ''; flex: 0 0 auto; margin-left: auto; margin-right: 4px; width: 6px; height: 6px;
  border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor; opacity: .75;
  transform: translateY(-2px) rotate(45deg); transition: transform .18s; }
.nav-label[aria-expanded="false"]::after { transform: translateX(-2px) rotate(-45deg); }
/* 收起的组名后面写「N 个」（2026-10-10 侧栏默认收起没用到的组；app.js countNavGroups 把组里看得见的入口数写在 data-n）。
   排在组名后面、箭头前面，淡一档、小一号、不加字距。写「几个」不写光数字：首页格子、订单全流程上的数字都是「要你管的事」，
   光一个数会被当成待办。组名文字被当折叠键 / 组名读，所以只能用 attr() 画、不往标题里塞字。
   收起时标题排成一行块：组名太长（「② 找产品·问工厂·做目录」、管理员的「我的工作 · 管理层」）就省略号截断，「N 个」和箭头钉在右边——
   组标题平时是 flex，flex 里的字截不了省略号，数字一挤会把箭头顶出侧栏、或者「沟通与工具」折成两行（1280 宽实测过）。
   flex: 0 0 auto 不能少：带 overflow:hidden 的项在侧栏这个竖排列表里最小高度算 0，入口一多整条标题被压成 0 高、看不见。
   只在 ≥901px 桌面侧栏：≤900px 横条里组标题整个藏着；找功能筛着时（[data-nf]）收起的组里对上的都露出来了，不画数；图标栏里组标题是一条线 */
@media (min-width: 901px) {
  .sidebar:not([data-nf]) .primary-nav .nav-label[aria-expanded="false"][data-n] {
    display: block; flex: 0 0 auto; position: relative; padding-right: 44px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  /* 一位数的「N 个」窄一点，组名多露两个字 */
  .sidebar:not([data-nf]) .primary-nav .nav-label[aria-expanded="false"]:is([data-n="1"], [data-n="2"], [data-n="3"], [data-n="4"], [data-n="5"], [data-n="6"], [data-n="7"], [data-n="8"], [data-n="9"]) { padding-right: 36px; }
  .sidebar:not([data-nf]) .primary-nav .nav-label[aria-expanded="false"][data-n]::before {
    content: attr(data-n) " 个"; position: absolute; top: 50%; right: 14px; transform: translateY(-50%);
    color: var(--d-text-3); opacity: .8; font-size: 11px; font-weight: 500; letter-spacing: 0; line-height: 1; white-space: nowrap; }
  .sidebar:not([data-nf]) .primary-nav .nav-label[aria-expanded="false"][data-n]::after { position: absolute; top: 50%; right: 0; margin: -3px 4px 0 0; }
  .sidebar:not([data-nf]) .primary-nav .nav-label[aria-expanded="false"][data-n] > .nav-dot { display: inline-block; margin: 0 6px 0 0; vertical-align: middle; }
  /* 页面反馈插的组点（shared/page-feedback.js .pf-mark-grp）挂在组名文字后面，收起的组名一长就跟着被省略号截掉，
     和左边的 .nav-dot 一起在时还把组名挤短。左边已经有 .nav-dot（同样是「这组里有页改过」）就不重复点；
     没有的话挪到组名前面、和 .nav-dot 同一个位置（:has 老浏览器不认就整条不生效，退回原样：点在后面、可能被截） */
  .sidebar:not([data-nf]) .primary-nav .nav-label[aria-expanded="false"][data-n] > .nav-dot ~ .pf-mark-grp { display: none; }
  .sidebar:not([data-nf]) .primary-nav .nav-label[aria-expanded="false"][data-n]:has(> .pf-mark-grp):not(:has(> .nav-dot)) { padding-left: 13px; }
  .sidebar:not([data-nf]) .primary-nav .nav-label[aria-expanded="false"][data-n]:has(> .pf-mark-grp):not(:has(> .nav-dot)) > .pf-mark-grp {
    position: absolute; left: 0; top: 50%; margin: -3.5px 0 0 0 !important; }
}
/* 收起的入口和小标题打 data-folded；!important：.nav 自带 display:flex、小标题在下面另有 display 声明 */
@media (min-width: 901px) { .primary-nav [data-folded] { display: none !important; } }
/* 首页那条（公司公告栏）单独放在所有组的上面，和第一个组标题之间留一口气 */
.primary-nav > .nav:first-child { margin-bottom: 6px; }
.primary-nav { display: flex; flex-direction: column; gap: 2px; }   /* 2026-10-10 4→2：侧栏变矮，一屏多放几条（见下面 .nav 那段） */
/* 侧栏入口早已超过一屏：菜单区自己滚，品牌区钉住。
   （账号与系统设置 2026-09-22 上移到顶栏右上角，底部工具区已不存在。）
   在这之前 .sidebar 写死 height:100vh 又没有任何 overflow 处理，装不下的入口
   会溢出到深色底之外掉在白底上，并把整页撑高出一截空白。 */
.primary-nav { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; scrollbar-width: thin; scrollbar-color: rgba(255,255,255,.16) transparent; }
.primary-nav::-webkit-scrollbar { width: 6px; }
.primary-nav::-webkit-scrollbar-thumb { border-radius: 3px; background: rgba(255,255,255,.16); }
.primary-nav::-webkit-scrollbar-track { background: transparent; }
.nav[hidden] { display: none; }
/* 按角色藏入口（shared/common.js 的 SquAccess；用户 2026-09-23：没权限的功能隐藏，不要提示没有权限）。
   拿到规则前，带 data-api 的入口与侧栏分组标题先不画，免得员工先看到一闪而过的管理入口；
   拿到后没放行的打 data-denied。!important：.nav 自带 display，会盖掉 [hidden]。
   外壳不加载 shared/common.css（它会改外壳的 toast 与弹窗样式），所以这两行在这里另写一份。 */
html:not([data-access-ready]) [data-api],
html:not([data-access-ready]) .primary-nav .nav-label,
[data-denied] { display: none !important; }
.primary-nav .nav-label { margin: 8px 10px 3px; }   /* 2026-10-10 15/7→8/3：默认收起后组标题成了侧栏主体，约 45px → 28px */
.primary-nav .nav-label { flex: 0 0 auto; }   /* 10-22：展开的组标题也不许压——二级菜单顶上同事的「我的工作」条目一多（Joyce 15 条），整条标题被压成 0 高看不见 */
.primary-nav .nav-label:first-child { margin-top: 2px; }
/* 组内小标题（「发票」）：比组标题轻一档，左边一条细线把下面几项串起来看（用户 2026-09-28：Nora 用的几页挨在一起） */
.primary-nav .nav-sub { margin: 4px 10px 1px 14px; padding-left: 8px; border-left: 2px solid var(--d-border-strong);
  color: var(--d-text-3); font-size: 12px; font-weight: 600; letter-spacing: .08em; }
html:not([data-access-ready]) .primary-nav .nav-sub { visibility: hidden; }
/* 小标题也能收起（2026-09-29）：和组标题一样是按钮，箭头小一号；只藏它下面到下一个小标题之间的几条 */
.primary-nav .nav-sub { display: flex; align-items: center; gap: 6px; padding: 0 0 0 8px; border-top: 0; border-right: 0; border-bottom: 0;
  background: transparent; font-family: inherit; line-height: inherit; text-align: left; cursor: pointer; transition: color .18s; }
.primary-nav .nav-sub:hover, .primary-nav .nav-sub:focus-visible { color: var(--d-text-2); outline: none; }
.primary-nav .nav-sub::after { content: ''; flex: 0 0 auto; margin-left: auto; margin-right: 6px; width: 5px; height: 5px;
  border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor; opacity: .7;
  transform: translateY(-1px) rotate(45deg); transition: transform .18s; }
.primary-nav .nav-sub[aria-expanded="false"]::after { transform: translateX(-2px) rotate(-45deg); }
/* 10-20 第二层不折叠：小标题只是标题，不画折角、不是手型 */
.primary-nav .nav-sub[data-flat] { cursor: default; }
/* 新版侧栏（10-21）：二级小标题稍靠里；旧组的元素藏着（hidden）不占位 */
.primary-nav .nav-sub[data-v2sub] { margin-top: 6px; }
.primary-nav [data-v2-old] { display: none !important; }
.primary-nav .nav-sub[data-flat]::after { display: none; }
.primary-nav .nav-sub[data-flat]:hover { color: var(--d-text-3); }
/* 原位灰字指路（2026-10-17 老板点「挪上去 + 原位灰字指路」，app.js navGhost）：挪进「我的工作」的入口在原组留一行「交货进度 ↑ 在上面」，
   字差不多和入口名对齐（左 40px；侧栏默认 196 宽，再多名字就被截），淡、小一号，悬停亮一点；点了直接打开那页。
   整组都挪空的不画灰字，只留淡灰组标题，组名后面写「都在我的工作里」（data-ghost-only；用 ::after 画，组名文字是折叠键不能塞字；那组没东西可收，不画箭头） */
.primary-nav .nav-ghost { display: flex; flex: 0 0 auto; align-items: baseline; gap: 6px; width: 100%; margin: 0; padding: 1px 8px 1px 40px; border: 0;
  background: transparent; color: var(--d-text-3); opacity: .62; font-family: inherit; font-size: 12px; line-height: 1.7;
  text-align: left; cursor: pointer; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; transition: opacity .18s, color .18s; }
.primary-nav .nav-ghost > b { font-weight: 500; overflow: hidden; text-overflow: ellipsis; }
.primary-nav .nav-ghost > small { flex: 0 0 auto; font-size: 11px; opacity: .85; }
.primary-nav .nav-ghost:hover, .primary-nav .nav-ghost:focus-visible { opacity: 1; color: var(--d-text-2); outline: none; }
.primary-nav .nav-ghost[data-ghost-hide] { display: none; }
.primary-nav .nav.nav-adm > b::after { content: "👑"; margin-left: 4px; font-size: 10px; vertical-align: 1px; opacity: .85; }   /* 10-20 只给主管理 */
.app-shell[data-rail] .primary-nav .nav.nav-adm > b::after { display: none; }
.primary-nav .nav-ghost.active { opacity: 1; color: var(--d-text); box-shadow: inset 2px 0 var(--d-accent); }   /* 10-20 点的是灰字就亮灰字 */
.primary-nav .nav-label[data-ghost-only] { opacity: .55; cursor: default; }
.primary-nav .nav-label[data-ghost-only]::after { content: '都在我的工作里'; width: auto; height: auto; margin: 0 4px 0 auto; border: 0; transform: none;
  transition: none; opacity: .9; font-size: 11px; font-weight: 500; letter-spacing: 0; white-space: nowrap; }
.app-shell[data-rail] .primary-nav .nav-ghost { display: none; }
/* 页内标签：一个侧栏入口下的几个页面（微信会话 = 群会话总览 + 直接对话） */
.page-tabs { display: flex; gap: 6px; margin-top: 8px; }
.page-tab { border: 1px solid var(--line); border-radius: 999px; padding: 5px 14px; font-size: 13px; cursor: pointer; background: var(--surface); color: var(--text-muted); transition: color .18s, background .18s, border-color .18s; }
.page-tab:hover { color: var(--ink); }
.page-tab.active { border-color: var(--d-selected); background: var(--d-selected); color: #fff; }
.nav {
  position: relative;
  width: 100%; border: 0; border-radius: 10px; padding: 5px 10px;   /* 2026-10-10 9/11→5/10：一条约 51px → 36px（同飞书桌面侧栏），字号颜色不变 */
  color:var(--d-text-3); background: transparent; cursor: pointer;
  display: flex; align-items: center; gap: 10px; text-align: left;
  transition: color .18s, background .18s, transform .18s;
}
.nav:hover { color:#fff; background: rgba(255, 255, 255, .055); }
.nav.active { color:#fff; background:var(--d-selected); box-shadow:inset 2px 0 var(--d-accent); }
.nav > span {
  width: 24px; height: 24px; flex: 0 0 24px; border-radius: 7px;   /* 2026-10-10 29→24（别再小：彩色块要认得出，9-27「给一个彩色的」） */
  display: grid; place-items: center; border: 1px solid rgba(255, 255, 255, .08);
  color:var(--d-text-3); background: rgba(255, 255, 255, .035); font-size: 13px;
}
.nav.active > span { color:var(--g-800); background:var(--g-200); border-color:var(--g-200); font-weight: 700; }
/* 常用页（app.js markHotPages：近 30 天打开最多的前 3 个）：图标块换成亮薄荷色、字变白，一眼先看到自己最常点的 */
.nav.nav-hot { color: var(--d-text); }
.nav.nav-hot:not(.active) > span { color: var(--d-bg); background: var(--d-accent); border-color: var(--d-accent); }
.nav > span svg { display: block; width: 15px; height: 15px; }   /* 图标在 app.js navIconSvg 里写死 17×17，跟着图标块缩到 15 */
/* 侧栏「改过了」绿点（app.js loadPageUpdates，规则 app/page_updates.py；10-10 起全站只这一套）：图标右上角一个亮绿点，外圈侧栏底色，压在常用页的亮图标上也看得清。
   组 / 小标题收起时标题前一个小的（markGroupDots）；页头标签上改过、还没看过的标签字后面一个（paintTabDots，浅底上换深一档的绿） */
.nav > span { position: relative; }
.nav-dot { position: absolute; top: -3px; right: -3px; width: 9px; height: 9px; border-radius: 50%;
  background: var(--d-accent); box-shadow: 0 0 0 2px var(--d-bg); pointer-events: auto; cursor: help; }
.nav-label > .nav-dot, .nav-sub > .nav-dot { position: static; flex: 0 0 auto; width: 7px; height: 7px; box-shadow: none; margin-right: -2px; }
.page-tab > .nav-dot { position: static; display: inline-block; width: 7px; height: 7px; margin: 0 0 0 6px; vertical-align: 1px;
  background: var(--g-400); box-shadow: none; }
.nav:not(.nav-hot):not(.active) > span { color: var(--d-text-2); }   /* 图标比原来的单字亮一档，一眼认得出 */
/* 图标按分组上色（用户 2026-09-27：「给一个彩色的，这样会显眼一点」）。组 → 颜色写在 index.html 的 .nav-label[data-hue]，app.js tintNavGroups 传给组里每个入口；
   手机「全部」里的格子沿用入口的颜色（phone.css）。样子像手机 App 图标：彩色实心块 + 近白线条（浅色线条配淡底试过，深色侧栏上还是发灰，不显眼）。
   常用前 3（nav-hot）再套一圈薄荷绿描边、名字变白（9-27「访问多的弄得鲜艳一点」照旧成立）；当前页维持浅绿块不变。
   不用自定义变量：test_ui_standard 要求 var() 的名字都在 tokens.css 里，所以六个颜色逐条写。 */
.nav[data-hue="amber"]:not(.active) > span { color: color-mix(in srgb, var(--a-600) 15%, var(--n-0)); background: color-mix(in srgb, var(--a-600) 82%, transparent); border-color: transparent; }
.nav[data-hue="blue"]:not(.active) > span { color: color-mix(in srgb, var(--b-600) 15%, var(--n-0)); background: color-mix(in srgb, var(--b-600) 82%, transparent); border-color: transparent; }
.nav[data-hue="teal"]:not(.active) > span { color: color-mix(in srgb, var(--chart-6) 15%, var(--n-0)); background: color-mix(in srgb, var(--chart-6) 82%, transparent); border-color: transparent; }
.nav[data-hue="red"]:not(.active) > span { color: color-mix(in srgb, var(--r-600) 15%, var(--n-0)); background: color-mix(in srgb, var(--r-600) 82%, transparent); border-color: transparent; }
.nav[data-hue="violet"]:not(.active) > span { color: color-mix(in srgb, var(--v-600) 15%, var(--n-0)); background: color-mix(in srgb, var(--v-600) 82%, transparent); border-color: transparent; }
.nav[data-hue="gray"]:not(.active) > span { color: color-mix(in srgb, var(--n-500) 15%, var(--n-0)); background: color-mix(in srgb, var(--n-500) 82%, transparent); border-color: transparent; }
.nav.nav-hot[data-hue]:not(.active) > span { box-shadow: 0 0 0 2px var(--d-accent); }
.nav b { font-size: 13px; font-weight: 560; }
/* 侧栏「找功能」（2026-09-26 是个输入框；2026-10-02 老板「全站只要一个搜索框」改成按钮，点了跳到全站搜索，app.js bindNavFinder）。
   不带 .nav 类（见 index.html 注释），样子还像原来那个框：深色凹槽、浅字，悬停 / 键盘停上去描薄荷绿边。 */
.nav-finder { flex: 0 0 auto; margin: -14px 0 8px; }
.nav-find {
  width: 100%; box-sizing: border-box; display: flex; align-items: center; gap: 6px;
  border: 1px solid var(--d-border); border-radius: 9px; padding: 8px 9px; cursor: pointer; text-align: left;
  font: inherit; font-size: 13px; line-height: 1.3; color: var(--d-text-3); background: var(--d-sunken);
  transition: color .18s, border-color .18s;
}
.nav-find:hover, .nav-find:focus-visible { color: var(--d-text-2); border-color: var(--d-accent); outline: none; }
.nav-find-ico { flex: 0 0 auto; color: var(--d-accent); font-size: 15px; font-weight: 700; line-height: 1; }
.nav-find-t { flex: 1 1 auto; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.nav-find kbd { flex: 0 0 auto; padding: 0 5px; border: 1px solid var(--d-border); border-radius: var(--radius-sm);
  font: inherit; font-size: 11px; line-height: 16px; color: var(--d-text-3); }
/* 2026-10-08 又改回框（老板：「一搜就弹到中间那个全站搜索那里去了」）：打字在侧栏里当场筛，逻辑在 app.js「侧栏找功能」段。
   框还是原来那颗按钮的样子（.nav-find）；收成图标栏时框藏起来，只露放大镜按钮 .nav-find-rail（点了去全站搜索）。 */
.nav-find-box { cursor: text; }
.nav-find-box:focus-within { color: var(--d-text-2); border-color: var(--d-accent); }
#nav-q { flex: 1 1 auto; min-width: 0; width: 100%; margin: 0; padding: 0; border: 0; border-radius: 0; background: transparent; box-shadow: none;
  color: var(--d-text); font: inherit; font-size: 13px; line-height: 1.3; }
#nav-q::placeholder { color: var(--d-text-3); opacity: 1; }
#nav-q:focus, #nav-q:focus-visible { outline: none; }
#nav-q::-webkit-search-cancel-button { cursor: pointer; filter: invert(1) brightness(.8); }
#nav-q:not(:placeholder-shown) + kbd { display: none; }   /* 打了字就不再提示「/」，给清除的小叉让地方 */
.nav-find-rail { display: none; }
/* 筛着的时候（.sidebar[data-nf]，app.js navFilterApply）：对不上的藏、收起的组里对上的也露出来，「当前组」那条盖顶的不出；
   对上的那几条里亮着的（回车会开的）描一圈薄荷绿。只在 ≥901px 生效：横条里没有这个框 */
@media (min-width: 901px) {
  .sidebar[data-nf] .primary-nav [data-folded] { display: flex !important; }
  .sidebar[data-nf] .primary-nav [data-nf-hide] { display: none !important; }
  .sidebar[data-nf] .nav-current { display: none !important; }
  /* 列表只占对上的那几条的高度，「在全站搜」紧跟在最后一条下面（对不上时就在框下面），底部两颗按钮照旧贴底 */
  .sidebar[data-nf] .primary-nav { flex: 0 1 auto; }
  .sidebar[data-nf] .sb-foot { margin-top: auto; }
}
.primary-nav .nav.nf-cur { color: var(--d-text); background: var(--d-hover); box-shadow: inset 0 0 0 1px var(--d-accent); }
.primary-nav .nav.nf-cur.active { background: var(--d-selected); }
/* 对上的是它下面的标签页（热卖品 › 出单看板、经验库 › 每日分享）：「› 标签名」另起一行写在名字下面，名字不被挤成两行 */
.primary-nav .nav.nf-tab { flex-wrap: wrap; row-gap: 0; }
.nf-via { flex: 0 0 calc(100% - 34px); min-width: 0; margin: -3px 0 0 34px; color: var(--d-text-3); font-size: 11.5px; line-height: 1.3;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* 列表下面那一块：侧栏没有时的一句话、右上角对上的、去全站搜索那一行。钉在列表和底部按钮之间，不跟着列表滚 */
.nav-find-more { flex: 0 0 auto; display: grid; gap: 4px; margin-top: 6px; padding-top: 8px; border-top: 1px solid var(--d-border); }
.nav-find-more[hidden] { display: none; }
.nav-find-none { margin: 0 4px 2px; color: var(--d-text-3); font-size: 12px; line-height: 1.5; }
.nav-find-none[hidden] { display: none; }
.nav-find-all { display: flex; flex-direction: column; align-items: flex-start; gap: 1px; width: 100%; padding: 7px 10px; border: 1px dashed var(--d-border-strong);
  border-radius: 9px; background: transparent; color: var(--d-text-2); font: inherit; font-size: 13px; line-height: 1.35; text-align: left; cursor: pointer;
  transition: color .18s, border-color .18s, background .18s; }
.nav-find-all .t { max-width: 100%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.nav-find-all b { color: var(--d-text); font-weight: 650; }
.nav-find-all small { color: var(--d-text-3); font-size: 11.5px; white-space: nowrap; }
.nav-find-all:hover, .nav-find-all:focus-visible, .nav-find-all.nf-cur { color: var(--d-text); border-style: solid; border-color: var(--d-accent); background: var(--d-hover); outline: none; }
/* ≤900px 侧栏变成顶部横条（见下方 @media），顶栏（首页是首页上）的搜索框就在眼前，这个框不再占一行 */
@media (max-width: 900px) {
  .nav-finder, .nav-find-more { display: none !important; }
}
.nav-live { width: 6px; height: 6px; margin-left: auto; border-radius: 50%; background:var(--d-accent); box-shadow: 0 0 0 4px rgba(126, 214, 157, .1); }

/* 内容区宽度跟着窗口走，不再写死像素上限。
   原来是 max-width:1640px 居中，而浏览器缩放改变的恰恰是「一个 CSS 像素有多大」：
   缩到 80%，可视区从 1900 变成 2375 CSS px，这个块还是 1640，左右各空出 250px 死白边。
   用户缩小本来就是想一屏多看点东西，多出来的地方却全是白的。
   现在铺满可用宽度，只让左右留白随视口缓慢变宽——宽屏上仍有呼吸感，但不会再有居中白边。
   正文行长不靠这个上限管：段落自己有 max-width（见 .page-intro p）。 */
.main-content { min-width: 0; width: 100%; max-width: none; padding: 25px clamp(32px, 2.2vw, 72px) 55px; }
.topbar { min-height: 54px; margin-bottom: 23px; display: flex; align-items: center; justify-content: space-between; gap: 20px; }
.topbar > div:first-child { min-width: 0; }
/* 顶栏吸顶（2026-09-22）：向下滚时右上角的账号与系统设置不能跟着滚走。
   搬家之前这两个入口在 .sidebar 里，而侧栏是 position:sticky——一直够得着；
   搬到顶栏后如果不吸顶，滚一屏就没了，在「随时够得着」这件事上反而是退步。
   （用户给的简道云截图里顶栏也是钉死的，只有中间内容滚。）

   **刻意不用负 margin 去吃 .main-content 的内边距**：那样要和内边距值永远保持一致，
   而这个值有三处在写（styles.css:82 的 clamp、ui-polish.css:4 的 padding-top:22px、
   ≤900px 的 16px），对不齐就顶出内容框——实测 880px 下多出一条横向滚动条。
   实际上也不需要：页面内容本来就排在同一个内边距框内，左右留白里没有任何东西会透上来，
   吸顶后元素紧贴视口顶边，上方也不留缝。只要背景不透明就够了。

   z-index 取 15：盖得住表格那条 sticky 表头（z-index:1），
   又低于 #sku-tip(90) / #toast(100) / .modal-backdrop(200)。 */
.topbar {
  position: sticky; top: 0; z-index: 15;
  background: var(--canvas);
  padding-bottom: 10px;
}
.topbar p, .section-kicker, .panel-title small, .sync-panel small, .route-head small {
  margin: 0 0 5px; color:var(--text-muted); font-size: 12px; font-weight: 750; letter-spacing: .17em;
}
h1, h2, h3, p { margin-top: 0; }
h1 { margin-bottom: 0; font-size: 24px; line-height: 1.25; letter-spacing: -.035em; }
h2 { margin-bottom: 0; font-size: 17px; line-height: 1.45; letter-spacing: -.018em; }
h3 { margin-bottom: 0; font-size: 14px; }
.topbar-right { display: flex; align-items: center; gap: 14px; flex: 0 0 auto; }
.api-state { display: flex; align-items: center; gap: 7px; color:var(--text-muted); font-size: 12px; }
.api-state i { width: 7px; height: 7px; border-radius: 50%; background:var(--g-500); box-shadow:0 0 0 4px var(--accent-soft-bg); }
.avatar { width: 38px; height: 38px; border-radius: 12px; display: grid; place-items: center; color:var(--text-on-accent); background: var(--green); font-size: 12px; font-weight: 750; letter-spacing: .06em; }

/* 右上角的账号与系统设置（2026-09-22 从侧栏底部搬来）。
   「系统设置」那条仍然带着 class="nav"——app.js 靠 .nav[data-embed] 扫出内嵌页路径表，
   换类名会让 /settings 退回整页跳转。但 .nav 整套是**深色侧栏专用**配色
   （浅灰字、白色半透明 hover、inset 绿条），原样放进白底顶栏就是隐形按钮，
   所以这里只在 .topbar-right 作用域内把它改写成浅色药丸，不动 .nav 本体。 */
.topbar-right .nav.topbar-entry {
  width: auto; flex: 0 0 auto; margin: 0; padding: 6px 10px; gap: 7px;
  /* 边框用 --border-control 而不是 --line：顶栏底色是 --canvas(#EEF1EF)，
     --line(#E3E8E5) 对它只有 1.09:1，药丸根本看不出轮廓（WCAG 1.4.11 要求控件边界 3:1）。
     文字也从 --text-muted 提到 --text-secondary —— 旁边那条「数据服务在线」是纯展示的
     --text-muted/12px，两者原来同色同字号，一个能点一个不能点却长得一模一样。 */
  border: 1px solid var(--border-control); border-radius: 999px;
  color: var(--text-secondary); background: var(--surface);
}
.topbar-right .nav.topbar-entry:hover { color:var(--ink); background: var(--surface-hover); }
/* 当前页要和 hover 分得开：hover 只是底色微变（#FFF→#F7F9F8，1.05:1，肉眼没差），
   所以 .active 改用品牌浅底+浅边框+深绿字。搬家时把侧栏那条 inset 绿条关掉了，
   这里是它的替代品，不能只写 box-shadow:none 就算完。 */
.topbar-right .nav.topbar-entry.active {
  color:var(--accent-soft-fg); background: var(--accent-soft-bg);
  border-color: var(--accent-soft-border); box-shadow: none;
}
.topbar-right .nav.topbar-entry > span {
  width: 20px; height: 20px; flex: 0 0 20px; border: 0; border-radius: 6px;
  color:var(--text-on-accent); background: var(--green); font-size: 11px; font-weight: 700;
}
.topbar-right .nav.topbar-entry b { font-size: 12px; font-weight: 600; }
/* 头像现在是真按钮（点开登录/退出弹窗），不再是写死的装饰 div */
button.avatar { border: 0; padding: 0; cursor: pointer; font-family: inherit; }
button.avatar:hover { filter: brightness(1.06); }
.topbar-right .nav.topbar-entry:focus-visible, button.avatar:focus-visible { outline: 2px solid var(--green); outline-offset: 2px; }

.page { display: none; animation: page-in .2s ease both; }
.page.active { display: block; }
/* 内嵌页：独立页面（/chat、/settings 等）在控制台内容区内联渲染，侧边栏与页头不动。
   iframe 不会自动撑高，实际高度由 app.js 按页头真实高度算；这里的 calc 只是脚本没跑起来时的兜底。
   内部滚动交给被嵌页面自己管，外层不能再出第二条滚动条。 */
.embed-page.active { display: flex; }
.embed-frame { flex: 1; width: 100%; height: calc(100vh - 200px); border: 0; border-radius: 12px; background:var(--canvas); }
.main-content.has-embed { padding-bottom: 20px; }
@keyframes page-in { from { opacity: 0; transform: translateY(3px); } to { opacity: 1; transform: none; } }
.hidden { display: none !important; }
.grid { display: grid; gap: 15px; margin-bottom: 15px; }
.grid.two { grid-template-columns: minmax(0, 1.08fr) minmax(0, .92fr); }
.grid.split { grid-template-columns: minmax(0, 1.65fr) minmax(270px, .7fr); }
.panel, .metrics article, .messenger { background: var(--card); border: 1px solid var(--line); box-shadow: var(--shadow); }
.panel { border-radius: 15px; padding: 22px; }
.panel-title { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; margin-bottom: 18px; }
.muted { color:var(--text-muted); font-size: 12px; }
.block-gap { display: inline-block; margin-top: 5px; }
.error-text { color:var(--danger-fg); font-size: 12px; }

.welcome-card {
  min-height: 138px; margin-bottom: 15px; padding: 25px 28px; border-radius: 16px; overflow: hidden;
  color:#fff; background:linear-gradient(100deg, rgba(17, 70, 50, .98), rgba(28, 100, 72, .88)),
    radial-gradient(circle at 80% 10%, var(--g-200), transparent 38%);
  display: flex; align-items: center; justify-content: space-between; gap: 28px;
  box-shadow: 0 14px 35px rgba(21, 82, 58, .13);
}
.welcome-card > div { max-width: 800px; }
.overline { display: block; margin-bottom: 9px; color:var(--g-200); font-size: 12px; font-weight: 750; letter-spacing: .18em; }
.welcome-card h2 { font-size: 22px; }
.welcome-card p { margin: 7px 0 0; color:var(--g-200); font-size: 13px; line-height: 1.7; }
.jump-button { flex: 0 0 auto; border: 1px solid rgba(255,255,255,.16); border-radius: 10px; padding: 11px 14px; color:var(--g-50); background: rgba(255,255,255,.08); cursor: pointer; font-size: 13px; font-weight: 650; }
.jump-button:hover { background: rgba(255,255,255,.15); }
.jump-button span { margin-left: 8px; }

.metrics { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 12px; margin-bottom: 15px; }
.metrics article { min-width: 0; border-radius: 14px; padding: 16px; display: flex; align-items: center; gap: 12px; }
.metrics article > div:last-child { min-width: 0; }
.metric-icon { width: 36px; height: 36px; flex: 0 0 36px; border-radius: 10px; display: grid; place-items: center; font-size: 12px; font-weight: 760; }
.metric-icon.green { color:var(--accent); background:var(--g-100); }
.metric-icon.mint { color:var(--accent); background:var(--g-100); }
.metric-icon.blue { color:var(--info-fg); background:var(--info-bg); }
.metric-icon.amber { color:var(--warning-fg); background:var(--warning-bg); }
.metric-icon.coral { color:var(--danger-fg); background:var(--danger-bg); }
.metric-icon.slate { color:var(--text-muted); background:var(--canvas); }
.metrics span, .metrics em { display: block; overflow: hidden; color: var(--muted); font-size: 12px; font-style: normal; text-overflow: ellipsis; white-space: nowrap; }
.metrics strong { display: block; margin: 3px 0 1px; font-size: 23px; line-height: 1.1; letter-spacing: -.04em; }
.metrics em { color:var(--text-muted); font-size: 11px; }

label { display: block; margin-bottom: 13px; color:var(--text-muted); font-size: 12px; font-weight: 650; }
input, textarea, select { width: 100%; margin-top: 6px; border: 1px solid var(--line-strong); border-radius: 9px; padding: 10px 11px; outline: 0; color: var(--ink); background:var(--surface-hover); font-size: 13px; transition: border .16s, box-shadow .16s; }
textarea { min-height: 106px; resize: vertical; line-height: 1.65; }
input:focus, textarea:focus, select:focus { border-color:var(--border-control); box-shadow: 0 0 0 3px rgba(51, 132, 93, .09); }
.primary, .soft, .danger, .examples button { border: 0; border-radius: 9px; padding: 10px 13px; cursor: pointer; font-size: 12px; font-weight: 650; transition: transform .16s, background .16s, opacity .16s; }
.primary { width: 100%; color:#fff; background: var(--green); }
.primary:hover { background:var(--accent-hover); transform: translateY(-1px); }
.primary:disabled { opacity: .5; transform: none; }
.primary.compact { width: auto; white-space: nowrap; }
.soft { color:var(--accent); background:var(--canvas); }
.soft:hover { background:var(--n-100); }
.danger { padding: 6px 9px; color:var(--danger-fg); background:var(--danger-bg); }
.status-pill { padding: 6px 9px; border-radius: 99px; color:var(--accent); background: var(--green-soft); font-size: 12px; font-weight: 650; }
.status-pill i { display: inline-block; width: 5px; height: 5px; margin-right: 5px; border-radius: 50%; background:var(--g-500); }
.examples { min-height: 28px; margin: -2px 0 14px; display: flex; align-items: center; flex-wrap: wrap; gap: 7px; }
.examples > span { color:var(--text-muted); font-size: 12px; }
.examples button { padding: 6px 8px; color:var(--text-secondary); background:var(--canvas); }
.result-panel { min-height: 340px; }
.empty { min-height: 245px; display: grid; place-content: center; justify-items: center; text-align: center; color:var(--text-muted); }
.empty-symbol { width: 46px; height: 46px; margin-bottom: 9px; border-radius: 15px; display: grid; place-items: center; color:var(--text-secondary); background:var(--canvas); font-size: 13px; font-weight: 760; }
.empty p { margin: 0; font-size: 13px; line-height: 1.7; }
.result { border:1px solid var(--border-subtle); border-radius: 12px; padding: 17px; background:var(--surface-hover); }
.result h3 { margin: 13px 0; }
.result p { margin: 0; padding: 8px 0; border-top:1px solid var(--border-subtle); display: grid; grid-template-columns: 76px 1fr; gap: 10px; font-size: 13px; line-height: 1.55; }
.result p b { color:var(--text-muted); font-weight: 600; }
.flow-panel { padding-bottom: 19px; }
.flow-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.flow-row > span { min-width: 0; flex: 1; border:1px solid var(--border-subtle); border-radius: 10px; padding: 10px; color:var(--text-secondary); background:var(--surface-hover); text-align: center; font-size: 12px; }
.flow-row > span i { display: inline-grid; width: 18px; height: 18px; margin-right: 6px; place-items: center; border-radius: 6px; color:var(--accent); background:var(--g-100); font-size: 11px; font-style: normal; }
.flow-row > b { color:var(--text-muted); font-weight: 500; }

.page-intro, .wechat-summary { margin-bottom: 17px; display: flex; align-items: flex-end; justify-content: space-between; gap: 30px; }
.page-intro h2, .wechat-summary h2 { font-size: 21px; }
.page-intro p:last-child, .wechat-summary > div:first-child > p:last-child { max-width: 680px; margin: 5px 0 0; color: var(--muted); font-size: 12px; line-height: 1.65; }
.wechat-stats { display: flex; align-items: center; gap: 6px; }
.wechat-stats > span { min-width: 70px; border-left: 1px solid var(--line-strong); padding-left: 13px; color:var(--text-muted); font-size: 11px; }
.wechat-stats > span b { display: block; margin-bottom: 2px; color: var(--ink); font-size: 16px; }
.wechat-stats .source-state { min-width: 105px; border: 0; border-radius: 9px; padding: 9px 11px; color:var(--text-muted); background:var(--canvas); display: flex; align-items: center; gap: 7px; }
.source-state i { width: 7px; height: 7px; border-radius: 50%; background:var(--n-300); }
.source-state i.ok { background:var(--g-500); box-shadow: 0 0 0 4px rgba(66,162,114,.1); }
.source-state i.error { background:var(--danger-solid); box-shadow: 0 0 0 4px rgba(206,90,69,.1); }
.wechat-stats .source-state b { margin: 0; font-size: 12px; white-space: nowrap; }

.messenger { overflow: hidden; border-radius: 16px; }
.messenger-toolbar { min-height: 66px; padding: 11px 15px; border-bottom: 1px solid var(--line); display: flex; align-items: center; justify-content: space-between; gap: 14px; }
.source-identity { display: flex; align-items: center; gap: 9px; }
.source-logo { width: 34px; height: 34px; border-radius: 10px; display: grid; place-items: center; color:#fff; background:linear-gradient(145deg, var(--g-500), var(--accent)); font-size: 13px; font-weight: 700; }
.source-identity b, .source-identity small { display: block; }
.source-identity b { font-size: 13px; }
.source-identity small { margin-top: 3px; color:var(--text-muted); font-size: 11px; }
.toolbar-actions { display: flex; align-items: center; justify-content: flex-end; gap: 8px; }
.search-box { position: relative; width: 230px; margin: 0; }
.search-box span { position: absolute; left: 11px; top: 50%; transform: translateY(-50%); color:var(--text-muted); font-size: 14px; }
.search-box input { height: 35px; margin: 0; padding-left: 31px; }
.toolbar-actions select { width: 105px; height: 35px; margin: 0; padding: 7px 9px; }
.icon-button { height: 35px; white-space: nowrap; }
.icon-button span { display: inline-block; margin-right: 5px; font-size: 14px; transition: transform .3s; }
.icon-button.loading span { transform: rotate(180deg); }
.auth-notice { margin: 10px 12px 0; border:1px solid var(--warning-border); border-radius: 11px; padding: 10px 12px; color:var(--warning-fg); background:var(--warning-bg); display: flex; align-items: center; justify-content: space-between; gap: 15px; }
.auth-notice b { font-size: 12px; }
.auth-notice p { margin: 2px 0 0; font-size: 12px; }

.messenger-grid { min-height: 600px; display: grid; grid-template-columns: minmax(245px, 285px) minmax(390px, 1fr) minmax(235px, 270px); }
.conversation-column, .message-column, .route-column { min-width: 0; }
.conversation-column { border-right: 1px solid var(--line); background:var(--surface-hover); }
.column-head { height: 54px; padding: 12px 14px 8px; display: flex; align-items: center; justify-content: space-between; }
.column-head > div { display: flex; align-items: center; gap: 7px; }
.column-head b { font-size: 13px; }
.column-head span { min-width: 20px; border-radius: 99px; padding: 3px 6px; color:var(--text-muted); background:var(--canvas); text-align: center; font-size: 11px; }
.column-head small { color:var(--text-muted); font-size: 11px; }
.filter-tabs { margin: 0 12px 9px; padding: 3px; border-radius: 9px; background:var(--canvas); display: grid; grid-template-columns: repeat(6, 1fr); gap: 2px; }
.chat-filter { border: 0; border-radius: 7px; padding: 6px 2px; white-space: nowrap; color:var(--text-muted); background: transparent; cursor: pointer; font-size: 11px; }
.chat-filter.active { color:var(--accent); background:#fff; box-shadow: 0 2px 8px rgba(31,52,42,.07); font-weight: 650; }
.conversation-list { height: 527px; overflow-y: auto; scrollbar-width: thin; scrollbar-color:var(--border) transparent; }
.conversation-item { width: 100%; border: 0; border-top:1px solid var(--border-subtle); padding: 12px; color: inherit; background: transparent; cursor: pointer; display: flex; align-items: flex-start; gap: 10px; text-align: left; transition: background .15s; }
.conversation-item:hover { background:var(--surface-hover); }
.conversation-item.active { position: relative; background:var(--canvas); }
.conversation-item.active::before { content: ""; position: absolute; inset: 8px auto 8px 0; width: 2px; border-radius: 2px; background: var(--green-2); }
.conversation-avatar, .chat-avatar { position: relative; overflow: hidden; border-radius: 11px; display: grid; place-items: center; color:var(--accent); background:var(--n-100); font-size: 12px; font-weight: 700; }
.conversation-avatar img, .chat-avatar img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.conversation-avatar { width: 38px; height: 38px; flex: 0 0 38px; }
.conversation-avatar.factory, .chat-avatar.factory { color:var(--warning-fg); background:var(--warning-bg); }
.conversation-avatar.internal, .chat-avatar.internal { color:var(--info-fg); background:var(--info-bg); }
.conversation-avatar.direct, .chat-avatar.direct { color:var(--info-fg); background:var(--info-bg); }
.conversation-avatar.unclassified, .chat-avatar.unclassified { color:var(--text-muted); background:var(--n-100); }
.conversation-avatar.customer, .chat-avatar.customer { color:var(--success-fg); background:var(--success-bg); }
.conversation-avatar.logistics, .chat-avatar.logistics { color:var(--text-secondary); background:var(--neutral-bg); }
.conversation-copy { min-width: 0; flex: 1; }
.conversation-title { display: flex; align-items: center; justify-content: space-between; gap: 7px; }
.conversation-title b { overflow: hidden; font-size: 13px; line-height: 1.35; text-overflow: ellipsis; white-space: nowrap; }
.conversation-title time { flex: 0 0 auto; color:var(--text-muted); font-size: 11px; }
.conversation-preview { display: block; overflow: hidden; margin-top: 4px; color:var(--text-muted); font-size: 12px; line-height: 1.4; text-overflow: ellipsis; white-space: nowrap; }
.conversation-meta { display: flex; align-items: center; gap: 5px; margin-top: 6px; color:var(--text-muted); font-size: 11px; }
.conversation-meta em { margin-left: auto; border-radius: 99px; padding: 2px 5px; color:var(--accent); background:var(--g-100); font-style: normal; }
.kind-dot { width: 5px; height: 5px; border-radius: 50%; background:var(--n-300); }
.kind-dot.internal { background: var(--blue); }
.kind-dot.factory { background: var(--amber); }
.kind-dot.direct { background:var(--b-600); }
.kind-dot.customer { background: var(--green); }
.kind-dot.logistics { background: var(--text-secondary); }
/* 「这几类分类有什么用」：会话列表和群分类管理页各一份，默认收起 */
.kind-help { margin: 0 12px 9px; font-size: 11px; color: var(--text-muted); }
.kind-help summary { cursor: pointer; }
.kind-help ul { margin: 6px 0 0; padding-left: 16px; line-height: 1.6; }
.kind-help b { color: var(--text-secondary); }
#group-management .kind-help { margin: 0 0 12px; font-size: 12px; }
.list-loading { padding: 15px 12px; display: grid; gap: 10px; }
.list-loading i { height: 55px; border-radius: 10px; background:linear-gradient(90deg, var(--canvas), var(--surface-hover), var(--canvas)); background-size: 200% 100%; animation: shimmer 1.15s infinite linear; }
@keyframes shimmer { to { background-position: -200% 0; } }
.list-empty { min-height: 300px; padding: 40px 20px; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; }
.list-empty > span { width: 35px; height: 35px; margin-bottom: 8px; border-radius: 11px; display: grid; place-items: center; color:var(--text-muted); background:var(--canvas); }
.list-empty b { font-size: 12px; }
.list-empty p { margin: 5px 0 0; color:var(--text-muted); font-size: 11px; line-height: 1.55; }
.list-empty.error > span { color:var(--danger-fg); background:var(--danger-bg); }

.message-column { display: grid; grid-template-rows: 64px 1fr auto 35px; background:var(--surface-hover); }
.chat-compose { display: flex; gap: 8px; padding: 10px 14px; border-top: 1px solid var(--line); background:#fff; }
.chat-compose[hidden] { display: none; }
.chat-compose input { flex: 1; margin: 0; font-size: 14px; }
.chat-compose button { flex: 0 0 auto; }
.chat-header { padding: 11px 15px; border-bottom: 1px solid var(--line); background:#fff; display: flex; align-items: center; gap: 10px; }
.chat-avatar { width: 38px; height: 38px; flex: 0 0 38px; }
.chat-header > div:nth-child(2) { min-width: 0; flex: 1; }
.chat-header b, .chat-header span { display: block; }
.chat-header b { overflow: hidden; font-size: 14px; text-overflow: ellipsis; white-space: nowrap; }
.chat-header > div:nth-child(2) span { margin-top: 4px; color:var(--text-muted); font-size: 11px; }
.readonly-badge { flex: 0 0 auto; border-radius: 99px; padding: 5px 7px; color:var(--text-muted); background:var(--canvas); font-size: 11px !important; }
.message-stream { height: 501px; overflow-y: auto; padding: 18px; scroll-behavior: smooth; scrollbar-width: thin; scrollbar-color:var(--border) transparent; }
.day-divider { margin: 8px 0 14px; display: flex; align-items: center; gap: 8px; }
.day-divider::before, .day-divider::after { content: ""; height: 1px; flex: 1; background:var(--n-100); }
.day-divider span { color:var(--text-muted); font-size: 11px; }
.message-row { margin-bottom: 15px; display: flex; align-items: flex-start; gap: 8px; }
.message-row.outgoing { flex-direction: row-reverse; }
.message-sender-avatar { width: 28px; height: 28px; flex: 0 0 28px; border-radius: 9px; display: grid; place-items: center; color:var(--text-secondary); background:var(--n-100); font-size: 11px; font-weight: 650; }
.message-sender-avatar { position: relative; overflow: hidden; }
.message-sender-avatar img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.message-row.outgoing .message-sender-avatar { color:#fff; background: var(--green); }
.message-body { max-width: min(78%, 540px); }
.message-row.outgoing .message-body { display: flex; flex-direction: column; align-items: flex-end; }
.message-sender { display: block; margin: 0 3px 4px; color:var(--text-muted); font-size: 11px; }
.bubble { border:1px solid var(--border-subtle); border-radius: 4px 12px 12px 12px; padding: 10px 12px; color:var(--text-secondary); background:#fff; box-shadow: 0 3px 10px rgba(27,42,35,.035); font-size: 14px; line-height: 1.7; overflow-wrap: anywhere; }
.outgoing .bubble { border-color:var(--accent); border-radius: 12px 4px 12px 12px; color:#fff; background:var(--accent); }
.media-bubble { padding: 5px; overflow: hidden; }
.message-image { display: block; width: 240px; max-width: 100%; border: 0; padding: 0; border-radius: 8px; color:var(--text-muted); background:var(--canvas); cursor: zoom-in; overflow: hidden; }
.message-image img { display: block; width: 240px; max-width: 100%; height: 180px; object-fit: contain; }
.message-image span { display: block; padding: 6px 8px; font-size: 13px; }
.message-image.media-error { cursor: pointer; }
.message-image.media-error span, .login-error { color:var(--danger-fg); }
.message-video { display: block; width: 280px; max-width: 100%; max-height: 240px; border-radius: 8px; background:var(--d-bg); }
.message-voice { display: flex; align-items: center; gap: 8px; }
.message-voice audio { width: 220px; max-width: 100%; height: 34px; }
.message-voice i { color:var(--text-muted); font-style: normal; font-size: 12px; white-space: nowrap; }
.outgoing .message-voice i { color:var(--g-100); }
.message-file { display: block; min-width: 180px; max-width: 260px; padding: 2px; color: inherit; text-decoration: none; }
.message-file b { display: block; font-size: 13px; overflow-wrap: anywhere; }
.message-file span { display: block; margin-top: 3px; color:var(--text-muted); font-size: 12px; }
.outgoing .message-file span { color:var(--g-100); }
.image-unavailable { padding: 7px; max-width: 240px; }
.image-unavailable b { display: block; color:var(--warning-fg); font-size: 13px; }
.image-unavailable span { display: block; margin-top: 5px; color:var(--text-muted); font-size: 13px; line-height: 1.6; }
.image-viewer { max-width: 94vw; max-height: 94vh; padding: 38px 16px 16px; border: 0; border-radius: 12px; background:var(--d-bg); box-shadow: var(--shadow-3); }
.image-viewer::backdrop { background: var(--overlay); }
.image-viewer img { display: block; max-width: 88vw; max-height: 82vh; min-width: 240px; object-fit: contain; }
#image-viewer-close { position: absolute; right: 8px; top: 4px; border: 0; background: transparent; color:#fff; font-size: 27px; cursor: pointer; }
.message-body time { display: block; margin: 4px 3px 0; color:var(--text-muted); font-size: 11px; }
.message-empty { min-height: 100%; display: flex; flex-direction: column; align-items: center; justify-content: center; color:var(--text-muted); text-align: center; }
.message-empty > span { width: 44px; height: 44px; margin-bottom: 9px; border-radius: 15px; display: grid; place-items: center; color:var(--text-muted); background:var(--n-100); font-size: 12px; font-weight: 700; }
.message-empty b { color:var(--text-muted); font-size: 12px; }
.message-empty p { margin: 5px 0 0; color:var(--text-muted); font-size: 11px; }
.message-empty.error > span { color:var(--danger-fg); background:var(--danger-bg); }
.message-loading { min-height: 100%; display: flex; align-items: center; justify-content: center; gap: 8px; color:var(--text-muted); font-size: 12px; }
.message-loading i { width: 14px; height: 14px; border:2px solid var(--border); border-top-color: var(--green); border-radius: 50%; animation: spin .7s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }
.message-foot { border-top: 1px solid var(--line); padding: 0 14px; color:var(--text-muted); background:#fff; display: flex; align-items: center; justify-content: space-between; font-size: 11px; }
.message-foot span { display: flex; align-items: center; gap: 5px; }
.message-foot i { width: 5px; height: 5px; border-radius: 50%; background:var(--g-500); }

.route-column { border-left: 1px solid var(--line); padding: 17px 15px 14px; background:#fff; display: flex; flex-direction: column; }
.route-head { padding-bottom: 13px; border-bottom:1px solid var(--border-subtle); }
.route-inspector { flex: 1; }
.route-placeholder { min-height: 300px; display: grid; place-content: center; justify-items: center; text-align: center; }
.route-placeholder span { width: 39px; height: 39px; margin-bottom: 8px; border-radius: 12px; display: grid; place-items: center; color:var(--text-muted); background:var(--canvas); font-size: 12px; }
.route-placeholder p { max-width: 180px; margin: 0; color:var(--text-muted); font-size: 11px; line-height: 1.6; }
.route-status { margin: 14px 0; border-radius: 10px; padding: 11px; display: flex; align-items: center; gap: 9px; }
.route-status.ok { color:var(--accent); background:var(--accent-soft-bg); }
.route-status.pending { color:var(--warning-fg); background:var(--warning-bg); }
.route-status > i { width: 8px; height: 8px; border-radius: 50%; background: currentColor; box-shadow: 0 0 0 4px rgba(255,255,255,.45); }
.route-status b, .route-status small { display: block; }
.route-status b { font-size: 12px; }
.route-status small { margin-top: 3px; opacity: .7; font-size: 11px; }
.route-details { margin: 0; }
.route-details > div { padding: 8px 0; border-bottom:1px solid var(--border-subtle); display: grid; grid-template-columns: 60px 1fr; gap: 9px; }
.route-details dt { color:var(--text-muted); font-size: 11px; }
.route-details dd { margin: 0; overflow: hidden; color:var(--text-secondary); font-size: 11px; text-align: right; text-overflow: ellipsis; white-space: nowrap; }
.route-suppliers, .route-skus { margin-top: 14px; }
.route-suppliers > div:first-child, .route-skus > div:first-child { display: flex; align-items: center; justify-content: space-between; }
.route-suppliers b, .route-skus b { font-size: 12px; }
.route-suppliers > div:first-child span, .route-skus > div:first-child span { color:var(--text-muted); font-size: 11px; }
.supplier-pills { max-height: 76px; margin-top: 8px; overflow-y: auto; display: flex; flex-wrap: wrap; gap: 5px; }
.supplier-pills span { border-radius: 6px; padding: 4px 6px; color:var(--accent); background:var(--canvas); font-size: 11px; }
.classify-group { margin-top: 13px; }
.classify-group > b { display: block; margin-bottom: 7px; font-size: 12px; }
.classify-group > div { padding: 3px; border-radius: 8px; background:var(--canvas); display: grid; grid-template-columns: 1fr 1fr; gap: 3px; }
.classify-group button { border: 0; border-radius: 6px; padding: 6px; color:var(--text-muted); background: transparent; cursor: pointer; font-size: 11px; }
.classify-group button.active { color:var(--accent); background:#fff; box-shadow: 0 2px 8px rgba(31,52,42,.07); font-weight: 650; }
.sku-pills { max-height: 100px; margin-top: 8px; overflow-y: auto; display: flex; flex-wrap: wrap; gap: 5px; }
.sku-pills span { border-radius: 6px; padding: 4px 6px; color:var(--accent); background:var(--canvas); font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 11px; }
.route-suppliers p, .route-skus p { margin: 7px 0 0; color:var(--text-muted); font-size: 11px; line-height: 1.6; }
.route-id { margin-top: 15px; border-radius: 9px; padding: 9px; background:var(--surface-hover); }
.route-id span, .route-id code { display: block; }
.route-id span { margin-bottom: 5px; color:var(--text-muted); font-size: 11px; }
.route-id code { overflow: hidden; color:var(--text-muted); font-size: 11px; text-overflow: ellipsis; white-space: nowrap; }
.route-action { width: 100%; margin-top: 13px; display: flex; justify-content: space-between; align-items: center; }

.compact-panel { align-self: start; }
.note { align-self: start; border-color:var(--warning-border); background:var(--warning-bg); display: flex; gap: 12px; }
.note-icon { width: 27px; height: 27px; flex: 0 0 27px; border-radius: 9px; display: grid; place-items: center; color:var(--warning-fg); background:var(--warning-bg); font-size: 12px; font-weight: 750; }
.note b { font-size: 13px; }
.note p { margin: 5px 0 0; color:var(--text-muted); font-size: 12px; line-height: 1.7; }
.table-panel { padding: 0; overflow: hidden; }
.table-panel .panel-title { margin: 0; padding: 19px 20px 15px; }
.table-wrap { overflow: auto; }
.data-table { max-height: 560px; }
.supplier-relations { margin-bottom: 15px; }
.supplier-master { margin-top: 15px; }
table { width: 100%; border-collapse: collapse; font-size: 12px; }
th { position: sticky; top: 0; z-index: 1; color:var(--text-muted); background:var(--surface-hover); text-align: left; font-size: 11px; font-weight: 750; letter-spacing: .08em; text-transform: uppercase; }
th, td { padding: 11px 14px; border-top: 1px solid var(--line); vertical-align: top; }
td { color:var(--text-secondary); line-height: 1.5; }
td strong { color: var(--ink); }
.table-empty { padding: 32px; color:var(--text-muted); text-align: center; }
.tag { display: inline-block; border-radius: 99px; padding: 4px 7px; color:var(--accent); background:var(--canvas); font-size: 11px; font-weight: 650; white-space: nowrap; }
.tag.pending { color:var(--warning-fg); background:var(--warning-bg); }
.tag.done { color:var(--accent); background:var(--accent-soft-bg); }
.tag.warn { color:var(--danger-fg); background:var(--danger-bg); }
.reply-box { min-width: 185px; display: flex; gap: 5px; }
.reply-box input { margin: 0; padding: 7px; font-size: 11px; }
.reply-box button { width: auto; padding: 6px 8px; font-size: 11px; }
.sync-panel { margin-bottom: 15px; display: flex; align-items: center; gap: 10px; }
.sync-panel > div { flex: 1; }
.sync-panel p { margin: 5px 0 0; color: var(--muted); font-size: 12px; }

#toast { position: fixed; right: 22px; bottom: 22px; z-index: 100; max-width: min(360px, calc(100vw - 44px)); border-radius: 10px; padding: 11px 14px; color:#fff; background:var(--d-selected); box-shadow: 0 12px 30px rgba(16, 49, 37, .22); opacity: 0; pointer-events: none; transform: translateY(8px); transition: .2s; font-size: 12px; }
#toast.show { opacity: 1; transform: none; }

.modal-backdrop { position: fixed; inset: 0; z-index: 200; padding: 20px; display: grid; place-items: center; background: rgba(12, 25, 20, .52); backdrop-filter: blur(5px); }
.modal-card { width: min(420px, 100%); border: 1px solid rgba(255,255,255,.45); border-radius: 16px; padding: 24px; background:#fff; box-shadow: 0 24px 70px rgba(8, 25, 18, .28); }
.modal-kicker { color:var(--text-muted); font-size: 11px; font-weight: 750; letter-spacing: .18em; }
.modal-card h2 { margin-top: 6px; font-size: 19px; }
.modal-card > p { margin: 7px 0 18px; color:var(--text-muted); font-size: 12px; line-height: 1.65; }
.modal-card label { margin-bottom: 19px; }
.modal-actions { display: flex; justify-content: flex-end; gap: 8px; }

/* 登录弹窗：飞书为主、管理员账号为辅。
   形态要和 shared/common.css 里子页面那个弹窗保持一致——同一个人从首页进和从
   /library 进不该看到两种登录方式。改这里记得一起看那边。 */
#key-modal-feishu {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  height: 42px; border-radius: 10px; text-decoration: none; width: 100%;
  background: var(--green); color: var(--text-on-accent); font-size: 15px; font-weight: 600;
}
#key-modal-feishu[hidden] { display: none; }
#key-modal-feishu:hover { background: var(--green-2); }
#key-modal-feishu span {
  width: 20px; height: 20px; border-radius: 5px; display: grid; place-items: center;
  background: rgba(255, 255, 255, .22); font-size: 12px; font-weight: 400;
}
/* 管理员登录刻意做成一行小字而不是按钮：它是备用入口，不该和飞书登录抢注意力 */
#key-modal-toggle {
  display: block; margin: 14px auto 0; border: 0; background: none; cursor: pointer; font: inherit;
  color: var(--text-muted); font-size: 12px; text-decoration: underline; padding: 2px;
}
#key-modal-toggle:hover { color: var(--ink-2); }
#key-modal-toggle.hidden { display: none; }
#key-modal-form[hidden] { display: none; }
#key-modal-form { margin-top: 16px; }
#key-modal-error:empty { display: none; }

@media (max-width: 1220px) {
  .metrics { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .messenger-grid { grid-template-columns: 265px minmax(390px, 1fr); }
  .route-column { grid-column: 1 / -1; border-top: 1px solid var(--line); border-left: 0; display: grid; grid-template-columns: 190px 1fr auto; gap: 15px; align-items: start; }
  .route-head { border: 0; }
  .route-inspector { display: contents; }
  .route-placeholder { min-height: 100px; }
  .route-action { width: auto; align-self: center; }
}

@media (max-width: 900px) {
  .app-shell { grid-template-columns: 1fr; }
  .sidebar { position: static; height: auto; padding: 13px 14px; }
  .brand { padding: 0 2px 12px; }
  .brand-mark { width: 34px; height: 34px; border-radius: 10px; }
  .brand-logo { padding: 4px 6px; }
  .brand-logo img { width: 41px; height: 28px; }
  .brand .brand-word { width: 90px; height: 25px; }
  /* 带上 .primary-nav：上面 .primary-nav .nav-sub { display: flex } 更具体，只写 .nav-sub 盖不住，窄窗口横条里小标题会被挤成一字一行（2026-10-08「每天先看」） */
  .primary-nav .nav-label, .primary-nav .nav-sub { display: none; }
  .primary-nav { flex-direction: row; overflow-x: auto; overflow-y: visible; flex: 0 0 auto; }
  .page-tabs { margin-top: 6px; }
  .nav { min-width: max-content; padding: 7px 9px; }
  .nav > span { width: 25px; height: 25px; flex-basis: 25px; }
  .nav-live { display: none; }
  .main-content { padding: 20px 16px 45px; }
  .grid.two, .grid.split { grid-template-columns: 1fr; }
  .wechat-summary { align-items: flex-start; flex-direction: column; gap: 12px; }
  .messenger-toolbar { align-items: flex-start; flex-direction: column; }
  .toolbar-actions { width: 100%; }
  .search-box { flex: 1; width: auto; }
}

@media (max-width: 720px) {
  .topbar { margin-bottom: 17px; }
  .api-state { display: none; }
  .welcome-card { align-items: flex-start; flex-direction: column; }
  .welcome-card h2 { font-size: 18px; }
  .metrics { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .messenger-grid { display: block; }
  .conversation-column { border-right: 0; border-bottom: 1px solid var(--line); }
  .conversation-list { height: 310px; }
  .message-stream { height: 430px; }
  .route-column { display: flex; border-top: 1px solid var(--line); }
  .route-inspector { display: block; }
  .route-action { width: 100%; }
  .wechat-stats { width: 100%; overflow-x: auto; }
  .toolbar-actions { flex-wrap: wrap; }
  .search-box { flex-basis: 100%; }
  .flow-row { flex-wrap: wrap; }
  .flow-row > b { display: none; }
  .flow-row > span { flex-basis: 30%; }
  .sync-panel { align-items: stretch; flex-direction: column; }
  .primary.compact { width: 100%; }
}

@media (max-width: 470px) {
  .metrics { grid-template-columns: 1fr; }
  .topbar-right { gap: 7px; }
  /* 手机上只留「设」字图标给 h1 让位；入口本身必须留着——
     原来这里是 .sidebar-bottom{display:none}，把全站唯一的登录入口藏掉了。 */
  .topbar-right .nav.topbar-entry b { display: none; }
  .topbar-right .nav.topbar-entry { padding: 6px; }
  .wechat-stats > span { min-width: 77px; }
  .toolbar-actions select, .icon-button { flex: 1; }
  .flow-row > span { flex-basis: 45%; }
}
.selection-status { display:flex; justify-content:space-between; align-items:center; gap:16px; margin-bottom:20px; }
.selection-status p { margin:8px 0 0; }
.selection-metrics { grid-template-columns:repeat(4,minmax(0,1fr)); }
.selection-metrics strong { font-size:25px; }
.selection-rules { align-items:flex-start; }
.selection-rules p { margin:12px 0; line-height:1.8; }
.selection-preview-result { padding:18px 0 0; line-height:1.8; }
.selection-preview-result small { display:block; margin-top:12px; }
.selection-catalog { margin:24px 0; }
.selection-catalog > .search-box { max-width:540px; margin:18px 0; }
.selection-product-list { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:14px; }
.selection-product { border:1px solid var(--selection-border); border-radius:12px; padding:18px; min-width:0; }
.selection-product-heading { display:flex; flex-direction:column; gap:6px; margin-bottom:12px; overflow-wrap:anywhere; }
.selection-product-heading strong { color:var(--accent); }
.selection-product-heading span { color:var(--text-muted); font-size:13px; }
.selection-keywords { display:flex; flex-wrap:wrap; gap:6px; margin-bottom:16px; }
.keyword-chip { border:1px solid var(--accent-soft-border); border-radius:6px; padding:5px 9px; background:var(--accent-soft-bg); color:var(--accent-soft-fg); font-size:12px; overflow-wrap:anywhere; text-align:left; max-width:100%; }
.keyword-chip.disabled { background:var(--surface-sunken); color:var(--text-disabled); text-decoration:line-through; }
.selection-custom { display:flex; gap:10px; align-items:flex-end; }
.selection-custom label { flex:1; margin:0; font-size:12px; min-width:0; }
.selection-custom input { margin-top:7px; }
.selection-custom button { flex-shrink:0; }
.selection-pagination { display:flex; align-items:center; justify-content:center; gap:18px; padding:20px 0 6px; }
.selection-message-cell { min-width:220px; max-width:350px; white-space:pre-wrap; overflow-wrap:anywhere; }
.selection-candidate-cell { min-width:190px; max-width:300px; overflow-wrap:anywhere; }
.selection-candidate { display:block; padding:5px 0; font-size:12px; line-height:1.6; }
.selection-candidate-cell details { margin-top:10px; }
.selection-candidate-cell summary { cursor:pointer; color:var(--accent); }
.selection-actions { min-width:170px; max-width:250px; }
.selection-actions select { max-width:230px; margin-bottom:8px; }
@media(max-width:1100px) { .selection-product-list { grid-template-columns:1fr; } .selection-metrics { grid-template-columns:repeat(2,minmax(0,1fr)); } }
@media(max-width:600px) { .selection-status { align-items:flex-start; flex-direction:column; } .selection-custom { flex-direction:column; align-items:stretch; } }

/* SKU 悬浮信息卡：悬停 SKU 标签显示产品名，有 image_url 时显示产品图 */
#sku-tip { position: fixed; z-index: 90; max-width: 260px; border: 1px solid var(--line-strong); border-radius: 10px; padding: 10px 12px; background:#fff; box-shadow: 0 10px 30px rgba(21, 42, 32, .16); pointer-events: none; }
#sku-tip[hidden] { display: none; }
#sku-tip b { display: block; font-size: 13px; }
#sku-tip span { display: block; margin-top: 3px; color:var(--text-muted); font-size: 12px; line-height: 1.55; }
#sku-tip img { display: block; width: 100%; max-height: 170px; margin-top: 8px; border-radius: 8px; object-fit: contain; background:var(--surface-hover); }
.sku-pills span { cursor: default; }

/* 会话接管按钮与选品页开关排布 */
.chat-header .takeover-toggle { flex: 0 0 auto; }
.selection-status-actions { display: flex; align-items: center; gap: 10px; flex: 0 0 auto; }

/* 顶栏全局发送状态：全站可见，点击直达选品触发页开关 */
button.api-state.send-mode { border: 0; border-radius: 99px; padding: 7px 12px; cursor: pointer; font-weight: 600; }
#send-mode-state.live { color:var(--accent); background:var(--accent-soft-bg); }
#send-mode-state.live i { background:var(--g-500); box-shadow: 0 0 0 4px rgba(69,165,116,.16); }
#send-mode-state.paused { color:var(--warning-fg); background:var(--warning-bg); }
#send-mode-state.paused i { background: var(--amber); box-shadow: 0 0 0 4px rgba(229,160,77,.18); }

/* 微信桌面版参考重构：时间分隔、成员网格、会话详情、加大输入区 */
.day-divider { justify-content: center; }
.day-divider::before, .day-divider::after { display: none; }
.day-divider span { padding: 3px 10px; border-radius: 6px; color:var(--text-muted); background:var(--canvas); }
.conversation-avatar { width: 40px; height: 40px; flex: 0 0 40px; border-radius: 9px; }
.chat-compose textarea { flex: 1; margin: 0; min-height: 58px; resize: none; font-size: 14px; line-height: 1.6; }
.chat-compose button { align-self: flex-end; }
.member-section { margin-bottom: 16px; }
.member-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 9px; }
.member-head b { font-size: 13px; }
.member-head span { color:var(--text-muted); font-size: 12px; }
.member-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px 6px; }
.member { min-width: 0; border: 0; padding: 0; background: transparent; text-align: center; }
.member-avatar { position: relative; overflow: hidden; width: 38px; height: 38px; margin: 0 auto; border-radius: 9px; display: grid; place-items: center; font-style: normal; color:var(--text-secondary); background:var(--n-100); font-size: 12px; font-weight: 650; }
.member-avatar img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.member > span { display: block; margin-top: 4px; color:var(--text-muted); font-size: 11px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.member.more { cursor: pointer; }
.member.more .member-avatar { color:var(--text-muted); background:var(--canvas); }
.member.more:hover .member-avatar { background:var(--n-100); }
.member-hint { grid-column: 1 / -1; margin: 0; color:var(--text-muted); font-size: 12px; }
.chat-info { margin: 0 0 14px; }
.chat-info > div { padding: 8px 0; border-top:1px solid var(--border-subtle); display: flex; justify-content: space-between; gap: 10px; }
.chat-info dt { flex: none; color:var(--text-muted); font-size: 12px; }
.chat-info dd { margin: 0; min-width: 0; font-size: 12px; text-align: right; overflow-wrap: anywhere; }
.member-owner { position: absolute; left: 0; right: 0; bottom: 0; padding: 1px 0; color:#fff; background: rgba(22, 100, 71, .82); font-style: normal; font-size: 10px; line-height: 1.3; }

/* 选品触发页 · 基本设置（回复方式） */
.selection-settings { margin-bottom: 20px; }
.setting-row { display: flex; justify-content: space-between; align-items: center; gap: 16px; flex-wrap: wrap; }
.setting-row > div:first-child p { margin: 5px 0 0; font-size: 12px; }
.segmented { display: inline-flex; padding: 3px; border:1px solid var(--border); border-radius: 10px; background:var(--canvas); flex: 0 0 auto; }
.segmented button { border: 0; padding: 7px 16px; border-radius: 8px; color:var(--text-muted); background: transparent; font-size: 13px; cursor: pointer; }
.segmented button[aria-pressed="true"] { color:#fff; background:var(--accent); box-shadow: 0 2px 6px rgba(28,110,80,.25); }
.segmented button:disabled { opacity: .6; cursor: default; }
.style-compare { margin-top: 14px; }
.style-compare summary { cursor: pointer; color:var(--accent); font-size: 13px; }
.style-compare-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-top: 12px; }
.style-compare-grid > div > p { margin: 4px 0 8px; font-size: 12px; }
.style-sample { margin: 0; white-space: pre-wrap; font-family: inherit; }
@media(max-width: 760px) { .style-compare-grid { grid-template-columns: 1fr; } }

/* 微信会话页交互修复（2026-09-14）
   问题一：气泡是块级元素，同一条消息下方的意图分析卡把 .message-body 撑到 540px 时，
   图片/短文本气泡跟着占满整行，右侧留大片空白。让气泡按内容收缩。 */
.message-body .bubble { width: fit-content; max-width: 100%; }

/* 问题二：三栏原来用固定像素高度（列表 527px、消息流 501px），右侧详情栏内容一长就把
   整张卡撑高，中间和左侧在半截断掉、下方大片空白，整页还要再滚一层。
   宽屏下改成：卡片高度跟随视口，三栏等高、各自内部滚动。窄屏（≤1220px）维持原布局。 */
@media (min-width: 1221px) {
  .messenger-grid { height: clamp(560px, calc(100vh - 252px), 1200px); min-height: 0; }
  .conversation-column { display: flex; flex-direction: column; min-height: 0; }
  .conversation-list { flex: 1; height: auto; min-height: 0; }
  .message-column { min-height: 0; }
  .message-stream { height: auto; min-height: 0; }
  .route-column { min-height: 0; }
  .route-inspector { min-height: 0; overflow-y: auto; scrollbar-width: thin; scrollbar-color: var(--border) transparent; }
}

/* 任务的问答轮次（app.js toggleTaskRounds）：点任务号展开这条线问了什么、答了什么。
   追问沿用原号之后一个任务可能装着好几轮，表格里 question 一整坨、answer 只剩最后一句。 */
.task-code { padding: 0; border: 0; background: none; color: var(--accent); font: inherit; font-weight: 650; cursor: pointer; }
.task-code:hover { text-decoration: underline; }
.task-rounds > td { padding: 0 14px 12px; background: var(--surface-hover); }
.rounds { display: grid; gap: 8px; padding: 10px 12px; border-left: 3px solid var(--border-strong); border-radius: 0 10px 10px 0; background: var(--surface); }
.round { display: flex; gap: 10px; align-items: flex-start; }
.round p { margin: 0; color: var(--text-primary); font-size: 13px; line-height: 1.6; overflow-wrap: anywhere; }
.round small { color: var(--text-muted); font-size: 11.5px; }
.round-tag { flex: 0 0 auto; min-width: 4.5em; padding: 1px 8px; border-radius: 99px; text-align: center;
  background: var(--n-100); color: var(--text-muted); font-size: 11px; font-weight: 650; }
.round.ask .round-tag { background: var(--b-200); color: var(--info-fg); }
.round.reply .round-tag { background: var(--g-100); color: var(--g-700); }
.round.dropped { opacity: .75; }
.round.dropped .round-tag { background: var(--a-200); color: var(--warning-fg); }
.round.dropped p { color: var(--text-muted); }
#wechat-batch-classify { white-space: nowrap; }   /* 窗口窄 / 放大看时别折成两行 */

/* 2026-09-29 老板：侧栏往下滚时组标题要一直看得见（知道自己在哪一组）。组标题是一排平铺的兄弟元素（折叠、上色、
   空组自动藏都靠这个结构），直接给它们 sticky 会一个个叠在顶上，所以改成列表顶上盖一条「当前组」：app.js trackNavGroup
   随滚动换字，回到最顶上就藏。它高度为 0、不占位置，里面那条绝对定位盖在列表最上面，滚动时不会把列表顶得跳一下。 */
.nav-current { position: relative; height: 0; z-index: 4; }
.nav-current[hidden] { display: none !important; }
.nav-current > button { position: absolute; left: 0; right: 0; top: 0; display: block; width: 100%; padding: 6px 10px;
  border: 0; border-bottom: 1px solid var(--d-border-strong); background: var(--sidebar); color: var(--d-text-2);
  font: inherit; font-size: 12px; font-weight: 700; letter-spacing: .12em; text-align: left; cursor: pointer;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.nav-current > button:hover { color: var(--d-text); }
/* 10-20 这条只是告诉你在哪组，不再能点：它盖在第一行上，点组名常点到它 → 滚一下、组没收 */
.nav-current > button { pointer-events: none; cursor: default; }
/* 组标题做成按钮时（「我的工作」一直是按钮；可收起的组也是）去掉浏览器默认按钮样式，整宽，好让钉住时的底色盖满 */
.primary-nav button.nav-label { display: flex; align-items: center; border: 0; background: transparent; font-family: inherit;
  font-size: 13px; font-weight: 700; letter-spacing: .16em; color: var(--d-text-3); text-align: left; cursor: pointer; }
/* ≤900px 侧栏变成顶部横条时组标题一律藏：上面 @media (max-width: 900px) 里的 .nav-label{display:none}
   会被这条按钮样式盖掉（更具体、写得更靠后），「我的工作 · 管理层」被挤成一字一行、整条顶栏变形（2026-10-01 老板截图）。
   这条必须写在按钮样式后面。 */
@media (max-width: 900px) { .primary-nav button.nav-label { display: none; } }
@media (max-width: 900px) { .primary-nav .nav-ghost { display: none; } }   /* 横条里只放真入口，原位灰字不画（10-17） */

/* 侧栏按工作流 ①–⑧ 分组（2026-10-01）：步骤名长（「② 找产品·问工厂·做目录」），组标题小一号、不加字距、不换行，196 宽放得下（实测 13px 宽 165 > 152）；≤900px 横条里组标题照旧藏（上面那条 display:none 不受影响，这里不写 display） */
.primary-nav .nav-label[data-step] { font-size: 12px; letter-spacing: 0; white-space: nowrap; }
/* 「我的工作 · B2C 店长」「我的工作 · 开发 / 采购」：岗位名长，13px 加 .16em 字距在 196 宽里折成两行（10-17 拆 B2C 两行时看到）——字距收小、不折行，真放不下就省略号（悬停看全） */
.primary-nav .nav-label[data-flow] { letter-spacing: .04em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* 首页改版第一步（2026-10-02）：首页上方有一个大的全站搜索（同一套），顶栏这个就不重复摆了；手机外壳（html.is-phone）顶上那条照旧 */
html:not(.is-phone) body[data-page="home"] #gs { display: none; }


/* ================= 侧栏可拖宽 / 收成图标栏 / 顶栏不再重复页名（老板 2026-10-07）=================
   老板的四条：① 侧栏已经写着功能名，内容区左上角又一个大标题——重复；② 侧栏不能手动调宽；
   ③ 有些页缩放后留白（各页的事，见 shared/embed-fit.css）；④ 侧栏整体再优化。
   这一段：右边缘拖柄 .sb-resize、底部 .sb-foot 两颗按钮、图标栏 [data-rail] 的样子、顶栏页名的显示规则。颜色全走 tokens.css。 */

/* 拖柄：贴在侧栏右边缘，8px 宽好抓，平时看不见，停上去 / 拖的时候亮一条薄荷绿 */
.sb-resize { position: absolute; top: 0; right: -4px; bottom: 0; width: 8px; cursor: col-resize; z-index: 21; touch-action: none; }
.sb-resize::after { content: ''; position: absolute; top: 0; bottom: 0; left: 3px; width: 2px; background: transparent; transition: background .15s; }
.sb-resize:hover::after, .sb-resize.on::after { background: var(--d-accent); }
.app-shell.sb-dragging { cursor: col-resize; user-select: none; }
.app-shell.sb-dragging .embed-frame { pointer-events: none; }   /* 拖的时候鼠标滑到 iframe 上，事件会被它吞掉 */

/* 底部两颗按钮：和「找功能」那颗同一套深色描边 */
.sb-foot { flex: 0 0 auto; display: flex; gap: 6px; margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--d-border); }
.sb-btn { flex: 1 1 0; min-width: 0; display: inline-flex; align-items: center; justify-content: center; gap: 4px; height: 30px; padding: 0 4px;
  border: 1px solid var(--d-border); border-radius: var(--radius-sm); background: transparent; color: var(--d-text-3);
  font: inherit; font-size: 12px; line-height: 1; cursor: pointer; white-space: nowrap; transition: color .18s, border-color .18s; }
.sb-btn:hover, .sb-btn:focus-visible { color: var(--d-text); border-color: var(--d-accent); outline: none; }
.sb-btn svg { flex: 0 0 auto; }
.sb-btn b { font-weight: 500; overflow: hidden; text-overflow: ellipsis; }
.sb-btn[aria-pressed="true"] svg { transform: rotate(180deg); }

/* 图标栏：64px，只留图标；名字在 title 里（app.js syncNavTitles）。组标题变成一条细线，小标题藏起来，折叠状态不管（全部显示） */
.app-shell[data-rail] { grid-template-columns: 64px minmax(0, 1fr); }   /* 展开时的宽度由 app.js 写成行内 grid-template-columns（不用自定义变量：test_ui_standard 要求 var() 名字都在 tokens.css 里） */
.app-shell[data-rail] .sidebar { padding-left: 8px; padding-right: 8px; }
.app-shell[data-rail] .brand { justify-content: center; gap: 0; padding: 0 0 16px; }
.app-shell[data-rail] .brand > div { display: none; }
.app-shell[data-rail] .brand-logo { padding: 4px 5px; }
.app-shell[data-rail] .brand-logo img { width: 38px; height: 26px; }
.app-shell[data-rail] .nav-finder { margin-top: -6px; }
.app-shell[data-rail] .nav-find { justify-content: center; padding: 8px 0; }
.app-shell[data-rail] .nav-find-t, .app-shell[data-rail] .nav-find kbd { display: none; }
.app-shell[data-rail] .nav-find-box, .app-shell[data-rail] .nav-find-more { display: none; }   /* 2026-10-08 侧栏找功能框：图标栏放不下，只留放大镜 */
.app-shell[data-rail] .nav-find-rail { display: flex; }
.app-shell[data-rail] .nav-current { display: none; }
.app-shell[data-rail] .primary-nav { overflow-x: hidden; }
.app-shell[data-rail] .primary-nav .nav-label { height: 0; margin: 9px 8px 5px; padding: 0; border-top: 1px solid var(--d-border); font-size: 0; overflow: hidden; pointer-events: none; }
.app-shell[data-rail] .primary-nav .nav-label::after, .app-shell[data-rail] .primary-nav .nav-label::before { display: none; }
.app-shell[data-rail] .primary-nav .nav-sub { display: none !important; }
/* 图标栏里收起的组照样全显示——但只放出本来就该看得见的入口：原来写的是 [data-folded]，收起的组里的小标题、藏着的标签页登记（hidden）、
   没权限的（data-denied）、跳转壳（display:none）也被这条 !important 放了出来（2026-10-10 默认收起以后每个人都碰得到，小标题竖成一字一行） */
.app-shell[data-rail] .primary-nav .nav[data-folded]:not([hidden]):not([data-denied]):not([style*="display:none"]) { display: flex !important; }
.app-shell[data-rail] .primary-nav > .nav:first-child { margin-bottom: 0; }
.app-shell[data-rail] .nav { justify-content: center; gap: 0; padding: 7px 0; }
.app-shell[data-rail] .nav b, .app-shell[data-rail] .nav-live { display: none; }
.app-shell[data-rail] .nav.active { box-shadow: none; }
.app-shell[data-rail] .sb-foot { flex-direction: column; gap: 4px; }
.app-shell[data-rail] .sb-btn b { display: none; }

/* 顶栏页名：一直显示在「返回」按钮右边（2026-10-09 老板截图：「返回 · 开票申请」旁边「能不能也显示一下当前是哪个页?」——
   只看到回哪一屏、看不到自己在哪一屏，盖掉 10-07「侧栏展开时不重复页名」）。小一号、加粗，「? 说明」跟在它后面。
   用 #page-title 而不是 h1：help-tip.css 里有 `.topbar #page-title { display:inline-block }`，权重得压过它。 */
.topbar > div:first-child { display: flex; align-items: center; flex-wrap: wrap; gap: 6px 10px; }
.topbar #page-title { font-size: 15px; font-weight: 600; line-height: 1.3; letter-spacing: 0; color: var(--text-primary); }
.topbar .page-tabs { margin-top: 0; }
/* 页头标签放不下就在条里横着滑（2026-10-10：找工厂、AI 成绩单各会有 5 个标签）。原来标签条不换行也不能滑，左块（返回 + 页名 + 标签）
   又不许缩（shared/share-link.css 的 flex: 1 0 auto），窗口一窄整块顶出顶栏、页面横着滚。现在：顶栏放不下时照旧先折行（全站搜索框和右上角
   那串挪到第二行，搜索框自己最窄 120px 不会被挤没）；左块自己一行还放不下，标签条另起一行、在条里横滑，滚动条细细一条、只有放不下时才有，
   当前那个标签自动滚进来（app.js renderPageTabs）。左块能缩不会把页名挤成竖排：#page-title 是 nowrap（share-link.css）。手机版另有规则（phone.css） */
.main-content > .topbar > div:first-child { flex-shrink: 1; min-width: 0; }
.topbar .page-tabs { min-width: 0; max-width: 100%; overflow-x: auto; overflow-y: hidden; overscroll-behavior-x: contain;
  scrollbar-width: thin; scrollbar-color: var(--line) transparent; }
.topbar .page-tabs::-webkit-scrollbar { height: 4px; }
.topbar .page-tabs::-webkit-scrollbar-thumb { border-radius: 2px; background: var(--line); }
.topbar .page-tabs::-webkit-scrollbar-track { background: transparent; }
.page-tab { flex: 0 0 auto; white-space: nowrap; }
.topbar .gs { margin-left: auto; }   /* 搜索框靠右，挨着右上角那串按钮；左边空着给页内标签 */
/* 「返回」上一屏（2026-10-08 老板：「我要返回我上一个界面」）：顶栏左边第一个，当前页名紧跟在它右边。
   和右上角入口同一种浅色药丸，只有箭头一点绿，不抢眼；后面小字写回到哪一屏（窄了只留在悬停说明里）。
   第一屏时照样摆着、灰着（让人记住它在哪），点不了，不会把人退出中台。手机上只剩一个圆形 ‹，在页名左边 */
.topbar .nav-back {
  display: inline-flex; align-items: center; gap: 5px; flex: 0 1 auto; min-width: 0; max-width: min(40vw, 320px); height: 32px;
  padding: 0 12px 0 8px; border: 1px solid var(--border-control); border-radius: 999px; background: var(--surface);
  color: var(--text-primary); font: inherit; font-size: 13px; font-weight: 650; white-space: nowrap; cursor: pointer; touch-action: manipulation;
}
.nav-back svg { flex: 0 0 auto; color: var(--green); }
.nav-back .nav-back-to { min-width: 0; overflow: hidden; text-overflow: ellipsis; font-weight: 500; color: var(--text-secondary); }
.nav-back .nav-back-to::before { content: '·'; margin-right: 5px; color: var(--text-muted); }
/* 悬停和顶栏其他按钮一样（浅底）：用 accent 浅绿的话看着像「当前所在页」 */
.nav-back:hover:not(:disabled) { color: var(--text-primary); background: var(--surface-hover); }
.nav-back b { font-weight: inherit; }
.nav-back:focus-visible { outline: 2px solid var(--green); outline-offset: 2px; }
.nav-back:disabled { opacity: .45; cursor: default; }
.nav-back:disabled svg { color: inherit; }
@media (max-width: 1100px) { .nav-back .nav-back-to { display: none; } }   /* 回到哪一屏还在悬停说明和读屏里 */
/* 顶栏挤不下（页内标签多、右上角按钮多）时 app.js navFitBack 加的：先收小字，再只留箭头，顶栏不折成两行 */
.nav-back.nb-short .nav-back-to, .nav-back.nb-icon b { display: none; }
.topbar .nav-back.nb-icon { width: 32px; flex: 0 0 32px; padding: 0; justify-content: center; }
html.is-phone .topbar .nav-back { width: 36px; height: 36px; flex: 0 0 36px; padding: 0; justify-content: center; }
html.is-phone .nav-back b, html.is-phone .nav-back .nav-back-to { display: none; }
/* 顶栏尽量一行：1440 宽的屏上管理员右上角那串（反馈、链接、以谁的身份看、演练中、人员管理、系统设置、账）放不下会折成第二行，
   ≤1560px 时「人员管理 / 系统设置」只留图标（鼠标停上去有名字，和「复制链接」一样的做法） */
@media (max-width: 1560px) {
  .topbar-right .nav.topbar-entry b { display: none; }
  .topbar-right .nav.topbar-entry { padding: 6px 7px; }
}

/* 10-18 侧栏改版第 1 步：顶栏「等我的 N」/「今天要我做的 N」小牌子 + 侧栏「首页」右边同一个数（app.js loadTodoChip，app/home.py todo） */
.todo-chip { display: inline-flex; align-items: center; gap: 6px; padding: 5px 10px 5px 12px; border-radius: 999px; white-space: nowrap;
  border: 1px solid var(--warning-border); background: var(--warning-bg); color: var(--warning-fg); font-size: 12px; font-weight: 600; text-decoration: none; }
.todo-chip b { min-width: 20px; height: 20px; padding: 0 6px; box-sizing: border-box; border-radius: 999px; display: inline-grid; place-items: center;
  background: var(--warning-fg); color: var(--n-0); font-size: 12px; font-variant-numeric: tabular-nums; }
.todo-chip:hover { border-color: var(--warning-fg); }
.todo-chip.zero { border-color: var(--border); background: var(--surface); color: var(--text-muted); }
.todo-chip.zero b { background: var(--surface-sunken); color: var(--text-muted); }
.nav > .nav-todo { margin-left: auto; flex: 0 0 auto; min-width: 18px; height: 18px; padding: 0 5px; box-sizing: border-box; border-radius: 999px;
  background: var(--a-200); color: var(--d-bg); font: 700 11px/18px system-ui, sans-serif; font-style: normal; text-align: center; }

/* 10-24 工序条（app.js paintFlowChain；Edmond：「颜色能不能弄得显眼一点……让大家更容易理解上下游工序之间的关联」）：
   整条淡绿底；这一步实心「你在这」；前后两步描边写「上一步 / 下一步」；打不开的那步灰虚线、写哪个岗在做；下面一句单从哪来、做完去哪 */
.flow-chain { margin: -8px 0 12px; padding: 8px 10px 7px; border: 1px solid var(--accent-soft-border); border-radius: 12px; background: var(--accent-soft-bg); font-size: 13px; }
.flow-chain .fc-row { display: flex; align-items: stretch; gap: 0; min-width: 0; }
.flow-chain .fc-head { flex: 0 0 auto; display: flex; flex-direction: column; justify-content: center; gap: 1px; padding: 0 12px 0 2px; margin-right: 6px;
  border-right: 1px solid var(--accent-soft-border); white-space: nowrap; }
.flow-chain .fc-head b { font-size: 14px; color: var(--accent-soft-fg); }
.flow-chain .fc-head span { font-size: 12px; color: var(--text-secondary); }
.flow-chain .fc-step { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; gap: 1px; padding: 5px 9px 6px; border: 1px solid var(--border-subtle);
  border-radius: 9px; background: var(--surface); color: var(--text-primary); text-align: left; font: inherit; line-height: 1.35; }
.flow-chain button.fc-step { cursor: pointer; }
.flow-chain button.fc-step:hover { border-color: var(--accent); background: var(--surface-hover); }
.flow-chain .fc-step.near { border-color: var(--accent-soft-border); }
.flow-chain .fc-step.here { border-color: var(--accent); background: var(--accent); color: var(--text-on-accent); }
.flow-chain .fc-step.off { border-style: dashed; background: transparent; color: var(--text-muted); }
.flow-chain .fc-tag { font-style: normal; font-size: 11px; color: var(--text-muted); white-space: nowrap; }
.flow-chain .fc-step.near .fc-tag { color: var(--accent-soft-fg); font-weight: 600; }
.flow-chain .fc-step.here .fc-tag { color: var(--text-on-accent); font-weight: 600; }
.flow-chain .fc-name { display: flex; align-items: baseline; gap: 5px; font-size: 14px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.flow-chain .fc-name em { flex: none; font-style: normal; font-size: 11px; font-weight: 700; display: inline-grid; place-items: center; width: 17px; height: 17px;
  border-radius: 999px; background: var(--surface-sunken); color: var(--text-secondary); }
.flow-chain .fc-step.here .fc-name em { background: var(--text-on-accent); color: var(--accent); }
.flow-chain .fc-step small { font-size: 12px; color: var(--text-secondary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.flow-chain .fc-step.here small { color: var(--text-on-accent); }
.flow-chain .fc-step.off small { color: var(--text-muted); }
.flow-chain .fc-step.bad small { color: var(--danger-fg); font-weight: 600; }
.flow-chain .fc-step.warn small { color: var(--warning-fg); font-weight: 600; }
/* 10-24 Edmond 截图「你在这个颜色反向完全看不到」：「你在这」那格是实心绿底，数字的红 / 橙字压在绿底上看不清——这格一律白字加粗 */
.flow-chain .fc-step.here small, .flow-chain .fc-step.here.bad small, .flow-chain .fc-step.here.warn small { color: var(--text-on-accent); font-weight: 700; }
.flow-chain .fc-arrow { flex: 0 0 16px; align-self: center; height: 2px; margin: 0 3px 0 2px; background: var(--accent); position: relative; opacity: .55; }
.flow-chain .fc-arrow::after { content: ""; position: absolute; right: -2px; top: -4px; border: 5px solid transparent; border-left-color: var(--accent); }
.flow-chain .fc-more { flex: 0 0 auto; align-self: center; border: 1px dashed var(--accent-soft-border); border-radius: 8px; background: transparent; color: var(--accent-soft-fg);
  padding: 4px 8px; font: inherit; cursor: pointer; }
.flow-chain .fc-why { display: flex; flex-wrap: wrap; gap: 2px 18px; margin-top: 6px; padding-left: 2px; color: var(--text-secondary); font-size: 12px; }
.flow-chain .fc-why i { font-style: normal; color: var(--accent-soft-fg); font-weight: 600; margin-right: 6px; }

/* 10-18 侧栏改版第 2 步「今天要我做的」那条（app.js paintTodoStrip）：主页展开（.main）= 一排卡片；别的页（.line）= 一行 + 点开下拉 */
.todo-strip { margin: -8px 0 12px; font-size: 13px; }
.todo-strip .ts-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 6px; }
.todo-strip .ts-head b { font-size: 14px; color: var(--ink); white-space: nowrap; }
.todo-strip .ts-head small { color: var(--text-muted); white-space: nowrap; }
.todo-strip .ts-cards, .todo-strip .ts-drop { display: flex; flex-wrap: wrap; gap: 8px; }
.todo-strip .ts-drop { margin-top: 6px; padding: 8px; border: 1px solid var(--border); border-radius: 10px; background: var(--surface); }
.todo-strip.main .ts-cards { flex-wrap: nowrap; }
.todo-strip .ts-card { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: 8px; flex: 1 1 0; min-width: 0; max-width: 320px;
  padding: 5px 10px 5px 5px; border: 1px solid var(--border-subtle); border-radius: 10px; background: var(--surface); color: inherit; text-align: left; cursor: pointer; }
.todo-strip .ts-drop .ts-card { flex: 0 1 300px; }
.todo-strip .ts-card:hover { border-color: var(--accent); background: var(--surface-hover); }
.todo-strip .ts-card .n { display: grid; place-items: center; min-width: 30px; height: 30px; padding: 0 4px; border-radius: 8px; font-weight: 700;
  background: var(--info-bg); color: var(--info-fg); font-variant-numeric: tabular-nums; }
.todo-strip .ts-card.danger .n { background: var(--danger-solid); color: var(--text-on-accent); }
.todo-strip .ts-card.warn .n { background: var(--warning-bg); color: var(--warning-fg); }
.todo-strip .ts-card .t { display: flex; flex-direction: column; min-width: 0; }
.todo-strip .ts-card .t b { color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.todo-strip .ts-card .t small { color: var(--text-muted); font-size: 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.todo-strip .ts-card em { font-style: normal; font-size: 12px; color: var(--accent); white-space: nowrap; }
.todo-strip .ts-out { display: inline-flex; align-items: baseline; gap: 4px; padding: 2px 10px; border: 1px dashed var(--border); border-radius: 999px;
  color: var(--text-secondary); text-decoration: none; white-space: nowrap; font-size: 12px; }
.todo-strip .ts-out small { font-size: 11px; color: var(--text-muted); }
.todo-strip .ts-out:hover { border-color: var(--accent); color: var(--ink); }
.todo-strip .ts-none { color: var(--success-fg); padding: 6px 2px; }
.todo-strip .ts-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.todo-strip .ts-mine { border: 1px solid var(--border); border-radius: 999px; padding: 3px 10px; background: var(--surface); color: var(--text-secondary);
  cursor: pointer; white-space: nowrap; font-size: 12px; }
.todo-strip .ts-mine.has { border-color: var(--warning-border); background: var(--warning-bg); color: var(--warning-fg); font-weight: 600; }
.todo-strip .ts-mine b { font-variant-numeric: tabular-nums; }
.todo-strip .ts-rel { display: inline-flex; align-items: center; gap: 4px; flex-wrap: wrap; min-width: 0; }
.todo-strip .ts-rel i { font-style: normal; color: var(--text-muted); font-size: 12px; margin-right: 2px; }
.todo-strip .ts-rel button { border: 0; background: none; padding: 2px 6px; border-radius: 6px; color: var(--accent); cursor: pointer; font-size: 12px; white-space: nowrap; }
.todo-strip .ts-rel button:hover { background: var(--surface-hover); }
.todo-strip .ts-daily { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: 8px; }
.todo-strip .ts-daily > i { font-style: normal; font-size: 12px; color: var(--muted); margin-right: 2px; }
.todo-strip .ts-day { display: inline-flex; align-items: center; gap: 6px; border: 1px solid var(--line); border-radius: 999px; padding: 3px 10px;
  background: var(--surface); color: var(--ink); font-size: 13px; cursor: pointer; }
.todo-strip .ts-day:hover { border-color: var(--accent); }
.todo-strip .ts-day b { font-size: 12px; color: var(--muted); }
.todo-strip .ts-day.warn b { color: var(--warning-fg); }
.todo-strip .ts-day.danger { border-color: var(--danger-solid); }
.todo-strip .ts-day.danger b { color: var(--danger-solid); }
.todo-strip .ts-try { display: inline-flex; align-items: center; gap: 4px; border: 1px solid var(--success-border); border-radius: 999px; padding: 2px 10px 2px 4px;
  background: var(--success-bg); color: var(--success-fg); cursor: pointer; font-size: 12px; white-space: nowrap; }
.todo-strip .ts-try i { font-style: normal; font-size: 11px; padding: 0 5px; border-radius: 999px; background: var(--success-fg); color: var(--n-0); }
@media (max-width: 640px) { .todo-strip { display: none !important; } }

/* 10-18 侧栏改版第 3 步：我的工作下面的「新·试试」（最多 2 条）和最底下一条「全部功能 · N 个」（app.js setupAllFn）。侧栏是深色底 */
.primary-nav > .nav-try { display: flex; align-items: center; gap: 6px; width: 100%; border: 0; border-radius: 10px; padding: 4px 10px 4px 12px;
  background: transparent; color: var(--d-text-3); cursor: pointer; text-align: left; font-size: 13px; }
.primary-nav > .nav-try:hover { color: var(--n-0); background: rgba(255, 255, 255, .055); }
.primary-nav > .nav-try i { font-style: normal; font-size: 11px; padding: 0 6px; border-radius: 999px; background: var(--d-accent); color: var(--d-bg); white-space: nowrap; }
.primary-nav > .nav-try b { font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.primary-nav > .nav-allfn { position: relative; display: flex; align-items: center; justify-content: space-between; gap: 6px; width: 100%; margin-top: 8px;
  border: 1px dashed rgba(255, 255, 255, .18); border-radius: 10px; padding: 7px 12px; background: transparent; color: var(--d-text-2); cursor: pointer;
  font-size: 13px; text-align: left; }
.primary-nav > .nav-allfn:hover { color: var(--n-0); border-color: var(--d-accent); }
.primary-nav > .nav-allfn em { font-style: normal; transition: transform .18s; }
.primary-nav > .nav-allfn[aria-expanded="true"] em { transform: rotate(90deg); }
.primary-nav > .nav-allfn > .nav-dot { position: static; flex: 0 0 auto; width: 7px; height: 7px; box-shadow: none; }
@media (min-width: 901px) {
  .app-shell:not([data-rail]) .sidebar:not([data-nf]) .primary-nav[data-allfn-shut] > [data-allfn]:not([data-tour-on]) { display: none !important; }
}
@media (max-width: 900px) { .primary-nav > .nav-allfn, .primary-nav > .nav-try { display: none; } }
/* 第一次看到「全部功能」时旁边那句（app.js allfnHintOnce） */
.allfn-tip { position: fixed; z-index: 60; width: 260px; padding: 10px 12px; border-radius: 10px; background: var(--surface); color: var(--ink);
  border: 1px solid var(--border); box-shadow: 0 8px 24px rgba(0, 0, 0, .18); font-size: 13px; line-height: 1.55; display: flex; flex-direction: column; gap: 4px; }
.allfn-tip b { font-size: 14px; }
.allfn-tip span { color: var(--text-secondary); }
.allfn-tip button { align-self: flex-end; border: 0; border-radius: 8px; padding: 4px 12px; background: var(--accent); color: var(--text-on-accent); cursor: pointer; font-size: 12px; }
@media (max-width: 900px) { .allfn-tip { display: none; } }


/* ===== 第 13 版导航 v3（2026-10-26，imai；只在 ai.itopkitchen.com / squ.navV3=on 时 app.js applyNavV3 给 .app-shell 打 data-v3）：
   顶上一条 44px 深色模块栏（首页 · 智脑 · 业务 · 产品与工厂 · 跟单 · 财务 · 经营数据 · 沟通与工具 + 右上角系统管理齿轮），
   左侧只放当前模块的分组和入口。颜色全用侧栏那套深色 token（--d-*）和图表色，不写裸色（test_ui_standard）。老板 10-26：
   「菜单栏的交互、icon 太没有科技感」→ 底边一条青绿→紫的光线、选中的图标发光、换模块时光条滑过去；科技感只到顶栏为止，业务页面保持干净。 */
.app-shell[data-v3] { grid-template-rows: 44px minmax(0, 1fr); }
.app-shell[data-v3] > .v3-top { grid-column: 1 / -1; }
.app-shell[data-v3] .sidebar { top: 44px; height: calc(100vh - 44px); padding-top: 12px; }
.app-shell[data-v3] .sidebar .nav-finder { margin-top: 0; }
.app-shell[data-v3] .topbar { top: 44px; }
.v3-top { position: sticky; top: 0; z-index: 25; height: 44px; min-width: 0; display: flex; align-items: center; gap: 4px; padding: 0 10px 0 12px;
  color: var(--d-text); background: linear-gradient(90deg, var(--d-sunken), var(--d-bg) 55%, var(--d-sunken)); border-bottom: 1px solid var(--d-border); }
.v3-top::before { content: ""; position: absolute; inset: 0; pointer-events: none; opacity: .45;
  background-image: linear-gradient(rgba(255, 255, 255, .05) 1px, transparent 1px), linear-gradient(90deg, rgba(255, 255, 255, .05) 1px, transparent 1px);
  background-size: 22px 22px; mask-image: linear-gradient(180deg, rgba(0, 0, 0, 1), transparent); -webkit-mask-image: linear-gradient(180deg, rgba(0, 0, 0, 1), transparent); }
.v3-top::after { content: ""; position: absolute; left: 0; right: 0; bottom: -1px; height: 1px; pointer-events: none; opacity: .75;
  background: linear-gradient(90deg, transparent, var(--d-accent) 30%, var(--chart-4) 70%, transparent); }
.v3-top > * { position: relative; z-index: 1; }
.v3-ic { width: 18px; height: 18px; flex: 0 0 auto; display: block; }
/* 字标搬到顶栏左边（原来在侧栏顶上） */
.v3-top .brand { flex: 0 0 auto; height: 32px; gap: 8px; margin-right: 6px; padding: 0 12px 0 0; border-right: 1px solid var(--d-border); }
.v3-top .brand-logo { padding: 2px 5px; border-radius: 7px; box-shadow: none; }
.v3-top .brand-logo img { width: 34px; height: 23px; }
.v3-top .brand > div { display: flex; align-items: baseline; gap: 6px; }
.v3-top .brand .brand-word { font-size: 15px; letter-spacing: .04em; }
.v3-top .brand .brand-word + small { margin: 0; font-size: 11px; letter-spacing: .04em; }
/* 模块按钮 */
.v3-mods { position: relative; display: flex; gap: 2px; flex: 1 1 auto; min-width: 0; height: 44px; align-items: stretch; overflow-x: auto; scrollbar-width: none; }
.v3-mods::-webkit-scrollbar { display: none; }
.v3-mod { flex: 0 0 auto; position: relative; display: flex; align-items: center; gap: 7px; padding: 0 12px; border: 0; background: transparent;
  color: var(--d-text-2); font: inherit; font-size: 13.5px; font-weight: 500; letter-spacing: .01em; white-space: nowrap; cursor: pointer; transition: color .18s; }
.v3-mod[hidden] { display: none; }
.v3-mod::before { content: ""; position: absolute; inset: 8px 3px; border-radius: var(--radius-sm); background: rgba(255, 255, 255, .06); opacity: 0; transition: opacity .18s; }
.v3-mod:hover, .v3-mod.hov, .v3-mod:focus-visible { color: var(--d-text); outline: none; }
.v3-mod:hover::before, .v3-mod.hov::before, .v3-mod:focus-visible::before { opacity: 1; }
.v3-mod .v3-ic { transition: transform .25s, color .18s, filter .18s; }
.v3-mod:hover .v3-ic, .v3-mod.hov .v3-ic { transform: translateY(-1px); }
.v3-mod[aria-current="true"] { color: var(--d-text); }
.v3-mod[aria-current="true"] .v3-ic { color: var(--d-accent); filter: drop-shadow(0 0 6px color-mix(in srgb, var(--d-accent) 70%, transparent)); }
.v3-mod[data-hue="violet"][aria-current="true"] .v3-ic { color: color-mix(in srgb, var(--chart-4) 55%, var(--n-0)); filter: drop-shadow(0 0 6px color-mix(in srgb, var(--chart-4) 85%, transparent)); }
.v3-ink { position: absolute; left: 0; bottom: 0; height: 2px; width: 0; border-radius: 2px; opacity: 0; pointer-events: none;
  background: linear-gradient(90deg, var(--d-accent), var(--chart-4)); box-shadow: 0 0 10px color-mix(in srgb, var(--d-accent) 80%, transparent);
  transition: transform .32s cubic-bezier(.2, .7, .2, 1), width .32s cubic-bezier(.2, .7, .2, 1), opacity .2s; }
/* 右边：等我的 / 发送状态 / 数据服务 / 系统管理齿轮 / 头像（原来在页头右上角，节点原样搬过来、id 不变） */
.v3-right { display: flex; align-items: center; gap: 10px; flex: 0 0 auto; margin-left: 6px; }
.v3-right .api-state { color: var(--d-text-3); }
.v3-right .avatar { width: 30px; height: 30px; border-radius: var(--radius-full); box-shadow: 0 0 0 2px rgba(255, 255, 255, .12); }
.v3-icon-btn { width: 30px; height: 30px; border-radius: var(--radius-full); border: 1px solid var(--d-border); background: rgba(255, 255, 255, .06);
  color: var(--d-text-2); display: grid; place-items: center; cursor: pointer; padding: 0; transition: color .18s, border-color .18s, background .18s; }
.v3-icon-btn:hover, .v3-icon-btn:focus-visible { color: var(--d-text); border-color: var(--d-accent); background: rgba(255, 255, 255, .12); outline: none; }
.v3-icon-btn[aria-current="true"] { color: var(--d-accent); border-color: var(--d-accent); background: color-mix(in srgb, var(--d-accent) 14%, transparent); }
.v3-icon-btn[hidden] { display: none; }
.v3-icon-btn .v3-ic { width: 16px; height: 16px; }
/* 悬停展开（模块下面这一块的全部分组和入口；只在这一块里，不放指向别的模块的快捷引用） */
.v3-mega { position: absolute; top: 44px; left: 12px; z-index: 40; max-height: calc(100vh - 70px); overflow: auto; padding: 12px 14px 14px;
  color: var(--ink); background: var(--surface); border: 1px solid var(--border); border-top: 0; border-radius: 0 0 var(--radius-lg) var(--radius-lg);
  box-shadow: var(--shadow-3); opacity: 0; transform: translateY(-6px); transition: opacity .16s, transform .2s cubic-bezier(.2, .7, .2, 1); }
.v3-mega::before { content: ""; position: absolute; left: 0; right: 0; top: 0; height: 2px; background: linear-gradient(90deg, var(--d-accent), var(--chart-4)); }
.v3-mega.on { opacity: 1; transform: none; }
.v3-mega[hidden] { display: none; }
.v3-mega-h { display: flex; align-items: center; gap: 8px; padding: 2px 4px 10px; margin-bottom: 8px; border-bottom: 1px solid var(--border-subtle); }
.v3-mega-h .v3-ic { color: var(--accent); }
.v3-mega-h b { font-size: 14px; }
.v3-mega-h small { margin-left: auto; font-size: 11.5px; color: var(--text-muted); }
.v3-mega-cols { display: grid; grid-template-columns: repeat(auto-fill, minmax(170px, 1fr)); gap: 6px 10px; }
.v3-mega-col h6 { margin: 4px 6px 4px; font-size: 11.5px; color: var(--text-muted); font-weight: 600; letter-spacing: .04em; }
.v3-mega-col button { display: flex; align-items: center; gap: 6px; width: 100%; text-align: left; padding: 6px 8px; border: 0; border-radius: var(--radius-sm);
  background: transparent; color: var(--ink); font: inherit; cursor: pointer; transition: background .12s; }
.v3-mega-col button:hover, .v3-mega-col button:focus-visible { background: var(--surface-hover); outline: none; }
.v3-mega-col button[aria-current="true"] { background: var(--surface-selected); }
.v3-mega-col button span { font-size: 13.5px; font-weight: 600; }
.v3-mega-col button small { margin-left: auto; font-size: 11px; color: var(--text-muted); white-space: nowrap; }
/* 左侧：当前模块名 + 分组小标题（小标题不折叠，和二级菜单一样） */
.v3-mod-head { display: flex; align-items: center; gap: 8px; margin: 2px 10px 6px; color: var(--d-text); font-size: 13px; font-weight: 700; letter-spacing: .06em; }
.v3-mod-head .v3-ic { color: var(--d-accent); width: 17px; height: 17px; }
.app-shell[data-rail] .v3-mod-head b { display: none; }
.app-shell[data-v3] .primary-nav .nav-sub[data-v3sub] { margin-top: 8px; }
.app-shell[data-v3] .primary-nav .nav-sub[data-v3sub]:first-of-type { margin-top: 2px; }
/* 首页入口永远排第一（landingPage 认「第一条看得见的入口」=首页，权限不够落回首页时也靠它）；不在首页模块时只是不画 */
.app-shell[data-v3] .primary-nav .nav[data-v3-home]:not([data-v3-show]) { display: none; }
/* 合并页的入口：名字后面一个小数字 = 里面几个标签（鼠标停上去有全名） */
.app-shell[data-v3] .primary-nav .nav[data-v3-merged] > b::after { content: attr(data-v3-n); margin-left: 6px; padding: 0 5px; border-radius: var(--radius-full);
  font-size: 10px; font-weight: 600; line-height: 15px; color: var(--d-text-3); background: rgba(255, 255, 255, .08); vertical-align: 1px; }
.app-shell[data-v3] .primary-nav .nav.active[data-v3-merged] > b::after { color: var(--d-text); }
.app-shell[data-v3] .topbar-right[hidden] { display: none; }
/* 窄一点的屏（老板「我的屏幕很小」，大家多是 1080 宽）：先去掉右边的字、模块按钮收紧；再窄只留图标、当前模块才带字（鼠标停上去有名字） */
@media (max-width: 1240px) {
  .v3-top .brand .brand-word + small { display: none; }
  .v3-right { gap: 8px; }
  .v3-right .api-state:not(#send-mode-state) span { display: none; }
  .v3-mod { padding: 0 9px; font-size: 13px; }
}
@media (max-width: 1100px) {
  .v3-mod:not([aria-current="true"]) > span { display: none; }
  .v3-mod { padding: 0 10px; }
  .v3-right #send-mode-state span { display: none; }
}
@media (max-width: 900px) { .v3-top { display: none; } .app-shell[data-v3] { grid-template-rows: none; } }
