/* =========================================================================
   字体 —— 本地化
   -------------------------------------------------------------------------
   原来这里是 @import url("https://fonts.googleapis.com/...")
   → 国内网络基本加载失败，且 @import 会**阻塞渲染**；
     失败后静默回退到系统字体，等于这段配置白写。
   现改为把 Inter 的 4 个字重（latin 子集，共 ~90KB）放到 public/fonts/ 本地加载：
   离线可用、不阻塞、不依赖任何 CDN。中文走系统字体栈（见 body）。
   ========================================================================= */
@font-face{font-family:Inter;font-style:normal;font-weight:400;font-display:swap;
  src:url("fonts/inter-400.woff2") format("woff2")}
@font-face{font-family:Inter;font-style:normal;font-weight:500;font-display:swap;
  src:url("fonts/inter-500.woff2") format("woff2")}
@font-face{font-family:Inter;font-style:normal;font-weight:600;font-display:swap;
  src:url("fonts/inter-600.woff2") format("woff2")}
@font-face{font-family:Inter;font-style:normal;font-weight:700;font-display:swap;
  src:url("fonts/inter-700.woff2") format("woff2")}

/* =========================================================================
   设计令牌 —— 复刻 satnaing/shadcn-admin（oklch → hex）
   ========================================================================= */
:root{
  --radius: 0.625rem;
  --background:#ffffff;      --foreground:#020618;
  --card:#ffffff;            --card-foreground:#020618;
  --primary:#0f172b;         --primary-foreground:#f8fafc;
  --secondary:#f1f5f9;       --secondary-foreground:#0f172b;
  --muted:#f1f5f9;           --muted-foreground:#62748e;
  --accent:#f1f5f9;          --accent-foreground:#0f172b;
  --destructive:#e7000b;
  --border:#e2e8f0;          --input:#e2e8f0;      --ring:#90a1b9;
  --sidebar:#ffffff;         --sidebar-accent:#f1f5f9;  --sidebar-border:#e2e8f0;
  --r-sm: calc(var(--radius) - 4px);
  --r:    calc(var(--radius) - 2px);
  --r-lg: var(--radius);
  --r-xl: calc(var(--radius) + 4px);
  --sidebar-w: 264px;
  --header-h: 64px;
  --sh-xs: 0 1px 2px 0 rgb(0 0 0 / .05);
  --sh-sm: 0 1px 3px 0 rgb(0 0 0 / .1), 0 1px 2px -1px rgb(0 0 0 / .1);
  --sh-lg: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);
}
.dark{
  --background:#020618;      --foreground:#f8fafc;
  --card:#020919;            --card-foreground:#f8fafc;
  --primary:#e2e8f0;         --primary-foreground:#0f172b;
  --secondary:#1d293d;       --secondary-foreground:#f8fafc;
  --muted:#1d293d;           --muted-foreground:#90a1b9;
  --accent:#1d293d;          --accent-foreground:#f8fafc;
  --destructive:#ff6467;
  --border: rgba(255,255,255,.1);   --input: rgba(255,255,255,.15);   --ring:#6a7282;
  --sidebar:#020618;         --sidebar-accent:#1d293d;   --sidebar-border: rgba(255,255,255,.1);
  --sh-xs: 0 1px 2px 0 rgb(0 0 0 / .3);
  --sh-sm: 0 1px 3px 0 rgb(0 0 0 / .4);
  --sh-lg: 0 10px 15px -3px rgb(0 0 0 / .5);
}

/* =========================================================================
   基础
   ========================================================================= */
*{box-sizing:border-box}
html,body{height:100%}
body{
  margin:0; background:var(--background); color:var(--foreground);
  /* Latin 用本地 Inter；中文按平台优先级回退（Windows 上 YaHei UI 比旧 YaHei 渲染更细腻） */
  font-family:Inter,"Segoe UI Variable Text","Segoe UI",-apple-system,
    "Microsoft YaHei UI","Microsoft YaHei","PingFang SC","Hiragino Sans GB",
    "Source Han Sans SC","Noto Sans CJK SC",system-ui,sans-serif;
  font-size:14px; line-height:1.55; -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
  text-rendering:optimizeLegibility;
  transition:background .15s, color .15s;
}
/* 数字用等宽数字，表格/看板里对齐更整齐 */
table,.kpi b,.chart{font-variant-numeric:tabular-nums}
a{color:var(--foreground); text-decoration:none}
a:hover{text-decoration:underline}
code{background:var(--muted); padding:1px 6px; border-radius:var(--r-sm); font-size:12px}
::-webkit-scrollbar{width:9px;height:9px}
::-webkit-scrollbar-track{background:transparent}
::-webkit-scrollbar-thumb{background:var(--border); border-radius:5px}
::-webkit-scrollbar-thumb:hover{background:var(--muted-foreground)}
@keyframes fade{from{opacity:0}to{opacity:1}}
@keyframes slideIn{from{opacity:0;transform:translateY(16px)}to{opacity:1;transform:none}}

/* =========================================================================
   表单控件
   ========================================================================= */
input,select,textarea,button{font-family:inherit;outline:none}
input,select,textarea{
  padding:8px 12px; border:1px solid var(--input); border-radius:var(--r);
  background:transparent; color:var(--foreground); font-size:14px;
  max-width:100%; box-shadow:var(--sh-xs); transition:border-color .15s, box-shadow .15s;
}
input::placeholder,textarea::placeholder{color:var(--muted-foreground)}
input:focus,select:focus,textarea:focus{
  border-color:var(--ring);
  box-shadow:0 0 0 3px color-mix(in srgb, var(--ring) 40%, transparent);
}
input[type=checkbox]{width:auto; padding:0; box-shadow:none; accent-color:var(--primary)}
textarea{line-height:1.6; resize:vertical}

button{
  display:inline-flex; align-items:center; justify-content:center; gap:6px;
  padding:8px 16px; border:1px solid var(--primary); border-radius:var(--r);
  background:var(--primary); color:var(--primary-foreground);
  font-size:14px; font-weight:500; white-space:nowrap; cursor:pointer;
  box-shadow:var(--sh-xs); transition:opacity .15s, background .15s;
}
button:hover{opacity:.9}
button:active{transform:translateY(1px)}
button.sec{background:var(--background); color:var(--foreground); border-color:var(--border)}
button.sec:hover{background:var(--accent); opacity:1}
button.danger{background:var(--background); color:var(--destructive); border-color:var(--border)}
button.danger:hover{background:color-mix(in srgb, var(--destructive) 10%, transparent); opacity:1}
button.ghost{background:transparent; border-color:transparent; box-shadow:none; color:var(--muted-foreground)}
button.ghost:hover{background:var(--accent); color:var(--foreground); opacity:1}
button.mini{padding:3px 10px; font-size:12px; border-radius:var(--r-sm)}

/* =========================================================================
   登录 —— 左右分栏（左：品牌区 / 右：表单区）
   ========================================================================= */
#login{display:flex; min-height:100vh; background:var(--background)}

