<template>
	<view class="ie-page" :class="{ 'low-performance': lowPowerMode, 'android-home': isAndroid }">
		<view class="aurora aurora-a"></view>
		<view class="aurora aurora-b"></view>
		<view class="aurora aurora-c"></view>
		<view class="top-safe" :style="{ height: menuButtonInfo.top + 'px' }"></view>

		<view class="float-bar">
			<view class="home-back" @tap="backHome">
				<text class="home-back-icon">‹</text>
				<text>返回首页</text>
			</view>
		</view>

		<view class="hero">
			<view class="hero-top">
				<view class="hero-eyebrow">{{ timeLabel }} · {{ greeting }}</view>
				<view class="perf-toggle" :class="{ active: lowPowerMode }" @tap="toggleLowPowerMode">
					{{ lowPowerMode ? '⚡ 流畅' : '✨ 氛围' }}
				</view>
			</view>
			<view class="hero-statement">
				此刻有 <text class="hero-num">{{ displayAwakeCount }}</text> 个灵魂正在这片星系漂流
			</view>
			<!-- <view class="hero-statement second"></view> -->
			<view class="hero-live daily-live" v-if="dailyQuestion.exists" @tap="goDailyQuestion">
				<text class="live-dot"></text>
				<text class="daily-live-tag">同频一题</text>
				<text class="daily-live-text">{{ dailyQuestion.content }}</text>
				<text class="daily-live-go">{{ dailyQuestion.answered ? '看答案' : '去回答' }} ›</text>
			</view>
			<view class="hero-profile-line">
				<view class="hero-profile" @tap="goUniverse">
					<image class="profile-avatar-img" v-if="profile.avatarUrl" :src="profile.avatarUrl" mode="aspectFill"></image>
					<view class="profile-avatar" v-else>{{ profile.avatarText || '我' }}</view>
					<view class="profile-meta">
						<view class="profile-name">{{ profile.anonymousName || '半匿名漂流者' }}</view>
						<view class="profile-tags">{{ profileTagsText }}</view>
					</view>
					<view class="profile-arrow">›</view>
				</view>
				<view class="say-intent-btn" @tap.stop="openCompanionEditor">我也说一句</view>
			</view>
		</view>

		<view class="lower-stack">
		<view class="drift-field">
			<view class="spark spark-a">✦</view>
			<view class="spark spark-b">✧</view>
			<view class="spark spark-c">✦</view>
			<view class="spark spark-d">✧</view>

			<view class="danmu-lane lane-0">
				<view class="lane-track">
					<view class="danmu-item" v-for="(item,idx) in danmuLanes[0]" :key="idx"
						:class="['tint-' + (idx % 4), item.type]" @tap="selectDrift(item)">
						<text class="danmu-emoji">{{ moodEmoji(item) }}</text>
						<text class="danmu-text">{{ item.text }}</text>
					</view>
				</view>
			</view>
			<view class="danmu-lane lane-1">
				<view class="lane-track">
					<view class="danmu-item" v-for="(item,idx) in danmuLanes[1]" :key="idx"
						:class="['tint-' + ((idx + 1) % 4), item.type]" @tap="selectDrift(item)">
						<text class="danmu-emoji">{{ moodEmoji(item) }}</text>
						<text class="danmu-text">{{ item.text }}</text>
					</view>
				</view>
			</view>
			<view class="danmu-lane lane-2">
				<view class="lane-track">
					<view class="danmu-item" v-for="(item,idx) in danmuLanes[2]" :key="idx"
						:class="['tint-' + ((idx + 2) % 4), item.type]" @tap="selectDrift(item)">
						<text class="danmu-emoji">{{ moodEmoji(item) }}</text>
						<text class="danmu-text">{{ item.text }}</text>
					</view>
				</view>
			</view>

			<view class="signal-planet" :style="galaxyStyle" @touchstart.stop="startGalaxyDrag" @touchmove.stop="moveGalaxyDrag"
				@touchend="endGalaxyDrag" @touchcancel="endGalaxyDrag">
				<view class="galaxy-breath">
					<view class="galaxy-ring ring-main"></view>
					<view class="galaxy-ring ring-second"></view>
					<view class="galaxy-ring ring-third"></view>
					<view class="orbit-planet" v-for="(planet,index) in orbitPlanets" :key="planet.name"
						:class="'orbit-planet-' + index" :style="orbitPlanetStyles[index]"></view>
					<view class="galaxy-body">
						<view class="liquid liquid-a"></view>
						<view class="liquid liquid-b"></view>
						<view class="soul-particle soul-a"></view>
						<view class="soul-particle soul-b"></view>
						<view class="soul-particle soul-c"></view>
						<view class="planet-core">
							<view class="planet-text">有人在等你</view>
							<view class="planet-sub">{{ currentMode === 'i' ? '安静靠近' : '轻轻热闹' }}</view>
							<view class="planet-cta" @tap.stop="goMatch" @click.stop="goMatch" @touchstart.stop @touchend.stop="goMatch">戳我 开始漂流 →</view>
						</view>
					</view>
				</view>
			</view>
		</view>

		<view class="home-action-panel">
			<view class="play-deck">
				<view class="ticket" @tap="showTicketTip">
					<view class="ticket-left">
						<text class="ticket-icon">🎫</text>
						<text class="ticket-label">今日漂流票</text>
					</view>
					<view class="ticket-divider"></view>
					<view class="ticket-right">
						<text class="ticket-num">{{ chancesLeft }}</text>
						<text class="ticket-unit">张</text>
					</view>
				</view>
				<view class="target-btn" @tap="openTargetPanel">
					<text class="target-star">✦</text>
					<text class="target-text">想遇见谁</text>
					<text class="target-sub">偏好设置</text>
				</view>
			</view>

			<view class="daily-q-bar mood-copy-bar">
				<text>“{{ displayMoodCopy }}”</text><text class="typing-cursor" v-if="displayMoodCopy.length < activeMood.copy.length"></text>
			</view>

			<view class="mood-strip">
				<view class="mood-orbs">
					<view class="mood-orb" v-for="item in moods" :key="item.key"
						:class="{ active: currentMood === item.key }" @tap="changeMood(item.key)">
						<view class="orb-face"><text class="orb-emoji">{{ item.icon }}</text></view>
						<text class="orb-label">{{ item.label }}</text>
					</view>
				</view>
			</view>
		</view>
		</view>

		<view class="target-mask" v-if="showTargetPanel" @tap="closeTargetPanel">
			<view class="target-popup" @tap.stop>
				<view class="target-popup-head">
					<view>
						<view class="target-popup-title">随机陪伴设置</view>
						<view class="target-popup-sub">选择此刻想遇见的人，再开始漂流。</view>
					</view>
					<view class="target-close" @tap="closeTargetPanel">×</view>
				</view>
				<view class="target-title">找什么搭子（可选）</view>
				<view class="target-row intent-row">
					<view class="target-chip intent-chip" v-for="item in intents" :key="item.key"
						:class="{ active: matchIntent === item.key }" @tap="toggleIntent(item.key)">
						{{ item.icon }} {{ item.label }}
					</view>
				</view>
				<input class="target-input search-input" v-model="fuzzyKeyword" maxlength="24" placeholder="模糊搜索昵称/签名/找搭子内容" />
				<view class="target-title gender-title">今天想遇见谁</view>
				<view class="target-row">
					<view class="target-chip" v-for="item in targetModes" :key="item.key"
						:class="{ active: targetMode === item.key }" @tap="setTargetMode(item.key)">
						{{ item.label }}
					</view>
				</view>
				<view class="target-title gender-title">匹配范围</view>
				<view class="target-row">
					<view class="target-chip scope-chip" v-for="item in matchScopes" :key="item.key"
						:class="{ active: matchScope === item.key }" @tap="matchScope = item.key">
						{{ item.label }}
					</view>
				</view>
				<view class="target-title gender-title">想匹配的性别</view>
				<view class="target-row">
					<view class="target-chip gender-chip" v-for="item in targetGenders" :key="item.key"
						:class="{ active: targetGender === item.key }" @tap="setTargetGender(item.key)">
						{{ item.label }}
					</view>
				</view>
				<view class="start-match-btn" @tap="openMatch">开始随机陪伴</view>
			</view>
		</view>

		<ie-bottom-tab active="index" :unread-count="unreadCount"></ie-bottom-tab>

		<view class="companion-mask" v-if="showCompanionEditor" :style="companionMaskStyle" @tap="closeCompanionEditor">
			<view class="companion-editor" :style="companionEditorStyle" @tap.stop>
				<view class="companion-editor-head">
					<view>
						<view class="companion-editor-title">我也说一句</view>
						<view class="companion-editor-sub">写下你此刻想找什么搭子，会展示在星系漂流里。</view>
					</view>
					<view class="target-close" @tap="closeCompanionEditor">×</view>
				</view>
				<input class="target-input companion-input" v-model="editCompanionIntent" maxlength="30" :adjust-position="false"
					placeholder="例如：想找散步搭子" @focus="onCompanionInputFocus" @blur="onCompanionInputBlur" />
				<view class="companion-save" :class="{ disabled: savingCompanionIntent }" @tap="saveCompanionIntent">
					{{ savingCompanionIntent ? '保存中...' : '发布一句' }}
				</view>
			</view>
		</view>

		<view class="match-mask" v-if="showMatch" @tap="closeMatch">
			<view class="match-panel" @tap.stop>
				<scroll-view scroll-y class="match-scroll">
					<view class="match-banner">
						<view class="match-banner-deco">✦ ✧ ✦</view>
						<view class="match-label">缘分签 · 半匿名漂流者</view>
						<view class="close" @tap="closeMatch">×</view>
					</view>
					<view class="match-body">
						<view class="match-avatar-wrap">
							<image class="companion-orb-img" v-if="matchedPerson.avatarUrl" :src="matchedPerson.avatarUrl" mode="aspectFill"></image>
							<view class="companion-orb" v-else :class="matchedPerson.mode || currentMode">{{ matchedPerson.avatar }}</view>
						</view>
						<view class="match-name">{{ matchedPerson.name }}</view>
						<view class="match-online" v-if="matchedPerson.lastActiveText">
							<view class="online-dot" :class="{ on: matchedOnline }"></view>
							<text>{{ matchedPerson.lastActiveText }}</text>
						</view>
						<view class="match-intent" v-if="currentMatch && currentMatch.intentMatched">
							⚡ TA 也在找{{ intentLabel(currentMatch.intent) }}
						</view>
						<view class="match-mood" v-if="matchedPerson.moodText">
							<text class="match-mood-icon">{{ matchedPerson.moodIcon }}</text>
							<text>{{ matchedPerson.moodText }}</text>
						</view>
						<view class="match-state">{{ modeText(matchedPerson.mode) }} · {{ genderText(matchedPerson.gender) }}</view>
						<view class="match-region" v-if="matchedPerson.regionName">📍 {{ matchedPerson.regionName }}</view>
						<view class="match-tags" v-if="matchedPerson.tags && matchedPerson.tags.length">
							<text v-for="tag in matchedPerson.tags" :key="tag"># {{ tag }}</text>
						</view>
						<view class="match-state-text">{{ matchedPerson.state }}</view>
						<view class="match-quote">{{ matchedPerson.quote }}</view>
						<view class="match-persona" v-if="matchedPerson.personaImages && matchedPerson.personaImages.length">
							<view class="match-section-title">人格卡片</view>
							<scroll-view scroll-x class="match-persona-scroll">
								<image class="match-persona-image" v-for="(img,index) in matchedPerson.personaImages" :key="img"
									:src="img" mode="aspectFill" @tap="previewMatchedPersona(index)"></image>
							</scroll-view>
						</view>
						<view class="match-actions">
							<view class="ghost-btn" @tap="skipMatch">轻轻划过</view>
							<view class="solid-btn" @tap="goChat">进入聊天 →</view>
						</view>
						<view class="match-groupbuy" v-if="showGroupBuyEntry" @tap="goGroupBuy">
							🛍 搭子福利：一起拼一单更划算 →
						</view>
					</view>
				</scroll-view>
			</view>
		</view>

		<view class="profile-mask" v-if="showProfile" @tap="closeProfile">
			<view class="profile-mini" @tap.stop>
				<view class="mini-orb">◌</view>
				<view class="mini-title">半匿名漂流者</view>
				<view class="mini-sub">今天更适合：{{ currentMode === 'i' ? '慢一点靠近' : '轻轻热闹一下' }}</view>
				<view class="mini-action" @tap="goUniverse">进入我的宇宙</view>
			</view>
		</view>

		<view class="creating-mask" v-if="matching">
			<view class="creating-card">
				<view class="creating-orbit">
					<view class="creating-dot dot-a"></view>
					<view class="creating-dot dot-b"></view>
					<view class="creating-core">{{ currentMode }}</view>
				</view>
				<view class="creating-title">寻找同频中</view>
				<view class="creating-sub">正在捕捉附近的轻轻回应，请稍等一下</view>
				<view class="creating-progress"><view></view></view>
			</view>
		</view>
	</view>
