/* ================= 设计令牌基座（全局单一来源，各主题只覆盖色值） ================= */
:root{
  /* 品牌 / 状态色 */
  --primary:#1677ff;--primary-dark:#0958d9;--primary-light:#e8f2ff;
  --accent:#00b8d9;--accent-light:#e6fffb;
  --success:#10b981;--warning:#faad14;--danger:#ef4444;
  /* 表面 / 文字 / 描边 */
  --bg:#f4f6fb;--bg2:#f8fafc;--bg3:#f1f5f9;--card:#fff;--overlay:rgba(255,255,255,.95);
  --text:#0f172a;--text2:#5b6472;--border:#e6e8ee;--border-strong:#d4d9e2;
  --surface:var(--card);--surface-muted:var(--bg2);--surface-sunken:var(--bg3);
  /* 文字语义别名（历史代码大量使用 --text-secondary，此前未定义导致回退为继承色） */
  --text-secondary:var(--text2);--text-muted:var(--text2);--text-tertiary:#94a3b8;
  /* 数据页主题变量（CPA-282 修）：原仅定义在 .dv 上，弹层/iframe 里挂在 body 下拿不到 →
     .dv-btn 背景 var(--t) 落空成透明、白字看不见。补到 :root 作兜底，.dv / .dv.purple 仍按各自取值覆盖。 */
  --t:#1677ff;--t2:#0958d9;--tg1:#f0f9ff;--tg2:#e0f2fe;
  /* 控件聚焦：中性柔光，避免非蓝主题下出现蓝色光晕 */
  --ring:0 0 0 3px rgba(15,23,42,.10);
  /* 圆角刻度：随主题 --radius 等比派生，主题改半径即整体联动 */
  --radius:12px;--radius-sm:calc(var(--radius) * .7);--radius-lg:calc(var(--radius) * 1.3);--radius-pill:999px;
  --btn-radius:8px;
  /* 阴影刻度 */
  --shadow:0 1px 2px rgba(15,23,42,.04),0 2px 8px rgba(15,23,42,.06);
  --shadow-sm:0 1px 2px rgba(15,23,42,.06);
  --shadow-pop:0 12px 32px rgba(15,23,42,.16);
  /* 间距刻度 */
  --sp-1:4px;--sp-2:8px;--sp-3:12px;--sp-4:16px;--sp-5:20px;--sp-6:24px;
  /* 字号 / 行高刻度 */
  --fs-caption:12px;--lh-caption:18px;--fs-body:14px;--lh-body:20px;
  --fs-title:16px;--lh-title:24px;--fs-h1:20px;--lh-h1:28px;
  --font-family:-apple-system,BlinkMacSystemFont,"SF Pro Text","Segoe UI","Helvetica Neue",Inter,Arial,"PingFang SC","Hiragino Sans GB","Microsoft YaHei",sans-serif;
  --card-border:1px solid var(--border);
  /* CPA-274 需求⑤⑥（老板 2026-10-08）：「我的」页头像卡片原本取 --primary→--primary-dark 的
     高饱和渐变（纯蓝/纯红…太重、太扎眼），且深色模式下不变色。改用「主题淡色」派生：
     --primary-light 在每个主题域（含 [data-theme="dark"]）各自取值、--card 亦随主题切换，
     故一条公式即同时满足「随各主题色」与「深色模式自动适配」，不再是刺眼纯色块。 */
  --my-card-bg:linear-gradient(135deg,var(--primary-light),var(--card));
}

@keyframes float{0%,100%{transform:translateY(0)}50%{transform:translateY(-20px)}}
@keyframes spin{to{transform:rotate(360deg)}}

