<template>
	<view class="page" :class="{ 'page-record': !isQuitMode }">
		<!-- 背景装饰 -->
		<view v-if="isQuitMode" class="bg-gradient"></view>
		<view v-if="isQuitMode" class="bg-pattern"></view>

		<view class="nav-placeholder" :style="{ height: navBarHeight + 'px' }"></view>

		<!-- 骨架屏 -->
		<view v-if="loading" class="skeleton-wrap">
			<view class="sk-circle"></view>
			<view class="sk-row"></view>
			<view class="sk-row sk-row-short"></view>
			<view class="sk-card"></view>
		</view>

		<view v-else class="content">
			<!-- 戒烟模式 -->
			<view v-if="isQuitMode" class="bio-home" :style="hpVisualStyle">
				<view class="bio-status-card">
					<view class="bio-breath-line"></view>
					<view class="bio-profile-row">
						<view class="bio-avatar"><text>{{ bioAvatarText }}</text></view>
						<view class="bio-profile-main">
							<text class="bio-rank">{{ bioRankText }} <text class="bio-level">{{ bioLevelText }}</text></text>
							<text class="bio-subtitle">冷静恢复中 · {{ todayChecked ? '今日已确认' : '等待今日确认' }}</text>
						</view>
						<view class="bio-coin-pill">
							<text class="bio-coin-icon">💰</text>
							<text class="bio-coin-value">×{{ savedMoney }}</text>
						</view>
					</view>

					<view class="bio-hp-box">
						<view class="bio-hp-track">
							<view class="bio-hp-fill" :style="bioHpBarStyle"></view>
							<view class="bio-hp-clear"></view>
						</view>
						<view class="bio-hp-meta">
							<text>HP: {{ hpValue }}%</text>
							<text>浊 → 清</text>
						</view>
					</view>

					<view class="bio-buff-pill">
						<text class="bio-buff-star">✦</text>
						<text>{{ bioBuffText }}</text>
					</view>
				</view>

				<view class="bio-console-card" @tap="handleQuitCheckin">
					<view class="bio-console-orbit">
						<view class="bio-console-core" :class="{ 'bio-console-core-done': todayChecked }">
							<text>{{ todayChecked ? '✓' : '◐' }}</text>
						</view>
					</view>
					<view class="bio-console-copy">
						<text class="bio-console-kicker">CORE CONSOLE</text>
						<text class="bio-console-title">{{ todayChecked ? '今天的清澈已记录' : '确认今天没有抽烟' }}</text>
						<text class="bio-console-desc">{{ todayChecked ? `${todayCheckinTime} 已完成打卡，继续维持身体修复节奏。` : '轻点完成今日确认，用一次温和反馈替代刺激奖励。' }}</text>
					</view>
					<view class="bio-console-action">
						<text>{{ todayChecked ? '已完成' : '打卡' }}</text>
					</view>
				</view>

				<view class="bio-health-card">
					<view class="bio-section-head">
						<view>
							<text class="bio-section-title">健康仪表盘</text>
							<text class="bio-section-subtitle">身体正在把每一次选择转化为回收值</text>
						</view>
						<text class="bio-section-chip">{{ nextHealthMilestoneText }}</text>
					</view>
					<view class="bio-health-body">
						<view class="bio-health-ring" :style="hpGaugeStyle">
							<view class="bio-health-ring-inner">
								<text class="bio-health-ring-value">{{ hpValue }}%</text>
								<text class="bio-health-ring-label">健康指数</text>
							</view>
						</view>
						<view class="bio-health-metrics">
							<view v-for="item in bioHealthItems" :key="item.name" class="bio-health-row">
								<text class="bio-health-name">{{ item.name }}</text>
								<text class="bio-health-value">{{ item.value }}</text>
							</view>
							<view class="bio-health-divider"></view>
							<view class="bio-life-row">
								<text class="bio-life-value">+{{ lifeSaved }} 小时</text>
								<text class="bio-life-label">生命已回收</text>
							</view>
						</view>
					</view>
				</view>

				<view class="bio-trend-card">
					<view class="bio-section-head bio-section-head-compact">
						<text class="bio-section-title">7 天趋势</text>
						<text class="bio-section-chip">{{ lungMomentumText }}</text>
					</view>
					<view class="bio-trend-chart">
						<view v-for="item in bioTrendItems" :key="item.label" class="bio-trend-col">
							<view class="bio-trend-line" :style="{ height: item.height }">
								<view class="bio-trend-dot" :class="{ 'bio-trend-dot-active': item.active }"></view>
							</view>
							<text class="bio-trend-label">{{ item.label }}</text>
						</view>
					</view>
				</view>

				<view class="bio-action-grid">
					<view class="bio-action-card" @tap="openSmokeDialog">
						<text class="bio-action-title">没扛住？</text>
						<text class="bio-action-desc">记录诱因，比责备自己更有用</text>
					</view>
					<view class="bio-action-card" @tap="gotoDreamGoals">
						<text class="bio-action-title">梦想清单</text>
						<text class="bio-action-desc">{{ activeGoalText }}</text>
					</view>
				</view>

				<view class="bio-tip-card">
					<text class="bio-tip-icon">✦</text>
					<text class="bio-tip-text">{{ healthTip }}</text>
				</view>
			</view>
			<!-- 记录模式 -->
			<view v-else class="record-bio-home">
				<view class="record-bio-status-card">
					<view class="record-bio-breath-line"></view>
					<view class="record-bio-profile-row">
						<view class="record-bio-avatar-medal">
							<image class="record-bio-avatar-bg" src="/static/achievements/theme-medallion.png" mode="aspectFill" />
							<text class="record-bio-avatar-icon">{{ recordTitle.icon }}</text>
						</view>
						<view class="record-bio-profile-main">
							<text class="record-bio-rank">{{ recordTitle.name }} <text class="record-bio-level">{{ recordTitle.level }}</text></text>
							<text class="record-bio-subtitle">{{ recordTitle.description }}</text>
						</view>
						<view class="record-bio-target-pill">
							<text class="record-bio-target-icon">◎</text>
							<text class="record-bio-target-value">少 {{ recordReducedCigs }} 根</text>
						</view>
					</view>

					<view class="record-bio-title-panel">
						<view class="record-bio-title-copy">
							<text class="record-bio-title-kicker">REDUCTION TITLE</text>
							<text class="record-bio-title-name">{{ recordTitle.badge }}</text>
						</view>
						<text class="record-bio-title-hint">{{ recordNextTitleHint }}</text>
					</view>

					<view class="record-bio-hp-box">
						<view class="record-bio-hp-track">
							<view class="record-bio-hp-fill" :style="{ width: recordControlScore + '%' }"></view>
							<view class="record-bio-hp-clear"></view>
						</view>
						<view class="record-bio-hp-meta">
							<text>控制率: {{ recordControlScore }}%</text>
							<text>刺激 → 清醒</text>
						</view>
					</view>

					<view class="record-bio-buff-pill">
						<text class="record-bio-buff-star">✦</text>
						<text>{{ recordBioBuffText }}</text>
					</view>
				</view>

				<view class="record-bio-console-card">
					<view class="record-bio-console-left">
						<view class="record-bio-orbit" :style="todayCountRingStyle">
							<view class="record-bio-orbit-inner">
								<text class="record-bio-orbit-kicker">距上次</text>
								<text class="record-bio-orbit-value">{{ timerDisplay }}</text>
								<text class="record-bio-orbit-label">抽烟间隔</text>
							</view>
						</view>
					</view>
					<view class="record-bio-console-main">
						<text class="record-bio-console-kicker">CONTROL CONSOLE</text>
						<text class="record-bio-console-title">{{ recordHeroTitle }}</text>
						<text class="record-bio-console-desc">{{ recordRhythmText }}</text>
						<view class="record-bio-action-row">
							<view class="record-bio-action record-bio-action-primary" :class="{ 'record-bio-action-disabled': quickSubmitting }" @tap="quickRecordSmoke">
								<text class="record-bio-action-icon">+</text>
								<text>快捷记录</text>
							</view>
							<view class="record-bio-action record-bio-action-ghost" @tap="openDetailedSmokeDialog">
								<text class="record-bio-action-icon">✎</text>
								<text>详细记录</text>
							</view>
						</view>
					</view>
				</view>

				<view class="record-bio-health-card">
					<view class="record-bio-section-head">
						<view>
							<text class="record-bio-section-title">控烟仪表盘</text>
							<text class="record-bio-section-subtitle">用真实记录换取更清醒的下一次选择</text>
						</view>
						<text class="record-bio-section-chip">{{ reducePercent }}% 少抽</text>
					</view>
					<view class="record-bio-health-body">
						<view class="record-bio-health-ring" :style="recordControlRingStyle">
							<view class="record-bio-health-ring-inner">
								<text class="record-bio-health-ring-value">{{ todayCount }}</text>
								<text class="record-bio-health-ring-label">今日已抽</text>
							</view>
						</view>
						<view class="record-bio-metrics">
							<view v-for="item in recordBioHealthItems" :key="item.name" class="record-bio-metric-row">
								<text class="record-bio-metric-name">{{ item.name }}</text>
								<text class="record-bio-metric-value">{{ item.value }}</text>
							</view>
						</view>
					</view>
				</view>

				<view class="record-bio-tip-card">
					<text class="record-bio-tip-icon">✦</text>
					<text class="record-bio-tip-text">{{ recordHealthTip }}</text>
				</view>
			</view>
			<smoke-record-dialog
				v-model:show="showDialog"
				:type="dialogType"
				:quick-mode="dialogQuickMode"
				@submit="handleSubmit"
			/>
		</view>

		<view v-if="checkinCelebrating" class="checkin-celebration-mask">
			<view class="checkin-celebration-card">
				<view class="checkin-celebration-burst">
					<view
						v-for="burst in celebrationBursts"
						:key="burst.id"
						class="checkin-celebration-ray"
						:style="{ transform: `rotate(${burst.rotate}deg) translateY(-88rpx)` }"
					></view>
				</view>
				<view class="checkin-celebration-icon">✓</view>
				<text class="checkin-celebration-title">今日打卡完成</text>
				<text class="checkin-celebration-desc">已连续无烟 {{ quitDays }} 天，{{ lungPhaseLabel }}</text>
				<view class="checkin-celebration-chip-row">
					<view class="checkin-celebration-chip">
						<text class="checkin-celebration-chip-label">肺部 HP</text>
						<text class="checkin-celebration-chip-value">{{ hpValue }}</text>
					</view>
					<view class="checkin-celebration-chip">
						<text class="checkin-celebration-chip-label">已省下</text>
						<text class="checkin-celebration-chip-value">¥{{ savedMoney }}</text>
					</view>
				</view>
			</view>
		</view>
	</view>
</template>

<script setup>
import { ref, computed, onMounted, onUnmounted } from 'vue'
import { onShareAppMessage, onShow } from '@dcloudio/uni-app'
import * as api from '@/api'
import { useLogin } from '@/hooks/useLogin'
import { useProfileStore } from '@/stores/profile'
import { useUserStore } from '@/stores/user'
import { storage, QUIT_CHECKIN_KEY } from '@/utils/storage'
// formatDate / formatTime 来自公共工具，避免重复实现
import { formatDate, formatTime } from '@/utils/time'

const profileStore = useProfileStore()
const userStore = useUserStore()
const { waitForLogin } = useLogin()

// ---- 页面状态 ----
const loading = ref(true)
const pageReady = ref(false)
const navBarHeight = ref(0)
const showDialog = ref(false)
const dialogType = ref('smoke')
const dialogQuickMode = ref(false)
const quickSubmitting = ref(false)

// ---- 数据 ----
const homeData = ref(null)         // 记录模式首页数据
const quitHomeData = ref(null)     // 戒烟模式首页数据
const achievementData = ref(null)  // 成就数据
const quitState = ref(defaultQuitState()) // 本地缓存的打卡状态（网络失败时兜底）

