/* ═══════════════════════════════════════════════════════════════════
   雅思教练 · 微型可视化（Micro Visualizations）
   ───────────────────────────────────────────────────────────────────
   参考图的设计语言里，**每一张卡都带一个微型图表** ——
   进度条、头像堆叠、小表格、迷你柱状图。
   这不是为了装饰，而是因为数字本身不会说话：
     · 77 道真题 → 「哪一册最多」才是信息
     · 28 条错误谱系 → 「哪一类占多数」才是信息
     · 303 个教学单元 → 「哪一册最密」才是信息

   审计（2026-10-28）：首页 9 张卡里 6 张是纯文字堆，
   只有 15 条 CSS 进度条 —— 缺少「数据 → 图形」的转译层。

   这一层提供 5 种微型图表，全部纯 CSS/SVG（零依赖）：
     ① sparkbar   横向条形（分布）
     ② donut      环形占比（构成）
     ③ stackbar   堆叠条（构成 + 总量）
     ④ heatgrid   热力格（矩阵密度）
     ⑤ avatarrow  头像堆叠（群像）
   ═══════════════════════════════════════════════════════════════════ */

/* ═══════════ 1. 横向条形（Sparkbar）═══════════ */
/* 用于：真题各册分布、错误分类分布、精讲各册单元数 */
.spark {
  display: flex; flex-direction: column;
  gap: calc(4 * var(--u));
}
.spark-row {
  display: grid;
  grid-template-columns: calc(58 * var(--u)) minmax(0, 1fr) auto;
  gap: calc(9 * var(--u));
  align-items: center;
}
.spark-k {
  font-size: var(--fs-1);
  color: var(--ink-4);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.spark-t {
  height: calc(6 * var(--u));
  border-radius: 999px;
  background: var(--n-750);
  overflow: hidden;
  position: relative;
}
.spark-f {
  display: block; height: 100%;
  border-radius: 999px;
  background: var(--acc);
  transition: width .5s var(--e-out);
}
/* 次要项用弱化色 —— 让最大值成为焦点 */
.spark-f.dim { background: color-mix(in srgb, var(--acc) 38%, var(--n-700)); }
.spark-v {
  font-size: var(--fs-1);
  color: var(--ink-3);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.spark-row.top .spark-k { color: var(--ink-1); font-weight: 700; }
.spark-row.top .spark-v { color: var(--ink-1); font-weight: 700; }

/* ═══════════ 2. 环形占比（Donut）═══════════ */
/* 用于：写作四维得分构成、词汇四维度占比 */
.donut {
  position: relative;
  width: calc(92 * var(--u));
  height: calc(92 * var(--u));
  flex: 0 0 auto;
}
.donut svg {
  width: 100%; height: 100%;
  transform: rotate(-90deg);
  display: block;
}
.donut circle {
  fill: none;
  stroke-width: calc(9 * var(--u));
  stroke-linecap: butt;
}
.donut .trk { stroke: var(--n-750); }
.donut .seg { transition: stroke-dasharray .6s var(--e-out); }
.donut-c {
  position: absolute; inset: 0;
  display: grid; place-items: center;
  text-align: center;
}
.donut-v {
  font-size: calc(19 * var(--u));
  font-weight: 800; color: var(--ink);
  letter-spacing: calc(-.5 * var(--u));
  line-height: 1.05;
  font-variant-numeric: tabular-nums;
}
.donut-l {
  font-size: var(--fs-1);
  color: var(--ink-4);
  margin-top: calc(2 * var(--u));
  white-space: nowrap;
}
/* 图例 */
.donut-legend {
  display: flex; flex-direction: column;
  gap: calc(4 * var(--u));
  min-width: 0;
  flex: 1 1 auto;
}
.dl-row {
  display: grid;
  grid-template-columns: calc(7 * var(--u)) minmax(0, 1fr) auto;
  gap: calc(7 * var(--u));
  align-items: center;
  font-size: var(--fs-2);
  color: var(--ink-2);
}
.dl-dot {
  width: calc(7 * var(--u)); height: calc(7 * var(--u));
  border-radius: 2px;
}
.dl-v {
  color: var(--ink-1); font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* ═══════════ 3. 堆叠条（Stackbar）═══════════ */
/* 用于：一句话构成（听说读写占比）、层级完成度 */
.stack {
  display: flex;
  height: calc(8 * var(--u));
  border-radius: 999px;
  overflow: hidden;
  background: var(--n-750);
  gap: calc(1.5 * var(--u));
}
.stack > i {
  display: block;
  height: 100%;
  transition: width .5s var(--e-out);
}
.stack > i:first-child { border-radius: 999px 0 0 999px; }
.stack > i:last-child { border-radius: 0 999px 999px 0; }
.stack-legend {
  display: flex; flex-wrap: wrap; gap: calc(9 * var(--u));
  margin-top: calc(8 * var(--u));
}
.sl-item {
  display: inline-flex; align-items: center; gap: calc(5 * var(--u));
  font-size: var(--fs-2); color: var(--ink-3);
}
.sl-dot {
  width: calc(6 * var(--u)); height: calc(6 * var(--u));
  border-radius: 2px;
}
.sl-v { color: var(--ink-1); font-weight: 700; font-variant-numeric: tabular-nums; }

/* ═══════════ 4. 热力格（Heat Grid）═══════════ */
/* 用于：剑 1–13 各册覆盖矩阵（一格 = 一册，一列 = 一个维度） */
.heat {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(calc(11 * var(--u)), 1fr));
  gap: calc(2.5 * var(--u));
}
.heat-c {
  aspect-ratio: 1;
  border-radius: calc(2.5 * var(--u));
  background: var(--n-750);
  position: relative;
}
/* 强度分级 —— 用 accent 的透明度表达量级 */
.heat-c.l1 { background: color-mix(in srgb, var(--acc) 22%, var(--n-750)); }
.heat-c.l2 { background: color-mix(in srgb, var(--acc) 44%, var(--n-750)); }
.heat-c.l3 { background: color-mix(in srgb, var(--acc) 68%, var(--n-750)); }
.heat-c.l4 { background: var(--acc); }
.heat-legend {
  display: flex; align-items: center; gap: calc(4 * var(--u));
  margin-top: calc(7 * var(--u));
  font-size: var(--fs-1); color: var(--ink-4);
}
.heat-legend .heat-c {
  width: calc(9 * var(--u)); height: calc(9 * var(--u));
  aspect-ratio: auto;
}

/* ═══════════ 5. 头像堆叠（Avatar Row）═══════════ */
/* 用于：册数、题型数、角色群像 */
.avatarrow {
  display: flex; align-items: center;
}
.avatarrow .av {
  width: calc(24 * var(--u)); height: calc(24 * var(--u));
  border-radius: 50%;
  margin-left: calc(-7 * var(--u));
  border: 2px solid var(--n-800);
  background: var(--n-700);
  color: var(--ink-1);
  display: grid; place-items: center;
  font-size: calc(9 * var(--u)); font-weight: 800;
}
.avatarrow .av:first-child { margin-left: 0; }
.avatarrow .av.on { background: var(--acc); color: var(--acc-ink); }
.avatarrow .av.more {
  background: var(--n-750); color: var(--ink-3);
}

/* ═══════════ 6. 微型折线（Sparkline）═══════════ */
/* 用于：分数趋势、错误类型变化 */
.sparkline {
  width: 100%; height: calc(34 * var(--u));
  display: block; overflow: visible;
}
.sparkline .sl-area { fill: color-mix(in srgb, var(--acc) 14%, transparent); }
.sparkline .sl-line {
  fill: none; stroke: var(--acc);
  stroke-width: calc(1.8 * var(--u));
  stroke-linecap: round; stroke-linejoin: round;
}
.sparkline .sl-dot { fill: var(--acc); }
.sparkline .sl-grid {
  stroke: var(--glass-line); stroke-width: 1;
  stroke-dasharray: calc(3 * var(--u)) calc(3 * var(--u));
}

/* ═══════════ 7. 数值徽标（Metric Chip）═══════════ */
/* 用于：把一个数字 + 标签做成视觉焦点 */
.metric {
  display: inline-flex; align-items: baseline; gap: calc(6 * var(--u));
  padding: calc(4 * var(--u)) calc(10 * var(--u));
  border-radius: 999px;
  background: var(--n-750);
}
.metric-v {
  font-size: var(--fs-4); font-weight: 800; color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.metric-l { font-size: var(--fs-2); color: var(--ink-3); }
.metric.on { background: var(--acc-soft); }
.metric.on .metric-v { color: var(--acc); }

/* ═══════════ 8. 图形与文字的比例约束 ═══════════ */
/* 参考图的卡：图形约占卡高 40–55%。
   约束图形容器最大高度，避免图表压过内容。 */
.viz {
  margin: calc(11 * var(--u)) 0 calc(3 * var(--u));
}
.viz-cap {
  font-size: var(--fs-1);
  color: var(--ink-4);
  margin-bottom: calc(6 * var(--u));
  display: flex; align-items: center; justify-content: space-between;
  gap: calc(8 * var(--u));
}
.viz-cap b { color: var(--ink-3); font-weight: 700; }

/* 图表与文字并排 */
.viz-row {
  display: flex; align-items: center; gap: calc(14 * var(--u));
}
.viz-row > .donut { flex: 0 0 auto; }

/* ═══════════ 9. 响应式 ═══════════ */
@media (max-width: 700px) {
  .viz-row { flex-direction: column; align-items: stretch; }
  .donut { margin: 0 auto; }
}

/* ═══════════ 10. 修正：窄容器下的溢出与换行 ═══════════ */
/* 条形图：标签列太窄（58px）导致"剑9A"被截，数值列被挤。
   改成「标签自适应 + 数值定宽」，并允许标签省略。 */
.spark-row {
  grid-template-columns: minmax(calc(38 * var(--u)), max-content) minmax(0, 1fr) auto;
  gap: calc(8 * var(--u));
}
.spark-k {
  max-width: calc(72 * var(--u));
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.spark-v {
  min-width: calc(34 * var(--u));
  text-align: right;
}

/* 环形图图例：名称可能很长（"连贯与衔接 Coherence & Cohesion"），
   两行显示会挤爆 —— 改为单行省略 + 悬停完整提示。 */
.dl-row {
  grid-template-columns: calc(7 * var(--u)) minmax(0, 1fr) auto;
  gap: calc(6 * var(--u));
}
.dl-row > span:nth-child(2) {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  min-width: 0;
}
.donut-legend { min-width: 0; }

/* 图表卡：图例与环形的比例 —— 窄卡里环要小一点 */
@media (max-width: 1400px) {
  .kpi-band { grid-template-columns: 1.85fr .88fr .88fr 1.35fr; }
  .donut { width: calc(78 * var(--u)); height: calc(78 * var(--u)); }
}
@media (max-width: 1180px) {
  .kpi-band { grid-template-columns: 1.6fr .9fr .9fr; }
  .kpi-band .kpi:nth-child(4) { grid-column: span 3; }
  /* 第四张卡变宽后，图例可以横排 */
  .kpi-band .kpi:nth-child(4) .viz-row { align-items: flex-start; }
  .kpi-band .kpi:nth-child(4) .donut-legend {
    display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: calc(3 * var(--u)) calc(12 * var(--u));
  }
}

/* 热力格：格数多时保持方形且不撑破 */
.heat { grid-template-columns: repeat(auto-fit, minmax(min(calc(13 * var(--u)), 1fr)); }
