<template>
	<view class="growth-page" :style="{ background: themeConfig.bgColor }">
		<view class="bg-decoration">
			<view class="deco-blob deco-1" :style="{ background: `radial-gradient(circle, ${themeConfig.primaryColor}28 0%, transparent 70%)` }"></view>
			<view class="deco-blob deco-2" :style="{ background: `radial-gradient(circle, ${themeConfig.secondaryColor}22 0%, transparent 70%)` }"></view>
			<view class="deco-blob deco-3" :style="{ background: `radial-gradient(circle, ${themeConfig.accentColor}18 0%, transparent 70%)` }"></view>
		</view>

		<scroll-view class="scroll-container" scroll-y :show-scrollbar="false">
			<view class="header-card" :style="{ background: themeConfig.gradientVibrant, boxShadow: `0 16rpx 48rpx ${themeConfig.shadowColor}` }">
				<view class="card-bg">
					<view class="bg-orb"></view>
					<view class="bg-grid"></view>
					<view class="bg-float-shape shape-1" :style="{ background: `linear-gradient(135deg, rgba(255,255,255,0.25) 0%, rgba(255,255,255,0.08) 100%)` }"></view>
					<view class="bg-float-shape shape-2" :style="{ background: `linear-gradient(135deg, ${themeConfig.secondaryColor}40 0%, transparent 100%)` }"></view>
				</view>
				<view class="card-content">
					<view class="user-card">
						<view class="avatar-ring" :style="{ background: 'rgba(255, 255, 255, 0.25)' }">
							<FaIcon v-if="growthInfo.levelIcon && growthInfo.levelIcon.startsWith && !growthInfo.levelIcon.startsWith('\\u')" :icon="growthInfo.levelIcon" :size="40"  />
						<FaIcon v-else icon="trophy" :size="40" color="#fff" />
						</view>
						<view class="user-info">
							<text class="user-name">{{ growthInfo.levelTitle || '记录小白' }}</text>
							<view class="level-badge" :style="{ background: 'rgba(255, 255, 255, 0.2)' }">
								<text>Lv.{{ growthInfo.currentLevel }}</text>
							</view>
						</view>
					</view>
					
					<view class="exp-section">
						<view class="exp-header">
							<text class="exp-label">当前经验</text>
							<view class="exp-value">
								<text class="exp-current">{{ animatedExp }}</text>
								<text class="exp-divider">/</text>
								<text class="exp-max">{{ growthInfo.nextLevelExp }} EXP</text>
							</view>
						</view>
						<view class="progress-wrapper">
							<view class="progress-bar" :style="{ background: 'rgba(255, 255, 255, 0.25)' }">
								<view class="progress-fill" :style="{ width: animatedProgress + '%', background: 'linear-gradient(90deg, #fff 0%, rgba(255,255,255,0.8) 100%)' }">
									<view class="progress-shine"></view>
								</view>
							</view>
							<view class="progress-text">{{ animatedProgress }}%</view>
						</view>
					</view>
				</view>
			</view>

			<view class="content-area">
				<view class="stats-row">
					<view class="stat-item" :style="{ background: themeConfig.cardBgColor, boxShadow: `0 6rpx 24rpx ${themeConfig.shadowLight}` }">
						<view class="stat-icon-wrap" :style="{ background: `${themeConfig.primaryColor}12` }">
							<FaIcon icon="calendar-check" :size="22" :color="themeConfig.primaryColor" />
						</view>
						<text class="stat-num" :style="{ color: themeConfig.textPrimary }">{{ growthInfo.totalDays }}</text>
						<text class="stat-label" :style="{ color: themeConfig.textSecondary }">累计天数</text>
					</view>
					<view class="stat-item" :style="{ background: themeConfig.cardBgColor, boxShadow: `0 6rpx 24rpx ${themeConfig.shadowLight}` }">
						<view class="stat-icon-wrap" :style="{ background: `${themeConfig.warningColor}12` }">
							<FaIcon icon="fire" :size="22" :color="themeConfig.warningColor" />
						</view>
						<text class="stat-num" :style="{ color: themeConfig.textPrimary }">{{ growthInfo.streakDays }}</text>
						<text class="stat-label" :style="{ color: themeConfig.textSecondary }">连续打卡</text>
					</view>
					<view class="stat-item" :style="{ background: themeConfig.cardBgColor, boxShadow: `0 6rpx 24rpx ${themeConfig.shadowLight}` }">
						<view class="stat-icon-wrap" :style="{ background: `${themeConfig.successColor}12` }">
							<FaIcon icon="trophy" :size="22" :color="themeConfig.successColor" />
						</view>
						<text class="stat-num" :style="{ color: themeConfig.textPrimary }">{{ growthInfo.maxStreakDays }}</text>
						<text class="stat-label" :style="{ color: themeConfig.textSecondary }">最高连续</text>
					</view>
				</view>

				<view class="rules-entry" :style="{ background: themeConfig.cardBgColor, boxShadow: `0 8rpx 32rpx ${themeConfig.shadowLight}` }" @click="goToRules">
					<view class="entry-icon" :style="{ background: `linear-gradient(135deg, ${themeConfig.primaryColor}15 0%, ${themeConfig.secondaryColor}10 100%)` }">
						<FaIcon icon="book-open" :size="24" :color="themeConfig.primaryColor" />
					</view>
					<view class="entry-text">
						<text class="entry-title" :style="{ color: themeConfig.textPrimary }">成长规则</text>
						<text class="entry-desc" :style="{ color: themeConfig.textSecondary }">了解升级攻略和特权说明</text>
					</view>
					<view class="entry-arrow" :style="{ background: `${themeConfig.primaryColor}12` }">
						<FaIcon icon="chevron-right" :size="14" :color="themeConfig.primaryColor" />
					</view>
				</view>

				<view class="module-card" :style="{ background: themeConfig.cardBgColor, boxShadow: `0 8rpx 32rpx ${themeConfig.shadowLight}` }">
					<view class="module-header">
						<view class="module-icon-wrap" :style="{ background: `${themeConfig.primaryColor}15` }">
							<FaIcon icon="chart-column" :size="22" :color="themeConfig.primaryColor" />
						</view>
						<view class="module-title-wrap">
							<text class="module-title" :style="{ color: themeConfig.textPrimary }">今日进度</text>
							<text class="module-subtitle" :style="{ color: themeConfig.textSecondary }">{{ todayDate }}</text>
						</view>
					</view>
					
					<view class="today-exp">
						<view class="exp-display">
							<text class="exp-number" :style="{ background: themeConfig.gradientSoft, WebkitBackgroundClip: 'text', WebkitTextFillColor: 'transparent' }">{{ growthInfo.todayExp }}</text>
							<text class="exp-slash" :style="{ color: themeConfig.textSecondary }">/</text>
							<text class="exp-total" :style="{ color: themeConfig.textSecondary }">{{ growthInfo.todayProgress.maxDailyExp || 120 }}</text>
							<text class="exp-unit-text" :style="{ color: themeConfig.textSecondary }">EXP</text>
						</view>
						<view class="progress-bar-small" :style="{ background: themeConfig.borderLight }">
							<view class="progress-fill-small" :style="{ width: dailyExpPercent + '%', background: themeConfig.gradientSoft }"></view>
						</view>
					</view>

					<view class="task-list">
						<view class="task-item" v-for="(item, index) in todayProgressItems" :key="index">
						<view class="task-icon-box" :style="{ background: item.bgColor }">
							<FaIcon :icon="item.iconName" :size="20" :color="item.color" />
						</view>
							<view class="task-info">
								<text class="task-name" :style="{ color: themeConfig.textPrimary }">{{ item.name }}</text>
								<text class="task-detail" :style="{ color: themeConfig.textSecondary }">{{ item.detail }}</text>
							</view>
							<text class="task-value" :style="{ color: item.color }">{{ item.value }}</text>
						</view>
					</view>
				</view>

				<view class="module-card" :style="{ background: themeConfig.cardBgColor, boxShadow: `0 8rpx 32rpx ${themeConfig.shadowLight}` }">
					<view class="module-header">
						<view class="module-icon-wrap" :style="{ background: `${themeConfig.warningColor}15` }">
							<FaIcon icon="medal" :size="22" :color="themeConfig.warningColor" />
						</view>
						<view class="module-title-wrap">
							<text class="module-title" :style="{ color: themeConfig.textPrimary }">成就</text>
							<text class="achievement-count" :style="{ color: themeConfig.primaryColor }">{{ achievementsData.unlocked.length }}/{{ achievementsData.unlocked.length + achievementsData.locked.length }}</text>
						</view>
					</view>

					<view class="tab-group">
						<view 
							class="tab-item" 
							:class="{ active: activeTab === 'unlocked' }"
							:style="activeTab === 'unlocked' ? { background: themeConfig.gradientSoft, color: '#fff', boxShadow: `0 8rpx 24rpx ${themeConfig.shadowColor}` } : { background: `${themeConfig.textPrimary}05`, color: themeConfig.textSecondary }"
							@click="activeTab = 'unlocked'"
						>
							已解锁
							<view class="tab-badge" :style="activeTab === 'unlocked' ? { background: 'rgba(255,255,255,0.2)' } : {}">{{ achievementsData.unlocked.length }}</view>
						</view>
						<view 
							class="tab-item" 
							:class="{ active: activeTab === 'locked' }"
							:style="activeTab === 'locked' ? { background: themeConfig.gradientSoft, color: '#fff', boxShadow: `0 8rpx 24rpx ${themeConfig.shadowColor}` } : { background: `${themeConfig.textPrimary}05`, color: themeConfig.textSecondary }"
							@click="activeTab = 'locked'"
						>
							未解锁
							<view class="tab-badge" :style="activeTab === 'locked' ? { background: 'rgba(255,255,255,0.2)' } : {}">{{ achievementsData.locked.length }}</view>
						</view>
					</view>

					<view class="achievement-grid">
						<view class="achievement-card"
							v-for="(item, index) in (activeTab === 'unlocked' ? achievementsData.unlocked : achievementsData.locked)"
							:key="item.id || index"
							:style="{ animationDelay: index * 0.08 + 's' }"
						>
							<view class="achievement-top">
								<view class="achievement-avatar" :style="activeTab === 'unlocked' ? { background: getCategoryBg(item.category) } : { background: themeConfig.borderLight }">
									<text class="achievement-emoji" :class="{ 'is-locked': activeTab === 'locked' }">{{ item.icon }}</text>
									<view class="achievement-glow" v-if="activeTab === 'unlocked'"></view>
								</view>
								<view class="achievement-category-tag" :style="{ background: getCategoryBg(item.category), color: getCategoryColor(item.category) }">
									<text>{{ getCategoryName(item.category) }}</text>
								</view>
							</view>
							<view class="achievement-text">
								<text class="achievement-name" :style="{ color: activeTab === 'unlocked' ? themeConfig.textPrimary : themeConfig.textSecondary }">{{ item.name }}</text>
								<text class="achievement-desc" :style="{ color: themeConfig.textSecondary }">{{ item.description }}</text>
							</view>
							<view class="achievement-reward" :style="activeTab === 'unlocked' ? { background: themeConfig.gradientSoft, color: '#fff' } : { background: themeConfig.borderLight, color: themeConfig.textSecondary }">
								<text>+{{ item.expReward }} EXP</text>
							</view>
						</view>
					</view>
					<EmptyState v-if="(activeTab === 'unlocked' ? achievementsData.unlocked : achievementsData.locked).length === 0" type="default" :title="activeTab === 'unlocked' ? '暂无已解锁成就' : '暂无未解锁成就'" :subtitle="activeTab === 'unlocked' ? '完成今日任务开始解锁成就吧' : '所有成就都已解锁，继续保持'" compact />
				</view>

				<view class="module-card" :style="{ background: themeConfig.cardBgColor, boxShadow: `0 8rpx 32rpx ${themeConfig.shadowLight}` }">
					<view class="module-header">
						<view class="module-icon-wrap" :style="{ background: `${themeConfig.dangerColor}15` }">
							<FaIcon icon="gift" :size="22" :color="themeConfig.dangerColor" />
						</view>
						<text class="module-title" :style="{ color: themeConfig.textPrimary }">特权</text>
					</view>

					<view class="privilege-section">
						<view class="section-label">
							<text class="label-text" :style="{ color: themeConfig.textSecondary }">当前等级特权</text>
							<view class="section-tag active" :style="{ background: `${themeConfig.successColor}15`, color: themeConfig.successColor }">
								<text>已解锁</text>
							</view>
						</view>
						<view class="privilege-tags">
							<view class="privilege-tag" v-for="(privilege, index) in growthInfo.currentPrivileges" :key="index" :style="{ background: `${themeConfig.successColor}10` }">
								<FaIcon icon="check" :size="14" :color="themeConfig.successColor" />
								<text class="tag-text" :style="{ color: themeConfig.textPrimary }">{{ privilege }}</text>
							</view>
							<view class="privilege-tag empty" v-if="!growthInfo.currentPrivileges || growthInfo.currentPrivileges.length === 0" :style="{ background: themeConfig.borderLight }">
								<text class="tag-text" :style="{ color: themeConfig.textSecondary }">暂无特权</text>
							</view>
						</view>
					</view>

					<view class="privilege-section next-level" v-if="growthInfo.nextLevelPrivileges && growthInfo.nextLevelPrivileges.length > 0">
						<view class="section-label">
							<text class="label-text" :style="{ color: themeConfig.textSecondary }">下一级特权</text>
								<view class="section-tag locked" :style="{ background: `${themeConfig.textPrimary}08`, color: themeConfig.textSecondary }">
									<FaIcon icon="lock" :size="14" :color="themeConfig.textSecondary" />
									<text style="margin-left: 6rpx;">即将解锁</text>
								</view>
						</view>
						<view class="privilege-tags">
							<view class="privilege-tag locked" v-for="(privilege, index) in growthInfo.nextLevelPrivileges" :key="index" :style="{ background: themeConfig.borderLight }">
								<text class="tag-text" :style="{ color: themeConfig.textSecondary }">{{ privilege }}</text>
							</view>
						</view>
					</view>
				</view>
			</view>

			<view class="bottom-padding"></view>
		</scroll-view>
	</view>