// ---- 打卡庆祝动画 ----
const checkinCelebrating = ref(false)
let checkinCelebrationTimer = null

// ---- 记录模式计时器：距上次抽烟的秒数 ----
let timerInterval = null
const timerBaseSeconds = ref(-1) // -1 表示从未记录过
const timerSeconds = ref(0)      // 页面存活期间累计秒数

// ========== 基础计算 ==========

const isQuitMode = computed(() => userStore.mode === 'quit')
const homeSummary = computed(() => homeData.value?.summary || {})
const homeTimer = computed(() => homeData.value?.timer || {})
const homeMotivation = computed(() => homeData.value?.motivation || {})
const quitSummary = computed(() => quitHomeData.value?.summary || {})
const quitDailyStatus = computed(() => quitHomeData.value?.daily_status || {})

// 用户档案基础数据
const baselineCigsPerDay = computed(() => profileStore.profile?.baseline_cigs_per_day || 10)
const packPriceYuan = computed(() => (profileStore.profile?.pack_price_cent || 2500) / 100)

// ========== 记录模式 ==========

const todayCount = computed(() => homeSummary.value.today_count ?? 0)
const dailyTarget = computed(() => {
	const target = homeSummary.value.daily_target
	if (target != null) return target
	return profileStore.profile?.baseline_cigs_per_day || 0
})
const recordReducedCigs = computed(() => Math.max(0, (dailyTarget.value || 0) - todayCount.value))
const changeText = computed(() => {
	const reduced = homeSummary.value.reduced_from_yesterday
	if (reduced == null) return '较昨日暂无对比'
	if (reduced === 0) return '较昨日持平'
	return homeSummary.value.exceeded_yesterday ? `较昨日多 ${reduced} 根` : `较昨日少 ${reduced} 根`
})

// 格式化计时器显示 HH:MM:SS
const timerDisplay = computed(() => {
	if (timerBaseSeconds.value < 0) return '--:--:--'
	const total = timerBaseSeconds.value + timerSeconds.value
	const h = Math.floor(total / 3600)
	const m = Math.floor((total % 3600) / 60)
	const s = total % 60
	return [h, m, s].map(n => String(n).padStart(2, '0')).join(':')
})

// 下次建议抽烟时间
const nextSmokeTimeText = computed(() => {
	const timer = homeTimer.value
	if (!timer) return ''
	if (timer.next_suggested_clock) return timer.next_suggested_clock
	if (!timer.next_suggested_at) return ''
	const date = new Date(timer.next_suggested_at)
	return Number.isNaN(date.getTime()) ? '' : formatTime(date)
})

// 今日进度环百分比（已抽/目标）
const todayCountPercent = computed(() => {
	if (!dailyTarget.value || dailyTarget.value <= 0) return todayCount.value > 0 ? 100 : 0
	return Math.min(Math.max(Math.round((todayCount.value / dailyTarget.value) * 100), 0), 100)
})

const todayCountRingStyle = computed(() => {
	const angle = Math.round(todayCountPercent.value * 3.6)
	const accent = todayCount.value > dailyTarget.value && dailyTarget.value > 0 ? '#f97316' : '#1fbf8f'
	return { background: `conic-gradient(${accent} 0deg ${angle}deg, rgba(226, 239, 233, 0.88) ${angle}deg 360deg)` }
})

const recordHasData = computed(() => todayCount.value > 0 || timerBaseSeconds.value >= 0)

const recordHeroTitle = computed(() => {
	if (!recordHasData.value) return '先记录第一刻'
	if (todayCount.value === 0) return '今天还没抽烟'
	if (todayCount.value < dailyTarget.value) return '节奏控制不错'
	if (todayCount.value === dailyTarget.value) return '已经到达目标线'
	return '今天需要收一收'
})

const recordRhythmText = computed(() => {
	if (!recordHasData.value) return '点击下方按钮开始记录，建立自己的控烟节奏。'
	if (nextSmokeTimeText.value) return `建议下次 ${nextSmokeTimeText.value} 后再抽，给身体留一点恢复时间。`
	return changeText.value
})

const reducePercent = computed(() => {
	if (dailyTarget.value <= 0) return 0
	return Math.round(recordReducedCigs.value / dailyTarget.value * 100)
})

const recordHealthTip = computed(() => {
	if (homeMotivation.value.message) return homeMotivation.value.message
	if (todayCount.value === 0) return '今天还没抽烟，继续保持！'
	if (todayCount.value < dailyTarget.value) return `今天比目标少抽了${dailyTarget.value - todayCount.value}根，很棒！`
	if (todayCount.value === dailyTarget.value) return '今天已达到目标，加油！'
	return '今天超标了，明天继续努力'
})

const recordControlScore = computed(() => {
	if (!dailyTarget.value || dailyTarget.value <= 0) return todayCount.value > 0 ? 40 : 88
	const score = Math.round((1 - Math.min(todayCount.value / dailyTarget.value, 1)) * 72) + 18
	return Math.min(Math.max(score, todayCount.value > dailyTarget.value ? 12 : 18), 100)
})

const recordStatusLabel = computed(() => {
	if (!recordHasData.value) return '等待第一条真实记录'
	if (todayCount.value === 0) return '清醒保持中'
	if (todayCount.value < dailyTarget.value) return '节奏稳定'
	if (todayCount.value === dailyTarget.value) return '接近边界'
	return '需要降速'
})

const recordBioBuffText = computed(() => nextSmokeTimeText.value ? `下一次建议 ${nextSmokeTimeText.value}` : '正在建立控烟节奏')
const recordControlRingStyle = computed(() => {
	const angle = Math.round(recordControlScore.value * 3.6)
	const accent = todayCount.value > dailyTarget.value && dailyTarget.value > 0 ? '#D97706' : '#67E8F9'
	return { background: `conic-gradient(${accent} 0deg ${angle}deg, rgba(226, 232, 240, 0.78) ${angle}deg 360deg)` }
})

const recordYesterdayText = computed(() => {
	const reduced = Number(homeSummary.value.reduced_from_yesterday)
	if (Number.isNaN(reduced)) return '暂无对比'
	if (reduced === 0) return '持平'
	return homeSummary.value.exceeded_yesterday ? `多 ${reduced} 根` : `少 ${reduced} 根`
})

const recordBioHealthItems = computed(() => [
	{ name: '今日目标', value: `${todayCount.value}/${dailyTarget.value || '-'} 根` },
	{ name: '较昨日', value: recordYesterdayText.value },
	{ name: '建议时间', value: nextSmokeTimeText.value || '--:--' }
])

const recordTitle = computed(() => {
	const current = achievementData.value?.current
	const metrics = achievementData.value?.metrics || {}
	return {
		icon: current?.icon || achievementData.value?.theme_icon || '◎',
		name: current?.name || '节奏观察者',
		level: achievementData.value?.score !== undefined ? `积分 ${achievementData.value.score}` : '积分 0',
		badge: achievementData.value?.theme_name || '成就称号',
		description: metrics.scored_days > 0
			? `累计少抽 ${metrics.total_reduced_cigs || 0} 根，稳定记录 ${metrics.stable_days || 0} 天。`
			: '完成记录后，会按少抽数量解锁称号。'
	}
})

const recordNextTitleHint = computed(() => {
	const next = achievementData.value?.next
	if (!next) return achievementData.value?.current ? '已达当前最高称号' : '记录后开始进阶'
	const score = Number(achievementData.value?.score) || 0
	const required = Number(next.required_score ?? next.required_days) || 0
	return `距「${next.name}」还差 ${Math.max(0, required - score)} 分`
})

// ========== 戒烟模式 ==========

// 服务端连续无烟天数优先，失败时从本地缓存推算
const quitDays = computed(() => {
	if (quitSummary.value.current_streak_days !== undefined) return quitSummary.value.current_streak_days
	if (!quitState.value.lastCheckinDate) return 0
	// 超过 1 天未打卡则连续中断归零
	const gap = diffDays(quitState.value.lastCheckinDate, formatDate(new Date()))
	return gap > 1 ? 0 : Number(quitState.value.streakDays || 0)
})

const todayChecked = computed(() => {
	if (quitDailyStatus.value.status) return quitDailyStatus.value.status === 'checked_in'
	return quitState.value.lastCheckinDate === formatDate(new Date())
})

const todayCheckinTime = computed(() => {
	const src = quitDailyStatus.value.checkin_at || quitState.value.lastCheckinAt
	return formatClock(src)
})

const savedMoney = computed(() => {
	if (quitSummary.value.saved_money_cent !== undefined) return Math.round(quitSummary.value.saved_money_cent / 100)
	return Math.round((quitDays.value * baselineCigsPerDay.value / 20) * packPriceYuan.value)
})

const avoidedCigs = computed(() => quitSummary.value.avoided_cigs ?? quitDays.value * baselineCigsPerDay.value)
const lifeSaved = computed(() => Math.round(avoidedCigs.value * 11 / 60))

// HP 值：服务端优先，否则按天数本地估算
const healthProgress = computed(() => {
	if (quitSummary.value.health_recovery_percent !== undefined) return quitSummary.value.health_recovery_percent
	const d = quitDays.value
	if (d >= 365) return 100; if (d >= 180) return 85; if (d >= 90) return 70
	if (d >= 30) return 55;  if (d >= 14) return 35;  if (d >= 7) return 20
	if (d >= 3) return 10;   if (d >= 1) return 5;    return 0
})

const hpValue = computed(() => {
	const v = Number(quitSummary.value.hp_current ?? healthProgress.value)
	return Number.isNaN(v) ? 0 : Math.min(Math.max(Math.round(v), 0), 100)
})

// 根据 HP 区间决定主题色和文案
const hpState = computed(() => {
	const hp = hpValue.value
	if (hp <= 20) return { label: '危险期', title: '先保住今天的底线', description: '身体恢复动力偏弱，先把眼前这一波烟瘾稳住最重要。', accent: '#64748b', soft: '#e2e8f0', deep: '#334155' }
	if (hp <= 40) return { label: '恢复中', title: '状态正在往回拉', description: '已经开始脱离最低谷，再多守住几次关键时刻，HP 会明显回升。', accent: '#0f766e', soft: '#ccfbf1', deep: '#115e59' }
	if (hp <= 60) return { label: '稳定期', title: '节奏开始站稳', description: '你已经进入可持续恢复阶段，规律打卡会让状态越来越稳。', accent: '#0891b2', soft: '#cffafe', deep: '#155e75' }
	if (hp <= 80) return { label: '强韧期', title: '恢复势头很不错', description: '肺部状态正在加速恢复，继续把高风险场景提前处理掉。', accent: '#16a34a', soft: '#dcfce7', deep: '#166534' }
	return { label: '高能期', title: '你已经进入高能状态', description: '当前状态非常好，保持日常节奏和打卡，就能继续巩固恢复成果。', accent: '#ea580c', soft: '#ffedd5', deep: '#9a3412' }
})

// CSS 变量注入（供卡片内动态主题色使用）
const hpVisualStyle = computed(() => ({
	'--hp-accent': hpState.value.accent,
	'--hp-soft': hpState.value.soft,
	'--hp-deep': hpState.value.deep
}))

const hpGaugeStyle = computed(() => {
	const angle = Math.round(hpValue.value * 3.6)
	return { background: `conic-gradient(var(--hp-accent) 0deg ${angle}deg, rgba(226, 232, 240, 0.88) ${angle}deg 360deg)` }
})

const hpChangeText = computed(() => {
	const delta = Number(quitSummary.value.hp_change_today ?? quitSummary.value.hp_delta_today ?? quitSummary.value.hp_change)
	if (!Number.isNaN(delta) && delta !== 0) return delta > 0 ? `今日 +${delta}` : `今日 ${delta}`
	if (todayChecked.value) return '今日已保住状态'
	return quitDays.value > 0 ? '先打卡再继续回血' : '从今天开始积累'
})

