/* ===== 星链视图（概览页第二套展示：树状图 + 排行榜 + 新注册） =====
   设计基调：一根主干长出一片星链——根节点是发光核心，加盟层级 / 业务分支
   是二级干，明细是挂在枝上的节点。配色沿用控制台主题令牌，只补一层色阶。 */

.d2 {
  --d2-c0: #4f6ef7;
  --d2-c1: #0ea5a4;
  --d2-c2: #f0a02a;
  --d2-c3: #8b5cf6;
  --d2-c4: #ec4899;
  --d2-line: var(--line);
  display: flex;
  flex-direction: column;
  gap: 16px;
  animation: d2In 0.32s ease both;
}
[data-theme="dark"] .d2 {
  --d2-c0: #7c93ff;
  --d2-c1: #2dd4bf;
  --d2-c2: #fbbf24;
  --d2-c3: #a78bfa;
  --d2-c4: #f472b6;
}
.d2[hidden] { display: none !important; }

@keyframes d2In {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: none; }
}

/* ---------- 顶部条（大盘条 / 星链条） ---------- */
.dash-bar {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 10px 12px;
  flex-wrap: wrap;
  margin-bottom: 14px;
}
.dash-bar-l { display: flex; align-items: baseline; gap: 9px; min-width: 0; margin-right: auto; }
.dash-bar-title {
  font-size: 13px;
  font-weight: 650;
  letter-spacing: 0.01em;
  color: var(--text);
  white-space: nowrap;
}
.dash-bar-sub {
  font-size: 11.5px;
  color: var(--muted-2);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.dash-bar .seg button { font-size: 12px; padding: 5px 12px; }
.dash-bar-r { display: flex; align-items: center; gap: 10px; }
.dash-bar-r[hidden] { display: none !important; }
.dash-bar .mt-stamp { font-size: 11px; color: var(--muted-2); white-space: nowrap; }

/* ---------- 星链外壳：标题条 + 画布 ---------- */
.d2-shell {
  margin-top: 18px;
  padding: 0;
}
.d2-head {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  padding: 0 2px 10px;
}
.d2-head-l { display: flex; align-items: center; gap: 9px; min-width: 0; }
.d2-head-title {
  position: relative;
  font-size: 14px;
  font-weight: 680;
  letter-spacing: 0.02em;
  white-space: nowrap;
}
/* 标题下面一条会流动的渐变线，作为"这块是活的"的第一个暗示 */
.d2-head-title::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: -4px;
  height: 2px;
  border-radius: 2px;
  background: linear-gradient(90deg, var(--d2-c0), var(--d2-c3), var(--d2-c1));
}
@keyframes d2TitleFlow { to { background-position: -220% 0; } }
.d2-head-live {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 2px 8px;
  border-radius: 20px;
  font-size: 10.5px;
  color: var(--accent-2);
  background: var(--accent-soft);
  white-space: nowrap;
}
.d2-head-live i {
  width: 5px; height: 5px;
  border-radius: 50%;
  background: var(--accent-2);
  /* v1.25.0：原来是 box-shadow 无限扩散，等于每帧重绘一圈模糊阴影；
     改成静态光晕 + 透明度呼吸，视觉一样「在闪」，但只走合成不重绘。 */
  box-shadow: 0 0 0 3px rgba(14, 165, 164, 0.18);
  animation: d2LivePulse 1.6s ease-in-out infinite;
}
@keyframes d2LivePulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.42; }
}
.d2-head-sub {
  font-size: 11.5px;
  color: var(--muted-2);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.d2-head-r { display: flex; align-items: center; gap: 10px; margin-left: auto; }
.d2-head-r .seg button { font-size: 12px; padding: 5px 12px; }
.d2-head-r .mt-stamp { font-size: 11px; color: var(--muted-2); white-space: nowrap; }

/* ---------- 顶部 KPI 条 ---------- */
.d2-kpis {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 12px;
}
.d2-kpi {
  position: relative;
  overflow: hidden;
  padding: 12px 14px 13px;
  border-radius: 14px;
  border: 1px solid var(--line);
  background: var(--panel);
  box-shadow: var(--shadow-sm);
  transition: transform 0.18s ease, box-shadow 0.18s ease, border-color 0.18s ease;
}
.d2-kpi::before {
  content: "";
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 3px;
  background: var(--d2-c0);
  opacity: 0.85;
}
.d2-kpi:nth-child(2)::before { background: var(--d2-c1); }
.d2-kpi:nth-child(3)::before { background: var(--d2-c2); }
.d2-kpi:nth-child(4)::before { background: var(--d2-c3); }
.d2-kpi:nth-child(5)::before { background: var(--d2-c4); }
.d2-kpi:hover { transform: translateY(-2px); box-shadow: 0 10px 24px rgba(23, 42, 84, 0.1); }
.d2-kpi-label {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 11.5px;
  color: var(--muted);
  margin-bottom: 6px;
}
.d2-kpi-val {
  display: flex;
  align-items: baseline;
  gap: 4px;
  font-variant-numeric: tabular-nums;
}
.d2-kpi-val b {
  font-size: 21px;
  font-weight: 650;
  letter-spacing: -0.02em;
  color: var(--text);
  line-height: 1.1;
}
.d2-kpi-val span { font-size: 11px; color: var(--muted-2); }
.d2-delta {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  font-size: 10.5px;
  padding: 1px 6px;
  border-radius: 20px;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.d2-delta.up { color: var(--ok); background: var(--ok-soft); }
.d2-delta.down { color: var(--danger); background: var(--danger-soft); }
.d2-delta.flat { color: var(--muted-2); background: var(--panel-3); }

/* ---------- 树画布 ---------- */
.d2-stage {
  position: relative;
  padding: 18px 18px 12px;
  border-radius: 18px;
  border: 1px solid var(--line);
  background:
    radial-gradient(720px 260px at 50% -10%, var(--accent-soft), transparent 70%),
    var(--panel);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
}
.d2-canvas { position: relative; }
.d2-links {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  overflow: visible;
}
.d2-links path {
  fill: none;
  stroke: var(--accent);
  stroke-width: 1.4;
  stroke-linecap: round;
  opacity: 0.3;
  stroke-dasharray: 4 6;
}
@keyframes d2Flow { to { stroke-dashoffset: -20; } }

/* 根节点：发光核心 */
.d2-root {
  position: relative;
  width: min(360px, 100%);
  margin: 0 auto 34px;
  padding: 15px 18px 13px;
  border-radius: 18px;
  color: #fff;
  background: var(--grad);
  box-shadow: 0 16px 36px rgba(79, 110, 247, 0.28);
  overflow: hidden;
  isolation: isolate;
}
.d2-root::after {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(220px 120px at 88% -20%, rgba(255, 255, 255, 0.42), transparent 70%);
  pointer-events: none;
}
.d2-orbit { position: absolute; inset: 0; pointer-events: none; z-index: 0; }
.d2-orbit i {
  position: absolute;
  top: -46px; right: -30px;
  width: 148px; height: 148px;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, 0.22);
}
.d2-orbit i:nth-child(2) { width: 96px; height: 96px; top: -20px; right: -6px; border-style: dashed; }
.d2-orbit i::after {
  content: "";
  position: absolute;
  left: 50%; top: -3px;
  width: 6px; height: 6px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.9);
  box-shadow: 0 0 10px rgba(255, 255, 255, 0.8);
  transform-origin: 0 77px;
  animation: d2Spin 9s linear infinite;
}
.d2-orbit i:nth-child(2)::after { transform-origin: 0 51px; animation-duration: 6s; animation-direction: reverse; }
@keyframes d2Spin { to { transform: rotate(360deg); } }

