/* ==========================================================================
 * 色板：晨雾蓝 + 钢蓝（2026-10-21 冷调改版）
 * --------------------------------------------------------------------------
 * 2026-10-20 做过一版「暖砂 + 陶土橙」，用户反馈橙色大面积使用太晃眼，
 * 故改回冷调。但不是回到「高饱和宝蓝 + 纯白」的通用后台脸：
 * 主色压到中饱和钢蓝 #1E5FA8，背景走低饱和晨雾蓝灰，长时间看不刺眼。
 * 同样注意「隐形层」：投影 RGB、网格线、轴文字、卡片白必须一起偏冷灰蓝，
 * 否则蓝色主色会被暖底衬得发脏、发灰。
 *   背景 #F3F7FB 晨雾蓝灰 / 面板 #FCFDFF 微蓝白 / 文字 #1B2733 墨蓝
 *   投影底 24,42,63 / 侧栏 #16304E 深海军蓝
 * 换肤只需改本块 + --nav-* 两块；下面所有规则一律引用变量，不写 #xxxxxx。
 * ========================================================================== */
:root{
  --bg:#F3F7FB; --panel:#FCFDFF; --line:#DCE5EF; --line-strong:#C4D2E2;
  --text:#1B2733; --text-2:#566B80; --text-3:#8695A8;
  --brand:#1E5FA8; --brand-soft:#EAF2FB;      /* 钢蓝：全站唯一强调色 */
  /* 2026-10-20 补齐的 4 个变量（此前只被引用、从未定义，导致颜色静默失效） */
  --primary:#1E5FA8;     /* 与 --brand 同值，保留为「链接/文字型主色」语义 */
  --primary-soft:#EAF2FB;
  --text-1:#1B2733;
  --danger:#B2352E;      /* 索赔金额 / 删除按钮 必须用同一个红 */
  --pending:#8A6100; --pending-soft:#FFF7E6;  /* 深琥珀：进行中 */
  --ok:#2E7D4F; --ok-soft:#E9F5EE;            /* 青绿：达标（不用荧光绿） */
  --warn:#C0342B; --warn-soft:#FBEAE8;        /* 砖红：超标 */
  --radius:8px;

  /* 表面层级（由浅到深）与状态三色 */
  --inverse:#FFFFFF;          /* 反白文字：深色底（侧栏/主按钮/徽标）上的字 */
  --surface-1:#F8FBFE;        /* 最浅面：附件框底 */
  --surface-2:#EFF5FB;        /* 表头 / 行悬停 / 斑马纹 */
  --surface-3:#E3ECF6;        /* 更深的面：badge、hover 强调 */
  --st-ok-ink:#256B44;   --st-ok-bg:#E8F4ED;   --st-ok-bd:#C2E0CF;
  --st-warn-ink:#7E5800; --st-warn-bg:#FFF7E6; --st-warn-bd:#EFDCA8;
  --st-bad-ink:#9B2C24;  --st-bad-bg:#FBEAE8;  --st-bad-bd:#EFC5BF;
  --amber-ink:#7E5800;   --amber-bg:#FFF7E6;   --amber-bd:#EFDCA8;
  --rose-bg:#FBEAE8;     --rose-bd:#EFC5BF;
  --link-bd:#B9CFE8;          /* 链接型按钮描边 */
  --ink-black:#122031;        /* 视频缩略图底 */

  /* 供 rgba(...) 复用的分量：聚焦光圈 / 投影 / 遮罩 */
  --brand-rgb:30,95,168;
  --shadow-rgb:24,42,63;
  --veil-rgb:15,25,38;        /* 遮罩/灯箱底：冷黑，不是纯黑 */

  /* 侧栏：深海军蓝与浅色两套，默认深海军蓝。
     切浅色：给 <body> 加 data-nav="light"（见文件末尾 body[data-nav] 块）。 */
  --nav-bg:#16304E;
  --nav-ink:#EAF2FB;
  --nav-ink-2:rgba(234,242,251,.66);
  --nav-ink-dim:rgba(234,242,251,.44);
  --nav-line:rgba(234,242,251,.16);
  --nav-hover:rgba(234,242,251,.10);
  --nav-active:rgba(234,242,251,.16);
  --nav-accent:#5B9BD5;       /* 活跃项左侧标线 */
}
*{box-sizing:border-box;margin:0;padding:0}
body{background:var(--bg);color:var(--text);
  font-family:"Microsoft YaHei","PingFang SC","Segoe UI",system-ui,sans-serif;
  font-size:14px;line-height:1.5;-webkit-font-smoothing:antialiased}
.num{font-variant-numeric:tabular-nums;font-feature-settings:"tnum"}
.side,.main{height:100vh}

/* 登录 */
#login{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
  background:var(--bg)}
.login-box{width:360px;background:var(--panel);border:1px solid var(--line);
  border-radius:12px;padding:28px}
.login-box h1{font-size:17px;font-weight:600;margin-bottom:4px}
.login-box p{font-size:12px;color:var(--text-3);margin-bottom:20px}
.field{margin-bottom:14px}
.field label{display:block;font-size:12px;color:var(--text-2);margin-bottom:6px}
input,select{width:100%;height:34px;padding:0 10px;font-size:14px;font-family:inherit;
  color:var(--text);background:var(--panel);border:1px solid var(--line-strong);
  border-radius:6px;outline:none}
input:focus,select:focus{border-color:var(--brand);box-shadow:0 0 0 3px rgba(var(--brand-rgb),.14)}
.btn{height:34px;padding:0 16px;font-size:14px;font-family:inherit;cursor:pointer;
  border-radius:6px;border:1px solid var(--line-strong);background:var(--panel);color:var(--text)}
