.timer-page { display: flex; flex-direction: column; align-items: center; justify-content: space-between; padding-top: 80rpx; padding-bottom: calc(170rpx + env(safe-area-inset-bottom)); min-height: 100vh; box-sizing: border-box; } /* ---- ring wrapper ---- */ .ring-wrapper { position: relative; display: flex; align-items: center; justify-content: center; } /* breathing guide rings — three concentric layers */ .breathe-ring { position: absolute; border-radius: 50%; border: 3rpx solid rgba(var(--primary-rgb), 0.15); animation: breathePulse 3.5s ease-in-out infinite; pointer-events: none; z-index: 0; } .breathe-ring-1 { width: 480rpx; height: 480rpx; animation-delay: 0s; } .breathe-ring-2 { width: 400rpx; height: 400rpx; animation-delay: 0.5s; border-color: rgba(var(--primary-rgb), 0.25); border-width: 4rpx; } .breathe-ring-3 { width: 320rpx; height: 320rpx; animation-delay: 1s; border-color: rgba(var(--primary-rgb), 0.35); border-width: 5rpx; } .breathe-ring.fast { animation: breathePulseFast 1.4s ease-in-out infinite; } .breathe-ring.fast.breathe-ring-1 { animation-delay: 0s; border-color: rgba(var(--primary-rgb), 0.3); } .breathe-ring.fast.breathe-ring-2 { animation-delay: 0.25s; border-color: rgba(var(--primary-rgb), 0.45); } .breathe-ring.fast.breathe-ring-3 { animation-delay: 0.5s; border-color: rgba(var(--primary-rgb), 0.6); } /* celebration burst */ .celebrate-burst { position: absolute; width: 520rpx; height: 520rpx; pointer-events: none; z-index: 2; } .spark { position: absolute; font-size: 36rpx; animation: sparkBurst 1s ease-out forwards; } .s1 { top: -10rpx; left: 50%; margin-left: -18rpx; animation-delay: 0s; } .s2 { top: 30rpx; right: -10rpx; animation-delay: 0.1s; } .s3 { bottom: -10rpx; right: 50rpx; animation-delay: 0.2s; } .s4 { bottom: 20rpx; left: 30rpx; animation-delay: 0.15s; } .s5 { top: 50%; right: -20rpx; animation-delay: 0.25s; } .s6 { top: -20rpx; left: 40rpx; animation-delay: 0.05s; } @keyframes sparkBurst { 0% { opacity: 0; transform: translate(0, 0) scale(0.3); } 40% { opacity: 1; transform: translate(0, -30rpx) scale(1.3); } 100% { opacity: 0; transform: translate(0, -80rpx) scale(0.4); } } /* overtime badge */ .overtime-badge { position: absolute; bottom: 10rpx; left: 50%; transform: translateX(-50%); background: rgba(76, 175, 80, 0.12); border: 2rpx solid rgba(76, 175, 80, 0.3); color: var(--success); padding: 8rpx 24rpx; border-radius: 24rpx; font-size: 28rpx; font-weight: 600; display: flex; align-items: center; gap: 6rpx; animation: popIn 0.4s cubic-bezier(0.34, 1.56, 0.64, 1); } .overtime-icon { width: 28rpx; height: 28rpx; } /* ---- hint section ---- */ .hint-section { margin-top: 36rpx; text-align: center; } .hint-row { display: inline-flex; align-items: center; justify-content: center; gap: 10rpx; } .hint-icon { width: 32rpx; height: 32rpx; } .running-pulse { animation: float 1.5s ease-in-out infinite; } .completed-bounce { animation: bounceSoft 0.6s ease infinite; } .hint-text { font-size: 28rpx; color: var(--text-secondary); line-height: 1.3; } .hint-text.running { color: var(--primary); font-weight: 600; } .hint-text.paused { color: var(--primary-light); } .hint-text.completed { color: var(--success); font-weight: 600; } .completed-hint { animation: popIn 0.5s ease; } /* ---- controls ---- */ .controls { margin-top: 60rpx; width: 100%; display: flex; justify-content: center; } .ctrl-row { display: flex; justify-content: center; align-items: center; } /* ---- full-screen confetti ---- */ .confetti { position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; pointer-events: none; z-index: 9999; overflow: hidden; } .confetti-piece { position: absolute; top: -20rpx; width: 16rpx; height: 32rpx; border-radius: 4rpx; animation: confettiFall 2.4s ease-out forwards; } .c1 { left: 10%; background: #FF6B35; animation-delay: 0.00s; transform: rotate(15deg); } .c2 { left: 22%; background: #FFD93D; animation-delay: 0.10s; transform: rotate(-20deg); } .c3 { left: 34%; background: #4CAF50; animation-delay: 0.20s; transform: rotate(30deg); } .c4 { left: 46%; background: #2979FF; animation-delay: 0.05s; transform: rotate(-10deg); } .c5 { left: 58%; background: #EC407A; animation-delay: 0.15s; transform: rotate(45deg); } .c6 { left: 70%; background: #7E57C2; animation-delay: 0.25s; transform: rotate(-30deg); } .c7 { left: 82%; background: #FF8C5A; animation-delay: 0.08s; transform: rotate(20deg); } .c8 { left: 14%; background: #5C9CFF; animation-delay: 0.18s; transform: rotate(-40deg); } .c9 { left: 38%; background: #6EC072; animation-delay: 0.28s; transform: rotate(50deg); } .c10 { left: 90%; background: #FFD93D; animation-delay: 0.12s; transform: rotate(-25deg); } @keyframes confettiFall { 0% { opacity: 1; transform: translateY(0) rotate(0deg); } 100% { opacity: 0.6; transform: translateY(100vh) rotate(720deg); } }