/* ============================================================
   数据中台 · SVG 图表样式 V4
   - 渐变配色、数据点光晕、轴线跟随、富 Tooltip、加载动效、流光线条
   ============================================================ */
.dt-chart {
  width: 100%; height: 100%;
  position: relative;
  font-family: var(--font-sans);
  color: var(--ink-1);
  overflow: visible;     /* v6 任务 8：图表容器禁滚动 */
}
.dt-chart svg { width: 100%; height: 100%; display: block; overflow: visible; }
/* v6 任务 8：所有图表/SVG 容器禁纵向滚动 */
.dt-chart, .svg-chart, .chart, [class*="chart-"] { overflow-y: hidden !important; }

/* ---------------- 坐标轴 ---------------- */
.dt-chart .ax-line { stroke: var(--line-2); stroke-width: 1; }
.dt-chart .ax-tick { stroke: var(--line-2); stroke-width: 1; }
.dt-chart .ax-text { fill: var(--ink-3); font-size: 11.5px; font-family: var(--font-sans); user-select: none; }
.dt-chart .ax-text.num { font-family: var(--font-num); font-size: 11.5px; }
.dt-chart .grid-line { stroke: var(--line-1); stroke-width: 1; stroke-dasharray: 3 4; }
.dt-chart .grid-line.strong { stroke-dasharray: none; }
.dt-chart .grid-line-v { stroke: rgba(46,99,232,.25); stroke-width: 1; stroke-dasharray: none; pointer-events: none; opacity: 0; transition: opacity .12s; }
.dt-chart .grid-line-v.show { opacity: 1; }

/* ---------------- 图例 ---------------- */
.dt-legend {
  position: absolute; display: flex; gap: 12px; flex-wrap: wrap;
  font-size: 12px; color: var(--ink-2);
  padding: 6px 8px; user-select: none;
}
.dt-legend .lg-item {
  display: inline-flex; align-items: center; gap: 5px;
  cursor: pointer; transition: all .18s;
  padding: 3px 8px; border-radius: 4px;
}
.dt-legend .lg-item:hover { background: var(--bg-hover); color: var(--ink-1); }
.dt-legend .lg-item .lg-dot {
  width: 12px; height: 12px; border-radius: 3px; display: inline-block;
  box-shadow: 0 1px 3px rgba(0,0,0,.12);
}
.dt-legend .lg-item .lg-dot.round { border-radius: 50%; }
.dt-legend .lg-item .lg-dot.line {
  width: 14px; height: 3px; border-radius: 2px;
}
.dt-legend .lg-item.off { opacity: .32; }
.dt-legend .lg-item.off .lg-dot { background: var(--ink-5) !important; }

.dt-legend.top    { top: 2px; left: 8px; }
.dt-legend.bottom { bottom: 2px; left: 8px; }
.dt-legend.right  { top: 2px; right: 8px; flex-direction: column; gap: 6px; }

/* ---------------- Tooltip ---------------- */
.dt-tip {
  position: fixed; z-index: 9999;
  min-width: 140px; max-width: 280px;
  padding: 10px 12px;
  background: rgba(15,26,51,.94);
  color: #fff; font-size: 12px;
  border-radius: 8px;
  box-shadow: 0 8px 24px rgba(0,0,0,.24);
  pointer-events: none;
  opacity: 0; transform: translateY(4px);
  transition: opacity .12s, transform .12s;
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
  line-height: 1.55;
  font-variant-numeric: tabular-nums;
}
.dt-tip.show { opacity: 1; transform: translateY(0); }
.dt-tip .tip-title {
  font-weight: 600; color: #fff; margin-bottom: 6px;
  font-size: 12.5px; padding-bottom: 5px;
  border-bottom: 1px solid rgba(255,255,255,.16);
}
.dt-tip .tip-row {
  display: flex; align-items: center; gap: 7px;
  font-size: 12px; padding: 2px 0;
}
.dt-tip .tip-row .tip-dot {
  width: 8px; height: 8px; border-radius: 50%;
  flex-shrink: 0; box-shadow: 0 0 6px currentColor;
}
.dt-tip .tip-row .tip-name { opacity: .8; }
.dt-tip .tip-row .tip-val,
.dt-tip .tip-row .tip-v {
  margin-left: auto; font-weight: 600; color: #fff;
  font-family: var(--font-num);
}
.dt-tip .tip-row .tip-k { opacity: .8; }