.btn:hover{background:var(--surface-3)}
.btn-primary{background:var(--brand);border-color:var(--brand);color:var(--inverse)}
.btn-primary:hover{background:#16497F}
.btn-primary:disabled{opacity:.6;cursor:default}
.chk{display:flex;align-items:center;gap:6px;font-size:12px;color:var(--text-2);margin-bottom:16px}
.chk input{width:14px;height:14px}
.err{color:var(--warn);font-size:12px;margin-top:10px;min-height:18px}

/* 布局 */
#app{display:flex;height:100vh}
.side{width:216px;flex:0 0 216px;background:var(--nav-bg);border-right:1px solid var(--nav-bg);
  display:flex;flex-direction:column;color:var(--nav-ink)}
.brand{padding:18px 20px;border-bottom:1px solid var(--nav-line)}
.brand b{font-size:15px;font-weight:600;display:block;color:var(--inverse)}
.brand span{font-size:11px;color:var(--nav-ink-2)}
.nav{padding:12px 10px;flex:1}
.nav-item{padding:9px 12px;border-radius:6px;color:var(--nav-ink);font-size:14px;
  display:flex;align-items:center;justify-content:space-between;margin-bottom:2px}
.nav-item:hover{background:var(--nav-hover);color:var(--nav-ink)}
.nav-item.active{background:var(--nav-active);color:var(--nav-ink);font-weight:600;
  box-shadow:inset 3px 0 0 var(--nav-accent)}
.nav-item.off{color:var(--nav-ink-dim);cursor:default}
.nav-tag{font-size:10px;color:var(--nav-ink-2);background:rgba(234,242,251,.14);padding:1px 6px;border-radius:4px}
.nav-item.active .nav-tag{background:rgba(234,242,251,.22);color:var(--nav-ink)}
.side-foot{padding:12px 20px;border-top:1px solid var(--nav-line);font-size:11px;color:var(--nav-ink-2)}

.main{flex:1;display:flex;flex-direction:column;overflow:hidden}
.topbar{height:56px;background:var(--panel);border-bottom:1px solid var(--line);
  display:flex;align-items:center;padding:0 24px;gap:16px}
.topbar h2{font-size:16px;font-weight:600}
.topbar .sub{font-size:12px;color:var(--text-3)}
.spacer{flex:1}
.user{font-size:12px;color:var(--text-2)}

.content{flex:1;overflow:auto;padding:20px 24px 32px}

/* Tab 切换（信息管理） */
.tabs{display:flex;gap:4px;margin-bottom:16px;background:var(--panel);border:1px solid var(--line);
  border-radius:var(--radius);padding:4px;width:fit-content}
.tab{height:32px;padding:0 18px;font-size:14px;font-family:inherit;cursor:pointer;
  border:none;background:none;border-radius:6px;color:var(--text-2);transition:all .15s}
.tab:hover{background:var(--surface-3);color:var(--text)}
.tab.active{background:var(--brand-soft);color:var(--brand);font-weight:600}
.btn-danger{color:var(--warn);border-color:#EFC5BF;background:var(--panel)}
.btn-danger:hover{background:var(--warn-soft);border-color:var(--warn)}
.att-count{display:inline-flex;align-items:center;gap:4px;font-size:12px;
  padding:2px 8px;border-radius:12px;background:var(--brand-soft);color:var(--brand)}

/* 首页 */
.home-topbar h2{font-size:18px;font-weight:600}
.home-content{padding:20px 24px 32px}
.year-select{display:flex;align-items:center;gap:8px;border:1px solid var(--line);border-radius:6px;padding:4px 10px;background:var(--panel)}
.year-select button{background:none;border:none;cursor:pointer;font-size:14px;color:var(--text-2)}
.year-select button:hover{color:var(--brand)}
.year-select span{font-weight:600;min-width:58px;text-align:center}
.home-alerts{display:grid;grid-template-columns:repeat(2,1fr);gap:14px;margin-bottom:16px}
.home-alert{padding:12px 16px;border-radius:8px;display:flex;align-items:center;gap:10px;cursor:pointer;font-size:13px;transition:all .15s}
.home-alert:hover{transform:translateY(-1px)}
.home-alert.internal{background:var(--rose-bg);border:1px solid var(--rose-bd);color:var(--danger)}
.home-alert.complaint{background:var(--amber-bg);border:1px solid var(--amber-bd);color:var(--amber-ink)}
.home-alert.complaint.zero{background:var(--st-ok-bg);border:1px solid var(--st-ok-bd);color:#256B44}
.home-alert b{font-size:18px}
.home-alert .arr{margin-left:auto;font-size:18px}
.home-kpis{display:grid;grid-template-columns:repeat(3,1fr);gap:14px;margin-bottom:16px}
.home-kpi{background:var(--panel);border:1px solid var(--line);border-radius:8px;
  padding:11px 15px;min-height:72px;display:flex;flex-direction:column;justify-content:center}
.home-kpi .kpi-label{font-size:13px;color:var(--text-2);margin-bottom:5px;line-height:1.3}
.home-kpi .kpi-value{font-size:24px;font-weight:600;color:var(--text);line-height:1.1;
  display:flex;align-items:baseline;gap:10px;flex-wrap:wrap}
.home-kpi .kpi-value.blue{color:var(--brand)}
.home-kpi .kpi-value.orange{color:#1E5FA8}
.home-kpi .kpi-value.warn{color:var(--warn)}
.home-kpi.big .kpi-value{font-size:28px}
.home-kpi .kpi-sub{font-size:12px;color:var(--text-3);font-weight:400}
.home-kpi .kpi-sub b{color:var(--text);font-weight:600}
.home-split{display:grid;grid-template-columns:repeat(2,1fr);gap:16px}
.home-main-chart{margin-bottom:16px}
/* 标题 + 说明小字 + 筛选框排在同一行、整体左对齐
   （.panel-head h3 默认 flex:0 0 100% 会独占整行，这里针对主图面板覆盖） */
.home-main-chart .panel-head h3{flex:0 0 auto}
.home-main-chart .panel-head .hint{margin-left:0;flex:0 0 auto}
/* 首页月度趋势筛选：项目 / 产品（只联动主图，不联动壳体/结构件） */
.chart-filter{display:flex;align-items:center;gap:8px;flex:0 0 auto}
.chart-filter label{font-size:12px;color:var(--text-2);white-space:nowrap}
.chart-filter select{height:30px;width:150px;font-size:13px;padding:0 8px}
.chart-filter select:disabled{background:var(--bg);color:var(--text-3);cursor:not-allowed}
.chart-filter .btn{height:30px;padding:0 14px;font-size:13px}
.cf-status{font-size:12px;color:var(--text-3);white-space:nowrap}
.cf-status.loading{color:var(--brand)}
.cf-status.err{color:var(--warn)}

/* 图表组件未就绪/加载失败时的可见提示（替代以前的静默空白） */
.chart-fallback{display:flex;align-items:center;justify-content:center;
  height:100%;min-height:160px;color:var(--text-3);font-size:13px;
  background:repeating-linear-gradient(45deg,var(--surface-2),var(--surface-2) 12px,var(--surface-3) 12px,var(--surface-3) 24px);
  border-radius:var(--radius);text-align:center;padding:12px}

/* 筛选条 */
.filters{background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);
  padding:14px 16px;display:flex;align-items:flex-end;gap:14px;flex-wrap:wrap;margin-bottom:16px}
.fg{display:flex;flex-direction:column;gap:5px}
.fg label{font-size:12px;color:var(--text-2)}
.fg input,.fg select{height:32px;width:150px}
.fg select{width:170px}

/* 产品名称多选（自定义下拉 + checkbox 面板） */
.ms{position:relative}
.ms-btn{height:32px;width:190px;text-align:left;padding:0 26px 0 10px;background:var(--panel);
  border:1px solid var(--line);border-radius:6px;font-family:inherit;font-size:13px;color:var(--text);
  cursor:pointer;position:relative;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ms-btn::after{content:'';position:absolute;right:10px;top:13px;border:4px solid transparent;
  border-top-color:var(--text-3)}
.ms-btn:hover{border-color:var(--brand)}
.ms-btn.on{border-color:var(--brand);color:var(--brand);font-weight:500;
  background:var(--brand-soft)}
.ms-panel{position:absolute;top:36px;left:0;z-index:30;width:260px;background:var(--panel);
  border:1px solid var(--line);border-radius:8px;box-shadow:0 8px 24px rgba(var(--shadow-rgb),.14)}
.ms-head{display:flex;align-items:center;padding:8px 10px;border-bottom:1px solid var(--line);
  font-size:12px;color:var(--text-3)}
.ms-ops{margin-left:auto;display:flex;gap:10px}
.ms-ops a{color:var(--brand);text-decoration:none;font-size:12px}
.ms-ops a:hover{text-decoration:underline}
.ms-list{max-height:240px;overflow:auto;padding:4px}
.ms-item{display:flex;align-items:center;gap:8px;padding:6px 8px;border-radius:6px;
  font-size:13px;cursor:pointer}
.ms-item:hover{background:var(--brand-soft)}
.ms-item.on{color:var(--brand)}
.ms-item input{margin:0;width:14px;height:14px}
.ms-item em{margin-left:auto;font-style:normal;font-size:11px;color:var(--text-3)}
.ms-empty{padding:10px;font-size:12px;color:var(--text-3);text-align:center}

/* 指标卡（KPI · 紧凑横排 chip，点击联动台账） */
.cards{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:16px}
.kpi{display:inline-flex;align-items:center;gap:8px;padding:7px 14px;
  background:var(--panel);border:1px solid var(--line);border-radius:18px;cursor:pointer;
  font-family:inherit;font-size:12px;line-height:1.2;transition:all .15s;color:var(--text)}
.kpi:hover{border-color:var(--brand);background:var(--brand-soft);color:var(--brand)}
.kpi .v{font-size:16px;font-weight:600;font-variant-numeric:tabular-nums;min-width:18px;text-align:center}
.kpi .k{color:var(--text-2);font-weight:500}
.kpi .r{color:var(--text-3);font-size:11px;border-left:1px solid var(--line);padding-left:8px;margin-left:2px}
.kpi:hover .r{color:var(--text-2)}
.kpi:hover .k{color:var(--brand)}
.kpi.active{background:var(--brand);border-color:var(--brand);color:var(--inverse)}
.kpi.active .k,.kpi.active .r,.kpi.active:hover .k,.kpi.active:hover .r{color:rgba(255,255,255,.92)}
.kpi.active .r{border-left-color:rgba(255,255,255,.4)}
.kpi.warn .v{color:var(--warn)}
.kpi.warn{border-color:#EFC5BF}
.kpi.warn:hover{background:#FBEAE8;border-color:var(--warn)}
.kpi.warn.active{background:var(--warn);border-color:var(--warn)}
.kpi.warn.active .v,.kpi.warn.active .k,.kpi.warn.active .r{color:var(--inverse)}
.kpi.warn.active .r{border-left-color:rgba(255,255,255,.4)}

/* 表格 */
.panel{background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);
  margin-bottom:16px;overflow:hidden}
.panel-head{display:flex;align-items:center;flex-wrap:wrap;gap:8px 12px;padding:12px 16px;border-bottom:1px solid var(--line)}
.panel-head h3{font-size:14px;font-weight:600;flex:0 0 100%}
.panel-head .hint{font-size:11px;color:var(--text-3);flex:1 1 auto}
table{width:100%;border-collapse:collapse;font-size:14px}
th{position:sticky;top:0;background:var(--surface-2);text-align:right;font-weight:600;
  color:var(--text-2);padding:10px 14px;border-bottom:1px solid var(--line);
  white-space:nowrap;cursor:pointer;user-select:none}
th:first-child,th:nth-child(2){text-align:left}
th:hover{background:var(--surface-3)}
th .sort{color:var(--brand);font-size:10px;margin-left:3px}
td{padding:9px 14px;border-bottom:1px solid #E3ECF6;text-align:right;white-space:nowrap}
td:first-child,td:nth-child(2){text-align:left}
tbody tr:hover{background:var(--surface-2)}
tfoot td{background:var(--surface-2);font-weight:600;border-top:1px solid var(--line);
  border-bottom:none;padding:10px 14px}
.mono{font-variant-numeric:tabular-nums}
.muted{color:var(--text-3)}
.badge{display:inline-block;font-size:10px;color:var(--text-2);background:var(--surface-3);
  border:1px solid var(--line);border-radius:4px;padding:0 5px;margin-left:6px}
.rate-high{color:var(--warn);font-weight:600}
.empty{padding:36px;text-align:center;color:var(--text-3);font-size:14px}
.loading{padding:36px;text-align:center;color:var(--text-3);font-size:14px}
.note{font-size:11px;color:var(--text-3);line-height:1.7;padding:4px 2px}
.badge-ok{display:inline-block;font-size:10px;color:var(--ok);background:var(--ok-soft);
  border-radius:4px;padding:0 6px;margin-left:6px}

/* 年度报废趋势图 */
.chart-panel #trendChart{width:100%;min-height:320px;padding:6px 8px 10px}
/* 图表容器 + 加载遮罩：遮罩是图表的**兄弟节点**，绝不能写进容器内部
   （写进去会把 ECharts 根节点挤下去，横轴标签溢出容器、被下方面板遮住） */
.chart-box{position:relative}
.chart-mask{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
  background:rgba(255,255,255,.68);color:var(--text-3);font-size:14px;z-index:6;pointer-events:none}
.chart-mask[hidden]{display:none}

/* 导航链接 */
a.nav-item{text-decoration:none;cursor:pointer}
a.nav-item:hover{background:var(--nav-hover);color:var(--nav-ink)}
a.nav-item.active:hover{background:var(--nav-active)}
a.nav-item.off:hover{background:transparent}

/* 录入表 */
table.entry th,table.hist th{text-align:left;background:var(--surface-2);cursor:default}
table.entry th:hover,table.hist th:hover{background:var(--surface-2)}
table.entry td,table.hist td{text-align:left}
table.entry select,table.entry input{height:30px;font-size:13px;width:100%}
table.entry td{padding:6px 10px}
table.hist td{padding:8px 14px}
.entry-tip{font-size:12px;color:var(--text-3)}

.row-actions{display:flex;align-items:center;gap:12px;margin-top:14px}
.msg{font-size:12px;color:var(--text-2)}
.msg.ok{color:var(--ok);font-weight:600}
.msg.err{color:var(--warn);font-weight:600}

.link-del,.link-edit{background:none;border:none;color:var(--brand);cursor:pointer;
  font-size:13px;font-family:inherit;padding:0 6px}
.link-del{color:var(--warn)}
.link-del:hover,.link-edit:hover{text-decoration:underline}

/* 弹窗 */
.mask{position:fixed;inset:0;background:rgba(var(--veil-rgb),.42);display:none;
  align-items:center;justify-content:center;z-index:50}
.modal{width:540px;max-height:80vh;overflow:auto;background:var(--panel);border-radius:12px;
  padding:22px 24px}
.modal-title{font-size:15px;font-weight:600;margin-bottom:14px}
.modal-body{font-size:13px;line-height:1.7;color:var(--text-2)}
.modal-body p{margin-bottom:10px}
.cf-item{background:var(--surface-2);border:1px solid var(--line);border-radius:8px;
  padding:10px 12px;margin-bottom:10px}
.cf-name{font-weight:600;color:var(--text);margin-bottom:6px}
.cf-diff{font-size:12px;color:var(--text-2)}
.cf-diff .old{color:var(--text-3);text-decoration:line-through;margin-right:4px}
.cf-diff .new{color:var(--warn);font-weight:600}
.modal-foot{display:flex;justify-content:flex-end;gap:10px;margin-top:18px}
.modal-lg{width:min(1560px,96vw)}

/* ===== 客诉管理 ===== */
/* 客诉台账：固定高度滚动容器，让横向滚动条始终在可视区域 */
.cpl-wrap{overflow:auto;border-bottom:1px solid var(--line);position:relative;
  max-height:calc(100vh - 280px)}
.cpl-wrap table.cpl{min-width:max-content}
.cpl-wrap table.cpl th{position:sticky;top:0;z-index:1}

table.cpl th,table.cpl td{text-align:left;white-space:nowrap}
table.cpl th{cursor:default}
table.cpl th:hover{background:var(--surface-2)}
/* 问题描述：列宽 -1/3（200 → 134）。auto 布局下宽度会被内容撑开，
   光改 th 的 min-width 没用，必须给单元格加 max-width 才真的收窄 */
table.cpl td.desc{white-space:normal;min-width:110px;max-width:134px;line-height:1.45;color:var(--text)}
/* 产品名称：列宽 -1/4（120 → 90），长产品名换行不撑宽 */
table.cpl td.cm-prod{max-width:90px;white-space:normal}
table.cpl tr.cpl-row{cursor:pointer}
table.cpl td .att-count{background:var(--brand-soft);color:var(--brand);font-size:12px;padding:2px 8px;border-radius:12px}
table.cpl td .claim-amt{color:var(--danger);font-weight:600}

/* ===== 客诉附件 ===== */
.blk-t .att-add,.blk-t .att-link{margin-left:auto}
.blk-t .att-link{margin-left:6px}
.att-link{border-color:var(--brand-soft);color:var(--brand)}
.att-link:hover{background:var(--brand-soft);border-color:var(--brand)}
.blk-t{display:flex;align-items:center;gap:8px}
.att-grid{display:flex;flex-wrap:wrap;gap:10px;margin-top:8px;min-height:28px}
.att-grid .muted{color:var(--text-3);font-size:12px}
.att-item{position:relative;width:92px;height:92px;border:1px solid var(--line);
  border-radius:8px;overflow:hidden;background:var(--surface-2)}
.att-item img{width:100%;height:100%;object-fit:cover;display:block;cursor:zoom-in}
.att-item a{display:flex;align-items:center;justify-content:center;width:100%;height:100%}
.att-file{font-size:11px;padding:4px;text-align:center;word-break:break-all;color:var(--primary)}
.att-del{position:absolute;top:2px;right:2px;width:20px;height:20px;border:none;border-radius:50%;
  background:rgba(var(--veil-rgb),.62);color:var(--inverse);font-size:14px;line-height:18px;cursor:pointer;padding:0;z-index:2}
.att-del:hover{background:var(--danger)}
/* 附件「记录还在、磁盘文件已丢失」：给个明确提示，别让人以为是没加载出来 */
.att-item.att-broken,.is-thumb.att-broken{border-color:#B2352E}
.att-item.att-broken img,.is-thumb.att-broken img{opacity:.35}
.att-item.att-broken:after,.is-thumb.att-broken:after{
  content:'文件丢失';position:absolute;left:0;right:0;bottom:0;z-index:1;
  background:rgba(178,58,34,.86);color:var(--inverse);font-size:10px;line-height:14px;text-align:center}
table.cpl td.ops{white-space:nowrap}

/* 视频附件：自动播放条停在中间，长宽比铺满格子 */
.att-item.att-video{background:var(--ink-black)}
.att-item.att-video video{width:100%;height:100%;object-fit:cover;display:block}
/* 文档类附件：图标 + 类型 + 文件名（垂直三行） */
.att-item.att-doc{width:120px;height:92px;background:var(--surface-1);border:1px solid var(--line)}
.att-doc-link{display:flex;flex-direction:column;align-items:center;justify-content:center;
  padding:6px;width:100%;height:100%;text-decoration:none;color:var(--text);gap:2px}
.att-doc-link:hover{background:var(--brand-soft)}
.att-doc-icon{font-size:24px;line-height:1}
.att-doc-type{font-size:10px;color:var(--text-2);font-weight:600;letter-spacing:.5px;
  background:#E3ECF6;border-radius:3px;padding:0 5px;line-height:14px}
.att-doc.att-doc a:hover .att-doc-type{background:var(--brand-soft);color:var(--brand)}
.att-doc-name{font-size:10px;color:var(--text-3);width:100%;text-align:center;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;line-height:1.2}
.att-tip{margin-top:6px;font-size:11px;line-height:1.55}

/* ===== 图片灯箱 ===== */
.lightbox{position:fixed;inset:0;background:rgba(var(--veil-rgb),.92);display:none;
  align-items:center;justify-content:center;z-index:200;cursor:zoom-out;
  -webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}
.lightbox.show{display:flex}
.lightbox-inner{display:flex;flex-direction:column;align-items:center;gap:10px;max-width:92vw;max-height:92vh}
.lightbox img{max-width:92vw;max-height:86vh;object-fit:contain;
  border-radius:6px;box-shadow:0 12px 48px rgba(var(--veil-rgb),.55);cursor:zoom-in;background:var(--panel)}
.lightbox.zoomed img{max-width:none;max-height:none;width:auto;height:auto;cursor:zoom-out}
.lightbox-name{color:var(--inverse);font-size:12px;background:rgba(var(--veil-rgb),.55);padding:4px 12px;border-radius:14px}
.lightbox-close{position:absolute;top:18px;right:18px;width:36px;height:36px;border:none;
  border-radius:50%;background:rgba(234,242,251,.18);color:var(--inverse);font-size:22px;line-height:32px;
  cursor:pointer;padding:0;font-family:inherit;z-index:2;transition:background .15s}
.lightbox-close:hover{background:rgba(234,242,251,.32)}

.sev{display:inline-block;min-width:20px;text-align:center;font-size:11px;font-weight:600;
  border-radius:4px;padding:1px 6px}
.sev-a{color:var(--inverse);background:var(--danger)}
.sev-b{color:#7E5800;background:#FFF6E3}
.sev-c{color:#5A6B80;background:#EEF3F9}
.pg{display:inline-block;font-size:11px;border-radius:4px;padding:1px 6px;font-weight:600}
.pg-done{color:var(--ok);background:var(--ok-soft)}
.pg-doing{color:var(--amber-ink);background:#FFF7E6}
.pg-none{color:var(--text-3);background:var(--surface-3)}
.pg-pending{color:#7E5800;background:#FFF6E3;border:1px solid var(--amber-bd)}

/* 内部报废台账：宽表格与缩略图 */
table.cpl-wide{min-width:1400px}
table.cpl td.cell-multi{white-space:normal;min-width:100px;max-width:260px;line-height:1.55;
  font-size:13px}
/* 产生原因 / 长期措施：列宽 +1/4，同时放开单元格上限（否则只改 th 不生效） */
table.cpl td.cm-cause,table.cpl td.cm-long{max-width:340px}
.is-thumb{position:relative;width:64px;height:64px;border:1px solid var(--line);border-radius:4px;
  overflow:hidden;cursor:zoom-in;background:var(--surface-3)}
.is-thumb img{width:100%;height:100%;object-fit:cover;display:block}
.is-thumb .img-more{position:absolute;right:2px;bottom:2px;background:rgba(var(--veil-rgb),.68);
  color:var(--inverse);font-size:11px;padding:1px 5px;border-radius:4px}
.img-empty{color:var(--text-3);font-size:12px}

/* 弹窗内动态列表（产生原因 / 临时措施 / 长期措施） */
.dyn-list{margin-bottom:8px}
.dyn-head{display:grid;grid-template-columns:36px 1fr 120px 130px 110px 36px;gap:8px;
  font-size:12px;color:var(--text-2);padding:4px 0 4px 8px;border-bottom:1px solid var(--line)}
.dyn-row{display:flex;align-items:center;gap:8px;margin-top:8px}
/* 产生原因描述框：撑满剩余宽度（dyn-row 是 flex，textarea 默认不伸展） */
.dyn-row textarea.dyn-input{flex:1 1 auto;width:100%;min-width:0}
.dyn-row-3{display:grid;grid-template-columns:36px 1fr 120px 130px 110px 36px;gap:8px}
.dyn-idx{width:28px;text-align:center;color:var(--text-3);font-size:12px;user-select:none}
.dyn-input{border:1px solid var(--line-strong);border-radius:6px;padding:6px 8px;font-size:13px;
  outline:none;font-family:inherit}
.dyn-input:focus{border-color:var(--brand);box-shadow:0 0 0 2px var(--brand-soft)}
/* 信息管理 — 字典管理 */
#dictWrap{display:flex;flex-direction:column;gap:16px;max-width:960px}
.dict-card{border:1px solid var(--line);border-radius:10px;padding:14px 16px;background:var(--panel);box-shadow:0 1px 3px rgba(var(--shadow-rgb),.06)}
.dict-head{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:10px}
.dict-title{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.dict-title b{font-size:15px;color:var(--text)}
.dict-title .muted{font-size:12px}
.dict-module{font-size:11px;font-weight:600;color:#7E5800;background:#FFF6E3;border:1px solid #EFDCA8;
  padding:3px 10px;border-radius:12px;white-space:nowrap}
.dict-body{display:flex;flex-wrap:wrap;gap:8px;min-height:34px;align-items:center;padding:4px 0}
.dict-chip{display:inline-flex;align-items:center;gap:6px;padding:5px 10px;border-radius:6px;
  background:var(--st-ok-bg);border:1px solid var(--st-ok-bd);color:var(--st-ok-ink);font-size:13px}
.dict-del{color:var(--danger);font-weight:700;text-decoration:none;font-size:16px;line-height:1}
.dict-del:hover{color:#B26A00}
.dict-add{display:flex;gap:10px;margin-top:12px}
.dict-input{flex:1;min-width:240px;max-width:560px;padding:8px 12px;border:1px solid var(--line-strong);
  border-radius:6px;font-size:13px}
.dict-input:focus{outline:none;border-color:var(--brand);box-shadow:0 0 0 2px var(--brand-soft)}

/* 责任项目选择弹窗 */
.up-row{display:block;padding:12px 14px;border-bottom:1px solid var(--line);cursor:pointer;
  transition:background .12s}
.up-row:hover{background:#EFF5FB}
.up-row.up-checked{background:#E8F1FC}
.up-head{display:flex;align-items:center;gap:10px}
.up-head input[type=checkbox]{width:18px;height:18px;flex:0 0 18px;cursor:pointer}
.up-head b{font-size:14px;color:var(--text-1)}
.up-products{margin-left:28px;margin-top:5px;font-size:12px;line-height:1.6;color:var(--text-3)}

.dyn-input.dyn-sm{width:auto}
.dyn-del{width:28px;height:28px;padding:0;border:none;background:transparent;color:var(--text-3);
  cursor:pointer;font-size:14px;border-radius:4px}
.dyn-del:hover{background:#FBEAE8;color:var(--danger)}

/* 完成进度单选 */
.progress-options{display:flex;flex-wrap:wrap;gap:8px}
.progress-option{display:inline-flex;align-items:center;justify-content:center;min-width:44px;
  padding:5px 10px;border:1px solid var(--line-strong);border-radius:6px;cursor:pointer;
  font-size:13px;color:var(--text-2);background:var(--panel);user-select:none}
.progress-option input{position:absolute;opacity:0;pointer-events:none}
.progress-option:hover{border-color:var(--brand);color:var(--brand)}
.progress-option.checked{border-color:var(--brand);background:var(--brand-soft);color:var(--brand);
  font-weight:600}

/* 完成状态徽标 G/Y/R（弹窗详情用） */
.st-badge{display:inline-block;font-size:11px;font-weight:600;padding:2px 8px;border-radius:4px;
  white-space:nowrap;line-height:1.4}
.st-green{color:var(--st-ok-ink);background:var(--st-ok-bg);border:1px solid var(--st-ok-bd)}
.st-yellow{color:var(--st-warn-ink);background:var(--st-warn-bg);border:1px solid var(--st-warn-bd)}
.st-red{color:var(--st-bad-ink);background:var(--st-bad-bg);border:1px solid var(--st-bad-bd)}
.st-empty{color:var(--text-3);background:var(--surface-3);border:1px solid var(--line)}

/* 台账 责任人/完成时间 列：按措施状态整行着色（不显示文字徽标） */
.stline{display:block;padding:1px 5px;border-radius:3px;margin:1px 0;line-height:1.5;white-space:nowrap}
.stline.st-green{color:var(--st-ok-ink);background:var(--st-ok-bg)}
.stline.st-yellow{color:var(--st-warn-ink);background:var(--st-warn-bg)}
.stline.st-red{color:var(--st-bad-ink);background:var(--st-bad-bg)}

.link-ok{color:var(--primary);background:var(--primary-soft);border:1px solid var(--link-bd);
  border-radius:4px;padding:2px 7px;font-size:12px;cursor:pointer}
.link-ok:hover{background:#CFE3F8}
.close-tip{margin-top:8px;font-size:12px;color:var(--text-3);background:var(--surface-2);
  border:1px dashed var(--line);border-radius:6px;padding:8px 10px;line-height:1.6}
.rep{color:var(--warn);font-weight:600}
.v-ok{color:var(--ok);font-size:11px;background:var(--ok-soft);border-radius:4px;padding:1px 6px}
.v-no{color:var(--text-3);font-size:11px}

/* 弹窗内表单输入撑满 */
.modal .fg input,.modal .fg select{width:100%}
.modal .fg input[readonly]{background:#E9F0F8;color:var(--text-3);cursor:not-allowed}
.badge-green{color:var(--st-ok-ink);background:var(--st-ok-bg);border:1px solid var(--st-ok-bd)}
.badge-gray{color:var(--text-2);background:var(--surface-3);border:1px solid var(--line)}

/* 弹窗表单 */
.form .sec-t{font-size:12px;font-weight:600;color:var(--brand);background:var(--brand-soft);
  border-radius:4px;padding:5px 9px;margin:16px 0 10px}
.form .sec-t:first-child{margin-top:0}
.form .grid4{display:grid;grid-template-columns:repeat(4,1fr);gap:10px 12px}
.form .fi{margin-bottom:12px}
.form .fi label{display:block;font-size:12px;color:var(--text-2);margin-bottom:5px}
.form .fi label i{color:var(--warn);font-style:normal}
.form .fi input,.form .fi select,.form .fi textarea{width:100%;font-size:13px}
.form .fi textarea{height:auto;padding:7px 9px;line-height:1.55;resize:vertical;
  font-family:inherit;border:1px solid var(--line-strong);border-radius:6px;outline:none}
.form .fi textarea:focus{border-color:var(--brand);box-shadow:0 0 0 3px rgba(var(--brand-rgb),.14)}
.form .grid4 .fi{margin-bottom:0}

.act-group{border:1px solid var(--line);border-radius:8px;padding:10px 12px;margin-bottom:10px;
  background:var(--surface-1)}
.act-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:8px}
.act-head span{font-size:12px;font-weight:600;color:var(--text-2)}
.btn-mini{height:24px;padding:0 9px;font-size:12px}
.act-row{display:grid;grid-template-columns:1fr 110px 142px 110px 28px;gap:8px;margin-bottom:8px}
.act-row textarea,.act-row input{height:32px;font-size:12px;padding:4px 8px;
  border:1px solid var(--line-strong);border-radius:6px;font-family:inherit;outline:none}
.act-row textarea{height:52px;resize:vertical}
.act-row textarea:focus,.act-row input:focus{border-color:var(--brand)}
.btn-del{padding:0;color:var(--warn);width:28px}
.act-empty{font-size:12px;color:var(--text-3);padding:2px 0 6px}

.blk{margin-bottom:14px}
.blk-row{display:flex;gap:12px;margin-bottom:14px}
.blk-row .blk{flex:1 1 0;min-width:0;margin-bottom:0}
.blk-row .blk-content{overflow-wrap:break-word}
.blk-t{font-size:12px;font-weight:600;color:var(--text-2);margin-bottom:6px}
.blk-c{font-size:13px;line-height:1.7;color:var(--text);background:var(--surface-2);
  border:1px solid var(--line);border-radius:6px;padding:9px 11px;white-space:normal}
table.mini{width:100%;border-collapse:collapse;font-size:13.5px}
table.mini td{border:1px solid var(--line);padding:6px 9px;vertical-align:top;
  white-space:normal;background:var(--surface-2)}
table.mini td.o{width:80px;color:var(--text-2)}
table.mini td.d{width:128px;color:var(--text-2)}

.kv{display:grid;grid-template-columns:repeat(4,1fr);gap:8px 12px;margin-bottom:16px}
.kv.kv-5{grid-template-columns:repeat(5,1fr)}
.kv-i{background:var(--surface-2);border:1px solid var(--line);border-radius:6px;padding:7px 10px}
.kv-i span{display:block;font-size:11px;color:var(--text-3);margin-bottom:2px}
.kv-i b{font-size:13px;font-weight:600}
.blk-foot{font-size:11px;color:var(--text-3);border-top:1px dashed var(--line);padding-top:10px}


/* ============ 2026-09-14 报废原因明细 ============ */
#ddKpis{grid-template-columns:repeat(5,1fr)}
@media (max-width:1500px){#ddKpis{grid-template-columns:repeat(3,1fr)}}
.dd-legend{display:flex;flex-wrap:wrap;gap:16px;margin-bottom:8px;font-size:12px;color:var(--text-2)}
.dd-legend span{display:inline-flex;align-items:center;gap:5px}
.dd-legend i{width:10px;height:10px;border-radius:2px;display:inline-block}
.dd-legend i.line{width:14px;height:2px;border-radius:0}
.dd-tabs{display:inline-flex;border:1px solid var(--line);border-radius:6px;overflow:hidden}
.dd-tab{height:28px;padding:0 12px;font-size:13px;background:var(--panel);border:none;color:var(--text-2);cursor:pointer}
.dd-tab.active{background:var(--brand);color:var(--inverse)}
.dd-tab + .dd-tab{border-left:1px solid var(--line)}
.chart-fallback{padding:24px;text-align:center;color:var(--warn);font-size:13px}
.cf-status.err{color:var(--warn)}
/* 录入页：报废明细弹窗 */
.dt-head{display:flex;gap:14px;flex-wrap:wrap;padding:10px 12px;background:var(--surface-3);border:1px solid var(--line);border-radius:8px;margin-bottom:14px}
.dt-head-item{display:flex;flex-direction:column;gap:4px;min-width:150px}
.dt-head-item label{font-size:12px;color:var(--text-2)}
.dt-head-item input{height:36px;width:132px;padding:0 10px;border:1px solid var(--line-strong);
  border-radius:8px;font-size:15px;font-weight:500;text-align:center;font-variant-numeric:tabular-nums}
.dt-head-die .mono{font-size:18px}
.dt-head-die .muted{font-size:11px}
.dt-cols{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:18px}
.dt-col-title{font-size:13px;font-weight:600;padding-bottom:6px;border-bottom:1px solid var(--line);margin-bottom:8px}
/* 列表：整行底色带 + 隔行浅色，已填写行浅蓝，便于一屏扫读 */
.dt-list{max-height:min(54vh,470px);overflow-y:auto;border:1px solid var(--line);
  border-radius:8px;background:var(--panel);padding:4px 6px}
.dt-row{display:flex;align-items:center;gap:12px;padding:4px 8px;border-radius:6px}
.dt-row:nth-child(odd){background:#EFF5FB}
.dt-row:nth-child(even){background:var(--panel)}
.dt-row.filled{background:var(--brand-soft)}
.dt-row:hover{background:#E8F1FC}
/* 原因名宽度由 JS 按该栏最长原因测出（--dt-w）：输入框左对齐、又紧贴原因名不留大空隙 */
.dt-name{flex:0 0 var(--dt-w,104px);font-size:13px;color:var(--text);white-space:nowrap;overflow:hidden}
.dt-row.filled .dt-name{color:var(--brand);font-weight:600}
.dt-row input{width:84px;height:36px;padding:0 10px;border:1px solid var(--line-strong);
  border-radius:8px;font-size:15px;font-weight:500;text-align:center;color:var(--text);
  background:var(--panel);font-variant-numeric:tabular-nums}
.dt-row input::placeholder{color:var(--text-3);font-weight:400}
.dt-row input:focus{outline:none;border-color:var(--brand);box-shadow:0 0 0 3px rgba(var(--brand-rgb),.14)}
.dt-row input::-webkit-outer-spin-button,
.dt-row input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}
.modal-dt{width:min(1000px,94vw)}
.dt-check{margin-top:8px}
.dt-sum{font-size:12px;color:var(--text-2)}
.dt-status{margin-top:6px;padding:6px 10px;border-radius:6px;font-size:12px;display:flex;align-items:center;gap:10px}
.dt-status.dt-ok{background:var(--ok-soft);color:var(--ok)}
.dt-status.dt-bad{background:#FBEAE8;color:var(--warn)}
.dt-status.dt-idle{background:var(--surface-3);color:var(--text-2)}
.dt-tip{margin-top:12px;font-size:12px;color:var(--text-3)}


/* ==========================================================
   2026-10-20 新增（一）· 键盘焦点
   —— 放在文件末尾：前面多处写了 outline:none（.dyn-input / .form textarea 等），
      同优先级下后者胜，只有放最后才能真正生效。
   ========================================================== */
:focus-visible{outline:2px solid var(--brand);outline-offset:2px;border-radius:4px}
:focus:not(:focus-visible){outline:none}          /* 鼠标点击不出焦点圈 */


/* ==========================================================
   2026-10-20 新增（二）· 宽表横向滚动时冻结左侧标识列
   用法：<table class="cpl freeze" style="--freeze-1:52px">
        --freeze-1 = 第 1 列宽度，第 2 列紧贴其右侧
   注意：sticky 单元格不继承 tr 的 hover 背景，所以用 --row-bg 变量同步。
   ========================================================== */
table.cpl.freeze th:nth-child(1),table.cpl.freeze td:nth-child(1),
table.cpl.freeze th:nth-child(2),table.cpl.freeze td:nth-child(2){
  position:sticky;background:var(--row-bg,var(--panel));z-index:2}
table.cpl.freeze th:nth-child(1),table.cpl.freeze td:nth-child(1){left:0}
table.cpl.freeze th:nth-child(2),table.cpl.freeze td:nth-child(2){
  left:var(--freeze-1,52px);box-shadow:2px 0 4px rgba(var(--shadow-rgb),.10)}
/* 表头两格同时吸顶，层级要盖过普通表头 */
table.cpl.freeze th:nth-child(1),table.cpl.freeze th:nth-child(2){z-index:4}
table.cpl.freeze tbody tr:hover{--row-bg:var(--surface-2)}


/* ==========================================================
   2026-10-20 新增（三）· 打印 / 另存 PDF
   8D 报告、内部报废台账、客诉台账常要打印交人，
   此前直接 Ctrl+P 会把侧栏、按钮、色块全打出来。
   ⚠️ 大量 !important：internal-scrap.html 的内联 <style> 在 <link> 之后，
      （.content / .panel / .cpl-wrap 的 flex 布局）同优先级下会赢过这里。
   ========================================================== */
/* 台账/8D 报告是宽表，默认给横向 A4（@page 写在 @media 外面兼容性最好） */
@page{size:A4 landscape;margin:12mm}
@media print{
  html,body{background:#fff!important}
  .side,.topbar,.filters,.tabs,.chart-filter,.btn,
  .mask,.lightbox,.att-del,.panel-head .act,.row-actions,
  .g12-tabs,.dd-tabs,.dict-add,.dict-del{display:none!important}
  #app{display:block!important;height:auto!important}
  .main{height:auto!important;overflow:visible!important}
  .content{display:block!important;overflow:visible!important;
    padding:0!important;height:auto!important}
  .panel{flex:none!important;border:0!important;margin:0 0 6mm!important;
    overflow:visible!important;page-break-inside:avoid}
  .panel-head{border-bottom:1px solid #999!important;padding:2px 0 4px!important}
  .panel-head .hint,.note{color:#555!important}
  .cpl-wrap{flex:none!important;max-height:none!important;overflow:visible!important}
  table{min-width:0!important;font-size:11px}
  table.cpl{min-width:0!important}
  thead{display:table-header-group}              /* 翻页时重复表头 */
  tfoot{display:table-footer-group}
  tr{page-break-inside:avoid}
  th,td{border-bottom:1px solid #bbb!important;background:#fff!important;
    color:#000!important;padding:4px 6px!important}
  /* 冻结列在纸上不需要，去掉阴影与粘性 */
  table.cpl.freeze th,table.cpl.freeze td{position:static!important;box-shadow:none!important}
  .is-thumb,.att-item{width:48px!important;height:36px!important}
  a{color:#000!important;text-decoration:none}
  .chart-box .chart-mask{display:none!important}
}

/* ==========================================================================
 * 2026-10-20 新增：站内提示 / 确认组件（static/ui.js）
 * 替代原生 alert / confirm：不阻塞页面、风格统一、**文字可选中复制**。
 * ========================================================================== */
.ui-toast-host{position:fixed;top:16px;right:16px;z-index:120;display:flex;
  flex-direction:column;gap:10px;align-items:flex-end;pointer-events:none;
  max-width:min(560px,60vw)}
.ui-toast{pointer-events:auto;display:flex;align-items:flex-start;gap:10px;
  min-width:220px;max-width:100%;background:var(--panel);border:1px solid var(--line);
  border-left:4px solid var(--brand);border-radius:8px;padding:10px 12px;
  box-shadow:0 6px 22px rgba(var(--shadow-rgb),.16);font-size:13px;line-height:1.6;
  color:var(--text);opacity:0;transform:translateY(-8px);
  transition:opacity .18s ease,transform .18s ease}
.ui-toast.is-in{opacity:1;transform:translateY(0)}
.ui-toast.is-out{opacity:0;transform:translateY(-6px)}
.ui-toast--ok{border-left-color:var(--ok)}
.ui-toast--err{border-left-color:var(--warn)}
.ui-toast--info{border-left-color:var(--brand)}
.ui-toast__icon{flex:none;width:18px;height:18px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;font-size:12px;
  font-weight:700;color:#fff;background:var(--brand);margin-top:1px}
.ui-toast--ok .ui-toast__icon{background:var(--ok)}
.ui-toast--err .ui-toast__icon{background:var(--warn)}
/* 提示正文允许选中复制——原生 alert 做不到，这是换掉它的主要原因之一 */
.ui-toast__text{flex:1;word-break:break-word;white-space:pre-wrap;user-select:text}
.ui-toast__x{flex:none;border:0;background:transparent;color:var(--text-3);
  font-size:16px;line-height:1;cursor:pointer;padding:0 2px}
.ui-toast__x:hover{color:var(--text)}

/* 确认框：沿用 .mask/.modal 版式，只是内容固定为「文案 + 取消/确定」 */
.ui-confirm-mask.is-open{display:flex}
.ui-confirm{width:min(460px,92vw);padding:20px 22px}
.ui-confirm__body{white-space:pre-wrap;user-select:text}
.ui-confirm .modal-foot{margin-top:16px}

/* ==========================================================================
 * 2026-10-20 新增：加载态骨架屏（替代原来光秃秃的一行「数据加载中…」）
 * 说明：.loading 有两种用法——
 *   ① 容器占位（表格 td 内 / #monthTable 等）→ 转圈 + 骨架条
 *   ② 图表遮罩里的 <span class="loading">加载中…</span> → 只要转圈，不能撑大
 * 因此基础样式只给「转圈 + 文字」，骨架条单独挂在 td > .loading 上。
 * ========================================================================== */
.loading{display:inline-flex;align-items:center;justify-content:center;gap:8px;
  padding:10px 0;text-align:center;color:var(--text-3);font-size:13px;
  animation:qc-fadein .2s ease both}
.loading::before{content:'';flex:none;width:14px;height:14px;border-radius:50%;
  border:2px solid var(--line-strong);border-top-color:var(--brand);
  animation:qc-spin .7s linear infinite}
@keyframes qc-spin{to{transform:rotate(360deg)}}
@keyframes qc-fadein{from{opacity:0}to{opacity:1}}

/* 表格内的加载态：多给一块骨架条，让人一眼看出"这里会是一张表" */
td > .loading,.cpl-wrap .loading{display:flex;flex-direction:column;gap:14px;
  width:100%;padding:26px 0}
td > .loading::after,.cpl-wrap .loading::after{
  content:'';width:min(760px,88%);height:104px;border-radius:8px;
  background:repeating-linear-gradient(to bottom,
    var(--surface-2) 0 16px, transparent 16px 26px);
  animation:qc-breathe 1.5s ease-in-out infinite}
@keyframes qc-breathe{0%,100%{opacity:.55}50%{opacity:1}}

/* 晕动症/性能优先：用户系统关闭动效时不转圈不闪烁 */
@media (prefers-reduced-motion:reduce){
  .loading::before{animation:none;border-top-color:var(--line-strong)}
  td > .loading::after,.cpl-wrap .loading::after{animation:none;opacity:.7}
  .ui-toast{transition:none}
}

/* ==========================================================================
 * 冷调改版 · 第三部分
 *  1) 页面冷光背景：大面积蓝灰会发闷，顶部压一层极淡冷光提亮
 *  2) 侧栏「浅色」备选：给 <body> 加 data-nav="light" 即切换（默认深海军蓝）
 *  3) 从模板内联 <style> 迁来的样式（gp12 / report / internal-scrap）
 *     —— 原先写在页面里，换肤改不到，是「换了一半的皮」的根源
 *  4) 报废明细柏拉图图例色块（原先是 5 处内联 style）
 * ========================================================================== */

/* 1) 冷光：只作用于背景，不覆盖内容（不用伪元素遮挡，避免压低文字对比） */
body{background:
  radial-gradient(1200px 620px at 88% -12%, #E7F0FA 0%, rgba(231,240,250,0) 62%),
  var(--bg)}

/* 2) 侧栏浅色备选：白底侧栏 + 钢蓝选中，整体明亮轻盈 */
body[data-nav="light"],body[data-nav="sand"]{
  --nav-bg:#FFFFFF; --nav-ink:#1B2733; --nav-ink-2:#566B80;
  --nav-ink-dim:#93A3B5; --nav-line:#DCE5EF;
  --nav-hover:#F1F6FC; --nav-active:#E8F1FC; --nav-accent:#1E5FA8;
}
body[data-nav="light"] .side,body[data-nav="sand"] .side{border-right-color:var(--line)}
body[data-nav="light"] .nav-item.active,body[data-nav="sand"] .nav-item.active{color:var(--brand)}

/* 3.1 从 gp12.html 内联 <style> 迁入（已 token 化） */
.g12-tabs{display:inline-flex;border:1px solid var(--line);border-radius:6px;overflow:hidden}
.g12-tabs button{height:28px;padding:0 14px;font-size:13px;background:var(--panel);
  border:none;color:var(--text-2);cursor:pointer}
.g12-tabs button.active{background:var(--brand);color:var(--inverse)}
.g12-tabs button + button{border-left:1px solid var(--line)}
.g12-hide{display:none}
.up-zone{border:2px dashed var(--line);border-radius:8px;padding:22px;text-align:center;
  color:var(--text-2);font-size:13px;background:var(--surface-2)}
.up-zone.over{border-color:var(--brand);background:var(--brand-soft);color:var(--brand)}
.pv-box{border:1px solid var(--line);border-radius:8px;padding:12px 14px;margin-top:12px;
  background:var(--panel)}
.pv-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:10px;
  margin-bottom:10px}
.pv-item{border:1px solid var(--line);border-radius:6px;padding:8px 10px;background:var(--surface-2)}
.pv-item b{display:block;font-size:18px;color:var(--brand);font-variant-numeric:tabular-nums}
.pv-item span{font-size:12px;color:var(--text-2)}
.pv-item.warn b{color:var(--warn)}
.tag{display:inline-block;padding:1px 7px;border-radius:9px;font-size:11px;
  line-height:17px;margin-right:4px}
.tag-new{background:var(--brand-soft);color:var(--brand)}
.tag-conflict{background:var(--st-warn-bg);color:var(--st-warn-ink)}
.tag-miss{background:var(--surface-3);color:var(--text-2)}
.tag-ok{background:var(--st-ok-bg);color:var(--st-ok-ink)}
.g12-note{font-size:12px;color:var(--text-3);margin-top:8px;line-height:1.7}
/* 上传预览顶部红色警告：文件名月份 ≠ 数据实际月份（口径提示，必须显眼） */
.g12-alert{font-size:12px;line-height:1.7;margin-bottom:10px;padding:9px 12px;
  border-radius:6px;background:var(--warn-soft);border:1px solid var(--st-bad-bd);
  color:var(--warn)}
.g12-alert b{color:var(--st-bad-ink)}
/* 警告条里的「按 X月归档」一键按钮 */
.btn-g12-alert{margin-left:8px;height:26px;padding:0 10px;font-size:12px;
  font-family:inherit;cursor:pointer;border-radius:6px;border:1px solid var(--warn);
  background:var(--panel);color:var(--warn);font-weight:600}
.btn-g12-alert:hover{background:var(--warn);color:var(--inverse)}
/* 已按指定月归档：绿色确认条 */
.g12-ok-note{font-size:12px;line-height:1.7;margin-bottom:10px;padding:9px 12px;
  border-radius:6px;background:var(--st-ok-bg);border:1px solid var(--st-ok-bd);
  color:var(--st-ok-ink)}
.miss-list{font-size:11px;color:var(--text-3);word-break:break-all}
table.g12 th,table.g12 td{padding:6px 10px;border-bottom:1px solid var(--line);
  font-size:13px;white-space:nowrap}
table.g12 th{background:var(--surface-3);font-weight:600;color:var(--text-2);text-align:left}
table.g12 td.n{text-align:right;font-variant-numeric:tabular-nums}
.rate-over{background:var(--warn-soft);color:var(--warn);font-weight:600}
.bar{display:inline-block;height:8px;background:var(--brand);border-radius:2px;
  vertical-align:middle;margin-right:6px}

/* 3.2 从 report.html 内联 <style> 迁入（已 token 化） */
.rpt-gen{display:flex;gap:14px;align-items:flex-end;flex-wrap:wrap}
.rpt-gen .fg{margin:0}
.rpt-bar{height:10px;background:var(--surface-3);border-radius:6px;overflow:hidden;margin-top:10px}
.rpt-bar>i{display:block;height:100%;width:0;background:var(--brand);border-radius:6px;
  transition:width .4s}
.rpt-steps{margin-top:8px;font-size:12px;color:var(--text-2)}
.rpt-files{display:flex;gap:10px;flex-wrap:wrap;margin-top:6px}
.rpt-file{display:inline-flex;align-items:center;gap:6px;padding:8px 14px;
  border:1px solid var(--line-strong);border-radius:8px;background:var(--panel);
  color:var(--text);text-decoration:none;font-size:13px}
.rpt-file:hover{border-color:var(--brand);color:var(--brand)}
.rpt-file.miss{opacity:.45;pointer-events:none}
.rpt-file b{font-weight:600}
.rpt-hist td{padding:9px 10px}
.badge-ok{display:inline-block;min-width:18px;text-align:center;background:var(--st-ok-bg);
  color:var(--st-ok-ink);border-radius:4px;padding:1px 5px;font-size:12px}
.badge-no{display:inline-block;min-width:18px;text-align:center;background:var(--surface-3);
  color:var(--text-3);border-radius:4px;padding:1px 5px;font-size:12px}

/* 3.3 从 internal-scrap.html 内联 <style> 迁入
 * 原写法直接改全局 .content/.panel/.cpl-wrap，会污染其它页面；
 * 改用 .page-iscrap 作用域（该页 body 加 class="page-iscrap"）。 */
.page-iscrap .content{display:flex;flex-direction:column}
.page-iscrap .panel{flex:1 1 auto;display:flex;flex-direction:column;min-height:0}
.page-iscrap .cpl-wrap{flex:1 1 auto;min-height:0;max-height:none}

/* 4) 报废明细柏拉图图例色块
 * 色值与 static/chart-theme.js 的 QC.stack.* / QC.rateOnStack 严格一致，
 * 改图表配色时两边必须同时改，否则「图例说是橙、柱子是别的色」。 */
.dd-legend i.lg-material{background:#5B9BD5}   /* 机加料废 QC.stack.material */
.dd-legend i.lg-process{background:#1E5FA8}    /* 机加工废 QC.stack.process  */
.dd-legend i.lg-die{background:#9AAFC4}        /* 压铸内废 QC.stack.die      */
.dd-legend i.lg-mixed{background:#CBD8E6}      /* 历史未细分 QC.stack.mixed  */
.dd-legend i.line.lg-rate{background:#B26A00}  /* 累计占比 QC.rateOnStack    */

/* 信息管理的行内提示 */
.err-mt{margin-top:8px}