</template>

<script>
import { getThemeConfigFromStorage, THEME_PRESETS } from '@/utils/theme'
import { refreshNavBarTheme, forceApplyTabBarTheme } from '@/utils/themeGlobal'
import { getGrowthInfo, getGrowthAchievements } from '@/api/index'
import FaIcon from '@/components/FaIcon.vue'
import EmptyState from '@/components/EmptyState.vue'

export default {
	components: { FaIcon, EmptyState },
	data() {
		return {
			themeConfig: getThemeConfigFromStorage() || THEME_PRESETS['default'],
			todayDate: '',
			activeTab: 'unlocked',
			achievementsData: {
				unlocked: [],
				locked: []
			},
			animatedProgress: 0,
			animatedExp: 0,
			growthInfo: {
				currentLevel: 1,
				levelTitle: '记录小白',
				levelIcon: '',
				levelColor: '#94A3B8',
				totalExp: 0,
				nextLevelExp: 200,
				levelProgress: 0,
				totalDays: 0,
				streakDays: 0,
				maxStreakDays: 0,
				todayExp: 0,
				todayProgress: {
					tasksCompleted: 0,
					taskExp: 0,
					billsRecorded: 0,
					billExp: 0,
					moodRecorded: false,
					moodExp: 0,
					totalExp: 0,
					maxDailyExp: 120
				},
				currentPrivileges: [],
				nextLevelPrivileges: []
			}
		}
	},
	computed: {
		expPercent() {
			if (!this.growthInfo.nextLevelExp || this.growthInfo.nextLevelExp <= 0) return 0
			return Math.min(100, Math.round((this.growthInfo.totalExp / this.growthInfo.nextLevelExp) * 100))
		},
		dailyExpPercent() {
			return Math.min(100, Math.round((this.growthInfo.todayExp / 150) * 100))
		},
		todayProgressItems() {
			return [
				{
					iconName: 'list-check',
					name: '任务完成',
					detail: `+${this.growthInfo.todayProgress.taskExp} EXP`,
					value: `${this.growthInfo.todayProgress.tasksCompleted}个`,
					color: this.themeConfig.primaryColor,
					bgColor: `${this.themeConfig.primaryColor}08`
				},
				{
					iconName: 'money-bill',
					name: '账单记录',
					detail: `+${this.growthInfo.todayProgress.billExp} EXP`,
					value: `${this.growthInfo.todayProgress.billsRecorded}笔`,
					color: '#f59e0b',
					bgColor: 'rgba(245, 158, 11, 0.08)'
				},
				{
					iconName: this.growthInfo.todayProgress.moodRecorded ? 'face-smile' : 'calendar-xmark',
					name: '心情记录',
					detail: `+${this.growthInfo.todayProgress.moodExp} EXP`,
					value: this.growthInfo.todayProgress.moodRecorded ? '已完成' : '待记录',
					color: '#ec4899',
					bgColor: 'rgba(236, 72, 153, 0.08)'
				},
				{
					iconName: this.growthInfo.todayProgress.reviewRecorded ? 'face-smile' : 'calendar-xmark',
					name: '复盘记录',
					detail: `+${this.growthInfo.todayProgress.reviewExp} EXP`,
					value: this.growthInfo.todayProgress.reviewRecorded ? '已完成' : '待记录',
					color: '#673ab7',
					bgColor: 'rgba(153, 72, 153, 0.08)'
				}
			]
		}
	},
	onLoad() {
		this.setTodayDate()
		this.loadGrowthInfo()
		this.loadAchievements()

		this.themeChangeHandler = (themeData) => {
			let newTheme = null
			if (themeData?.key && THEME_PRESETS[themeData.key]) {
				newTheme = THEME_PRESETS[themeData.key]
			} else if (themeData?.config) {
				newTheme = themeData.config
			}
			if (newTheme) {
				this.themeConfig = newTheme
			}
		}
		uni.$on('themeChanged', this.themeChangeHandler)
	},
	onShow() {
		const latestTheme = getThemeConfigFromStorage() || THEME_PRESETS['default']
		if (JSON.stringify(latestTheme) !== JSON.stringify(this.themeConfig)) {
			this.themeConfig = latestTheme
		}
		refreshNavBarTheme()
		setTimeout(() => {
			forceApplyTabBarTheme(latestTheme)
		}, 100)
	},
	onUnload() {
		uni.$off('themeChanged', this.themeChangeHandler)
	},
	methods: {
		setTodayDate() {
			const now = new Date()
			const month = now.getMonth() + 1
			const day = now.getDate()
			const weekDays = ['周日', '周一', '周二', '周三', '周四', '周五', '周六']
			const weekDay = weekDays[now.getDay()]
			this.todayDate = `${month}月${day}日 ${weekDay}`
		},
		async loadGrowthInfo() {
			try {
				const res = await getGrowthInfo()
				if (res) {
					const data = res.data || res
					this.growthInfo = {
						currentLevel: data.level || data.currentLevel || 1,
						levelTitle: data.title || data.levelTitle || '记录小白',
						levelIcon: data.titleIcon || data.levelIcon || '',
						levelColor: data.color || data.levelColor || '#94A3B8',
						totalExp: data.experience || data.totalExp || 0,
						nextLevelExp: data.nextLevelExp || 200,
						levelProgress: data.levelProgress || 0,
						totalDays: data.totalDays || 0,
						streakDays: data.streakDays || 0,
						maxStreakDays: data.maxStreakDays || 0,
						todayExp: data.todayExp || (data.todayProgress ? data.todayProgress.billExp + data.todayProgress.taskExp + data.todayProgress.moodExp + data.todayProgress.reviewExp: 0),
						todayProgress: {
							tasksCompleted: data.todayProgress?.tasksCompleted || 0,
							taskExp: data.todayProgress?.taskExp || 0,
							billsRecorded: data.todayProgress?.billsRecorded || 0,
							billExp: data.todayProgress?.billExp || 0,
							moodRecorded: data.todayProgress?.moodRecorded || false,
							moodExp: data.todayProgress?.moodExp || 0,
							reviewRecorded: data.todayProgress?.reviewRecorded || false,
							reviewExp: data.todayProgress?.reviewExp || 0,
							totalExp: data.todayProgress?.totalExp || 0,
							maxDailyExp: data.todayProgress?.maxDailyExp || 120
						},
						currentPrivileges: data.currentPrivileges || data.privileges || [],
						nextLevelPrivileges: data.nextLevelPrivileges || []
					}
					
					this.animateProgress()
					this.animateExp()
				}
			} catch (e) {
				console.log('加载成长信息失败:', e)
			}
		},
		animateProgress() {
			const targetProgress = this.growthInfo.levelProgress || this.expPercent
			const duration = 1000
			const startTime = Date.now()
			const startValue = 0
			
			const animate = () => {
				const elapsed = Date.now() - startTime
				const progress = Math.min(elapsed / duration, 1)
				const easeOut = 1 - Math.pow(1 - progress, 3)
				this.animatedProgress = Math.round(startValue + (targetProgress - startValue) * easeOut)
				
				if (progress < 1) {
					setTimeout(animate, 16)
				}
			}
			
			setTimeout(() => {
				animate()
			}, 300)
		},
		animateExp() {
			const targetExp = this.growthInfo.totalExp
			const duration = 800
			const startTime = Date.now()
			const startValue = 0
			
			const animate = () => {
				const elapsed = Date.now() - startTime
				const progress = Math.min(elapsed / duration, 1)
				const easeOut = 1 - Math.pow(1 - progress, 3)
				this.animatedExp = Math.round(startValue + (targetExp - startValue) * easeOut)
				
				if (progress < 1) {
					setTimeout(animate, 16)
				}
			}
			
			setTimeout(() => {
				animate()
			}, 300)
		},
		async loadAchievements() {
			try {
				const res = await getGrowthAchievements()
				if (res) {
					const data = res.data || res
					this.achievementsData = {
						unlocked: this.formatAchievements(data.unlockedList || data.unlocked || []),
						locked: this.formatAchievements(data.lockedList || data.locked || [])
					}
				}
			} catch (e) {
				console.log('加载成就列表失败:', e)
			}
		},
		formatAchievements(list) {
			return list.map(item => {
				// 后端直接返回 emoji 字符作为 icon 字段
				const iconChar = item.icon && typeof item.icon === 'string' && item.icon.length > 0 ? item.icon : '🏆'
				return {
					id: item.id || (item.category || 'ach') + '_' + Math.random().toString(36).slice(2, 8),
					icon: iconChar,
					name: item.name || item.title || this.getCategoryName(item.category),
					description: item.description || item.desc,
					expReward: item.expReward || item.exp || item.reward || 0,
					category: item.category,
					rarity: item.rarity || '初级'
				}
			})
		},
		getCategoryIcon(category) {
			// 返回 emoji 字符作为兜底分类图标
			const icons = {
				bill: '💰',
				task: '📋',
				mood: '🌈',
				streak: '🔥',
				review: '✨',
				default: '🏆'
			}
			return icons[category] || icons.default
		},
		getCategoryName(category) {
			const names = {
				bill: '账单达人',
				task: '任务能手',
				mood: '心情记录',
				streak: '连续之星',
				review: '复盘感悟',
				default: '成就'
			}
			return names[category] || names.default
		},
		getCategoryColor(category) {
			const map = {
				streak: '#F59E0B',
				task: '#9B8AFB',
				mood: '#EC4899',
				bill: '#4ECDC4',
				review: '#7B6CEB'
			}
			return map[category] || this.themeConfig.primaryColor
		},
		getCategoryBg(category) {
			const map = {
				streak: 'rgba(245, 158, 11, 0.15)',
				task: 'rgba(155, 138, 251, 0.15)',
				mood: 'rgba(236, 72, 153, 0.15)',
				bill: 'rgba(78, 205, 196, 0.15)',
				review: 'rgba(123, 108, 235, 0.15)'
			}
			return map[category] || 'rgba(155, 138, 251, 0.12)'
		},
		goToRules() {
			uni.navigateTo({
				url: '/pages/growth/rules'
			})
		}
	}
}
</script>