</template>

<script>
	import { ieHome, getIeUnreadCount, updateIeStatus, startIeMatch, matchIeProfile, getIeDailyQuestion, saveIeProfile } from '@/common/ieApi.js'
	import IeBottomTab from '@/components/ie-bottom-tab/ie-bottom-tab.vue'

	export default {
		components: { IeBottomTab },
		data() {
			return {
				menuButtonInfo: { top: 44 },
				hasShownOnce: false,
				currentMood: 'quiet',
				currentMode: 'i',
				chancesLeft: 20,
				unreadCount: 0,
				showMatch: false,
				isAndroid: false,
				ieBannedRedirecting: false,
				now: new Date(),
				awakeCount: 127,
				onlineCountBase: 0,
				displayAwakeCount: 0,
				waitingCount: 49,
				liveTimer: null,
				unreadTimer: null,
				countTimer: null,
				showProfile: false,
				showTargetPanel: false,
				showCompanionEditor: false,
				matching: false,
				savingCompanionIntent: false,
				keyboardHeight: 0,
				profileReady: false,
				profile: {},
				lowPowerMode: false,
				targetMode: 'any',
				targetGender: 'any',
				matchScope: 'school',
				matchIntent: '',
				customCompanionIntent: '',
				editCompanionIntent: '',
				fuzzyKeyword: '',
				intents: [
					{ key: 'milktea', icon: '🧋', label: '奶茶搭子' },
					{ key: 'meal', icon: '🍚', label: '吃饭搭子' },
					{ key: 'study', icon: '📚', label: '自习搭子' },
					{ key: 'walk', icon: '🚶', label: '散步搭子' },
					{ key: 'chat', icon: '💬', label: '只想聊聊' }
				],
				dailyQuestion: { exists: false },
				activeDriftText: '',
				displayMoodCopy: '对方没有催我讲话，沉默变得没那么尴尬',
				moodTypeTimer: null,
				galaxyRotateX: -8,
				galaxyRotateY: 18,
				galaxyDragging: false,
				galaxyMoved: false,
				galaxyStartX: 0,
				galaxyStartY: 0,
				galaxyLastMoveTime: 0,
				galaxyAutoAngle: 0,
				galaxyTimer: null,
				orbitPlanets: [
					{ name: 'mint', angle: 12, radiusX: 269, radiusY: 70, size: 22, speed: 1.05, color: 'rgba(169,255,231,.92)' },
					{ name: 'violet', angle: 86, radiusX: 228, radiusY: 110, size: 31, speed: .72, color: 'rgba(162,155,254,.86)' },
					{ name: 'peach', angle: 156, radiusX: 295, radiusY: 89, size: 18, speed: .9, color: 'rgba(255,184,209,.9)' },
					{ name: 'lemon', angle: 218, radiusX: 242, radiusY: 132, size: 14, speed: 1.22, color: 'rgba(255,226,139,.88)' },
					{ name: 'aqua', angle: 288, radiusX: 324, radiusY: 101, size: 26, speed: .62, color: 'rgba(132,233,255,.82)' },
					{ name: 'snow', angle: 332, radiusX: 199, radiusY: 58, size: 12, speed: 1.38, color: 'rgba(255,255,255,.95)' }
				],
				doneText: "今天先到这里，平台下单可增加匹配次数",
				moods: [{"key":"quiet","label":"想安静","icon":"🌙","copy":"对方没有催我讲话，沉默变得没那么尴尬。"},{"key":"talk","label":"想说话","icon":"💭","copy":"聊了一个很小的日常话题，心情被拉亮了一点。"},{"key":"listen","label":"听着呢","icon":"🎧","copy":"像有人坐在旁边，不需要解释为什么低落。"},{"key":"drift","label":"轻了一点","icon":"🫧","copy":"只是给今天留一点柔软的痕迹。"}],
				targetModes: [{ key: 'i', label: '匹配 i 人' }, { key: 'e', label: '匹配 e 人' }, { key: 'any', label: '都可以' }],
				targetGenders: [{ key: 'male', label: '男生' }, { key: 'female', label: '女生' }, { key: 'any', label: '不限' }],
				matchScopes: [{ key: 'school', label: '本校区' }, { key: 'world', label: '世界用户' }],
				companions: {"i":[{"name":"树荫下的风","avatar":"风","state":"在校园里发呆","quote":"可以安静待 15 分钟，不用急着找话题。"},{"name":"耳机里的云","avatar":"云","state":"刚从教室出来","quote":"今天只想慢慢说两句。"}],"e":[{"name":"便利店灯光","avatar":"光","state":"想聊点不重要的","quote":"要不要交换一句今天最荒唐的小事？"},{"name":"操场散步员","avatar":"跑","state":"刚从操场回来","quote":"我可以负责开场，你负责随便接。"}]},
				matchedPerson: {},
				currentMatch: null,
				presetDriftMessages: [
					{ type: 'i', mood: 'quiet', text: '操场现在风很舒服' },
					{ type: 'i', mood: 'listen', text: '有人在图书馆假装努力' },
					{ type: 'e', mood: 'talk', text: '谁愿意陪我散步 10 分钟' },
					{ type: 'i', mood: 'quiet', text: '刚刚有人有点低落' },
					{ type: 'e', mood: 'talk', text: '想听一个不重要的故事' },
					{ type: 'i', mood: 'drift', text: '走在路上突然有点空' }
				],
				driftMessages: []
			}
		},
		computed: {
			activeMood() {
				return this.moods.find(item => item.key === this.currentMood) || this.moods[0]
			},
			matchedOnline() {
				const text = this.matchedPerson.lastActiveText || ''
				return text === '当前在线' || text === '刚刚在线'
			},
			showGroupBuyEntry() {
				// 吃喝类搭子才挂拼团入口，意图越具体转化越自然
				const intent = this.currentMatch && this.currentMatch.intent
				return intent === 'milktea' || intent === 'meal'
			},
			profileTagsText() {
				const tags = this.profile.interestTags || []
				return tags.length ? tags.slice(0, 3).join(' · ') : (this.currentMode === 'i' ? '安静陪伴' : '轻轻热闹')
			},
			timeLabel() {
				const hours = String(this.now.getHours()).padStart(2, '0')
				const minutes = String(this.now.getMinutes()).padStart(2, '0')
				return `${hours}:${minutes}`
			},
			greeting() {
				const hour = this.now.getHours()
				if (hour < 5) return '夜深了，漂流者'
				if (hour < 11) return '早安，漂流者'
				if (hour < 14) return '午安，漂流者'
				if (hour < 18) return '下午好，漂流者'
				if (hour < 23) return '晚上好，漂流者'
				return '夜深了，漂流者'
			},
			danmuLanes() {
				const lanes = [[], [], []]
				const source = this.driftMessages.length ? this.driftMessages : this.presetDriftMessages
				source.forEach((item, index) => {
					lanes[index % 3].push(item)
				})
				// Duplicate each lane so the marquee loops seamlessly.
				return lanes.map(lane => lane.concat(lane))
			},
			galaxyStyle() {
				return 'transform: translate(-50%, -50%);'
			},
			orbitPlanetStyles() {
				return this.orbitPlanets.map((planet) => {
					const angle = (planet.angle + this.galaxyRotateY + this.galaxyAutoAngle * planet.speed) * Math.PI / 180
					const tilt = this.galaxyRotateX * Math.PI / 180
					const depth = Math.sin(angle)
					const x = Math.cos(angle) * planet.radiusX
					const y = Math.sin(angle) * planet.radiusY * Math.cos(tilt) + Math.sin(tilt) * 20
					const scale = 0.72 + (depth + 1) * 0.18
					const opacity = 0.42 + (depth + 1) * 0.25
					const zIndex = Math.round(8 + (depth + 1) * 7)
					return [
						`width: ${planet.size}rpx`,
						`height: ${planet.size}rpx`,
						`background: ${planet.color}`,
						`color: ${planet.color}`,
						`opacity: ${opacity}`,
						`z-index: ${zIndex}`,
						`transform: translate(-50%, -50%) translate(${x}rpx, ${y}rpx) scale(${scale})`
					].join(';')
				})
			},
			companionMaskStyle() {
				const lift = this.keyboardHeight ? Math.max(this.keyboardHeight - 24, 0) : 0
				return lift ? `padding-bottom: ${lift}px` : ''
			},
			companionEditorStyle() {
				return this.keyboardHeight ? 'margin-bottom: 24rpx' : ''
			}
		},
		onLoad() {
			if (uni.getMenuButtonBoundingClientRect) {
				this.menuButtonInfo = uni.getMenuButtonBoundingClientRect()
			}
			this.lowPowerMode = uni.getStorageSync('ieLowPowerMode') === '1'
			this.detectPlatform()
			this.pickCompanion()
			this.loadHome()
			this.loadDailyQuestion()
			this.animateAwakeCount(this.awakeCount)
			this.startPageTimers()
			this.displayMoodCopy = this.activeMood.copy
		},
		onShow() {
			this.startPageTimers()
			if (this.hasShownOnce) {
				this.loadHome()
				this.loadDailyQuestion()
			} else {
				this.hasShownOnce = true
			}
			uni.authorize({
				scope: 'scope.record',
				success() {

				},
				fail() {
					this.tui.toast("您未授权，语音功能可能会出现错误")
				}
			})
		},
		onHide() {
			this.stopPageTimers()
		},
		onUnload() {
			this.stopPageTimers()
		},
		methods: {
			startPageTimers() {
				if (!this.liveTimer) {
					this.liveTimer = setInterval(() => {
						this.now = new Date()
						this.awakeCount = this.randomAwakeCount(this.onlineCountBase)
						this.waitingCount = 39 + Math.floor(Math.random() * 18)
						this.animateAwakeCount(this.awakeCount)
					}, this.lowPowerMode ? 9000 : 4200)
				}
				if (!this.lowPowerMode && !this.galaxyTimer) {
					this.galaxyTimer = setInterval(() => {
						this.galaxyAutoAngle = (this.galaxyAutoAngle + 3.8) % 360
					}, 160)
				}
				if (!this.unreadTimer) {
					this.unreadTimer = setInterval(() => {
						this.refreshUnreadCount()
					}, 15000)
				}
			},
			detectPlatform() {
				try {
					const info = uni.getSystemInfoSync ? uni.getSystemInfoSync() : {}
					this.isAndroid = String(info.platform || '').toLowerCase() === 'android'
				} catch (e) {
					this.isAndroid = false
				}
			},
			stopPageTimers() {
				if (this.liveTimer) {
					clearInterval(this.liveTimer)
					this.liveTimer = null
				}
				if (this.unreadTimer) {
					clearInterval(this.unreadTimer)
					this.unreadTimer = null
				}
				if (this.countTimer) {
					clearInterval(this.countTimer)
					this.countTimer = null
				}
				if (this.galaxyTimer) {
					clearInterval(this.galaxyTimer)
					this.galaxyTimer = null
				}
				if (this.moodTypeTimer) {
					clearInterval(this.moodTypeTimer)
					this.moodTypeTimer = null
				}
			},
			async refreshUnreadCount() {
				const count = await getIeUnreadCount()
				if (count === null || count === undefined) return
				this.unreadCount = Number(count) || 0
			},
			randomBetween(min, max) {
				return min + Math.floor(Math.random() * (max - min + 1))
			},
			wait(ms) {
				return new Promise(resolve => setTimeout(resolve, ms))
			},
			randomAwakeCount(onlineCount) {
				const count = Number(onlineCount) || 0
				if (count > 1000) {
					const min = Math.floor(count / 1000) * 1000
					return this.randomBetween(min, min + 999)
				}
				return this.randomBetween(1000, 2000)
			},
			animateAwakeCount(target) {
				if (this.countTimer) {
					clearInterval(this.countTimer)
				}
				if (this.lowPowerMode) {
					this.displayAwakeCount = target
					return
				}
				const start = this.displayAwakeCount
				const diff = target - start
				let step = 0
				this.countTimer = setInterval(() => {
					step += 1
					const progress = Math.min(step / 10, 1)
					const eased = 1 - Math.pow(1 - progress, 3)
					this.displayAwakeCount = Math.round(start + diff * eased)
					if (progress >= 1) {
						clearInterval(this.countTimer)
						this.countTimer = null
					}
				}, 42)
			},
			pickCompanion() {
				const list = this.companions[this.currentMode]
				this.matchedPerson = list[Math.floor(Math.random() * list.length)]
			},
			toggleLowPowerMode() {
				this.lowPowerMode = !this.lowPowerMode
				uni.setStorageSync('ieLowPowerMode', this.lowPowerMode ? '1' : '0')
				this.stopPageTimers()
				this.startPageTimers()
				uni.showToast({ title: this.lowPowerMode ? '已开启流畅模式' : '已开启氛围动效', icon: 'none' })
			},
			loadDailyQuestion() {
				getIeDailyQuestion().then(res => {
					if (res) this.dailyQuestion = res
				}).catch(() => {})
			},
			goDailyQuestion() {
				uni.navigateTo({ url: '/package1/ieBrowser/dailyQuestion' })
			},
			toggleIntent(key) {
				this.matchIntent = this.matchIntent === key ? '' : key
			},
			setTargetMode(key) {
				this.targetMode = key
				this.syncStatus()
			},
			setTargetGender(key) {
				this.targetGender = key
				this.syncStatus()
			},
			intentLabel(key) {
				const item = this.intents.find(intent => intent.key === key)
				return item ? item.label : '搭子'
			},
			goGroupBuy() {
				this.showMatch = false
				uni.navigateTo({ url: '/package2/group/groupBuyList' })
			},
			async loadHome() {
				const home = await ieHome()
				if (home && home.banned) {
					this.redirectBannedIe(home.message)
					return
				}
				if (!home) return
				if (home.profileCompleted !== 1) {
					uni.redirectTo({ url: '/package1/ieBrowser/profileSetup' })
					return
				}
				this.profile = home.profile || {}
				this.customCompanionIntent = this.profile.companionIntent || this.customCompanionIntent
				this.editCompanionIntent = this.customCompanionIntent
				this.profileReady = true
				this.onlineCountBase = Number(home.onlineCount) || 0
				this.awakeCount = this.randomAwakeCount(this.onlineCountBase)
				this.waitingCount = home.waitingCount || this.waitingCount
				this.chancesLeft = Math.max((home.dailyQuota || 20) - (home.usedQuota || 0), 0)
				this.unreadCount = home.unreadCount || 0
				this.currentMode = home.currentMode || this.currentMode
				this.currentMood = home.currentMood || this.currentMood
				this.targetMode = home.targetModePreference || this.targetMode
				this.targetGender = home.targetGenderPreference || this.targetGender
				this.driftMessages = this.buildDriftMessages(home)
				this.animateAwakeCount(this.awakeCount)
				this.syncStatus()
			},
			buildDriftMessages(home = {}) {
				const realItems = (home.companionIntents || []).filter(item => item && item.text).slice(0, 50).map((item, index) => ({
					type: item.type || (index % 2 === 0 ? 'i' : 'e'),
					mood: item.mood || this.moods[index % this.moods.length].key,
					text: item.text,
					userId: item.userId,
					anonymousName: item.anonymousName || '',
					avatarText: item.avatarText || '',
					avatarUrl: item.avatarUrl || '',
					isSelf: !!item.isSelf,
					isUserIntent: true
				}))
				const fillTexts = (home.hotStatuses && home.hotStatuses.length ? home.hotStatuses : this.presetDriftMessages.map(item => item.text))
				const fillItems = fillTexts.map((text, index) => ({
					type: index % 2 === 0 ? 'i' : 'e',
					mood: this.moods[index % this.moods.length].key,
					text,
					isUserIntent: false
				}))
				return realItems.concat(fillItems).slice(0, 50)
			},
			redirectBannedIe(message) {
				if (this.ieBannedRedirecting) return
				this.ieBannedRedirecting = true
				this.stopPageTimers()
				this.matching = false
				this.showMatch = false
				uni.showToast({
					title: message || '你的 i/e 身份已被封禁',
					icon: 'none',
					duration: 1800
				})
				setTimeout(() => {
					uni.switchTab({
						url: '/pages/index/index',
						fail: () => {
							uni.reLaunch({ url: '/pages/index/index' })
						}
					})
				}, 1800)
			},
			syncStatus() {
				if (!this.profileReady) return
				const areaInfo = this.getAreaInfo()
				updateIeStatus({
					mode: this.currentMode,
					targetMode: this.targetMode,
					targetGender: this.targetGender,
					mood: this.currentMood,
					statusText: this.activeMood.copy,
					...areaInfo,
					interestTags: [this.activeMood.label]
				})
			},
			getAreaInfo() {
				try {
					const area = JSON.parse(uni.getStorageSync('area') || '{}')
					return {
						regionId: area.id || '',
						regionName: area.title || ''
					}
				} catch (e) {
					return { regionId: '', regionName: '' }
				}
			},
			async openMatch() {
				if (this.matching) return
				this.showTargetPanel = false
				if (this.chancesLeft === 0) {
					uni.showToast({ title: this.doneText, icon: 'none' })
					return
				}
				const areaInfo = this.getAreaInfo()
				if (this.matchScope === 'school' && !areaInfo.regionId) {
					uni.showToast({ title: '请先选择校区', icon: 'none' })
					return
				}
				this.matching = true
				try {
					const matchAnimation = this.wait(2000)
					const match = await startIeMatch({
						mode: this.currentMode,
						targetMode: this.targetMode,
						targetGender: this.targetGender,
						matchScope: this.matchScope,
						intent: this.matchIntent || '',
						fuzzyKeyword: this.fuzzyKeyword.trim(),
						mood: this.currentMood,
						...areaInfo,
						interestTags: [this.activeMood.label]
					})
					await matchAnimation
					if (!match || !match.roomId) {
						uni.showToast({ title: (match && match.failReason) || '暂时没有同频的人', icon: 'none' })
						return
					}
					this.applyMatchResult(match)
					// 匹配成功即消耗一次机会，与服务端 usedQuota 保持一致
					this.chancesLeft = Math.max(this.chancesLeft - 1, 0)
					this.showMatch = true
				} finally {
					this.matching = false
				}
			},
			applyMatchResult(match) {
				this.currentMatch = match
				this.matchedPerson = {
					avatar: match.avatarText || '◌',
					avatarUrl: match.avatarUrl || '',
					name: match.anonymousName || '半匿名漂流者',
					mode: match.mode || this.currentMode,
					mood: match.mood || 'quiet',
					moodIcon: this.moodIcon(match.mood || 'quiet'),
					moodText: this.moodText(match.mood || 'quiet'),
					gender: match.gender || '',
					regionName: match.regionName || '',
					tags: match.interestTags || [],
					personaImages: match.personaImages || [],
					state: match.stateText || '也在等一句轻轻的回应',
					quote: match.companionIntent || match.quoteText || '可以先安静待一会，不用急着找话题。',
					lastActiveText: match.lastActiveText || ''
				}
			},
			modeText(mode) {
				return mode === 'e' ? 'e 人' : 'i 人'
			},
			moodIcon(key) {
				const item = this.moods.find(mood => mood.key === key)
				return item ? item.icon : '🌙'
			},
			moodText(key) {
				const item = this.moods.find(mood => mood.key === key)
				return item ? `此刻${item.label}` : '此刻想安静'
			},
			moodEmoji(item) {
				const map = { quiet: '🌙', talk: '💭', listen: '🎧', drift: '🫧' }
				return map[item.mood] || (item.type === 'e' ? '⚡' : '🌱')
			},
			genderText(gender) {
				if (gender === 'male') return '男生'
				if (gender === 'female') return '女生'
				return '性别未设置'
			},
			previewMatchedPersona(index) {
				const images = this.matchedPerson.personaImages || []
				if (!images.length) return
				uni.previewImage({ urls: images, current: images[index] })
			},
			closeMatch() { this.showMatch = false },
			showTicketTip() {
				uni.showToast({ title: '平台下单，订单完成可获得更多漂流票哦', icon: 'none' })
			},
			toggleMode() {
				this.currentMode = this.currentMode === 'i' ? 'e' : 'i'
				this.syncStatus()
			},
			changeMood(key) {
				this.currentMood = key
				this.playMoodCopy(this.activeMood.copy)
				this.syncStatus()
			},
			async selectDrift(item) {
				if (item && item.isUserIntent && item.userId) {
					if (item.isSelf) {
						uni.showToast({ title: '这是你发布的内容，不能匹配自己', icon: 'none' })
						return
					}
					await this.matchDriftUser(item)
				}
			},
			async matchDriftUser(item) {
				if (this.matching) return
				this.matching = true
				try {
					const match = await matchIeProfile(item.userId)
					if (!match || !match.roomId) {
						uni.showToast({ title: (match && match.failReason) || '暂时不能发起聊天', icon: 'none' })
						return
					}
					this.applyMatchResult(match)
					this.showMatch = true
				} finally {
					this.matching = false
				}
			},
			playMoodCopy(text) {
				if (this.moodTypeTimer) {
					clearInterval(this.moodTypeTimer)
					this.moodTypeTimer = null
				}
				const chars = Array.from(text)
				let index = 0
				this.displayMoodCopy = ''
				this.moodTypeTimer = setInterval(() => {
					index += 1
					this.displayMoodCopy = chars.slice(0, index).join('')
					if (index >= chars.length) {
						clearInterval(this.moodTypeTimer)
						this.moodTypeTimer = null
					}
				}, 42)
			},
			replyDrift() {
				uni.showToast({ title: '可以从一句话开始', icon: 'none' })
			},
			likeDrift() {
				uni.showToast({ title: '已轻轻回应', icon: 'none' })
			},
			openProfile() {
				this.goUniverse()
			},
			openTargetPanel() {
				this.showTargetPanel = true
			},
			closeTargetPanel() {
				this.showTargetPanel = false
			},
			openCompanionEditor() {
				this.editCompanionIntent = this.customCompanionIntent || ''
				this.showCompanionEditor = true
			},
			closeCompanionEditor() {
				if (this.savingCompanionIntent) return
				this.keyboardHeight = 0
				this.showCompanionEditor = false
			},
			onCompanionInputFocus(event) {
				const height = event && event.detail ? Number(event.detail.height) || 0 : 0
				this.keyboardHeight = height
			},
			onCompanionInputBlur() {
				this.keyboardHeight = 0
			},
			async saveCompanionIntent() {
				if (this.savingCompanionIntent) return
				const text = this.editCompanionIntent.trim()
				if (!text) {
					uni.showToast({ title: '先写一句想找什么搭子', icon: 'none' })
					return
				}
				this.savingCompanionIntent = true
				uni.showLoading({ title: '保存中...', mask: true })
				try {
					const saved = await saveIeProfile({
						...this.profile,
						companionIntent: text
					})
					if (!saved) return
					this.profile = saved
					this.customCompanionIntent = saved.companionIntent || text
					this.editCompanionIntent = this.customCompanionIntent
					this.showCompanionEditor = false
					uni.showToast({ title: '已发布', icon: 'none' })
					this.loadHome()
				} finally {
					this.savingCompanionIntent = false
					uni.hideLoading()
				}
			},
			closeProfile() {
				this.showProfile = false
			},
			getGalaxyPoint(event) {
				const touch = (event.touches && event.touches[0]) || (event.changedTouches && event.changedTouches[0])
				if (!touch) return null
				const x = touch.pageX !== undefined ? touch.pageX : touch.clientX
				const y = touch.pageY !== undefined ? touch.pageY : touch.clientY
				if (x === undefined || y === undefined) return null
				return { x, y }
			},
			startGalaxyDrag(event) {
				const point = this.getGalaxyPoint(event)
				if (!point) return
				this.galaxyDragging = true
				this.galaxyMoved = false
				this.galaxyStartX = point.x
				this.galaxyStartY = point.y
			},
			moveGalaxyDrag(event) {
				if (!this.galaxyDragging) return
				const now = Date.now()
				if (now - this.galaxyLastMoveTime < 32) return
				this.galaxyLastMoveTime = now
				const point = this.getGalaxyPoint(event)
				if (!point) return
				const deltaX = point.x - this.galaxyStartX
				const deltaY = point.y - this.galaxyStartY
				if (Math.abs(deltaX) + Math.abs(deltaY) > 4) {
					this.galaxyMoved = true
				}
				this.galaxyRotateY = (this.galaxyRotateY + deltaX * 0.82) % 360
				this.galaxyRotateX = Math.max(-48, Math.min(48, this.galaxyRotateX - deltaY * 0.28))
				this.galaxyStartX = point.x
				this.galaxyStartY = point.y
			},
			endGalaxyDrag() {
				if (!this.galaxyDragging) return
				this.galaxyDragging = false
			},
			skipMatch() {
				this.showMatch = false
				uni.showToast({ title: "这次轻轻划过了", icon: 'none' })
			},
			goChat() {
				this.showMatch = false
				const room = this.currentMatch ? '&roomId=' + this.currentMatch.roomId + '&targetUserId=' + this.currentMatch.targetUserId +
					'&name=' + encodeURIComponent(this.matchedPerson.name || '') +
					'&avatar=' + encodeURIComponent(this.matchedPerson.avatar || '') +
					'&avatarUrl=' + encodeURIComponent(this.matchedPerson.avatarUrl || '') +
					'&quote=' + encodeURIComponent(this.matchedPerson.quote || '') : ''
				uni.navigateTo({ url: '/package1/ieBrowser/chat?mode=' + this.currentMode + '&mood=' + this.currentMood + room })
			},
			async goMatch() {
				await this.openMatch()
			},
			goMatchPage() {
				uni.navigateTo({ url: '/package1/ieBrowser/match?mode=' + this.currentMode + '&mood=' + this.currentMood + '&targetMode=' + this.targetMode + '&targetGender=' + this.targetGender + '&matchScope=' + this.matchScope + '&intent=' + (this.matchIntent || '') })
			},
			goRecords() { uni.navigateTo({ url: '/package1/ieBrowser/chatList' }) },
			goArchive() { uni.navigateTo({ url: '/package1/ieBrowser/universe' }) },
			goFate() { uni.navigateTo({ url: '/package1/ieBrowser/fate' }) },
			goMessages() { uni.navigateTo({ url: '/package1/ieBrowser/messages?unreadCount=' + encodeURIComponent(String(this.unreadCount || 0)) }) },
			goUniverse() { uni.navigateTo({ url: '/package1/ieBrowser/universe?unreadCount=' + encodeURIComponent(String(this.unreadCount || 0)) }) },
			backHome() { uni.switchTab({ url: '/pages/index/index' }) }
		}
	}