const healthTip = computed(() => {
	const d = quitDays.value
	if (d >= 365) return '肺部功能显著改善，心血管疾病风险大幅降低'
	if (d >= 180) return '血液循环持续改善，肺功能逐步恢复'
	if (d >= 90)  return '味觉嗅觉恢复，呼吸更加顺畅'
	if (d >= 30)  return '咳嗽减少，体能开始恢复'
	if (d >= 14)  return '尼古丁戒断症状明显减轻'
	if (d >= 7)   return '一氧化碳水平恢复正常'
	if (d >= 3)   return '呼吸开始变得顺畅'
	if (d >= 1)   return '身体开始自我修复'
	return '开始戒烟，身体即将启动修复'
})

const quitEncouragement = computed(() => {
	const d = quitDays.value
	if (todayChecked.value) {
		if (d >= 30) return '太棒了！坚持一个月以上，你已经战胜了最难的部分'
		if (d >= 7)  return '一周没抽了！身体正在快速恢复中'
		if (d >= 3)  return '三天没抽了，最难的时期正在过去'
		return '今天打卡成功，继续保持！'
	}
	if (d === 0) return '迈出第一步，从今天开始无烟生活'
	if (d < 3)   return '坚持住，前三天是最关键的'
	if (d < 7)   return '你已经走了很远，继续加油'
	return `已坚持 ${d} 天，你很了不起`
})

// 静态数据：肺泡动画气泡配置
const lungBubbleItems = [
	{ id: 1, left: '18rpx', delay: '0s', duration: '4.6s' },
	{ id: 2, left: '64rpx', delay: '1.2s', duration: '5.2s' },
	{ id: 3, left: '116rpx', delay: '0.8s', duration: '4.9s' },
	{ id: 4, left: '158rpx', delay: '1.8s', duration: '5.5s' }
]

// 静态数据：打卡庆祝放射线（8 根均匀分布）
const celebrationBursts = Array.from({ length: 8 }, (_, i) => ({ id: i + 1, rotate: i * 45 }))

// 健康里程碑（天数节点）
const healthMilestones = computed(() => [
	{ days: 1, label: '1天' }, { days: 7, label: '1周' },
	{ days: 30, label: '1月' }, { days: 90, label: '3月' }, { days: 365, label: '1年' }
])

const nextHealthMilestone = computed(() => healthMilestones.value.find(m => quitDays.value < m.days) || null)
const nextHealthMilestoneText = computed(() => nextHealthMilestone.value ? `${nextHealthMilestone.value.label} 里程碑` : '已完成全年恢复')
const smokeFreeTimeLabel = computed(() => quitDays.value >= 1 ? `${quitDays.value} 天` : '刚开始')

const lungRecoveryFillStyle = computed(() => ({
	height: `${Math.max(hpValue.value, 6)}%`,
	background: `linear-gradient(180deg, ${hpState.value.soft} 0%, ${hpState.value.accent} 100%)`
}))

const lungPhaseLabel = computed(() => {
	const hp = hpValue.value
	if (hp >= 100) return '肺部状态已进入长期巩固阶段'
	if (hp >= 80) return '当前恢复速度很稳定'
	if (hp >= 60) return '肺部恢复节奏正在变强'
	if (hp >= 40) return '身体正在持续找回呼吸效率'
	if (hp >= 20) return '恢复已经启动，别让节奏断掉'
	return '先把今天守住，HP 就会慢慢往上走'
})

const lungRecoverySummary = computed(() => {
	const suffix = nextHealthMilestone.value
		? `，距离下一阶段还差 ${Math.max(nextHealthMilestone.value.days - quitDays.value, 0)} 天。`
		: '，已经进入长期巩固阶段。'
	return healthTip.value + suffix
})

const lungMomentumText = computed(() => {
	const hp = hpValue.value
	if (hp >= 100) return '稳定达成'
	if (hp >= 70)  return '恢复加速中'
	if (hp >= 35)  return '持续回升'
	return '刚刚启动'
})

const lungRecoveryCaption = computed(() => {
	if (!nextHealthMilestone.value) return '所有关键节点已完成'
	return `${Math.max(nextHealthMilestone.value.days - quitDays.value, 0)} 天后解锁 ${nextHealthMilestone.value.label}`
})

// 6 个关键健康恢复节点及进度
const healthMilestoneItems = computed(() => {
	const milestones = [
		{ name: '血压心率恢复', minutes: 20 },
		{ name: '一氧化碳排出', minutes: 480 },
		{ name: '尼古丁代谢完', minutes: 4320 },
		{ name: '味觉嗅觉恢复', minutes: 43200 },
		{ name: '血液循环改善', minutes: 129600 },
		{ name: '肺功能提升',   minutes: 525600 }
	]
	const minutes = quitDays.value * 1440
	return milestones.map(m => ({
		name: m.name,
		percent: Math.min(Math.round((minutes / m.minutes) * 100), 100)
	}))
})

const activeGoalText = computed(() => {
	const goal = quitHomeData.value?.goal
	if (!goal) return '设定一个小目标，攒钱实现它'
	const remaining = goal.target_amount_cent - (goal.current_amount_cent || 0)
	if (remaining <= 0) return `「${goal.title}」已攒够！`
	return `「${goal.title}」还差 ¥${Math.round(remaining / 100)}`
})

const bioAvatarText = computed(() => achievementData.value?.theme_icon || '净')
const bioRankText = computed(() => achievementData.value?.current?.name || '意志骑士')
const bioLevelText = computed(() => `Lv.${Math.max(1, Math.floor(quitDays.value / 7) + 1)}`)
const bioHpBarStyle = computed(() => ({ width: `${hpValue.value}%` }))
const bioBuffText = computed(() => `深度含氧（已坚持 ${smokeFreeTimeLabel.value}）`)

const bioHealthItems = computed(() => {
	const items = healthMilestoneItems.value
	return [
		{ name: '呼吸系统', value: `+${items[5]?.percent || 0}%` },
		{ name: '心脏功能', value: `+${items[0]?.percent || 0}%` },
		{ name: '血液纯净', value: `+${items[1]?.percent || 0}%` }
	]
})

const bioTrendItems = computed(() => {
	const labels = ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
	const step = Math.max(3, Math.round(Math.max(hpValue.value, 12) / 16))
	return labels.map((label, index) => {
		const value = Math.min(100, Math.max(12, hpValue.value - (6 - index) * step))
		return {
			label,
			height: `${Math.max(24, Math.round(value * 0.9))}rpx`,
			active: index === labels.length - 1
		}
	})
})

// ========== 工具函数 ==========

function defaultQuitState() {
	return { lastCheckinDate: '', lastCheckinAt: '', streakDays: 0 }
}

/** 两日期之间的天数差（有符号，floor），用于判断打卡是否连续 */
function diffDays(fromDate, toDate) {
	if (!fromDate || !toDate) return 0
	const from = new Date(`${fromDate}T00:00:00`)
	const to = new Date(`${toDate}T00:00:00`)
	if (Number.isNaN(from.getTime()) || Number.isNaN(to.getTime())) return 0
	return Math.floor((to.getTime() - from.getTime()) / 86400000)
}

/** 将 ISO 时间字符串格式化为 HH:MM，无效时返回 '--:--' */
function formatClock(value) {
	if (!value) return '--:--'
	const date = new Date(value)
	return Number.isNaN(date.getTime()) ? '--:--' : formatTime(date)
}

function setupNavBar() {
	const systemInfo = uni.getSystemInfoSync()
	const statusBarH = systemInfo.statusBarHeight || 0
	try {
		const menuBtn = uni.getMenuButtonBoundingClientRect()
		navBarHeight.value = menuBtn.bottom + (menuBtn.top - statusBarH)
	} catch {
		navBarHeight.value = statusBarH + 44
	}
}

// ========== 本地状态持久化 ==========

function loadQuitState() {
	quitState.value = { ...defaultQuitState(), ...(storage.get(QUIT_CHECKIN_KEY) || {}) }
}

function saveQuitState(nextState) {
	quitState.value = { ...defaultQuitState(), ...nextState }
	storage.set(QUIT_CHECKIN_KEY, quitState.value)
}

// ========== 计时器 ==========

function startTimer() {
	stopTimer()
	if (timerBaseSeconds.value < 0) return
	timerInterval = setInterval(() => { timerSeconds.value++ }, 1000)
}

function stopTimer() {
	if (!timerInterval) return
	clearInterval(timerInterval)
	timerInterval = null
}

// ========== 交互 ==========

function playQuitCheckinCelebration() {
	// 先重置再触发，避免重复动画
	checkinCelebrating.value = false
	if (checkinCelebrationTimer) { clearTimeout(checkinCelebrationTimer); checkinCelebrationTimer = null }
	setTimeout(() => {
		checkinCelebrating.value = true
		try { uni.vibrateShort() } catch { /* 部分平台不支持震动，忽略 */ }
		checkinCelebrationTimer = setTimeout(() => {
			checkinCelebrating.value = false
			checkinCelebrationTimer = null
		}, 1800)
	}, 20)
}

function openSmokeDialog() { openDetailedSmokeDialog() }
function openDetailedSmokeDialog() { dialogType.value = 'smoke'; dialogQuickMode.value = false; showDialog.value = true }
function gotoDreamGoals() { uni.navigateTo({ url: '/pages/dream-goals/index' }) }

function buildQuickSmokePayload() {
	const now = new Date()
	const dateStr = formatDate(now)
	const timeStr = `${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')}`
	return {
		smoke_time: dateStr,
		smoke_at: `${dateStr} ${timeStr}:00`,
		remark: '',
		reason_tags: [],
		level: 2,
		num: 1
	}
}

// ========== API 调用 ==========

function applyHomeData(data) {
	homeData.value = data
	const seconds = data?.timer?.seconds_since_last
	timerBaseSeconds.value = typeof seconds === 'number' ? seconds : -1
	timerSeconds.value = 0
	startTimer()
}

async function fetchRecordHomeData() {
	const res = await api.getHome()
	applyHomeData(res.data || {})
}

async function fetchAchievement() {
	try {
		const res = await api.getAchievement()
		achievementData.value = res.data?.achievement || null
	} catch (e) {
		console.error('fetchAchievement error:', e)
	}
}

function applyQuitHomeData(data) {
	if (!data) return
	quitHomeData.value = data
	if (data.daily_status?.status === 'checked_in' && data.daily_status?.checkin_at) {
		saveQuitState({
			lastCheckinDate: data.daily_status.date,
			lastCheckinAt: data.daily_status.checkin_at,
			streakDays: data.summary?.current_streak_days || 0
		})
	}
}

async function fetchQuitHomeData() {
	try {
		const res = await api.getQuitCheckinHome()
		applyQuitHomeData(res.data)
	} catch (e) {
		const msg = e?.message || ''
		if (msg.includes('基础资料')) {
			// 首次使用戒烟模式时后端要求先补填档案，自动补填后重试一次
			await ensureQuitProfile()
			try {
				const res = await api.getQuitCheckinHome()
				applyQuitHomeData(res.data)
			} catch (retryErr) {
				console.error('fetchQuitHomeData retry error:', retryErr)
				loadQuitState()
			}
		} else {
			console.error('fetchQuitHomeData error:', e)
			loadQuitState()
		}
	}
}

async function ensureQuitProfile() {
	const profile = profileStore.profile
	if (!profile) return
	await api.upsertQuitCheckinProfile({
		quit_start_date: formatDate(new Date()),
		pack_price_cent: profile.pack_price_cent || 2500,
		baseline_cigs_per_day: profile.baseline_cigs_per_day || 10
	})
}

async function submitQuitCheckin() {
	const today = formatDate(new Date())
	const res = await api.quitCheckin({ date: today })
	applyQuitHomeData(res.data)
	saveQuitState({
		lastCheckinDate: res.data?.daily_status?.date || today,
		lastCheckinAt: res.data?.daily_status?.checkin_at || new Date().toISOString(),
		streakDays: res.data?.summary?.current_streak_days || 0
	})
	await fetchQuitHomeData()
	await fetchAchievement()
	return res
}