<style lang="scss" scoped>
.growth-page {
	min-height: 100vh;
	position: relative;
	overflow: hidden;
}

.bg-decoration {
	position: fixed;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	pointer-events: none;
	z-index: 0;
	overflow: hidden;
}

.deco-blob {
	position: absolute;
	border-radius: 50%;
	filter: blur(120rpx);
	opacity: 0.7;
}

.deco-1 {
	width: 550rpx;
	height: 550rpx;
	top: -150rpx;
	right: -120rpx;
}

.deco-2 {
	width: 450rpx;
	height: 450rpx;
	bottom: 280rpx;
	left: -100rpx;
}

.deco-3 {
	width: 350rpx;
	height: 350rpx;
	top: 380rpx;
	right: -80rpx;
}

.scroll-container {
	height: 100vh;
	position: relative;
	z-index: 5;
}

.header-card {
	margin: 20rpx 24rpx;
	border-radius: 12rpx;
	padding: 32rpx;
	position: relative;
	overflow: hidden;
}

.card-bg {
	position: absolute;
	top: 0;
	left: 0;
	right: 0;
	bottom: 0;
	overflow: hidden;
}

.bg-orb {
	position: absolute;
	width: 350rpx;
	height: 350rpx;
	border-radius: 50%;
	background: radial-gradient(circle at 40% 40%, rgba(255,255,255,0.3) 0%, rgba(255,255,255,0.1) 30%, transparent 70%);
	top: -180rpx;
	right: -100rpx;
	filter: blur(20rpx);
	animation: orbFloat 8s ease-in-out infinite;
}

