/* 看板版式（v0.68.0 看板改版）
   ============================================================================
   本文件原先住在 app/static/js/admin/charts.js 的 `_dashCss()` 里（幂等哨兵 +
   createElement("style") 内联注入，与同一个文件里的 `_chartCss()` 同一套手法）。
   v0.68.0 收尾时整块搬到这里，由 admin.html 在 tokens.css 之后用 <link> 引入。

   为什么搬（三条，顺序即重要程度）：
   ① 行数：这 48 行把 charts.js 顶到 603 行，越过了「单个 admin 模块 < 600 行」
      的硬闸门（verify_v381.py / verify_v3829.py）。闸门的解法是搬家，不是改数字。
   ② 归位：这一段**零 JS 插值**，搬出去是等价的文本搬家 —— CSS 住进 .css 之后，
      顺带被 verify_v0610_tokens.py 的 F 组（全站禁半像素字号）纳管。
   ③ 级联不变：原先是运行时 appendChild 到 head 末尾、天然压尾；改成 <link> 之后
      排在 tokens.css 之后。admin.html 的内联样式里 .sect / .fx / .fn-* / #ch-*
      零同名规则，.bi-grid.hero 靠权重（0-2-0 > 0-1-0）胜出、与加载顺序无关。

   色值与字号一律用 tokens.css 与 admin.html :root 里的令牌，不新增硬编码色值。
   这里的 height 是几何尺寸（canvas 容器高度），不是字号/圆角，因此不走标尺。
   ========================================================================= */

/* 分区标题：把十几张卡分成「主图 / 构成 / 流程健康 / 效率 / 岗位」，一屏里先看到什么
   由它决定。基线对齐让说明文字与标题同一条视线，不靠 padding 凑。 */
.sect{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap;margin:18px 0 8px}
.sect b{font-size:var(--fs-md);font-weight:600}
.sect span{font-size:var(--fs-xs);color:var(--muted)}

/* 栅格分组。.bi-grid 的基础规则（auto-fit 460px）在 admin.html 的内联样式里，
   这里按分组语义覆盖：主图 2:1（趋势要宽度、漏斗只要窄条）；构成三列（占比图并排
   才好比）；流程健康与效率两列。 */

/* v0.71.4 排布：列数**固定**，不再用 auto-fit 让它随视口漂。
   为什么：每组卡片数量本来就是固定的（KPI 阶段卡 7 + 汇总 3；流程健康 4；
   效率 4；构成 3），而 auto-fit 会在宽屏多给一列 —— 1920 视口（内容列 1392px）
   实测：KPI 排成 8+2（两颗深色汇总卡单独占一行）、4 张一组的图表区排成 3+1
   （入职漏斗 / 人才库构成被甩到下一行），末行右侧空出 937px。卡片是对的，
   错的是列数跟着窗口变。固定成 5×2 / 2×2 / 3×1 之后每一行都是满的。
   窄屏在文件末尾的 @media 里降列：10 能被 5 和 2 整除，任何档位都不会剩半截行。 */
#stats{grid-template-columns:repeat(5,minmax(0,1fr))}
.bi-grid.hero{grid-template-columns:minmax(0,1.9fr) minmax(0,1fr)}
.bi-grid.g2{grid-template-columns:repeat(2,minmax(0,1fr))}
.bi-grid.g3{grid-template-columns:repeat(3,minmax(0,1fr))}

/* 说明文字统一两行高。同一行里有的说明一行、有的两行（「各环节状态分布」那句
   跨了行），图就从两条不同的线开始 —— 单看每张卡没问题，并排看就是「没对齐」。
   2.45em = fs-sm 的行高（1.6）× 两行 + 一点余量。只取标题后的第一段，
   不碰卡片底部那行补充说明（#ch-offer-cap 那种）。 */
.chart>h3+.cap{min-height:2.45em}

