/* ============================================================
   图表样式（2026-09-08）
   ------------------------------------------------------------
   配套 Components/Charts 下的四个 SVG 组件（柱 / 折线 / 环 / 雷达）。
   零依赖：不引任何图表库，全部手写 SVG——现有的「打印」与「导出 PNG」
   都是对着 DOM 做的，换成第三方 canvas 库那两条要重做。

   三条固定规格（来自图表规范，别随手改）：
     · 柱子 ≤24px 粗、数据端 4px 圆角、基线端方角；
     · 线 2px、圆角圆头；端点圆点 ≥8px 直径且带 2px 画布色描边（压住交叉处）；
     · 网格线一档灰、1px 实线，绝不虚线——网格是背景不是数据。

   「两个空白」：相邻色块之间留 2px 画布色缝隙来分隔，不画描边；
   圆点用 2px 画布色环。描边会增加不是数据的墨水。
   ============================================================ */

.bom-chart {
    /* 颜色角色集中在这里：以后要加深色模式，只需在这一层覆盖，组件不用动 */
    --chart-surface: #ffffff;
    --chart-grid: #e5e7eb;
    --chart-axis-text: #6b7280;
    --chart-ink: #1f2937;
    --chart-muted: #9ca3af;

    position: relative;
    width: 100%;
}

.bom-chart svg { display: block; width: 100%; height: auto; overflow: visible; }

/* 网格与坐标轴：一律最轻的存在感 */
.bom-chart .cx-grid { stroke: var(--chart-grid); stroke-width: 1; shape-rendering: crispEdges; }
.bom-chart .cx-axis-text { fill: var(--chart-axis-text); font-size: 11px; }
.bom-chart .cx-label { fill: var(--chart-ink); font-size: 12px; }
.bom-chart .cx-value { fill: var(--chart-ink); font-size: 12px; font-weight: 600; }
.bom-chart .cx-muted { fill: var(--chart-muted); font-size: 11px; }

/* 柱：数据端圆角由 path 画出来，这里只管交互反馈 */
.bom-chart .cx-bar { transition: opacity .12s ease; }
.bom-chart .cx-hit { fill: transparent; cursor: default; }
.bom-chart .cx-hit.drillable { cursor: pointer; }
.bom-chart.has-hover .cx-bar { opacity: .45; }
.bom-chart.has-hover .cx-bar.on { opacity: 1; }