@keyframes orbFloat {
	0%, 100% { transform: translate(0, 0) scale(1); }
	50% { transform: translate(-20rpx, 15rpx) scale(1.08); }
}

.bg-grid {
	position: absolute;
	top: 0;
	left: 0;
	right: 0;
	bottom: 0;
	background-image: 
		linear-gradient(rgba(255,255,255,0.03) 1px, transparent 1px),
		linear-gradient(90deg, rgba(255,255,255,0.03) 1px, transparent 1px);
	background-size: 32rpx 32rpx;
}

.bg-float-shape {
	position: absolute;
	border-radius: 50%;
	opacity: 0.5;
}

.shape-1 {
	width: 220rpx;
	height: 220rpx;
	top: -100rpx;
	left: -80rpx;
	animation: shapeFloat1 8s ease-in-out infinite;
}

.shape-2 {
	width: 180rpx;
	height: 180rpx;
	top: 40rpx;
	right: 80rpx;
	animation: shapeFloat2 7s ease-in-out infinite;
}

@keyframes shapeFloat1 {
	0%, 100% { transform: translate(0, 0) rotate(0deg); }
	50% { transform: translate(15rpx, -12rpx) rotate(8deg); }
}

@keyframes shapeFloat2 {
	0%, 100% { transform: translate(0, 0) scale(1); }
	50% { transform: translate(-10rpx, 15rpx) scale(1.1); }
}

