:root{
  --ui-zoom:1;
  /* 整站按 innerWidth/1600 缩放，所以「实际可用布局高度」= 100vh / zoom。
     侧边栏要据此收紧菜单间距，不能用 @media(max-height) —— 媒体查询看的是未缩放的视口高度，会判断错。 */
  --app-h:calc(100vh / var(--ui-zoom,1));
  --primary:#2563eb; --primary-d:#1d4ed8; --bg:#f5f7fb; --card:#fff;
  --line:#e5e9f2; --text:#1f2937; --muted:#6b7280; --ok:#16a34a; --warn:#d97706; --danger:#dc2626;
}
*{box-sizing:border-box;margin:0;padding:0}
body{font-family:-apple-system,"PingFang SC","Microsoft YaHei",Segoe UI,sans-serif;background:var(--bg);color:var(--text);font-size:14px}
.hidden{display:none!important}
button{cursor:pointer;font-family:inherit}
input,select,textarea{font-family:inherit;font-size:14px;padding:8px 10px;border:1px solid var(--line);border-radius:8px;outline:none;width:100%;background:#fff}
input:focus,select:focus,textarea:focus{border-color:var(--primary)}
/* 勾选框/单选框不能跟着 input 一起被撑成 100% 宽，否则会出现「左边文字、中间空白、右边勾选框」的错位 */
input[type=checkbox],input[type=radio]{width:auto;flex:none;padding:0;margin:0;vertical-align:middle;accent-color:var(--primary);cursor:pointer}

/* 登录 */
.login-wrap{height:calc(100vh / var(--ui-zoom,1));display:flex;align-items:center;justify-content:center;background:linear-gradient(135deg,#2563eb,#0ea5e9)}
.login-card{background:#fff;padding:36px 32px;border-radius:16px;width:320px;box-shadow:0 18px 50px rgba(0,0,0,.18);text-align:center}
/* 登录页品牌：2026-10-19 换成公司横版 logo（蓝版，白底用）
   文件是 2x（432×122），显示 216×61；窄屏用 max-width 兜底等比缩 */
.brand-logo{display:block;width:216px;max-width:100%;height:auto;margin:0 auto}
.brand-sub{color:var(--muted);margin:10px 0 22px;font-size:13px}
.login-form{display:flex;flex-direction:column;gap:12px}
.login-form button{background:var(--primary);color:#fff;border:none;padding:11px;border-radius:8px;font-size:15px;font-weight:600}
.login-form button:hover{background:var(--primary-d)}
.err{color:var(--danger);font-size:13px;min-height:16px}
/* 备案号（2026-10-19 ICP 备案通过后挂上）：首页底部展示并链接工信部，管局抽查项 */
.login-foot{margin-top:18px;padding-top:14px;border-top:1px solid #eef2f7;font-size:12px;color:#94a3b8;line-height:1.8}
.login-foot span{display:block}
.login-foot a{color:#94a3b8;text-decoration:none}
.login-foot a:hover{color:var(--primary);text-decoration:underline}

/* 布局 */
/* 高度按缩放倍数回补：小屏整体缩放后仍要刚好铺满一屏 */
.app{display:flex;height:calc(100vh / var(--ui-zoom,1))}
/* overflow:hidden 是兜底（2026-10-19 修）：侧边栏高度锁死 100vh，内容超出时必须
   在栏内消化，否则「系统管理员 / 退出 / 备案号」会溢到栏外、掉在白色背景上看不见。 */
.sidebar{width:200px;background:#0f2540;color:#cbd5e1;display:flex;flex-direction:column;padding:18px 12px;overflow:hidden}
/* 侧边栏品牌（2026-10-19）：马头白图标 + 两行文字。
   侧边栏只有 176px 可用宽，横版 logo 带拼音会缩到看不清，
   所以拆成「图标 + 文字」——视觉上等同于横版 logo，各尺寸都清晰。 */
.logo{display:flex;align-items:center;gap:8px;margin-bottom:clamp(12px,calc(var(--app-h) * .02),20px);padding-left:6px;position:relative;flex:none}
.logo-mark{width:30px;height:30px;flex:none;display:block}
.logo-txt{font-size:15px;font-weight:800;color:#fff;line-height:1.15;letter-spacing:.5px}
.logo-txt span{display:block;font-size:11px;color:#7dd3fc;font-weight:600;letter-spacing:1.5px}
/* 菜单区可滚动（2026-10-19）：flex 子项默认 min-height:auto，不加这一行它就撑到内容高度、
   拒绝收缩，整个侧边栏的高度就爆了。min-height:0 是让 flex:1 真正生效的前提。 */
.sidebar nav{display:flex;flex-direction:column;gap:3px;flex:1;min-height:0;overflow-y:auto;overflow-x:hidden;
  scrollbar-width:thin;scrollbar-color:#1e3a5f transparent}
.sidebar nav::-webkit-scrollbar{width:6px}
.sidebar nav::-webkit-scrollbar-track{background:transparent}
.sidebar nav::-webkit-scrollbar-thumb{background:#1e3a5f;border-radius:3px}
.sidebar nav::-webkit-scrollbar-thumb:hover{background:#2c4a70}
/* 菜单项上下留白随可用高度收缩（2026-10-19）：15 个菜单在 1600×900 全屏时是 11px 舒服，
   浏览器工具栏一占、可视高只剩 720 时就放不下 —— 按可用高度线性收紧，尽量不出滚动条。
   再矮（<650）交给 nav 的 overflow-y 兜底。 */
.sidebar nav a{color:#cbd5e1;text-decoration:none;padding:clamp(7px,calc(var(--app-h) * .0105),11px) 12px;border-radius:8px;font-size:14px}
.sidebar nav a:hover{background:#1e3a5f;color:#fff}
.sidebar nav a.active{background:var(--primary);color:#fff}
.side-foot{font-size:12px;color:#94a3b8;border-top:1px solid #1e3a5f;padding-top:12px;display:flex;flex-direction:column;gap:8px;flex:none}
.side-foot button{background:none;border:1px solid #1e3a5f;color:#cbd5e1;padding:6px;border-radius:6px}
.side-foot button:hover{background:#1e3a5f;color:#fff}
/* 侧边栏底部的备案号：登录后的内页也能看到（字号刻意压到 10.5px，不抢视线） */
.side-icp{font-size:10.5px;color:#7c93b0;text-decoration:none;text-align:center;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;letter-spacing:-.2px}
.side-icp:hover{color:#a8bed6;text-decoration:underline}

/* 内容区做成纵向 flex：普通视图按内容自然撑开（超出就滚动），
   列表页（.view.fill）则把剩余高度全部分给表格 —— 见下方「列表页撑满一屏」 */
.content{flex:1;min-width:0;overflow:auto;padding:24px 28px;display:flex;flex-direction:column}
.view{flex:none;min-width:0}
.view h2{font-size:20px;margin-bottom:16px}
.view h2 small{font-size:13px;color:var(--muted);font-weight:400;margin-left:8px}

/* 卡片/网格 */
.cards{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:14px;margin-bottom:22px}
.kpi{background:var(--card);border:1px solid var(--line);border-radius:12px;padding:16px}
.kpi .num{font-size:26px;font-weight:800;color:var(--primary)}
.kpi .lbl{color:var(--muted);margin-top:4px}
/* 看板卡片可点击下钻 */
.kpi.clickable{cursor:pointer;transition:transform .12s,box-shadow .12s,border-color .12s}
.kpi.clickable:hover{border-color:var(--primary);box-shadow:0 8px 20px rgba(37,99,235,.14);transform:translateY(-2px)}
.kpi .go{font-size:11px;color:#9aa4b2;float:right}
.kpi.clickable:hover .go{color:var(--primary)}
.drill{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:6px 9px;border:1px solid transparent;border-radius:8px;cursor:pointer;font-size:13px}
.drill:hover{background:#f5f9ff;border-color:#d6e4ff}
.drill .n{color:var(--primary);font-weight:700}
.dash-item{display:block;padding:9px 11px;border:1px solid var(--line);border-radius:10px;margin:7px 0;cursor:pointer;background:#fff}
.dash-item:hover{border-color:var(--primary);background:#f8fbff}
.dash-item .t1{font-size:12px;color:var(--muted)}
.dash-item .t2{margin-top:2px;color:var(--text)}
.panel{background:var(--card);border:1px solid var(--line);border-radius:12px;padding:16px;margin-bottom:18px}
.panel h3{font-size:15px;margin-bottom:12px}

/* 工具条 */
.toolbar{display:flex;gap:10px;flex-wrap:wrap;margin-bottom:14px;align-items:center}
.toolbar .grow{flex:1}
/* ---------- 按日期范围检索（2026-10-12）：字段下拉 + 开始 / 至 / 结束 ---------- */
/* 所有列表页共用；不是 flex:1，保持紧凑 —— 工具栏本来就是 flex-wrap，放不下会自己换行 */
.dr-box{display:inline-flex;align-items:center;gap:6px;white-space:nowrap}
.dr-box select{width:116px}
.dr-box input[type=date]{width:146px}
.dr-box .dr-sep{color:#999;font-size:12px}
/* ---------- 工具栏里的搜索框（2026-10-17 修） ----------
   原来写的是内联 flex:1;max-width:240px。`flex:1` = flex-basis:0%，工具栏元素一多，
   它按 0 宽参与换行计算（永远"放得下"），于是被压成一条线 —— 客户档案页只剩 placeholder
   的第一个字「搜」，眼睛都看不见。
   给 flex-basis 一个真实宽度，放不下时交给 .toolbar 的 flex-wrap 去换行。
   `min-width` 兜底：万一父容器被挤，也不至于缩到 0。 */
.toolbar .tb-q{flex:1 1 220px;min-width:200px;max-width:280px}
/* 员工权限勾选（2026-10-13）：员工管理 → 「新建/编辑员工」弹窗里的权限清单 */
/* 权限清单限高、自己内部滚动：10 项权限全展开会把弹窗撑到 88vh 上限，
   底部「保存」按钮要滚到底才点得到（小屏笔记本尤其明显）。 */
.perm-pick{display:flex;flex-direction:column;gap:14px;max-height:min(38vh,340px);overflow:auto;padding-right:6px}
.perm-g{display:flex;flex-direction:column}
.perm-g>b{display:block;font-size:12px;color:#8a8f99;font-weight:600;margin-bottom:6px}
.perm-item{display:flex;align-items:flex-start;gap:8px;padding:8px 10px;border:1px solid var(--line);border-radius:8px;background:#fff;cursor:pointer;transition:border-color .12s,background .12s;margin:0 0 6px}
.perm-item:last-child{margin-bottom:0}
.perm-item:hover{border-color:var(--primary);background:#f8fbff}
.perm-item input{width:auto;flex:none;margin:2px 0 0;padding:0}
.perm-item>span{display:flex;flex-direction:column;min-width:0}
.perm-item i{font-style:normal;font-size:13px;color:#222;line-height:1.4}
.perm-item em{font-style:normal;font-size:11px;color:#9aa0a6;line-height:1.5;margin-top:1px}
/* 非管理员打开时：整块置灰、不可点，提示「只有管理员能改」 */
.perm-item.dis{opacity:.6;cursor:not-allowed}
.perm-item.dis:hover{border-color:var(--line);background:#fff}
/* 员工列表「可用权限」列：权限多时换行而不是把表格撑宽 */
.perm-cell{max-width:280px;word-break:break-word}
.btn{background:var(--primary);color:#fff;border:none;padding:8px 14px;border-radius:8px;font-size:13px}
.btn:hover{background:var(--primary-d)}
.btn.ghost{background:#fff;color:var(--primary);border:1px solid var(--primary)}
.btn.danger{background:var(--danger)}
.btn.sm{padding:5px 10px;font-size:12px}

/* 表格 */
table{width:100%;border-collapse:collapse;background:var(--card)}
th,td{text-align:left;padding:10px 12px;border-bottom:1px solid var(--line);font-size:13px}
th{background:#f1f5f9;color:var(--muted);font-weight:600}
tbody tr:hover{background:#f8fafc}
.tag{display:inline-block;background:#e0edff;color:var(--primary-d);border-radius:20px;padding:2px 9px;font-size:12px;margin:2px 3px 0 0}
.badge.warn{display:inline-block;background:#fff3cd;color:#a36200;border:1px solid #f3d266;border-radius:6px;padding:1px 7px;font-size:12px;font-weight:600;margin-left:4px}
.tag.o{background:#fef3c7;color:var(--warn)}
.pill{display:inline-block;padding:2px 9px;border-radius:20px;font-size:12px}
.pill.negotiating{background:#fef3c7;color:#b45309}
.pill.signed{background:#dbeafe;color:#1d4ed8}
.pill.ongoing{background:#ede9fe;color:#6d28d9}
.pill.done{background:#dcfce7;color:#15803d}
.pill.cancelled{background:#fee2e2;color:#b91c1c}
.link{color:var(--primary);cursor:pointer;text-decoration:underline}
.act{color:var(--primary);cursor:pointer;margin-left:6px;font-size:12px}
.act:hover{text-decoration:underline}
.seg{display:inline-flex;border:1px solid var(--line);border-radius:8px;overflow:hidden}
.seg-btn{background:#fff;border:none;padding:8px 14px;font-size:13px;color:var(--muted)}
.seg-btn.active{background:var(--primary);color:#fff}
.seg-btn+.seg-btn{border-left:1px solid var(--line)}

/* 弹窗 */
.modal{position:fixed;left:0;top:0;width:calc(100vw / var(--ui-zoom,1));height:calc(100vh / var(--ui-zoom,1));background:rgba(15,23,42,.5);display:flex;align-items:center;justify-content:center;z-index:50}
.modal-box{background:#fff;border-radius:14px;padding:24px;width:min(680px,calc(92vw / var(--ui-zoom,1)));max-height:calc(88vh / var(--ui-zoom,1));overflow:auto}
.modal-box h3{margin-bottom:14px}
/* 弹窗可拖动（2026-09-22 第六轮）：按住标题条就能把窗口挪开，方便看被它挡住的内容。
   位移用 transform 实现，不改布局 —— 弹窗靠 flex 居中，改 margin 会影响定位与滚动。 */
#modalBox h3{cursor:move;user-select:none;-webkit-user-select:none;touch-action:none}
#modalBox h3::after{content:"（按住标题可拖动）";font-size:11px;font-weight:400;color:#9aa4b2;margin-left:6px}
#modalBox.dragging{cursor:move}
#modalBox.dragging,#modalBox.dragging *{user-select:none!important;-webkit-user-select:none!important}
.form-grid{display:grid;grid-template-columns:1fr 1fr;gap:12px}
.form-grid .full{grid-column:1/-1}
/* 联系人的「多个手机号」多行输入：一行一个号，右边一个删除链接 */
.phone-row{display:flex;gap:8px;align-items:center;margin-bottom:6px}
.phone-row .ct_phone_i{flex:1;min-width:0}
.phone-row .act{flex:none;cursor:pointer;color:var(--muted);padding:0 4px;font-size:13px}
.phone-row .act:hover{color:var(--danger)}
.modal-actions{display:flex;justify-content:flex-end;gap:10px;margin-top:18px}
/* 订单跟进状态（2026-09-21 改版）配色；旧的五个类保留，万一有历史数据没迁移完也不会掉样式 */
.pill.initial{background:#f1f5f9;color:#475569}
.pill.quoting{background:#fef3c7;color:#b45309}
.pill.contract{background:#ede9fe;color:#6d28d9}
.pill.deal{background:#dcfce7;color:#15803d}
.pill.lost{background:#fee2e2;color:#b91c1c}
/* 图片查看器：按原始比例完整显示，长图自己纵向滚动（见 app.js openImageViewer） */
.img-viewer{position:fixed;left:0;top:0;width:calc(100vw / var(--ui-zoom,1));height:calc(100vh / var(--ui-zoom,1));z-index:200;background:rgba(15,23,42,.88);display:flex;flex-direction:column}
.iv-bar{display:flex;align-items:center;gap:8px;padding:10px 14px;background:rgba(255,255,255,.08);color:#fff;flex:none}
.iv-name{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:13px}
.iv-body{flex:1;overflow:auto;padding:14px;display:flex;align-items:flex-start;justify-content:center}
.iv-body img{max-width:100%;height:auto;display:block;background:#fff;border-radius:4px}
/* 表格横向滚动容器：订单列多，窄屏时整表可左右拖，不挤压列宽 */
.tbl-scroll{overflow:auto;max-width:100%}
.tbl-scroll table{min-width:max-content}
/* 需求 / 订单列表页的表格（.tbl-page，2026-09-22）：
   ① 容器限高 → 横向滚动条始终贴在可见区域底部，小屏不用先滚到表格最下面才够得着；
   ② 表头吸顶，纵向滚动时列名还在；
   ③ 操作列吸附右侧 —— 不横向滚动也能点到「转订单 / 编辑 / 删除」。 */
.tbl-page{max-height:calc(100vh / var(--ui-zoom,1) - 330px);min-height:220px;overflow:auto}
.tbl-page thead th{position:sticky;top:0;z-index:3;box-shadow:inset 0 -1px 0 var(--line)}
.tbl-page th:last-child,.tbl-page td:last-child:not(.empty){position:sticky;right:0;z-index:2;background:var(--card);box-shadow:-9px 0 12px -10px rgba(15,23,42,.45),inset 0 -1px 0 var(--line)}
.tbl-page thead th:last-child{background:#f1f5f9;z-index:4}
.tbl-page tbody tr:hover td:last-child{background:#f8fafc}
/* 跟进提醒页上下两张表：上面「待跟进」若按默认高度占满整屏，下面「最近跟进记录」就得滚半天才看得见。
   这里只压这一页（桌面端），留出下方表格的位置；窄屏是卡片流，不适用。 */
@media (min-width:821px){#view-tasks .tbl-page{max-height:calc(100vh / var(--ui-zoom,1) - 430px)}}
/* 「最近跟进记录」列多，窄屏要横向滚；把最右「操作」列固定住，滚到哪儿都能点到（与 .tbl-page 同一手法） */
@media (min-width:821px){
  #view-tasks .tbl-scroll:not(.tbl-page) table th:last-child,
  #view-tasks .tbl-scroll:not(.tbl-page) table td:last-child:not(.empty){position:sticky;right:0;background:var(--card);box-shadow:-9px 0 12px -10px rgba(15,23,42,.45)}
  #view-tasks .tbl-scroll:not(.tbl-page) table thead th:last-child{background:#f1f5f9}
  /* 待跟进表 8 列，「上次跟进内容 / 下次要谈」是长文本；不锁上限时整表横向溢出 360px 左右，
     最右的「操作」列被压成一条缝（实测只剩 39px，"打开"两个字都放不下）。
     给这两列锁一个上限、单行省略号（完整内容看悬浮提示或点客户名进去看），并保住操作列的宽度。

     ⚠️ 这些宽度只在用户**还没拖过列宽**（表格没有 .tx-fixed）时生效。
        一旦用户自己拖过列宽，TblX 会切成固定布局、用 colgroup 说了算，
        这时再压着 max-width 就会出现"把列拖宽了字却被省略号截住"的怪现象。 */
  #view-tasks table[data-tx="taskfu"]:not(.tx-fixed) th:nth-child(6),
  #view-tasks table[data-tx="taskfu"]:not(.tx-fixed) td:nth-child(6){width:200px;max-width:200px}
  #view-tasks table[data-tx="taskfu"]:not(.tx-fixed) th:nth-child(7),
  #view-tasks table[data-tx="taskfu"]:not(.tx-fixed) td:nth-child(7){width:140px;max-width:140px}
  #view-tasks table[data-tx="taskfu"]:not(.tx-fixed) th:last-child,
  #view-tasks table[data-tx="taskfu"]:not(.tx-fixed) td:last-child{min-width:76px}
  /* 长文本列一律单行省略号：锁定布局下也保证不撑破单元格 */
  #view-tasks table[data-tx="taskfu"] td:nth-child(6),
  #view-tasks table[data-tx="taskfu"] td:nth-child(7),
  #view-tasks table[data-tx="taskfu"] td:last-child{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
}
/* 列表页「撑满一屏」（2026-09-22 第三轮，用户反馈：表格没占满、下方留白却还要滚）：
   视图铺满可视高度 → 表格容器吃掉「标题+工具条+分页条」之外的全部高度 → 表底贴到窗口底部，
   页面本身不再出现纵向滚动条；数据多时只在表格内部滚动（表头吸顶、横向滚动条也一直贴在最下面）。
   不用 100vh 减固定像素的估算，是因为窗口高低、界面缩放变了都对得上。 */
.view.fill{flex:1;min-height:0;display:flex;flex-direction:column}
/* 标题、工具条、统计条、翻页条等一律按内容高度（不参与伸缩），高度全给表格 */
.view.fill>*{flex:none;min-width:0}
.view.fill>.panel{flex:1;min-height:0;margin-bottom:6px;display:flex;flex-direction:column;overflow:hidden}
.view.fill .tbl-page{flex:1;min-height:0;max-height:none}
.view.fill>.list-pager{margin:0 2px}
/* 列表分页条（需求 / 订单） */
.list-pager{display:flex;gap:8px;align-items:center;margin:8px 2px;font-size:13px;color:#666;flex-wrap:wrap}
.field label{display:block;font-size:12px;color:var(--muted);margin-bottom:4px}
.tabs{display:flex;gap:8px;margin-bottom:14px;border-bottom:1px solid var(--line)}
.tabs button{background:none;border:none;padding:8px 12px;color:var(--muted);border-bottom:2px solid transparent}
.tabs button.active{color:var(--primary);border-bottom-color:var(--primary);font-weight:600}
.timeline{position:relative;padding-left:18px;border-left:2px solid var(--line)}
.timeline .item{position:relative;margin-bottom:14px}
.timeline .item::before{content:"";position:absolute;left:-25px;top:4px;width:10px;height:10px;border-radius:50%;background:var(--primary)}
.timeline .meta{font-size:12px;color:var(--muted);margin-bottom:3px}
/* 「下次跟进」：跟进记录里最该被一眼看见的一条，原来挤在 meta 小灰字里看不出来（2026-09-28 用户反馈），
   单独做成带底色 + 左侧色条的醒目块，日期再放大一档 */
.fu-next{display:flex;flex-wrap:wrap;align-items:center;gap:4px 8px;margin-top:7px;padding:5px 10px;
  border-radius:8px;background:#eef4ff;border-left:3px solid var(--primary);
  color:var(--primary-d);font-size:13.5px;font-weight:600;line-height:1.55}
.fu-next .d{font-size:15px;font-weight:800;letter-spacing:.4px}
.fu-next .c{font-weight:500;color:var(--text);font-size:13.5px}
/* 跟进正文：只放文字，粘贴进来的图片统一在下方附件区展示 */
.fcontent{line-height:1.65;word-break:break-word}
/* 往输入框里拖图片时的提示态 */
textarea.drop-img{border-color:var(--primary);border-style:dashed;background:#f2f7ff}
/* 粘贴图片正在上传时的提示态（传完自动恢复） */
textarea.img-uploading{border-color:var(--primary);background:#f2f7ff;background-image:linear-gradient(90deg,rgba(37,99,235,.06) 0,rgba(37,99,235,.06) 100%)}
.muted{color:var(--muted)}
.right{text-align:right}
.empty{color:var(--muted);text-align:center;padding:30px}
.dot{display:inline-block;width:10px;height:10px;border-radius:50%;vertical-align:middle;margin-right:2px}
.qcc-item:hover{background:#f1f5f9}
.badge.warn{display:inline-block;background:#fff3cd;color:#a36200;border:1px solid #f3d266;border-radius:6px;padding:1px 7px;font-size:12px;font-weight:600;margin-left:4px}

/* ================= 表头交互：点击排序 + 拖拽调列宽（2026-09-24） =================
   只作用在带 data-tx 的列表表格上（表单里的小表不受影响）。
   要点：
   ① th 必须是定位元素，拖拽手柄才能贴住它的右边缘 —— .tbl-page 里 th 已经是 position:sticky，
      sticky 元素同样能作为绝对定位子元素的包含块，所以那边不用额外处理；
      没有 sticky 的普通表格（联系人/员工）由 th.thx 补上 position:relative。
   ② 手柄用 absolute 骑在列边界内侧（right:0，宽 9px，正好压在单元格 12px 右内边距上），
      比只点 1px 的边框好抓；th 上要设 overflow:hidden（见下），手柄必须在框内，否则会被裁掉。
   ③ 拖拽期间给 body 加 .tx-resizing，整页锁住文本选中和光标，松手即恢复。 */
th.thx{cursor:pointer;user-select:none;-webkit-user-select:none;position:relative;overflow:hidden}
th.thx:hover{background:#e8eefb}
.tbl-page thead th.thx:hover{background:#e8eefb}
th .txrz{position:absolute;top:0;right:0;width:9px;height:100%;cursor:col-resize;z-index:6;touch-action:none}
th .txrz::after{content:"";position:absolute;right:0;top:0;bottom:0;width:1px;background:transparent}
th .txrz:hover::after{background:var(--primary)}
th .txsort{font-size:10px;margin-left:4px;vertical-align:1px;color:var(--primary)}
th .txsort.off{color:#c3cbd8;opacity:0;transition:opacity .12s}
th.thx:hover .txsort.off{opacity:1}
body.tx-resizing{cursor:col-resize}
body.tx-resizing *{user-select:none!important;-webkit-user-select:none!important;cursor:col-resize!important}
/* 拖过列宽的表切成固定布局，宽度才真的由用户说了算（没拖过的表不加这个类，保持原自适应外观） */
table.tx-fixed{table-layout:fixed}

/* 系统配置 / 标签组 / 状态 */
.panel-h{display:flex;align-items:center;justify-content:space-between;margin-bottom:8px}
.item-row{display:flex;align-items:center;gap:8px;margin:8px 0;padding:8px 10px;border:1px solid var(--line);border-radius:8px}
.item-row label{display:flex;align-items:center;gap:8px;cursor:pointer}
.item-row .won{font-weight:600;color:var(--primary-d)}
.g-card{border:1px solid var(--line);border-radius:10px;padding:10px;margin:10px 0}
.tag-pick{display:flex;flex-direction:column;gap:10px}
.tp-group{border:1px dashed var(--line);border-radius:8px;padding:8px 10px}
.tp-gname{font-size:13px;font-weight:600;margin-bottom:6px;display:flex;align-items:center;gap:6px}
/* 勾选项：每一条都单独框起来，避免"左边选项、右边勾选框"分家，也防止点错 */
.tp-tag{display:flex;align-items:center;gap:8px;margin:0;padding:8px 10px;border:1px solid var(--line);border-radius:8px;background:#fff;font-size:13px;cursor:pointer;transition:border-color .12s,background .12s}
.tp-tag:hover{border-color:var(--primary);background:#f8fbff}
.tp-tag.on{border-color:var(--primary);background:#eef4ff}
.tp-tag input{width:auto;flex:none;margin:0;padding:0}
/* 单选式选择框（重复客户合并等）同样每条一个框 */
.pick-box{display:flex;align-items:flex-start;gap:8px;margin:6px 0;padding:8px 10px;border:1px solid var(--line);border-radius:8px;background:#fff;cursor:pointer}
.pick-box:hover{border-color:var(--primary);background:#f8fbff}
.pick-box.on{border-color:var(--primary);background:#eef4ff}
.pick-box input{width:auto;flex:none;margin-top:2px}

/* 多选下拉框（外观与普通 select 一致，可多选） */
.ms{position:relative}
.ms-ctl{display:flex;align-items:center;justify-content:space-between;gap:8px;min-height:36px;padding:8px 10px;border:1px solid var(--line);border-radius:8px;background:#fff;cursor:pointer}
.ms-ctl:hover{border-color:#c7d2e5}
.ms.open .ms-ctl{border-color:var(--primary)}
.ms-text{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ms-text.ph{color:#9aa4b2}
.ms-caret{color:var(--muted);font-size:11px;transition:transform .15s}
.ms.open .ms-caret{transform:rotate(180deg)}
.ms-pop{position:absolute;left:0;right:0;top:calc(100% + 4px);z-index:20;background:#fff;border:1px solid var(--line);border-radius:8px;box-shadow:0 10px 26px rgba(15,23,42,.14);max-height:210px;overflow:auto;padding:5px}
.ms-op{display:flex;align-items:center;gap:8px;margin:0;padding:7px 8px;border-radius:6px;font-size:13px;font-weight:400;color:var(--text);cursor:pointer}
.ms-op:hover{background:#f1f5f9}
.ms-op.on{background:#eef4ff}
.ms-op input[type=checkbox]{width:auto;flex:none;padding:0;margin:0;accent-color:var(--primary)}
.ms-op.dis{opacity:.5;cursor:not-allowed;background:#fafbfc}
.ms-own{font-style:normal;font-size:11px;color:var(--muted)}
.ms-empty{padding:8px;color:var(--muted);font-size:12px;text-align:center}

/* 批量导入前的「客户归属核对」面板（2026-09-22） */
.imp-list{max-height:40vh;overflow:auto;border:1px solid var(--line);border-radius:10px;padding:2px 10px;background:#fbfcfe}
.imp-details .imp-list{max-height:34vh;border:0;background:transparent;padding:0}
.imp-item{padding:9px 2px;border-bottom:1px dashed var(--line)}
.imp-item:last-child{border-bottom:0}
.imp-item.done{background:#f3fbf5}
.imp-title{font-size:13px;line-height:1.7;display:flex;align-items:baseline;flex-wrap:wrap;gap:0 4px}
.imp-tag{display:inline-block;font-size:11px;line-height:16px;padding:0 6px;border-radius:9px;margin-right:2px;white-space:nowrap}
.imp-tag.warn{background:#fef3c7;color:#92400e;border:1px solid #fde68a}
.imp-tag.ok{background:#dcfce7;color:#166534;border:1px solid #bbf7d0}
.imp-opt{display:flex;align-items:flex-start;gap:6px;font-size:13px;padding:4px 6px;border-radius:6px;cursor:pointer;line-height:1.7}
.imp-opt:hover{background:#eef2ff}
.imp-opt.on{background:#e8f0fe}
.imp-opt input[type=radio]{margin-top:5px}
.imp-sim{color:var(--muted);font-size:12px;margin-left:4px}
.imp-own{font-size:12px;color:var(--muted);padding:3px 0 0 24px}
.imp-clashbox{margin:5px 0 2px 24px;padding:6px 9px;font-size:12px;line-height:1.75;background:#fef2f2;border:1px solid #fecaca;border-left:3px solid #dc2626;border-radius:6px;color:#991b1b}
.imp-dupbox{margin:5px 0 2px 24px;padding:5px 9px;font-size:12px;line-height:1.75;background:#fffbeb;border:1px solid #fde68a;border-left:3px solid #f59e0b;border-radius:6px;color:#92400e}
.imp-dup{font-size:11px;color:#92400e;background:#fef3c7;border:1px solid #fde68a;border-radius:9px;padding:0 6px;margin-left:4px;white-space:nowrap}
.imp-hitown{color:#166534;font-weight:500}
.imp-search-wrap{position:relative;margin:2px 0 6px 24px}
.imp-search-wrap.hidden{display:none}
.imp-hit{position:absolute;left:0;right:0;top:calc(100% + 4px);z-index:30;background:#fff;border:1px solid var(--line);border-radius:8px;box-shadow:0 10px 26px rgba(15,23,42,.14);max-height:200px;overflow:auto;padding:4px}
.imp-sec{margin-bottom:12px}
.imp-sec-h{font-size:13px;font-weight:600;margin:8px 0 6px}
.imp-details{margin:8px 0 12px;border:1px solid var(--line);border-radius:10px;padding:6px 10px;background:#fbfcfe}
.imp-details summary{cursor:pointer;font-size:13px;color:var(--primary);padding:2px 0}
.imp-warn{color:var(--warn)}
.imp-weak{font-size:12px;color:var(--muted);padding:0 0 4px 24px;display:flex;flex-wrap:wrap;gap:6px;align-items:center}
.imp-quick{background:#fff;border:1px solid var(--line);border-radius:6px;padding:2px 8px;font-size:12px;color:var(--primary)}
.imp-quick:hover{background:#eef2ff}
.imp-quick.on{background:#e8f0fe;border-color:var(--primary)}

/* 客户列表「更新内容」列（2026-10-10）：一行显示最近一次变更的摘要，点一下看该客户变更历史。
   限宽 + 省略号，避免长摘要把表格撑宽。 */
/* 「更新内容」列：外面这层负责裁切。
   必须有一个「宽度确定 + overflow:hidden」的块级容器 —— 表格切成固定布局（用户拖过列宽）时
   单元格宽度是写死的，里面 nowrap 的长文本会照自己的宽度渲染，直接盖到右边的「来源」列上。
   2026-10-10 修：小屏/拖过列宽后这一列与「来源」列重合就是这个原因。 */
.hist-clip{overflow:hidden;max-width:210px}
.hist-link{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;cursor:pointer;color:var(--primary);text-decoration:underline dashed rgba(37,99,235,.45);text-underline-offset:3px}
.hist-link:hover{text-decoration-style:solid}
/* 单元格裁切（通用兜底，2026-10-10）：表格切成固定布局后单元格宽度写死，
   里面的 nowrap 内容（状态胶囊、金额）会照自己的宽度渲染、盖到右边那一列上。
   给内容套一层「宽度确定 + overflow:hidden」的块级容器就不会越界了。
   订单列表的「合同」「开票」两列用它（曾盖住「已收款」列）。 */
.cell-clip{overflow:hidden}
.cell-clip>*{max-width:100%}
/* 客户查重页（2026-10-10） */
.dd-group{margin-bottom:14px}
.dd-group h3{display:inline-flex;align-items:center;gap:6px}
.dd-group table{font-size:13px}
.dd-group th,.dd-group td{white-space:nowrap;padding:5px 10px}
.dd-group tbody tr:hover{background:#f8fbff}
.dd-group .badge+.badge{margin-left:2px}
#ddConf{width:auto;min-width:130px;padding:6px 10px;font-size:13px}
.badge.ok{display:inline-block;background:#e6ffed;color:#237804;border:1px solid #a7e2b8;border-radius:6px;padding:1px 7px;font-size:12px;font-weight:600;margin-left:4px}
/* 跟进提醒用的三档状态标签（2026-10-14）：逾期=红、今天到期=橙（.warn）、7 天内=蓝、更远=灰 */
.badge.danger{display:inline-block;background:#fee2e2;color:#b91c1c;border:1px solid #fca5a5;border-radius:6px;padding:1px 7px;font-size:12px;font-weight:600;white-space:nowrap}
.badge.soon{display:inline-block;background:#dbeafe;color:#1d4ed8;border:1px solid #bfdbfe;border-radius:6px;padding:1px 7px;font-size:12px;font-weight:600;white-space:nowrap}
.badge.mut{display:inline-block;background:#f1f5f9;color:#64748b;border:1px solid #e2e8f0;border-radius:6px;padding:1px 7px;font-size:12px;font-weight:600;white-space:nowrap}
#view-activity table,#view-dedupe table{font-size:13px}
#view-activity th,#view-activity td{padding:6px 10px}
/* 员工动态：表格里的数字也是下钻入口，做成一眼能看出可点 */
#view-activity .act-link{color:var(--primary);cursor:pointer;font-weight:600;text-decoration:none;border-bottom:1px dashed rgba(37,99,235,.45);padding-bottom:1px}
#view-activity .act-link:hover{border-bottom-style:solid}
/* 员工动态「操作明细」：每一条都是一个入口（2026-10-15）。原来只是一行行文字，看不出能点。 */
.act-hit{cursor:pointer;position:relative;transition:border-color .12s,box-shadow .12s,background .12s}
.act-hit:hover{border-color:var(--primary);background:#f8fbff;box-shadow:0 4px 12px rgba(37,99,235,.10)}
.act-hit:focus{outline:none;border-color:var(--primary);box-shadow:0 0 0 3px rgba(37,99,235,.18)}
.act-hit.flat{cursor:default}
.act-hit.flat:hover{border-color:var(--line);background:transparent;box-shadow:none}
.act-hit .go{flex:none;font-size:12px;color:#9aa4b2;white-space:nowrap}
.act-hit:hover .go{color:var(--primary)}
.act-hit .act-cust{font-weight:600;text-decoration:none}
.act-hit .act-ref{display:inline-block;background:#eef2f7;color:#5b6b7c;border-radius:5px;padding:0 5px;font-size:11px}
#view-dedupe .dd-pick,#view-dedupe .dd-keep{cursor:pointer;width:15px;height:15px;margin:0;vertical-align:middle}
#view-dedupe .dd-group .panel-h{flex-wrap:wrap;gap:6px}
#view-dedupe .btn[disabled]{opacity:.45;cursor:not-allowed}

/* ===== 第一期：合同 / 开票 / 站内通知（2026-10-10）===== */
/* 侧边栏铃铛 + 未读红点 */
/* 铃铛：2026-10-19 侧边栏 logo 换成 flex 布局后，铃铛由绝对定位改为靠右的 flex 项。
   position:relative 必须留着 —— .bell-dot 是按它定位的，改成 static 红点会跑到侧边栏角上。 */
.logo{position:relative}
.bell{position:relative;margin-left:auto;flex:none;background:none;border:none;font-size:18px;line-height:1;cursor:pointer;padding:4px 6px;border-radius:8px}
.bell:hover{background:#1e3a5f}
.bell-dot{position:absolute;top:0;right:0;min-width:16px;height:16px;line-height:16px;text-align:center;background:#ef4444;color:#fff;border-radius:9px;font-size:10px;font-weight:700;padding:0 4px}
/* 消息列表 */
.ntf-list{border:1px solid var(--line);border-radius:10px;overflow:auto;max-height:58vh}
.ntf{padding:10px 12px;border-bottom:1px solid #f1f5f9;cursor:pointer}
.ntf:last-child{border-bottom:none}
.ntf:hover{background:#f8fbff}
.ntf.unread{background:#eff6ff}
.ntf.unread:hover{background:#e0efff}
.ntf-h{display:flex;justify-content:space-between;gap:10px;align-items:baseline;font-size:13px}
.ntf-b{color:#64748b;font-size:12px;margin-top:3px;line-height:1.5}
/* 合同状态 */
.pill.ct-unsigned{background:#f1f5f9;color:#475569}
.pill.ct-sent{background:#fef3c7;color:#b45309}
.pill.ct-returned{background:#dcfce7;color:#15803d}
.pill.ct-archived{background:#e2e8f0;color:#334155}
/* 开票状态 */
.pill.inv-pending{background:#fef3c7;color:#b45309}
.pill.inv-issued{background:#dcfce7;color:#15803d}
.pill.inv-rejected{background:#fee2e2;color:#b91c1c}
.pill.inv-withdrawn{background:#f1f5f9;color:#64748b}
/* 开票弹窗顶部进度条 */
.inv-progress{display:flex;flex-wrap:wrap;gap:16px;align-items:center;background:#f8fafc;border:1px solid var(--line);border-radius:10px;padding:10px 12px;font-size:13px}
/* 订单设为「不需开票」时，行尾的「开票」入口是灰字（点了会说明原因，不是直接藏掉） */
.no-inv{color:#9aa4b2;cursor:not-allowed}
.no-inv:hover{text-decoration:underline dotted}
/* 「不需开票」的订单在开票弹窗里只显示一条说明 */
.inv-off{background:#f8fafc;border:1px dashed var(--line);border-radius:10px;padding:12px 14px;font-size:13px;line-height:1.7}
#view-approvals table{font-size:13px}
#view-approvals th,#view-approvals td{padding:6px 10px}
/* 请假状态（第二期）：待审批 / 已通过 / 已完成 / 已驳回 / 已撤回 */
.pill.lv-pending{background:#fef3c7;color:#b45309}
.pill.lv-approved{background:#dbeafe;color:#1d4ed8}
.pill.lv-done{background:#dcfce7;color:#15803d}
.pill.lv-rejected{background:#fee2e2;color:#b91c1c}
.pill.lv-withdrawn{background:#f1f5f9;color:#64748b}
/* 报销状态（第三期）：待审批 / 待打款 / 已打款 / 已驳回 / 已撤回 */
.pill.ex-pending{background:#fef3c7;color:#b45309}
.pill.ex-approved{background:#ede9fe;color:#6d28d9}
.pill.ex-paid{background:#dcfce7;color:#15803d}
.pill.ex-rejected{background:#fee2e2;color:#b91c1c}
.pill.ex-withdrawn{background:#f1f5f9;color:#64748b}
/* 报销明细表：行内输入框撑满单元格，看起来很整齐 */
#ex_tbl th,#ex_tbl td{padding:4px 6px}
#ex_tbl input,#ex_tbl select{width:100%;padding:5px 7px;font-size:13px}
#ex_tbl .ei_del{cursor:pointer}
/* 年假额度表里的输入框 */
.lq_in{padding:4px 6px;font-size:13px}

/* ==========================================================================
   移动端适配（2026-10-12）—— 手机 / 小平板（≤820px）
   --------------------------------------------------------------------------
   桌面端一行不受影响：所有规则都收在下面这个 @media 块里。
   手机上有两件根本改动：
   ① 关掉「整站等比缩放」。app.js 的 applyUiScale 按 innerWidth/1600 缩放，
      390px 屏会被压到 0.6 的下限 —— 等于把 1600px 的桌面布局缩到 0.6 倍，
      正文字号只剩 8.4px，完全没法看。手机上一律按真实 CSS 像素渲染。
   ② 换一套布局范式：200px 侧边栏 → 顶栏 + 底部标签栏；
      多列表格 → 卡片（列名由 app.js 的 mLabelTable() 注入到 td[data-l]）；
      居中弹窗 → 全屏页；两列表单 → 单列。
   ========================================================================== */
.mtop,.mtab,.msheet{display:none}

@media (max-width:820px){
html,body{overflow-x:hidden}

/* ---------- 骨架：顶栏 + 内容 + 底部标签栏 ---------- */
.app{flex-direction:column;height:100vh;height:100dvh}
.sidebar{display:none}
.content{padding:10px 12px 14px}

.mtop{display:flex;align-items:center;gap:6px;flex:none;background:#0f2540;color:#fff;
  padding:9px 12px;padding-top:calc(9px + env(safe-area-inset-top,0px))}
.mtop .mtb{flex:1;min-width:0;font-size:15px;font-weight:700;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* 手机顶栏马头（2026-10-19）：用 inline 而不是 flex，否则 .mtb 的省略号失效 */
.mtop .mtb-mark{width:24px;height:24px;vertical-align:-6px;margin-right:6px}
.mtop .mtb i{font-style:normal;font-size:11px;font-weight:600;color:#7dd3fc;margin-left:5px}
.mtop button{background:none;border:none;color:#fff;font-size:17px;line-height:1;padding:7px 9px;border-radius:8px;position:relative}
.mtop button:active{background:#1e3a5f}
.mtop .mtu{max-width:92px;font-size:12px;color:#cbd5e1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

.mtab{display:flex;flex:none;background:#fff;border-top:1px solid var(--line);position:relative;z-index:20;
  padding-bottom:env(safe-area-inset-bottom,0px)}
.mtab a{flex:1 1 0;min-width:0;position:relative;text-align:center;text-decoration:none;
  color:#94a3b8;font-size:11px;padding:6px 2px 5px}
.mtab a .mi{display:block;font-size:19px;line-height:1.3}
.mtab a.active{color:var(--primary);font-weight:600}
.mbdg{position:absolute;top:2px;left:50%;margin-left:5px;min-width:15px;height:15px;line-height:15px;
  padding:0 4px;background:#ef4444;color:#fff;border-radius:8px;font-size:10px;font-weight:700}

/* ---------- 「更多」底部面板 ---------- */
/* ⚠️ display:block 不能省：文件顶部有全局的 `.mtop,.mtab,.msheet{display:none}`
   （那是给桌面端用的隐藏），这里必须显式覆盖回来，否则手机上抽屉永远不显示。
   `.msheet.hidden` 的 (0,2,0) 优先级更高，关闭逻辑不受影响。 */
.msheet{display:block;position:fixed;left:0;top:0;right:0;bottom:0;z-index:60}
.msheet.hidden{display:none}
.msheet-mask{position:absolute;inset:0;background:rgba(15,23,42,.45)}
.msheet-box{position:absolute;left:0;right:0;bottom:0;background:#fff;border-radius:16px 16px 0 0;
  padding:14px 14px calc(14px + env(safe-area-inset-bottom,0px));max-height:84%;overflow:auto}
.msheet-t{display:flex;align-items:center;font-size:13px;color:var(--muted);margin-bottom:10px}
.msheet-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:8px}
.msheet-grid a{display:flex;flex-direction:column;align-items:center;gap:5px;padding:12px 4px;
  border:1px solid var(--line);border-radius:12px;text-decoration:none;color:var(--text);font-size:12px;text-align:center}
.msheet-grid a .mi{font-size:21px;line-height:1}
.msheet-grid a.active{border-color:var(--primary);background:#eef4ff;color:var(--primary-d)}
.msheet-foot{display:flex;gap:10px;margin-top:12px}
.msheet-foot button{flex:1;min-height:44px;border-radius:10px}

/* ---------- 视图与卡片 ---------- */
.view h2{font-size:17px;margin-bottom:10px}
.cards{grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;margin-bottom:14px}
.kpi{padding:12px}
.kpi .num{font-size:21px}
.kpi .lbl{font-size:12px;line-height:1.45}
.panel{padding:12px;border-radius:12px;margin-bottom:12px}

/* 列表页取消「表格内部滚动」：整页滚动，表头不再吸顶（卡片用不到） */
.view.fill{display:block}
.view.fill>*{flex:none}
.view.fill>.panel{display:block;flex:none;overflow:visible;margin-bottom:0}
/* 注意作用域只到 .content（页面级列表）：弹窗里的表（请假统计 22 列、单团成本等）**必须保留**
   overflow:auto + min-width:max-content 的横向滚动，否则 22 列会被压进 362px，中文逐字竖排。
   2026-10-12 把这条写成全局 .tbl-scroll 时踩过。 */
.content .tbl-page,.content .view.fill .tbl-page{max-height:none;min-height:0;overflow:visible}
.content .tbl-scroll{overflow:visible}
.content .tbl-scroll table{min-width:0}
.content .tbl-page thead th{position:static}
.content .tbl-page th:last-child,.content .tbl-page td:last-child:not(.empty){position:static;box-shadow:none}
/* 桌面上拖过列宽的表会切成固定布局（colgroup 定宽）；手机上改卡片，宽度存档不参与 */
table.tx-fixed{table-layout:auto!important}
table.tx-fixed>colgroup{display:none}

/* ---------- 表格 → 卡片 ---------- */
table.mcard{display:block;background:transparent}
table.mcard thead{display:none}
table.mcard tbody,table.mcard tr,table.mcard td{display:block;width:auto}
table.mcard tbody tr{position:relative;background:var(--card);border:1px solid var(--line);
  border-radius:12px;padding:10px 12px;margin-bottom:10px}
table.mcard tbody tr:hover{background:var(--card)}
table.mcard td{border:0;padding:3px 0;font-size:14px;line-height:1.55;
  display:flex;gap:10px;align-items:flex-start;word-break:break-word}
table.mcard td[data-l]::before{content:attr(data-l);flex:0 0 74px;color:var(--muted);font-size:13px}
table.mcard td[data-l]>*{min-width:0}
table.mcard td.mtitle{padding:0 0 6px;font-size:15.5px;font-weight:600}
table.mcard td.mtitle::before{display:none}
table.mcard td.mpick{position:absolute;top:13px;right:12px;padding:0;width:auto}
table.mcard td.mpick input{width:18px;height:18px;margin:0}
table.mcard td.mact{flex-wrap:wrap;justify-content:flex-end;gap:6px 16px;margin-top:7px;padding-top:8px;
  border-top:1px dashed var(--line);font-size:14px}
table.mcard td.mact::before{display:none}
table.mcard td.mact .link,table.mcard td.mact .act{margin:0;font-size:14px}
table.mcard td.empty{display:block;padding:26px 6px;text-align:center}
table.mcard td.empty::before{display:none}
table.mcard .pill,table.mcard .tag,table.mcard .badge{white-space:nowrap}
/* 跟进提醒的列名偏长（「上次跟进内容」「下次要谈」），
   卡片左侧标签列按 74px 会把标签自己挤成两行，这一页给宽一点 */
#view-tasks table.mcard td[data-l]::before{flex:0 0 88px}

/* ---------- 弹窗 → 全屏页 ---------- */
.modal-box{width:100%;max-width:none;height:100%;max-height:100%;border-radius:0;
  padding:14px;padding-top:calc(14px + env(safe-area-inset-top,0px));-webkit-overflow-scrolling:touch}
#modalBox h3{cursor:default}
#modalBox h3::after{content:""}
#modalBox .modal-actions{position:sticky;bottom:0;z-index:5;display:flex;flex-wrap:wrap;gap:10px;
  margin-top:18px;padding:10px 0 calc(10px + env(safe-area-inset-bottom,0px));
  background:var(--card);box-shadow:0 -1px 0 var(--line)}
/* 必须允许换行 + 不给按钮"无限缩"：客户详情一排有 6 个按钮（退回公海/移交/分配/编辑资料/确认删除/关闭），
   不分行的话每个只剩 55px 宽，中文会被逐字竖排（2026-10-12 踩到）。
   nowrap 保证文字不拆行，min-width 保证一行最多放 3 个。 */
#modalBox .modal-actions .btn{flex:1 1 auto;min-width:104px;white-space:nowrap}
.form-grid{grid-template-columns:1fr;gap:10px}
.field label{font-size:13px}

/* ---------- 触控与可读性 ---------- */
input,select,textarea{font-size:16px;padding:10px 11px}   /* 16px 是 iOS 的临界值，低于它聚焦时会自动放大整页 */
.btn{padding:10px 14px;font-size:14px;min-height:42px;border-radius:10px}
.btn.sm{min-height:34px}
.seg-btn{padding:9px 12px;font-size:13px}
.link,.act{font-size:14px}
*{-webkit-tap-highlight-color:transparent}
.toolbar{gap:8px;margin-bottom:10px}
.list-pager{font-size:12px;gap:6px}
.tabs{display:block;overflow-x:auto;white-space:nowrap}
.tabs button{padding:10px 12px}
.login-card{width:100%;max-width:340px;padding:30px 22px;border-radius:14px}
/* 手机上卡片变宽了，logo 跟着放大一档；320px 窄屏靠 max-width:100% 自动缩 */
.brand-logo{width:240px}
.login-wrap{height:100vh;height:100dvh}
/* 手机上不让标题条吞掉滚动：拖动已由 app.js 关掉（canDragFrom 里判 isMobile），
   但 touch-action:none 还留着会挡住手指在标题上的下滑 */
#modalBox h3{touch-action:auto}
/* 弹窗内「表格里嵌输入框」的地方（报销明细 / 年假额度）在手机上要给够触摸高度 */
#ex_tbl input,#ex_tbl select,.lq_in{padding:8px;font-size:15px;min-height:38px}
/* 小屏上「更新内容」列不再需要限宽（卡片里本来就换行） */
.hist-clip{max-width:none}

/* ---------- 客户 / 公海 / 需求 / 订单：筛选区占地太大，把列表挤到两屏以外 ---------- */
/* ① 搜索框独占一行并提到最前（手机上「搜一条记录」是第一动作） */
#fQ,#dmQ,#oQ{order:-1;flex:1 1 100%!important;max-width:none!important}
/* ①' 日期范围控件：下拉独占一行，「开始 至 结束」在第二行平分宽度。
   手机上原生日期框有个最小宽度，写死 146px 会溢出，所以这里改成弹性宽度。 */
.dr-box{flex:1 1 100%;flex-wrap:wrap;justify-content:space-between;gap:6px}
.dr-box select{flex:1 1 100%;width:auto!important}
.dr-box input[type=date]{flex:1 1 0;width:auto!important;min-width:0}
/* 手机上表格变卡片，权限列不再限制宽度（否则权限名会被截断） */
.perm-cell{max-width:none}
/* 手机上弹窗本来就是全屏页、「保存」是吸底的，权限清单不必再限高（限了反而只剩一小条不好点） */
.perm-pick{max-height:none;overflow:visible;padding-right:0}
/* ② 下拉框两两一排，不再各自写死宽度 */
#fType,#fSort,#fGroup,#fOwner,#fPool,#fReason,#fRelBy,
#dmStatus,#dmSort,#dmOwner,#oStatus,#oSort,#oOwner{flex:1 1 calc(50% - 5px);width:auto!important;min-width:0}
/* ③ 统计卡片改成一条横向滚动带：原来换行成 3~4 排要吃掉近一屏 */
#custStats{flex-wrap:nowrap!important;gap:10px!important;margin:8px 0 0!important;align-items:flex-start!important;
  overflow-x:auto;padding-bottom:6px;-webkit-overflow-scrolling:touch}
#custStats>*{flex:none!important}
#custStats .stat-card{padding:8px 12px!important;min-width:66px!important}
#custStats .stat-card>div:first-child{font-size:18px!important}
#custStats>div>div:first-child{font-size:11px!important}
#custStats>div>div:last-child{flex-wrap:nowrap!important;gap:6px!important}

/* ---------- 备份状态提示条：桌面上是一行小字，手机上那段路径会占掉半屏 ---------- */
#bkAlert{font-size:12px!important;padding:8px 10px!important;line-height:1.5}
#bkAlert *{font-size:12px!important;line-height:1.5}
#bkAlert div{word-break:break-all}

/* ---------- 「我的申请 / 审批中心」等页面的工具条：按钮允许换行、不撑破 ---------- */
.view>.toolbar,.view.fill>.toolbar{flex-wrap:wrap}
}