async function handleSubmit(submitData) {
	try {
		await api.createLog(submitData)
		if (isQuitMode.value) {
			await fetchQuitHomeData()
			uni.showToast({ title: '已记下这次波动', icon: 'success' })
		} else {
			timerBaseSeconds.value = 0
			timerSeconds.value = 0
			startTimer()
			uni.showToast({ title: '记录成功', icon: 'success' })
		}
		if (isQuitMode.value) { await fetchAchievement(); return }
		await fetchRecordHomeData()
	} catch (e) {
		console.error('handleSubmit error:', e)
		uni.showToast({ title: '保存失败', icon: 'none' })
	}
}

async function quickRecordSmoke() {
	if (quickSubmitting.value) return
	quickSubmitting.value = true
	try {
		await handleSubmit(buildQuickSmokePayload())
	} finally {
		quickSubmitting.value = false
	}
}

async function handleQuitCheckin() {
	if (todayChecked.value) { uni.showToast({ title: '今天已经打过卡', icon: 'none' }); return }
	try {
		await submitQuitCheckin()
		playQuitCheckinCelebration()
		uni.showToast({ title: '打卡成功', icon: 'success' })
	} catch (e) {
		const message = e?.message || ''
		if (message.includes('基础资料')) {
			try {
				await ensureQuitProfile()
				await submitQuitCheckin()
				playQuitCheckinCelebration()
				uni.showToast({ title: '打卡成功', icon: 'success' })
			} catch (retryErr) {
				console.error('handleQuitCheckin retry error:', retryErr)
				uni.showToast({ title: retryErr?.message || '打卡失败，请重试', icon: 'none' })
			}
			return
		}
		console.error('handleQuitCheckin error:', e)
		uni.showToast({ title: message || '打卡失败，请重试', icon: 'none' })
	}
}

// 确认 profile 已完善，未完成则跳转 onboarding
async function ensureProfileReady() {
	const profileData = await profileStore.fetchProfile()
	const { profile, is_completed, exists } = profileData
	const completed = is_completed || !!profile?.onboarding_completed_at || (profile?.baseline_cigs_per_day > 0)
	if (!exists || !completed) {
		uni.navigateTo({ url: '/pages/onboarding/index' })
		return false
	}
	if (!userStore.mode) {
		userStore.setMode(profile?.mode || 'record')
	}
	return true
}

async function refreshCurrentMode() {
	if (!await ensureProfileReady()) return
	if (isQuitMode.value) {
		stopTimer()
		await Promise.all([fetchQuitHomeData(), fetchAchievement()])
		return
	}
	await Promise.all([fetchRecordHomeData(), fetchAchievement()])
}

async function initPage() {
	setupNavBar()
	loading.value = true
	try {
		await waitForLogin()
		await refreshCurrentMode()
	} catch (e) {
		console.error('initPage error:', e)
	} finally {
		pageReady.value = true
		loading.value = false
	}
}

onMounted(() => { initPage() })

onShow(async () => {
	if (!pageReady.value) return
	try { await refreshCurrentMode() } catch (e) { console.error('home onShow error:', e) }
})

onUnmounted(() => {
	stopTimer()
	if (checkinCelebrationTimer) { clearTimeout(checkinCelebrationTimer); checkinCelebrationTimer = null }
})

onShareAppMessage(() => ({
	title: isQuitMode.value ? '我在坚持戒烟打卡' : '我在记录自己的抽烟变化',
	path: 'pages/index/index'
}))
</script>

<style lang="scss" scoped>
// ===== 页面基础 =====
.page {
	min-height: 100vh;
	position: relative;
	background: $bg-page;
	overflow: hidden;
	box-sizing: border-box;
}