/* ---------------- 数据点/高亮 ---------------- */
.dt-chart .data-point {
  fill: #fff; stroke-width: 2;
  transition: r .2s, stroke-width .2s, filter .2s;
  cursor: pointer;
}
.dt-chart .data-point.hl {
  r: 5.5;
  filter: drop-shadow(0 0 6px currentColor);
  stroke-width: 2.5;
}
.dt-chart .data-line {
  transition: stroke-width .18s, opacity .18s;
}
.dt-chart .data-line.dim { opacity: .25; }
.dt-chart .data-line.hl { stroke-width: 2.4; }

/* 柱状 hover */
.dt-chart .bar-rect { transition: opacity .15s, filter .15s; cursor: pointer; }
.dt-chart .bar-rect:hover { filter: brightness(1.15) drop-shadow(0 2px 6px rgba(46,99,232,.3)); }
.dt-chart .bar-rect.dim { opacity: .35; }

/* 饼图切片 */
.dt-chart .pie-slice { transition: transform .18s var(--ease, cubic-bezier(.22,.82,.36,1)), filter .18s; cursor: pointer; transform-origin: center; }
.dt-chart .pie-slice:hover { transform: scale(1.035); filter: drop-shadow(0 4px 10px rgba(0,0,0,.18)); }

/* ---------------- 加载骨架（shimmer） ---------------- */
.dt-chart.is-loading { position: relative; }
.dt-chart.is-loading::before {
  content: ''; position: absolute; inset: 0; z-index: 10;
  background: linear-gradient(90deg, rgba(255,255,255,0) 0%, rgba(255,255,255,.6) 50%, rgba(255,255,255,0) 100%);
  background-size: 50% 100%; background-repeat: no-repeat;
  animation: chartShimmer 1.3s infinite linear;
  pointer-events: none;
}
.dt-chart.is-loading::after {
  content: attr(data-loading);
  position: absolute; left: 50%; top: 50%; transform: translate(-50%,-50%);
  color: var(--ink-3); font-size: 12px;
  background: rgba(255,255,255,.8); padding: 4px 10px; border-radius: 4px;
  z-index: 11;
}
@keyframes chartShimmer { 0% { background-position: -50% 0; } 100% { background-position: 150% 0; } }

.dt-chart.is-empty::after {
  content: attr(data-empty);
  position: absolute; left: 50%; top: 50%; transform: translate(-50%,-50%);
  color: var(--ink-4); font-size: 12px;
  pointer-events: none;
}

/* ---------------- 入场动画 ---------------- */
.dt-chart .anim-draw {
  stroke-dasharray: var(--len, 1000);
  stroke-dashoffset: var(--len, 1000);
  animation: chartDraw 1.1s ease-out forwards;
}
@keyframes chartDraw { to { stroke-dashoffset: 0; } }

.dt-chart .anim-rise {
  transform-origin: 50% 100%;
  animation: chartRise .8s cubic-bezier(.22,.82,.36,1) backwards;
}
@keyframes chartRise { from { transform: scaleY(.01); opacity: .2; } to { transform: scaleY(1); opacity: 1; } }

.dt-chart .anim-fade-in {
  animation: chartFadeIn .5s ease backwards;
}
@keyframes chartFadeIn { from { opacity: 0; } to { opacity: 1; } }

.dt-chart .anim-sweep {
  animation: chartSweep 1s cubic-bezier(.22,.82,.36,1) backwards;
  transform-origin: center;
}
@keyframes chartSweep { from { transform: rotate(-90deg) scale(.9); opacity: 0; } to { transform: none; opacity: 1; } }

.dt-chart .anim-pulse {
  animation: chartPulse 2s ease-in-out infinite;
}
@keyframes chartPulse {
  0%, 100% { filter: drop-shadow(0 0 0 currentColor); }
  50%      { filter: drop-shadow(0 0 6px currentColor); }
}

/* ---------------- 流光指向性线（DAG/血缘/Sankey） ---------------- */
.dt-chart .flow-line,
.flow-line {
  stroke-dasharray: 6 5;
  animation: flowMarch 1.3s linear infinite;
}
.dt-chart .flow-line.reverse,
.flow-line.reverse { animation-direction: reverse; }
.dt-chart .flow-line.fast { animation-duration: .75s; }
.dt-chart .flow-line.slow { animation-duration: 2.6s; }
@keyframes flowMarch { to { stroke-dashoffset: -22; } }