.card-content {
	position: relative;
	z-index: 1;
	display: flex;
	flex-direction: column;
	gap: 24rpx;
}

.user-card {
	display: flex;
	align-items: center;
	gap: 22rpx;
}

.avatar-ring {
	width: 96rpx;
	height: 96rpx;
	border-radius: 50%;
	display: flex;
	align-items: center;
	justify-content: center;
	border: 3rpx solid rgba(255, 255, 255, 0.3);
	transition: transform 0.3s ease;
}

.avatar-ring:active {
	transform: scale(0.95);
}

.avatar-emoji {
	display: flex;
	align-items: center;
	justify-content: center;
}

.user-info {
	flex: 1;
	display: flex;
	flex-direction: column;
	gap: 8rpx;
}

.user-name {
	font-size: 32rpx;
	font-weight: 700;
	color: #fff;
}

.level-badge {
	display: inline-flex;
	padding: 4rpx 18rpx;
	border-radius: 100rpx;
	width: fit-content;
	backdrop-filter: blur(10px);
}

.level-badge text {
	font-size: 22rpx;
	font-weight: 600;
	color: #fff;
}

.exp-section {
	display: flex;
	flex-direction: column;
	gap: 14rpx;
}

.exp-header {
	display: flex;
	justify-content: space-between;
	align-items: center;
}

