/* 全站可视化小零件（2026-10-04 老板：「所有页面的一个可视化优化……现在的文字和各方面，稍微设计一下，让这个界面对人更友好」；
   同日：「多做一些可视化的东西，这样我比较容易理解，也比较容易找到需要的东西」）。
   一套零件各页共用，长得一样、意思一样：红 = 马上处理、橙 = 要盯、绿 = 好了、蓝 = 提示、灰 = 看看。
   怎么画由 shared/viz.js（window.SquViz）出 HTML 字符串，这里只管样子；颜色只用 tokens.css 的变量（UI 门禁）。
   零件：数字卡 sqv-kpi（可带小趋势线）、进度条 sqv-meter、排行条 sqv-bars、占比条 sqv-stack、进度点 sqv-steps、
   状态牌 sqv-pill、到期 sqv-due、小标题 sqv-h、空状态 sqv-empty、悬停说明 sqv-tip。 */

/* ---------- 数字卡：一排大数字，点得动的写成 <button class="sqv-kpi"> ---------- */
.sqv-kpis { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin: var(--sp-3) 0; }
.sqv-kpi { flex: 1 1 150px; min-width: 128px; max-width: 280px; display: flex; flex-direction: column; gap: 2px; box-sizing: border-box;
  padding: 10px 12px; border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--surface);
  text-align: left; font: inherit; color: inherit; }
button.sqv-kpi { cursor: pointer; }
button.sqv-kpi:hover { border-color: var(--border-strong); }
button.sqv-kpi:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.sqv-kpi.on { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); }
.sqv-kpi.zero { opacity: .6; }
.sqv-kpi-l { display: flex; align-items: center; gap: 6px; font-size: var(--fs-xs); line-height: var(--lh-xs); color: var(--text-secondary); }
.sqv-kpi-l .sqv-ico { color: var(--text-muted); }
.sqv-kpi-v { display: flex; align-items: baseline; gap: 6px; font-size: 24px; line-height: 30px; font-weight: var(--fw-semibold); color: var(--text-primary); }
.sqv-kpi-v small { font-size: var(--fs-xs); font-weight: var(--fw-regular); color: var(--text-muted); }
.sqv-kpi-n { font-size: var(--fs-xs); line-height: var(--lh-xs); color: var(--text-muted); }
.sqv-kpi.bad { border-color: var(--danger-border); background: var(--danger-bg); }
.sqv-kpi.bad .sqv-kpi-v, .sqv-kpi.bad .sqv-kpi-l .sqv-ico { color: var(--danger-fg); }
.sqv-kpi.warn { border-color: var(--warning-border); background: var(--warning-bg); }
.sqv-kpi.warn .sqv-kpi-v, .sqv-kpi.warn .sqv-kpi-l .sqv-ico { color: var(--warning-fg); }
.sqv-kpi.good .sqv-kpi-v, .sqv-kpi.good .sqv-kpi-l .sqv-ico { color: var(--success-fg); }
.sqv-kpi.money { border-color: var(--accent-soft-border); background: var(--accent-soft-bg); }
/* 选中的卡（老板 10-10 截图交货进度：「点了哪个框也不是特别明显，都不知道点了没点」）：原来的 .on 写在上面、颜色卡（bad/warn/money）
   的边框盖掉了它，红黄卡选中了看不出来。现在：选中的加粗一圈主色 + 右上角「✓ 正在看」，同一排没选中的变淡 */
.sqv-kpis .sqv-kpi.on { position: relative; border-color: var(--accent); box-shadow: inset 0 0 0 2px var(--accent); }
.sqv-kpis .sqv-kpi.on::after { content: "✓ 正在看"; position: absolute; top: 6px; right: 8px; padding: 0 6px; border-radius: var(--radius-sm);
  background: var(--accent); color: var(--text-on-accent); font-size: 11px; line-height: 17px; font-weight: var(--fw-semibold); white-space: nowrap; }
.sqv-kpis:has(.sqv-kpi.on) button.sqv-kpi:not(.on) { opacity: .6; }
.sqv-kpis:has(.sqv-kpi.on) button.sqv-kpi:not(.on):hover { opacity: 1; }
.sqv-delta { font-size: var(--fs-xs); font-weight: var(--fw-medium); white-space: nowrap; }
.sqv-delta.good { color: var(--success-fg); }
.sqv-delta.bad { color: var(--danger-fg); }
.sqv-delta.flat { color: var(--text-muted); }