/* 细亮流光（在粗线之上叠加一条细光条） */
.dt-chart .flow-glow,
.flow-glow {
  stroke-dasharray: 10 36;
  animation: flowGlow 2s linear infinite;
  opacity: .85; filter: drop-shadow(0 0 4px currentColor);
}
@keyframes flowGlow { to { stroke-dashoffset: -46; } }

/* ---------------- KPI 内嵌 Sparkline 容器 ---------------- */
.dt-chart.spark { min-height: 30px; }

/* ---------------- Gauge（仪表盘） ---------------- */
.dt-chart .gauge-bg { fill: none; stroke: #EEF2F9; }
.dt-chart .gauge-fg { fill: none; transition: stroke-dashoffset 1s cubic-bezier(.22,.82,.36,1); }
.dt-chart .gauge-value { font-family: var(--font-num); font-weight: 700; fill: var(--ink-1); }
.dt-chart .gauge-label { fill: var(--ink-3); }

/* ---------------- Heatmap ---------------- */
.dt-chart .hm-cell { stroke: #fff; stroke-width: 1; transition: filter .15s, stroke-width .15s; cursor: pointer; }
.dt-chart .hm-cell:hover { stroke: var(--brand); stroke-width: 2; filter: brightness(1.1); }

/* ---------------- 漏斗 ---------------- */
.dt-chart .funnel-seg { transition: filter .15s; cursor: pointer; }
.dt-chart .funnel-seg:hover { filter: brightness(1.12); }

/* ---------------- 雷达 ---------------- */
.dt-chart .radar-web { fill: rgba(46,99,232,.05); stroke: var(--line-2); }
.dt-chart .radar-area { fill-opacity: .3; transition: fill-opacity .2s; }
.dt-chart .radar-area:hover { fill-opacity: .5; }

/* ---------------- 散点 ---------------- */
.dt-chart .sc-dot { stroke-width: 1.5; stroke: #fff; cursor: pointer; transition: r .2s, filter .2s; }
.dt-chart .sc-dot:hover { filter: drop-shadow(0 0 6px currentColor); }

/* ---------------- Spark ---------------- */
.dt-chart .sp-line { fill: none; stroke-width: 1.6; }
.dt-chart .sp-area { opacity: .85; }
.dt-chart .sp-dot  { filter: drop-shadow(0 0 4px currentColor); }

/* ---------------- 桑基 / 弦图 ---------------- */
.dt-chart .sk-node { fill: var(--brand); }
.dt-chart .sk-link { fill-opacity: .28; transition: fill-opacity .18s; }
.dt-chart .sk-link:hover { fill-opacity: .6; }

/* ---------------- 通用文字 ---------------- */
.dt-chart .val-text { fill: var(--ink-1); font-family: var(--font-num); font-size: 12px; }
.dt-chart .val-text.sm { font-size: 10.5px; }
.dt-chart .val-text.lg { font-size: 15px; font-weight: 600; }

/* ---------------- 图表容器卡 ---------------- */
.chart-card {
  background: #fff; border: 1px solid var(--line-1);
  border-radius: var(--radius-md); overflow: hidden;
  transition: border-color .18s, box-shadow .18s;
  display: flex; flex-direction: column;
}
.chart-card:hover { border-color: var(--brand-100); box-shadow: var(--shadow-sm); }
.chart-card .chart-head {
  display: flex; align-items: center; gap: 8px;
  padding: 10px 14px; border-bottom: 1px solid var(--line-1);
  min-height: 44px;
}
.chart-card .chart-title {
  font-weight: 600; font-size: 14px; color: var(--ink-1);
  display: flex; align-items: center; gap: 6px;
}
.chart-card .chart-title::before {
  content: ''; width: 3px; height: 12px;
  background: linear-gradient(180deg, var(--brand), var(--c7));
  border-radius: 2px;
}
.chart-card .chart-actions { margin-left: auto; display: flex; gap: 4px; }
.chart-card .chart-body {
  flex: 1; min-height: 200px; padding: 10px 12px;
  position: relative;
}

/* ---------------- 数值贴图（状态卡） ---------------- */
.dt-chart .status-text { font-weight: 700; fill: currentColor; }