.exp-label {
	font-size: 22rpx;
	color: rgba(255, 255, 255, 0.85);
}

.exp-value {
	display: flex;
	align-items: baseline;
	gap: 6rpx;
}

.exp-current {
	font-size: 36rpx;
	font-weight: 700;
	color: #fff;
}

.exp-divider {
	font-size: 24rpx;
	color: rgba(255, 255, 255, 0.6);
}

.exp-max {
	font-size: 24rpx;
	color: rgba(255, 255, 255, 0.75);
}

.progress-wrapper {
	display: flex;
	align-items: center;
	gap: 16rpx;
}

.progress-bar {
	flex: 1;
	height: 14rpx;
	border-radius: 100rpx;
	overflow: hidden;
	position: relative;
}

.progress-fill {
	height: 100%;
	border-radius: 100rpx;
	transition: width 1s cubic-bezier(0.34, 1.56, 0.64, 1);
	position: relative;
	overflow: hidden;
}

.progress-shine {
	position: absolute;
	top: 0;
	left: -100%;
	width: 100%;
	height: 100%;
	background: linear-gradient(90deg, transparent, rgba(255,255,255,0.4), transparent);
	animation: progressShine 2s ease-in-out infinite;
}

@keyframes progressShine {
	0% { left: -100%; }
	100% { left: 100%; }
}

