Files
wx_pbzc/pages/index/index.wxss
T
lc 05c4763e49 feat(timer): 循环训练组进度改为圆环分段弧 + 信息气泡三行合一
- progress-ring 新增 sets/currentSet/resting/successColor 属性,
  圆环外圈绘制分段弧(已完成=主色/当前=呼吸光点/休息下一组=绿),单组模式零渲染
- timer 删除顶部 circuit-bar 进度面板,布局骨架三模式统一
- 呼吸环淡化(描边 0.55→0.20,柔光渐变强度减半)
- 目标卡与提示气泡合并为 info-bubble,状态文案(撑住/休息中/已暂停)并入气泡顶部
2026-08-12 09:39:41 +08:00

449 lines
9.3 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* ===== 全宽渐变头图 hero ===== */
/* 负 margin 抵消 container 的 24rpx 内边距,让头图左右贯穿并贴到导航栏底边;
底部留大内边距给下方 quest-card 负 margin 上浮叠住。文字统一白色,图标用
*White 变体(若有)。hero 用 opacity-only 动画,避免 transform 把 .container
变成 containing block 而破坏弹窗定位(同 app.wxss pageIn 思路)。 */
/* index-page:仅本页面把 .container 升级为 flex 列,
时钟区 flex:1 居中,操作按钮 margin-top:auto 贴底(不动全局 container)。 */
.index-page {
display: flex;
flex-direction: column;
}
.hero {
margin: -24rpx -24rpx 0;
padding: 24rpx 24rpx 72rpx;
background: linear-gradient(160deg, var(--primary) 0%, var(--primary-light) 100%);
color: #fff;
position: relative;
overflow: hidden;
animation: heroFade 0.4s ease both;
}
.hero::after {
content: '';
position: absolute;
right: -60rpx;
top: -60rpx;
width: 240rpx;
height: 240rpx;
border-radius: 50%;
background: radial-gradient(circle, rgba(255, 255, 255, 0.18), transparent 70%);
pointer-events: none;
}
@keyframes heroFade {
from { opacity: 0; }
to { opacity: 1; }
}
/* 顶部行:圆形头像 + 时间问候 */
.hero-top {
display: flex;
align-items: center;
gap: 18rpx;
}
.hero-avatar {
width: 84rpx;
height: 84rpx;
flex-shrink: 0;
border-radius: 50%;
overflow: hidden;
background: #fff;
display: flex;
align-items: center;
justify-content: center;
border: 3rpx solid rgba(255, 255, 255, 0.6);
}
.hero-avatar-img {
width: 100%;
height: 100%;
border-radius: 50%;
display: block;
}
/* 有头像时去掉白底,只留浅描边,避免深色头像边缘露白缝 */
.hero-avatar.has-avatar {
background: transparent;
border-color: rgba(255, 255, 255, 0.85);
}
.hero-user {
display: flex;
flex-direction: row;
align-items: center;
gap: 14rpx;
min-width: 0;
}
.hero-greet {
font-size: 28rpx;
color: rgba(255, 255, 255, 0.92);
font-weight: 500;
}
/* 挑战主句:时长强调色 + 「敢不敢」白字 */
.hero-challenge {
margin-top: 28rpx;
display: flex;
align-items: baseline;
flex-wrap: wrap;
}
.hero-time {
font-size: 48rpx;
font-weight: 800;
color: #FFE3C2;
letter-spacing: 1rpx;
margin-right: 12rpx;
font-variant-numeric: tabular-nums;
}
.hero-cta-text {
font-size: 44rpx;
font-weight: 800;
color: #fff;
text-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.15);
line-height: 1.2;
}
.hero-social {
margin-top: 0;
font-size: 28rpx;
color: rgba(255, 255, 255, 0.9);
}
/* ===== 闯关进度地图(上浮卡片) ===== */
.quest-card {
margin-top: -56rpx;
margin-left: 0;
margin-right: 0;
position: relative;
z-index: 2;
}
.quest-head {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 24rpx;
}
.quest-title {
font-size: 32rpx;
font-weight: 700;
color: var(--text);
}
.quest-sub {
font-size: 24rpx;
font-weight: 400;
color: var(--text-secondary);
margin-left: 12rpx;
}
.quest-map {
display: flex;
align-items: center;
padding: 8rpx 4rpx;
}
.q-node {
width: 48rpx;
height: 48rpx;
border-radius: 50%;
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
font-size: 24rpx;
font-weight: 700;
background: var(--bg-soft);
color: var(--text-secondary);
}
.q-node.done {
background: var(--primary);
color: #fff;
}
.q-node.now {
background: linear-gradient(135deg, var(--primary), var(--primary-light));
color: #fff;
box-shadow: 0 0 0 6rpx rgba(var(--primary-rgb), 0.18);
animation: qPulse 1.6s ease-in-out infinite;
}
.q-node.final {
background: #FFF3E0;
font-size: 30rpx;
}
.q-link {
flex: 1;
height: 4rpx;
background: var(--bg-soft);
margin: 0 2rpx;
}
.q-link.done {
background: var(--primary);
}
.quest-tip {
display: block;
margin-top: 20rpx;
font-size: 24rpx;
font-weight: 600;
color: var(--primary);
}
@keyframes qPulse {
0% { box-shadow: 0 0 0 4rpx rgba(var(--primary-rgb), 0.28); }
70% { box-shadow: 0 0 0 12rpx rgba(var(--primary-rgb), 0); }
100% { box-shadow: 0 0 0 4rpx rgba(var(--primary-rgb), 0); }
}
/* ===== 今日目标时长(无圆环, 大字流光) =====
在 index-page 这条 flex 列里 .timer-wrap 充当"中间时钟区":flex:1 占满
hero+quest 与底部按钮之间的剩余高度,内部再垂直居中把"00:30 / 今日目标
时长 / 预计消耗 千卡"这组文字真正落到屏幕中部(原来只是默认排在卡片下方) */
.timer-wrap {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
text-align: center;
min-height: 0;
}
.time-display {
display: block;
font-family: 'Saira Condensed', 'Arial Narrow', sans-serif;
font-size: 200rpx;
font-weight: 900;
line-height: 1.1;
letter-spacing: 6rpx;
font-variant-numeric: tabular-nums;
color: var(--primary);
text-shadow: 0 8rpx 6rpx rgba(var(--primary-rgb), 0.35);
}
.time-label {
display: block;
font-size: 26rpx;
color: var(--text-secondary);
margin-top: 8rpx;
}
.benefit {
margin-top: 18rpx;
font-size: 28rpx;
color: var(--text-secondary);
}
.benefit-hl {
color: var(--primary);
font-weight: 700;
font-size: 30rpx;
}
/* ===== action buttons ===== */
/* 在 index-page flex 列里,3 个按钮(rechallenge + free + circuit)靠
margin-top:auto 推到列底、紧贴底部 toolbar 上方,与上方居中的时钟
区之间自然留白;gap 保持按钮自身间距不变 */
.action-buttons {
display: flex;
flex-direction: column;
gap: 24rpx;
margin: 8rpx 0 8rpx;
margin-top: auto;
}
/* 自由训练 / 循环训练 并排一行 */
.action-row {
display: flex;
gap: 16rpx;
}
.action-row .action-cell {
flex: 1;
min-width: 0; /* 防止图标+文字在窄屏撑破 flex 项 */
}
/* 主按钮脉冲发光(加在 ui-btn 宿主上,__usePrivacyCheck__ 不影响) */
@keyframes ctaPulse {
0%, 100% { box-shadow: 0 8rpx 20rpx rgba(var(--primary-rgb), 0.35); }
50% { box-shadow: 0 8rpx 30rpx rgba(var(--primary-rgb), 0.6); }
}
/* ===== picker ===== */
.picker-title {
font-size: 34rpx;
font-weight: 600;
color: var(--text);
display: block;
text-align: center;
margin-bottom: 32rpx;
}
.preset-grid {
display: flex;
flex-wrap: wrap;
gap: 16rpx;
margin-bottom: 28rpx;
}
.preset-item {
flex: 0 0 calc(33.33% - 12rpx);
box-sizing: border-box;
background: var(--bg-soft);
border: 2rpx solid transparent;
border-radius: 16rpx;
padding: 20rpx 0;
text-align: center;
display: flex;
flex-direction: column;
transition: all 0.2s ease;
}
.preset-item:active {
transform: scale(0.94);
}
.preset-item.selected {
background: var(--primary-bg);
border: 2rpx solid var(--primary);
}
.preset-num {
font-size: 36rpx;
font-weight: 700;
color: var(--text);
line-height: 1.1;
}
.preset-item.selected .preset-num {
color: var(--primary);
}
.preset-unit {
font-size: 20rpx;
color: var(--text-secondary);
margin-top: 2rpx;
line-height: 1;
}
.custom-input-row {
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 28rpx;
}
.custom-label {
font-size: 28rpx;
color: var(--text-secondary);
line-height: 1;
}
.custom-input {
width: 160rpx;
height: 64rpx;
background: var(--bg-soft);
border-radius: 12rpx;
text-align: center;
font-size: 32rpx;
font-weight: 600;
color: var(--primary);
margin: 0 16rpx;
}
.picker-cancel {
display: block;
text-align: center;
font-size: 28rpx;
color: var(--text-secondary);
padding: 12rpx 0;
margin-top: 8rpx;
}
/* ===== circuit (循环训练) config panel ===== */
.picker-sub {
display: block;
text-align: center;
font-size: 24rpx;
color: var(--text-secondary);
margin: -18rpx 0 24rpx;
}
.circuit-row {
display: flex;
align-items: center;
justify-content: space-between;
padding: 20rpx 8rpx;
border-bottom: 1rpx solid var(--border);
}
.circuit-row-label {
font-size: 30rpx;
color: var(--text);
font-weight: 500;
}
.stepper {
display: flex;
align-items: center;
gap: 20rpx;
}
.stepper-btn {
width: 64rpx;
height: 64rpx;
border-radius: 50%;
background: var(--bg-soft);
color: var(--primary);
font-size: 40rpx;
font-weight: 700;
display: flex;
align-items: center;
justify-content: center;
line-height: 1;
transition: transform 0.12s ease, opacity 0.12s ease;
}
.stepper-btn:active {
transform: scale(0.9);
opacity: 0.8;
}
.stepper-val {
min-width: 124rpx;
text-align: center;
font-size: 32rpx;
font-weight: 700;
color: var(--text);
font-variant-numeric: tabular-nums;
}
/* ===== 训练完成高亮 (3 秒后淡出) ===== */
/* 这个 class 落在 <ui-card> 宿主节点上(ui-card.wxss 已把宿主设为 display:block
否则 border/box-shadow 只会碎成两根竖条、transform 完全不生效)。
描边用 box-shadow 的 spread 而非 borderborder 会撑大宿主 8rpx,高亮出现/消失
时整页布局跳动;box-shadow 不占布局空间。宿主自身无圆角,必须补上与内部卡片
一致的 24rpx,否则描边会是直角框套在圆角卡片外面。 */
.just-completed {
animation: justCompletedPulse 1s ease-in-out 2;
border-radius: 24rpx;
box-shadow: 0 0 0 4rpx var(--primary), 0 4rpx 24rpx rgba(var(--primary-rgb), 0.3);
}
@keyframes justCompletedPulse {
0%, 100% { transform: scale(1); }
50% { transform: scale(1.02); }
}