/* 暗黑主题 */
[data-theme="dark"]{--primary:#4096ff;--primary-dark:#1677ff;--primary-light:#111a2c;--accent:#22d3ee;--accent-light:#0f2a33;--success:#34d399;--warning:#fbbf24;--danger:#f87171;--bg:#0f172a;--card:#1e293b;--text:#e2e8f0;--text2:#94a3b8;--border:#334155;--border-strong:#475569;--bg2:#0f172a;--bg3:#16233b;--text-tertiary:#64748b;--ring:0 0 0 3px rgba(255,255,255,.16);--shadow:0 1px 2px rgba(0,0,0,.3),0 4px 14px rgba(0,0,0,.28);--overlay:rgba(15,23,42,.94)}
[data-theme="dark"] .login-card{background:#1e293b;border:1px solid #334155;box-shadow:var(--shadow-pop)}
[data-theme="dark"] .topbar{background:#1e293b;border-bottom:1px solid #334155}
[data-theme="dark"] .stat-card{background:#1e293b;border:1px solid #334155}
[data-theme="dark"] .card{background:#1e293b;border:1px solid #334155}
[data-theme="dark"] .card-header{border-bottom:1px solid #334155}
[data-theme="dark"] table th{background:#0f172a;color:#e2e8f0}
[data-theme="dark"] table td{border-bottom:1px solid #334155;color:#e2e8f0}
[data-theme="dark"] table tr:hover{background:#0f172a}
[data-theme="dark"] input,[data-theme="dark"] select,[data-theme="dark"] textarea{background:#0f172a;color:#e2e8f0;border:1px solid #334155}
[data-theme="dark"] .btn-default{background:#334155;color:#e2e8f0;border:1px solid #475569}
[data-theme="dark"] .btn-default:hover{background:#475569}
[data-theme="dark"] .modal-content{background:#1e293b;border:1px solid #334155}
[data-theme="dark"] .modal-header{border-bottom:1px solid #334155}
/* 暗黑模式通用覆盖：所有写死白色背景的元素 */
[data-theme="dark"] .modal{background:#1e293b!important;color:#e2e8f0!important}
[data-theme="dark"] .pagination button{background:#334155!important;color:#e2e8f0!important;border:1px solid #475569!important}
[data-theme="dark"] .footer{background:#1e293b!important;border-top:1px solid #334155!important}
[data-theme="dark"] .mobile-footer{background:#1e293b!important;border-top:1px solid #334155!important}
[data-theme="dark"] .mobile-nav{background:#1e293b!important;border-bottom:1px solid #334155!important}
[data-theme="dark"] .mobile-stat-card{background:#1e293b!important;border:1px solid #334155!important;box-shadow:0 2px 8px rgba(0,0,0,.3)!important}
[data-theme="dark"] .mobile-task-card{background:#1e293b!important;border:1px solid #334155!important;box-shadow:0 2px 8px rgba(0,0,0,.3)!important}
[data-theme="dark"] .mobile-nav-item{background:#1e293b!important;box-shadow:0 2px 8px rgba(0,0,0,.3)!important}
[data-theme="dark"] .mobile-tabs{background:#1e293b!important;border-bottom:1px solid #334155!important}
[data-theme="dark"] .mobile-card{background:#1e293b!important;box-shadow:0 2px 8px rgba(0,0,0,.3)!important}
[data-theme="dark"] .mobile-filter-bar{background:#1e293b!important}
[data-theme="dark"] .mobile-batch-bar{background:#1e293b!important;border-bottom:1px solid #334155!important}
[data-theme="dark"] .mobile-batch-bar button{background:#334155!important;color:#e2e8f0!important;border:1px solid #475569!important}
[data-theme="dark"] .mobile-pagination button{background:#334155!important;color:#e2e8f0!important;border:1px solid #475569!important}
[data-theme="dark"] .badge-active{background:#14532d!important;color:#4ade80!important;border:1px solid #16a34a40}
[data-theme="dark"] .badge-pending{background:#1e3a5f!important;color:#69b1ff!important;border:1px solid #2563eb40}
[data-theme="dark"] .badge-suspend{background:#450a0a!important;color:#f87171!important;border:1px solid #dc262640}
[data-theme="dark"] .badge-pause{background:#431407!important;color:#fb923c!important;border:1px solid #ea580c40}
[data-theme="dark"] .badge-done{background:#334155!important;color:#94a3b8!important;border:1px solid #47556940}
[data-theme="dark"] .badge-offline{background:#1e293b!important;color:#64748b!important;border:1px solid #33415540}
[data-theme="dark"] .tag{background:#334155!important;color:#cbd5e1!important;border:1px solid #475569!important}
[data-theme="dark"] .search-bar{background:#1e293b!important}
[data-theme="dark"] .tabs{background:#1e293b!important}
[data-theme="dark"] .tab{background:#1e293b!important;color:#94a3b8!important}
[data-theme="dark"] .tab.active{background:#0f172a!important;color:#4096ff!important}
[data-theme="dark"] .empty{background:#1e293b!important;color:#94a3b8!important}
[data-theme="dark"] .toast{background:#1e293b!important;color:#e2e8f0!important;border:1px solid #334155!important}
[data-theme="dark"] .logout{color:#94a3b8!important}
[data-theme="dark"] .logout:hover{color:#e2e8f0!important}
[data-theme="dark"] .link{color:#4096ff!important}
[data-theme="dark"] .progress-cell span{color:#64748b!important}
[data-theme="dark"] .info{color:#94a3b8!important}
[data-theme="dark"] .label{color:#94a3b8!important}
[data-theme="dark"] .value{color:#e2e8f0!important}
[data-theme="dark"] .title{color:#e2e8f0!important}
[data-theme="dark"] .subtitle{color:#94a3b8!important}
[data-theme="dark"] .version{color:#64748b!important}
[data-theme="dark"] .icon{background:#334155!important}
[data-theme="dark"] .stat-cards{background:transparent!important}
[data-theme="dark"] .card-body{background:transparent!important}
[data-theme="dark"] .table-wrap{background:transparent!important}
[data-theme="dark"] .batch-bar{background:#1e293b!important;border-bottom:1px solid #334155!important}
[data-theme="dark"] .batch-bar button{background:#334155!important;color:#e2e8f0!important;border:1px solid #475569!important}
[data-theme="dark"] .filter-bar{background:#1e293b!important}
[data-theme="dark"] .pagination{background:transparent!important}
[data-theme="dark"] .pagination .info{color:#94a3b8!important}
[data-theme="dark"] .nav-item{color:#94a3b8!important}
[data-theme="dark"] .nav-item.active{color:#4096ff!important}
[data-theme="dark"] .nav-item:hover{color:#e2e8f0!important}
[data-theme="dark"] .user-info{color:#e2e8f0!important}
[data-theme="dark"] .mobile-section-title{color:#e2e8f0!important}
[data-theme="dark"] .mobile-empty{color:#64748b!important}
[data-theme="dark"] .mobile-page{background:var(--bg)!important}
[data-theme="dark"] .mobile-nav-item .name{color:#e2e8f0!important}
[data-theme="dark"] .mobile-form-item label{color:#e2e8f0!important}
[data-theme="dark"] .mobile-form-item input,[data-theme="dark"] .mobile-form-item select,[data-theme="dark"] .mobile-form-item textarea{background:#0f172a!important;color:#e2e8f0!important;border:1px solid #334155!important}
[data-theme="dark"] .mobile-card{background:#1e293b!important;border:1px solid #334155!important}
[data-theme="dark"] .mobile-btn{background:#1677ff!important;color:#fff!important}
/* 手机端"我的"页面 - 个人设置区域 */
[data-theme="dark"] .mobile-page div[style*="background:#fff"][style*="border-radius:12px"]{background:#1e293b!important;border:1px solid #334155!important}
[data-theme="dark"] .mobile-page div[style*="color:#1e293b"][style*="font-size:14px"]{color:#e2e8f0!important}
[data-theme="dark"] .mobile-page span[style*="color:#1e293b"][style*="flex:1"]{color:#e2e8f0!important}
[data-theme="dark"] .mobile-page div[style*="border-bottom:1px solid #f1f5f9"]{border-bottom:1px solid #334155!important}
/* 排期相关 - 时间选择器和时间段选择器 */
[data-theme="dark"] .schedule-time-picker,[data-theme="dark"] .schedule-week-picker{background:#1e293b!important;border:1px solid #334155!important;color:#e2e8f0!important}
[data-theme="dark"] .schedule-time-picker input,[data-theme="dark"] .schedule-week-picker input{background:#0f172a!important;color:#e2e8f0!important;border:1px solid #334155!important}
[data-theme="dark"] .schedule-time-tag,[data-theme="dark"] .schedule-week-tag{background:#334155!important;color:#e2e8f0!important;border:1px solid #475569!important}
[data-theme="dark"] .schedule-time-tag.active,[data-theme="dark"] .schedule-week-tag.active{background:#1677ff!important;color:#fff!important;border:1px solid #1677ff!important}
/* 排期详情弹窗 - 待上架任务的上架时间突出显示 */
[data-theme="dark"] .modal-content div[style*="background:#f5f3ff"]{background:#1e1b4b!important;border-left:3px solid #8b5cf6!important}
[data-theme="dark"] .modal-content div[style*="background:#f5f3ff"] span{color:#c4b5fd!important}
[data-theme="dark"] .modal-content div[style*="background:#f5f3ff"] b{color:#c4b5fd!important}
/* 排期编辑弹窗 - 完成时间输入框和投放时段 */
[data-theme="dark"] .modal-content input[type="datetime-local"]{background:#0f172a!important;color:#e2e8f0!important;border:1px solid #334155!important}
[data-theme="dark"] .modal-content .form-group label{color:#e2e8f0!important}
[data-theme="dark"] .modal-content .form-actions{background:#1e293b!important;border-top:1px solid #334155!important}
/* 排期详情弹窗 - 投放时段的星期标签 */
[data-theme="dark"] .modal-content div[style*="background:#f0f9ff"]{background:#0f172a!important;border:1px solid #334155!important}
[data-theme="dark"] .modal-content div[style*="background:#f0f9ff"] span{color:#e2e8f0!important}
[data-theme="dark"] .modal-content div[style*="background:#dbeafe"]{background:#1e40af!important;color:#fff!important}
/* 新增任务卡片 - 手机端批量上传卡片（使用更具体的选择器确保生效） */
[data-theme="dark"] .mobile-page div[data-row]{
  background:#1e293b!important;
  border:1px solid #334155!important;
}
[data-theme="dark"] .mobile-page div[data-row] label{
  color:#94a3b8!important;
}
[data-theme="dark"] .mobile-page div[data-row] input{
  background:#0f172a!important;
  color:#e2e8f0!important;
  border:1px solid #334155!important;
}
[data-theme="dark"] .mobile-page div[data-row] .task-number{
  color:#e2e8f0!important;
}
[data-theme="dark"] .mobile-page div[data-row] .validate-cell{
  background:#0f172a!important;
  color:#94a3b8!important;
}
[data-theme="dark"] .mobile-page div[data-row] .fail-backfill-cell{
  background:#450a0a!important;
  border:1px solid #7f1d1d!important;
  color:#fca5a5!important;
}
/* 手机端批量上传页面 - 排期配置卡片 */
[data-theme="dark"] .mobile-page div[style*="background:#fff"][style*="border-radius:10px"][style*="padding:12px"]{
  background:#1e293b!important;
  border:1px solid #334155!important;
}
[data-theme="dark"] .mobile-page div[style*="background:#fff"][style*="border-radius:10px"][style*="padding:12px"] label{
  color:#e2e8f0!important;
}
[data-theme="dark"] .mobile-page div[style*="background:#fff"][style*="border-radius:10px"][style*="padding:12px"] span{
  color:#e2e8f0!important;
}
/* 手机端批量上传页面 - 全选复选框区域 */
[data-theme="dark"] .mobile-page div[style*="background:#f8fafc"][style*="border:1px solid #e2e8f0"]{
  background:#0f172a!important;
  border:1px solid #334155!important;
}
[data-theme="dark"] .mobile-page div[style*="background:#f8fafc"][style*="border:1px solid #e2e8f0"] span{
  color:#e2e8f0!important;
}
/* 手机端批量上传页面 - 进度条 */
[data-theme="dark"] .mobile-page div[style*="background:#eff6ff"][style*="border:1px solid #93c5fd"]{
  background:#1e3a8a!important;
  border:1px solid #3b82f6!important;
}
[data-theme="dark"] .mobile-page div[style*="background:#eff6ff"][style*="border:1px solid #93c5fd"] div{
  color:#bfdbfe!important;
}
/* 底部导航栏 - 深色模式 */
[data-theme="dark"] .mobile-bottom-nav{background:#1e293b!important;border-top:1px solid #334155!important}
[data-theme="dark"] .mobile-bottom-nav-item:active{background:#334155!important}
[data-theme="dark"] .mobile-bottom-nav-item .name{color:#94a3b8!important}
[data-theme="dark"] .mobile-bottom-nav-item.active .name{color:#818cf8!important}
/* CPA-241(h)：暗色模式有一条 `[data-theme="dark"] .icon{background:#334155!important}` 的通用底色，
   会把底部 4 个标签图标的 SVG 底衬成一块「四四方方」的灰色蒙版（老板反馈）。
   这里把导航图标底色显式置透明，只保留图标本身。 */
[data-theme="dark"] .mobile-bottom-nav .icon,
[data-theme="dark"] .mobile-nav .icon{background:transparent!important}
/* 复选框 - 深色模式（使用更具体的选择器确保生效） */
[data-theme="dark"] .mobile-page input[type="checkbox"]{
  appearance:none!important;
  -webkit-appearance:none!important;
  width:18px!important;
  height:18px!important;
  background:#0f172a!important;
  border:2px solid #475569!important;
  border-radius:4px!important;
  cursor:pointer!important;
  position:relative!important;
  vertical-align:middle!important;
}
[data-theme="dark"] .mobile-page input[type="checkbox"]:checked{
  background:#1677ff!important;
  border:2px solid #1677ff!important;
}
[data-theme="dark"] .mobile-page input[type="checkbox"]:checked::after{
  content:''!important;
  position:absolute!important;
  left:5px!important;
  top:1px!important;
  width:5px!important;
  height:10px!important;
  border:solid #fff!important;
  border-width:0 2px 2px 0!important;
  transform:rotate(45deg)!important;
}
[data-theme="dark"] .mobile-page input[type="radio"]{
  appearance:none!important;
  -webkit-appearance:none!important;
  width:18px!important;
  height:18px!important;
  background:#0f172a!important;
  border:2px solid #475569!important;
  border-radius:50%!important;
  cursor:pointer!important;
  position:relative!important;
  vertical-align:middle!important;
}
[data-theme="dark"] .mobile-page input[type="radio"]:checked{
  background:#0f172a!important;
  border:2px solid #1677ff!important;
}
[data-theme="dark"] .mobile-page input[type="radio"]:checked::after{
  content:''!important;
  position:absolute!important;
  left:3px!important;
  top:3px!important;
  width:8px!important;
  height:8px!important;
  background:#1677ff!important;
  border-radius:50%!important;
}
/* PC端复选框和单选框 - 深色模式 */
[data-theme="dark"] .card input[type="checkbox"],
[data-theme="dark"] .modal-content input[type="checkbox"],
[data-theme="dark"] .search-bar input[type="checkbox"]{
  appearance:none!important;
  -webkit-appearance:none!important;
  width:16px!important;
  height:16px!important;
  background:#0f172a!important;
  border:2px solid #475569!important;
  border-radius:3px!important;
  cursor:pointer!important;
  position:relative!important;
  vertical-align:middle!important;
}
[data-theme="dark"] .card input[type="checkbox"]:checked,
[data-theme="dark"] .modal-content input[type="checkbox"]:checked,
[data-theme="dark"] .search-bar input[type="checkbox"]:checked{
  background:#1677ff!important;
  border:2px solid #1677ff!important;
}
[data-theme="dark"] .card input[type="checkbox"]:checked::after,
[data-theme="dark"] .modal-content input[type="checkbox"]:checked::after,
[data-theme="dark"] .search-bar input[type="checkbox"]:checked::after{
  content:''!important;
  position:absolute!important;
  left:4px!important;
  top:0px!important;
  width:4px!important;
  height:9px!important;
  border:solid #fff!important;
  border-width:0 2px 2px 0!important;
  transform:rotate(45deg)!important;
}
/* Logo - 深色模式（使用CSS滤镜调整颜色，使用!important确保生效） */
[data-theme="dark"] .topbar .brand img{
  filter: brightness(1.3) contrast(1.2) !important;
  border: 1px solid rgba(255,255,255,0.2) !important;
}
[data-theme="dark"] .mobile-header .logo img{
  filter: brightness(1.3) contrast(1.2) !important;
  border: 1px solid rgba(255,255,255,0.2) !important;
}
/* PC端深色模式优化 - 通用元素 */
[data-theme="dark"] .app{background:var(--bg)!important}
[data-theme="dark"] .main{background:var(--bg)!important}
[data-theme="dark"] .content{background:var(--bg)!important}
[data-theme="dark"] .page{background:var(--bg)!important}
[data-theme="dark"] .section{background:var(--card)!important;border:1px solid var(--border)!important}
[data-theme="dark"] .panel{background:var(--card)!important;border:1px solid var(--border)!important}
[data-theme="dark"] .box{background:var(--card)!important;border:1px solid var(--border)!important}
[data-theme="dark"] .widget{background:var(--card)!important;border:1px solid var(--border)!important}
/* PC端深色模式优化 - 表格 */
[data-theme="dark"] .table{background:var(--card)!important}
[data-theme="dark"] .table th{background:var(--bg)!important;color:var(--text)!important;border-bottom:1px solid var(--border)!important}
[data-theme="dark"] .table td{background:var(--card)!important;color:var(--text)!important;border-bottom:1px solid var(--border)!important}
[data-theme="dark"] .table tr:hover td{background:var(--bg)!important}
/* PC端深色模式优化 - 表单 */
[data-theme="dark"] .form-group label{color:var(--text)!important}
[data-theme="dark"] .form-control{background:var(--bg)!important;color:var(--text)!important;border:1px solid var(--border)!important}
[data-theme="dark"] .form-control:focus{border-color:var(--primary)!important;box-shadow:0 0 0 2px rgba(22,119,255,.2)!important}
/* PC端深色模式优化 - 按钮 */
[data-theme="dark"] .btn{border:1px solid var(--border)!important}
[data-theme="dark"] .btn-default{background:var(--card)!important;color:var(--text)!important}
[data-theme="dark"] .btn-default:hover{background:var(--bg)!important}
[data-theme="dark"] .btn-primary{background:var(--primary)!important;color:#fff!important;border:1px solid var(--primary)!important}
[data-theme="dark"] .btn-danger{background:#dc2626!important;color:#fff!important;border:1px solid #dc2626!important}
[data-theme="dark"] .btn-success{background:#16a34a!important;color:#fff!important;border:1px solid #16a34a!important}
[data-theme="dark"] .btn-warning{background:#d97706!important;color:#fff!important;border:1px solid #d97706!important}
/* PC端深色模式优化 - 标签和徽章 */
[data-theme="dark"] .badge{background:var(--bg)!important;color:var(--text)!important;border:1px solid var(--border)!important}
[data-theme="dark"] .tag{background:var(--bg)!important;color:var(--text)!important;border:1px solid var(--border)!important}
[data-theme="dark"] .label{background:var(--bg)!important;color:var(--text)!important;border:1px solid var(--border)!important}
/* PC端深色模式优化 - 分页 */
[data-theme="dark"] .pagination{background:var(--card)!important}
[data-theme="dark"] .pagination button{background:var(--card)!important;color:var(--text)!important;border:1px solid var(--border)!important}
[data-theme="dark"] .pagination button:hover{background:var(--bg)!important}
[data-theme="dark"] .pagination button.active{background:var(--primary)!important;color:#fff!important;border:1px solid var(--primary)!important}
/* PC端深色模式优化 - 下拉菜单 */
[data-theme="dark"] .dropdown-menu{background:var(--card)!important;border:1px solid var(--border)!important}
[data-theme="dark"] .dropdown-menu a{color:var(--text)!important}
[data-theme="dark"] .dropdown-menu a:hover{background:var(--bg)!important}
/* PC端深色模式优化 - 提示框 */
[data-theme="dark"] .alert{background:var(--card)!important;border:1px solid var(--border)!important;color:var(--text)!important}
[data-theme="dark"] .alert-info{background:#0c4a6e!important;border:1px solid #0369a1!important;color:#7dd3fc!important}
[data-theme="dark"] .alert-warning{background:#78350f!important;border:1px solid #b45309!important;color:#fcd34d!important}
[data-theme="dark"] .alert-danger{background:#7f1d1d!important;border:1px solid #b91c1c!important;color:#fca5a5!important}
[data-theme="dark"] .alert-success{background:#14532d!important;border:1px solid #15803d!important;color:#86efac!important}
/* PC端深色模式优化 - 进度条 */
[data-theme="dark"] .progress{background:var(--bg)!important}
[data-theme="dark"] .progress-bar{background:var(--primary)!important}
/* PC端深色模式优化 - 选项卡 */
[data-theme="dark"] .tabs{background:var(--card)!important;border-bottom:1px solid var(--border)!important}
[data-theme="dark"] .tab{color:var(--text2)!important}
[data-theme="dark"] .tab:hover{color:var(--primary)!important;background:var(--bg)!important}
[data-theme="dark"] .tab.active{color:var(--primary)!important;border-bottom:2px solid var(--primary)!important}
/* 手机端首页深色模式优化 */
[data-theme="dark"] .mobile-page{background:var(--bg)!important}
[data-theme="dark"] .mobile-header{background:var(--card)!important;border-bottom:1px solid var(--border)!important}
[data-theme="dark"] .mobile-header .title{color:var(--text)!important}
[data-theme="dark"] .mobile-header .sub{color:var(--text2)!important}
[data-theme="dark"] .mobile-section{background:transparent!important}
[data-theme="dark"] .mobile-section-title{color:var(--text)!important}
[data-theme="dark"] .mobile-stats-grid{gap:10px!important}
[data-theme="dark"] .mobile-stat-card{background:var(--card)!important;border:1px solid var(--border)!important;box-shadow:0 2px 8px rgba(0,0,0,.2)!important}
[data-theme="dark"] .mobile-stat-card .value{color:var(--text)!important}
[data-theme="dark"] .mobile-stat-card .label{color:var(--text2)!important}
[data-theme="dark"] .mobile-stat-card .icon{background:var(--bg)!important;color:var(--text)!important}
[data-theme="dark"] .mobile-task-card{background:var(--card)!important;border:1px solid var(--border)!important;box-shadow:0 2px 8px rgba(0,0,0,.2)!important}
[data-theme="dark"] .mobile-task-card .name{color:var(--text)!important}
[data-theme="dark"] .mobile-task-card .meta{color:var(--text2)!important}
[data-theme="dark"] .mobile-task-card .tag{background:var(--bg)!important;color:var(--text2)!important;border:1px solid var(--border)!important}
[data-theme="dark"] .mobile-task-card .pv{color:var(--text2)!important}
[data-theme="dark"] .mobile-progress{background:var(--bg)!important}
[data-theme="dark"] .mobile-progress .fill{background:var(--primary)!important}
[data-theme="dark"] .mobile-empty{color:var(--text2)!important}
[data-theme="dark"] .mobile-nav-grid{gap:10px!important}
[data-theme="dark"] .mobile-nav-item{background:var(--card)!important;border:1px solid var(--border)!important;box-shadow:0 2px 8px rgba(0,0,0,.2)!important}
[data-theme="dark"] .mobile-nav-item .icon{color:var(--text)!important}
[data-theme="dark"] .mobile-nav-item .name{color:var(--text)!important}
/* 手机端2列瀑布流对齐 */
.mobile-stats-grid{
  display:grid!important;
  grid-template-columns:1fr 1fr!important;
  gap:10px!important;
}
.mobile-stats-grid .mobile-stat-card{
  width:100%!important;
  box-sizing:border-box!important;
}
/* 手机端分渠道和分归属人汇总卡片 - 深色模式 */
[data-theme="dark"] .mobile-page .channel-summary-card,
[data-theme="dark"] .mobile-page .owner-summary-card{
  background:#1e293b!important;
  border:1px solid #334155!important;
}
[data-theme="dark"] .mobile-page .channel-summary-card .channel-name,
[data-theme="dark"] .mobile-page .owner-summary-card .owner-name{
  color:#e2e8f0!important;
}
[data-theme="dark"] .mobile-page .channel-summary-card div,
[data-theme="dark"] .mobile-page .owner-summary-card div{
  color:#94a3b8!important;
}
[data-theme="dark"] .mobile-page .channel-summary-card span,
[data-theme="dark"] .mobile-page .owner-summary-card span{
  color:#94a3b8!important;
}
/* 补充：遗漏的白色区域 */
[data-theme="dark"] .card-header{background:var(--card)!important}
[data-theme="dark"] thead th{background:#0f172a!important;color:#e2e8f0!important}
/* 批量上传表格样式 - 现代表格风格 */
.batch-table-wrap{border:1px solid var(--border-strong)!important;border-radius:var(--radius-sm)!important;overflow:hidden!important;margin-bottom:12px!important;box-shadow:var(--shadow-sm)!important}
.batch-table{width:100%;border-collapse:collapse;font-size:13px;background:var(--card)}
.batch-table thead th{background:var(--bg2)!important;color:var(--text)!important;font-weight:600!important;padding:10px 8px!important;text-align:center!important;border-bottom:2px solid var(--border-strong)!important;border-right:1px solid var(--border)!important;font-size:12px!important;white-space:nowrap!important;position:sticky!important;top:0!important;z-index:2!important}
.batch-table thead th:last-child{border-right:none!important}
/* v6.29 任务列表：可排序列头 / 列筛选漏斗 / 已选条件标签条 统一美化 */
#taskPageCard table thead th.sortable{transition:background .15s,color .15s;white-space:nowrap}
#taskPageCard table thead th.sortable:hover{background:var(--bg3)}
#taskPageCard table thead th.sortable.active{color:var(--primary)}
.col-caret{display:inline-flex;flex-direction:column;vertical-align:middle;margin-left:3px;gap:1px;line-height:1}
.col-funnel{display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px;border-radius:5px;margin-left:2px;vertical-align:middle;cursor:pointer;color:var(--text-tertiary);background:transparent;transition:all .15s}
.col-funnel:hover{background:var(--primary-light);color:var(--primary)}
.col-funnel.on{background:var(--primary);color:#fff}
.col-funnel.on:hover{background:var(--primary-dark)}
.ftag{display:inline-flex;align-items:center;gap:5px;background:var(--primary-light);color:var(--primary-dark);border:1px solid var(--primary-light);border-radius:999px;padding:3px 6px 3px 11px;font-size:12px;line-height:1.4}
.ftag.sort{background:#fffbeb;color:#b45309;border-color:#fde68a}
.ftag .x{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;border-radius:50%;cursor:pointer;font-weight:700;background:rgba(37,99,235,.12);transition:background .15s}
.ftag .x:hover{background:rgba(37,99,235,.25)}
.ftag.sort .x{background:rgba(180,83,9,.14)}
.ftag.sort .x:hover{background:rgba(180,83,9,.28)}
.fclear{display:inline-flex;align-items:center;gap:3px;border:1px solid #fca5a5;color:#dc2626;background:var(--card);border-radius:999px;padding:2px 12px;font-size:12px;cursor:pointer;transition:all .15s}
.fclear:hover{background:#fef2f2}
/* CPA-915：已选标签条右侧「刷新」（就地刷新、保留筛选/排序） */
.frefresh{display:inline-flex;align-items:center;gap:3px;border:1px solid var(--primary);color:var(--primary-dark);background:var(--card);border-radius:999px;padding:2px 12px;font-size:12px;cursor:pointer;transition:all .15s}
.frefresh:hover{background:var(--primary-light)}
.frefresh:active{transform:scale(.96)}
.batch-table tbody td{padding:0!important;border-bottom:1px solid var(--border)!important;border-right:1px solid var(--border)!important;background:var(--card)!important;vertical-align:middle!important}
.batch-table tbody td:last-child{border-right:none!important}
.batch-table tbody tr:hover td{background:var(--bg2)!important}
.batch-table tbody tr:nth-child(even) td{background:var(--bg2)!important}
.batch-table tbody tr:nth-child(even):hover td{background:var(--bg3)!important}
.batch-table input[type="text"],.batch-table input:not([type="checkbox"]){width:100%;padding:8px 6px!important;border:none!important;background:transparent!important;font-size:13px!important;color:var(--text)!important;outline:none!important;box-sizing:border-box!important}
.batch-table input[type="text"]:focus,.batch-table input:not([type="checkbox"]):focus{background:var(--primary-light)!important;box-shadow:inset 0 0 0 2px var(--primary)!important}
/* v6.18 类Excel选区：鼠标点击选中、按住左键框选；活动格沿用focus蓝框 */
.batch-table tbody td input.cell-selected{background:var(--primary-light)!important}
.batch-table tbody td input.cell-active{background:var(--card)!important;box-shadow:inset 0 0 0 2px var(--primary)!important}
.batch-table{user-select:none}
.batch-table input[data-col]{user-select:text}
.batch-table .batch-checkbox-cell{width:40px!important;text-align:center!important;padding:8px 4px!important}
.batch-table .batch-select-cell{width:60px!important;text-align:center!important;padding:8px 4px!important}
.batch-table .batch-row-num{width:40px!important;text-align:center!important;color:var(--text-tertiary)!important;font-size:11px!important;font-weight:500!important;background:var(--bg2)!important}
.batch-table .validate-cell{width:80px!important;text-align:center!important;padding:6px 4px!important;font-size:11px!important;font-weight:600!important}
.batch-table .validate-pass{color:#16a34a!important;background:#f0fdf4!important}
.batch-table .validate-fail{color:#dc2626!important;background:#fef2f2!important}
.batch-table .fail-backfill-cell{padding:6px 8px!important;text-align:left!important;font-size:10px!important;line-height:1.4!important;color:#dc2626!important;background:#fef2f2!important;max-width:180px!important;max-height:50px!important;overflow-y:auto!important;word-break:break-all!important;white-space:normal!important;border-left:3px solid #dc2626!important}
/* 暗黑模式下的批量上传表格样式 */
[data-theme="dark"] .batch-table-wrap{border:1px solid #475569!important;box-shadow:0 1px 3px rgba(0,0,0,0.3)!important}
[data-theme="dark"] .batch-table{background:#1e293b!important}
[data-theme="dark"] .batch-table thead th{background:#0f172a!important;color:#e2e8f0!important;border-bottom:2px solid #475569!important;border-right:1px solid #334155!important}
[data-theme="dark"] .batch-table tbody td{border-bottom:1px solid #334155!important;border-right:1px solid #334155!important;background:#1e293b!important}
[data-theme="dark"] .batch-table tbody tr:hover td{background:#334155!important}
[data-theme="dark"] .batch-table tbody tr:nth-child(even) td{background:#1e293b!important}
[data-theme="dark"] .batch-table tbody tr:nth-child(even):hover td{background:#334155!important}
[data-theme="dark"] .batch-table input[type="text"],[data-theme="dark"] .batch-table input:not([type="checkbox"]){color:#e2e8f0!important}
[data-theme="dark"] .batch-table input[type="text"]:focus,[data-theme="dark"] .batch-table input:not([type="checkbox"]):focus{background:#1e3a5f!important;box-shadow:inset 0 0 0 2px #3b82f6!important}
[data-theme="dark"] .batch-table .batch-row-num{background:#0f172a!important;color:#64748b!important}
[data-theme="dark"] .batch-table .validate-pass{color:#4ade80!important;background:#14532d!important}
[data-theme="dark"] .batch-table .validate-fail{color:#f87171!important;background:#450a0a!important}
[data-theme="dark"] .fail-backfill-cell{background:#450a0a!important;color:#fca5a5!important;border-left:3px solid #dc2626!important}
[data-theme="dark"] .batch-select-here{background:#334155!important;color:#94a3b8!important;border:1px solid #475569!important}
[data-theme="dark"] .fail-backfill-cell{background:#450a0a!important;color:#fca5a5!important}
[data-theme="dark"] .mobile-page-wrap{background:transparent!important}
[data-theme="dark"] .mobile-content{background:transparent!important}
[data-theme="dark"] .mobile-list{background:transparent!important}
[data-theme="dark"] .mobile-task-detail{background:#1e293b!important}
[data-theme="dark"] .mobile-task-detail-header{background:#0f172a!important}
[data-theme="dark"] .mobile-data-card{background:#1e293b!important;border:1px solid #334155!important}
[data-theme="dark"] .mobile-stat-row{background:transparent!important}
[data-theme="dark"] .mobile-stat-item{background:#0f172a!important}
[data-theme="dark"] .mobile-action-bar{background:#1e293b!important;border-top:1px solid #334155!important}
[data-theme="dark"] .mobile-action-btn{background:#334155!important;color:#e2e8f0!important}
[data-theme="dark"] .mobile-record-btn{background:transparent!important;color:#94a3b8!important}
[data-theme="dark"] .mobile-record-icon{background:#334155!important}
[data-theme="dark"] .mobile-progress-bar{background:#334155!important}
[data-theme="dark"] .mobile-progress-fill{background:#4096ff!important}
[data-theme="dark"] .mobile-tab-count{color:#64748b!important}
[data-theme="dark"] .mobile-tab.active .mobile-tab-count{color:#4096ff!important}
[data-theme="dark"] .mobile-search-input{background:#0f172a!important;color:#e2e8f0!important;border:1px solid #334155!important}
[data-theme="dark"] .mobile-filter-select{background:#0f172a!important;color:#e2e8f0!important;border:1px solid #334155!important}
[data-theme="dark"] .mobile-batch-select{background:#334155!important;color:#e2e8f0!important;border:1px solid #475569!important}
[data-theme="dark"] .mobile-batch-select-here{background:#334155!important;color:#94a3b8!important;border:1px solid #475569!important}
[data-theme="dark"] .mobile-batch-select-here.active{background:#1677ff!important;color:#fff!important}
[data-theme="dark"] .mobile-checkbox{background:#0f172a!important;border:1px solid #475569!important}
[data-theme="dark"] .mobile-checkbox:checked{background:#1677ff!important;border-color:#1677ff!important}
[data-theme="dark"] .mobile-table-input{background:transparent!important;color:#e2e8f0!important}
[data-theme="dark"] .mobile-table-input:focus{background:#0f172a!important;border-color:#4096ff!important}
[data-theme="dark"] .mobile-table-cell{border-bottom:1px solid #334155!important}
[data-theme="dark"] .mobile-table-header{background:#0f172a!important;color:#e2e8f0!important}
[data-theme="dark"] .mobile-upload-result{background:#0f172a!important;border:1px solid #334155!important}
[data-theme="dark"] .mobile-upload-success{color:#34d399!important}
[data-theme="dark"] .mobile-upload-fail{color:#f87171!important}
[data-theme="dark"] .mobile-upload-progress{background:#334155!important}
[data-theme="dark"] .mobile-upload-progress-fill{background:#4096ff!important}
[data-theme="dark"] .mobile-theme-picker{background:#1e293b!important;border:1px solid #334155!important}
[data-theme="dark"] .mobile-theme-option{background:#0f172a!important;border:1px solid #334155!important}
[data-theme="dark"] .mobile-theme-option.active{border-color:#4096ff!important}
[data-theme="dark"] .mobile-user-menu{background:#1e293b!important;border:1px solid #334155!important}
[data-theme="dark"] .mobile-user-menu-item{color:#e2e8f0!important}
[data-theme="dark"] .mobile-user-menu-item:hover{background:#0f172a!important}
[data-theme="dark"] .mobile-log-item{background:#0f172a!important;border:1px solid #334155!important}
[data-theme="dark"] .mobile-log-time{color:#64748b!important}
[data-theme="dark"] .mobile-log-content{color:#e2e8f0!important}
[data-theme="dark"] .mobile-log-ip{color:#94a3b8!important}
[data-theme="dark"] .mobile-version-item{background:#0f172a!important;border:1px solid #334155!important}
[data-theme="dark"] .mobile-version-number{color:#4096ff!important}
[data-theme="dark"] .mobile-version-date{color:#64748b!important}
[data-theme="dark"] .mobile-version-content{color:#e2e8f0!important}
[data-theme="dark"] .mobile-agent-item{background:#0f172a!important;border:1px solid #334155!important}
[data-theme="dark"] .mobile-agent-name{color:#e2e8f0!important}
[data-theme="dark"] .mobile-agent-role{color:#94a3b8!important}
[data-theme="dark"] .mobile-threshold-item{background:#0f172a!important;border:1px solid #334155!important}
[data-theme="dark"] .mobile-replenish-item{background:#0f172a!important;border:1px solid #334155!important}
[data-theme="dark"] .mobile-channel-link-item{background:#0f172a!important;border:1px solid #334155!important}
[data-theme="dark"] .mobile-stats-card{background:#1e293b!important;border:1px solid #334155!important}
[data-theme="dark"] .mobile-stats-number{color:#e2e8f0!important}
[data-theme="dark"] .mobile-stats-label{color:#94a3b8!important}
[data-theme="dark"] .mobile-stats-table{background:transparent!important}
[data-theme="dark"] .mobile-stats-th{background:#0f172a!important;color:#e2e8f0!important}
[data-theme="dark"] .mobile-stats-td{border-bottom:1px solid #334155!important;color:#e2e8f0!important}
[data-theme="dark"] .mobile-stats-tr:hover{background:#0f172a!important}
[data-theme="dark"] .mobile-chart-container{background:#1e293b!important;border:1px solid #334155!important}
[data-theme="dark"] .mobile-chart-title{color:#e2e8f0!important}
[data-theme="dark"] .mobile-chart-legend{color:#94a3b8!important}
[data-theme="dark"] .mobile-empty-state{color:#64748b!important}
[data-theme="dark"] .mobile-loading{color:#94a3b8!important}
[data-theme="dark"] .mobile-error{color:#f87171!important}
[data-theme="dark"] .mobile-success{color:#34d399!important}
[data-theme="dark"] .mobile-warning{color:#fbbf24!important}
[data-theme="dark"] .mobile-info{color:#4096ff!important}
/* 内联样式白色背景的覆盖 */
[data-theme="dark"] div[style*="background:#fff"],[data-theme="dark"] div[style*="background: #fff"]{background:#1e293b!important}
[data-theme="dark"] button[style*="background:#fff"],[data-theme="dark"] button[style*="background: #fff"]{background:#334155!important;color:#e2e8f0!important;border-color:#475569!important}
[data-theme="dark"] input[style*="background:#fff"],[data-theme="dark"] input[style*="background: #fff"]{background:#0f172a!important;color:#e2e8f0!important}
[data-theme="dark"] td[style*="background:#fff"],[data-theme="dark"] td[style*="background: #fff"]{background:#1e293b!important}
[data-theme="dark"] th[style*="background:#fff"],[data-theme="dark"] th[style*="background: #fff"]{background:#0f172a!important}
/* v5.91 用户数据模块深色模式适配 */
[data-theme="dark"] .user-card{background:#1e293b!important;border:1px solid #334155!important}
[data-theme="dark"] .user-card div[style*="color:#166534"]{color:#86efac!important}
[data-theme="dark"] .user-card div[style*="color:#16a34a"]{color:#4ade80!important}
[data-theme="dark"] .user-card div[style*="color:#1e40af"]{color:#93c5fd!important}
[data-theme="dark"] .user-card div[style*="color:#2563eb"]{color:#60a5fa!important}
[data-theme="dark"] .user-card div[style*="color:#9d174d"]{color:#f9a8d4!important}
[data-theme="dark"] .user-card div[style*="color:#db2777"]{color:#f472b6!important}
[data-theme="dark"] .user-card div[style*="color:#075985"]{color:#7dd3fc!important}
[data-theme="dark"] .user-card div[style*="color:#0284c7"]{color:#38bdf8!important}
[data-theme="dark"] .user-card div[style*="color:#6b21a8"]{color:#d8b4fe!important}
[data-theme="dark"] .user-card div[style*="color:#9333ea"]{color:#c084fc!important}
[data-theme="dark"] .user-card div[style*="color:#92400e"]{color:#fcd34d!important}
[data-theme="dark"] .user-card div[style*="color:#d97706"]{color:#fbbf24!important}
/* v5.91 运维数据模块深色模式适配：浅色渐变背景覆盖 */
[data-theme="dark"] div[style*="background:linear-gradient(135deg,#f0fdf4"]{background:#14532d!important;border:1px solid #15803d!important}
[data-theme="dark"] div[style*="background:linear-gradient(135deg,#eff6ff"]{background:#1e3a8a!important;border:1px solid #2563eb!important}
[data-theme="dark"] div[style*="background:linear-gradient(135deg,#fdf2f8"]{background:#831843!important;border:1px solid #be185d!important}
[data-theme="dark"] div[style*="background:linear-gradient(135deg,#f0f9ff"]{background:#0c4a6e!important;border:1px solid #0284c7!important}
[data-theme="dark"] div[style*="background:linear-gradient(135deg,#faf5ff"]{background:#581c87!important;border:1px solid #9333ea!important}
[data-theme="dark"] div[style*="background:linear-gradient(135deg,#fef3c7"]{background:#78350f!important;border:1px solid #d97706!important}
[data-theme="dark"] div[style*="background:#f0fdf4"]{background:#14532d!important}
[data-theme="dark"] div[style*="background:#eff6ff"]{background:#1e3a8a!important}
[data-theme="dark"] div[style*="background:#fdf2f8"]{background:#831843!important}
[data-theme="dark"] div[style*="background:#f0f9ff"]{background:#0c4a6e!important}
[data-theme="dark"] div[style*="background:#faf5ff"]{background:#581c87!important}
[data-theme="dark"] div[style*="background:#fef3c7"]{background:#78350f!important}
[data-theme="dark"] div[style*="background:#f8fafc"]{background:#0f172a!important}
/* 护眼绿主题 */
[data-theme="green"]{--primary:#10b981;--primary-dark:#047857;--primary-light:#d1fae5;--accent:#14b8a6;--accent-light:#ccfbf1;--bg:#f0fdf4;--card:#fff;--text:#0f172a;--text2:#5b6472;--border:#dcefe2;--border-strong:#b9e3c9}
/* 暖橙主题 */
[data-theme="orange"]{--primary:#f97316;--primary-dark:#c2410c;--primary-light:#ffedd5;--accent:#f59e0b;--accent-light:#fef3c7;--bg:#fff7ed;--card:#fff;--text:#0f172a;--text2:#5b6472;--border:#f6e2cc;--border-strong:#eccfa8}
/* 紫色主题 */
[data-theme="purple"]{--primary:#8b5cf6;--primary-dark:#7c3aed;--primary-light:#ede9fe;--accent:#a855f7;--accent-light:#f3e8ff;--bg:#faf5ff;--card:#fff;--text:#0f172a;--text2:#5b6472;--border:#e9e0fb;--border-strong:#d8c8f7}
/* 猛男粉 */
[data-theme="pink"]{--primary:#ec4899;--primary-dark:#db2777;--primary-light:#fce7f3;--accent:#f472b6;--accent-light:#fbcfe8;--bg:#fdf2f8;--card:#fff;--text:#0f172a;--text2:#5b6472;--border:#f7dfe9;--border-strong:#f0c6d9}
/* 中国红 */
[data-theme="red"]{--primary:#dc2626;--primary-dark:#b91c1c;--primary-light:#fee2e2;--accent:#ef4444;--accent-light:#fecaca;--bg:#fef2f2;--card:#fff;--text:#0f172a;--text2:#5b6472;--border:#f6dcdc;--border-strong:#efc2c2}
/* 所有主题：内联样式白色背景统一用CSS变量 */
[data-theme="green"] div[style*="background:#fff"],[data-theme="green"] div[style*="background: #fff"]{background:var(--card)!important}
[data-theme="green"] button[style*="background:#fff"],[data-theme="green"] button[style*="background: #fff"]{background:var(--card)!important;border-color:var(--border)!important}
[data-theme="green"] input[style*="background:#fff"],[data-theme="green"] input[style*="background: #fff"]{background:var(--bg)!important}
[data-theme="orange"] div[style*="background:#fff"],[data-theme="orange"] div[style*="background: #fff"]{background:var(--card)!important}
[data-theme="orange"] button[style*="background:#fff"],[data-theme="orange"] button[style*="background: #fff"]{background:var(--card)!important;border-color:var(--border)!important}
[data-theme="orange"] input[style*="background:#fff"],[data-theme="orange"] input[style*="background: #fff"]{background:var(--bg)!important}
[data-theme="purple"] div[style*="background:#fff"],[data-theme="purple"] div[style*="background: #fff"]{background:var(--card)!important}
[data-theme="purple"] button[style*="background:#fff"],[data-theme="purple"] button[style*="background: #fff"]{background:var(--card)!important;border-color:var(--border)!important}
[data-theme="purple"] input[style*="background:#fff"],[data-theme="purple"] input[style*="background: #fff"]{background:var(--bg)!important}
[data-theme="pink"] div[style*="background:#fff"],[data-theme="pink"] div[style*="background: #fff"]{background:var(--card)!important}
[data-theme="pink"] button[style*="background:#fff"],[data-theme="pink"] button[style*="background: #fff"]{background:var(--card)!important;border-color:var(--border)!important}
[data-theme="pink"] input[style*="background:#fff"],[data-theme="pink"] input[style*="background: #fff"]{background:var(--bg)!important}
[data-theme="red"] div[style*="background:#fff"],[data-theme="red"] div[style*="background: #fff"]{background:var(--card)!important}
[data-theme="red"] button[style*="background:#fff"],[data-theme="red"] button[style*="background: #fff"]{background:var(--card)!important;border-color:var(--border)!important}
[data-theme="red"] input[style*="background:#fff"],[data-theme="red"] input[style*="background: #fff"]{background:var(--bg)!important}
*{margin:0;padding:0;box-sizing:border-box}
/* CPA-941：根元素补主题背景（老板 2026-10-12 报「切换 tab 页能看到白色闪屏」）——
   仅 body 有背景时，整页导航/重绘的首帧画布仍是浏览器默认白色，深色模式下尤其刺眼；html 补上即与主题同色。 */
html{background:var(--bg)}
body{font-family:var(--font-family);background:var(--bg);color:var(--text);font-size:var(--fs-body);line-height:var(--lh-body);min-height:100vh;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-feature-settings:"tnum" 1,"cv03" 1;letter-spacing:.1px}
.login-wrap{display:flex;justify-content:center;align-items:center;min-height:100vh;background:var(--bg);position:relative;overflow:hidden}
.login-wrap::before{content:'';position:absolute;top:-260px;right:-180px;width:620px;height:620px;background:radial-gradient(circle,rgba(22,119,255,.07) 0%,transparent 68%);border-radius:50%}
.login-wrap::after{content:'';position:absolute;bottom:-200px;left:-160px;width:520px;height:520px;background:radial-gradient(circle,rgba(0,184,217,.05) 0%,transparent 68%);border-radius:50%}
.login-card{background:var(--card);border-radius:var(--radius-lg);padding:36px 32px;width:380px;max-width:92vw;box-shadow:var(--shadow-pop);text-align:center;position:relative;z-index:1;border:1px solid var(--border)}
.login-card h1{font-size:22px;margin-bottom:6px;color:var(--primary);font-weight:700;letter-spacing:0}
.login-card .subtitle{color:var(--text2);font-size:13px;margin-bottom:26px}
.login-card input{width:100%;padding:12px 14px;border:1px solid var(--border);border-radius:var(--radius-sm);font-size:var(--fs-body);margin-bottom:14px;outline:none;transition:border-color .18s,box-shadow .18s;background:var(--card);color:var(--text)}
.login-card input:focus{border-color:var(--primary);box-shadow:var(--ring)}
.login-card .login-btn{width:100%;padding:14px;background:var(--primary);color:#fff;border:none;border-radius:var(--radius-sm);font-size:16px;font-weight:600;cursor:pointer;transition:background .15s,box-shadow .15s,transform .1s;position:relative;z-index:10;-webkit-tap-highlight-color:rgba(22,119,255,.3);touch-action:manipulation;user-select:none;-webkit-user-select:none}
.login-card .login-btn:active{transform:scale(0.98)}
.login-card .login-btn:disabled{opacity:0.6;cursor:not-allowed}
.login-switch-link{color:var(--primary);cursor:pointer;user-select:none}
.login-switch-link:hover{text-decoration:underline}
.login-sms-btn{flex:0 0 116px;border:1px solid var(--primary);background:var(--card);color:var(--primary);border-radius:var(--radius-sm);font-size:13px;cursor:pointer;white-space:nowrap;padding:0 8px;transition:background .15s}
.login-sms-btn:hover:not(:disabled){background:var(--primary-light)}
.login-sms-btn:disabled{border-color:var(--border);color:var(--text-tertiary);background:var(--bg2);cursor:not-allowed}
.login-card .login-btn:hover{background:var(--primary-dark);box-shadow:0 6px 16px rgba(15,23,42,.14)}
.login-card .version{font-size:11px;color:var(--text-tertiary);margin-top:16px}
.app{display:none;min-height:100vh}
.topbar{background:var(--card);color:var(--text);padding:0 20px;display:flex;align-items:center;height:60px;position:sticky;top:0;z-index:100;box-shadow:var(--shadow-sm);border-bottom:1px solid var(--border)}
.topbar .brand{display:flex;align-items:center;gap:10px;margin-right:24px;font-size:17px;font-weight:700;color:var(--primary);white-space:nowrap}
.topbar .brand img{width:32px;height:32px;border-radius:var(--radius-sm);object-fit:cover}
.topbar .nav{display:flex;gap:4px;flex:1;overflow-x:auto;flex-wrap:nowrap;scrollbar-width:none;-ms-overflow-style:none;align-items:center}
.topbar .nav::-webkit-scrollbar{display:none}
.topbar .nav-item{padding:0 14px;height:36px;display:flex;align-items:center;cursor:pointer;font-size:var(--fs-body);transition:color .15s,background .15s;color:var(--text2);font-weight:500;flex-shrink:0;white-space:nowrap;position:relative;border-radius:var(--radius-sm)}
.topbar .nav-item:hover{color:var(--primary);background:var(--primary-light)}
.topbar .nav-item.active{color:var(--primary);font-weight:600;background:var(--primary-light)}
.topbar .user{display:flex;align-items:center;gap:8px;font-size:13px;color:var(--text2)}
.topbar .logout{cursor:pointer;padding:4px 12px;border-radius:var(--radius-sm);color:var(--primary);border:1px solid var(--primary);transition:background .15s}
.topbar .logout:hover{background:var(--primary-light)}
/* 不再区分电脑版/手机版，隐藏UI模式切换按钮 */
#ui_mode_switch, #mobile_ui_mode_switch{display:none!important}
/* 小屏幕适配：顶部导航栏改成两行布局 */
@media (max-width: 900px){
  .topbar{flex-wrap:wrap;height:auto;padding:8px 12px;gap:8px}
  .topbar .brand{flex:1;margin-right:0;font-size:15px;justify-content:flex-start;min-width:0}
  .topbar .nav{order:3;width:100%;overflow-x:auto;scrollbar-width:thin;-ms-overflow-style:auto}
  .topbar .nav::-webkit-scrollbar{display:block;height:3px}
  .topbar .nav::-webkit-scrollbar-thumb{background:#cbd5e1;border-radius:2px}
  .topbar .nav-item{padding:0 12px;height:44px;font-size:13px}
  .topbar .user{order:2;gap:6px;flex-shrink:0}
  .topbar .logout{padding:3px 8px;font-size:12px}
}

/* CPA-246：移除手机端顶部「时间+天气」纯 CSS 图片横幅（老板反馈不好看）；左上角品牌名统一为「盈钱树 投放平台 v版本号」 */

/* ========== 手机端响应式适配（max-width: 768px） ========== */
/* 所有功能完全复用PC端，只做适配优化，Pad（>=768px）按PC端处理 */
@media (max-width: 768px){
  /* 顶部导航：隐藏导航菜单，使用底部导航栏 */
  .topbar{height:60px;padding:8px 14px;flex-wrap:nowrap}
  .topbar .brand{font-size:14px;margin-right:8px;gap:6px}
  .topbar .brand img{width:28px;height:28px}
  .topbar .brand span{display:inline!important;font-size:11px;color:#94a3b8;font-weight:500} /* 手机端显示版本号，字体小一些 */
  /* CPA-246：手机端恢复显示「投放平台 +版本号」副标题（CPA-172 曾隐藏），品牌名统一为「盈钱树 投放平台 v版本号」 */
  .topbar .brand span:last-child{display:inline!important}
  .topbar .nav{display:none!important} /* 隐藏顶部导航菜单 */
  /* 手机端隐藏右上角账户功能（已集成到"我的"页面），但保留深色模式按钮 */
  #theme_switch, #ui_mode_switch, .topbar .user > div[style*="position:relative"]{display:none!important}
  #dark_switch{display:inline-flex!important}
  .topbar .user{gap:6px}
  .topbar .user > span{
    width:36px!important;height:36px!important; /* 增加点击区域 */
    font-size:16px!important;
    display:flex!important;align-items:center!important;justify-content:center!important;
    border-radius:8px!important;
    -webkit-tap-highlight-color:transparent!important;
    touch-action:manipulation!important;
  }
  .topbar .logout{padding:8px 12px!important;font-size:13px!important} /* 增加退出按钮点击区域 */
  
  /* 主内容区：减少padding，增加内容显示空间 */
  .main{padding:10px 10px 80px 10px}
  
  /* 卡片：减少padding */
  .card{border-radius:10px;margin-bottom:10px}
  .card-header{padding:10px 12px;flex-wrap:wrap;gap:6px}
  .card-header .title{font-size:14px}
  .card-body{padding:10px 12px}
  
  /* 统计卡片：2列布局，减少padding */
  .stat-cards{grid-template-columns:repeat(2,1fr);gap:8px;margin-bottom:12px}
  .stat-card{padding:12px;gap:10px}
  .stat-card .icon{width:36px;height:36px;font-size:16px}
  .stat-card .value{font-size:18px}
  .stat-card .label{font-size:11px}
  /* v6.10 任务数据弹窗卡片：2列、标签在上数字在下纵向排列，大数字完整不截断 */
  .task-data-cards{grid-template-columns:repeat(2,1fr)!important;gap:8px!important}
  .task-data-cards .stat-card{flex-direction:column;align-items:flex-start;gap:2px!important;padding:12px!important;min-width:0}
  .task-data-cards .stat-card .value{font-size:19px!important;font-weight:800;white-space:nowrap;line-height:1.15;width:100%}
  .task-data-cards .stat-card .label{font-size:11px;margin-bottom:2px}
  
  /* v5.91 用户总览卡片：手机端2列布局，横排显示 */
  .user-overview-grid{grid-template-columns:repeat(2,1fr)!important;gap:8px!important}
  .user-card{padding:12px!important}
  .user-card div[style*="font-size:28px"]{font-size:20px!important}
  .user-card div[style*="font-size:11px"]{font-size:10px!important}
  
  /* ========== 任务列表优化：尽量多显示任务条数，好操作 ========== */
  /* 表格容器：横向滚动 */
  .table-wrap{overflow-x:auto;-webkit-overflow-scrolling:touch}
  .table-wrap table{min-width:700px;font-size:12px;border-collapse:collapse}
  
  /* 表格表头：固定背景，减少高度 */
  .table-wrap thead th{padding:6px 8px;font-size:11px;font-weight:600;white-space:nowrap;background:var(--bg2);position:sticky;top:0;z-index:1}
  
  /* 表格行：减少高度，尽量多显示 */
  .table-wrap tbody td{padding:5px 8px;font-size:12px;vertical-align:middle;white-space:nowrap;max-width:150px;overflow:hidden;text-overflow:ellipsis}
  .table-wrap tbody tr{transition:background .15s}
  .table-wrap tbody tr:hover{background:var(--primary-light)}
  
  /* 任务名称列：限制宽度，显示省略号 */
  .table-wrap tbody td:nth-child(2){max-width:120px}
  
  /* 状态标签：变小 */
  .status-tag{padding:2px 6px;font-size:10px;border-radius:4px}
  
  /* 操作按钮：变小但保持可点击 */
  .btn{padding:4px 8px;font-size:11px;border-radius:5px}
  .btn-sm{padding:3px 6px;font-size:10px}
  .btn-group{gap:3px}
  
  /* 复选框：变小 */
  .table-wrap input[type="checkbox"]{width:14px;height:14px}
  
  /* 批量操作栏：适配手机宽度 */
  .batch-bar{padding:8px 10px;flex-wrap:wrap;gap:6px}
  .batch-bar .btn{padding:5px 10px;font-size:11px}
  
  /* 分页栏：适配手机宽度 */
  .pagination{padding:8px 10px;flex-wrap:wrap;gap:4px;justify-content:center}
  .pagination button{padding:4px 8px;font-size:11px;min-width:28px}
  .pagination .page-info{font-size:11px;width:100%;text-align:center;margin-bottom:4px}
  
  /* 筛选栏：适配手机宽度 */
  .filter-bar{padding:8px 10px;flex-wrap:wrap;gap:6px}
  .filter-bar select,.filter-bar input{padding:5px 8px;font-size:11px;max-width:120px}

  /* ===== v6.10 手机端任务页：筛选折叠 + 批量悬浮 + 紧凑模式 ===== */
  /* CPA-204：工具行本身不换行，左侧三颗按钮装进 .mtt-row 在组内换行 —— 分页/全览 seg 恒钉在第一行右侧。
     原实现（#mTaskToolbar 直接 flex-wrap:wrap + .mtt-spacer{flex:1}）在点「精简」后按钮文案多出「·开」两字、
     整行超出宽度，seg 被挤到第二行而第一行的 spacer 吃掉全部余量 ⇒ 呈现为「上面有空位却把分页/全览挪到下面」。
     ① align-items 必须是 flex-start 而非 center：万一左组仍换行，center 会把单行的 seg 垂直居中到两行之间，
        看上去依旧像「挪到了下面」；flex-start 让 seg 恒与第一行按钮同顶边。
     ② 间距/内边距按手机宽度收窄（gap 4px、按钮 6px 9px、seg 6px 8px），让「筛选+精简·开+修改记录+分页/全览」
        在 375/390px 这类常见视口下能整行放下（原 6px/12px 在 390px 就已差十几像素 ⇒ 精简一开就换行）。
     CPA-916（老板：筛选后「复投」被挤到第二行，其实一行放得下）：CPA-193 的「筛选(n)」角标使筛选按钮
        增宽约 15px，把 CPA-204 抠出的余量吃光 → 复投换行。故再收窄一档：工具行 gap 2px、左右留白 8px、
        按钮组内 gap 2px、按钮 6px 5px、seg 6px 6px（PC 侧同款度量同步收窄以保 cpa250 统一口径）。
        实测（headless Edge，列宽模拟，见 tests/cpa916_toolbar_nowrap.py E 组）：360/375/390/414px 下
        「筛选(1~12)/变动史/复投(0~1234) + 精简/分页/全览」六控件全部同一行（含最坏 360px）。 */
  #mTaskToolbar{display:flex!important;flex-wrap:nowrap;gap:2px;align-items:flex-start;margin:8px 0 10px;padding:0 8px}
  #mTaskToolbar .mtt-row{display:flex;flex-wrap:wrap;gap:2px;align-items:center;flex:1;min-width:0}
  #mTaskToolbar .mtt-btn{font-size:12px;padding:6px 5px;border:1px solid var(--border);border-radius:var(--btn-radius);background:var(--bg2);color:var(--text);display:flex;align-items:center;gap:2px}
  #mTaskToolbar .mtt-btn.active{background:var(--primary-light);border-color:var(--primary);color:var(--primary);font-weight:600}
  #mTaskToolbar .mtt-seg{display:flex;flex-shrink:0;border:1px solid var(--border);border-radius:var(--btn-radius);overflow:hidden}
  #mTaskToolbar .mtt-seg button{font-size:11px;padding:6px 6px;border:none;background:var(--bg2);color:var(--text2)}
  #mTaskToolbar .mtt-seg button.on{background:var(--primary);color:#fff;font-weight:600}
  /* CPA-228 需求C：精简从左侧 .mtt-row 挪进本 seg，沿用 seg 分隔样式；激活态用浅色高亮（与 分页/全览 实心「on」区分） */
  #mTaskToolbar .mtt-seg button.active{background:var(--primary-light);color:var(--primary);font-weight:600}
  #mTaskToolbar .mtt-seg button+button{border-left:1px solid var(--border)}
  /* 筛选区默认折叠，加 m-open 才展开 */
  #taskSearchBar{display:none!important}
  #taskSearchBar.m-open{display:flex!important}
  /* 原整排批量按钮手机端隐藏，改底部悬浮 */
  #taskBatchBar{display:none!important}
  #mBatchFloat.show{display:flex!important}
  /* v6.61 紧凑模式隐藏哪些列由全局 body.task-compact .cc-hide 统一控制（任务ID/任务链接/排期/控量方式/变动记录），不再用 nth-child（角色不同列数会错位），也不隐藏备注 */

  /* 弹窗：适配手机宽度 */
  .modal{padding:10px}
  .modal-content{width:100%!important;max-width:100%!important;margin:0;border-radius:12px 12px 0 0;max-height:90vh;overflow-y:auto}
  .modal-header{padding:12px 14px}
  .modal-header h3{font-size:15px}
  .modal-body{padding:12px 14px}
  .modal-footer{padding:10px 14px}
  
  /* 表单：适配手机宽度 */
  .form-group{margin-bottom:10px}
  .form-group label{font-size:12px;margin-bottom:4px}
  .form-group input,.form-group select,.form-group textarea{padding:8px 10px;font-size:13px}
  .form-actions{gap:8px}
  .form-actions .btn{padding:8px 16px;font-size:13px;flex:1}
  
  /* 两列表单：手机端改成单列 */
  .form-grid-2{grid-template-columns:1fr!important;gap:10px}
  .form-grid-3{grid-template-columns:1fr!important;gap:10px}
  
  /* 数据中心：适配手机宽度，强制覆盖内联样式 */
  /* 平台总览4列卡片 -> 2列 */
  #overview_cards > div[style*="grid-template-columns:1fr 1fr 1fr 1fr"],
  #overview_cards > div[style*="grid-template-columns: 1fr 1fr 1fr 1fr"]{
    grid-template-columns:1fr 1fr!important;
    gap:8px!important;
  }
  /* 平台总览2列卡片 -> 1列 */
  #overview_cards > div[style*="grid-template-columns:1fr 1fr"],
  #overview_cards > div[style*="grid-template-columns: 1fr 1fr"]{
    grid-template-columns:1fr!important;
    gap:10px!important;
  }
  /* 数据中心所有卡片容器，如果内容太宽允许横向滚动 */
  .card-body > div[style*="display:grid"]{
    overflow-x:hidden!important; /* 数据中心不要左右滑动 */
  }
  /* 分渠道数据卡片：强制2列瀑布流，覆盖内联的5列布局 */
  .card-body > div[style*="grid-template-columns:repeat(5"],
  .card-body > div[style*="grid-template-columns: repeat(5"]{
    grid-template-columns:1fr 1fr!important;
    gap:8px!important;
    row-gap:8px!important;
  }
  /* 分渠道数据卡片：强制2列 */
  .channel-cards,
  .card-body > .channel-cards{
    grid-template-columns:repeat(2,1fr)!important;
    gap:8px!important;
  }
  /* v6.09 异常渠道卡片：手机端强制2列 */
  .abnormal-cards{
    grid-template-columns:repeat(2,1fr)!important;
    gap:8px!important;
  }
  /* 分归属人数据卡片：强制2列 */
  .owner-cards,
  .card-body > .owner-cards{
    grid-template-columns:repeat(2,1fr)!important;
    gap:8px!important;
  }
  /* 数据中心的3列布局 -> 2列 */
  .card-body > div[style*="grid-template-columns:1fr 1fr 1fr"],
  .card-body > div[style*="grid-template-columns: 1fr 1fr 1fr"]{
    grid-template-columns:1fr 1fr!important;
    gap:8px!important;
  }
  /* 分渠道/分归属人卡片内部，确保内容不溢出 */
  .card-body > div[style*="display:grid"] > div{
    min-width:0!important;
    overflow:hidden!important;
  }
  /* 首页流量数据三列口径卡（业务/异常/含异常）：手机端保持三列等宽不竖向堆叠，字号自适应防挤爆 */
  .flow-tri-col{grid-template-columns:repeat(3,minmax(0,1fr))!important;gap:6px!important}
  .flow-tri-col>div{min-width:0!important;overflow:visible!important;padding:8px 4px!important}
  .flow-tri-col .ftc-num{font-size:15px!important}
  .flow-tri-col .ftc-uv{font-size:13px!important}
  /* UID访问流 + 系统失败日志：手机端改为上下排列（瀑布流），不要并列 */
  div[style*="grid-template-columns:1fr 1fr"]{
    grid-template-columns:1fr!important;
    gap:12px!important;
  }
  /* UID访问流内部表格：手机端调整列宽，确保不需要左右滑动 */
  .card-body > div[style*="grid-template-columns:70px"]{
    grid-template-columns:55px 1fr 50px 50px!important;
    gap:4px!important;
    font-size:11px!important;
  }
  /* 系统失败日志内部表格：手机端调整列宽，确保不需要左右滑动 */
  .card-body > div[style*="grid-template-columns:120px"]{
    grid-template-columns:70px 40px 50px 1fr!important;
    gap:4px!important;
    font-size:11px!important;
  }
  /* 确保所有卡片内容不溢出，不需要左右滑动（除了任务列表） */
  .card, .card-body, .card-header{
    max-width:100%!important;
    overflow-x:hidden!important;
  }
  /* 任务列表除外：允许横向滚动 */
  .table-wrap{
    overflow-x:auto!important;
  }
  
  /* 底部导航栏显示 */
  .mobile-bottom-nav{display:block!important}
  
  /* 隐藏PC端底部版权 */
  #pcFooter{display:none}
  
  /* Toast提示：适配手机宽度 */
  .toast{max-width:90%;font-size:13px;padding:10px 16px}
  
  /* 全局加载遮罩 */
  #globalLoading{height:2px}
}

/* 手机端横屏适配（max-width: 768px 且高度 < 500px） */
@media (max-width: 768px) and (max-height: 500px){
  .topbar{height:44px}
  .main{padding:8px}
  .table-wrap tbody td{padding:4px 6px;font-size:11px}
  .table-wrap thead th{padding:4px 6px;font-size:10px}
}
.main{padding:20px 24px;max-width:1600px;margin:0 auto}
.stat-cards{display:grid;grid-template-columns:repeat(4,1fr);gap:16px;margin-bottom:20px}
.stat-card{background:var(--card);border:1px solid var(--border);border-radius:var(--radius);padding:18px;box-shadow:var(--shadow);display:flex;align-items:center;gap:14px;position:relative;overflow:hidden;transition:transform .18s,box-shadow .18s}
.stat-card:hover{transform:translateY(-1px);box-shadow:var(--shadow-pop)}
.stat-card::before{content:'';position:absolute;left:0;top:0;bottom:0;width:3px;background:var(--primary)}
.stat-card .icon{width:44px;height:44px;border-radius:var(--radius-sm);display:flex;align-items:center;justify-content:center;font-size:20px;flex-shrink:0;background:var(--primary-light);color:var(--primary)}
.stat-card .label{font-size:var(--fs-caption);color:var(--text2);margin-bottom:3px}
.stat-card .value{font-size:24px;font-weight:700;color:var(--text);font-variant-numeric:tabular-nums}
/* CPA-252 需求③：作为「跳转入口」的统计卡右上角加「›」，提示点击会跳出本页；仅 .stat-card-link，管理员运维指标卡不加 */
.stat-card-link{cursor:pointer}
.stat-card-link::after{content:'›';position:absolute;top:10px;right:12px;font-size:15px;font-weight:700;line-height:1;color:var(--border-strong)}
.card{background:var(--card);border-radius:var(--radius);box-shadow:var(--shadow);margin-bottom:16px;overflow:hidden;border:1px solid var(--border)}
.card-header{padding:14px 18px;border-bottom:1px solid var(--border);display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:10px;background:var(--card)}
.card-header .title{font-size:15px;font-weight:600;color:var(--text)}
.card-body{padding:16px 18px}
.search-bar{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:14px}
.search-bar label{font-size:13px;color:var(--text2)}
.search-bar input,.search-bar select{padding:7px 12px;border:1px solid var(--border);border-radius:var(--radius-sm);font-size:13px;outline:none;transition:border-color .18s,box-shadow .18s;background:var(--card);color:var(--text)}
.search-bar input:focus,.search-bar select:focus{border-color:var(--primary);box-shadow:var(--ring)}
.search-bar select.filter-active{background:var(--primary-light);border-color:var(--primary);color:var(--primary-dark);font-weight:500}
.btn{padding:7px 14px;border:none;border-radius:var(--btn-radius);font-size:13px;cursor:pointer;font-weight:500;display:inline-flex;align-items:center;justify-content:center;gap:4px;transition:background .15s,border-color .15s,color .15s,box-shadow .15s,transform .1s;line-height:1.4}
.btn:active{transform:translateY(1px)}
.btn-primary{background:var(--primary);color:#fff;box-shadow:var(--shadow-sm)}
.btn-primary:hover{background:var(--primary-dark);box-shadow:0 4px 12px rgba(15,23,42,.16)}
.btn-default{background:var(--card);color:var(--text);border:1px solid var(--border)}
.btn-default:hover{border-color:var(--primary);color:var(--primary);background:var(--primary-light)}
.btn-danger{background:#dc2626;color:#fff}
.btn-danger:hover{background:#b91c1c}
.btn-success{background:#047857;color:#fff}
.btn-success:hover{background:#065f46}
.btn-sm{padding:4px 10px;font-size:12px}
.btn-warning{background:#fbbf24;color:#1f2937}
.btn-warning:hover{background:#f59e0b}
.batch-bar{display:flex;gap:8px;flex-wrap:wrap;align-items:center;padding:10px 0;margin-bottom:10px;border-bottom:1px solid var(--border)}
.batch-row{display:flex;gap:6px;align-items:center;flex-wrap:wrap}
.tabs{display:flex;gap:0;border-bottom:1px solid var(--border);margin-bottom:16px;overflow-x:auto;flex-wrap:nowrap;scrollbar-width:thin}
.tabs::-webkit-scrollbar{height:3px}
.tabs::-webkit-scrollbar-thumb{background:var(--border-strong);border-radius:2px}
.tab{padding:10px 18px;cursor:pointer;font-size:var(--fs-body);color:var(--text2);border-bottom:2px solid transparent;margin-bottom:-1px;transition:color .15s,border-color .15s;font-weight:500;flex-shrink:0;white-space:nowrap}
.tab:hover{color:var(--primary)}
.tab.active{color:var(--primary);border-bottom-color:var(--primary);font-weight:600}
/* CPA-948 返工（老板 2026-10-12）：「顶部的状态选项变成 5 个（待上架 0 隐藏）/6 个时，有的上下结构、有的左右结构，
   不统一」——统一为「上下结构」：上行=图标+状态名，下行=数量。此处按 #taskStatusTabs 单独锁定，不受数量/宽度影响，
   PC 与手机端一致（手机端不再靠 flex-wrap 逐格折行，消除参差）。 */
#taskStatusTabs .tab{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:0;padding:8px 14px;line-height:1.25;text-align:center}
#taskStatusTabs .tab .tab-main{display:block;white-space:nowrap}
#taskStatusTabs .tab .tab-count{display:block;margin-left:0!important;font-size:11px;line-height:1.2}
.table-wrap{overflow-x:auto;border-radius:var(--radius-sm)}
table{width:100%;border-collapse:collapse;font-size:13px}
thead th{background:var(--bg2);color:var(--text2);font-weight:600;padding:11px 10px;text-align:center;border-bottom:1px solid var(--border);white-space:nowrap;font-size:var(--fs-caption)}
tbody td{padding:11px 10px;text-align:center;border-bottom:1px solid var(--border);white-space:nowrap;color:var(--text)}
tbody tr:hover{background:var(--bg2)}
.badge{display:inline-block;padding:3px 9px;border-radius:var(--radius-sm);font-size:11px;font-weight:600;line-height:1.5}
/* CPA-228：状态徽标按语义分色（投放中=绿 / 待上架=蓝 / 暂停中=橙 / 已挂起=红 / 已完成=灰 / 已下架=浅灰） */
.badge-active{background:#dcfce7;color:#15803d}
.badge-pending{background:#e6f4ff;color:#2563eb}
.badge-suspend{background:#fef2f2;color:#dc2626}
.badge-pause{background:#fff7ed;color:#ea580c}
.badge-done{background:var(--bg3);color:#475569}
.badge-offline{background:var(--bg3);color:#94a3b8}
/* CPA-138：开放API隐患账号（已开通API·未分配渠道）行高亮 + 角标 */
tbody tr.row-warn td{background:#fef2f2}
tbody tr.row-warn:hover td{background:#fee2e2}
.ag-badge-warn{display:inline-block;margin-left:4px;padding:0 4px;border:1px solid #dc2626;border-radius:3px;font-size:10px;font-weight:600;color:#dc2626;white-space:nowrap}
[data-theme="dark"] tbody tr.row-warn td{background:#3f1d1d!important}
[data-theme="dark"] tbody tr.row-warn:hover td{background:#4c1d1d!important}
[data-theme="dark"] .ag-badge-warn{border-color:#f87171;color:#f87171}
.link{color:var(--primary);cursor:pointer;text-decoration:none}
.link:hover{color:var(--primary-dark);text-decoration:underline}
/* CPA-195：弹窗遮罩必须高于常驻浮层（手机端底部导航 z-index:9999、批量条 9998），
   否则弹窗最下方的「提交/保存」按钮会被底部导航压住点不到。全站弹窗共用本层，改这一处即全站生效。 */
.modal-mask{display:flex;position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(15,23,42,.5);z-index:10000;justify-content:center;align-items:center;backdrop-filter:blur(3px);opacity:0;visibility:hidden;transition:opacity .2s ease,visibility .2s ease}
/* CPA-940：遮罩改为「常驻 flex + 透明可见性过渡」——弹窗打开时遮罩与面板一起淡入，关闭时一起淡出，
   不再瞬现瞬隐（视觉更柔和）；未打开时 visibility:hidden 不拦截点击。面板出入场动效见文件末尾 ②。
   ★CPA-948 返工（老板 2026-10-12「弹窗…有一个迟滞…不要让我有感觉有等待感」）：该淡入/出入场动效
   在文件末尾以「无等待感」覆盖块统一关闭（此处声明保留，便于回滚与守卫锚点不变）。 */
.modal-mask.show{opacity:1;visibility:visible}
.modal{position:relative;background:var(--card);border-radius:var(--radius-lg);width:600px;max-width:94vw;max-height:85vh;overflow-y:auto;overflow-x:hidden;padding:22px;box-shadow:var(--shadow-pop);box-sizing:border-box}
/* v6.19 统一弹窗右上角关闭X（CPA-940：键盘可达加 focus 环，移动端放大点按区域） */
.modal-x{position:absolute;top:10px;right:12px;z-index:30;width:30px;height:30px;border:none;background:var(--bg3);border-radius:var(--radius-pill);color:var(--text2);font-size:15px;line-height:30px;text-align:center;cursor:pointer;padding:0;transition:background .15s,color .15s,transform .15s}
.modal-x:hover{background:var(--border-strong);color:var(--text)}
.modal-x:active{transform:scale(.92)}
.modal-x:focus-visible{outline:2px solid var(--primary);outline-offset:2px}
.modal.modal-lg{width:960px;max-width:96vw}
.modal *{box-sizing:border-box}
.modal table{width:100%;border-collapse:collapse}
.modal table td,.modal table th{word-break:break-word;white-space:normal}
.modal input,.modal select,.modal textarea{width:100%;max-width:100%}
.modal h3{font-size:var(--fs-title);line-height:var(--lh-title);margin-bottom:18px;color:var(--text);font-weight:600}
.form-group{margin-bottom:14px}
.form-group label{display:block;font-size:13px;color:var(--text2);margin-bottom:5px;font-weight:500}
.form-group input,.form-group select,.form-group textarea{width:100%;padding:9px 12px;border:1px solid var(--border);border-radius:var(--radius-sm);font-size:13px;outline:none;transition:border-color .18s,box-shadow .18s;background:var(--card);color:var(--text)}
.form-group input:focus,.form-group select:focus,.form-group textarea:focus{border-color:var(--primary);box-shadow:var(--ring)}
.form-actions{display:flex;gap:10px;justify-content:flex-end;margin-top:20px}
.pagination{display:flex;justify-content:center;align-items:center;gap:8px;margin-top:14px}
.pagination button{padding:6px 14px;border:1px solid var(--border);background:var(--card);color:var(--text);border-radius:var(--radius-sm);cursor:pointer;font-size:var(--fs-caption);transition:border-color .15s,color .15s,background .15s}
.pagination button:hover:not(:disabled){border-color:var(--primary);color:var(--primary);background:var(--primary-light)}
.pagination button:disabled{opacity:.5;cursor:not-allowed}
/* ========== SVG图标系统 ========== */
.icon-svg{display:inline-block;width:1em;height:1em;vertical-align:-0.125em;fill:currentColor;stroke:currentColor;stroke-width:0}
.icon-svg-stroke{fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.nav-item .icon-svg{margin-right:6px;font-size:16px}
.card-header .icon-svg{margin-right:6px;font-size:18px}
.btn .icon-svg{margin-right:4px;font-size:14px}
.pagination .info{font-size:var(--fs-caption);color:var(--text2)}
textarea{resize:vertical;font-family:inherit}
.muted{color:var(--text2);font-size:var(--fs-caption)}
.empty{text-align:center;padding:40px;color:var(--text2);font-size:13px}
/* 复投/锁图标整改：取消「暂停中」行前锁图标，改为列表下方一处温馨提示（老板 2026-10-12） */
.task-pause-tip{margin-top:14px;padding:10px 14px;border-radius:var(--radius-sm);background:var(--warning-light,#fff7ed);border:1px solid #fed7aa;color:#b45309;font-size:13px;line-height:1.6}
[data-theme="dark"] .task-pause-tip{background:#3a2a12!important;border-color:#7c5216!important;color:#fbbf24!important}

/* ===== CPA-938·10 / CPA-941 更正：页面切换转场（渐进增强） =====
   CPA-938·10 原用 JS `document.startViewTransition(()=>location.assign(url))` 包跳转——本项目是 MPA
   （每个 page 是独立 html），导航会打断同文档 View Transition，既产生不了转场、又让导航白等一下并放大了
   整页白闪（老板 2026-10-12「切换 tab 页能看到白色闪屏」）。CPA-941 更正为**跨文档转场**的正确写法：
   纯 CSS opt-in（@view-transition{navigation:auto}），由浏览器接管先后快照，旧页在导航期间保留 ⇒ 不再白闪。
   不支持的浏览器忽略该 @规则（伪元素无效），零副作用。prefers-reduced-motion 下直接关闭动画。 */
@view-transition{navigation:auto}
::view-transition-old(root){animation:vtFadeOut 180ms ease both}
::view-transition-new(root){animation:vtFadeIn 180ms ease both}
@keyframes vtFadeOut{from{opacity:1}to{opacity:0}}
@keyframes vtFadeIn{from{opacity:0}to{opacity:1}}
@media (prefers-reduced-motion: reduce){::view-transition-old(root),::view-transition-new(root){animation:none!important}}

/* ===== CPA-938·11：空状态/错误态/无搜索结果 统一插画组件（common.js emptyState） ===== */
.empty-state{text-align:center;padding:40px 24px;color:var(--text2);font-size:13px}
.empty-state .empty-illus{display:flex;align-items:center;justify-content:center;margin:0 auto 10px;color:var(--text-tertiary,#94a3b8);opacity:.85}
.empty-state .empty-illus-svg{width:56px;height:56px}
.empty-state.empty-state-error .empty-illus{color:var(--danger,#ef4444)}
.empty-state .empty-title{font-size:14px;font-weight:600;color:var(--text);margin-bottom:4px}
.empty-state .empty-desc{font-size:12px;color:var(--text2);line-height:1.6;max-width:360px;margin:0 auto}
.empty-state .empty-action-btn{margin-top:14px;padding:6px 16px;border:1px solid var(--border);border-radius:var(--btn-radius,6px);background:var(--card);color:var(--text);font-size:13px;cursor:pointer;display:inline-flex;align-items:center;gap:4px}
.empty-state .empty-action-btn:hover{border-color:var(--primary);color:var(--primary)}
[data-theme="dark"] .empty-state .empty-title{color:#e2e8f0!important}
[data-theme="dark"] .empty-state .empty-desc{color:#94a3b8!important}
[data-theme="dark"] .empty-state .empty-illus{color:#64748b!important}
[data-theme="dark"] .empty-state.empty-state-error .empty-illus{color:#f87171!important}
[data-theme="dark"] .empty-state .empty-action-btn{background:#1e293b!important;color:#e2e8f0!important;border-color:#334155!important}

/* ===== CPA-938·13：表单就地实时校验（链接格式）红字提示 ===== */
.field-error{color:var(--danger,#ef4444);font-size:12px;line-height:1.4;margin-top:4px}
.field-invalid{border-color:#ef4444!important;box-shadow:0 0 0 2px rgba(239,68,68,.12)}
[data-theme="dark"] .field-error{color:#f87171!important}
[data-theme="dark"] .field-invalid{border-color:#f87171!important}
@media(max-width:768px){
  .login-wrap{background:var(--bg)!important}
  .login-wrap::before,.login-wrap::after{display:none}
  .login-card{width:92%;padding:32px 24px;box-shadow:var(--shadow-pop)}
  .stat-cards{grid-template-columns:repeat(2,1fr)}
  .topbar{padding:0 8px;overflow-x:auto;white-space:nowrap;-webkit-overflow-scrolling:touch}
  .topbar .nav-item{padding:0 12px;font-size:13px;flex-shrink:0}
  .topbar .logo{font-size:16px;padding:0 8px}
  .topbar .user-info{font-size:12px}
  .main{padding:10px}
  .card{border-radius:10px}
  /* CPA-172 手机端卡片内距统一收紧：本块此前把内距放大成 12px 14px / 12px，与上方 768 块（.card-header 10px 12px）打架，
     实际生效的是本块。这里改回与上方一致，让全站手机端卡片内距统一为 10px 12px（更紧凑、不挤内容）。 */
  .card-header{padding:10px 12px}
  .card-body{padding:10px 12px}
  .tabs{overflow-x:visible;flex-wrap:wrap;gap:4px;padding-bottom:0;white-space:normal}
  /* CPA-211：手机端标签/按钮行等分铺满整行（原 flex:0 1 auto 各按内容宽、换行后右缘参差且留白），
     改 flex:1 1 0 + min-width:max-content：行内各项按内容宽度换行，再等分吃掉整行剩余宽度，
     故每行左右两端都对齐、无空档（任务上传页 / 中控台配置中心等所有 .tabs 子页签共用）。 */
  .tabs .tab{flex:1 1 0;min-width:max-content;text-align:center;white-space:nowrap;padding:7px 10px;font-size:12px}
  .search-bar{flex-wrap:wrap;gap:8px}
  .search-bar label{font-size:12px}
  .search-bar input,.search-bar select{font-size:13px;padding:6px 8px}
  .batch-bar{gap:6px}
  .batch-bar .btn{font-size:11px;padding:4px 8px}
  .table-wrap{overflow-x:auto;-webkit-overflow-scrolling:touch}
  table{font-size:12px;min-width:700px}
  th,td{padding:8px 6px}
  .form-actions{flex-direction:row;gap:10px;justify-content:flex-end}
  .form-actions .btn{width:auto;min-width:80px;flex:1;max-width:160px}
  .modal{width:92%;max-height:85vh;overflow-y:auto;overflow-x:hidden;padding:20px 16px}
  .modal h3{font-size:16px;margin-bottom:14px}
  .modal .form-group{margin-bottom:12px}
  .modal .form-group label{font-size:12px}
  .modal .form-group input,.modal .form-group select,.modal .form-group textarea{font-size:14px;padding:10px 12px}
  .modal .form-actions{margin-top:18px;padding-top:14px;border-top:1px solid #f1f5f9}
  .modal *{box-sizing:border-box;max-width:100%}
  .modal table{min-width:0;width:100%;font-size:12px}
  .modal .table-wrap{overflow-x:auto;-webkit-overflow-scrolling:touch}
}

/* ========== 进度条 ========== */
.progress-col{min-width:100px;text-align:left}
/* CPA-045：电脑端隐藏『选到这』（shift+点击段选代替）；触屏设备保留 */
/* v6.58 CPA-064：PC(>768)已支持 shift 段选，不再显示“选到这”，并收紧勾选首列；手机(<=768)无 shift 必须保留“选到这”。
   改用屏宽断点而非 hover/pointer 媒体（触屏本/远程桌面 pointer 非 fine 会漏网，导致 PC 仍显示）。 */
@media (min-width:769px){
  .select-here{display:none!important}
  #taskTable th:first-child,#taskTable td:first-child{width:1%;padding-left:8px;padding-right:8px}
}
@media (max-width:768px){
  /* v6.73 手机端“选到这”未勾选时隐藏、勾选>=1条才出现；PC仍恒隐藏(见上 min-width:769) */
  .select-here{display:none!important}
  body.has-task-sel .select-here{display:inline-block!important}
}
/* CPA-172 字号统一：10px→11px（该元素在 PC(>=769) 恒被 display:none，实际只在手机端可见，故只影响手机端观感） */
.select-here{font-size:11px;color:var(--text-tertiary);cursor:pointer;padding:2px 6px;border-radius:4px;margin-left:4px;transition:all .2s}
/* v6.58 单任务行内联编辑：去掉“改/调/调整”文字后，数值本身可点，badge 可点 */
/* CPA-240①：任务列表内所有虚线下划线一律去掉（老板口径「所有的下滑线虚线去掉」），仅保留 hover 变色作为可编辑提示 */
.inline-edit{cursor:pointer;transition:color .15s}
.inline-edit:hover{color:var(--primary)}
/* CPA-260 需求①：状态列（点击调整任务状态）手机端点按阴影只应覆盖三字状态名，不得含左侧图标与空格。
   掐掉整块默认 tap 高亮，再把高亮单独挂到 .status-edit-text（三字）上；:active 再补一层以兼容不支持 tap-highlight 的环境。 */
.inline-edit[title="点击调整任务状态"]{-webkit-tap-highlight-color:transparent}
.inline-edit[title="点击调整任务状态"] .status-edit-text{-webkit-tap-highlight-color:rgba(127,127,127,.16);border-radius:5px}
.inline-edit[title="点击调整任务状态"]:active .status-edit-text{background:rgba(127,127,127,.16);box-shadow:0 0 0 3px rgba(127,127,127,.16)}
.badge-edit{cursor:pointer}
.badge-edit:hover{filter:brightness(.94)}
.select-here:hover{color:var(--primary);background:var(--primary-light)}
.select-here.active{color:var(--primary);background:var(--primary-light);font-weight:600}
.progress-bar{width:56px;height:6px;background:var(--bg3);border-radius:var(--radius-pill);overflow:hidden;display:inline-block;vertical-align:middle;margin-right:6px}
.progress-fill{height:100%;background:var(--primary);border-radius:var(--radius-pill);transition:width .3s}
.progress-text{font-size:11px;color:var(--text2);vertical-align:middle}
.quick-time-btn{font-size:11px;padding:2px 8px;border:1px solid var(--border);border-radius:var(--radius-sm);background:var(--bg2);color:var(--text2);cursor:pointer;transition:all .15s;white-space:nowrap}
.quick-time-btn:hover{background:var(--primary-light);color:var(--primary);border-color:var(--primary)}
.week-cell{user-select:none;-webkit-user-select:none;transition:background .1s,border-color .1s}
.week-cell:hover{border-color:var(--primary)!important}

/* ========== CPA-210 投放时段「每天」选择器：单日 24 小时时间轴（对齐简洁、美观大方） ========== */
.sched-radio-row{display:flex;align-items:center;gap:18px;flex-wrap:wrap}
.sched-radio{display:inline-flex;align-items:center;gap:6px;font-size:14px;color:var(--text);cursor:pointer;white-space:nowrap;flex-shrink:0;line-height:1.4}
.sched-radio input[type="radio"]{width:16px;height:16px;flex:0 0 auto;margin:0;accent-color:var(--primary);cursor:pointer}
/* 模态框内 label/input 会被 .form-group label{display:block} / .form-group input{width:100%} 命中，需提高优先级复位 */
.form-group .sched-radio-row{display:flex;align-items:center;gap:18px;flex-wrap:wrap;margin-bottom:2px}
.form-group .sched-radio-row .sched-radio{display:inline-flex;align-items:center;gap:6px;font-size:14px;color:var(--text);font-weight:400;margin-bottom:0;cursor:pointer;white-space:nowrap;flex-shrink:0;line-height:1.4}
.form-group .sched-radio-row .sched-radio input[type="radio"]{width:16px;height:16px;min-width:16px;flex:0 0 auto;margin:0;padding:0;accent-color:var(--primary);cursor:pointer}
/* 时间轴容器（renderWeekSchedule 自带，无需调用方加类） */
.sched-box{background:var(--bg2);border:1px solid var(--border);border-radius:var(--radius-sm);padding:14px}
.sched-toolbar{display:flex;align-items:center;justify-content:space-between;gap:10px;flex-wrap:wrap;margin-bottom:12px}
.sched-summary{font-size:13px;font-weight:600;color:var(--primary);line-height:1.5}
.sched-chips{display:flex;gap:8px;flex-wrap:wrap}
.sched-chip{font-size:12px;padding:4px 12px;border:1px solid var(--border);border-radius:var(--radius-pill);background:var(--card);color:var(--text2);cursor:pointer;transition:all .15s;white-space:nowrap;user-select:none}
.sched-chip:hover{background:var(--primary-light);color:var(--primary);border-color:var(--primary)}
.sched-grid{display:grid;grid-template-columns:repeat(12,1fr);gap:4px;touch-action:none;-webkit-user-select:none;user-select:none;-webkit-touch-callout:none}
.sched-grid .week-cell{height:30px;display:flex;align-items:center;justify-content:center;font-size:11px;color:var(--text2);border:1px solid var(--border);background:var(--card);border-radius:var(--radius-sm);cursor:pointer;touch-action:none}
.sched-grid .week-cell.on{background:var(--primary);border-color:var(--primary);color:#fff;font-weight:600}
.sched-hint{margin-top:12px;font-size:11px;color:var(--text-tertiary);line-height:1.5}
@media (max-width:768px){
  .sched-box{padding:12px 10px}
  .sched-grid{grid-template-columns:repeat(6,1fr);gap:6px}
  .sched-grid .week-cell{height:38px;font-size:12px}
  .form-group .sched-radio-row{gap:16px}
}

/* ========== CPA-172 数据中心「平台总览」时间范围筛选行（今日实时/昨天/最近7天/本月/最近30天/累计） ========== */
.ov-range-row{display:flex;gap:12px;flex-wrap:wrap;align-items:center}
@media (max-width:768px){
  /* CPA-182：老板要求「基于对齐、不需要左右滑、可以等比缩小文字」——六个范围按钮由横向滚动改为
     整行铺满、自动换行；按钮文字放宽不折行（窄屏优先缩字号），彻底消除「昨天」被挤成上下两字。 */
  .ov-range-row{flex-wrap:wrap;overflow:visible;gap:6px;min-width:0;max-width:100%}
  .ov-range-row button{padding:5px 9px!important;font-size:11px!important;white-space:nowrap!important}
}

/* ========== 底部版权 ========== */
.footer{text-align:center;padding:20px 16px;color:var(--text-tertiary);font-size:var(--fs-caption);border-top:1px solid var(--border);background:var(--card);display:flex;align-items:center;justify-content:center;gap:8px;flex-wrap:wrap}
.footer-sep{color:var(--border-strong)}
.mobile-footer{text-align:center;padding:16px;color:var(--text-tertiary);font-size:11px;border-top:1px solid var(--border);background:var(--card);margin-top:16px;display:flex;align-items:center;justify-content:center;gap:6px;flex-wrap:wrap}
@media(max-width:768px){.footer{display:none}}
/* ========== 移动端专用UI（支付宝风格） ========== */
.mobile-page{min-height:100vh;background:var(--bg);padding-bottom:20px}
.mobile-header{display:flex;justify-content:space-between;align-items:center;padding:16px;background:var(--primary);color:#fff;box-shadow:var(--shadow-sm)}
.mobile-header .logo{width:40px;height:40px;background:rgba(255,255,255,.2);border-radius:var(--radius-sm);display:flex;align-items:center;justify-content:center;font-size:20px}
.mobile-header .title{font-size:17px;font-weight:700}
.mobile-header .sub{font-size:var(--fs-caption);opacity:.85}
.mobile-header .logout{font-size:var(--fs-caption);padding:4px 12px;background:rgba(255,255,255,.2);border-radius:var(--radius-pill)}
.mobile-nav{display:flex;background:var(--card);padding:0 8px;border-bottom:1px solid var(--border);position:sticky;top:0;z-index:10;overflow-x:auto;flex-wrap:nowrap;scrollbar-width:thin;box-shadow:var(--shadow-sm)}
.mobile-nav::-webkit-scrollbar{height:3px}
.mobile-nav::-webkit-scrollbar-thumb{background:var(--border-strong);border-radius:2px}
.mobile-nav .nav-item{flex-shrink:0;text-align:center;padding:12px 14px;font-size:13px;color:var(--text2);white-space:nowrap;min-width:60px;font-weight:500;border-radius:var(--radius-sm) var(--radius-sm) 0 0}
.mobile-nav .nav-item.active{color:var(--primary);background:var(--primary-light);font-weight:600}
.mobile-section{padding:12px 16px 0}
.mobile-section-title{font-size:var(--fs-body);font-weight:600;color:var(--text);margin-bottom:10px}
.mobile-stats-grid{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-bottom:10px}
.mobile-stat-card{display:flex;align-items:center;gap:10px;background:var(--card);border:1px solid var(--border);border-radius:var(--radius);padding:12px;box-shadow:var(--shadow);position:relative;overflow:hidden}
.mobile-stat-card::before{content:'';position:absolute;left:0;top:0;bottom:0;width:3px;background:var(--primary)}
.mobile-stat-card .icon{width:36px;height:36px;border-radius:var(--radius-sm);display:flex;align-items:center;justify-content:center;font-size:16px;background:var(--primary-light);color:var(--primary);flex-shrink:0}
.mobile-stat-card .info{flex:1;min-width:0}
.mobile-stat-card .value{font-size:20px;font-weight:700;color:var(--text);font-variant-numeric:tabular-nums}
.mobile-stat-card .label{font-size:11px;color:var(--text-tertiary);margin-top:2px}
.mobile-task-card{background:var(--card);border:1px solid var(--border);border-radius:var(--radius);padding:14px;margin-bottom:10px;box-shadow:var(--shadow)}
.mobile-task-card .name{font-size:15px;font-weight:600;color:var(--text);margin-bottom:8px}
.mobile-task-card .meta{display:flex;align-items:center;gap:8px;margin-bottom:8px;flex-wrap:wrap}
.mobile-task-card .tag{font-size:11px;padding:2px 8px;background:var(--bg3);color:var(--text2);border-radius:var(--radius-sm)}
.mobile-task-card .pv{font-size:var(--fs-caption);color:var(--text-tertiary)}
.mobile-progress{height:5px;background:var(--bg3);border-radius:var(--radius-pill);overflow:hidden}
.mobile-progress .fill{height:100%;background:var(--primary);border-radius:var(--radius-pill)}
.mobile-nav-grid{display:grid;grid-template-columns:1fr 1fr 1fr 1fr;gap:10px}
.mobile-nav-item{position:relative;display:flex;flex-direction:column;align-items:center;gap:6px;background:var(--card);border:1px solid var(--border);border-radius:var(--radius);padding:14px 6px;box-shadow:var(--shadow)}
.mobile-nav-item .icon{font-size:22px}
.mobile-nav-item .name{font-size:var(--fs-caption);color:var(--text2)}
/* CPA-252 需求③：功能入口右上角「›」——提示点击会跳出本页（与其他页「xx ›」角标语义一致） */
.mobile-nav-item .nav-arrow{position:absolute;top:4px;right:8px;font-size:13px;font-weight:700;line-height:1;color:var(--border-strong);pointer-events:none}

/* ========== 移动端底部导航栏（固定底部） ========== */
.mobile-bottom-nav{
  display:none; /* 默认隐藏，移动端显示 */
  position:fixed;
  bottom:0;
  left:0;
  right:0;
  background:var(--card);
  border-top:1px solid var(--border);
  box-shadow:0 -2px 12px rgba(15,23,42,.08);
  z-index:9999; /* 确保在最上层，不被其他元素遮挡 */
  padding:8px 0 calc(8px + env(safe-area-inset-bottom));
}
.mobile-bottom-nav-inner{
  display:flex;
  justify-content:space-around;
  align-items:center;
  max-width:600px;
  margin:0 auto;
}
.mobile-bottom-nav-item{
  flex:1 1 0;
  min-width:0; /* 4 项等分：允许内容收缩，避免某一项被内容顶宽导致间距不均 */
  display:flex;
  flex-direction:column;
  align-items:center;
  justify-content:center;
  gap:5px;
  padding:11px 6px; /* 增加点击区域，同时保持 4 项视觉等距 */
  cursor:pointer;
  transition:all .2s;
  border-radius:10px;
  -webkit-tap-highlight-color:transparent; /* 移除移动端点击高亮 */
  touch-action:manipulation; /* 优化移动端点击响应 */
  position:relative;
  z-index:1;
}
.mobile-bottom-nav-item:active{
  background:var(--bg3);
  transform:scale(0.92);
}
.mobile-bottom-nav-item .icon{
  font-size:24px;
  line-height:1;
  display:flex;
  align-items:center;
  justify-content:center;
  pointer-events:none; /* 图标不拦截点击事件 */
}
/* 内联 svg 间距写死了 22px，用 CSS 统一放大到 24px，使图标与文字比例更均衡（免改所有 pages/*.html） */
.mobile-bottom-nav-item .icon svg{width:24px!important;height:24px!important}
.mobile-bottom-nav-item .name{
  font-size:12px;
  line-height:1.15;
  color:var(--text-tertiary);
  font-weight:500;
  white-space:nowrap;
  pointer-events:none; /* 文字不拦截点击事件 */
}
.mobile-bottom-nav-item.active .name{
  color:var(--primary);
  font-weight:600;
}
.mobile-bottom-nav-item.active .icon{
  transform:scale(1.08);
}
/* 移动端主内容区底部留白，避免被底部导航栏遮挡
   CPA-943：底栏净高再抬高（≈67px→≈79px），正文让位同步 70px→90px，避免末行内容被底栏压住。
   CPA-947（老板 2026-10-12「底部的 4 个 tab 改为跟放在顶部的时候一样大」）：底栏 4 入口尺寸回调、
   净高回落到 ≈57px，正文让位同步 90px→70px 收口，避免底部留出多余空白（与 CPA-265 的 70px 口径一致）。 */
.mobile-page .main{
  padding-bottom:70px;
}
.mobile-tabs{display:flex;background:var(--card);padding:0 8px;border-bottom:1px solid var(--border);overflow-x:auto;flex-wrap:nowrap;scrollbar-width:thin}
.mobile-tabs::-webkit-scrollbar{height:3px}
.mobile-tabs::-webkit-scrollbar-thumb{background:var(--border-strong);border-radius:2px}
.mobile-tabs .tab{flex-shrink:0;text-align:center;padding:12px 14px;font-size:13px;color:var(--text2);border-bottom:3px solid transparent;white-space:nowrap;min-width:70px;font-weight:500}
.mobile-tabs .tab.active{color:var(--primary);border-bottom-color:var(--primary);font-weight:600}
.mobile-card{background:var(--card);border:1px solid var(--border);border-radius:var(--radius);padding:16px;box-shadow:var(--shadow);margin:12px 16px}
.mobile-form-item{margin-bottom:14px}
.mobile-form-item label{display:block;font-size:13px;color:var(--text2);margin-bottom:6px;font-weight:500}
.mobile-form-item input,.mobile-form-item select,.mobile-form-item textarea{width:100%;padding:10px;background:var(--bg2);border:1px solid var(--border);border-radius:var(--radius-sm);font-size:var(--fs-body);box-sizing:border-box;color:var(--text)}
.mobile-btn{width:100%;padding:12px;border-radius:var(--radius-sm);font-size:15px;border:none;color:#fff;background:var(--primary);box-shadow:var(--shadow-sm)}
.mobile-btn-default{background:var(--bg3);color:var(--text2);box-shadow:none}
.mobile-btn-row{display:flex;gap:10px}
.mobile-btn-row .mobile-btn{flex:1}
.mobile-filter-bar{display:flex;gap:8px;padding:10px 16px;background:var(--card);flex-wrap:wrap;align-items:center}
.mobile-filter-bar select,.mobile-filter-bar input{padding:6px 10px;font-size:var(--fs-caption);border:1px solid var(--border);border-radius:var(--radius-sm);background:var(--bg2);color:var(--text)}
.mobile-filter-bar select.filter-active{background:var(--primary-light);border-color:var(--primary);color:var(--primary-dark);font-weight:500}
/* ===== v6.10 手机端任务页：筛选折叠 + 底部悬浮批量条 + 紧凑模式（PC端一律隐藏，仅手机媒体查询内显示） ===== */
#mTaskToolbar{display:none}              /* 手机任务工具行：筛选/紧凑/分页全览，PC隐藏 */
#mBatchFloat{display:none}               /* 底部悬浮批量操作条，默认隐藏，手机端勾选后浮出 */
#taskSearchBar{}
/* 悬浮批量条基础定位（手机端才 display:flex，见媒体查询） */
.m-batch-float{position:fixed;left:0;right:0;bottom:calc(62px + env(safe-area-inset-bottom));z-index:9998;background:var(--card);border-top:1px solid var(--border);box-shadow:0 -4px 16px rgba(0,0,0,.12);padding:8px 10px;align-items:center;gap:8px}
.m-batch-float .mbf-count{font-size:12px;font-weight:700;color:var(--primary);white-space:nowrap}
.m-batch-float .mbf-btns{display:flex;gap:6px;overflow-x:auto;-webkit-overflow-scrolling:touch;flex:1;padding-bottom:2px}
.m-batch-float .mbf-btns::-webkit-scrollbar{display:none}
.m-batch-float .mbf-btns button{font-size:11px;white-space:nowrap;padding:5px 10px;border:1px solid var(--border);border-radius:var(--radius-sm);background:var(--bg2);color:var(--text);flex-shrink:0}
.m-batch-float .mbf-clear{font-size:11px;white-space:nowrap;padding:5px 10px;border:none;border-radius:var(--radius-sm);background:var(--bg3);color:var(--text2);flex-shrink:0}
/* CPA-239⑧：手机端批量条右侧操作列（复制任务 / 取消选择，上下两行、右对齐） */
.m-batch-float .mbf-right{display:flex;flex-direction:column;gap:4px;flex:0 0 auto;align-items:stretch}
.m-batch-float .mbf-right button{font-size:11px;white-space:nowrap;padding:5px 10px;border:1px solid var(--border);border-radius:var(--radius-sm);background:var(--bg2);color:var(--text)}
.m-batch-float .mbf-right .mbf-clear{border:none;background:var(--bg3);color:var(--text2)}
/* 紧凑模式：手机端缩小任务表格行高/字号，隐藏次要列，一屏显示更多（PC不受影响，媒体查询内启用） */
.mobile-batch-bar{display:flex;gap:6px;padding:8px 16px;background:var(--card);flex-wrap:wrap;border-bottom:1px solid var(--border)}
.mobile-batch-bar button{font-size:11px;padding:4px 10px;border:1px solid var(--border);border-radius:var(--radius-sm);background:var(--card);color:var(--text2)}
.mobile-task-actions{display:flex;gap:6px;margin-top:10px}
.mobile-task-actions button{font-size:12px;padding:5px 12px;border-radius:6px;border:none;color:#fff}
.mobile-task-actions .btn-warning{background:#d4a843}
.mobile-task-actions .btn-success{background:#22c55e}
.mobile-task-actions .btn-default{background:#94a3b8}
.mobile-task-actions .btn-danger{background:#ef4444}
.mobile-empty{text-align:center;padding:30px;color:var(--text-tertiary);font-size:13px}
.mobile-pagination{display:flex;justify-content:center;align-items:center;gap:16px;padding:16px;font-size:13px;color:var(--text2)}
.mobile-pagination button{padding:6px 16px;border:1px solid var(--border);border-radius:var(--radius-sm);background:var(--card);color:var(--text);font-size:13px}

.batch-select-here.active{background:var(--primary)!important;color:#fff!important;}
.batch-row-check{accent-color:var(--primary);}
@keyframes numFlash{0%{color:var(--primary);font-weight:700;transform:scale(1.15)}50%{color:var(--accent)}100%{color:inherit;font-weight:inherit;transform:scale(1)}}
.num-flash{animation:numFlash 0.8s ease-out;display:inline-block}

/* ===================== v6.57 ===================== */
/* 需求3：顶部主导航(<a class=nav-item>)浏览器默认下划线根治——历史几次只改border-bottom未改到点 */
.topbar .nav-item,.topbar .nav-item:link,.topbar .nav-item:visited{text-decoration:none}
.topbar .nav-item:hover,.topbar .nav-item:active,.topbar .nav-item:focus,.topbar .nav-item.active{text-decoration:none}
.mobile-nav .nav-item,.mobile-nav .nav-item.active{text-decoration:none}
/* 需求2：分页/全览 移到状态筛选栏(全部/待上架..)最右的分段控件；PC显示，手机仍用 #mTaskToolbar 内 seg */
.task-view-seg{margin-left:auto;flex-shrink:0;align-self:center;display:flex;border:1px solid var(--border);border-radius:var(--btn-radius);overflow:hidden;background:var(--card);position:sticky;right:0;box-shadow:-8px 0 8px -8px rgba(0,0,0,.06)}
.task-view-seg button{font-size:12px;padding:6px 14px;border:none;background:var(--bg2);color:var(--text2);cursor:pointer;white-space:nowrap;transition:all .15s;font-weight:500}
.task-view-seg button:hover{color:var(--primary);background:var(--primary-light)}
.task-view-seg button.on{background:var(--primary);color:#fff;font-weight:600}
.task-view-seg #pcCompactBtn{border-right:1px solid var(--border)}
.task-view-seg #pcCompactBtn.active{background:var(--primary);color:#fff;font-weight:600}
/* CPA-228 需求C：「在投重复 N」——PC 段选内新增一颗；激活态与精简同色高亮，右侧留分隔线 */
.task-view-seg #pcDupBtn{border-right:1px solid var(--border)}
.task-view-seg #pcDupBtn.active{background:var(--primary);color:#fff;font-weight:600}
/* CPA-247：复投按钮内的重复双箭头沿用状态列的红色警示色（.st-ico-warn 默认无独立配色，仅 .st-warn-ico 下为红，
   故此处单独给 PC/手机两颗复投按钮内的双箭头着色），与「状态列前面的重复标识」保持同一视觉语义 */
.task-view-seg #pcDupBtn .st-ico-warn,#mDupBtn .st-ico-warn{color:#e60000;vertical-align:-2px;margin-right:3px}
/* CPA-248：复投数量特别大（N≥1000）时按钮内改竖排——「复投」（含图标）在上、数字在下，避免长数字撑乱按钮宽度。
   PC 段选为普通按钮、手机 .mtt-btn 本就是 flex ⇒ 统一用 flex-wrap + 数字 flex-basis:100% 强制换行到第二行。 */
.task-view-seg #pcDupBtn.dup-stack{display:inline-flex;flex-wrap:wrap;justify-content:center;align-items:center;column-gap:3px;row-gap:0;line-height:1.1}
.task-view-seg #pcDupBtn.dup-stack #pcDupCount{flex-basis:100%;text-align:center}
#mTaskToolbar #mDupBtn.dup-stack{flex-wrap:wrap;justify-content:center;column-gap:3px;row-gap:0;line-height:1.1}
#mTaskToolbar #mDupBtn.dup-stack #mDupCount{flex-basis:100%;text-align:center}
/* ===== CPA-250 需求①：PC 任务工具栏「变动史 / 复投N / 精简」与手机端外观统一 =====
   手机端对应件：变动史/复投 = .mtt-btn 胶囊（font-size:12px;padding:6px 5px;color:var(--text)）；
   精简/分页/全览 = .mtt-seg button（font-size:11px;padding:6px 6px;border:none;background:var(--bg2);color:var(--text2)），
   其激活态用浅色高亮（.active{background:var(--primary-light);color:var(--primary)}），实心态仅用于 分页/全览(.on)。
   PC 端对应件：变动史 = 表头 .task-hdr-btn[onclick=showBatchLogs]、复投/精简/分页展示/全览展示 = .task-view-seg button。
   此处只对齐视觉度量（内边距/字号/文字色/激活配色），不动 DOM 结构与 #taskViewSeg 内 4 颗按钮，
   保 cpa222 B6（_SEG_PC/_SEG_MOBILE 逐字）、cpa224 B1/B2（表头变动史与 seg 4 颗）、cpa247/cpa248 逐字锚点不破。
   【CPA-916 同步】手机端为让工具栏整行放下再度收窄（变动史/复投胶囊 6px 5px、seg 6px 6px），PC 侧同款度量同步收窄，
   维持「PC 与手机端外观统一」口径。 */
.card-header .task-hdr-btn[onclick="showBatchLogs()"]{padding:6px 5px;color:var(--text)}
.task-view-seg button{font-size:11px;padding:6px 6px}
.task-view-seg #pcCompactBtn.active,.task-view-seg #pcDupBtn.active{background:var(--primary-light);border-color:var(--primary);color:var(--primary);font-weight:600}
/* CPA-932（老板 2026-10-11）：原「到顶/到底」浮窗（CPA-248/257/259/260）整体移除——按钮、拖动换位/吸附/关闭、
   「我的」页开关与相关样式一并删除。
   CPA-934（老板 2026-10-12「刷新按钮干脆不要」）：CPA-917 的「刷新」浮钮（.task-refresh-float / .tsf-btn / tsf-refresh）
   亦整体移除——刷新入口统一走顶部筛选标签条 refreshTaskListNow / 下拉刷新 / 整页刷新，不再有右下角浮钮。 */
/* CPA-932/934（老板 2026-10-11/10-12）：备注提醒气泡——盖在「任务 ID」上的一次性提醒，点击/滚动/超时即呼吸式淡出
   （逻辑见 tasks.shared.js::popRemarkBubbles / _remarkBubblesFadeOut）。
   固定于视口（body 承载，绕开单元格 overflow:hidden 裁剪）。
   CPA-935（老板 2026-10-12「气泡的备注是点击查看」）：pointer-events 由 none 改为 auto + cursor:pointer，
   气泡可点击 → 打开只读全文弹窗（.remark-full）；清除监听已忽略气泡内事件，点击不会被提前清掉。 */
.task-remark-bubble{position:fixed;z-index:9998;max-width:240px;padding:7px 11px;border-radius:10px;background:var(--card);color:var(--text);border:1px solid var(--primary);box-shadow:var(--shadow-pop);font-size:12px;line-height:1.45;white-space:pre-wrap;word-break:break-word;pointer-events:auto;cursor:pointer;transform-origin:left center;animation:taskRemarkBubbleIn .24s cubic-bezier(.34,1.56,.64,1)}
.task-remark-bubble:hover{border-color:var(--primary);box-shadow:0 6px 18px rgba(0,0,0,.18)}
/* CPA-935：输入框实时字数提示（任务名称/备注共用） + 备注只读全文弹窗 */
.len-hint{text-align:right;font-size:12px;color:var(--text-tertiary);margin-top:4px}
.remark-full{white-space:pre-wrap;word-break:break-word;max-height:50vh;overflow:auto;font-size:13px;line-height:1.55;color:var(--text);background:var(--bg2);border:1px solid var(--border);border-radius:6px;padding:10px}
.task-remark-bubble.out{animation:taskRemarkBubbleOut .26s ease-in forwards}
@keyframes taskRemarkBubbleIn{0%{opacity:0;transform:scale(.92)}62%{opacity:1;transform:scale(1.04)}100%{opacity:1;transform:scale(1)}}
@keyframes taskRemarkBubbleOut{from{opacity:1;transform:scale(1)}to{opacity:0;transform:scale(.94)}}
/* CPA-257：通用小开关（历史上「我的」页深色模式「跟随系统」/ 功能 tab 位置 / 到顶到底 用；后两者已随功能调整不再引用，规则保留不降级） */
.my-switch{position:relative;display:inline-block;width:42px;height:24px;padding:0;border-radius:12px;border:1px solid var(--border);background:var(--bg3);cursor:pointer;transition:background .18s,border-color .18s;flex-shrink:0}
.my-switch.on{background:var(--primary);border-color:var(--primary)}
.my-switch-knob{position:absolute;top:2px;left:2px;width:18px;height:18px;border-radius:50%;background:#fff;box-shadow:0 1px 3px rgba(0,0,0,.25);transition:left .18s}
.my-switch.on .my-switch-knob{left:20px}
/* CPA-942（老板 2026-10-12）：个人设置「深色模式」「功能 tab 位置」由行内开关/分段改为「点击整行→弹窗选择」，
   弹窗内每个选项用 .my-opt-row（选中态 .on）。原 .my-mode-seg 分段样式随该形态取消。 */
.my-opt-row{display:flex;align-items:center;gap:12px;padding:12px 16px;border-radius:8px;border:1px solid transparent;cursor:pointer;transition:background .15s,border-color .15s,color .15s}
.my-opt-row.on{background:var(--primary-light);border-color:var(--primary);color:var(--primary);font-weight:600}
.my-opt-row .my-opt-ic{display:inline-flex;align-items:center}
/* 需求4：压测参与渠道——卡片芯片网格，电脑多列/手机自适应，选中渐变+对勾角标，替代旧竖排方框 */
.st-chk-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(118px,1fr));gap:8px}
.st-chk-empty{font-size:12px;color:var(--text-tertiary)}
.st-ch{position:relative;display:flex;flex-direction:column;gap:2px;padding:9px 12px;border-radius:var(--radius-sm);cursor:pointer;border:1.5px solid var(--border);background:var(--card);transition:all .15s;user-select:none}
.st-ch:hover{border-color:var(--primary);box-shadow:0 2px 8px rgba(15,23,42,.08);transform:translateY(-1px)}
.st-ch-name{font-size:13px;font-weight:600;color:var(--text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;padding-right:18px;line-height:1.3}
.st-ch-id{font-size:11px;color:var(--text-tertiary);font-weight:500}
.st-ch-tick{position:absolute;top:8px;right:9px;width:15px;height:15px;border-radius:50%;background:var(--border-strong);display:flex;align-items:center;justify-content:center;flex-shrink:0}
.st-ch-tick::after{content:"";display:none;width:7px;height:4px;border-left:2px solid #fff;border-bottom:2px solid #fff;transform:rotate(-45deg) translate(1px,-1px)}
.st-ch.on{border-color:var(--primary);background:var(--primary-light);box-shadow:var(--shadow-sm)}
.st-ch.on .st-ch-name{color:var(--primary-dark)}
.st-ch.on .st-ch-id{color:var(--primary)}
.st-ch.on .st-ch-tick{background:var(--primary)}
.st-ch.on .st-ch-tick::after{display:block}
[data-theme="dark"] .st-ch-id{color:#94a3b8}
[data-theme="dark"] .st-ch.on{background:rgba(22,119,255,.18);border-color:#4096ff}

/* ===== CPA-245：任务管理页「6 态状态栏 + 工具行」滚动吸顶 ===== */
/* 老板口径：任务多要下滑时，从「全部」到「筛选/变动史/复投/精简/分页/全览」这一整块应固定在顶部，
   随时可切状态/改筛选，不必滑回页首；桌面端占两行（状态行 + 筛选行），手机端占两行（状态行 + 工具行）。 */
/* .card 默认 overflow:hidden 会成为最近的可滚动祖先 ⇒ position:sticky 只贴卡片顶、不贴视口，吸顶必失效；
   故对本卡片放行 overflow。表头圆角因失去裁剪会外溢，单独补回。 */
#taskPageCard{overflow:visible}
#taskPageCard>.card-header{border-radius:var(--radius) var(--radius) 0 0}
.task-sticky-head{position:sticky;top:60px;z-index:30;background:var(--card);border-bottom:1px solid var(--border);box-shadow:0 6px 10px -8px rgba(15,23,42,.18)}
.task-sticky-head .tabs{margin-bottom:0}
.task-sticky-head .search-bar{margin:10px 18px 12px}
/* 顶栏在上小屏会换行增高（769-900px 为两行 ≈100px），吸顶偏移需随之抬高，否则会钻到顶栏下方被遮住 */
@media (min-width:769px) and (max-width:900px){.task-sticky-head{top:100px}}
@media (max-width:768px){.task-sticky-head{top:60px}}
@media (max-width:768px) and (max-height:500px){.task-sticky-head{top:44px}}

@media(max-width:768px){
  /* CPA-248：手机端上方 L842-845 的 .card{overflow-x:hidden!important} 会压过 L1266 无 !important 的
     #taskPageCard{overflow:visible}，使卡片成为最近可滚动祖先 ⇒ .task-sticky-head 的 position:sticky
     只贴卡片顶、不贴视口，手机端吸顶失效（老板「有一个功能没有加」）。此处用更高特异性 + !important 放行。 */
  #taskPageCard{overflow:visible!important}
  .task-view-seg{display:none!important}
  /* CPA-245：状态栏手机端由 CPA-222 的 3+3 两行改为「6 态恒定单行」。
     ① flex:1 1 0 + min-width:0：6 格严格等分容器宽、永不横溢 ⇒ 不需要左右滑（老板「自适应屏幕宽度」）；
     ② 每格 flex-wrap:wrap + 居中：状态名与数字放得下就并排，数字过大放不下时自动折行到状态名下方，
        单格高度略增但 6 格始终同处一行（老板「数字放在状态下面」）；
     ③ 覆盖内联 padding（原 0 18px 在 6 列下浪费近半宽）并抵消手机端 .tabs .tab 的 min-width:max-content。 */
  #taskStatusTabs{display:flex;flex-wrap:nowrap;gap:4px;overflow:visible;padding:4px 8px!important}
  /* CPA-948 返工（老板 2026-10-12）：手机端同样统一「上下结构」（上行=图标+状态名、下行=数量），
     不再用 flex-wrap 逐格折行 ⇒ 5 态/6 态结构一致，不再出现「有的上下、有的左右」参差。 */
  #taskStatusTabs .tab{flex:1 1 0;min-width:0;max-width:none;padding:6px 1px;font-size:11px;white-space:normal}
  .st-chk-grid{grid-template-columns:repeat(auto-fill,minmax(96px,1fr));gap:6px}
  .st-ch{padding:7px 9px;border-radius:8px;min-height:44px;justify-content:center}
  .st-ch-name{font-size:12px;padding-right:16px}
  .st-line-btn{min-height:44px;display:inline-flex;align-items:center;justify-content:center}
}

/* ===== v6.59 任务页精细化 ===== */
/* CPA-249 需求5：状态列「状态名 + 括号多图标」宽度自适应——三块（前缀图标列 / 状态名 / 括号区）一律 flex:0 0 auto
   互不收缩，杜绝图标被压扁/裁切；状态名与括号区各按内容取宽，整体随状态值的宽度自适应。 */
.status-edit-text{font-weight:500;white-space:nowrap;flex:0 0 auto}
.status-edit-text svg{vertical-align:-2px;margin-right:2px}
/* CPA-948（老板 2026-10-12 第六批第 2 条）：状态列 8 色重设——
   投放中‑消耗中 #00B42A / 投放中‑待消耗 #86D995 / 暂停中 #FF7D00 / 已挂起 #F53F3F /
   待上架 #1677FF / 已完成 #86909C / 已下架 #4E5969 / 回收站 #C9CDD4
   （消耗中=同渠道权重最小，优先投放，深绿；待消耗=同渠道其余投放中，浅绿；两者均为小字，见 .st-small） */
.st-consuming{color:#00B42A}.st-waiting{color:#86D995}.st-pause{color:#FF7D00}.st-suspend{color:#F53F3F}
.st-pending{color:#1677FF}.st-done{color:#86909C}.st-offline{color:#4E5969}.st-recycle{color:#C9CDD4}
/* CPA-948：消耗中/待消耗改为小字（老板「这两个类型辛苦帮我改为小字的那种」） */
.status-edit-text.st-small{font-size:11px}
/* CPA-948 返工2（老板 2026-10-12）：「投放中·消耗中 / 投放中·待消耗」6 字过长 ⇒ 状态列统一只显示「投放中」3 字，
   两个子态以「字重 + 深浅」区分：消耗中=加粗(600)+深绿(#00B42A)，待消耗=常规(400)+浅绿(#86D995)（色值沿用第六批口径不变）。
   用复合选择器提权，避免与 .status-edit-text{font-weight:500} 的先后顺序耦合。 */
.status-edit-text.st-consuming{font-weight:600}
.status-edit-text.st-waiting{font-weight:400}
/* CPA-951（老板 2026-10-12「好，按照你的推荐开始落地」/ 返工「实心的点用红心的点」）：投放中两个子态在
   原「字重+深浅」基础上再加「彩色状态点」，让「消耗中 / 待消耗」一眼可辨——消耗中=实心红点(#F53F3F，
   取本仓状态 8 色口径的「已挂起」红，不引入新色值)，待消耗=空心绿点(#86D995 描边)；文字仍只显「投放中」3 字，
   完整语义见悬停 title。空心底透明、描边取色 ⇒ 深浅色主题自适应。 */
.st-dot{display:inline-block;box-sizing:border-box;flex:0 0 auto;width:8px;height:8px;border-radius:50%;margin-right:.35em;vertical-align:middle}
.st-dot.st-consuming{background:#F53F3F;border:1.5px solid #F53F3F}
.st-dot.st-waiting{background:transparent;border:1.5px solid #86D995}
/* 兼容旧类名（避免历史调用点空样式）：st-active 仍归投放中底色语义（现由 st-consuming/st-waiting 派生细色） */
.st-active{color:#00B42A}
/* CPA-228：状态括号标记区（复制标记 + 排期三图标）；⚠ 需手动上架前缀 */
/* CPA-249 需求5：括号区不参与收缩；display:inline-flex + align-items:center 让「括号内多图标」与「前缀图标」
   在同一水平中线，消除上下错位；margin-left:.25em 补回 flex 容器中被丢弃的空白（原 `' <span>'` 前导空格失效）。 */
.st-paren{color:var(--text-tertiary);font-size:11px;letter-spacing:1px;white-space:nowrap;flex:0 0 auto;display:inline-flex;align-items:center;margin-left:.25em}
.st-paren .st-ico{vertical-align:-2px;margin:0 1px;color:var(--text2)}
.st-warn-ico,.st-ico-tip{display:inline-block;margin-right:2px;cursor:pointer;padding:2px 0}
.st-warn-ico .st-ico-warn{vertical-align:-2px;color:#e60000;width:1.15em;height:1.15em}
/* CPA-239②：警示图标放大到与状态名同字号（1em）并与状态文字留出间距 */
.st-warn-ico{margin-right:6px}
/* CPA-239④-2：暂停中锁定标（沿用暂停橙色，同字号） */
.st-lock-ico .st-ico{vertical-align:-2px;color:#ea580c;width:1.15em;height:1.15em}
/* CPA-239⑦：状态列前缀图标独立成列（更靠左、与文字留空隙），状态文字列统一左对齐 */
.st-cell{display:inline-flex;align-items:center;white-space:nowrap}
/* CPA-944（老板 2026-10-12「状态前面只留一个空格到 2 个就够了，也是有图标才移位」）：
   状态前图标槽「有图标才占位」——无图标时零宽零距（不再预留 1 个空格），有图标时才留约 1 个空格（.25em）。 */
.st-ico-col{display:inline-flex;align-items:center;justify-content:flex-start;gap:2px;flex:0 0 auto;min-width:0;margin-right:0}
.st-ico-col:not(:empty){margin-right:.25em}
.st-ico-col .st-warn-ico{margin-right:0}
#taskTable .remark-cell{width:130px;min-width:130px;max-width:130px!important;white-space:normal!important;word-break:break-word;overflow:hidden;vertical-align:top}
#taskTable .remark-cell .remark-text{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;color:var(--primary);font-size:12px;line-height:1.35}
#taskTable .remark-cell .remark-add{color:var(--text-tertiary);font-size:12px}
/* v6.61 紧凑模式：隐藏 任务ID/任务链接/排期/控量方式/变动记录 5个不常用列（th+td 均带 cc-hide），展开全部列时移除 body.task-compact；
   CPA-240：备注列改为随紧凑隐藏；PV/UV 四列（cc-hide）在精简态隐藏，改由合并列（cc-merge「今日/总」，按控量方式显对应指标）呈现 */
body.task-compact #taskTable .cc-hide{display:none!important}
body:not(.task-compact) #taskTable .cc-merge{display:none!important}
/* CPA-946（老板 2026-10-12「最后的取消精简按钮，可以去除了，风格变了」）：CPA-943 的精简态尾列提示胶囊
   整体移除（默认隐藏 / 精简态 table-cell / 胶囊按钮三条规则一并删除）——退出精简改由页面顶部「精简模式」
   开关（#mCompactBtn / #pcCompactBtn，均调 toggleTaskCompact）承担，列表末列不再占位。 */
/* CPA-946（老板 2026-10-12「今日完成改为完成进度。今日和总完成上下结构，变成小字」）：精简态合并列由
   原「今日完成 / 总完成」两列合并为一列「完成进度」——今日/总两行小字上下堆叠（百分比），限额≤0 时该行显「—」；
   两行各自可点开 CPA-241 访问明细弹窗。 */
.cc-progress{display:none!important}
body.task-compact #taskTable .cc-progress{display:table-cell!important;text-align:left;line-height:1.3;white-space:nowrap}
body.task-compact #taskTable .cc-progress .cc-progress-line{display:flex;align-items:baseline;gap:4px;font-size:11px;cursor:pointer}
body.task-compact #taskTable .cc-progress .cc-progress-line em{font-style:normal;font-size:10px;color:var(--text-tertiary);flex:0 0 auto}
body.task-compact #taskTable .cc-progress .cc-progress-line b{font-weight:600;font-size:11px;color:var(--text);font-variant-numeric:tabular-nums}
/* CPA-948 返工（老板 2026-10-12）：「精简模式下的完成进度……我本来是让你在表格里面做那个数字背后的
   那个进度条……你在普通模式，非精简模式下你不是都能给我弄了个背景进度条吗？」——精简态「完成进度」
   列不再是独立百分比行，而是让「数值（管理员）/百分比（代理商）」两行各自铺满列宽，条宽由行内
   linear-gradient 依完成度渲染（复用普通模式 progressCell 同款手法）。故此处仅补「铺满列宽 + 内缩圆角」，
   行内条由 JS 注入；原精简态底部的独立百分比行（CPA-948 第六批引入）随之删除。 */
body.task-compact #taskTable .cc-progress .cc-progress-line{box-sizing:border-box;width:100%;padding:1px 5px;border-radius:3px}
/* CPA-944（老板 2026-10-12「精简模式，变成 3 列 状态 任务名称 今日完成（背景百分比）」）：
   精简态只保留 3 个数据列（状态 / 任务名称 / 今日完成·背景百分比），其余数据列（渠道/权重/排期/日限量/总限量/总完成/归属人）随 cc-hide2 隐藏；
   渠道与权重改由任务名称后的小字「（渠道，权重）」呈现（.cc-only 仅精简态显示）。勾选列与末列提示胶囊为功能列，不计入 3 个数据列。 */
body.task-compact #taskTable .cc-hide2{display:none!important}
#taskTable .cc-only{display:none!important}
body.task-compact #taskTable .cc-only{display:inline!important;font-size:11px;color:var(--text-tertiary);margin-left:3px;font-weight:400}
/* CPA-948 第四轮返工（老板 2026-10-12「任务名称长一些的，渠道号和权重看不到了」）：任务名称与名称后的
   「（渠道，权重）」小字（cc-only）同处一个 flex 行——名称可收缩并省略号截断，cc-only 不收缩、始终可见。
   旧结构下名称与 cc-only 是同 td 内的相邻 inline，长名称会把 cc-only 挤出 td 被 overflow:hidden 裁掉。
   td 内联 max-width:160px + ellipsis 原样保留（cpa166 A6 判据不动），此处仅新增包裹层规则。 */
#taskTable .cc-name-wrap{display:flex;align-items:baseline;min-width:0}
#taskTable .cc-name-wrap > .inline-edit{flex:0 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
#taskTable .cc-name-wrap > .cc-only{flex:0 0 auto}
/* CPA-944（老板 2026-10-12「注意状态列的对齐」）：精简态状态列与全览态统一左对齐（原 CPA-243③ 为居中覆盖，
   已作废）；图标槽「有图标才移位」由 .st-ico-col 基础规则统一保证，此处不再做绝对定位特例。 */
/* CPA-249 需求5：手机紧凑态状态列原受 max-width:120px + overflow:hidden 夹逼，多图标（前缀重复/锁定标）时
   图标被裁掉、前后图标共同挤占致偏移；此处放开宽度上限并允许溢出可见，列宽随「状态名 + 图标」内容自适应。 */
body.task-compact #taskTable td:nth-child(2){max-width:none!important;overflow:visible!important}
/* CPA-173① 表头按钮「上下失真」修复：三颗按钮共用本类，但「上传」内含图标而曾受 .card-header .icon-svg 的 18px 影响，
   内容高 18px（≈32px 按钮）比只有文字的「已下架/回收站」（12px，≈26px）高一截。改为 inline-flex 垂直居中 + 图标取 1em
   （=按钮字号），三颗按钮内容高都等于文字行高，总高一致；vertical-align:middle 让它与「任务管理」标题文字对齐。 */
.task-hdr-btn{border:1px solid var(--border);background:var(--bg2);color:var(--text2);font-size:12px;line-height:1;padding:6px 10px;border-radius:var(--btn-radius);cursor:pointer;transition:all .15s;white-space:nowrap;display:inline-flex;align-items:center;justify-content:center;vertical-align:middle}
.task-hdr-btn .icon-svg{font-size:1em;margin-right:4px;vertical-align:0}
.task-hdr-btn:hover{border-color:var(--primary);color:var(--primary)}
.task-hdr-btn.active{background:var(--primary-light);border-color:var(--primary);color:var(--primary);font-weight:600}
.task-offline-btn.active{background:var(--border-strong);border-color:var(--text-tertiary);color:var(--text);font-weight:700}
@media(max-width:768px){.task-hdr-btn{padding:5px 8px;font-size:11px}}
/* CPA-203 回退 CPA-171/CPA-202 的手机端特例：老板拍板「表头图标加上后很好看、很好用，也不拥挤，
   在线版本下回收站留存在任务管理里」，故手机端表头与电脑端同形态——回收站按钮的图标与文字都显示，
   只沿用上一行的 ≤768px 缩字兜底（padding 5px 8px / font-size 11px），不再有任何隐藏规则。 */
/* CPA-173② 任务管理页内「回收站」视图：批量条上的按钮换成回收站语义（批量恢复/批量复制名称）——
   原「批量改渠道/改状态/改限量/改排期/改归属」对回收站里已删除的任务没有意义；body.in-recycle 由 applyRecycleView() 切换。
   #taskBatchBar 是电脑端批量条、#mBatchFloat 是手机底部悬浮条，两者按钮集相同，故两条规则一并换。 */
.rbf-only{display:none!important}
body.in-recycle #taskBatchBar .batch-row > button:not(.rbf-only){display:none!important}
body.in-recycle #mBatchFloat .mbf-btns > button:not(.rbf-only){display:none!important}
body.in-recycle #taskBatchBar .batch-row > button.rbf-only{display:inline-block!important}
body.in-recycle #mBatchFloat .mbf-btns > button.rbf-only{display:inline-flex!important}
/* CPA-073 非紧凑(全列展开)模式：任务表按容器自适应列宽；紧凑(默认)模式维持原样，手机端维持原生横滑 */
/* CPA-166 修复：原 table-layout:fixed + 全列 text-overflow:ellipsis，全列展开时 18 列里只有 4 列有显式宽度，
   其余列（含今日/总 PV·UV 等数值列、以及带排序箭头+筛选漏斗的表头）被均分到约 50px 后裁成「…」，完全不可用。
   改为 auto 布局 + width:max-content（每列取自身内容宽，不再被挤到内容之下，既不裁「…」也不与邻列重叠），
   min-width:100% 保证宽屏下表仍铺满容器；总宽超出容器时才横向滚动——宁可横向滚，也不要「…」。 */
@media(min-width:769px){
  body:not(.task-compact) #taskTable{overflow-x:auto}
  body:not(.task-compact) #taskTable table{width:max-content;min-width:100%;table-layout:auto}
  body:not(.task-compact) #taskTable th,
  body:not(.task-compact) #taskTable td{white-space:nowrap;padding-left:4px;padding-right:4px}
  body:not(.task-compact) #taskTable th:nth-child(1),
  body:not(.task-compact) #taskTable td:nth-child(1){width:44px;text-align:left}
  body:not(.task-compact) #taskTable .progress-col{white-space:nowrap}
}
/* CPA-074 暗黑模式补漏：把内联写死浅色的按钮/开关/标签/信息块在 dark 下统一压暗（!important 覆盖内联浅色，浅色主题外观不变） */
[data-theme="dark"] .st-ch-tick{background:#475569!important}
[data-theme="dark"] .task-hdr-btn{background:#0f172a!important;border-color:#334155!important;color:#cbd5e1!important}
[data-theme="dark"] .task-hdr-btn:hover{border-color:#4096ff!important;color:#7cc0ff!important}
[data-theme="dark"] .task-hdr-btn.active{background:rgba(22,119,255,.22)!important;border-color:#4096ff!important;color:#7cc0ff!important}
[data-theme="dark"] .task-offline-btn.active{background:#334155!important;border-color:#475569!important;color:#e2e8f0!important}
[data-theme="dark"] .st-line-btn{background:#0f172a!important;border-color:#334155!important;color:#cbd5e1!important}
[data-theme="dark"] .tool-tab{background:#0f172a!important;color:#cbd5e1!important;border:1px solid #334155!important}
[data-theme="dark"] .tool-tab.on,[data-theme="dark"] .tool-tab.active{background:rgba(22,119,255,.22)!important;color:#7cc0ff!important;border-color:#4096ff!important}
[data-theme="dark"] .d-tint{background:#0f172a!important;color:#cbd5e1!important;border-color:#334155!important}
[data-theme="dark"] .d-tint-red{background:rgba(248,113,113,.13)!important;color:#fca5a5!important;border-color:rgba(248,113,113,.30)!important}
[data-theme="dark"] .d-tint-green{background:rgba(52,211,153,.13)!important;color:#6ee7b7!important;border-color:rgba(52,211,153,.30)!important}
[data-theme="dark"] .d-tint-orange{background:rgba(251,191,36,.13)!important;color:#fcd34d!important;border-color:rgba(251,191,36,.30)!important}
[data-theme="dark"] .d-tint-blue{background:rgba(64,150,255,.13)!important;color:#7cc0ff!important;border-color:rgba(64,150,255,.30)!important}
[data-theme="dark"] .d-status-box{background:#0f172a!important}
/* 暗底下内联写死的深灰/近黑文字提亮（状态红绿等彩色保留） */
[data-theme="dark"] .d-tint [style*="#1e293b"],[data-theme="dark"] .d-status-box [style*="#1e293b"]{color:#e2e8f0!important}
[data-theme="dark"] .d-tint [style*="#64748b"],[data-theme="dark"] .d-status-box [style*="#64748b"]{color:#94a3b8!important}
/* 中性浅色内联兜底：dark 下把写死的浅灰/纯白底块统一压暗（语义红绿橙蓝由 .d-tint-* 精细处理；浅色主题完全不受影响） */
[data-theme="dark"] [style*="background:#f8fafc"],
[data-theme="dark"] [style*="background:#f1f5f9"],
[data-theme="dark"] [style*="background:#f5f7fa"],
[data-theme="dark"] [style*="background:#fafafa"],
[data-theme="dark"] [style*="background:#f5f5f5"],
[data-theme="dark"] [style*="background:#f4f4f5"],
[data-theme="dark"] [style*="background:#fff"]{background-color:#0f172a!important}
/* dark 下内联写死的中性深色文字提亮（彩色状态文字保留） */
[data-theme="dark"] [style*="color:#1e293b"]{color:#e2e8f0!important}
[data-theme="dark"] [style*="color:#334155"],[data-theme="dark"] [style*="color:#475569"]{color:#cbd5e1!important}
[data-theme="dark"] [style*="color:#64748b"]{color:#94a3b8!important}
[data-theme="dark"] [style*="border-color:#e2e8f0"],[data-theme="dark"] [style*="border:1px solid #e2e8f0"],[data-theme="dark"] [style*="border-bottom:1px solid #f1f5f9"]{border-color:#334155!important}
/* 浅彩语义块 dark 兜底：按内联色值压成半透深色（绿/红/黄/蓝/粉），渐变背景一并覆盖 */
[data-theme="dark"] [style*="#f0fdf4"],[data-theme="dark"] [style*="#dcfce7"],[data-theme="dark"] [style*="#bbf7d0"],[data-theme="dark"] [style*="#f0fdfa"],[data-theme="dark"] [style*="#ccfbf1"]{background:rgba(52,211,153,.13)!important;border-color:rgba(52,211,153,.30)!important}
[data-theme="dark"] [style*="#fef2f2"],[data-theme="dark"] [style*="#fee2e2"],[data-theme="dark"] [style*="#fecaca"]{background:rgba(248,113,113,.13)!important;border-color:rgba(248,113,113,.30)!important}
[data-theme="dark"] [style*="#fffbeb"],[data-theme="dark"] [style*="#fef3c7"],[data-theme="dark"] [style*="#fde68a"]{background:rgba(251,191,36,.13)!important;border-color:rgba(251,191,36,.30)!important}
[data-theme="dark"] [style*="#eff6ff"],[data-theme="dark"] [style*="#dbeafe"],[data-theme="dark"] [style*="#bfdbfe"]{background:rgba(64,150,255,.13)!important;border-color:rgba(64,150,255,.30)!important}
[data-theme="dark"] [style*="#fdf2f8"],[data-theme="dark"] [style*="#fce7f3"],[data-theme="dark"] [style*="#fbcfe8"]{background:rgba(244,114,182,.13)!important;border-color:rgba(244,114,182,.30)!important}
/* 暗底下深彩文字提亮 */
[data-theme="dark"] [style*="color:#15803d"],[data-theme="dark"] [style*="color:#166534"]{color:#6ee7b7!important}
[data-theme="dark"] [style*="color:#991b1b"],[data-theme="dark"] [style*="color:#9f1239"],[data-theme="dark"] [style*="color:#b91c1c"]{color:#fca5a5!important}
[data-theme="dark"] [style*="color:#92400e"],[data-theme="dark"] [style*="color:#854d0e"]{color:#fcd34d!important}
[data-theme="dark"] [style*="color:#1e40af"],[data-theme="dark"] [style*="color:#1e3a8a"]{color:#7cc0ff!important}
/* 外发数据查看 .dv-m 语义统计卡 dark（CPA-954：补默认蓝卡底色/描边，此前只盖了 green/amber/pink，
   默认 .dv-m 仍取本地 --tg1=#f0f9ff 浅蓝 → 深色下整块发白） */
[data-theme="dark"] .dv-m,[data-theme="dark"] .dv-m.green,[data-theme="dark"] .dv-m.amber,[data-theme="dark"] .dv-m.pink{background:#0f172a!important;border-color:#334155!important}
[data-theme="dark"] .dv-m .l{color:#94a3b8!important}
/* CPA-954：外发数据查看页表格悬停/斑马底 dark（.dv-tbl 用本地 --tg1 浅蓝，深色下悬停发白） */
[data-theme="dark"] .dv-tbl tbody tr:hover{background:#16233b!important}
/* CPA-954：媒体日志标签 .mlog-tag 此前无深色覆盖，亮橙底在深色卡片上突兀 */
[data-theme="dark"] .mlog-tag{background:rgba(251,191,36,.13)!important;color:#fcd34d!important;border:1px solid rgba(251,191,36,.30)!important}
[data-theme="dark"] .ftag.sort{background:rgba(251,191,36,.13)!important;color:#fcd34d!important;border-color:rgba(251,191,36,.30)!important}
[data-theme="dark"] .ubm-fail{background:rgba(248,113,113,.13)!important;color:#fca5a5!important}
/* CPA-074 第二轮补漏（WB B264/B268 复扫残留15处：media_console整页+home3+toolbox2；渐变用 background 简写连 gradient 一起盖） */
[data-theme="dark"] [style*="#ecfeff"],[data-theme="dark"] [style*="#f0f9ff"],[data-theme="dark"] [style*="#e0f2fe"],[data-theme="dark"] [style*="#bae6fd"],[data-theme="dark"] [style*="#eaf2ff"]{background:rgba(64,150,255,.12)!important;border-color:rgba(64,150,255,.28)!important}
[data-theme="dark"] [style*="#faf5ff"],[data-theme="dark"] [style*="#f3e8ff"],[data-theme="dark"] [style*="#f5f3ff"],[data-theme="dark"] [style*="#ddd6fe"]{background:rgba(167,139,250,.12)!important;border-color:rgba(167,139,250,.30)!important}
[data-theme="dark"] [style*="#fcd34d"]{border-color:rgba(251,191,36,.35)!important}
[data-theme="dark"] [style*="#cbd5e1"]{border-color:#334155!important}
[data-theme="dark"] [style*="#eef2f7"]{border-color:#334155!important}
[data-theme="dark"] [style*="color:#0284c7"]{color:#7dd3fc!important}
[data-theme="dark"] [style*="color:#9a3412"]{color:#fdba74!important}

/* ===== WB-B266/CPA-075 极简流主题（纯CSS浅色，主按钮 --primary-dark 对白均过 WCAG AA≥4.5；只动容器不改顶部导航底色；石墨暗夜/新粗野/柔软/清新风已按老板口径下线） ===== */
/* 极简流：近黑主色、去阴影、细线、小圆角、留白 */
[data-theme="minimal"]{--primary:#1c1b18;--primary-dark:#000000;--primary-light:#f0efec;--accent:#57534e;--accent-light:#f5f5f4;--success:#047857;--warning:#b45309;--danger:#dc2626;--bg:#fafaf9;--card:#ffffff;--text:#1c1b18;--text2:#6b675f;--border:#e7e5e0;--radius:4px;--shadow:none;--btn-radius:4px;--bg2:#f5f5f4;--bg3:#efeeea;--card-border:1px solid #e7e5e0}
[data-theme="minimal"] body{background:#fafaf9}
[data-theme="minimal"] .card,[data-theme="minimal"] .stat-card{border:1px solid #e7e5e0;box-shadow:none!important;border-radius:4px}
[data-theme="minimal"] .btn-primary{box-shadow:none!important}
[data-theme="minimal"] table th{background:#f5f5f4;color:#1c1b18;border-bottom:1px solid #1c1b18}
[data-theme="minimal"] input,[data-theme="minimal"] select,[data-theme="minimal"] textarea{border:1px solid #d6d3cd;border-radius:4px;box-shadow:none!important}
[data-theme="minimal"] .tab.active{background:transparent;border-bottom:2px solid #000;border-radius:0}
/* ===== CPA-250 需求⑥：新增「工业风 / 清新风」两主题 + 「我的」头像卡片按主题取色 =====
   老板口径：我的页卡片背景是纯蓝不协调，按不同主题换和谐一致的背景色；再加 2 个带具体背景的科技主题（工业风/清新风）。
   --my-card-bg 已在 :root 用 var(--primary)、var(--primary-dark) 派生，各主题无需重复定义；此处只补两个新主题。 */
[data-theme="industrial"]{--primary:#475569;--primary-dark:#1e293b;--primary-light:#e2e8f0;--accent:#0ea5e9;--accent-light:#e0f2fe;--success:#047857;--warning:#b45309;--danger:#dc2626;--bg:#eaeef3;--card:#ffffff;--text:#1e293b;--text2:#64748b;--border:#d3dae3;--border-strong:#b6c1cd;--bg2:#eef2f6;--bg3:#e3e9ef;--radius:6px;--btn-radius:6px}
[data-theme="industrial"] body{background:linear-gradient(180deg,#eaeef3 0%,#dfe6ee 100%);background-attachment:fixed}
[data-theme="industrial"] .card,[data-theme="industrial"] .stat-card{border:1px solid #d3dae3}
[data-theme="industrial"] table th{background:#eef2f6;color:#1e293b}
/* 「我的」头像卡片背景：按主题取 --my-card-bg（:root 用当前主题 --primary-light/--card 派生，CPA-274 改）。
   卡片原为内联 background:var(--primary)（cpa172 D2 逐字锚定，不能改），故此处用 !important 覆盖内联。 */
.my-card{background:var(--my-card-bg,var(--primary))!important}
/* CPA-274 需求⑤⑥：「我的」卡片底色压淡后，原内联 color:#fff 会看不清 —— 文字随主题取 --text
   （浅色主题=深字、深色模式=浅字）；头像圆圈原为 rgba(255,255,255,.2)（在淡底上等于没有），
   改用 --bg3 底 + --border 描边，两个主题域都清晰。仍是 CSS !important 覆盖内联，保 cpa172 D2 字面量不破。 */
.my-card{color:var(--text)!important}
.my-card div[style*="rgba(255,255,255,.2)"]{background:var(--bg3)!important;border:1px solid var(--border)!important}

/* CPA-074 第三轮：内联色值若写成 rgb() 形态，前两轮 #hex 属性选择器命中不到（home异常卡/媒体台同类），补 rgb 形态兜底 */
[data-theme="dark"] div[style*="rgb(255, 255, 255)"],[data-theme="dark"] div[style*="rgb(255,255,255)"],[data-theme="dark"] span[style*="rgb(255, 255, 255)"],[data-theme="dark"] span[style*="rgb(255,255,255)"],[data-theme="dark"] li[style*="rgb(255, 255, 255)"],[data-theme="dark"] td[style*="rgb(255, 255, 255)"]{background-color:#1e293b!important}
[data-theme="dark"] [style*="rgb(254, 202, 202)"],[data-theme="dark"] [style*="rgb(254,202,202)"]{border-color:rgba(248,113,113,.30)!important}

/* ===== CPA-109 / REQ-002 手机端弹窗展示不全 + 整页防横滑 统一加固 ===== */
@media (max-width:768px){
  /* 页面级禁止整页左右横滑（数据表仍可在 .table-wrap 容器内横滑）
     必须用 overflow-x:clip 而非 hidden：hidden 会让 html/body 成为滚动容器（另一轴被计算成 auto），
     任务页 .task-sticky-head 的 position:sticky 便无法相对视口吸顶；clip 只裁剪、不建立滚动容器，吸顶与防横滑可兼得。
     保留 hidden 作旧内核兜底，后写的 clip 在支持内核中生效（cascade 后者覆盖前者）。 */
  html,body{max-width:100%;overflow-x:hidden;overflow-x:clip}
  img,video,pre,canvas{max-width:100%}
  /* CPA-943（老板 2026-10-12「首页平台汇总弹窗底部没有弹窗感，需要小点，跟底部 tab 重合了 其他同理」）：
     遮罩底部让出底栏高度（calc(88px + safe-area)）→ 弹窗整体上移、不再压在底部 tab 上；
     弹窗高度收小为 calc(100dvh - 124px)，上下都留出「弹窗感」（改用 dvh 兼容 iOS 地址栏遮挡，超高可滚）。 */
  .modal-mask{align-items:center;padding:12px 10px calc(88px + env(safe-area-inset-bottom))}
  .modal{width:100%!important;max-width:100%!important;max-height:calc(100vh - 124px);max-height:calc(100dvh - 124px);padding:18px 14px;overflow-y:auto;overflow-x:hidden;-webkit-overflow-scrolling:touch}
  .modal.modal-lg{width:100%!important}
  /* 弹窗内任何写死宽度的元素一律不超出容器 */
  .modal [style*="width:"]{max-width:100%!important}
  /* 弹窗内所有内联栅格在窄屏自适应换行，不再多列挤压/把弹窗撑宽 */
  .modal [style*="grid-template-columns"]{grid-template-columns:repeat(auto-fit,minmax(min(100%,120px),1fr))!important}
  /* 宽表格只在表内横滑，不撑宽弹窗；单元格允许换行 */
  .modal table{min-width:0!important;width:100%}
  .modal .table-wrap{overflow-x:auto;-webkit-overflow-scrolling:touch}
  /* JSON/长文本/代码块换行，不横向溢出 */
  .modal pre,.modal code,.modal textarea{white-space:pre-wrap;word-break:break-word;max-width:100%}
  /* 底部操作按钮可换行、等宽、触控区足够，不被裁切 */
  .modal .form-actions{flex-wrap:wrap}
  .modal .form-actions .btn{flex:1 1 auto;min-width:120px}
  /* CPA-940：移动端把右上角 ✕ 放大到 38px，满足触控最小点按区域，更好按 */
  .modal-x{top:8px;right:10px;width:38px;height:38px;line-height:38px;font-size:17px}
}
@media (max-width:380px){
  /* iPhone SE 等超窄屏：弹窗内栅格一律单列 */
  .modal [style*="grid-template-columns"]{grid-template-columns:minmax(0,1fr)!important}
}

/* CPA-109 / REQ-002 手机端页面级宽表兜底：未包 .table-wrap 的表格不强制全局 700 最小宽，列换行显示而非整列被裁切；需横滑的宽表应包 .table-wrap（压测分渠道结果表已包） */
@media (max-width:768px){
  table:not(.table-wrap table):not(.modal table){min-width:0!important;width:100%}
}

/* ===== CPA-175① 撤销 CPA-174① 的手机端导航置顶 =====
   （老板原话：「刚才调上去之后，我发现这 4 个功能键放在上面不好看，我们把它再改回放到下面去。」）
   CPA-174① 曾把 .mobile-bottom-nav 由固定底部改到固定顶部（top:0 + --mnav-h:52px + .app 占位 +
   把 .main/.mobile-page .main 的底部让位 80px/70px 作废为 16px）。本单整块删除以**恢复基础规则**：
     .mobile-bottom-nav{position:fixed;bottom:0;z-index:9999}（上 L1057）、
     .main{padding:10px 10px 80px 10px}、.mobile-page .main{padding-bottom:70px}、
     [data-theme="dark"] .mobile-bottom-nav{border-top:1px solid #334155!important}
   即 4 个功能键回到屏幕底部，与 HTML 无关（13 个页面外壳一个字都没改）。 */

/* ===== CPA-174② 手机端批量条：贴底显示 + 按钮换行铺满（老板：批量的操作都看不到） =====
   触发口径不变（仍是勾选任务后才浮出，updateMobileBatchBar 未动），只修位置与可见性。
   CPA-175② 后前提更新：导航已回到（并会在勾选期隐藏于）底部，故批量条仍贴底独占底部。 */
@media (max-width:768px){
  /* ① 批量条贴底（勾选期底部导航被隐藏，故可 bottom:0；旧 62px 让位 < 导航实测高 87.3px，下沿约 25px 曾被压住） */
  .m-batch-float{bottom:0;padding-bottom:calc(8px + env(safe-area-inset-bottom))}
  /* ② 按钮由「一行横滑」改为「换行铺满」：勾选后所有按钮一屏可见，不再需要左右滑动 */
  .m-batch-float .mbf-btns{flex:1 1 auto;flex-wrap:wrap;overflow:visible;padding-bottom:0}
  /* ③ 勾选期间给主内容区让位，避免贴底的批量条盖住列表最后几行（复用既有 body.has-task-sel 类，未新增 JS）
     让位值 120px 取自实测：换行后批量条实测高 77px（内容宽 375）/110px（内容宽 345），取最大值再留余量 */
  body.has-task-sel .main{padding-bottom:120px}
  /* ④ CPA-175② 勾选任务浮出批量条时，底部 4 个导航按钮整体让位（老板：只出现批量操作的这个功能）
     复用既有 body.has-task-sel 类（updateMobileBatchBar 已在勾选数>0 时 toggle），取消勾选后自动恢复；
     必须 !important —— 上 L834 的 .mobile-bottom-nav{display:block!important} 使导航在手机端强制显示。 */
  body.has-task-sel .mobile-bottom-nav{display:none!important}
}

/* ===== CPA-180② 手机端日志卡片（修改记录 / 变动记录 / 登录日志 / 操作日志 共用） =====
   老板 2026-10-01：「手机端展示要简洁，最好单屏就能读完。时间上下稍微错位一点，上面日期、下面是具体时间；
   任务 ID 显示简洁一点；尽量单屏不用左右滑就能显示出来。」
   背景：原「修改记录」是 6 列宽表（min-width:860px），手机上必须左右横滑、行高被撑大，正是老板点名的痛点。
   现改为「一行一卡」的卡片流：时间两行（上日期/下时分）、任务ID 可点新标签跳转、详情自动换行、全程不横滑。
   PC 端仍走原 .table-wrap 宽表（本单未动 PC 分支），故这些类只在手机端卡片里出现。 */
/* CPA-194：卡片列表自成独立滚动区（有界高度 + 惯性滚动 + 滚动链不外溢）。
   修老板报的「卡片翻到底页面就死了，无法操作弹窗」——原实现里 .modal 自身是唯一滚动容器，
   100 张卡片把整个弹窗撑成一大张滚动面，`.modal-x`（position:absolute）随内容滚出视野 ⇒ 到底后 ✕ 找不到。
   现在列表内滚、弹窗不滚，✕ 与「关闭」按钮固定在位。 */
.mlog-list{display:flex;flex-direction:column;gap:8px;max-height:min(60vh,600px);overflow-y:auto;overscroll-behavior:contain;-webkit-overflow-scrolling:touch;padding-right:2px}
@media (max-width:768px){.mlog-list{max-height:58dvh}}
.mlog-card{padding:10px 12px;border:1px solid var(--border);border-radius:var(--radius-sm);background:var(--bg2)}
.mlog-card.is-batch{background:var(--primary-light);border-color:var(--primary)}
.mlog-card.is-auto{background:var(--bg3)}
.mlog-r1{display:flex;align-items:flex-start;justify-content:space-between;gap:10px;margin-bottom:6px}
.mlog-r2{display:flex;align-items:center;flex-wrap:wrap;gap:6px 10px;margin-bottom:4px}
/* 时间上下错位：上日期（小字灰）、下时分（加粗）；两行同宽左对齐，整体更整齐 */
.mlog-time{display:inline-flex;flex-direction:column;line-height:1.25}
.mlog-time .d{font-size:12px;color:var(--text2)}
.mlog-time .t{font-size:13px;font-weight:600;color:var(--text);font-variant-numeric:tabular-nums}
.mlog-type{font-size:12px;font-weight:600;color:var(--primary);white-space:nowrap;text-align:right;flex-shrink:0}
.mlog-op{font-size:12.5px;color:var(--text2);white-space:nowrap}
.mlog-ip{font-size:11.5px;color:var(--text2);font-variant-numeric:tabular-nums;white-space:nowrap}
.mlog-field{font-size:12px;color:var(--text2);background:var(--bg3);padding:1px 6px;border-radius:var(--radius-pill);white-space:nowrap}
.mlog-tag{font-size:11px;font-weight:600;color:#d97706;background:#fff7e6;padding:1px 6px;border-radius:var(--radius-pill);white-space:nowrap}
/* 任务ID：等宽字体、可点新标签打开数据页；过长时省略号收口，绝不撑出横向滚动 */
/* CPA-249 需求2：任务 ID 由蓝色链接色改为常规正文黑（var(--text)），与任务列表口径一致，避免误认为可点击链接。 */
.mlog-adid{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:12.5px;color:var(--text);text-decoration:none;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}
.mlog-adid:hover{text-decoration:underline}
.mlog-adid.is-muted{color:var(--text2);font-family:inherit}
.mlog-detail{font-size:12.5px;color:var(--text);line-height:1.45;word-break:break-word;overflow-wrap:anywhere}
.mlog-empty{text-align:center;color:var(--text2);padding:24px 0;font-size:13px}
[data-theme="dark"] .mlog-card{background:#1e293b;border-color:#334155}
[data-theme="dark"] .mlog-card.is-batch{background:rgba(22,119,255,.18);border-color:#4096ff}
[data-theme="dark"] .mlog-card.is-auto{background:#0f172a}
[data-theme="dark"] .mlog-time .t{color:#e2e8f0}
[data-theme="dark"] .mlog-adid{color:var(--text)}
[data-theme="dark"] .mlog-detail{color:#cbd5e1}

/* ===== CPA-212：任务ID / 任务名称 → 任务概览浮层（hover 悬浮预览，点击固定；手机端点击） ===== */
.mlog-taskref{display:inline-flex;align-items:baseline;gap:6px;cursor:pointer;max-width:100%;min-width:0}
.mlog-taskref .mlog-adid{flex-shrink:0}
.mlog-taskref:hover .mlog-adid{text-decoration:underline}
.mlog-kname{font-size:12.5px;color:var(--text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:220px}
.tov-panel{position:fixed;z-index:10001;width:320px;max-width:calc(100vw - 16px);background:var(--card);border:1px solid var(--border);border-radius:var(--radius);box-shadow:0 12px 36px rgba(0,0,0,.22);font-size:12.5px;overflow:hidden}
.tov-head{display:flex;align-items:center;justify-content:space-between;padding:8px 12px;border-bottom:1px solid var(--bg3);background:var(--bg2)}
.tov-title{font-weight:600;color:var(--text);font-size:12.5px}
.tov-close{border:none;background:transparent;cursor:pointer;font-size:16px;line-height:1;color:var(--text2);padding:0 4px}
.tov-close:hover{color:var(--text)}
.tov-body{padding:8px 12px;max-height:60vh;overflow-y:auto}
.tov-row{display:flex;gap:10px;padding:5px 0;border-bottom:1px dashed var(--bg3);align-items:flex-start}
.tov-row:last-child{border-bottom:none}
.tov-k{flex:0 0 66px;color:var(--text-tertiary);white-space:nowrap}
.tov-v{flex:1;min-width:0;color:var(--text);word-break:break-word}
.tov-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;color:var(--primary)}
.tov-sub{color:var(--text2);font-size:11.5px;margin-left:4px}
.tov-link-txt{word-break:break-all;color:var(--text2);font-size:11.5px}
.tov-foot{padding-top:8px;text-align:right}
.tov-goto{color:var(--primary);text-decoration:none;font-weight:500}
.tov-goto:hover{text-decoration:underline}
.tov-loading,.tov-empty{color:var(--text2);padding:14px 0;text-align:center}
[data-theme="dark"] .tov-head{background:#0f172a}
[data-theme="dark"] .mlog-kname{color:#cbd5e1}

/* ===== CPA-224：修改记录「任务」列轻量 hover 吐司浮窗（只读） =====
   单条 hover 任务ID 出任务名称；批量 hover「N 个任务」出该批次全部 任务ID+名称。
   层级取 10001：与 toast 同级、高于弹窗遮罩 10000 —— 修改记录本身是个弹窗，浮层若低于遮罩就会「hover 没反应」。 */
.mlog-adid-only{cursor:help;border-bottom:1px dashed var(--border-strong)}
.mlog-batch-ref{cursor:help;border-bottom:1px dashed var(--border-strong)}
.ht-tip{position:fixed;z-index:10001;max-width:340px;max-height:min(60vh,420px);overflow:auto;background:var(--card);border:1px solid var(--border);border-radius:var(--radius-sm);box-shadow:0 10px 30px rgba(0,0,0,.2);padding:8px 10px;font-size:12.5px;line-height:1.5}
.ht-tip-row{display:flex;gap:8px;align-items:baseline;padding:2px 0}
.ht-tip-id{flex-shrink:0;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;color:var(--primary);white-space:nowrap}
.ht-tip-name{color:var(--text);word-break:break-word}
.ht-tip-row:only-child .ht-tip-name{white-space:normal}
[data-theme="dark"] .ht-tip-id{color:#7cc0ff}

/* ===== CPA-212：批量「展开」按钮 + 独立明细弹窗（任务ID/名称/字段/详情/结果 + 搜索 + 独立滚动） ===== */
.mlog-expand{margin-left:6px;padding:1px 9px;font-size:11.5px;line-height:1.6;border:1px solid var(--border);background:var(--card);color:var(--primary);border-radius:999px;cursor:pointer;white-space:nowrap;display:inline-flex;align-items:center;vertical-align:middle}
.mlog-expand:hover{border-color:var(--primary);background:var(--primary-light,#e6f0ff)}
.blg-sum{font-size:12.5px;color:var(--text2);margin:6px 0 10px;display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.blg-sum b{color:var(--text)}
.blg-time{margin-left:auto;color:var(--text-tertiary);font-size:11.5px}
.blg-search{width:100%;margin-bottom:10px}
.blg-wrap{max-height:56vh;overflow:auto;border:1px solid var(--border);border-radius:var(--radius);overscroll-behavior:contain;-webkit-overflow-scrolling:touch}
.blg-table{width:100%;border-collapse:collapse;font-size:12.5px}
.blg-table thead th{position:sticky;top:0;background:var(--bg2);text-align:left;padding:8px 10px;font-weight:600;color:var(--text2);border-bottom:1px solid var(--border);white-space:nowrap;z-index:1}
.blg-table td{padding:7px 10px;border-bottom:1px solid var(--bg3);vertical-align:top}
.blg-table tbody tr:last-child td{border-bottom:none}
.blg-id{white-space:nowrap}
.blg-name{color:var(--text);max-width:220px;word-break:break-word}
.blg-field{white-space:nowrap}
.blg-dtl{color:var(--text2);word-break:break-word}
.blg-st{white-space:nowrap}
.blg-badge{display:inline-flex;align-items:center;font-size:11px;padding:1px 8px;border-radius:999px;white-space:nowrap}
.blg-badge.ok{background:#dcfce7;color:#15803d}
.blg-badge.bad{background:#fee2e2;color:#b91c1c}
.blg-tr.bad{background:rgba(239,68,68,.05)}
[data-theme="dark"] .blg-badge.ok{background:rgba(21,128,61,.25);color:#86efac}
[data-theme="dark"] .blg-badge.bad{background:rgba(185,28,28,.25);color:#fca5a5}
[data-theme="dark"] .blg-table thead th{background:#0f172a}
[data-theme="dark"] .blg-tr.bad{background:rgba(239,68,68,.12)}
/* 手机端批量明细改卡片流，窄屏不横滑 */
@media (max-width:768px){
  .blg-wrap{max-height:58vh;border:none;overflow-x:hidden}
  .blg-table thead{display:none}
  .blg-table,.blg-table tbody,.blg-table tr,.blg-table td{display:block;width:100%}
  .blg-table tr{border:1px solid var(--border);border-radius:var(--radius);margin-bottom:8px;padding:6px 10px}
  .blg-table td{border:none;padding:3px 0;max-width:none}
  .blg-name{font-weight:600}
  .blg-search{font-size:13px}
}

/* ===== CPA-194 修改记录卡片增强（操作人三色 / 日期头 / 旧→新 chip / 成功失败徽标 / IP 弱化） =====
   老板 2026-10-02：「再基于手动和自动把 SVG 加上；根据不同的操作人——本人本账号、其他人的、系统自动的，
   卡片颜色都改一下；里面的内容看还有没有优化的空间。」
   口径：颜色＝身份（本人/他人/系统自动），图标＝手动(铅笔)/自动(闪电)，两者由同一判据 _mlogOpKind 驱动。
   三色取「左侧色条 + 浅底」而非整卡重底：既有 .mlog-card.is-batch / .is-auto 的底色会被下方 ko-* 覆盖，
   批量改由「成功/失败徽标」表达，避免同一张卡既按身份上色又按批量上色互相打架。 */
.mlog-card.ko-self{background:var(--primary-light);border-color:rgba(22,119,255,.35);box-shadow:inset 3px 0 0 var(--primary)}
.mlog-card.ko-other{background:var(--bg2);border-color:var(--border);box-shadow:inset 3px 0 0 #94a3b8}
.mlog-card.ko-auto{background:var(--bg3);border-color:var(--border);box-shadow:inset 3px 0 0 #f59e0b}
[data-theme="dark"] .mlog-card.ko-self{background:rgba(22,119,255,.16);border-color:#4096ff}
[data-theme="dark"] .mlog-card.ko-other{background:#1e293b;border-color:#334155}
[data-theme="dark"] .mlog-card.ko-auto{background:#0f172a;border-color:#334155}
/* 操作人徽记：SVG + 姓名，颜色与所属卡片同一口径 */
.mlog-actor{display:inline-flex;align-items:center;gap:4px;font-size:12.5px;font-weight:600;padding:1px 8px 1px 6px;border-radius:var(--radius-pill);white-space:nowrap;max-width:100%;overflow:hidden;text-overflow:ellipsis}
.mlog-actor.ko-self{color:#1677ff;background:rgba(22,119,255,.12)}
.mlog-actor.ko-other{color:#475569;background:rgba(100,116,139,.16)}
.mlog-actor.ko-auto{color:#b45309;background:rgba(245,158,11,.18)}
[data-theme="dark"] .mlog-actor.ko-self{color:#7cc0ff;background:rgba(22,119,255,.22)}
[data-theme="dark"] .mlog-actor.ko-other{color:#cbd5e1;background:rgba(148,163,184,.2)}
[data-theme="dark"] .mlog-actor.ko-auto{color:#fbbf24;background:rgba(245,158,11,.2)}
.mlog-ico{display:inline-flex;align-items:center;font-size:12px;line-height:1}
/* 日期头（按天分组）：文案 + 右侧贯通细线，落到同一天的卡片之上 */
.mlog-day{display:flex;align-items:center;gap:8px;font-size:11.5px;font-weight:600;color:var(--text2);padding:4px 0 2px}
.mlog-day::after{content:'';flex:1;height:1px;background:var(--border)}
/* 相对时间：靠右收口（flex 行内 margin-left:auto），不与左侧任务ID 抢位 */
.mlog-rel{font-size:11.5px;color:var(--text2);white-space:nowrap;margin-left:auto}
/* 旧值 → 新值 分段展示 */
.mlog-chips{display:flex;align-items:center;flex-wrap:wrap;gap:4px;margin-top:6px}
.mlog-chip{font-size:12px;padding:1px 7px;border-radius:var(--radius-sm);background:var(--bg3);color:var(--text2);word-break:break-word;overflow-wrap:anywhere;max-width:100%}
.mlog-chip.is-old{opacity:.85}
.mlog-chip.is-new{background:var(--primary-light);color:var(--primary);font-weight:600}
.mlog-chip.is-empty{font-style:italic;opacity:.65}
.mlog-arrow{color:var(--text2);font-size:12px}
/* CPA-199：IP 归属地展示 —— 卡片页脚保持右对齐两行（上 IP、下城市） */
.mlog-ip-wrap{display:inline-flex;flex-direction:column;align-items:flex-end;line-height:1.35}
.mlog-ip-city{font-size:10.5px;color:var(--text-tertiary);white-space:nowrap}
/* CPA-199：表格单元格里的 IP —— 「IP: x」+ 下一行城市（列宽自适应，不撑破表格） */
.ip-cell{display:inline-flex;flex-direction:column;line-height:1.35;font-size:12px}
.ip-cell .ip-v{font-variant-numeric:tabular-nums;white-space:nowrap}
.ip-cell .ip-city{font-size:11px;color:var(--text-tertiary);white-space:nowrap}
/* 批量操作结果徽标：成功 / 失败分开报数（失败>0 才出红色徽标，警示为主） */
.mlog-badge{display:inline-flex;align-items:center;gap:3px;font-size:11.5px;font-weight:600;padding:1px 7px;border-radius:var(--radius-pill);white-space:nowrap}
.mlog-badge.ok{color:#15803d;background:rgba(34,197,94,.14)}
.mlog-badge.bad{color:#b91c1c;background:rgba(239,68,68,.16)}
[data-theme="dark"] .mlog-badge.ok{color:#4ade80;background:rgba(34,197,94,.2)}
[data-theme="dark"] .mlog-badge.bad{color:#f87171;background:rgba(239,68,68,.22)}
/* 卡片页脚：绝对时间 + IP（弱化），与正文用虚线分隔 */
.mlog-foot{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-top:6px;padding-top:5px;border-top:1px dashed var(--border)}
.mlog-foot .mlog-time .t{font-size:12px;font-weight:500}
/* IP 弱化：页脚小字灰显、可点复制；去掉 button 默认外观 */
.mlog-ip{font-size:11.5px;color:var(--text2);font-variant-numeric:tabular-nums;white-space:nowrap;background:none;border:0;padding:0;font-family:inherit;cursor:pointer}
.mlog-ip:hover{color:var(--primary);text-decoration:underline}
/* PC 表格：行首色条按身份上色（表格里无法整卡上色，用首列 inset 色条等价表达） */
.mlog-tr.ko-self td:first-child{box-shadow:inset 3px 0 0 var(--primary)}
.mlog-tr.ko-other td:first-child{box-shadow:inset 3px 0 0 #94a3b8}
.mlog-tr.ko-auto td:first-child{box-shadow:inset 3px 0 0 #f59e0b}

/* ===== CPA-227：日志类模块「账号可见范围」筛选控件（管理员专用：我的｜全部[+账号下拉]） =====
   代理商不渲染（后端强制只看本人）。横向排布、窄屏自动换行；下拉与分段控件同高对齐。 */
.log-scope{display:flex;align-items:center;flex-wrap:wrap;gap:8px;margin:0 0 12px}
.log-scope-seg{display:flex;border:1px solid var(--border);border-radius:var(--btn-radius);overflow:hidden;flex-shrink:0}
.log-scope-seg button{font-size:12.5px;padding:6px 14px;border:none;background:var(--bg2);color:var(--text);cursor:pointer}
.log-scope-seg button.on{background:var(--primary);color:#fff;font-weight:600}
.log-scope-user{font-size:12.5px;padding:6px 10px;border:1px solid var(--border);border-radius:var(--btn-radius);background:var(--card);color:var(--text);max-width:240px}
@media (max-width:768px){
  .log-scope-seg button{font-size:12px;padding:6px 12px}
  .log-scope-user{flex:1;min-width:0;max-width:none}
}

/* ===== CPA-180③ 手机端对齐加固（老板：「整体风格要做成对齐的，让人一看就很整洁」） =====
   针对「三个字被排成上面两个字下面一个字」「按钮文字折行、上下错落」这类问题：
   按钮 / 标签 / 徽标 / 芯片一律不折行 + 垂直居中，行内元素基线对齐，消除错落。 */
@media (max-width:768px){
  .btn,.badge,.tab,.task-hdr-btn,.mtt-btn,.mlog-type,.mlog-op,.mlog-ip,.mlog-tag,.mlog-field{white-space:nowrap}
  .btn,.task-hdr-btn,.mtt-btn{display:inline-flex;align-items:center;justify-content:center;line-height:1.2}
  .badge{display:inline-flex;align-items:center;justify-content:center}
  .card-header{gap:8px}
  .mlog-r2{align-items:center}
  /* CPA-182：短中文标签/标题一律不逐字折行（窄容器优先压缩字号，绝不竖排）；
     覆盖统计卡标签、卡片标题、手机端区块标题等"一旦折行就很难看"的位置。 */
  .stat-card .label,.mobile-stat-card .label,.card-header .title,.mobile-section-title,.mobile-header .title{white-space:nowrap}
  /* CPA-182：范围筛选行 / 过去数据筛选控件所在的卡片头，禁止横向滚动条撑出（与整行铺满口径一致） */
  .ov-range-row,#statsPastKind{max-width:100%}
}

/* ===== CPA-206 手机端批量上传：卡片流（一条一卡、字段竖排）+ 底部操作条 =====
   背景：手机端原先统一走 PC 的 N 列宽表（横向挤压、触屏框选/填充柄失效），
   现将手机端（getIsMobile()）分流为卡片流；PC 端表格形态与本文件 .batch-table 规则不变。
   仅 .ub-card / .ubm-* 新增类，不改动既有批量条（.m-batch-float）与批量表格（.batch-table）声明。
   CPA-211：手机端收敛为「1 卡快速提交面板」——去掉卡内勾选/序号/删除与底部全选/清空/删除选中，
   入口只留「导入文件」，底部只留一颗「提交」（对应 .ubm-foot .btn.ubm-submit）。 */
.ubm-entries{display:flex;gap:8px;flex-wrap:wrap;margin-bottom:10px}
.ubm-entries .ubm-entry{flex:1 1 0;min-width:0;white-space:nowrap}
.ubm-bar{display:flex;flex-wrap:wrap;gap:10px;align-items:center;font-size:12px;margin-bottom:8px;min-height:18px}
.ubm-bar .ubm-hint{color:var(--primary)}
.ubm-bar .ubm-res{font-weight:600}
.ubm-list{display:flex;flex-direction:column;gap:10px;margin-bottom:10px}
.ub-card{background:var(--card);border:1px solid var(--border);border-left:3px solid var(--border);border-radius:var(--radius-sm);padding:10px 12px}
/* CPA-216：卡头整条下线（空态「-」占位 +「▾」折叠一并去掉），.ubm-st 移入卡体首行、空态 :empty 自动收起 */
.ubm-st{font-size:11px;font-weight:600;text-align:center;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ubm-st:empty{display:none}
.ubm-bd{display:flex;flex-direction:column;gap:8px}
.ubm-field{display:flex;flex-direction:column;gap:3px}
.ubm-lb{font-size:11px;font-weight:600;color:var(--text2)}
.ubm-inp{width:100%;box-sizing:border-box;padding:9px 10px;border:1px solid var(--border);border-radius:var(--btn-radius);font-size:14px;background:var(--bg2);color:var(--text);outline:none}
.ubm-inp:focus{border-color:var(--primary);background:var(--card);box-shadow:0 0 0 2px var(--primary-light)}
.ubm-fail{display:none;margin-top:8px;padding:6px 8px;font-size:11px;line-height:1.4;color:#dc2626;background:#fef2f2;border-radius:var(--btn-radius);word-break:break-all;white-space:normal}
.ubm-fail:not(:empty){display:block}
/* CPA-216：底部「提交」不再吸底悬停（原 position:sticky;bottom:70px 会在滚动时压住其后的
   #fileProgress/#batchResult 结果区，老板反馈「提交按钮后面还有内容被挡住了」），改随卡片自然流式排列 */
.ubm-foot{display:flex;flex-wrap:wrap;gap:6px;align-items:center;padding:8px 10px;background:var(--bg2);border:1px solid var(--border);border-radius:var(--radius-sm)}
.ubm-foot .btn{white-space:nowrap}
/* CPA-211：手机端批量上传改「1 卡快速提交面板」，底部只剩一颗「提交」——占满整行并加大点击区。
   用 .btn.ubm-submit 提高特异性，避免被下方 ≤400px 的 .ubm-foot .btn 缩字规则压小。 */
.ubm-foot .btn.ubm-submit{flex:1 1 100%;width:100%;padding:10px 12px;font-size:15px;font-weight:600}

/* ===== CPA-206 S3：PC 端批量表格重做（固定列宽 / 表头真吸顶 / 状态列合一 / 只看错误 / 错误行底色）=====
   1) colgroup + table-layout:fixed：选择/序号/状态列定量，业务列均分剩余宽度，整表 min-width 兜底横向滚动；
   2) .batch-table-wrap 由 overflow:hidden 改 auto + max-height，使既有 thead sticky 声明真正生效；
   3) 「校验结果」「失败原因回显」两列合并为 .batch-status-cell，两个既有类名与 data-row 保留（选择器逻辑不变）；
   4) 错误行底色走 tr.row-error（与斑马纹同特异性、后置覆盖），不再依赖被 input 的 !important 压掉的 inline 底色。
   不修改批量悬浮条的既有声明，也不触碰任务页「回收站换装」与回收站按钮类名的既有口径。 */
.batch-table{table-layout:fixed;min-width:760px}
.batch-table-wrap{overflow:auto!important;max-height:72vh}
.batch-table tbody td.batch-status-cell{padding:4px 6px!important;text-align:center!important;vertical-align:middle!important}
.batch-table .batch-status-cell .validate-cell{width:auto!important;padding:0!important;font-size:11px!important;font-weight:600!important;text-align:center!important;background:transparent!important}
.batch-table .batch-status-cell .fail-backfill-cell{padding:4px 0 0 0!important;border-left:none!important;background:transparent!important;max-width:100%!important;max-height:44px!important;text-align:left!important}
.batch-table tbody tr.row-error td{background:#fef2f2!important}
[data-theme="dark"] .batch-table tbody tr.row-error td{background:#450a0a!important}
.batch-onlyerr{display:inline-flex;align-items:center;gap:4px;font-size:12px;color:var(--text2);cursor:pointer;white-space:nowrap;user-select:none}
.batch-sum-all{font-size:12px;color:var(--text2);white-space:nowrap}
/* 手机端卡片错误态：只染左色条 */
.ub-card.row-error{border-left-color:#dc2626}

/* ===== CPA-206 返工：大数据量离屏渲染优化（content-visibility）=====
   500 行 × N 列表格 / 500+ 张卡片时，离屏的行与卡片跳过布局与绘制，显著降低首屏与滚动开销；
   contain-intrinsic-size 提供占位高度（auto 关键字记住上次实测尺寸），避免滚动条跳动。
   这是「分片渲染 + 校验去重 + 惰性填充柄」之外的正交优化，仅影响渲染，不改任何 DOM/业务口径。 */
.batch-table tbody tr{content-visibility:auto;contain-intrinsic-size:auto 38px}
.ub-card{content-visibility:auto;contain-intrinsic-size:auto 120px}

/* ===== CPA-216：手机端卡片流窄屏收字（CPA-206 S5 的「逐条折叠」已随卡头一并下线）=====
   老板反馈去掉「小横杠 + 展开」两处 ⇒ 卡头、折叠箭头、折叠态三族规则整体退役；
   校验状态格 .ubm-st 移入卡体首行、空态 :empty 不占位（样式见上方 CPA-206 卡片流块）。 */
@media(max-width:400px){
  .ubm-entries{gap:6px}
  .ubm-entries .ubm-entry{padding:7px 4px;font-size:12px}
  .ubm-foot{gap:5px;padding:7px 8px}
  .ubm-foot .btn{padding:6px 8px;font-size:12px}
}

/* ===== CPA-216 手机端任务上传页布局收口（老板口径：选择类三四个一排、页面别拉长、提示收进输入框）=====
   ① 顶部 tabs（.up-tabs）4 项一行：后台账号恰好 4 个 tab（单任务上传/批量上传/测试任务/上传记录），
      25% 基准 + min-width:0 ⇒ 整行铺满不换行；≤360px 隐去图标保文字（agent 6 个 tab 自然排 4+2 两行）。
   ② 批量上传预选区（.up-grid）选择类 3 个一行：.up-preset/.up-pick 一律 33.333% 基准（渠道/状态/控量一行、
      上架/下架/投放时段一行）；PC 端行为与旧行内样式逐值等价（flex:1 + min-width:130/160px）。
   ③ 单任务表单（.up-form）手机端改 4 列栅格：名称/链接占满整行，选择类与数字类按 2:1 分格；
      排期三格（.up-sched）手机端保持 3 列一行；PC 端两容器仍按 1fr 1fr / 1fr 1fr 1fr 排布，不受影响。 */
.up-grid{display:flex;gap:12px;flex-wrap:wrap;margin-bottom:12px}
.up-preset{flex:1;min-width:130px}
.up-pick{flex:1;min-width:160px}
/* 表单/排期栅格走 CSS 类而非行内样式：既有 `div[style*="grid-template-columns:1fr 1fr"]`（手机端强制 1 列）
   与 `…1fr 1fr 1fr`（强制 2 列）两条兜底规则会按属性选择器命中行内写法，把本页布局压歪。 */
.up-form{display:grid;grid-template-columns:1fr 1fr;gap:12px}
.up-sched{display:grid;grid-template-columns:1fr 1fr 1fr;gap:12px}
@media(max-width:768px){
  .tabs.up-tabs .tab{flex:1 1 calc(25% - 3px);min-width:0;padding:7px 4px;font-size:11px}
  .up-grid .up-preset,.up-grid .up-pick{flex:1 1 calc(33.333% - 8px);min-width:0}
  /* 预选区/排期六+三格标签统一 11px：360/320px 窄屏下「投放时段（每天）」不再折两行、栅格内不再溢出 */
  .up-grid .up-preset > label,.up-grid .up-pick > label,.up-sched .up-pick > label{font-size:11px!important}
  .up-pick{min-width:0}
  .up-form{grid-template-columns:repeat(4,minmax(0,1fr));gap:8px 8px}
  .up-sched{grid-template-columns:repeat(3,minmax(0,1fr));gap:8px}
  .up-form .form-group{margin-bottom:0}
  .up-form .form-group input,.up-form .form-group select{padding:7px 8px;font-size:13px}
  .up-form .fg-2{grid-column:span 2}
  .up-form .fg-4{grid-column:span 4}
}
@media(max-width:360px){
  .tabs.up-tabs .tab{min-width:0;padding:7px 3px}
  .tabs.up-tabs .tab .icon-svg{display:none}
}

/* ===== CPA-218：单表单提交按钮居中 + 输入聚焦舒适位兜底 =====
   ① .form-actions-center 只加在上传页三处单表单（单任务上传/单个上新/单个补量），
      不改全局 .form-actions 的 flex-end（弹窗页脚共用，动全局会波及全站）。
      特异性 0,2,0 高于各断点里的 .form-actions（0,1,0），无需依赖先后顺序即生效。
   ② scroll-margin-top 是纯 CSS 兜底：浏览器在聚焦元素时会「滚动到可见」并尊重 scroll-margin，
      给顶部留出 ~96px 缓冲，避免被键盘顶起后贴死在页面最顶端；JS 侧 visualViewport 再做精调。 */
.form-actions.form-actions-center{justify-content:center}
.form-group input,.form-group select,.form-group textarea,
.up-form input,.up-form select,.up-form textarea,
.search-bar input,.search-bar select{scroll-margin-top:96px}

/* ===== CPA-241：PV/UV 访问明细弹窗 =====
   老板：今日PV/今日UV/总PV/总UV 点开看明细（第N个 / UID / 访问时间），不跳新标签页。
   明细可能较大：弹窗内 .visit-body 自成滚动区（有界高度 + 惯性滚动），右上角 ✕ 固定不动；
   手机端整屏宽、行高紧凑，表头吸顶；总口径按日折叠（今天默认展开，其余点击展开）。 */
.visit-modal{display:flex;flex-direction:column;gap:8px}
.visit-title{font-size:var(--fs-title);font-weight:600;color:var(--text);padding-right:34px}
.visit-body{max-height:min(64vh,640px);overflow-y:auto;overscroll-behavior:contain;-webkit-overflow-scrolling:touch;border:1px solid var(--border);border-radius:var(--radius);background:var(--bg2)}
.visit-loading,.visit-empty{color:var(--text2);text-align:center;padding:26px 12px;font-size:13px}
.visit-table{display:flex;flex-direction:column}
.visit-thead{position:sticky;top:0;z-index:1;display:grid;grid-template-columns:84px 1fr 168px;gap:8px;padding:8px 12px;background:var(--bg3);border-bottom:1px solid var(--border);font-size:12px;font-weight:600;color:var(--text2)}
.visit-trow{display:grid;grid-template-columns:84px 1fr 168px;gap:8px;padding:7px 12px;border-bottom:1px solid var(--bg3);font-size:12.5px;color:var(--text);align-items:center}
.visit-trow:last-child{border-bottom:none}
.visit-n{color:var(--text2);font-variant-numeric:tabular-nums}
.visit-uid{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;color:var(--primary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.visit-ts{color:var(--text2);font-variant-numeric:tabular-nums;white-space:nowrap}
.visit-more{padding:6px 12px;font-size:11.5px;color:var(--text-tertiary);text-align:center}
/* CPA-243④：明细分页条（每页 100 条，吸底；可往返翻页 / 输入页码跳转 / 直达尾页） */
.visit-pager{position:sticky;bottom:0;z-index:1;display:flex;align-items:center;justify-content:space-between;gap:8px;flex-wrap:wrap;padding:8px 12px;background:var(--bg3);border-top:1px solid var(--border);font-size:12px;color:var(--text2)}
.visit-pager-info{font-variant-numeric:tabular-nums}
.visit-pager-btns{display:inline-flex;align-items:center;gap:6px;flex-wrap:wrap}
.visit-pg{height:26px;padding:0 10px;border:1px solid var(--border);border-radius:6px;background:var(--card);color:var(--text);font-size:12px;line-height:1;cursor:pointer}
.visit-pg:hover:not(:disabled){border-color:var(--primary);color:var(--primary)}
.visit-pg:disabled{opacity:.45;cursor:not-allowed}
.visit-pg-input{width:56px;height:26px;padding:0 6px;border:1px solid var(--border);border-radius:6px;background:var(--card);color:var(--text);font-size:12px;text-align:center;-moz-appearance:textfield}
.visit-pg-input::-webkit-outer-spin-button,.visit-pg-input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}
.visit-day{border-bottom:1px solid var(--border)}
.visit-day:last-child{border-bottom:none}
.visit-day-head{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:10px 12px;cursor:pointer;background:var(--bg2);user-select:none}
.visit-day-head:hover{background:var(--bg3)}
.visit-day-label{font-size:13px;font-weight:600;color:var(--text)}
.visit-day-date{font-size:11px;font-weight:400;color:var(--text-tertiary);margin-left:4px}
.visit-day-count{font-size:12px;color:var(--text2);white-space:nowrap}
.visit-caret{display:inline-block;transition:transform .15s;color:var(--text2)}
.visit-day.open .visit-caret{transform:rotate(180deg)}
.visit-day-body{display:none}
.visit-day.open .visit-day-body{display:block}
[data-theme="dark"] .visit-body{background:#0f172a}
[data-theme="dark"] .visit-thead{background:#1e293b}
[data-theme="dark"] .visit-pager{background:#1e293b}
[data-theme="dark"] .visit-pg,[data-theme="dark"] .visit-pg-input{background:#0f172a}
@media (max-width:768px){
  .visit-body{max-height:60dvh}
  .visit-thead,.visit-trow{grid-template-columns:56px 1fr 132px;gap:6px;padding-left:8px;padding-right:8px}
  .visit-trow{font-size:12px}
  .visit-ts{font-size:11.5px}
  .visit-pager{padding:8px;gap:6px}
  .visit-pg{padding:0 8px}
}

/* ===== CPA-241 需求5/6：内部落地页 / 长图 一律本页大弹窗承载（iframe），不再新开标签页 ===== */
.modal.modal-frame{width:1100px;max-width:96vw;height:88vh;max-height:88vh;padding:0;overflow:hidden}
.frame-wrap,.img-modal{display:flex;flex-direction:column;height:100%;width:100%}
.frame-head,.img-modal-head{flex:0 0 auto;display:flex;align-items:center;gap:8px;padding:12px 48px 12px 16px;border-bottom:1px solid var(--border);background:var(--card);font-size:14px;font-weight:700;color:var(--text)}
.frame-body{flex:1 1 auto;width:100%;border:0;background:var(--bg);display:block}
.img-modal-body{flex:1 1 auto;overflow:auto;-webkit-overflow-scrolling:touch;background:var(--bg2);text-align:center;padding:8px}
.img-modal-body img{max-width:100%;height:auto;display:block;margin:0 auto}
@media (max-width:768px){
  /* CPA-247：手机端内部落地页弹窗不能再铺满整屏（100vw/100dvh + 无圆角会被误认为「本页直接打开了链接」）——
     改为四周留出可见遮罩的大弹窗（94vw × 86dvh、圆角保留），与 PC 端同属「本页大弹窗」形态。 */
  .modal.modal-frame{width:94vw;max-width:94vw;height:86dvh;max-height:86dvh;border-radius:12px}
  .frame-head,.img-modal-head{padding:10px 46px 10px 12px}
}

/* ===== CPA-248：AI 上传小助手（单任务 / 批量上传页悬浮窗） ===== */
/* 形态：上传页右下角常驻悬浮球（.ai-up-fab），点击展开对话面板（.ai-up-panel）。
   本项目无大模型后端，故面板是「前端规则式解析 + 一键填表」的引导壳：把粘贴文本按列分隔符拆成行，
   再按当前子页签列序填入表单/批量表格，数据仍走原有上传接口（/api/tasks、/api/upload/batch）。
   浮层用 position:fixed 脱离 #mainContent 文档流；子页签切换只重写 #uploadContent，
   故小助手在单任务/批量之间往返时保持常驻、不残留（挂载/同步逻辑见 page-upload.js）。
   z-index 取 9990/9991：低于弹窗遮罩(10000)，避免盖住大弹窗。 */
.ai-up-root{position:fixed;right:0;bottom:0;width:0;height:0;z-index:9990;pointer-events:none}
.ai-up-root>*{pointer-events:auto}
/* 悬浮球：桌面端为「图标 + 文字」胶囊；手机端收成纯图标圆钮并抬高到常驻底部导航(z-index:9999, ≈62px)之上 */
.ai-up-fab{position:fixed;right:20px;bottom:calc(24px + env(safe-area-inset-bottom));z-index:9990;display:flex;align-items:center;gap:8px;padding:11px 16px;border:none;border-radius:999px;background:linear-gradient(135deg,var(--primary),var(--primary-dark));color:#fff;font-size:13px;font-weight:600;line-height:1;cursor:pointer;box-shadow:0 6px 18px rgba(22,119,255,.35);transition:transform .15s,box-shadow .15s,background .15s}
.ai-up-fab:hover{transform:translateY(-2px);box-shadow:0 10px 24px rgba(22,119,255,.45)}
.ai-up-fab.active{background:linear-gradient(135deg,var(--primary-dark),var(--primary))}
.ai-up-fab .icon-svg{width:20px;height:20px;font-size:20px;margin:0;flex-shrink:0}
.ai-up-fab-txt{white-space:nowrap}
/* 对话面板：右下角浮出，桌面上限高避免溢屏并留出顶栏空间；display 由 JS 在 ''/none 间切换，此处默认 flex */
.ai-up-panel{position:fixed;right:20px;bottom:calc(78px + env(safe-area-inset-bottom));z-index:9991;width:376px;max-width:calc(100vw - 32px);height:520px;max-height:calc(100vh - 128px);display:flex;flex-direction:column;background:var(--card);border:1px solid var(--border);border-radius:var(--radius-lg);box-shadow:var(--shadow-pop,0 12px 40px rgba(15,23,42,.22));overflow:hidden}
.ai-up-hd{flex:0 0 auto;display:flex;align-items:center;justify-content:space-between;gap:8px;padding:12px 14px;background:linear-gradient(135deg,var(--primary),var(--primary-dark));color:#fff}
.ai-up-title{font-size:14px;font-weight:700;letter-spacing:.3px}
.ai-up-x{width:26px;height:26px;flex-shrink:0;border:none;border-radius:50%;background:rgba(255,255,255,.18);color:#fff;font-size:18px;line-height:1;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:background .15s}
.ai-up-x:hover{background:rgba(255,255,255,.34)}
/* 消息区：机器人靠左（浅色气泡）、用户靠右（主题色气泡），新消息自动滚到底（JS 置 scrollTop） */
.ai-up-log{flex:1 1 auto;overflow-y:auto;-webkit-overflow-scrolling:touch;padding:12px;display:flex;flex-direction:column;gap:10px;background:var(--bg2)}
.ai-up-msg{max-width:86%;padding:8px 11px;border-radius:12px;font-size:12.5px;line-height:1.55;white-space:normal;word-break:break-word;overflow-wrap:anywhere}
.ai-up-bot{align-self:flex-start;background:var(--card);color:var(--text);border:1px solid var(--border);border-bottom-left-radius:4px;box-shadow:var(--shadow-sm)}
.ai-up-user{align-self:flex-end;background:var(--primary);color:#fff;border-bottom-right-radius:4px}
.ai-up-fillbtn{margin-top:8px;font-size:12px!important;padding:6px 12px!important}
/* 快捷指令：为空时整块隐藏，避免占位留白 */
.ai-up-chips{flex:0 0 auto;display:flex;flex-wrap:wrap;gap:6px;padding:9px 12px 0;background:var(--bg2)}
.ai-up-chips:empty{display:none;padding:0}
.ai-up-chip{font-size:12px;padding:5px 11px;border:1px solid var(--border);border-radius:999px;background:var(--card);color:var(--primary);cursor:pointer;white-space:nowrap;transition:background .15s,border-color .15s}
.ai-up-chip:hover{background:var(--primary-light);border-color:var(--primary)}
/* 输入区：文本域 + 三颗操作钮（清空 / 识别预览 / 发送） */
.ai-up-input{flex:0 0 auto;display:flex;flex-direction:column;gap:8px;padding:10px 12px 12px;border-top:1px solid var(--border);background:var(--card)}
.ai-up-input textarea{width:100%;box-sizing:border-box;resize:none;padding:9px 10px;border:1px solid var(--border);border-radius:var(--btn-radius);background:var(--bg2);color:var(--text);font-size:13px;line-height:1.5;font-family:inherit;outline:none;transition:border-color .15s,box-shadow .15s}
.ai-up-input textarea:focus{border-color:var(--primary);box-shadow:0 0 0 2px rgba(22,119,255,.15)}
.ai-up-actions{display:flex;gap:8px;justify-content:flex-end}
.ai-up-actions .btn{font-size:12px;padding:7px 14px}
/* 手机端：悬浮球收成圆钮并抬到常驻底部导航之上；面板贴边近全宽、落在圆钮上方，避免互相遮挡 */
@media (max-width:768px){
  .ai-up-fab{right:12px;bottom:calc(74px + env(safe-area-inset-bottom));padding:12px;border-radius:50%}
  .ai-up-fab-txt{display:none}
  .ai-up-panel{right:8px;left:8px;bottom:calc(132px + env(safe-area-inset-bottom));width:auto;max-width:none;height:auto;max-height:64vh;max-height:64dvh;border-radius:var(--radius)}
  .ai-up-log{padding:10px}
  .ai-up-msg{max-width:92%}
}
/* 深色主题：渐变头与用户气泡沿用 --primary 自适应，仅给机器人气泡补深色底以保对比 */
[data-theme="dark"] .ai-up-bot{background:#16233b;border-color:var(--border)}

/* ===== CPA-250 需求②：首页 3 项 / 中控台 5 项 / 「我的」头像卡片 —— 顶部吸顶 ===== */
/* 老板口径：这三处随页面下滑时应固定在顶栏下方，随时能切换/看到，不必滑回页首。
   吸顶偏移随顶栏高度走（PC 60px / 小屏换行 100px / 手机 60px / 矮屏 44px），与 .task-sticky-head 同一套口径。
   position:sticky 只相对「最近的可滚动祖先」生效：吸顶元素不得被 .card{overflow:hidden} 包住（祖先 overflow 会截断吸顶），
   故三处均置于 .main 直接子层，并各自带不透明底色，避免下滑内容从缝隙透出。 */
/* CPA-257 需求：老板口径「最顶上这个吸顶是固定的，下面的数据页和中控台那个吸顶取消掉，不做吸顶了」。
   故仅 .topbar 固定；.sticky-top-bar（首页平台/用户/代理请求数据切换行 + 中控台左侧菜单）恢复常规文档流，不再吸顶。 */
.sticky-top-bar{position:static}
/* 首页 3 项（平台数据/用户数据/代理请求数据）：切换行本身无底色，吸顶时补主题页底遮住下滑内容 */
.sticky-top-bar.stats-tabs{background:var(--bg)}

/* ===== CPA-250 需求⑤：手机端页脚与 PC 一致（logo + 上海得到文化传媒有限公司 + 技术支持 + 版本号） =====
   老板口径：手机端每个页面底部都跟电脑端一致，加上图标和上海得到那些。
   原先 #pcFooter 在 ≤768px 被 display:none 关掉（common.css 内两条：#pcFooter{display:none} 与
   @media(max-width:768px){.footer{display:none}}）；此处用 ID 选择器在末尾放开，id 优先级高于
   那条 .footer 类规则、同优先级则靠后者胜出，无需 !important。 */
@media (max-width:768px){
  #pcFooter{display:flex}
}

/* ===== CPA-250 需求③：手机端顶栏 sticky→fixed，修正 overscroll（底部橡皮筋回弹）时顶部「盈钱树」横幅消失 ===== */
/* 老板现象：手机端下滑到最底部继续拉一下并保持不动，顶部「盈钱树」图标横幅区域却消失了。
   根因：.topbar 用 position:sticky。iOS 滚动到底继续下拉回弹时，sticky 顶栏被带出视口而暂时不可见。
   改法：手机端顶栏改 position:fixed，恒定吸附视口顶，回弹时不再被拖动（PC 保持 sticky 不变，桌面无此现象）。
   顶栏 fixed 后脱离文档流，主内容区补「顶栏等高」padding-top（含刘海 safe-area），避免首屏内容压到顶栏下。
   用 .app .main 而不用 .mobile-page .main：isMobile 判定为「手机且宽度<768」，与「≤768px」媒体查询存在 1px 错位，
   .app .main 只随媒体查询走、不依赖 JS 是否加 mobile-page 类，覆盖更稳。
   各吸顶元素（.task-sticky-head）的 top 偏移本就等于手机端顶栏高度（60px / 矮屏 44px），fixed 后仍对齐。 */
@media (max-width:768px){
  .topbar{position:fixed;top:0;left:0;right:0}
  .app .main{padding-top:calc(60px + env(safe-area-inset-top))}
}
@media (max-width:768px) and (max-height:500px){
  .app .main{padding-top:calc(44px + env(safe-area-inset-top))}
}

/* ===== CPA-250 需求④：手机端底栏 4 项上移顶栏 + 顶栏品牌副标题隐藏 + 深色开关改挂「我的」 ===== */
/* 老板口径：底栏 4 个入口挪到顶部展示（顶部空间够、底栏腾出的高度还给内容）；CPA-257 手机端顶栏由 52px
   加高到 60px（矮屏仍 44px），.task-sticky-head / .app .main 偏移随之对齐此值，
   故 4 项与品牌同处顶栏一行（插在品牌与右侧图标之间），不做第二行；4 个入口统一圆形、只留图标。 */
@media (max-width:768px){
  /* 【CPA-254 需求③b】品牌改上下两行：logo 独占第一行（跨两列），第二行左『盈钱树』右『投放平台 + 版本号』；
     两 span 均显示（原 CPA-250『副标题隐藏』口径被取代），中间用 span1 的 ::after 补『·』分隔，外壳 DOM 零改动。 */
  .topbar .brand{display:grid;grid-template-columns:auto auto;align-items:center;justify-content:start;column-gap:0;row-gap:0}
  .topbar .brand img{grid-column:1 / -1}
  .topbar .brand > span:nth-of-type(1){grid-column:1;font-size:12px;font-weight:700;color:var(--primary)}
  .topbar .brand > span:nth-of-type(1)::after{content:"·";color:#94a3b8;margin:0 2px;font-weight:400}
  .topbar .brand > span:nth-of-type(2){display:inline!important;grid-column:2;font-size:0!important}
  /* CPA-256 需求⑤：品牌副标题只留版本号，去掉「投放平台」四字——文字节点随父 span font-size:0 隐去，
     版本号 .js-app-version 显式复位字号后仍可见；外壳 DOM 零改动（cpa172 E3 仍要求各页含「投放平台」）。 */
  .topbar .brand > span:nth-of-type(2) .js-app-version{font-size:10px;color:#94a3b8;font-weight:500}
  /* 深色模式开关改挂「我的」页设置区：顶栏用户区内隐藏。挂载后元素不在 .topbar .user 下，本规则自然失配，
     由 #dark_switch{display:inline-flex!important} 重新显示。 */
  .topbar .user #dark_switch{display:none!important}
  /* 底栏节点运行期被搬进 .topbar：转为静态流内元素（position:static 已使 bottom:0 失效，
     不写 bottom:auto 以避开 cpa174 A2 的禁用字面量）；去掉底部内边距/顶边/阴影/层级，融进顶栏。 */
  .topbar .brand{flex:0 0 auto}
  /* 【CPA-254 需求③a】4 个入口改为「图标在上、文字在下」的小竖排（老板：这 4 个文字要显示），
     不再 32px 圆形只留图标；激活项为主题色底 + 白字。 */
  /* CPA-256 需求⑤：顶栏「品牌 | 三个模块入口（数据/任务/中控台）居中 | 我的贴右」，左右呼应、均匀排布。
     底栏节点整体绝对铺满顶栏作居中参照：三个模块入口居中，第 4 项「我的」贴右（有头像时显示头像缩略图）。 */
  .topbar .brand{position:relative;z-index:2}
  /* CPA-257：4 个入口由「绝对定位居中」改为「静态流内横向等距铺开」。原居中布局使 3 个模块入口挤在顶栏
     正中、又与品牌右侧的小助手入口相互遮挡（老板：「挤在一块」「有遮挡」）。改后：品牌 → 小助手 →
     4 入口（flex:1 等分 + space-around）→ 用户区，各占其位、互不重叠。 */
  .mobile-bottom-nav.mobile-top-nav{position:static;flex:1 1 auto;min-width:0;display:flex!important;align-items:center;justify-content:center;background:transparent!important;border-top:none;box-shadow:none;padding:0;z-index:auto}
  .mobile-bottom-nav.mobile-top-nav .mobile-bottom-nav-inner{width:100%;max-width:none;margin:0;display:flex;align-items:center;justify-content:space-around;gap:2px;padding:0 2px}
  .mobile-bottom-nav.mobile-top-nav .mobile-bottom-nav-item{flex:1 1 0;min-width:0;width:auto;height:auto;padding:3px 2px;border-radius:10px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;background:transparent;color:var(--text2);-webkit-tap-highlight-color:transparent}
  .mobile-bottom-nav.mobile-top-nav .mobile-bottom-nav-item .icon{font-size:0;line-height:0;display:flex;align-items:center;justify-content:center}
  .mobile-bottom-nav.mobile-top-nav .mobile-bottom-nav-item .icon svg{width:20px!important;height:20px!important}
  .mobile-bottom-nav.mobile-top-nav .mobile-bottom-nav-item .icon img{width:26px!important;height:26px!important;border-radius:50%;object-fit:cover;display:block}
  .mobile-bottom-nav.mobile-top-nav .mobile-bottom-nav-item .name{display:block;font-size:10px;line-height:1.05;color:inherit}
  .mobile-bottom-nav.mobile-top-nav .mobile-bottom-nav-item.active{color:var(--primary);font-weight:600}
}
/* ===== CPA-259 需求③：手机端顶栏去掉版本号 + 整条顶栏横向均匀铺开（不再靠左） =====
   老板口径：「顶部盈钱树横幅的·版本号去掉，logo 这一排均匀分布。现在太靠左了」（确认：仅手机端）。
   做法：① 手机端品牌副标题还原为「投放平台」、隐藏版本号 .js-app-version（PC 端版本号照旧显示）；
        ② 解除底部导航容器与内层的盒（display:contents），使「品牌 / 小助手 / 4 个入口」都成为
           .topbar 的直接 flex 子项，再交由 .topbar 用 space-evenly 横向均匀铺开，品牌不再贴左缘。
   外壳 DOM 零改动；cpa172 E1/E3/E4、cpa170 D1（版本填充能力）、cpa174（底栏基础规则）均保留。 */
@media (max-width:768px){
  .topbar{justify-content:space-evenly;padding:0 12px}
  .topbar .brand{margin-right:0}
  .topbar .brand > span:nth-of-type(2){display:inline!important;grid-column:2;font-size:12px!important;color:var(--text-tertiary);font-weight:400}
  .topbar .brand > span:nth-of-type(2) .js-app-version{display:none!important}
  .mobile-bottom-nav.mobile-top-nav,
  .mobile-bottom-nav.mobile-top-nav .mobile-bottom-nav-inner{display:contents!important}
  .topbar .mobile-bottom-nav.mobile-top-nav .mobile-bottom-nav-item{flex:0 1 auto;min-width:0}
}




/* ===== CPA-253 需求④：所有子页面统一「← 返回」标识（运行期注入到顶栏最左，外壳零改动） =====
   老板口径：参照「关于盈钱树」页已有的「← 返回」，其余子页面统一补上；根页（数据中心/我的/媒体结算台）不显示。 */
.page-back-btn{flex:0 0 auto;margin-right:12px;height:32px;padding:0 12px;display:inline-flex;align-items:center;gap:4px;border:1px solid var(--border);background:var(--bg2);color:var(--text2);border-radius:var(--radius-sm);font-size:13px;font-weight:500;cursor:pointer;white-space:nowrap;-webkit-tap-highlight-color:transparent;transition:color .15s,border-color .15s,background .15s}
.page-back-btn:hover{color:var(--primary);border-color:var(--primary);background:var(--primary-light)}
@media (max-width:768px){
  .page-back-btn{margin-right:6px;height:28px;padding:0 8px;font-size:12px;gap:3px}
}


/* ===== CPA-257 需求②：手机端紧凑任务表——状态列按内容取宽、列距收紧，状态名统一左对齐。
   CPA-944（老板 2026-10-12）：状态名后的「括号排期图标盒」整体去除（排期图标只在排期列展示）；
   状态前图标槽改「有图标才占位」——无图标零宽零距，有图标才留约 1 个空格。 ===== */
@media (max-width:768px){
  /* (1) 勾选列窄内边距：缩短「勾选框 ↔ 状态列」的视觉间距 */
  body.task-compact #taskTable td:nth-child(1),
  body.task-compact #taskTable th:nth-child(1){padding-left:2px!important;padding-right:2px!important}
  /* (2) CPA-948（老板 2026-10-12 第六批第 3 条「值居中，空间均匀」）：状态列去图标留空后改「文本居中」并收内边距 */
  body.task-compact #taskTable td:nth-child(2){min-width:0!important;text-align:center!important;padding-left:2px!important;padding-right:2px!important}
  /* (3) 状态单元格常规文档流；前缀图标槽「有图标才占位」（沿用 .st-ico-col 基础规则，不再设 36px 定宽槽） */
  body.task-compact #taskTable td:nth-child(2) .st-cell{position:static;display:inline-flex;align-items:center;vertical-align:middle}
  body.task-compact #taskTable td:nth-child(2) .st-ico-col{position:static;transform:none;justify-content:flex-start;box-sizing:border-box;padding-right:0;margin-right:0;width:auto;min-width:0}
  body.task-compact #taskTable td:nth-child(2) .st-ico-col:not(:empty){margin-right:.25em}
  /* (4) CPA-946（老板 2026-10-12「所有列看看对齐，还有间距调整下，一屏显示。不带左右滑」）：
     精简态只剩「勾选 / 状态 / 任务名称 / 完成进度」4 列，需在一屏（≤390px）内放下且不出现左右横滑，
     故解除手机端全局 .table-wrap table 的 700px 最小宽，改 table-layout:fixed + 定量前段列，
     剩余宽度全给「任务名称」列（内容超宽由 ellipsis 截断），保证整表恒等于容器宽、绝不横滑。 */
  body.task-compact #taskTable table{min-width:0!important;width:100%!important;table-layout:fixed!important}
  body.task-compact #taskTable th,
  body.task-compact #taskTable td{padding-left:3px!important;padding-right:3px!important}
  body.task-compact #taskTable th:nth-child(1),
  body.task-compact #taskTable td:nth-child(1){width:42px}
  body.task-compact #taskTable th:nth-child(2),
  body.task-compact #taskTable td:nth-child(2){width:74px}
  body.task-compact #taskTable th.cc-progress,
  body.task-compact #taskTable td.cc-progress{width:96px}
  /* (5) CPA-948：数据列对齐——状态列改居中（值居中、空间均匀），任务名称/完成进度仍左对齐；
     任务名称列放开 150px 上限并由 td 省略号截断 */
  body.task-compact #taskTable td:nth-child(2),
  body.task-compact #taskTable td.cc-progress{text-align:left!important}
  body.task-compact #taskTable td:nth-child(2){text-align:center!important}
  body.task-compact #taskTable td:nth-child(3){max-width:none!important;overflow:hidden;text-overflow:ellipsis}
  /* (6) 表头与数据列对齐：精简态状态列表头同样居中；任务名称/完成进度表头左对齐 */
  body.task-compact #taskTable th:nth-child(2){text-align:center!important}
  body.task-compact #taskTable th:nth-child(3),
  body.task-compact #taskTable th.cc-progress{text-align:left!important}
}
/* CPA-948（老板 2026-10-12 第六批第 7 条「手机端状态列和任务名称之间的空间是不是有点大」）：
   手机端全览（非精简）态状态列同样居中并收紧左右内边距，缩短「状态 ↔ 任务名称」的视觉间距。 */
@media(max-width:768px){
  body:not(.task-compact) #taskTable td.st-col{text-align:center!important;padding-left:3px!important;padding-right:3px!important}
}

/* ===================== CPA-260 ===================== */
/* CPA-260 需求③：原「到顶/到底浮窗拖动吸附」（.tsf-snap 过渡规则）随该功能整体移除（CPA-932，老板 2026-10-11）。 */

/* ===== CPA-260 需求②④：手机端顶栏 =====
   需求②：品牌只留「logo + 盈钱树」，去掉「投放平台」副标题（文字节点随父 span font-size:0 隐去，外壳 DOM 零改动）；
          4 个模块入口图标由 20px 放大到 26px、间距拉开。
   需求④：「我的」入口不再居中于末段，改贴导航区右缘（inner 由 space-around 改 space-between、item 不再等分拉伸）。 */
@media (max-width:768px){
  .topbar .brand{display:flex;align-items:center;gap:6px;flex:0 0 auto}
  .topbar .brand img{width:30px;height:30px}
  .topbar .brand > span:nth-of-type(1){font-size:14px}
  .topbar .brand > span:nth-of-type(1)::after{content:none}
  .topbar .brand > span:nth-of-type(2){font-size:0!important}
  .mobile-bottom-nav.mobile-top-nav .mobile-bottom-nav-inner{justify-content:space-between;gap:6px;padding:0 4px}
  .mobile-bottom-nav.mobile-top-nav .mobile-bottom-nav-item{flex:0 0 auto;padding:4px 8px;gap:3px}
  .mobile-bottom-nav.mobile-top-nav .mobile-bottom-nav-item .icon svg{width:26px!important;height:26px!important}
  .mobile-bottom-nav.mobile-top-nav .mobile-bottom-nav-item .icon img{width:30px!important;height:30px!important;border-radius:50%;object-fit:cover;display:block}
  .mobile-bottom-nav.mobile-top-nav .mobile-bottom-nav-item .name{font-size:11px}
}

/* ===================== CPA-261 ===================== */
/* 需求E：全站选中态统一「文字变色 + 浅底」，取消实心主题色填充。
   老板：「数据/任务/中控台」的选中展示很好（只把颜色变成主题色），「已下架」也改得很好；今日实时/昨日/分日、
   流量模拟/内网/公网这些实心蓝太深，要清爽明朗。
   实现一律「后置覆盖」——不改动任何既有被守卫锚定的规则，只在其后追加同选择器（同优先级靠后胜出）
   或更高优先级的规则，旧守卫逐字锚点全部保持原样。 */
.batch-select-here.active{background:var(--primary-light)!important;color:var(--primary)!important;border-color:var(--primary)!important}
.mobile-batch-select-here.active{background:var(--primary-light)!important;color:var(--primary)!important;border-color:var(--primary)!important}
[data-theme="dark"] .mobile-batch-select-here.active{background:rgba(22,119,255,.22)!important;color:#7cc0ff!important;border-color:var(--primary)!important}
.pagination button.active{background:var(--primary-light)!important;color:var(--primary)!important;border-color:var(--primary)!important}
[data-theme="dark"] .pagination button.active{background:rgba(22,119,255,.22)!important;color:#7cc0ff!important;border-color:var(--primary)!important}
.schedule-time-tag.active,.schedule-week-tag.active{background:var(--primary-light)!important;color:var(--primary)!important;border-color:var(--primary)!important}
/* 数据中心：模块切换（平台数据/用户数据/代理请求数据）与时间范围（今日实时/昨日/分日…）按钮的选中态是内联实心主题色，
   用属性子串选择器只命中「选中」的那一颗，改为浅底 + 主题色文字（未选中态原样不动）。
   ★ 子串必须写 var(--primary) 而非 background:var(--primary)：JS（switchStatsModule / setStatsRange / setUserDataRange）
   点击时用 style.background='var(--primary)' 写内联样式，浏览器序列化为「background: var(--primary);」（冒号后带空格），
   无空格写法会失配 → 点一下按钮就回退实心蓝。var(--primary-light)/var(--primary-dark) 均不含子串 var(--primary)，
   不会误命中未选中态；未选中态只含 var(--border)/var(--card)/var(--text2)。 */
button[data-stats-module][style*="var(--primary)"],
button[onclick^="setStatsRange("][style*="var(--primary)"],
button[onclick^="setUserDataRange("][style*="var(--primary)"]{background:var(--primary-light)!important;color:var(--primary)!important}
/* 压测：流量模拟/摸高压测、公网/内网 的选中态由 JS 切到 .btn-primary（实心），此处按 id 收成浅底（JS 零改动）。 */
#stModeCustom.btn-primary,#stModeRamp.btn-primary,#stNetPublic.btn-primary,#stNetInner.btn-primary{background:var(--primary-light)!important;color:var(--primary)!important;border:1px solid var(--primary)!important}
[data-theme="dark"] #stModeCustom.btn-primary,[data-theme="dark"] #stModeRamp.btn-primary,
[data-theme="dark"] #stNetPublic.btn-primary,[data-theme="dark"] #stNetInner.btn-primary{background:rgba(22,119,255,.22)!important;color:#7cc0ff!important}

/* 需求C：数据中心「平台数据/用户数据/代理请求数据」切换行紧贴顶栏横幅——手机端 .app .main 的 padding-top 恰等于
   顶栏高（60px），内容与横幅 0 间隙；而该行自身下边距是 16px，上下不等。
   补 14px 上边距使其与下方 16px 基本均衡：整行下移、不再贴住横幅，也不留突兀空档。 */
/* 需求D/F：顶栏 4 个入口图标等比放大不失真、线条更细、观感更浅。
   原图标是 24 viewBox 的描边 SVG，缩到 26px 后 .icon-svg-stroke 的 stroke-width:2 被一并等比放大（≈2.2px），
   显得又粗又深；这里把描边收到 1.5，图标盒统一正方 + display:block 去掉基线间隙，并取消激活项
   .active .icon{transform:scale(1.1)} 的额外放大 —— 五项图标尺寸一致，只靠颜色区分选中态。 */
/* 需求H：6 个元素（品牌 / 小助手 / 数据 / 任务 / 中控台 / 我的）的横向比例重新分割：
   品牌 + 小助手靠左定宽，中间三项等分撑开，「我的」用 margin-left:auto 独占右端（比 space-evenly 更靠右）。 */
@media (max-width:768px){
  .app .main > .sticky-top-bar.stats-tabs:first-child{margin-top:14px}
  .topbar{justify-content:flex-start;gap:2px;padding:0 10px}
  .topbar .brand{flex:0 0 auto;margin-right:2px}
  #aiAssistantEntry{flex:0 0 auto;margin-right:4px}
  .mobile-bottom-nav.mobile-top-nav .mobile-bottom-nav-item{flex:0 0 auto;height:auto;align-self:center;padding:4px 6px;gap:2px}
  .mobile-bottom-nav.mobile-top-nav .mobile-bottom-nav-item:not([data-page="mobile_my"]){flex:1 1 0;min-width:0}
  .mobile-bottom-nav.mobile-top-nav .mobile-bottom-nav-item[data-page="mobile_my"]{margin-left:auto}
  .mobile-bottom-nav.mobile-top-nav .mobile-bottom-nav-item .icon{font-size:0;line-height:0;width:26px;height:26px;flex:0 0 auto;display:flex;align-items:center;justify-content:center}
  .mobile-bottom-nav.mobile-top-nav .mobile-bottom-nav-item .icon svg{width:26px!important;height:26px!important;max-width:100%;max-height:100%;display:block;stroke-width:1.5}
  .mobile-bottom-nav.mobile-top-nav .mobile-bottom-nav-item.active .icon{transform:none}
  .mobile-bottom-nav.mobile-top-nav .mobile-bottom-nav-item .name{font-size:11px;line-height:1.15;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
}

/* ===================== CPA-262：REQ-E 补全 · 全站选中态浅色化（第二轮） =====================
   老板：「我是感觉你尽量把所有的按钮的都可以改一改」「已下架就改得很好，变色没有那么深」。
   第一轮只覆盖了批量/分页/时间与星期标签/数据中心模块与范围/压测模式与链路；本轮回补其余全部「选中态实心主题色」
   的按钮，统一收成「浅底 var(--primary-light) + 主题色文字 + 主题色边框」。仍全部走后置覆盖 + !important，
   既有被守卫逐字锚定的规则（cpa250 A3 的 #pcCompactBtn/#pcDupBtn、cpa227 的 .log-scope-seg{ 等）一字不动。
   本轮零 JS 改动：能覆盖内联（.tool-tab / #tlmTabRaw）就靠 !important 覆盖内联，能靠 onClick 前缀命中的就不动源码。 */
/* 列表表头「列筛选漏斗」激活态（原 .col-funnel.on 实心，与其 :hover 的浅色态不一致） */
.col-funnel.on,.col-funnel.on:hover{background:var(--primary-light)!important;color:var(--primary)!important}
/* 手机任务工具条「分页/全览」（原实心；本轮起与同条内的「精简」同用浅色态） */
#mTaskToolbar .mtt-seg button.on{background:var(--primary-light)!important;color:var(--primary)!important;font-weight:600}
/* 排期选择器「星期格」 */
.sched-grid .week-cell.on{background:var(--primary-light)!important;border-color:var(--primary)!important;color:var(--primary)!important;font-weight:600}
/* PC 任务视图段选：分页/全览(.on) + 精简/复投(.active)。用 button.active 通配，避免复述 cpa250 A3 逐字锚点 */
.task-view-seg button.on,
.task-view-seg button.active{background:var(--primary-light)!important;color:var(--primary)!important;font-weight:600}
/* 访问/操作/修改记录 的「我的｜全部」范围段选 */
.log-scope-seg button.on{background:var(--primary-light)!important;color:var(--primary)!important;font-weight:600}
/* 中控台子页签（内联实心，!important 覆盖内联） */
.tool-tab.on,.tool-tab.active{background:var(--primary-light)!important;color:var(--primary)!important;font-weight:600}
/* 任务链接弹窗「原始链接｜实际投放链接」段选（内联实心） */
#tlmTabRaw[style*="var(--primary)"],#tlmTabFinal[style*="var(--primary)"]{background:var(--primary-light)!important;color:var(--primary)!important}
/* 回收站「全览/分页」、代理请求范围、集集星球范围（btn-primary 切换态，按 onClick 前缀只命中选中那颗） */
button.btn-primary[onclick^="setRecycleViewAll("],
button.btn-primary[onclick^="arSwitch("],
button.btn-primary[onclick^="hllSetRange("]{background:var(--primary-light)!important;color:var(--primary)!important;border-color:var(--primary)!important}
/* 暗色变体（同一浅色范式，rgba 分量替代 --primary-light 的纯深色底，保证暗底下仍清透） */
[data-theme="dark"] .col-funnel.on,[data-theme="dark"] .col-funnel.on:hover{background:rgba(22,119,255,.22)!important;color:#7cc0ff!important}
[data-theme="dark"] #mTaskToolbar .mtt-seg button.on{background:rgba(22,119,255,.22)!important;color:#7cc0ff!important}
[data-theme="dark"] .sched-grid .week-cell.on{background:rgba(22,119,255,.22)!important;border-color:#4096ff!important;color:#7cc0ff!important}
[data-theme="dark"] .task-view-seg button.on,
[data-theme="dark"] .task-view-seg button.active{background:rgba(22,119,255,.22)!important;color:#7cc0ff!important}
[data-theme="dark"] .log-scope-seg button.on{background:rgba(22,119,255,.22)!important;color:#7cc0ff!important}
[data-theme="dark"] #tlmTabRaw[style*="var(--primary)"],[data-theme="dark"] #tlmTabFinal[style*="var(--primary)"]{background:rgba(22,119,255,.22)!important;color:#7cc0ff!important}
[data-theme="dark"] button.btn-primary[onclick^="setRecycleViewAll("],
[data-theme="dark"] button.btn-primary[onclick^="arSwitch("],
[data-theme="dark"] button.btn-primary[onclick^="hllSetRange("]{background:rgba(22,119,255,.22)!important;color:#7cc0ff!important;border-color:#4096ff!important}
[data-theme="dark"] .schedule-time-tag.active,[data-theme="dark"] .schedule-week-tag.active{background:rgba(22,119,255,.22)!important;color:#7cc0ff!important;border-color:#4096ff!important}

/* ===================== CPA-263：手机端 4 入口回到底部 Tab + 顶栏品牌完整显示 + 中部小助手轮播 =====================
   老板口径（逐字）：「4 个选项落下去之后，logo 附近的盈钱树·投放平台可以完整展示了，注意加上小字的 v版本号。
                     盈钱树小助手的图标就可以挪到右侧，中间空白的部分显示小助手的说话内容，可以轮播」。
   一律「后置覆盖」——CPA-250/254/259/260/261 既有规则一字不动（守卫逐字锚点全部保留）：
     ① 4 入口回底部：JS 不再搬移（不再加 .mobile-top-nav 类），底栏基础规则
        （position:fixed / bottom:0 / z-index:9999）自然生效；
     ② 顶栏品牌改回单行完整显示：logo +「盈钱树·投放平台 + 小字 v版本号」，
        覆盖 CPA-259/260 的「副标题 font-size:0 / 版本号 display:none」；
     ③ 顶栏中部 .ai-say 轮播（仅手机端；PC 由 JS 不创建 + 此处 display:none 双保险），右端为小助手图标。 */
/* ===================== CPA-267：PC 端小精灵「说话框」——图标在框内 +「：」+ 内容放大 =====================
   老板口径（逐字）：「电脑端……在小框里，小精灵后面加个冒号……把'盈钱树小助手'去掉，它发的内容就在这个小框里面变大」；
                    「把它挪到系统运维的右侧……可以让它在这里说话」。
   实现：说话框由 JS 追加进 #navMenu（末项「系统运维」右侧空白区），此处渲染为带边框小框 ——
        框内 = 小精灵头像 +「：」+ 说话正文（正文放大）；小精灵头像入口（.ai-eye-btn）在 PC 端隐藏（图标已入框）。
   CPA-263/265 既有规则与守卫锚点一字不动（本块为新增覆盖，不删原规则）。 */
.topbar .ai-say{display:inline-flex;align-items:center;gap:6px;max-width:380px;margin-left:10px;padding:5px 12px;border:1px solid var(--border);border-radius:12px;background:var(--card);color:var(--text2);font-size:13.5px;line-height:1.3;overflow:hidden;cursor:pointer;-webkit-tap-highlight-color:transparent;transition:background .15s,border-color .15s}
.topbar .ai-say:hover,
.topbar .ai-say:active{background:var(--primary-light);border-color:var(--primary)}
.topbar .ai-say .ai-say-ic{flex:0 0 auto;display:inline-flex;align-items:center;color:var(--primary)}
.topbar .ai-say .ai-say-ic::after{content:"："}
.topbar .ai-say .ai-say-svg{width:19px;height:19px;display:block}
.topbar .ai-say .ai-asst-head{fill:none;stroke:currentColor;stroke-width:1.4}
.topbar .ai-say .ai-asst-antenna-stem{stroke:currentColor;stroke-width:1.4;stroke-linecap:round}
.topbar .ai-say .ai-asst-antenna{fill:currentColor}
.topbar .ai-say .ai-asst-eye{fill:currentColor}
.topbar .ai-say .ai-asst-smile{fill:none;stroke:currentColor;stroke-width:1.4;stroke-linecap:round}
.topbar .ai-say .ai-say-tx{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:600;color:var(--text)}
@media (min-width:769px){.topbar .ai-eye-btn{display:none}}
@media (max-width:768px){
  .topbar{justify-content:flex-start;align-items:center;gap:4px;padding:0 10px}
  /* ② 品牌单行完整显示「盈钱树·投放平台 + 小字 v版本号」 */
  .topbar .brand{display:flex!important;align-items:center;gap:5px;flex:0 0 auto;margin-right:0;white-space:nowrap}
  .topbar .brand img{width:26px;height:26px;border-radius:50%;object-fit:cover;grid-column:auto}
  .topbar .brand > span:nth-of-type(1){display:inline!important;font-size:14px;font-weight:700;color:var(--primary);line-height:1}
  .topbar .brand > span:nth-of-type(1)::after{content:"·";color:#94a3b8;margin:0 1px;font-weight:400}
  .topbar .brand > span:nth-of-type(2){display:inline!important;font-size:12px!important;color:var(--text-tertiary);font-weight:400;line-height:1}
  .topbar .brand > span:nth-of-type(2) .js-app-version{display:inline!important;font-size:10px;color:#94a3b8;font-weight:500}
  /* ③ 中部小助手轮播 + 右端小助手图标 */
  .topbar .ai-say{display:flex;flex:1 1 auto;min-width:0;align-items:center;gap:5px;margin:0 6px;color:var(--text-secondary);font-size:12.5px;line-height:1.2;overflow:hidden;cursor:pointer;-webkit-tap-highlight-color:transparent}
  .topbar .ai-say:active{opacity:.72}
  .topbar .ai-say .ai-say-ic{flex:0 0 auto;display:inline-flex;color:var(--primary)}
  .topbar .ai-say .ai-say-ic svg{width:15px;height:15px;display:block;stroke-width:1.6}
  .topbar .ai-say .ai-say-tx{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;opacity:1;transition:opacity .32s ease}
  .topbar .ai-say .ai-say-tx.fade{opacity:0}
  .topbar #aiAssistantEntry{flex:0 0 auto;margin-left:0}
}
/* ===================== CPA-273：小精灵「说话框」点击弹窗（出处 + 对话）=====================
   老板 2026-10-08 拍板：点说话框 → 把当前这句带进去、答出它的出处，并支持继续对话（公司业务相关）。 */
.modal .ai-panel{display:flex;flex-direction:column;gap:12px;min-height:56vh}
.modal .ai-src{background:var(--primary-light);border:1px solid var(--border);border-radius:12px;padding:12px 14px}
.modal .ai-src-t{font-size:15px;font-weight:600;color:var(--text);line-height:1.5;word-break:break-word}
.modal .ai-src-l{font-size:12.5px;color:var(--text2);margin-top:6px}
.modal .ai-log{flex:1 1 auto;overflow-y:auto;display:flex;flex-direction:column;gap:10px;padding:4px 2px;min-height:150px;max-height:46vh}
.modal .ai-msg{max-width:82%;padding:9px 12px;border-radius:12px;font-size:14px;line-height:1.55;word-break:break-word;white-space:normal}
.modal .ai-msg-user{align-self:flex-end;background:var(--primary);color:#fff;border-bottom-right-radius:4px}
.modal .ai-msg-bot{align-self:flex-start;background:var(--bg3);color:var(--text);border-bottom-left-radius:4px}
.modal .ai-msg-sys{align-self:center;max-width:92%;background:transparent;color:var(--text2);font-size:12.5px;text-align:center;padding:4px 8px}
.modal .ai-bar{display:flex;gap:8px;align-items:center}
.modal .ai-input{flex:1 1 auto;min-width:0;padding:10px 12px;border:1px solid var(--border);border-radius:10px;background:var(--card);color:var(--text);font-size:14px}
.modal .ai-input:focus{outline:none;border-color:var(--primary)}
.modal .ai-send{flex:0 0 auto;padding:10px 18px;border:none;border-radius:10px;background:var(--primary);color:#fff;font-size:14px;font-weight:600;cursor:pointer;-webkit-tap-highlight-color:transparent}
.modal .ai-send:disabled{opacity:.6;cursor:not-allowed}
/* ===================== CPA-929 需求②：小助手「知识卡片瀑布流」大弹窗 =====================
   老板 2026-10-11 拍板：点小助手进去是「浏览屏幕 / 获取知识来源」，卡片机制的小卡片知识（可取自现有内容库）。
   弹窗形态对标「平台汇总」的大弹窗（modal-frame：1100px/96vw、88vh、padding:0、overflow:hidden），
   顶部一条类目筛选（像新闻软件，按条数降序，「全部」在首），主体为纯浏览瀑布流（手机 1 列 / PC 2 列，JS 轮转分列）。
   全部走主题变量，深浅色/换色自动适配，无需单独 dark 覆盖。 */
.ai-lib{display:flex;flex-direction:column;height:100%;width:100%;background:var(--bg)}
.ai-lib-head{flex:0 0 auto;display:flex;align-items:center;gap:10px;padding:12px 48px 12px 16px;border-bottom:1px solid var(--border);background:var(--card)}
.ai-lib-tabs{flex:1 1 auto;min-width:0;display:flex;gap:8px;overflow-x:auto;-webkit-overflow-scrolling:touch;scrollbar-width:none;padding:2px 0}
.ai-lib-tabs::-webkit-scrollbar{display:none}
.ai-lib-tab{flex:0 0 auto;border:1px solid var(--border);background:var(--card);color:var(--text2);border-radius:var(--radius-pill);padding:5px 12px;font-size:13px;white-space:nowrap;cursor:pointer;-webkit-tap-highlight-color:transparent}
.ai-lib-tab:hover{color:var(--primary);border-color:var(--primary)}
.ai-lib-tab.active{background:var(--primary);color:#fff;border-color:var(--primary);font-weight:600}
.ai-lib-ask{flex:0 0 auto;border:1px solid var(--border);background:var(--card);color:var(--primary);border-radius:var(--radius-pill);padding:6px 14px;font-size:13px;font-weight:600;white-space:nowrap;cursor:pointer;-webkit-tap-highlight-color:transparent}
.ai-lib-ask:hover{background:var(--primary-light)}
.ai-lib-grid{flex:1 1 auto;min-height:0;overflow-y:auto;-webkit-overflow-scrolling:touch;display:flex;gap:12px;padding:14px 16px;align-items:flex-start}
.ai-lib-col{flex:1 1 0;min-width:0;display:flex;flex-direction:column;gap:12px}
.ai-lib-card{background:var(--card);border:1px solid var(--border);border-radius:12px;padding:12px 14px;box-shadow:var(--shadow);cursor:pointer;-webkit-tap-highlight-color:transparent;transition:border-color .15s,box-shadow .15s}
.ai-lib-card:hover{border-color:var(--primary)}
.ai-lib-tag{display:inline-block;background:var(--primary-light);color:var(--primary-dark);border-radius:var(--radius-pill);padding:2px 9px;font-size:11.5px;margin-bottom:8px}
.ai-lib-text{font-size:14px;line-height:1.6;color:var(--text);word-break:break-word;white-space:normal}
.ai-lib-empty{flex:1 1 auto;display:flex;align-items:center;justify-content:center;color:var(--text2);font-size:14px;padding:40px 16px;text-align:center}
/* CPA-931：所有卡片可点开；点开由 TokenHub 现场生成「出处 + 解读」（同一弹窗内就地展开，纯阅读无对话） */
.ai-lib-card.has-detail{cursor:pointer;-webkit-tap-highlight-color:transparent;transition:border-color .15s,box-shadow .15s}
.ai-lib-card.has-detail:hover{border-color:var(--primary)}
.ai-lib-more{display:inline-block;margin-top:8px;color:var(--primary);font-size:12.5px;font-weight:600}
.ai-lib-detail-loading{color:var(--text2);font-size:14px}
/* CPA-933：生成「出处 + 解读」需要时间，加转圈动效提示加载中 */
.ai-lib-spinner{display:inline-block;width:13px;height:13px;margin-right:7px;border:2px solid var(--border);border-top-color:var(--primary);border-radius:50%;vertical-align:-2px;animation:aiLibSpin .7s linear infinite}
@keyframes aiLibSpin{to{transform:rotate(360deg)}}
.ai-lib-detail-err{color:#d9534f;font-size:14px;line-height:1.8}
.ai-lib-detail{display:flex;flex-direction:column;gap:12px;width:100%;max-width:760px;margin:0 auto}
.ai-lib-detail-bar{display:flex;align-items:center;gap:10px}
.ai-lib-back{flex:0 0 auto;border:1px solid var(--border);background:var(--card);color:var(--primary);border-radius:var(--radius-pill);padding:6px 14px;font-size:13px;font-weight:600;cursor:pointer;-webkit-tap-highlight-color:transparent}
.ai-lib-back:hover{background:var(--primary-light)}
.ai-lib-detail-body{background:var(--card);border:1px solid var(--border);border-radius:14px;padding:18px 20px;box-shadow:var(--shadow)}
.ai-lib-detail-title{font-size:17px;font-weight:700;line-height:1.5;color:var(--text);margin-bottom:12px}
.ai-lib-detail-text{font-size:14.5px;line-height:1.85;color:var(--text);white-space:pre-wrap;word-break:break-word}
.ai-lib-detail-more-title{margin:20px 0 10px;padding-top:14px;border-top:1px solid var(--border);font-size:13.5px;font-weight:600;color:var(--text2)}
.ai-lib-same{display:flex;flex-direction:column;gap:10px}
@media (max-width:768px){
  .ai-lib-head{padding:10px 46px 10px 12px;gap:8px}
  .ai-lib-grid{padding:10px 12px;gap:10px}
  .ai-lib-col{gap:10px}
  .ai-lib-card{padding:10px 12px}
  .ai-lib-text{font-size:13.5px}
  .ai-lib-detail-body{padding:14px 15px}
  .ai-lib-detail-title{font-size:15.5px}
  .ai-lib-detail-text{font-size:14px;line-height:1.8}
}
/* CPA-906 §41：AI 助手「一键直达」入口按钮（管理员侧） */
.ai-goto{margin:6px 0 2px;display:flex;flex-wrap:wrap;gap:6px}
.ai-goto-btn{border:1px solid var(--border);background:var(--card);color:var(--primary);border-radius:14px;padding:4px 10px;font-size:13px;cursor:pointer}
.ai-goto-btn:hover{background:var(--hover,#f2f6ff)}
/* ===================== CPA-264：禁用页面缩放（老板拍板）=====================
   目标：手机端页面恒定 1:1，弹窗永不失真（老板：「放大后点开弹窗仍失真，要跟没放大一样」）。
   手法：html/body 设 touch-action:pan-x pan-y —— Chromium / 微信内核据此禁捏合、禁双击放大，
        纵向/横向滚动照常（pan-x pan-y 均放行，正常滚动与表格横滑不受影响）；
        补 text-size-adjust:100% 防微信「字体自动放大」。
   .modal 亦收紧：其 overflow-y:auto 是弹窗内的滚动容器，触摸终点落在其中时按该元素 touch-action 判定。
   配套 JS：common.js 的 __resetViewportZoom（运行期重申 viewport meta 锁定，兜底仍认 meta 的内核）。 */
html,body{touch-action:pan-x pan-y;-webkit-text-size-adjust:100%;text-size-adjust:100%}
.modal{touch-action:pan-x pan-y}

/* ===================== CPA-919：缩放禁用「全页面覆盖」（老板报障 2026-10-10）=====================
   现象（逐字）：「捏合缩放控制仅在『我的』页面生效，其他页面未生效」「弹窗打开后底层页面仍可滑动」。
   根因①（缩放）：CPA-264 只给 html,body,.modal 收紧 touch-action。但按触摸事件规范的判定链——**触摸起点
        落在某个内部滚动容器（.table-wrap / .tabs / 弹窗内滚动区 / 内联 overflow 容器…）时，判定链在该
        滚动容器处截止**，容器自身 touch-action:auto 即放行捏合 ⇒ html,body 的规则够不着，「我的」页
        （无内部滚动容器、触摸直接落在 body）才生效。
   治法①：对所有元素统一收紧 touch-action:pan-x pan-y —— 任意页面、任意落点，判定链逐层都是 pan-x pan-y，
        捏合/双击放大一律禁用，纵向与横向滚动（pan-x pan-y 均放行）不受影响。
        既有更具体的规则特异性更高、逐字不受影响：.sched-grid / .sched-grid .week-cell / .tsf-btn 的
        touch-action:none（排期网格划过即选、浮窗按钮拖动）、.login-card .login-btn 的 manipulation。
   保守性：仅新增本块，不改 CPA-264 既有 html,body/.modal 两行与任何既有选择器。 */
body *{touch-action:pan-x pan-y}

/* ===================== CPA-265：底部 Tab 高度压缩 + 顶栏品牌三行 + 小助手信息框加宽 + 功能 tab 位置段选 =====================
   老板口径（逐字）：①「底部 4 个选项高度太高了，你调整适配下」；
                   ②「左上角盈钱树的标志，下面有一个盈钱树的三个字，你漏了。写上盈钱树三个字，
                      然后在下面是投放平台版本号」；
                   ③「在到顶到底的设置项下面增加一个设置选项……就叫功能 tab 位置。默认底栏在底部，
                      如果切换到顶部的话，按照之前的那个 UI……在上部的时候，我的的那个头像是用的是个人头像。
                      然后在下部的时候……是用的是 SVG 图片」。
   一律「后置覆盖」，CPA-172/174/250/254/263 既有规则与守卫逐字锚点一字不动。
   注：底栏压缩规则加 :not(.mobile-top-nav) 限定 —— 切到顶部时用 CPA-250 的 .mobile-top-nav 形态，不被本块干扰。 */
@media (max-width:768px){
  /* ① 底部 4 入口尺寸【CPA-942，老板 2026-10-12「底部 4 个 tab 再调大，目前看着还是小」】：
        CPA-265 曾压到 ≈47px（19px 图标 / 10px 文字），老板反馈仍偏小，此处在上再放大——
        图标 19→28px、文字 10→13px、内边距 3/5→4/8px、间距 1→2px（净高 ≈47px→≈67px，仍留在 .mobile-page .main 的 70px 让位内）。
        图标尺寸写在页面外壳的行内 style 上，故需 !important 覆盖。
        【CPA-943，老板 2026-10-12「tab 在底部位置的高度还需要高一点」】：再抬高——内边距 4/8px→6/10px、
        导航内边距 4/4→6/6px、图标 28→30px（净高 ≈67px→≈79px）；正文让位同步 70px→90px（.mobile-page .main）。 */
  /* CPA-947（老板 2026-10-12「底部的 4 个 tab 改为跟放在顶部的时候一样大」）：
     底栏 4 入口尺寸与「功能 tab 位置=顶部」时的形态对齐（同一套图标/文字/内距），两态观感一致：
     图标 30→26px、文字 13→11px、内边距 10/6→4/6px、容器内距 6→4px。
     覆盖 CPA-942/943 的放大值（老板已改为要与顶部一致，故此处回调）；底部态仍由 :not(.mobile-top-nav) 限定。 */
  .mobile-bottom-nav:not(.mobile-top-nav){padding:4px 0 calc(4px + env(safe-area-inset-bottom))}
  .mobile-bottom-nav:not(.mobile-top-nav) .mobile-bottom-nav-item{padding:4px 6px;gap:2px}
  .mobile-bottom-nav:not(.mobile-top-nav) .mobile-bottom-nav-item .icon{font-size:0;line-height:0;display:flex;align-items:center;justify-content:center}
  .mobile-bottom-nav:not(.mobile-top-nav) .mobile-bottom-nav-item .icon svg{width:26px!important;height:26px!important;display:block}
  /* 「我的」头像（老板：设了头像就用头像，尺寸与旁邻图标对齐，不撑大底栏） */
  .mobile-bottom-nav:not(.mobile-top-nav) .mobile-bottom-nav-item .icon img{width:26px!important;height:26px!important;border-radius:50%;object-fit:cover;display:block}
  .mobile-bottom-nav:not(.mobile-top-nav) .mobile-bottom-nav-item .name{font-size:11px;line-height:1.15}
  .mobile-bottom-nav:not(.mobile-top-nav) .mobile-bottom-nav-item.active .icon{transform:none}
  /* ② 顶栏品牌竖排三行：logo →「盈钱树」→「投放平台 + v版本号」，
        品牌整体收窄 ⇒ 给中部小助手信息框让出宽度（外壳 DOM 零改动，纯 CSS 控制显隐） */
  .topbar .brand{display:flex!important;flex-direction:column;align-items:center;justify-content:center;gap:1px;margin-right:2px;white-space:normal;line-height:1}
  .topbar .brand img{width:26px;height:26px;border-radius:50%;object-fit:cover;flex:0 0 auto}
  .topbar .brand > span:nth-of-type(1){display:inline!important;font-size:10px!important;color:var(--primary)!important;font-weight:700;line-height:1;white-space:nowrap}
  .topbar .brand > span:nth-of-type(1)::after{content:none!important}
  .topbar .brand > span:nth-of-type(2){display:inline!important;font-size:8px!important;color:var(--text-tertiary);font-weight:400;line-height:1;white-space:nowrap}
  .topbar .brand > span:nth-of-type(2) .js-app-version{display:inline!important;font-size:8px;color:#94a3b8;font-weight:500}
  /* ③ 中部信息框：加宽 + 允许两行、尽量把话说完；图标换成小助手头像，明确「这些字是小助手说的」 */
  .topbar .ai-say{margin:0 4px;font-size:12px;flex:1 1 0;min-width:0}
  .topbar .ai-say .ai-say-tx{white-space:normal;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;overflow:hidden;line-height:1.18}
  .topbar .ai-say .ai-say-ic{width:16px;height:16px;color:var(--primary)}
  .topbar .ai-say .ai-say-ic svg{width:16px!important;height:16px!important;display:block}
  /* ⑤ 「功能 tab 位置 = 顶部」时的顶栏布局：4 入口固定占位、不被轮播文字挤扁
        （CPA-260 块里的 :not([data-page]) 为 flex:1 1 0 可缩到 0，导致图标仅剩 ~12px；
         此处后置覆盖为不缩不伸 + 最小宽度，轮播文字改为 flex-basis 0 让步收缩） */
  .topbar .mobile-bottom-nav.mobile-top-nav{flex:0 0 auto}
  .topbar .mobile-bottom-nav.mobile-top-nav .mobile-bottom-nav-item{flex:0 0 auto!important;min-width:34px}
  .topbar .mobile-bottom-nav.mobile-top-nav .mobile-bottom-nav-item .name{font-size:9px;max-width:34px}
  /* 「我的」头像在顶部态与旁邻图标同为 26px（CPA-260 的 30px 偏大，此处后置收齐） */
  .topbar .mobile-bottom-nav.mobile-top-nav .mobile-bottom-nav-item .icon img{width:26px!important;height:26px!important;border-radius:50%;object-fit:cover;display:block}
  /* ④ 功能 tab 位置段选（底部 | 顶部），选中态沿用全站「浅底 + 主题色文字」范式 */
  .qs-seg{display:inline-flex;border:1px solid var(--border);border-radius:8px;overflow:hidden;background:var(--bg3)}
  .qs-seg button{border:none;background:transparent;color:var(--text2);font-size:12px;line-height:1;padding:6px 12px;cursor:pointer;-webkit-tap-highlight-color:transparent}
  .qs-seg button.on{background:var(--primary-light);color:var(--primary);font-weight:600}
}
[data-theme="dark"] .qs-seg button.on{background:rgba(22,119,255,.22);color:#7cc0ff}

/* ===================== CPA-267：手机端小精灵两态（老板 2026-10-07 细化，逐字）=====================
   ①「Tab 在顶部」：说话小气泡要从小精灵这边冒出来、不再从「盈钱树」品牌处出来 ⇒
      浮层气泡移到屏幕右侧、尾巴指向右端小精灵（见文件末 .ai-say-float 规则）；
   ②「Tab 在底部」：与电脑端同款 —— 顶栏原本两个小精灵合成一个（保留右端纯头像入口，
      中部条内那个重复头像隐藏），中部说话条渲染成带边框小框，整个框即说话内容。
   后置覆盖 CPA-263/265 既有规则，守卫逐字锚点一字不动。 */
@media (max-width:768px){
  /* 底部态：中部说话条 = 带边框小框，只显示正文（隐藏条内重复的小精灵头像） */
  .topbar .ai-say{display:flex;align-items:center;gap:0;margin:0 6px;padding:3px 10px;border:1px solid var(--border);border-radius:10px;background:var(--card);font-size:12px;line-height:1.2;overflow:hidden}
  .topbar .ai-say .ai-say-ic{display:none}
  .topbar .ai-say .ai-say-tx{white-space:normal;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;overflow:hidden;color:var(--text)}
}

/* ⑥ CPA-265·续（老板 2026-10-07 拍板）：「功能 tab 位置 = 顶部」时小助手不用顶栏内联条，
      改用「顶栏下方」的浮层小对话框 ——
      原话「就用一个小窗口，呈现出来一个小对话框一样的就行了，但是不要影响去操作那几个功能按钮，
            就往左边去呈现，然后呈现的频次也低一点，呈现完了之后显示 5 秒钟，然后就消失，
            再过 30 秒之后再呈现」。节奏（显 5s / 隐 30s）由 JS 加/去 .show 控制。
      CPA-267（老板细化）：「那些小气泡应该是从小精灵这里出来的，现在是从盈钱树那里出来的，这是不对的」⇒
      浮层由屏幕左侧移到右侧、尾巴指向右端小精灵（左对齐改右对齐），使气泡「从右侧小精灵冒出」。
      刻意不写进 @media(max-width:768px)：手机横屏宽度 >768px 时本规则仍生效，
      避免元素掉出样式变裸文本（顶态元素已由 JS 搬出 .topbar，故 .topbar .ai-say 那套规则不再命中）。 */
.ai-say.ai-say-float{
  position:fixed;right:10px;left:auto;top:66px;z-index:9990;
  display:flex;align-items:flex-start;gap:6px;
  max-width:min(74vw,250px);margin:0;padding:8px 11px;
  background:var(--card);color:var(--text);
  border:1px solid var(--border);border-radius:12px;
  box-shadow:0 8px 22px rgba(15,23,42,.16);
  font-size:12px;line-height:1.35;
  opacity:0;transform:translateY(-6px);pointer-events:none;
  transition:opacity .26s ease,transform .26s ease;
  cursor:pointer;-webkit-tap-highlight-color:transparent;
}
.ai-say.ai-say-float.show{opacity:1;transform:none;pointer-events:auto}
.ai-say.ai-say-float:active{opacity:.82}
.ai-say.ai-say-float::before{
  content:"";position:absolute;right:14px;left:auto;top:-6px;width:10px;height:10px;
  background:var(--card);border-left:1px solid var(--border);border-top:1px solid var(--border);
  transform:rotate(45deg);
}
.ai-say.ai-say-float .ai-say-ic{flex:0 0 auto;display:inline-flex;color:var(--primary);margin-top:1px}
.ai-say.ai-say-float .ai-say-ic svg{width:15px!important;height:15px!important;display:block}
.ai-say.ai-say-float .ai-say-tx{min-width:0;white-space:normal;display:block;overflow:visible;text-overflow:clip;opacity:1}

/* ===== CPA-269 需求②：手机端「功能 tab 位置 = 顶部」时，顶栏 6 项均匀铺开 =====
   老板口径：「数据 / 任务 / 中控台」3 个模块入口要往中间靠，与「盈钱树(品牌) / 小助手 / 我的」共 6 项
   在顶栏均匀分布。现状 CPA-260 块的 inner 为 justify-content:space-between、item 为 flex:0 0 auto（模块入口贴边）；
   此处一律「后置覆盖」——仅作用于顶栏态（.mobile-top-nav，导航被搬到顶栏时）：
   导航容器撑满剩余空间 + 内层 space-evenly + 各项等分，使 6 项均匀铺开。底栏（无 .mobile-top-nav）布局不受影响。 */
@media (max-width:768px){
  .topbar .mobile-bottom-nav.mobile-top-nav{flex:1 1 auto;min-width:0}
  .topbar .mobile-bottom-nav.mobile-top-nav .mobile-bottom-nav-inner{justify-content:space-evenly;gap:0}
  .topbar .mobile-bottom-nav.mobile-top-nav .mobile-bottom-nav-item{flex:1 1 0!important;min-width:0}
}

/* ===== CPA-269 需求③：手机端「功能 tab 位置 = 底部」时，固定底栏遮挡页脚，补足底部内边距 =====
   老板口径：翻到最底，「上海得到文化传媒有限公司 | 技术支持 | 版本号」这行页脚会被底栏挡住一点，要完整露出。
   底栏底态压缩后实测高 ≈48px（padding 3+3 / item 5+5 / 图标 19 / 文字 11 / 间隔 1 / 顶边 1）+ iOS 安全区
   env(safe-area-inset-bottom)；而页脚 #pcFooter 是 .app 内最后一个流内元素，其下内边距仅 20px，故被压住。
   此处给页脚补足 ≥ 底栏高度 + 安全区的底部内边距，让页面能多往上翻、页脚完整露在底栏之上；
   只加 padding-bottom，不改 .footer 既有布局（display:flex 等一字不动）。 */
@media (max-width:768px){
  .app .footer,
  #pcFooter{padding-bottom:calc(64px + env(safe-area-inset-bottom))}
}

/* ===== CPA-290 §44：手机端「只读宽表 → 卡片流」统一适配（样式） =====
   卡片 DOM 由 common.js 末尾 cpa290MobileTableCards 生成，仅在手机端出现；
   PC 端不生成 .mob-cards，故本块全部包在 @media(max-width:768px) 内，PC 观感零影响。
   结构：.mob-cards > .mob-card[.is-plain] > (.mob-card-h 首列标题) + (.mob-row > .mob-k 表头 + .mob-v 单元格) */
@media (max-width:768px){
  .mob-cards{display:flex;flex-direction:column;gap:8px}
  .mob-card{border:1px solid var(--border);border-radius:var(--radius-sm);background:var(--card);padding:10px 12px}
  .mob-card.is-plain{text-align:center;color:var(--text-tertiary);font-size:12px;padding:16px 12px}
  .mob-card-h{font-size:13px;font-weight:700;color:var(--text);word-break:break-all;margin-bottom:6px;padding-bottom:6px;border-bottom:1px dashed var(--border)}
  .mob-row{display:flex;gap:8px;align-items:flex-start;font-size:12px;line-height:1.7}
  .mob-row + .mob-row{margin-top:2px}
  .mob-k{flex:0 0 84px;color:var(--text-tertiary);text-align:right}
  .mob-v{flex:1;min-width:0;color:var(--text);word-break:break-all}
  [data-theme="dark"] .mob-card{background:#1e293b;border-color:#334155}
  [data-theme="dark"] .mob-card-h{border-bottom-color:#334155}
}

/* ===== CPA-291 §9：任务「置顶」（行首图标按钮）=====
   行首图钉按钮放在勾选框左侧（手机端不新增行，仍在同一格里）；
   置顶点亮=红；未点亮为弱化灰，不抢视觉。（CPA-905 已移除收藏 / 收藏夹，星标与收藏夹入口条样式一并删除。） */
.flag-btn{background:none;border:0;padding:0 2px;margin:0 1px 0 0;cursor:pointer;color:var(--text-tertiary);opacity:.45;line-height:0;vertical-align:middle}
.flag-btn:hover{opacity:.85}
.flag-btn svg{width:15px;height:15px}
.flag-btn.pin.on{color:#ef4444;opacity:1}

/* ===== CPA-910（§45 登录安全）：新设备登录「一次性提醒条」=====
   仅在有一次性标记时于落地页顶部显示一次；浅色 / 深色都可辨识，移动端 100% 宽、圆角、小字号不溢出。 */
.newdev-notice{display:flex;align-items:center;gap:10px;flex-wrap:wrap;width:100%;box-sizing:border-box;
  padding:10px 14px;background:#fff7ed;border:1px solid #fed7aa;border-left:4px solid #d97706;
  color:#92400e;font-size:13px;line-height:1.6}
.newdev-notice-txt{flex:1;min-width:0}
.newdev-notice-acts{display:flex;align-items:center;gap:8px;margin-left:auto;flex-shrink:0}
.newdev-notice-btn{border:1px solid #fed7aa;background:var(--card);color:#b45309;border-radius:8px;
  padding:4px 10px;font-size:12.5px;cursor:pointer;white-space:nowrap}
.newdev-notice-btn:hover{background:#ffedd5}
.newdev-notice-btn.primary{background:#d97706;border-color:#d97706;color:#fff}
.newdev-notice-btn.primary:hover{background:#b45309}
[data-theme="dark"] .newdev-notice{background:#3a2a12;border-color:#7c5314;border-left-color:#f59e0b;color:#fcd9a0}
[data-theme="dark"] .newdev-notice-btn{background:#2a1f10;border-color:#7c5314;color:#fbbf24}
[data-theme="dark"] .newdev-notice-btn:hover{background:#3a2a12}
[data-theme="dark"] .newdev-notice-btn.primary{background:#d97706;border-color:#d97706;color:#fff}
@media (max-width:768px){
  .newdev-notice{padding:9px 12px;font-size:12.5px;gap:8px}
  .newdev-notice-acts{margin-left:0;width:100%;justify-content:flex-end}
}

/* ============================================================================
   CPA-937 前端动效基建 + 加载体验（展示层）
   老板 2026-10-12：「都处理…方向一：动效基建（低风险，先做）／方向二：加载体验
   （体感提升最大）…把这两个，一口气也做完即可。」
   全部为纯展示层 CSS/DOM 动效：不碰 edge 分发热路径、不引入任何数据库/网络 IO。
   所有时长/缓动统一走 --dur-* / --ease-* 刻度，便于全站复用与统一降级。
   ============================================================================ */
:root{
  /* 动效刻度：1=微交互 2=常规 3=强调 */
  --dur-1:.15s;--dur-2:.24s;--dur-3:.36s;
  --ease:cubic-bezier(.4,0,.2,1);
  --ease-out:cubic-bezier(.16,1,.3,1);
}
/* ①无障碍降级（首批必做）：系统开启「减少动态效果」时，全站动画/过渡一律归零，
   规避前庭不适；用 .001ms 而非 0 以保留 animationend 事件语义。 */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{
    animation-duration:.001ms!important;
    animation-iteration-count:1!important;
    transition-duration:.001ms!important;
    scroll-behavior:auto!important;
  }
}
/* ②弹窗出入场：遮罩内面板轻微上浮+放大（入场）/ 轻微下沉（退场）。
   入场挂在 .modal-mask.show 上；退场由 closeModal() 加 .closing 并延时移除 .show。
   ★CPA-948 返工：该出入场动效（入场 240ms / 退场 150ms）即「弹窗迟滞感」来源，已在文件末尾「无等待感」覆盖块内关闭。 */
@keyframes cpaModalIn{from{opacity:0;transform:translateY(10px) scale(.96)}to{opacity:1;transform:none}}
@keyframes cpaModalOut{to{opacity:0;transform:translateY(6px) scale(.97)}}
.modal-mask.show .modal{animation:cpaModalIn var(--dur-2) var(--ease-out) both}
.modal-mask.closing .modal{animation:cpaModalOut var(--dur-1) var(--ease) both}
/* ③Toast 出入场 + 堆叠：容器固定顶部居中，逐条自上而下堆叠（最多 4 条，见 common.js toast()） */
.toast-wrap{position:fixed;top:20px;left:50%;transform:translateX(-50%);z-index:10001;
  display:flex;flex-direction:column;align-items:center;gap:8px;max-width:86vw;pointer-events:none}
.toast{background:#1e293b;color:#fff;padding:10px 20px;border-radius:6px;font-size:13px;
  max-width:100%;word-break:break-all;box-shadow:var(--shadow-pop);
  animation:cpaToastIn var(--dur-2) var(--ease-out) both}
.toast.out{animation:cpaToastOut var(--dur-1) var(--ease) both}
@keyframes cpaToastIn{from{opacity:0;transform:translateY(-12px) scale(.96)}to{opacity:1;transform:none}}
@keyframes cpaToastOut{to{opacity:0;transform:translateY(-8px) scale(.97)}}
/* ④列表/卡片错峰入场：仅前 12 条做 stagger（40ms 步进，累计 440ms），其余不参与，
   规避老安卓低端机在大列表（全览 1000 条）下逐行动画造成的掉帧。 */
@keyframes cpaRowIn{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
.stagger>tr:nth-child(-n+12),.stagger>.stagger-item:nth-child(-n+12){animation:cpaRowIn var(--dur-2) var(--ease-out) both}
.stagger>tr:nth-child(1),.stagger>.stagger-item:nth-child(1){animation-delay:0ms}
.stagger>tr:nth-child(2),.stagger>.stagger-item:nth-child(2){animation-delay:40ms}
.stagger>tr:nth-child(3),.stagger>.stagger-item:nth-child(3){animation-delay:80ms}
.stagger>tr:nth-child(4),.stagger>.stagger-item:nth-child(4){animation-delay:120ms}
.stagger>tr:nth-child(5),.stagger>.stagger-item:nth-child(5){animation-delay:160ms}
.stagger>tr:nth-child(6),.stagger>.stagger-item:nth-child(6){animation-delay:200ms}
.stagger>tr:nth-child(7),.stagger>.stagger-item:nth-child(7){animation-delay:240ms}
.stagger>tr:nth-child(8),.stagger>.stagger-item:nth-child(8){animation-delay:280ms}
.stagger>tr:nth-child(9),.stagger>.stagger-item:nth-child(9){animation-delay:320ms}
.stagger>tr:nth-child(10),.stagger>.stagger-item:nth-child(10){animation-delay:360ms}
.stagger>tr:nth-child(11),.stagger>.stagger-item:nth-child(11){animation-delay:400ms}
.stagger>tr:nth-child(12),.stagger>.stagger-item:nth-child(12){animation-delay:440ms}
/* ⑤按钮微交互：按下轻微缩放（叠加既有 translateY 轻抬），仅对可点按钮生效 */
.btn:not(:disabled):not(.is-loading):active{transform:translateY(1px) scale(.97)}
/* ⑥分段控件滑块（任务列表「分页/全览」互斥组）：JS 定位 .seg-ind 使其在两项间滑动 */
.task-view-seg{position:relative}
.task-view-seg .seg-ind{position:absolute;top:1px;bottom:1px;left:0;width:0;border-radius:calc(var(--btn-radius) - 1px);
  background:var(--primary-light);opacity:0;z-index:0;pointer-events:none;
  transition:transform var(--dur-2) var(--ease),width var(--dur-2) var(--ease),opacity var(--dur-1) var(--ease)}
.task-view-seg .seg-ind.on{opacity:1}
.task-view-seg button{position:relative;z-index:1}
.task-view-seg button.on{background:transparent!important}
/* ⑦骨架屏：shimmer 微光扫过，替代「转圈」空等；用于表格/卡片首屏加载占位 */
@keyframes cpaShimmer{0%{background-position:-180px 0}100%{background-position:180px 0}}
.sk{display:inline-block;height:12px;border-radius:6px;
  background:linear-gradient(90deg,var(--bg3) 25%,var(--border) 37%,var(--bg3) 63%);
  background-size:360px 100%;animation:cpaShimmer 1.1s linear infinite}
[data-theme="dark"] .sk{background:linear-gradient(90deg,#16233b 25%,#243449 37%,#16233b 63%);background-size:360px 100%}
.sk-table{width:100%;border-collapse:collapse}
.sk-table th,.sk-table td{border-bottom:1px solid var(--border)}
/* ⑧提交类按钮 loading 态：文字隐藏、转圈保留，pointer-events 关闭防重复提交 */
.btn.is-loading{color:transparent!important;pointer-events:none;opacity:.85;position:relative}
.btn.is-loading::after{content:"";position:absolute;top:50%;left:50%;width:14px;height:14px;margin:-7px 0 0 -7px;
  border:2px solid var(--primary);border-top-color:transparent;border-radius:50%;animation:spin .7s linear infinite}
.btn-primary.is-loading::after,.btn-danger.is-loading::after,.btn-success.is-loading::after,.btn-warning.is-loading::after{
  border-color:#fff;border-top-color:transparent}

/* ============================================================================
   CPA-948 返工（老板 2026-10-12）：「现在后台页面，包括弹窗，所有的东西响应的时候都会感觉有一个迟滞…
   你帮我把这个去掉，就是不要让我有感觉有等待感。」
   排查结论（迟滞来自 CPA-937 引入的「装饰性入场动效」，非后端/网络）：
     ① 弹窗：遮罩淡入 200ms + 面板上浮放大 240ms（入场）/ 150ms（退场）——点开弹窗要等遮罩淡完才「看清、点得到」；
     ② 跨文档转场 @view-transition：旧页淡出 + 新页淡入各 180ms——每次换页都多等一截淡入淡出；
     ③ 列表错峰入场：前 12 行 40ms 步进、最长 440ms——行「一行行渐显」= 明确的等待感。
   处置：本块把这些「门控可见性」的出入场动效统一置零（保留 hover 等即时反馈、保留 toast/骨架屏等非阻塞反馈）。
   ★原声明一律保留不删（便于回滚；CPA-937/941 守卫逐字锚点不变），此处仅以 !important 覆盖使其不生效。
   ============================================================================ */
.modal-mask{transition:none!important}
.modal-mask.show .modal,.modal-mask.closing .modal{animation:none!important}
.stagger>tr,.stagger>.stagger-item{animation:none!important;animation-delay:0s!important}
::view-transition-old(root),::view-transition-new(root){animation:none!important}