.progress-text {
	font-size: 24rpx;
	font-weight: 600;
	color: #fff;
	min-width: 60rpx;
	text-align: right;
}

.content-area {
	padding: 0 24rpx;
}

.stats-row {
	display: flex;
	gap: 14rpx;
	margin-bottom: 20rpx;
}

.stat-item {
	flex: 1;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 10rpx;
	padding: 24rpx 12rpx;
	border-radius: 22rpx;
	transition: all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
}

.stat-item:active {
	transform: scale(0.96);
}

.stat-icon-wrap {
	width: 72rpx;
	height: 72rpx;
	border-radius: 20rpx;
	display: flex;
	align-items: center;
	justify-content: center;
	transition: transform 0.3s ease;
}

.stat-item:active .stat-icon-wrap {
	transform: scale(1.1);
}

.stat-icon {
	font-size: 36rpx;
}

.stat-num {
	font-size: 36rpx;
	font-weight: 700;
}

.stat-label {
	font-size: 22rpx;
}

.rules-entry {
	display: flex;
	align-items: center;
	gap: 18rpx;
	padding: 24rpx;
	border-radius: 22rpx;
	margin-bottom: 20rpx;
	transition: all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
}

.rules-entry:active {
	transform: scale(0.98);
}

.entry-icon {
	width: 72rpx;
	height: 72rpx;
	border-radius: 20rpx;
	display: flex;
	align-items: center;
	justify-content: center;
	font-size: 34rpx;
}

.entry-text {
	flex: 1;
	display: flex;
	flex-direction: column;
	gap: 4rpx;
}

.entry-title {
	font-size: 30rpx;
	font-weight: 700;
}

.entry-desc {
	font-size: 24rpx;
}

.entry-arrow {
	width: 48rpx;
	height: 48rpx;
	border-radius: 50%;
	display: flex;
	align-items: center;
	justify-content: center;
	font-size: 28rpx;
	font-weight: 600;
}

.module-card {
	border-radius: 12rpx;
	padding: 28rpx;
	margin-bottom: 20rpx;
}

.module-header {
	display: flex;
	align-items: center;
	gap: 14rpx;
	margin-bottom: 24rpx;
}

.module-icon-wrap {
	width: 56rpx;
	height: 56rpx;
	border-radius: 16rpx;
	display: flex;
	align-items: center;
	justify-content: center;
	flex-shrink: 0;
}

.module-icon {
	font-size: 28rpx;
}

.module-title-wrap {
	flex: 1;
	display: flex;
	align-items: center;
	gap: 12rpx;
}

.module-title {
	font-size: 30rpx;
	font-weight: 700;
}

.module-subtitle {
	font-size: 24rpx;
}

.achievement-count {
	font-size: 26rpx;
	font-weight: 700;
}

.today-exp {
	display: flex;
	flex-direction: column;
	gap: 14rpx;
	margin-bottom: 24rpx;
	padding-bottom: 24rpx;
	border-bottom: 1rpx solid rgba(0, 0, 0, 0.05);
}

.exp-display {
	display: flex;
	align-items: baseline;
	gap: 8rpx;
}

.exp-number {
	font-size: 48rpx;
	font-weight: 700;
	font-weight: 800;
}

.exp-slash {
	font-size: 30rpx;
}

.exp-total {
	font-size: 30rpx;
}

.exp-unit-text {
	font-size: 24rpx;
	margin-left: 6rpx;
}

.progress-bar-small {
	height: 10rpx;
	border-radius: 100rpx;
	overflow: hidden;
}

.progress-fill-small {
	height: 100%;
	border-radius: 100rpx;
	transition: width 0.6s cubic-bezier(0.34, 1.56, 0.64, 1);
}

.task-list {
	display: flex;
	flex-direction: column;
	gap: 18rpx;
}

