Files

1026 lines
28 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view class="affinity-screen">
<!-- 星空背景 -->
<view class="affinity-starfield">
<view class="affinity-stars"></view>
<view class="affinity-stars2"></view>
</view>
<!-- 浮动装饰 -->
<view class="affinity-floating-hearts">
<text class="affinity-heart heart-1"></text>
<text class="affinity-heart heart-2"></text>
<text class="affinity-heart heart-3"></text>
</view>
<!-- 状态栏占位 -->
<view class="status-bar-placeholder" :style="{ height: statusBarHeight }"></view>
<!-- Header -->
<view class="affinity-header">
<view class="affinity-back-btn" @click="emit('back')">
<text class="affinity-back-icon"></text>
</view>
<view class="affinity-header-center">
<text class="affinity-header-title">缘分合盘</text>
<text class="affinity-header-subtitle">三生石上刻姻缘</text>
</view>
<view class="affinity-header-spacer"></view>
</view>
<!-- Content -->
<scroll-view :scroll-y="true" class="affinity-content">
<view class="affinity-container">
<!-- 顶部装饰图案 -->
<view class="affinity-top-deco">
<view class="affinity-moon"></view>
<view class="affinity-cloud cloud-1"></view>
<view class="affinity-cloud cloud-2"></view>
</view>
<!-- Intro -->
<view class="affinity-intro">
<view class="affinity-intro-ring">
<view class="affinity-intro-icon">
<text class="affinity-intro-icon-text"></text>
</view>
</view>
<text class="affinity-intro-title">前世今生 · 姻缘天定</text>
<view class="affinity-intro-divider">
<view class="affinity-intro-line"></view>
<text class="affinity-intro-dot"></text>
<view class="affinity-intro-line"></view>
</view>
<text class="affinity-intro-desc">周易八字 · 紫微斗数 · 多维解析</text>
</view>
<!-- 关系类型 -->
<view class="affinity-section">
<view class="affinity-section-header">
<view class="affinity-section-icon">
<text class="affinity-section-icon-text"></text>
</view>
<text class="affinity-section-title">缘分类型</text>
</view>
<view class="affinity-relation-grid">
<view v-for="item in relationTypes" :key="item.id" class="affinity-relation-item"
:class="{ active: form.relationship === item.id }" @click="form.relationship = item.id">
<text class="affinity-relation-icon">{{ item.icon }}</text>
<text class="affinity-relation-text">{{ item.label }}</text>
</view>
</view>
</view>
<!-- 红线连接装饰 -->
<view class="affinity-red-thread">
<view class="affinity-thread-line"></view>
<view class="affinity-thread-knot">
<text class="affinity-thread-knot-text"></text>
</view>
<view class="affinity-thread-line"></view>
</view>
<!-- 双方信息卡片 -->
<view class="affinity-cards-wrap">
<!-- 甲方信息 -->
<view class="affinity-card affinity-card-left">
<view class="affinity-card-glow"></view>
<view class="affinity-card-inner">
<view class="affinity-card-header">
<view class="affinity-card-badge">
<text class="affinity-card-badge-text"></text>
</view>
<text class="affinity-card-title">君之信息</text>
</view>
<view class="affinity-form-group">
<text class="affinity-form-label">芳名</text>
<view class="affinity-input-wrap">
<input v-model="form.person1.name" class="affinity-input" placeholder="请书芳名" />
</view>
</view>
<view class="affinity-form-group">
<text class="affinity-form-label">性别</text>
<view class="affinity-gender-row">
<view class="affinity-gender-item"
:class="{ active: form.person1.gender === 'male' }"
@click="form.person1.gender = 'male'">
<text class="affinity-gender-icon"></text>
<text class="affinity-gender-text">郎君</text>
</view>
<view class="affinity-gender-item"
:class="{ active: form.person1.gender === 'female' }"
@click="form.person1.gender = 'female'">
<text class="affinity-gender-icon"></text>
<text class="affinity-gender-text">佳人</text>
</view>
</view>
</view>
<view class="affinity-form-group">
<text class="affinity-form-label">生辰八字</text>
<view class="affinity-picker" @click="showPerson1Picker = true">
<text :class="['affinity-picker-text', { placeholder: !form.person1.birthDate }]">
{{ form.person1.birthDate || '择日选时' }}
</text>
<text class="affinity-picker-arrow"></text>
</view>
</view>
</view>
</view>
<!-- 中间连接 -->
<view class="affinity-cards-connector">
<view class="affinity-connector-heart">
<text class="affinity-connector-heart-icon"></text>
</view>
<view class="affinity-connector-pulse"></view>
</view>
<!-- 乙方信息 -->
<view class="affinity-card affinity-card-right">
<view class="affinity-card-glow affinity-card-glow-pink"></view>
<view class="affinity-card-inner">
<view class="affinity-card-header">
<view class="affinity-card-badge affinity-card-badge-pink">
<text class="affinity-card-badge-text"></text>
</view>
<text class="affinity-card-title">卿之信息</text>
</view>
<view class="affinity-form-group">
<text class="affinity-form-label">芳名</text>
<view class="affinity-input-wrap">
<input v-model="form.person2.name" class="affinity-input" placeholder="请书芳名" />
</view>
</view>
<view class="affinity-form-group">
<text class="affinity-form-label">性别</text>
<view class="affinity-gender-row">
<view class="affinity-gender-item"
:class="{ active: form.person2.gender === 'male' }"
@click="form.person2.gender = 'male'">
<text class="affinity-gender-icon"></text>
<text class="affinity-gender-text">郎君</text>
</view>
<view class="affinity-gender-item"
:class="{ active: form.person2.gender === 'female' }"
@click="form.person2.gender = 'female'">
<text class="affinity-gender-icon"></text>
<text class="affinity-gender-text">佳人</text>
</view>
</view>
</view>
<view class="affinity-form-group">
<text class="affinity-form-label">生辰八字</text>
<view class="affinity-picker" @click="showPerson2Picker = true">
<text :class="['affinity-picker-text', { placeholder: !form.person2.birthDate }]">
{{ form.person2.birthDate || '择日选时' }}
</text>
<text class="affinity-picker-arrow"></text>
</view>
</view>
</view>
</view>
</view>
<!-- 提交按钮 -->
<view class="affinity-submit-wrap">
<button class="affinity-submit-btn" @click="handleSubmit">
<view class="affinity-submit-glow"></view>
<text class="affinity-submit-text">开启姻缘测算</text>
</button>
</view>
<view class="affinity-footer">
<text class="affinity-footer-text">月老牵线 · 天作之合</text>
<text class="affinity-privacy-note">您的信息将被严格保密</text>
</view>
</view>
</scroll-view>
<!-- 日期选择器 -->
<MysticDatePicker :is-open="showPerson1Picker" title="君之生辰" :default-value="form.person1.birthDate"
@close="showPerson1Picker = false" @confirm="handlePerson1DateConfirm" />
<MysticDatePicker :is-open="showPerson2Picker" title="卿之生辰" :default-value="form.person2.birthDate"
@close="showPerson2Picker = false" @confirm="handlePerson2DateConfirm" />
</view>
</template>
<script setup lang="ts">
import { reactive, ref } from 'vue';
import MysticDatePicker from '../MysticDatePicker.vue';
import { affinityApi, type AffinityCalculateRequest } from '../../api';
declare const uni: any;
const emit = defineEmits<{
back: [];
showResult: [data: any];
}>();
// 状态栏高度
const statusBarHeight = ref('0px');
try {
const systemInfo = uni.getSystemInfoSync();
statusBarHeight.value = (systemInfo.statusBarHeight || 20) + 'px';
} catch (e) {
statusBarHeight.value = '44px';
}
const relationTypes = [
{ id: 'couple', label: '情侣', icon: '💑' },
{ id: 'married', label: '夫妻', icon: '💒' },
{ id: 'crush', label: '暗恋', icon: '💘' },
{ id: 'partner', label: '合伙', icon: '🤝' },
{ id: 'friend', label: '知己', icon: '🌙' },
{ id: 'family', label: '亲缘', icon: '🏠' },
];
const form = reactive({
relationship: 'couple',
person1: {
name: '',
gender: 'male',
birthDate: '',
birthDateApi: '',
},
person2: {
name: '',
gender: 'female',
birthDate: '',
birthDateApi: '',
},
});
const showPerson1Picker = ref(false);
const showPerson2Picker = ref(false);
const handlePerson1DateConfirm = (displayVal: string, apiVal: string) => {
form.person1.birthDate = displayVal;
form.person1.birthDateApi = apiVal;
};
const handlePerson2DateConfirm = (displayVal: string, apiVal: string) => {
form.person2.birthDate = displayVal;
form.person2.birthDateApi = apiVal;
};
const handleSubmit = async () => {
if (!form.person1.name) {
uni.showToast({ title: '请输入君之芳名', icon: 'none' });
return;
}
if (!form.person1.birthDate) {
uni.showToast({ title: '请选择君之生辰', icon: 'none' });
return;
}
if (!form.person2.name) {
uni.showToast({ title: '请输入卿之芳名', icon: 'none' });
return;
}
if (!form.person2.birthDate) {
uni.showToast({ title: '请选择卿之生辰', icon: 'none' });
return;
}
uni.showLoading({ title: '测算中...', mask: true });
try {
const requestData: AffinityCalculateRequest = {
relationship: form.relationship as any,
person1: {
name: form.person1.name,
gender: form.person1.gender as 'male' | 'female',
birth_date: form.person1.birthDate,
birth_date_api: form.person1.birthDateApi,
},
person2: {
name: form.person2.name,
gender: form.person2.gender as 'male' | 'female',
birth_date: form.person2.birthDate,
birth_date_api: form.person2.birthDateApi,
},
};
const result = await affinityApi.calculateAffinity(requestData);
uni.hideLoading();
emit('showResult', result);
} catch (error: any) {
uni.hideLoading();
// 如果是认证失败错误不显示toast因为API函数中已经处理了跳转
if (error.message !== '认证失败,请登录后再试') {
uni.showToast({
title: error.message || '测算失败,请稍后重试',
icon: 'none',
duration: 2000,
});
}
}
};
</script>
<style scoped>
.affinity-screen {
height: 100%;
display: flex;
flex-direction: column;
background: linear-gradient(180deg, #1a1a2e 0%, #16213e 50%, #0f3460 100%);
position: relative;
overflow: hidden;
}
/* 星空背景 */
.affinity-starfield {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
overflow: hidden;
pointer-events: none;
}
.affinity-stars {
position: absolute;
width: 100%;
height: 100%;
background-image:
radial-gradient(2rpx 2rpx at 20% 30%, rgba(255, 255, 255, 0.8), transparent),
radial-gradient(2rpx 2rpx at 40% 70%, rgba(255, 255, 255, 0.5), transparent),
radial-gradient(3rpx 3rpx at 50% 40%, rgba(255, 255, 255, 0.9), transparent),
radial-gradient(2rpx 2rpx at 60% 20%, rgba(255, 255, 255, 0.6), transparent),
radial-gradient(2rpx 2rpx at 70% 60%, rgba(255, 255, 255, 0.4), transparent),
radial-gradient(2rpx 2rpx at 80% 10%, rgba(255, 255, 255, 0.7), transparent),
radial-gradient(2rpx 2rpx at 10% 80%, rgba(255, 255, 255, 0.5), transparent),
radial-gradient(3rpx 3rpx at 30% 50%, rgba(255, 255, 255, 0.8), transparent);
animation: twinkle 4s ease-in-out infinite;
}
.affinity-stars2 {
position: absolute;
width: 100%;
height: 100%;
background-image:
radial-gradient(2rpx 2rpx at 15% 45%, rgba(255, 200, 200, 0.6), transparent),
radial-gradient(2rpx 2rpx at 85% 35%, rgba(255, 200, 200, 0.5), transparent),
radial-gradient(2rpx 2rpx at 45% 85%, rgba(255, 200, 200, 0.7), transparent);
animation: twinkle 3s ease-in-out infinite 1s;
}
@keyframes twinkle {
0%,
100% {
opacity: 0.5;
}
50% {
opacity: 1;
}
}
/* 浮动爱心 */
.affinity-floating-hearts {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
pointer-events: none;
overflow: hidden;
}
.affinity-heart {
position: absolute;
color: rgba(255, 100, 130, 0.3);
animation: floatHeart 8s ease-in-out infinite;
}
.heart-1 {
font-size: 48rpx;
left: 10%;
top: 20%;
animation-delay: 0s;
}
.heart-2 {
font-size: 32rpx;
right: 15%;
top: 35%;
animation-delay: 2s;
}
.heart-3 {
font-size: 40rpx;
left: 20%;
bottom: 30%;
animation-delay: 4s;
}
@keyframes floatHeart {
0%,
100% {
transform: translateY(0) rotate(0deg);
opacity: 0.3;
}
50% {
transform: translateY(-30rpx) rotate(10deg);
opacity: 0.6;
}
}
.status-bar-placeholder {
width: 100%;
flex-shrink: 0;
}
/* Header */
.affinity-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 24rpx 32rpx;
position: relative;
z-index: 10;
}
.affinity-back-btn {
width: 72rpx;
height: 72rpx;
display: flex;
align-items: center;
justify-content: center;
background: rgba(255, 255, 255, 0.1);
border: 1rpx solid rgba(255, 255, 255, 0.2);
border-radius: 50%;
}
.affinity-back-icon {
font-size: 40rpx;
color: #fff;
font-weight: bold;
}
.affinity-header-center {
text-align: center;
}
.affinity-header-title {
font-size: 36rpx;
font-weight: bold;
color: #fff;
letter-spacing: 0.3em;
display: block;
text-shadow: 0 0 20rpx rgba(255, 100, 130, 0.5);
}
.affinity-header-subtitle {
font-size: 20rpx;
color: rgba(255, 200, 200, 0.8);
letter-spacing: 0.2em;
display: block;
margin-top: 4rpx;
}
.affinity-header-spacer {
width: 72rpx;
}
.affinity-content {
flex: 1;
height: 0;
}
.affinity-container {
padding: 32rpx 40rpx 80rpx;
}
/* 顶部装饰 */
.affinity-top-deco {
position: relative;
height: 120rpx;
margin-bottom: 20rpx;
}
.affinity-moon {
position: absolute;
right: 40rpx;
top: 0;
width: 80rpx;
height: 80rpx;
background: radial-gradient(circle at 30% 30%, #fffacd, #ffd700);
border-radius: 50%;
box-shadow: 0 0 40rpx rgba(255, 215, 0, 0.5), 0 0 80rpx rgba(255, 215, 0, 0.3);
}
.affinity-cloud {
position: absolute;
background: rgba(255, 255, 255, 0.1);
border-radius: 100rpx;
}
.cloud-1 {
width: 160rpx;
height: 40rpx;
left: 20rpx;
top: 40rpx;
animation: cloudFloat 6s ease-in-out infinite;
}
.cloud-2 {
width: 120rpx;
height: 30rpx;
right: 140rpx;
top: 60rpx;
animation: cloudFloat 8s ease-in-out infinite 2s;
}
@keyframes cloudFloat {
0%,
100% {
transform: translateX(0);
}
50% {
transform: translateX(20rpx);
}
}
/* Intro */
.affinity-intro {
text-align: center;
margin-bottom: 48rpx;
}
.affinity-intro-ring {
width: 140rpx;
height: 140rpx;
margin: 0 auto 24rpx;
border: 2rpx solid rgba(255, 100, 130, 0.3);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
animation: ringPulse 3s ease-in-out infinite;
}
@keyframes ringPulse {
0%,
100% {
transform: scale(1);
border-color: rgba(255, 100, 130, 0.3);
}
50% {
transform: scale(1.05);
border-color: rgba(255, 100, 130, 0.6);
}
}
.affinity-intro-icon {
width: 100rpx;
height: 100rpx;
background: linear-gradient(135deg, #ff6b8a 0%, #c44569 100%);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 8rpx 32rpx rgba(255, 100, 130, 0.4);
}
.affinity-intro-icon-text {
font-size: 48rpx;
color: #fff;
font-weight: bold;
}
.affinity-intro-title {
font-size: 36rpx;
font-weight: bold;
color: #fff;
display: block;
letter-spacing: 0.15em;
text-shadow: 0 0 20rpx rgba(255, 100, 130, 0.5);
}
.affinity-intro-divider {
display: flex;
align-items: center;
justify-content: center;
margin: 20rpx 0;
gap: 16rpx;
}
.affinity-intro-line {
width: 80rpx;
height: 2rpx;
background: linear-gradient(90deg, transparent, rgba(255, 100, 130, 0.5), transparent);
}
.affinity-intro-dot {
font-size: 16rpx;
color: rgba(255, 100, 130, 0.8);
}
.affinity-intro-desc {
font-size: 24rpx;
color: rgba(255, 255, 255, 0.6);
display: block;
letter-spacing: 0.1em;
}
/* Section */
.affinity-section {
margin-bottom: 40rpx;
}
.affinity-section-header {
display: flex;
align-items: center;
margin-bottom: 24rpx;
}
.affinity-section-icon {
width: 48rpx;
height: 48rpx;
background: rgba(255, 100, 130, 0.2);
border: 1rpx solid rgba(255, 100, 130, 0.3);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin-right: 16rpx;
}
.affinity-section-icon-text {
font-size: 24rpx;
color: #ff6b8a;
}
.affinity-section-title {
font-size: 28rpx;
font-weight: bold;
color: #fff;
letter-spacing: 0.1em;
}
.affinity-relation-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20rpx;
}
.affinity-relation-item {
text-align: center;
padding: 24rpx 16rpx;
border-radius: 16rpx;
border: 2rpx solid rgba(255, 255, 255, 0.1);
background: rgba(255, 255, 255, 0.05);
transition: all 0.3s;
}
.affinity-relation-item.active {
background: linear-gradient(135deg, rgba(255, 100, 130, 0.3) 0%, rgba(196, 69, 105, 0.3) 100%);
border-color: rgba(255, 100, 130, 0.5);
transform: scale(1.05);
box-shadow: 0 8rpx 24rpx rgba(255, 100, 130, 0.2);
}
.affinity-relation-icon {
font-size: 36rpx;
display: block;
margin-bottom: 8rpx;
}
.affinity-relation-text {
font-size: 24rpx;
color: rgba(255, 255, 255, 0.7);
}
.affinity-relation-item.active .affinity-relation-text {
color: #fff;
}
/* 红线装饰 */
.affinity-red-thread {
display: flex;
align-items: center;
justify-content: center;
margin: 32rpx 0;
}
.affinity-thread-line {
flex: 1;
height: 2rpx;
background: linear-gradient(90deg, transparent, #ff6b8a, transparent);
}
.affinity-thread-knot {
width: 56rpx;
height: 56rpx;
background: linear-gradient(135deg, #ff6b8a 0%, #c44569 100%);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin: 0 16rpx;
box-shadow: 0 4rpx 16rpx rgba(255, 100, 130, 0.4);
}
.affinity-thread-knot-text {
font-size: 24rpx;
color: #fff;
font-weight: bold;
}
/* Cards */
.affinity-cards-wrap {
position: relative;
}
.affinity-card {
position: relative;
margin-bottom: 24rpx;
border-radius: 24rpx;
overflow: hidden;
}
.affinity-card-glow {
position: absolute;
top: -50%;
right: -50%;
width: 200%;
height: 200%;
background: radial-gradient(circle, rgba(100, 150, 255, 0.1) 0%, transparent 70%);
pointer-events: none;
}
.affinity-card-glow-pink {
background: radial-gradient(circle, rgba(255, 100, 130, 0.1) 0%, transparent 70%);
}
.affinity-card-inner {
background: rgba(255, 255, 255, 0.08);
border: 1rpx solid rgba(255, 255, 255, 0.15);
border-radius: 24rpx;
padding: 40rpx;
backdrop-filter: blur(20rpx);
}
.affinity-card-header {
display: flex;
align-items: center;
margin-bottom: 32rpx;
}
.affinity-card-badge {
width: 56rpx;
height: 56rpx;
background: linear-gradient(135deg, #4a90d9 0%, #357abd 100%);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin-right: 16rpx;
box-shadow: 0 4rpx 16rpx rgba(74, 144, 217, 0.4);
}
.affinity-card-badge-pink {
background: linear-gradient(135deg, #ff6b8a 0%, #c44569 100%);
box-shadow: 0 4rpx 16rpx rgba(255, 100, 130, 0.4);
}
.affinity-card-badge-text {
font-size: 28rpx;
color: #fff;
font-weight: bold;
}
.affinity-card-title {
font-size: 30rpx;
font-weight: bold;
color: #fff;
letter-spacing: 0.1em;
}
.affinity-form-group {
margin-bottom: 28rpx;
}
.affinity-form-group:last-child {
margin-bottom: 0;
}
.affinity-form-label {
font-size: 24rpx;
color: rgba(255, 255, 255, 0.6);
display: block;
margin-bottom: 12rpx;
letter-spacing: 0.1em;
}
.affinity-input-wrap {
position: relative;
}
.affinity-input {
width: 100%;
height: 88rpx;
background: rgba(255, 255, 255, 0.1);
border: 1rpx solid rgba(255, 255, 255, 0.2);
border-radius: 12rpx;
padding: 0 24rpx;
font-size: 28rpx;
color: #fff;
box-sizing: border-box;
}
.affinity-input::placeholder {
color: rgba(255, 255, 255, 0.4);
}
.affinity-gender-row {
display: flex;
gap: 20rpx;
}
.affinity-gender-item {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
padding: 20rpx;
border: 1rpx solid rgba(255, 255, 255, 0.2);
border-radius: 12rpx;
background: rgba(255, 255, 255, 0.05);
transition: all 0.3s;
gap: 8rpx;
}
.affinity-gender-item.active {
background: rgba(255, 255, 255, 0.15);
border-color: rgba(255, 255, 255, 0.4);
}
.affinity-gender-icon {
font-size: 28rpx;
color: rgba(255, 255, 255, 0.8);
}
.affinity-gender-text {
font-size: 26rpx;
color: rgba(255, 255, 255, 0.8);
}
.affinity-picker {
display: flex;
align-items: center;
justify-content: space-between;
height: 88rpx;
background: rgba(255, 255, 255, 0.1);
border: 1rpx solid rgba(255, 255, 255, 0.2);
border-radius: 12rpx;
padding: 0 24rpx;
}
.affinity-picker-text {
font-size: 28rpx;
color: #fff;
}
.affinity-picker-text.placeholder {
color: rgba(255, 255, 255, 0.4);
}
.affinity-picker-arrow {
font-size: 32rpx;
color: rgba(255, 255, 255, 0.4);
}
/* Connector */
.affinity-cards-connector {
display: flex;
justify-content: center;
margin: -12rpx 0;
position: relative;
z-index: 10;
}
.affinity-connector-heart {
width: 72rpx;
height: 72rpx;
background: linear-gradient(135deg, #ff6b8a 0%, #c44569 100%);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 8rpx 32rpx rgba(255, 100, 130, 0.5);
position: relative;
z-index: 2;
}
.affinity-connector-heart-icon {
font-size: 36rpx;
color: #fff;
}
.affinity-connector-pulse {
position: absolute;
width: 72rpx;
height: 72rpx;
border: 2rpx solid rgba(255, 100, 130, 0.5);
border-radius: 50%;
animation: heartPulse 2s ease-out infinite;
}
@keyframes heartPulse {
0% {
transform: scale(1);
opacity: 1;
}
100% {
transform: scale(2);
opacity: 0;
}
}
/* Submit */
.affinity-submit-wrap {
margin-top: 48rpx;
}
.affinity-submit-btn {
position: relative;
width: 100%;
height: 100rpx;
background: linear-gradient(135deg, #ff6b8a 0%, #c44569 100%);
border-radius: 50rpx;
display: flex;
align-items: center;
justify-content: center;
border: none;
overflow: hidden;
box-shadow: 0 8rpx 32rpx rgba(255, 100, 130, 0.4);
}
.affinity-submit-glow {
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.3), transparent);
animation: submitGlow 3s ease-in-out infinite;
}
@keyframes submitGlow {
0% {
left: -100%;
}
50%,
100% {
left: 100%;
}
}
.affinity-submit-text {
font-size: 32rpx;
font-weight: bold;
color: #fff;
letter-spacing: 0.2em;
position: relative;
z-index: 1;
}
/* Footer */
.affinity-footer {
text-align: center;
margin-top: 40rpx;
}
.affinity-footer-text {
font-size: 24rpx;
color: rgba(255, 200, 200, 0.6);
display: block;
letter-spacing: 0.2em;
margin-bottom: 8rpx;
}
.affinity-privacy-note {
font-size: 20rpx;
color: rgba(255, 255, 255, 0.3);
display: block;
}
</style>