.d2-root-head {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 11px;
  margin-bottom: 7px;
  color: rgba(255, 255, 255, 0.86);
}
.d2-live {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 2px 8px;
  border-radius: 20px;
  background: rgba(255, 255, 255, 0.18);
  font-size: 10.5px;
  letter-spacing: 0.04em;
}
.d2-live i {
  width: 5px; height: 5px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.22);
  animation: d2Pulse 1.8s ease-in-out infinite;
}
@keyframes d2Pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.45; }
}
.d2-root-badge {
  margin-left: auto;
  padding: 2px 8px;
  border-radius: 20px;
  border: 1px solid rgba(255, 255, 255, 0.28);
  font-size: 10.5px;
  white-space: nowrap;
}
.d2-root-label {
  position: relative;
  z-index: 1;
  font-size: 12px;
  color: rgba(255, 255, 255, 0.82);
  margin-bottom: 2px;
}
.d2-root-num {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: baseline;
  gap: 6px;
  font-variant-numeric: tabular-nums;
}
.d2-root-num b {
  font-size: 34px;
  font-weight: 680;
  letter-spacing: -0.03em;
  line-height: 1.12;
  text-shadow: 0 2px 12px rgba(0, 0, 0, 0.12);
}
.d2-root-num span { font-size: 11.5px; color: rgba(255, 255, 255, 0.82); }
.d2-root-hint {
  position: relative;
  z-index: 1;
  margin-top: 4px;
  font-size: 11px;
  color: rgba(255, 255, 255, 0.82);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.d2-spark { position: relative; z-index: 1; display: block; width: 100%; height: 34px; margin-top: 6px; }

/* 分支列 */
.d2-cols {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: repeat(var(--d2-cols, 4), minmax(0, 1fr));
  gap: 14px;
  align-items: start;
}
.d2-col {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-width: 0;
  transition: opacity 0.2s ease, filter 0.2s ease;
}
.d2-col-head {
  position: relative;
  padding: 9px 12px 10px;
  border-radius: 13px;
  border: 1px solid var(--line);
  background: var(--panel-2);
  overflow: hidden;
}
.d2-col-head::before {
  content: "";
  position: absolute;
  left: 0; right: 0; top: 0;
  height: 2.5px;
  background: linear-gradient(90deg, var(--d2-c0), var(--d2-c3), var(--d2-c1));
  opacity: 0.9;
}
.d2-col[data-tone="1"] .d2-col-head::before { background-image: linear-gradient(90deg, var(--d2-c1), var(--d2-c0), var(--d2-c2), var(--d2-c1)); }
.d2-col[data-tone="2"] .d2-col-head::before { background-image: linear-gradient(90deg, var(--d2-c2), var(--d2-c4), var(--d2-c0), var(--d2-c2)); }
.d2-col[data-tone="3"] .d2-col-head::before { background-image: linear-gradient(90deg, var(--d2-c3), var(--d2-c1), var(--d2-c4), var(--d2-c3)); }
.d2-col[data-tone="4"] .d2-col-head::before { background-image: linear-gradient(90deg, var(--d2-c4), var(--d2-c3), var(--d2-c2), var(--d2-c4)); }
@keyframes d2HeadFlow { to { background-position: -220% 0; } }
.d2-col[data-tone="1"] .d2-node-dot { background: var(--d2-c1); }
.d2-col[data-tone="2"] .d2-node-dot { background: var(--d2-c2); }
.d2-col[data-tone="3"] .d2-node-dot { background: var(--d2-c3); }
.d2-col[data-tone="4"] .d2-node-dot { background: var(--d2-c4); }

.d2-col-title {
  display: flex;
  align-items: center;
  gap: 7px;
  min-width: 0;
}
.d2-col-title b {
  font-size: 12.5px;
  font-weight: 650;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.d2-col-dot {
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--d2-c0);
  box-shadow: 0 0 0 3px rgba(79, 110, 247, 0.16);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--d2-c0) 18%, transparent);
  flex: 0 0 auto;
}
.d2-col-meta {
  margin-top: 3px;
  font-size: 10.5px;
  color: var(--muted-2);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.d2-col-num {
  margin-top: 6px;
  display: flex;
  align-items: baseline;
  gap: 4px;
  font-variant-numeric: tabular-nums;
}
.d2-col-num b { font-size: 19px; font-weight: 650; letter-spacing: -0.02em; }
.d2-col-num span { font-size: 10.5px; color: var(--muted-2); }

.d2-col-body { position: relative; display: flex; flex-direction: column; gap: 8px; padding-left: 12px; }
.d2-col-body::before {
  content: "";
  position: absolute;
  left: 3px;
  top: -6px;
  height: var(--rail-h, 100%);
  width: 1.5px;
  border-radius: 2px;
  /* 一小段亮光沿着导轨往下走，表示数据正往这条枝里灌 */
  background-image: linear-gradient(180deg, transparent 0%, var(--d2-c0) 42%, var(--d2-c1) 58%, transparent 100%);
  background-size: 100% 45%;
  background-repeat: no-repeat;
  background-position: 0 45%;
}
.d2-col[data-tone="1"] .d2-col-body::before { background-image: linear-gradient(180deg, transparent 0%, var(--d2-c1) 42%, var(--d2-c0) 58%, transparent 100%); }
.d2-col[data-tone="2"] .d2-col-body::before { background-image: linear-gradient(180deg, transparent 0%, var(--d2-c2) 42%, var(--d2-c4) 58%, transparent 100%); }
.d2-col[data-tone="3"] .d2-col-body::before { background-image: linear-gradient(180deg, transparent 0%, var(--d2-c3) 42%, var(--d2-c1) 58%, transparent 100%); }
.d2-col[data-tone="4"] .d2-col-body::before { background-image: linear-gradient(180deg, transparent 0%, var(--d2-c4) 42%, var(--d2-c3) 58%, transparent 100%); }
@keyframes d2RailFlow {
  from { background-position: 0 -55%; }
  to { background-position: 0 155%; }
}
.d2-node {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 8px;
  padding: 8px 10px 8px 12px;
  border-radius: 11px;
  border: 1px solid var(--line);
  background: var(--panel);
  cursor: default;
  transition: transform 0.16s ease, border-color 0.16s ease, box-shadow 0.16s ease;
  animation: d2NodeIn 0.36s cubic-bezier(0.2, 0.8, 0.2, 1) both;
}
@keyframes d2NodeIn {
  from { opacity: 0; transform: translateY(6px) scale(0.985); }
  to { opacity: 1; transform: none; }
}
/* 按节点序号错峰生长：--i 由 JS 写在节点上，列号 --ci 决定整列的起步 */
.d2-col-body .d2-node { animation-delay: calc(var(--ci, 0) * 90ms + var(--i, 0) * 45ms + 30ms); }
.d2-node[data-clickable="1"] { cursor: pointer; }
.d2-node::before {
  content: "";
  position: absolute;
  left: -9px; top: 50%;
  width: 9px; height: 1px;
  background: var(--line-2);
}
.d2-node-dot {
  position: absolute;
  left: -11px;
  top: 50%;
  width: 5px; height: 5px;
  margin-top: -2.5px;
  border-radius: 50%;
  background: var(--d2-c0);
  box-shadow: 0 0 0 2.5px var(--panel);
}
.d2-node:hover,
.d2-node:focus-visible {
  transform: translateY(-1px);
  border-color: rgba(79, 110, 247, 0.42);
  border-color: color-mix(in srgb, var(--accent) 45%, var(--line));
  box-shadow: 0 8px 18px rgba(23, 42, 84, 0.1);
  outline: none;
}
.d2-node-main { position: relative; z-index: 1; min-width: 0; }
.d2-node-row1 {
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
}
.d2-node-label {
  font-size: 12px;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.d2-node-badge {
  flex: 0 0 auto;
  font-size: 9.5px;
  line-height: 1.5;
  padding: 0 5px;
  border-radius: 20px;
  color: var(--muted);
  background: var(--panel-3);
  white-space: nowrap;
}
.d2-node[data-state="ok"] .d2-node-badge { color: var(--ok); background: var(--ok-soft); }
.d2-node[data-state="warn"] .d2-node-badge { color: var(--warn); background: var(--warn-soft); }
.d2-node[data-state="danger"] .d2-node-badge { color: var(--danger); background: var(--danger-soft); }
.d2-node-row2 {
  display: flex;
  align-items: baseline;
  gap: 5px;
  margin-top: 2px;
  min-width: 0;
  font-variant-numeric: tabular-nums;
}
.d2-node-v { font-size: 14.5px; font-weight: 650; letter-spacing: -0.02em; }
.d2-node-u { font-size: 10px; color: var(--muted-2); }
.d2-node-hint {
  font-size: 10px;
  color: var(--muted-2);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}
.d2-mini { position: relative; z-index: 1; display: block; width: 52px; height: 22px; opacity: 0.9; }
.d2-node-bar {
  display: none;
  margin-top: 5px;
  height: 3px;
  border-radius: 3px;
  background: var(--panel-3);
  overflow: hidden;
}
.d2-node-bar i {
  display: block;
  height: 100%;
  width: 0;
  border-radius: 3px;
  background: var(--accent);
  transition: width 0.5s cubic-bezier(0.2, 0.8, 0.2, 1);
}
.d2-node[data-pct="1"] .d2-node-bar { display: block; }
.d2-node[data-state="warn"] .d2-node-bar i { background: var(--warn); }
.d2-node[data-state="danger"] .d2-node-bar i { background: var(--danger); }
.d2-node[data-state="idle"] { opacity: 0.72; }

/* 悬停某一列时压暗其它列，突出当前枝 */
.d2-stage.is-focus .d2-col { opacity: 0.4; filter: saturate(0.6); }
.d2-stage.is-focus .d2-col.on { opacity: 1; filter: none; }
.d2-stage.is-focus .d2-root { opacity: 0.55; }

/* 今日时段分布 */
.d2-hours {
  position: relative;
  z-index: 1;
  margin-top: 16px;
  padding-top: 12px;
  border-top: 1px dashed var(--line);
}
.d2-hours-head {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 10.5px;
  color: var(--muted-2);
  margin-bottom: 7px;
}
.d2-hours-head b { color: var(--text-2); font-weight: 600; font-size: 11px; }
.d2-hours-head .spacer { flex: 1; }
.d2-hours-bars {
  display: grid;
  grid-template-columns: repeat(24, minmax(0, 1fr));
  align-items: end;
  gap: 3px;
  height: 44px;
}
.d2-hours-bars i {
  display: block;
  border-radius: 3px 3px 1px 1px;
  background: var(--panel-3);
  min-height: 3px;
  transition: height 0.45s cubic-bezier(0.2, 0.8, 0.2, 1), background 0.2s;
}
.d2-hours-bars i.hot { background: var(--accent); }
.d2-hours-bars i.now { background: var(--accent-2); }

/* ---------- 下半区三张卡 ---------- */
.d2-lower {
  display: grid;
  grid-template-columns: 1.1fr 1fr 1fr;
  gap: 16px;
  align-items: start;
}
.d2-card {
  position: relative;
  padding: 14px 16px 12px;
  border-radius: 16px;
  border: 1px solid var(--line);
  background: var(--panel);
  box-shadow: var(--shadow-sm);
  min-width: 0;
}
.d2-card-head {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 10px;
}
.d2-card-head h3 {
  margin: 0;
  font-size: 12.5px;
  font-weight: 650;
  letter-spacing: 0.01em;
}
.d2-card-head .d2-card-sub {
  margin-left: auto;
  font-size: 10px;
  color: var(--muted-2);
  padding: 1px 7px;
  border-radius: 20px;
  background: var(--panel-3);
  white-space: nowrap;
}

/* 排行榜 */
.d2-rank-list { display: flex; flex-direction: column; }
.d2-rank {
  display: grid;
  grid-template-columns: 20px minmax(0, 1fr) auto;
  align-items: center;
  gap: 10px;
  padding: 7px 0;
  border-bottom: 1px solid var(--line);
}
.d2-rank:last-child { border-bottom: none; }
.d2-rank-no {
  width: 20px; height: 20px;
  border-radius: 7px;
  display: grid;
  place-items: center;
  font-size: 10.5px;
  font-weight: 700;
  color: var(--muted);
  background: var(--panel-3);
  font-variant-numeric: tabular-nums;
}
.d2-rank[data-top="1"] .d2-rank-no { color: #a86600; background: linear-gradient(135deg, #ffe9b8, #ffd166); }
.d2-rank[data-top="2"] .d2-rank-no { color: #5f6b7d; background: linear-gradient(135deg, #eef2f7, #d3dbe6); }
.d2-rank[data-top="3"] .d2-rank-no { color: #8a5527; background: linear-gradient(135deg, #ffe2c8, #f2c39b); }
[data-theme="dark"] .d2-rank[data-top="1"] .d2-rank-no { color: #3b2a00; }
[data-theme="dark"] .d2-rank[data-top="2"] .d2-rank-no { color: #22303f; }
[data-theme="dark"] .d2-rank[data-top="3"] .d2-rank-no { color: #3f2410; }
.d2-rank-main { min-width: 0; }
.d2-rank-row1 {
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
}
.d2-rank-name {
  font-size: 12px;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.d2-rank-sub {
  margin-top: 1px;
  font-size: 10px;
  color: var(--muted-2);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.d2-rank-track {
  margin-top: 5px;
  height: 3px;
  border-radius: 3px;
  background: var(--panel-3);
  overflow: hidden;
}
.d2-rank-track i {
  display: block;
  height: 100%;
  width: 0;
  border-radius: 3px;
  background: linear-gradient(90deg, var(--accent), var(--accent-2));
  transition: width 0.6s cubic-bezier(0.2, 0.8, 0.2, 1);
}
.d2-rank-val {
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.d2-rank-val b { font-size: 14.5px; font-weight: 650; letter-spacing: -0.02em; }
.d2-rank-val span { font-size: 9.5px; color: var(--muted-2); margin-left: 2px; }

/* 新注册时间线 */
.d2-tl { position: relative; display: flex; flex-direction: column; }
.d2-tl-item {
  position: relative;
  display: grid;
  grid-template-columns: 40px 12px minmax(0, 1fr) auto;
  align-items: center;
  gap: 8px;
  padding: 6px 0;
}
.d2-tl-time {
  font-size: 10px;
  color: var(--muted-2);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.d2-tl-dot { position: relative; align-self: stretch; display: grid; place-items: center; }
.d2-tl-dot::before {
  content: "";
  position: absolute;
  top: 0; bottom: 0;
  width: 1px;
  background: var(--line);
}
.d2-tl-item:first-child .d2-tl-dot::before { top: 50%; }
.d2-tl-item:last-child .d2-tl-dot::before { bottom: 50%; }
.d2-tl-dot i {
  position: relative;
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--panel-3);
  border: 1.5px solid var(--panel);
  box-shadow: 0 0 0 1.5px var(--line-2);
}
.d2-tl-item[data-new="1"] .d2-tl-dot i {
  background: var(--accent-2);
  box-shadow: 0 0 0 3px var(--accent-soft);
  animation: d2PulseDot 2s ease-out infinite;
}
@keyframes d2PulseDot {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.5; }
}
.d2-tl-main { min-width: 0; }
.d2-tl-main b {
  display: block;
  font-size: 12px;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.d2-tl-main span {
  display: block;
  font-size: 10px;
  color: var(--muted-2);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.d2-tl-tag {
  font-size: 9.5px;
  padding: 1px 6px;
  border-radius: 20px;
  color: var(--muted);
  background: var(--panel-3);
  white-space: nowrap;
}
.d2-tl-item[data-new="1"] .d2-tl-tag { color: var(--accent-2); background: rgba(14, 165, 164, 0.12); }

/* 结构占比：stack / bars 两种形态 */
.d2-stack {
  display: flex;
  height: 12px;
  border-radius: 8px;
  overflow: hidden;
  background: var(--panel-3);
  gap: 2px;
}
.d2-stack i {
  display: block;
  height: 100%;
  width: 0;
  transition: width 0.6s cubic-bezier(0.2, 0.8, 0.2, 1);
}
.d2-legend {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 6px 12px;
  margin-top: 12px;
}
.d2-legend-item {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 11px;
  color: var(--muted);
  min-width: 0;
}
.d2-legend-item i {
  width: 7px; height: 7px;
  border-radius: 2px;
  flex: 0 0 auto;
}
.d2-legend-item span {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.d2-legend-item b {
  margin-left: auto;
  font-size: 11px;
  color: var(--text-2);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.d2-bars { display: flex; flex-direction: column; gap: 11px; }
.d2-bar-top {
  display: flex;
  align-items: baseline;
  gap: 6px;
  font-size: 11px;
  color: var(--muted);
  margin-bottom: 5px;
}
.d2-bar-top b {
  margin-left: auto;
  font-size: 11.5px;
  font-weight: 650;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}
.d2-bar-top b i { font-style: normal; font-size: 9.5px; color: var(--muted-2); font-weight: 400; margin-left: 3px; }
.d2-bar-track {
  height: 5px;
  border-radius: 5px;
  background: var(--panel-3);
  overflow: hidden;
}
.d2-bar-track i {
  display: block;
  height: 100%;
  width: 0;
  border-radius: 5px;
  background: linear-gradient(90deg, var(--accent), var(--accent-2));
  transition: width 0.6s cubic-bezier(0.2, 0.8, 0.2, 1);
}
.d2-bar[data-state="warn"] .d2-bar-track i { background: linear-gradient(90deg, #f0a02a, #f5c451); }
.d2-bar[data-state="danger"] .d2-bar-track i { background: linear-gradient(90deg, #e5484d, #f2777b); }

.d2-empty {
  padding: 22px 0;
  text-align: center;
  font-size: 11.5px;
  color: var(--muted-2);
}

/* ================= 动效层（v1.21.7）：让整棵星链一直在动 ================= */

/* 画布星野：两层错峰呼吸，比整片一起闪更自然 */
.d2-stage::before,
.d2-stage::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-repeat: no-repeat;
}
.d2-stage::before {
  background-image:
    radial-gradient(1.5px 1.5px at 9% 24%, color-mix(in srgb, var(--accent) 70%, transparent), transparent 62%),
    radial-gradient(1.2px 1.2px at 24% 71%, color-mix(in srgb, var(--accent-2) 60%, transparent), transparent 62%),
    radial-gradient(1.4px 1.4px at 41% 13%, color-mix(in srgb, var(--accent) 50%, transparent), transparent 62%),
    radial-gradient(1.1px 1.1px at 58% 82%, color-mix(in srgb, var(--accent) 55%, transparent), transparent 62%),
    radial-gradient(1.3px 1.3px at 73% 31%, color-mix(in srgb, var(--accent-2) 55%, transparent), transparent 62%),
    radial-gradient(1.5px 1.5px at 88% 66%, color-mix(in srgb, var(--accent) 60%, transparent), transparent 62%);
  opacity: .58;
}
.d2-stage::after {
  background-image:
    radial-gradient(1.2px 1.2px at 15% 52%, color-mix(in srgb, var(--accent-2) 50%, transparent), transparent 62%),
    radial-gradient(1.6px 1.6px at 33% 88%, color-mix(in srgb, var(--accent) 55%, transparent), transparent 62%),
    radial-gradient(1.1px 1.1px at 47% 44%, color-mix(in srgb, var(--accent) 45%, transparent), transparent 62%),
    radial-gradient(1.4px 1.4px at 66% 12%, color-mix(in srgb, var(--accent-2) 50%, transparent), transparent 62%),
    radial-gradient(1.2px 1.2px at 81% 48%, color-mix(in srgb, var(--accent) 50%, transparent), transparent 62%),
    radial-gradient(1.5px 1.5px at 95% 28%, color-mix(in srgb, var(--accent-2) 45%, transparent), transparent 62%);
  opacity: .34;
}
@keyframes d2StarA { from { opacity: 0.25; } to { opacity: 0.85; } }
@keyframes d2StarB { from { opacity: 0.7; } to { opacity: 0.18; } }

/* 连线上的光点：快的一颗带辉光，慢的一颗压暗，避免整齐划一 */
.d2-comet { fill: var(--accent-2); opacity: 0.95; }
.d2-comet.is-alt { fill: var(--accent); opacity: 0.5; }
.d2-stage.is-focus .d2-links { opacity: 0.4; }
.d2-links { transition: opacity 0.2s ease; }

/* 根核心：保留静态高光，数据变化时再播放短促反馈 */
.d2-root::before {
  content: "";
  position: absolute;
  inset: -55%;
  z-index: 0;
  background: conic-gradient(from 0deg,
    transparent 0deg 232deg,
    rgba(255, 255, 255, 0.5) 282deg,
    rgba(255, 255, 255, 0.05) 312deg,
    transparent 336deg);
  mix-blend-mode: screen;
  transform: rotate(18deg);
  pointer-events: none;
}
@keyframes d2RootSweep { to { transform: rotate(360deg); } }
@keyframes d2RootBreath {
  0%, 100% { box-shadow: 0 16px 36px rgba(79, 110, 247, 0.26), 0 0 0 0 rgba(124, 147, 255, 0); }
  50% { box-shadow: 0 20px 46px rgba(79, 110, 247, 0.4), 0 0 0 7px rgba(124, 147, 255, 0.07); }
}
/* 数据真的变了才扩散一次的脉冲环 */
.d2-beat {
  position: absolute;
  left: 50%; top: 50%;
  width: 74px; height: 74px;
  margin: -37px 0 0 -37px;
  border-radius: 50%;
  border: 1.5px solid rgba(255, 255, 255, 0.8);
  opacity: 0;
  pointer-events: none;
  z-index: 2;
}
.d2-stage.is-beat .d2-beat { animation: d2Ring 1.25s cubic-bezier(0.2, 0.8, 0.2, 1) 1; }
@keyframes d2Ring {
  from { opacity: 0.85; transform: scale(0.35); }
  to { opacity: 0; transform: scale(4.4); }
}
/* 三层轨道，第三层反向，让核心外面的环永远不是静止的同心圆 */
.d2-orbit i:nth-child(3) {
  width: 188px; height: 188px;
  top: -66px; right: -50px;
  border-color: rgba(255, 255, 255, 0.12);
  border-style: dotted;
}
.d2-orbit i:nth-child(3)::after {
  width: 5px; height: 5px;
  transform-origin: 0 97px;
  animation: d2Spin 14s linear infinite reverse;
}

/* 节点扫光：每张卡按序号错峰，光带从左往右划一次再歇很久，不抢读数 */
.d2-shine {
  position: absolute;
  inset: 0;
  z-index: 0;
  border-radius: inherit;
  overflow: hidden;
  pointer-events: none;
}
.d2-shine::before {
  content: "";
  position: absolute;
  top: -30%; bottom: -30%; left: 0;
  width: 46%;
  background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--d2-c0) 34%, transparent), transparent);
  opacity: 0;
  transform: translateX(-170%) skewX(-16deg);
}
@keyframes d2ShineSweep {
  0%, 76% { opacity: 0; transform: translateX(-170%) skewX(-16deg); }
  80% { opacity: 1; }
  96% { opacity: 0.6; }
  100% { opacity: 0; transform: translateX(330%) skewX(-16deg); }
}

/* 数值刚变过：节点弹一下 + 描边亮一下 */
.d2-node.is-bump { animation: d2NodeBump 0.95s cubic-bezier(0.2, 0.8, 0.2, 1) 1; animation-delay: 0s; }
@keyframes d2NodeBump {
  0% { transform: none; }
  18% {
    transform: translateY(-2px) scale(1.014);
    border-color: color-mix(in srgb, var(--accent) 60%, var(--line));
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 15%, transparent), 0 10px 22px rgba(23, 42, 84, 0.12);
  }
  100% { transform: none; }
}
.d2-node.is-tap { animation: d2NodeTap 0.32s ease; animation-delay: 0s; }
@keyframes d2NodeTap {
  0% { transform: scale(1); }
  45% { transform: scale(0.976); }
  100% { transform: scale(1); }
}
.d2-kpi.is-bump { animation: d2KpiBump 1s cubic-bezier(0.2, 0.8, 0.2, 1) 1; }
@keyframes d2KpiBump {
  0% { transform: none; }
  22% {
    transform: translateY(-3px);
    border-color: color-mix(in srgb, var(--accent) 45%, var(--line));
    box-shadow: 0 12px 26px rgba(23, 42, 84, 0.14);
  }
  100% { transform: none; }
}
.d2-col-head.is-bump { animation: d2HeadBump 1s ease 1; }
@keyframes d2HeadBump {
  0% { transform: none; }
  22% { transform: scale(1.012); }
  100% { transform: none; }
}

/* KPI 卡片：一道更慢的光从左上扫过，和节点的扫光错开节奏 */
.d2-kpi::after {
  content: "";
  position: absolute;
  top: -40%; bottom: -40%; left: 0;
  width: 55%;
  background: linear-gradient(105deg, transparent, rgba(255, 255, 255, 0.5), transparent);
  opacity: 0;
  transform: translateX(-180%) skewX(-18deg);
  pointer-events: none;
}
[data-theme="dark"] .d2-kpi::after,
.d2-kpi::after {
  background: linear-gradient(105deg, transparent, rgba(160, 190, 255, 0.16), transparent);
}
@keyframes d2KpiSweep {
  0%, 82% { opacity: 0; transform: translateX(-180%) skewX(-18deg); }
  86% { opacity: 1; }
  99% { opacity: 0; transform: translateX(300%) skewX(-18deg); }
  100% { opacity: 0; }
}

/* 今日时段柱：柱子上涨带一点涟漪延迟，"现在"这一根持续呼吸 */
.d2-hours-bars i { transition-delay: calc(var(--i, 0) * 12ms); }
.d2-hours-bars i.now { box-shadow: 0 0 8px rgba(240, 160, 42, 0.42); }
@keyframes d2NowBreath {
  0%, 100% { box-shadow: 0 0 0 0 rgba(240, 160, 42, 0); }
  50% { box-shadow: 0 0 10px 1px rgba(240, 160, 42, 0.55); }
}
.d2-hours-bars i.hot { box-shadow: 0 0 8px rgba(79, 110, 247, 0.35); }

/* 下半区入场：排行榜逐行落下，时间线逐条滑入 */
.d2-rank { animation: d2RowIn 0.42s cubic-bezier(0.2, 0.8, 0.2, 1) both; animation-delay: calc(var(--i, 0) * 40ms); }
@keyframes d2RowIn {
  from { opacity: 0; transform: translateX(-6px); }
  to { opacity: 1; transform: none; }
}
.d2-tl-item { animation: d2RowIn 0.42s cubic-bezier(0.2, 0.8, 0.2, 1) both; animation-delay: calc(var(--i, 0) * 55ms); }
.d2-bar { animation: d2RowIn 0.42s cubic-bezier(0.2, 0.8, 0.2, 1) both; animation-delay: calc(var(--i, 0) * 70ms); }

/* 同步失败：整块降饱和，别让"看着在动"骗人 */
.d2.is-stale .d2-stage::before,
.d2.is-stale .d2-stage::after { opacity: 0.08; }
.d2.is-stale .d2-comet { display: none; }
.d2.is-stale .d2-root { filter: saturate(0.45); animation: none; }

/* ---------- 响应式 ---------- */

@media (max-width: 1500px) {
  .d2-kpis { grid-template-columns: repeat(5, minmax(0, 1fr)); }
  .d2-kpi-val b { font-size: 19px; }
}
@media (max-width: 1240px) {
  .d2-lower { grid-template-columns: 1fr 1fr; }
  .d2-lower > .d2-card:first-child { grid-column: 1 / -1; }
}
@media (max-width: 1100px) {
  .d2-kpis { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .d2-cols { gap: 10px; }
  .d2-node-hint { display: none; }
  .d2-mini { display: none; }
}
@media (max-width: 900px) {
  /* 竖屏窄宽度：主干改为自上而下，分支整行堆叠，连线交给左侧导轨 */
  .d2-links { display: none; }
  .d2-root { margin-bottom: 16px; }
  .d2-cols { grid-template-columns: 1fr; gap: 12px; }
  .d2-col {
    padding: 10px 12px 12px;
    border-radius: 14px;
    border: 1px solid var(--line);
    background: var(--panel-2);
  }
  .d2-col-head { border: none; background: none; padding: 0 0 8px; }
  .d2-col-head::before { left: 0; right: auto; bottom: 0; top: auto; height: 2px; width: 26px; }
  .d2-col-num { position: absolute; right: 0; top: 0; margin: 0; }
  .d2-col-body { padding-left: 10px; }
  .d2-col-body::before { display: none; }
  .d2-node::before, .d2-node-dot { display: none; }
  .d2-node-hint { display: inline; }
  .d2-stage.is-focus .d2-col { opacity: 1; filter: none; }
}
/* 平板竖屏：分支两列并排，比单列一长条更好扫 */
@media (max-width: 900px) and (min-width: 640px) {
  .d2-cols { grid-template-columns: 1fr 1fr; align-items: start; }
}
@media (max-width: 720px) {
  .d2-kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
  .d2-lower { grid-template-columns: 1fr; }
  .d2-lower > .d2-card:first-child { grid-column: auto; }
  .d2-stage { padding: 14px 12px 10px; }
  .d2-root { padding: 13px 14px 11px; }
  .d2-root-num b { font-size: 29px; }
  .d2-hours-bars { gap: 2px; height: 38px; }
  .dash-bar-label { display: none; }
  .d2-head-sub { display: none; }
}
@media (max-width: 460px) {
  .d2-kpi { padding: 10px 12px 11px; }
  .d2-kpi-val b { font-size: 18px; }
  .d2-rank-sub, .d2-tl-main span { font-size: 9.5px; }
  .d2-legend { grid-template-columns: 1fr; }
  .d2-head-r .mt-stamp { display: none; }
  .d2-head-title { font-size: 13px; }
}

@media (prefers-reduced-motion: reduce) {
  .d2, .d2-orbit i::after, .d2-live i, .d2-links path, .d2-tl-item[data-new="1"] .d2-tl-dot i { animation: none !important; }
  .d2-node, .d2-rank, .d2-tl-item, .d2-bar { animation: none !important; }
  /* 所有装饰性动效一并停掉：星野、扫光、流光导轨、色条流动、核心呼吸与扫光、光点 */
  .d2-stage::before, .d2-stage::after,
  .d2-root, .d2-root::before, .d2-beat,
  .d2-shine::before, .d2-kpi::after,
  .d2-col-head::before, .d2-col-body::before,
  .d2-head-title::after, .d2-head-live i,
  .d2-hours-bars i.now { animation: none !important; }
  .d2-comet { display: none !important; }
  .d2-node, .d2-kpi, .d2-rank-track i, .d2-bar-track i, .d2-stack i, .d2-node-bar i, .d2-hours-bars i { transition: none !important; }
}