.page-record {
	background: linear-gradient(180deg, #F6F8F6 0%, #EFF4F1 52%, #E9F0EC 100%);
}

// ===== 背景装饰 =====
.bg-gradient {
	position: absolute;
	top: 0;
	left: 0;
	right: 0;
	height: 600rpx;
	background: linear-gradient(180deg, $color-primary-soft 0%, $color-primary-softer 40%, $bg-page 100%);
	pointer-events: none;
}

.bg-pattern {
	position: absolute;
	top: 0;
	left: 0;
	right: 0;
	height: 400rpx;
	background-image:
		radial-gradient(circle at 20% 30%, rgba($color-primary-dark, 0.08) 0%, transparent 50%),
		radial-gradient(circle at 80% 20%, rgba($color-primary, 0.06) 0%, transparent 40%);
	pointer-events: none;
}

// ===== 骨架屏 =====
.skeleton-wrap {
	padding: 48rpx $spacing-xl;
	position: relative;
	z-index: 1;
}

.sk-circle {
	width: 280rpx;
	height: 280rpx;
	border-radius: 50%;
	@include skeleton-shimmer;
	margin: 0 auto 48rpx;
}

.sk-row {
	height: 32rpx;
	border-radius: $radius-md;
	@include skeleton-shimmer;
	margin-bottom: $spacing-lg;

	&-short { width: 60%; }
}

.sk-card {
	height: 160rpx;
	border-radius: $radius-xl;
	@include skeleton-shimmer;
	margin-top: $spacing-xl;
}

@keyframes shimmer {
	0% { background-position: -200% 0; }
	100% { background-position: 200% 0; }
}

// ===== 主内容 =====
.nav-placeholder, .content {
	position: relative;
	z-index: 1;
}

.content {
	padding: $spacing-lg $spacing-lg 200rpx;
}

// ===== 戒烟模式 =====
.quit-home {
	@include flex-col;
	gap: $spacing-lg;
}

// 玻璃卡片基础样式
.quit-hero-card,
.quit-checkin-card,
.quit-health-card {
	position: relative;
	overflow: hidden;
	background: $gradient-card;
	-webkit-backdrop-filter: blur(20px);
	backdrop-filter: blur(20px);
	border-radius: $radius-2xl;
	border: 1rpx solid $border-light;
	box-shadow: $shadow-lg, 0 6rpx 14rpx rgba(15, 23, 42, 0.03), inset 0 1rpx 0 rgba(255, 255, 255, 0.88);

	&::before {
		content: '';
		position: absolute;
		width: 240rpx;
		height: 240rpx;
		left: -72rpx;
		top: -72rpx;
		border-radius: 50%;
		background: radial-gradient(circle, var(--hp-soft, rgba($color-primary, 0.18)) 0%, rgba($color-primary, 0) 72%);
		pointer-events: none;
	}
}

.quit-hero-card {
	padding: 28rpx $spacing-lg;
	--hp-accent: #{$color-primary-deeper};
	--hp-soft: #def7ec;
	--hp-deep: #0f766e;
}

.quit-hero-top,
.quit-overview,
.quit-health-header,
.quit-health-milestones {
	position: relative;
	z-index: 1;
}

.quit-hero-top {
	@include flex-between;
	align-items: flex-start;
	gap: $spacing-md;
	margin-bottom: 20rpx;
}

.quit-hero-copy {
	flex: 1;
	min-width: 0;
}

.quit-hero-eyebrow {
	@include chip;
	background: rgba($color-primary-softer, 0.94);
	border: 1rpx solid $border-light;
	color: $text-tertiary;
}

.quit-hero-title {
	display: block;
	margin-top: 10rpx;
	font-size: $font-lg;
	line-height: $line-height-normal;
	font-weight: $font-weight-bold;
	color: var(--hp-accent);
}

.quit-hero-chip {
	@include chip;
	flex-shrink: 0;
	padding: 10rpx 18rpx;
	background: rgba($color-primary-softer, 0.94);
	border: 1rpx solid $border-light;
	color: $color-primary-deeper;
}

.quit-overview {
	@include flex-col;
	gap: 18rpx;
}

// HP 面板
.quit-hp-panel {
	display: flex;
	align-items: center;
	gap: 18rpx;
	padding: 18rpx;
	border-radius: $radius-xl + 2rpx;
	background: linear-gradient(135deg, rgba(255, 255, 255, 0.94) 0%, rgba(248, 251, 249, 0.92) 100%);
	border: 1rpx solid $border-light;
	box-shadow: inset 0 1rpx 0 rgba(255, 255, 255, 0.92);
}

.quit-hp-ring {
	@include ring(200rpx);
	padding: 12rpx;
	box-shadow: 0 16rpx 34rpx rgba(15, 23, 42, 0.08);
}

.quit-hp-ring-inner {
	width: 100%;
	height: 100%;
	border-radius: 50%;
	background: linear-gradient(180deg, $bg-card 0%, $bg-card-hover 100%);
	@include flex-col;
	align-items: center;
	justify-content: center;
	box-shadow: inset 0 1rpx 0 rgba(255, 255, 255, 0.92);
	padding: 0 12rpx;
	text-align: center;
}

.quit-hp-ring-kicker {
	font-size: $font-xs;
	font-weight: $font-weight-bold;
	color: $text-tertiary;
}

.quit-hp-ring-value {
	margin-top: 10rpx;
	font-size: $font-display;
	font-weight: $font-weight-heavy;
	line-height: 1;
	color: var(--hp-accent);
	font-family: $font-family-number;
}

.quit-hp-ring-label {
	margin-top: $spacing-xs;
	padding: $spacing-xs $spacing-md;
	border-radius: $radius-full;
	background: var(--hp-soft);
	color: var(--hp-deep);
	font-size: $font-sm;
	font-weight: $font-weight-bold;
}

.quit-hp-copy {
	flex: 1;
	min-width: 0;
	@include flex-col;
	justify-content: center;
}

.quit-hp-title {
	display: block;
	font-size: $font-2xl;
	line-height: 1.35;
	font-weight: $font-weight-heavy;
	color: var(--hp-deep);
}

.quit-hp-desc {
	display: block;
	margin-top: 10rpx;
	font-size: 23rpx;
	line-height: $line-height-relaxed;
	color: $text-secondary;
}

.quit-hp-pill-row {
	display: flex;
	gap: $spacing-sm;
	margin-top: 18rpx;
}

.quit-hp-pill {
	flex: 1;
	min-width: 0;
	padding: 14rpx $spacing-md;
	border-radius: 18rpx;
	background: rgba(255, 255, 255, 0.8);
	border: 1rpx solid $border-light;

	&-strong {
		background: linear-gradient(180deg, var(--hp-soft) 0%, rgba(255, 255, 255, 0.88) 100%);
	}

	&-label {
		display: block;
		font-size: 18rpx;
		color: $text-muted;
	}

	&-value {
		display: block;
		margin-top: 6rpx;
		font-size: $font-sm;
		font-weight: $font-weight-bold;
		color: $text-primary;
	}
}

// 指标网格
.quit-metrics-grid {
	width: 100%;
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 14rpx;
}

.quit-metric-card {
	padding: 18rpx 18rpx 20rpx;
	border-radius: $radius-lg + 2rpx;
	background: $gradient-card-subtle;
	border: 1rpx solid $border-light;
	box-shadow: inset 0 1rpx 0 rgba(255, 255, 255, 0.92);

	&-wide { grid-column: 1 / -1; }
}

.quit-metric-kicker {
	display: block;
	font-size: $font-sm;
	color: $text-tertiary;
}

.quit-metric-value {
	display: block;
	margin-top: 10rpx;
	font-size: $font-2xl;
	line-height: $line-height-tight;
	font-weight: $font-weight-heavy;
	color: $text-primary;
	font-family: $font-family-number;
}

// 打卡卡片
.quit-checkin-card {
	@include flex-between;
	gap: 18rpx;
	padding: 26rpx $spacing-lg;

	&-done {
		background: linear-gradient(180deg, rgba($color-primary-softer, 0.98) 0%, rgba(249, 252, 250, 0.94) 100%);
	}
}

.quit-checkin-main {
	display: flex;
	align-items: center;
	gap: 18rpx;
	flex: 1;
	min-width: 0;
}

.quit-checkin-icon {
	width: 84rpx;
	height: 84rpx;
	border-radius: 28rpx;
	flex-shrink: 0;
	background: $gradient-primary;
	box-shadow: 0 16rpx 30rpx rgba($color-primary-dark, 0.22);
	@include flex-center;

	text {
		font-size: 36rpx;
		font-weight: $font-weight-bold;
		color: $text-inverse;
	}

	&-done {
		background: linear-gradient(180deg, #26b47f 0%, $color-primary-deeper 100%);
	}
}

.quit-checkin-copy {
	flex: 1;
	min-width: 0;
}

.quit-checkin-title {
	display: block;
	font-size: $font-2xl;
	font-weight: $font-weight-bold;
	color: $text-primary;
}

.quit-checkin-desc {
	display: block;
	margin-top: $spacing-xs;
	font-size: 23rpx;
	line-height: 1.6;
	color: $text-tertiary;
}

.quit-checkin-side {
	flex-shrink: 0;
	padding: $spacing-sm 18rpx;
	border-radius: $radius-full;
	background: rgba($color-primary-softer, 0.94);
	border: 1rpx solid $border-light;

	&-label {
		font-size: $font-sm;
		font-weight: $font-weight-semibold;
		color: $color-primary-deeper;
	}
}

// 健康卡片
.quit-health-card {
	padding: 26rpx $spacing-lg $spacing-lg;
}

.quit-health-header {
	@include flex-between;
	gap: $spacing-md;
	margin-bottom: 20rpx;
}

.quit-health-title {
	display: block;
	font-size: $font-xl;
	font-weight: $font-weight-bold;
	color: $text-primary;
}

.quit-health-badge {
	@include chip;
	background: rgba($color-primary-softer, 0.94);
	border: 1rpx solid $border-light;
	color: $color-primary-deeper;

	&-done {
		background: linear-gradient(135deg, $color-success, $color-primary-deeper);
		color: $text-inverse;
		border-color: transparent;
	}
}

// 破戒入口
.quit-slip-entry {
	@include flex-between;
	gap: $spacing-md;
	padding: 22rpx $spacing-lg;
	border-radius: $radius-xl;
	background: linear-gradient(135deg, var(--hp-soft, #def7ec) 0%, rgba(255, 255, 255, 0.96) 100%);
	border: 1rpx solid $border-light;
	box-shadow: 0 10rpx $spacing-lg rgba(15, 23, 42, 0.05);
}

.quit-slip-copy {
	flex: 1;
	min-width: 0;
}

.quit-slip-title {
	display: block;
	font-size: $font-lg;
	font-weight: $font-weight-bold;
	color: $text-primary;
}

.quit-slip-desc {
	display: block;
	margin-top: $spacing-xs;
	font-size: $font-sm;
	line-height: 1.6;
	color: $text-tertiary;
}

.quit-slip-action {
	flex-shrink: 0;
	padding: $spacing-md 18rpx;
	border-radius: 18rpx;
	background: linear-gradient(180deg, var(--hp-accent, $color-primary-deeper) 0%, var(--hp-deep, #0f766e) 100%);
	box-shadow: 0 14rpx 26rpx rgba($color-primary-deeper, 0.2);

	&-main {
		display: block;
		font-size: $font-base;
		font-weight: $font-weight-bold;
		color: $text-inverse;
	}

	&-sub {
		display: block;
		margin-top: 6rpx;
		font-size: 19rpx;
		color: rgba(255, 255, 255, 0.82);
	}
}

// 里程碑
.quit-milestone-list {
	position: relative;
	z-index: 1;
	@include flex-col;
	gap: $spacing-md;
}

.quit-ms-item { position: relative; }

.quit-ms-top {
	@include flex-between;
	margin-bottom: $spacing-xs;
}

.quit-ms-name {
	font-size: $font-base;
	color: #374151;
	font-weight: $font-weight-medium;
}

.quit-ms-pct {
	font-size: $font-sm;
	color: $text-muted;
	font-weight: $font-weight-semibold;

	&-done { color: $color-primary-deeper; }
}

.quit-ms-bar {
	@include progress-bar;
}

.quit-ms-fill {
	@include progress-fill;

	&-done { background: linear-gradient(90deg, $color-primary, $color-primary-deeper); }
	&-pending { background: rgba($color-primary, 0.3); }
}

// 成就内联
.quit-ach-inline {
	@include flex-between;
	gap: $spacing-md;
	margin-top: 20rpx;
	padding: 18rpx 20rpx;
	border-radius: $radius-lg + 2rpx;
	background: linear-gradient(180deg, #f5fbf9 0%, #eef6f2 100%);
	border: 1rpx solid $border-light;
	position: relative;
	z-index: 1;
}

.quit-ach-left {
	display: flex;
	align-items: center;
	gap: $spacing-sm;
	flex-shrink: 0;
}

.quit-ach-icon {
	font-size: 36rpx;
	line-height: 1;
}

.quit-ach-info {
	@include flex-col;
}

.quit-ach-rank {
	font-size: $font-lg;
	font-weight: $font-weight-heavy;
	color: $color-primary-deeper;
	line-height: $line-height-tight;
}

.quit-ach-theme {
	font-size: $font-xs;
	color: $text-muted;
	margin-top: 2rpx;
}

.quit-ach-right {
	flex: 1;
	min-width: 0;
	display: flex;
	align-items: center;
	justify-content: flex-end;
}

.quit-ach-progress-area {
	width: 100%;
	max-width: 280rpx;
}

.quit-ach-bar {
	@include progress-bar(8rpx);
}

.quit-ach-fill {
	@include progress-fill;
}

.quit-ach-hint {
	display: block;
	margin-top: 6rpx;
	font-size: $font-xs;
	color: $text-muted;
	text-align: right;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}

.quit-ach-max {
	font-size: $font-xs;
	color: $color-primary-deeper;
	font-weight: $font-weight-semibold;
}

// 梦想入口
.quit-dream-entry {
	@include flex-between;
	padding: 22rpx $spacing-lg;
	background: $gradient-card;
	border-radius: $radius-xl;
	border: 1rpx solid $border-light;
	box-shadow: 0 8rpx 20rpx rgba(15, 23, 42, 0.04);
}

.quit-dream-left {
	display: flex;
	align-items: center;
	gap: $spacing-md;
	flex: 1;
	min-width: 0;
}

.quit-dream-icon {
	font-size: 36rpx;
	flex-shrink: 0;
}

.quit-dream-info {
	flex: 1;
	min-width: 0;
}

.quit-dream-title {
	display: block;
	font-size: $font-lg;
	font-weight: $font-weight-bold;
	color: $text-primary;
}

.quit-dream-desc {
	display: block;
	margin-top: 4rpx;
	font-size: $font-sm;
	color: $text-muted;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.quit-dream-arrow {
	font-size: 36rpx;
	color: $text-disabled;
	flex-shrink: 0;
	font-weight: 300;
}

// 提示栏
.quit-tip-bar {
	display: flex;
	align-items: center;
	gap: $spacing-xs;
	padding: 14rpx 18rpx;
	border-radius: $radius-md;
	background: rgba($color-primary-softer, 0.6);
	border: 1rpx solid rgba(15, 23, 42, 0.03);
}

.quit-tip-icon {
	font-size: $font-sm;
	flex-shrink: 0;
}

.quit-tip-text {
	font-size: $font-xs;
	line-height: $line-height-normal;
	color: $text-muted;
}

// ===== 记录模式 =====
.record-home {
	@include flex-col;
	gap: $spacing-lg;
}

.record-hero-card,
.record-insight-card,
.record-achievement-card {
	position: relative;
	overflow: hidden;
	border-radius: 36rpx;
	background: rgba(255, 255, 255, 0.86);
	-webkit-backdrop-filter: blur(22px);
	backdrop-filter: blur(22px);
	border: 1rpx solid rgba(255, 255, 255, 0.82);
	box-shadow: 0 24rpx 60rpx rgba(23, 55, 46, 0.08), inset 0 1rpx 0 rgba(255, 255, 255, 0.96);
}

.record-hero-card {
	padding: 32rpx;
	background:
		linear-gradient(145deg, rgba(255, 255, 255, 0.92) 0%, rgba(241, 250, 246, 0.9) 56%, rgba(232, 244, 238, 0.88) 100%);
}

.record-hero-card-empty {
	background:
		linear-gradient(145deg, rgba(255, 255, 255, 0.94) 0%, rgba(244, 250, 247, 0.92) 56%, rgba(237, 247, 242, 0.9) 100%);
}

.record-hero-bg {
	position: absolute;
	border-radius: 50%;
	pointer-events: none;
	filter: blur(2rpx);
}

.record-hero-bg-one {
	width: 360rpx;
	height: 360rpx;
	right: -138rpx;
	top: -150rpx;
	background: radial-gradient(circle, rgba(31, 191, 143, 0.2) 0%, rgba(31, 191, 143, 0) 70%);
}

.record-hero-bg-two {
	width: 280rpx;
	height: 280rpx;
	left: -120rpx;
	bottom: -132rpx;
	background: radial-gradient(circle, rgba(14, 165, 233, 0.12) 0%, rgba(14, 165, 233, 0) 72%);
}

.record-hero-header,
.record-hero-body,
.record-action-card {
	position: relative;
	z-index: 1;
}

.record-hero-header {
	@include flex-between;
	align-items: flex-start;
	gap: $spacing-md;
	margin-bottom: 30rpx;
}

.record-hero-title-block {
	flex: 1;
	min-width: 0;
}

.record-hero-eyebrow {
	display: block;
	font-size: $font-sm;
	font-weight: $font-weight-semibold;
	letter-spacing: 2rpx;
	color: $color-primary-deeper;
}

.record-hero-title {
	display: block;
	margin-top: 10rpx;
	font-size: 46rpx;
	line-height: 1.16;
	font-weight: $font-weight-heavy;
	color: #13251f;
	letter-spacing: -0.8rpx;
}

.record-hero-chip {
	flex-shrink: 0;
	display: flex;
	align-items: baseline;
	padding: 14rpx 18rpx;
	border-radius: 22rpx;
	background: rgba(255, 255, 255, 0.76);
	border: 1rpx solid rgba(31, 191, 143, 0.12);
	box-shadow: inset 0 1rpx 0 rgba(255, 255, 255, 0.95);
}

.record-hero-chip-value {
	font-size: $font-2xl;
	font-weight: $font-weight-heavy;
	line-height: 1;
	color: $color-primary-deeper;
	font-family: $font-family-number;
}

.record-hero-chip-label {
	font-size: $font-xs;
	font-weight: $font-weight-semibold;
	color: $text-muted;
}

.record-hero-body {
	@include flex-col;
	gap: 22rpx;
}

.record-timer-panel {
	display: flex;
	align-items: center;
	gap: 24rpx;
	padding: 24rpx;
	border-radius: 32rpx;
	background: rgba(255, 255, 255, 0.66);
	border: 1rpx solid rgba(255, 255, 255, 0.86);
	box-shadow: inset 0 1rpx 0 rgba(255, 255, 255, 0.9);
}

.record-ring {
	@include ring(220rpx);
	flex-shrink: 0;
	padding: 12rpx;
	box-shadow: 0 18rpx 34rpx rgba(31, 191, 143, 0.12), inset 0 2rpx 8rpx rgba(15, 23, 42, 0.04);
}

.record-ring-inner {
	width: 100%;
	height: 100%;
	border-radius: 50%;
	background: linear-gradient(180deg, rgba(255, 255, 255, 0.98) 0%, rgba(247, 252, 249, 0.96) 100%);
	box-shadow: inset 0 1rpx 0 rgba(255, 255, 255, 1);
	@include flex-col;
	align-items: center;
	justify-content: center;
	text-align: center;
	padding: 0 18rpx;
}

.record-ring-kicker,
.record-ring-label {
	font-size: 20rpx;
	font-weight: $font-weight-semibold;
	color: $text-muted;
}

.record-ring-value {
	margin: 8rpx 0;
	font-size: 38rpx;
	line-height: 1;
	font-weight: $font-weight-heavy;
	color: $color-primary-deeper;
	font-family: $font-family-number;
	letter-spacing: -1rpx;
}

.record-progress-copy {
	flex: 1;
	min-width: 0;
}

.record-progress-row {
	@include flex-between;
	gap: $spacing-sm;
	margin-bottom: 12rpx;
}

.record-progress-label,
.record-progress-value {
	font-size: $font-sm;
	font-weight: $font-weight-bold;
	color: $text-secondary;
}

.record-progress-value { color: $color-primary-deeper; }

.record-progress-track {
	height: 16rpx;
	border-radius: $radius-full;
	background: rgba(213, 232, 223, 0.82);
	overflow: hidden;
}

.record-progress-fill {
	height: 100%;
	border-radius: inherit;
	background: linear-gradient(90deg, #1fbf8f 0%, #79ddbd 100%);
	box-shadow: 0 0 16rpx rgba(31, 191, 143, 0.32);
	transition: width 0.35s ease;
}

.record-progress-note {
	display: block;
	margin-top: 16rpx;
	font-size: $font-sm;
	line-height: $line-height-relaxed;
	color: $text-secondary;
}

.record-today-grid {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 18rpx;
}

.record-today-grid-single {
	grid-template-columns: 1fr;
}

.record-today-card {
	padding: 22rpx;
	border-radius: 28rpx;
	background: rgba(255, 255, 255, 0.7);
	border: 1rpx solid rgba(255, 255, 255, 0.86);
	box-shadow: inset 0 1rpx 0 rgba(255, 255, 255, 0.9);
}

.record-today-card-smoke { background: linear-gradient(145deg, rgba(255, 255, 255, 0.78) 0%, rgba(255, 247, 237, 0.68) 100%); }

.record-today-value {
	display: block;
	font-size: 48rpx;
	line-height: 1;
	font-weight: $font-weight-heavy;
	color: #14261f;
	font-family: $font-family-number;
}

.record-today-label {
	display: block;
	margin-top: 10rpx;
	font-size: $font-sm;
	font-weight: $font-weight-semibold;
	color: $text-muted;
}

.record-action-card {
	margin-top: 24rpx;
	padding: 24rpx;
	border-radius: 30rpx;
	background: rgba(18, 37, 31, 0.92);
	box-shadow: 0 18rpx 40rpx rgba(19, 37, 31, 0.14);
}

.record-action-title {
	display: block;
	font-size: $font-lg;
	font-weight: $font-weight-heavy;
	color: $text-inverse;
}

.record-action-desc {
	display: block;
	margin-top: 8rpx;
	font-size: $font-sm;
	line-height: $line-height-normal;
	color: rgba(255, 255, 255, 0.68);
}

.record-action-buttons {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 16rpx;
	margin-top: 22rpx;
}

.record-action-btn {
	height: 88rpx;
	border-radius: $radius-full;
	@include flex-center;
	gap: 10rpx;
	font-weight: $font-weight-heavy;
}

.record-action-btn-primary {
	background: linear-gradient(135deg, #1fbf8f 0%, #42d6a7 100%);
	box-shadow: 0 14rpx 26rpx rgba(31, 191, 143, 0.34);
	color: $text-inverse;
}

.record-action-btn-ghost {
	background: rgba(255, 255, 255, 0.1);
	border: 1rpx solid rgba(255, 255, 255, 0.18);
	color: $text-inverse;
}

.record-action-btn-disabled {
	opacity: 0.68;
	pointer-events: none;
}

.record-action-btn-icon {
	font-size: 30rpx;
	line-height: 1;
}

.record-action-btn-text {
	font-size: $font-base;
}

.record-insight-card {
	padding: 28rpx;
}

.record-section-header {
	@include flex-between;
	align-items: flex-start;
	gap: $spacing-md;
	margin-bottom: 22rpx;
}

.record-section-title {
	display: block;
	font-size: $font-xl;
	font-weight: $font-weight-heavy;
	color: #13251f;
}

.record-section-subtitle {
	display: block;
	margin-top: 6rpx;
	font-size: $font-sm;
	color: $text-muted;
}

.record-section-badge {
	flex-shrink: 0;
	padding: 10rpx 16rpx;
	border-radius: $radius-full;
	background: rgba(31, 191, 143, 0.1);
	color: $color-primary-deeper;
	font-size: $font-xs;
	font-weight: $font-weight-heavy;
}

.health-metrics {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: 14rpx;
}

.health-metric-item {
	@include flex-col;
	align-items: flex-start;
	gap: 14rpx;
	padding: 18rpx;
	min-height: 142rpx;
	background: linear-gradient(180deg, rgba(247, 251, 249, 0.96) 0%, rgba(241, 248, 245, 0.96) 100%);
	border-radius: 24rpx;
	border: 1rpx solid $border-light;
	box-shadow: inset 0 1rpx 0 rgba(255, 255, 255, 0.92);
}

.health-metric-icon {
	width: 48rpx;
	height: 48rpx;
	border-radius: 16rpx;
	@include flex-center;
	font-size: $font-base;
	font-weight: $font-weight-heavy;

	&-money { color: #a16207; background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%); }
	&-time { color: #075985; background: linear-gradient(135deg, #e0f2fe 0%, #bae6fd 100%); }
}

.health-metric-content { @include flex-col; }

.health-metric-value {
	font-size: $font-xl;
	font-weight: $font-weight-heavy;
	line-height: 1;
	color: $text-primary;
	font-family: $font-family-number;
}

.health-metric-label {
	margin-top: 8rpx;
	font-size: 21rpx;
	line-height: $line-height-normal;
	color: $text-tertiary;
}

.health-tip-bar {
	display: flex;
	align-items: flex-start;
	gap: 12rpx;
	margin-top: 20rpx;
	padding: 18rpx 20rpx;
	background: linear-gradient(135deg, rgba(236, 253, 245, 0.82) 0%, rgba(240, 249, 255, 0.7) 100%);
	border-radius: 24rpx;
	border: 1rpx solid rgba(31, 191, 143, 0.1);
}

.health-tip-icon {
	font-size: $font-base;
	color: $color-primary-deeper;
	font-weight: $font-weight-heavy;
}

.health-tip-text {
	flex: 1;
	font-size: $font-sm;
	color: $text-secondary;
	line-height: $line-height-relaxed;
}

.record-achievement-card {
	padding: 28rpx;
	background: linear-gradient(145deg, rgba(255, 255, 255, 0.9) 0%, rgba(248, 250, 252, 0.9) 100%);
}

.ach-header {
	@include flex-between;
	align-items: flex-start;
	gap: $spacing-md;
	margin-bottom: $spacing-md;
}

.ach-title {
	display: block;
	font-size: $font-md;
	font-weight: $font-weight-heavy;
	color: $text-primary;
}

.ach-theme-name {
	display: block;
	margin-top: 8rpx;
	font-size: $font-xs;
	color: $text-muted;
}

.ach-days {
	flex-shrink: 0;
	font-size: $font-xs;
	font-weight: $font-weight-bold;
	color: $color-primary-deeper;
	padding: 8rpx 14rpx;
	border-radius: $radius-full;
	background: rgba(31, 191, 143, 0.1);
}

.ach-body {
	position: relative;
	z-index: 1;
}

.ach-rank {
	display: block;
	font-size: $font-3xl;
	font-weight: $font-weight-heavy;
	color: $color-primary-deeper;
	font-family: $font-family-number;
	margin-bottom: $spacing-md;
}

.ach-progress-wrap { margin-bottom: 4rpx; }

.ach-progress-bar {
	@include progress-bar(12rpx);
	border-radius: 6rpx;
	margin-bottom: 10rpx;
}

.ach-progress-fill {
	@include progress-fill;
	border-radius: 6rpx;
}

.ach-next-hint {
	font-size: $font-sm;
	color: $text-tertiary;
}

.ach-max { margin-top: 4rpx; }

.ach-max-text {
	font-size: $font-sm;
	color: $color-primary-deeper;
	font-weight: $font-weight-semibold;
}

// ===== 庆祝弹窗 =====
.checkin-celebration-mask {
	position: fixed;
	inset: 0;
	background: rgba(15, 23, 42, 0.24);
	@include flex-center;
	z-index: 40;
	padding: 0 $spacing-2xl;
}

.checkin-celebration-card {
	position: relative;
	width: 100%;
	padding: 42rpx $spacing-2xl - 6rpx $spacing-2xl - 6rpx;
	border-radius: $radius-2xl;
	background: linear-gradient(180deg, rgba(255, 255, 255, 0.98) 0%, rgba(242, 251, 247, 0.96) 100%);
	box-shadow: 0 26rpx 56rpx rgba(15, 23, 42, 0.18);
	@include flex-col;
	align-items: center;
	animation: celebrateEnter 0.28s ease-out;
}

.checkin-celebration-burst {
	position: absolute;
	left: 50%;
	top: 82rpx;
	width: 0;
	height: 0;
}

.checkin-celebration-ray {
	position: absolute;
	left: 50%;
	top: 50%;
	width: 8rpx;
	height: 34rpx;
	margin-left: -4rpx;
	border-radius: $radius-full;
	background: linear-gradient(180deg, rgba($color-primary-light, 0.2) 0%, rgba($color-primary-deeper, 0.92) 100%);
}

.checkin-celebration-icon {
	position: relative;
	z-index: 1;
	width: 112rpx;
	height: 112rpx;
	border-radius: 50%;
	background: $gradient-primary;
	box-shadow: 0 18rpx 36rpx rgba($color-primary-deeper, 0.3);
	@include flex-center;
	font-size: $font-4xl;
	font-weight: $font-weight-heavy;
	color: $text-inverse;
	animation: pulseCheck 0.8s ease-out;
}

.checkin-celebration-title {
	display: block;
	margin-top: 26rpx;
	font-size: $font-2xl;
	font-weight: $font-weight-heavy;
	color: $text-primary;
}

.checkin-celebration-desc {
	display: block;
	margin-top: 10rpx;
	font-size: $font-base;
	line-height: $line-height-relaxed;
	color: $text-secondary;
	text-align: center;
}

.checkin-celebration-chip-row {
	width: 100%;
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 14rpx;
	margin-top: 26rpx;
}

.checkin-celebration-chip {
	padding: 18rpx $spacing-md;
	border-radius: $radius-lg;
	background: rgba(255, 255, 255, 0.76);
	border: 1rpx solid $border-light;
	text-align: center;

	&-label {
		display: block;
		font-size: $font-xs;
		color: $text-muted;
	}

	&-value {
		display: block;
		margin-top: $spacing-xs;
		font-size: $font-lg;
		font-weight: $font-weight-heavy;
		color: $color-primary-deeper;
	}
}

@keyframes breathBubble {
	0% {
		transform: translateY(0) scale(0.88);
		opacity: 0;
	}
	20% {
		opacity: 0.95;
	}
	100% {
		transform: translateY(-170rpx) scale(1.2);
		opacity: 0;
	}
}

@keyframes recordFabFloat {
	0%, 100% { transform: translateY(0); }
	50% { transform: translateY(-6rpx); }
}

@keyframes celebrateEnter {
	0% {
		opacity: 0;
		transform: translateY(24rpx) scale(0.94);
	}
	100% {
		opacity: 1;
		transform: translateY(0) scale(1);
	}
}

@keyframes celebrateGlow {
	0%, 100% {
		transform: translate(-50%, -50%) scale(0.96);
		opacity: 0.9;
	}
	50% {
		transform: translate(-50%, -50%) scale(1.04);
		opacity: 1;
	}
}

@keyframes pulseCheck {
	0% {
		transform: scale(0.82);
	}
	55% {
		transform: scale(1.08);
	}
	100% {
		transform: scale(1);
	}
}
// ===== UI.md 生物数据仪表盘首页 =====
.bio-home {
	--bio-hp-clear: #67E8F9;
	--bio-hp-life: #6EE7B7;
	--bio-amber: #D97706;
	--bio-gold: #FBBF24;
	--bio-lavender: #A78BFA;
	--bio-bg: #F8FAFC;
	--bio-text: #1E293B;
	@include flex-col;
	gap: 20rpx;
	color: var(--bio-text);
}

.bio-status-card,
.bio-console-card,
.bio-health-card,
.bio-trend-card,
.bio-action-card,
.bio-tip-card {
	position: relative;
	overflow: hidden;
	border: 1rpx solid rgba(255, 255, 255, 0.82);
	background: rgba(255, 255, 255, 0.72);
	box-shadow: 0 18rpx 44rpx rgba(30, 41, 59, 0.07);
	backdrop-filter: blur(12px);
}

.bio-status-card {
	padding: 28rpx;
	border-radius: 34rpx;
	background:
		linear-gradient(135deg, rgba(255, 255, 255, 0.76), rgba(240, 249, 255, 0.62)),
		radial-gradient(circle at top right, rgba(103, 232, 249, 0.22), transparent 36%);
}

.bio-breath-line {
	position: absolute;
	top: 0;
	left: 32rpx;
	right: 32rpx;
	height: 2rpx;
	background: linear-gradient(90deg, transparent, rgba(103, 232, 249, 0.58), rgba(110, 231, 183, 0.48), transparent);
	animation: bioBreathLine 6s ease-in-out infinite;
}

.bio-profile-row {
	display: flex;
	align-items: center;
	gap: 18rpx;
}

.bio-avatar {
	width: 76rpx;
	height: 76rpx;
	border-radius: 28rpx;
	@include flex-center;
	background: linear-gradient(135deg, rgba(110, 231, 183, 0.95), rgba(103, 232, 249, 0.88));
	box-shadow: 0 12rpx 28rpx rgba(20, 184, 166, 0.18);
	color: #ffffff;
	font-size: 34rpx;
	font-weight: 900;
}

.bio-profile-main {
	flex: 1;
	min-width: 0;
	@include flex-col;
	gap: 6rpx;
}

.bio-rank {
	font-size: 29rpx;
	line-height: 1.25;
	font-weight: 900;
	color: var(--bio-text);
}

.bio-level {
	font-size: 23rpx;
	font-weight: 800;
	color: #64748B;
}

.bio-subtitle {
	font-size: 21rpx;
	line-height: 1.45;
	color: #64748B;
}

.bio-coin-pill {
	flex-shrink: 0;
	display: flex;
	align-items: center;
	gap: 6rpx;
	padding: 10rpx 14rpx;
	border-radius: 999rpx;
	background: rgba(255, 251, 235, 0.78);
	border: 1rpx solid rgba(251, 191, 36, 0.22);
}

.bio-coin-icon,
.bio-coin-value {
	font-size: 22rpx;
	font-weight: 900;
	color: #92400E;
}

.bio-hp-box {
	margin-top: 30rpx;
	padding: 18rpx;
	border-radius: 26rpx;
	background: rgba(248, 250, 252, 0.72);
	border: 1rpx solid rgba(148, 163, 184, 0.12);
}

.bio-hp-track {
	position: relative;
	height: 24rpx;
	border-radius: 999rpx;
	overflow: hidden;
	background: linear-gradient(90deg, rgba(217, 119, 6, 0.18), rgba(226, 232, 240, 0.66));
}

.bio-hp-fill {
	position: absolute;
	top: 0;
	left: 0;
	height: 100%;
	border-radius: inherit;
	background: linear-gradient(90deg, var(--bio-hp-life), var(--bio-hp-clear));
	box-shadow: 0 0 18rpx rgba(103, 232, 249, 0.26);
	animation: bioHpPulse 5s ease-in-out infinite;
}

.bio-hp-clear {
	position: absolute;
	inset: 0;
	background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.28), transparent);
	animation: bioClearFlow 2s ease-in-out infinite;
}

.bio-hp-meta {
	margin-top: 12rpx;
	display: flex;
	justify-content: space-between;
	font-size: 22rpx;
	font-weight: 800;
	color: #475569;
}

.bio-buff-pill {
	align-self: flex-start;
	margin-top: 24rpx;
	display: inline-flex;
	align-items: center;
	gap: 8rpx;
	padding: 12rpx 18rpx;
	border-radius: 999rpx;
	border: 1rpx solid rgba(167, 139, 250, 0.44);
	background: rgba(250, 245, 255, 0.58);
	color: #6D28D9;
	font-size: 22rpx;
	font-weight: 800;
}

.bio-buff-star {
	color: var(--bio-lavender);
}

.bio-console-card {
	display: flex;
	align-items: center;
	gap: 20rpx;
	padding: 28rpx;
	border-radius: 34rpx;
	background:
		radial-gradient(circle at 18% 50%, rgba(110, 231, 183, 0.25), transparent 36%),
		linear-gradient(135deg, rgba(255, 255, 255, 0.8), rgba(236, 253, 245, 0.62));
}

.bio-console-orbit {
	width: 128rpx;
	height: 128rpx;
	border-radius: 50%;
	@include flex-center;
	background: conic-gradient(from 180deg, rgba(110, 231, 183, 0.9), rgba(103, 232, 249, 0.55), rgba(217, 119, 6, 0.22), rgba(110, 231, 183, 0.9));
}

.bio-console-core {
	width: 96rpx;
	height: 96rpx;
	border-radius: 50%;
	@include flex-center;
	background: #ffffff;
	color: #0F766E;
	font-size: 46rpx;
	font-weight: 900;
}

.bio-console-core-done {
	background: linear-gradient(135deg, var(--bio-hp-life), var(--bio-hp-clear));
	color: #ffffff;
}

.bio-console-copy {
	flex: 1;
	min-width: 0;
	@include flex-col;
	gap: 8rpx;
}

.bio-console-kicker {
	font-size: 19rpx;
	font-weight: 900;
	letter-spacing: 1.6rpx;
	color: #0891B2;
}

.bio-console-title {
	font-size: 31rpx;
	line-height: 1.25;
	font-weight: 900;
	color: var(--bio-text);
}

.bio-console-desc {
	font-size: 22rpx;
	line-height: 1.55;
	color: #64748B;
}

.bio-console-action {
	align-self: stretch;
	@include flex-center;
	min-width: 86rpx;
	padding: 0 18rpx;
	border-radius: 22rpx;
	background: linear-gradient(180deg, #FBBF24, #D97706);
	color: #ffffff;
	font-size: 23rpx;
	font-weight: 900;
}

.bio-health-card,
.bio-trend-card {
	padding: 28rpx;
	border-radius: 34rpx;
}

.bio-section-head {
	display: flex;
	align-items: flex-start;
	justify-content: space-between;
	gap: 18rpx;
}

.bio-section-head-compact {
	align-items: center;
}

.bio-section-title {
	display: block;
	font-size: 29rpx;
	font-weight: 900;
	color: var(--bio-text);
}

.bio-section-subtitle {
	display: block;
	margin-top: 8rpx;
	font-size: 21rpx;
	line-height: 1.45;
	color: #64748B;
}

.bio-section-chip {
	flex-shrink: 0;
	padding: 8rpx 14rpx;
	border-radius: 999rpx;
	background: rgba(236, 253, 245, 0.86);
	border: 1rpx solid rgba(110, 231, 183, 0.28);
	font-size: 20rpx;
	font-weight: 900;
	color: #0F766E;
}

.bio-health-body {
	margin-top: 24rpx;
	display: flex;
	align-items: center;
	gap: 26rpx;
}

.bio-health-ring {
	width: 166rpx;
	height: 166rpx;
	border-radius: 50%;
	padding: 12rpx;
	box-sizing: border-box;
	flex-shrink: 0;
}

.bio-health-ring-inner {
	width: 100%;
	height: 100%;
	border-radius: 50%;
	@include flex-center;
	flex-direction: column;
	background: rgba(255, 255, 255, 0.92);
	box-shadow: inset 0 0 0 1rpx rgba(148, 163, 184, 0.1);
}

.bio-health-ring-value {
	font-size: 34rpx;
	font-weight: 900;
	color: var(--bio-text);
}

.bio-health-ring-label {
	margin-top: 4rpx;
	font-size: 20rpx;
	font-weight: 800;
	color: #64748B;
}

.bio-health-metrics {
	flex: 1;
	min-width: 0;
	padding: 18rpx 20rpx;
	border-radius: 26rpx;
	background: linear-gradient(180deg, rgba(248, 250, 252, 0.78), rgba(255, 255, 255, 0.68));
	border: 1rpx solid rgba(148, 163, 184, 0.1);
}

.bio-health-row {
	display: flex;
	justify-content: space-between;
	gap: 14rpx;
	padding: 8rpx 0;
}

.bio-health-name {
	font-size: 22rpx;
	font-weight: 800;
	color: #475569;
}

.bio-health-value {
	font-size: 22rpx;
	font-weight: 900;
	color: #0F766E;
}

.bio-health-divider {
	height: 1rpx;
	margin: 12rpx 0 14rpx;
	background: rgba(148, 163, 184, 0.18);
}

.bio-life-row {
	@include flex-col;
	gap: 4rpx;
}

.bio-life-value {
	font-size: 34rpx;
	line-height: 1.2;
	font-weight: 900;
	color: var(--bio-gold);
}

.bio-life-label {
	font-size: 21rpx;
	font-weight: 800;
	color: #64748B;
}

.bio-trend-card {
	background: linear-gradient(135deg, #ECFDF5 0%, #F0F9FF 100%);
}

.bio-trend-chart {
	height: 176rpx;
	margin-top: 22rpx;
	padding: 0 4rpx;
	display: flex;
	align-items: flex-end;
	justify-content: space-between;
	border-bottom: 1rpx solid rgba(100, 116, 139, 0.18);
}

.bio-trend-col {
	flex: 1;
	min-width: 0;
	@include flex-center;
	flex-direction: column;
	justify-content: flex-end;
	gap: 10rpx;
}

.bio-trend-line {
	position: relative;
	width: 4rpx;
	border-radius: 999rpx;
	background: linear-gradient(180deg, rgba(103, 232, 249, 0.86), rgba(110, 231, 183, 0.44));
}

.bio-trend-dot {
	position: absolute;
	top: -8rpx;
	left: 50%;
	width: 16rpx;
	height: 16rpx;
	margin-left: -8rpx;
	border-radius: 50%;
	background: #67E8F9;
	box-shadow: 0 0 0 5rpx rgba(103, 232, 249, 0.14);
}

.bio-trend-dot-active {
	background: var(--bio-gold);
	box-shadow: 0 0 0 6rpx rgba(251, 191, 36, 0.18);
}

.bio-trend-label {
	font-size: 18rpx;
	color: #64748B;
}

.bio-action-grid {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 18rpx;
}

.bio-action-card {
	padding: 22rpx;
	border-radius: 28rpx;
	background: rgba(255, 255, 255, 0.74);
}

.bio-action-title {
	display: block;
	font-size: 25rpx;
	font-weight: 900;
	color: var(--bio-text);
}

.bio-action-desc {
	display: block;
	margin-top: 8rpx;
	font-size: 21rpx;
	line-height: 1.45;
	color: #64748B;
}

.bio-tip-card {
	display: flex;
	align-items: flex-start;
	gap: 12rpx;
	padding: 20rpx 22rpx;
	border-radius: 26rpx;
	background: rgba(250, 245, 255, 0.54);
	border-color: rgba(167, 139, 250, 0.2);
}

.bio-tip-icon {
	font-size: 24rpx;
	color: var(--bio-lavender);
	flex-shrink: 0;
}

.bio-tip-text {
	font-size: 22rpx;
	line-height: 1.55;
	color: #475569;
}

@keyframes bioHpPulse {
	0%, 100% { filter: brightness(1); }
	50% { filter: brightness(1.05); }
}

@keyframes bioClearFlow {
	0% { transform: translateX(-100%); opacity: 0.15; }
	50% { opacity: 0.28; }
	100% { transform: translateX(100%); opacity: 0.15; }
}

@keyframes bioBreathLine {
	0%, 100% { opacity: 0.1; }
	50% { opacity: 0.22; }
}
// ===== UI.md 记录模式生物数据仪表盘 =====
.record-bio-home {
	--record-clear: #67E8F9;
	--record-life: #6EE7B7;
	--record-amber: #D97706;
	--record-gold: #FBBF24;
	--record-lavender: #A78BFA;
	--record-text: #1E293B;
	@include flex-col;
	gap: 20rpx;
	color: var(--record-text);
}

.record-bio-status-card,
.record-bio-console-card,
.record-bio-health-card,
.record-bio-tip-card {
	position: relative;
	overflow: hidden;
	border: 1rpx solid rgba(255, 255, 255, 0.82);
	background: rgba(255, 255, 255, 0.72);
	box-shadow: 0 18rpx 44rpx rgba(30, 41, 59, 0.07);
	backdrop-filter: blur(12px);
}

.record-bio-status-card {
	padding: 28rpx;
	border-radius: 34rpx;
	background:
		linear-gradient(135deg, rgba(255, 255, 255, 0.76), rgba(240, 249, 255, 0.62)),
		radial-gradient(circle at top right, rgba(251, 191, 36, 0.17), transparent 34%);
}

.record-bio-breath-line {
	position: absolute;
	top: 0;
	left: 32rpx;
	right: 32rpx;
	height: 2rpx;
	background: linear-gradient(90deg, transparent, rgba(251, 191, 36, 0.38), rgba(103, 232, 249, 0.44), transparent);
	animation: bioBreathLine 6s ease-in-out infinite;
}

.record-bio-profile-row {
	display: flex;
	align-items: center;
	gap: 18rpx;
}

.record-bio-avatar-medal {
	position: relative;
	width: 96rpx;
	height: 96rpx;
	flex-shrink: 0;
	@include flex-center;
}

.record-bio-avatar-bg {
	position: absolute;
	inset: 0;
	width: 96rpx;
	height: 96rpx;
	border-radius: 30rpx;
	box-shadow: 0 12rpx 28rpx rgba(15, 118, 110, 0.12);
}

.record-bio-avatar-icon {
	position: relative;
	z-index: 1;
	font-size: 44rpx;
	line-height: 1;
}

.record-bio-profile-main {
	flex: 1;
	min-width: 0;
	@include flex-col;
	gap: 6rpx;
}

.record-bio-rank {
	font-size: 29rpx;
	line-height: 1.25;
	font-weight: 900;
	color: var(--record-text);
}

.record-bio-level {
	font-size: 23rpx;
	font-weight: 800;
	color: #64748B;
}

.record-bio-subtitle {
	font-size: 21rpx;
	line-height: 1.45;
	color: #64748B;
}

.record-bio-target-pill {
	flex-shrink: 0;
	display: flex;
	align-items: center;
	gap: 6rpx;
	padding: 10rpx 14rpx;
	border-radius: 999rpx;
	background: rgba(236, 253, 245, 0.82);
	border: 1rpx solid rgba(16, 185, 129, 0.16);
}

.record-bio-target-icon,
.record-bio-target-value {
	font-size: 22rpx;
	font-weight: 900;
	color: #0F766E;
}

.record-bio-title-panel {
	margin-top: 24rpx;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 16rpx;
	padding: 18rpx 20rpx;
	border-radius: 26rpx;
	background:
		radial-gradient(circle at 12% 30%, rgba(103, 232, 249, 0.2), transparent 34%),
		linear-gradient(135deg, rgba(255, 251, 235, 0.82), rgba(236, 253, 245, 0.72));
	border: 1rpx solid rgba(251, 191, 36, 0.18);
}

.record-bio-title-copy {
	min-width: 0;
	@include flex-col;
	gap: 4rpx;
}

.record-bio-title-kicker {
	font-size: 18rpx;
	font-weight: 900;
	letter-spacing: 1.2rpx;
	color: #0891B2;
}

.record-bio-title-name {
	font-size: 27rpx;
	line-height: 1.25;
	font-weight: 900;
	color: #0F766E;
}

.record-bio-title-hint {
	flex-shrink: 0;
	max-width: 280rpx;
	font-size: 20rpx;
	line-height: 1.4;
	font-weight: 800;
	text-align: right;
	color: #B45309;
}

.record-bio-hp-box {
	margin-top: 30rpx;
	padding: 18rpx;
	border-radius: 26rpx;
	background: rgba(248, 250, 252, 0.72);
	border: 1rpx solid rgba(148, 163, 184, 0.12);
}

.record-bio-hp-track {
	position: relative;
	height: 24rpx;
	border-radius: 999rpx;
	overflow: hidden;
	background: linear-gradient(90deg, rgba(217, 119, 6, 0.18), rgba(226, 232, 240, 0.66));
}

.record-bio-hp-fill {
	position: absolute;
	top: 0;
	left: 0;
	height: 100%;
	border-radius: inherit;
	background: linear-gradient(90deg, var(--record-life), var(--record-clear));
	box-shadow: 0 0 18rpx rgba(103, 232, 249, 0.26);
	animation: bioHpPulse 5s ease-in-out infinite;
}

.record-bio-hp-clear {
	position: absolute;
	inset: 0;
	background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.28), transparent);
	animation: bioClearFlow 2s ease-in-out infinite;
}

.record-bio-hp-meta {
	margin-top: 12rpx;
	display: flex;
	justify-content: space-between;
	font-size: 22rpx;
	font-weight: 800;
	color: #475569;
}

.record-bio-buff-pill {
	align-self: flex-start;
	margin-top: 24rpx;
	display: inline-flex;
	align-items: center;
	gap: 8rpx;
	padding: 12rpx 18rpx;
	border-radius: 999rpx;
	border: 1rpx solid rgba(167, 139, 250, 0.36);
	background: rgba(250, 245, 255, 0.58);
	color: #6D28D9;
	font-size: 22rpx;
	font-weight: 800;
}

.record-bio-buff-star {
	color: var(--record-lavender);
}

.record-bio-console-card {
	display: flex;
	align-items: center;
	gap: 22rpx;
	padding: 28rpx;
	border-radius: 34rpx;
	background:
		radial-gradient(circle at 18% 50%, rgba(251, 191, 36, 0.18), transparent 34%),
		linear-gradient(135deg, rgba(255, 255, 255, 0.8), rgba(236, 253, 245, 0.62));
}

.record-bio-console-left {
	flex-shrink: 0;
}

.record-bio-orbit {
	width: 154rpx;
	height: 154rpx;
	border-radius: 50%;
	padding: 12rpx;
	box-sizing: border-box;
}

.record-bio-orbit-inner {
	width: 100%;
	height: 100%;
	border-radius: 50%;
	@include flex-center;
	flex-direction: column;
	background: rgba(255, 255, 255, 0.94);
}

.record-bio-orbit-kicker,
.record-bio-orbit-label {
	font-size: 18rpx;
	font-weight: 800;
	color: #64748B;
}

.record-bio-orbit-value {
	margin: 5rpx 0;
	font-size: 24rpx;
	line-height: 1.1;
	font-weight: 900;
	color: var(--record-text);
}

.record-bio-console-main {
	flex: 1;
	min-width: 0;
	@include flex-col;
	gap: 8rpx;
}

.record-bio-console-kicker {
	font-size: 19rpx;
	font-weight: 900;
	letter-spacing: 1.6rpx;
	color: #0891B2;
}

.record-bio-console-title {
	font-size: 31rpx;
	line-height: 1.25;
	font-weight: 900;
	color: var(--record-text);
}

.record-bio-console-desc {
	font-size: 22rpx;
	line-height: 1.55;
	color: #64748B;
}

.record-bio-action-row {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 12rpx;
	margin-top: 12rpx;
}

.record-bio-action {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 8rpx;
	height: 64rpx;
	border-radius: 20rpx;
	font-size: 22rpx;
	font-weight: 900;
}

.record-bio-action-primary {
	background: linear-gradient(135deg, #FBBF24, #D97706);
	color: #ffffff;
	box-shadow: 0 10rpx 22rpx rgba(217, 119, 6, 0.16);
}

.record-bio-action-ghost {
	background: rgba(255, 255, 255, 0.78);
	border: 1rpx solid rgba(15, 118, 110, 0.16);
	color: #0F766E;
}

.record-bio-action-disabled {
	opacity: 0.58;
}

.record-bio-action-icon {
	font-size: 24rpx;
	font-weight: 900;
}

.record-bio-health-card {
	padding: 28rpx;
	border-radius: 34rpx;
}

.record-bio-section-head {
	display: flex;
	align-items: flex-start;
	justify-content: space-between;
	gap: 18rpx;
}

.record-bio-section-head-compact {
	align-items: center;
}

.record-bio-section-title {
	display: block;
	font-size: 29rpx;
	font-weight: 900;
	color: var(--record-text);
}

.record-bio-section-subtitle {
	display: block;
	margin-top: 8rpx;
	font-size: 21rpx;
	line-height: 1.45;
	color: #64748B;
}

.record-bio-section-chip {
	flex-shrink: 0;
	padding: 8rpx 14rpx;
	border-radius: 999rpx;
	background: rgba(255, 251, 235, 0.9);
	border: 1rpx solid rgba(251, 191, 36, 0.22);
	font-size: 20rpx;
	font-weight: 900;
	color: #B45309;
}

.record-bio-health-body {
	margin-top: 24rpx;
	display: flex;
	align-items: center;
	gap: 26rpx;
}

.record-bio-health-ring {
	width: 166rpx;
	height: 166rpx;
	border-radius: 50%;
	padding: 12rpx;
	box-sizing: border-box;
	flex-shrink: 0;
}

.record-bio-health-ring-inner {
	width: 100%;
	height: 100%;
	border-radius: 50%;
	@include flex-center;
	flex-direction: column;
	background: rgba(255, 255, 255, 0.92);
	box-shadow: inset 0 0 0 1rpx rgba(148, 163, 184, 0.1);
}

.record-bio-health-ring-value {
	font-size: 36rpx;
	font-weight: 900;
	color: var(--record-text);
}

.record-bio-health-ring-label {
	margin-top: 4rpx;
	font-size: 20rpx;
	font-weight: 800;
	color: #64748B;
}

.record-bio-metrics {
	flex: 1;
	min-width: 0;
	padding: 18rpx 20rpx;
	border-radius: 26rpx;
	background: linear-gradient(180deg, rgba(248, 250, 252, 0.78), rgba(255, 255, 255, 0.68));
	border: 1rpx solid rgba(148, 163, 184, 0.1);
}

.record-bio-metric-row {
	display: flex;
	justify-content: space-between;
	gap: 14rpx;
	padding: 8rpx 0;
}

.record-bio-metric-name {
	font-size: 22rpx;
	font-weight: 800;
	color: #475569;
}

.record-bio-metric-value {
	font-size: 22rpx;
	font-weight: 900;
	color: #0F766E;
}

.record-bio-tip-card {
	display: flex;
	align-items: flex-start;
	gap: 12rpx;
	padding: 20rpx 22rpx;
	border-radius: 26rpx;
	background: rgba(250, 245, 255, 0.54);
	border-color: rgba(167, 139, 250, 0.2);
}

.record-bio-tip-icon {
	font-size: 24rpx;
	color: var(--record-lavender);
	flex-shrink: 0;
}

.record-bio-tip-text {
	font-size: 22rpx;
	line-height: 1.55;
	color: #475569;
}
</style>