/* ---------- 左：品牌区 ---------- */
.lg-brand{
  position:relative; flex:0 0 46%; max-width:640px; overflow:hidden;
  display:flex; align-items:center; justify-content:center;
  background:linear-gradient(150deg,#0f172b 0%,#16233d 45%,#1e3a5f 100%);
  color:#e8eefc;
}
/* 柔光 */
.lg-glow{
  position:absolute; width:620px; height:620px; border-radius:50%; pointer-events:none;
  top:-180px; left:-140px; filter:blur(90px); opacity:.5;
  background:radial-gradient(circle,#3b82f6 0%,transparent 68%);
}
.lg-glow::after{
  content:""; position:absolute; inset:0;
}
/* 网格纹理 */
.lg-grid{
  position:absolute; inset:0; opacity:.16; pointer-events:none;
  background-image:linear-gradient(rgba(255,255,255,.5) 1px,transparent 1px),
                   linear-gradient(90deg,rgba(255,255,255,.5) 1px,transparent 1px);
  background-size:46px 46px;
  mask-image:radial-gradient(ellipse 78% 68% at 34% 42%,#000 30%,transparent 100%);
  -webkit-mask-image:radial-gradient(ellipse 78% 68% at 34% 42%,#000 30%,transparent 100%);
}
.lg-brand-in{position:relative; z-index:2; padding:56px 60px; max-width:520px; width:100%}
.lg-logo{
  width:54px; height:54px; border-radius:15px; display:grid; place-items:center;
  font-size:26px; font-weight:700; line-height:1; color:#0f172b;
  background:linear-gradient(150deg,#fff,#c7d7f5);
  box-shadow:0 10px 26px -8px rgba(0,0,0,.55), inset 0 1px 0 #fff;
  margin-bottom:22px;
}
.lg-brand-in h2{
  margin:0 0 10px; font-size:31px; font-weight:700; letter-spacing:-.7px; line-height:1.2; color:#fff;
}
.lg-brand-in h2 small{
  display:block; margin-top:6px; font-size:16px; font-weight:500; letter-spacing:.4px;
  color:#8fb2e8; opacity:.95;
}
.lg-tag{margin:0 0 34px; font-size:13.5px; line-height:1.75; color:#9db4d8}
.lg-feats{list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:20px}
.lg-feats li{display:flex; gap:14px; align-items:flex-start}
.lg-fi{
  flex:none; width:36px; height:36px; border-radius:10px; display:grid; place-items:center;
  background:rgba(255,255,255,.09); border:1px solid rgba(255,255,255,.14); color:#8fb2e8;
}
.lg-fi svg{width:19px; height:19px}
.lg-feats b{display:block; font-size:14px; font-weight:600; color:#fff; margin-bottom:3px}
.lg-feats span{display:block; font-size:12.5px; line-height:1.6; color:#8ea6c8}
.lg-foot{
  margin-top:46px; padding-top:22px; font-size:12px; letter-spacing:.3px; color:#6d86ab;
  border-top:1px solid rgba(255,255,255,.1);
}

/* ---------- 右：表单区 ---------- */
.lg-form{flex:1; display:flex; align-items:center; justify-content:center; padding:40px 32px}
.lg-form-in{width:100%; max-width:376px}
.lg-form-in header{margin-bottom:26px}
.lg-form-in h1{margin:0 0 7px; font-size:25px; font-weight:600; letter-spacing:-.5px}
.lg-form-in header p{margin:0; font-size:13.5px; color:var(--muted-foreground)}

.lg-field{display:block; margin-bottom:16px}
.lg-field>span{display:block; margin-bottom:7px; font-size:13px; font-weight:500}
.lg-iw{position:relative; display:flex; align-items:center}
.lg-ic{
  position:absolute; left:13px; width:17px; height:17px; color:var(--muted-foreground);
  pointer-events:none; transition:color .15s;
}
.lg-iw input{
  width:100%; height:44px; padding:0 42px 0 40px; font-size:14px;
  background:var(--card); box-shadow:none;
}
.lg-iw input:focus ~ .lg-ic, .lg-iw:focus-within .lg-ic{color:var(--foreground)}
.lg-eye{
  position:absolute; right:5px; width:32px; height:32px; padding:0;
  background:transparent; border-color:transparent; box-shadow:none; color:var(--muted-foreground);
  border-radius:var(--r-sm);
}
.lg-eye:hover{background:var(--muted); color:var(--foreground); opacity:1}
.lg-eye svg{width:17px; height:17px}

.lg-btn{
  width:100%; height:44px; margin-top:8px; font-size:15px; font-weight:600; letter-spacing:.5px;
  box-shadow:0 6px 16px -6px color-mix(in srgb, var(--primary) 65%, transparent);
}
.lg-btn:hover{opacity:.92; box-shadow:0 8px 20px -6px color-mix(in srgb, var(--primary) 70%, transparent)}
.lg-hint{margin:18px 0 0; font-size:11.5px; line-height:1.6; color:var(--muted-foreground); text-align:center}

/* 窄屏：收起品牌区，表单占满 */
@media (max-width:900px){
  .lg-brand{display:none}
  .lg-form{padding:36px 22px}
}
/* 中等屏：品牌区收窄、隐藏特性列表 */
@media (min-width:901px) and (max-width:1180px){
  .lg-brand{flex:0 0 42%}
  .lg-brand-in{padding:44px 40px}
  .lg-brand-in h2{font-size:26px}
  .lg-feats{display:none}
}

/* =========================================================================
   布局
   ========================================================================= */
#app{display:none; height:100vh; overflow:hidden}
#app.on{display:flex}

aside.side{
  width:var(--sidebar-w); flex:none; display:flex; flex-direction:column;
  background:var(--sidebar); border-right:1px solid var(--sidebar-border); transition:width .2s;
}
aside.side .brand{display:flex; align-items:center; gap:10px; padding:14px 16px; height:var(--header-h); flex:none}
aside.side .brand .logo{
  width:32px; height:32px; flex:none; border-radius:var(--r); display:grid; place-items:center;
  background:var(--primary); color:var(--primary-foreground); font-weight:700; font-size:15px;
}
aside.side .brand b{display:block; font-size:14px; font-weight:600; line-height:18px}
aside.side .brand small{display:block; font-size:11.5px; color:var(--muted-foreground); line-height:15px}
aside.side nav{padding:8px; display:flex; flex-direction:column; gap:2px; overflow-y:auto; flex:1}
aside.side .nav-label{padding:14px 16px 5px; font-size:11px; font-weight:600; letter-spacing:.4px; color:var(--muted-foreground)}
aside.side nav a{
  display:flex; align-items:center; gap:10px; padding:8px 12px; border-radius:var(--r);
  font-size:14px; font-weight:400; color:var(--foreground); cursor:pointer; transition:background .12s;
}
aside.side nav a:hover{background:var(--sidebar-accent); text-decoration:none}
aside.side nav a.on{background:var(--sidebar-accent); font-weight:500}
aside.side nav a .ni{display:inline-flex; align-items:center; justify-content:center; width:16px; flex:none; opacity:.7}
aside.side nav a:hover .ni, aside.side nav a.on .ni{opacity:1}
aside.side nav a .nav-badge{
  margin-left:auto; font-style:normal; font-size:11px; font-weight:600; line-height:17px;
  padding:1px 7px; border-radius:99px; background:var(--primary); color:var(--primary-foreground);
}
aside.side .side-foot{padding:12px 16px; border-top:1px solid var(--sidebar-border); font-size:11.5px; color:var(--muted-foreground); display:flex; align-items:center; gap:6px; letter-spacing:.2px}
aside.side .side-foot .sf-dot{width:6px; height:6px; border-radius:50%; background:#22c55e; flex:none; box-shadow:0 0 0 3px rgba(34,197,94,.16)}
aside.side .side-foot .sf-n{margin-left:auto; padding:1px 7px; border-radius:99px; background:rgba(255,255,255,.09); font-variant-numeric:tabular-nums}

.wrap{display:flex; flex-direction:column; flex:1; min-width:0; overflow-y:auto; overflow-x:hidden; background:var(--background)}
.wrap>header{
  position:sticky; top:0; z-index:15; flex:none; height:var(--header-h);
  display:flex; align-items:center; gap:12px; padding:0 24px;
  background:var(--background); border-bottom:1px solid var(--border);
}
.wrap>header h1{font-size:18px; font-weight:600; letter-spacing:-.3px; margin:0; white-space:nowrap; overflow:hidden; text-overflow:ellipsis}
.wrap>header .sp{flex:1}
main{flex:1; min-width:0; padding:24px}
main>section{animation:fade .15s ease}
main>section:not(:first-child){margin-top:0}

.who{
  display:flex; align-items:center; gap:8px; padding:5px 12px 5px 5px;
  font-size:13.5px; border:1px solid var(--border); border-radius:99px; background:var(--card); white-space:nowrap;
}
.who .av{
  width:26px; height:26px; flex:none; border-radius:50%; display:grid; place-items:center;
  font-size:11.5px; font-weight:600; background:var(--primary); color:var(--primary-foreground);
}
.hsearch{position:relative; display:flex; align-items:center}
.hsearch .hs-ico{position:absolute; left:10px; display:inline-flex; color:var(--muted-foreground); pointer-events:none}
.hsearch input{padding-left:33px; width:230px; height:37px; background:var(--muted); border-color:transparent; box-shadow:none}
.hsearch input:focus{background:var(--background); border-color:var(--border)}
.icon-btn{
  display:inline-flex; align-items:center; justify-content:center; padding:8px;
  background:transparent; border-color:transparent; box-shadow:none; color:var(--muted-foreground); border-radius:var(--r);
}
.icon-btn:hover{background:var(--muted); color:var(--foreground); opacity:1}

/* =========================================================================
   卡片 / 栅格
   ========================================================================= */
.card{
  background:var(--card); color:var(--card-foreground);
  border:1px solid var(--border); border-radius:var(--r-xl);
  padding:22px 24px; margin-bottom:20px; box-shadow:var(--sh-xs);
  min-width:0; overflow:hidden;
}
.card h3{margin:0 0 16px; font-size:16px; font-weight:600; letter-spacing:-.2px; display:flex; align-items:center; flex-wrap:wrap; gap:4px}
.card h3 .ci{display:inline-flex; align-items:center; color:var(--muted-foreground); margin-right:2px; flex:none}
.scroll table{min-width:1000px}          /* 列多时不挤压，改为横向滚动 */
/* 商机池表格：列从 11 砍到 6 之后，不再需要 1000px 的最小宽度 ——
   实测过：留着它表格仍是 1484px，而区块只有 902px，右边几列要横向滚动才看得见。
   改成 fixed 布局，列宽按表头的百分比分配，长内容不再把列撑开。 */
.scroll table.opp-table{min-width:0; width:100%; table-layout:fixed}
/* ★ 2026-10-14 用户要求：商机池列表**不要外框**。
   原来 .scroll{max-height:62vh; overflow:auto; border; background} 把列表关进一个
   小框里，而行高本来就大（标题+meta+能力标签），62vh 只放得下 4 条左右。
   这一块改成跟页面一起滚（列表长就往下滚，不再有内滚动条和外边框）。 */
.scroll.no-box{
  max-height:none; overflow:visible; border:none; background:transparent; border-radius:0;
}
.scroll table.opp-table th{padding:8px 10px}
.scroll table.opp-table td{vertical-align:top; padding:5px 10px}
.scroll table.opp-table td b{font-size:13px; line-height:1.35}
/* 操作列要塞 4 个按钮（跟进/指派/忽略/删），原来的内边距放不下 ——
   实测 110px 里只显示得出前两个，后两个被挤出格。收紧内边距和字号。 */
.scroll table.opp-table td:last-child button{padding:3px 7px; font-size:11.5px; margin:0 2px 2px 0}
@media (max-width:820px){.scroll table{min-width:0}}
.row{display:flex; gap:10px; flex-wrap:wrap; align-items:center; margin-bottom:12px}
.row:last-child{margin-bottom:0}
.grid{display:grid; grid-template-columns:repeat(auto-fill, minmax(180px,1fr)); gap:8px}

/* =========================================================================
   表格
   ========================================================================= */
.scroll{
  max-height:62vh; overflow:auto; min-width:0; -webkit-overflow-scrolling:touch;
  border:1px solid var(--border); border-radius:var(--r-lg); background:var(--card);
}
table{width:100%; border-collapse:separate; border-spacing:0; font-size:13.5px; table-layout:auto}
th{
  position:sticky; top:0; z-index:2; padding:12px 14px; text-align:left; white-space:nowrap;
  font-size:13px; font-weight:500; color:var(--muted-foreground);
  background:var(--card); border-bottom:1px solid var(--border);
}
td{
  padding:12px 14px; vertical-align:top; color:var(--foreground);
  border-bottom:1px solid var(--border);
  overflow-wrap:anywhere; word-break:break-word;   /* 防止长 URL 撑破 */
  max-width:340px;
}
tbody tr{transition:background .1s}
tbody tr:hover{background:var(--muted)}
tbody tr:last-child td{border-bottom:none}
td b{font-weight:500}
/* 表格里的链接不换行、超长省略 */
td a{overflow-wrap:anywhere; word-break:break-word}
#modal .box a, .banner a{overflow-wrap:anywhere; word-break:break-word}
td .muted{font-size:12.5px; line-height:1.55}

/* =========================================================================
   标签
   ========================================================================= */
.tag{
  display:inline-flex; align-items:center; padding:2px 10px; margin:0 4px 3px 0;
  border-radius:99px; font-size:12px; line-height:18px; font-weight:500; white-space:nowrap;
  background:var(--secondary); color:var(--secondary-foreground); border:1px solid transparent;
}
.tag.g{background:#f0fdf4; color:#15803d; border-color:#bbf7d0}
.tag.o{background:#fffbeb; color:#a16207; border-color:#fde68a}
.tag.r{background:#fef2f2; color:#b91c1c; border-color:#fecaca}
.tag.gray{background:var(--secondary); color:var(--muted-foreground); border-color:var(--border)}
.dark .tag.g{background:rgba(34,197,94,.12); color:#4ade80; border-color:rgba(34,197,94,.25)}
.dark .tag.o{background:rgba(234,179,8,.12); color:#facc15; border-color:rgba(234,179,8,.25)}
.dark .tag.r{background:rgba(239,68,68,.12); color:#f87171; border-color:rgba(239,68,68,.25)}

/* =========================================================================
   KPI
   ========================================================================= */
.kpi{display:grid; grid-template-columns:repeat(auto-fit, minmax(148px,1fr)); gap:14px; margin-bottom:20px}
.kpi>div{
  background:var(--card); border:1px solid var(--border); border-radius:var(--r-xl);
  padding:18px; box-shadow:var(--sh-xs); transition:box-shadow .15s; min-width:0;
}
.kpi>div:hover{box-shadow:var(--sh-sm)}
.kpi b{display:block; font-size:27px; font-weight:600; letter-spacing:-.8px; line-height:1.15}
.kpi span{font-size:13px; color:var(--muted-foreground); display:block; overflow-wrap:anywhere}
.kpi .ico{
  display:inline-flex; align-items:center; justify-content:center;
  width:34px; height:34px; margin-bottom:9px; border-radius:var(--r);
  background:var(--muted); color:var(--muted-foreground);
}
.kpi .hint{font-size:11.5px; color:var(--muted-foreground); margin-top:3px}

/* =========================================================================
   提示条 / Toast / 弹窗
   ========================================================================= */
.banner{
  padding:12px 16px; margin-bottom:20px; font-size:13px; line-height:19px;
  background:var(--muted); border:1px solid var(--border); border-radius:var(--r-lg);
}
.banner b{font-weight:600}
.itabs{display:flex; gap:6px; flex-wrap:wrap; margin-bottom:14px}
.itabs button{background:var(--background); color:var(--muted-foreground); border:1px solid var(--border);
  border-radius:99px; padding:7px 16px; font-size:13.5px; font-weight:500; box-shadow:none}
.itabs button:hover{background:var(--muted); opacity:1}
.itabs button.on{background:var(--primary); color:var(--primary-foreground); border-color:var(--primary)}
.itabs button em{font-style:normal; font-size:11.5px; margin-left:6px; opacity:.75}
.localbadge{display:inline-flex; align-items:center; gap:4px; font-size:11.5px; color:var(--muted-foreground)}
.banner a{text-decoration:underline}
.msg{
  position:fixed; right:24px; bottom:24px; z-index:80; display:none; max-width:420px;
  padding:12px 16px; font-size:13.5px; font-weight:500;
  background:var(--card); color:var(--card-foreground);
  border:1px solid var(--border); border-radius:var(--r-lg); box-shadow:var(--sh-lg);
}
.msg.on{display:flex; align-items:center; gap:8px; animation:slideIn .25s cubic-bezier(.16,1,.3,1)}
.msg.err{color:var(--destructive); border-color:color-mix(in srgb, var(--destructive) 35%, transparent)}
.msg.ok{border-color:var(--border)}

#modal{position:fixed; inset:0; z-index:90; display:none; align-items:center; justify-content:center; padding:20px; background:rgba(2,6,24,.5)}
#modal.on{display:flex}
#modal .box{
  width:100%; max-width:880px; max-height:88vh; overflow:auto;
  padding:24px; background:var(--card); color:var(--card-foreground);
  border:1px solid var(--border); border-radius:var(--r-xl); box-shadow:var(--sh-lg);
  animation:slideIn .2s cubic-bezier(.16,1,.3,1);
}
#modal .box h3{margin:0 0 16px; font-size:18px; font-weight:600; letter-spacing:-.2px}
#modal .box pre{white-space:pre-wrap; overflow-wrap:anywhere}

/* ---- 商机详情：左右结构（左=信息与操作，右=原文）---- */
#modal .box.wide{max-width:1320px; width:96vw}
.dt-grid{display:grid; grid-template-columns:minmax(0,46%) minmax(0,54%); gap:24px; align-items:start}
.dt-right{position:sticky; top:0; display:flex; flex-direction:column; gap:8px;
  border-left:1px solid var(--border); padding-left:20px; max-height:78vh}
.dt-right .dt-scroll{overflow:auto; flex:1; min-height:120px;
  padding:14px 16px; background:var(--muted); border-radius:var(--r-lg);
  font-size:13px; line-height:1.95; white-space:pre-wrap; overflow-wrap:anywhere}
/* 公告正文：段落是前端 prettyText() 补出来的，必须 pre-wrap 才看得见换行。
   这条单独写出来，是防止 dtBody 将来被用到 .dt-right 之外时丢掉这个属性。 */
.dt-text{white-space:pre-wrap; overflow-wrap:anywhere; line-height:1.95}
.dt-right .dt-head{display:flex; align-items:center; gap:8px; flex-wrap:wrap}
.dt-right .dt-head h3{margin:0; font-size:14.5px}
.dt-idx{display:inline-flex; gap:4px; margin-left:auto}
/* 详情弹框头部第二行：区域 / 发布 / 截止 / 能力 —— 一眼看清，不跟状态标签混在一起 */
.dt-facts{display:flex; flex-wrap:wrap; gap:7px 20px; margin-bottom:14px;
  padding:9px 13px; background:var(--muted); border-radius:var(--r-lg); font-size:12.5px;
  align-items:baseline}
.dt-fact{display:inline-flex; align-items:baseline; gap:6px}
.dt-fact i{font-style:normal; color:var(--muted-foreground); font-size:11.5px; flex:none}
.kwtag{display:inline-flex; align-items:center; padding:1px 8px; margin:0 4px 3px 0;
  border-radius:99px; font-size:11.5px; line-height:17px; background:var(--accent); color:var(--accent-foreground)}
@media (max-width:1000px){
  .dt-grid{grid-template-columns:1fr}
  .dt-right{position:static; border-left:0; padding-left:0; border-top:1px solid var(--border);
    padding-top:14px; max-height:none}
}

/* =========================================================================
   其它
   ========================================================================= */
.muted{color:var(--muted-foreground); font-size:12.5px}
.opp-title{display:block; cursor:pointer; border-radius:var(--r-sm); transition:color .12s}
.opp-title b{font-weight:500; text-decoration:underline; text-decoration-color:transparent; text-underline-offset:3px; transition:text-decoration-color .12s}
.opp-title:hover b{text-decoration-color:currentColor}
.opp-title:active{opacity:.7}
.follow{border-left:2px solid var(--border); padding:6px 0 6px 12px; margin:9px 0; font-size:13px}
.follow b{font-weight:600}

/* =========================================================================
   看板
   ========================================================================= */
.dash-2{display:grid; grid-template-columns:1fr 1fr; gap:20px; margin-bottom:20px}
.dash-2>.card{margin-bottom:0}
.donut-wrap{display:flex; align-items:center; gap:22px; flex-wrap:wrap}
.legend{flex:1; min-width:170px}
.legend div{display:flex; align-items:center; gap:8px; padding:4px 0; font-size:13px}
.legend .dot{width:9px; height:9px; border-radius:3px; flex:none}
.legend .val{margin-left:auto; font-weight:600; font-variant-numeric:tabular-nums}
.hbar{margin:9px 0}
.hbar .top{display:flex; justify-content:space-between; gap:10px; font-size:12.5px; margin-bottom:4px}
.hbar .top span:first-child{color:var(--muted-foreground); overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.hbar .top b{font-variant-numeric:tabular-nums; flex:none}
.hbar .track{height:7px; background:var(--muted); border-radius:4px; overflow:hidden}
.hbar .fill{height:100%; border-radius:4px; transition:width .4s ease}
.focus-list div.item{display:flex; gap:10px; padding:9px 0; border-bottom:1px solid var(--border); font-size:13px}
.focus-list div.item:last-child{border-bottom:none}
.focus-list .rank{
  width:20px; height:20px; flex:none; border-radius:5px; display:grid; place-items:center;
  font-size:11px; font-weight:600; background:var(--muted); color:var(--muted-foreground);
}
.focus-list .rank.top{background:var(--primary); color:var(--primary-foreground)}
.focus-list .bd{flex:1; min-width:0}
.focus-list .bd .t{font-weight:500; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.focus-list .bd .m{color:var(--muted-foreground); font-size:11.5px; margin-top:1px}
.tl div.it{position:relative; padding:9px 0 9px 14px; border-left:2px solid var(--border); font-size:13px}
.tl div.it:before{
  content:""; position:absolute; left:-5px; top:14px; width:8px; height:8px;
  border-radius:50%; background:var(--background); border:2px solid var(--border);
}
.tl div.it:first-child:before{border-color:var(--primary)}
.tl .when{color:var(--muted-foreground); font-size:11.5px}

/* =========================================================================
   设置页
   ========================================================================= */
.set-card .desc{color:var(--muted-foreground); font-size:13px; margin:-10px 0 16px}
.set-sep{height:1px; background:var(--border); margin:16px 0}
.set-row{display:flex; gap:20px; align-items:flex-start; padding:12px 0}
.set-row .lab{width:190px; flex:none}
.set-row .lab b{display:block; font-size:13.5px; font-weight:500}
.set-row .lab span{display:block; font-size:12px; color:var(--muted-foreground); margin-top:2px; line-height:17px}
.set-row .ctl{flex:1; min-width:0; display:flex; gap:8px; align-items:center; flex-wrap:wrap}
.set-row .ctl input, .set-row .ctl select{flex:1; min-width:180px}
.theme-opts{display:flex; gap:12px; flex-wrap:wrap}
.theme-opt{
  display:flex; align-items:center; gap:9px; min-width:150px; padding:10px 14px; cursor:pointer;
  font-size:13.5px; background:var(--card); border:2px solid var(--border); border-radius:var(--r-lg); transition:.15s;
}
.theme-opt:hover{border-color:var(--ring)}
.theme-opt.on{border-color:var(--primary); background:var(--muted)}
.theme-opt .sw{width:22px; height:22px; flex:none; border-radius:6px; border:1px solid var(--border)}
.theme-opt .sw.l{background:#fff}
.theme-opt .sw.d{background:#020618}

/* =========================================================================
   移动端（≤820px 显示底部标签栏）
   ========================================================================= */
.mnav, .msheet{display:none}
.mnav button{
  flex:1; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:3px;
  min-height:50px; padding:6px 2px; border:none; border-radius:0; box-shadow:none;
  background:transparent; color:var(--muted-foreground); font-size:10.5px; font-weight:500;
}
.mnav button:hover{background:transparent; opacity:1}
.mnav button.on{color:var(--primary)}
.msheet{position:fixed; inset:0; z-index:96; align-items:flex-end; background:rgba(2,6,24,.5)}
.msheet.on{display:flex}
.msheet .inner{width:100%; padding:16px 16px calc(24px + env(safe-area-inset-bottom)); background:var(--card); border-radius:18px 18px 0 0}
.msheet .inner h4{margin:0 0 14px; font-size:15px; font-weight:600; text-align:center}
.msheet .g2{display:grid; grid-template-columns:repeat(3,1fr); gap:10px}
.msheet .g2 a{
  display:flex; flex-direction:column; align-items:center; gap:7px; padding:15px 6px;
  font-size:12px; color:var(--foreground); text-decoration:none;
  border:1px solid var(--border); border-radius:var(--r-lg);
}

/* =========================================================================
   响应式 —— 三个断点：1180 / 900 / 820
   ========================================================================= */

/* ---------- ≤1180：侧栏默认收成图标条 ----------
   ⚠ 这里全是「默认值」，不是「强制值」：一旦用户手动点过左上角「荆」，
   html 上会挂 .side-manual，下面所有规则就都不再生效，改由用户的
   展开/收起决定。否则用户点了展开也没用 —— 1024×768 的屏幕正落在
   这条规则里，会被永久压成图标条，文字再也出不来（实际发生过）。
   另外原来写的是 `nav a span{display:none}`：图标本身就是 span.ni，
   会被一起隐藏，只是靠 .ni 的优先级(0,3,2 > 0,2,2)侥幸躲过 —— 改成
   显式排除，别依赖运气。 */
@media (max-width:1180px){
  :root:not(.side-manual){--sidebar-w:64px}
  :root:not(.side-manual) aside.side .brand b,
  :root:not(.side-manual) aside.side .brand small,
  :root:not(.side-manual) aside.side .side-foot,
  :root:not(.side-manual) aside.side nav a span:not(.ni),
  :root:not(.side-manual) aside.side .nav-label{display:none}
  :root:not(.side-manual) aside.side nav a{justify-content:center; padding:10px 0}
  /* ⚠ 角标这里**不能 display:none**。原规则把它一起藏了，导致 1024 这类
     窄屏在默认图标条模式下，商机池/消息中心/单位动态的角标全部看不见 ——
     用户会觉得「有新消息却不提示」。改成和收起态一致：只留一个小红点。
     数字在悬停 title 和展开态里看。 */
  :root:not(.side-manual) aside.side nav a{position:relative}
  :root:not(.side-manual) aside.side nav a .nav-badge{
    position:absolute; top:4px; right:8px; margin:0;
    min-width:8px; width:8px; height:8px; line-height:0;
    padding:0; font-size:0; border-radius:50%;
    overflow:hidden; box-shadow:0 0 0 2px var(--sidebar);
  }
  .hsearch input{width:150px}
}

/* ---------- ≤900：隐藏侧栏，启用底部标签栏 ---------- */
@media (max-width:900px){
  aside.side{display:none}
  .hsearch{display:none}
  .who .nm{display:none}
  .wrap>header{padding:0 14px; height:56px; --header-h:56px}
  .wrap>header h1{font-size:16px}
  main{padding:12px 12px calc(88px + env(safe-area-inset-bottom)) 12px}

  .mnav{
    display:flex; position:fixed; left:0; right:0; bottom:0; z-index:40;
    justify-content:space-around; padding:4px 2px calc(4px + env(safe-area-inset-bottom));
    background:var(--card); border-top:1px solid var(--border); box-shadow:0 -2px 12px rgba(16,24,40,.06);
  }

  /* KPI 两列 */
  .kpi{grid-template-columns:repeat(2,1fr); gap:10px}
  .kpi>div{padding:14px}
  .kpi b{font-size:22px}
  .kpi .ico{width:28px; height:28px; margin-bottom:7px}

  /* 图表单列 */
  .dash-2{grid-template-columns:1fr; gap:14px}

  .card{padding:15px 16px; border-radius:var(--r-lg); margin-bottom:14px}
  .card h3{font-size:14.5px; margin-bottom:12px}

  /* 触控尺寸 */
  button{min-height:42px; padding:10px 14px}
  button.mini{min-height:34px; padding:6px 11px}
  input,select,textarea{min-height:44px; font-size:16px}   /* 16px 防 iOS 聚焦缩放 */
  input[type=checkbox]{min-height:auto}

  .set-row{flex-direction:column; gap:8px}
  .set-row .lab{width:auto}
  .set-row .ctl{width:100%}
  .set-row .ctl input, .set-row .ctl select{width:100%; min-width:0}
  .grid{grid-template-columns:repeat(auto-fill, minmax(140px,1fr))}
  .msg{left:12px; right:12px; bottom:calc(80px + env(safe-area-inset-bottom)); max-width:none}
  #modal .box{padding:18px; border-radius:14px; max-height:92vh}
  .donut-wrap{gap:14px}
  .focus-list .bd .t{white-space:normal}
}

/* ---------- ≤820：表格转卡片 ---------- */
@media (max-width:820px){
  .scroll{border:none; max-height:none; overflow:visible; background:transparent; border-radius:0}
  .scroll table, .scroll thead, .scroll tbody, .scroll tr, .scroll td{display:block; width:100%}
  .scroll thead{display:none}
  .scroll tbody tr{
    margin-bottom:10px; padding:12px 13px; background:var(--card);
    border:1px solid var(--border); border-radius:var(--r-lg); box-shadow:var(--sh-xs);
  }
  .scroll tbody tr:hover{background:var(--card)}
  .scroll td{border:none; padding:2px 0; max-width:none}
  .scroll td:empty{display:none}
  .scroll td b{display:block; margin-bottom:2px; font-size:14px; line-height:1.45}
  .scroll td:last-child{
    margin-top:9px; padding-top:9px;
    border-top:1px solid var(--border) !important;
  }
  .scroll td:last-child button{flex:1}
  .msheet .g2{grid-template-columns:repeat(3,1fr)}
}
@media (max-width:400px){
  .kpi b{font-size:20px}
  .msheet .g2{grid-template-columns:repeat(2,1fr)}
}
.scroll th[onclick]{transition:background .12s}
.scroll th[onclick]:hover{background:var(--muted); color:var(--foreground)}
/* ---------- 看板 v2 · ECharts ---------- */
.chart{width:100%; min-height:120px}
.chart canvas{border-radius:6px}
#v-dash .card h3+.muted{margin-top:-4px}
@media (max-width:900px){
  .chart{height:auto !important; min-height:200px}
}

/* =========================================================================
   视觉精修 v3
   -------------------------------------------------------------------------
   独立区块，不修改上面的原规则；全部走设计令牌，明暗主题自动适配。
   ========================================================================= */

/* ① 表头：sticky 滚动时不再"透底"（原来背景是 --card，行内容会透出来） */
h1,h2,h3,h4{text-wrap:balance}
th{
  background:color-mix(in srgb, var(--muted) 60%, var(--card));
  backdrop-filter:saturate(1.5) blur(6px);
  font-weight:600; font-size:12.5px; letter-spacing:.2px;
  padding:11px 14px;
}
/* 表头底部用双层线，层次更清楚 */
th{border-bottom:1px solid color-mix(in srgb, var(--border) 70%, var(--muted-foreground) 12%)}

/* ② 行：极淡斑马纹，宽表横向看不容易串行 */
tbody tr:nth-child(even){background:color-mix(in srgb, var(--muted) 38%, transparent)}
tbody tr:hover{background:color-mix(in srgb, var(--muted) 100%, transparent)}
td{padding:11px 14px; line-height:1.6}

/* ③ 卡片：极细内高光，脱离"纯白平板"的观感 */
.card{box-shadow:var(--sh-xs), inset 0 1px 0 0 rgb(255 255 255 / .6)}
.dark .card{box-shadow:var(--sh-xs), inset 0 1px 0 0 rgb(255 255 255 / .04)}
.card h3{font-size:15.5px; letter-spacing:-.15px}
.kpi>div{box-shadow:var(--sh-xs), inset 0 1px 0 0 rgb(255 255 255 / .6)}
.dark .kpi>div{box-shadow:var(--sh-xs), inset 0 1px 0 0 rgb(255 255 255 / .04)}

/* ④ 键盘可访问性：焦点环（鼠标点击不显示，Tab 才显示） */
:focus-visible{outline:2px solid var(--ring); outline-offset:2px; border-radius:var(--r-sm)}

/* ⑤ 文本选区用主题色 */
::selection{background:color-mix(in srgb, var(--ring) 32%, transparent)}

/* ⑥ 滚动区域：右侧渐隐，提示"还有更多列" */
.scroll{
  background-image:linear-gradient(to left, color-mix(in srgb, var(--muted-foreground) 9%, transparent), transparent 22px);
  background-repeat:no-repeat; background-position:right; background-size:22px 100%;
  background-attachment:local;
}

/* ⑦ 侧栏激活项：左侧主题色竖条，比单纯换底色更明确 */
aside.side nav a{position:relative}
aside.side nav a.on::before{
  content:""; position:absolute; left:0; top:50%; transform:translateY(-50%);
  width:3px; height:18px; border-radius:0 3px 3px 0; background:var(--foreground);
}

/* ⑧ 数字/金额：等宽数字，纵向对齐 */
.kpi b,td,.tag{font-variant-numeric:tabular-nums}

/* ⑨ 减少动效偏好（无障碍） */
@media (prefers-reduced-motion: reduce){
  *{animation-duration:.01ms !important; transition-duration:.01ms !important}
}

/* ⑩ 商机池表格的列行为 —— ★ 必须挂在 .opp-table 上，**不能再用 :nth-child**
   这批规则原来写的是 td:nth-child(6)/(7)/(8..11)、td:nth-child(5)，
   都是按「11 列表格」的列位置写的（注释里写着"日期列""业务线"
   "状态/优先/负责人/操作"）。
   后来列从 11 砍到 6：nth-child(6) 变成了「操作」列 → 被强制 nowrap，
   4 个按钮挤在一行溢出容器（实测 right 992/1025 > 容器 965）；
   而 nth-child(8..11) 压根不存在了。**位置型规则在列数变化时会静默
   作用到错误的列**，而且它们当时还同时命中了意向/单位/来源等其他表。
   一律改成类名作用域。 */
.opp-table td{white-space:nowrap}
/* 商机列：标题和 meta 都要能换行/省略 */
.opp-table td:first-child{white-space:normal; min-width:0}
/* 操作列：必须允许换行，否则 4 个按钮（要 161px）在 111px 格子里溢出 */
.opp-table td:last-child{white-space:normal}
.opp-table td:first-child{min-width:0}   /* 列宽由表头百分比分配，不再靠 min-width 撑 */
/* 中文断行更优雅：不再按单字硬断，仅在必要时断（全局，其他表也受益） */
td{word-break:normal; overflow-wrap:anywhere; line-break:strict}

/* =========================================================================
   视觉打磨层（2026-10 追加）
   目标：更克制的层次、更顺的过渡、更清晰的数据可读性。
   只做叠加，不改原有选择器语义。
   ========================================================================= */

/* ---- 全局过渡与滚动手感 ---- */
*{scroll-behavior:smooth}
html{-webkit-font-smoothing:antialiased; text-rendering:optimizeLegibility}
.wrap{scrollbar-gutter:stable}
::-webkit-scrollbar{width:10px; height:10px}
::-webkit-scrollbar-track{background:transparent}
::-webkit-scrollbar-thumb{background:var(--gray-300,#cbd5e1); border-radius:99px; border:3px solid transparent; background-clip:content-box}
::-webkit-scrollbar-thumb:hover{background:var(--gray-400,#94a3b8); background-clip:content-box}

/* ---- 卡片：悬浮微抬升 ---- */
.card{transition:box-shadow .22s cubic-bezier(.4,0,.2,1), border-color .22s cubic-bezier(.4,0,.2,1), transform .22s cubic-bezier(.4,0,.2,1)}
.card:hover{box-shadow:0 4px 14px -4px rgba(15,23,43,.10), 0 2px 6px -3px rgba(15,23,43,.06); border-color:var(--gray-300,#cbd5e1)}

/* ---- 表格：吸顶表头 + 斑马纹 + 悬停 ---- */
table thead th{
  position:sticky; top:0; z-index:2;
  backdrop-filter:saturate(1.6) blur(6px);
  box-shadow:inset 0 -1px 0 var(--border);
}
table tbody tr{transition:background .14s ease}
table tbody tr:nth-child(even){background:rgba(15,23,43,.014)}
table tbody tr:hover{background:rgba(59,130,246,.055)}
table tbody tr.row-active{background:rgba(59,130,246,.10); box-shadow:inset 3px 0 0 var(--primary)}

/* ---- 按钮：按下反馈 + 焦点环 ---- */
button, .btn{transition:background .16s ease, border-color .16s ease, box-shadow .16s ease, transform .1s ease}
button:active, .btn:active{transform:translateY(.5px)}
button:focus-visible, .btn:focus-visible, a:focus-visible, input:focus-visible, select:focus-visible, textarea:focus-visible{
  outline:2px solid var(--ring, #93c5fd); outline-offset:2px;
}

/* ---- 输入控件：更明显的聚焦态 ---- */
input, select, textarea{transition:border-color .16s ease, box-shadow .16s ease}
input:focus, select:focus, textarea:focus{
  border-color:var(--primary);
  box-shadow:0 0 0 3px rgba(37,99,235,.12);
}

/* ---- 导航：当前项更明确 ---- */
aside.side nav a{transition:background .16s ease, color .16s ease, padding-left .16s ease}
aside.side nav a:hover{padding-left:2px}
aside.side nav a.on{position:relative}
aside.side nav a.on::before{
  content:""; position:absolute; left:0; top:6px; bottom:6px; width:2.5px;
  border-radius:0 2px 2px 0; background:var(--sidebar-primary,#fff); opacity:.9;
}

/* ---- 徽章 / KPI 数字：等宽对齐 ---- */
.badge, .kpi b, .num{font-variant-numeric:tabular-nums}

/* ---- 图表容器：统一留白 ---- */
.chart{padding:4px 2px 0}

/* ---- 标题层级：收紧字距 ---- */
h1,h2,h3{letter-spacing:-.012em}
h1#pageTitle{letter-spacing:-.02em}

/* ---- 空态：居中且克制 ---- */
.empty{padding:44px 20px; text-align:center; color:var(--muted-foreground); font-size:13px}

/* ---- 页脚 ---- */
.wrap>footer{letter-spacing:.2px}

/* ---- 尊重系统的"减少动效" ---- */
@media (prefers-reduced-motion: reduce){
  *{animation-duration:.01ms !important; transition-duration:.01ms !important; scroll-behavior:auto !important}
}

/* =========================================================================
   个人设置 · 微信推送
   ========================================================================= */
.wx-on{color:#16a34a; font-weight:600}
.wx-off{color:var(--gray-400,#94a3b8); font-weight:600}

.wx-grid{display:grid; grid-template-columns:repeat(auto-fill,minmax(300px,1fr)); gap:10px; margin-top:8px}
.wx-t{display:flex; gap:10px; align-items:flex-start; padding:11px 13px; border:1px solid var(--border);
      border-radius:10px; cursor:pointer; transition:border-color .16s ease, background .16s ease}
.wx-t:hover{border-color:var(--gray-300,#cbd5e1); background:rgba(15,23,43,.014)}
.wx-t input{margin-top:2px; flex:none}
.wx-t-b{display:flex; flex-direction:column; gap:3px; line-height:1.35}
.wx-t-b b{font-size:13.5px; font-weight:600}
.wx-t-b span{font-size:11.5px; color:var(--muted-foreground)}
.wx-t-b em{font-style:normal; font-size:10.5px; font-weight:600; color:#b45309;
           background:rgba(180,83,9,.1); padding:1px 6px; border-radius:99px; margin-left:4px}
.wx-lock{cursor:not-allowed; background:rgba(15,23,43,.028); border-style:dashed}
.wx-lock:hover{border-color:var(--border); background:rgba(15,23,43,.028)}

.wx-radio{display:inline-flex; gap:7px; align-items:center; padding:5px 12px 5px 0; font-size:13px; cursor:pointer; white-space:nowrap}
/* 单选组：横排、间距均匀、不撑满
   注意：.set-row .ctl input 有 flex:1 + min-width:180px，会把每个圆圈撑宽，
   所以这里必须用同等或更高的特异性把它覆盖掉，否则文字会被推到两头（实测过）。*/
.set-row .ctl .wx-radio input{flex:none; min-width:0; width:auto}
.set-row .ctl:has(.wx-radio){display:flex; flex-wrap:wrap; gap:4px 22px; align-items:center}

#wxLog table{margin-top:6px}

/* ---- Token 获取指引：扫一扫 + 三步 ---- */
.wx-guide{display:flex; gap:26px; align-items:flex-start; flex-wrap:wrap; width:100%}

.wx-prov{display:flex; flex-direction:column; gap:10px; align-items:center; flex:none}
.wx-ptab{display:flex; flex-direction:column; align-items:center; gap:2px; width:100%;
         padding:7px 14px; border:1px solid var(--border); border-radius:9px; background:transparent;
         font-size:12.5px; font-weight:600; color:var(--muted-foreground); cursor:pointer;
         transition:all .16s ease; line-height:1.25}
.wx-ptab span{font-size:10.5px; font-weight:400; opacity:.8}
.wx-ptab:hover{border-color:var(--gray-300,#cbd5e1); color:var(--foreground)}
.wx-ptab.on{border-color:var(--primary); color:var(--foreground); background:rgba(37,99,235,.055)}

.wx-qrbox{padding:9px; background:#fff; border:1px solid var(--border); border-radius:12px; line-height:0}
.wx-qrbox img{display:block; border-radius:6px}
.wx-qrhint{font-size:11px; color:var(--muted-foreground); text-align:center; padding-top:7px; line-height:1.2}
.wx-plink{font-size:11.5px; color:var(--muted-foreground); text-decoration:none}
.wx-plink:hover{color:var(--primary); text-decoration:underline}

.wx-steps{flex:1; min-width:260px; margin:0; padding-left:0; list-style:none; counter-reset:wxs}
.wx-steps li{position:relative; padding:0 0 16px 34px; counter-increment:wxs}
.wx-steps li:last-child{padding-bottom:0}
.wx-steps li::before{content:counter(wxs); position:absolute; left:0; top:1px;
                     width:22px; height:22px; border-radius:50%; background:var(--primary);
                     color:#fff; font-size:12px; font-weight:600; display:flex;
                     align-items:center; justify-content:center}
.wx-steps li::after{content:""; position:absolute; left:10.5px; top:26px; bottom:2px;
                    width:1px; background:var(--border)}
.wx-steps li:last-child::after{display:none}
.wx-steps b{display:block; font-size:13.5px; font-weight:600; margin-bottom:3px}
.wx-steps span{display:block; font-size:11.5px; color:var(--muted-foreground); line-height:1.5}

/* ---- ilink 扫码绑定 ---- */
.wx-qrbox{position:relative}
.wx-qrload{position:absolute; inset:9px; display:flex; align-items:center; justify-content:center;
           background:#fff; font-size:12px; color:var(--muted-foreground); text-align:center; padding:10px; line-height:1.5}
.wx-fallback{border:1px dashed var(--border); border-radius:10px; padding:10px 14px; width:100%}
.wx-fallback>summary{cursor:pointer; font-size:12.5px; color:var(--muted-foreground); outline:none}
.wx-fallback>summary:hover{color:var(--foreground)}

/* ---- 推送记录：测试条目 + 失败原因 ---- */
.wx-test-tag{display:inline-block; padding:1px 7px; border-radius:99px; font-size:11px; font-weight:600;
             color:var(--muted-foreground); background:rgba(15,23,43,.07)}
.wx-row-test td{background:rgba(15,23,43,.018)}
.wx-err{display:block; font-size:11px; color:#b91c1c; margin-top:2px; line-height:1.35}

/* ---- 待办事宜：可点统计块（数字就是筛选器）---- */
.todo-kpis{display:flex;gap:10px;margin-bottom:14px;flex-wrap:wrap}
.todo-kpi{flex:1;min-width:120px;padding:12px 14px;border:1px solid var(--border);border-radius:10px;
  cursor:pointer;transition:border-color .18s,background .18s,transform .18s;background:var(--card)}
.todo-kpi:hover{border-color:var(--primary);transform:translateY(-1px)}
.todo-kpi.on{border-color:var(--primary);background:color-mix(in srgb,var(--primary) 8%,transparent)}
.todo-kpi b{display:block;font-size:24px;line-height:1.2;font-variant-numeric:tabular-nums}
.todo-kpi span{font-size:12px;color:var(--muted-foreground)}
.todo-kpi.on span{color:var(--primary);font-weight:600}

/* ---- 项目跟进页：状态筛选 chips ---- */
.fu-chips{display:flex;gap:8px;flex-wrap:wrap;margin-bottom:12px}
.fu-chip{padding:4px 11px;border:1px solid var(--border);border-radius:99px;cursor:pointer;font-size:12.5px;
  transition:border-color .18s,background .18s}
.fu-chip b{font-variant-numeric:tabular-nums}
.fu-chip:hover{border-color:var(--primary)}
.fu-chip.on{border-color:var(--primary);background:color-mix(in srgb,var(--primary) 10%,transparent);font-weight:600}

/* ---- 消息中心：未读圆点 ---- */
.ntc-dot{display:inline-block;width:7px;height:7px;border-radius:50%;background:#e5484d;
  margin-right:7px;vertical-align:middle}
#myNotice table tbody tr:hover{background:color-mix(in srgb,var(--primary) 6%,transparent)}

/* ================= 侧栏收起态（点左上角「荆」切换）=================
   收起只留竖排图标；展开带文字。图标是 span.ni，文字是不带 class 的 span ——
   所以隐藏文字要用 span:not(.ni)，不能直接 a>span（会把图标也干掉）。 */
aside.side .brand{cursor:pointer; border-radius:var(--r); transition:background .18s}
aside.side .brand:hover{background:var(--sidebar-accent)}
aside.side .brand:focus-visible{outline:2px solid var(--ring); outline-offset:2px}

/* ★ 侧栏品牌（2026-10-14 改版）：
   用户第 1 版看到「整标(ttlogo) + 荆州铁塔/商机管理平台两行字」挤在一起，说「位置不好」——
   整标带中英文全长，缩到 22px 后字太小，又和右侧两行文字抢地方。
   改成**只用图形标（tt2logo）**：展开 = 图形标 + 文字；收起 = 只剩图形标。
   整标（ttlogo）保留给登录页。 */
.brand .brand-mark{display:block; height:28px; width:auto; flex:0 0 auto}
aside.side.collapsed .brand .brand-mark{height:26px}
/* ★ logo 与文字之间的竖线（2026-10-14 用户要求）：黑色、高度与 logo 等高、左右等距。
   左右等距靠 .brand 的 flex gap 保证 —— 竖线本身是 flex 项，所以
   「logo→线」和「线→文字」各吃一个 gap，天然相等，不用写死 margin。 */
.brand .brand-div{width:1px; height:28px; flex:0 0 auto; background:#000; border-radius:1px}
/* 暗色主题下纯黑看不见（侧栏底色是深的），换成浅色；浅色主题下就是你看到的黑色 */
body.dark .brand .brand-div{background:rgba(255,255,255,.7)}
/* 收起时文字隐藏，竖线也就没有意义了 */
aside.side.collapsed .brand .brand-div{display:none}
/* 登录页整标：logo 是深色字，直接摆在深色背景上看不见 —— 垫一个白底圆角块 */
.lg-logo-box{background:#fff; border-radius:12px; padding:9px 13px; display:inline-block;
             box-shadow:0 8px 22px rgba(0,0,0,.22)}
.lg-logo-box img{display:block; height:36px; width:auto}
aside.side.collapsed{width:62px}
aside.side.collapsed .brand{justify-content:center; padding-left:0; padding-right:0}
aside.side.collapsed .brand > div{display:none}
aside.side.collapsed .nav-label{display:none}
aside.side.collapsed nav{padding:8px 6px}
aside.side.collapsed nav a{justify-content:center; padding:9px 0; position:relative}
aside.side.collapsed nav a > span:not(.ni){display:none}
aside.side.collapsed nav a .ni{opacity:.85}
aside.side.collapsed nav a:hover .ni,
aside.side.collapsed nav a.on .ni{opacity:1}
/* 收起时角标只留一个小红点（不显示数字）——
   62px 宽里再塞「223」这种数字会把 16px 的图标整个盖住，
   截图确认过：数字比图标还显眼，一眼看过去全是数字看不出是什么功能。
   悬停有 title，数字在展开态看。 */
aside.side.collapsed nav a .nav-badge{
  position:absolute; top:4px; right:8px; margin:0;
  min-width:8px; width:8px; height:8px; line-height:0;
  padding:0; font-size:0; border-radius:50%;
  overflow:hidden; box-shadow:0 0 0 2px var(--sidebar);
}
aside.side.collapsed .side-foot{display:none}

/* ================= 消息中心表格 =================
   全局的 .scroll table{min-width:1000px} 是给商机池那种多列表用的
   （不让列被挤压，改为横向滚动）。消息中心只有「时间 / 内容」两列，
   被这条规则强制 1000px 后比容器还宽 —— 实测容器 852px、表格 1000px，
   日期列被拉成 280px，整块横向溢出，用户看到的是「日期太长影响布局」。
   所以这里显式摘出来：不设最小宽、固定布局、时间列定宽不换行、
   内容列负责换行吸收剩余宽度。 */
/* ⚠ 必须写成 `.scroll table.ntc-table`：全局的 `.scroll table` 优先级是 (0,1,1)，
   单纯 `.ntc-table` 只有 (0,1,0) —— 实测会输，表格照样被撑到 1000px。 */
.scroll table.ntc-table{min-width:0; table-layout:fixed}
/* 列宽交给 colgroup —— 比在 td 上写 width 硬：不依赖任何一行内容，
   也不会和内容列平分（用户反馈「日期列和内容列一样宽」）。 */
.ntc-table col.c-time{width:96px}
.ntc-table td:first-child{
  white-space:nowrap; font-size:12px; vertical-align:top; padding-top:14px;
  font-variant-numeric:tabular-nums;   /* 数字等宽，多条日期能对齐 */
}
.ntc-table td.ntc-msg{
  word-break:break-word; overflow-wrap:anywhere; white-space:normal;
}

/* ================= 项目跟进表格 =================
   和 .ntc-table 同一个原因：全局 .scroll table{min-width:1000px} 是给
   商机池那种多列表用的，项目跟进只有 6 列，被强制 1000px 后比容器还宽，
   最右边的「转派」按钮被挤出可视区（1024 下实测）。
   注意选择器必须带 .scroll 前缀（(0,2,1)）才盖得住 .scroll table（(0,1,1)）——
   只写 .fu-table 会输，实测踩过。 */
.scroll table.fu-table{min-width:0; table-layout:fixed}
.fu-table td:first-child, .fu-table th:first-child{
  white-space:normal; word-break:break-word; overflow-wrap:anywhere;
}
.fu-table td:first-child a{display:inline}
