diff --git a/app.js b/app.js
index f21b53a..8454e2a 100644
--- a/app.js
+++ b/app.js
@@ -1,5 +1,53 @@
App({
- onLaunch() {
- console.log('小程序启动啦!')
+
+ onShow: function (options) {
+
+ // 检查是否从分享卡片进入 (场景值 1007, 1008)
+ if (options && (options.scene === 1007 || options.scene === 1008)) {
+
+ console.log('[App] 用户通过分享卡片进入');
+
+ // 获取来源用户ID(保留结构,暂不使用)
+ const fromUserId = options.query && options.query.fromUserId;
+ if (fromUserId) {
+ console.log('[App] 来源用户ID:', fromUserId);
+ }
+
+ // 只做欢迎提示,不发积分
+ wx.showToast({
+ title: '欢迎进入今日命运场 ✨',
+ icon: 'none',
+ duration: 2000
+ });
+ }
+ },
+
+ onLaunch: function () {
+
+ console.log('小程序启动啦!');
+
+ // 检查隐私协议同意状态
+ const agreed = wx.getStorageSync('privacyAgreed');
+
+ if (!agreed) {
+
+ wx.onAppRoute((res) => {
+
+ const isAgreed = wx.getStorageSync('privacyAgreed');
+ if (isAgreed) return;
+
+ if (res.path !== 'pages/privacy-agree/privacy-agree' &&
+ res.path !== 'pages/privacy/privacy') {
+
+ wx.reLaunch({
+ url: '/pages/privacy-agree/privacy-agree'
+ });
+ }
+ });
+
+ wx.reLaunch({
+ url: '/pages/privacy-agree/privacy-agree'
+ });
+ }
}
-})
\ No newline at end of file
+});
\ No newline at end of file
diff --git a/app.json b/app.json
index dd75728..1ab5300 100644
--- a/app.json
+++ b/app.json
@@ -1,15 +1,22 @@
{
"pages": [
"pages/home/home",
+ "pages/zodiac/index",
"pages/index/index",
"pages/knowledge/index",
"pages/knowledge/list",
"pages/knowledge/article",
"pages/webview/index",
- "pages/privacy/privacy"
+ "pages/privacy/privacy",
+ "pages/privacy-agree/privacy-agree",
+ "pages/settings/settings",
+ "pages/user-agreement/user-agreement"
],
"window": {
- "navigationBarTitleText": "我的第一个小程序"
+ "navigationBarTitleText": "塔罗星语",
+ "navigationBarBackgroundColor": "#1a1a2e",
+ "navigationBarTextStyle": "white",
+ "backgroundColor": "#1a1a2e"
},
"style": "v2",
"sitemapLocation": "sitemap.json"
diff --git a/components/spread-container/spread-container.js b/components/spread-container/spread-container.js
new file mode 100644
index 0000000..8942c76
--- /dev/null
+++ b/components/spread-container/spread-container.js
@@ -0,0 +1,105 @@
+Component({
+ properties: {
+ spread: { type: Object, value: null },
+ cards: { type: Array, value: [] },
+ revealedCount: { type: Number, value: 0 },
+ cardWidth: { type: Number, value: 160 } // 安全默认值 160
+ },
+
+ data: {
+ displayList: [] // 统一渲染列表 (merged with layout info)
+ },
+
+ lifetimes: {
+ attached() {
+ this.updateLayout();
+ }
+ },
+
+ observers: {
+ 'spread, cards, cardWidth': function (spread, cards, cardWidth) {
+ this.updateLayout();
+ }
+ },
+
+ methods: {
+ updateLayout() {
+ const { spread, cards, cardWidth } = this.data;
+ if (!spread || !spread.layout || !cards || cards.length === 0) return;
+
+ const layoutType = spread.layout.type;
+
+ // 1. Grid 处理 (简单网格布局,不涉及复杂计算)
+ if (layoutType === 'grid') {
+ const list = cards.map((c, i) => ({
+ ...c,
+ _posName: spread.positions[i],
+ _seq: i + 1,
+ _index: i,
+ _style: '' // 无内联样式,交给 grid CSS
+ }));
+ this.setData({ displayList: list });
+ return;
+ }
+
+ // 2. Celtic Cross (静止百分比布局 - 600x900rpx 容器适配)
+ if (layoutType === 'celtic') {
+ // 容器: 600rpx x 900rpx
+ // 卡牌: 140rpx x 210rpx
+ // 安全水平间距: 140/600 = 23.3% -> 中心间距需 > 23.3%
+ // 安全垂直间距: 210/900 = 23.3% -> 中心间距需 > 23.3%
+
+ // 中轴 X: 38% (228rpx) - 左移给右侧列留空间
+ // 左牌 X: 38% - 25% = 13% (78rpx) - 安全
+ // 右牌 X: 38% + 25% = 63% (378rpx) - 安全
+ // 右侧列 X: 85% (510rpx) - 离右牌 22% = 132rpx > 140rpx 略挤,调整到 87%
+
+ const positions = [
+ { left: 38, top: 47 }, // 1 现状
+ { left: 38, top: 47, rotate: 'rotate(90deg)' }, // 2 阻碍 (重叠)
+ { left: 38, top: 73 }, // 3 根基 (47+26=73)
+ { left: 13, top: 47 }, // 4 过去
+ { left: 38, top: 21 }, // 5 可能性 (47-26=21)
+ { left: 63, top: 47 }, // 6 近期未来
+
+ // 右侧列 X: 87%, 纵向间距 ~22% of 900 = 198rpx > 210rpx 略挤
+ // 调整为 4 张牌均匀分布在 10%-90% 之间
+ // 间距: (90-10)/3 = 26.7% = 240rpx > 210rpx ✓
+ { left: 87, top: 15 }, // 7 你的态度
+ { left: 87, top: 38 }, // 8 外部影响 (15+23=38)
+ { left: 87, top: 61 }, // 9 希望与恐惧 (38+23=61)
+ { left: 87, top: 84 }, // 10 最终结果 (61+23=84)
+ ];
+
+ // Merge Layout + Card Data
+ const list = cards.map((c, i) => {
+ const pos = positions[i] || {};
+ // 直接生成内联样式,移除所有动态计算
+ const style = `left: ${pos.left}%; top: ${pos.top}%; transform: translate(-50%, -50%) ${pos.rotate || ''};`;
+
+ return {
+ ...c,
+ _posName: spread.positions[i],
+ _seq: i + 1,
+ _index: i,
+ _style: style
+ };
+ });
+
+ this.setData({ displayList: list });
+ }
+ },
+
+ // 移除多余的 calcCelticLayout 方法,直接在 updateLayout 中处理
+ handleCardTap(e) {
+ const idx = e.currentTarget.dataset.index;
+ if (idx === undefined) return;
+
+ if (idx === this.data.revealedCount) {
+ this.triggerEvent('reveal', { index: idx });
+ } else if (idx < this.data.revealedCount) {
+ this.triggerEvent('viewDetail', { index: idx });
+ }
+ }
+ }
+});
diff --git a/components/spread-container/spread-container.json b/components/spread-container/spread-container.json
new file mode 100644
index 0000000..7e37c03
--- /dev/null
+++ b/components/spread-container/spread-container.json
@@ -0,0 +1,4 @@
+{
+ "component": true,
+ "usingComponents": {}
+}
\ No newline at end of file
diff --git a/components/spread-container/spread-container.wxml b/components/spread-container/spread-container.wxml
new file mode 100644
index 0000000..693c9ac
--- /dev/null
+++ b/components/spread-container/spread-container.wxml
@@ -0,0 +1,82 @@
+
+
+
+
+
+
+
+
+ {{card._posName}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{card.name}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{item._posName}}
+
+
+
+
+
+
+
+
+
+
+
+ {{item.name}}
+
+
+
+
+
+
diff --git a/components/spread-container/spread-container.wxss b/components/spread-container/spread-container.wxss
new file mode 100644
index 0000000..542db88
--- /dev/null
+++ b/components/spread-container/spread-container.wxss
@@ -0,0 +1,165 @@
+/* components/spread-container/spread-container.wxss */
+
+/* 通用容器 */
+.spread-wrapper {
+ width: 100%;
+ padding: 0 40rpx;
+ box-sizing: border-box;
+}
+
+/* =========================================
+ 卡牌单元 (Card Item)
+ ========================================= */
+.card-slot {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ position: relative;
+ /* 默认尺寸,grid 布局使用 */
+ width: 124rpx;
+ margin-bottom: 24rpx;
+}
+
+/* 翻牌场景 */
+.flip-scene {
+ width: 100%;
+ /* 保持 160:260 比例 -> 1:1.625 */
+ /* 或 124:200 -> 1:1.61 */
+ aspect-ratio: 2/3;
+ perspective: 1000rpx;
+ position: relative;
+}
+
+.flip-card {
+ width: 100%;
+ height: 100%;
+ position: relative;
+ transform-style: preserve-3d;
+ transition: transform 0.6s;
+}
+
+.flip-card.flipped {
+ transform: rotateY(180deg);
+}
+
+.card-face {
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ backface-visibility: hidden;
+ border-radius: 12rpx;
+ overflow: hidden;
+ box-shadow: 0 4rpx 12rpx rgba(0,0,0,0.2);
+}
+
+.face-front {
+ transform: rotateY(180deg);
+}
+
+.card-image {
+ width: 100%;
+ height: 100%;
+ display: block;
+}
+
+.card-image.reversed {
+ transform: rotate(180deg);
+}
+
+/* 文字信息 */
+.pos-info {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ margin-bottom: 8rpx;
+}
+
+.pos-name {
+ font-size: 22rpx;
+ color: #ddd;
+ line-height: 1.2;
+ text-align: center;
+}
+
+.pos-seq {
+ font-size: 18rpx;
+ color: #aaa;
+}
+
+.card-name-sm {
+ font-size: 20rpx;
+ color: #fff;
+ margin-top: 8rpx;
+ text-align: center;
+ max-width: 120%;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+/* =========================================
+ 布局 1: Grid (网格)
+ ========================================= */
+.layout-grid {
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: center;
+ gap: 30rpx;
+ padding: 40rpx 0;
+}
+
+ /* =========================================
+ 布局系统 2: Celtic Cross (从零重构 - 绝对锁定)
+ ========================================= */
+
+ /* 1. 全屏垂直水平居中包装器 (仅 celtic 模式) */
+ .spread-wrapper.celtic-mode {
+ width: 100%;
+ /* 高度设为 100vh 可能会导致不可滚动,这里视情况调整 */
+ /* 用户虽然要求 100vh,但在小程序组件中可能会溢出,建议 min-height */
+ min-height: 80vh;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ padding: 0;
+ box-sizing: border-box;
+ }
+
+ /* 2. 核心容器 (600x900rpx) */
+ .spread-container {
+ position: relative;
+ width: 600rpx;
+ height: 900rpx;
+ /* 调试辅助: border: 1px dashed rgba(255,255,255,0.2); */
+ }
+
+ /* 3. 卡牌通用样式 (绝对定位 + 居中) */
+ .stage-card {
+ position: absolute;
+ transform: translate(-50%, -50%); /* 核心锚点居中 */
+ z-index: 10;
+ width: 140rpx; /* 适配 600rpx 容器的推荐尺寸 */
+ display: flex;
+ flex-direction: column; /* 确保文字在下方 */
+ justify-content: center;
+ align-items: center;
+ transition: all 0.3s ease;
+ }
+
+ /* 复写卡牌槽样式以匹配新容器 */
+ .spread-container .card-slot {
+ width: 100%; /* 跟随 stage-card */
+ margin: 0;
+ }
+
+ .spread-container .flip-scene {
+ width: 100%;
+ height: 210rpx; /* 强制高度 (140 * 1.5) */
+ background: rgba(255, 255, 255, 0.1); /* 调试背景,确保占位可见 */
+ border-radius: 8rpx;
+ }
+
+ .spread-container .card-face {
+ background: #1a1a2e; /* 默认深色背景,防图挂 */
+ border: 1px solid rgba(255,255,255,0.2); /* 边框 */
+ }
diff --git a/pages/home/home.js b/pages/home/home.js
index 8735b40..b41afdb 100644
--- a/pages/home/home.js
+++ b/pages/home/home.js
@@ -2,15 +2,28 @@ const { getPoints, checkDailyReward, canWatchAd, getTodayAdCount, rewardFromAd,
const { getDailyAdvice } = require('../../utils/dailyAdvice');
const { getDailyArticle, getCategories } = require('../../utils/knowledgeData');
+
/**
- * 🔧 开发模式配置
+ * 🔧 广告功能开关 (上线前配置)
*
- * DEV_MODE = true: 使用模拟广告(开发测试)
- * DEV_MODE = false: 使用真实广告(正式上线)
+ * 1. ENABLE_AD (总开关):
+ * - true: 开启广告功能
+ * - false: 关闭广告功能 (隐藏按钮, 点击提示"即将上线")
*
- * ⚠️ 上线前务必改为 false!
+ * 2. DEV_MODE (开发模式):
+ * - true: 使用模拟广告 (不拉起微信广告, 直接发奖励)
+ * - false: 使用真实广告 (拉起微信广告组件)
+ *
+ * ⚠️ 上线前:
+ * - 确保已开通流量主并填入真实 ID
+ * - 将 DEV_MODE 改为 false
+ * - 将 ENABLE_AD 改为 true
*/
-const DEV_MODE = true; // 👈 开发时设为 true,上线前改为 false
+const ENABLE_AD = false; // 👈 暂时关闭广告功能
+const DEV_MODE = true; // 👈 开发测试模式
+
+// 积分系统开关 (即便 ENABLE_AD 为 true, 如果此开关为 false, UI 也不显示积分)
+const ENABLE_POINTS_UI = true;
Page({
data: {
@@ -24,7 +37,7 @@ Page({
categoryName: '',
type: 'local'
},
- energyVisible: false,
+ showAdButton: ENABLE_AD, // 控制广告按钮显示
knowledgeVisible: false
},
@@ -36,14 +49,29 @@ Page({
this.initRewardedAd();
},
+ // ... (keeping other methods)
+
+ // 跳转到星座模块
+ goToZodiac: function () {
+ wx.navigateTo({
+ url: '/pages/zodiac/index'
+ });
+ },
+
/**
* 初始化激励视频广告
* ⚠️ 需要在微信公众平台开通流量主并获取广告位ID
*/
initRewardedAd: function () {
- // 🔧 开发模式:跳过真实广告初始化
+ // 1. 如果广告功能关闭,直接返回
+ if (!ENABLE_AD) {
+ console.log('[广告系统] 🔧 广告功能已关闭 (ENABLE_AD = false)');
+ return;
+ }
+
+ // 2. 如果是开发模式,使用模拟广告,不需要初始化真实组件
if (DEV_MODE) {
- console.log('[广告系统] 🔧 开发模式:使用模拟广告');
+ console.log('[广告系统] 🔧 开发模式:使用模拟广告 (DEV_MODE = true)');
return;
}
@@ -56,6 +84,7 @@ Page({
try {
// 创建激励视频广告实例
// ⚠️ TODO: 替换为你的真实广告位ID
+ // 只有在非开发模式且开启广告时才创建
this.rewardedAd = wx.createRewardedVideoAd({
adUnitId: 'adunit-xxxxxxxxxxxxxxxx' // 请替换为你的广告位ID
});
@@ -122,22 +151,24 @@ Page({
},
onShow: function () {
- // 检查每日登录奖励
- const rewardResult = checkDailyReward();
+ if (ENABLE_POINTS_UI) {
+ // 检查每日登录奖励
+ const rewardResult = checkDailyReward();
- // 如果获得了奖励,显示提示
- if (rewardResult.rewarded) {
- wx.showToast({
- title: rewardResult.message,
- icon: 'success',
- duration: 2000
+ // 如果获得了奖励,显示提示
+ if (rewardResult.rewarded) {
+ wx.showToast({
+ title: rewardResult.message,
+ icon: 'success',
+ duration: 2000
+ });
+ }
+
+ // 刷新积分显示
+ this.setData({
+ currentPoints: getPoints()
});
}
-
- // 刷新积分显示
- this.setData({
- currentPoints: getPoints()
- });
},
// 加载每日内容
@@ -213,6 +244,13 @@ Page({
});
},
+ // 跳转到星座模块
+ goToZodiac: function () {
+ wx.navigateTo({
+ url: '/pages/zodiac/index'
+ });
+ },
+
// 跳转到文章详情
goToArticle: function () {
const article = this.data.dailyArticle;
@@ -238,61 +276,40 @@ Page({
}, 300);
},
- // 跳转到隐私政策
- goToPrivacy: function () {
+ // 跳转到设置页
+ goToSettings: function () {
wx.navigateTo({
- url: '/pages/privacy/privacy'
+ url: '/pages/settings/settings'
});
},
- // 显示积分说明
+ // 显示积分说明 (切换为自定义浮层)
showPointsInfo: function () {
- try {
- console.log('[首页] 点击积分徽章');
- const remaining = AD_REWARD_CONFIG.DAILY_LIMIT - getTodayAdCount();
- const canWatch = canWatchAd();
+ this.setData({
+ pointsVisible: true
+ });
+ },
- console.log('[首页] 剩余广告次数:', remaining);
- console.log('[首页] 是否可以观看:', canWatch);
- console.log('[首页] 当前积分:', this.data.currentPoints);
-
- const lines = [
- '当前积分:' + this.data.currentPoints,
- '',
- '每次占卜会消耗积分,不同牌阵消耗不同。',
- '每日首次登录可获得 +3 积分奖励。',
- '',
- '看广告可获得积分(今日剩余 ' + remaining + ' 次)'
- ];
-
- const content = lines.join('\n');
- console.log('[首页] 弹窗内容:', content);
-
- console.log('[首页] 准备调用 wx.showModal');
- wx.showModal({
- title: '积分说明',
- content: content,
- confirmText: canWatch ? '看广告' : '知道了',
- cancelText: '关闭',
- success: (res) => {
- console.log('[首页] 弹窗回调:', res);
- if (res.confirm && canWatch) {
- this.watchAdForPoints();
- }
- },
- fail: (err) => {
- console.error('[首页] 弹窗失败:', err);
- }
- });
- console.log('[首页] wx.showModal 已调用');
- } catch (error) {
- console.error('[首页] showPointsInfo 错误:', error);
- }
+ // 关闭积分说明
+ hidePointsInfo: function () {
+ this.setData({
+ pointsVisible: false
+ });
},
// 观看广告获取积分(支持开发模式)
watchAdForPoints: function () {
- // 检查是否还有观看次数
+ // 1. 全局开关检查
+ if (!ENABLE_AD) {
+ wx.showToast({
+ title: '功能即将上线',
+ icon: 'none',
+ duration: 2000
+ });
+ return;
+ }
+
+ // 2. 检查是否还有观看次数
if (!canWatchAd()) {
wx.showToast({
title: '今日广告次数已用完',
diff --git a/pages/home/home.wxml b/pages/home/home.wxml
index c694de8..29bc657 100644
--- a/pages/home/home.wxml
+++ b/pages/home/home.wxml
@@ -1,16 +1,37 @@
+
+
+
-
+
🎯
{{currentPoints}}
+
+
+
+ 今日星象能量
+ 看看今天宇宙给你的提示
+
+ 🌑
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+ ✡
+
+
开始抽牌
@@ -41,9 +62,9 @@
🎯
积分说明
-
- 🔒
- 隐私政策
+
+ ⚙️
+ 更多设置
@@ -56,6 +77,43 @@
+
+
+
+
+
+
+
+ 📅
+
+ 每日登录
+ 自动获得 +3 积分
+
+
+
+ 🎁
+
+ 分享给朋友
+ 获得 +10 积分 (每日限3次)
+
+
+
+ 🔮
+
+ 消耗规则
+ 不同牌阵消耗不同积分
+
+
+
+
+ 知道了
+
+
+
diff --git a/pages/home/home.wxss b/pages/home/home.wxss
index fb50c27..1e44c91 100644
--- a/pages/home/home.wxss
+++ b/pages/home/home.wxss
@@ -10,14 +10,20 @@ page {
height: 100vh;
position: relative;
display: flex;
+ flex-direction: column;
align-items: center;
- justify-content: center;
+ justify-content: flex-start;
+ padding-top: 120rpx;
+ gap: 40px;
+ box-sizing: border-box;
}
+/* ========== 顶部栏 (已移除) ========== */
+
/* ========== 右上角积分徽章 ========== */
.points-badge {
position: absolute;
- top: 30px;
+ top: 30px; /* Restore original position */
right: 20px;
background: linear-gradient(135deg, rgba(233, 69, 96, 0.25), rgba(233, 69, 96, 0.15));
border: 1px solid rgba(233, 69, 96, 0.5);
@@ -31,6 +37,56 @@ page {
cursor: pointer;
}
+/* ========== 星座入口 ========== */
+.zodiac-entry {
+ width: 80%;
+ max-width: 320px;
+ background: linear-gradient(90deg, #2a2a3e, #16213e);
+ border: 1px solid rgba(255, 255, 255, 0.15);
+ border-radius: 16px;
+ padding: 15px 20px;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ box-shadow: 0 4px 15px rgba(0, 0, 0, 0.3);
+ z-index: 10;
+ animation: float 6s ease-in-out infinite;
+ margin-top: 120rpx;
+}
+
+.entry-hover {
+ transform: scale(0.98);
+ opacity: 0.9;
+}
+
+.zodiac-content {
+ display: flex;
+ flex-direction: column;
+ gap: 4px;
+}
+
+.zodiac-title {
+ color: #fff;
+ font-size: 16px;
+ font-weight: bold;
+ letter-spacing: 1px;
+}
+
+.zodiac-subtitle {
+ color: rgba(255, 255, 255, 0.6);
+ font-size: 12px;
+}
+
+.zodiac-icon {
+ font-size: 28px;
+ filter: drop-shadow(0 0 10px rgba(255, 255, 255, 0.3));
+}
+
+@keyframes float {
+ 0%, 100% { transform: translateY(0); }
+ 50% { transform: translateY(-8px); }
+}
+
.badge-icon {
font-size: 16px;
}
@@ -61,10 +117,79 @@ page {
position: absolute;
width: 180px;
height: 260px;
- background: linear-gradient(135deg, #e94560 0%, #8b3a62 50%, #4a1942 100%);
+ /* background moved to .card-bg */
border-radius: 12px;
- box-shadow: 0 10px 40px rgba(0, 0, 0, 0.5);
+ box-shadow: 0 10px 40px rgba(0, 0, 0, 0.6);
transition: all 0.3s ease;
+ /* overflow: hidden; Removed to allow glow to show outside */
+}
+
+.card-bg {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background: linear-gradient(135deg, #4a1942 0%, #8b3a62 50%, #e94560 100%);
+ border-radius: 12px;
+ z-index: 0;
+}
+
+/* 模糊光晕描边 */
+.card-stack::after {
+ content: "";
+ position: absolute;
+ top: -2px;
+ left: -2px;
+ right: -2px;
+ bottom: -2px;
+ z-index: -1;
+ background: linear-gradient(135deg, #7a5cff, #005bea);
+ border-radius: 14px;
+ filter: blur(2px); /* 微调模糊度 */
+ opacity: 1; /* 增强可见度 */
+}
+
+/* Card Pattern Overlay */
+.card-stack::before {
+ content: "";
+ position: absolute;
+ top: 10px;
+ left: 10px;
+ right: 10px;
+ bottom: 10px;
+ border: 1px solid rgba(255, 215, 0, 0.2);
+ border-radius: 8px;
+}
+
+.card-pattern {
+ width: 100%;
+ height: 100%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background-image: radial-gradient(circle at center, rgba(255,255,255,0.1) 0%, transparent 60%);
+}
+
+.card-symbol {
+ font-size: 200rpx; /* 最大化视局冲击 */
+ font-weight: bold;
+ background: linear-gradient(180deg, #FFD700 10%, #E0C3FC 50%, #8A2BE2 90%); /* 金色-淡紫-深紫渐变,增加神秘感 */
+ -webkit-background-clip: text;
+ background-clip: text;
+ color: transparent;
+ filter: drop-shadow(0 0 20rpx rgba(255, 215, 0, 0.5)) drop-shadow(0 0 50rpx rgba(138, 43, 226, 0.7)); /* 静态综合光晕 */
+ animation: pulseMystic 4s infinite ease-in-out;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ line-height: 1;
+ will-change: transform, opacity; /* 硬件加速优化 */
+}
+
+@keyframes pulseMystic {
+ 0%, 100% { transform: scale(1); opacity: 0.85; }
+ 50% { transform: scale(1.15); opacity: 1; }
}
.card-1 {
@@ -113,8 +238,8 @@ page {
position: absolute;
width: 90px;
height: 120px;
- background: rgba(255, 255, 255, 0.08);
- border: 1px solid rgba(255, 255, 255, 0.15);
+ background: rgba(255, 255, 255, 0.08); /* Semi-transparent white */
+ border: 1px solid rgba(255, 255, 255, 0.15); /* Light border */
border-radius: 12px;
display: flex;
flex-direction: column;
@@ -124,6 +249,8 @@ page {
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.3);
transition: all 0.3s ease;
z-index: 5;
+ top: 50%;
+ transform: translateY(-50%);
}
.card-hover {
@@ -132,15 +259,11 @@ page {
}
.energy-card {
- left: 30px;
- top: 50%;
- transform: translateY(-50%);
+ left: 10px;
}
.knowledge-card {
- right: 30px;
- top: 50%;
- transform: translateY(-50%);
+ right: 10px;
}
.card-icon {
@@ -163,7 +286,7 @@ page {
background: rgba(0, 0, 0, 0.3);
backdrop-filter: blur(10px);
border-top: 1px solid rgba(255, 255, 255, 0.1);
- padding: 15px 20px 25px;
+ padding: 8px 10px 15px;
display: flex;
justify-content: space-around;
z-index: 20;
@@ -173,8 +296,8 @@ page {
display: flex;
flex-direction: column;
align-items: center;
- gap: 8px;
- padding: 10px 15px;
+ gap: 2px;
+ padding: 4px 8px;
border-radius: 12px;
transition: all 0.3s ease;
}
@@ -347,3 +470,95 @@ page {
background: rgba(255, 255, 255, 0.1);
box-shadow: none;
}
+
+/* 积分浮层特有样式 */
+.points-header {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ margin-bottom: 25px;
+ position: relative;
+}
+
+.points-big-icon {
+ font-size: 40px;
+ margin-bottom: 5px;
+ filter: drop-shadow(0 0 10px rgba(233, 69, 96, 0.4));
+ animation: float 4s ease-in-out infinite;
+}
+
+.points-big-value {
+ font-size: 48px;
+ font-weight: bold;
+ color: #fff;
+ text-shadow: 0 0 20px rgba(233, 69, 96, 0.6);
+ line-height: 1;
+ margin-bottom: 5px;
+}
+
+.points-label {
+ font-size: 14px;
+ color: rgba(255, 255, 255, 0.6);
+ letter-spacing: 2px;
+}
+
+.points-rules {
+ background: rgba(0, 0, 0, 0.2);
+ border-radius: 12px;
+ padding: 15px;
+ width: 100%;
+ box-sizing: border-box;
+ margin-bottom: 25px;
+ border: 1px solid rgba(255, 255, 255, 0.05);
+}
+
+.rule-item {
+ display: flex;
+ align-items: center;
+ margin-bottom: 15px;
+}
+
+.rule-item:last-child {
+ margin-bottom: 0;
+}
+
+.rule-icon {
+ font-size: 24px;
+ margin-right: 15px;
+ width: 30px;
+ text-align: center;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+
+.rule-text {
+ display: flex;
+ flex-direction: column;
+ flex: 1;
+}
+
+
+.rule-title {
+ color: #ffffff !important;
+ font-size: 15px;
+ font-weight: bold;
+ margin-bottom: 4px;
+ text-align: left;
+ text-shadow: 0 1px 2px rgba(0,0,0,0.8);
+}
+
+.rule-desc {
+ color: #eeeeee !important;
+ font-size: 13px;
+ text-align: left;
+ opacity: 0.9;
+ text-shadow: 0 1px 2px rgba(0,0,0,0.5);
+}
+
+
+.points-content {
+ width: 70% !important;
+ max-width: 300px !important;
+ padding: 20px !important;
+}
diff --git a/pages/index/index.js b/pages/index/index.js
index 4f7eafb..d31007c 100644
--- a/pages/index/index.js
+++ b/pages/index/index.js
@@ -64,7 +64,20 @@ const TAROT_PROMPT_NIGHT = `你是一位安静、克制、不制造依赖的塔
// 3. 增强版模板:解读稳定器 + 高关联性结构化解读
const TAROT_PROMPT_ENHANCED = `📏 解读稳定规则(高优先级执行)
-你必须保持解读风格稳定、具体且一致,不允许出现质量波动。
+【合规红线 - 必须遵守】
+1. **娱乐属性**:明确告知用户内容仅供参考,不构成现实决策依据。
+2. **严禁迷信**:禁止使用“注定”、“必然”、“灾祸”、“鬼神”等封建迷信词汇。
+3. **禁止决策建议**:严禁提供任何医疗、法律、投资理财方面的具体建议。
+4. **正向引导**:解读必须积极向上,侧重心理疏导和个人成长,避免制造焦虑。
+
+1. **结构化输出**:必须严格遵循JSON格式,包含 theme, status, influence, advice, positions (数组)。
+2. **字数控制**:
+ - 核心主题:15-20字(精炼一句话)
+ - 单个位置解读:60-100字(深度但不过长)每张牌2句以内
+ - 当前状态:2~3句
+ - 发展趋势:2~3句
+ - 行动建议:3~5条短句
+• 禁止:超长段落、大段心理学科普、冗长比喻
【一、解读长度控制】
• 整体长度:400~700 字(不少于 300 字,不超过 900 字)
@@ -168,7 +181,8 @@ const SPREADS = [
"positions": ["当下的指引"],
"description": "为你此刻的状态提供一个温和而清晰的方向提示",
"tags": ["综合"],
- "aiSchema": ["core_theme", "current_state", "action_advice"]
+ "aiSchema": ["core_theme", "current_state", "action_advice"],
+ layout: { type: 'grid' }
},
{
"id": "three_time_flow",
@@ -178,7 +192,8 @@ const SPREADS = [
"positions": ["过去", "现在", "未来"],
"description": "帮助你理解事情的发展过程与可能走向",
"tags": ["综合", "决策"],
- "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"]
+ "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"],
+ layout: { type: 'grid' }
},
{
"id": "three_problem_solution",
@@ -188,7 +203,8 @@ const SPREADS = [
"positions": ["问题核心", "当前阻碍", "行动建议"],
"description": "聚焦关键问题,找出当下最可行的应对方式",
"tags": ["决策"],
- "aiSchema": ["core_theme", "current_state", "action_advice"]
+ "aiSchema": ["core_theme", "current_state", "action_advice"],
+ layout: { type: 'grid' }
},
{
"id": "love_spark",
@@ -198,7 +214,8 @@ const SPREADS = [
"positions": ["你的感受", "对方的感受", "关系潜力"],
"description": "探索彼此的真实感受与这段关系的可能性",
"tags": ["爱情"],
- "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"]
+ "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"],
+ layout: { type: 'grid' }
},
{
"id": "two_choice_decision",
@@ -208,7 +225,8 @@ const SPREADS = [
"positions": ["选择A的发展", "选择A的结果", "选择B的发展", "选择B的结果"],
"description": "对比两种选择的潜在走向,辅助理性决策",
"tags": ["决策"],
- "aiSchema": ["core_theme", "potential_influence", "action_advice"]
+ "aiSchema": ["core_theme", "potential_influence", "action_advice"],
+ layout: { type: 'grid' }
},
{
"id": "relationship_healing",
@@ -218,7 +236,8 @@ const SPREADS = [
"positions": ["问题根源", "你的责任", "对方的责任", "修复方向"],
"description": "深入理解关系裂痕,找到和解与修复的路径",
"tags": ["爱情"],
- "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"]
+ "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"],
+ layout: { type: 'grid' }
},
{
"id": "five_situation_analysis",
@@ -228,7 +247,8 @@ const SPREADS = [
"positions": ["现状", "内在因素", "外在影响", "行动方向", "可能结果"],
"description": "从内外层面拆解局势,明确下一步行动",
"tags": ["事业", "综合"],
- "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"]
+ "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"],
+ layout: { type: 'grid' }
},
{
"id": "relationship_spread",
@@ -238,7 +258,8 @@ const SPREADS = [
"positions": ["你的位置", "对方的位置", "关系现状", "隐藏影响", "未来趋势"],
"description": "理解一段关系中的互动模式与发展方向",
"tags": ["爱情"],
- "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"]
+ "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"],
+ layout: { type: 'grid' }
},
{
"id": "destiny_connection",
@@ -248,7 +269,8 @@ const SPREADS = [
"positions": ["前世因缘", "今生相遇", "情感纽带", "考验挑战", "缘分走向"],
"description": "探索两人之间的灵性连接与命运安排",
"tags": ["爱情"],
- "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"]
+ "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"],
+ layout: { type: 'grid' }
},
{
"id": "career_breakthrough",
@@ -258,7 +280,8 @@ const SPREADS = [
"positions": ["当前困境", "优势资源", "潜在机会", "需要克服", "突破方向"],
"description": "识别职场瓶颈,找到突破与晋升的关键",
"tags": ["事业"],
- "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"]
+ "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"],
+ layout: { type: 'grid' }
},
{
"id": "timeline_spread",
@@ -268,7 +291,8 @@ const SPREADS = [
"positions": ["远古根源", "过去影响", "当下状态", "近期发展", "未来趋势"],
"description": "追溯事件的时间线,看清发展脉络",
"tags": ["综合"],
- "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"]
+ "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"],
+ layout: { type: 'grid' }
},
{
"id": "diamond_spread",
@@ -278,7 +302,8 @@ const SPREADS = [
"positions": ["问题本质", "过去原因", "未来发展", "外部资源", "最佳行动"],
"description": "多角度剖析问题,找到解决之道",
"tags": ["决策"],
- "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"]
+ "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"],
+ layout: { type: 'grid' }
},
{
"id": "career_planning",
@@ -288,7 +313,8 @@ const SPREADS = [
"positions": ["当前位置", "核心优势", "发展方向", "潜在障碍", "贵人助力", "长期目标"],
"description": "全面规划职业发展路径,明确长期目标",
"tags": ["事业"],
- "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"]
+ "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"],
+ layout: { type: 'grid' }
},
{
"id": "wealth_analysis",
@@ -298,7 +324,8 @@ const SPREADS = [
"positions": ["财务现状", "收入来源", "支出模式", "投资机会", "财务风险", "财富增长"],
"description": "深入分析财务状况,找到财富增长的路径",
"tags": ["事业"],
- "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"]
+ "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"],
+ layout: { type: 'grid' }
},
{
"id": "spiritual_guidance",
@@ -308,7 +335,8 @@ const SPREADS = [
"positions": ["当前能量", "内在阻碍", "潜在天赋", "灵性课题", "指导建议", "未来机遇", "最高指引"],
"description": "深入探索内在世界,获得灵性层面的启发",
"tags": ["深度"],
- "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"]
+ "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"],
+ layout: { type: 'grid' }
},
{
"id": "horseshoe_spread",
@@ -318,7 +346,8 @@ const SPREADS = [
"positions": ["过去", "现在", "未来", "你的态度", "他人影响", "障碍", "最终结果"],
"description": "全面了解情况的来龙去脉与未来走向",
"tags": ["综合"],
- "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"]
+ "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"],
+ layout: { type: 'grid' }
},
{
"id": "celtic_cross",
@@ -328,7 +357,8 @@ const SPREADS = [
"positions": ["现状", "挑战", "根基", "过去", "可能性", "近期未来", "你的态度", "外部影响", "希望与恐惧", "最终结果"],
"description": "最经典的综合牌阵,深度解析生命议题",
"tags": ["深度"],
- "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"]
+ "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"],
+ layout: { type: 'grid' }
},
{
"id": "tree_of_life",
@@ -338,7 +368,8 @@ const SPREADS = [
"positions": ["王冠", "智慧", "理解", "慈悲", "严厉", "美丽", "胜利", "荣耀", "基础", "王国"],
"description": "基于卡巴拉生命之树的深度灵性探索",
"tags": ["深度"],
- "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"]
+ "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"],
+ layout: { type: 'grid' }
},
// 新增爱情牌阵
{
@@ -349,7 +380,8 @@ const SPREADS = [
"positions": ["核心关系", "你的状态", "对方状态", "未来发展"],
"description": "适合恋人关系 & 互动解析",
"tags": ["爱情"],
- "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"]
+ "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"],
+ layout: { type: 'grid' }
},
{
"id": "new_love",
@@ -359,7 +391,8 @@ const SPREADS = [
"positions": ["当前状态", "遇见契机", "发展方向"],
"description": "适合新的感情 & 遇见新欢,为单身的你或刚分手的你带来新爱提示",
"tags": ["爱情"],
- "aiSchema": ["core_theme", "current_state", "action_advice"]
+ "aiSchema": ["core_theme", "current_state", "action_advice"],
+ layout: { type: 'grid' }
},
{
"id": "relationship_basic",
@@ -369,7 +402,8 @@ const SPREADS = [
"positions": ["你的想法", "对方想法", "关系走向"],
"description": "适合梳理关系 & 拉近距离,回溯结识初衷,梳理人际关系,拉近彼此距离",
"tags": ["爱情"],
- "aiSchema": ["core_theme", "current_state", "action_advice"]
+ "aiSchema": ["core_theme", "current_state", "action_advice"],
+ layout: { type: 'grid' }
},
{
"id": "love_tree_spread",
@@ -379,7 +413,8 @@ const SPREADS = [
"positions": ["核心问题", "过去影响", "现在状况", "未来趋势", "最终结果"],
"description": "适合深度求爱 & 寻找症结,解析前因后果,回溯爱情过往,探究本源核心",
"tags": ["爱情"],
- "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"]
+ "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"],
+ layout: { type: 'grid' }
},
{
"id": "love_cross_spread",
@@ -389,7 +424,8 @@ const SPREADS = [
"positions": ["你的状态", "对方状态", "过去影响", "现在情况", "未来发展"],
"description": "适合解析两性关系 & 爱情状况,基于洞悉彼此关系中的情感状况并分析结果",
"tags": ["爱情"],
- "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"]
+ "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"],
+ layout: { type: 'grid' }
},
{
"id": "mr_right",
@@ -399,7 +435,8 @@ const SPREADS = [
"positions": ["内心期待", "现实阻碍", "理想对象", "行动建议", "遇见时机"],
"description": "单身探索有缘人 & 合适对象,探索内心的想法,改善外在的行为,遇到适合的人",
"tags": ["爱情"],
- "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"]
+ "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"],
+ layout: { type: 'grid' }
},
{
"id": "search_lover",
@@ -409,7 +446,8 @@ const SPREADS = [
"positions": ["当前状态", "优势特质", "改进方向", "寻找方式", "目标确定"],
"description": "适合寻找意中人 & 有缘人,睁全宫中人的愿景,帮助自己确定目标",
"tags": ["爱情"],
- "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"]
+ "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"],
+ layout: { type: 'grid' }
},
{
"id": "inspiration_correspondence",
@@ -419,7 +457,8 @@ const SPREADS = [
"positions": ["情感现状", "内心需求", "对方感受", "互动方式", "发展建议", "最终走向"],
"description": "适合情感困惑 & 人际关系,增长解析指缘联接或情感互动,帮您交融状态",
"tags": ["爱情"],
- "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"]
+ "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"],
+ layout: { type: 'grid' }
},
{
"id": "gypsy_spread",
@@ -429,7 +468,8 @@ const SPREADS = [
"positions": ["你的想法", "对方想法", "过去经历", "现在状况", "未来发展"],
"description": "适合情侣分析 & 关系延展,探索彼此内心想法,找到合适的相处方式",
"tags": ["爱情"],
- "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"]
+ "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"],
+ layout: { type: 'grid' }
},
{
"id": "venus_spread",
@@ -439,7 +479,8 @@ const SPREADS = [
"positions": ["你的状态", "对方状态", "关系开始", "当前情况", "核心问题", "最终结果", "外部影响", "内在感受"],
"description": "适合爱情发展 & 判断走向,全面的爱情解析牌阵,深入分析两性关系",
"tags": ["爱情"],
- "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"]
+ "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"],
+ layout: { type: 'grid' }
},
{
"id": "lover_tree",
@@ -449,7 +490,8 @@ const SPREADS = [
"positions": ["你的行为", "对方行为", "你的想法", "对方想法", "你的感受", "对方感受", "关系走向"],
"description": "适合探究对方心理 & 行为模式,对比情侣间的行为差异,进而根据事实做出判断",
"tags": ["爱情"],
- "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"]
+ "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"],
+ layout: { type: 'grid' }
},
{
"id": "marriage_spread",
@@ -459,7 +501,8 @@ const SPREADS = [
"positions": ["婚姻基础", "你的期望", "对方期望", "核心问题", "外部影响", "内在感受", "未来走向"],
"description": "适合婚姻状况 & 内在剖析,针对婚姻状况和期望进行解析,通过细致分析把握婚姻走向",
"tags": ["爱情"],
- "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"]
+ "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"],
+ layout: { type: 'grid' }
},
// 新增事业牌阵
{
@@ -470,7 +513,8 @@ const SPREADS = [
"positions": ["问题核心", "左侧因素", "右侧因素"],
"description": "适合财富探索 & 问题解析,清楚审视整个问题的来龙去脉,进而做出正确决策",
"tags": ["事业", "财富"],
- "aiSchema": ["core_theme", "current_state", "action_advice"]
+ "aiSchema": ["core_theme", "current_state", "action_advice"],
+ layout: { type: 'grid' }
},
{
"id": "success_star",
@@ -480,7 +524,8 @@ const SPREADS = [
"positions": ["当前位置", "行动方向", "成功目标"],
"description": "适合走位辨路 & 累积行动,锁定目标破除阻碍,告诉星光,心有明月再出发",
"tags": ["事业"],
- "aiSchema": ["core_theme", "current_state", "action_advice"]
+ "aiSchema": ["core_theme", "current_state", "action_advice"],
+ layout: { type: 'grid' }
},
{
"id": "career_pyramid",
@@ -490,7 +535,8 @@ const SPREADS = [
"positions": ["核心优势", "需要改进", "外部机会", "未来发展"],
"description": "适合解析财富运势 & 提升财商,明晰自我的优缺点,帮助自己除弊趋利在事业中获得优势",
"tags": ["事业"],
- "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"]
+ "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"],
+ layout: { type: 'grid' }
},
{
"id": "wealth_tree",
@@ -500,7 +546,8 @@ const SPREADS = [
"positions": ["财务基础", "收入来源", "支出状况", "当前状态", "未来趋势"],
"description": "适合事业发展 & 状态评估,通过对财富的梳理,健全适合自己的财务模式",
"tags": ["事业", "财富"],
- "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"]
+ "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"],
+ layout: { type: 'grid' }
},
{
"id": "x_opportunity",
@@ -510,7 +557,8 @@ const SPREADS = [
"positions": ["当前时机", "有利因素", "不利因素", "行动建议", "结果预测"],
"description": "适合时机捕捉 & 临场决策,以事物处理时机为主线轴,牵挂问题解决的成功概率",
"tags": ["事业", "决策"],
- "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"]
+ "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"],
+ layout: { type: 'grid' }
},
{
"id": "job_interview",
@@ -520,7 +568,8 @@ const SPREADS = [
"positions": ["自我状态", "优势展现", "需要注意", "面试官印象", "录用可能"],
"description": "适合解析应聘面试 & 求职状况,洞察对方需求与自我留言,有效提高面试成功率",
"tags": ["事业"],
- "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"]
+ "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"],
+ layout: { type: 'grid' }
},
{
"id": "work_problems",
@@ -530,7 +579,8 @@ const SPREADS = [
"positions": ["问题核心", "上级态度", "同事关系", "个人能力", "外部环境", "解决方案"],
"description": "适合聚焦目标 & 优化路径,当你明确自己的目标,全世界都会为你让路",
"tags": ["事业"],
- "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"]
+ "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"],
+ layout: { type: 'grid' }
},
{
"id": "turbulent_finances",
@@ -540,7 +590,8 @@ const SPREADS = [
"positions": ["财务起点", "第一波动", "稳定期", "第二波动", "调整期", "未来趋势"],
"description": "适合借力打力 & 多空对比,追问本质,结合正反两方面的分析,做出理智判断",
"tags": ["事业", "财富"],
- "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"]
+ "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"],
+ layout: { type: 'grid' }
},
{
"id": "desired_job",
@@ -550,7 +601,8 @@ const SPREADS = [
"positions": ["理想工作", "个人优势", "需要提升", "寻找方向", "关键因素", "实现可能"],
"description": "适合评估工作前景 & 关联因素,剖析工作前景,理清相关因素,给出明确的思路",
"tags": ["事业"],
- "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"]
+ "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"],
+ layout: { type: 'grid' }
},
// 新增决策牌阵
{
@@ -561,7 +613,8 @@ const SPREADS = [
"positions": ["选项A", "选项B", "建议方向"],
"description": "适合评测选项 & 做出抉择,在两难的处境中给出建议,选出适合自己的抉择",
"tags": ["决策"],
- "aiSchema": ["core_theme", "current_state", "action_advice"]
+ "aiSchema": ["core_theme", "current_state", "action_advice"],
+ layout: { type: 'grid' }
},
{
"id": "three_options",
@@ -571,7 +624,8 @@ const SPREADS = [
"positions": ["当前状况", "参考方向一", "参考方向二"],
"description": "提供参考方向 & 行动指向,遇到3个选择时,给你提供参考的方向",
"tags": ["决策"],
- "aiSchema": ["core_theme", "current_state", "action_advice"]
+ "aiSchema": ["core_theme", "current_state", "action_advice"],
+ layout: { type: 'grid' }
},
{
"id": "daily_tree",
@@ -581,7 +635,8 @@ const SPREADS = [
"positions": ["今日核心", "需要注意", "有利因素", "行动建议"],
"description": "适长当日难题 & 当日解决,天天没烦恼,解决每天遇到的问题",
"tags": ["综合"],
- "aiSchema": ["core_theme", "current_state", "action_advice"]
+ "aiSchema": ["core_theme", "current_state", "action_advice"],
+ layout: { type: 'grid' }
},
{
"id": "weigh_two",
@@ -591,7 +646,8 @@ const SPREADS = [
"positions": ["当前状况", "选项A优势", "选项B优势", "选项A劣势", "选项B劣势"],
"description": "主要用于抉择 & 判断,二选一,适用于二种情况选择其中一种",
"tags": ["决策"],
- "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"]
+ "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"],
+ layout: { type: 'grid' }
},
{
"id": "comparing_choices",
@@ -601,7 +657,8 @@ const SPREADS = [
"positions": ["选项A现状", "选项A发展", "选项A结果", "选项B现状", "选项B发展", "选项B结果"],
"description": "适合判断情势 & 决定方向,多层面聚焦两个方向,更多的线索更多的细节",
"tags": ["决策"],
- "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"]
+ "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"],
+ layout: { type: 'grid' }
},
{
"id": "weigh_three",
@@ -611,7 +668,8 @@ const SPREADS = [
"positions": ["当前状况", "选项A优势", "选项B优势", "选项A劣势", "选项C优势", "选项C劣势", "选项B劣势"],
"description": "适合事情抉择 & 选择评估,对利弊关系进行分析判断,权衡利弊,做出最终的选择",
"tags": ["决策"],
- "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"]
+ "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"],
+ layout: { type: 'grid' }
},
// 新增深度探索牌阵
{
@@ -622,7 +680,8 @@ const SPREADS = [
"positions": ["身体", "心智", "灵性", "整体状态"],
"description": "适合自我探索 & 了解自己,透彻审视自我,更直切明了自身成长路径",
"tags": ["成长", "综合"],
- "aiSchema": ["core_theme", "current_state", "action_advice"]
+ "aiSchema": ["core_theme", "current_state", "action_advice"],
+ layout: { type: 'grid' }
},
{
"id": "four_elements",
@@ -632,7 +691,8 @@ const SPREADS = [
"positions": ["感性", "理性", "物质", "行动"],
"description": "适合问题探索 & 多方解析,从感性、理性、物质、行动四方面分析,进而接近实质",
"tags": ["探索", "综合"],
- "aiSchema": ["core_theme", "current_state", "action_advice"]
+ "aiSchema": ["core_theme", "current_state", "action_advice"],
+ layout: { type: 'grid' }
},
{
"id": "self_discovery",
@@ -642,7 +702,8 @@ const SPREADS = [
"positions": ["核心自我", "潜能", "优势", "需要提升"],
"description": "适合认识自我 & 提升潜能,开发自身潜力,提高对自己的认识",
"tags": ["探索", "成长"],
- "aiSchema": ["core_theme", "current_state", "action_advice"]
+ "aiSchema": ["core_theme", "current_state", "action_advice"],
+ layout: { type: 'grid' }
},
{
"id": "know_yourself",
@@ -652,7 +713,8 @@ const SPREADS = [
"positions": ["核心自我", "思想", "行为", "情感", "环境影响"],
"description": "适合自我剖析 & 境况认知,人无时无刻不受环境的影响,在各种关系的交织中成长",
"tags": ["成长", "综合"],
- "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"]
+ "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"],
+ layout: { type: 'grid' }
},
{
"id": "your_breakthrough",
@@ -662,7 +724,8 @@ const SPREADS = [
"positions": ["当前困境", "阻碍因素", "突破点", "行动方向", "预期结果"],
"description": "适合打破僵环 & 突破自我,识别固定模式,突破往复循环",
"tags": ["成长"],
- "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"]
+ "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"],
+ layout: { type: 'grid' }
},
{
"id": "elemental_cross",
@@ -672,7 +735,8 @@ const SPREADS = [
"positions": ["核心问题", "火元素", "水元素", "风元素", "土元素", "解决方案"],
"description": "主要用于带入问题 & 解决问题,根据现实情况全面运用四元素能提升自己",
"tags": ["探索", "综合"],
- "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"]
+ "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"],
+ layout: { type: 'grid' }
},
{
"id": "wheel_spread",
@@ -682,7 +746,8 @@ const SPREADS = [
"positions": ["中心", "过去", "现在", "未来", "机会", "挑战", "结果"],
"description": "适合专注自我 & 探寻改变,有时走出循环照顾的舒适圈,有所改变时,才能成长",
"tags": ["成长"],
- "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"]
+ "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"],
+ layout: { type: 'grid' }
},
{
"id": "seven_planets",
@@ -692,7 +757,8 @@ const SPREADS = [
"positions": ["核心", "月亮", "水星", "金星", "太阳", "火星", "木星"],
"description": "适合审视目前状态 & 了解自己,综合分析当下状况,全面的了解自己",
"tags": ["成长", "综合"],
- "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"]
+ "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"],
+ layout: { type: 'grid' }
},
{
"id": "dream_mirror",
@@ -702,7 +768,8 @@ const SPREADS = [
"positions": ["梦境表象", "潜意识", "情感", "符号", "启示", "行动", "整合"],
"description": "适合分析梦境 & 获得启迪,梦像一面镜子,解读梦境,是理解自己的渠道",
"tags": ["探索"],
- "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"]
+ "aiSchema": ["core_theme", "current_state", "potential_influence", "action_advice"],
+ layout: { type: 'grid' }
}
];
@@ -739,17 +806,29 @@ Page({
// AI 解读相关
aiResult: null,
isAiLoading: false,
- aiLoadingText: '正在抽取牌面…', // 动态加载提示
+ aiLoadingText: '正在深度解读...', // 动态加载提示
spreadStory: '',
// 3. 前缀文案列表(随机抽取)
prefixList: [
- "今天,这张牌提醒你:",
- "此刻,宇宙传递的信息:",
- "这张牌想告诉你:",
- "请收下这份指引:"
+ "透过层层迷雾,牌面显示...",
+ "连接此刻的能量,这张牌意味着...",
+ "这是一个特别的信号...",
+ "如同命运的低语...",
+ "在潜意识的深处..."
],
+ // 4. 分享引导文案
+ randomGuidanceText: "",
+ guidanceList: [
+ "这组牌很少见",
+ "你的能量状态正在转折",
+ "这个答案值得记录",
+ "一次直抵内心的对话",
+ "命运在这一刻给予了回应"
+ ],
+
+
// 2. 完整的 22 张大阿尔卡那牌组(包含逆位含义)
cardList: [
{
@@ -1206,7 +1285,7 @@ Page({
// --- 4. 逐一翻牌 ---
revealNext: function (e) {
- const index = e.currentTarget.dataset.index;
+ const index = (e.detail && e.detail.index !== undefined) ? e.detail.index : e.currentTarget.dataset.index;
if (index === this.data.revealedCount) {
const nextCount = index + 1;
this.setData({
@@ -1215,12 +1294,34 @@ Page({
// 如果全部翻开,触发解读
if (nextCount === this.data.selectedSpread.cardCount) {
- this.setData({ state: 'revealed' });
+ // 随机生成分享引导文案
+ // Note: guidanceList needs to be defined in data or elsewhere for this to work.
+ // For now, assuming it exists or will be added.
+ const guidanceIdx = Math.floor(Math.random() * (this.data.guidanceList ? this.data.guidanceList.length : 1));
+ const guidanceText = this.data.guidanceList ? this.data.guidanceList[guidanceIdx] : '分享你的塔罗解读,获得更多指引!';
+
+ this.setData({
+ state: 'revealed',
+ randomGuidanceText: guidanceText // 设置引导文案
+ });
this.showInterpretation();
}
}
},
+ // 查看已翻开牌的详情
+ viewCardDetail: function (e) {
+ const index = (e.detail && e.detail.index !== undefined) ? e.detail.index : e.currentTarget.dataset.index;
+ const card = this.data.drawnCards[index];
+ if (card) {
+ wx.showToast({
+ title: card.name + (card.isReversed ? '(逆)' : ''),
+ icon: 'none',
+ duration: 1500
+ });
+ }
+ },
+
// --- 展示解读内容 ---
showInterpretation: function () {
const infoAnim = wx.createAnimation({
@@ -1242,6 +1343,7 @@ Page({
this.setData({
isAiLoading: true,
aiResult: null,
+ aiStreamText: '',
aiLoadingText: '正在抽取牌面…'
});
@@ -1305,11 +1407,7 @@ ${cardMeanings}
// 5. 处理结果
if (result.status === 'blocked') {
- wx.showToast({
- title: result.message,
- icon: 'none',
- duration: 2000
- });
+ wx.showToast({ title: result.message, icon: 'none', duration: 2000 });
this.setData({ isAiLoading: false });
return;
}
@@ -1326,14 +1424,69 @@ ${cardMeanings}
// 8. 如果是 fallback,显示提示
if (result.status === 'fallback' && result.error) {
- wx.showToast({
- title: 'AI 解读失败,已使用备用解读',
- icon: 'none',
- duration: 3000
- });
+ wx.showToast({ title: 'AI 解读失败,已使用备用解读', icon: 'none', duration: 3000 });
}
},
+ // --- 打字机效果:逐字显示 AI 解读 ---
+ typewriterReveal: function (data) {
+ // 初始化空的 aiResult 结构,先占位
+ const emptyResult = {
+ theme: '',
+ status: '',
+ influence: '',
+ advice: '',
+ positions: (data.positions || []).map(p => ({
+ posName: p.posName,
+ posMeaning: ''
+ }))
+ };
+ this.setData({ aiResult: emptyResult });
+
+ // 把所有需要打字机显示的字段排成队列
+ const fields = [
+ { key: 'aiResult.theme', text: data.theme || '' },
+ { key: 'aiResult.status', text: data.status || '' },
+ { key: 'aiResult.influence', text: data.influence || '' },
+ { key: 'aiResult.advice', text: data.advice || '' },
+ ];
+
+ // 加入每个位置的解读
+ (data.positions || []).forEach((pos, i) => {
+ fields.push({
+ key: `aiResult.positions[${i}].posMeaning`,
+ text: pos.posMeaning || ''
+ });
+ });
+
+ // 逐字段、逐字符地显示
+ let fieldIndex = 0;
+
+ const revealNextField = () => {
+ if (fieldIndex >= fields.length) return; // 全部完成
+
+ const field = fields[fieldIndex];
+ const fullText = field.text;
+ let charIndex = 0;
+
+ // 每个字符间隔 25ms(约 40字/秒)
+ const timer = setInterval(() => {
+ charIndex++;
+ const partial = fullText.slice(0, charIndex);
+ this.setData({ [field.key]: partial });
+
+ if (charIndex >= fullText.length) {
+ clearInterval(timer);
+ fieldIndex++;
+ // 字段间停顿 150ms 再开始下一个字段
+ setTimeout(revealNextField, 150);
+ }
+ }, 25);
+ };
+
+ revealNextField();
+ },
+
handleAiFallback: function () {
// 构建一个基础的回退对象
const fallback = {
@@ -1401,11 +1554,30 @@ ${cardMeanings}
wx.navigateBack({
delta: 1
});
- } else {
- // 其他状态直接返回主页
- wx.navigateBack({
- delta: 1
- });
}
+ },
+
+ /**
+ * 用户点击右上角分享
+ */
+ onShareAppMessage: function () {
+ const titles = [
+ "我刚抽到一组很准的塔罗…",
+ "这次塔罗结果让我有点意外",
+ "今天的塔罗指引比我想象深",
+ "这是我此刻的能量状态✨",
+ "这里有一个答案,也许你也需要"
+ ];
+ const randomTitle = titles[Math.floor(Math.random() * titles.length)];
+
+ // 模拟生成 fromUserId (实际应从用户信息获取)
+ // 这里简单使用一个随机字符串代替,或者保留为空等待后续接入用户系统
+ const mockUserId = 'user_' + Math.random().toString(36).substr(2, 9);
+
+ return {
+ title: randomTitle,
+ path: `/pages/home/home?fromUserId=${mockUserId}`,
+ imageUrl: '/images/share-cover.png' // 建议后续添加一张通用的分享图
+ };
}
})
diff --git a/pages/index/index.json b/pages/index/index.json
index f6beb02..2b5a71a 100644
--- a/pages/index/index.json
+++ b/pages/index/index.json
@@ -1,4 +1,6 @@
{
"navigationBarTitleText": "塔罗指引",
- "usingComponents": {}
+ "usingComponents": {
+ "spread-container": "/components/spread-container/spread-container"
+ }
}
\ No newline at end of file
diff --git a/pages/index/index.wxml b/pages/index/index.wxml
index ed73751..07efb40 100644
--- a/pages/index/index.wxml
+++ b/pages/index/index.wxml
@@ -4,6 +4,7 @@
⇠
返回
+
@@ -47,7 +48,7 @@
@@ -145,33 +146,42 @@
module.exports.getTransform = function(indices, currentIdx, count) {
var pos = indices.indexOf(currentIdx);
if (pos !== -1) {
- // 每排最多5张牌
var maxPerRow = 5;
- var row = Math.floor(pos / maxPerRow); // 第几排(0或1)
- var col = pos % maxPerRow; // 该排的第几个
- var cardsInRow = (row === 0) ? Math.min(count, maxPerRow) : (count - maxPerRow);
+ var row = Math.floor(pos / maxPerRow);
+ var col = pos % maxPerRow;
- // 槽位:宽100rpx + gap 20rpx = 120rpx 间距
- var slotWidth = 100;
- var gap = 20;
- var slotSpacing = slotWidth + gap;
+ var cardsRemaining = count - (row * maxPerRow);
+ var cardsInRow = (cardsRemaining > maxPerRow) ? maxPerRow : cardsRemaining;
- // 计算该排槽位的水平居中偏移
- // 从该排中间位置开始计算
- var centerOffset = (col - (cardsInRow - 1) / 2) * slotSpacing;
+ // Container Calculation
+ var rowCount = Math.ceil(count / maxPerRow);
+ var contentHeight = (rowCount * 160) + ((rowCount - 1) * 20);
+ if (contentHeight < 240) { contentHeight = 240; } // Handle min-height: 240rpx
- // 垂直偏移计算
- // 第一排槽位:向上 -520rpx(已验证接近正确)
- // 第二排:需要减少向上的距离
- // 槽位高度160 + gap 20 = 180,但实际可能需要微调
- var firstRowY = -520;
- var secondRowOffset = 200; // 增加偏移量,让第二排更接近fan-deck
- var yOffset = firstRowY + (row * secondRowOffset); // row=0: -520, row=1: -320
+ // Distance from Slot Container Top to Fan Deck Bottom
+ // FanHeight(380) + FanMarginTop(20) + ContainerMarginBottom(60) + ContainerHeight
+ var distToFanBottom = 380 + 20 + 60 + contentHeight;
+
+ // Determine Slot Center Y from Container Top
+ // Row 0 starts at 0. Center is 80.
+ // Row 1 starts at 180. Center is 260.
+ var slotCenterY = (row * 180) + 80;
+
+ // Target Y relative to Fan Bottom (0)
+ // SlotCenter is above FanBottom, so negative.
+ var targetY = -(distToFanBottom - slotCenterY);
+
+ // Adjust for Card Visual Center (Transform Origin: Bottom Center)
+ // Card Height 260 -> Scaled 0.65 -> 169
+ // Visual Center is 84.5 from bottom.
+ // We want visual center at targetY.
+ // Origin (Bottom) needs to be at targetY + 84.5
+ var yOffset = targetY + 84.5;
+
+ var centerOffset = (col - (cardsInRow - 1) / 2) * 120;
- // 位移并缩小到0.65
return 'translate(' + centerOffset + 'rpx, ' + yOffset + 'rpx) scale(0.65) rotate(0deg)';
} else {
- // 保持在牌堆中的放射状
return 'rotate(' + ((currentIdx - 10) * 8) + 'deg)';
}
};
@@ -184,25 +194,25 @@
-
-
- {{selectedSpread.positions[index]}}(第{{index + 1}}张)
-
-
-
-
-
-
-
-
-
-
- {{item.name}}{{item.isReversed ? '(逆)' : ''}}
-
+
+
+
+
+
+ ✦
+ 依次点击牌面,逐一揭示
+ ✦
+
···
{{aiLoadingText}}
@@ -243,6 +253,20 @@
{{aiResult.advice}}
+
+ ⚠ 塔罗映照潜意识的微光,最终的选择始终在你手中。
+
+
+
+
+
+ “{{randomGuidanceText}}”
+
+
+
+
diff --git a/pages/index/index.wxss b/pages/index/index.wxss
index c80b3d8..6137b18 100644
--- a/pages/index/index.wxss
+++ b/pages/index/index.wxss
@@ -1,1486 +1,1603 @@
-page {
- background-color: #0f0f1b;
- color: #e0e0e0;
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
-}
-
-.container {
- min-height: 100vh;
- background-color: #0f0f1b;
- padding: 40rpx 30rpx 100rpx;
- box-sizing: border-box;
- color: #e0e0e0;
- display: flex;
- flex-direction: column;
- position: relative;
-}
-
-/* 自定义返回按钮样式 */
-.nav-back {
- position: absolute;
- top: 40rpx;
- left: 30rpx;
- display: flex;
- align-items: center;
- z-index: 100;
- padding: 10rpx 20rpx;
- border-radius: 30rpx;
- background: rgba(255, 255, 255, 0.05);
-}
-
-.back-icon {
- font-size: 32rpx;
- margin-right: 8rpx;
- color: #c9a0dc;
-}
-
-.back-text {
- font-size: 26rpx;
- color: #c9a0dc;
- letter-spacing: 2rpx;
-}
-
-/* 标题通用样式 */
-.title-area {
- text-align: center;
- margin-top: 40rpx;
- margin-bottom: 60rpx;
-}
-
-.app-title {
- font-size: 44rpx;
- font-weight: 600;
- color: #c9a0dc;
- letter-spacing: 4rpx;
- display: block;
- margin-bottom: 16rpx;
-}
-
-.instruction {
- font-size: 26rpx;
- color: #8a8a9d;
- letter-spacing: 1rpx;
-}
-
-/* 1. 牌阵选择 - 卡片式V2 */
-
-/* 顶部标题区域 */
-.spread-header {
- text-align: center;
- padding: 60rpx 0 40rpx;
-}
-
-.spread-title {
- display: block;
- font-size: 36rpx;
- color: #c9a0dc;
- font-weight: 500;
- margin-bottom: 12rpx;
- letter-spacing: 2rpx;
-}
-
-.spread-subtitle {
- display: block;
- font-size: 24rpx;
- color: rgba(201, 160, 220, 0.7);
- letter-spacing: 2rpx;
- font-weight: 300;
-}
-
-/* 标签筛选条 */
-.tags-area {
- padding: 0 30rpx 30rpx;
-}
-
-.tags-scroll {
- white-space: nowrap;
-}
-
-.tag-item {
- display: inline-block;
- padding: 12rpx 28rpx;
- margin-right: 16rpx;
- background: rgba(255, 255, 255, 0.05);
- border: 1px solid rgba(201, 160, 220, 0.3);
- border-radius: 30rpx;
- font-size: 26rpx;
- color: rgba(201, 160, 220, 0.8);
- transition: all 0.3s ease;
-}
-
-.tag-item.active {
- background: rgba(201, 160, 220, 0.2);
- border-color: rgba(201, 160, 220, 0.6);
- color: #ffffff;
- transform: scale(1.05);
-}
-
-/* 两列卡片网格 */
-.spread-grid {
- display: grid;
- grid-template-columns: 1fr 1fr;
- gap: 20rpx;
- padding: 0 30rpx 40rpx;
-}
-
-.spread-card {
- background: rgba(255, 255, 255, 0.05);
- border: 1px solid rgba(201, 160, 220, 0.3);
- border-radius: 20rpx;
- padding: 30rpx 24rpx;
- position: relative;
- box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.3);
- transition: all 0.3s ease;
- min-height: 240rpx;
- display: flex;
- flex-direction: column;
-}
-
-.spread-card:active {
- transform: translateY(-4rpx);
- box-shadow: 0 8rpx 30rpx rgba(201, 160, 220, 0.3);
- border-color: rgba(201, 160, 220, 0.5);
-}
-
-.card-badge {
- position: absolute;
- top: 12rpx;
- right: 12rpx;
- background: rgba(201, 160, 220, 0.3);
- padding: 4rpx 12rpx;
- border-radius: 8rpx;
- font-size: 20rpx;
- color: #c9a0dc;
-}
-
-.card-name {
- display: block;
- font-size: 30rpx;
- color: #ffffff;
- font-weight: 500;
- margin-bottom: 12rpx;
- padding-right: 60rpx;
-}
-
-.card-desc {
- display: block;
- font-size: 22rpx;
- color: rgba(255, 255, 255, 0.6);
- line-height: 1.5;
- margin-bottom: 20rpx;
- flex: 1;
-}
-
-.card-footer {
- display: flex;
- justify-content: space-between;
- font-size: 20rpx;
- color: rgba(201, 160, 220, 0.7);
- padding-top: 16rpx;
- border-top: 1px solid rgba(255, 255, 255, 0.05);
-}
-
-.card-count {
- opacity: 0.8;
-}
-
-.card-cost {
- font-weight: 500;
-}
-
-/* 2. 洗牌仪式感 */
-.ritual-area {
- flex: 1;
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
-}
-
-.shuffling-container {
- position: relative;
- width: 200rpx;
- height: 300rpx;
- margin-bottom: 80rpx;
-}
-
-.shuffling-card {
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- border-radius: 12rpx;
- box-shadow: 0 4rpx 12rpx rgba(0,0,0,0.5);
- animation: shuffle 1s infinite alternate ease-in-out;
-}
-
-@keyframes shuffle {
- from { transform: translateX(-40rpx) rotate(-5deg); }
- to { transform: translateX(40rpx) rotate(5deg); }
-}
-
-.ritual-hint {
- font-size: 28rpx;
- color: #c9a0dc;
- opacity: 0.8;
- animation: breathe 2s infinite ease-in-out;
-}
-
-@keyframes breathe {
- 0%, 100% { opacity: 0.4; }
- 50% { opacity: 1; }
-}
-
-/* 3. 抽牌区域 (槽位 + 扇形) */
-.drawing-area {
- flex: 1;
- display: flex;
- flex-direction: column;
- align-items: center;
- padding-top: 40rpx;
-}
-
-.slots-container {
- display: flex;
- flex-wrap: wrap; /* 允许换行 */
- justify-content: center;
- gap: 20rpx; /* 保持20rpx间距,与计算一致 */
- min-height: 240rpx; /* 改为最小高度 */
- max-height: 480rpx; /* 最多两排的高度 */
- margin-bottom: 60rpx;
- width: 100%;
- padding: 0 30rpx; /* 增加左右padding确保居中 */
-}
-
-.slot-item {
- width: 100rpx; /* 与WXS计算的宽度一致 */
- height: 160rpx; /* 与WXS计算的高度一致 */
- position: relative;
- flex-shrink: 0; /* 防止收缩 */
-}
-
-.slot-placeholder {
- width: 100%;
- height: 100%;
- border: 2rpx dashed rgba(201, 160, 220, 0.3);
- border-radius: 12rpx;
- display: flex;
- align-items: center;
- justify-content: center;
- background: rgba(255, 255, 255, 0.02);
-}
-
-.slot-num {
- font-size: 40rpx;
- color: rgba(201, 160, 220, 0.2);
- font-family: serif;
-}
-
-.slot-card-wrapper {
- width: 100%;
- height: 100%;
- animation: flyInSlot 0.4s cubic-bezier(0.34, 1.56, 0.64, 1) both;
-}
-
-.slot-card-back {
- width: 100%;
- height: 100%;
- border-radius: 12rpx;
- box-shadow: 0 8rpx 20rpx rgba(0,0,0,0.6);
- border: 1px solid rgba(255, 255, 255, 0.1);
-}
-
-@keyframes flyInSlot {
- from {
- transform: translateY(400rpx) scale(0.8) rotate(10deg);
- opacity: 0;
- }
- to {
- transform: translateY(0) scale(1) rotate(0);
- opacity: 1;
- }
-}
-
-.fan-deck {
- position: relative;
- height: 380rpx;
- width: 100%;
- margin-top: 20rpx;
- perspective: 1000px;
- overflow: visible; /* 允许卡牌飞出容器 */
-}
-
-.fan-card {
- position: absolute;
- left: 50%;
- bottom: 0;
- width: 150rpx;
- height: 260rpx;
- margin-left: -75rpx;
- transform-origin: bottom center;
- transition: transform 0.6s cubic-bezier(0.19, 1, 0.22, 1);
- z-index: 10;
-}
-
-.card-back-sm {
- width: 100%;
- height: 100%;
- border-radius: 10rpx;
- box-shadow: 0 4rpx 12rpx rgba(0,0,0,0.5);
- border: 1px solid rgba(255, 255, 255, 0.05);
-}
-
-.fan-card.is-selected {
- z-index: 100;
- pointer-events: auto; /* 允许点击已抽出的牌返回 */
-}
-
-.draw-count {
- text-align: center;
- font-size: 36rpx;
- color: #c9a0dc;
- margin-top: 60rpx;
-}
-
-.confirm-draw-btn {
- margin: 40rpx auto;
- background: #c9a0dc;
- color: #1a1a2e;
- border-radius: 40rpx;
- font-weight: 600;
- width: 300rpx;
-}
-
-/* 4. 翻牌结果展示 */
-.result-area {
- flex: 1;
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: flex-start;
- padding: 30rpx 20rpx;
- overflow-y: auto;
-}
-
-.spread-display {
- display: flex;
- flex-wrap: wrap;
- justify-content: center;
- align-items: flex-start;
- gap: 12rpx;
- padding: 20rpx 0;
- margin: 0 auto;
-}
-
-/* 牌阵专属布局 - 传统排列方式 */
-
-/* 1张牌 - 居中 */
-.spread-display.one_card_guidance {
- max-width: 130rpx;
-}
-
-/* 3张牌 - 横排 */
-.spread-display.three_time_flow,
-.spread-display.three_problem_solution,
-.spread-display.love_spark {
- display: grid;
- grid-template-columns: repeat(3, 110rpx);
- gap: 15rpx;
- max-width: 375rpx;
-}
-
-/* 4张牌 - 2x2网格 */
-.spread-display.two_choice_decision,
-.spread-display.relationship_healing {
- display: grid;
- grid-template-columns: repeat(2, 110rpx);
- gap: 15rpx;
- max-width: 245rpx;
-}
-
-/* 5张牌 - 十字形 (现状分析) */
-.spread-display.five_situation_analysis {
- display: grid;
- grid-template-columns: repeat(3, 110rpx);
- grid-template-rows: repeat(3, auto);
- gap: 15rpx;
- max-width: 375rpx;
-}
-
-.spread-display.five_situation_analysis .card-slot:nth-child(1) { grid-area: 2 / 2; }
-.spread-display.five_situation_analysis .card-slot:nth-child(2) { grid-area: 1 / 2; }
-.spread-display.five_situation_analysis .card-slot:nth-child(3) { grid-area: 3 / 2; }
-.spread-display.five_situation_analysis .card-slot:nth-child(4) { grid-area: 2 / 1; }
-.spread-display.five_situation_analysis .card-slot:nth-child(5) { grid-area: 2 / 3; }
-
-/* 5张牌 - 关系洞察 */
-.spread-display.relationship_spread {
- display: grid;
- grid-template-columns: repeat(3, 110rpx);
- grid-template-rows: repeat(3, auto);
- gap: 15rpx;
- max-width: 375rpx;
-}
-
-.spread-display.relationship_spread .card-slot:nth-child(1) { grid-area: 2 / 1; }
-.spread-display.relationship_spread .card-slot:nth-child(2) { grid-area: 2 / 3; }
-.spread-display.relationship_spread .card-slot:nth-child(3) { grid-area: 2 / 2; }
-.spread-display.relationship_spread .card-slot:nth-child(4) { grid-area: 1 / 2; }
-.spread-display.relationship_spread .card-slot:nth-child(5) { grid-area: 3 / 2; }
-
-/* 5张牌 - 缘分探索 */
-.spread-display.destiny_connection {
- display: grid;
- grid-template-columns: repeat(3, 110rpx);
- grid-template-rows: repeat(3, auto);
- gap: 15rpx;
- max-width: 375rpx;
-}
-
-.spread-display.destiny_connection .card-slot:nth-child(1) { grid-area: 1 / 2; }
-.spread-display.destiny_connection .card-slot:nth-child(2) { grid-area: 2 / 2; }
-.spread-display.destiny_connection .card-slot:nth-child(3) { grid-area: 2 / 1; }
-.spread-display.destiny_connection .card-slot:nth-child(4) { grid-area: 2 / 3; }
-.spread-display.destiny_connection .card-slot:nth-child(5) { grid-area: 3 / 2; }
-
-/* 5张牌 - 职场突破 */
-.spread-display.career_breakthrough {
- display: grid;
- grid-template-columns: repeat(3, 110rpx);
- grid-template-rows: repeat(3, auto);
- gap: 15rpx;
- max-width: 375rpx;
-}
-
-.spread-display.career_breakthrough .card-slot:nth-child(1) { grid-area: 2 / 2; }
-.spread-display.career_breakthrough .card-slot:nth-child(2) { grid-area: 1 / 2; }
-.spread-display.career_breakthrough .card-slot:nth-child(3) { grid-area: 2 / 3; }
-.spread-display.career_breakthrough .card-slot:nth-child(4) { grid-area: 3 / 2; }
-.spread-display.career_breakthrough .card-slot:nth-child(5) { grid-area: 2 / 1; }
-
-/* 5张牌 - 横排 */
-.spread-display.timeline_spread,
-.spread-display.diamond_spread {
- display: grid;
- grid-template-columns: repeat(5, 110rpx);
- gap: 12rpx;
- max-width: 600rpx;
-}
-
-/* 6张牌 - 2x3网格 */
-.spread-display.career_planning,
-.spread-display.wealth_analysis {
- display: grid;
- grid-template-columns: repeat(3, 110rpx);
- gap: 15rpx;
- max-width: 375rpx;
-}
-
-/* 7张牌 - 马蹄铁形 */
-.spread-display.horseshoe_spread {
- display: grid;
- grid-template-columns: repeat(3, 110rpx);
- grid-template-rows: repeat(4, auto);
- gap: 12rpx;
- max-width: 375rpx;
-}
-
-.spread-display.horseshoe_spread .card-slot:nth-child(1) { grid-area: 4 / 1; }
-.spread-display.horseshoe_spread .card-slot:nth-child(2) { grid-area: 3 / 1; }
-.spread-display.horseshoe_spread .card-slot:nth-child(3) { grid-area: 2 / 1; }
-.spread-display.horseshoe_spread .card-slot:nth-child(4) { grid-area: 1 / 2; }
-.spread-display.horseshoe_spread .card-slot:nth-child(5) { grid-area: 2 / 3; }
-.spread-display.horseshoe_spread .card-slot:nth-child(6) { grid-area: 3 / 3; }
-.spread-display.horseshoe_spread .card-slot:nth-child(7) { grid-area: 4 / 3; }
-
-/* 7张牌 - 灵性指引 */
-.spread-display.spiritual_guidance {
- display: grid;
- grid-template-columns: repeat(3, 110rpx);
- gap: 15rpx;
- max-width: 375rpx;
-}
-
-/* 10张牌 - 凯尔特十字 */
-.spread-display.celtic_cross {
- display: grid;
- grid-template-columns: repeat(6, 90rpx);
- grid-template-rows: repeat(4, auto);
- gap: 8rpx;
- max-width: 580rpx;
-}
-
-.spread-display.celtic_cross .card-slot { width: 90rpx; }
-.spread-display.celtic_cross .flip-scene { width: 90rpx; height: 150rpx; }
-
-.spread-display.celtic_cross .card-slot:nth-child(1) { grid-area: 2 / 3; }
-.spread-display.celtic_cross .card-slot:nth-child(2) { grid-area: 2 / 3; transform: rotate(90deg); z-index: 1; }
-.spread-display.celtic_cross .card-slot:nth-child(3) { grid-area: 3 / 3; }
-.spread-display.celtic_cross .card-slot:nth-child(4) { grid-area: 2 / 2; }
-.spread-display.celtic_cross .card-slot:nth-child(5) { grid-area: 1 / 3; }
-.spread-display.celtic_cross .card-slot:nth-child(6) { grid-area: 2 / 4; }
-.spread-display.celtic_cross .card-slot:nth-child(7) { grid-area: 1 / 5; }
-.spread-display.celtic_cross .card-slot:nth-child(8) { grid-area: 2 / 5; }
-.spread-display.celtic_cross .card-slot:nth-child(9) { grid-area: 3 / 5; }
-.spread-display.celtic_cross .card-slot:nth-child(10) { grid-area: 4 / 5; }
-
-/* 10张牌 - 生命之树 */
-.spread-display.tree_of_life {
- display: grid;
- grid-template-columns: repeat(3, 90rpx);
- grid-template-rows: repeat(5, auto);
- gap: 10rpx;
- max-width: 310rpx;
-}
-
-.spread-display.tree_of_life .card-slot { width: 90rpx; }
-.spread-display.tree_of_life .flip-scene { width: 90rpx; height: 150rpx; }
-
-.spread-display.tree_of_life .card-slot:nth-child(1) { grid-area: 1 / 2; }
-.spread-display.tree_of_life .card-slot:nth-child(2) { grid-area: 2 / 1; }
-.spread-display.tree_of_life .card-slot:nth-child(3) { grid-area: 2 / 3; }
-.spread-display.tree_of_life .card-slot:nth-child(4) { grid-area: 3 / 1; }
-.spread-display.tree_of_life .card-slot:nth-child(5) { grid-area: 3 / 3; }
-.spread-display.tree_of_life .card-slot:nth-child(6) { grid-area: 3 / 2; }
-.spread-display.tree_of_life .card-slot:nth-child(7) { grid-area: 4 / 1; }
-.spread-display.tree_of_life .card-slot:nth-child(8) { grid-area: 4 / 3; }
-.spread-display.tree_of_life .card-slot:nth-child(9) { grid-area: 4 / 2; }
-.spread-display.tree_of_life .card-slot:nth-child(10) { grid-area: 5 / 2; }
-
-/* 新增爱情牌阵布局 */
-
-/* 恋人金字塔 - 4张牌 */
-.spread-display.lover_pyramid {
- display: grid;
- grid-template-columns: repeat(3, 110rpx);
- grid-template-rows: repeat(2, auto);
- gap: 15rpx;
- max-width: 375rpx;
-}
-
-.spread-display.lover_pyramid .card-slot:nth-child(1) { grid-area: 2 / 2; }
-.spread-display.lover_pyramid .card-slot:nth-child(2) { grid-area: 2 / 1; }
-.spread-display.lover_pyramid .card-slot:nth-child(3) { grid-area: 2 / 3; }
-.spread-display.lover_pyramid .card-slot:nth-child(4) { grid-area: 1 / 2; }
-
-/* 新爱牌阵 - 3张牌对角线 */
-.spread-display.new_love {
- display: grid;
- grid-template-columns: repeat(3, 110rpx);
- grid-template-rows: repeat(3, auto);
- gap: 15rpx;
- max-width: 375rpx;
-}
-
-.spread-display.new_love .card-slot:nth-child(1) { grid-area: 1 / 1; }
-.spread-display.new_love .card-slot:nth-child(2) { grid-area: 2 / 2; }
-.spread-display.new_love .card-slot:nth-child(3) { grid-area: 3 / 3; }
-
-/* 人际关系牌阵 - 3张牌倒三角 */
-.spread-display.relationship_basic {
- display: grid;
- grid-template-columns: repeat(2, 110rpx);
- grid-template-rows: repeat(2, auto);
- gap: 15rpx;
- max-width: 245rpx;
-}
-
-.spread-display.relationship_basic .card-slot:nth-child(1) { grid-area: 1 / 1; }
-.spread-display.relationship_basic .card-slot:nth-child(2) { grid-area: 1 / 2; }
-.spread-display.relationship_basic .card-slot:nth-child(3) { grid-area: 2 / 1 / 2 / 3; justify-self: center; }
-
-/* 爱情树牌阵 - 5张牌树形 */
-.spread-display.love_tree_spread {
- display: grid;
- grid-template-columns: repeat(3, 110rpx);
- grid-template-rows: repeat(3, auto);
- gap: 15rpx;
- max-width: 375rpx;
-}
-
-.spread-display.love_tree_spread .card-slot:nth-child(1) { grid-area: 2 / 2; }
-.spread-display.love_tree_spread .card-slot:nth-child(2) { grid-area: 1 / 1; }
-.spread-display.love_tree_spread .card-slot:nth-child(3) { grid-area: 1 / 2; }
-.spread-display.love_tree_spread .card-slot:nth-child(4) { grid-area: 1 / 3; }
-.spread-display.love_tree_spread .card-slot:nth-child(5) { grid-area: 3 / 2; }
-
-/* 爱情大十字 - 5张牌十字形 */
-.spread-display.love_cross_spread {
- display: grid;
- grid-template-columns: repeat(3, 110rpx);
- grid-template-rows: repeat(3, auto);
- gap: 15rpx;
- max-width: 375rpx;
-}
-
-.spread-display.love_cross_spread .card-slot:nth-child(1) { grid-area: 2 / 1; }
-.spread-display.love_cross_spread .card-slot:nth-child(2) { grid-area: 2 / 3; }
-.spread-display.love_cross_spread .card-slot:nth-child(3) { grid-area: 1 / 2; }
-.spread-display.love_cross_spread .card-slot:nth-child(4) { grid-area: 2 / 2; }
-.spread-display.love_cross_spread .card-slot:nth-child(5) { grid-area: 3 / 2; }
-
-/* 真命天子牌阵 - 5张牌菱形 */
-.spread-display.mr_right {
- display: grid;
- grid-template-columns: repeat(3, 110rpx);
- grid-template-rows: repeat(3, auto);
- gap: 15rpx;
- max-width: 375rpx;
-}
-
-.spread-display.mr_right .card-slot:nth-child(1) { grid-area: 3 / 1; }
-.spread-display.mr_right .card-slot:nth-child(2) { grid-area: 2 / 1; }
-.spread-display.mr_right .card-slot:nth-child(3) { grid-area: 1 / 2; }
-.spread-display.mr_right .card-slot:nth-child(4) { grid-area: 2 / 3; }
-.spread-display.mr_right .card-slot:nth-child(5) { grid-area: 3 / 3; }
-
-/* 寻找对象牌阵 - 5张牌X形 */
-.spread-display.search_lover {
- display: grid;
- grid-template-columns: repeat(3, 110rpx);
- grid-template-rows: repeat(3, auto);
- gap: 15rpx;
- max-width: 375rpx;
-}
-
-.spread-display.search_lover .card-slot:nth-child(1) { grid-area: 2 / 2; }
-.spread-display.search_lover .card-slot:nth-child(2) { grid-area: 1 / 1; }
-.spread-display.search_lover .card-slot:nth-child(3) { grid-area: 1 / 3; }
-.spread-display.search_lover .card-slot:nth-child(4) { grid-area: 3 / 1; }
-.spread-display.search_lover .card-slot:nth-child(5) { grid-area: 3 / 3; }
-
-/* 灵感对应牌阵 - 6张牌2x3网格 */
-.spread-display.inspiration_correspondence {
- display: grid;
- grid-template-columns: repeat(3, 110rpx);
- gap: 15rpx;
- max-width: 375rpx;
-}
-
-/* 吉普赛牌阵 - 5张牌十字形 */
-.spread-display.gypsy_spread {
- display: grid;
- grid-template-columns: repeat(3, 110rpx);
- grid-template-rows: repeat(3, auto);
- gap: 15rpx;
- max-width: 375rpx;
-}
-
-.spread-display.gypsy_spread .card-slot:nth-child(1) { grid-area: 1 / 2; }
-.spread-display.gypsy_spread .card-slot:nth-child(2) { grid-area: 3 / 2; }
-.spread-display.gypsy_spread .card-slot:nth-child(3) { grid-area: 2 / 1; }
-.spread-display.gypsy_spread .card-slot:nth-child(4) { grid-area: 2 / 2; }
-.spread-display.gypsy_spread .card-slot:nth-child(5) { grid-area: 2 / 3; }
-
-/* 维纳斯牌阵 - 8张牌复杂菱形 */
-.spread-display.venus_spread {
- display: grid;
- grid-template-columns: repeat(3, 110rpx);
- grid-template-rows: repeat(4, auto);
- gap: 12rpx;
- max-width: 375rpx;
-}
-
-.spread-display.venus_spread .card-slot:nth-child(1) { grid-area: 2 / 1; }
-.spread-display.venus_spread .card-slot:nth-child(2) { grid-area: 2 / 3; }
-.spread-display.venus_spread .card-slot:nth-child(3) { grid-area: 1 / 2; }
-.spread-display.venus_spread .card-slot:nth-child(4) { grid-area: 2 / 2; }
-.spread-display.venus_spread .card-slot:nth-child(5) { grid-area: 3 / 2; }
-.spread-display.venus_spread .card-slot:nth-child(6) { grid-area: 4 / 2; }
-.spread-display.venus_spread .card-slot:nth-child(7) { grid-area: 3 / 1; }
-.spread-display.venus_spread .card-slot:nth-child(8) { grid-area: 3 / 3; }
-
-/* 恋人之树牌阵 - 7张牌树形对称 */
-.spread-display.lover_tree {
- display: grid;
- grid-template-columns: repeat(3, 110rpx);
- grid-template-rows: repeat(4, auto);
- gap: 12rpx;
- max-width: 375rpx;
-}
-
-.spread-display.lover_tree .card-slot:nth-child(1) { grid-area: 1 / 1; }
-.spread-display.lover_tree .card-slot:nth-child(2) { grid-area: 1 / 3; }
-.spread-display.lover_tree .card-slot:nth-child(3) { grid-area: 2 / 1; }
-.spread-display.lover_tree .card-slot:nth-child(4) { grid-area: 2 / 3; }
-.spread-display.lover_tree .card-slot:nth-child(5) { grid-area: 3 / 1; }
-.spread-display.lover_tree .card-slot:nth-child(6) { grid-area: 3 / 3; }
-.spread-display.lover_tree .card-slot:nth-child(7) { grid-area: 4 / 2; }
-
-/* 婚姻牌阵 - 7张牌六芒星形 */
-.spread-display.marriage_spread {
- display: grid;
- grid-template-columns: repeat(3, 110rpx);
- grid-template-rows: repeat(4, auto);
- gap: 12rpx;
- max-width: 375rpx;
-}
-
-.spread-display.marriage_spread .card-slot:nth-child(1) { grid-area: 4 / 2; }
-.spread-display.marriage_spread .card-slot:nth-child(2) { grid-area: 3 / 1; }
-.spread-display.marriage_spread .card-slot:nth-child(3) { grid-area: 3 / 3; }
-.spread-display.marriage_spread .card-slot:nth-child(4) { grid-area: 2 / 2; }
-.spread-display.marriage_spread .card-slot:nth-child(5) { grid-area: 1 / 1; }
-.spread-display.marriage_spread .card-slot:nth-child(6) { grid-area: 1 / 3; }
-.spread-display.marriage_spread .card-slot:nth-child(7) { grid-area: 1 / 2; }
-
-/* 新增事业牌阵布局 */
-
-/* 金三角牌阵 - 3张牌金字塔形 */
-.spread-display.golden_triangle {
- display: grid;
- grid-template-columns: repeat(2, 110rpx);
- grid-template-rows: repeat(2, auto);
- gap: 15rpx;
- max-width: 245rpx;
-}
-
-.spread-display.golden_triangle .card-slot:nth-child(1) { grid-area: 1 / 1 / 1 / 3; justify-self: center; }
-.spread-display.golden_triangle .card-slot:nth-child(2) { grid-area: 2 / 1; }
-.spread-display.golden_triangle .card-slot:nth-child(3) { grid-area: 2 / 2; }
-
-/* 成功之星牌阵 - 3张牌三角形 */
-.spread-display.success_star {
- display: grid;
- grid-template-columns: repeat(2, 110rpx);
- grid-template-rows: repeat(2, auto);
- gap: 15rpx;
- max-width: 245rpx;
-}
-
-.spread-display.success_star .card-slot:nth-child(1) { grid-area: 1 / 1; }
-.spread-display.success_star .card-slot:nth-child(2) { grid-area: 2 / 1; }
-.spread-display.success_star .card-slot:nth-child(3) { grid-area: 1 / 2 / 3 / 3; align-self: center; }
-
-/* 事业金字塔 - 4张牌金字塔形 */
-.spread-display.career_pyramid {
- display: grid;
- grid-template-columns: repeat(3, 110rpx);
- grid-template-rows: repeat(2, auto);
- gap: 15rpx;
- max-width: 375rpx;
-}
-
-.spread-display.career_pyramid .card-slot:nth-child(1) { grid-area: 2 / 2; }
-.spread-display.career_pyramid .card-slot:nth-child(2) { grid-area: 2 / 1; }
-.spread-display.career_pyramid .card-slot:nth-child(3) { grid-area: 2 / 3; }
-.spread-display.career_pyramid .card-slot:nth-child(4) { grid-area: 1 / 2; }
-
-/* 财富之树牌阵 - 5张牌十字树形 */
-.spread-display.wealth_tree {
- display: grid;
- grid-template-columns: repeat(3, 110rpx);
- grid-template-rows: repeat(3, auto);
- gap: 15rpx;
- max-width: 375rpx;
-}
-
-.spread-display.wealth_tree .card-slot:nth-child(1) { grid-area: 3 / 2; }
-.spread-display.wealth_tree .card-slot:nth-child(2) { grid-area: 2 / 2; }
-.spread-display.wealth_tree .card-slot:nth-child(3) { grid-area: 2 / 3; }
-.spread-display.wealth_tree .card-slot:nth-child(4) { grid-area: 2 / 1; }
-.spread-display.wealth_tree .card-slot:nth-child(5) { grid-area: 1 / 2; }
-
-/* X时机牌阵 - 5张牌X形 */
-.spread-display.x_opportunity {
- display: grid;
- grid-template-columns: repeat(3, 110rpx);
- grid-template-rows: repeat(3, auto);
- gap: 15rpx;
- max-width: 375rpx;
-}
-
-.spread-display.x_opportunity .card-slot:nth-child(1) { grid-area: 2 / 2; }
-.spread-display.x_opportunity .card-slot:nth-child(2) { grid-area: 1 / 1; }
-.spread-display.x_opportunity .card-slot:nth-child(3) { grid-area: 1 / 3; }
-.spread-display.x_opportunity .card-slot:nth-child(4) { grid-area: 3 / 1; }
-.spread-display.x_opportunity .card-slot:nth-child(5) { grid-area: 3 / 3; }
-
-/* 面试求职牌阵 - 5张牌十字形 */
-.spread-display.job_interview {
- display: grid;
- grid-template-columns: repeat(3, 110rpx);
- grid-template-rows: repeat(3, auto);
- gap: 15rpx;
- max-width: 375rpx;
-}
-
-.spread-display.job_interview .card-slot:nth-child(1) { grid-area: 3 / 2; }
-.spread-display.job_interview .card-slot:nth-child(2) { grid-area: 2 / 1; }
-.spread-display.job_interview .card-slot:nth-child(3) { grid-area: 2 / 3; }
-.spread-display.job_interview .card-slot:nth-child(4) { grid-area: 2 / 2; }
-.spread-display.job_interview .card-slot:nth-child(5) { grid-area: 1 / 2; }
-
-/* 工作问题牌阵 - 6张牌六边形 */
-.spread-display.work_problems {
- display: grid;
- grid-template-columns: repeat(3, 110rpx);
- grid-template-rows: repeat(3, auto);
- gap: 12rpx;
- max-width: 375rpx;
-}
-
-.spread-display.work_problems .card-slot:nth-child(1) { grid-area: 2 / 2; }
-.spread-display.work_problems .card-slot:nth-child(2) { grid-area: 1 / 1; }
-.spread-display.work_problems .card-slot:nth-child(3) { grid-area: 2 / 1; }
-.spread-display.work_problems .card-slot:nth-child(4) { grid-area: 2 / 3; }
-.spread-display.work_problems .card-slot:nth-child(5) { grid-area: 1 / 3; }
-.spread-display.work_problems .card-slot:nth-child(6) { grid-area: 3 / 2; }
-
-/* 财富波浪牌阵 - 6张牌波浪形 */
-.spread-display.turbulent_finances {
- display: grid;
- grid-template-columns: repeat(3, 110rpx);
- grid-template-rows: repeat(3, auto);
- gap: 12rpx;
- max-width: 375rpx;
-}
-
-.spread-display.turbulent_finances .card-slot:nth-child(1) { grid-area: 3 / 1; }
-.spread-display.turbulent_finances .card-slot:nth-child(2) { grid-area: 2 / 1; }
-.spread-display.turbulent_finances .card-slot:nth-child(3) { grid-area: 2 / 2; }
-.spread-display.turbulent_finances .card-slot:nth-child(4) { grid-area: 2 / 3; }
-.spread-display.turbulent_finances .card-slot:nth-child(5) { grid-area: 3 / 3; }
-.spread-display.turbulent_finances .card-slot:nth-child(6) { grid-area: 1 / 2; }
-
-/* 期望的工作 - 6张牌对称形 */
-.spread-display.desired_job {
- display: grid;
- grid-template-columns: repeat(3, 110rpx);
- grid-template-rows: repeat(3, auto);
- gap: 12rpx;
- max-width: 375rpx;
-}
-
-.spread-display.desired_job .card-slot:nth-child(1) { grid-area: 1 / 2; }
-.spread-display.desired_job .card-slot:nth-child(2) { grid-area: 2 / 1; }
-.spread-display.desired_job .card-slot:nth-child(3) { grid-area: 2 / 3; }
-.spread-display.desired_job .card-slot:nth-child(4) { grid-area: 3 / 1; }
-.spread-display.desired_job .card-slot:nth-child(5) { grid-area: 3 / 2; }
-.spread-display.desired_job .card-slot:nth-child(6) { grid-area: 3 / 3; }
-
-/* 新增决策牌阵布局 */
-
-/* 二个选择牌阵 - 3张牌倒三角 */
-.spread-display.two_options {
- display: grid;
- grid-template-columns: repeat(2, 110rpx);
- grid-template-rows: repeat(2, auto);
- gap: 15rpx;
- max-width: 245rpx;
-}
-
-.spread-display.two_options .card-slot:nth-child(1) { grid-area: 1 / 1; }
-.spread-display.two_options .card-slot:nth-child(2) { grid-area: 1 / 2; }
-.spread-display.two_options .card-slot:nth-child(3) { grid-area: 2 / 1 / 2 / 3; justify-self: center; }
-
-/* 三个选择牌阵 - 3张牌正三角 */
-.spread-display.three_options {
- display: grid;
- grid-template-columns: repeat(2, 110rpx);
- grid-template-rows: repeat(2, auto);
- gap: 15rpx;
- max-width: 245rpx;
-}
-
-.spread-display.three_options .card-slot:nth-child(1) { grid-area: 1 / 1 / 1 / 3; justify-self: center; }
-.spread-display.three_options .card-slot:nth-child(2) { grid-area: 2 / 1; }
-.spread-display.three_options .card-slot:nth-child(3) { grid-area: 2 / 2; }
-
-/* 每日树牌阵 - 4张牌十字形 */
-.spread-display.daily_tree {
- display: grid;
- grid-template-columns: repeat(3, 110rpx);
- grid-template-rows: repeat(3, auto);
- gap: 15rpx;
- max-width: 375rpx;
-}
-
-.spread-display.daily_tree .card-slot:nth-child(1) { grid-area: 3 / 2; }
-.spread-display.daily_tree .card-slot:nth-child(2) { grid-area: 2 / 1; }
-.spread-display.daily_tree .card-slot:nth-child(3) { grid-area: 1 / 2; }
-.spread-display.daily_tree .card-slot:nth-child(4) { grid-area: 2 / 3; }
-
-/* 二选一牌阵 - 5张牌菱形 */
-.spread-display.weigh_two {
- display: grid;
- grid-template-columns: repeat(3, 110rpx);
- grid-template-rows: repeat(3, auto);
- gap: 15rpx;
- max-width: 375rpx;
-}
-
-.spread-display.weigh_two .card-slot:nth-child(1) { grid-area: 3 / 2; }
-.spread-display.weigh_two .card-slot:nth-child(2) { grid-area: 2 / 1; }
-.spread-display.weigh_two .card-slot:nth-child(3) { grid-area: 2 / 3; }
-.spread-display.weigh_two .card-slot:nth-child(4) { grid-area: 1 / 1; }
-.spread-display.weigh_two .card-slot:nth-child(5) { grid-area: 1 / 3; }
-
-/* 比较选择牌阵 - 6张牌3+3排列 */
-.spread-display.comparing_choices {
- display: grid;
- grid-template-columns: repeat(3, 110rpx);
- gap: 12rpx;
- max-width: 375rpx;
-}
-
-/* 三选一牌阵 - 7张牌复杂对称形 */
-.spread-display.weigh_three {
- display: grid;
- grid-template-columns: repeat(3, 110rpx);
- grid-template-rows: repeat(3, auto);
- gap: 12rpx;
- max-width: 375rpx;
-}
-
-.spread-display.weigh_three .card-slot:nth-child(1) { grid-area: 2 / 1; }
-.spread-display.weigh_three .card-slot:nth-child(2) { grid-area: 1 / 2; }
-.spread-display.weigh_three .card-slot:nth-child(3) { grid-area: 2 / 2; }
-.spread-display.weigh_three .card-slot:nth-child(4) { grid-area: 3 / 2; }
-.spread-display.weigh_three .card-slot:nth-child(5) { grid-area: 1 / 3; }
-.spread-display.weigh_three .card-slot:nth-child(6) { grid-area: 2 / 3; }
-.spread-display.weigh_three .card-slot:nth-child(7) { grid-area: 3 / 3; }
-
-/* 新增深度探索牌阵布局 */
-
-/* 身心灵牌阵 - 4张牌倒T形 */
-.spread-display.mind_body_spirit {
- display: grid;
- grid-template-columns: repeat(3, 110rpx);
- grid-template-rows: repeat(2, auto);
- gap: 15rpx;
- max-width: 375rpx;
-}
-
-.spread-display.mind_body_spirit .card-slot:nth-child(1) { grid-area: 2 / 1; }
-.spread-display.mind_body_spirit .card-slot:nth-child(2) { grid-area: 2 / 2; }
-.spread-display.mind_body_spirit .card-slot:nth-child(3) { grid-area: 2 / 3; }
-.spread-display.mind_body_spirit .card-slot:nth-child(4) { grid-area: 1 / 2; }
-
-/* 四元素牌阵 - 4张牌2x2方形 */
-.spread-display.four_elements {
- display: grid;
- grid-template-columns: repeat(2, 110rpx);
- grid-template-rows: repeat(2, auto);
- gap: 15rpx;
- max-width: 245rpx;
-}
-
-.spread-display.four_elements .card-slot:nth-child(1) { grid-area: 1 / 1; }
-.spread-display.four_elements .card-slot:nth-child(2) { grid-area: 2 / 1; }
-.spread-display.four_elements .card-slot:nth-child(3) { grid-area: 2 / 2; }
-.spread-display.four_elements .card-slot:nth-child(4) { grid-area: 1 / 2; }
-
-/* 自我探索牌阵 - 4张牌箭头三角形 */
-.spread-display.self_discovery {
- display: grid;
- grid-template-columns: repeat(3, 110rpx);
- grid-template-rows: repeat(3, auto);
- gap: 15rpx;
- max-width: 375rpx;
-}
-
-.spread-display.self_discovery .card-slot:nth-child(1) { grid-area: 2 / 2; }
-.spread-display.self_discovery .card-slot:nth-child(2) { grid-area: 1 / 2; }
-.spread-display.self_discovery .card-slot:nth-child(3) { grid-area: 3 / 1; }
-.spread-display.self_discovery .card-slot:nth-child(4) { grid-area: 3 / 3; }
-
-/* 认识你自己 - 5张牌十字形 */
-.spread-display.know_yourself {
- display: grid;
- grid-template-columns: repeat(3, 110rpx);
- grid-template-rows: repeat(3, auto);
- gap: 15rpx;
- max-width: 375rpx;
-}
-
-.spread-display.know_yourself .card-slot:nth-child(1) { grid-area: 2 / 2; }
-.spread-display.know_yourself .card-slot:nth-child(2) { grid-area: 1 / 2; }
-.spread-display.know_yourself .card-slot:nth-child(3) { grid-area: 2 / 3; }
-.spread-display.know_yourself .card-slot:nth-child(4) { grid-area: 3 / 2; }
-.spread-display.know_yourself .card-slot:nth-child(5) { grid-area: 2 / 1; }
-
-/* 你的突破牌阵 - 5张牌五角形 */
-.spread-display.your_breakthrough {
- display: grid;
- grid-template-columns: repeat(3, 110rpx);
- grid-template-rows: repeat(3, auto);
- gap: 12rpx;
- max-width: 375rpx;
-}
-
-.spread-display.your_breakthrough .card-slot:nth-child(1) { grid-area: 2 / 1; }
-.spread-display.your_breakthrough .card-slot:nth-child(2) { grid-area: 2 / 3; }
-.spread-display.your_breakthrough .card-slot:nth-child(3) { grid-area: 1 / 2; }
-.spread-display.your_breakthrough .card-slot:nth-child(4) { grid-area: 3 / 1; }
-.spread-display.your_breakthrough .card-slot:nth-child(5) { grid-area: 3 / 3; }
-
-/* 元素十字牌阵 - 6张牌十字形 */
-.spread-display.elemental_cross {
- display: grid;
- grid-template-columns: repeat(3, 110rpx);
- grid-template-rows: repeat(4, auto);
- gap: 12rpx;
- max-width: 375rpx;
-}
-
-.spread-display.elemental_cross .card-slot:nth-child(1) { grid-area: 2 / 2; }
-.spread-display.elemental_cross .card-slot:nth-child(2) { grid-area: 2 / 3; }
-.spread-display.elemental_cross .card-slot:nth-child(3) { grid-area: 2 / 1; }
-.spread-display.elemental_cross .card-slot:nth-child(4) { grid-area: 1 / 2; }
-.spread-display.elemental_cross .card-slot:nth-child(5) { grid-area: 3 / 2; }
-.spread-display.elemental_cross .card-slot:nth-child(6) { grid-area: 4 / 2; }
-
-/* 车轮牌阵 - 7张牌圆形轮状 */
-.spread-display.wheel_spread {
- display: grid;
- grid-template-columns: repeat(3, 110rpx);
- grid-template-rows: repeat(4, auto);
- gap: 10rpx;
- max-width: 375rpx;
-}
-
-.spread-display.wheel_spread .card-slot:nth-child(1) { grid-area: 2 / 2; }
-.spread-display.wheel_spread .card-slot:nth-child(2) { grid-area: 1 / 1; }
-.spread-display.wheel_spread .card-slot:nth-child(3) { grid-area: 2 / 1; }
-.spread-display.wheel_spread .card-slot:nth-child(4) { grid-area: 3 / 1; }
-.spread-display.wheel_spread .card-slot:nth-child(5) { grid-area: 1 / 3; }
-.spread-display.wheel_spread .card-slot:nth-child(6) { grid-area: 2 / 3; }
-.spread-display.wheel_spread .card-slot:nth-child(7) { grid-area: 3 / 3; }
-
-/* 七行星牌阵 - 7张牌星形排列 */
-.spread-display.seven_planets {
- display: grid;
- grid-template-columns: repeat(3, 110rpx);
- grid-template-rows: repeat(4, auto);
- gap: 10rpx;
- max-width: 375rpx;
-}
-
-.spread-display.seven_planets .card-slot:nth-child(1) { grid-area: 4 / 1; }
-.spread-display.seven_planets .card-slot:nth-child(2) { grid-area: 3 / 1; }
-.spread-display.seven_planets .card-slot:nth-child(3) { grid-area: 2 / 1; }
-.spread-display.seven_planets .card-slot:nth-child(4) { grid-area: 1 / 2; }
-.spread-display.seven_planets .card-slot:nth-child(5) { grid-area: 2 / 3; }
-.spread-display.seven_planets .card-slot:nth-child(6) { grid-area: 3 / 3; }
-.spread-display.seven_planets .card-slot:nth-child(7) { grid-area: 4 / 3; }
-
-/* 梦镜牌阵 - 7张牌金字塔形 */
-.spread-display.dream_mirror {
- display: grid;
- grid-template-columns: repeat(3, 110rpx);
- grid-template-rows: repeat(3, auto);
- gap: 10rpx;
- max-width: 375rpx;
-}
-
-.spread-display.dream_mirror .card-slot:nth-child(1) { grid-area: 2 / 1; }
-.spread-display.dream_mirror .card-slot:nth-child(2) { grid-area: 3 / 1; }
-.spread-display.dream_mirror .card-slot:nth-child(3) { grid-area: 2 / 2; }
-.spread-display.dream_mirror .card-slot:nth-child(4) { grid-area: 3 / 2; }
-.spread-display.dream_mirror .card-slot:nth-child(5) { grid-area: 2 / 3; }
-.spread-display.dream_mirror .card-slot:nth-child(6) { grid-area: 3 / 3; }
-.spread-display.dream_mirror .card-slot:nth-child(7) { grid-area: 1 / 2; }
-
-
-
-
-
-.card-slot {
- display: flex;
- flex-direction: column;
- align-items: center;
- width: 110rpx;
- margin-bottom: 8rpx;
-}
-
-.pos-name {
- font-size: 20rpx;
- color: #8a8a9d;
- margin-bottom: 8rpx;
- text-align: center;
- height: 40rpx;
- display: flex;
- align-items: center;
- line-height: 1.2;
-}
-
-.flip-scene {
- width: 110rpx;
- height: 185rpx;
- perspective: 1000rpx;
-}
-
-.flip-card {
- position: relative;
- width: 100%;
- height: 100%;
- transition: transform 0.6s;
- transform-style: preserve-3d;
-}
-
-.flip-card.flipped {
- transform: rotateY(180deg);
-}
-
-.card-face {
- position: absolute;
- width: 100%;
- height: 100%;
- backface-visibility: hidden;
- border-radius: 12rpx;
- overflow: hidden;
-}
-
-.face-back { background: #2a2a3e; }
-.face-front { background: #1a1a2e; transform: rotateY(180deg); }
-
-.card-image { width: 100%; height: 100%; }
-.card-image.reversed { transform: rotate(180deg); }
-
-.card-name-sm {
- margin-top: 12rpx;
- font-size: 18rpx;
- color: #c9a0dc;
- text-align: center;
-}
-
-/* 5. 深度解读区域 */
-.interpretation-area {
- margin-top: 60rpx;
- background: rgba(255, 255, 255, 0.03);
- border-radius: 24rpx;
- padding: 40rpx;
-}
-
-.theme-box {
- text-align: center;
- margin-bottom: 60rpx;
- background: rgba(201, 160, 220, 0.08);
- padding: 30rpx;
- border-radius: 16rpx;
-}
-
-.label {
- display: block;
- font-size: 20rpx;
- color: #c9a0dc;
- text-transform: uppercase;
- letter-spacing: 4rpx;
- margin-bottom: 16rpx;
- opacity: 0.6;
-}
-
-.theme-box .content {
- font-size: 34rpx;
- font-weight: 500;
- color: #ffffff;
- line-height: 1.4;
-}
-
-.info-grid {
- display: grid;
- grid-template-columns: 1fr 1fr;
- gap: 30rpx;
- margin-bottom: 60rpx;
-}
-
-.info-item .content {
- font-size: 26rpx;
- line-height: 1.6;
- color: #b0b0cf;
-}
-
-.pos-meanings {
- border-top: 1px solid rgba(255, 255, 255, 0.05);
- padding-top: 40rpx;
- margin-bottom: 60rpx;
-}
-
-.pos-meaning-item {
- margin-bottom: 40rpx;
-}
-
-.pos-title {
- font-size: 24rpx;
- color: #c9a0dc;
- display: block;
- margin-bottom: 12rpx;
- font-weight: 500;
-}
-
-.pos-text {
- font-size: 26rpx;
- color: #b0b0cf;
- line-height: 1.8;
-}
-
-.advice-box {
- background: linear-gradient(135deg, rgba(201, 160, 220, 0.1), rgba(201, 160, 220, 0.03));
- padding: 40rpx;
- border-radius: 20rpx;
- border-left: 4rpx solid #c9a0dc;
-}
-
-.advice-box .content {
- font-size: 28rpx;
- color: #ffffff;
- font-weight: 500;
- line-height: 1.6;
-}
-
-.reset-btn {
- margin-top: 80rpx;
- background: transparent;
- color: #c9a0dc;
- border: 1px solid rgba(201, 160, 220, 0.4);
- font-size: 24rpx;
- border-radius: 40rpx;
- width: 240rpx;
-}
-
-/* AI Loading */
-.loading-ai {
- display: flex;
- flex-direction: column;
- align-items: center;
- padding: 80rpx 0;
- color: #c9a0dc;
- font-size: 26rpx;
-}
-
-.loading-dot {
- font-size: 60rpx;
- margin-bottom: 30rpx;
- animation: flash 1.5s infinite;
-}
-
-@keyframes flash {
- 0%, 100% { opacity: 0.3; transform: scale(0.9); }
- 50% { opacity: 1; transform: scale(1.1); }
-}
-
-/* 整体趋势故事框 */
-.story-box {
- background: linear-gradient(135deg, rgba(201, 160, 220, 0.1), rgba(138, 138, 157, 0.05));
- padding: 30rpx;
- border-radius: 16rpx;
- margin-bottom: 30rpx;
- border-left: 4rpx solid #c9a0dc;
-}
-
-.story-box .label {
- display: block;
- font-size: 24rpx;
- color: #c9a0dc;
- margin-bottom: 15rpx;
- font-weight: 600;
- letter-spacing: 2rpx;
-}
-
-.story-box .content {
- font-size: 28rpx;
- color: #e0e0e0;
- line-height: 1.8;
-}
-
-/* 提问区域 - 沉浸式仪式感版本 */
-.asking-area {
- flex: 1;
- display: flex;
- flex-direction: column;
- align-items: center;
- padding: 80rpx 40rpx 60rpx;
- background: linear-gradient(180deg, #0f0f1b 0%, #1a1a2e 50%, #16213e 100%);
- position: relative;
-}
-
-/* 顶部引导语 */
-.asking-title {
- font-size: 24rpx;
- color: rgba(201, 160, 220, 0.6);
- letter-spacing: 4rpx;
- text-align: center;
- margin-bottom: 60rpx;
- font-weight: 300;
-}
-
-/* 中央塔罗卡片式输入区 */
-.input-card {
- width: 100%;
- background: rgba(201, 160, 220, 0.08);
- backdrop-filter: blur(10px);
- border: 2px solid rgba(201, 160, 220, 0.3);
- border-radius: 40rpx;
- padding: 40rpx;
- margin-bottom: 50rpx;
- position: relative;
- box-shadow: 0 0 40rpx rgba(201, 160, 220, 0.2);
- transition: all 0.4s ease;
-}
-
-.input-card:focus-within {
- border-color: rgba(201, 160, 220, 0.6);
- box-shadow: 0 0 60rpx rgba(201, 160, 220, 0.4);
- background: rgba(201, 160, 220, 0.12);
-}
-
-.question-input {
- width: 100%;
- height: 280rpx;
- font-size: 32rpx;
- color: #ffffff;
- line-height: 1.6;
- background: transparent;
-}
-
-.placeholder-style {
- color: rgba(255, 255, 255, 0.25);
- font-size: 28rpx;
-}
-
-.char-count {
- position: absolute;
- bottom: 30rpx;
- right: 40rpx;
- font-size: 20rpx;
- color: rgba(138, 138, 157, 0.5);
-}
-
-/* 质量评分指示器 - 精简版 */
-.quality-indicator {
- display: flex;
- align-items: center;
- justify-content: center;
- margin-top: 24rpx;
- padding: 12rpx 20rpx;
- background: rgba(139, 233, 253, 0.08);
- border-radius: 20rpx;
- border: 1px solid rgba(139, 233, 253, 0.2);
-}
-
-.quality-icon {
- font-size: 32rpx;
- margin-right: 8rpx;
-}
-
-.quality-text {
- font-size: 24rpx;
- color: #8be9fd;
- font-weight: 400;
- opacity: 0.8;
-}
-
-/* 温和分割线 */
-.divider {
- width: 200rpx;
- height: 1px;
- background: linear-gradient(90deg, transparent, rgba(201, 160, 220, 0.3), transparent);
- margin: 30rpx 0 40rpx;
-}
-
-/* 塔罗低语区域 */
-.whispers-area {
- width: 100%;
- margin-bottom: 60rpx;
-}
-
-.whispers-title {
- display: block;
- font-size: 24rpx;
- color: rgba(201, 160, 220, 0.7);
- text-align: center;
- margin-bottom: 30rpx;
- letter-spacing: 3rpx;
- font-weight: 300;
-}
-
-.whispers-scroll {
- width: 100%;
- white-space: nowrap;
-}
-
-/* 塔罗低语卡片 */
-.whisper-card {
- display: inline-flex;
- align-items: center;
- justify-content: center;
- background: rgba(255, 255, 255, 0.05);
- border: 1px solid rgba(201, 160, 220, 0.3);
- border-radius: 20rpx;
- padding: 28rpx 32rpx;
- margin-right: 20rpx;
- min-width: 260rpx;
- max-width: 340rpx;
- box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.3);
- transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
- position: relative;
- overflow: hidden;
-}
-
-.whisper-card::before {
- content: '';
- position: absolute;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- background: radial-gradient(circle at center, rgba(201, 160, 220, 0.1), transparent);
- opacity: 0;
- transition: opacity 0.3s ease;
-}
-
-.whisper-card:active {
- transform: scale(1.05);
-}
-
-.whisper-card.selected {
- background: rgba(201, 160, 220, 0.15);
- border-color: rgba(201, 160, 220, 0.6);
- box-shadow: 0 0 30rpx rgba(201, 160, 220, 0.4);
-}
-
-.whisper-card.selected::before {
- opacity: 1;
-}
-
-.whisper-text {
- font-size: 28rpx;
- color: #e0e0e0;
- line-height: 1.5;
- text-align: center;
- word-wrap: break-word;
- white-space: normal;
- position: relative;
- z-index: 1;
-}
-
-.whisper-card.selected .whisper-text {
- color: #ffffff;
- font-weight: 500;
-}
-
-/* 开启塔罗指引按钮 */
-.start-btn {
- background: linear-gradient(135deg, #c9a0dc 0%, #8b7ba8 100%);
- color: #ffffff;
- font-size: 32rpx;
- font-weight: 600;
- padding: 28rpx 120rpx;
- border-radius: 50rpx;
- box-shadow: 0 8rpx 30rpx rgba(201, 160, 220, 0.4);
- transition: all 0.2s ease;
- border: none;
- letter-spacing: 2rpx;
-}
-
-.start-btn::after {
- border: none;
-}
-
-.start-btn:active {
- transform: scale(0.95);
- box-shadow: 0 4rpx 20rpx rgba(201, 160, 220, 0.3);
-}
-
+page {
+ background-color: #0f0f1b;
+ color: #e0e0e0;
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
+}
+
+.container {
+ min-height: 100vh;
+ background-color: #0f0f1b;
+ padding: 40rpx 30rpx 100rpx;
+ box-sizing: border-box;
+ color: #e0e0e0;
+ display: flex;
+ flex-direction: column;
+ position: relative;
+}
+
+/* 自定义返回按钮样式 */
+.nav-back {
+ position: absolute;
+ top: 40rpx;
+ left: 30rpx;
+ display: flex;
+ align-items: center;
+ z-index: 100;
+ padding: 10rpx 20rpx;
+ border-radius: 30rpx;
+ background: rgba(255, 255, 255, 0.05);
+}
+
+.back-icon {
+ font-size: 32rpx;
+ margin-right: 8rpx;
+ color: #c9a0dc;
+}
+
+.back-text {
+ font-size: 26rpx;
+ color: #c9a0dc;
+ letter-spacing: 2rpx;
+}
+
+/* 标题通用样式 */
+.title-area {
+ text-align: center;
+ margin-top: 40rpx;
+ margin-bottom: 60rpx;
+}
+
+.app-title {
+ font-size: 44rpx;
+ font-weight: 600;
+ color: #c9a0dc;
+ letter-spacing: 4rpx;
+ display: block;
+ margin-bottom: 16rpx;
+}
+
+.instruction {
+ font-size: 26rpx;
+ color: #8a8a9d;
+ letter-spacing: 1rpx;
+}
+
+/* 1. 牌阵选择 - 卡片式V2 */
+
+/* 顶部标题区域 */
+.spread-header {
+ text-align: center;
+ padding: 60rpx 0 40rpx;
+}
+
+.spread-title {
+ display: block;
+ font-size: 36rpx;
+ color: #c9a0dc;
+ font-weight: 500;
+ margin-bottom: 12rpx;
+ letter-spacing: 2rpx;
+}
+
+.spread-subtitle {
+ display: block;
+ font-size: 24rpx;
+ color: rgba(201, 160, 220, 0.7);
+ letter-spacing: 2rpx;
+ font-weight: 300;
+}
+
+/* 标签筛选条 */
+.tags-area {
+ padding: 0 30rpx 30rpx;
+}
+
+.tags-scroll {
+ white-space: nowrap;
+}
+
+.tag-item {
+ display: inline-block;
+ padding: 12rpx 28rpx;
+ margin-right: 16rpx;
+ background: rgba(255, 255, 255, 0.05);
+ border: 1px solid rgba(201, 160, 220, 0.3);
+ border-radius: 30rpx;
+ font-size: 26rpx;
+ color: rgba(201, 160, 220, 0.8);
+ transition: all 0.3s ease;
+}
+
+.tag-item.active {
+ background: rgba(201, 160, 220, 0.2);
+ border-color: rgba(201, 160, 220, 0.6);
+ color: #ffffff;
+ transform: scale(1.05);
+}
+
+/* 两列卡片网格 */
+.spread-grid {
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ gap: 20rpx;
+ padding: 0 30rpx 40rpx;
+}
+
+.spread-card {
+ background: rgba(255, 255, 255, 0.05);
+ border: 1px solid rgba(201, 160, 220, 0.3);
+ border-radius: 20rpx;
+ padding: 30rpx 24rpx;
+ position: relative;
+ box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.3);
+ transition: all 0.3s ease;
+ min-height: 240rpx;
+ display: flex;
+ flex-direction: column;
+}
+
+.spread-card:active {
+ transform: translateY(-4rpx);
+ box-shadow: 0 8rpx 30rpx rgba(201, 160, 220, 0.3);
+ border-color: rgba(201, 160, 220, 0.5);
+}
+
+.card-badge {
+ position: absolute;
+ top: 12rpx;
+ right: 12rpx;
+ background: rgba(201, 160, 220, 0.3);
+ padding: 4rpx 12rpx;
+ border-radius: 8rpx;
+ font-size: 20rpx;
+ color: #c9a0dc;
+}
+
+.card-name {
+ display: block;
+ font-size: 30rpx;
+ color: #ffffff;
+ font-weight: 500;
+ margin-bottom: 12rpx;
+ padding-right: 60rpx;
+}
+
+.card-desc {
+ display: block;
+ font-size: 22rpx;
+ color: rgba(255, 255, 255, 0.6);
+ line-height: 1.5;
+ margin-bottom: 20rpx;
+ flex: 1;
+}
+
+.card-footer {
+ display: flex;
+ justify-content: space-between;
+ font-size: 20rpx;
+ color: rgba(201, 160, 220, 0.7);
+ padding-top: 16rpx;
+ border-top: 1px solid rgba(255, 255, 255, 0.05);
+}
+
+.card-count {
+ opacity: 0.8;
+}
+
+.card-cost {
+ font-weight: 500;
+}
+
+/* 2. 洗牌仪式感 */
+.ritual-area {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+}
+
+.shuffling-container {
+ position: relative;
+ width: 200rpx;
+ height: 300rpx;
+ margin-bottom: 80rpx;
+}
+
+.shuffling-card {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ border-radius: 12rpx;
+ box-shadow: 0 4rpx 12rpx rgba(0,0,0,0.5);
+ animation: shuffle 1s infinite alternate ease-in-out;
+}
+
+@keyframes shuffle {
+ from { transform: translateX(-40rpx) rotate(-5deg); }
+ to { transform: translateX(40rpx) rotate(5deg); }
+}
+
+.ritual-hint {
+ font-size: 28rpx;
+ color: #c9a0dc;
+ opacity: 0.8;
+ animation: breathe 2s infinite ease-in-out;
+}
+
+@keyframes breathe {
+ 0%, 100% { opacity: 0.4; }
+ 50% { opacity: 1; }
+}
+
+/* 3. 抽牌区域 (槽位 + 扇形) */
+.drawing-area {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ padding-top: 40rpx;
+}
+
+.slots-container {
+ display: flex;
+ flex-wrap: wrap; /* 允许换行 */
+ justify-content: center;
+ gap: 20rpx; /* 保持20rpx间距,与计算一致 */
+ min-height: 240rpx; /* 改为最小高度 */
+ max-height: 480rpx; /* 最多两排的高度 */
+ margin-bottom: 60rpx;
+ width: 100%;
+ padding: 0 30rpx; /* 增加左右padding确保居中 */
+}
+
+.slot-item {
+ width: 100rpx; /* 与WXS计算的宽度一致 */
+ height: 160rpx; /* 与WXS计算的高度一致 */
+ position: relative;
+ flex-shrink: 0; /* 防止收缩 */
+}
+
+.slot-placeholder {
+ width: 100%;
+ height: 100%;
+ border: 2rpx dashed rgba(201, 160, 220, 0.3);
+ border-radius: 12rpx;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background: rgba(255, 255, 255, 0.02);
+}
+
+.slot-num {
+ font-size: 40rpx;
+ color: rgba(201, 160, 220, 0.2);
+ font-family: serif;
+}
+
+.slot-card-wrapper {
+ width: 100%;
+ height: 100%;
+ animation: flyInSlot 0.4s cubic-bezier(0.34, 1.56, 0.64, 1) both;
+}
+
+.slot-card-back {
+ width: 100%;
+ height: 100%;
+ border-radius: 12rpx;
+ box-shadow: 0 8rpx 20rpx rgba(0,0,0,0.6);
+ border: 1px solid rgba(255, 255, 255, 0.1);
+}
+
+@keyframes flyInSlot {
+ from {
+ transform: translateY(400rpx) scale(0.8) rotate(10deg);
+ opacity: 0;
+ }
+ to {
+ transform: translateY(0) scale(1) rotate(0);
+ opacity: 1;
+ }
+}
+
+.fan-deck {
+ position: relative;
+ height: 380rpx;
+ width: 100%;
+ margin-top: 20rpx;
+ perspective: 1000px;
+ overflow: visible; /* 允许卡牌飞出容器 */
+}
+
+.fan-card {
+ position: absolute;
+ left: 50%;
+ bottom: 0;
+ width: 150rpx;
+ height: 260rpx;
+ margin-left: -75rpx;
+ transform-origin: bottom center;
+ transition: transform 0.6s cubic-bezier(0.19, 1, 0.22, 1);
+ z-index: 10;
+}
+
+.card-back-sm {
+ width: 100%;
+ height: 100%;
+ border-radius: 10rpx;
+ box-shadow: 0 4rpx 12rpx rgba(0,0,0,0.5);
+ border: 1px solid rgba(255, 255, 255, 0.05);
+}
+
+.fan-card.is-selected {
+ z-index: 100;
+ pointer-events: auto; /* 允许点击已抽出的牌返回 */
+}
+
+.draw-count {
+ text-align: center;
+ font-size: 36rpx;
+ color: #c9a0dc;
+ margin-top: 60rpx;
+}
+
+.confirm-draw-btn {
+ margin: 40rpx auto;
+ background: #c9a0dc;
+ color: #1a1a2e;
+ border-radius: 40rpx;
+ font-weight: 600;
+ width: 300rpx;
+}
+
+/* 4. 翻牌结果展示 */
+.result-area {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: flex-start;
+ padding: 30rpx 20rpx;
+ overflow-y: auto;
+}
+
+.spread-display {
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: center;
+ align-items: flex-start;
+ gap: 12rpx;
+ padding: 20rpx 0;
+ margin: 0 auto;
+}
+
+/* 牌阵专属布局 - 传统排列方式 */
+
+/* 1张牌 - 居中 */
+.spread-display.one_card_guidance {
+ max-width: 130rpx;
+}
+
+/* 3张牌 - 横排 */
+.spread-display.three_time_flow,
+.spread-display.three_problem_solution,
+.spread-display.love_spark {
+ display: grid;
+ grid-template-columns: repeat(3, 110rpx);
+ gap: 15rpx;
+ max-width: 375rpx;
+}
+
+/* 4张牌 - 2x2网格 */
+.spread-display.two_choice_decision,
+.spread-display.relationship_healing {
+ display: grid;
+ grid-template-columns: repeat(2, 110rpx);
+ gap: 15rpx;
+ max-width: 245rpx;
+}
+
+/* 5张牌 - 十字形 (现状分析) */
+.spread-display.five_situation_analysis {
+ display: grid;
+ grid-template-columns: repeat(3, 110rpx);
+ grid-template-rows: repeat(3, auto);
+ gap: 15rpx;
+ max-width: 375rpx;
+}
+
+.spread-display.five_situation_analysis .card-slot:nth-child(1) { grid-area: 2 / 2; }
+.spread-display.five_situation_analysis .card-slot:nth-child(2) { grid-area: 1 / 2; }
+.spread-display.five_situation_analysis .card-slot:nth-child(3) { grid-area: 3 / 2; }
+.spread-display.five_situation_analysis .card-slot:nth-child(4) { grid-area: 2 / 1; }
+.spread-display.five_situation_analysis .card-slot:nth-child(5) { grid-area: 2 / 3; }
+
+/* 5张牌 - 关系洞察 */
+.spread-display.relationship_spread {
+ display: grid;
+ grid-template-columns: repeat(3, 110rpx);
+ grid-template-rows: repeat(3, auto);
+ gap: 15rpx;
+ max-width: 375rpx;
+}
+
+.spread-display.relationship_spread .card-slot:nth-child(1) { grid-area: 2 / 1; }
+.spread-display.relationship_spread .card-slot:nth-child(2) { grid-area: 2 / 3; }
+.spread-display.relationship_spread .card-slot:nth-child(3) { grid-area: 2 / 2; }
+.spread-display.relationship_spread .card-slot:nth-child(4) { grid-area: 1 / 2; }
+.spread-display.relationship_spread .card-slot:nth-child(5) { grid-area: 3 / 2; }
+
+/* 5张牌 - 缘分探索 */
+.spread-display.destiny_connection {
+ display: grid;
+ grid-template-columns: repeat(3, 110rpx);
+ grid-template-rows: repeat(3, auto);
+ gap: 15rpx;
+ max-width: 375rpx;
+}
+
+.spread-display.destiny_connection .card-slot:nth-child(1) { grid-area: 1 / 2; }
+.spread-display.destiny_connection .card-slot:nth-child(2) { grid-area: 2 / 2; }
+.spread-display.destiny_connection .card-slot:nth-child(3) { grid-area: 2 / 1; }
+.spread-display.destiny_connection .card-slot:nth-child(4) { grid-area: 2 / 3; }
+.spread-display.destiny_connection .card-slot:nth-child(5) { grid-area: 3 / 2; }
+
+/* 5张牌 - 职场突破 */
+.spread-display.career_breakthrough {
+ display: grid;
+ grid-template-columns: repeat(3, 110rpx);
+ grid-template-rows: repeat(3, auto);
+ gap: 15rpx;
+ max-width: 375rpx;
+}
+
+.spread-display.career_breakthrough .card-slot:nth-child(1) { grid-area: 2 / 2; }
+.spread-display.career_breakthrough .card-slot:nth-child(2) { grid-area: 1 / 2; }
+.spread-display.career_breakthrough .card-slot:nth-child(3) { grid-area: 2 / 3; }
+.spread-display.career_breakthrough .card-slot:nth-child(4) { grid-area: 3 / 2; }
+.spread-display.career_breakthrough .card-slot:nth-child(5) { grid-area: 2 / 1; }
+
+/* 5张牌 - 横排 */
+.spread-display.timeline_spread,
+.spread-display.diamond_spread {
+ display: grid;
+ grid-template-columns: repeat(5, 110rpx);
+ gap: 12rpx;
+ max-width: 600rpx;
+}
+
+/* 6张牌 - 2x3网格 */
+.spread-display.career_planning,
+.spread-display.wealth_analysis {
+ display: grid;
+ grid-template-columns: repeat(3, 110rpx);
+ gap: 15rpx;
+ max-width: 375rpx;
+}
+
+/* 7张牌 - 马蹄铁形 */
+.spread-display.horseshoe_spread {
+ display: grid;
+ grid-template-columns: repeat(3, 110rpx);
+ grid-template-rows: repeat(4, auto);
+ gap: 12rpx;
+ max-width: 375rpx;
+}
+
+.spread-display.horseshoe_spread .card-slot:nth-child(1) { grid-area: 4 / 1; }
+.spread-display.horseshoe_spread .card-slot:nth-child(2) { grid-area: 3 / 1; }
+.spread-display.horseshoe_spread .card-slot:nth-child(3) { grid-area: 2 / 1; }
+.spread-display.horseshoe_spread .card-slot:nth-child(4) { grid-area: 1 / 2; }
+.spread-display.horseshoe_spread .card-slot:nth-child(5) { grid-area: 2 / 3; }
+.spread-display.horseshoe_spread .card-slot:nth-child(6) { grid-area: 3 / 3; }
+.spread-display.horseshoe_spread .card-slot:nth-child(7) { grid-area: 4 / 3; }
+
+/* 7张牌 - 灵性指引 */
+.spread-display.spiritual_guidance {
+ display: grid;
+ grid-template-columns: repeat(3, 110rpx);
+ gap: 15rpx;
+ max-width: 375rpx;
+}
+
+/* 10张牌 - 凯尔特十字 */
+.spread-display.celtic_cross {
+ display: grid;
+ grid-template-columns: repeat(6, 104rpx);
+ grid-template-rows: repeat(4, auto);
+ gap: 8rpx;
+ max-width: 100%;
+}
+
+.spread-display.celtic_cross .card-slot { width: 104rpx; }
+.spread-display.celtic_cross .flip-scene { width: 104rpx; height: 174rpx; }
+
+.spread-display.celtic_cross .card-slot:nth-child(1) { grid-area: 2 / 3; }
+.spread-display.celtic_cross .card-slot:nth-child(2) { grid-area: 2 / 3; transform: rotate(90deg); z-index: 1; }
+.spread-display.celtic_cross .card-slot:nth-child(3) { grid-area: 3 / 3; }
+.spread-display.celtic_cross .card-slot:nth-child(4) { grid-area: 2 / 2; }
+.spread-display.celtic_cross .card-slot:nth-child(5) { grid-area: 1 / 3; }
+.spread-display.celtic_cross .card-slot:nth-child(6) { grid-area: 2 / 4; }
+.spread-display.celtic_cross .card-slot:nth-child(7) { grid-area: 1 / 5; }
+.spread-display.celtic_cross .card-slot:nth-child(8) { grid-area: 2 / 5; }
+.spread-display.celtic_cross .card-slot:nth-child(9) { grid-area: 3 / 5; }
+.spread-display.celtic_cross .card-slot:nth-child(10) { grid-area: 4 / 5; }
+
+/* 10张牌 - 生命之树 */
+.spread-display.tree_of_life {
+ display: grid;
+ grid-template-columns: repeat(3, 104rpx);
+ grid-template-rows: repeat(5, auto);
+ gap: 10rpx;
+ max-width: 100%;
+}
+
+.spread-display.tree_of_life .card-slot { width: 104rpx; }
+.spread-display.tree_of_life .flip-scene { width: 104rpx; height: 174rpx; }
+
+.spread-display.tree_of_life .card-slot:nth-child(1) { grid-area: 1 / 2; }
+.spread-display.tree_of_life .card-slot:nth-child(2) { grid-area: 2 / 1; }
+.spread-display.tree_of_life .card-slot:nth-child(3) { grid-area: 2 / 3; }
+.spread-display.tree_of_life .card-slot:nth-child(4) { grid-area: 3 / 1; }
+.spread-display.tree_of_life .card-slot:nth-child(5) { grid-area: 3 / 3; }
+.spread-display.tree_of_life .card-slot:nth-child(6) { grid-area: 3 / 2; }
+.spread-display.tree_of_life .card-slot:nth-child(7) { grid-area: 4 / 1; }
+.spread-display.tree_of_life .card-slot:nth-child(8) { grid-area: 4 / 3; }
+.spread-display.tree_of_life .card-slot:nth-child(9) { grid-area: 4 / 2; }
+.spread-display.tree_of_life .card-slot:nth-child(10) { grid-area: 5 / 2; }
+
+/* 新增爱情牌阵布局 */
+
+/* 恋人金字塔 - 4张牌 */
+.spread-display.lover_pyramid {
+ display: grid;
+ grid-template-columns: repeat(3, 110rpx);
+ grid-template-rows: repeat(2, auto);
+ gap: 15rpx;
+ max-width: 375rpx;
+}
+
+.spread-display.lover_pyramid .card-slot:nth-child(1) { grid-area: 2 / 2; }
+.spread-display.lover_pyramid .card-slot:nth-child(2) { grid-area: 2 / 1; }
+.spread-display.lover_pyramid .card-slot:nth-child(3) { grid-area: 2 / 3; }
+.spread-display.lover_pyramid .card-slot:nth-child(4) { grid-area: 1 / 2; }
+
+/* 新爱牌阵 - 3张牌对角线 */
+.spread-display.new_love {
+ display: grid;
+ grid-template-columns: repeat(3, 110rpx);
+ grid-template-rows: repeat(3, auto);
+ gap: 15rpx;
+ max-width: 375rpx;
+}
+
+.spread-display.new_love .card-slot:nth-child(1) { grid-area: 1 / 1; }
+.spread-display.new_love .card-slot:nth-child(2) { grid-area: 2 / 2; }
+.spread-display.new_love .card-slot:nth-child(3) { grid-area: 3 / 3; }
+
+/* 人际关系牌阵 - 3张牌倒三角 */
+.spread-display.relationship_basic {
+ display: grid;
+ grid-template-columns: repeat(2, 110rpx);
+ grid-template-rows: repeat(2, auto);
+ gap: 15rpx;
+ max-width: 245rpx;
+}
+
+.spread-display.relationship_basic .card-slot:nth-child(1) { grid-area: 1 / 1; }
+.spread-display.relationship_basic .card-slot:nth-child(2) { grid-area: 1 / 2; }
+.spread-display.relationship_basic .card-slot:nth-child(3) { grid-area: 2 / 1 / 2 / 3; justify-self: center; }
+
+/* 爱情树牌阵 - 5张牌树形 */
+.spread-display.love_tree_spread {
+ display: grid;
+ grid-template-columns: repeat(3, 110rpx);
+ grid-template-rows: repeat(3, auto);
+ gap: 15rpx;
+ max-width: 375rpx;
+}
+
+.spread-display.love_tree_spread .card-slot:nth-child(1) { grid-area: 2 / 2; }
+.spread-display.love_tree_spread .card-slot:nth-child(2) { grid-area: 1 / 1; }
+.spread-display.love_tree_spread .card-slot:nth-child(3) { grid-area: 1 / 2; }
+.spread-display.love_tree_spread .card-slot:nth-child(4) { grid-area: 1 / 3; }
+.spread-display.love_tree_spread .card-slot:nth-child(5) { grid-area: 3 / 2; }
+
+/* 爱情大十字 - 5张牌十字形 */
+.spread-display.love_cross_spread {
+ display: grid;
+ grid-template-columns: repeat(3, 110rpx);
+ grid-template-rows: repeat(3, auto);
+ gap: 15rpx;
+ max-width: 375rpx;
+}
+
+.spread-display.love_cross_spread .card-slot:nth-child(1) { grid-area: 2 / 1; }
+.spread-display.love_cross_spread .card-slot:nth-child(2) { grid-area: 2 / 3; }
+.spread-display.love_cross_spread .card-slot:nth-child(3) { grid-area: 1 / 2; }
+.spread-display.love_cross_spread .card-slot:nth-child(4) { grid-area: 2 / 2; }
+.spread-display.love_cross_spread .card-slot:nth-child(5) { grid-area: 3 / 2; }
+
+/* 真命天子牌阵 - 5张牌菱形 */
+.spread-display.mr_right {
+ display: grid;
+ grid-template-columns: repeat(3, 110rpx);
+ grid-template-rows: repeat(3, auto);
+ gap: 15rpx;
+ max-width: 375rpx;
+}
+
+.spread-display.mr_right .card-slot:nth-child(1) { grid-area: 3 / 1; }
+.spread-display.mr_right .card-slot:nth-child(2) { grid-area: 2 / 1; }
+.spread-display.mr_right .card-slot:nth-child(3) { grid-area: 1 / 2; }
+.spread-display.mr_right .card-slot:nth-child(4) { grid-area: 2 / 3; }
+.spread-display.mr_right .card-slot:nth-child(5) { grid-area: 3 / 3; }
+
+/* 寻找对象牌阵 - 5张牌X形 */
+.spread-display.search_lover {
+ display: grid;
+ grid-template-columns: repeat(3, 110rpx);
+ grid-template-rows: repeat(3, auto);
+ gap: 15rpx;
+ max-width: 375rpx;
+}
+
+.spread-display.search_lover .card-slot:nth-child(1) { grid-area: 2 / 2; }
+.spread-display.search_lover .card-slot:nth-child(2) { grid-area: 1 / 1; }
+.spread-display.search_lover .card-slot:nth-child(3) { grid-area: 1 / 3; }
+.spread-display.search_lover .card-slot:nth-child(4) { grid-area: 3 / 1; }
+.spread-display.search_lover .card-slot:nth-child(5) { grid-area: 3 / 3; }
+
+/* 灵感对应牌阵 - 6张牌2x3网格 */
+.spread-display.inspiration_correspondence {
+ display: grid;
+ grid-template-columns: repeat(3, 110rpx);
+ gap: 15rpx;
+ max-width: 375rpx;
+}
+
+/* 吉普赛牌阵 - 5张牌十字形 */
+.spread-display.gypsy_spread {
+ display: grid;
+ grid-template-columns: repeat(3, 110rpx);
+ grid-template-rows: repeat(3, auto);
+ gap: 15rpx;
+ max-width: 375rpx;
+}
+
+.spread-display.gypsy_spread .card-slot:nth-child(1) { grid-area: 1 / 2; }
+.spread-display.gypsy_spread .card-slot:nth-child(2) { grid-area: 3 / 2; }
+.spread-display.gypsy_spread .card-slot:nth-child(3) { grid-area: 2 / 1; }
+.spread-display.gypsy_spread .card-slot:nth-child(4) { grid-area: 2 / 2; }
+.spread-display.gypsy_spread .card-slot:nth-child(5) { grid-area: 2 / 3; }
+
+/* 维纳斯牌阵 - 8张牌复杂菱形 */
+.spread-display.venus_spread {
+ display: grid;
+ grid-template-columns: repeat(3, 110rpx);
+ grid-template-rows: repeat(4, auto);
+ gap: 12rpx;
+ max-width: 375rpx;
+}
+
+.spread-display.venus_spread .card-slot:nth-child(1) { grid-area: 2 / 1; }
+.spread-display.venus_spread .card-slot:nth-child(2) { grid-area: 2 / 3; }
+.spread-display.venus_spread .card-slot:nth-child(3) { grid-area: 1 / 2; }
+.spread-display.venus_spread .card-slot:nth-child(4) { grid-area: 2 / 2; }
+.spread-display.venus_spread .card-slot:nth-child(5) { grid-area: 3 / 2; }
+.spread-display.venus_spread .card-slot:nth-child(6) { grid-area: 4 / 2; }
+.spread-display.venus_spread .card-slot:nth-child(7) { grid-area: 3 / 1; }
+.spread-display.venus_spread .card-slot:nth-child(8) { grid-area: 3 / 3; }
+
+/* 恋人之树牌阵 - 7张牌树形对称 */
+.spread-display.lover_tree {
+ display: grid;
+ grid-template-columns: repeat(3, 110rpx);
+ grid-template-rows: repeat(4, auto);
+ gap: 12rpx;
+ max-width: 375rpx;
+}
+
+.spread-display.lover_tree .card-slot:nth-child(1) { grid-area: 1 / 1; }
+.spread-display.lover_tree .card-slot:nth-child(2) { grid-area: 1 / 3; }
+.spread-display.lover_tree .card-slot:nth-child(3) { grid-area: 2 / 1; }
+.spread-display.lover_tree .card-slot:nth-child(4) { grid-area: 2 / 3; }
+.spread-display.lover_tree .card-slot:nth-child(5) { grid-area: 3 / 1; }
+.spread-display.lover_tree .card-slot:nth-child(6) { grid-area: 3 / 3; }
+.spread-display.lover_tree .card-slot:nth-child(7) { grid-area: 4 / 2; }
+
+/* 婚姻牌阵 - 7张牌六芒星形 */
+.spread-display.marriage_spread {
+ display: grid;
+ grid-template-columns: repeat(3, 110rpx);
+ grid-template-rows: repeat(4, auto);
+ gap: 12rpx;
+ max-width: 375rpx;
+}
+
+.spread-display.marriage_spread .card-slot:nth-child(1) { grid-area: 4 / 2; }
+.spread-display.marriage_spread .card-slot:nth-child(2) { grid-area: 3 / 1; }
+.spread-display.marriage_spread .card-slot:nth-child(3) { grid-area: 3 / 3; }
+.spread-display.marriage_spread .card-slot:nth-child(4) { grid-area: 2 / 2; }
+.spread-display.marriage_spread .card-slot:nth-child(5) { grid-area: 1 / 1; }
+.spread-display.marriage_spread .card-slot:nth-child(6) { grid-area: 1 / 3; }
+.spread-display.marriage_spread .card-slot:nth-child(7) { grid-area: 1 / 2; }
+
+/* 新增事业牌阵布局 */
+
+/* 金三角牌阵 - 3张牌金字塔形 */
+.spread-display.golden_triangle {
+ display: grid;
+ grid-template-columns: repeat(2, 110rpx);
+ grid-template-rows: repeat(2, auto);
+ gap: 15rpx;
+ max-width: 245rpx;
+}
+
+.spread-display.golden_triangle .card-slot:nth-child(1) { grid-area: 1 / 1 / 1 / 3; justify-self: center; }
+.spread-display.golden_triangle .card-slot:nth-child(2) { grid-area: 2 / 1; }
+.spread-display.golden_triangle .card-slot:nth-child(3) { grid-area: 2 / 2; }
+
+/* 成功之星牌阵 - 3张牌三角形 */
+.spread-display.success_star {
+ display: grid;
+ grid-template-columns: repeat(2, 110rpx);
+ grid-template-rows: repeat(2, auto);
+ gap: 15rpx;
+ max-width: 245rpx;
+}
+
+.spread-display.success_star .card-slot:nth-child(1) { grid-area: 1 / 1; }
+.spread-display.success_star .card-slot:nth-child(2) { grid-area: 2 / 1; }
+.spread-display.success_star .card-slot:nth-child(3) { grid-area: 1 / 2 / 3 / 3; align-self: center; }
+
+/* 事业金字塔 - 4张牌金字塔形 */
+.spread-display.career_pyramid {
+ display: grid;
+ grid-template-columns: repeat(3, 110rpx);
+ grid-template-rows: repeat(2, auto);
+ gap: 15rpx;
+ max-width: 375rpx;
+}
+
+.spread-display.career_pyramid .card-slot:nth-child(1) { grid-area: 2 / 2; }
+.spread-display.career_pyramid .card-slot:nth-child(2) { grid-area: 2 / 1; }
+.spread-display.career_pyramid .card-slot:nth-child(3) { grid-area: 2 / 3; }
+.spread-display.career_pyramid .card-slot:nth-child(4) { grid-area: 1 / 2; }
+
+/* 财富之树牌阵 - 5张牌十字树形 */
+.spread-display.wealth_tree {
+ display: grid;
+ grid-template-columns: repeat(3, 110rpx);
+ grid-template-rows: repeat(3, auto);
+ gap: 15rpx;
+ max-width: 375rpx;
+}
+
+.spread-display.wealth_tree .card-slot:nth-child(1) { grid-area: 3 / 2; }
+.spread-display.wealth_tree .card-slot:nth-child(2) { grid-area: 2 / 2; }
+.spread-display.wealth_tree .card-slot:nth-child(3) { grid-area: 2 / 3; }
+.spread-display.wealth_tree .card-slot:nth-child(4) { grid-area: 2 / 1; }
+.spread-display.wealth_tree .card-slot:nth-child(5) { grid-area: 1 / 2; }
+
+/* X时机牌阵 - 5张牌X形 */
+.spread-display.x_opportunity {
+ display: grid;
+ grid-template-columns: repeat(3, 110rpx);
+ grid-template-rows: repeat(3, auto);
+ gap: 15rpx;
+ max-width: 375rpx;
+}
+
+.spread-display.x_opportunity .card-slot:nth-child(1) { grid-area: 2 / 2; }
+.spread-display.x_opportunity .card-slot:nth-child(2) { grid-area: 1 / 1; }
+.spread-display.x_opportunity .card-slot:nth-child(3) { grid-area: 1 / 3; }
+.spread-display.x_opportunity .card-slot:nth-child(4) { grid-area: 3 / 1; }
+.spread-display.x_opportunity .card-slot:nth-child(5) { grid-area: 3 / 3; }
+
+/* 面试求职牌阵 - 5张牌十字形 */
+.spread-display.job_interview {
+ display: grid;
+ grid-template-columns: repeat(3, 110rpx);
+ grid-template-rows: repeat(3, auto);
+ gap: 15rpx;
+ max-width: 375rpx;
+}
+
+.spread-display.job_interview .card-slot:nth-child(1) { grid-area: 3 / 2; }
+.spread-display.job_interview .card-slot:nth-child(2) { grid-area: 2 / 1; }
+.spread-display.job_interview .card-slot:nth-child(3) { grid-area: 2 / 3; }
+.spread-display.job_interview .card-slot:nth-child(4) { grid-area: 2 / 2; }
+.spread-display.job_interview .card-slot:nth-child(5) { grid-area: 1 / 2; }
+
+/* 工作问题牌阵 - 6张牌六边形 */
+.spread-display.work_problems {
+ display: grid;
+ grid-template-columns: repeat(3, 110rpx);
+ grid-template-rows: repeat(3, auto);
+ gap: 12rpx;
+ max-width: 375rpx;
+}
+
+.spread-display.work_problems .card-slot:nth-child(1) { grid-area: 2 / 2; }
+.spread-display.work_problems .card-slot:nth-child(2) { grid-area: 1 / 1; }
+.spread-display.work_problems .card-slot:nth-child(3) { grid-area: 2 / 1; }
+.spread-display.work_problems .card-slot:nth-child(4) { grid-area: 2 / 3; }
+.spread-display.work_problems .card-slot:nth-child(5) { grid-area: 1 / 3; }
+.spread-display.work_problems .card-slot:nth-child(6) { grid-area: 3 / 2; }
+
+/* 财富波浪牌阵 - 6张牌波浪形 */
+.spread-display.turbulent_finances {
+ display: grid;
+ grid-template-columns: repeat(3, 110rpx);
+ grid-template-rows: repeat(3, auto);
+ gap: 12rpx;
+ max-width: 375rpx;
+}
+
+.spread-display.turbulent_finances .card-slot:nth-child(1) { grid-area: 3 / 1; }
+.spread-display.turbulent_finances .card-slot:nth-child(2) { grid-area: 2 / 1; }
+.spread-display.turbulent_finances .card-slot:nth-child(3) { grid-area: 2 / 2; }
+.spread-display.turbulent_finances .card-slot:nth-child(4) { grid-area: 2 / 3; }
+.spread-display.turbulent_finances .card-slot:nth-child(5) { grid-area: 3 / 3; }
+.spread-display.turbulent_finances .card-slot:nth-child(6) { grid-area: 1 / 2; }
+
+/* 期望的工作 - 6张牌对称形 */
+.spread-display.desired_job {
+ display: grid;
+ grid-template-columns: repeat(3, 110rpx);
+ grid-template-rows: repeat(3, auto);
+ gap: 12rpx;
+ max-width: 375rpx;
+}
+
+.spread-display.desired_job .card-slot:nth-child(1) { grid-area: 1 / 2; }
+.spread-display.desired_job .card-slot:nth-child(2) { grid-area: 2 / 1; }
+.spread-display.desired_job .card-slot:nth-child(3) { grid-area: 2 / 3; }
+.spread-display.desired_job .card-slot:nth-child(4) { grid-area: 3 / 1; }
+.spread-display.desired_job .card-slot:nth-child(5) { grid-area: 3 / 2; }
+.spread-display.desired_job .card-slot:nth-child(6) { grid-area: 3 / 3; }
+
+/* 新增决策牌阵布局 */
+
+/* 二个选择牌阵 - 3张牌倒三角 */
+.spread-display.two_options {
+ display: grid;
+ grid-template-columns: repeat(2, 110rpx);
+ grid-template-rows: repeat(2, auto);
+ gap: 15rpx;
+ max-width: 245rpx;
+}
+
+.spread-display.two_options .card-slot:nth-child(1) { grid-area: 1 / 1; }
+.spread-display.two_options .card-slot:nth-child(2) { grid-area: 1 / 2; }
+.spread-display.two_options .card-slot:nth-child(3) { grid-area: 2 / 1 / 2 / 3; justify-self: center; }
+
+/* 三个选择牌阵 - 3张牌正三角 */
+.spread-display.three_options {
+ display: grid;
+ grid-template-columns: repeat(2, 110rpx);
+ grid-template-rows: repeat(2, auto);
+ gap: 15rpx;
+ max-width: 245rpx;
+}
+
+.spread-display.three_options .card-slot:nth-child(1) { grid-area: 1 / 1 / 1 / 3; justify-self: center; }
+.spread-display.three_options .card-slot:nth-child(2) { grid-area: 2 / 1; }
+.spread-display.three_options .card-slot:nth-child(3) { grid-area: 2 / 2; }
+
+/* 每日树牌阵 - 4张牌十字形 */
+.spread-display.daily_tree {
+ display: grid;
+ grid-template-columns: repeat(3, 110rpx);
+ grid-template-rows: repeat(3, auto);
+ gap: 15rpx;
+ max-width: 375rpx;
+}
+
+.spread-display.daily_tree .card-slot:nth-child(1) { grid-area: 3 / 2; }
+.spread-display.daily_tree .card-slot:nth-child(2) { grid-area: 2 / 1; }
+.spread-display.daily_tree .card-slot:nth-child(3) { grid-area: 1 / 2; }
+.spread-display.daily_tree .card-slot:nth-child(4) { grid-area: 2 / 3; }
+
+/* 二选一牌阵 - 5张牌菱形 */
+.spread-display.weigh_two {
+ display: grid;
+ grid-template-columns: repeat(3, 110rpx);
+ grid-template-rows: repeat(3, auto);
+ gap: 15rpx;
+ max-width: 375rpx;
+}
+
+.spread-display.weigh_two .card-slot:nth-child(1) { grid-area: 3 / 2; }
+.spread-display.weigh_two .card-slot:nth-child(2) { grid-area: 2 / 1; }
+.spread-display.weigh_two .card-slot:nth-child(3) { grid-area: 2 / 3; }
+.spread-display.weigh_two .card-slot:nth-child(4) { grid-area: 1 / 1; }
+.spread-display.weigh_two .card-slot:nth-child(5) { grid-area: 1 / 3; }
+
+/* 比较选择牌阵 - 6张牌3+3排列 */
+.spread-display.comparing_choices {
+ display: grid;
+ grid-template-columns: repeat(3, 110rpx);
+ gap: 12rpx;
+ max-width: 375rpx;
+}
+
+/* 三选一牌阵 - 7张牌复杂对称形 */
+.spread-display.weigh_three {
+ display: grid;
+ grid-template-columns: repeat(3, 110rpx);
+ grid-template-rows: repeat(3, auto);
+ gap: 12rpx;
+ max-width: 375rpx;
+}
+
+.spread-display.weigh_three .card-slot:nth-child(1) { grid-area: 2 / 1; }
+.spread-display.weigh_three .card-slot:nth-child(2) { grid-area: 1 / 2; }
+.spread-display.weigh_three .card-slot:nth-child(3) { grid-area: 2 / 2; }
+.spread-display.weigh_three .card-slot:nth-child(4) { grid-area: 3 / 2; }
+.spread-display.weigh_three .card-slot:nth-child(5) { grid-area: 1 / 3; }
+.spread-display.weigh_three .card-slot:nth-child(6) { grid-area: 2 / 3; }
+.spread-display.weigh_three .card-slot:nth-child(7) { grid-area: 3 / 3; }
+
+/* 新增深度探索牌阵布局 */
+
+/* 身心灵牌阵 - 4张牌倒T形 */
+.spread-display.mind_body_spirit {
+ display: grid;
+ grid-template-columns: repeat(3, 110rpx);
+ grid-template-rows: repeat(2, auto);
+ gap: 15rpx;
+ max-width: 375rpx;
+}
+
+.spread-display.mind_body_spirit .card-slot:nth-child(1) { grid-area: 2 / 1; }
+.spread-display.mind_body_spirit .card-slot:nth-child(2) { grid-area: 2 / 2; }
+.spread-display.mind_body_spirit .card-slot:nth-child(3) { grid-area: 2 / 3; }
+.spread-display.mind_body_spirit .card-slot:nth-child(4) { grid-area: 1 / 2; }
+
+/* 四元素牌阵 - 4张牌2x2方形 */
+.spread-display.four_elements {
+ display: grid;
+ grid-template-columns: repeat(2, 110rpx);
+ grid-template-rows: repeat(2, auto);
+ gap: 15rpx;
+ max-width: 245rpx;
+}
+
+.spread-display.four_elements .card-slot:nth-child(1) { grid-area: 1 / 1; }
+.spread-display.four_elements .card-slot:nth-child(2) { grid-area: 2 / 1; }
+.spread-display.four_elements .card-slot:nth-child(3) { grid-area: 2 / 2; }
+.spread-display.four_elements .card-slot:nth-child(4) { grid-area: 1 / 2; }
+
+/* 自我探索牌阵 - 4张牌箭头三角形 */
+.spread-display.self_discovery {
+ display: grid;
+ grid-template-columns: repeat(3, 110rpx);
+ grid-template-rows: repeat(3, auto);
+ gap: 15rpx;
+ max-width: 375rpx;
+}
+
+.spread-display.self_discovery .card-slot:nth-child(1) { grid-area: 2 / 2; }
+.spread-display.self_discovery .card-slot:nth-child(2) { grid-area: 1 / 2; }
+.spread-display.self_discovery .card-slot:nth-child(3) { grid-area: 3 / 1; }
+.spread-display.self_discovery .card-slot:nth-child(4) { grid-area: 3 / 3; }
+
+/* 认识你自己 - 5张牌十字形 */
+.spread-display.know_yourself {
+ display: grid;
+ grid-template-columns: repeat(3, 110rpx);
+ grid-template-rows: repeat(3, auto);
+ gap: 15rpx;
+ max-width: 375rpx;
+}
+
+.spread-display.know_yourself .card-slot:nth-child(1) { grid-area: 2 / 2; }
+.spread-display.know_yourself .card-slot:nth-child(2) { grid-area: 1 / 2; }
+.spread-display.know_yourself .card-slot:nth-child(3) { grid-area: 2 / 3; }
+.spread-display.know_yourself .card-slot:nth-child(4) { grid-area: 3 / 2; }
+.spread-display.know_yourself .card-slot:nth-child(5) { grid-area: 2 / 1; }
+
+/* 你的突破牌阵 - 5张牌五角形 */
+.spread-display.your_breakthrough {
+ display: grid;
+ grid-template-columns: repeat(3, 110rpx);
+ grid-template-rows: repeat(3, auto);
+ gap: 12rpx;
+ max-width: 375rpx;
+}
+
+.spread-display.your_breakthrough .card-slot:nth-child(1) { grid-area: 2 / 1; }
+.spread-display.your_breakthrough .card-slot:nth-child(2) { grid-area: 2 / 3; }
+.spread-display.your_breakthrough .card-slot:nth-child(3) { grid-area: 1 / 2; }
+.spread-display.your_breakthrough .card-slot:nth-child(4) { grid-area: 3 / 1; }
+.spread-display.your_breakthrough .card-slot:nth-child(5) { grid-area: 3 / 3; }
+
+/* 元素十字牌阵 - 6张牌十字形 */
+.spread-display.elemental_cross {
+ display: grid;
+ grid-template-columns: repeat(3, 110rpx);
+ grid-template-rows: repeat(4, auto);
+ gap: 12rpx;
+ max-width: 375rpx;
+}
+
+.spread-display.elemental_cross .card-slot:nth-child(1) { grid-area: 2 / 2; }
+.spread-display.elemental_cross .card-slot:nth-child(2) { grid-area: 2 / 3; }
+.spread-display.elemental_cross .card-slot:nth-child(3) { grid-area: 2 / 1; }
+.spread-display.elemental_cross .card-slot:nth-child(4) { grid-area: 1 / 2; }
+.spread-display.elemental_cross .card-slot:nth-child(5) { grid-area: 3 / 2; }
+.spread-display.elemental_cross .card-slot:nth-child(6) { grid-area: 4 / 2; }
+
+/* 车轮牌阵 - 7张牌圆形轮状 */
+.spread-display.wheel_spread {
+ display: grid;
+ grid-template-columns: repeat(3, 110rpx);
+ grid-template-rows: repeat(4, auto);
+ gap: 10rpx;
+ max-width: 375rpx;
+}
+
+.spread-display.wheel_spread .card-slot:nth-child(1) { grid-area: 2 / 2; }
+.spread-display.wheel_spread .card-slot:nth-child(2) { grid-area: 1 / 1; }
+.spread-display.wheel_spread .card-slot:nth-child(3) { grid-area: 2 / 1; }
+.spread-display.wheel_spread .card-slot:nth-child(4) { grid-area: 3 / 1; }
+.spread-display.wheel_spread .card-slot:nth-child(5) { grid-area: 1 / 3; }
+.spread-display.wheel_spread .card-slot:nth-child(6) { grid-area: 2 / 3; }
+.spread-display.wheel_spread .card-slot:nth-child(7) { grid-area: 3 / 3; }
+
+/* 七行星牌阵 - 7张牌星形排列 */
+.spread-display.seven_planets {
+ display: grid;
+ grid-template-columns: repeat(3, 110rpx);
+ grid-template-rows: repeat(4, auto);
+ gap: 10rpx;
+ max-width: 375rpx;
+}
+
+.spread-display.seven_planets .card-slot:nth-child(1) { grid-area: 4 / 1; }
+.spread-display.seven_planets .card-slot:nth-child(2) { grid-area: 3 / 1; }
+.spread-display.seven_planets .card-slot:nth-child(3) { grid-area: 2 / 1; }
+.spread-display.seven_planets .card-slot:nth-child(4) { grid-area: 1 / 2; }
+.spread-display.seven_planets .card-slot:nth-child(5) { grid-area: 2 / 3; }
+.spread-display.seven_planets .card-slot:nth-child(6) { grid-area: 3 / 3; }
+.spread-display.seven_planets .card-slot:nth-child(7) { grid-area: 4 / 3; }
+
+/* 梦镜牌阵 - 7张牌金字塔形 */
+.spread-display.dream_mirror {
+ display: grid;
+ grid-template-columns: repeat(3, 110rpx);
+ grid-template-rows: repeat(3, auto);
+ gap: 10rpx;
+ max-width: 375rpx;
+}
+
+.spread-display.dream_mirror .card-slot:nth-child(1) { grid-area: 2 / 1; }
+.spread-display.dream_mirror .card-slot:nth-child(2) { grid-area: 3 / 1; }
+.spread-display.dream_mirror .card-slot:nth-child(3) { grid-area: 2 / 2; }
+.spread-display.dream_mirror .card-slot:nth-child(4) { grid-area: 3 / 2; }
+.spread-display.dream_mirror .card-slot:nth-child(5) { grid-area: 2 / 3; }
+.spread-display.dream_mirror .card-slot:nth-child(6) { grid-area: 3 / 3; }
+.spread-display.dream_mirror .card-slot:nth-child(7) { grid-area: 1 / 2; }
+
+
+
+
+
+.card-slot {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ width: 124rpx;
+ margin-bottom: 8rpx;
+}
+
+.pos-info {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: flex-end;
+ min-height: 60rpx;
+ margin-bottom: 8rpx;
+ width: 140%; /* Allow spilling over slightly */
+ margin-left: -20%; /* Center the spill */
+}
+
+.pos-text-main {
+ font-size: 24rpx;
+ color: #8a8a9d;
+ text-align: center;
+ line-height: 1.2;
+ white-space: nowrap; /* Force single line if possible, or allow wrap controlling height */
+}
+
+.pos-seq {
+ font-size: 20rpx;
+ color: rgba(138, 138, 157, 0.6);
+ margin-top: 4rpx;
+}
+
+.flip-scene {
+ width: 124rpx;
+ height: 208rpx;
+ perspective: 1000rpx;
+}
+
+.flip-card {
+ position: relative;
+ width: 100%;
+ height: 100%;
+ transition: transform 0.6s;
+ transform-style: preserve-3d;
+}
+
+.flip-card.flipped {
+ transform: rotateY(180deg);
+}
+
+.card-face {
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ backface-visibility: hidden;
+ border-radius: 12rpx;
+ overflow: hidden;
+}
+
+.face-back { background: #2a2a3e; }
+.face-front { background: #1a1a2e; transform: rotateY(180deg); }
+
+.card-image { width: 100%; height: 100%; }
+.card-image.reversed { transform: rotate(180deg); }
+
+.card-name-sm {
+ margin-top: 12rpx;
+ font-size: 22rpx;
+ color: #c9a0dc;
+ text-align: center;
+}
+
+/* 5. 深度解读区域 */
+.interpretation-area {
+ margin-top: 20rpx;
+ background: rgba(255, 255, 255, 0.03);
+ border-radius: 24rpx;
+ padding: 20rpx;
+}
+
+.theme-box {
+ text-align: center;
+ margin-bottom: 60rpx;
+ background: rgba(201, 160, 220, 0.08);
+ padding: 30rpx;
+ border-radius: 16rpx;
+}
+
+.label {
+ display: block;
+ font-size: 20rpx;
+ color: #c9a0dc;
+ text-transform: uppercase;
+ letter-spacing: 4rpx;
+ margin-bottom: 16rpx;
+ opacity: 0.6;
+}
+
+.theme-box .content {
+ font-size: 34rpx;
+ font-weight: 500;
+ color: #ffffff;
+ line-height: 1.4;
+}
+
+.info-grid {
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ gap: 30rpx;
+ margin-bottom: 60rpx;
+}
+
+.info-item .content {
+ font-size: 26rpx;
+ line-height: 1.6;
+ color: #b0b0cf;
+}
+
+.pos-meanings {
+ border-top: 1px solid rgba(255, 255, 255, 0.05);
+ padding-top: 40rpx;
+ margin-bottom: 60rpx;
+}
+
+.pos-meaning-item {
+ margin-bottom: 40rpx;
+}
+
+.pos-title {
+ font-size: 24rpx;
+ color: #c9a0dc;
+ display: block;
+ margin-bottom: 12rpx;
+ font-weight: 500;
+}
+
+.pos-text {
+ font-size: 26rpx;
+ color: #b0b0cf;
+ line-height: 1.8;
+}
+
+.advice-box {
+ background: linear-gradient(135deg, rgba(201, 160, 220, 0.1), rgba(201, 160, 220, 0.03));
+ padding: 40rpx;
+ border-radius: 20rpx;
+ border-left: 4rpx solid #c9a0dc;
+}
+
+.advice-box .content {
+ font-size: 28rpx;
+ color: #ffffff;
+ font-weight: 500;
+ line-height: 1.6;
+}
+
+.reset-btn {
+ margin-top: 80rpx;
+ background: transparent;
+ color: #c9a0dc;
+ border: 1px solid rgba(201, 160, 220, 0.4);
+ font-size: 24rpx;
+ border-radius: 40rpx;
+ width: 240rpx;
+}
+
+/* AI Loading */
+.loading-ai {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ padding: 20rpx 0;
+ color: #c9a0dc;
+ font-size: 26rpx;
+}
+
+.loading-dot {
+ font-size: 60rpx;
+ margin-bottom: 30rpx;
+ animation: flash 1.5s infinite;
+}
+
+@keyframes flash {
+ 0%, 100% { opacity: 0.3; transform: scale(0.9); }
+ 50% { opacity: 1; transform: scale(1.1); }
+}
+
+/* 整体趋势故事框 */
+.story-box {
+ background: linear-gradient(135deg, rgba(201, 160, 220, 0.1), rgba(138, 138, 157, 0.05));
+ padding: 30rpx;
+ border-radius: 16rpx;
+ margin-bottom: 30rpx;
+ border-left: 4rpx solid #c9a0dc;
+}
+
+.story-box .label {
+ display: block;
+ font-size: 24rpx;
+ color: #c9a0dc;
+ margin-bottom: 15rpx;
+ font-weight: 600;
+ letter-spacing: 2rpx;
+}
+
+.story-box .content {
+ font-size: 28rpx;
+ color: #e0e0e0;
+ line-height: 1.8;
+}
+
+/* 提问区域 - 沉浸式仪式感版本 */
+.asking-area {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ padding: 80rpx 40rpx 60rpx;
+ background: linear-gradient(180deg, #0f0f1b 0%, #1a1a2e 50%, #16213e 100%);
+ position: relative;
+}
+
+/* 顶部引导语 */
+.asking-title {
+ font-size: 24rpx;
+ color: rgba(201, 160, 220, 0.6);
+ letter-spacing: 4rpx;
+ text-align: center;
+ margin-bottom: 60rpx;
+ font-weight: 300;
+}
+
+/* 中央塔罗卡片式输入区 */
+.input-card {
+ width: 100%;
+ background: rgba(201, 160, 220, 0.08);
+ backdrop-filter: blur(10px);
+ border: 2px solid rgba(201, 160, 220, 0.3);
+ border-radius: 40rpx;
+ padding: 40rpx;
+ margin-bottom: 50rpx;
+ position: relative;
+ box-shadow: 0 0 40rpx rgba(201, 160, 220, 0.2);
+ transition: all 0.4s ease;
+}
+
+.input-card:focus-within {
+ border-color: rgba(201, 160, 220, 0.6);
+ box-shadow: 0 0 60rpx rgba(201, 160, 220, 0.4);
+ background: rgba(201, 160, 220, 0.12);
+}
+
+.question-input {
+ width: 100%;
+ height: 280rpx;
+ font-size: 32rpx;
+ color: #ffffff;
+ line-height: 1.6;
+ background: transparent;
+}
+
+.placeholder-style {
+ color: rgba(255, 255, 255, 0.25);
+ font-size: 28rpx;
+}
+
+.char-count {
+ position: absolute;
+ bottom: 30rpx;
+ right: 40rpx;
+ font-size: 20rpx;
+ color: rgba(138, 138, 157, 0.5);
+}
+
+/* 质量评分指示器 - 精简版 */
+.quality-indicator {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ margin-top: 24rpx;
+ padding: 12rpx 20rpx;
+ background: rgba(139, 233, 253, 0.08);
+ border-radius: 20rpx;
+ border: 1px solid rgba(139, 233, 253, 0.2);
+}
+
+.quality-icon {
+ font-size: 32rpx;
+ margin-right: 8rpx;
+}
+
+.quality-text {
+ font-size: 24rpx;
+ color: #8be9fd;
+ font-weight: 400;
+ opacity: 0.8;
+}
+
+/* 温和分割线 */
+.divider {
+ width: 200rpx;
+ height: 1px;
+ background: linear-gradient(90deg, transparent, rgba(201, 160, 220, 0.3), transparent);
+ margin: 30rpx 0 40rpx;
+}
+
+/* 塔罗低语区域 */
+.whispers-area {
+ width: 100%;
+ margin-bottom: 60rpx;
+}
+
+.whispers-title {
+ display: block;
+ font-size: 24rpx;
+ color: rgba(201, 160, 220, 0.7);
+ text-align: center;
+ margin-bottom: 30rpx;
+ letter-spacing: 3rpx;
+ font-weight: 300;
+}
+
+.whispers-scroll {
+ width: 100%;
+ white-space: nowrap;
+}
+
+/* 塔罗低语卡片 */
+.whisper-card {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ background: rgba(255, 255, 255, 0.05);
+ border: 1px solid rgba(201, 160, 220, 0.3);
+ border-radius: 20rpx;
+ padding: 28rpx 32rpx;
+ margin-right: 20rpx;
+ min-width: 260rpx;
+ max-width: 340rpx;
+ box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.3);
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
+ position: relative;
+ overflow: hidden;
+}
+
+.whisper-card::before {
+ content: '';
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background: radial-gradient(circle at center, rgba(201, 160, 220, 0.1), transparent);
+ opacity: 0;
+ transition: opacity 0.3s ease;
+}
+
+.whisper-card:active {
+ transform: scale(1.05);
+}
+
+.whisper-card.selected {
+ background: rgba(201, 160, 220, 0.15);
+ border-color: rgba(201, 160, 220, 0.6);
+ box-shadow: 0 0 30rpx rgba(201, 160, 220, 0.4);
+}
+
+.whisper-card.selected::before {
+ opacity: 1;
+}
+
+.whisper-text {
+ font-size: 28rpx;
+ color: #e0e0e0;
+ line-height: 1.5;
+ text-align: center;
+ word-wrap: break-word;
+ white-space: normal;
+ position: relative;
+ z-index: 1;
+}
+
+.whisper-card.selected .whisper-text {
+ color: #ffffff;
+ font-weight: 500;
+}
+
+/* 开启塔罗指引按钮 */
+.start-btn {
+ background: linear-gradient(135deg, #c9a0dc 0%, #8b7ba8 100%);
+ color: #ffffff;
+ font-size: 32rpx;
+ font-weight: 600;
+ padding: 28rpx 120rpx;
+ border-radius: 50rpx;
+ box-shadow: 0 8rpx 30rpx rgba(201, 160, 220, 0.4);
+ transition: all 0.2s ease;
+ border: none;
+ letter-spacing: 2rpx;
+}
+
+.start-btn::after {
+ border: none;
+}
+
+.start-btn:active {
+ transform: scale(0.95);
+ box-shadow: 0 4rpx 20rpx rgba(201, 160, 220, 0.3);
+}
+
+/* =========================================
+ 流式 AI 解读输出样式
+ ========================================= */
+.stream-result {
+ padding: 30rpx 20rpx;
+ animation: fadeIn 0.3s ease;
+}
+
+.stream-text {
+ display: block;
+ font-size: 28rpx;
+ color: #e8e0f0;
+ line-height: 1.8;
+ white-space: pre-wrap; /* 保留换行 */
+ word-break: break-all;
+ letter-spacing: 0.5rpx;
+}
+
+@keyframes fadeIn {
+ from { opacity: 0; transform: translateY(10rpx); }
+ to { opacity: 1; transform: translateY(0); }
+}
+
+/* 翻牌提示 */
+.flip-hint {
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: center;
+ gap: 16rpx;
+ margin-top: 32rpx;
+ animation: hintPulse 2s ease-in-out infinite;
+}
+
+.flip-hint-text {
+ font-size: 26rpx;
+ color: #c9a0dc;
+ letter-spacing: 2rpx;
+}
+
+.flip-hint-icon {
+ font-size: 20rpx;
+ color: #c9a0dc;
+}
+
+@keyframes hintPulse {
+ 0%, 100% { opacity: 0.5; }
+ 50% { opacity: 1; }
+}
+
+/* AI 警示语精简版 */
+.ai-warning {
+ margin-top: 40rpx;
+ text-align: center;
+ font-size: 22rpx;
+ color: rgba(201, 160, 220, 0.4);
+ letter-spacing: 1rpx;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ padding: 0 40rpx;
+}
+/* 5. 分享引导模块 */
+.share-guidance {
+ width: 100%;
+ max-width: 600rpx;
+ background: linear-gradient(135deg, rgba(201, 160, 220, 0.1) 0%, rgba(201, 160, 220, 0.05) 100%);
+ border: 1px solid rgba(201, 160, 220, 0.3);
+ border-radius: 20rpx;
+ padding: 30rpx;
+ margin: 40rpx 0;
+ text-align: center;
+ box-sizing: border-box;
+}
+
+.guidance-text {
+ font-size: 28rpx;
+ color: #c9a0dc;
+ margin-bottom: 24rpx;
+ font-style: italic;
+ letter-spacing: 2rpx;
+ text-shadow: 0 0 10rpx rgba(201, 160, 220, 0.3);
+}
+
+.share-btn {
+ background: linear-gradient(90deg, #ffd700, #daa520);
+ color: #1a1a2e;
+ font-size: 30rpx;
+ font-weight: 600;
+ border-radius: 40rpx;
+ padding: 0 40rpx;
+ line-height: 80rpx;
+ border: none;
+ box-shadow: 0 4rpx 16rpx rgba(218, 165, 32, 0.3);
+ transition: all 0.3s ease;
+}
+
+.share-btn:active {
+ transform: scale(0.96);
+ box-shadow: 0 2rpx 8rpx rgba(218, 165, 32, 0.3);
+}
+/ * @ i m p o r t ' . . / . . / s t y l e s / d i s c l a i m e r . w x s s ' ; * /
+
\ No newline at end of file
diff --git a/pages/knowledge/article.js b/pages/knowledge/article.js
index c95a1f6..739e59a 100644
--- a/pages/knowledge/article.js
+++ b/pages/knowledge/article.js
@@ -5,6 +5,10 @@ Page({
article: null
},
+ handleBack() {
+ wx.navigateBack({ delta: 1 });
+ },
+
onLoad(options) {
const id = options.id;
const article = getArticleById(id);
diff --git a/pages/knowledge/article.wxml b/pages/knowledge/article.wxml
index 09cee28..1db22bd 100644
--- a/pages/knowledge/article.wxml
+++ b/pages/knowledge/article.wxml
@@ -1,4 +1,8 @@
+
+ ⇠
+ 返回
+
{{article.title}}
{{article.summary}}
diff --git a/pages/knowledge/article.wxss b/pages/knowledge/article.wxss
index 34313a0..12200a8 100644
--- a/pages/knowledge/article.wxss
+++ b/pages/knowledge/article.wxss
@@ -1,7 +1,32 @@
.container {
min-height: 100vh;
background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
- padding: 40rpx 30rpx 120rpx;
+ padding: 140rpx 30rpx 120rpx;
+}
+
+/* 自定义返回按钮样式 */
+.nav-back {
+ position: absolute;
+ top: 40rpx;
+ left: 30rpx;
+ display: flex;
+ align-items: center;
+ z-index: 100;
+ padding: 10rpx 20rpx;
+ border-radius: 30rpx;
+ background: rgba(255, 255, 255, 0.05);
+}
+
+.back-icon {
+ font-size: 32rpx;
+ margin-right: 8rpx;
+ color: #c9a0dc;
+}
+
+.back-text {
+ font-size: 26rpx;
+ color: #c9a0dc;
+ letter-spacing: 2rpx;
}
.article-header {
diff --git a/pages/knowledge/index.js b/pages/knowledge/index.js
index 48cb937..4875642 100644
--- a/pages/knowledge/index.js
+++ b/pages/knowledge/index.js
@@ -11,6 +11,13 @@ Page({
});
},
+ // 返回上一页
+ handleBack() {
+ wx.navigateBack({
+ delta: 1
+ });
+ },
+
// 点击分类卡片
goToList(e) {
const category = e.currentTarget.dataset.category;
diff --git a/pages/knowledge/index.wxml b/pages/knowledge/index.wxml
index de11cfd..194112c 100644
--- a/pages/knowledge/index.wxml
+++ b/pages/knowledge/index.wxml
@@ -1,4 +1,8 @@
+
+ ⇠
+ 返回
+
diff --git a/pages/knowledge/index.wxss b/pages/knowledge/index.wxss
index 015712e..e9faf26 100644
--- a/pages/knowledge/index.wxss
+++ b/pages/knowledge/index.wxss
@@ -1,7 +1,32 @@
.container {
min-height: 100vh;
background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
- padding: 40rpx 30rpx;
+ padding: 140rpx 30rpx;
+}
+
+/* 自定义返回按钮样式 */
+.nav-back {
+ position: absolute;
+ top: 40rpx;
+ left: 30rpx;
+ display: flex;
+ align-items: center;
+ z-index: 100;
+ padding: 10rpx 20rpx;
+ border-radius: 30rpx;
+ background: rgba(255, 255, 255, 0.05);
+}
+
+.back-icon {
+ font-size: 32rpx;
+ margin-right: 8rpx;
+ color: #c9a0dc;
+}
+
+.back-text {
+ font-size: 26rpx;
+ color: #c9a0dc;
+ letter-spacing: 2rpx;
}
.header {
diff --git a/pages/knowledge/list.js b/pages/knowledge/list.js
index e16e267..9df20be 100644
--- a/pages/knowledge/list.js
+++ b/pages/knowledge/list.js
@@ -7,6 +7,10 @@ Page({
articles: []
},
+ handleBack() {
+ wx.navigateBack({ delta: 1 });
+ },
+
onLoad(options) {
const category = options.category || 'beginner';
const categories = getCategories();
diff --git a/pages/knowledge/list.wxml b/pages/knowledge/list.wxml
index d171c2e..71f1867 100644
--- a/pages/knowledge/list.wxml
+++ b/pages/knowledge/list.wxml
@@ -1,4 +1,8 @@
+
+ ⇠
+ 返回
+
diff --git a/pages/knowledge/list.wxss b/pages/knowledge/list.wxss
index 6109e5e..d6edf97 100644
--- a/pages/knowledge/list.wxss
+++ b/pages/knowledge/list.wxss
@@ -1,7 +1,32 @@
.container {
min-height: 100vh;
background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
- padding: 40rpx 30rpx;
+ padding: 140rpx 30rpx;
+}
+
+/* 自定义返回按钮样式 */
+.nav-back {
+ position: absolute;
+ top: 40rpx;
+ left: 30rpx;
+ display: flex;
+ align-items: center;
+ z-index: 100;
+ padding: 10rpx 20rpx;
+ border-radius: 30rpx;
+ background: rgba(255, 255, 255, 0.05);
+}
+
+.back-icon {
+ font-size: 32rpx;
+ margin-right: 8rpx;
+ color: #c9a0dc;
+}
+
+.back-text {
+ font-size: 26rpx;
+ color: #c9a0dc;
+ letter-spacing: 2rpx;
}
.header {
diff --git a/pages/mine/mine.js b/pages/mine/mine.js
new file mode 100644
index 0000000..a3002f5
--- /dev/null
+++ b/pages/mine/mine.js
@@ -0,0 +1,6 @@
+Page({
+ data: {
+ },
+ onLoad: function (options) {
+ }
+})
diff --git a/pages/mine/mine.json b/pages/mine/mine.json
new file mode 100644
index 0000000..947f5d2
--- /dev/null
+++ b/pages/mine/mine.json
@@ -0,0 +1,3 @@
+{
+ "navigationBarTitleText": "我的"
+}
\ No newline at end of file
diff --git a/pages/mine/mine.wxml b/pages/mine/mine.wxml
new file mode 100644
index 0000000..82f26eb
--- /dev/null
+++ b/pages/mine/mine.wxml
@@ -0,0 +1,3 @@
+
+ Mine Page
+
diff --git a/pages/mine/mine.wxss b/pages/mine/mine.wxss
new file mode 100644
index 0000000..93f8d92
--- /dev/null
+++ b/pages/mine/mine.wxss
@@ -0,0 +1 @@
+/* pages/mine/mine.wxss */
diff --git a/pages/privacy-agree/privacy-agree.js b/pages/privacy-agree/privacy-agree.js
new file mode 100644
index 0000000..986ef16
--- /dev/null
+++ b/pages/privacy-agree/privacy-agree.js
@@ -0,0 +1,19 @@
+Page({
+ data: {
+ show: false
+ },
+
+ onLoad() {
+ setTimeout(() => {
+ this.setData({ show: true })
+ }, 100)
+ },
+
+ handleAgree() {
+ wx.setStorageSync('privacyAgreed', true)
+
+ wx.reLaunch({
+ url: '/pages/home/home'
+ })
+ }
+})
diff --git a/pages/privacy-agree/privacy-agree.json b/pages/privacy-agree/privacy-agree.json
new file mode 100644
index 0000000..f31b22d
--- /dev/null
+++ b/pages/privacy-agree/privacy-agree.json
@@ -0,0 +1,4 @@
+{
+ "navigationBarTitleText": "隐私保护提示",
+ "navigationStyle": "default"
+}
\ No newline at end of file
diff --git a/pages/privacy-agree/privacy-agree.wxml b/pages/privacy-agree/privacy-agree.wxml
new file mode 100644
index 0000000..7d0af9a
--- /dev/null
+++ b/pages/privacy-agree/privacy-agree.wxml
@@ -0,0 +1,25 @@
+
+
+
+ 🔮 神秘仪式开启前
+
+
+
+ 在揭开塔罗的神秘面纱之前,
+ 请您阅读并同意《隐私政策》。
+
+ 我们仅在必要范围内收集信息,
+ 用于生成解读指引与积分功能。
+
+
+
+ 查看完整《隐私政策》
+
+
+
+
+
+
+
diff --git a/pages/privacy-agree/privacy-agree.wxss b/pages/privacy-agree/privacy-agree.wxss
new file mode 100644
index 0000000..0243966
--- /dev/null
+++ b/pages/privacy-agree/privacy-agree.wxss
@@ -0,0 +1,85 @@
+/* 整体遮罩背景 */
+page {
+ height: 100%;
+ overflow: hidden;
+}
+
+.overlay {
+ height: 100vh;
+ width: 100vw;
+ background: radial-gradient(circle at top, #1b1b3a, #0d0d1f);
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+
+/* 弹窗卡片 */
+.modal {
+ width: 75%;
+ background: rgba(255, 255, 255, 0.08);
+ backdrop-filter: blur(20rpx);
+ border-radius: 30rpx;
+ padding: 50rpx 40rpx;
+ opacity: 0;
+ transform: translateY(40rpx);
+ transition: all 0.6s cubic-bezier(0.19, 1, 0.22, 1);
+ box-shadow: 0 0 40rpx rgba(122, 92, 255, 0.2);
+ border: 1px solid rgba(255, 255, 255, 0.1);
+}
+
+/* 动画显示 */
+.modal-show {
+ opacity: 1;
+ transform: translateY(0);
+}
+
+/* 标题 */
+.title {
+ font-size: 38rpx;
+ font-weight: bold;
+ color: #ffffff;
+ text-align: center;
+ margin-bottom: 40rpx;
+ text-shadow: 0 2rpx 10rpx rgba(122, 92, 255, 0.5);
+}
+
+/* 内容区域 */
+.content {
+ height: 300rpx;
+ margin-bottom: 50rpx;
+}
+
+/* 文本 */
+.text {
+ font-size: 28rpx;
+ color: #ddddff;
+ line-height: 1.8;
+ text-align: center;
+}
+
+/* 链接 */
+.link {
+ color: #b499ff;
+ margin-top: 30rpx;
+ display: block;
+ text-align: center;
+ text-decoration: underline;
+ font-size: 26rpx;
+}
+
+/* 按钮 */
+.agree-btn {
+ background: linear-gradient(135deg, #7a5cff, #b499ff);
+ color: #ffffff;
+ border-radius: 60rpx;
+ font-size: 32rpx;
+ padding: 10rpx 0;
+ box-shadow: 0 8rpx 30rpx rgba(122, 92, 255, 0.4);
+ font-weight: bold;
+ border: none;
+}
+
+.agree-btn:active {
+ transform: scale(0.96);
+ box-shadow: 0 4rpx 15rpx rgba(122, 92, 255, 0.4);
+}
diff --git a/pages/privacy/privacy.wxml b/pages/privacy/privacy.wxml
index a8d751e..72a8553 100644
--- a/pages/privacy/privacy.wxml
+++ b/pages/privacy/privacy.wxml
@@ -5,135 +5,190 @@
+
引言
- 欢迎使用我们的塔罗占卜小程序。我们非常重视您的隐私保护和个人信息安全。本隐私政策将帮助您了解我们如何收集、使用、存储和保护您的信息。
+
+ 欢迎使用我们的塔罗占卜小程序。本小程序由【XXX】运营。
+ 我们非常重视您的隐私保护和个人信息安全。
+ 在您使用本小程序前,请您仔细阅读并充分理解本隐私政策。
+ 当您点击“同意”并开始使用本小程序时,即表示您已阅读、
+ 理解并同意本政策的全部内容。
+
- 一、信息收集
- 为了向您提供更好的服务,我们可能会收集以下信息:
+ 一、我们收集的信息
+
+ 为向您提供塔罗解读服务,我们可能会收集以下信息:
+
+
•
- 您输入的占卜问题和相关内容
+ 您输入的占卜问题内容
+
•
- 积分记录和使用情况
+ 积分记录与使用情况
+
•
- 广告观看记录(仅用于积分奖励统计)
+ 广告观看记录(仅用于积分奖励统计)
+
•
- 设备信息(用于优化服务体验)
+ 设备基础信息(用于保障运行及优化体验)
- 注: 所有信息仅存储在您的设备本地,我们不会上传到服务器。
+
+
+ 注:除使用第三方AI服务生成解读外,
+ 所有数据默认仅存储在您的设备本地,
+ 我们不会主动上传至自有服务器。
+
- 二、信息使用
- 我们收集的信息将用于:
+ 二、信息的使用目的
+
•
- 提供塔罗占卜解读服务
+ 为您生成塔罗牌解读内容
+
•
- 管理积分系统和奖励机制
+ 管理积分系统与奖励机制
+
•
- 改进和优化用户体验
+ 优化产品功能与用户体验
+
•
- 提供个性化的内容推荐
+ 实现广告奖励功能
- 三、信息存储
- 您的所有数据均通过微信小程序的本地存储功能保存在您的设备上。我们不会将您的个人信息上传至任何外部服务器。数据的保存和删除完全由您控制。
+ 三、信息存储与删除
+
+ 您的塔罗问题、积分记录等数据默认通过微信小程序
+ 本地存储功能保存在您的设备中。
+ 您可以通过删除小程序清除全部本地数据。
+ 我们不会在服务器长期保存您的个人历史记录。
+
- 四、第三方服务
- 为了提供完整的服务功能,我们使用了以下第三方服务:
+ 四、第三方服务说明
+
+ 为实现部分功能,我们可能会使用以下第三方服务:
+
+
•
- DeepSeek AI: 用于生成塔罗牌解读内容。您的问题将被发送至DeepSeek API进行处理,但不会包含任何可识别您身份的信息。
+
+ DeepSeek AI 服务:用于生成塔罗解读内容。
+ 您输入的占卜问题文本将发送至 DeepSeek API 接口进行处理,
+ 仅用于生成解读结果,不会包含您的昵称、头像、
+ 手机号等可识别身份信息。
+
+
•
- 微信激励视频广告: 用于积分奖励功能。广告服务由微信官方提供,遵循微信隐私政策。
+
+ 微信激励视频广告:用于积分奖励功能。
+ 广告服务由微信官方提供,数据处理遵循微信平台相关隐私政策。
+
五、用户权利
- 您拥有以下权利:
+
•
- 随时查看和管理您的积分记录
+ 查看和管理您的积分记录
+
•
- 通过删除小程序清除所有本地数据
+ 选择是否观看广告获取奖励
+
•
- 选择是否观看广告获取积分
+ 删除小程序以清除本地数据
+
•
- 随时停止使用我们的服务
+ 随时停止使用本服务
六、信息安全
- 我们采取合理的安全措施保护您的信息:
+
•
- 使用HTTPS加密传输与AI服务的通信
+ 与AI接口通信采用HTTPS加密传输
+
•
- 不收集任何可直接识别您身份的信息
+ 不收集敏感身份识别信息
+
•
- 遵循微信小程序平台的安全规范
+ 遵循微信小程序平台安全规范
七、未成年人保护
- 我们非常重视未成年人的隐私保护。如果您是未成年人,请在监护人的陪同下使用本小程序。
+
+ 如您为未成年人,请在监护人指导下阅读本政策并使用本服务。
+
- 八、政策更新
- 我们可能会不定期更新本隐私政策。更新后的政策将在小程序内公布,并在页面顶部标注更新日期。继续使用我们的服务即表示您同意更新后的隐私政策。
+ 八、免责声明
+
+ 本小程序提供的塔罗解读内容仅供娱乐和参考,
+ 不构成任何现实决策建议或结果承诺。
+
九、联系我们
- 如果您对本隐私政策有任何疑问、意见或建议,欢迎通过以下方式联系我们:
+
+ 本小程序运营者:XXX
+
+
•
- 在小程序内提供反馈
+ 联系邮箱:xxx@xxx.com
+
•
- 通过微信公众平台留言
+ 反馈方式:小程序内反馈入口
+
diff --git a/pages/privacy/privacy.wxss b/pages/privacy/privacy.wxss
index b795679..dd336a6 100644
--- a/pages/privacy/privacy.wxss
+++ b/pages/privacy/privacy.wxss
@@ -32,6 +32,8 @@
.privacy-content {
height: calc(100vh - 280rpx);
padding: 0 30rpx;
+ box-sizing: border-box;
+ width: 100%;
}
.section {
@@ -40,6 +42,8 @@
padding: 32rpx;
margin-bottom: 24rpx;
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08);
+ box-sizing: border-box;
+ width: 100%;
}
.section-title {
diff --git a/pages/settings/settings.js b/pages/settings/settings.js
new file mode 100644
index 0000000..b727b93
--- /dev/null
+++ b/pages/settings/settings.js
@@ -0,0 +1,55 @@
+
+Page({
+ clearCache() {
+ wx.showModal({
+ title: '确认清除',
+ content: '将清除所有本地数据,包括积分记录,是否继续?',
+ success(res) {
+ if (res.confirm) {
+ try {
+ wx.clearStorageSync()
+ wx.showToast({
+ title: '已清除',
+ icon: 'none'
+ })
+ // Consider re-initializing necessary keys if needed, or just let app.js handle it on next launch
+ } catch (e) {
+ wx.showToast({
+ title: '清除失败',
+ icon: 'none'
+ })
+ }
+ }
+ }
+ })
+ },
+
+ revokePrivacy() {
+ wx.showModal({
+ title: '撤销隐私授权',
+ content: '撤销后将重置隐私协议状态,下次启动需重新同意,是否继续?',
+ success(res) {
+ if (res.confirm) {
+ try {
+ wx.removeStorageSync('privacyAgreed')
+ wx.showToast({
+ title: '已撤销',
+ icon: 'none'
+ })
+ // 延迟跳转,确保提示显示
+ setTimeout(() => {
+ wx.reLaunch({
+ url: '/pages/privacy-agree/privacy-agree'
+ })
+ }, 1500)
+ } catch (e) {
+ wx.showToast({
+ title: '操作失败',
+ icon: 'none'
+ })
+ }
+ }
+ }
+ })
+ }
+})
diff --git a/pages/settings/settings.json b/pages/settings/settings.json
new file mode 100644
index 0000000..d3feda7
--- /dev/null
+++ b/pages/settings/settings.json
@@ -0,0 +1,6 @@
+{
+ "navigationBarTitleText": "设置",
+ "navigationStyle": "default",
+ "navigationBarBackgroundColor": "#0d0d1f",
+ "navigationBarTextStyle": "white"
+}
\ No newline at end of file
diff --git a/pages/settings/settings.wxml b/pages/settings/settings.wxml
new file mode 100644
index 0000000..5d2d7f0
--- /dev/null
+++ b/pages/settings/settings.wxml
@@ -0,0 +1,39 @@
+
+
+
+
+
+ 账户与数据
+
+
+ 清除本地数据
+ >
+
+
+
+ 撤销隐私授权
+ >
+
+
+
+
+
+ 协议与说明
+
+
+ 隐私政策
+ >
+
+
+
+ 用户协议
+ >
+
+
+
+ 当前版本
+ v1.0.0
+
+
+
+
diff --git a/pages/settings/settings.wxss b/pages/settings/settings.wxss
new file mode 100644
index 0000000..c9dc57c
--- /dev/null
+++ b/pages/settings/settings.wxss
@@ -0,0 +1,35 @@
+
+.settings-container {
+ padding: 30rpx;
+ background: #0d0d1f;
+ min-height: 100vh;
+}
+
+.group {
+ margin-bottom: 40rpx;
+ background: rgba(255,255,255,0.06);
+ border-radius: 20rpx;
+ padding: 0 20rpx;
+}
+
+.group-title {
+ font-size: 24rpx;
+ color: #b499ff;
+ margin-bottom: 10rpx;
+ padding-left: 10rpx;
+ padding-top: 20rpx;
+}
+
+.item {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 30rpx 10rpx;
+ border-bottom: 1rpx solid rgba(255,255,255,0.05);
+ color: #ffffff;
+ font-size: 28rpx;
+}
+
+.item:last-child {
+ border-bottom: none;
+}
diff --git a/pages/user-agreement/user-agreement.js b/pages/user-agreement/user-agreement.js
new file mode 100644
index 0000000..4aecb77
--- /dev/null
+++ b/pages/user-agreement/user-agreement.js
@@ -0,0 +1,8 @@
+Page({
+ data: {
+
+ },
+ onLoad(options) {
+
+ }
+})
diff --git a/pages/user-agreement/user-agreement.json b/pages/user-agreement/user-agreement.json
new file mode 100644
index 0000000..719e356
--- /dev/null
+++ b/pages/user-agreement/user-agreement.json
@@ -0,0 +1,3 @@
+{
+ "navigationBarTitleText": "用户协议"
+}
\ No newline at end of file
diff --git a/pages/user-agreement/user-agreement.wxml b/pages/user-agreement/user-agreement.wxml
new file mode 100644
index 0000000..9cdb3c8
--- /dev/null
+++ b/pages/user-agreement/user-agreement.wxml
@@ -0,0 +1,156 @@
+
+
+
+
+
+
+ 一、协议说明
+
+ 欢迎使用本塔罗占卜小程序。本小程序由【XXX运营者名称】开发和运营。
+ 在您使用本服务前,请您仔细阅读本协议全部内容。
+ 当您点击“同意”或实际使用本服务,即表示您已阅读、
+ 理解并同意受本协议约束。
+
+
+
+
+ 二、服务内容
+
+ 本小程序为娱乐性质的塔罗解读服务,
+ 通过人工智能技术生成塔罗牌解读内容。
+ 所有解读内容仅供娱乐和参考,
+ 不构成任何现实决策建议、投资建议、
+ 医疗建议或法律建议。
+
+
+
+
+ 三、用户行为规范
+
+
+ •
+ 不得利用本服务发布违法、违规内容
+
+
+
+ •
+ 不得利用本服务进行欺诈或恶意行为
+
+
+
+ •
+ 不得尝试破坏系统安全或恶意攻击接口
+
+
+
+ •
+ 不得批量抓取或复制生成内容用于商业用途
+
+
+
+
+ 四、AI内容免责声明(重要提示)
+
+
+ 本小程序提供的塔罗解读内容由人工智能系统自动生成,
+ 基于算法模型对塔罗象征意义进行语言表达,
+ 不代表真实占卜师的专业判断。
+
+
+
+ 所有解读结果仅供娱乐和文化参考,
+ 不构成任何形式的现实建议,
+ 包括但不限于投资建议、医疗建议、
+ 心理咨询建议、法律建议或情感决策建议。
+
+
+
+ 人工智能生成内容可能存在理解偏差、
+ 信息不完整或表达不准确的情况,
+ 我们不对解读结果的准确性、完整性、
+ 时效性或适用性作任何保证。
+
+
+
+ 因依赖或使用解读内容所产生的任何直接或间接后果,
+ 包括经济损失、决策失误或其他损害,
+ 均由用户自行承担责任。
+
+
+
+ 如您对生成内容存在疑问,
+ 请理性判断并结合现实情况作出决策。
+
+
+
+ 本服务不提供预测未来、保证结果或改变现实结果的能力。
+ 塔罗解读仅作为象征性表达与自我思考工具。
+
+
+
+
+ 五、积分与广告机制
+
+ 本小程序采用积分机制提供服务。
+ 用户可通过观看微信官方激励视频广告获得积分奖励。
+ 积分仅用于本小程序内使用,不可兑换现金或转让。
+
+
+
+
+ 六、知识产权
+
+ 本小程序的界面设计、功能结构、代码、品牌标识等
+ 均归【XXX运营者名称】所有。
+ 未经许可,不得擅自复制、传播或用于商业用途。
+
+
+
+
+ 七、责任限制
+
+ 因使用本服务所产生的任何直接或间接损失,
+ 包括但不限于决策失误、投资损失等,
+ 运营方不承担任何法律责任。
+ 如因不可抗力或系统维护导致服务中断,
+ 我们不承担由此产生的损失。
+
+
+
+
+ 八、协议修改
+
+ 我们有权根据法律法规或运营需要对本协议进行修改。
+ 修改后的协议将在小程序内公布。
+ 您继续使用本服务即视为接受更新后的协议内容。
+
+
+
+
+ 九、联系我们
+
+ 如您对本协议有任何疑问或建议,请联系:
+
+
+
+ •
+ 运营者名称:【XXX运营者名称】
+
+
+
+ •
+ 联系邮箱:【xxx@xxx.com】
+
+
+
+
+
+
+
diff --git a/pages/user-agreement/user-agreement.wxss b/pages/user-agreement/user-agreement.wxss
new file mode 100644
index 0000000..6f17e85
--- /dev/null
+++ b/pages/user-agreement/user-agreement.wxss
@@ -0,0 +1,112 @@
+/* 协议页面样式 - 优化阅读体验 */
+
+
+.agreement-container {
+ min-height: 100vh;
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+ padding-bottom: 40rpx;
+}
+
+.agreement-header {
+ text-align: center;
+ padding: 60rpx 40rpx;
+ background: rgba(255, 255, 255, 0.95);
+ margin-bottom: 20rpx;
+ box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.05);
+ margin: 40rpx 30rpx 30rpx;
+ border-radius: 20rpx;
+}
+
+.agreement-title {
+ display: block;
+ font-size: 40rpx;
+ font-weight: bold;
+ color: #2d3748;
+ margin-bottom: 16rpx;
+ letter-spacing: 2rpx;
+}
+
+.update-date {
+ display: block;
+ font-size: 24rpx;
+ color: #a0aec0;
+}
+
+.agreement-content {
+ height: calc(100vh - 240rpx);
+ padding: 0 30rpx;
+ box-sizing: border-box;
+}
+
+.section {
+ background: rgba(255, 255, 255, 0.95);
+ border-radius: 16rpx;
+ padding: 40rpx;
+ margin-bottom: 30rpx;
+ box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.03);
+}
+
+.section-title {
+ display: block;
+ font-size: 32rpx;
+ font-weight: 600;
+ color: #2d3748;
+ margin-bottom: 24rpx;
+ position: relative;
+ padding-left: 20rpx;
+}
+
+.section-title::before {
+ content: '';
+ position: absolute;
+ left: 0;
+ top: 8rpx;
+ bottom: 8rpx;
+ width: 8rpx;
+ background: #667eea;
+ border-radius: 4rpx;
+}
+
+.section-text {
+ display: block;
+ font-size: 28rpx;
+ color: #4a5568;
+ line-height: 1.8;
+ text-align: justify;
+ margin-bottom: 10rpx;
+}
+
+.list-item {
+ display: flex;
+ margin-bottom: 16rpx;
+ align-items: flex-start;
+}
+
+.bullet {
+ color: #667eea;
+ font-size: 24rpx; /* Smaller bullet for subtleness */
+ margin-right: 16rpx;
+ margin-top: 6rpx; /* Align with text */
+ flex-shrink: 0;
+}
+
+.list-text {
+ flex: 1;
+ font-size: 28rpx;
+ color: #4a5568;
+ line-height: 1.8;
+ text-align: justify;
+}
+
+.footer {
+ text-align: center;
+ padding: 60rpx 40rpx;
+ margin-top: 40rpx;
+}
+
+.footer-text {
+ display: block;
+ font-size: 26rpx;
+ color: #a0aec0;
+ letter-spacing: 1rpx;
+}
diff --git a/pages/zodiac/index.js b/pages/zodiac/index.js
index 94b383a..a0a7dbf 100644
--- a/pages/zodiac/index.js
+++ b/pages/zodiac/index.js
@@ -1,326 +1,78 @@
+const { getZodiacList } = require('../../utils/zodiacData');
+const { fetchZodiacFortune, fetchDailyOverview } = require('../../utils/zodiacAI');
+const { checkShareReward } = require('../../utils/pointsManager');
+
Page({
data: {
selectedZodiac: null,
- currentFortune: null, // { keyword, today, lucky, notice, match, action, summary }
- isMatchExpanded: false, // 控制关系提示的展开状态
+ currentFortune: null,
+ isLoading: false,
+ isMatchExpanded: false,
+ zodiacList: [],
+ dailyOverview: null // 新增:星象概览
+ },
- // 12星座数据 - 增加 summary 字段
- zodiacList: [
- {
- name: '白羊座',
- symbol: '♈',
- range: '3.21 – 4.19',
- fortunes: [
- {
- keyword: '开启',
- today: '感觉能量在一点点回升,像温柔的晨光,正如适合开启一个小计划。',
- lucky: '试着做一件从未做过的小事,哪怕只是换条路漫步回家。',
- notice: '稍微慢下来也没关系,深呼吸,给自己一点缓冲的时间。',
- action: '也许可以尝试一项简单的运动,或者把那个想了很久的小决定做了。',
- match: '狮子座',
- summary: '整体氛围积极向上,适宜迈出新的一步。'
- },
- {
- keyword: '直觉',
- today: '直觉敏锐的一天,内心的声音会温柔地指引你去对的地方。',
- lucky: '流一点汗,让身体的能量自由流动起来。',
- notice: '倾听也是一种力量,试着先听听别人的想法。',
- action: '相信你的第一反应,今天不需要过度分析,跟着感觉走就好。',
- match: '射手座',
- summary: '这是一个依靠感性而非逻辑的时刻,信任直觉。'
- }
- ]
- },
- {
- name: '金牛座',
- symbol: '♉',
- range: '4.20 – 5.20',
- fortunes: [
- {
- keyword: '安稳',
- today: '享受当下的安稳就好,物质的触感能带给你实实在在的安全感。',
- lucky: '一杯温热的茶,或是一顿用心准备的晚餐,都是很好的滋养。',
- notice: '柔软一点,你会发现世界比想象中更宽阔。',
- action: '花点时间整理一下钱包或书桌,有序的环境会让你感到平静。',
- match: '处女座',
- summary: '平稳是今日的主基调,无需向外过多索求。'
- },
- {
- keyword: '秩序',
- today: '按部就班也很好,秩序感会让你感到踏实和放松。',
- lucky: '在整理收纳中梳理思绪,享受物品归位的快乐。',
- notice: '试着松开手,有时候放手反而能拥有更多。',
- action: '去做一次舒缓的按摩,或者仅仅是静静地听一段白噪音。',
- match: '摩羯座',
- summary: '在规则与秩序中能找到内心的宁静。'
- }
- ]
- },
- {
- name: '双子座',
- symbol: '♊',
- range: '5.21 – 6.21',
- fortunes: [
- {
- keyword: '灵感',
- today: '思维很活跃,灵感像小火花一样在闪烁。',
- lucky: '翻翻新书的目录,或和陌生人简单聊几句。',
- notice: '试着一次只做一件事情,专注会让你更舒服。',
- action: '随身带一个小本子,记录下今天那些有趣的小念头。',
- match: '水瓶座',
- summary: '思维跳跃的一天,由于灵感的迸发而显得生动。'
- },
- {
- keyword: '表达',
- today: '沟通的桥梁已经架好,适合真实而轻松地表达自己。',
- lucky: '记录下脑海中一闪而过的念头,它们很珍贵。',
- notice: '有时候稍微沉默一下,给自己留点空间。',
- action: '给许久未见的老朋友发个信息,简单的问候就很好。',
- match: '天秤座',
- summary: '适宜交流与分享,信息的流动会带来新的机会。'
- }
- ]
- },
- {
- name: '巨蟹座',
- symbol: '♋',
- range: '6.22 – 7.22',
- fortunes: [
- {
- keyword: '疗愈',
- today: '情感细腻丰富,适合向内探索,疗愈旧日的伤口。',
- lucky: '去水边走走,水的包容会让你感到平静。',
- notice: '保护好自己的情绪边界,不用对所有人的话都太在意。',
- action: '今晚给自己做一顿暖胃的食物,或者泡一个舒服的热水澡。',
- match: '双鱼座',
- summary: '向内关注自我,是一个适合自我修复的温和日子。'
- },
- {
- keyword: '关怀',
- today: '温柔是你的铠甲,你对他人的关怀也会回流到自己身上。',
- lucky: '给家人打个电话,或者照顾一株植物。',
- notice: '过去已去,当下才是最真实的,试着活在此时此刻。',
- action: '整理一下旧照片,保留快乐的记忆就好。',
- match: '天蝎座',
- summary: '被温柔的情绪包围,付出与接受都自然发生。'
- }
- ]
- },
- {
- name: '狮子座',
- symbol: '♌',
- range: '7.23 – 8.22',
- fortunes: [
- {
- keyword: '舞台',
- today: '自信的光芒很美,你本身就是舞台的中心。',
- lucky: '穿一件喜欢的亮色衣服,或者大方地接受别人的赞美。',
- notice: '真正的王者懂得示弱的艺术,柔软也是一种力量。',
- action: '对着镜子里的自己微笑,肯定自己的一个优点。',
- match: '白羊座',
- summary: '光芒外露,适宜展示自我,但也需张弛有度。'
- },
- {
- keyword: '创造',
- today: '创造力在涌动,与其等待机会,不如自己创造一个小舞台。',
- lucky: '像孩子一样去玩耍,画画或者唱歌都很棒。',
- notice: '保持谦逊,你会看到更多不一样的风景。',
- action: '尝试一种新的娱乐方式,或者去一个从未去过的店。',
- match: '射手座',
- summary: '创造力充沛,是表达个性和释放天性的好时机。'
- }
- ]
- },
- {
- name: '处女座',
- symbol: '♍',
- range: '8.23 – 9.22',
- fortunes: [
- {
- keyword: '清晰',
- today: '逻辑很清晰,能看透事物的本质,混乱将离你而去。',
- lucky: '列一张简单的清单,每划掉一项都是一种治愈。',
- notice: '对自己宽容一点,完美是一个方向,而不是必须到达的终点。',
- action: '清理手机里无用的截图和APP,数字极简也能带来清爽。',
- match: '金牛座',
- summary: '条理清晰,事半功倍,适合处理复杂的细节事务。'
- },
- {
- keyword: '服务',
- today: '助人的愿望很美好,你的细心能帮到很多人。',
- lucky: '做一次深度的清洁,无论是环境还是心灵。',
- notice: '偶尔也要抬头看看森林,不要总是盯着细节看。',
- action: '在这个周末,尝试“一次只做一件事”,体验专注的快乐。',
- match: '摩羯座',
- summary: '在付出中获得满足感,但也需注意微观与宏观的平衡。'
- }
- ]
- },
- {
- name: '天秤座',
- symbol: '♎',
- range: '9.23 – 10.23',
- fortunes: [
- {
- keyword: '平衡',
- today: '追求和谐与美,在平衡中找到内心的宁静。',
- lucky: '去美术馆逛逛,或者欣赏一首优美的乐曲。',
- notice: '不要为了取悦他人而委屈自己,温和地拒绝也是可以的。',
- action: '更换一下手机或电脑的壁纸,换成一张让你觉得美的图片。',
- match: '双子座',
- summary: '适宜在审美与艺术中寻找平衡,享受片刻的优雅。'
- },
- {
- keyword: '连接',
- today: '人际关系很顺畅,适合化解误会,建立新的连接。',
- lucky: '买一束花插在瓶中,为生活增添一点仪式感。',
- notice: '犹豫不决时,抛硬币也是一种把命运交给天意的智慧。',
- action: '主动赞美身边的一个人,真诚的赞美会让大家都很开心。',
- match: '水瓶座',
- summary: '良性的互动会带来好运,人际关系是今日的重点。'
- }
- ]
- },
- {
- name: '天蝎座',
- symbol: '♏',
- range: '10.24 – 11.22',
- fortunes: [
- {
- keyword: '洞察',
- today: '洞察力很强,能看穿表象,直达事物的核心。',
- lucky: '在日记本里写下秘密,或者进行一次深刻的冥想。',
- notice: '放下执念,学会像蛇蜕皮一样重生。',
- action: '读一本悬疑小说或者看一部深度电影,满足你的探索欲。',
- match: '巨蟹座',
- summary: '直觉与洞察力并存,适合深入思考而非浅尝辄止。'
- },
- {
- keyword: '坚定',
- today: '意志力坚定,现在是攻克难题的好时机。',
- lucky: '独处,享受一个人的高质量时光。',
- notice: '试着交付一点信任,你会发现没有那么多需要防备的事。',
- action: '尝试与一个信任的人进行一次深度谈话,不设防的那种。',
- match: '双鱼座'
- }
- ]
- },
- {
- name: '射手座',
- symbol: '♐',
- range: '11.23 – 12.21',
- fortunes: [
- {
- keyword: '自由',
- today: '视野开阔,心向远方,自由的感觉真好。',
- lucky: '规划一次未来的旅行,或者看一部异国电影。',
- notice: '承诺之前先想一下,不要因为一时兴起而许下诺言。',
- action: '去户外走走,甚至只是去楼下公园转一圈,看看天空。',
- match: '白羊座',
- summary: '心向自由,适合拓展视野,不宜被琐事困住眼界。'
- },
- {
- keyword: '乐观',
- today: '乐观的精神很有感染力,你是身边人的开心果。',
- lucky: '去户外奔跑,去接触大自然和新鲜空气。',
- notice: '检查一下随身物品,细心一点能避免小麻烦。',
- action: '学习一个全新的冷知识,或者尝试一种异国料理。',
- match: '狮子座',
- summary: '积极乐观的一天,行动力是好运的来源。'
- }
- ]
- },
- {
- name: '摩羯座',
- symbol: '♑',
- range: '12.22 – 1.19',
- fortunes: [
- {
- keyword: '踏实',
- today: '脚踏实地,每一步都算数,成就感源于自律。',
- lucky: '制定一个长期的目标,并迈出第一步。',
- notice: '不要把自己逼得太紧,工作之余也要学会“虚度时光”。',
- action: '复盘一下本周的计划,把完成的事项画上大大的勾。',
- match: '金牛座',
- summary: '耕耘即有收获,适合专注于当下脚踏实地的积累。'
- },
- {
- keyword: '权威',
- today: '权威感提升,你的专业度会得到大家的认可。',
- lucky: '向一位长辈或导师请教,汲取传统的智慧。',
- notice: '给生活加点糖,不用总是那么严肃。',
- action: '给自己泡一杯好茶或好咖啡,在工作间隙享受片刻宁静。',
- match: '处女座',
- summary: '专业与稳重是今日的通行证,但也需适度放松。'
- }
- ]
- },
- {
- name: '水瓶座',
- symbol: '♒',
- range: '1.20 – 2.18',
- fortunes: [
- {
- keyword: '创意',
- today: '特立独行的一天,你的怪念头也许就是天才的创意。',
- lucky: '尝试一种新的科技产品,或者研究一个小众领域。',
- notice: '给身边人一点温度,理智之外也需要温情。',
- action: '去浏览一些前沿科技或艺术资讯,给大脑“充充电”。',
- match: '双子座',
- summary: '思维活跃且独特,适合进行创造性的脑力活动。'
- },
- {
- keyword: '理想',
- today: '为了理想而战,你的视野超越了当下,看向未来。',
- lucky: '参加一个社群活动,寻找志同道合的伙伴。',
- notice: '保持开放的心态,固执己见和坚持真理只有一线之隔。',
- action: '换一条平时不走的路去上班/回家,观察沿途的新风景。',
- match: '天秤座',
- summary: '目光长远,适合规划未来,不宜纠结于眼前的小节。'
- }
- ]
- },
- {
- name: '双鱼座',
- symbol: '♓',
- range: '2.19 – 3.20',
- fortunes: [
- {
- keyword: '灵感',
- today: '梦幻与现实的边界模糊,灵感如潮水般涌来。',
- lucky: '听海浪的声音,或者在睡前读一首诗。',
- notice: '勇敢面对现实问题,比躲进幻想更有效。',
- action: '听一首纯音乐,闭上眼睛想象一个完美的场景。',
- match: '巨蟹座',
- summary: '感受力极强的一天,适合艺术创作与精神探索。'
- },
- {
- keyword: '同理心',
- today: '同理心爆棚,你能轻易感知他人的悲喜。',
- lucky: '做一件善事,哪怕只是给流浪猫一点食物。',
- notice: '学会自我净化,不要做情绪的海绵。',
- action: '写下一件让你感到焦虑的事,然后把纸条撕碎扔掉。',
- match: '天蝎座',
- summary: '情感流动充沛,在关怀他人的同时也需照顾好自己。'
- }
- ]
+ onLoad: async function () {
+ this.setData({
+ zodiacList: getZodiacList()
+ });
+
+ // 加载星象概览
+ const overview = await fetchDailyOverview();
+ this.setData({ dailyOverview: overview });
+ },
+
+ // 返回上一页或列表
+ goBack: function () {
+ console.log('[Zodiac] goBack triggered');
+ if (this.data.selectedZodiac) {
+ // 如果在详情页,返回列表
+ this.setData({
+ selectedZodiac: null
+ });
+ } else {
+ // 如果在列表页,尝试返回上一页
+ const pages = getCurrentPages();
+ if (pages.length > 1) {
+ wx.navigateBack({
+ delta: 1
+ });
+ } else {
+ // 如果是直接打开(如分享进入),则返回首页
+ wx.reLaunch({
+ url: '/pages/home/home'
+ });
}
- ]
+ }
},
// 选择星座
- selectZodiac: function (e) {
+ selectZodiac: async function (e) {
const index = e.currentTarget.dataset.index;
const zodiac = this.data.zodiacList[index];
- const randomIdx = Math.floor(Math.random() * zodiac.fortunes.length);
- const fortuneData = zodiac.fortunes[randomIdx];
-
+ // 1. 设置加载状态 & 选中星座
this.setData({
selectedZodiac: zodiac,
- currentFortune: fortuneData,
- isMatchExpanded: false // 重置展开状态
+ currentFortune: null, // 清空旧数据
+ isLoading: true, // 开启 Loading
+ isMatchExpanded: false
});
+
+ // 2. 获取运势 (AI 或 缓存)
+ try {
+ const fortuneData = await fetchZodiacFortune(zodiac.name);
+
+ // 3. 渲染数据
+ this.setData({
+ currentFortune: fortuneData,
+ isLoading: false
+ });
+ } catch (err) {
+ console.error('获取运势失败', err);
+ this.setData({ isLoading: false });
+ wx.showToast({ title: '网络小差,请重试', icon: 'none' });
+ }
},
// 切换关系提示展开状态
@@ -335,7 +87,48 @@ Page({
this.setData({
selectedZodiac: null,
currentFortune: null,
+ isLoading: false,
isMatchExpanded: false // 重置展开状态
});
+ },
+
+ // 跳转回塔罗页面
+ goToTarot: function () {
+ wx.navigateTo({
+ url: '/pages/index/index'
+ });
+ },
+
+ /**
+ * 用户点击右上角分享
+ */
+ onShareAppMessage: function () {
+ const titles = [
+ "我的今日星象运势竟然是...",
+ "宇宙刚刚给我发了一条星语指引 ✨",
+ "准到离谱!快来看看你的今日星象",
+ "这是我此刻的星象能量状态 🌟",
+ "为你抽取了一份宇宙星象指引"
+ ];
+ const randomTitle = titles[Math.floor(Math.random() * titles.length)];
+
+ // 尝试发放分享奖励
+ const rewardResult = checkShareReward();
+ if (rewardResult.success) {
+ wx.showToast({
+ title: rewardResult.message,
+ icon: 'none',
+ duration: 2000
+ });
+ }
+
+ // 模拟生成 fromUserId
+ const mockUserId = 'user_' + Math.random().toString(36).substr(2, 9);
+
+ return {
+ title: randomTitle,
+ path: `/pages/zodiac/index?fromUserId=${mockUserId}`,
+ imageUrl: '/images/share-cover.png' // 使用统一的分享图或后续专用图
+ };
}
})
diff --git a/pages/zodiac/index.wxml b/pages/zodiac/index.wxml
index 2d07997..7c2ddae 100644
--- a/pages/zodiac/index.wxml
+++ b/pages/zodiac/index.wxml
@@ -1,7 +1,24 @@
+
+
+ ⇠
+ 返回
+
+
+
+
+ 今日星象概览
+ {{dailyOverview.content}}
+
+
+ {{item}}
+
+
+
+
@@ -14,64 +31,117 @@
-
-
+
+
+ {{selectedZodiac.symbol}}
+ 正在接收宇宙讯息...
+
+
+
+
-
+
-
-
+
+
✨ 今日关键词
{{currentFortune.keyword}}
-
-
-
-
- ✨ 今日运势
- {{currentFortune.today}}
-
-
-
-
- 🍀 幸运提示
- {{currentFortune.lucky}}
-
-
-
-
- 💡 注意事项
- {{currentFortune.notice}}
-
-
-
-
- 🌱 今日行动建议
- {{currentFortune.action}}
-
-
-
-
-
- {{isMatchExpanded ? '收起关系提示' : '🌸 今日关系提示(点击查看)'}}
-
-
- 今天,与你能量更顺的星座是:
- {{currentFortune.match}}
+
+ 🌙 今日核心能量
+ {{currentFortune.core_energy}}
+
+
+
+
+ 📊 运势指数
+
+
+ 综合
+
+
+ {{item <= currentFortune.ratings.overall ? '★' : '☆'}}
+
+
+
+
+ 爱情
+
+
+ {{item <= currentFortune.ratings.love ? '★' : '☆'}}
+
+
+
+
+ 事业
+
+
+ {{item <= currentFortune.ratings.career ? '★' : '☆'}}
+
+
+
+
+ 财运
+
+
+ {{item <= currentFortune.ratings.wealth ? '★' : '☆'}}
+
+
+
+
+
+
+
+
+ ❤️ 感情运势
+ {{currentFortune.fortune_text.love}}
+
+
+
+ 💼 事业运势
+ {{currentFortune.fortune_text.career}}
+
+
+
+ 💰 财运提醒
+ {{currentFortune.fortune_text.wealth}}
+
+
+
+
+
+
+ 🎨 幸运元素
+
+ 颜色:{{currentFortune.lucky_elements.color}}
+ 数字:{{currentFortune.lucky_elements.number}}
+ 时间:{{currentFortune.lucky_elements.time}}
+
+
+
+
+
+ 🌿 今日行动建议
+ {{currentFortune.action}}
+
+
-
- {{currentFortune.summary}}
-
-
- ⬅ 选其他星座
+
+ ⬅ 选其他星座
+
+ 前往塔罗验证能量
+
+
+
+ 内容仅供娱乐与参考,不构成现实决策依据
diff --git a/pages/zodiac/index.wxss b/pages/zodiac/index.wxss
index 02434f1..994f136 100644
--- a/pages/zodiac/index.wxss
+++ b/pages/zodiac/index.wxss
@@ -2,24 +2,119 @@
page {
background-color: #1a1a2e;
height: 100%;
- color: #fff;
+ box-sizing: border-box;
}
.container {
- padding: 30px 20px;
+ padding: 100rpx 40rpx 60rpx; /* Increased top padding to avoid overlap */
box-sizing: border-box;
min-height: 100%;
display: flex;
flex-direction: column;
}
+/* 自定义返回按钮样式 (同塔罗页) */
+.nav-back {
+ position: absolute;
+ top: 30rpx;
+ left: 30rpx;
+ display: flex;
+ align-items: center;
+ z-index: 100;
+ padding: 10rpx 20rpx;
+ border-radius: 30rpx;
+ background: rgba(255, 255, 255, 0.05);
+}
+
+.back-icon {
+ font-size: 32rpx;
+ margin-right: 8rpx;
+ color: #c9a0dc;
+}
+
+.back-text {
+ font-size: 26rpx;
+ color: #c9a0dc;
+ letter-spacing: 2rpx;
+}
+
+/* --- 加载状态样式 --- */
+.loading-container {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ padding-bottom: 100rpx;
+}
+
+.loading-symbol {
+ font-size: 60px;
+ color: #e94560;
+ margin-bottom: 20px;
+ animation: breathe 2s infinite alternate;
+}
+
+.loading-text {
+ font-size: 16px;
+ color: rgba(255, 255, 255, 0.7);
+ letter-spacing: 2px;
+}
+
+@keyframes breathe {
+ 0% { transform: scale(0.9); opacity: 0.7; text-shadow: 0 0 10px rgba(233, 69, 96, 0.3); }
+ 100% { transform: scale(1.1); opacity: 1; text-shadow: 0 0 25px rgba(233, 69, 96, 0.8); }
+}
+
/* --- 列表状态样式 --- */
+.daily-overview {
+ background: rgba(255, 255, 255, 0.05); /* Unified dark theme background */
+ border-radius: 12px;
+ padding: 15px; /* Reduced padding */
+ margin-bottom: 20px; /* Reduced margin */
+ border: 1px solid rgba(255, 255, 255, 0.1);
+ animation: slideUp 0.6s ease;
+}
+
+.overview-title {
+ font-size: 15px; /* SLightly smaller */
+ font-weight: bold;
+ color: #fff; /* White text */
+ margin-bottom: 8px;
+}
+
+.overview-content {
+ font-size: 12px;
+ color: rgba(255, 255, 255, 0.8); /* Light grey text */
+ line-height: 1.5;
+ margin-bottom: 10px;
+ text-align: justify;
+}
+
+.overview-tags {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 6px;
+}
+
+.tag-item {
+ font-size: 10px;
+ background-color: rgba(255, 255, 255, 0.1); /* Darker tag bg */
+ color: #a29bfe; /* Light purple tag text */
+ padding: 3px 8px;
+ border-radius: 10px;
+ font-weight: 500;
+ border: 1px solid rgba(162, 155, 254, 0.3);
+}
+
.header-tip {
- font-size: 20px;
- margin-bottom: 30px;
+ font-size: 16px; /* Smaller header */
+ margin-bottom: 15px; /* Reduced margin */
text-align: center;
- opacity: 0.9;
+ color: #fff;
+ opacity: 1;
letter-spacing: 1px;
+ font-weight: bold;
}
.grid-container {
@@ -30,31 +125,35 @@ page {
.zodiac-item {
width: 30%; /* 三列布局 */
- background-color: rgba(255, 255, 255, 0.05);
- margin-bottom: 20px;
- padding: 20px 0;
- border-radius: 12px;
+ background-color: rgba(255, 255, 255, 0.08);
+ margin-bottom: 12px; /* Reduced margin */
+ padding: 12px 0; /* Reduced padding */
+ border-radius: 10px;
display: flex;
flex-direction: column;
align-items: center;
- border: 1px solid rgba(255, 255, 255, 0.05);
+ border: 1px solid rgba(255, 255, 255, 0.1);
cursor: pointer;
}
.zodiac-symbol {
- font-size: 28px;
- margin-bottom: 5px;
+ font-size: 24px; /* Smaller symbol */
+ margin-bottom: 4px;
+ color: rgb(240, 240, 255);
+ text-shadow: 0 0 10px rgba(255, 255, 255, 0.3);
}
.zodiac-name {
- font-size: 14px;
- opacity: 0.8;
+ font-size: 12px; /* Smaller name */
+ color: #fff;
+ opacity: 1;
+ font-weight: 500;
}
.zodiac-range {
- font-size: 10px;
- opacity: 0.5;
- margin-top: 3px;
+ font-size: 9px; /* Smaller range */
+ color: rgba(255, 255, 255, 0.6);
+ margin-top: 2px;
}
/* --- 结果状态样式 --- */
@@ -83,7 +182,11 @@ page {
.today-title {
font-size: 18px;
- opacity: 0.8;
+ color: #fff;
+ opacity: 1;
+ font-weight: 500;
+ letter-spacing: 2px;
+ text-shadow: 0 2px 4px rgba(0, 0, 0, 0.5);
}
.fortune-card {
@@ -99,84 +202,194 @@ page {
flex-direction: column;
}
-/* 0. 关键词卡片样式 */
-.keyword-card {
- background-color: rgba(0, 0, 0, 0.2);
- border-radius: 12px;
- padding: 15px;
+/* --- 新版结果展示样式 --- */
+.keyword-section {
display: flex;
flex-direction: column;
align-items: center;
- margin-bottom: 25px;
- border: 1px solid rgba(255, 255, 255, 0.05);
+ margin-bottom: 20px;
}
.keyword-label {
font-size: 12px;
color: #a29bfe;
- margin-bottom: 5px;
opacity: 0.8;
+ margin-bottom: 5px;
}
.keyword-text {
- font-size: 32px; /* 进一步加大关键词字号 */
+ font-size: 36px;
color: #fff;
font-weight: bold;
letter-spacing: 4px;
- margin-top: 5px;
text-shadow: 0 2px 10px rgba(0,0,0,0.3);
+ margin-bottom: 15px;
}
-/* 三段式内容的样式 */
-.section {
+.core-energy {
+ background: rgba(255, 255, 255, 0.05);
+ padding: 10px 15px;
+ border-radius: 8px;
+ width: 100%;
+ box-sizing: border-box;
+}
+
+.energy-label {
+ display: block;
+ font-size: 12px;
+ color: #fbaceb;
+ margin-bottom: 4px;
+}
+
+.energy-text {
+ font-size: 14px;
+ color: #fff;
+ line-height: 1.5;
+}
+
+.divider {
+ width: 100%;
+ height: 1px;
+ background: rgba(255, 255, 255, 0.1);
+ margin: 20px 0;
+}
+
+.section-block {
+ margin-bottom: 25px;
+ width: 100%;
+}
+
+.section-title {
+ display: block;
+ font-size: 15px;
+ color: #e94560;
+ font-weight: bold;
+ margin-bottom: 10px;
+}
+
+.section-content {
+ font-size: 14px;
+ color: rgba(255, 255, 255, 0.9);
+ line-height: 1.6;
+ text-align: left;
+}
+
+/* 评分网格 */
+.rating-grid {
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: space-between;
+}
+
+.rating-item {
+ width: 48%;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 8px;
+ background: rgba(0,0,0,0.2);
+ padding: 8px 10px;
+ border-radius: 6px;
+ box-sizing: border-box;
+}
+
+.rating-label {
+ font-size: 12px;
+ color: rgba(255,255,255,0.7);
+}
+
+.stars {
+ font-size: 12px;
+ color: #ffd700;
+ letter-spacing: 2px;
+}
+
+/* 幸运元素 */
+.lucky-grid {
display: flex;
flex-direction: column;
- margin-bottom: 25px;
- border-bottom: 1px dashed rgba(255, 255, 255, 0.1); /* 分隔线 */
- padding-bottom: 15px;
+ gap: 8px;
+ background: rgba(0,0,0,0.2);
+ padding: 15px;
+ border-radius: 8px;
+}
+
+.lucky-item {
+ font-size: 14px;
+ color: rgba(255,255,255,0.8);
+}
+
+.lucky-item .highlight {
+ color: #fff;
+ font-weight: bold;
+ margin-left: 5px;
}
.last-section {
margin-bottom: 0;
- border-bottom: none;
- padding-bottom: 0;
}
-.section-label {
- font-size: 14px;
- color: #a29bfe; /* 浅紫色标签 */
- margin-bottom: 8px;
- font-weight: bold;
+/* 总体结论样式 */
+.summary-text {
+ font-size: 13px;
+ color: rgba(255, 255, 255, 0.5); /* 中性灰 */
+ margin-top: -20px; /* 调整间距 */
+ margin-bottom: 30px;
+ text-align: center;
+ max-width: 80%;
+ line-height: 1.5;
}
-.section-content {
- font-size: 14px; /* 二级信息字号调小 */
- line-height: 1.6;
+.action-area {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 15px;
+ margin-bottom: 30px;
+ width: 100%;
+}
+
+.verify-btn {
+ background: linear-gradient(135deg, #e94560, #8b3a62);
color: #fff;
- opacity: 0.75; /* 二级信息透明度降低 */
- text-align: left;
+ font-size: 16px;
+ font-weight: bold;
+ padding: 12px 30px;
+ border-radius: 25px;
+ box-shadow: 0 4px 15px rgba(233, 69, 96, 0.4);
+ letter-spacing: 1px;
+ animation: pulseBtn 2s infinite;
}
-/* 一级信息强调样式 */
-.primary-section .section-content {
- font-size: 17px;
- opacity: 1;
- font-weight: 500;
- line-height: 1.7;
- letter-spacing: 0.5px;
+.share-btn {
+ background: linear-gradient(135deg, #7a5cff, #005bea); /* 不同的蓝紫色渐变 */
+ color: #fff;
+ font-size: 16px;
+ font-weight: bold;
+ padding: 12px 30px;
+ border-radius: 25px;
+ box-shadow: 0 4px 15px rgba(122, 92, 255, 0.4);
+ letter-spacing: 1px;
+ width: auto !important;
+ margin-bottom: 15px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ line-height: 1.2;
}
-.primary-section .section-label {
- font-size: 15px;
- color: #e94560; /* 稍微强调标题颜色 */
- opacity: 1;
+@keyframes pulseBtn {
+ 0% { transform: scale(1); box-shadow: 0 4px 15px rgba(233, 69, 96, 0.4); }
+ 50% { transform: scale(1.05); box-shadow: 0 6px 20px rgba(233, 69, 96, 0.6); }
+ 100% { transform: scale(1); box-shadow: 0 4px 15px rgba(233, 69, 96, 0.4); }
}
.back-btn {
font-size: 14px;
- opacity: 0.6;
+ color: #c9a0dc; /* Light purple to match theme but be visible */
+ opacity: 0.9;
text-decoration: underline;
- padding: 10px;
+ padding: 10px; /* Increased padding */
}
/* 简单的动效 */
@@ -194,7 +407,7 @@ page {
.status-divider {
width: 100%;
height: 1px;
- background-color: rgba(255, 255, 255, 0.05);
+ background-color: rgba(255, 255, 255, 0.1);
margin: 15px 0;
}
@@ -208,10 +421,11 @@ page {
.match-trigger {
font-size: 14px;
- color: #fbaceb; /* 淡淡的粉色 */
- opacity: 0.8;
+ color: #ffccff; /* Brighter pink/purple */
+ opacity: 1;
text-decoration: underline;
margin-bottom: 5px;
+ font-weight: 500;
}
.match-content {
@@ -233,15 +447,22 @@ page {
font-size: 18px;
color: #fff;
font-weight: bold;
-}
-
-/* 总体结论样式 */
-.summary-text {
- font-size: 13px;
- color: rgba(255, 255, 255, 0.5); /* 中性灰 */
margin-top: -20px; /* 调整间距 */
margin-bottom: 30px;
text-align: center;
max-width: 80%;
line-height: 1.5;
}
+
+/* 免责声明 */
+.disclaimer {
+ width: 100%;
+ text-align: center;
+ padding-bottom: 30px;
+ margin-top: 10px;
+}
+
+.disclaimer text {
+ font-size: 11px;
+ color: rgba(255, 255, 255, 0.3);
+}
diff --git a/styles/disclaimer.wxss b/styles/disclaimer.wxss
new file mode 100644
index 0000000..913ffce
--- /dev/null
+++ b/styles/disclaimer.wxss
@@ -0,0 +1,14 @@
+/* 免责声明样式 */
+.disclaimer {
+ width: 100%;
+ text-align: center;
+ padding: 20rpx 0;
+ margin-top: 20rpx;
+ border-top: 1rpx solid rgba(255, 255, 255, 0.05);
+}
+
+.disclaimer text {
+ font-size: 20rpx;
+ color: rgba(255, 255, 255, 0.3);
+ letter-spacing: 1rpx;
+}
diff --git a/update_index_function.js b/update_index_function.js
new file mode 100644
index 0000000..08a739b
--- /dev/null
+++ b/update_index_function.js
@@ -0,0 +1,61 @@
+const fs = require('fs');
+const path = 'e:\\I code\\pages\\index\\index.js';
+
+try {
+ let content = fs.readFileSync(path, 'utf8');
+
+ // Define old and new function
+ // We use a simple string replace for the function head and body start
+ const oldFn = ` revealNext: function (e) {
+ const index = e.currentTarget.dataset.index;`;
+
+ const newFn = ` revealNext: function (e) {
+ const index = (e.detail && e.detail.index !== undefined) ? e.detail.index : e.currentTarget.dataset.index;`;
+
+ if (content.indexOf(oldFn) === -1) {
+ console.log('Could not find exact function match. Trying flexible match...');
+ // regex fallback
+ content = content.replace(
+ /revealNext:\s*function\s*\(e\)\s*\{\s*const\s*index\s*=\s*e\.currentTarget\.dataset\.index;/g,
+ `revealNext: function (e) {
+ const index = (e.detail && e.detail.index !== undefined) ? e.detail.index : e.currentTarget.dataset.index;`
+ );
+ } else {
+ content = content.replace(oldFn, newFn);
+ }
+
+ // Add viewCardDetail if missing
+ if (content.indexOf('viewCardDetail:') === -1) {
+ const insertPoint = ` }
+ },
+
+ // --- 展示解读内容 ---`;
+
+ // Find the end of revealNext and insert viewCardDetail
+ // revealNext ends, usually followed by showInterpretation
+ const showInterp = ` // --- 展示解读内容 ---`;
+
+ const newMethod = ` // 查看已翻开牌的详情
+ viewCardDetail: function(e) {
+ const index = (e.detail && e.detail.index !== undefined) ? e.detail.index : e.currentTarget.dataset.index;
+ const card = this.data.drawnCards[index];
+ if (card) {
+ wx.showToast({
+ title: card.name + (card.isReversed ? '(逆)' : ''),
+ icon: 'none',
+ duration: 1500
+ });
+ }
+ },
+
+ // --- 展示解读内容 ---`;
+
+ content = content.replace(showInterp, newMethod);
+ }
+
+ fs.writeFileSync(path, content, 'utf8');
+ console.log('Successfully updated index.js functions');
+
+} catch (e) {
+ console.error(e);
+}
diff --git a/update_spreads.js b/update_spreads.js
new file mode 100644
index 0000000..b30068e
--- /dev/null
+++ b/update_spreads.js
@@ -0,0 +1,55 @@
+const fs = require('fs');
+const path = 'e:\\I code\\pages\\index\\index.js';
+
+try {
+ let content = fs.readFileSync(path, 'utf8');
+
+ // Regex to match aiSchema: [...] and append layout
+ // We match "aiSchema": [ ... ] (multiline)
+ // And escape the replacement curlies
+ const regex = /("aiSchema":\s*\[[^\]]*\])/g;
+
+ let newContent = content.replace(regex, (match) => {
+ return match + ',\n layout: { type: \'grid\' }';
+ });
+
+ // Special handling for Celtic Cross
+ // Find the generated text for celtic_cross and replace grid with specific layout
+ // We need to look for "id": "celtic_cross" ... layout: { type: 'grid' }
+
+ const celticLayout = `layout: {
+ type: 'celtic',
+ areas: [
+ { area: 'center', rotate: 0 },
+ { area: 'center', rotate: 90 },
+ { area: 'bottom' },
+ { area: 'left' },
+ { area: 'top' },
+ { area: 'right' },
+ { area: 'side' },
+ { area: 'side' },
+ { area: 'side' },
+ { area: 'side' }
+ ]
+ }`;
+
+ // Use a regex that finds the celtic_cross object and its layout
+ // Look for id: celtic_cross, then scan until layout: { type: 'grid' }
+ // This is tricky with regex.
+ // Let's just replacing the specific string unique to celtic cross context if possible.
+
+ // Easier: Split by "id": "celtic_cross"
+ const parts = newContent.split('"id": "celtic_cross"');
+ if (parts.length > 1) {
+ // part[1] starts after celtic_cross.
+ // Find the first layout: { type: 'grid' } in part[1] and replace it.
+ parts[1] = parts[1].replace("layout: { type: 'grid' }", celticLayout);
+ newContent = parts.join('"id": "celtic_cross"');
+ }
+
+ fs.writeFileSync(path, newContent, 'utf8');
+ console.log('Successfully updated index.js');
+
+} catch (e) {
+ console.error('Error:', e);
+}
diff --git a/utils/aiRequestManager.js b/utils/aiRequestManager.js
index 3304344..9f1e5de 100644
--- a/utils/aiRequestManager.js
+++ b/utils/aiRequestManager.js
@@ -8,16 +8,12 @@ let isRequesting = false;
/**
* 安全的 JSON 解析
- * @param {string} text - 待解析的文本
- * @returns {Object} 解析结果
*/
function safeJSONParse(text) {
try {
return JSON.parse(text);
} catch (e) {
console.log('AI_JSON_FALLBACK: 首次解析失败,尝试提取 JSON 代码块');
-
- // 尝试提取 JSON 代码块(可能被包裹在 ```json ``` 中)
const jsonMatch = text.match(/```json\s*([\s\S]*?)\s*```/) || text.match(/```\s*([\s\S]*?)\s*```/);
if (jsonMatch && jsonMatch[1]) {
try {
@@ -26,20 +22,12 @@ function safeJSONParse(text) {
console.error('AI_JSON_FALLBACK: JSON 代码块解析也失败');
}
}
-
- // 完全失败,返回 fallback 状态
- return {
- status: 'fallback_text',
- raw: text
- };
+ return { status: 'fallback_text', raw: text };
}
}
/**
* 生成兜底解读内容
- * @param {Array} drawnCards - 抽到的牌
- * @param {Object} spread - 牌阵信息
- * @returns {Object} 兜底解读
*/
function generateFallbackInterpretation(drawnCards, spread) {
const positions = drawnCards.map((card, index) => ({
@@ -58,8 +46,6 @@ function generateFallbackInterpretation(drawnCards, spread) {
/**
* 执行单次 AI 请求
- * @param {Object} config - 请求配置
- * @returns {Promise} 请求结果
*/
function executeRequest(config) {
return new Promise((resolve, reject) => {
@@ -87,9 +73,6 @@ function executeRequest(config) {
/**
* 带重试的请求执行
- * @param {Object} config - 请求配置
- * @param {number} retryCount - 当前重试次数
- * @returns {Promise} 请求结果
*/
async function executeWithRetry(config, retryCount = 0) {
try {
@@ -104,8 +87,6 @@ async function executeWithRetry(config, retryCount = 0) {
if (shouldRetry) {
console.log(`AI_REQUEST_RETRY: 第 ${retryCount + 1} 次重试`);
-
- // 等待 1500ms 后重试
await new Promise(resolve => setTimeout(resolve, 1500));
return executeWithRetry(config, retryCount + 1);
}
@@ -116,8 +97,6 @@ async function executeWithRetry(config, retryCount = 0) {
/**
* 安全的 AI 请求(主函数)
- * @param {Object} payload - 请求参数
- * @returns {Promise