/* 线与面积 */
.bom-chart .cx-line { fill: none; stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.bom-chart .cx-area { stroke: none; opacity: .10; }
.bom-chart .cx-dot { stroke: var(--chart-surface); stroke-width: 2; }
.bom-chart .cx-crosshair { stroke: var(--chart-muted); stroke-width: 1; shape-rendering: crispEdges; }

/* 扇形：相邻扇区之间的 2px 缝隙用画布色描边实现（这是「空白分隔」不是「描边分隔」） */
.bom-chart .cx-slice { stroke: var(--chart-surface); stroke-width: 2; transition: opacity .12s ease; }
.bom-chart.has-hover .cx-slice { opacity: .45; }
.bom-chart.has-hover .cx-slice.on { opacity: 1; }

/* 雷达 */
.bom-chart .cx-radar-web { fill: none; stroke: var(--chart-grid); stroke-width: 1; }
.bom-chart .cx-radar-area { fill-opacity: .12; stroke-width: 2; stroke-linejoin: round; }

/* 图例：≥2 个系列必给。柱/面积用方块、折线用短线——与图上的标记形状一致 */
.bom-chart-legend {
    display: flex; flex-wrap: wrap; gap: 4px 16px;
    margin-top: 10px; font-size: 12px; color: var(--chart-ink);
}
.bom-chart-legend .lg { display: inline-flex; align-items: center; gap: 6px; cursor: default; }
.bom-chart-legend .lg-rect { width: 12px; height: 12px; border-radius: 3px; flex: none; }
.bom-chart-legend .lg-line { width: 14px; height: 2px; border-radius: 1px; flex: none; }
.bom-chart-legend .lg-val { color: var(--chart-axis-text); }

/* 悬浮读数：数值是主角（高对比、加粗），系列名是配角——与图例的主次正好相反 */
.bom-chart-tip {
    position: absolute; z-index: 5; pointer-events: none;
    min-width: 120px; max-width: 260px;
    background: #ffffff; border: 1px solid var(--chart-grid); border-radius: 8px;
    box-shadow: 0 6px 18px rgba(15, 23, 42, .12);
    padding: 8px 10px; font-size: 12px; color: var(--chart-ink);
    transform: translate(-50%, -100%);
}
.bom-chart-tip .tp-title { color: var(--chart-axis-text); margin-bottom: 4px; word-break: break-all; }
.bom-chart-tip .tp-row { display: flex; align-items: center; gap: 6px; white-space: nowrap; }
.bom-chart-tip .tp-key { width: 12px; height: 2px; border-radius: 1px; flex: none; }
.bom-chart-tip .tp-name { color: var(--chart-axis-text); }
.bom-chart-tip .tp-val { margin-left: auto; font-weight: 600; }

/* 打印：交互层不出现在纸上 */
@media print {
    .bom-chart-tip, .bom-chart .cx-crosshair { display: none !important; }
    .bom-chart.has-hover .cx-bar,
    .bom-chart.has-hover .cx-slice { opacity: 1 !important; }
}

/* ------------------------------------------------------------
   统计页的图表版式
   排行柱与占比环并排：两张图回答的是两个问题（谁最大 / 谁占大头），
   不是同一个问题画两遍。窄屏下自动堆叠——环形图挤到 300px 以下就没法读了。
   ------------------------------------------------------------ */
.chart-split { display: flex; gap: 24px; align-items: flex-start; }
.chart-split .chart-main { flex: 1 1 60%; min-width: 0; }
.chart-split .chart-side { flex: 0 0 360px; max-width: 360px; }

@media (max-width: 1100px) {
    .chart-split { flex-direction: column; }
    .chart-split .chart-side { flex: 1 1 auto; max-width: 420px; }
}

/* 小标题：说明这张图在回答什么问题，比图例更重要 */
.chart-cap {
    font-size: 13px; font-weight: 600; color: #1f2937;
    margin: 0 0 8px 2px;
}

/* 明细表折叠：图是给人看趋势的，精确数值在这里 */
.chart-table > summary {
    cursor: pointer; font-size: 13px; color: #6b7280;
    padding: 6px 0; user-select: none;
}
.chart-table > summary:hover { color: #2563eb; }
.chart-table table { margin-bottom: 0; }

/* ------------------------------------------------------------
   迷你趋势线（工作台卡片用）
   高度压到 30px 以内：它是数字的上下文，不是图表，不能抢走大字的位置。
   等比缩放（不横向拉伸），所以高度随卡片宽度在 20~30px 之间浮动；
   卡片特别宽时由 max-height 兜住，图形居中而不是被拉扁。
   ------------------------------------------------------------ */
.bom-spark {
    display: block;
    width: 100%;
    height: auto;
    max-height: 30px;
    margin-top: 6px;
    overflow: visible;
}

.bom-spark .sp-line {
    fill: none;
    stroke-width: 1.5;
    stroke-linecap: round;
    stroke-linejoin: round;
    /* 打印时浏览器默认丢颜色，线会整条消失 */
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
    /* 缩放后线宽保持 1.5px，不随卡片变粗变细 */
    vector-effect: non-scaling-stroke;
}

.bom-spark .sp-area { opacity: .10; }
.bom-spark .sp-dot { stroke: #fff; stroke-width: 1; vector-effect: non-scaling-stroke; }

/* 整段为 0 的迷你线：虚线 + 中性灰，一看就是「没发生」，不冒充趋势也不像下划线 */
.bom-spark .sp-flat {
    stroke: #cbd5e1;
    stroke-width: 1;
    stroke-dasharray: 3 4;
    vector-effect: non-scaling-stroke;
}