</script>

<style lang="scss" scoped>
	page {
		background: #f7f9ff;
	}

	/* ============ 页面底色：通透极光星系 ============ */
	.ie-page {
		position: relative;
		min-height: 100vh;
		padding: 0 32rpx 230rpx;
		box-sizing: border-box;
		color: #161b2e;
		overflow: hidden;
		display: flex;
		flex-direction: column;
		background:
			radial-gradient(circle at 12% 8%, rgba(221, 231, 255, .9), transparent 320rpx),
			radial-gradient(circle at 90% 16%, rgba(169, 255, 231, .5), transparent 340rpx),
			radial-gradient(circle at 16% 66%, rgba(255, 214, 165, .42), transparent 360rpx),
			radial-gradient(circle at 88% 76%, rgba(255, 184, 209, .3), transparent 400rpx),
			linear-gradient(180deg, #fbfdff 0%, #eef4ff 56%, #fff5ea 100%);
	}

	.android-home {
		height: 100vh;
		padding-bottom: 232rpx;
	}

	/* 星点纹理 */
	.ie-page::before {
		content: '';
		position: absolute;
		inset: 0;
		pointer-events: none;
		opacity: .1;
		background-image:
			radial-gradient(circle, rgba(22, 27, 46, .4) 0 1rpx, transparent 1rpx),
			radial-gradient(circle, rgba(108, 92, 231, .3) 0 1rpx, transparent 1rpx);
		background-size: 46rpx 46rpx, 74rpx 74rpx;
	}

	.aurora {
		position: absolute;
		border-radius: 50%;
		filter: blur(60rpx);
		pointer-events: none;
		animation: auroraDrift 10s ease-in-out infinite;
	}

	.aurora-a {
		top: 140rpx;
		right: -120rpx;
		width: 380rpx;
		height: 380rpx;
		background: rgba(162, 155, 254, .3);
	}

	.aurora-b {
		left: -160rpx;
		top: 560rpx;
		width: 420rpx;
		height: 420rpx;
		background: rgba(169, 255, 231, .4);
		animation-delay: 2s;
	}

	.aurora-c {
		right: -100rpx;
		bottom: 240rpx;
		width: 340rpx;
		height: 340rpx;
		background: rgba(255, 184, 209, .3);
		animation-delay: 4s;
	}

	/* ============ 顶部悬浮条 ============ */
	.float-bar {
		position: relative;
		z-index: 5;
		display: flex;
		align-items: center;
		justify-content: space-between;
		margin-top: 14rpx;
	}

	.home-back {
		display: flex;
		align-items: center;
		height: 58rpx;
		padding: 0 22rpx 0 12rpx;
		border: 1rpx solid rgba(255, 255, 255, .88);
		border-radius: 999rpx;
		color: rgba(22, 27, 46, .66);
		background: rgba(255, 255, 255, .66);
		backdrop-filter: blur(20rpx);
		box-shadow: 0 14rpx 36rpx rgba(96, 112, 160, .12), inset 0 1rpx 0 rgba(255, 255, 255, .95);
		font-size: 23rpx;
		font-weight: 800;
	}

	.home-back:active {
		transform: scale(.95);
		background: rgba(169, 255, 231, .7);
	}

	.home-back-icon {
		margin-right: 6rpx;
		padding-bottom: 6rpx;
		font-size: 40rpx;
		line-height: 50rpx;
		font-weight: 400;
	}

	.perf-toggle {
		flex-shrink: 0;
		height: 52rpx;
		line-height: 52rpx;
		padding: 0 20rpx;
		border-radius: 999rpx;
		color: rgba(22, 27, 46, .58);
		background: rgba(255, 255, 255, .66);
		border: 1rpx solid rgba(255, 255, 255, .88);
		box-shadow: 0 10rpx 26rpx rgba(96, 112, 160, .1);
		font-size: 21rpx;
		font-weight: 800;
	}

	.perf-toggle.active {
		color: #11162a;
		background: #a9ffe7;
	}

	/* ============ Hero 海报大字区 ============ */
	.hero {
		position: relative;
		z-index: 4;
		margin-top: 20rpx;
		animation: riseIn .5s ease both;
	}

	.hero-top {
		display: flex;
		align-items: center;
		gap: 16rpx;
	}

	.hero-eyebrow {
		display: inline-block;
		padding: 8rpx 22rpx;
		border-radius: 999rpx;
		color: #5b4fd6;
		background: rgba(139, 124, 255, .12);
		font-size: 22rpx;
		font-weight: 800;
		letter-spacing: 2rpx;
	}

	.hero-statement {
		margin-top: 14rpx;
		font-size: 38rpx;
		line-height: 54rpx;
		font-weight: 900;
		letter-spacing: -1rpx;
		color: #161b2e;
	}

	.hero-statement.second {
		margin-top: 0;
	}

	.hero-num {
		display: inline-block;
		margin: 0 6rpx;
		padding-right: 4rpx;
		font-size: 54rpx;
		font-weight: 900;
		color: #6c5ce7;
		background: linear-gradient(115deg, #6c5ce7 10%, #00cba9 55%, #ff7eb3 95%);
		-webkit-background-clip: text;
		background-clip: text;
		-webkit-text-fill-color: transparent;
		animation: countPop .42s ease;
	}

	.hero-live {
		display: inline-flex;
		align-items: center;
		max-width: 100%;
		margin-top: 12rpx;
		padding: 8rpx 22rpx;
		border-radius: 999rpx;
		color: rgba(22, 27, 46, .62);
		background: rgba(255, 255, 255, .6);
		border: 1rpx solid rgba(255, 255, 255, .88);
		backdrop-filter: blur(16rpx);
		box-shadow: inset 0 1rpx 0 rgba(255, 255, 255, .92), 0 10rpx 28rpx rgba(96, 112, 160, .08);
		font-size: 23rpx;
		font-weight: 600;
	}

	.daily-live {
		box-sizing: border-box;
		gap: 10rpx;
		padding-right: 18rpx;
	}

	.live-dot {
		width: 14rpx;
		height: 14rpx;
		border-radius: 50%;
		background: #2bd9a4;
		animation: liveDotPulse 1.8s ease-out infinite;
	}

	.daily-live-tag,
	.daily-live-go {
		flex-shrink: 0;
		font-weight: 900;
	}

	.daily-live-tag {
		color: #6c5ce7;
	}

	.daily-live-text {
		flex: 1;
		min-width: 0;
		overflow: hidden;
		white-space: nowrap;
		text-overflow: ellipsis;
		color: rgba(22, 27, 46, .66);
	}

	.daily-live-go {
		color: #8b7cff;
		font-size: 21rpx;
	}

	.hero-profile-line {
		display: flex;
		align-items: center;
		justify-content: space-between;
		gap: 14rpx;
		margin-top: 14rpx;
	}

	.hero-profile {
		display: flex;
		align-items: center;
		width: fit-content;
		max-width: 600rpx;
		min-width: 0;
		padding: 10rpx 22rpx 10rpx 10rpx;
		border-radius: 999rpx;
		background: rgba(255, 255, 255, .56);
		border: 1rpx solid rgba(255, 255, 255, .82);
		box-shadow: 0 14rpx 40rpx rgba(96, 112, 160, .1);
		transition: transform .16s ease;
	}

	.say-intent-btn {
		flex-shrink: 0;
		height: 58rpx;
		line-height: 58rpx;
		padding: 0 22rpx;
		border-radius: 999rpx;
		color: #5b4fd6;
		background: rgba(255, 255, 255, .62);
		border: 1rpx solid rgba(255, 255, 255, .9);
		box-shadow: 0 12rpx 30rpx rgba(96, 112, 160, .1);
		font-size: 22rpx;
		font-weight: 900;
	}

	.say-intent-btn:active {
		transform: scale(.96);
		background: rgba(169, 255, 231, .76);
	}

	.hero-profile:active {
		transform: scale(.97);
	}

	.profile-avatar,
	.profile-avatar-img {
		width: 64rpx;
		height: 64rpx;
		margin-right: 16rpx;
		border-radius: 50%;
		flex-shrink: 0;
	}

	.profile-avatar {
		text-align: center;
		line-height: 64rpx;
		color: #11162a;
		background: linear-gradient(145deg, #effffb, #a9ffe7);
		font-size: 26rpx;
		font-weight: 800;
	}

	.profile-name {
		font-size: 26rpx;
		font-weight: 800;
	}

	.profile-tags {
		margin-top: 4rpx;
		color: rgba(22, 27, 46, .44);
		font-size: 20rpx;
	}

	.profile-arrow {
		margin-left: 18rpx;
		color: rgba(22, 27, 46, .35);
		font-size: 36rpx;
		font-weight: 300;
	}

	/* ============ 漂流星域：弹幕 + 星球 ============ */
	.lower-stack {
		position: relative;
		z-index: 3;
	}

	.android-home .lower-stack {
		transform: translateY(28rpx);
	}

	.drift-field {
		position: relative;
		z-index: 3;
		height: 470rpx;
		margin: 36rpx -32rpx 0;
	}

	.spark {
		position: absolute;
		z-index: 1;
		color: rgba(108, 92, 231, .55);
		font-size: 24rpx;
		animation: sparkTwinkle 2.6s ease-in-out infinite;
		pointer-events: none;
	}

	.spark-a { left: 92rpx; top: 168rpx; }
	.spark-b { right: 70rpx; top: 120rpx; color: rgba(255, 158, 194, .7); font-size: 30rpx; animation-delay: .8s; }
	.spark-c { right: 160rpx; bottom: 70rpx; color: rgba(43, 217, 164, .7); animation-delay: 1.6s; }
	.spark-d { left: 60rpx; bottom: 150rpx; color: rgba(255, 214, 165, .9); font-size: 28rpx; animation-delay: 2.2s; }

	/* 弹幕轨道：上下留出余量，避免倾斜的气泡被裁切 */
	.danmu-lane {
		position: absolute;
		left: 0;
		right: 0;
		z-index: 2;
		padding: 14rpx 0;
		overflow: hidden;
	}

	.lane-0 { top: 0; }
	.lane-1 { top: 188rpx; z-index: 1; }
	.lane-2 { bottom: 0; }

	.lane-track {
		display: flex;
		align-items: center;
		width: max-content;
		animation: laneScroll 26s linear infinite;
	}

	.lane-1 .lane-track {
		animation-duration: 34s;
		animation-direction: reverse;
		opacity: .85;
	}

	.lane-2 .lane-track {
		animation-duration: 22s;
	}

	.danmu-item {
		display: flex;
		align-items: center;
		flex-shrink: 0;
		margin-right: 56rpx;
		padding: 14rpx 26rpx;
		border-radius: 999rpx;
		border: 1rpx solid rgba(255, 255, 255, .9);
		transition: transform .16s ease;
	}

	.danmu-item:active {
		transform: scale(1.06);
	}

	.danmu-item.tint-0 { background: linear-gradient(135deg, rgba(217, 250, 240, .96), rgba(255, 255, 255, .9)); transform: rotate(-1.6deg); }
	.danmu-item.tint-1 { background: linear-gradient(135deg, rgba(228, 235, 255, .96), rgba(255, 255, 255, .9)); transform: rotate(1.4deg); }
	.danmu-item.tint-2 { background: linear-gradient(135deg, rgba(255, 235, 211, .96), rgba(255, 255, 255, .9)); transform: rotate(-1.2deg); }
	.danmu-item.tint-3 { background: linear-gradient(135deg, rgba(255, 226, 237, .96), rgba(255, 255, 255, .9)); transform: rotate(1.8deg); }

	.danmu-emoji {
		margin-right: 12rpx;
		font-size: 28rpx;
		line-height: 1;
	}

	.danmu-text {
		color: rgba(22, 27, 46, .76);
		font-size: 24rpx;
		font-weight: 600;
		white-space: nowrap;
	}

	/* 中央星球 */
	.signal-planet {
		position: absolute;
		left: 50%;
		top: 50%;
		z-index: 5;
		width: 410rpx;
		height: 410rpx;
		perspective: 1180rpx;
	}

	.galaxy-breath {
		position: absolute;
		inset: 0;
		animation: galaxyBreath 4.2s ease-in-out infinite;
	}

	.galaxy-body {
		position: absolute;
		left: 50%;
		top: 50%;
		width: 260rpx;
		height: 260rpx;
		transform: translate(-50%, -50%) translateZ(34rpx);
		border-radius: 47% 53% 44% 56% / 56% 42% 58% 44%;
		background:
			radial-gradient(circle at 28% 24%, rgba(255, 255, 255, .94), rgba(255, 255, 255, 0) 38%),
			radial-gradient(circle at 70% 74%, rgba(162, 155, 254, .66), rgba(162, 155, 254, 0) 46%),
			linear-gradient(135deg, rgba(169, 255, 231, .78), rgba(221, 231, 255, .76) 54%, rgba(255, 184, 209, .52));
		box-shadow:
			0 36rpx 96rpx rgba(108, 92, 231, .22),
			inset 10rpx 12rpx 34rpx rgba(255, 255, 255, .64),
			inset -20rpx -22rpx 42rpx rgba(108, 92, 231, .18);
		overflow: hidden;
		z-index: 12;
		animation: blobMorph 9s ease-in-out infinite;
	}

	.galaxy-body::before {
		content: '';
		position: absolute;
		left: 28rpx;
		top: 22rpx;
		width: 108rpx;
		height: 86rpx;
		border-radius: 50%;
		background: radial-gradient(circle, rgba(255, 255, 255, .85), rgba(255, 255, 255, 0) 68%);
		filter: blur(2rpx);
		z-index: 1;
	}

	.galaxy-ring {
		position: absolute;
		left: 50%;
		top: 50%;
		border-radius: 50%;
		pointer-events: none;
	}

	.ring-main {
		width: 480rpx;
		height: 148rpx;
		margin-left: -240rpx;
		margin-top: -74rpx;
		border: 12rpx solid rgba(111, 231, 224, .36);
		box-shadow: 0 0 34rpx rgba(169, 255, 231, .32), inset 0 0 22rpx rgba(255, 255, 255, .46);
		transform: rotateX(66deg) rotateZ(-14deg);
		animation: ringDrift 18s linear infinite;
	}

	.ring-second {
		width: 396rpx;
		height: 120rpx;
		margin-left: -198rpx;
		margin-top: -60rpx;
		border: 4rpx solid rgba(162, 155, 254, .38);
		transform: rotateX(72deg) rotateZ(24deg) translateZ(24rpx);
		animation: ringDrift 24s linear infinite reverse;
	}

	.ring-third {
		width: 318rpx;
		height: 318rpx;
		margin-left: -159rpx;
		margin-top: -159rpx;
		border: 3rpx solid rgba(255, 214, 165, .36);
		transform: rotateX(18deg) rotateY(64deg);
		animation: ringDrift 30s linear infinite;
	}

	.orbit-planet {
		position: absolute;
		left: 50%;
		top: 50%;
		border-radius: 50%;
		pointer-events: none;
		box-shadow:
			0 0 18rpx rgba(255, 255, 255, .72),
			0 0 34rpx currentColor,
			inset 3rpx 4rpx 8rpx rgba(255, 255, 255, .68),
			inset -4rpx -5rpx 10rpx rgba(108, 92, 231, .18);
		transition: transform .16s linear, opacity .16s linear;
	}

	.orbit-planet::after {
		content: '';
		position: absolute;
		left: 18%;
		top: 16%;
		width: 34%;
		height: 28%;
		border-radius: 50%;
		background: rgba(255, 255, 255, .86);
		filter: blur(1rpx);
	}

	.liquid {
		position: absolute;
		border-radius: 45%;
		filter: blur(2rpx);
	}

	.liquid-a {
		left: -46rpx;
		top: 16rpx;
		width: 250rpx;
		height: 226rpx;
		background: rgba(169, 255, 231, .58);
		animation: liquidMove 7s ease-in-out infinite;
	}

	.liquid-b {
		right: -60rpx;
		bottom: -20rpx;
		width: 238rpx;
		height: 232rpx;
		background: rgba(139, 124, 255, .28);
		animation: liquidMove 8s ease-in-out infinite reverse;
	}

	.soul-particle {
		position: absolute;
		width: 8rpx;
		height: 8rpx;
		border-radius: 50%;
		background: rgba(255, 255, 255, .86);
		box-shadow: 0 0 18rpx rgba(255, 255, 255, .8);
		z-index: 2;
		animation: soulFloat 5s ease-in-out infinite;
	}

	.soul-a { left: 78rpx; top: 66rpx; }
	.soul-b { right: 70rpx; top: 116rpx; animation-delay: 1.2s; }
	.soul-c { left: 142rpx; bottom: 70rpx; animation-delay: 2s; }

	.planet-core {
		position: relative;
		z-index: 2;
		height: 100%;
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
		text-align: center;
	}

	.planet-text {
		font-size: 32rpx;
		line-height: 44rpx;
		font-weight: 800;
		color: #161b2e;
		white-space: nowrap;
	}

	.planet-sub {
		margin-top: 8rpx;
		color: rgba(22, 27, 46, .5);
		font-size: 23rpx;
		animation: subBreath 3s ease-in-out infinite;
	}

	.planet-cta {
		margin-top: 16rpx;
		padding: 8rpx 20rpx;
		border-radius: 999rpx;
		color: #5b4fd6;
		background: rgba(255, 255, 255, .78);
		box-shadow: 0 8rpx 22rpx rgba(108, 92, 231, .2), inset 0 1rpx 0 rgba(255, 255, 255, .95);
		font-size: 20rpx;
		font-weight: 800;
		letter-spacing: 1rpx;
		animation: ctaBreath 2.2s ease-in-out infinite;
	}

	/* ============ 底部功能面板 ============ */
	.home-action-panel {
		position: relative;
		z-index: 4;
		margin-top: 26rpx;
		padding: 14rpx 14rpx 18rpx;
		border-radius: 32rpx;
		background:
			linear-gradient(180deg, rgba(255, 255, 255, .82), rgba(255, 255, 255, .68)),
			radial-gradient(circle at 16% 0%, rgba(169, 255, 231, .28), transparent 220rpx),
			radial-gradient(circle at 88% 22%, rgba(162, 155, 254, .2), transparent 240rpx);
		border: 1rpx solid rgba(255, 255, 255, .9);
		backdrop-filter: blur(22rpx);
		box-shadow: 0 22rpx 70rpx rgba(96, 112, 160, .14), inset 0 1rpx 0 rgba(255, 255, 255, .92);
	}

	.android-home .drift-field {
		margin-top: 22rpx;
	}

	.android-home .home-action-panel {
		margin-top: 18rpx;
	}

	.play-deck {
		display: flex;
		align-items: stretch;
		top: 12rpx;
		gap: 12rpx;
	}

	.ticket {
		flex: 1.3;
		display: flex;
		align-items: stretch;
		min-height: 94rpx;
		border-radius: 24rpx;
		overflow: hidden;
		background: #ffffff;
		box-shadow: 0 12rpx 30rpx rgba(96, 112, 160, .12);
		transition: transform .16s ease;
	}

	.ticket:active {
		transform: scale(.95);
	}

	.ticket-left {
		flex: 1;
		display: flex;
		align-items: center;
		gap: 10rpx;
		padding: 0 12rpx 0 18rpx;
		background: linear-gradient(135deg, #dffef4, #aef5dd);
	}

	.ticket-icon {
		font-size: 34rpx;
	}

	.ticket-label {
		color: #0e4a35;
		font-size: 22rpx;
		font-weight: 900;
		letter-spacing: 1rpx;
		white-space: nowrap;
	}

	.ticket-divider {
		position: relative;
		width: 0;
		margin: 14rpx 0;
		border-left: 3rpx dashed rgba(22, 27, 46, .18);
	}

	.ticket-divider::before,
	.ticket-divider::after {
		content: '';
		position: absolute;
		left: -11rpx;
		width: 20rpx;
		height: 20rpx;
		border-radius: 50%;
		background: #f1f5fd;
	}

	.ticket-divider::before { top: -24rpx; }
	.ticket-divider::after { bottom: -24rpx; }

	.ticket-right {
		display: flex;
		align-items: center;
		justify-content: center;
		gap: 6rpx;
		min-width: 106rpx;
		padding: 0 16rpx;
	}

	.ticket-num {
		font-size: 46rpx;
		font-weight: 900;
		color: #6c5ce7;
		background: linear-gradient(120deg, #6c5ce7, #00b894);
		-webkit-background-clip: text;
		background-clip: text;
		-webkit-text-fill-color: transparent;
	}

	.ticket-unit {
		color: rgba(22, 27, 46, .45);
		font-size: 20rpx;
		font-weight: 700;
	}

	.target-btn {
		flex: 1;
		position: relative;
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
		gap: 4rpx;
		min-height: 94rpx;
		border-radius: 24rpx;
		overflow: hidden;
		color: #fff;
		background: linear-gradient(135deg, #6c5ce7, #a29bfe);
		box-shadow: 0 14rpx 34rpx rgba(108, 92, 231, .28);
		transition: transform .16s ease;
		animation: entryWiggle 5s ease-in-out infinite;
	}

	.target-btn:active {
		transform: scale(.95);
	}

	.target-star {
		position: absolute;
		right: 16rpx;
		top: 10rpx;
		color: #ffe28b;
		font-size: 26rpx;
		animation: sparkTwinkle 1.6s ease-in-out infinite;
	}

	.target-text {
		font-size: 27rpx;
		font-weight: 900;
		letter-spacing: 1rpx;
	}

	.target-sub {
		color: rgba(255, 255, 255, .72);
		font-size: 18rpx;
		font-weight: 700;
	}

	/* ============ 心情星球带 ============ */
	.daily-q-bar {
		position: relative;
		z-index: 4;
		display: flex;
		align-items: center;
		gap: 12rpx;
		margin-top: 28rpx;
		padding: 22rpx 18rpx;
		border-radius: 999rpx;
		background: rgba(255, 255, 255, .76);
		border: 1rpx solid rgba(255, 255, 255, .8);
		box-shadow: 0 10rpx 26rpx rgba(96, 112, 160, .1);
	}

	.daily-q-bar:active {
		transform: scale(.98);
	}

	.mood-copy-bar {
		justify-content: center;
		min-height: 58rpx;
		color: rgba(22, 27, 46, .62);
		font-size: 23rpx;
		line-height: 32rpx;
		text-align: center;
		font-weight: 800;
	}

	.daily-q-tag {
		flex-shrink: 0;
		padding: 6rpx 16rpx;
		border-radius: 999rpx;
		font-size: 20rpx;
		font-weight: 800;
		color: #fff;
		background: linear-gradient(135deg, #7a4dff, #ff7eb3);
	}

	.daily-q-text {
		flex: 1;
		overflow: hidden;
		white-space: nowrap;
		text-overflow: ellipsis;
		font-size: 24rpx;
		font-weight: 700;
		color: rgba(22, 27, 46, .76);
	}

	.daily-q-go {
		flex-shrink: 0;
		font-size: 22rpx;
		font-weight: 800;
		color: #7a4dff;
	}

	.mood-strip {
		position: relative;
		z-index: 4;
		margin-top: 22rpx;
		padding: 2rpx 4rpx 0;
	}

	.strip-tag {
		display: inline-block;
		padding: 8rpx 22rpx;
		border-radius: 999rpx;
		color: #7a4b12;
		background: linear-gradient(135deg, #ffe9c9, #ffd6a5);
		box-shadow: 0 10rpx 24rpx rgba(255, 195, 130, .3);
		font-size: 22rpx;
		font-weight: 900;
		letter-spacing: 1rpx;
		transform: rotate(-2deg);
	}

	.mood-orbs {
		display: flex;
		justify-content: space-between;
		padding: 0 8rpx;
	}

	.mood-orb {
		display: flex;
		flex-direction: column;
		align-items: center;
		gap: 8rpx;
	}

	.orb-face {
		position: relative;
		width: 94rpx;
		height: 94rpx;
		border-radius: 50%;
		display: flex;
		align-items: center;
		justify-content: center;
		background: #ffffff;
		border: 1rpx solid rgba(255, 255, 255, .92);
		box-shadow: 0 12rpx 28rpx rgba(96, 112, 160, .14), inset 0 -8rpx 14rpx rgba(139, 124, 255, .07);
		transition: transform .2s cubic-bezier(.34, 1.56, .64, 1), background .24s ease, box-shadow .24s ease;
	}

	.mood-orb:active .orb-face {
		transform: scale(.86);
	}

	.mood-orb.active .orb-face {
		background: linear-gradient(145deg, #eafff8, #a9ffe7);
		box-shadow: 0 16rpx 36rpx rgba(43, 217, 164, .34);
		transform: translateY(-8rpx) scale(1.1);
	}

	.mood-orb.active .orb-face::after {
		content: '';
		position: absolute;
		inset: -12rpx;
		border-radius: 50%;
		border: 3rpx dashed rgba(43, 217, 164, .6);
		animation: orbSpin 9s linear infinite;
	}

	.orb-emoji {
		font-size: 44rpx;
		line-height: 1;
	}

	.mood-orb.active .orb-emoji {
		animation: emojiBounce .42s cubic-bezier(.34, 1.56, .64, 1);
	}

	.orb-label {
		color: rgba(22, 27, 46, .5);
		font-size: 22rpx;
		font-weight: 700;
		transition: color .2s ease;
	}

	.mood-orb.active .orb-label {
		color: #0e4a35;
		font-weight: 900;
	}

	.say-bubble {
		position: relative;
		width: fit-content;
		max-width: 620rpx;
		margin: 24rpx auto 0;
		display: flex;
		align-items: center;
		justify-content: center;
		padding: 12rpx 24rpx;
		border-radius: 999rpx;
		color: rgba(22, 27, 46, .58);
		background: rgba(255, 255, 255, .76);
		border: 1rpx solid rgba(255, 255, 255, .94);
		box-shadow: 0 12rpx 34rpx rgba(139, 124, 255, .1), inset 0 1rpx 0 rgba(255, 255, 255, .95);
		font-size: 23rpx;
		line-height: 34rpx;
		text-align: center;
		font-weight: 700;
		min-height: 34rpx;
	}

	.typing-cursor {
		display: inline-block;
		width: 3rpx;
		height: 28rpx;
		margin-left: 6rpx;
		border-radius: 999rpx;
		background: rgba(108, 92, 231, .58);
		vertical-align: -4rpx;
		animation: typingCursor .86s steps(1) infinite;
	}

	/* ============ 随机陪伴设置弹层 ============ */
	.target-mask {
		position: fixed;
		inset: 0;
		z-index: 99;
		display: flex;
		align-items: flex-end;
		padding: 32rpx 30rpx 158rpx;
		box-sizing: border-box;
		background: rgba(22, 27, 46, .42);
		backdrop-filter: blur(24rpx);
	}

	.target-popup {
		width: 100%;
		padding: 34rpx 30rpx 30rpx;
		border-radius: 42rpx;
		border: 1rpx solid rgba(255, 255, 255, .9);
		background:
			linear-gradient(135deg, #ffffff, #f9fbff),
			radial-gradient(circle at 82% 0%, rgba(169, 255, 231, .28), transparent 220rpx);
		box-shadow: 0 34rpx 100rpx rgba(96, 112, 160, .22);
		box-sizing: border-box;
		animation: targetUp .18s ease-out both;
	}

	.target-popup-head {
		display: flex;
		align-items: flex-start;
		justify-content: space-between;
		margin-bottom: 28rpx;
	}

	.target-popup-title {
		color: #161b2e;
		font-size: 34rpx;
		font-weight: 900;
	}

	.target-popup-sub {
		margin-top: 8rpx;
		color: rgba(22, 27, 46, .46);
		font-size: 23rpx;
	}

	.target-close {
		width: 58rpx;
		height: 58rpx;
		border-radius: 50%;
		text-align: center;
		line-height: 54rpx;
		color: rgba(22, 27, 46, .5);
		background: rgba(238, 244, 255, .78);
		font-size: 36rpx;
		font-weight: 700;
	}

	.target-title {
		color: rgba(22, 27, 46, .54);
		font-size: 23rpx;
		font-weight: 800;
	}

	.target-row {
		display: flex;
		margin-top: 18rpx;
	}

	.intent-row {
		flex-wrap: wrap;
		gap: 12rpx 0;
	}

	.target-input {
		height: 68rpx;
		margin-top: 16rpx;
		padding: 0 24rpx;
		border-radius: 999rpx;
		color: #161b2e;
		background: rgba(255, 255, 255, .72);
		border: 1rpx solid rgba(255, 255, 255, .9);
		box-shadow: inset 0 1rpx 0 rgba(255, 255, 255, .96);
		font-size: 23rpx;
		font-weight: 700;
	}

	.search-input {
		margin-top: 12rpx;
		background: rgba(239, 244, 255, .74);
	}

	.companion-mask {
		position: fixed;
		inset: 0;
		z-index: 99;
		display: flex;
		align-items: flex-end;
		padding: 0 32rpx 190rpx;
		box-sizing: border-box;
		background: rgba(22, 27, 46, .2);
		backdrop-filter: blur(10rpx);
		transition: padding-bottom .18s ease;
	}

	.companion-editor {
		width: 100%;
		padding: 34rpx 30rpx 30rpx;
		border-radius: 42rpx;
		border: 1rpx solid rgba(255, 255, 255, .9);
		background: linear-gradient(135deg, rgba(255, 255, 255, .96), rgba(255, 255, 255, .84));
		box-shadow: 0 34rpx 100rpx rgba(96, 112, 160, .22);
		box-sizing: border-box;
		animation: targetUp .18s ease-out both;
	}

	.companion-editor-head {
		display: flex;
		align-items: flex-start;
		justify-content: space-between;
		gap: 24rpx;
		margin-bottom: 12rpx;
	}

	.companion-editor-title {
		color: #161b2e;
		font-size: 34rpx;
		font-weight: 900;
	}

	.companion-editor-sub {
		margin-top: 8rpx;
		color: rgba(22, 27, 46, .46);
		font-size: 23rpx;
		line-height: 34rpx;
	}

	.companion-input {
		margin-top: 22rpx;
	}

	.companion-save {
		height: 86rpx;
		line-height: 86rpx;
		margin-top: 22rpx;
		border-radius: 999rpx;
		text-align: center;
		color: #11162a;
		background: linear-gradient(135deg, #effffb, #a9ffe7 62%, #ffd6a5);
		box-shadow: 0 18rpx 46rpx rgba(169, 255, 231, .3);
		font-size: 28rpx;
		font-weight: 900;
	}

	.companion-save.disabled {
		opacity: .62;
	}

	.intent-chip.active {
		color: #fff;
		background: linear-gradient(135deg, #ff8a54, #ff5f8f);
		box-shadow: 0 10rpx 24rpx rgba(255, 110, 110, .3);
	}

	.target-chip {
		height: 62rpx;
		line-height: 62rpx;
		padding: 0 24rpx;
		margin-right: 14rpx;
		border-radius: 999rpx;
		color: rgba(22, 27, 46, .52);
		background: rgba(238, 244, 255, .78);
		font-size: 23rpx;
		font-weight: 700;
		transition: transform .14s ease;
	}

	.target-chip:active {
		transform: scale(.94);
	}

	.target-chip.active {
		color: #11162a;
		background: #a9ffe7;
	}

	.gender-title {
		margin-top: 24rpx;
	}

	.start-match-btn {
		height: 92rpx;
		line-height: 92rpx;
		margin-top: 26rpx;
		border-radius: 999rpx;
		text-align: center;
		color: #11162a;
		background: linear-gradient(135deg, #effffb, #a9ffe7 62%, #ffd6a5);
		box-shadow: 0 18rpx 46rpx rgba(169, 255, 231, .3);
		font-size: 29rpx;
		font-weight: 900;
		animation: breathButton 2.8s ease-in-out infinite;
	}

	.start-match-btn:active {
		transform: scale(.97);
	}

	/* ============ 缘分签弹层 ============ */
	.match-mask {
		position: fixed;
		inset: 0;
		z-index: 99;
		display: flex;
		align-items: flex-end;
		padding: 30rpx;
		background: rgba(22, 27, 46, .58);
		backdrop-filter: blur(24rpx);
		box-sizing: border-box;
	}

	.match-panel {
		width: 100%;
		max-height: 80vh;
		border: 1rpx solid rgba(255, 255, 255, .9);
		border-radius: 46rpx;
		background: #ffffff;
		box-sizing: border-box;
		box-shadow: 0 34rpx 110rpx rgba(22, 27, 46, .34);
		overflow: hidden;
		animation: targetUp .22s ease-out both;
	}

	.match-scroll {
		max-height: 80vh;
		box-sizing: border-box;
		background: linear-gradient(180deg, #ffffff 0%, #f7f9ff 100%);
	}

	.match-banner {
		position: relative;
		padding: 30rpx 34rpx 64rpx;
		background:
			radial-gradient(circle at 80% 20%, rgba(255, 226, 139, .3), transparent 200rpx),
			linear-gradient(135deg, rgba(108, 92, 231, .92), rgba(162, 155, 254, .88));
	}

	.match-banner-deco {
		position: absolute;
		right: 90rpx;
		top: 26rpx;
		color: rgba(255, 255, 255, .55);
		font-size: 22rpx;
		letter-spacing: 8rpx;
	}

	.match-label {
		color: rgba(255, 255, 255, .92);
		font-size: 24rpx;
		font-weight: 800;
		letter-spacing: 2rpx;
	}

	.close {
		position: absolute;
		right: 30rpx;
		top: 24rpx;
		width: 52rpx;
		height: 52rpx;
		border-radius: 50%;
		text-align: center;
		line-height: 48rpx;
		color: #fff;
		background: rgba(255, 255, 255, .2);
		font-size: 36rpx;
	}

	.match-body {
		position: relative;
		z-index: 2;
		padding: 0 34rpx 34rpx;
		background: linear-gradient(180deg, #ffffff 0%, #f7f9ff 100%);
	}

	.match-avatar-wrap {
		position: relative;
		z-index: 3;
		display: flex;
		justify-content: center;
		margin-top: -52rpx;
	}

	.companion-orb,
	.companion-orb-img {
		width: 148rpx;
		height: 148rpx;
		border-radius: 50%;
		border: 8rpx solid rgba(255, 255, 255, .96);
		background: #ffffff;
		box-shadow: 0 18rpx 46rpx rgba(108, 92, 231, .24);
		box-sizing: border-box;
	}

	.companion-orb {
		text-align: center;
		line-height: 132rpx;
		font-size: 48rpx;
		font-weight: 800;
	}

	.companion-orb.i {
		color: #f7f4ff;
		background: linear-gradient(145deg, #8b7cff, #dde7ff);
	}

	.companion-orb.e {
		color: #11162a;
		background: linear-gradient(145deg, #a9ffe7, #ffd6a5);
	}

	.match-name {
		margin-top: 18rpx;
		text-align: center;
		font-size: 36rpx;
		font-weight: 900;
	}

	.match-intent {
		margin: 12rpx auto 0;
		width: fit-content;
		padding: 8rpx 24rpx;
		border-radius: 999rpx;
		font-size: 23rpx;
		font-weight: 800;
		color: #ff5f3c;
		background: rgba(255, 138, 84, .12);
		border: 1rpx solid rgba(255, 138, 84, .32);
	}

	.match-mood {
		margin: 12rpx auto 0;
		display: flex;
		align-items: center;
		justify-content: center;
		gap: 8rpx;
		width: fit-content;
		max-width: 520rpx;
		padding: 8rpx 22rpx;
		border-radius: 999rpx;
		color: #5a55c8;
		background: rgba(139, 124, 255, .1);
		border: 1rpx solid rgba(139, 124, 255, .18);
		font-size: 22rpx;
		font-weight: 800;
	}

	.match-mood-icon {
		font-size: 24rpx;
		line-height: 1;
	}

	.match-groupbuy {
		margin: -10rpx 34rpx 34rpx;
		padding: 18rpx;
		border-radius: 22rpx;
		text-align: center;
		font-size: 24rpx;
		font-weight: 800;
		color: #7a4b12;
		background: linear-gradient(135deg, #ffe9c9, #ffd6a5);
	}

	.match-online {
		margin: 10rpx auto 0;
		display: flex;
		align-items: center;
		justify-content: center;
		gap: 8rpx;
		width: fit-content;
		padding: 6rpx 20rpx;
		border-radius: 999rpx;
		background: rgba(22, 27, 46, .05);
		font-size: 22rpx;
		color: rgba(22, 27, 46, .55);
	}

	.online-dot {
		width: 12rpx;
		height: 12rpx;
		border-radius: 50%;
		background: #c2c8d6;
	}

	.online-dot.on {
		background: #3ddc97;
		box-shadow: 0 0 8rpx rgba(61, 220, 151, .8);
	}

	.match-state {
		margin-top: 8rpx;
		text-align: center;
		color: rgba(22, 27, 46, .48);
		font-size: 23rpx;
	}

	.match-region {
		width: fit-content;
		max-width: 520rpx;
		margin: 14rpx auto 0;
		padding: 8rpx 20rpx;
		border-radius: 999rpx;
		color: #6c69d8;
		background: rgba(139, 124, 255, .1);
		font-size: 22rpx;
		font-weight: 700;
	}

	.match-tags {
		margin-top: 16rpx;
		padding: 0 34rpx;
		text-align: center;
	}

	.match-tags text {
		display: inline-block;
		height: 46rpx;
		line-height: 46rpx;
		padding: 0 18rpx;
		margin: 0 8rpx 10rpx;
		border-radius: 999rpx;
		color: #6c69d8;
		background: rgba(139, 124, 255, .1);
		font-size: 21rpx;
		font-weight: 700;
	}

	.match-state-text {
		margin-top: 8rpx;
		text-align: center;
		color: rgba(22, 27, 46, .54);
		font-size: 23rpx;
	}

	.match-quote {
		margin: 26rpx 34rpx 0;
		padding: 26rpx;
		border-radius: 8rpx 28rpx 28rpx 28rpx;
		color: rgba(22, 27, 46, .72);
		background: rgba(139, 124, 255, .08);
		font-size: 26rpx;
		line-height: 42rpx;
	}

	.match-persona {
		margin: 22rpx 34rpx 0;
	}

	.match-section-title {
		margin-bottom: 14rpx;
		color: rgba(22, 27, 46, .62);
		font-size: 24rpx;
		font-weight: 800;
	}

	.match-persona-scroll {
		white-space: nowrap;
	}

	.match-persona-image {
		display: inline-block;
		width: 168rpx;
		height: 208rpx;
		margin-right: 16rpx;
		border-radius: 26rpx;
		background: rgba(22, 27, 46, .06);
		box-shadow: 0 14rpx 34rpx rgba(96, 112, 160, .12);
	}

	.match-actions {
		display: flex;
		gap: 18rpx;
		margin: 30rpx 34rpx 34rpx;
	}

	.ghost-btn,
	.solid-btn {
		flex: 1;
		height: 90rpx;
		border-radius: 999rpx;
		text-align: center;
		line-height: 90rpx;
		font-size: 26rpx;
		font-weight: 800;
		transition: transform .14s ease;
	}

	.ghost-btn:active,
	.solid-btn:active {
		transform: scale(.96);
	}

	.ghost-btn {
		color: rgba(22, 27, 46, .55);
		background: rgba(238, 244, 255, .85);
	}

	.solid-btn {
		color: #11162a;
		background: linear-gradient(135deg, #a9ffe7, #8ef0ff 60%, #c9c2ff);
		box-shadow: 0 16rpx 38rpx rgba(120, 200, 230, .32);
	}

	/* ============ 个人浮层 ============ */
	.profile-mask {
		position: fixed;
		inset: 0;
		z-index: 30;
		display: flex;
		align-items: flex-end;
		padding: 34rpx;
		background: rgba(22, 27, 46, .12);
		backdrop-filter: blur(18rpx);
		box-sizing: border-box;
	}

	.profile-mini {
		width: 100%;
		padding: 40rpx 34rpx;
		border-radius: 44rpx;
		background: rgba(255, 255, 255, .82);
		border: 1rpx solid rgba(255, 255, 255, .9);
		box-shadow: 0 30rpx 90rpx rgba(96, 112, 160, .18), inset 0 1rpx 0 rgba(255, 255, 255, .96);
		text-align: center;
	}

	.mini-orb {
		width: 104rpx;
		height: 104rpx;
		margin: 0 auto;
		border-radius: 50%;
		line-height: 104rpx;
		color: #fff;
		background: linear-gradient(135deg, #6c5ce7, #a29bfe);
		font-size: 44rpx;
	}

	.mini-title {
		margin-top: 22rpx;
		font-size: 34rpx;
		font-weight: 700;
	}

	.mini-sub {
		margin-top: 10rpx;
		color: rgba(22, 27, 46, .5);
		font-size: 24rpx;
	}

	.mini-action {
		margin-top: 28rpx;
		height: 82rpx;
		line-height: 82rpx;
		border-radius: 999rpx;
		color: #161b2e;
		background: linear-gradient(135deg, #eafff8, #a9ffe7);
		font-size: 26rpx;
		font-weight: 700;
	}

	.creating-mask {
		position: fixed;
		inset: 0;
		z-index: 80;
		display: flex;
		align-items: center;
		justify-content: center;
		padding: 48rpx;
		box-sizing: border-box;
		background: rgba(20, 26, 46, .24);
		backdrop-filter: blur(18rpx);
	}

	.creating-card {
		width: 100%;
		padding: 52rpx 40rpx 42rpx;
		border-radius: 44rpx;
		text-align: center;
		background: linear-gradient(180deg, rgba(255, 255, 255, .96), rgba(247, 249, 255, .9));
		border: 1rpx solid rgba(255, 255, 255, .92);
		box-shadow: 0 34rpx 100rpx rgba(42, 50, 86, .22);
		box-sizing: border-box;
	}

	.creating-orbit {
		position: relative;
		width: 132rpx;
		height: 132rpx;
		margin: 0 auto;
		border-radius: 50%;
		background: radial-gradient(circle, #effffb 0%, #a9ffe7 58%, rgba(169, 255, 231, .2) 100%);
		box-shadow: 0 20rpx 54rpx rgba(96, 200, 170, .26), inset 0 2rpx 0 rgba(255, 255, 255, .9);
		animation: creatingPulse 1.8s ease-in-out infinite;
	}

	.creating-orbit::before {
		content: '';
		position: absolute;
		inset: -18rpx;
		border-radius: 50%;
		border: 3rpx dashed rgba(108, 105, 216, .24);
		animation: creatingSpin 5s linear infinite;
	}

	.creating-core {
		position: absolute;
		left: 50%;
		top: 50%;
		transform: translate(-50%, -50%);
		color: #151a2d;
		font-size: 48rpx;
		font-weight: 900;
	}

	.creating-dot {
		position: absolute;
		width: 18rpx;
		height: 18rpx;
		border-radius: 50%;
		background: #8b7cff;
		box-shadow: 0 0 24rpx rgba(139, 124, 255, .45);
	}

	.dot-a {
		right: 2rpx;
		top: 22rpx;
		animation: dotFloatA 1.7s ease-in-out infinite;
	}

	.dot-b {
		left: 8rpx;
		bottom: 26rpx;
		background: #ff9fc1;
		animation: dotFloatB 1.9s ease-in-out infinite;
	}

	.creating-title {
		margin-top: 34rpx;
		font-size: 36rpx;
		font-weight: 900;
		color: #151a2d;
	}

	.creating-sub {
		margin-top: 12rpx;
		color: rgba(21, 26, 45, .52);
		font-size: 24rpx;
		line-height: 38rpx;
	}

	.creating-progress {
		height: 10rpx;
		margin-top: 34rpx;
		border-radius: 999rpx;
		overflow: hidden;
		background: rgba(21, 26, 45, .06);
	}

	.creating-progress view {
		width: 44%;
		height: 100%;
		border-radius: 999rpx;
		background: linear-gradient(90deg, #a9ffe7, #8b7cff, #ff9fc1);
		animation: loadingSlide 1.2s ease-in-out infinite;
	}

	/* ============ 动画 ============ */
	@keyframes riseIn {
		from { opacity: 0; transform: translateY(20rpx); }
		to { opacity: 1; transform: translateY(0); }
	}

	@keyframes auroraDrift {
		0%, 100% { transform: translate3d(0, 0, 0) scale(1); }
		50% { transform: translate3d(24rpx, -30rpx, 0) scale(1.1); }
	}

	@keyframes laneScroll {
		from { transform: translateX(0); }
		to { transform: translateX(-50%); }
	}

	@keyframes liveDotPulse {
		0% { box-shadow: 0 0 0 0 rgba(43, 217, 164, .5); }
		70% { box-shadow: 0 0 0 14rpx rgba(43, 217, 164, 0); }
		100% { box-shadow: 0 0 0 0 rgba(43, 217, 164, 0); }
	}

	@keyframes entryWiggle {
		0%, 86%, 100% { transform: rotate(0); }
		90% { transform: rotate(-2deg); }
		94% { transform: rotate(2deg); }
		98% { transform: rotate(-1deg); }
	}

	@keyframes sparkTwinkle {
		0%, 100% { opacity: .25; transform: scale(.8) rotate(0deg); }
		50% { opacity: 1; transform: scale(1.15) rotate(20deg); }
	}

	@keyframes ctaBreath {
		0%, 100% { transform: scale(1); opacity: .85; }
		50% { transform: scale(1.06); opacity: 1; }
	}

	@keyframes countPop {
		0% { transform: translateY(8rpx) scale(.96); opacity: .55; }
		70% { transform: translateY(-3rpx) scale(1.04); opacity: 1; }
		100% { transform: translateY(0) scale(1); }
	}

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

	@keyframes emojiBounce {
		0% { transform: scale(.6); }
		60% { transform: scale(1.25); }
		100% { transform: scale(1); }
	}

	@keyframes blobMorph {
		0%, 100% { border-radius: 47% 53% 44% 56% / 56% 42% 58% 44%; }
		50% { border-radius: 58% 42% 55% 45% / 44% 58% 42% 56%; }
	}

	@keyframes soulFloat {
		0%, 100% { transform: translate3d(0, 0, 0); opacity: .36; }
		50% { transform: translate3d(12rpx, -18rpx, 0); opacity: .95; }
	}

	@keyframes subBreath {
		0%, 100% { opacity: .75; }
		50% { opacity: 1; }
	}

	@keyframes typingCursor {
		0%, 48% { opacity: 1; }
		49%, 100% { opacity: 0; }
	}

	@keyframes galaxyBreath {
		0%, 100% { transform: scale(.98); }
		50% { transform: scale(1.035); }
	}

	@keyframes ringDrift {
		from { filter: hue-rotate(0deg); }
		to { filter: hue-rotate(18deg); }
	}

	@keyframes breathButton {
		0%, 100% { transform: scale(1); }
		50% { transform: scale(1.015); }
	}

	@keyframes liquidMove {
		0%, 100% { transform: translate(0, 0) rotate(0deg) scale(1); }
		50% { transform: translate(22rpx, 18rpx) rotate(18deg) scale(1.12); }
	}

	@keyframes targetUp {
		from { transform: translateY(42rpx); opacity: 0; }
		to { transform: translateY(0); opacity: 1; }
	}

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

	@keyframes creatingPulse {
		0%, 100% { transform: scale(.98); }
		50% { transform: scale(1.04); }
	}

	@keyframes dotFloatA {
		0%, 100% { transform: translate(0, 0); }
		50% { transform: translate(-10rpx, 8rpx); }
	}

	@keyframes dotFloatB {
		0%, 100% { transform: translate(0, 0); }
		50% { transform: translate(12rpx, -8rpx); }
	}

	@keyframes loadingSlide {
		0% { transform: translateX(-120%); }
		100% { transform: translateX(230%); }
	}

	/* ============ 流畅模式降级 ============ */
	.low-performance::before,
	.low-performance .aurora,
	.low-performance .spark,
	.low-performance .liquid,
	.low-performance .soul-particle,
	.low-performance .galaxy-ring,
	.low-performance .orbit-planet::after {
		display: none !important;
	}

	.low-performance .lane-track {
		animation-duration: 60s;
	}

	.low-performance .galaxy-breath,
	.low-performance .galaxy-body,
	.low-performance .planet-sub,
	.low-performance .planet-cta,
	.low-performance .target-btn,
	.low-performance .target-star,
	.low-performance .mood-orb.active .orb-face::after,
	.low-performance .live-dot,
	.low-performance .hero-num,
	.low-performance .start-match-btn,
	.low-performance .typing-cursor {
		animation: none !important;
	}

	.low-performance .galaxy-body {
		box-shadow:
			0 18rpx 48rpx rgba(108, 92, 231, .14),
			inset 8rpx 10rpx 24rpx rgba(255, 255, 255, .52);
	}

	.low-performance .danmu-item,
	.low-performance .hero-live,
	.low-performance .home-back,
	.low-performance .perf-toggle,
	.low-performance .target-mask,
	.low-performance .match-mask,
	.low-performance .profile-mask {
		backdrop-filter: none !important;
	}
</style>