/* 横条图按「行内配对」给最小绘图高。ECharts 的类目轴会把行均分到容器高度，
   给了下限之后，1~3 条的小卡不会缩成一条缝，同一行两张卡的内部也齐。
   #ch-status 的 7 行本来就是 210，这里写出来是为了让「同一行 210」可读。 */
#ch-status{min-height:210px}
#ch-ivload{min-height:200px}
#ch-ivstatus{min-height:150px}

/* 入场：逐块淡入上浮。延迟由 dashEnter() 按序号写进 style.animationDelay，
   这里只管时长与曲线。 */
@keyframes dashUpFx{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
.fx{animation:dashUpFx .45s both}

/* 漏斗条：居中横条 + 右侧相邻转化率。用 HTML 而不是 ECharts —— 见 charts.js 里
   funnelBars() 的注释（ECharts 的 funnel 是倒三角，与本页图意不同）。 */
.fn-wrap{display:flex;flex-direction:column;gap:6px}
.fn-row{display:flex;align-items:center;gap:10px}
.fn-cell{flex:1;display:flex;justify-content:center}
/* 不写 overflow:hidden、且显式给 min-width:min-content —— 两个都得做：
   ① overflow 非 visible 的 flex 项「自动最小宽度」归 0；② 就算 overflow 可见，
   自动最小尺寸也是 **min(显式 width, min-content)** —— 设了 width:14%（35px）
   就取 35px，真机上照样裁成 Assess… / Interv… / Offere…。所以必须显式声明
   min-width:min-content，条长才至少装得下自己的标签。
   条宽本是形状线索（14% 下限已经破坏了严格比例），精确数字由右侧的转化率列
   承担，卡片说明也是这么写的。0 的那条由 JS 内联 min-width:0 压掉（否则
   min-content 会把 width:0 的条也撑成一条彩条，凭空多出一格）。 */
.fn-bar{border-radius:var(--r-sm);padding:5px 0;text-align:center;
  font-size:var(--fs-sm);white-space:nowrap;min-width:min-content}
.fn-row.big .fn-bar{padding:7px 0}
.fn-pct{width:44px;flex:none;text-align:right;font-size:var(--fs-xs);color:var(--muted)}

/* 系统开了「减少动态效果」就整体不播（CSS 与 ECharts 两侧一起关 —— 只关一侧会变成
   「一半静一半动」，比全开更刺眼）。 */
@media (prefers-reduced-motion: reduce){.fx{animation:none}}

/* ECharts 画在 canvas 上，容器必须有**确定高度** —— 以前手写 SVG 自带高度，
   换成 canvas 后 0 高容器画出来就是一张看不见的图（真机量过：canvas 在、内容空白）。
   横向条不需要这条：它的行数可变，由 ecHBar 按行数设高。 */
#ch-trend, #ch-score{height:230px}
#ch-decision, #ch-source, #ch-visit, #ch-offer{height:210px}
#tn-ch-trend, #tn-ch-tokens, #tn-ch-ttrend, #tn-ch-tscore{height:230px}
#tn-ch-status, #tn-ch-tdecision, #tn-ch-tsource{height:210px}

/* 内容列放不下并排时降成单列。1100 是量出来的：视口 − 侧栏 228 − 内边距 40 ≈ 830px，
   hero 的 2:1 到这时漏斗只剩 277px，转化率已经贴到条上。 */
@media (max-width:1100px){.bi-grid.hero{grid-template-columns:minmax(0,1fr)}}

/* v0.71.4：窄屏的列数也固定。KPI 10 格降到 2 列 = 5 行（10 能被 2 整除）；
   图表分组（4 张 / 3 张）直接单列 —— 用 2 列装 3 张会剩一张孤零零地占半行，
   正是这一版要消灭的那种排布。 */
@media (max-width:900px){
  #stats{grid-template-columns:repeat(2,minmax(0,1fr))}
  .bi-grid.g2,.bi-grid.g3{grid-template-columns:minmax(0,1fr)}
}