/* ---------- 小趋势线（数字卡里、表格里都能放） ---------- */
.sqv-spark { display: block; margin-top: 4px; overflow: visible; }
.sqv-spark.inline { display: inline-block; margin: 0; vertical-align: middle; }
.sqv-spark .ln { fill: none; stroke: var(--accent); stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.sqv-spark .ar { fill: var(--accent); opacity: .1; }
.sqv-spark .pt { fill: var(--accent); stroke: var(--surface); stroke-width: 2; }
.sqv-spark .hit { fill: transparent; }
.sqv-spark .hit:hover + .dot { opacity: 1; }
.sqv-spark .dot { fill: var(--accent); opacity: 0; pointer-events: none; }
.sqv-spark .base { stroke: var(--chart-grid); stroke-width: 1; }

/* ---------- 进度条：一个数对着上限（完成几成、用了多少） ---------- */
.sqv-meter { display: flex; align-items: center; gap: 8px; min-width: 0; }
.sqv-meter-t { flex: 1 1 auto; min-width: 48px; height: 8px; border-radius: var(--radius-full); background: var(--accent-soft-bg); overflow: hidden; }
.sqv-meter-f { height: 100%; border-radius: var(--radius-full); background: var(--accent); }
.sqv-meter.warn .sqv-meter-t { background: var(--warning-bg); }
.sqv-meter.warn .sqv-meter-f { background: var(--warning-fg); }
.sqv-meter.bad .sqv-meter-t { background: var(--danger-bg); }
.sqv-meter.bad .sqv-meter-f { background: var(--danger-fg); }
.sqv-meter.muted .sqv-meter-t { background: var(--neutral-bg); }
.sqv-meter.muted .sqv-meter-f { background: var(--n-400); }
.sqv-meter-v { flex: none; font-size: var(--fs-xs); color: var(--text-secondary); font-variant-numeric: tabular-nums; white-space: nowrap; }

/* ---------- 排行条：几样东西比多少（左名字、中间条、右数） ---------- */
.sqv-bars { display: grid; grid-template-columns: minmax(48px, max-content) minmax(60px, 1fr) max-content; gap: 6px 10px; align-items: center;
  font-size: var(--fs-sm); line-height: var(--lh-sm); }
.sqv-bars-l { min-width: 0; max-width: 240px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--text-primary); }
.sqv-bars-t { position: relative; height: 14px; }
.sqv-bars-f { height: 14px; min-width: 2px; border-radius: 0 4px 4px 0; background: var(--chart-seq-3); }
.sqv-bars-f.hi { background: var(--accent); }
.sqv-bars-f.bad { background: var(--danger-fg); }
.sqv-bars-f.warn { background: var(--warning-fg); }
.sqv-bars-f.muted { background: var(--n-300); }
.sqv-bars-v { color: var(--text-secondary); font-variant-numeric: tabular-nums; text-align: right; white-space: nowrap; }
.sqv-bars > [data-viz-tip] { cursor: default; }

/* ---------- 占比条：一个整体分成几块（横着一条，块和块之间 2px 空） ---------- */
.sqv-stack { display: flex; gap: 2px; height: 12px; border-radius: 4px; overflow: hidden; background: var(--surface); }
.sqv-stack > i { display: block; min-width: 2px; height: 100%; }
.sqv-legend { display: flex; flex-wrap: wrap; gap: 4px 14px; margin-top: 6px; font-size: var(--fs-xs); color: var(--text-secondary); }
.sqv-legend span { display: inline-flex; align-items: center; gap: 5px; white-space: nowrap; }
.sqv-legend i { width: 10px; height: 10px; border-radius: 3px; display: inline-block; }
.sqv-c1 { background: var(--chart-1); } .sqv-c2 { background: var(--chart-2); } .sqv-c3 { background: var(--chart-3); }
.sqv-c4 { background: var(--chart-4); } .sqv-c5 { background: var(--chart-5); } .sqv-c6 { background: var(--chart-6); }
.sqv-c7 { background: var(--chart-7); } .sqv-c8 { background: var(--chart-8); } .sqv-c0 { background: var(--n-300); }
.sqv-cbad { background: var(--danger-fg); } .sqv-cwarn { background: var(--warning-fg); } .sqv-cgood { background: var(--success-fg); }

/* ---------- 进度点：一单走到哪一步（下单 → 定金 → 交货 → 到货 → 发货 → 签收） ---------- */
.sqv-steps { display: flex; align-items: flex-start; margin: 0; padding: 0; list-style: none; min-width: 0; }
.sqv-step { position: relative; flex: 1 1 0; min-width: 0; text-align: center; font-size: var(--fs-xs); line-height: var(--lh-xs); color: var(--text-muted); }
.sqv-step::before { content: ""; position: absolute; top: 6px; left: -50%; right: 50%; height: 2px; background: var(--border); }
.sqv-step:first-child::before { display: none; }
.sqv-step > i { position: relative; z-index: 1; display: block; box-sizing: border-box; width: 14px; height: 14px; margin: 0 auto 3px;
  border: 2px solid var(--border-strong); border-radius: 50%; background: var(--surface); }
