/* 指标图表的样式。和 metrics.js 配套，比赛页与球员页共用。
 *
 * 类名一律 `mx-` 前缀，避免和两个页面已有的样式撞。
 *
 * ## 动效的两条规矩（都是 person.html 踩过的）
 *
 * 1. **内容默认可见。** 只有 `html.mx-can-anim` 存在（= JS 确认观察器可用）
 *    才把元素藏起来等入场。反过来写（默认隐藏靠 JS 点亮）在观察器不触发时
 *    会留下永久空白，而且控制台一声不响。
 * 2. **`prefers-reduced-motion` 交给 CSS**，不在 JS 里查一次 —— JS 只反映
 *    渲染那一刻的设置，用户之后改系统偏好就失效了。
 */

/* ── 容器 ── */
.mx-chart{margin-top:4px}
.mx-pair{display:grid;grid-template-columns:1fr 1fr;gap:clamp(18px,3vw,40px)}
@media(max-width:760px){.mx-pair{grid-template-columns:1fr;gap:26px}}
.mx-col{min-width:0}
.mx-h{display:flex;align-items:center;gap:7px;margin:0 0 12px;
  font:750 12.5px/1.2 var(--sans);color:var(--ink)}
.mx-h i{width:9px;height:9px;border-radius:2px;flex:none}
.mx-empty{font-size:12px;color:var(--ink-3);padding:24px 0;margin:0}
.mx-sum{margin:10px 0 0;font-size:11.5px;color:var(--ink-3);
  font-variant-numeric:tabular-nums}
.mx-sum b,.mx-sum .mx-count{font-weight:750;color:var(--ink-2)}

/* ── ① 球门六分区 ──
   **铺满整列**：两列布局下每列约 580px，原来限宽 340px 会让右侧空一大片。
   球门本身是 3:1 的宽扁形，铺满之后格子里的数字才够大。 */
.mx-gm{width:100%;display:block}
/* 门框：画在格子之后（见 metrics.js 里的说明），并且要压得住格子的浅色描边，
   所以 3px 且不透明 —— 2.5px 配 .55 透明度时和格线混在一起，看不出是门框。 */
.mx-frame{fill:none;stroke:var(--plum);stroke-width:3;opacity:.72;
  vector-effect:non-scaling-stroke;stroke-linecap:square}
.mx-cellnum{font:750 .52px var(--sans);fill:var(--ink);
  font-variant-numeric:tabular-nums}
.mx-miss{font:700 .42px var(--sans);fill:var(--ink-3);
  font-variant-numeric:tabular-nums}
/* 偏出的方向线：**用 non-scaling-stroke**，否则线宽会被 viewBox 放大约 80 倍。
   箭头本身用 marker 太重，一条带端点的短线就够表达「往这个方向飞了」。 */
.mx-missarrow{stroke:var(--ink-4);stroke-width:1.5;stroke-linecap:round;
  vector-effect:non-scaling-stroke}

/* ── ② 双环 ──
   环和图例并排，图例吃掉剩下的宽度（`flex:1`）—— 否则两者都靠左挤着、
   右侧空一片。 */
.mx-rings{display:flex;align-items:center;gap:clamp(14px,2.5vw,26px);flex-wrap:wrap}
.mx-ring{width:clamp(120px,13vw,152px);height:clamp(120px,13vw,152px);flex:none}
.mx-big{font:800 26px var(--sans);fill:var(--ink);letter-spacing:-1px;
  font-variant-numeric:tabular-nums}
.mx-cap{font:650 9px var(--sans);fill:var(--ink-3);letter-spacing:.04em}
.mx-key{display:flex;flex-direction:column;gap:11px;min-width:0;flex:1}
/* 两组图例之间画一条细线分开：外环和内环讲的是两件事（部位 / 方式），
   挤成一列会读成一个六项的列表。 */
.mx-keyrow{display:flex;flex-direction:column;gap:4px}
.mx-keyrow+.mx-keyrow{padding-top:10px;border-top:1px solid var(--line-2)}
.mx-keyrow>span{display:flex;align-items:center;gap:6px;font-size:11.5px;
  color:var(--ink-2);white-space:nowrap}
.mx-keyrow i{width:9px;height:9px;border-radius:2px;flex:none}
.mx-keyrow b{margin-left:auto;padding-left:8px;font-weight:750;color:var(--ink);
  font-variant-numeric:tabular-nums}

/* ── ③ 三区 ──
   球场是竖的，所以不铺满整列宽（会变成一个巨大的竖条）。
   **左对齐，不要 `margin:0 auto`** —— 居中会让两列的球场各自跑到列中心，
   两张图对不齐（实测主队那张跑到整节中央、客队被推到右边）。
   左对齐之后两列的起点一致，横向比较才成立。 */
/* 整个球场（68 x 113 含顶部箭头留白），竖向，比例约 1:1.66。
   **居中，不左对齐** —— 它自身对称，没有可对齐的轴。 */
.mx-pitch3{width:100%;max-width:236px;display:block;margin-inline:auto}
/* 球场白线：**一个颜色、一个线宽、non-scaling-stroke**。
   缺了最后一项，线宽会随图的缩放变化 —— 那正是之前「有粗有细」的来源。 */
.mx-pline{fill:none;stroke:#fff;stroke-width:1.4;
  vector-effect:non-scaling-stroke}
