feat: 排行榜虚拟领奖台 + 勋章对齐与尺寸统一

- 领奖台数据不足 3 名时显示虚拟空位(虚线轮廓+虚位以待)
- 领奖台勋章与昵称对齐改为等高盒结构性修复(移除 margin 盲推)
- 全 app 成就勋章图标尺寸统一为 30rpx(前三名/列表/设置页/记录页一致)
- 勋章 SVG 按包围盒精确居中(utils/icons.js)
- 设置页/记录页勋章展示配套调整
This commit is contained in:
2026-08-04 11:23:48 +08:00
parent bce796d893
commit b52db87ddf
17 changed files with 690 additions and 67 deletions
+76 -6
View File
@@ -194,16 +194,42 @@
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
line-height: 1.3;
/* 用 name 的 margin-top 直接控制与上方头像/角标的间距:它是 flex 子元素,
margin 必定生效不折叠,不依赖 avatar margin-bottom 的 collapse 行为
(WebView/Skyline 下不一致,曾导致角标压住昵称)。 */
margin-top: 30rpx;
/* 关键对齐修复:行盒高度设为与勋章等高(30rpx)。这样 flex 的 align-items:center
对齐的是"昵称盒中心"与"勋章盒中心"两个等高盒,而非 line-height:1 下偏矮、
且中文 glyph 视觉重心偏下的行盒,图标不会再飘在昵称上方。 */
line-height: 30rpx;
}
.podium-name--first {
font-size: 28rpx;
font-weight: 600;
line-height: 30rpx; /* 与首名勋章统一为 30rpx,前三名勋章等大且和昵称盒等高对齐 */
}
/* 领奖台名字 + 勋章横排(居中)。名字保留自身 max-width/省略,勋章固定不挤压 */
.podium-name-row {
display: flex;
align-items: center;
justify-content: center;
gap: 6rpx;
max-width: 220rpx;
/* 原间距 margin-top:30rpx 从 .podium-name 移到此处:避免在 flex 子项上用
cross 轴 margin 干扰昵称与勋章的居中(那是之前图标"偏高"的隐藏元凶)。 */
margin-top: 30rpx;
}
.podium-badge {
width: 30rpx;
height: 30rpx;
flex-shrink: 0;
/* 不再用 margin-top 盲推:昵称行盒已设为与勋章等高(30rpx),flex align-items:center
直接对齐两盒中心,图标与昵称视觉对齐。若个别冠类勋章因图形重心仍有 ±1~2rpx
偏差,再单独给该图加 transform: translateY(2rpx) 即可,不要回退到 margin 推法。 */
}
.podium-badge--first {
width: 30rpx;
height: 30rpx;
}
/* session count printed on the podium base. Pinned a fixed offset above the
@@ -243,7 +269,8 @@
font-size: 24rpx;
font-weight: 600;
color: var(--text-secondary);
margin-top: 2rpx;
/* line-height 收紧后行盒缩短约 8rpx,此处补偿保持与名字的视觉间距 */
margin-top: 10rpx;
font-variant-numeric: tabular-nums;
}
@@ -277,6 +304,30 @@
box-shadow: 0 6rpx 18rpx rgba(212, 107, 8, 0.22), inset 0 2rpx 4rpx rgba(255, 255, 255, 0.45);
}
/* 虚拟领奖台:空位占位(名单不足 3 名时,空缺名次渲染成"虚位以待") */
.podium-avatar--empty {
opacity: 1;
border: 4rpx dashed rgba(var(--primary-rgb), 0.35);
box-shadow: none;
background: rgba(var(--primary-rgb), 0.04);
}
.podium-avatar__img--empty {
opacity: 0.26;
filter: grayscale(1);
}
.podium-empty-label {
font-size: 22rpx;
font-weight: 500;
color: var(--text-secondary);
opacity: 0.5;
}
.podium-crown--empty {
opacity: 0.3;
}
/* Rank list */
.rank-list {
padding: 16rpx 24rpx;
@@ -340,6 +391,25 @@
white-space: nowrap;
}
/* 昵称 + 最新勋章横排:昵称可省略,勋章固定不挤压 */
.rank-name-row {
display: flex;
align-items: center;
gap: 6rpx;
min-width: 0;
}
.rank-name-row .rank-name {
flex: 0 1 auto;
min-width: 0;
}
.rank-badge {
width: 30rpx;
height: 30rpx;
flex-shrink: 0;
}
.rank-sessions {
font-size: 22rpx;
color: var(--text-secondary);