.task-item {
	display: flex;
	align-items: center;
	gap: 16rpx;
	padding: 16rpx;
	background: rgba(0, 0, 0, 0.02);
	border-radius: 16rpx;
}

.task-icon-box {
	width: 56rpx;
	height: 56rpx;
	border-radius: 14rpx;
	display: flex;
	align-items: center;
	justify-content: center;
	font-size: 28rpx;
	flex-shrink: 0;
}

.task-info {
	flex: 1;
}

.task-name {
	font-size: 26rpx;
	font-weight: 600;
	display: block;
}

.task-detail {
	font-size: 22rpx;
	margin-top: 4rpx;
}

.task-value {
	font-size: 26rpx;
	font-weight: 600;
}

.tab-group {
	display: flex;
	gap: 14rpx;
	margin-bottom: 24rpx;
}

.tab-item {
	flex: 1;
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 8rpx;
	padding: 18rpx;
	border-radius: 16rpx;
	font-size: 26rpx;
	font-weight: 600;
	transition: all 0.35s cubic-bezier(0.34, 1.56, 0.64, 1);
}

.tab-item:active {
	transform: scale(0.96);
}

.tab-badge {
	padding: 4rpx 12rpx;
	border-radius: 100rpx;
	font-size: 20rpx;
	font-weight: 700;
}

.achievement-grid {
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	gap: 16rpx;
}

.achievement-card {
	position: relative;
	display: flex;
	flex-direction: column;
	gap: 14rpx;
	padding: 24rpx;
	background: rgba(0, 0, 0, 0.03);
	border-radius: 20rpx;
	transition: all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
	animation: cardFadeIn 0.5s ease-out forwards;
	opacity: 0;
	transform: translateY(20rpx);
	min-height: 200rpx;
}

@keyframes cardFadeIn {
	to {
		opacity: 1;
		transform: translateY(0);
	}
}

.achievement-card:active {
	transform: scale(0.97);
	background: rgba(0, 0, 0, 0.05);
}

.achievement-top {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 10rpx;
}

.achievement-avatar {
	width: 72rpx;
	height: 72rpx;
	border-radius: 20rpx;
	display: flex;
	align-items: center;
	justify-content: center;
	position: relative;
	overflow: hidden;
	flex-shrink: 0;
}

.achievement-emoji {
	font-size: 44rpx;
	line-height: 1;
	display: block;
}

.achievement-emoji.is-locked {
	filter: grayscale(0.85);
	opacity: 0.6;
}

.achievement-glow {
	position: absolute;
	top: -50%;
	left: -50%;
	width: 200%;
	height: 200%;
	background: radial-gradient(circle, rgba(255, 255, 255, 0.3) 0%, transparent 70%);
	animation: glowRotate 4s linear infinite;
	pointer-events: none;
}

@keyframes glowRotate {
	from { transform: rotate(0deg); }
	to { transform: rotate(360deg); }
}

.achievement-category-tag {
	padding: 4rpx 12rpx;
	border-radius: 100rpx;
	font-size: 18rpx;
	font-weight: 600;
	max-width: 60%;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.achievement-text {
	flex: 1;
	display: flex;
	flex-direction: column;
	gap: 6rpx;
}

.achievement-name {
	font-size: 26rpx;
	font-weight: 700;
	display: block;
	line-height: 1.3;
}

.achievement-desc {
	font-size: 22rpx;
	line-height: 1.4;
	display: -webkit-box;
	-webkit-line-clamp: 2;
	line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

.achievement-reward {
	padding: 8rpx 18rpx;
	border-radius: 100rpx;
	font-size: 22rpx;
	font-weight: 600;
	text-align: center;
	width: fit-content;
}

.privilege-section {
	margin-bottom: 24rpx;
}

.privilege-section.next-level {
	padding-top: 24rpx;
	border-top: 1rpx solid rgba(0, 0, 0, 0.05);
	margin-bottom: 0;
}

.section-label {
	display: flex;
	align-items: center;
	gap: 12rpx;
	margin-bottom: 18rpx;
}

.label-text {
	font-size: 24rpx;
}

.section-tag {
	padding: 6rpx 14rpx;
	border-radius: 100rpx;
	font-size: 22rpx;
	font-weight: 500;
}

.privilege-tags {
	display: flex;
	flex-wrap: wrap;
	gap: 12rpx;
}

.privilege-tag {
	display: flex;
	align-items: center;
	gap: 8rpx;
	padding: 12rpx 20rpx;
	border-radius: 100rpx;
}

.privilege-tag.empty,
.privilege-tag.locked {
	background: rgba(0, 0, 0, 0.03);
}

.tag-check {
	font-size: 22rpx;
	font-weight: 700;
}

.tag-text {
	font-size: 24rpx;
}

.privilege-tag.empty .tag-text,
.privilege-tag.locked .tag-text {
	color: #999;
}

.bottom-padding {
	height: 60rpx;
}
</style>