.mx-pspot{fill:#fff;stroke:none}
/* 球门那两段画粗一档：它是球场上唯一的实体 */
.mx-pgoal{stroke:#fff;stroke-width:3;stroke-linecap:round;
  vector-effect:non-scaling-stroke}
/* 三区色块：数据层，画在白线之下 */
.mx-zband{stroke:none}
/* 三区的文字压在球场线之上，所以**描一圈底色再画字**
   （`paint-order:stroke` 把描边放到文字下面）—— 中圈和禁区线正好穿过
   中场那一区的中心，不描边的话数字会被白线割开。 */
.mx-zname,.mx-zwon,.mx-zpc{paint-order:stroke;stroke:#fbfafc;
  stroke-linejoin:round;vector-effect:non-scaling-stroke}
.mx-zname{font:650 4.6px var(--sans);fill:var(--ink-2);stroke-width:2.6}
.mx-zwon{font:800 10px var(--sans);fill:var(--ink);
  font-variant-numeric:tabular-nums;stroke-width:3.2}
/* 每区占比：省得读者自己算三个数的比例 */
.mx-zpc{font:650 4.2px var(--sans);fill:var(--ink-3);
  font-variant-numeric:tabular-nums;stroke-width:2.4}
/* 进攻方向箭头：指向对方球门那一头 */
.mx-arrow{fill:none;stroke:var(--ink-4);stroke-width:1.4;stroke-linecap:round;
  stroke-linejoin:round;vector-effect:non-scaling-stroke}

/* ── ④ 绝佳机会 ──
   **不画漏斗。** created 和 scored/missed 不是同一口径（见 metrics.js 的说明），
   收口的漏斗会把「创造 2、打进 3」显示得像数据出错。
   现在：转化率大字 + 进/失一条分段条 + 两张独立小卡。 */
.mx-bc{display:flex;flex-direction:column;gap:13px}
.mx-bchero{display:flex;flex-direction:column;gap:2px}
.mx-bchero strong{font:800 clamp(26px,3.4vw,34px)/1 var(--sans);color:var(--ink);
  letter-spacing:-1.4px;font-variant-numeric:tabular-nums}
.mx-bchero strong i{font-style:normal;font-size:.5em;margin-left:2px;
  color:var(--ink-3)}
/* **`>` 是必需的。** 写成后代选择器时，这条会把 <strong> 里面的
   .mx-count span 也缩到 11.5px —— 于是转化率的数字比说明文字还小，
   只有 % 号是大的（实测容器 34px、数字 11.5px）。 */
.mx-bchero>span{font-size:11.5px;color:var(--ink-3)}
/* 进/失分段条：两段宽度按各自占比，加起来是他面对的绝佳机会总数 */
.mx-bcbar{display:flex;height:24px;border-radius:5px;overflow:hidden;
  background:var(--paper-2)}
.mx-seg{display:grid;place-items:center;min-width:0}
.mx-seg span{font:800 12.5px var(--sans);font-variant-numeric:tabular-nums}
/* 字色跟着段的深浅走：浅色段用深字。实测白字在 opacity .32 的段上
   只有 43/通道对比度（深色段 89），队色更浅时基本看不见。 */
.mx-seg[data-ink="light"] span{color:#fff}
.mx-seg[data-ink="dark"] span{color:var(--ink);opacity:.85}
.mx-bckey{display:flex;gap:14px;flex-wrap:wrap;font-size:11.5px;color:var(--ink-2)}
.mx-bckey span{display:inline-flex;align-items:center;gap:5px}
.mx-bckey i{width:9px;height:9px;border-radius:2px;flex:none}
.mx-bckey .mx-count{font-weight:750;color:var(--ink)}
/* 独立计数的小卡：和上面那条**不并排比较**，因为口径不同 */
.mx-bccards{display:grid;grid-template-columns:repeat(auto-fit,minmax(112px,1fr));
  gap:1px;background:var(--line);border:1px solid var(--line);border-radius:5px;
  overflow:hidden}
.mx-bccard{background:#fff;padding:9px 11px;display:flex;flex-direction:column;
  gap:2px}
.mx-bccard b{font:800 19px/1 var(--sans);color:var(--ink);
  font-variant-numeric:tabular-nums}
.mx-bccard>span{font-size:10.5px;color:var(--ink-3);line-height:1.3}

/* ── ⑤ 罗盘 ── */
/* 罗盘做大：原来 150px 在约 580px 宽的列里显得很小，方向标签也挤。
   跟着列宽走，上限 210px。 */
/* 画布现在是横向更宽的矩形（左右各留 44 给标签），所以按**高度**定尺寸、
   宽度交给 viewBox 的比例，否则圆会被压扁。 */
.mx-rose{height:clamp(150px,20vw,210px);width:auto;max-width:100%;
  display:block;margin-inline:auto}
.mx-dir{font:650 8.5px var(--sans);fill:var(--ink-3)}
.mx-pct{font:800 17px var(--sans);fill:var(--ink);
  font-variant-numeric:tabular-nums}

/* ── ⑥ 门将 ── */
.mx-gk{display:flex;flex-direction:column;gap:14px}
/* 同上：必须用 `>`，否则 <strong> 里的计数 span 被一起缩小 */
/* **格子不拉伸,也不画边框。**
   两处都改了：
   1. `auto-fill` 配 `1fr` 会把格子摊满整行 —— 8 个格子分到 7 列时最后一个
      落单、末尾空出一整格,而视口越宽每格被拉得越长。改成 `auto-fit` 配
      固定宽度,格子保持自己的尺寸,行末多出来的宽度留白。
   2. `gap:1px` 配线色背景就是在画单元格边框 —— 这和我在数字墙上改掉的
      是同一个做法（那次用户指出「这就是一张表」）。改成留白分隔。 */

/* ── 原始数据表 ── */
.mx-table{border-top:1px solid var(--line)}
.mx-trow{display:grid;grid-template-columns:1fr auto;gap:12px;padding:7px 10px;
  font-size:12.5px;align-items:baseline}
.mx-trow.mx-tpair{grid-template-columns:3.6em 1fr 3.6em}
.mx-trow:nth-child(even){background:var(--paper-2)}
.mx-tk{color:var(--ink-2);font-size:12px}
.mx-trow.mx-tpair .mx-tk{text-align:center}
.mx-trow b{font-weight:750;color:var(--ink);font-variant-numeric:tabular-nums}
.mx-trow.mx-tpair b:last-child{text-align:right}

/* ══ 动效 ══
   默认全部可见（没有 .mx-can-anim 时这一段不生效）。 */
.mx-can-anim .mx-chart .mx-cell,
.mx-can-anim .mx-chart .mx-zone,
.mx-can-anim .mx-chart .mx-wedge,
.mx-can-anim .mx-chart /* 格子/区块：淡入 + 轻微上移，按 --d 依次 */
.mx-can-anim .mx-chart.mx-in .mx-cell,
.mx-can-anim .mx-chart.mx-in .mx-zone{
  animation:mx-rise .44s cubic-bezier(.22,.7,.24,1) var(--d,0ms) both}
/* 罗盘扇形：从中心长出来 */
.mx-can-anim .mx-chart.mx-in .mx-wedge{
  animation:mx-grow .5s cubic-bezier(.22,.7,.24,1) var(--d,0ms) both;
  transform-origin:center}
/* 门将小格：逐个淡入 */
.mx-can-anim .mx-chart.mx-in /* 漏斗：条子从左展开，所以要分两层 —— 行本身淡入，里面的条宽度动画 */
/* 绝佳机会：分段条整条淡入 + 小卡依次淡入 */
.mx-can-anim .mx-chart.mx-in .mx-bcbar{
  animation:mx-rise .42s ease-out both}
.mx-can-anim .mx-chart.mx-in .mx-bccard{
  animation:mx-rise .38s ease-out var(--d,0ms) both}
/* 圆环：描边从 0 画到满 */
.mx-can-anim .mx-chart .mx-arc{stroke-dashoffset:var(--len)}
.mx-can-anim .mx-chart.mx-in .mx-arc{
  animation:mx-draw .7s cubic-bezier(.3,.7,.3,1) var(--d,0ms) both}

/* 末帧的不透明度读 `--o`（默认 1），**不写死 1**。
   `animation-fill-mode:both` 会让末帧值一直留在元素上，而动画填充的优先级
   高于普通声明 —— 写死 1 的话，任何想把这一行压暗的规则都会被它盖掉
   （实测 `.mx-rfaint{opacity:.55}` 完全不生效，计算值仍是 1）。 */
@keyframes mx-rise{from{opacity:0;transform:translateY(7px)}
  to{opacity:var(--o,1);transform:none}}
/* 横向生长：漏斗的条用它 —— 表达「筛下去」的过程 */
@keyframes mx-wipe{from{transform:scaleX(0)}to{transform:none}}
@keyframes mx-grow{from{opacity:0;transform:scale(.55)}
  to{opacity:1;transform:none}}
@keyframes mx-draw{from{stroke-dashoffset:var(--len)}to{stroke-dashoffset:0}}

/* **动效偏好交给 CSS 判断。** 关掉动效时一切保持终态可见 —— 不是隐藏，
   是直接显示结果。 */
@media(prefers-reduced-motion:reduce){
  .mx-can-anim .mx-chart .mx-cell,
  .mx-can-anim .mx-chart .mx-zone,
  .mx-can-anim .mx-chart .mx-wedge,
  .mx-can-anim .mx-chart   .mx-can-anim .mx-chart .mx-arc{stroke-dashoffset:0;animation:none}
}

/* ══ ⑥ 联赛雷达 ══
   轴的刻度是本赛季全联赛百分位（见 metrics.js）。网格 4 圈，
   50 那圈加重 —— 它是联赛中位数，读者最常用的参照线。 */
/* **居中，不左对齐。** 这三张图（雷达、方向盘、三段色块）都是自身对称的
   图形，没有可以对齐的基线或轴 —— 左对齐时右边空出一大片，读起来是
   "飘在一端"而不是"对齐"。雷达更明显：它的视觉左边缘是标签文字而不是
   多边形，所以连"和标题左对齐"都没做到。 */
/* 画布宽度跟着标签走（`--vbw`，见 metrics.js 雷达的 draw），上限按同一比例放大：
   圆在有地方的时候保持原来的大小，标签长了只让整张图变宽，不让圆变小。 */
.mx-radarfig{width:100%;max-width:calc(var(--vbw,230) * 280px / 230);display:block;margin-inline:auto}
.mx-rgrid{fill:none;stroke:var(--line);stroke-width:1;
  vector-effect:non-scaling-stroke}
.mx-rmid{stroke:#c3bacd}
.mx-rspoke{stroke:var(--line);stroke-width:1;vector-effect:non-scaling-stroke}
.mx-rarea{fill-opacity:.2;stroke-width:2;vector-effect:non-scaling-stroke}
.mx-rdot{stroke:#fff;stroke-width:1.2;vector-effect:non-scaling-stroke}
.mx-rlab{font:650 8.5px var(--sans);fill:var(--ink-3)}

/* ══ ⑦ 成功率对比 ══
   条长 = 成功率，条粗 = 尝试量（开方分档，3~11px）。
   粗细承载"这项试了多少次" —— 试 2 次的 100% 不该和试 200 次的 85% 一样重。 */
.mx-ratesfig{display:flex;flex-direction:column;gap:7px}
/* **百分比和分数各占一格。** 原来两者挤在同一个 5.4em 的格子里，
   而分数的宽度不一（`2/2` 和 `433/511` 差一倍多），于是百分比的起点
   跟着分数漂 —— 24 行的百分比没有一条竖线对齐，整块看起来是乱的。
   现在两列各自定宽、各自右对齐，加上等宽数字，上下必然成列。 */
.mx-rate{display:grid;
  grid-template-columns:7.6em minmax(60px,1fr) 2.9em 3.6em;
  align-items:center;gap:9px;transition:opacity .2s}
.mx-rname{font-size:11px;color:var(--ink-2);line-height:1.25;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* **所有条一样粗（7px）。** 原来按尝试量给 3~11px，24 行参差不齐，
   而粗细是最弱的比较通道、还在重复右边已经写出来的分数。 */
.mx-rtrack{background:var(--paper-2);border-radius:999px;overflow:hidden;
  height:7px;display:block}
.mx-rtrack i{display:block;height:100%;border-radius:999px}
.mx-rnum{display:flex;align-items:baseline;gap:5px;justify-content:flex-end;
  font-variant-numeric:tabular-nums}
.mx-rnum b{font:800 12.5px var(--sans);color:var(--ink)}
.mx-rnum em{font-style:normal;font-size:10px;color:var(--ink-3)}

/* ══ ⑧ 分组数字墙 ══
   剩下那些不成图的指标。按语义分组，组内是大数字 + 小标签的格子，
   两队同组并排、同指标上下对齐。差距 ≥25% 的一侧用队色加重。 */
.mx-wall{display:flex;flex-direction:column;gap:26px}
/* 组标题：一条细线 + 小字，**不用大写字母加粗** —— 七个组标题都那样会
   在页面上排成七道横杠，比它们下面的内容还抢。 */
.mx-wgroup h5{margin:0 0 10px;font:800 11.5px var(--sans);letter-spacing:.06em;
  color:var(--plum);display:flex;align-items:center;gap:9px}
.mx-wgroup h5::after{content:"";flex:1;height:1px;background:var(--line)}

/* ── 角力条 ──
   **没有边框。** 原来靠 `gap:1px` + 线色背景画格子，那就是在画表格。
   现在靠留白分行，靠条本身传达信息。

   两列铺开：89 个指标排成一列太长，而每行的内容（数字 条 数字 标签）
   本身不宽。 */
/* 列数自适应。**英文的下限要大得多** —— 英文标签最长 206px，
   310px 的列放不下「标签 + 条 + 数字」三样，于是标签被截。 */
.mx-duels{display:grid;grid-template-columns:repeat(auto-fit,minmax(310px,1fr));
  gap:2px 30px}
html[lang="en"] .mx-duels{grid-template-columns:repeat(auto-fit,minmax(430px,1fr))}
/* 一行：左数字、角力条、右数字、标签。
   **标签在最后一列**，不在中间 —— 夹在两个数字之间时它只有 ~5em 可用，
   中文标签会被挤成三四行竖排（实测「禁区内拦截」排成了四行）。 */
.mx-duel{display:grid;grid-template-columns:2.7em minmax(60px,1fr) 2.7em 8.4em;
  align-items:center;gap:8px;padding:5px 0}
.mx-duel b{font:800 14px/1 var(--sans);color:var(--ink-2);
  font-variant-numeric:tabular-nums}
.mx-da{text-align:right}
.mx-db{text-align:left}
/* 领先那一侧的数字加重一档。颜色由行内样式给（队色）。 */
.mx-duel b.mx-lead{font-size:15.5px}
.mx-dlab{display:flex;align-items:center;gap:6px;font-size:11px;
  color:var(--ink-3);min-width:0}
.mx-dlab>span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mx-dlab .mx-ico{width:14px;height:14px}
/* 条本身：**两条从中线往两侧长**，各自按两者中的大值归一。
   不是按比例分割一条 —— 那种编码对"接近 1 的比值"不敏感，
   541 比 720 和 13 比 12 会长得一样（量过）。

   **两侧各一条半宽轨道（`<s>`），条在轨道里按百分比伸展。**
   我一开始直接给两个 `<i>` 设 `width:%` + `max-width:50%`，结果所有条都被
   钉死在同一个宽度（实测全是 75px，和数值无关）—— 百分比在弹性行里按整行
   解析，再被 max-width 截断，信息就全丢了。轨道把「一半」这件事交给布局，
   百分比于是按自己那一半解析。 */
.mx-dtug{display:flex;height:8px;align-items:stretch}
/* 轨道：各占一半，所以中线永远在正中 —— 中线会漂的话，
   两边的长度就没有共同基准了。`<s>` 只是个无语义的行内容器，
   这里把它的删除线去掉。 */
.mx-dside{flex:1 1 50%;min-width:0;display:flex;text-decoration:none}
.mx-dleft{justify-content:flex-end}
.mx-dside>i{display:block;height:100%;border-radius:3px;min-width:2px}
/* 中线：一道细缝，读者的眼睛靠它做基准 */
.mx-dtug::before{content:"";order:1;width:1px;background:var(--line);flex:none;
  margin:-2px 3px;align-self:stretch}
.mx-dleft{order:0}
.mx-dside:not(.mx-dleft){order:2}
/* 两边都是 0 */
.mx-dnil .mx-dtug{opacity:.3}
.mx-dnil b{color:var(--ink-3);font-weight:700}
@media (max-width:640px){
  /* **单栏时列也要能缩到 0。** `1fr` 在这里不够 —— 行内子元素的固有宽度
     （9.2em 的标签 + 数字）会把列顶开,于是行比容器宽、整页能左右拖
     （实测 430px 视口下行宽 430 而容器 398,溢出 32px）。
     `minmax(0,1fr)` 才允许列收缩到内容以下。 */
  /* **两个选择器都要写。** `html[lang="en"] .mx-duels` 声明
     `minmax(430px,1fr)`（为英文长标签留的宽度）,它的特异性压过裸
     `.mx-duels` —— 于是窄屏下父容器仍然给出一个 430px 的列,而容器只有
     398px,行就溢出 32px、整页能左右拖。
     **这个错我在同一次改动里犯了两遍**:行的英文覆盖写了,父容器的漏了。
     凡是用 `html[lang=]` 加过宽度的地方,窄屏都要成对覆盖。 */
  .mx-duels,
  html[lang="en"] .mx-duels{grid-template-columns:minmax(0,1fr);gap:0}
  .mx-duel{grid-template-columns:2.4em minmax(40px,1fr) 2.4em 7em;gap:6px}
  .mx-dlab{font-size:10.5px}
  .mx-dlab>span{min-width:0}
}
.mx-can-anim .mx-chart .mx-duel{opacity:0}
/* 门将那两块的动效要和其余图表同一套节奏 —— 拆出来的新元素
   （漏斗的条、分区组）原本没有规则,于是它们直接出现而别的缓入,
   同一页两种节奏。 */
.mx-can-anim .mx-chart .mx-gkstep{opacity:0}
.mx-can-anim .mx-chart .mx-gkzone{opacity:0}
/* 漏斗的条从左长出来 —— 它表达的是"筛下去"的过程,横向生长最贴切 */
.mx-can-anim .mx-chart .mx-gkstep i{transform:scaleX(0);transform-origin:left}
/* 球门整体轻微放大入场,和射门落点图那张一致 */
.mx-can-anim .mx-chart .mx-gkgoal2{opacity:0}
.mx-can-anim .mx-chart.mx-in .mx-rate{
  animation:mx-rise .34s ease-out var(--d,0ms) both}
.mx-can-anim .mx-chart.mx-in .mx-gkstep{
  animation:mx-rise .34s ease-out var(--d,0ms) both}
.mx-can-anim .mx-chart.mx-in .mx-gkstep:nth-child(1){--d:0ms}
.mx-can-anim .mx-chart.mx-in .mx-gkstep:nth-child(2){--d:90ms}
.mx-can-anim .mx-chart.mx-in .mx-gkstep:nth-child(3){--d:180ms}
.mx-can-anim .mx-chart.mx-in .mx-gkstep:nth-child(4){--d:270ms}
.mx-can-anim .mx-chart.mx-in .mx-gkstep i{
  animation:mx-wipe .5s cubic-bezier(.22,.7,.2,1) var(--d,0ms) both}
.mx-can-anim .mx-chart.mx-in .mx-gkzone{
  animation:mx-rise .34s ease-out var(--d,0ms) both}
.mx-can-anim .mx-chart.mx-in .mx-gkgoal2{
  animation:mx-grow .46s cubic-bezier(.22,.7,.2,1) 60ms both}
.mx-can-anim .mx-chart.mx-in .mx-duel{
  animation:mx-rise .3s ease-out var(--d,0ms) both}
/* 雷达：多边形从中心长出来 */
.mx-can-anim .mx-chart .mx-rarea,
.mx-can-anim .mx-chart .mx-rdot{opacity:0}
.mx-can-anim .mx-chart.mx-in .mx-rarea{
  animation:mx-grow .62s cubic-bezier(.22,.7,.24,1) both;transform-origin:center}
.mx-can-anim .mx-chart.mx-in .mx-rdot{
  animation:mx-rise .4s ease-out .3s both}
/* 成功率条从 0 展开 */
.mx-can-anim .mx-chart .mx-rtrack i{transform:scaleX(0);transform-origin:left}
.mx-can-anim .mx-chart.mx-in .mx-rtrack i{
  animation:mx-stretch .58s cubic-bezier(.22,.7,.24,1) var(--d,0ms) both}
@keyframes mx-stretch{from{transform:scaleX(0)}to{transform:scaleX(1)}}

@media(prefers-reduced-motion:reduce){
  .mx-can-anim .mx-chart .mx-rate,
  .mx-can-anim .mx-chart .mx-duel,
  .mx-can-anim .mx-chart .mx-rarea,
  .mx-can-anim .mx-chart .mx-rdot,
  /* 门将那两块拆出来的新元素也要在这里 —— 漏掉就等于对晕动症用户
     强推动画,而这条媒体查询存在的全部意义就是不推。 */
  .mx-can-anim .mx-chart .mx-gkstep,
  .mx-can-anim .mx-chart .mx-gkzone,
  .mx-can-anim .mx-chart .mx-gkgoal2{opacity:1;animation:none;transform:none}
  .mx-can-anim .mx-chart .mx-rtrack i,
  .mx-can-anim .mx-chart .mx-gkstep i{transform:none;animation:none}
}

/* ── 差距条 ──
   一行一项指标：左边名字、中间一条联赛分布轴、右边分位差。
   **两支队是同一根轴上的两个点**，所以"差多少"是一段可以直接看长度的距离，
   不需要在两张并排的图之间来回扫。 */
.mx-spread{display:flex;flex-direction:column}
.mx-sphead{display:grid;grid-template-columns:8.2em 1fr 3.4em;gap:14px;
  align-items:end;padding:0 0 9px;font-size:10.5px;font-weight:700;
  letter-spacing:.04em;color:var(--ink-3)}
/* 刻度说明三等分，和下面轨道的 0/50/100 对齐 */
.mx-spscale{display:flex;justify-content:space-between}
.mx-spscale em{font-style:normal;opacity:.8}
.mx-spgaph{text-align:right}
.mx-sprow{display:grid;grid-template-columns:8.2em 1fr 3.4em;gap:14px;
  align-items:center;padding:7px 0;border-top:1px solid var(--line-2)}
.mx-spname{font-size:12px;font-weight:600;color:var(--ink);line-height:1.25}
/* 轨道：整条是联赛的 0~100 分位。高度给足，两个点各带一个数字。 */
.mx-sptrack{position:relative;height:26px}
/* 联赛分布的底：一条贯通的浅线 + 中间 25~75 分位那段加深。
   加深那段是"联赛大多数队落在哪"，读者据此判断一个点是常规还是极端。 */
.mx-sptrack::before{content:"";position:absolute;left:0;right:0;top:50%;
  height:3px;margin-top:-1.5px;background:var(--line);border-radius:2px}
/* 25~75 分位那段。**要比底线明显一档**，否则读者看不出"大多数队在这儿"
   —— 原来用 paper-2 配 line 的描边，两者和底线几乎同色，等于没画。 */
.mx-spiqr{position:absolute;left:25%;width:50%;top:50%;height:9px;
  margin-top:-4.5px;background:#e8e2ec;border-radius:2px}
.mx-spmid{position:absolute;left:50%;top:50%;width:1px;height:15px;
  margin:-7.5px 0 0 -.5px;background:var(--ink-3);opacity:.45}
/* 两点之间那一段：**这就是"差距"本身**，颜色属于做得多的那一边。 */
/* **必须在分布区之上。** 分布区是后面的背景，差距线是主角 ——
   不给 z-index 的话，后写的分布区会盖住连线中段（实测中间一段被压掉）。
   不透明度也从 .55 提到 .8：它是这张图要读的那条线。 */
.mx-spgap{position:absolute;top:50%;height:3px;margin-top:-1.5px;
  border-radius:2px;opacity:.8;z-index:1}
.mx-spdot{z-index:2}
/* 点上直接写数字 —— 悬停才看得到的信息等于没有，而这两个数是读者最想要的。
   数字挂在点的上方，两队一上一下错开，挨得近时不会叠在一起。 */
/* 两队各一个点，**点上直接写数字** —— 只有悬停才看得到的信息等于没有，
   而这两个数正是读者最想要的。数字挂在点外侧，主队在上、客队在下，
   两点挨得近时也不会叠。 */
.mx-spdot{position:absolute;top:50%;width:9px;height:9px;margin:-4.5px 0 0 -4.5px;
  border-radius:50%;box-shadow:0 0 0 2px #fff;display:grid;place-items:center}
.mx-spdot>span{position:absolute;bottom:10px;font:800 10.5px/1 var(--sans);
  font-style:normal;color:var(--ink);white-space:nowrap;
  font-variant-numeric:tabular-nums}
.mx-spb>span{bottom:auto;top:10px}
.mx-spgapn{text-align:right;font-size:12.5px;font-weight:800;
  font-variant-numeric:tabular-nums}
@media (max-width:700px){
  .mx-sphead,.mx-sprow{grid-template-columns:6.4em 1fr 2.6em;gap:8px}
  .mx-spname{font-size:11px}
}


/* ── 指标图标 ──
   手写 SVG（`assets/icons.js`），**颜色靠 currentColor 继承**，
   所以同一个图形在主队行是紫、客队行是青，不用两套文件。 */
/* **15px、不降透明度、深一档的颜色。**
   原来 14px + opacity .72 的结果是一排灰糊点（放大 3.4 倍验过）——
   1.8 的描边在 14px 里只剩一个像素多，再乘 .72 就散了。
   图标要么看得清，要么别放。 */
/* **不设 color —— 必须继承。** 我一度写了 `color:var(--ink-2)`，
   结果主队行和客队行的图标都是灰的，而"同一个图标跟着队色变"正是
   手写 SVG 的全部理由（位图做不到的就是这个）。
   需要中性色的地方由外层给，比如全量表那行。 */
.mx-ico{width:15px;height:15px;flex:none;display:block}
/* 差距条/成功率的行首标签本身是中性色，所以那里的图标也跟着中性 */
.mx-spname,.mx-tk{color:var(--ink)}
.mx-spname .mx-ico{color:var(--ink-3)}
/* 带图标的标签一律横排、图标和文字基线对齐 */
.mx-spname,.mx-rname,.mx-tk{display:flex;align-items:center;gap:6px}
.mx-spname>span,.mx-rname>span{min-width:0;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}
/* 数字墙的格子是竖排的，图标跟标签同一行 */
/* 射门构成的图例：色块 + 图标 + 名字 */
.mx-keyrow span{display:inline-flex;align-items:center;gap:5px}
.mx-keyrow .mx-ico{width:15px;height:15px}
/* 全量表的行很密，图标小半档 */
.mx-tk .mx-ico{width:12.5px;height:12.5px;opacity:.6}
@media (max-width:700px){
  .mx-ico{width:13px;height:13px}
}

/* 百分比：定宽右对齐 + 等宽数字，所以上下成列 */
.mx-rpct{text-align:right;font:800 12.5px/1 var(--sans);color:var(--ink);
  font-variant-numeric:tabular-nums}
/* 分数：自己一格，左对齐 —— 它是补充说明，不该推着百分比走 */
.mx-rfrac{font:600 10.5px/1 var(--sans);color:var(--ink-3);font-style:normal;
  font-variant-numeric:tabular-nums;white-space:nowrap}
/* 尝试次数少的行整行压暗：说的是"这行结论不够硬"。
   **不参与长度比较**，所以不干扰读者比对成功率。

   两个属性都要设：`--o` 给动画末帧读（动画填充会盖掉普通 opacity），
   `opacity` 管动画没启用时（`prefers-reduced-motion` 或 JS 没跑）。 */
.mx-rfaint{--o:.5;opacity:.5}
@media (max-width:700px){
  .mx-rate{grid-template-columns:6.4em minmax(40px,1fr) 2.7em 3.2em;gap:7px}
}

/* ── 球门的网 ──
   菱形网眼（真球网就是菱形，不是方格），线要极细 —— 它是质感不是信息，
   压过热区就本末倒置了。 */
/* 网纹：**不能太淡**。原来 .7px 配 .55 不透明度，在 450px 宽的球门上
   几乎看不见，网的质感等于没做。提到 1px / .8。
   仍然比热区和门柱淡 —— 它是质感不是信息。 */
.mx-netline{stroke:#a99fb5;stroke-width:1;stroke-opacity:.8;fill:none;
  vector-effect:non-scaling-stroke}
/* 门柱和横梁：有厚度的形状（真门柱直径 12cm），渐变给圆柱感。
   描一道极淡的边，免得白柱在白底上没有边界。 */
.mx-post{stroke:#b2a7bd;stroke-width:.6;stroke-opacity:.5;
  vector-effect:non-scaling-stroke}

/* ── 传球方向（两队合成一张）──
   取代并排的两张小方向盘：那两张各自按自己的最大值归一，
   看着可比其实没有共同刻度。合成一张之后两队同一把尺，也有地方舒展。 */
.mx-rosewrap{display:flex;flex-direction:column;align-items:center;gap:4px}
/* 图放大到列宽的七成（原来固定 210px，而列有 700px —— 憋着）。
   上限 460px：再大花瓣就比数字还抢。 */
.mx-rosebig{width:min(70%,460px);height:auto;display:block}
/* 图例：合并图没有分列表头，得自己交代哪个颜色是哪支队 */
.mx-rlegend{display:flex;gap:20px;font:700 11.5px var(--sans);color:var(--ink-2)}
.mx-rlegend span{display:inline-flex;align-items:center;gap:6px}
.mx-rlegend i{width:9px;height:9px;border-radius:2px;flex:none}
/* 刻度圈：虚线、很淡 —— 它是参照系不是内容 */
.mx-rring{fill:none;stroke:var(--line);stroke-width:1;stroke-dasharray:2.5 3.5;
  vector-effect:non-scaling-stroke}
.mx-rpeak{fill:var(--ink-3);font-weight:700;font-family:var(--sans)}
/* 中心的洞：盖住四片花瓣在圆心的交汇处 */
.mx-rhole{fill:#fff;stroke:var(--line);stroke-width:1;
  vector-effect:non-scaling-stroke}
.mx-rdir{fill:var(--ink-2);font-weight:650;font-family:var(--sans)}
/* 两队的数字用各自队色（颜色由行内 fill 给），等宽数字好对齐 */
.mx-rn{font-weight:800;font-variant-numeric:tabular-nums}
.mx-rsep{fill:var(--ink-4)}
@media (max-width:700px){
  .mx-rosebig{width:100%}
}

/* ── 抢球位置（两队合成一张球场）──
   横向球场，三条带是真实的三区；主队在上半、客队在下半，共用一把刻度。

   **字号用 user unit 写在这里。** viewBox 是 105 宽、显示约 620px，
   所以 1 unit ≈ 5.9px —— 字号要按这个比例给。写在 JS 里会和这里的
   max-width 耦合，改一处忘另一处字就失真。 */
.mx-p3wrap{display:flex;flex-direction:column;align-items:center;gap:6px}
.mx-p3big{width:min(94%,620px);height:auto;display:block}
.mx-p3team{font:800 3.4px var(--sans);font-family:var(--sans)}
.mx-pzname{font:700 3px var(--sans);fill:var(--ink-2);
  paint-order:stroke;stroke:#fbfafc;stroke-width:1.4;stroke-linejoin:round;
  vector-effect:non-scaling-stroke}
.mx-pnum{font:800 7.4px var(--sans);fill:var(--ink);
  font-variant-numeric:tabular-nums;paint-order:stroke;stroke:#fbfafc;
  stroke-width:2.2;stroke-linejoin:round;vector-effect:non-scaling-stroke}
.mx-ppc{font:650 2.9px var(--sans);fill:var(--ink-3);
  font-variant-numeric:tabular-nums;paint-order:stroke;stroke:#fbfafc;
  stroke-width:1.3;stroke-linejoin:round;vector-effect:non-scaling-stroke}
/* 两队的分界：虚线，**不是球场线** —— 真实球场中间没有这条横线。
   要比白线深，否则压在色块上看不见。 */
.mx-p3split{stroke:#5c4a68;stroke-width:1;stroke-dasharray:2.2 2.2;
  stroke-opacity:.6;vector-effect:non-scaling-stroke}
/* 进攻方向箭头：这张图读得通的关键 —— 它解释了为什么同一条带
   对主队是后场、对客队是前场。 */
.mx-p3arrow{stroke-width:1.3;stroke-linecap:round;stroke-linejoin:round;
  vector-effect:non-scaling-stroke;fill:none}
@media (max-width:700px){.mx-p3big{width:100%}}

/* 单人行（球员页）：**标签在最前、独占一列**。
   `.mx-duel` 那四列是为双队对照排的（数字 条 数字 标签），单人行只有三个
   子元素，直接套用会让标签落进 2.7em 的数字列里被截断。 */
/* **列宽按语言给。** 中文指标名普遍 4~6 字（约 60px），英文动辄一整句
   （实测「Goals conceded from outside the box」要 206px）。用同一个 9.2em
   的话中文合适、英文被截掉一半（线上实测 56 个里 16 个）。
   加宽这一列会挤掉条本身，所以英文改成**每行更宽、每屏更少列**。 */
.mx-dsolo{grid-template-columns:9.2em minmax(60px,1fr) 3.4em}
html[lang="en"] .mx-dsolo{grid-template-columns:15em minmax(50px,1fr) 3.4em}
/* **单人条要自己的尺寸。** `.mx-dbar` 从来没定义过高度 —— 双队那版用的是
   `.mx-dtug`，改成双向条时我把尺寸都写在了新类上，留下 `.mx-dbar` 是个
   零高度的空壳。于是球员页的说明写着「条长是百分位」，而页面上一根条都没有
   （宽度算对了、高度是 0，看起来像这一列本来就没东西）。 */
.mx-dbar{height:7px;border-radius:999px;background:var(--paper-2);
  overflow:hidden;display:block}
.mx-dbar>i{display:block;height:100%;border-radius:999px}
.mx-dsolo .mx-dlab{font-size:11.5px;color:var(--ink-2)}
.mx-dsolo>b{text-align:right}
@media (max-width:700px){
  /* **标签列要够窄、数字列要能缩到 0。**
     原来 7.6em + minmax(40px,…) 在 430px 视口下三列合计 418px,
     而容器只有 398px（页面两侧各 16px 内边距）—— 行于是比容器宽,
     整页能左右拖。实测溢出 32px。

     **这条必须放在 `.mx-dsolo` 的定义之后。** 我第一版写在文件中段的
     640px 块里,而全局定义在第 549 行、排在它后面 —— 优先级相同时
     后面的赢,所以那条规则从来没生效过。层叠顺序和媒体查询一样要紧。 */
  /* **两个选择器都要写。** 浏览器查出来真正生效的是
     `html[lang="en"] .mx-dsolo{15em …}` —— 它的特异性（属性 + 类）高于
     裸 `.mx-dsolo`,所以我在媒体查询里写裸类不管放多后面都赢不了。
     15em ≈ 225px,三列合计 418px 装不进 398px 的容器,整页就能左右拖。

     英文列宽那条是为长标签加的（"Goals conceded from outside the box"
     要 206px）,但窄屏放不下 —— 那里改成标签换行,不再靠列宽硬撑。 */
  .mx-dsolo,
  html[lang="en"] .mx-dsolo{grid-template-columns:6.2em minmax(0,1fr) 2.8em;
    gap:7px}
  .mx-dsolo .mx-dlab{font-size:10.5px}
  /* 窄屏允许标签换行,否则 6.2em 装不下英文就会溢出 */
  .mx-dsolo .mx-dlab{align-items:flex-start}
  .mx-dsolo .mx-dlab>span{min-width:0;white-space:normal;line-height:1.25;
    overflow:visible;text-overflow:clip}
}

/* ── 门将：禁区俯视图 + 漏斗 ──
   原来是「一个大百分比 + 一排等宽格子」，也就是一张表。而门将数据本身
   有空间含义：扑救在门线、拿球和摘高空球在小禁区、出击在禁区外沿 ——
   拍平成一行数字就把那层含义丢了。 */
/* **整块限宽,不跟着页面宽度长。**
   这是同一个毛病的第三次:内容被拉满而不是按自己该有的宽度。
   实测分区行拉到 1203px 而图只有 340px —— 标签在最左、数字在最右,
   中间隔着一米的空白,眼睛要横扫一整行才能把「扑救」和「9」对上。
   面板的内容(一张 340px 的图 + 几行「名字 → 数字」)撑不起 1200px,
   所以限到 820px,多出来的宽度让给外侧留白。 */
.mx-gkwrap{display:flex;flex-direction:column;gap:clamp(16px,2vw,24px)}
/* 漏斗：面对射门 → 射正 → 扑出 → 失球。每段一根条，长度按最大值归一，
   所以「53 脚里只有 13 脚射正」是看长度就能读出来的。 */
.mx-gkflow{display:grid;gap:7px}
/* **条要和自己的数字挨着。** 原来条占 1fr、数字在 3em 的格子里，
   宽屏下条拉到 1100px 而数字贴在最右 —— 读者得横扫一整行才能把
   「这根条」和「53」对上。条限宽之后两者始终相邻。 */
.mx-gkstep{display:grid;grid-template-columns:minmax(0,1fr) 3em 5.4em;
  align-items:center;gap:12px}
.mx-gkstep i{display:block;height:8px;border-radius:999px;min-width:3px}
.mx-gkstep b{font:800 15px/1 var(--sans);color:var(--ink);text-align:right;
  font-variant-numeric:tabular-nums}
.mx-gkstep span{font-size:11.5px;color:var(--ink-3);font-weight:600}
/* 失球那一段用警示色 —— 它和上面三段方向相反（越少越好） */
.mx-gkstep.bad b{color:var(--loss,#e5484d)}
/* 图和数字并排：图在左、分区数字在右 */
/* 图和数字并排。**图要给到 340px** —— 240px 画一个 40.32 x 16.5 米的禁区时
   门线只剩一道痕、小禁区几乎看不出（实测 230px 下就是这样）。
   这张图的比例是 2.4:1，横向很扁，所以宽度给足高度也不会太占版面。 */
.mx-gkmain{display:grid;grid-template-columns:minmax(240px,340px) minmax(0,1fr);
  gap:clamp(20px,2.6vw,36px);align-items:start}
.mx-gkbox{width:100%;height:auto;display:block}
.mx-gkband{stroke:none}
.mx-gkline{fill:none;stroke:#c9bfd2;stroke-width:1.2;
  vector-effect:non-scaling-stroke}
.mx-gkspot{fill:#c9bfd2}
.mx-gkgoal{stroke:var(--ink);stroke-width:2.6;stroke-linecap:round;
  vector-effect:non-scaling-stroke}
/* 分区数字：一区一组，组标题用发丝线分隔，**不画格子** */
/* 分区列表限宽:内容是「名字 + 一个数」,给 300px 就够。
   不限的话它会摊到栅格分给它的全部宽度。 */
.mx-gkzones{display:grid;gap:clamp(12px,1.6vw,18px)}
.mx-gkzone h6{margin:0 0 5px;font:800 10.5px var(--sans);letter-spacing:.05em;
  color:var(--plum);text-transform:none}
/* **一行 = 名字 + 数字,数字紧跟名字。**
   原来用 `space-between`,于是在 447px 的行里标签贴左、数字贴右,
   中间隔着 371px 空白(量过)—— 读者要横扫过去才能把「扑救」和「9」对上。
   改成固定两列:名字一列、数字一列,数字右对齐但不被推到行尾。 */
.mx-gkrow{display:grid;grid-template-columns:minmax(0,1fr) 3.4em;
  align-items:baseline;gap:12px;padding:4px 0;
  border-top:1px solid var(--line-2)}
.mx-gkrow>b{text-align:right}
.mx-gkrow>span{display:flex;align-items:center;gap:6px;font-size:11.5px;
  color:var(--ink-2);min-width:0}
.mx-gkrow>b{font:800 14px/1 var(--sans);color:var(--ink);flex:none;
  font-variant-numeric:tabular-nums}
.mx-gkrow>b>i{font-style:normal;font-weight:700;font-size:11px;
  color:var(--ink-3)}
@media (max-width:700px){
  .mx-gkmain{grid-template-columns:1fr}
  .mx-gkbox{max-width:260px;margin-inline:auto}
}


/* 门将面板里那个球门：正中写扑救成功率。
   字号用 user unit —— viewBox 只有 7.32 宽，按屏幕 px 给会大得离谱。 */
/* 球门在卡片里限宽居中 —— 列已铺满度量，上限给图不给列 */
.mx-gkgoal2{width:100%;max-width:300px;height:auto;display:block;
  margin-inline:auto}
.mx-gkrate{font:800 .95px var(--sans);fill:var(--ink);
  font-variant-numeric:tabular-nums;paint-order:stroke;stroke:#fff;
  stroke-width:.16;stroke-linejoin:round}
.mx-gkratelab{font:700 .26px var(--sans);fill:var(--ink-3);
  paint-order:stroke;stroke:#fff;stroke-width:.1;stroke-linejoin:round}