.sqv-step > span { display: block; padding: 0 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sqv-step.done > i { border-color: var(--accent); background: var(--accent); }
.sqv-step.done::before, .sqv-step.now::before { background: var(--accent); }
.sqv-step.now { color: var(--text-primary); font-weight: var(--fw-semibold); }
.sqv-step.now > i { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft-bg); }
.sqv-step.late { color: var(--danger-fg); font-weight: var(--fw-semibold); }
.sqv-step.late > i { border-color: var(--danger-fg); background: var(--danger-bg); box-shadow: 0 0 0 3px var(--danger-bg); }
.sqv-step.skip > i { border-style: dashed; }
/* 表格里一格放得下的小号：只有点和线，悬停看是哪一步 */
.sqv-steps.mini { display: inline-flex; vertical-align: middle; }
.sqv-steps.mini .sqv-step { flex: 0 0 16px; }
.sqv-steps.mini .sqv-step::before { top: 4px; left: -8px; right: 8px; }
.sqv-steps.mini .sqv-step > i { width: 10px; height: 10px; margin: 0 auto; border-width: 2px; }
.sqv-steps.mini .sqv-step.now > i, .sqv-steps.mini .sqv-step.late > i { box-shadow: 0 0 0 2px var(--accent-soft-bg); }
.sqv-steps.mini .sqv-step.late > i { box-shadow: 0 0 0 2px var(--danger-bg); }
.sqv-steps.mini .sqv-step > span { display: none; }

/* ---------- 状态牌：一个圆点 + 字（颜色从来不单独表意） ---------- */
.sqv-pill { display: inline-flex; align-items: center; gap: 5px; height: 22px; padding: 0 9px; box-sizing: border-box; vertical-align: middle;
  border: 1px solid var(--neutral-border); border-radius: var(--radius-full); background: var(--neutral-bg); color: var(--neutral-fg);
  font-size: var(--fs-xs); font-weight: var(--fw-medium); line-height: 1; white-space: nowrap; }
.sqv-pill::before { content: ""; flex: none; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.sqv-pill.nodot::before { display: none; }
.sqv-pill.bad { border-color: var(--danger-border); background: var(--danger-bg); color: var(--danger-fg); }
.sqv-pill.warn { border-color: var(--warning-border); background: var(--warning-bg); color: var(--warning-fg); }
.sqv-pill.good { border-color: var(--success-border); background: var(--success-bg); color: var(--success-fg); }
.sqv-pill.info { border-color: var(--info-border); background: var(--info-bg); color: var(--info-fg); }
.sqv-pill.accent { border-color: var(--accent-soft-border); background: var(--accent-soft-bg); color: var(--accent-soft-fg); }

/* ---------- 小标题：图标 + 名字 + 数，长页面上一眼认出这段是什么 ---------- */
.sqv-h { display: flex; align-items: center; gap: 8px; margin: var(--sp-5) 0 var(--sp-2); font-size: var(--fs-lg); line-height: var(--lh-lg);
  font-weight: var(--fw-semibold); color: var(--text-primary); }
.sqv-h .sqv-ico { flex: none; display: grid; place-items: center; width: 28px; height: 28px; border-radius: 8px;
  background: var(--accent-soft-bg); color: var(--accent); }
.sqv-h.bad .sqv-ico { background: var(--danger-bg); color: var(--danger-fg); }
.sqv-h.warn .sqv-ico { background: var(--warning-bg); color: var(--warning-fg); }
.sqv-h.info .sqv-ico { background: var(--info-bg); color: var(--info-fg); }
.sqv-h em { font-style: normal; font-size: var(--fs-sm); font-weight: var(--fw-regular); color: var(--text-muted); }
.sqv-h small { margin-left: auto; font-size: var(--fs-xs); font-weight: var(--fw-regular); color: var(--text-muted); }

/* ---------- 空状态：一个图标 + 一句大白话（+ 下一步按钮） ---------- */
.sqv-empty { display: flex; flex-direction: column; align-items: center; gap: 8px; padding: 28px 16px; text-align: center;
  font-size: var(--fs-sm); line-height: var(--lh-sm); color: var(--text-secondary); }
.sqv-empty-ico { display: grid; place-items: center; width: 44px; height: 44px; border-radius: 50%; background: var(--accent-soft-bg); color: var(--accent); }
.sqv-empty.good .sqv-empty-ico { background: var(--success-bg); color: var(--success-fg); }
.sqv-empty b { color: var(--text-primary); font-weight: var(--fw-semibold); }

/* ---------- 图标（viz.js 里那几十个线条图标，跟字一个颜色） ---------- */
.sqv-ico { display: inline-flex; flex: none; vertical-align: middle; }
.sqv-ico svg { display: block; }

/* ---------- 悬停说明：图上的点、条、块指上去看具体数 ---------- */
.sqv-tip { position: fixed; z-index: 70; max-width: 300px; padding: 6px 9px; border-radius: var(--radius-sm); pointer-events: none;
  background: var(--n-800); color: var(--n-0); box-shadow: var(--shadow-2); font-size: var(--fs-xs); line-height: var(--lh-xs); white-space: pre-line; }
.sqv-tip[hidden] { display: none; }

@media print { .sqv-tip { display: none !important; } }
@media (max-width: 640px) {
  .sqv-kpi { flex-basis: calc(50% - 4px); max-width: none; }
  .sqv-kpi-v { font-size: 20px; line-height: 26px; }
  .sqv-bars-l { max-width: 120px; }
}
