d304057e62
- h5/mine/index.html: 个人中心「我的页」H5 实现 - h5/shared/bridge.js, api.js: H5↔客户端桥与 API 封装(mine 依赖)
7772 lines
347 KiB
HTML
7772 lines
347 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
|
||
|
||
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>比价APP 高保真原型 (外卖版)</title>
|
||
<style>
|
||
* { margin: 0; padding: 0; box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
|
||
html { background: #000; }
|
||
body { font-family: -apple-system, BlinkMacSystemFont, 'PingFang SC', 'Helvetica Neue', sans-serif; background: #000; display: flex; justify-content: center; align-items: center; min-height: 100vh; -webkit-user-select: none; -moz-user-select: none; user-select: none; -webkit-touch-callout: none; }
|
||
/* WebView 长按禁止文字选区/蓝色高亮(导购页非可选文档);输入框单独恢复可选 */
|
||
input, textarea { -webkit-user-select: text; user-select: text; }
|
||
:root {
|
||
--primary: #FFD600; --primary-dark: #F5C500; --primary-light: #FFEB3B; --primary-bg: #FFFDE7;
|
||
--primary-pale: #FFFAEC;
|
||
--primary-gradient: linear-gradient(180deg, #FFE066 0%, #FFD600 100%);
|
||
--primary-gradient-soft: linear-gradient(180deg, #FFFAEC 0%, #FFEEB0 100%);
|
||
--accent-orange: #FF5722; --accent-red: #E53935;
|
||
--success: #4CAF50; --success-bg: #E8F5E9; --warning: #FFC107; --error: #F44336; --info: #2196F3;
|
||
--coin: #FFB300; --coin-bg: #FFF8E1;
|
||
--gray-900: #1A1A1A; --gray-800: #333; --gray-700: #4D4D4D; --gray-600: #666; --gray-500: #999; --gray-400: #B3B3B3; --gray-300: #CCC; --gray-200: #E5E5E5; --gray-100: #F5F5F5; --gray-50: #FAFAFA; --bg: #F5F5F5;
|
||
/* Onboarding 统一 token(B 方案) */
|
||
--cta-radius: 25px;
|
||
--cta-height: 50px;
|
||
--cta-font-size: 17px;
|
||
--cta-font-weight: 700;
|
||
--cta-letter-spacing: 1.5px;
|
||
--cta-shadow: 0 6px 18px rgba(255,179,0,.38), inset 0 1px 0 rgba(255,255,255,.55);
|
||
--cta-shadow-active: 0 3px 10px rgba(255,179,0,.30), inset 0 1px 0 rgba(255,255,255,.55);
|
||
--shadow-card-sm: 0 2px 8px rgba(0,0,0,.06);
|
||
--shadow-card-md: 0 6px 18px rgba(0,0,0,.08);
|
||
}
|
||
.device { width: 375px; height: 812px; background: #fff; border-radius: 32px; overflow: hidden; position: relative; box-shadow: 0 20px 60px rgba(0,0,0,0.5); }
|
||
.screen { position: absolute; inset: 0; display: none; flex-direction: column; overflow-y: auto; overflow-x: hidden; -webkit-overflow-scrolling: touch; }
|
||
.screen.active { display: flex; }
|
||
.screen.noscroll { overflow-y: hidden; }
|
||
.screen::-webkit-scrollbar { display: none; }
|
||
/* 通用样式 */
|
||
.header { display: flex; align-items: center; justify-content: space-between; padding: 40px 16px 12px; background: #fff; flex-shrink: 0; }
|
||
.header-title { font-size: 17px; font-weight: 600; color: var(--gray-900); }
|
||
.back-btn { font-size: 15px; font-weight: 600; color: var(--gray-800); cursor: pointer; background: none; border: none; }
|
||
.btn { display: flex; align-items: center; justify-content: center; border: none; border-radius: 14px; font-weight: 600; cursor: pointer; transition: opacity .15s; }
|
||
.btn:active { opacity: .7; }
|
||
.btn-primary { background: var(--primary); color: #1a1a1a; }
|
||
.btn-outline { background: transparent; border: 1.5px solid var(--primary); color: #1a1a1a; }
|
||
.btn-secondary { background: var(--primary-bg); color: var(--primary); }
|
||
.btn-lg { padding: 12px 24px; font-size: 17px; width: 100%; }
|
||
.btn-md { padding: 8px 16px; font-size: 15px; }
|
||
.btn-sm { padding: 8px 16px; font-size: 13px; }
|
||
/* ===== Onboarding 统一 CTA(B 方案)===== */
|
||
.btn-cta {
|
||
display: inline-flex; align-items: center; justify-content: center;
|
||
border: none; cursor: pointer;
|
||
background: var(--primary-gradient);
|
||
color: var(--gray-900);
|
||
font-family: inherit;
|
||
font-size: var(--cta-font-size);
|
||
font-weight: var(--cta-font-weight);
|
||
letter-spacing: var(--cta-letter-spacing);
|
||
border-radius: var(--cta-radius);
|
||
height: var(--cta-height);
|
||
box-shadow: var(--cta-shadow);
|
||
transition: transform .12s ease, box-shadow .2s ease, opacity .15s ease;
|
||
}
|
||
.btn-cta:active { transform: translateY(1px); box-shadow: var(--cta-shadow-active); }
|
||
.btn-cta.size-lg { width: 100%; padding: 0 24px; }
|
||
.btn-cta.size-md { padding: 0 24px; height: 44px; font-size: 15px; letter-spacing: 1px; border-radius: 24px; }
|
||
.btn-cta.size-pill { padding: 0 16px; height: 36px; font-size: 13px; letter-spacing: .5px; border-radius: 18px; }
|
||
/* 文字辅助按钮(取消、放弃等) */
|
||
.btn-text {
|
||
background: none; border: none; cursor: pointer;
|
||
color: var(--gray-500); font-size: 14px; font-weight: 500;
|
||
font-family: inherit; transition: opacity .15s;
|
||
}
|
||
.btn-text:active { opacity: .6; }
|
||
/* ===== Splash CTA Variants ===== */
|
||
.splash-cta { width: 100%; border: none; padding: 16px 0; border-radius: 14px; font-size: 17px; font-weight: 700; cursor: pointer; transition: transform .15s, box-shadow .25s; position: relative; overflow: hidden; }
|
||
.splash-cta:active { transform: scale(.97); }
|
||
/* V1 红橙渐变(当前) */
|
||
.splash-cta-v1 { background: linear-gradient(135deg, #FE2C55, #FF6B3D); color: #fff; box-shadow: 0 6px 16px rgba(255,68,68,.30); }
|
||
/* V2 黄底黑字(品牌主色) */
|
||
.splash-cta-v2 { background: #FFD600; color: #1a1a1a; box-shadow: 0 6px 16px rgba(255,214,0,.45); }
|
||
/* V3 黑底黄字(高对比) */
|
||
.splash-cta-v3 { background: #1a1a1a; color: #FFD600; box-shadow: 0 6px 16px rgba(0,0,0,.25); }
|
||
/* V4 黄→金渐变 + 光泽扫过 */
|
||
.splash-cta-v4 { background: linear-gradient(135deg, #FFEB3B 0%, #FFD600 50%, #FFA000 100%); color: #1a1a1a; box-shadow: 0 6px 20px rgba(249,168,37,.45); }
|
||
.splash-cta-v4::after { content: ""; position: absolute; top: 0; left: -75%; width: 50%; height: 100%; background: linear-gradient(120deg, transparent, rgba(255,255,255,.6), transparent); transform: skewX(-25deg); animation: ctaShine 2.6s infinite; }
|
||
@keyframes ctaShine { 0% { left: -75%; } 60%, 100% { left: 125%; } }
|
||
/* V5 玻璃质感 黄+白光 */
|
||
.splash-cta-v5 { background: linear-gradient(180deg, #FFEB3B, #FFC400); color: #1a1a1a; box-shadow: inset 0 1px 0 rgba(255,255,255,.7), inset 0 -2px 0 rgba(0,0,0,.08), 0 8px 20px rgba(255,193,7,.35); }
|
||
/* V6 描边款(克制风) */
|
||
.splash-cta-v6 { background: #fff; color: #1a1a1a; border: 2px solid #1a1a1a; box-shadow: 4px 4px 0 #FFD600; }
|
||
.splash-cta-v6:active { box-shadow: 2px 2px 0 #FFD600; transform: translate(2px, 2px); }
|
||
/* V7 红包红(喜庆款) */
|
||
.splash-cta-v7 { background: linear-gradient(135deg, #E53935 0%, #E02E24 100%); color: #FFD600; box-shadow: 0 6px 18px rgba(198,40,40,.40); text-shadow: 0 1px 2px rgba(0,0,0,.2); }
|
||
/* V8 跳动呼吸款(黄底) */
|
||
.splash-cta-v8 { background: #FFD600; color: #1a1a1a; box-shadow: 0 6px 16px rgba(255,214,0,.45); animation: ctaPulse 1.6s ease-in-out infinite; }
|
||
@keyframes ctaPulse { 0%,100% { transform: scale(1); box-shadow: 0 6px 16px rgba(255,214,0,.45);} 50% { transform: scale(1.03); box-shadow: 0 10px 24px rgba(255,214,0,.65);} }
|
||
/* V9 蜜糖渐变(黄→琥珀,温暖软渐变,无扫光)*/
|
||
.splash-cta-v9 { background: linear-gradient(180deg, #FFE066 0%, #FFB300 100%); color: #1a1a1a; box-shadow: 0 8px 22px rgba(255,140,0,.4); }
|
||
/* V10 金币描边(品牌黄 + 深金细边 + 内嵌高光,模拟铸币感)*/
|
||
.splash-cta-v10 { background: linear-gradient(180deg, #FFE066 0%, #FFD600 100%); color: #1a1a1a; border: 1.5px solid #8B6914; box-shadow: inset 0 1px 0 rgba(255,255,255,.7), 0 6px 18px rgba(184,134,11,.35); }
|
||
/* ===== Coupon Subtitle Variants ===== */
|
||
.cps { font-family: inherit; }
|
||
/* V1 当前灰色基线 */
|
||
.cps-v1 { font-size: 13px;font-weight: 500;color: var(--gray-500);line-height: 1.5; }
|
||
/* V2 系列:金币胶囊家族 */
|
||
.cps-v2 { display: inline-flex;align-items: center;gap: 6px;padding: 6px 12px;border-radius: 999px;background: linear-gradient(180deg,#FFE066,#FFC400);color: #5A3A00;font-size: 12px;font-weight: 600;letter-spacing: .2px;box-shadow: inset 0 1px 0 rgba(255,255,255,.7),0 2px 6px rgba(255,179,0,.35); }
|
||
.cps-v2 .cps-coin { width: 14px;height: 14px;border-radius: 50%;background: radial-gradient(circle at 35% 30%,#FFE0B2,#FFA000);box-shadow: inset 0 -1px 0 rgba(0,0,0,.15);display: inline-flex;align-items: center;justify-content: center;font-size: 10px;font-weight: 900;color: #7A4F00; }
|
||
/* V2b 金币翻转动效 */
|
||
.cps-v2b { display: inline-flex;align-items: center;gap: 6px;padding: 6px 12px;border-radius: 999px;background: linear-gradient(180deg,#FFE066,#FFC400);color: #5A3A00;font-size: 12px;font-weight: 600;letter-spacing: .2px;box-shadow: inset 0 1px 0 rgba(255,255,255,.7),0 2px 6px rgba(255,179,0,.35); }
|
||
.cps-v2b .cps-coin { width: 14px;height: 14px;border-radius: 50%;background: radial-gradient(circle at 35% 30%,#FFE0B2,#FFA000);box-shadow: inset 0 -1px 0 rgba(0,0,0,.15);display: inline-flex;align-items: center;justify-content: center;font-size: 10px;font-weight: 900;color: #7A4F00;animation: coinFlip 2.4s ease-in-out infinite; }
|
||
@keyframes coinFlip { 0%,70%,100% { transform: rotateY(0); } 80% { transform: rotateY(180deg); } 90% { transform: rotateY(360deg); } }
|
||
/* V2c 双色分段 */
|
||
.cps-v2c { display: inline-flex;align-items: center;padding: 0;border-radius: 999px;background: linear-gradient(180deg,#FFE066,#FFC400);font-size: 12px;font-weight: 600;letter-spacing: .2px;box-shadow: inset 0 1px 0 rgba(255,255,255,.7),0 2px 6px rgba(255,179,0,.35);overflow: hidden; }
|
||
.cps-v2c .cps-tag { background: #1a1a1a;color: #FFD600;padding: 6px 8px;font-weight: 900;letter-spacing: .5px;display: inline-flex;align-items: center;gap: 2px; }
|
||
.cps-v2c .cps-text { padding: 6px 12px 6px 8px;color: #5A3A00; }
|
||
/* V2d 闪光描边(轻盈款) */
|
||
.cps-v2d { position: relative;display: inline-flex;align-items: center;gap: 6px;padding: 6px 12px;border-radius: 999px;background: #FFFDF5;color: #1a1a1a;font-size: 12px;font-weight: 600;letter-spacing: .2px;border: 1.5px solid transparent;background-image: linear-gradient(#FFFDF5,#FFFDF5),linear-gradient(135deg,#FFD600,#F9A825,#FFD600);background-origin: border-box;background-clip: padding-box,border-box;box-shadow: 0 2px 8px rgba(255,179,0,.2); }
|
||
.cps-v2d .cps-coin { width: 14px;height: 14px;border-radius: 50%;background: radial-gradient(circle at 35% 30%,#FFE0B2,#FFA000);box-shadow: inset 0 -1px 0 rgba(0,0,0,.15);display: inline-flex;align-items: center;justify-content: center;font-size: 10px;font-weight: 900;color: #7A4F00; }
|
||
/* V2e 数字嵌入款 */
|
||
.cps-v2e { display: inline-flex;align-items: center;gap: 6px;padding: 4px 12px 4px 8px;border-radius: 999px;background: linear-gradient(180deg,#FFE066,#FFC400);color: #5A3A00;font-size: 12px;font-weight: 600;letter-spacing: .2px;box-shadow: inset 0 1px 0 rgba(255,255,255,.7),0 2px 6px rgba(255,179,0,.35); }
|
||
.cps-v2e .cps-amount { display: inline-flex;align-items: baseline;background: #1a1a1a;color: #FFD600;padding: 2px 8px;border-radius: 999px;font-weight: 900;font-size: 12px;letter-spacing: .3px; }
|
||
.cps-v2e .cps-amount small { font-size: 10px;font-weight: 700;opacity: .85;margin-left: 2px; }
|
||
/* V2f 双图标夹击 */
|
||
.cps-v2f { display: inline-flex;align-items: center;gap: 4px;padding: 6px 12px;border-radius: 999px;background: linear-gradient(180deg,#FFE066,#FFC400);color: #5A3A00;font-size: 12px;font-weight: 600;letter-spacing: .2px;box-shadow: inset 0 1px 0 rgba(255,255,255,.7),0 2px 6px rgba(255,179,0,.35); }
|
||
.cps-v2f .cps-coin { width: 14px;height: 14px;border-radius: 50%;background: radial-gradient(circle at 35% 30%,#FFE0B2,#FFA000);box-shadow: inset 0 -1px 0 rgba(0,0,0,.15);display: inline-flex;align-items: center;justify-content: center;font-size: 10px;font-weight: 900;color: #7A4F00; }
|
||
.cps-v2f .cps-bolt { width: 12px;height: 12px;display: inline-flex;align-items: center;justify-content: center; }
|
||
.cps-v2f .cps-bolt svg { display: block; }
|
||
/* V2g 立体浮起 */
|
||
.cps-v2g { display: inline-flex;align-items: center;gap: 6px;padding: 6px 12px;border-radius: 999px;background: linear-gradient(180deg,#FFE066 0%,#FFD600 50%,#FFA000 100%);color: #5A3A00;font-size: 12px;font-weight: 900;letter-spacing: .2px;box-shadow: inset 0 1.5px 0 rgba(255,255,255,.85),inset 0 -1.5px 0 rgba(184,134,11,.3),0 6px 14px rgba(249,168,37,.45),0 1px 2px rgba(0,0,0,.1);text-shadow: 0 1px 0 rgba(255,255,255,.4); }
|
||
.cps-v2g .cps-coin { width: 15px;height: 15px;border-radius: 50%;background: radial-gradient(circle at 35% 30%,#FFE0B2,#FFA000);box-shadow: inset 0 -1.5px 0 rgba(0,0,0,.2),0 1px 1px rgba(0,0,0,.15);display: inline-flex;align-items: center;justify-content: center;font-size: 10px;font-weight: 900;color: #7A4F00; }
|
||
.cps-v3f { display: inline-flex;align-items: center;gap: 6px;padding: 4px 12px;border-radius: 999px;background: rgba(255,179,0,.18);color: #8B6914;font-size: 12px;font-weight: 600;letter-spacing: .2px; }
|
||
.cps-v3f .cps-coin { display: inline-flex;align-items: center;justify-content: center;font-size: 15px;line-height: 1; }
|
||
/* V3 关键词高亮 */
|
||
.cps-v3 { font-size: 13px;font-weight: 500;color: var(--gray-700);line-height: 1.5; }
|
||
.cps-v3 em { font-style: normal;font-weight: 900;color: #1a1a1a;background: linear-gradient(to top,#FFD600 45%,transparent 45%);padding: 0 2px; }
|
||
/* V4 优惠券齿边小票 */
|
||
.cps-v4 { position: relative;display: inline-flex;align-items: stretch;background: #fff;border: 1.5px dashed #FFB300;border-radius: 8px;padding: 4px 12px;font-size: 12px;font-weight: 600;color: #E02E24;letter-spacing: .3px;box-shadow: 0 1px 4px rgba(255,179,0,.25); }
|
||
.cps-v4::before, .cps-v4::after { content: "";position: absolute;top: 50%;width: 8px;height: 8px;border-radius: 50%;background: #FFF3C4;transform: translateY(-50%); }
|
||
.cps-v4::before { left: -5px; }
|
||
.cps-v4::after { right: -5px; }
|
||
.cps-v4 .cps-amt { color: #1a1a1a;background: #FFD600;padding: 2px 6px;border-radius: 4px;margin: 0 4px;font-weight: 900; }
|
||
/* V5 数字驱动徽章 */
|
||
.cps-v5 { display: inline-flex;align-items: center;gap: 8px;padding: 4px 6px 4px 12px;border-radius: 999px;background: rgba(26,26,26,.06);font-size: 12px;font-weight: 600;color: var(--gray-800); }
|
||
.cps-v5 .cps-pill { display: inline-flex;align-items: baseline;gap: 2px;padding: 2px 8px;border-radius: 999px;background: #1a1a1a;color: #FFD600;font-weight: 900;font-size: 12px;letter-spacing: .3px; }
|
||
.cps-v5 .cps-pill small { font-size: 10px;font-weight: 700;opacity: .85; }
|
||
/* V6 双行节奏 */
|
||
.cps-v6 { display: flex;flex-direction: column;align-items: center;gap: 2px;line-height: 1.3; }
|
||
.cps-v6 .cps-top { font-size: 11px;font-weight: 600;color: var(--gray-500);letter-spacing: .5px;text-transform: uppercase; }
|
||
.cps-v6 .cps-bot { font-size: 13px;font-weight: 600;color: #E02E24; }
|
||
.cps-v6 .cps-bot em { font-style: normal;color: #1a1a1a;background: linear-gradient(to top,#FFD600 45%,transparent 45%);padding: 0 2px;font-weight: 900; }
|
||
|
||
/* ===== Tweaks Panel ===== */
|
||
.tweaks-panel { position: fixed; right: 20px; bottom: 20px; width: 280px; background: #fff; border-radius: 14px; box-shadow: 0 8px 32px rgba(0,0,0,.18); padding: 16px; z-index: 9998; font-family: -apple-system, sans-serif; display: none; }
|
||
.tweaks-panel.open { display: block; }
|
||
.tweaks-panel h3 { font-size: 14px; font-weight: 700; color: #1a1a1a; margin-bottom: 4px; }
|
||
.tweaks-panel .tweaks-sub { font-size: 11px; color: #999; margin-bottom: 12px; }
|
||
.tweaks-panel .tweaks-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
|
||
.tweaks-opt { padding: 8px 8px; border-radius: 8px; border: 1.5px solid #e5e5e5; cursor: pointer; font-size: 12px; font-weight: 600; color: #333; background: #fff; text-align: center; transition: all .15s; }
|
||
.tweaks-opt:hover { border-color: #999; }
|
||
.tweaks-opt.active { background: #FFD600; border-color: #FFD600; color: #1a1a1a; }
|
||
.tweaks-opt small { display: block; font-size: 10px; font-weight: 500; color: #999999; margin-top: 2px; }
|
||
.tweaks-opt.active small { color: #5A3A00; }
|
||
.tweaks-close { position: absolute; top: 10px; right: 10px; width: 22px; height: 22px; border-radius: 12px; background: #f0f0f0; border: none; cursor: pointer; font-size: 13px; line-height: 1; color: #666; }
|
||
.card { background: #fff; border-radius: 14px; padding: 16px; box-shadow: 0 2px 8px rgba(0,0,0,.06); }
|
||
.section-title { font-size: 17px; font-weight: 600; color: var(--gray-900); margin-bottom: 12px; }
|
||
.badge { display: inline-flex; align-items: center; padding: 2px 8px; border-radius: 4px; font-size: 11px; font-weight: 600; }
|
||
/* Tab bar — 4 tab + 中央 AI 领券 FAB(平 tab bar + FAB 站在上面) */
|
||
.tab-bar { display: flex; height: 60px; background: #fff; border-top: .5px solid var(--gray-200); flex-shrink: 0; position: relative; overflow: visible; }
|
||
.tab-item { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px; cursor: pointer; position: relative; z-index: 1; }
|
||
.tab-icon { width: 24px; height: 24px; display: flex; align-items: center; justify-content: center; }
|
||
.tab-label { font-size: 11px; color: var(--gray-800); font-weight: 400; }
|
||
.tab-item.active .tab-label { color: var(--gray-900); font-weight: 700; }
|
||
.tab-icon .i-outline { display: block; }
|
||
.tab-icon .i-filled { display: none; }
|
||
.tab-item.active .tab-icon .i-outline { display: none; }
|
||
.tab-item.active .tab-icon .i-filled { display: block; }
|
||
.welfare-tab-dot {
|
||
position: absolute;
|
||
left: 50%;
|
||
top: 9px;
|
||
width: 10px;
|
||
height: 10px;
|
||
border-radius: 50%;
|
||
background: #FF3B30;
|
||
border: 1px solid #FFFFFF;
|
||
box-shadow: 0 2px 5px rgba(255, 59, 48, .32);
|
||
transform: translateX(7px);
|
||
display: none;
|
||
pointer-events: none;
|
||
z-index: 3;
|
||
}
|
||
.tab-item.has-welfare-dot .welfare-tab-dot { display: block; }
|
||
/* 横幅轮播 */
|
||
@keyframes marqueeScroll { 0%{transform: translateX(0);} 100%{transform: translateX(-50%);} }
|
||
.marquee-wrap { overflow: hidden;border-radius: 8px;background: #FFF3E0;margin-bottom: 8px;height: 32px;display: flex;align-items: center; }
|
||
/* 用户案例翻页横幅 */
|
||
.flip-banner { height: 36px;border-radius: 18px;background: linear-gradient(90deg,#FFF3E0,#FFE0B2);margin-bottom: 12px;perspective: 800px;padding: 0 6px 0 4px; }
|
||
.flip-banner-stage { width: 100%;height: 100%;position: relative;transform-style: preserve-3d;transition: transform .55s cubic-bezier(.5,0,.4,1); }
|
||
.flip-banner.flipping .flip-banner-stage { transform: rotateX(-180deg); }
|
||
.flip-banner-face { position: absolute;inset: 0;display: flex;align-items: center;gap: 8px;backface-visibility: hidden;-webkit-backface-visibility: hidden;padding: 0 8px 0 4px;overflow: hidden; }
|
||
.flip-banner-face.back { transform: rotateX(180deg); }
|
||
.flip-banner-avatar { width: 28px;height: 28px;border-radius: 14px;display: flex;align-items: center;justify-content: center;font-size: 16px;flex-shrink: 0;box-shadow: 0 1px 3px rgba(0,0,0,.08); }
|
||
.flip-banner-text { flex: 1;font-size: 12px;font-weight: 500;color: var(--gray-700);white-space: nowrap;overflow: hidden;text-overflow: ellipsis; }
|
||
.flip-banner-text .flip-name { color: var(--gray-900);font-weight: 700;margin-right: 4px; }
|
||
.flip-banner-text em { font-style: normal;color: #FF5722;font-weight: 600;margin-left: 2px; }
|
||
.marquee-track { display: flex;white-space: nowrap;animation: marqueeScroll 20s linear infinite; }
|
||
.marquee-item { display: inline-flex;align-items: center;padding: 0 24px;font-size: 12px;font-weight: 600;color: var(--gray-700); }
|
||
/* 浮窗 */
|
||
.floating-btn { position: absolute; right: 16px; bottom: 80px; width: 56px; height: 56px; border-radius: 24px; background: var(--primary); color: #1a1a1a; display: flex; align-items: center; justify-content: center; font-size: 13px; font-weight: 600; box-shadow: 0 4px 12px rgba(255,87,34,.4); cursor: pointer; z-index: 100; animation: pulse 2s infinite; }
|
||
@keyframes pulse { 0%,100% { box-shadow: 0 4px 12px rgba(255,87,34,.4); } 50% { box-shadow: 0 4px 24px rgba(255,87,34,.6); } }
|
||
@keyframes spin { to { transform: rotate(360deg); } }
|
||
@keyframes cardHint { 0%,100% { box-shadow: 0 2px 8px rgba(255,87,34,.1); } 50% { box-shadow: 0 2px 16px rgba(255,87,34,.3); } }
|
||
@keyframes splashTickerScroll { 0% { transform: translateX(0); } 100% { transform: translateX(-50%); } }
|
||
@keyframes splashFadeIn { from { opacity: 0; } to { opacity: 1; } }
|
||
|
||
/* ===== Splash · 全图方案:splash-full-bg 含印章+tagline,HTML 仅放按钮 ===== */
|
||
.splash-illustration {
|
||
position: absolute;
|
||
top: 80px; left: 0; right: 0;
|
||
height: 575px;
|
||
background-image: url('../../assets/onboarding/index/full-bg.png');
|
||
background-size: 375px auto;
|
||
background-position: top center;
|
||
background-repeat: no-repeat;
|
||
background-color: transparent;
|
||
overflow: hidden;
|
||
z-index: 1;
|
||
}
|
||
.splash-illustration::before {
|
||
content: '';
|
||
position: absolute;
|
||
top: 0; left: 0; right: 0;
|
||
height: 90px;
|
||
background: linear-gradient(to top, rgba(253,250,249,0) 0%, rgba(253,250,249,.55) 55%, rgba(253,250,249,1) 100%);
|
||
pointer-events: none;
|
||
z-index: 1;
|
||
}
|
||
/* 底部渐变:仅最末端消接缝,远离"下单前先比价"避免糊字 */
|
||
.splash-illustration::after {
|
||
content: '';
|
||
position: absolute;
|
||
bottom: 0; left: 0; right: 0;
|
||
height: 14px;
|
||
background: linear-gradient(to bottom, rgba(253,250,249,0) 0%, rgba(253,250,249,1) 100%);
|
||
pointer-events: none;
|
||
}
|
||
.splash-start-btn {
|
||
position: absolute;
|
||
bottom: 60px;
|
||
left: 50%;
|
||
transform: translateX(-50%);
|
||
width: 220px;
|
||
height: 52px;
|
||
border-radius: 24px;
|
||
background: linear-gradient(180deg, #FFEB3B 0%, #FFD600 50%, #FFC400 100%);
|
||
color: #1A1A1A;
|
||
font-size: 17px;
|
||
font-weight: 700;
|
||
letter-spacing: 4px;
|
||
text-indent: 4px;
|
||
border: none;
|
||
cursor: pointer;
|
||
z-index: 10;
|
||
box-shadow: 0 8px 22px rgba(255,193,0,.45), inset 0 1px 0 rgba(255,255,255,.55), inset 0 -2px 0 rgba(180,110,0,.10);
|
||
transition: transform .12s ease, box-shadow .2s ease, opacity .15s ease;
|
||
}
|
||
.splash-start-btn:active {
|
||
transform: translateX(-50%) scale(0.97);
|
||
opacity: 0.92;
|
||
box-shadow: 0 4px 12px rgba(255,193,0,.35), inset 0 1px 0 rgba(255,255,255,.55);
|
||
}
|
||
@keyframes safetySlideUp { from { transform: translateY(100%); } to { transform: translateY(0); } }
|
||
@keyframes safetyPopIn { from { transform: scale(.92); opacity: 0; } to { transform: scale(1); opacity: 1; } }
|
||
@keyframes confettiDrop {
|
||
0% { transform: translateY(0) translateX(0) rotate(0deg) rotateY(0deg); opacity: 1; }
|
||
25% { translateX(var(--sway)); }
|
||
50% { transform: translateY(400px) translateX(calc(var(--sway) * -1)) rotate(360deg) rotateY(540deg); opacity: 1; }
|
||
75% { translateX(var(--sway)); }
|
||
100% { transform: translateY(850px) translateX(var(--sway)) rotate(720deg) rotateY(1080deg); opacity: 0; }
|
||
}
|
||
@keyframes confettiFloat {
|
||
0% { transform: translateY(0) translateX(0) rotate(0deg) rotateX(0deg) scale(1); opacity: 1; }
|
||
100% { transform: translateY(var(--dy)) translateX(var(--dx)) rotate(var(--spin)) rotateX(1080deg) scale(0.5); opacity: 0; }
|
||
}
|
||
/* 导航指示 */
|
||
.nav-hint { position: absolute; bottom: 8px; left: 50%; transform: translateX(-50%); font-size: 11px; color: var(--gray-400); background: rgba(255,255,255,.8); padding: 4px 12px; border-radius: 12px; z-index: 50; }
|
||
/* 方案切换控制面板 */
|
||
.variant-toggle { position: fixed; top: 16px; left: 16px; z-index: 9999; }
|
||
.variant-btn { width: 36px; height: 36px; border-radius: 18px; background: #333; color: #fff; border: none; font-size: 16px; cursor: pointer; box-shadow: 0 2px 8px rgba(0,0,0,.3); display: flex; align-items: center; justify-content: center; }
|
||
.variant-btn:hover { background: #666666; }
|
||
.variant-panel { display: none; position: absolute; top: 44px; left: 0; background: #fff; border-radius: 14px; box-shadow: 0 4px 24px rgba(0,0,0,.15); padding: 16px; min-width: 260px; max-height: 70vh; overflow-y: auto; }
|
||
.variant-panel.open { display: block; }
|
||
.variant-panel h3 { font-size: 14px; font-weight: 700; color: #333; margin-bottom: 12px; }
|
||
.variant-module { margin-bottom: 12px; }
|
||
.variant-module:last-child { margin-bottom: 0; }
|
||
.variant-module-label { font-size: 12px; font-weight: 600; color: #666; margin-bottom: 6px; }
|
||
.variant-options { display: flex; gap: 6px; flex-wrap: wrap; }
|
||
.variant-opt { padding: 4px 12px; border-radius: 32px; border: 1.5px solid #e5e5e5; font-size: 12px; font-weight: 600; cursor: pointer; background: #fff; color: #666; transition: all .15s; }
|
||
.variant-opt:hover { border-color: #999; }
|
||
.variant-opt.active { background: #FFD600; border-color: #FFD600; color: #1a1a1a; }
|
||
.variant-empty { font-size: 12px; color: #999; text-align: center; padding: 16px 0; }
|
||
/* 平台icon浮动动画 */
|
||
@keyframes float1 { 0%,100%{transform: translateY(0)} 50%{transform: translateY(-6px)} }
|
||
@keyframes float2 { 0%,100%{transform: translateY(0)} 50%{transform: translateY(-8px)} }
|
||
@keyframes float3 { 0%,100%{transform: translateY(0)} 50%{transform: translateY(-5px)} }
|
||
.fly-icon.fly1 { animation: float1 3s ease-in-out infinite; }
|
||
.fly-icon.fly2 { animation: float2 2.5s ease-in-out infinite .3s; }
|
||
.fly-icon.fly3 { animation: float3 3.2s ease-in-out infinite .6s; }
|
||
/* 下滑手势动画:底部开始→往上滑→底部消失 */
|
||
@keyframes swipeDown { 0%{transform: translateY(30px) rotate(-15deg);opacity: 0} 50%{transform: translateY(-30px) rotate(-15deg);opacity: 1} 100%{transform: translateY(30px) rotate(-15deg);opacity: 0} }
|
||
.swipe-hand { animation: swipeDown 2s ease-in-out infinite; }
|
||
/* 首个卡片呼吸光效 */
|
||
@keyframes breathGlow { 0%,100%{box-shadow: 0 2px 8px rgba(255,87,34,.06)} 50%{box-shadow: 0 2px 16px rgba(255,87,34,.18)} }
|
||
.platform-card-first { animation: breathGlow 2s ease-in-out infinite; border-color: #FFD600 !important; }
|
||
/* 点击手势提示 */
|
||
@keyframes tapHint { 0%,100%{transform: translate(0,0) scale(1)} 50%{transform: translate(-2px,2px) scale(.92)} }
|
||
.tap-hand { animation: tapHint 1.2s ease-in-out infinite; }
|
||
.gesture-hand-img { display: block; width: 100%; height: 100%; object-fit: contain; }
|
||
/* 加号二级高亮:贴近原按钮的双层呼吸圈 */
|
||
.demo-plus-focus {
|
||
display: none;
|
||
position: absolute;
|
||
z-index: 14;
|
||
width: 46px;
|
||
height: 46px;
|
||
border-radius: 50%;
|
||
transform: translate(-50%, -50%);
|
||
pointer-events: none;
|
||
}
|
||
.demo-plus-focus.circle { border-radius: 50%; }
|
||
.demo-plus-focus.pill { border-radius: 999px; }
|
||
.demo-plus-focus.rect { border-radius: 12px; }
|
||
.demo-plus-focus.confirm { border-radius: 4px 24px 24px 4px; }
|
||
.demo-plus-focus.clickable {
|
||
cursor: pointer;
|
||
pointer-events: auto;
|
||
}
|
||
.demo-plus-focus::before,
|
||
.demo-plus-focus::after {
|
||
content: "";
|
||
position: absolute;
|
||
inset: 5px;
|
||
border-radius: inherit;
|
||
border: 2px solid rgba(255,214,0,.92);
|
||
box-shadow: 0 0 12px rgba(255,214,0,.58);
|
||
transform-origin: 50% 50%;
|
||
animation: plusGuidePulse 1.45s ease-out infinite;
|
||
}
|
||
.demo-plus-focus::after {
|
||
inset: 3px;
|
||
border-color: rgba(255,255,255,.85);
|
||
animation-delay: .48s;
|
||
}
|
||
.demo-plus-core {
|
||
position: absolute;
|
||
left: 50%;
|
||
top: 50%;
|
||
width: calc(100% - 12px);
|
||
height: calc(100% - 12px);
|
||
transform: translate(-50%, -50%);
|
||
border-radius: inherit;
|
||
border: 2px solid #fff;
|
||
outline: 2px solid #FFD600;
|
||
box-shadow: 0 0 0 3px rgba(255,214,0,.18), 0 0 12px rgba(255,214,0,.68);
|
||
}
|
||
@keyframes plusGuidePulse {
|
||
0% { transform: scale(.76); opacity: .95; }
|
||
100% { transform: scale(1.38); opacity: 0; }
|
||
}
|
||
@keyframes plusGuideTap {
|
||
0%,100% { transform: translate(0,0) scale(1); }
|
||
50% { transform: translate(3px,-3px) scale(.93); }
|
||
}
|
||
#demoFinger.demo-plus-finger {
|
||
z-index: 14;
|
||
animation: plusGuideTap 1.18s ease-in-out infinite;
|
||
}
|
||
#demoFinger.demo-plus-finger .gesture-hand-img {
|
||
transform: scaleX(-1) rotate(-14deg);
|
||
}
|
||
/* 平台选择卡片 hover 效果 */
|
||
.platform-card:hover { border-color: #FF5722 !important; box-shadow: 0 0 0 1px #FF5722, 0 4px 14px rgba(255,87,34,.12); }
|
||
.platform-card:active { transform: scale(.98); }
|
||
/* 开始比价按钮光晕 */
|
||
@keyframes btnGlow {
|
||
0%,100% { box-shadow: 0 0 12px 4px rgba(218,165,0,.45), 0 0 28px 8px rgba(218,165,0,.15); }
|
||
50% { box-shadow: 0 0 22px 10px rgba(218,165,0,.6), 0 0 45px 16px rgba(218,165,0,.25); }
|
||
}
|
||
@keyframes btnGlowRing {
|
||
0% { transform: translate(-50%,-50%) scale(.85); opacity: .7; }
|
||
100% { transform: translate(-50%,-50%) scale(1.5); opacity: 0; }
|
||
}
|
||
@keyframes fadeInUp {
|
||
0% { opacity: 0; transform: translateY(20px); }
|
||
100% { opacity: 1; transform: translateY(0); }
|
||
}
|
||
@keyframes welcomeRing {
|
||
0% { transform: scale(1); opacity: .6; }
|
||
100% { transform: scale(1.4); opacity: 0; }
|
||
}
|
||
/* ===== Agent toast 数字暴涨动效 ===== */
|
||
@keyframes couponNumPop {
|
||
0% { transform: scale(1); }
|
||
30% { transform: scale(1.32); }
|
||
65% { transform: scale(.92); }
|
||
100% { transform: scale(1); }
|
||
}
|
||
.coupon-num-pop { animation: couponNumPop .28s ease-out; }
|
||
@keyframes couponPlusFly {
|
||
0% { opacity: 0; transform: translate(-50%, 0) scale(.6); }
|
||
20% { opacity: 1; transform: translate(calc(-50% + var(--dx, 0px) * .25), calc(var(--dy, -8px) * .25)) scale(1.1); }
|
||
100% { opacity: 0; transform: translate(calc(-50% + var(--dx, 0px)), var(--dy, -34px)) scale(.7); }
|
||
}
|
||
.coupon-plus-particle {
|
||
position: absolute; left: 50%; top: 6px;
|
||
font-size: 13px; font-weight: 900; color: #FF3D00;
|
||
text-shadow: 0 1px 4px rgba(255,107,0,.4);
|
||
pointer-events: none;
|
||
z-index: 3;
|
||
animation: couponPlusFly .85s ease-out forwards;
|
||
}
|
||
@keyframes couponBarFlow {
|
||
0% { width: 8%; }
|
||
100% { width: 92%; }
|
||
}
|
||
@keyframes couponBarShine {
|
||
0% { transform: translateX(-100%); }
|
||
100% { transform: translateX(400%); }
|
||
}
|
||
@keyframes giftAwait {
|
||
0%, 100% {
|
||
transform: translateY(-50%) scale(1) rotate(-8deg);
|
||
filter: drop-shadow(0 2px 4px rgba(255,180,0,.55));
|
||
}
|
||
50% {
|
||
transform: translateY(-72%) scale(1.18) rotate(8deg);
|
||
filter: drop-shadow(0 4px 10px rgba(255,180,0,.95));
|
||
}
|
||
}
|
||
/* ===== 比价副文案红包动效(摇摆 + 光晕 + sparkle)===== */
|
||
@keyframes redpacketBob {
|
||
0%, 100% { transform: translateY(0) rotate(-3deg); }
|
||
50% { transform: translateY(-3px) rotate(3deg); }
|
||
}
|
||
@keyframes redpacketGlow {
|
||
0%, 100% { opacity: .35; transform: scale(.85); }
|
||
50% { opacity: 1; transform: scale(1.18); }
|
||
}
|
||
@keyframes redpacketSparkleA {
|
||
0%, 100% { opacity: 0; transform: scale(.4); }
|
||
30%, 65% { opacity: 1; transform: scale(1); }
|
||
}
|
||
@keyframes redpacketSparkleB {
|
||
0%, 100% { opacity: 0; transform: scale(.4); }
|
||
20%, 55% { opacity: 1; transform: scale(1); }
|
||
}
|
||
.redpacket-bob { animation: redpacketBob 2.4s ease-in-out infinite; }
|
||
/* ===== AI 接管橘黄色流动光晕 ===== */
|
||
@property --aiGlowAngle {
|
||
syntax: '<angle>';
|
||
initial-value: 0deg;
|
||
inherits: false;
|
||
}
|
||
@keyframes aiGlowRotate { to { --aiGlowAngle: 360deg; } }
|
||
@keyframes aiGlowPulse {
|
||
0% { opacity: .7; }
|
||
50% { opacity: 1; }
|
||
100% { opacity: .7; }
|
||
}
|
||
@keyframes aiGlowBreathe {
|
||
0% { transform: scale(1); opacity: .85; }
|
||
50% { transform: scale(1.015); opacity: 1; }
|
||
100% { transform: scale(1); opacity: .85; }
|
||
}
|
||
.ai-takeover-glow {
|
||
display: none;
|
||
position: absolute;
|
||
inset: 0;
|
||
pointer-events: none;
|
||
z-index: 14;
|
||
border-radius: 32px;
|
||
}
|
||
.ai-takeover-glow.active { display: block; }
|
||
/* 外层流动光带:粗一圈 + 大模糊,形成柔和橘黄光晕 */
|
||
.ai-takeover-glow::before {
|
||
content: '';
|
||
position: absolute;
|
||
inset: 0;
|
||
padding: 8px;
|
||
border-radius: 32px;
|
||
background: conic-gradient(
|
||
from var(--aiGlowAngle, 0deg),
|
||
#FFE082 0%,
|
||
#FFC107 12%,
|
||
#FF8F00 24%,
|
||
#FF6B00 36%,
|
||
#FFB300 50%,
|
||
#FFD54F 62%,
|
||
#FF9800 75%,
|
||
#FF6B00 87%,
|
||
#FFE082 100%
|
||
);
|
||
-webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
|
||
-webkit-mask-composite: xor;
|
||
mask-composite: exclude;
|
||
filter: blur(7px);
|
||
animation: aiGlowRotate 5s linear infinite, aiGlowBreathe 3.2s ease-in-out infinite;
|
||
}
|
||
/* 内层柔光:从边缘向内渗透的橘色辉光,强化"光晕"感 */
|
||
.ai-takeover-glow::after {
|
||
content: '';
|
||
position: absolute;
|
||
inset: 0;
|
||
border-radius: 32px;
|
||
box-shadow: inset 0 0 36px rgba(255, 152, 0, .55),
|
||
inset 0 0 80px rgba(255, 107, 0, .28),
|
||
inset 0 0 140px rgba(255, 87, 34, .12);
|
||
animation: aiGlowPulse 2.6s ease-in-out infinite;
|
||
}
|
||
/* ===== 新手礼包弹窗 ===== */
|
||
.gift-overlay { position: absolute; inset: 0; background: rgba(0,0,0,.6); display: none; align-items: center; justify-content: center; z-index: 200; backdrop-filter: blur(2px); }
|
||
.gift-overlay.show { display: flex; animation: fadeIn .25s ease-out; }
|
||
.gift-card { width: 304px; background: #fff; border-radius: 24px; padding: 24px 16px; position: relative; box-shadow: 0 24px 60px rgba(0,0,0,.4); animation: giftPop .4s cubic-bezier(.34,1.56,.64,1); overflow: hidden; }
|
||
.gift-card::before { content: ''; position: absolute; top: 0; left: 0; right: 0; height: 120px; background: linear-gradient(180deg, #FFE066 0%, #FFD600 50%, transparent 100%); opacity: .6; pointer-events: none; }
|
||
.gift-close { position: absolute; top: 12px; right: 12px; width: 28px; height: 28px; border-radius: 14px; background: rgba(0,0,0,.08); display: flex; align-items: center; justify-content: center; font-size: 14px; color: #666; cursor: pointer; border: none; z-index: 2; }
|
||
.gift-confetti { font-size: 22px; text-align: center; letter-spacing: 4px; margin-bottom: 8px; position: relative; z-index: 1; }
|
||
.gift-title { font-size: 24px; font-weight: 600; color: #1a1a1a; text-align: center; margin-bottom: 4px; position: relative; z-index: 1; }
|
||
.gift-subtitle { font-size: 13px; color: var(--gray-700); text-align: center; margin-bottom: 16px; position: relative; z-index: 1; }
|
||
.gift-chest-wrap { position: relative; width: 160px; height: 160px; margin: 8px auto 16px; display: flex; align-items: center; justify-content: center; }
|
||
.gift-chest-glow { position: absolute; inset: 0; border-radius: 32px; background: radial-gradient(circle, rgba(255,214,0,.7) 0%, rgba(255,214,0,0) 65%); animation: chestGlow 2s ease-in-out infinite; }
|
||
.gift-chest-emoji { font-size: 48px; position: relative; z-index: 2; animation: chestBob 2s ease-in-out infinite; transition: transform .3s; }
|
||
.gift-card.opening .gift-chest-emoji { animation: chestShake .3s ease-out; }
|
||
/* 光线 burst */
|
||
.gift-burst { position: absolute; inset: 0; pointer-events: none; opacity: 0; }
|
||
.gift-card.opened .gift-burst { animation: burstFlash .6s ease-out; }
|
||
.gift-burst-ray { position: absolute; top: 50%; left: 50%; width: 6px; height: 80px; background: linear-gradient(180deg, rgba(255,214,0,1) 0%, rgba(255,214,0,0) 100%); transform-origin: 3px 0; }
|
||
.gift-burst-ray:nth-child(1) { transform: translate(-50%, 0) rotate(0deg); }
|
||
.gift-burst-ray:nth-child(2) { transform: translate(-50%, 0) rotate(60deg); }
|
||
.gift-burst-ray:nth-child(3) { transform: translate(-50%, 0) rotate(120deg); }
|
||
.gift-burst-ray:nth-child(4) { transform: translate(-50%, 0) rotate(180deg); }
|
||
.gift-burst-ray:nth-child(5) { transform: translate(-50%, 0) rotate(240deg); }
|
||
.gift-burst-ray:nth-child(6) { transform: translate(-50%, 0) rotate(300deg); }
|
||
.gift-amount { font-size: 48px; font-weight: 900; color: #FF5722; text-align: center; line-height: 1.1; display: none; }
|
||
.gift-amount-suffix { font-size: 18px; font-weight: 700; color: var(--gray-800); margin-left: 4px; }
|
||
.gift-amount-hint { font-size: 13px; color: var(--gray-700); text-align: center; margin: 6px 0 16px; display: none; }
|
||
.gift-card.opened .gift-stage-a { display: none; }
|
||
.gift-card.opened .gift-amount,
|
||
.gift-card.opened .gift-amount-hint { display: block; }
|
||
.gift-btn { width: 100%; height: 48px; border: none; border-radius: 24px; background: linear-gradient(180deg, #FFEB3B 0%, #FFD600 100%); color: #1a1a1a; font-size: 17px; font-weight: 700; cursor: pointer; box-shadow: 0 4px 16px rgba(255,214,0,.5); position: relative; z-index: 1; }
|
||
.gift-btn:active { opacity: .85; transform: translateY(1px); }
|
||
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
|
||
@keyframes giftPop { 0% { opacity: 0; transform: scale(.7) translateY(20px); } 100% { opacity: 1; transform: scale(1) translateY(0); } }
|
||
@keyframes chestBob { 0%,100% { transform: translateY(0) rotate(-2deg); } 50% { transform: translateY(-8px) rotate(2deg); } }
|
||
@keyframes chestGlow { 0%,100% { transform: scale(1); opacity: .6; } 50% { transform: scale(1.15); opacity: .9; } }
|
||
@keyframes chestShake { 0%,100% { transform: scale(1); } 25% { transform: scale(1.15) rotate(-8deg); } 75% { transform: scale(1.15) rotate(8deg); } }
|
||
@keyframes burstFlash { 0% { opacity: 0; transform: scale(.4); } 30% { opacity: 1; transform: scale(1.1); } 100% { opacity: 0; transform: scale(1.6); } }
|
||
/* 飞行金币 */
|
||
.fly-coin { position: absolute; left: 50%; top: 50%; font-size: 28px; line-height: 1; pointer-events: none; z-index: 250;
|
||
transform: translate(-50%, -50%);
|
||
animation: coinFly 1100ms cubic-bezier(.55,.05,.7,.4) forwards;
|
||
animation-delay: var(--d, 0ms);
|
||
--tx: 0px; --ty: 0px; --bx: 0px; --by: 0px;
|
||
filter: drop-shadow(0 2px 4px rgba(255,179,0,.6));
|
||
}
|
||
@keyframes coinFly {
|
||
0% { opacity: 0; transform: translate(-50%, -50%) scale(.4); }
|
||
15% { opacity: 1; transform: translate(calc(-50% + var(--bx)*.2), calc(-50% + var(--by)*.2)) scale(1.4); }
|
||
35% { opacity: 1; transform: translate(calc(-50% + var(--bx)), calc(-50% + var(--by))) scale(1.2); }
|
||
100% { opacity: 0; transform: translate(calc(-50% + var(--tx)), calc(-50% + var(--ty))) scale(.5); }
|
||
}
|
||
/* 福利 tab pulse + +5000 飘字 */
|
||
.tab-pulse { animation: tabPulse .6s ease-out; }
|
||
@keyframes tabPulse { 0% { transform: scale(1); } 40% { transform: scale(1.3); filter: drop-shadow(0 0 12px rgba(255,214,0,.9)); } 100% { transform: scale(1); } }
|
||
.tab-coin-badge { position: absolute; bottom: 50px; left: 50%; transform: translateX(-50%); background: linear-gradient(180deg,#FFEB3B,#FFD600); color: #1a1a1a; font-size: 13px; font-weight: 600; padding: 4px 8px; border-radius: 32px; box-shadow: 0 4px 12px rgba(255,179,0,.6); pointer-events: none; opacity: 0; z-index: 150; white-space: nowrap; }
|
||
.tab-coin-badge.show { animation: floatUp 1.2s ease-out forwards; }
|
||
@keyframes floatUp { 0% { opacity: 0; transform: translate(-50%, 0) scale(.7); } 20% { opacity: 1; transform: translate(-50%, -8px) scale(1.1); } 100% { opacity: 0; transform: translate(-50%, -32px) scale(1); } }
|
||
/* === 登录页 · E1 方案:PNG 背景 + 纯白渐变蒙版(分界 ~62%,红包区不糊) === */
|
||
/* 背景层:PNG 满屏 + 横向渐变兜底色(PNG 加载失败时不会露白) */
|
||
#login {
|
||
background: url("../../assets/login/index/redpacket-bg.png") center top / cover no-repeat,
|
||
linear-gradient(90deg, #FEE7B7 0%, #FDEFD0 50%, #FEE7B7 100%);
|
||
}
|
||
/* E1 渐变蒙版:28% 起、52.5% 之前完全透明(保红包+优惠券不糊),57% 处 .95,64% 处完全不透明 */
|
||
#login::before {
|
||
content: '';
|
||
position: absolute;
|
||
left: 0; right: 0; top: 28%; bottom: 0;
|
||
background: linear-gradient(180deg,
|
||
rgba(255, 255, 255, 0) 0%,
|
||
rgba(255, 255, 255, 0) 34%,
|
||
rgba(255, 255, 255, .55) 38%,
|
||
rgba(255, 255, 255, .95) 40.5%,
|
||
rgba(255, 255, 255, 1) 50%);
|
||
pointer-events: none;
|
||
z-index: 1;
|
||
}
|
||
/* 登录按钮去掉黄色光晕(全局 --cta-shadow 是黄底配黄阴影,登录页是白底要换中性阴影) */
|
||
#login .btn-cta {
|
||
box-shadow: 0 4px 14px rgba(0, 0, 0, .08), inset 0 1px 0 rgba(255, 255, 255, .55);
|
||
}
|
||
#login .btn-cta:active {
|
||
box-shadow: 0 2px 6px rgba(0, 0, 0, .06), inset 0 1px 0 rgba(255, 255, 255, .55);
|
||
}
|
||
/* 登录控件区:按钮位置沿用上一版,协议固定到底部 */
|
||
.lg-bottom { position: absolute; inset: 0; z-index: 5; }
|
||
.login-quick { position: absolute; inset: 0; display: block; }
|
||
.login-masked-phone { position: absolute; left: 0; right: 0; top: 64%; text-align: center; font-size: 28px; font-weight: 600; color: var(--gray-900); letter-spacing: .02em; line-height: 1; font-variant-numeric: tabular-nums; }
|
||
.login-main-btn { position: absolute; left: 7.5%; right: 7.5%; top: 71%; width: auto !important; height: 7.8%; min-height: 50px; font-size: 18px; }
|
||
.login-other-link { position: absolute; left: 0; right: 0; top: 81.5%; display: flex; align-items: center; justify-content: center; gap: 2px; border: 0; background: transparent; color: #999999; font-size: 13px; font-weight: 600; letter-spacing: .02em; cursor: pointer; font-family: inherit; }
|
||
.login-other-link .arrow { font-size: 15px; line-height: 1; color: inherit; transform: translateY(-.5px); }
|
||
.login-agreement { position: absolute; left: 50%; bottom: 24px; transform: translateX(-50%); z-index: 6; display: inline-flex; align-items: center; gap: 8px; border: 0; background: transparent; color: #999999; font-size: 12px; line-height: 1; white-space: nowrap; cursor: pointer; font-family: inherit; padding: 0; }
|
||
.login-agreement .check { width: 16px; height: 16px; margin-top: 2px; border-radius: 50%; border: 1.5px solid #CCCCCC; background: #fff; flex: 0 0 auto; position: relative; }
|
||
.login-agreement.checked .check { border-color: transparent; background: transparent url("data:image/svg+xml;utf8,<svg xmlns='http: //www.w3.org/2000/svg' fill='none' viewBox='0 0 16 16' stroke='%23D85A1F' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'><circle cx='8' cy='8' r='7'/><path d='M5 8.25 7 10 11 6'/></svg>") center/100% 100% no-repeat; background-origin: border-box; }
|
||
.login-agreement .link, .login-agreement-sheet-copy .link { color: #E65100; font-weight: 700; }
|
||
.login-phone-panel { position: absolute; left: 40px; right: 40px; top: 61%; z-index: 6; }
|
||
/* 祝贺页底部登录面板(方案 A:完整 banner + 白底简洁登录,celebration 屏内嵌一键登录) */
|
||
.celeb-login {
|
||
flex-shrink: 0; padding: 16px 24px 24px;
|
||
background: #fff; border-top: 1px solid var(--gray-200);
|
||
position: relative; z-index: 11; /* 高于 confettiCanvas(z-index: 10) */
|
||
display: flex; flex-direction: column; align-items: stretch;
|
||
}
|
||
.celeb-login-phone {
|
||
text-align: center; font-size: 24px; font-weight: 600;
|
||
color: var(--gray-900); letter-spacing: .02em; margin-bottom: 12px;
|
||
font-variant-numeric: tabular-nums; line-height: 1;
|
||
}
|
||
.celeb-login > .btn-cta { width: 100%; }
|
||
.celeb-login-other {
|
||
display: block; width: 100%; margin-top: 12px;
|
||
border: 0; background: transparent; cursor: pointer; font-family: inherit;
|
||
text-align: center; color: #999999; font-size: 13px; font-weight: 600; letter-spacing: .02em;
|
||
}
|
||
.celeb-login-other .arrow { font-size: 14px; vertical-align: -1px; color: inherit; }
|
||
.celeb-login-agreement {
|
||
position: static !important; transform: none !important;
|
||
margin: 12px auto 0; display: inline-flex; left: auto; right: auto; bottom: auto;
|
||
align-self: center;
|
||
}
|
||
/* 入口页协议 · 底部抽屉(一键登录场景) */
|
||
.login-agreement-sheet-layer { display: none; position: absolute; inset: 0; z-index: 30; align-items: flex-end; background: rgba(0,0,0,.48); }
|
||
.login-agreement-sheet { width: 100%; padding: 24px 24px 32px; border-radius: 24px 24px 0 0; background: #FFFDF5; color: #1A1A1A; text-align: center; box-shadow: 0 -12px 30px rgba(0,0,0,.16); animation: loginSheetIn .24s cubic-bezier(.22,1,.36,1); }
|
||
@keyframes loginSheetIn { from { transform: translateY(24px); opacity: .75; } to { transform: translateY(0); opacity: 1; } }
|
||
.login-agreement-sheet-title { font-size: 17px; font-weight: 600; letter-spacing: .01em; margin-bottom: 12px; }
|
||
.login-agreement-sheet-copy { font-size: 13px; line-height: 1.6; color: #666666; margin-bottom: 16px; }
|
||
.login-agreement-sheet-primary { width: 100%; height: 50px; border: 0; border-radius: 999px; background: linear-gradient(180deg, #FFE066 0%, #FFD600 55%, #FFC400 100%); color: #5A3A00; font-size: 16px; font-weight: 700; letter-spacing: .04em; box-shadow: 0 12px 24px rgba(255, 200, 0, .28), inset 0 1px 0 rgba(255, 255, 255, .65); cursor: pointer; font-family: inherit; }
|
||
.login-agreement-sheet-secondary { margin-top: 12px; border: 0; background: transparent; color: #999999; font-size: 13px; cursor: pointer; font-family: inherit; padding: 8px 16px; }
|
||
/* 独立手机号登录页 */
|
||
#loginPhone { background: #fff; }
|
||
.lp-topbar { position: absolute; top: 44px; left: 0; right: 0; height: 44px; display: flex; align-items: center; padding: 0 8px; z-index: 10; }
|
||
.lp-back { width: 44px; height: 44px; display: flex; align-items: center; justify-content: center; font-size: 24px; color: var(--gray-900); background: none; border: none; cursor: pointer; font-family: inherit; }
|
||
.lp-title { position: absolute; left: 0; right: 0; top: 132px; text-align: center; font-size: 24px; font-weight: 600; color: var(--gray-900); letter-spacing: .04em; }
|
||
.lp-form { position: absolute; left: 32px; right: 32px; top: 220px; }
|
||
.lp-input-row { display: flex; align-items: center; height: 50px; border-bottom: 1px solid var(--gray-200); }
|
||
.lp-input-row.focused { border-bottom-color: var(--gray-900); }
|
||
.lp-cc { font-size: 17px; font-weight: 600; color: var(--gray-900); letter-spacing: .02em; display: inline-flex; align-items: center; gap: 4px; margin-right: 12px; flex-shrink: 0; }
|
||
.lp-cc .chev { font-size: 10px; color: var(--gray-700); margin-left: 2px; }
|
||
.lp-divider { width: 1px; height: 18px; background: var(--gray-200); margin-right: 16px; flex-shrink: 0; }
|
||
.lp-input { flex: 1; height: 100%; border: none; padding: 0; font-size: 17px; font-weight: 500; color: var(--gray-900); letter-spacing: .04em; font-variant-numeric: tabular-nums; outline: none; background: transparent; }
|
||
.lp-input::placeholder { color: var(--gray-400); font-weight: 400; }
|
||
.lp-cta { width: 100%; margin-top: 40px; margin-bottom: 16px; }
|
||
.lp-cta.disabled { background: linear-gradient(180deg, #FFE0B2 0%, #FFE066 100%); color: rgba(26,26,26,.45); box-shadow: none; pointer-events: none; }
|
||
.lp-agreement { display: flex; align-items: flex-start; gap: 8px; color: #999999; font-size: 12px; line-height: 1.55; padding-right: 8px; cursor: pointer; border: 0; background: transparent; text-align: left; font-family: inherit; width: 100%; }
|
||
.lp-agreement .check { width: 16px; height: 16px; border-radius: 50%; border: 1.5px solid #CCCCCC; background: #fff; flex: 0 0 auto; margin-top: 2px; position: relative; }
|
||
.lp-agreement.checked .check { border-color: transparent; background: transparent url("data:image/svg+xml;utf8,<svg xmlns='http: //www.w3.org/2000/svg' fill='none' viewBox='0 0 16 16' stroke='%23D85A1F' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'><circle cx='8' cy='8' r='7'/><path d='M5 8.25 7 10 11 6'/></svg>") center/100% 100% no-repeat; background-origin: border-box; }
|
||
.lp-agreement .link { color: #E65100; font-weight: 600; }
|
||
/* 验证码步骤(沿用原 step2 视觉,放在新页内) */
|
||
.lp-sms-hint { font-size: 13px; color: var(--gray-500); margin-bottom: 16px; }
|
||
.lp-sms-boxes { display: flex; gap: 8px; justify-content: center; margin-bottom: 16px; }
|
||
.lp-sms-boxes input { width: 40px; height: 48px; border-radius: 12px; border: 1.5px solid var(--gray-200); text-align: center; font-size: 20px; font-weight: 700; outline: none; }
|
||
.lp-sms-actions { display: flex; justify-content: center; gap: 16px; }
|
||
.lp-sms-actions span { font-size: 13px; cursor: pointer; }
|
||
/* 手机号页协议 · 居中弹窗 */
|
||
.lp-modal-layer { display: none; position: absolute; inset: 0; z-index: 30; align-items: center; justify-content: center; padding: 0 32px; background: rgba(0,0,0,.5); }
|
||
.lp-modal-card { width: 100%; padding: 24px 24px 16px; border-radius: 18px; background: #fff; color: #1A1A1A; text-align: center; box-shadow: 0 20px 60px rgba(0,0,0,.3); animation: lpModalIn .24s cubic-bezier(.22,1,.36,1); }
|
||
@keyframes lpModalIn { from { transform: scale(.94); opacity: 0; } to { transform: scale(1); opacity: 1; } }
|
||
.lp-modal-title { font-size: 17px; font-weight: 600; letter-spacing: .01em; margin-bottom: 12px; color: var(--gray-900); }
|
||
.lp-modal-copy { font-size: 13px; line-height: 1.7; color: var(--gray-700); margin-bottom: 24px; text-align: left; }
|
||
.lp-modal-copy .link { color: #E65100; font-weight: 600; }
|
||
.lp-modal-primary { width: 100%; height: 44px; border: 0; border-radius: 24px; background: linear-gradient(180deg, #FFE066 0%, #FFD600 100%); color: var(--gray-900); font-size: 15px; font-weight: 700; letter-spacing: .04em; box-shadow: 0 4px 14px rgba(0, 0, 0, .08), inset 0 1px 0 rgba(255, 255, 255, .55); cursor: pointer; font-family: inherit; }
|
||
.lp-modal-secondary { margin-top: 4px; height: 40px; border: 0; background: transparent; color: var(--gray-500); font-size: 13px; cursor: pointer; font-family: inherit; padding: 8px 16px; }
|
||
/* 新人礼包 · 优惠券样式 */
|
||
.gift-coupon { position: relative; background: linear-gradient(90deg,#FF6B6B 0%,#FF5722 100%); border-radius: 24px; padding: 16px 16px 16px 24px; display: flex; align-items: center; gap: 12px; box-shadow: 0 6px 18px rgba(255,87,34,.35); color: #fff; overflow: visible; }
|
||
.gift-coupon::before { content: ''; position: absolute; top: 50%; left: -6px; transform: translateY(-50%); width: 12px; height: 12px; background: #FFF8E1; border-radius: 50%; }
|
||
.gift-coupon::after { content: ''; position: absolute; left: 16px; top: 12px; bottom: 12px; width: 1px; background-image: linear-gradient(180deg, rgba(255,255,255,.5) 50%, transparent 50%); background-size: 1px 6px; }
|
||
.gift-coupon .gc-icon { flex-shrink: 0; font-size: 48px; line-height: 1; filter: drop-shadow(0 2px 6px rgba(0,0,0,.2)); }
|
||
.gift-coupon .gc-title { font-size: 18px; font-weight: 900; color: #fff; margin-bottom: 4px; }
|
||
.gift-coupon .gc-sub { font-size: 12px; color: rgba(255,255,255,.9); }
|
||
/* 新人礼包 · 7 方案样式(用于 ?giftvariant= 切换) */
|
||
.gv-base { position: relative; border-radius: 24px; display: flex; align-items: center; gap: 12px; }
|
||
.gv-a { background: linear-gradient(135deg,#FFF3E0,#FFE0B2); padding: 16px; box-shadow: 0 4px 16px rgba(255,179,0,.18); }
|
||
.gv-a .gv-icon { flex-shrink: 0; font-size: 48px; line-height: 1; }
|
||
.gv-a .gv-title { font-size: 18px; font-weight: 600; color: #1a1a1a; margin-bottom: 4px; }
|
||
.gv-a .gv-sub { font-size: 12px; color: var(--gray-700); }
|
||
.gv-b { background: linear-gradient(135deg,#FFF3E0,#FFE0B2); padding: 16px; box-shadow: 0 4px 16px rgba(255,179,0,.18); }
|
||
.gv-b .gv-icon { flex-shrink: 0; font-size: 48px; line-height: 1; }
|
||
.gv-b .gv-title { font-size: 18px; font-weight: 600; color: #1a1a1a; margin-bottom: 4px; }
|
||
.gv-b .gv-sub { font-size: 12px; color: var(--gray-700); }
|
||
.gv-b .gv-stamp { position: absolute; top: -10px; right: 14px; background: linear-gradient(135deg,#FF5722,#E65100); color: #fff; font-size: 11px; font-weight: 600; padding: 6px 12px; border-radius: 12px 12px 12px 4px; box-shadow: 0 4px 10px rgba(255,87,34,.4); transform: rotate(8deg); }
|
||
.gv-c { background: linear-gradient(135deg,#FFF3E0,#FFE0B2); padding: 16px; box-shadow: 0 4px 16px rgba(255,179,0,.18); }
|
||
.gv-c .gv-icon { flex-shrink: 0; font-size: 48px; line-height: 1; }
|
||
.gv-c .gv-title { font-size: 18px; font-weight: 600; color: #1a1a1a; margin-bottom: 6px; }
|
||
.gv-c .gv-cd { display: inline-flex; align-items: center; gap: 4px; background: #1a1a1a; color: #FFD600; font-size: 11px; font-weight: 600; padding: 4px 8px; border-radius: 8px; font-variant-numeric: tabular-nums; }
|
||
.gv-c .gv-blink { animation: gvBlink 1s infinite; }
|
||
@keyframes gvBlink { 50% { opacity: .3; } }
|
||
.gv-d { background: linear-gradient(135deg,#FFE0B2 0%,#FFE066 50%,#FFE066 100%); padding: 24px 16px; box-shadow: 0 8px 24px rgba(255,87,34,.25), inset 0 1px 0 rgba(255,255,255,.6); overflow: hidden; }
|
||
.gv-d .gv-iconwrap { position: relative; flex-shrink: 0; width: 70px; height: 70px; display: flex; align-items: center; justify-content: center; }
|
||
.gv-d .gv-icon { position: relative; font-size: 48px; line-height: 1; filter: drop-shadow(0 4px 8px rgba(255,87,34,.3)); }
|
||
.gv-d .gv-text { position: relative; z-index: 1; }
|
||
.gv-d .gv-title { font-size: 20px; font-weight: 900; color: #1a1a1a; margin-bottom: 4px; letter-spacing: -.3px; }
|
||
.gv-d .gv-sub { font-size: 13px; color: #5A3A00; font-weight: 600; }
|
||
.gv-f { background: radial-gradient(circle at 50% 20%, rgba(255,255,255,.8), transparent 50%), linear-gradient(135deg,#FFF3E0,#FFE0B2); padding: 24px 16px 24px; box-shadow: 0 8px 24px rgba(255,179,0,.25); flex-direction: column; text-align: center; overflow: hidden; }
|
||
.gv-f .gv-rays { position: absolute; top: -20px; left: 50%; transform: translateX(-50%); width: 200px; height: 200px; pointer-events: none; background: conic-gradient(from 0deg, rgba(255,213,79,.3) 0deg, transparent 30deg, rgba(255,213,79,.3) 60deg, transparent 90deg, rgba(255,213,79,.3) 120deg, transparent 150deg, rgba(255,213,79,.3) 180deg, transparent 210deg, rgba(255,213,79,.3) 240deg, transparent 270deg, rgba(255,213,79,.3) 300deg, transparent 330deg); border-radius: 50%; animation: gvSpin 12s linear infinite; opacity: .6; }
|
||
@keyframes gvSpin { to { transform: translateX(-50%) rotate(360deg); } }
|
||
.gv-f .gv-iconwrap { position: relative; z-index: 1; margin-bottom: 8px; }
|
||
.gv-f .gv-icon { font-size: 48px; line-height: 1; display: inline-block; animation: gvBob 2.5s infinite ease-in-out; filter: drop-shadow(0 6px 12px rgba(255,87,34,.3)); }
|
||
@keyframes gvBob { 50% { transform: translateY(-4px); } }
|
||
@keyframes gvPop { 0% { transform: scale(.4); opacity: 0; } 60% { transform: scale(1.08); opacity: 1; } 100% { transform: scale(1); opacity: 1; } }
|
||
.gv-f .gv-title { position: relative; z-index: 1; font-size: 22px; font-weight: 900; color: #1a1a1a; margin-bottom: 4px; letter-spacing: -.3px; }
|
||
.gv-f .gv-sub { position: relative; z-index: 1; font-size: 12px; color: #5A3A00; font-weight: 600; }
|
||
.gv-g { background: linear-gradient(135deg,#FFF3E0,#FFE0B2); padding: 16px; box-shadow: 0 4px 16px rgba(255,179,0,.18); overflow: hidden; }
|
||
.gv-g .gv-iconwrap { position: relative; flex-shrink: 0; width: 56px; height: 56px; display: flex; align-items: center; justify-content: center; }
|
||
.gv-g .gv-icon { font-size: 48px; line-height: 1; }
|
||
.gv-g .gv-spark { position: absolute; width: 6px; height: 6px; background: #FFD600; border-radius: 50%; box-shadow: 0 0 8px #FFD600; }
|
||
.gv-g .gv-s1 { top: 0; right: 4px; animation: gvSparkle 1.8s infinite; }
|
||
.gv-g .gv-s2 { bottom: 4px; left: 0; animation: gvSparkle 1.8s infinite .6s; }
|
||
.gv-g .gv-s3 { top: 50%; right: -4px; animation: gvSparkle 1.8s infinite 1.2s; }
|
||
@keyframes gvSparkle { 0%,100% { transform: scale(0); opacity: 0; } 50% { transform: scale(1); opacity: 1; } }
|
||
.gv-g .gv-title { font-size: 18px; font-weight: 900; color: #1a1a1a; margin-bottom: 4px; }
|
||
.gv-g .gv-title em { font-style: normal; background: linear-gradient(90deg, #FF5722, #FFB300); -webkit-background-clip: text; background-clip: text; color: transparent; margin-left: 4px; font-weight: 900; }
|
||
.gv-g .gv-sub { font-size: 12px; color: var(--gray-700); }
|
||
body.gv-embed .variant-toggle { display: none !important; }
|
||
|
||
/* ===== Coupon prompt 变体 · 平台选择卡通用样式 ===== */
|
||
.cp-card { transition: all .2s; cursor: pointer; }
|
||
.cp-card[data-checked="false"] { opacity: .5; }
|
||
.cp-card[data-checked="false"] .cp-check { background: var(--gray-300) !important; }
|
||
.cp-card[data-checked="false"] .cp-check svg { opacity: 0; }
|
||
/* 选中态边框色按主题分 */
|
||
.cp-card-pink[data-checked="false"] { border-color: var(--gray-200) !important; }
|
||
.cp-card-red[data-checked="false"] { border-color: var(--gray-200) !important; }
|
||
.cp-card-yellow[data-checked="false"] { border-color: var(--gray-200) !important; }
|
||
.cp-card-yellow[data-checked="false"] .cp-toggle { background: var(--gray-200) !important; }
|
||
.cp-card-yellow[data-checked="false"] .cp-toggle::after { transform: translateX(0) !important; }
|
||
|
||
/* ============================================
|
||
一键领券完成 · 迭代 6 配色 B(朱红卡包风)
|
||
============================================ */
|
||
.coupon-done-k-mask {
|
||
position: absolute; inset: 0;
|
||
background: rgba(0,0,0,.55);
|
||
z-index: 28;
|
||
animation: kFadeIn .3s ease-out;
|
||
}
|
||
@keyframes kFadeIn { from { opacity: 0; } to { opacity: 1; } }
|
||
|
||
.coupon-done-k {
|
||
/* 配色 B · 朱红 */
|
||
--v6-bg-top: #FF1744;
|
||
--v6-bg-bottom: #C62828;
|
||
--v6-pocket-top: #FF5252;
|
||
--v6-pocket-bottom: #E53935;
|
||
--v6-notch: #C62828;
|
||
|
||
position: absolute; left: 50%; top: 50%;
|
||
transform: translate(-50%, -50%);
|
||
z-index: 30;
|
||
width: 296px;
|
||
background: linear-gradient(180deg, var(--v6-bg-top) 0%, var(--v6-bg-bottom) 65%, var(--v6-bg-bottom) 100%);
|
||
border-radius: 24px;
|
||
box-shadow: 0 20px 50px rgba(0,0,0,.4);
|
||
overflow: visible;
|
||
animation: kPopIn .5s cubic-bezier(.34,1.56,.64,1);
|
||
}
|
||
@keyframes kPopIn {
|
||
0% { opacity: 0; transform: translate(-50%, -50%) scale(.85); }
|
||
100% { opacity: 1; transform: translate(-50%, -50%) scale(1); }
|
||
}
|
||
|
||
/* 顶部居中品牌 logo(与 splash / 浮窗一致:黄色圆角方块 + 机器人 SVG + 文字) */
|
||
.coupon-done-k .coupon-done-logo {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
gap: 8px;
|
||
padding: 16px 0 2px;
|
||
position: relative;
|
||
z-index: 3;
|
||
}
|
||
.coupon-done-k .coupon-done-logo .logo-mark {
|
||
width: 32px; height: 32px;
|
||
border-radius: 8px;
|
||
background: linear-gradient(135deg, #FFD600, #FFB300);
|
||
display: flex; align-items: center; justify-content: center;
|
||
flex-shrink: 0;
|
||
box-shadow: 0 4px 10px rgba(0,0,0,.22);
|
||
}
|
||
.coupon-done-k .coupon-done-logo .logo-text {
|
||
font-size: 15px; font-weight: 900;
|
||
color: #fff;
|
||
letter-spacing: 0.8px;
|
||
text-shadow: 0 1px 2px rgba(0,0,0,.22);
|
||
}
|
||
|
||
/* sparkle 黄色星光 */
|
||
.coupon-done-k .v6-sparkle {
|
||
position: absolute;
|
||
width: 7px; height: 7px;
|
||
background: #FFE066; border-radius: 50%;
|
||
box-shadow: 0 0 8px #FFE082;
|
||
animation: kSparkleTwinkle 1.5s infinite ease-in-out;
|
||
z-index: 2;
|
||
}
|
||
.coupon-done-k .v6-sparkle.s1 { top: 14px; left: 22px; }
|
||
.coupon-done-k .v6-sparkle.s2 { top: 22px; right: 28px; animation-delay: .3s; }
|
||
.coupon-done-k .v6-sparkle.s3 { top: 60px; left: 28px; animation-delay: .6s; width: 5px; height: 5px; }
|
||
.coupon-done-k .v6-sparkle.s4 { top: 50px; right: 32px; animation-delay: .9s; width: 5px; height: 5px; }
|
||
.coupon-done-k .v6-sparkle.s5 { top: 38px; left: 50%; animation-delay: 1.1s; width: 4px; height: 4px; }
|
||
@keyframes kSparkleTwinkle {
|
||
0%, 100% { opacity: .3; transform: scale(.6); }
|
||
50% { opacity: 1; transform: scale(1.2); }
|
||
}
|
||
|
||
/* 头部双行渐变文案(票卡删除后改为页面中心展示) */
|
||
.coupon-done-k .v6-head {
|
||
text-align: center;
|
||
padding: 24px 16px 24px;
|
||
color: #fff; position: relative; z-index: 1;
|
||
}
|
||
.coupon-done-k .v6-head .lead-line {
|
||
font-size: 20px; font-weight: 600;
|
||
margin-bottom: 12px;
|
||
background: linear-gradient(180deg, #fff 30%, #FFE0B2 100%);
|
||
-webkit-background-clip: text;
|
||
-webkit-text-fill-color: transparent;
|
||
background-clip: text;
|
||
letter-spacing: 1px;
|
||
}
|
||
.coupon-done-k .v6-head .num-line {
|
||
font-size: 28px; font-weight: 900;
|
||
line-height: 1.1;
|
||
text-shadow: 0 2px 10px rgba(0,0,0,.28);
|
||
letter-spacing: 0.5px;
|
||
}
|
||
.coupon-done-k .v6-head .num-line .num {
|
||
color: #FFE066;
|
||
font-family: -apple-system, "DIN Alternate", sans-serif;
|
||
font-size: 36px;
|
||
margin-right: 2px;
|
||
}
|
||
.coupon-done-k .v6-head .num-line .rest {
|
||
background: linear-gradient(180deg, #fff 30%, #FFE066 100%);
|
||
-webkit-background-clip: text;
|
||
-webkit-text-fill-color: transparent;
|
||
background-clip: text;
|
||
}
|
||
/* 平台来源:"来自 + 两个 logo",不写平台名 */
|
||
.coupon-done-k .v6-from {
|
||
display: flex; align-items: center; justify-content: center;
|
||
gap: 8px;
|
||
padding: 6px 16px 12px;
|
||
position: relative; z-index: 1;
|
||
}
|
||
.coupon-done-k .v6-from .label {
|
||
font-size: 12px; font-weight: 600;
|
||
color: rgba(255,255,255,.85);
|
||
letter-spacing: 0.04em;
|
||
}
|
||
.coupon-done-k .v6-from .lgs { display: flex; align-items: center; gap: 6px; }
|
||
.coupon-done-k .v6-from .lg {
|
||
width: 28px; height: 28px;
|
||
border-radius: 8px; overflow: hidden;
|
||
border: 2px solid #fff;
|
||
box-shadow: 0 2px 6px rgba(0,0,0,.25);
|
||
background: #fff;
|
||
}
|
||
.coupon-done-k .v6-from .lg img { width: 100%; height: 100%; object-fit: cover; }
|
||
|
||
/* v3:标题内联式 — 把"领取自 + 平台 logo"嵌入第一行文案,密度最高 */
|
||
.coupon-done-k .v6-head .lead-line-inline {
|
||
display: inline-flex; align-items: center; justify-content: center;
|
||
flex-wrap: wrap; gap: 4px;
|
||
/* 取消渐变文字,避免与内联图片混搭显得别扭 */
|
||
background: none;
|
||
-webkit-text-fill-color: #fff;
|
||
color: #fff;
|
||
letter-spacing: .3px;
|
||
}
|
||
.coupon-done-k .v6-head .lead-line-inline .lg-inline {
|
||
display: inline-block;
|
||
width: 28px; height: 28px;
|
||
border-radius: 8px; overflow: hidden;
|
||
box-shadow: 0 1px 4px rgba(0,0,0,.25);
|
||
vertical-align: middle;
|
||
}
|
||
.coupon-done-k .v6-head .lead-line-inline .lg-inline img { width: 100%; height: 100%; object-fit: cover; display: block; }
|
||
|
||
/* v2:领取自上提(顶部胶囊;与领取数量绑定为同一信息块) */
|
||
.coupon-done-k .v6-from-top {
|
||
display: inline-flex; align-items: center; gap: 6px;
|
||
margin: 0 auto 12px;
|
||
padding: 4px 12px 4px 8px;
|
||
background: rgba(255,255,255,.16);
|
||
border: 1px solid rgba(255,255,255,.22);
|
||
border-radius: 999px;
|
||
backdrop-filter: blur(6px);
|
||
-webkit-backdrop-filter: blur(6px);
|
||
}
|
||
.coupon-done-k .v6-from-top .label {
|
||
font-size: 11px; font-weight: 700;
|
||
color: rgba(255,255,255,.92);
|
||
letter-spacing: 0.04em;
|
||
}
|
||
.coupon-done-k .v6-from-top .lgs { gap: 4px; }
|
||
.coupon-done-k .v6-from-top .lg {
|
||
width: 18px; height: 18px;
|
||
border-width: 1.5px;
|
||
box-shadow: 0 1px 3px rgba(0,0,0,.2);
|
||
}
|
||
/* 整体 head 容器在使用 v6-from-top 时改 flex column 居中(让胶囊上居中) */
|
||
.coupon-done-k .v6-head:has(> .v6-from-top) {
|
||
display: flex; flex-direction: column; align-items: center;
|
||
padding-top: 12px;
|
||
}
|
||
.coupon-done-k .v6-head:has(> .v6-from-top) .lead-line {
|
||
margin-bottom: 8px;
|
||
}
|
||
|
||
/* 白色票卡 */
|
||
.coupon-done-k .v6-tickets {
|
||
display: flex; gap: 12px;
|
||
padding: 6px 16px 16px;
|
||
position: relative; z-index: 1;
|
||
}
|
||
.coupon-done-k .v6-tickets .pl {
|
||
flex: 1;
|
||
background: #fff;
|
||
border-radius: 8px;
|
||
padding: 12px 6px;
|
||
text-align: center;
|
||
position: relative;
|
||
box-shadow: 0 4px 12px rgba(0,0,0,.15);
|
||
}
|
||
/* 票卡左右切角 */
|
||
.coupon-done-k .v6-tickets .pl::before,
|
||
.coupon-done-k .v6-tickets .pl::after {
|
||
content: '';
|
||
position: absolute;
|
||
width: 12px; height: 12px;
|
||
background: var(--v6-bg-top);
|
||
border-radius: 50%;
|
||
top: 50%; transform: translateY(-50%);
|
||
}
|
||
.coupon-done-k .v6-tickets .pl::before { left: -6px; clip-path: inset(0 0 0 50%); }
|
||
.coupon-done-k .v6-tickets .pl::after { right: -6px; clip-path: inset(0 50% 0 0); }
|
||
.coupon-done-k .v6-tickets .pl .num {
|
||
font-size: 24px; font-weight: 900; color: #E02E24;
|
||
font-family: -apple-system, "DIN Alternate", sans-serif;
|
||
line-height: 1; letter-spacing: -0.5px;
|
||
}
|
||
.coupon-done-k .v6-tickets .pl .num small {
|
||
font-size: 11px; color: #E02E24; font-weight: 700; margin-left: 2px;
|
||
}
|
||
.coupon-done-k .v6-tickets .pl .dash {
|
||
margin: 8px 4px;
|
||
border-top: 1px dashed #FFCDD2;
|
||
}
|
||
.coupon-done-k .v6-tickets .pl .lg {
|
||
width: 32px; height: 32px;
|
||
border-radius: 8px; overflow: hidden;
|
||
background: #FFF8E1; margin: 0 auto;
|
||
box-shadow: 0 2px 5px rgba(0,0,0,.06);
|
||
}
|
||
.coupon-done-k .v6-tickets .pl .lg img { width: 100%; height: 100%; object-fit: cover; }
|
||
|
||
/* pocket 上层(浅)+ U 形凹口 */
|
||
.coupon-done-k .v6-pocket {
|
||
background: linear-gradient(180deg, var(--v6-pocket-top) 0%, var(--v6-pocket-bottom) 100%);
|
||
padding: 24px 16px 12px;
|
||
position: relative;
|
||
z-index: 1;
|
||
border-radius: 24px;
|
||
box-shadow: 0 -6px 14px rgba(0,0,0,.18);
|
||
}
|
||
.coupon-done-k .v6-pocket-notch {
|
||
position: absolute;
|
||
top: 0; left: 50%;
|
||
transform: translateX(-50%);
|
||
width: 44px; height: 16px;
|
||
background: var(--v6-notch);
|
||
border-radius: 0 0 32px 32px;
|
||
z-index: 2;
|
||
}
|
||
.coupon-done-k .v6-expiry {
|
||
text-align: center;
|
||
color: #fff;
|
||
font-size: 13px;
|
||
font-weight: 600;
|
||
margin-bottom: 12px;
|
||
margin-top: 4px;
|
||
letter-spacing: 0.3px;
|
||
position: relative; z-index: 2;
|
||
}
|
||
.coupon-done-k .v6-expiry .time-box {
|
||
display: inline-block;
|
||
background: #fff;
|
||
color: #E02E24;
|
||
padding: 2px 4px;
|
||
border-radius: 4px;
|
||
font-weight: 600;
|
||
font-size: 13px;
|
||
font-family: -apple-system, "DIN Alternate", sans-serif;
|
||
margin: 0 2px;
|
||
letter-spacing: -0.5px;
|
||
box-shadow: 0 1px 3px rgba(0,0,0,.15);
|
||
}
|
||
.coupon-done-k .v6-cta {
|
||
width: 100%;
|
||
background: linear-gradient(135deg, #FFEB3B 0%, #FFD600 50%, #FFC400 100%);
|
||
color: #1a1a1a;
|
||
border: none;
|
||
padding: 12px;
|
||
border-radius: 24px;
|
||
font-size: 15px;
|
||
font-weight: 900;
|
||
cursor: pointer;
|
||
box-shadow: inset 0 -2px 0 rgba(184,134,11,.18);
|
||
position: relative; z-index: 2;
|
||
letter-spacing: 1px;
|
||
}
|
||
|
||
/* ===== 比价结果页:全网最低价徽章(图片) + N2 chip ===== */
|
||
.card.with-ribbon { overflow: visible; }
|
||
.ribbon-vi {
|
||
position: absolute;
|
||
top: -16px; right: -6px;
|
||
width: 104px;
|
||
height: auto;
|
||
z-index: 3;
|
||
pointer-events: none;
|
||
filter: drop-shadow(0 4px 10px rgba(220,40,40,0.25));
|
||
}
|
||
|
||
/* 价格旁红 chip "比原选择省 ¥X" — 强调"省了多少",刻意放大 */
|
||
.save-chip-red {
|
||
background: linear-gradient(135deg, #FE2C55, #FF6B3D);
|
||
color: #fff;
|
||
border-radius: 8px;
|
||
padding: 4px 12px;
|
||
font-size: 15px;
|
||
font-weight: 600;
|
||
letter-spacing: 0.2px;
|
||
align-self: center;
|
||
display: inline-flex; align-items: baseline; gap: 2px;
|
||
box-shadow: 0 2px 6px rgba(0,0,0,0.15);
|
||
white-space: nowrap;
|
||
-webkit-font-smoothing: antialiased;
|
||
-moz-osx-font-smoothing: grayscale;
|
||
}
|
||
.save-chip-red .small { font-size: 12px; opacity: 1; font-weight: 700; }
|
||
|
||
.result-cta {
|
||
flex-shrink: 0;
|
||
min-height: 34px;
|
||
padding: 6px 16px;
|
||
border: none;
|
||
border-radius: 999px;
|
||
font-size: 13px;
|
||
font-weight: 700;
|
||
line-height: 1;
|
||
cursor: pointer;
|
||
background: var(--gray-100);
|
||
color: var(--gray-800);
|
||
display: inline-flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
gap: 2px;
|
||
white-space: nowrap;
|
||
}
|
||
.result-cta .arrow {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
color: var(--gray-500);
|
||
font-size: 15px;
|
||
line-height: 1;
|
||
transform: translateY(-.5px);
|
||
}
|
||
|
||
/* 用户原选 chip:店名旁描边方角 */
|
||
.badge-userorig {
|
||
flex-shrink: 0;
|
||
display: inline-flex; align-items: center;
|
||
background: transparent;
|
||
border: 1px solid #CCCCCC;
|
||
border-radius: 4px;
|
||
padding: 2px 8px;
|
||
font-size: 11px; font-weight: 600;
|
||
color: #666666; letter-spacing: .3px;
|
||
white-space: nowrap;
|
||
}
|
||
|
||
/* ===== Kickoff 引导卡(首次进店)— L·I 升级版:黄 header + 米黄 body ===== */
|
||
.kickoff-card {
|
||
position: relative;
|
||
border-radius: 14px;
|
||
box-shadow: 0 14px 30px rgba(0,0,0,.32), 0 4px 14px rgba(255,179,0,.22);
|
||
}
|
||
/* 气泡上方的 journey 排版字(无卡片背景,闲鱼式:白字 + 关键词黄字 + 弧线下划) */
|
||
.kickoff-promo {
|
||
position: absolute;
|
||
bottom: 100%;
|
||
left: 0; right: 0;
|
||
margin-bottom: 24px;
|
||
text-align: center;
|
||
pointer-events: none;
|
||
}
|
||
.kickoff-promo .promo-line {
|
||
font-size: 22px;
|
||
font-weight: 900;
|
||
color: #fff;
|
||
line-height: 1.35;
|
||
letter-spacing: .5px;
|
||
-webkit-text-stroke: 0.4px currentColor; /* 在 900 之上再加描边,视觉更粗 */
|
||
text-stroke: 0.4px currentColor;
|
||
text-shadow: 0 2px 12px rgba(0,0,0,.7), 0 1px 3px rgba(0,0,0,.55), 0 0 2px rgba(0,0,0,.35);
|
||
}
|
||
.kickoff-promo .promo-accent {
|
||
position: relative;
|
||
display: inline-block;
|
||
padding: 0 2px;
|
||
color: #FFEB3B;
|
||
}
|
||
/* SVG 手绘风弧线下划,仿闲鱼那种"标注"感(按字号同比例放大) */
|
||
.kickoff-promo .promo-accent::after {
|
||
content: '';
|
||
position: absolute;
|
||
left: -2px; right: -2px;
|
||
bottom: -7px;
|
||
height: 9px;
|
||
background: url("data:image/svg+xml;utf8,<svg xmlns='http: //www.w3.org/2000/svg' viewBox='0 0 100 9' preserveAspectRatio='none'><path d='M2 5 Q 25 1 50 4.5 T 98 4.5' stroke='%23FFE34D' stroke-width='2.8' fill='none' stroke-linecap='round'/></svg>") no-repeat center / 100% 100%;
|
||
}
|
||
.kickoff-head {
|
||
background: linear-gradient(135deg, #FFEB3B 0%, #FFD600 100%);
|
||
padding: 8px 12px 8px;
|
||
display: flex; align-items: center; gap: 8px;
|
||
border-radius: 14px 14px 0 0;
|
||
}
|
||
.kickoff-dot {
|
||
width: 6px; height: 6px; border-radius: 50%;
|
||
background: #1a1a1a;
|
||
flex-shrink: 0;
|
||
}
|
||
.kickoff-title {
|
||
font-size: 14px; font-weight: 900; color: #1a1a1a;
|
||
letter-spacing: .5px; line-height: 1.2;
|
||
}
|
||
.kickoff-body {
|
||
background: #FFF8E1;
|
||
padding: 12px 12px 12px;
|
||
font-size: 13px; font-weight: 700; color: #1a1a1a;
|
||
line-height: 1.5;
|
||
border-radius: 0 0 14px 14px;
|
||
}
|
||
.kickoff-leader {
|
||
position: absolute;
|
||
bottom: -36px; left: 50%; margin-left: -1px;
|
||
width: 2px; height: 36px;
|
||
background: linear-gradient(180deg, rgba(255,214,0,0) 0%, #FFD600 30%, #FFD600 100%);
|
||
border-radius: 4px;
|
||
pointer-events: none;
|
||
}
|
||
.kickoff-leader::before {
|
||
content: '';
|
||
position: absolute; bottom: -4px; left: -4px;
|
||
width: 10px; height: 10px; border-radius: 50%;
|
||
background: #fff;
|
||
border: 2px solid #1a1a1a;
|
||
box-sizing: border-box;
|
||
box-shadow: 0 0 0 3px rgba(255,214,0,.55), 0 1px 3px rgba(0,0,0,.25);
|
||
animation: kickoffLeaderDot 1.6s ease-in-out infinite;
|
||
}
|
||
@keyframes kickoffLeaderDot {
|
||
0%, 100% { box-shadow: 0 0 0 3px rgba(255,214,0,.55), 0 1px 3px rgba(0,0,0,.25); }
|
||
50% { box-shadow: 0 0 0 6px rgba(255,214,0,.2), 0 1px 3px rgba(0,0,0,.25); }
|
||
}
|
||
/* 比价流程内引导气泡的黄色连接线(动态长度+方向,dot 落点贴住 spotlight 边缘) */
|
||
#demoGuide .demo-guide-leader {
|
||
position: absolute;
|
||
left: 50%; margin-left: -1px;
|
||
width: 2px;
|
||
border-radius: 4px;
|
||
pointer-events: none;
|
||
}
|
||
#demoGuide .demo-guide-leader.dir-down {
|
||
top: 100%;
|
||
background: linear-gradient(180deg, rgba(255,214,0,0) 0%, #FFD600 30%, #FFD600 100%);
|
||
}
|
||
#demoGuide .demo-guide-leader.dir-down::before {
|
||
content: '';
|
||
position: absolute; bottom: -4px; left: -4px;
|
||
width: 10px; height: 10px; border-radius: 50%;
|
||
background: #fff;
|
||
border: 2px solid #1a1a1a;
|
||
box-sizing: border-box;
|
||
box-shadow: 0 0 0 3px rgba(255,214,0,.55), 0 1px 3px rgba(0,0,0,.25);
|
||
animation: kickoffLeaderDot 1.6s ease-in-out infinite;
|
||
}
|
||
#demoGuide .demo-guide-leader.dir-up {
|
||
bottom: 100%;
|
||
background: linear-gradient(0deg, rgba(255,214,0,0) 0%, #FFD600 30%, #FFD600 100%);
|
||
}
|
||
#demoGuide .demo-guide-leader.dir-up::before {
|
||
content: '';
|
||
position: absolute; top: -4px; left: -4px;
|
||
width: 10px; height: 10px; border-radius: 50%;
|
||
background: #fff;
|
||
border: 2px solid #1a1a1a;
|
||
box-sizing: border-box;
|
||
box-shadow: 0 0 0 3px rgba(255,214,0,.55), 0 1px 3px rgba(0,0,0,.25);
|
||
animation: kickoffLeaderDot 1.6s ease-in-out infinite;
|
||
}
|
||
/* 一键比价入口 · 右下角 kickoff 卡(leader 偏右对齐侧贴按钮中心)*/
|
||
.start-compare-kickoff {
|
||
position: absolute;
|
||
right: 14px;
|
||
width: 310px;
|
||
bottom: 246px;
|
||
z-index: 16;
|
||
pointer-events: none;
|
||
}
|
||
.start-compare-kickoff .kickoff-leader {
|
||
left: auto;
|
||
right: 50px;
|
||
margin-left: 0;
|
||
}
|
||
/* 比价中浮窗 · 三平台并行 mini icons */
|
||
.cmp-platform-mini { position: relative; width: 24px; height: 24px; }
|
||
.cmp-platform-mini > img { width: 100%; height: 100%; border-radius: 4px; object-fit: cover; display: block; }
|
||
.cmp-platform-mini.done::after {
|
||
content: ''; position: absolute; bottom: -3px; right: -3px;
|
||
width: 12px; height: 12px; border-radius: 50%; background: #22C55E;
|
||
border: 1.5px solid #fff;
|
||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 10'%3E%3Cpath d='M2 5l2 2 4-5' stroke='%23fff' stroke-width='1.6' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
|
||
background-size: 8px; background-repeat: no-repeat; background-position: center;
|
||
}
|
||
.cmp-platform-mini.active::after {
|
||
content: ''; position: absolute; inset: -4px;
|
||
border: 2px solid #FFD600; border-top-color: transparent;
|
||
border-radius: 50%; animation: spin 0.8s linear infinite;
|
||
}
|
||
.cmp-platform-mini.pending { opacity: 0.4; filter: grayscale(0.6); }
|
||
/* ============ 2. VIDEO 教程页 (vt-) ============ */
|
||
#video .vt-video-player {
|
||
flex-shrink: 0; height: 667px; background: #000;
|
||
position: relative; overflow: hidden;
|
||
}
|
||
#video .vt-poster {
|
||
position: absolute; inset: 0;
|
||
background: radial-gradient(ellipse at 25% 15%, rgba(255,255,255,.45) 0%, transparent 55%),
|
||
radial-gradient(ellipse at 80% 90%, rgba(255,87,34,.18) 0%, transparent 60%),
|
||
linear-gradient(160deg, #FFE57F 0%, #FFD54F 35%, #FFB300 75%, #F57F17 100%);
|
||
display: flex; align-items: center; justify-content: center;
|
||
cursor: pointer; overflow: hidden;
|
||
}
|
||
#video .vt-poster::before {
|
||
content: ''; position: absolute; inset: 0;
|
||
background: radial-gradient(circle at 18% 88%, rgba(255,255,255,.15) 0%, transparent 8%),
|
||
radial-gradient(circle at 88% 22%, rgba(255,255,255,.18) 0%, transparent 6%);
|
||
pointer-events: none;
|
||
}
|
||
#video .vt-video-player.paused .vt-poster::after,
|
||
#video .vt-video-player.initial .vt-poster::after {
|
||
content: ''; position: absolute; inset: 0;
|
||
background: rgba(0,0,0,.18); z-index: 2; pointer-events: none;
|
||
}
|
||
/* 商品对比卡 */
|
||
#video .vt-poster-compare {
|
||
display: flex; align-items: center; gap: 8px;
|
||
background: rgba(255,255,255,.95); border-radius: 18px;
|
||
padding: 12px 16px;
|
||
box-shadow: 0 14px 36px rgba(140,70,0,.22), 0 2px 6px rgba(0,0,0,.08);
|
||
z-index: 2; position: relative;
|
||
}
|
||
#video .vt-pc-card {
|
||
display: flex; flex-direction: column; align-items: center;
|
||
gap: 4px; padding: 4px 8px; min-width: 70px; position: relative;
|
||
}
|
||
#video .vt-pc-label { font-size: 10px; color: #999; font-weight: 600; letter-spacing: .3px; }
|
||
#video .vt-pc-card.win .vt-pc-label {
|
||
color: #fff; background: linear-gradient(135deg, #FF6B6B, #E53935);
|
||
padding: 2px 8px; border-radius: 4px;
|
||
box-shadow: 0 2px 4px rgba(229,57,53,.3);
|
||
}
|
||
#video .vt-pc-price {
|
||
font-size: 22px; font-weight: 800; color: #1a1a1a;
|
||
font-variant-numeric: tabular-nums; letter-spacing: -.5px;
|
||
}
|
||
#video .vt-pc-price.strike { color: #CCCCCC; text-decoration: line-through; font-size: 18px; font-weight: 600; }
|
||
#video .vt-pc-price.now { color: #E53935; font-size: 24px; }
|
||
#video .vt-pc-arrow { color: #E65100; font-size: 22px; font-weight: 600; text-shadow: 0 2px 4px rgba(255,111,0,.3); }
|
||
#video .vt-pc-save-tag {
|
||
position: absolute; top: -10px; right: -8px;
|
||
font-size: 10px; font-weight: 600; color: #fff;
|
||
background: linear-gradient(135deg, #FF6B6B, #E53935);
|
||
padding: 2px 6px; border-radius: 8px 8px 8px 4px;
|
||
box-shadow: 0 2px 6px rgba(229,57,53,.45);
|
||
transform: rotate(8deg); white-space: nowrap;
|
||
}
|
||
/* 装饰金币 */
|
||
#video .vt-coin {
|
||
position: absolute; z-index: 1; border-radius: 50%;
|
||
background: linear-gradient(135deg, #FFE066 0%, #FFC300 50%, #FFA000 100%);
|
||
display: flex; align-items: center; justify-content: center;
|
||
font-weight: 800; color: #5A3A00;
|
||
box-shadow: 0 4px 10px rgba(120,60,0,.25),
|
||
inset 0 1px 2px rgba(255,255,255,.7),
|
||
inset 0 -1px 2px rgba(139,69,19,.3);
|
||
border: 1.5px solid rgba(180,100,30,.25);
|
||
}
|
||
#video .vt-coin-tl { top: 14%; left: 10%; width: 36px; height: 36px; font-size: 17px; transform: rotate(-12deg); animation: vtFloatA 3.2s ease-in-out infinite; }
|
||
#video .vt-coin-tr { top: 22%; right: 9%; width: 28px; height: 28px; font-size: 13px; transform: rotate(18deg); animation: vtFloatB 3.6s ease-in-out infinite .3s; }
|
||
#video .vt-coin-bl { bottom: 28%; left: 14%; width: 24px; height: 24px; font-size: 12px; transform: rotate(8deg); animation: vtFloatA 3.8s ease-in-out infinite .6s; }
|
||
#video .vt-coin-br { bottom: 18%; right: 12%; width: 32px; height: 32px; font-size: 15px; transform: rotate(-15deg); animation: vtFloatB 3.4s ease-in-out infinite .9s; }
|
||
@keyframes vtFloatA { 0%,100% { transform: rotate(-12deg) translateY(0); } 50% { transform: rotate(-12deg) translateY(-8px); } }
|
||
@keyframes vtFloatB { 0%,100% { transform: rotate(18deg) translateY(0); } 50% { transform: rotate(18deg) translateY(-10px); } }
|
||
/* 闪光 */
|
||
#video .vt-sparkle {
|
||
position: absolute; z-index: 1; width: 8px; height: 8px;
|
||
background: linear-gradient(to bottom, transparent 45%, rgba(255,255,255,.9) 50%, transparent 55%),
|
||
linear-gradient(to right, transparent 45%, rgba(255,255,255,.9) 50%, transparent 55%);
|
||
transform: rotate(45deg);
|
||
animation: vtSparkle 2.4s ease-in-out infinite;
|
||
}
|
||
#video .vt-sparkle-1 { top: 38%; left: 22%; }
|
||
#video .vt-sparkle-2 { top: 56%; right: 24%; animation-delay: .6s; }
|
||
#video .vt-sparkle-3 { top: 70%; left: 38%; width: 6px; height: 6px; animation-delay: 1.2s; }
|
||
@keyframes vtSparkle { 0%,100% { opacity: 0; transform: rotate(45deg) scale(.5); } 50% { opacity: 1; transform: rotate(45deg) scale(1); } }
|
||
/* dim overlay */
|
||
#video .vt-dim-overlay {
|
||
position: absolute; inset: 0; z-index: 4;
|
||
background: rgba(0,0,0,.5); pointer-events: none;
|
||
opacity: 0; transition: opacity .35s;
|
||
}
|
||
#video .vt-video-player.ended .vt-dim-overlay { opacity: 1; }
|
||
/* center play */
|
||
#video .vt-center-play {
|
||
position: absolute; left: 50%; top: 50%;
|
||
width: 72px; height: 72px;
|
||
background: rgba(0,0,0,.5); border-radius: 50%;
|
||
display: flex; align-items: center; justify-content: center;
|
||
transform: translate(-50%, -50%); cursor: pointer;
|
||
box-shadow: 0 8px 24px rgba(0,0,0,.3);
|
||
transition: opacity .2s, background .15s; z-index: 6;
|
||
}
|
||
#video .vt-center-play svg { width: 30px; height: 30px; fill: #fff; margin-left: 2px; }
|
||
#video .vt-video-player.playing .vt-center-play { opacity: 0; pointer-events: none; }
|
||
#video .vt-video-player.paused .vt-center-play,
|
||
#video .vt-video-player.initial .vt-center-play {
|
||
opacity: 1; visibility: visible; pointer-events: auto;
|
||
}
|
||
#video .vt-video-player.ended .vt-center-play {
|
||
width: 80px; height: 80px;
|
||
background: rgba(255,255,255,.18);
|
||
border: 2px solid rgba(255,255,255,.45);
|
||
backdrop-filter: blur(8px);
|
||
}
|
||
#video .vt-video-player.ended .vt-center-play svg { width: 32px; height: 32px; margin-left: 0; }
|
||
/* controls */
|
||
#video .vt-controls {
|
||
position: absolute; left: 0; right: 0; bottom: 0;
|
||
padding: 12px 12px 16px;
|
||
background: linear-gradient(180deg, transparent, rgba(0,0,0,.7) 55%);
|
||
z-index: 3;
|
||
}
|
||
#video .vt-progress-row { display: flex; align-items: center; gap: 8px; }
|
||
#video .vt-time {
|
||
font-size: 11px; font-weight: 600; color: #fff;
|
||
min-width: 32px; text-align: center; font-variant-numeric: tabular-nums;
|
||
}
|
||
#video .vt-ctrl-pill {
|
||
width: 36px; height: 36px; border-radius: 50%;
|
||
background: rgba(255,255,255,.18);
|
||
display: flex; align-items: center; justify-content: center;
|
||
cursor: pointer; flex-shrink: 0;
|
||
transition: background .15s, transform .12s;
|
||
backdrop-filter: blur(4px);
|
||
}
|
||
#video .vt-ctrl-pill:active { transform: scale(.92); }
|
||
#video .vt-ctrl-pill svg { width: 16px; height: 16px; fill: #fff; }
|
||
/* track 24px 大命中区 */
|
||
#video .vt-progress-track {
|
||
flex: 1; height: 24px; background: transparent;
|
||
display: flex; align-items: center; position: relative; cursor: pointer;
|
||
}
|
||
#video .vt-progress-track::before {
|
||
content: ''; position: absolute; left: 0; right: 0; top: 50%;
|
||
transform: translateY(-50%); height: 4px;
|
||
background: rgba(255,255,255,.3); border-radius: 4px;
|
||
pointer-events: none;
|
||
}
|
||
#video .vt-progress-fill {
|
||
position: absolute; left: 0; top: 50%;
|
||
transform: translateY(-50%); height: 4px;
|
||
background: linear-gradient(90deg, #FFE066, #FFD600);
|
||
border-radius: 4px; pointer-events: none;
|
||
transition: width .08s linear; width: 0%;
|
||
}
|
||
#video .vt-progress-fill::after {
|
||
content: ''; position: absolute; right: -5px; top: 50%;
|
||
width: 11px; height: 11px; background: #FFD600;
|
||
border-radius: 50%; transform: translateY(-50%);
|
||
box-shadow: 0 0 0 3px rgba(255,214,0,.25);
|
||
}
|
||
/* desc */
|
||
#video .vt-desc-body {
|
||
flex: 1; display: flex; align-items: center; justify-content: center;
|
||
text-align: center; padding: 16px 24px;
|
||
}
|
||
#video .vt-desc {
|
||
font-size: 22px; font-weight: 600; color: var(--gray-700);
|
||
letter-spacing: .5px; line-height: 1.4;
|
||
}
|
||
/* CTA */
|
||
#video .vt-cta-bar { padding: 12px 16px 32px; flex-shrink: 0; }
|
||
#video .vt-cta-btn {
|
||
width: 100%; padding: 16px 0; border: none;
|
||
background: linear-gradient(135deg, #FFE066 0%, #FFD600 50%, #FFB300 100%);
|
||
color: #1a1a1a; border-radius: 14px;
|
||
font-size: 17px; font-weight: 700; cursor: pointer;
|
||
box-shadow: 0 6px 18px rgba(255,179,0,.45),
|
||
inset 0 1px 0 rgba(255,255,255,.6);
|
||
position: relative; overflow: hidden;
|
||
letter-spacing: .5px; transition: transform .15s;
|
||
}
|
||
#video .vt-cta-btn:active { transform: scale(.98); }
|
||
#video .vt-cta-btn.disabled {
|
||
background: #E5E5E5 !important;
|
||
background-image: none !important;
|
||
color: #CCCCCC !important;
|
||
box-shadow: none !important;
|
||
cursor: not-allowed; font-weight: 600; letter-spacing: 0;
|
||
}
|
||
|
||
/* ============ Home v2026-05-10 (image-asset driven) ============ */
|
||
#home .home-scroll { padding: 40px 0 16px; }
|
||
|
||
/* 顶部 Banner —— 整图 */
|
||
#home .home-banner {
|
||
margin: 4px 12px 12px;
|
||
border-radius: 18px;
|
||
overflow: hidden;
|
||
box-shadow: 0 6px 20px rgba(255,179,0,.18);
|
||
cursor: pointer;
|
||
}
|
||
#home .home-banner img {
|
||
width: 100%;
|
||
display: block;
|
||
}
|
||
|
||
/* 5 类别快捷入口(无白底卡片,直接贴页面背景) */
|
||
#home .home-cats {
|
||
display: grid; grid-template-columns: repeat(5, 1fr);
|
||
margin: 0 12px;
|
||
padding: 12px 4px 6px;
|
||
background: transparent;
|
||
border-radius: 0;
|
||
box-shadow: none;
|
||
}
|
||
#home .home-cat {
|
||
display: flex; flex-direction: column; align-items: center;
|
||
cursor: pointer; transition: transform .12s;
|
||
padding: 0 2px;
|
||
}
|
||
#home .home-cat:active { transform: scale(.94); }
|
||
#home .home-cat img {
|
||
width: 62px; height: 62px; display: block; margin-bottom: 6px;
|
||
border-radius: 14px;
|
||
}
|
||
#home .home-cat-label {
|
||
font-size: 12px; font-weight: 600; color: #1a1a1a; letter-spacing: .2px;
|
||
}
|
||
|
||
/* 三联:左 双数据卡(HTML+CSS)+ 右 一键领优惠(橙色整卡) */
|
||
#home .home-tri {
|
||
display: grid; grid-template-columns: 1fr 1fr; gap: 8px;
|
||
padding: 12px 12px 12px;
|
||
align-items: stretch;
|
||
}
|
||
#home .tri-stats {
|
||
display: flex; flex-direction: column; gap: 8px;
|
||
height: 100%;
|
||
}
|
||
#home .tri-stat {
|
||
position: relative;
|
||
flex: 1; min-height: 84px;
|
||
border-radius: 14px;
|
||
background: linear-gradient(135deg,#FFF3E0 0%,#FFE0B2 100%);
|
||
padding: 12px 12px;
|
||
cursor: pointer; transition: transform .12s;
|
||
box-shadow: 0 4px 14px rgba(255,140,60,.10);
|
||
overflow: hidden;
|
||
}
|
||
#home .tri-stat:active { transform: translateY(1px); }
|
||
#home .tri-stat-label {
|
||
font-size: 13px; font-weight: 700; color: #1a1a1a; letter-spacing: .2px;
|
||
line-height: 1;
|
||
}
|
||
#home .tri-stat-amount {
|
||
margin-top: 8px;
|
||
color: #FF5722; font-weight: 900;
|
||
display: inline-flex; align-items: baseline; gap: 0;
|
||
letter-spacing: -.5px; line-height: 1;
|
||
}
|
||
#home .tri-stat-amount .yuan { font-size: 18px; font-weight: 900; margin-right: 2px; }
|
||
#home .tri-stat-amount .num { font-size: 28px; line-height: 1; }
|
||
#home .tri-stat-amount .dec { font-size: 14px; font-weight: 900; margin-left: 2px; }
|
||
#home .tri-stat-art {
|
||
position: absolute; right: 6px; bottom: 4px;
|
||
width: 70px; height: 64px;
|
||
pointer-events: none;
|
||
user-select: none;
|
||
filter: drop-shadow(0 4px 6px rgba(180,80,20,.12));
|
||
}
|
||
#home .tri-stat-art img {
|
||
width: 100%; height: 100%; object-fit: contain; object-position: right bottom; display: block;
|
||
}
|
||
#home .tri-claim {
|
||
position: relative; overflow: hidden;
|
||
border-radius: 14px;
|
||
cursor: pointer; transition: transform .12s;
|
||
box-shadow: 0 8px 22px rgba(255,87,34,.22);
|
||
background: linear-gradient(140deg,#FFE066 0%,#FF5722 55%,#FF5722 100%);
|
||
padding: 12px 12px 8px;
|
||
display: flex; flex-direction: column;
|
||
color: #fff;
|
||
}
|
||
#home .tri-claim:active { transform: translateY(1px); }
|
||
#home .tri-claim-bg {
|
||
position: absolute; inset: -2px;
|
||
background-image: url('../../assets/home/index/coupon-claim-bg.png');
|
||
background-size: cover; background-position: center bottom;
|
||
background-repeat: no-repeat;
|
||
pointer-events: none;
|
||
}
|
||
#home .tri-claim-inner {
|
||
position: relative; z-index: 1;
|
||
display: flex; flex-direction: column; height: 100%;
|
||
}
|
||
#home .tri-claim-title {
|
||
font-size: 22px; font-weight: 900; color: #fff;
|
||
letter-spacing: .5px; line-height: 1;
|
||
text-shadow: 0 2px 6px rgba(180,50,0,.22);
|
||
}
|
||
#home .tri-claim-sub {
|
||
margin-top: 8px;
|
||
font-size: 12px; font-weight: 600; color: #fff;
|
||
opacity: .95; letter-spacing: .3px;
|
||
text-shadow: 0 1px 3px rgba(180,50,0,.18);
|
||
}
|
||
#home .tri-claim-spacer { flex: 1; min-height: 56px; }
|
||
#home .tri-claim-cta {
|
||
align-self: stretch;
|
||
background: #fff; color: #FF5722;
|
||
border-radius: 999px;
|
||
padding: 8px 12px;
|
||
font-size: 14px; font-weight: 600; letter-spacing: .3px;
|
||
display: inline-flex; align-items: center; justify-content: center; gap: 4px;
|
||
box-shadow: 0 4px 10px rgba(180,60,0,.18);
|
||
}
|
||
#home .tri-claim-cta .arrow { font-size: 14px; font-weight: 900; margin-left: 2px; }
|
||
|
||
/* "已领"态:领券完成后回到首页时替换 .tri-claim 默认态 */
|
||
#home .tri-claim-done {
|
||
background: linear-gradient(140deg,#FF6B3D 0%,#FF5722 55%,#E65100 100%);
|
||
padding: 12px 12px 8px;
|
||
}
|
||
#home .tri-claim-bg-done {
|
||
background-image: none;
|
||
background: radial-gradient(circle at 80% 18%, rgba(255,224,160,.45) 0%, rgba(255,160,80,0) 55%);
|
||
}
|
||
#home .tcd-head {
|
||
font-size: 12px; font-weight: 600; color: #fff;
|
||
display: inline-flex; align-items: center; gap: 4px;
|
||
opacity: .98; letter-spacing: .2px;
|
||
text-shadow: 0 1px 2px rgba(180,50,0,.18);
|
||
}
|
||
#home .tcd-check {
|
||
width: 14px; height: 14px; border-radius: 50%;
|
||
background: rgba(255,255,255,.95); color: #FF5722;
|
||
font-size: 10px; font-weight: 900; line-height: 14px;
|
||
display: inline-flex; align-items: center; justify-content: center;
|
||
}
|
||
#home .tcd-num {
|
||
margin-top: 6px;
|
||
display: inline-flex; align-items: baseline; gap: 4px;
|
||
text-shadow: 0 2px 6px rgba(180,50,0,.25);
|
||
}
|
||
#home .tcd-num .num {
|
||
font-size: 28px; font-weight: 900; color: #fff;
|
||
line-height: 1; letter-spacing: -1px;
|
||
font-family: -apple-system, "DIN Alternate", sans-serif;
|
||
}
|
||
#home .tcd-num .unit {
|
||
font-size: 12px; font-weight: 600; color: #FFF3E0;
|
||
letter-spacing: .2px;
|
||
}
|
||
#home .tcd-from {
|
||
align-self: stretch;
|
||
background: rgba(255,255,255,.18);
|
||
border-radius: 999px;
|
||
padding: 4px 8px 4px 8px;
|
||
font-size: 11px; font-weight: 600;
|
||
display: inline-flex; align-items: center; gap: 6px; justify-content: center;
|
||
color: #fff; letter-spacing: .2px;
|
||
backdrop-filter: blur(2px);
|
||
}
|
||
#home .tcd-from-label { opacity: .9; }
|
||
#home .tcd-logos { display: inline-flex; align-items: center; gap: 2px; }
|
||
#home .tcd-logos img {
|
||
width: 16px; height: 16px; border-radius: 4px;
|
||
border: 1.5px solid rgba(255,255,255,.95);
|
||
background: #fff; object-fit: cover;
|
||
box-shadow: 0 1px 3px rgba(120,40,0,.25);
|
||
}
|
||
|
||
/* 推荐信息流 */
|
||
#home .home-feed-wrap {
|
||
background: #fff;
|
||
border-radius: 14px 14px 0 0;
|
||
margin: 8px 0 0;
|
||
overflow: hidden;
|
||
padding-bottom: 0;
|
||
}
|
||
#home .home-feed-head {
|
||
display: flex; align-items: center; justify-content: space-between;
|
||
padding: 12px 16px 8px;
|
||
}
|
||
#home .home-feed-title {
|
||
font-size: 17px; font-weight: 600; color: #1a1a1a; letter-spacing: -.2px;
|
||
display: inline-flex; align-items: center; gap: 4px;
|
||
}
|
||
#home .home-feed-title .feed-fire { font-size: 18px; line-height: 1; }
|
||
#home .feed-promo-tag {
|
||
background: linear-gradient(90deg, #FF6B3D, #FF5722);
|
||
color: #fff;
|
||
font-size: 10px;
|
||
font-weight: 600;
|
||
padding: 2px 8px;
|
||
border-radius: 999px;
|
||
display: inline-flex;
|
||
align-items: center;
|
||
letter-spacing: 0;
|
||
white-space: nowrap;
|
||
box-shadow: 0 2px 5px rgba(255,90,61,.22);
|
||
}
|
||
#home .feed-promo-tag .dot {
|
||
opacity: .85;
|
||
margin: 0 2px;
|
||
}
|
||
#home .home-feed {
|
||
display: flex; flex-direction: column;
|
||
padding: 0;
|
||
background: #fff;
|
||
}
|
||
#home .feed-card {
|
||
background: transparent;
|
||
border-radius: 0;
|
||
box-shadow: none;
|
||
cursor: pointer;
|
||
display: flex; flex-direction: row; align-items: stretch;
|
||
position: relative;
|
||
padding: 8px 12px;
|
||
}
|
||
#home .feed-card:active { background: #fafafa; }
|
||
#home .feed-img {
|
||
flex: 0 0 110px; width: 110px; height: 110px; aspect-ratio: 1/1;
|
||
border-radius: 8px;
|
||
overflow: hidden;
|
||
background: #fafafa;
|
||
}
|
||
#home .feed-img img {
|
||
width: 100%; height: 100%;
|
||
object-fit: cover;
|
||
display: block;
|
||
}
|
||
#home .feed-body {
|
||
flex: 1; min-width: 0;
|
||
padding: 0 0 0 12px;
|
||
display: flex; flex-direction: column;
|
||
gap: 4px;
|
||
}
|
||
#home .feed-title {
|
||
font-size: 13px; font-weight: 500; color: #1a1a1a; line-height: 1.35;
|
||
display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
|
||
overflow: hidden;
|
||
padding-right: 4px;
|
||
}
|
||
#home .feed-title .shop-name { color: #FF5722; font-weight: 600; }
|
||
#home .feed-title .title-sep { color: #CCCCCC; margin: 0 2px; font-weight: 400; }
|
||
#home .feed-meta {
|
||
display: flex; align-items: center; gap: 8px;
|
||
font-size: 11px; color: #999;
|
||
padding-right: 0;
|
||
}
|
||
#home .feed-meta .meta-left {
|
||
color: #999; font-weight: 400;
|
||
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
|
||
flex: 1 1 auto; min-width: 0;
|
||
}
|
||
#home .feed-meta .meta-right {
|
||
color: #999; font-weight: 400;
|
||
white-space: nowrap; flex-shrink: 0;
|
||
}
|
||
#home .feed-pricerow {
|
||
display: flex; align-items: baseline; gap: 4px;
|
||
margin-top: auto;
|
||
padding-right: 40px;
|
||
}
|
||
#home .feed-price {
|
||
display: inline-flex; align-items: baseline; gap: 0;
|
||
color: #E53935; font-weight: 700;
|
||
}
|
||
#home .feed-price .yuan { font-size: 12px; font-weight: 700; margin-right: 2px; }
|
||
#home .feed-price .num { font-size: 18px; letter-spacing: -.5px; line-height: 1; font-weight: 700; }
|
||
#home .feed-price .num small { font-size: 12px; font-weight: 700; }
|
||
#home .feed-original {
|
||
font-size: 12px; color: #999999; text-decoration: line-through;
|
||
font-weight: 400;
|
||
}
|
||
#home .feed-subsidy {
|
||
font-size: 10px; color: #E53935; font-weight: 400;
|
||
letter-spacing: .1px;
|
||
padding-right: 40px;
|
||
}
|
||
#home .feed-grab {
|
||
position: absolute; right: 14px; bottom: 14px;
|
||
background: linear-gradient(135deg,#FFE066,#FFD600); color: #1A1A1A;
|
||
font-size: 12px; font-weight: 600;
|
||
width: 38px; height: 38px;
|
||
border-radius: 14px 14px 14px 4px;
|
||
display: flex; align-items: center; justify-content: center;
|
||
box-shadow: 0 3px 8px rgba(255,179,0,.34),
|
||
inset 0 1px 0 rgba(255,255,255,.65);
|
||
letter-spacing: 1px;
|
||
z-index: 2;
|
||
}
|
||
|
||
/* ===== R8 福利页设计规范(仅作用在 .scheme-r8 节点内) ===== */
|
||
.scheme-r8 {
|
||
--r8-yellow: #FFD600;
|
||
--r8-yellow-deep: #FFC107;
|
||
--r8-orange: #FF6A1A;
|
||
--r8-green: #21C45A;
|
||
--r8-bg: #FBFAF6;
|
||
--r8-card: #FFFFFF;
|
||
--r8-divider: #EEE8D7;
|
||
--r8-aux: #8A8A8A;
|
||
--r8-text: #1F1F1F;
|
||
background: var(--r8-bg) !important;
|
||
padding: 0 12px 16px !important;
|
||
}
|
||
.r8-status-bar {
|
||
height: 40px;
|
||
padding: 12px 8px 0;
|
||
display: flex;
|
||
align-items: flex-start;
|
||
justify-content: space-between;
|
||
color: #1A1A1A;
|
||
font-size: 14px;
|
||
font-weight: 700;
|
||
letter-spacing: 0;
|
||
}
|
||
.r8-status-icons {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 6px;
|
||
height: 18px;
|
||
}
|
||
.r8-signal {
|
||
display: inline-flex;
|
||
align-items: flex-end;
|
||
gap: 2px;
|
||
height: 13px;
|
||
}
|
||
.r8-signal span {
|
||
width: 3px;
|
||
border-radius: 4px;
|
||
background: #1A1A1A;
|
||
}
|
||
.r8-signal span:nth-child(1) { height: 5px; }
|
||
.r8-signal span:nth-child(2) { height: 8px; }
|
||
.r8-signal span:nth-child(3) { height: 11px; }
|
||
.r8-signal span:nth-child(4) { height: 13px; }
|
||
.r8-wifi {
|
||
position: relative;
|
||
width: 16px;
|
||
height: 12px;
|
||
}
|
||
.r8-wifi::before,
|
||
.r8-wifi::after {
|
||
content: "";
|
||
position: absolute;
|
||
left: 50%;
|
||
border: 2px solid #1A1A1A;
|
||
border-left-color: transparent;
|
||
border-right-color: transparent;
|
||
border-bottom: none;
|
||
transform: translateX(-50%);
|
||
}
|
||
.r8-wifi::before {
|
||
top: 0;
|
||
width: 16px;
|
||
height: 9px;
|
||
border-radius: 14px 14px 0 0;
|
||
}
|
||
.r8-wifi::after {
|
||
top: 5px;
|
||
width: 9px;
|
||
height: 5px;
|
||
border-radius: 8px 8px 0 0;
|
||
}
|
||
.r8-wifi span {
|
||
position: absolute;
|
||
left: 50%;
|
||
bottom: 0;
|
||
width: 3px;
|
||
height: 3px;
|
||
transform: translateX(-50%);
|
||
border-radius: 50%;
|
||
background: #1A1A1A;
|
||
}
|
||
.r8-battery {
|
||
position: relative;
|
||
width: 24px;
|
||
height: 12px;
|
||
border: 1.8px solid #1A1A1A;
|
||
border-radius: 4px;
|
||
}
|
||
.r8-battery::before {
|
||
content: "";
|
||
position: absolute;
|
||
right: -4px;
|
||
top: 3px;
|
||
width: 2px;
|
||
height: 5px;
|
||
border-radius: 0 4px 4px 0;
|
||
background: #1A1A1A;
|
||
}
|
||
.r8-battery::after {
|
||
content: "";
|
||
position: absolute;
|
||
left: 2px;
|
||
top: 2px;
|
||
width: 17px;
|
||
height: 6px;
|
||
border-radius: 4px;
|
||
background: #1A1A1A;
|
||
}
|
||
.r8-page-header {
|
||
height: 50px;
|
||
padding: 4px 0 8px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
}
|
||
.r8-page-title {
|
||
display: flex;
|
||
align-items: baseline;
|
||
gap: 8px;
|
||
flex: 1;
|
||
min-width: 0;
|
||
}
|
||
.r8-page-title strong {
|
||
font-size: 24px;
|
||
line-height: 1;
|
||
font-weight: 900;
|
||
color: #1A1A1A;
|
||
letter-spacing: 0;
|
||
flex-shrink: 0;
|
||
white-space: nowrap;
|
||
}
|
||
.r8-page-title .sub {
|
||
font-size: 11px;
|
||
line-height: 1;
|
||
color: #666666;
|
||
font-weight: 500;
|
||
white-space: nowrap;
|
||
flex-shrink: 0;
|
||
}
|
||
.r8-page-title .star {
|
||
color: var(--r8-yellow);
|
||
font-size: 12px;
|
||
font-weight: 900;
|
||
transform: translateY(-10px);
|
||
flex-shrink: 0;
|
||
}
|
||
.r8-reward-btn {
|
||
height: 32px;
|
||
padding: 0 8px 0 8px;
|
||
border: none;
|
||
border-radius: 18px;
|
||
background: rgba(255,255,255,.92);
|
||
color: #1A1A1A;
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 6px;
|
||
font-size: 12px;
|
||
font-weight: 700;
|
||
box-shadow: 0 5px 14px rgba(173,128,18,.12);
|
||
cursor: pointer;
|
||
white-space: nowrap;
|
||
margin-left: 8px;
|
||
}
|
||
.r8-reward-btn svg {
|
||
width: 18px;
|
||
height: 18px;
|
||
flex-shrink: 0;
|
||
}
|
||
.r8-asset-card {
|
||
position: relative;
|
||
border-radius: 18px;
|
||
background: radial-gradient(ellipse 125% 86% at 4% 8%, rgba(255,255,255,.98) 0%, rgba(255,255,255,.56) 38%, rgba(255,255,255,0) 68%),
|
||
linear-gradient(155deg, #FFF5BF 0%, #FFE982 46%, #FFF9E4 100%);
|
||
min-height: 132px;
|
||
padding: 12px 16px 8px;
|
||
overflow: hidden;
|
||
border: 1px solid rgba(255,255,255,.78);
|
||
box-shadow: 0 8px 22px rgba(185,137,18,.10), inset 0 1px 0 rgba(255,255,255,.9);
|
||
}
|
||
.r8-asset-illustration {
|
||
position: absolute;
|
||
right: 6px; bottom: 17px;
|
||
width: 96px;
|
||
z-index: 2;
|
||
pointer-events: none; user-select: none;
|
||
}
|
||
.r8-corner-cut {
|
||
position: absolute; right: 0; top: 0;
|
||
width: 148px; height: 70px;
|
||
z-index: 1; pointer-events: none;
|
||
}
|
||
.r8-stars {
|
||
position: absolute; right: 98px; top: 42px;
|
||
width: 106px; height: 50px;
|
||
z-index: 1; pointer-events: none;
|
||
}
|
||
.r8-asset-header {
|
||
display: flex; align-items: baseline; gap: 8px;
|
||
position: relative; z-index: 3;
|
||
}
|
||
.r8-asset-title {
|
||
font-size: 18px; font-weight: 900; color: var(--r8-text);
|
||
letter-spacing: 0;
|
||
line-height: 1.08;
|
||
}
|
||
.r8-asset-withdraw {
|
||
font-size: 12px; color: #8B6914;
|
||
font-weight: 800; cursor: pointer;
|
||
}
|
||
.r8-asset-grid {
|
||
display: flex; align-items: flex-start; gap: 8px; margin-top: 16px;
|
||
position: relative; z-index: 3;
|
||
}
|
||
.r8-asset-col {
|
||
display: flex; flex-direction: column; gap: 6px;
|
||
flex: 0 1 auto; cursor: pointer;
|
||
}
|
||
.r8-asset-col:first-child {
|
||
width: 110px;
|
||
}
|
||
.r8-asset-col + .r8-asset-col {
|
||
min-width: 94px;
|
||
padding-left: 6px;
|
||
border-left: none;
|
||
}
|
||
.r8-asset-label-row {
|
||
display: flex; align-items: center; gap: 4px;
|
||
white-space: nowrap;
|
||
transform: translateX(-1px);
|
||
}
|
||
.r8-asset-coin-icon, .r8-asset-cash-icon-svg {
|
||
width: 17px; height: 17px; flex-shrink: 0; object-fit: contain;
|
||
margin-left: -3px;
|
||
}
|
||
.r8-asset-coin-label, .r8-asset-cash-label {
|
||
font-size: 13px; color: var(--r8-text); font-weight: 800;
|
||
display: inline-flex; align-items: center; gap: 2px;
|
||
}
|
||
.r8-asset-arrow {
|
||
font-size: 11px; color: #999999; font-weight: 600;
|
||
margin-left: 2px;
|
||
}
|
||
.r8-asset-coin-val, .r8-asset-cash-val {
|
||
font-size: 22px; font-weight: 800; color: #1A1A1A;
|
||
line-height: 1; letter-spacing: -.2px;
|
||
white-space: nowrap;
|
||
}
|
||
.r8-asset-coin-val, .r8-asset-cash-val {
|
||
color: var(--r8-orange);
|
||
}
|
||
.r8-asset-cash-val .unit {
|
||
font-size: 11px; font-weight: 800; margin-left: 2px;
|
||
}
|
||
.r8-asset-tip {
|
||
font-size: 10px; color: #999999;
|
||
margin-top: 12px;
|
||
position: relative; z-index: 3;
|
||
display: flex; align-items: center; gap: 4px;
|
||
line-height: 1.25;
|
||
white-space: nowrap;
|
||
}
|
||
.r8-info-icon {
|
||
width: 12px; height: 12px; border-radius: 50%;
|
||
background: rgba(138,138,138,.25); color: var(--r8-aux);
|
||
display: inline-flex; align-items: center; justify-content: center;
|
||
font-size: 10px; font-weight: 700; font-style: italic;
|
||
flex-shrink: 0;
|
||
}
|
||
.r8-checkin-card {
|
||
margin-top: 12px;
|
||
min-height: 58px;
|
||
background: linear-gradient(90deg, #FFE0B2 0%, #FFE066 100%);
|
||
border-radius: 18px;
|
||
padding: 6px 12px 6px 16px;
|
||
display: flex; align-items: center; gap: 8px;
|
||
box-shadow: 0 8px 18px rgba(185,137,18,.08);
|
||
cursor: pointer;
|
||
}
|
||
.r8-checkin-calendar {
|
||
width: 44px; height: 44px;
|
||
flex-shrink: 0; object-fit: contain;
|
||
}
|
||
.r8-checkin-text { flex: 1; min-width: 0; }
|
||
.r8-checkin-headline {
|
||
font-size: 16px; font-weight: 900; color: var(--r8-text);
|
||
display: flex; align-items: baseline; gap: 2px;
|
||
white-space: nowrap;
|
||
line-height: 1.08;
|
||
}
|
||
.r8-checkin-headline .num {
|
||
font-size: 22px; font-weight: 900; color: #FF5722;
|
||
margin: 0 4px;
|
||
}
|
||
.r8-checkin-sub {
|
||
font-size: 11px; color: #999999;
|
||
margin-top: 2px;
|
||
font-weight: 600;
|
||
white-space: nowrap;
|
||
display: none;
|
||
}
|
||
.r8-checkin-cta {
|
||
height: 32px;
|
||
background: #FFFFFF; border-radius: 32px;
|
||
padding: 0 12px 0 8px;
|
||
font-size: 12px; font-weight: 800; color: var(--r8-text);
|
||
border: none; cursor: pointer;
|
||
display: inline-flex; align-items: center; gap: 4px;
|
||
flex-shrink: 0; white-space: nowrap;
|
||
box-shadow: 0 4px 12px rgba(185,137,18,.08);
|
||
}
|
||
.r8-checkin-cta .check-tick {
|
||
display: inline-flex; align-items: center; justify-content: center;
|
||
width: 16px; height: 16px; border-radius: 4px;
|
||
background: var(--r8-green); color: #fff;
|
||
font-size: 11px; font-weight: 900;
|
||
}
|
||
.r8-section-title {
|
||
font-size: 17px; font-weight: 800; color: var(--r8-text);
|
||
margin: 0 0 8px;
|
||
}
|
||
.r8-task-card {
|
||
background: var(--r8-card);
|
||
border-radius: 14px;
|
||
padding: 12px 16px 12px;
|
||
box-shadow: 0 4px 12px rgba(0,0,0,0.04);
|
||
margin-top: 16px;
|
||
}
|
||
.r8-task-row {
|
||
display: flex; align-items: center; padding: 0;
|
||
border-bottom: none;
|
||
margin-top: 12px;
|
||
}
|
||
.r8-task-row:first-of-type { margin-top: 0; }
|
||
.r8-task-icon {
|
||
display: none;
|
||
}
|
||
.r8-task-info { flex: 1; min-width: 0; }
|
||
.r8-task-titlerow {
|
||
display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
|
||
}
|
||
.r8-task-title {
|
||
font-size: 15px; font-weight: 800; color: var(--r8-text);
|
||
}
|
||
.r8-task-coin {
|
||
display: inline-flex; align-items: center; gap: 0;
|
||
font-size: 12px; font-weight: 700; color: var(--r8-orange);
|
||
}
|
||
.r8-task-coin .ci {
|
||
width: 18px; height: 18px; flex-shrink: 0;
|
||
margin-right: -2px;
|
||
transform: scale(1.12);
|
||
transform-origin: center;
|
||
}
|
||
.r8-task-sub {
|
||
font-size: 12px; color: var(--r8-aux); margin-top: 2px; font-weight: 500;
|
||
}
|
||
.r8-task-cta {
|
||
background: var(--r8-yellow); color: var(--r8-text);
|
||
border: none; border-radius: 32px;
|
||
padding: 6px 12px;
|
||
font-size: 12px; font-weight: 800;
|
||
cursor: pointer; flex-shrink: 0;
|
||
}
|
||
.r8-checkin-task-row {
|
||
display: block;
|
||
margin-top: 8px;
|
||
padding: 2px 0 16px;
|
||
border-bottom: 1px solid #F0F0F0;
|
||
cursor: pointer;
|
||
transition: margin .18s ease;
|
||
}
|
||
.r8-checkin-task-main {
|
||
min-width: 0;
|
||
}
|
||
.r8-checkin-task-head {
|
||
display: flex;
|
||
align-items: flex-start;
|
||
gap: 8px;
|
||
}
|
||
.r8-checkin-task-copy {
|
||
flex: 1;
|
||
min-width: 0;
|
||
}
|
||
.r8-checkin-task-title {
|
||
color: var(--r8-text);
|
||
font-size: 15px;
|
||
line-height: 1.18;
|
||
font-weight: 800;
|
||
white-space: nowrap;
|
||
}
|
||
.r8-checkin-task-sub {
|
||
margin-top: 2px;
|
||
color: var(--r8-aux);
|
||
font-size: 12px;
|
||
line-height: 1.25;
|
||
font-weight: 500;
|
||
white-space: nowrap;
|
||
}
|
||
.r8-checkin-task-cta {
|
||
flex: 0 0 auto;
|
||
min-width: 54px;
|
||
height: auto;
|
||
border: none;
|
||
border-radius: 999px;
|
||
background: var(--r8-yellow);
|
||
color: var(--r8-text);
|
||
font-family: inherit;
|
||
padding: 6px 12px;
|
||
font-size: 12px;
|
||
font-weight: 800;
|
||
box-shadow: none;
|
||
cursor: pointer;
|
||
}
|
||
.r8-checkin-timeline {
|
||
position: relative;
|
||
display: grid;
|
||
grid-template-columns: repeat(5, minmax(0, 1fr));
|
||
column-gap: 2px;
|
||
margin-top: 16px;
|
||
}
|
||
.r8-checkin-timeline::before {
|
||
content: '';
|
||
position: absolute;
|
||
left: 20px;
|
||
right: 20px;
|
||
top: 32px;
|
||
height: 2px;
|
||
border-radius: 32px;
|
||
background: #E5E5E5;
|
||
}
|
||
.r8-checkin-step {
|
||
position: relative;
|
||
z-index: 1;
|
||
min-width: 0;
|
||
display: grid;
|
||
grid-template-rows: 18px 22px 15px;
|
||
justify-items: center;
|
||
align-items: center;
|
||
row-gap: 2px;
|
||
}
|
||
.r8-checkin-step-label {
|
||
min-height: 18px;
|
||
color: #999999;
|
||
font-size: 11px;
|
||
line-height: 18px;
|
||
font-weight: 650;
|
||
white-space: nowrap;
|
||
}
|
||
.r8-checkin-step-badge {
|
||
padding: 0 8px;
|
||
border-radius: 999px;
|
||
background: #fff;
|
||
color: #FFA000;
|
||
font-size: 11px;
|
||
line-height: 18px;
|
||
font-weight: 900;
|
||
box-shadow: 0 2px 8px rgba(0,0,0,.08);
|
||
white-space: nowrap;
|
||
}
|
||
.r8-checkin-step-icon {
|
||
box-sizing: border-box;
|
||
width: 22px;
|
||
height: 22px;
|
||
border-radius: 50%;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
.r8-checkin-step-icon img {
|
||
display: block;
|
||
width: 22px;
|
||
height: 22px;
|
||
object-fit: contain;
|
||
}
|
||
.r8-checkin-step.done .r8-checkin-step-icon {
|
||
background: #FFF3E0;
|
||
border: 1px solid #FFE066;
|
||
box-shadow: inset 0 1px 0 rgba(255,255,255,.72);
|
||
}
|
||
.r8-checkin-step.done .r8-checkin-step-icon img {
|
||
display: none;
|
||
}
|
||
.r8-checkin-step.done .r8-checkin-step-icon::before {
|
||
content: '✓';
|
||
color: #FFA000;
|
||
font-size: 13px;
|
||
line-height: 1;
|
||
font-weight: 900;
|
||
}
|
||
.r8-checkin-step.just-done .r8-checkin-step-icon {
|
||
animation: r8CheckDonePop .38s cubic-bezier(.22, 1.4, .36, 1);
|
||
}
|
||
.r8-checkin-step.current .r8-checkin-step-icon {
|
||
animation: r8CheckCoinPulse .42s ease-out;
|
||
}
|
||
@keyframes r8CheckDonePop {
|
||
0% { transform: scale(.68); opacity: .55; }
|
||
64% { transform: scale(1.12); opacity: 1; }
|
||
100% { transform: scale(1); opacity: 1; }
|
||
}
|
||
@keyframes r8CheckCoinPulse {
|
||
0% { transform: scale(.86); }
|
||
64% { transform: scale(1.1); }
|
||
100% { transform: scale(1); }
|
||
}
|
||
.r8-checkin-step.most .r8-checkin-step-icon img {
|
||
width: 22px;
|
||
height: 22px;
|
||
}
|
||
.r8-checkin-step-amount {
|
||
color: #999999;
|
||
font-size: 11px;
|
||
line-height: 1;
|
||
font-weight: 650;
|
||
font-variant-numeric: tabular-nums;
|
||
white-space: nowrap;
|
||
}
|
||
.r8-badge-update {
|
||
background: rgba(255,106,26,0.10); color: var(--r8-orange);
|
||
border: 1px solid rgba(255,106,26,0.35);
|
||
font-size: 10px; padding: 2px 4px; border-radius: 4px; font-weight: 700;
|
||
}
|
||
.r8-rule-entry {
|
||
margin: 16px auto 8px;
|
||
border: none;
|
||
background: transparent;
|
||
color: #999999;
|
||
font-family: inherit;
|
||
font-size: 12px;
|
||
font-weight: 500;
|
||
line-height: 18px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
gap: 2px;
|
||
cursor: pointer;
|
||
}
|
||
.r8-rule-entry span {
|
||
font-size: 13px;
|
||
transform: translateY(-.5px);
|
||
}
|
||
.welfare-rules-screen {
|
||
background: #FAFAFA !important;
|
||
color: #1A1A1A;
|
||
}
|
||
.welfare-rules-body {
|
||
flex: 1;
|
||
overflow-y: auto;
|
||
padding: 12px 16px 24px;
|
||
}
|
||
.welfare-rules-card {
|
||
background: #fff;
|
||
border-radius: 14px;
|
||
padding: 16px 16px 16px;
|
||
box-shadow: 0 4px 14px rgba(0,0,0,.04);
|
||
}
|
||
.welfare-rules-title {
|
||
font-size: 18px;
|
||
font-weight: 600;
|
||
color: #1A1A1A;
|
||
margin-bottom: 12px;
|
||
}
|
||
.welfare-rules-list {
|
||
display: grid;
|
||
gap: 12px;
|
||
}
|
||
.welfare-rules-item {
|
||
display: grid;
|
||
grid-template-columns: 20px 1fr;
|
||
gap: 8px;
|
||
align-items: start;
|
||
}
|
||
.welfare-rules-index {
|
||
width: 20px;
|
||
height: 20px;
|
||
border-radius: 50%;
|
||
background: #FFF3C4;
|
||
color: #8B6914;
|
||
display: inline-flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
font-size: 11px;
|
||
font-weight: 600;
|
||
}
|
||
.welfare-rules-text {
|
||
font-size: 13px;
|
||
line-height: 20px;
|
||
font-weight: 400;
|
||
color: #666666;
|
||
}
|
||
.welfare-rules-text strong {
|
||
display: block;
|
||
margin-bottom: 2px;
|
||
font-size: 14px;
|
||
line-height: 20px;
|
||
font-weight: 700;
|
||
color: #1A1A1A;
|
||
}
|
||
.r8-record-task-block {
|
||
margin-top: 12px;
|
||
}
|
||
.r8-record-task-row {
|
||
margin-top: 0;
|
||
}
|
||
.r8-record-rewards {
|
||
position: relative;
|
||
margin-top: 8px;
|
||
display: grid;
|
||
grid-template-columns: repeat(6, minmax(0, 1fr));
|
||
gap: 2px;
|
||
}
|
||
.r8-record-milestone {
|
||
position: relative;
|
||
z-index: 1;
|
||
min-width: 0;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
}
|
||
.r8-record-reward-box {
|
||
-webkit-appearance: none;
|
||
appearance: none;
|
||
width: 42px;
|
||
height: 50px;
|
||
border-radius: 8px;
|
||
background: #F0F0F0;
|
||
border: none;
|
||
font-family: inherit;
|
||
box-shadow: inset 0 1px 0 rgba(255,255,255,.75);
|
||
display: grid;
|
||
grid-template-rows: 10px 18px 13px;
|
||
align-content: center;
|
||
justify-items: center;
|
||
row-gap: 2px;
|
||
padding: 2px 2px;
|
||
position: relative;
|
||
transition: transform .12s ease, box-shadow .12s ease, background .12s ease;
|
||
}
|
||
button.r8-record-reward-box {
|
||
cursor: pointer;
|
||
-webkit-tap-highlight-color: transparent;
|
||
}
|
||
button.r8-record-reward-box:active {
|
||
transform: translateY(1px);
|
||
}
|
||
button.r8-record-reward-box:focus-visible {
|
||
outline: 2px solid rgba(255, 184, 0, .5);
|
||
outline-offset: 2px;
|
||
}
|
||
button.r8-record-reward-box.done,
|
||
button.r8-record-reward-box:disabled {
|
||
cursor: default;
|
||
pointer-events: none;
|
||
}
|
||
.r8-record-reward-box.done {
|
||
background: #FAFAFA;
|
||
display: flex;
|
||
flex-direction: column;
|
||
justify-content: center;
|
||
align-items: center;
|
||
row-gap: 2px;
|
||
}
|
||
.r8-record-reward-box.active {
|
||
background: #FFF3E0;
|
||
box-shadow: inset 0 0 0 1px #FFD979;
|
||
}
|
||
.r8-record-status {
|
||
position: static;
|
||
text-align: center;
|
||
font-size: 10px;
|
||
line-height: 1;
|
||
font-weight: 800;
|
||
color: var(--r8-orange);
|
||
white-space: nowrap;
|
||
}
|
||
.r8-record-reward-box.done .r8-record-status {
|
||
font-size: 10px;
|
||
color: #999999;
|
||
}
|
||
.r8-record-reward-box.active .r8-record-status {
|
||
color: #FFA000;
|
||
}
|
||
.r8-record-reward-box.locked .r8-record-status {
|
||
color: #999999;
|
||
}
|
||
.r8-record-coin {
|
||
width: 18px;
|
||
height: 18px;
|
||
object-fit: contain;
|
||
flex-shrink: 0;
|
||
transform: scale(1.12);
|
||
transform-origin: center;
|
||
}
|
||
.r8-record-num {
|
||
font-size: 12px;
|
||
line-height: 1;
|
||
font-weight: 800;
|
||
color: var(--r8-orange);
|
||
letter-spacing: 0;
|
||
white-space: nowrap;
|
||
}
|
||
.r8-record-reward-box.done .r8-record-num {
|
||
font-size: 10px;
|
||
color: #999999;
|
||
font-weight: 750;
|
||
}
|
||
.r8-record-reward-box.active .r8-record-num {
|
||
font-size: 13px;
|
||
color: var(--r8-orange);
|
||
}
|
||
.r8-record-label {
|
||
margin-top: 4px;
|
||
font-size: 10px;
|
||
line-height: 1;
|
||
font-weight: 750;
|
||
color: #666666;
|
||
white-space: nowrap;
|
||
}
|
||
.r8-task-cta.is-done {
|
||
background: #F0F0F0;
|
||
color: #999999;
|
||
cursor: default;
|
||
}
|
||
@keyframes rewardToastIn {
|
||
0% { opacity: 0; transform: translate(-50%, -48%) scale(.86); }
|
||
68% { opacity: 1; transform: translate(-50%, -50%) scale(1.04); }
|
||
100% { opacity: 1; transform: translate(-50%, -50%) scale(1); }
|
||
}
|
||
@keyframes rewardToastOut {
|
||
from { opacity: 1; transform: translate(-50%, -50%) scale(1); }
|
||
to { opacity: 0; transform: translate(-50%, -54%) scale(.96); }
|
||
}
|
||
.reward-toast {
|
||
position: absolute;
|
||
left: 50%;
|
||
top: 48%;
|
||
width: 176px;
|
||
min-height: 164px;
|
||
border-radius: 18px;
|
||
background: rgba(56, 56, 68, .98);
|
||
box-shadow: 0 18px 42px rgba(0,0,0,.24);
|
||
z-index: 10020;
|
||
pointer-events: none;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content: center;
|
||
padding: 16px 12px 16px;
|
||
color: #FFFFFF;
|
||
text-align: center;
|
||
animation: rewardToastIn .26s cubic-bezier(.18, .9, .25, 1.15) both;
|
||
}
|
||
.reward-toast.is-leaving {
|
||
animation: rewardToastOut .22s ease both;
|
||
}
|
||
.reward-toast-icon {
|
||
width: 72px;
|
||
height: 54px;
|
||
object-fit: contain;
|
||
display: block;
|
||
margin-bottom: 8px;
|
||
filter: drop-shadow(0 7px 10px rgba(255, 169, 27, .18));
|
||
}
|
||
.reward-toast-amount {
|
||
font-size: 28px;
|
||
line-height: 1;
|
||
font-weight: 900;
|
||
letter-spacing: 0;
|
||
color: #FFFFFF;
|
||
}
|
||
.reward-toast-title {
|
||
margin-top: 16px;
|
||
font-size: 20px;
|
||
line-height: 1;
|
||
font-weight: 700;
|
||
color: rgba(255,255,255,.9);
|
||
white-space: nowrap;
|
||
}
|
||
/* ===== 收益明细 / 提现 ===== */
|
||
.income-nav {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
padding: 40px 16px 16px;
|
||
background: #fff;
|
||
flex-shrink: 0;
|
||
}
|
||
.income-nav-title {
|
||
position: absolute;
|
||
left: 50%;
|
||
transform: translateX(-50%);
|
||
font-size: 18px;
|
||
font-weight: 500;
|
||
color: var(--gray-900);
|
||
letter-spacing: 0;
|
||
}
|
||
.income-nav-back,
|
||
.income-nav-link {
|
||
position: relative;
|
||
z-index: 1;
|
||
border: none;
|
||
background: none;
|
||
cursor: pointer;
|
||
font-family: inherit;
|
||
}
|
||
.income-nav-back {
|
||
width: 44px;
|
||
min-width: 44px;
|
||
height: 32px;
|
||
display: inline-flex;
|
||
align-items: center;
|
||
justify-content: flex-start;
|
||
padding: 0;
|
||
text-align: left;
|
||
font-size: 24px;
|
||
line-height: 1;
|
||
font-weight: 400;
|
||
color: var(--gray-800);
|
||
}
|
||
.income-nav-link {
|
||
min-width: 72px;
|
||
text-align: right;
|
||
font-size: 14px;
|
||
font-weight: 400;
|
||
color: var(--gray-500);
|
||
}
|
||
.income-rate {
|
||
padding: 0 16px 8px;
|
||
font-size: 12px;
|
||
line-height: 18px;
|
||
font-weight: 400;
|
||
color: var(--gray-500);
|
||
flex-shrink: 0;
|
||
}
|
||
.income-summary-card {
|
||
margin: 0 16px 16px;
|
||
padding: 24px 16px;
|
||
border-radius: 18px;
|
||
background: linear-gradient(135deg, #FFF3E0 0%, #FFFDE7 100%);
|
||
flex-shrink: 0;
|
||
}
|
||
.income-summary-grid {
|
||
display: grid;
|
||
grid-template-columns: 1fr 1fr;
|
||
gap: 24px;
|
||
}
|
||
.income-summary-label {
|
||
font-size: 13px;
|
||
font-weight: 400;
|
||
color: var(--gray-600);
|
||
margin-bottom: 6px;
|
||
}
|
||
.income-summary-value {
|
||
font-size: 28px;
|
||
line-height: 1;
|
||
font-weight: 700;
|
||
color: #FF5722;
|
||
letter-spacing: .2px;
|
||
}
|
||
.income-chip-btn {
|
||
margin-top: 8px;
|
||
height: 28px;
|
||
padding: 0 12px;
|
||
border-radius: 999px;
|
||
border: 1.5px solid #FF5722;
|
||
background: transparent;
|
||
color: #FF5722;
|
||
font-size: 13px;
|
||
font-weight: 500;
|
||
cursor: pointer;
|
||
font-family: inherit;
|
||
}
|
||
.income-chip-btn.filled {
|
||
background: #FF5722;
|
||
color: #fff;
|
||
}
|
||
.income-tabs {
|
||
position: relative;
|
||
display: flex;
|
||
padding: 0 16px;
|
||
border-bottom: 2px solid var(--gray-200);
|
||
flex-shrink: 0;
|
||
}
|
||
.income-tab {
|
||
flex: 1;
|
||
border: none;
|
||
background: none;
|
||
padding: 16px 0 12px;
|
||
text-align: center;
|
||
font-family: inherit;
|
||
font-size: 15px;
|
||
font-weight: 400;
|
||
color: var(--gray-500);
|
||
cursor: pointer;
|
||
}
|
||
.income-tab.active {
|
||
color: #000;
|
||
font-weight: 400;
|
||
}
|
||
.income-tab-indicator {
|
||
position: absolute;
|
||
left: 16px;
|
||
bottom: -2px;
|
||
width: calc((100% - 32px) / 2);
|
||
height: 2px;
|
||
background: #1a1a1a;
|
||
transition: transform .24s ease;
|
||
}
|
||
.income-tabs[data-active="cash"] .income-tab-indicator {
|
||
transform: translateX(100%);
|
||
}
|
||
.income-record-shell {
|
||
flex: 1;
|
||
overflow: hidden;
|
||
background: #fff;
|
||
touch-action: pan-y;
|
||
user-select: none;
|
||
-webkit-user-select: none;
|
||
}
|
||
.income-record-track {
|
||
height: 100%;
|
||
display: flex;
|
||
width: 200%;
|
||
transition: transform .24s ease;
|
||
}
|
||
.income-record-track.cash-active {
|
||
transform: translateX(-50%);
|
||
}
|
||
.income-record-panel {
|
||
width: 50%;
|
||
min-width: 50%;
|
||
overflow-y: auto;
|
||
-webkit-overflow-scrolling: touch;
|
||
padding: 0 16px 16px;
|
||
}
|
||
.income-record-row {
|
||
min-height: 72px;
|
||
display: flex;
|
||
align-items: center;
|
||
border-bottom: .5px solid var(--gray-100);
|
||
}
|
||
.income-record-main {
|
||
flex: 1;
|
||
min-width: 0;
|
||
}
|
||
.income-record-title {
|
||
font-size: 15px;
|
||
font-weight: 400;
|
||
color: #1A1A1A;
|
||
line-height: 1.3;
|
||
}
|
||
.income-record-date {
|
||
margin-top: 4px;
|
||
font-size: 13px;
|
||
font-weight: 400;
|
||
color: var(--gray-400);
|
||
}
|
||
.income-record-amount {
|
||
margin-left: 8px;
|
||
font-size: 16px;
|
||
font-weight: 400;
|
||
color: #FF5722;
|
||
white-space: nowrap;
|
||
}
|
||
.income-record-amount.cash {
|
||
color: #FE2C55;
|
||
}
|
||
.income-footer {
|
||
padding: 12px 16px 24px;
|
||
border-top: .5px solid var(--gray-200);
|
||
text-align: center;
|
||
flex-shrink: 0;
|
||
background: #fff;
|
||
}
|
||
.income-footer-note {
|
||
margin-bottom: 8px;
|
||
font-size: 14px;
|
||
font-weight: 400;
|
||
color: var(--gray-500);
|
||
}
|
||
.income-footer-note strong {
|
||
color: #FF5722;
|
||
font-weight: 500;
|
||
}
|
||
.income-footer .btn {
|
||
font-weight: 400;
|
||
}
|
||
.withdraw-screen {
|
||
background: #fff !important;
|
||
color: var(--gray-900);
|
||
}
|
||
#withdrawal .income-nav-title {
|
||
font-size: 16px;
|
||
font-weight: 500;
|
||
}
|
||
#withdrawal .income-nav {
|
||
background: transparent;
|
||
}
|
||
#withdrawal .income-nav-back {
|
||
font-size: 22px;
|
||
font-weight: 400;
|
||
}
|
||
.withdraw-nav-links {
|
||
min-width: 104px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: flex-end;
|
||
gap: 6px;
|
||
font-size: 12px;
|
||
font-weight: 400;
|
||
color: var(--gray-700);
|
||
}
|
||
.withdraw-nav-links button {
|
||
border: none;
|
||
background: none;
|
||
padding: 0;
|
||
font: inherit;
|
||
color: inherit;
|
||
cursor: pointer;
|
||
}
|
||
.withdraw-nav-sep {
|
||
width: 1px;
|
||
height: 12px;
|
||
background: var(--gray-300);
|
||
}
|
||
.withdraw-top {
|
||
flex-shrink: 0;
|
||
background: linear-gradient(126deg, #FFF3C4 0%, #FFFFFF 52%, #E8F5E9 100%);
|
||
border-bottom: .5px solid rgba(0,0,0,.04);
|
||
}
|
||
.withdraw-notice {
|
||
min-height: 40px;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 6px;
|
||
padding: 0 16px;
|
||
border-top: .5px solid rgba(0,0,0,.04);
|
||
border-bottom: .5px solid rgba(0,0,0,.05);
|
||
background: rgba(255,255,255,.50);
|
||
color: var(--gray-700);
|
||
font-size: 11px;
|
||
font-weight: 400;
|
||
}
|
||
.withdraw-notice-icon {
|
||
width: 14px;
|
||
height: 14px;
|
||
border-radius: 50%;
|
||
border: 1.3px solid currentColor;
|
||
display: inline-flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
flex-shrink: 0;
|
||
font-size: 10px;
|
||
line-height: 1;
|
||
}
|
||
.withdraw-notice-text {
|
||
flex: 1;
|
||
min-width: 0;
|
||
white-space: nowrap;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
}
|
||
.withdraw-notice-close {
|
||
border: none;
|
||
background: none;
|
||
color: var(--gray-700);
|
||
font-size: 18px;
|
||
font-weight: 400;
|
||
line-height: 1;
|
||
cursor: pointer;
|
||
}
|
||
.withdraw-content {
|
||
flex: 1;
|
||
overflow-y: auto;
|
||
-webkit-overflow-scrolling: touch;
|
||
padding: 24px 16px 24px;
|
||
background: #fff;
|
||
}
|
||
.withdraw-balance-card {
|
||
display: block;
|
||
text-align: center;
|
||
padding: 12px 0 32px;
|
||
margin-bottom: 0;
|
||
}
|
||
.withdraw-balance-amount {
|
||
font-size: 48px;
|
||
line-height: 1;
|
||
font-weight: 800;
|
||
color: #FFA000;
|
||
letter-spacing: 0;
|
||
}
|
||
.withdraw-balance-amount span {
|
||
font-size: 14px;
|
||
font-weight: 400;
|
||
margin-left: 4px;
|
||
}
|
||
.withdraw-balance-sub {
|
||
display: none;
|
||
}
|
||
.withdraw-method {
|
||
margin-bottom: 24px;
|
||
}
|
||
.withdraw-method-head {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
min-height: 26px;
|
||
margin-bottom: 12px;
|
||
}
|
||
.withdraw-method-title {
|
||
flex: 1;
|
||
font-size: 15px;
|
||
font-weight: 600;
|
||
color: var(--gray-900);
|
||
}
|
||
.withdraw-wechat-logo {
|
||
width: 22px;
|
||
height: 22px;
|
||
border-radius: 50%;
|
||
display: inline-flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
flex-shrink: 0;
|
||
background: #22C55E;
|
||
}
|
||
.withdraw-wechat-logo svg {
|
||
width: 16px;
|
||
height: 16px;
|
||
display: block;
|
||
}
|
||
.withdraw-amount-grid {
|
||
display: grid;
|
||
grid-template-columns: repeat(3, 1fr);
|
||
gap: 8px;
|
||
}
|
||
.withdraw-amount {
|
||
min-height: 66px;
|
||
border: 1px solid #F0F0F0;
|
||
border-radius: 12px;
|
||
background: #FAFAFA;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
text-align: center;
|
||
cursor: pointer;
|
||
font-family: inherit;
|
||
font-size: 18px;
|
||
font-weight: 700;
|
||
color: #1A1A1A;
|
||
box-shadow: 0 5px 14px rgba(0,0,0,.032);
|
||
}
|
||
.withdraw-amount small {
|
||
font-size: 12px;
|
||
font-weight: 400;
|
||
margin-left: 2px;
|
||
}
|
||
.withdraw-amount.active {
|
||
border-color: #FFD600;
|
||
background: #FFFDE7;
|
||
color: #1A1A1A;
|
||
box-shadow: inset 0 0 0 1px #FFD600, 0 7px 16px rgba(255,214,0,.13);
|
||
}
|
||
.wechat-bind-layer {
|
||
display: none;
|
||
position: absolute;
|
||
inset: 0;
|
||
z-index: 285;
|
||
overflow: hidden;
|
||
}
|
||
.wechat-bind-layer.open {
|
||
display: block;
|
||
}
|
||
.wechat-bind-mask {
|
||
position: absolute;
|
||
inset: 0;
|
||
background: rgba(0,0,0,.56);
|
||
}
|
||
.wechat-bind-sheet {
|
||
position: absolute;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
min-height: 520px;
|
||
border-radius: 24px 24px 0 0;
|
||
background: #FAFAFA;
|
||
padding: 24px 16px 24px;
|
||
animation: exchangeSheetUp .24s ease-out;
|
||
}
|
||
.wechat-bind-close {
|
||
width: 38px;
|
||
height: 38px;
|
||
border-radius: 18px;
|
||
border: none;
|
||
background: #F0F0F0;
|
||
display: inline-flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
color: #1A1A1A;
|
||
font-size: 28px;
|
||
font-weight: 400;
|
||
line-height: 1;
|
||
cursor: pointer;
|
||
font-family: inherit;
|
||
}
|
||
.wechat-bind-amount-label {
|
||
margin-top: 4px;
|
||
text-align: center;
|
||
font-size: 17px;
|
||
font-weight: 400;
|
||
color: var(--gray-600);
|
||
}
|
||
.wechat-bind-amount {
|
||
margin-top: 8px;
|
||
text-align: center;
|
||
font-size: 48px;
|
||
line-height: 1;
|
||
font-weight: 700;
|
||
color: #1A1A1A;
|
||
}
|
||
.wechat-bind-amount small {
|
||
font-size: 18px;
|
||
font-weight: 400;
|
||
margin-left: 4px;
|
||
}
|
||
.wechat-bind-card {
|
||
margin-top: 64px;
|
||
min-height: 92px;
|
||
border-radius: 14px;
|
||
background: #fff;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 12px;
|
||
padding: 0 16px;
|
||
box-shadow: 0 6px 20px rgba(0,0,0,.03);
|
||
}
|
||
.wechat-bind-card-logo {
|
||
width: 34px;
|
||
height: 34px;
|
||
border-radius: 18px;
|
||
background: #22C55E;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
flex-shrink: 0;
|
||
}
|
||
.wechat-bind-card-logo svg {
|
||
width: 24px;
|
||
height: 24px;
|
||
}
|
||
.wechat-bind-card-title {
|
||
font-size: 17px;
|
||
font-weight: 600;
|
||
color: #1A1A1A;
|
||
}
|
||
.wechat-bind-card-sub {
|
||
margin-top: 6px;
|
||
font-size: 14px;
|
||
font-weight: 400;
|
||
color: var(--gray-500);
|
||
}
|
||
.wechat-bind-cta {
|
||
position: absolute;
|
||
left: 20px;
|
||
right: 20px;
|
||
bottom: 28px;
|
||
height: 56px;
|
||
border: none;
|
||
border-radius: 14px;
|
||
background: linear-gradient(90deg, #FFE066 0%, #FFD600 52%, #FFE066 100%);
|
||
color: #1A1A1A;
|
||
font-family: inherit;
|
||
font-size: 17px;
|
||
font-weight: 600;
|
||
cursor: pointer;
|
||
}
|
||
.exchange-layer {
|
||
display: none;
|
||
position: absolute;
|
||
inset: 0;
|
||
z-index: 280;
|
||
overflow: hidden;
|
||
}
|
||
.exchange-layer.open {
|
||
display: block;
|
||
}
|
||
.exchange-mask {
|
||
position: absolute;
|
||
inset: 0;
|
||
background: rgba(0,0,0,.72);
|
||
}
|
||
.exchange-sheet {
|
||
position: absolute;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
background: #fff;
|
||
border-radius: 24px 24px 0 0;
|
||
padding: 24px 16px 24px;
|
||
animation: exchangeSheetUp .24s ease-out;
|
||
}
|
||
@keyframes exchangeSheetUp {
|
||
from { transform: translateY(100%); }
|
||
to { transform: translateY(0); }
|
||
}
|
||
.exchange-close {
|
||
position: absolute;
|
||
top: 18px;
|
||
right: 18px;
|
||
width: 38px;
|
||
height: 38px;
|
||
border-radius: 18px;
|
||
border: none;
|
||
background: #F0F0F0;
|
||
color: #1A1A1A;
|
||
font-size: 24px;
|
||
line-height: 1;
|
||
cursor: pointer;
|
||
font-family: inherit;
|
||
}
|
||
.exchange-title {
|
||
font-size: 20px;
|
||
font-weight: 900;
|
||
color: #1A1A1A;
|
||
margin-bottom: 8px;
|
||
}
|
||
.exchange-balance {
|
||
font-size: 15px;
|
||
font-weight: 600;
|
||
color: var(--gray-500);
|
||
margin-bottom: 24px;
|
||
}
|
||
.exchange-balance strong {
|
||
color: var(--gray-700);
|
||
font-weight: 800;
|
||
}
|
||
.exchange-convert-card {
|
||
height: 64px;
|
||
border-radius: 8px;
|
||
background: #FAFAFA;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
padding: 0 16px 0 16px;
|
||
margin-bottom: 24px;
|
||
}
|
||
.exchange-coin-side {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
}
|
||
.exchange-coin-icon {
|
||
width: 30px;
|
||
height: 30px;
|
||
border-radius: 14px;
|
||
background: radial-gradient(circle at 35% 30%, #FFE0B2, #FFB300);
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
color: #8B6914;
|
||
font-weight: 900;
|
||
font-size: 16px;
|
||
}
|
||
.exchange-coin-num {
|
||
font-size: 24px;
|
||
font-weight: 900;
|
||
color: #000;
|
||
}
|
||
.exchange-cash-num {
|
||
font-size: 28px;
|
||
font-weight: 900;
|
||
color: #FE2C55;
|
||
}
|
||
.exchange-cash-num small {
|
||
font-size: 17px;
|
||
margin-left: 2px;
|
||
}
|
||
.exchange-presets {
|
||
display: grid;
|
||
grid-template-columns: repeat(4, 1fr);
|
||
gap: 8px;
|
||
margin-bottom: 12px;
|
||
}
|
||
.exchange-preset {
|
||
height: 48px;
|
||
border-radius: 8px;
|
||
border: 1px solid #F0F0F0;
|
||
background: #fff;
|
||
color: var(--gray-400);
|
||
font-family: inherit;
|
||
font-size: 16px;
|
||
font-weight: 700;
|
||
cursor: pointer;
|
||
}
|
||
.exchange-preset.active {
|
||
border-color: #FF6B6B;
|
||
color: #FE2C55;
|
||
background: #FAFAFA;
|
||
}
|
||
.exchange-error {
|
||
min-height: 22px;
|
||
color: #FE2C55;
|
||
font-size: 14px;
|
||
font-weight: 700;
|
||
margin-bottom: 24px;
|
||
}
|
||
.exchange-rule {
|
||
text-align: center;
|
||
font-size: 15px;
|
||
font-weight: 600;
|
||
color: var(--gray-500);
|
||
margin-bottom: 24px;
|
||
}
|
||
.exchange-submit {
|
||
width: 100%;
|
||
height: 56px;
|
||
border: none;
|
||
border-radius: 8px;
|
||
background: #FE2C55;
|
||
color: #fff;
|
||
font-family: inherit;
|
||
font-size: 18px;
|
||
font-weight: 700;
|
||
cursor: pointer;
|
||
}
|
||
|
||
/* === 标准返回按钮 (统一 design.md - icons.back-chevron) === */
|
||
.btn-back {
|
||
width: 44px; height: 44px;
|
||
display: flex; align-items: center; justify-content: center;
|
||
background: transparent; border: none; padding: 0;
|
||
cursor: pointer; -webkit-tap-highlight-color: transparent;
|
||
flex-shrink: 0;
|
||
}
|
||
.btn-back:active { opacity: 0.5; }
|
||
.btn-back svg { width: 24px; height: 24px; display: block; }
|
||
|
||
</style>
|
||
|
||
<style>
|
||
/* === 跳转动画(原 shared/transitions.css 内嵌) === */
|
||
/* tokens.css 是空文件已废弃,未内嵌;token 由各 HTML 的 :root 单独定义 */
|
||
/**
|
||
* 7 种跳转动画
|
||
* 用法:JS 给 body 加 .transitioning-{词} class,触发对应动画
|
||
*/
|
||
|
||
/* push: 右进左出(进入下一层级) */
|
||
@keyframes nav-push-out {
|
||
from { transform: translateX(0); opacity: 1; }
|
||
to { transform: translateX(-30%); opacity: 0.6; }
|
||
}
|
||
body.transitioning-push { animation: nav-push-out 280ms ease-in forwards; }
|
||
|
||
/* pop: 左进右出(返回) */
|
||
@keyframes nav-pop-out {
|
||
from { transform: translateX(0); opacity: 1; }
|
||
to { transform: translateX(100%); opacity: 0.8; }
|
||
}
|
||
body.transitioning-pop { animation: nav-pop-out 280ms ease-in forwards; }
|
||
|
||
/* modal: 从底弹起(即将离开页面,向上让位) */
|
||
@keyframes nav-modal-out {
|
||
from { transform: translateY(0); opacity: 1; }
|
||
to { transform: translateY(-8%); opacity: 0.6; }
|
||
}
|
||
body.transitioning-modal { animation: nav-modal-out 280ms ease-in forwards; }
|
||
|
||
/* dismiss: 向下收起 */
|
||
@keyframes nav-dismiss-out {
|
||
from { transform: translateY(0); opacity: 1; }
|
||
to { transform: translateY(100%); opacity: 0.4; }
|
||
}
|
||
body.transitioning-dismiss { animation: nav-dismiss-out 280ms ease-in forwards; }
|
||
|
||
/* replace: 直接替换(淡出) */
|
||
@keyframes nav-replace-out {
|
||
from { opacity: 1; }
|
||
to { opacity: 0; }
|
||
}
|
||
body.transitioning-replace { animation: nav-replace-out 200ms ease-out forwards; }
|
||
|
||
/* fade: 淡入淡出(splash 类过渡) */
|
||
@keyframes nav-fade-out {
|
||
from { opacity: 1; }
|
||
to { opacity: 0; }
|
||
}
|
||
body.transitioning-fade { animation: nav-fade-out 400ms ease-in-out forwards; }
|
||
|
||
/* tab: 无动画(瞬切) */
|
||
body.transitioning-tab { /* no animation */ }
|
||
|
||
/* 进入动画(DOMContentLoaded 前的初始状态由 body.preanim 控制,可选) */
|
||
@keyframes nav-fade-in {
|
||
from { opacity: 0; }
|
||
to { opacity: 1; }
|
||
}
|
||
body { /* nav-fade-in disabled — tab 切换闪烁源头 */ }
|
||
</style>
|
||
<!-- webview 改造:H5↔原生桥 + 同源后端调用层(必须在页面其他脚本之前加载) -->
|
||
<script src="../shared/bridge.js"></script>
|
||
<script src="../shared/api.js"></script>
|
||
</head>
|
||
<body data-cc-id="cc-1" style="cursor: crosshair; background-color: rgb(0, 0, 0);">
|
||
<!--
|
||
@page: profile
|
||
@path: app/profile
|
||
@source: 2026-05-18.html
|
||
TODO: 补充 @owner / @from / @to / @notes(参照 FLOW.md)
|
||
-->
|
||
|
||
<!-- 方案切换控制面板 -->
|
||
<div class="variant-toggle" id="variantToggle">
|
||
<button class="variant-btn" onclick="toggleVariantPanel()" title="方案切换">⚙</button>
|
||
<div class="variant-panel" id="variantPanel">
|
||
<h3>方案切换</h3>
|
||
<div id="variantList"><div class="variant-empty">暂无多方案模块<br><span style="font-size: 11px;">在 variants 配置中添加模块即可</span></div></div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="device" id="app">
|
||
<!-- 调试返回按钮 -->
|
||
<div id="debugBack" onclick="debugGoBack()" style="position: absolute; left: 0px; bottom: 0px; z-index: 99999; background: rgb(0, 0, 0); color: rgb(255, 255, 255); font-size: 11px; font-weight: 700; padding: 8px 8px; border-radius: 0px 4px 0px 0px; cursor: pointer; opacity: 0.7; line-height: 1; letter-spacing: 1px;" data-cc-id="cc-11">返回</div>
|
||
<!-- ===== 11. LOGIN ===== -->
|
||
<!-- screen #login removed for split -->
|
||
|
||
<!-- 入口页协议 · 底部抽屉(device 级 overlay,可跨屏触发:login / celebration 都用) -->
|
||
<div id="agreeModal" class="login-agreement-sheet-layer">
|
||
<div class="login-agreement-sheet">
|
||
<div class="login-agreement-sheet-title">用户协议及隐私保护</div>
|
||
<div class="login-agreement-sheet-copy">我已阅读并同意<span class="link">用户协议</span>、<span class="link">基本功能隐私政策</span></div>
|
||
<button class="login-agreement-sheet-primary" type="button" onclick="agreeAndLogin()">同意并登录</button>
|
||
<button class="login-agreement-sheet-secondary" type="button" onclick="closeAgreeModal()">不同意</button>
|
||
</div>
|
||
</div>
|
||
<!-- 通用 Toast(device 级,跨屏可见) -->
|
||
<div id="loginToast" style="display: none;position: absolute;left: 50%;bottom: 120px;transform: translateX(-50%);background: rgba(0,0,0,.75);color: #fff;font-size: 13px;font-weight: 500;padding: 8px 16px;border-radius: 8px;white-space: nowrap;z-index: 40;"></div>
|
||
|
||
<!-- ===== 11b. LOGIN PHONE(独立手机号登录页) ===== -->
|
||
<!-- screen #loginPhone removed for split -->
|
||
|
||
<!-- ===== HOME TAB ===== -->
|
||
<!-- screen #home removed for split -->
|
||
|
||
<!-- [ECOM-ONLY] BLIND BOX screen removed for waimai V1 -->
|
||
<!-- Original: 150+ lines of blind box full-page screen with card slider -->
|
||
|
||
|
||
<!-- ===== WELFARE TAB (红果风格) ===== -->
|
||
<!-- screen #welfare removed for split -->
|
||
|
||
<!-- ===== WELFARE RULES / 活动规则 ===== -->
|
||
<!-- screen #welfareRules removed for split -->
|
||
|
||
<!-- ===== PROFILE TAB ===== -->
|
||
<style>
|
||
/* —— 我的页 (profile) —— */
|
||
#profile {
|
||
background: radial-gradient(circle at 84% 17%, rgba(255,255,255,.82) 0 36px, transparent 37px),
|
||
radial-gradient(circle at 98% 20%, rgba(255,255,255,.66) 0 42px, transparent 43px),
|
||
linear-gradient(180deg, #FFF1D9 0%, #FFF6E8 28%, #FFF8EF 48%, #F8F8F8 70%, #F7F7F7 100%);
|
||
}
|
||
.prof-statusbar { position: absolute; left: 0; right: 0; top: 0; height: 42px; z-index: 20; display: flex; align-items: center; justify-content: space-between; padding: 8px 32px 0 32px; pointer-events: none; color: #000; }
|
||
.prof-status-time { font-size: 15px; font-weight: 600; letter-spacing: .1px; line-height: 1; font-variant-numeric: tabular-nums; }
|
||
.prof-status-icons { display: flex; align-items: center; gap: 8px; }
|
||
.prof-cell { display: flex; align-items: flex-end; gap: 2px; height: 14px; }
|
||
.prof-cell i { display: block; width: 3px; border-radius: 4px; background: #000; }
|
||
.prof-cell i:nth-child(1) { height: 5px; }
|
||
.prof-cell i:nth-child(2) { height: 8px; }
|
||
.prof-cell i:nth-child(3) { height: 11px; }
|
||
.prof-cell i:nth-child(4) { height: 14px; }
|
||
.prof-wifi { position: relative; width: 17px; height: 13px; overflow: hidden; }
|
||
.prof-wifi::before, .prof-wifi::after { content: ''; position: absolute; left: 50%; border: 3px solid #000; border-color: #000 transparent transparent transparent; border-radius: 50%; transform: translateX(-50%); }
|
||
.prof-wifi::before { width: 21px; height: 21px; top: 1px; }
|
||
.prof-wifi::after { width: 11px; height: 11px; top: 6px; }
|
||
.prof-wifi i { position: absolute; left: 50%; bottom: 0; width: 5px; height: 5px; margin-left: -2.5px; border-radius: 50%; background: #000; }
|
||
.prof-battery { position: relative; width: 23px; height: 12px; border: 1.7px solid #000; border-radius: 4px; padding: 2px; }
|
||
.prof-battery::before { content: ''; position: absolute; right: -3.7px; top: 3.1px; width: 2px; height: 5px; border-radius: 0 4px 4px 0; background: #000; }
|
||
.prof-battery i { display: block; width: 100%; height: 100%; border-radius: 4px; background: #000; }
|
||
.prof-scroll { flex: 1; overflow-y: auto; overflow-x: hidden; }
|
||
.prof-hero { position: relative; padding: 64px 16px 0; min-height: 154px; overflow: visible; }
|
||
.prof-clouds { position: absolute; left: 0; right: 0; top: 0; width: 100%; height: 174px; object-fit: cover; opacity: .72; pointer-events: none; }
|
||
.prof-piggy { position: absolute; top: 36px; right: -12px; width: 160px; height: auto; pointer-events: none; z-index: 1; filter: drop-shadow(0 10px 18px rgba(255,125,50,.16)); }
|
||
.prof-hero::after { content: ''; position: absolute; right: 160px; top: 114px; width: 9px; height: 9px; background: #FFB300; transform: rotate(45deg); box-shadow: 7px 0 0 -3px rgba(255,179,0,.75), 0 7px 0 -3px rgba(255,179,0,.75); z-index: 1; }
|
||
.prof-id { position: relative; z-index: 2; display: flex; align-items: center; gap: 12px; }
|
||
.prof-avatar { width: 64px; height: 64px; border-radius: 50%; flex-shrink: 0; background: radial-gradient(circle at 42% 32%, #FFE0B2 0%, #FFE066 43%, #FFEB3B 100%); border: 3px solid #fff; box-shadow: 0 6px 16px rgba(255,137,32,.20); display: flex; align-items: center; justify-content: center; overflow: hidden; }
|
||
.prof-avatar svg { width: 60px; height: 60px; display: block; }
|
||
.prof-meta { flex: 1; min-width: 0; min-height: 64px; display: flex; align-items: center; }
|
||
.prof-name { max-width: 9em; font-size: 17.5px; font-weight: 600; color: #000000; line-height: 1.2; letter-spacing: 0; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; text-overflow: ellipsis; word-break: break-all; }
|
||
.prof-phone { font-size: 13px; color: rgba(0,0,0,.58); margin-top: 6px; letter-spacing: .1px; font-variant-numeric: tabular-nums; }
|
||
.prof-badge { display: inline-flex; align-items: center; gap: 4px; margin-top: 8px; padding: 4px 8px 4px 6px; background: rgba(255,255,255,.58); border: 1px solid rgba(255,255,255,.95); border-radius: 999px; font-size: 12px; line-height: 1; font-weight: 700; color: #FF5722; box-shadow: 0 2px 8px rgba(143,84,25,.08); backdrop-filter: blur(4px); }
|
||
.prof-badge svg { width: 15px; height: 15px; }
|
||
.prof-badge svg path:first-child { fill: #FFA000; }
|
||
.prof-badge svg path:last-child { stroke: #fff; }
|
||
.prof-body-inner { position: relative; z-index: 3; padding: 12px 16px 16px; }
|
||
/* —— 累计帮省卡片 —— */
|
||
.prof-savings-card { position: relative; border-radius: 24px; padding: 16px 22px 17px; background: linear-gradient(180deg, #FF6A00 0%, #FF5722 52%, #FFA000 100%); box-shadow: inset 0 1px 0 rgba(255,255,255,.30); overflow: hidden; color: #fff; border: 1px solid rgba(255,172,63,.55); }
|
||
.prof-savings-card::before { content: ''; position: absolute; inset: 0; background: radial-gradient(circle at 18% 26%, rgba(255,255,255,.10), transparent 18%), radial-gradient(circle at 75% 35%, rgba(255,255,255,.08), transparent 24%); pointer-events: none; }
|
||
.prof-savings-deco { position: absolute; left: -14px; bottom: -12px; width: 160px; height: 128px; object-fit: contain; object-position: left bottom; opacity: .30; pointer-events: none; }
|
||
.prof-savings-coin { position: absolute; top: auto; bottom: 112px; right: 18px; width: 44px; height: 44px; opacity: .82; pointer-events: none; transform: rotate(-22deg); }
|
||
.prof-savings-head { position: relative; z-index: 1; display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 10px; }
|
||
.prof-savings-title { display: inline-flex; align-items: center; gap: 5px; font-size: 16px; font-weight: 700; color: #fff; line-height: 1.2; }
|
||
.prof-savings-title .spark { font-size: 12px; color: #FFEB3B; }
|
||
.prof-savings-label { position: relative; z-index: 1; font-size: 15px; line-height: 1.1; font-weight: 700; color: rgba(255,255,255,.96); text-align: center; letter-spacing: .2px; }
|
||
.prof-amount-row { position: relative; z-index: 1; display: flex; align-items: center; justify-content: center; gap: 8px; height: 62px; margin: 5px 0 5px; }
|
||
.prof-amount-row::before { content: none; }
|
||
.prof-wheat { width: 46px; height: 64px; flex: 0 0 auto; opacity: .58; background-image: url('../../assets/profile/index/laurel.png'); background-repeat: no-repeat; background-size: 230px 77px; pointer-events: none; }
|
||
.prof-wheat.left { background-position: 17% center; }
|
||
.prof-wheat.right { background-position: 83% center; }
|
||
.prof-laurel { display: none; }
|
||
.prof-laurel.left { object-position: left center; }
|
||
.prof-laurel.right { object-position: right center; transform: scaleX(-1); }
|
||
.prof-amount { position: relative; z-index: 1; display: inline-flex; align-items: baseline; font-family: "DIN Alternate", "Helvetica Neue", sans-serif; font-size: 36px; font-weight: 900; color: #fff; line-height: 1; letter-spacing: -0.5px; text-shadow: 0 2px 6px rgba(160,50,0,.16); font-variant-numeric: tabular-nums; }
|
||
.prof-currency { font-size: 26px; margin-right: 4px; font-weight: 800; }
|
||
.prof-cents { font-size: 20px; font-weight: 800; margin-left: 1px; }
|
||
.prof-stats-row { position: relative; z-index: 1; display: flex; align-items: center; justify-content: center; gap: 0; margin: 4px 0 0; padding-top: 10px; border-top: 1px solid rgba(255,255,255,.35); }
|
||
.prof-stats-row > div:not(.prof-stats-div) { flex: 1; text-align: center; }
|
||
.prof-stat-num { font-family: "DIN Alternate", "Helvetica Neue", sans-serif; font-size: 18px; font-weight: 900; color: #fff; line-height: 1; font-variant-numeric: tabular-nums; }
|
||
.prof-stat-num .prof-stat-cur { font-size: 13px; font-weight: 800; margin-right: 1px; }
|
||
.prof-stat-unit { font-size: 12px; font-weight: 700; margin-left: 1px; font-family: -apple-system, "PingFang SC", sans-serif; }
|
||
.prof-stat-key { font-size: 12px; font-weight: 600; color: rgba(255,255,255,.88); margin-bottom: 4px; }
|
||
.prof-stats-div { width: 1px; height: 34px; background: rgba(255,255,255,.33); }
|
||
.prof-savings-btn { position: relative; z-index: 1; display: flex; align-items: center; justify-content: center; gap: 6px; width: 142px; height: 34px; margin: 12px auto 0; padding: 0 16px; background: #fff; border: none; border-radius: 999px; font-size: 14px; font-weight: 600; color: #FF5722; cursor: pointer; box-shadow: 0 6px 12px rgba(214,82,0,.14); }
|
||
.prof-savings-btn span { font-size: 18px; line-height: 1; margin-left: 0; display: inline-block; transform: translateY(-1px); }
|
||
/* —— 未比价锁定蒙层(不透明,盖住示例数据)—— */
|
||
.prof-lock-overlay { display: none; position: absolute; inset: 0; z-index: 6; flex-direction: column; align-items: center; justify-content: center; gap: 8px; padding: 0 24px; text-align: center; background: linear-gradient(180deg, #FF6A00 0%, #FF5722 52%, #FFA000 100%); border-radius: 24px; }
|
||
#profSavingsCard.locked .prof-lock-overlay { display: flex; }
|
||
.prof-lock-ico { width: 38px; height: 38px; border-radius: 50%; background: rgba(255,255,255,.92); display: flex; align-items: center; justify-content: center; font-size: 18px; box-shadow: 0 6px 14px rgba(0,0,0,.18); margin-bottom: 2px; }
|
||
.prof-lock-text { font-size: 14px; font-weight: 700; color: #fff; line-height: 1.35; text-shadow: 0 2px 4px rgba(160,50,0,.30); max-width: 240px; }
|
||
.prof-lock-cta { display: inline-flex; align-items: center; gap: 4px; height: 34px; padding: 0 18px; background: #fff; border: none; border-radius: 999px; font-size: 14px; font-weight: 700; color: #FF5722; cursor: pointer; box-shadow: 0 6px 14px rgba(0,0,0,.18); margin-top: 2px; }
|
||
.prof-lock-cta .arr { font-size: 16px; line-height: 1; }
|
||
/* —— 去点餐选平台弹窗(移植自首页 home-picker)—— */
|
||
.home-picker-mask { display: none; position: absolute; inset: 0; z-index: 250; background: rgba(20,12,4,.5); backdrop-filter: blur(2px); -webkit-backdrop-filter: blur(2px); align-items: center; justify-content: center; padding: 24px; }
|
||
.home-picker-mask.show { display: flex; animation: homePickerFade .22s ease-out; }
|
||
@keyframes homePickerFade { from { opacity: 0; } to { opacity: 1; } }
|
||
.home-picker-modal { width: 100%; max-width: 304px; background: linear-gradient(180deg, #FFFAF0 0%, #FFFFFF 70%); border-radius: 24px; padding: 22px 18px 20px; box-shadow: 0 24px 60px rgba(120,80,30,.28), 0 2px 8px rgba(0,0,0,.06), inset 0 1px 0 rgba(255,255,255,.85); border: 1px solid rgba(255,220,120,.4); animation: homePickerIn .35s cubic-bezier(.22,1,.36,1); position: relative; overflow: hidden; }
|
||
.home-picker-modal::before { content: ''; position: absolute; top: -60px; left: 50%; transform: translateX(-50%); width: 220px; height: 120px; background: radial-gradient(ellipse at center, rgba(255,214,0,.25), transparent 65%); pointer-events: none; }
|
||
@keyframes homePickerIn { from { opacity: 0; transform: scale(.86) translateY(-6px); } to { opacity: 1; transform: scale(1) translateY(0); } }
|
||
.home-picker-close { position: absolute; top: 12px; right: 12px; width: 28px; height: 28px; border-radius: 14px; background: rgba(0,0,0,.06); display: flex; align-items: center; justify-content: center; font-size: 13px; color: #4D4D4D; cursor: pointer; font-weight: 700; z-index: 2; }
|
||
.home-picker-emoji { width: 38px; height: 38px; margin: 0 auto 6px; border-radius: 12px; background: linear-gradient(135deg, #FFE066 0%, #FFB300 100%); box-shadow: 0 4px 10px rgba(255,160,0,.35), inset 0 1px 0 rgba(255,255,255,.6); display: flex; align-items: center; justify-content: center; font-size: 20px; position: relative; }
|
||
.home-picker-title { font-size: 18px; font-weight: 900; color: #1a1a1a; text-align: center; letter-spacing: .3px; margin-bottom: 4px; position: relative; }
|
||
.home-picker-sub { font-size: 12px; color: #4D4D4D; text-align: center; margin-bottom: 18px; line-height: 1.5; position: relative; }
|
||
.home-picker-sub strong { color: #FF5722; font-weight: 800; }
|
||
.home-picker-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; position: relative; }
|
||
.home-picker-item { position: relative; background: linear-gradient(180deg, #FFFFFF 0%, #FFFDF5 100%); border: 1.5px solid #F2EBD8; border-radius: 14px; padding: 14px 6px 12px; text-align: center; cursor: pointer; transition: transform .15s, border-color .15s, box-shadow .15s; -webkit-tap-highlight-color: transparent; box-shadow: 0 2px 6px rgba(120,80,20,.05); }
|
||
.home-picker-item:active { transform: scale(.94); border-color: #FFD600; box-shadow: 0 4px 14px rgba(255,179,0,.25); }
|
||
.home-picker-item .home-picker-logo { width: 46px; height: 46px; border-radius: 12px; margin: 0 auto 8px; overflow: hidden; box-shadow: 0 2px 8px rgba(0,0,0,.08); }
|
||
.home-picker-item .home-picker-logo img { width: 100%; height: 100%; object-fit: cover; }
|
||
.home-picker-item .home-picker-name { font-size: 12px; font-weight: 700; color: #1a1a1a; line-height: 1.2; letter-spacing: .2px; }
|
||
.home-picker-item.uninstalled { background: #FAFAFA; border-color: #ECECEC; box-shadow: none; }
|
||
.home-picker-item.uninstalled .home-picker-logo { box-shadow: 0 1px 3px rgba(0,0,0,.04); }
|
||
.home-picker-item.uninstalled .home-picker-logo img { filter: grayscale(.7); opacity: .55; }
|
||
.home-picker-item.uninstalled .home-picker-name { color: #BBB; }
|
||
.home-picker-install-chip { position: absolute; top: 6px; right: 6px; width: 18px; height: 18px; border-radius: 50%; background: #FFD600; box-shadow: 0 0 0 1.5px rgba(255,179,0,.35); display: flex; align-items: center; justify-content: center; }
|
||
/* —— 省钱战绩卡 —— */
|
||
.prof-card { background: rgba(255,255,255,.96); border-radius: 18px; padding: 12px 12px; margin-top: 12px; box-shadow: 0 6px 18px rgba(151,93,35,.08); border: 1px solid rgba(255,255,255,.82); }
|
||
.prof-achv-title { display: flex; align-items: center; gap: 6px; font-size: 16px; font-weight: 600; color: #1A1A1A; margin-bottom: 12px; letter-spacing: 0; }
|
||
.prof-achv-title .prof-trophy { width: 23px; height: 23px; display: inline-flex; align-items: center; justify-content: center; background: transparent; border-radius: 0; font-size: 20px; filter: drop-shadow(0 3px 5px rgba(255,133,0,.22)); }
|
||
.prof-achv-title .prof-spark { color: #FFEB3B; font-size: 14px; margin-left: 2px; }
|
||
.prof-achv-row { display: flex; align-items: stretch; gap: 0; }
|
||
.prof-achv-item { position: relative; flex: 1; display: flex; align-items: flex-start; justify-content: center; gap: 0; min-width: 0; padding: 0 8px; text-align: center; }
|
||
.prof-achv-item > div { display: grid; grid-template-rows: 17px 23px 14px; justify-items: center; align-items: center; }
|
||
.prof-achv-item::after { content: ''; position: absolute; right: 0; top: 3px; bottom: 3px; width: 1px; background: #F0F0F0; }
|
||
.prof-achv-item:last-child::after { display: none; }
|
||
.prof-achv-ico { width: 34px; height: 34px; border-radius: 18px; flex-shrink: 0; display: flex; align-items: center; justify-content: center; }
|
||
.prof-achv-ico.ico-orange { background: linear-gradient(180deg,#FFF3C4 0%,#FFE066 100%); }
|
||
.prof-achv-ico.ico-green { background: linear-gradient(180deg,#E8F5E9 0%,#CCCCCC 100%); }
|
||
.prof-achv-ico.ico-blue { background: linear-gradient(180deg,#E3F2FD 0%,#DDDDDD 100%); }
|
||
.prof-achv-ico svg { width: 19px; height: 19px; }
|
||
.prof-achv-item .prof-achv-key { font-size: 12px; color: #1A1A1A; font-weight: 500; line-height: 1.15; white-space: nowrap; }
|
||
.prof-achv-item .prof-achv-val { font-size: 18px; font-weight: 900; color: #FF5722; line-height: 1; margin-top: 0; font-variant-numeric: tabular-nums; }
|
||
.prof-achv-item .prof-achv-val span { font-size: 12px; font-weight: 500; color: #1A1A1A; margin-left: 2px; }
|
||
/* —— 菜单卡 —— */
|
||
.prof-menu-card { padding: 8px 12px; }
|
||
.prof-menu-item { display: flex; align-items: center; gap: 12px; padding: 6px 0; cursor: pointer; border-bottom: .5px solid #F0F0F0; }
|
||
.prof-menu-item:last-child { border-bottom: none; }
|
||
.prof-menu-ico { width: 34px; height: 34px; flex-shrink: 0; filter: drop-shadow(0 4px 6px rgba(49,99,180,.10)); }
|
||
.prof-report-ico { transform: scale(0.79); transform-origin: center center; }
|
||
.prof-menu-text { flex: 1; min-width: 0; }
|
||
.prof-menu-title { font-size: 14px; font-weight: 600; color: #1A1A1A; line-height: 1.2; }
|
||
.prof-report-title { position: relative; display: inline-flex; align-items: center; overflow: visible; }
|
||
.prof-report-badge { position: absolute; top: -7px; right: -34px; height: 14px; padding: 0 4px; background: #FF3D00; color: #fff; font-size: 8px; font-weight: 700; border-radius: 999px; display: inline-flex; align-items: center; justify-content: center; line-height: 1; white-space: nowrap; box-shadow: 0 1px 3px rgba(255,61,0,.25); }
|
||
.prof-menu-sub { font-size: 12px; color: #666666; margin-top: 2px; }
|
||
.prof-menu-right { display: inline-flex; align-items: center; gap: 6px; flex-shrink: 0; }
|
||
.prof-menu-dot { width: 6px; height: 6px; border-radius: 50%; background: #FF3D00; flex-shrink: 0; }
|
||
.prof-menu-arrow { width: 10px; height: 14px; display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; color: #999999; font-size: 0; line-height: 1; }
|
||
.prof-menu-arrow::before { content: ''; width: 7px; height: 7px; border-top: 2px solid currentColor; border-right: 2px solid currentColor; transform: rotate(45deg); }
|
||
/* —— 未登录 —— */
|
||
.prof-unlogged-hero { position: relative; padding: 64px 16px 24px; text-align: center; }
|
||
.prof-unlogged-hero .prof-avatar { margin: 0 auto 12px; background: linear-gradient(180deg,#F0F0F0 0%,#DDDDDD 100%); }
|
||
.prof-unlogged-cta { margin-top: 6px; background: linear-gradient(180deg,#FFD600 0%,#FFB300 100%); border: none; padding: 8px 24px; border-radius: 999px; font-size: 14px; font-weight: 700; color: #1a1a1a; cursor: pointer; box-shadow: 0 4px 12px rgba(255,180,52,.35); }
|
||
</style>
|
||
<div class="screen active" id="profile">
|
||
<div class="prof-statusbar">
|
||
<div class="prof-status-time">9:41</div>
|
||
<div class="prof-status-icons">
|
||
<span class="prof-cell"><i></i><i></i><i></i><i></i></span>
|
||
<span class="prof-wifi"><i></i></span>
|
||
<span class="prof-battery"><i></i></span>
|
||
</div>
|
||
</div>
|
||
<!-- 未登录态 -->
|
||
<div id="profileUnlogged" class="prof-scroll">
|
||
<div class="prof-hero prof-unlogged-hero">
|
||
<img class="prof-clouds" src="../../assets/profile/index/top-clouds.png" alt="">
|
||
<div class="prof-avatar"><svg viewBox="0 0 64 64" fill="none"><circle cx="32" cy="26" r="11" fill="#fff" opacity=".7"/><path d="M14 54c2-8 9-12 18-12s16 4 18 12" stroke="#fff" stroke-width="3" stroke-linecap="round" opacity=".8" fill="none"/></svg></div>
|
||
<div class="prof-name">未登录</div>
|
||
<div class="prof-phone" style="margin-bottom: 8px;">登录后查看你的省钱战绩</div>
|
||
<button class="prof-unlogged-cta" onclick="loginFrom='profile'; try{localStorage.setItem('proto_loginFrom','profile');}catch(e){}go('login');">立即登录</button>
|
||
</div>
|
||
<div class="prof-body-inner">
|
||
<div class="prof-card prof-menu-card" style="margin-top: 0;">
|
||
<div class="prof-menu-item" onclick="loginFrom='profile'; try{localStorage.setItem('proto_loginFrom','profile');}catch(e){}go('login');"><img src="../../assets/profile/index/lower-price-report-medal.png" class="prof-menu-ico prof-report-ico" alt=""><div class="prof-menu-text"><div class="prof-menu-title prof-report-title">上报更低价<span class="prof-report-badge">赚金币</span></div></div><span class="prof-menu-arrow">›</span></div>
|
||
<div class="prof-menu-item" onclick="loginFrom='profile'; try{localStorage.setItem('proto_loginFrom','profile');}catch(e){}go('login');"><img src="../../assets/profile/index/orders.svg" class="prof-menu-ico" alt=""><div class="prof-menu-text"><div class="prof-menu-title">比价记录</div></div><span class="prof-menu-arrow">›</span></div>
|
||
<div class="prof-menu-item" onclick="go('feedback')"><img src="../../assets/profile/index/help.png" class="prof-menu-ico" alt=""><div class="prof-menu-text"><div class="prof-menu-title">意见反馈</div></div><span class="prof-menu-arrow">›</span></div>
|
||
<div class="prof-menu-item" onclick="loginFrom='profile'; try{localStorage.setItem('proto_loginFrom','profile');}catch(e){}go('login');"><img src="../../assets/profile/index/settings.png" class="prof-menu-ico" alt=""><div class="prof-menu-text"><div class="prof-menu-title">设置</div></div><span class="prof-menu-arrow">›</span></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<!-- 已登录态 -->
|
||
<div id="profileLogged" class="prof-scroll" style="display: none;">
|
||
<div class="prof-hero">
|
||
<img class="prof-clouds" src="../../assets/profile/index/top-clouds.png" alt="">
|
||
<img class="prof-piggy" src="../../assets/profile/index/piggy-coins.png" alt="">
|
||
<div class="prof-id">
|
||
<div class="prof-avatar">
|
||
<svg viewBox="0 0 80 80" fill="none">
|
||
<defs>
|
||
<radialGradient id="profAvatarBg" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(31 24) rotate(58) scale(52)">
|
||
<stop offset="0" stop-color="#FFF5B5"/>
|
||
<stop offset=".58" stop-color="#FFD45F"/>
|
||
<stop offset="1" stop-color="#FFB43A"/>
|
||
</radialGradient>
|
||
<linearGradient id="profFace" x1="39" y1="25" x2="39" y2="55" gradientUnits="userSpaceOnUse">
|
||
<stop stop-color="#FFE0B0"/>
|
||
<stop offset="1" stop-color="#FFC783"/>
|
||
</linearGradient>
|
||
<linearGradient id="profHood" x1="40" y1="45" x2="40" y2="78" gradientUnits="userSpaceOnUse">
|
||
<stop stop-color="#FFD742"/>
|
||
<stop offset="1" stop-color="#FFA923"/>
|
||
</linearGradient>
|
||
</defs>
|
||
<circle cx="40" cy="40" r="40" fill="url(#profAvatarBg)"/>
|
||
<path d="M15 72c2.5-13 12.2-21 25-21s22.5 8 25 21H15z" fill="url(#profHood)"/>
|
||
<path d="M26 62c2.8 4.8 7.4 7.4 14 7.4 6.5 0 11.2-2.6 14-7.4-2.6-7.2-7.2-10.8-14-10.8S28.6 54.8 26 62z" fill="#FFE789" opacity=".8"/>
|
||
<path d="M20.5 37.5c0-13.2 8.3-22.2 20.3-22.2 11.7 0 19.7 8.8 19.7 22.1 0 2.4-.3 4.6-.8 6.8H21.3c-.5-2.2-.8-4.5-.8-6.7z" fill="#3B2416"/>
|
||
<path d="M23.5 36.3c.8-11.4 7.7-18 17.1-18 9.8 0 16.4 6.9 16.8 18.3-3.3-5.2-8.1-7.7-14.4-7.5-3.1.1-5.2 1.6-8 1.6-3.8 0-7.7 1.5-11.5 5.6z" fill="#5B3520"/>
|
||
<path d="M22.8 39.6c-2.9.1-5.2 2.5-5.1 5.7.1 3.1 2.4 5.3 5.5 5.4l.5-11.1h-.9z" fill="#FFC783"/>
|
||
<path d="M57.2 39.6c2.9.1 5.2 2.5 5.1 5.7-.1 3.1-2.4 5.3-5.5 5.4l-.5-11.1h.9z" fill="#FFC783"/>
|
||
<path d="M22.5 38.4c0-10.5 7.2-17.7 17.5-17.7s17.5 7.2 17.5 17.7v5.8c0 10.2-7.2 17.2-17.5 17.2s-17.5-7-17.5-17.2v-5.8z" fill="url(#profFace)"/>
|
||
<path d="M22.7 35.8c2.5-8.7 9.7-13.2 18-13.2 7.7 0 13.7 4.4 16.1 11.9-4.8-.3-8.5-2.5-11-6.5-3.2 4.7-10 7.8-23.1 7.8z" fill="#3B2416"/>
|
||
<circle cx="31.3" cy="42.5" r="2.1" fill="#3A2113"/>
|
||
<circle cx="48.7" cy="42.5" r="2.1" fill="#3A2113"/>
|
||
<circle cx="28.2" cy="48.4" r="3.2" fill="#FF916C" opacity=".54"/>
|
||
<circle cx="51.8" cy="48.4" r="3.2" fill="#FF916C" opacity=".54"/>
|
||
<path d="M35.8 50.8c2.7 2.1 5.7 2.1 8.4 0" stroke="#6B2C19" stroke-width="1.8" stroke-linecap="round"/>
|
||
<path d="M27 34.2c1.8-3.2 3.9-5.7 6.3-7.3-1.7 3.3-2.5 6.6-2.4 9.8-1.2-.8-2.5-1.6-3.9-2.5zM39.5 22c-4.1 1.7-7.2 4.1-9.4 7.3 5.8-.1 10.5-1.6 14-4.5L39.5 22z" fill="#2A170E"/>
|
||
<path d="M33 63.7c3.7 1.8 10.3 1.8 14 0" stroke="#FFF2B3" stroke-width="2.2" stroke-linecap="round" opacity=".75"/>
|
||
</svg>
|
||
</div>
|
||
<div class="prof-meta">
|
||
<div class="prof-name" id="profName" data-fullname="省钱小能手省钱小能手省钱小能手省钱小能手">省钱小能手省钱小能手省钱小能手省钱小能手</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="prof-body-inner">
|
||
<!-- 省钱战绩 -->
|
||
<div class="prof-savings-card" id="profSavingsCard">
|
||
<img class="prof-savings-deco" src="../../assets/profile/index/savings-bg.png" alt="">
|
||
<img class="prof-savings-coin" src="../../assets/profile/index/coin.png" alt="">
|
||
<div class="prof-savings-label">累计发现可省</div>
|
||
<div class="prof-amount-row">
|
||
<span class="prof-wheat left" aria-hidden="true"></span>
|
||
<span class="prof-amount"><span class="prof-currency">¥</span>1,287<span class="prof-cents">.50</span></span>
|
||
<span class="prof-wheat right" aria-hidden="true"></span>
|
||
</div>
|
||
<div class="prof-stats-row">
|
||
<div><div class="prof-stat-key">领取优惠券</div><div class="prof-stat-num">18<span class="prof-stat-unit">张</span></div></div>
|
||
<div class="prof-stats-div"></div>
|
||
<div><div class="prof-stat-key">完成比价</div><div class="prof-stat-num">23<span class="prof-stat-unit">次</span></div></div>
|
||
<div class="prof-stats-div"></div>
|
||
<div><div class="prof-stat-key">赚取金币</div><div class="prof-stat-num">580<span class="prof-stat-unit">个</span></div></div>
|
||
</div>
|
||
<!-- 未比价锁定态:不透明蒙层盖住示例数据,点「立即开始」弹去点餐选平台窗 -->
|
||
<div class="prof-lock-overlay">
|
||
<div class="prof-lock-ico">🔒</div>
|
||
<div class="prof-lock-text">完成首次比价<br>解锁你的专属省钱战绩</div>
|
||
<button class="prof-lock-cta" type="button" onclick="if(window.SGBridge){SGBridge.navigate('home')}else{openComparePicker()}">立即开始 <span class="arr">›</span></button>
|
||
</div>
|
||
</div>
|
||
<!-- 菜单 -->
|
||
<div class="prof-card prof-menu-card">
|
||
<div class="prof-menu-item" onclick="window.SGBridge&&SGBridge.navigate('reportFlow')"><img src="../../assets/profile/index/lower-price-report-medal.png" class="prof-menu-ico prof-report-ico" alt=""><div class="prof-menu-text"><div class="prof-menu-title prof-report-title">上报更低价<span class="prof-report-badge">赚金币</span></div></div><span class="prof-menu-arrow">›</span></div>
|
||
<div class="prof-menu-item" onclick="window.SGBridge&&SGBridge.navigate('compareRecords')"><img src="../../assets/profile/index/orders.svg" class="prof-menu-ico" alt=""><div class="prof-menu-text"><div class="prof-menu-title">比价记录</div></div><span class="prof-menu-arrow">›</span></div>
|
||
<div class="prof-menu-item" onclick="window.SGBridge&&SGBridge.navigate('feedback')"><img src="../../assets/profile/index/help.png" class="prof-menu-ico" alt=""><div class="prof-menu-text"><div class="prof-menu-title">意见反馈</div></div><span class="prof-menu-arrow">›</span></div>
|
||
<div class="prof-menu-item" onclick="window.SGBridge&&SGBridge.navigate('settings')"><img src="../../assets/profile/index/settings.png" class="prof-menu-ico" alt=""><div class="prof-menu-text"><div class="prof-menu-title">设置</div></div><span class="prof-menu-arrow">›</span></div>
|
||
</div>
|
||
</div>
|
||
</div><!-- end profileLogged -->
|
||
<div class="tab-bar">
|
||
<div class="tab-item" onclick="go('home')"><span class="tab-icon"><svg class="i-outline" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#1a1a1a" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 12l9-8 9 8"></path><path d="M5 10v9a1 1 0 001 1h3v-5h6v5h3a1 1 0 001-1v-9"></path></svg><svg class="i-filled" width="24" height="24" viewBox="0 0 24 24" fill="none"><path d="M3 12l9-8 9 8" stroke="#1a1a1a" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path><path d="M5 10v9a1 1 0 001 1h3v-5h6v5h3a1 1 0 001-1v-9" fill="#FFD600" stroke="#1a1a1a" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path></svg></span><span class="tab-label">首页</span></div>
|
||
<div class="tab-item" id="homeTabWelfare" onclick="go('welfare')"><span class="welfare-tab-dot" aria-hidden="true"></span><span class="tab-icon" id="homeTabWelfareIcon"><svg class="i-outline" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#1a1a1a" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="8" width="18" height="4" rx="1"></rect><path d="M12 8v12"></path><path d="M5 12v7a1 1 0 001 1h12a1 1 0 001-1v-7"></path><path d="M7.5 8C6 8 5 6.5 6 5.5S9 4 9.5 5.5c.4 1.2 2.5 2.5 2.5 2.5s2.1-1.3 2.5-2.5C15 4 17 4.5 18 5.5s-1 2.5-2.5 2.5"></path></svg><svg class="i-filled" width="24" height="24" viewBox="0 0 24 24" fill="none"><rect x="3" y="8" width="18" height="4" rx="1" fill="#FFD600" stroke="#1a1a1a" stroke-width="2"></rect><path d="M5 12v7a1 1 0 001 1h12a1 1 0 001-1v-7" fill="#FFD600" stroke="#1a1a1a" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path><path d="M12 8v12" stroke="#1a1a1a" stroke-width="2"></path><path d="M7.5 8C6 8 5 6.5 6 5.5S9 4 9.5 5.5c.4 1.2 2.5 2.5 2.5 2.5s2.1-1.3 2.5-2.5C15 4 17 4.5 18 5.5s-1 2.5-2.5 2.5" stroke="#1a1a1a" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path></svg></span><span class="tab-label">福利</span></div>
|
||
<div class="tab-item" onclick="go('history')"><span class="tab-icon"><svg class="i-outline" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#1a1a1a" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="4" y="4" width="16" height="16" rx="2.5"></rect><path d="M8 9h8"></path><path d="M8 13h8"></path><path d="M8 17h5"></path></svg><svg class="i-filled" width="24" height="24" viewBox="0 0 24 24" fill="none"><rect x="4" y="4" width="16" height="16" rx="2.5" fill="#FFD600" stroke="#1a1a1a" stroke-width="2"></rect><path d="M8 9h8" stroke="#1a1a1a" stroke-width="2" stroke-linecap="round"></path><path d="M8 13h8" stroke="#1a1a1a" stroke-width="2" stroke-linecap="round"></path><path d="M8 17h5" stroke="#1a1a1a" stroke-width="2" stroke-linecap="round"></path></svg></span><span class="tab-label">记录</span></div>
|
||
<div class="tab-item active" onclick="go('profile')"><span class="tab-icon"><svg class="i-outline" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#1a1a1a" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="8" r="4"></circle><path d="M4 20c0-4 4-6 8-6s8 2 8 6"></path></svg><svg class="i-filled" width="24" height="24" viewBox="0 0 24 24" fill="none"><circle cx="12" cy="8" r="4" fill="#FFD600" stroke="#1a1a1a" stroke-width="2"></circle><path d="M4 20c0-4 4-6 8-6s8 2 8 6" fill="#FFD600" stroke="#1a1a1a" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path></svg></span><span class="tab-label">我的</span></div>
|
||
</div>
|
||
<!-- 去点餐选平台弹窗(锁定态「立即开始」触发,移植自首页)-->
|
||
<div class="home-picker-mask" id="comparePickerMask">
|
||
<div class="home-picker-modal">
|
||
<div class="home-picker-close" onclick="closeComparePicker()">✕</div>
|
||
<div class="home-picker-emoji">🍱</div>
|
||
<div class="home-picker-title">请选择您常用的平台</div>
|
||
<div class="home-picker-sub">进入平台选好商品后,<strong>AI 一键替你比多家</strong></div>
|
||
<div class="home-picker-grid" id="comparePickerGrid"><!-- 动态渲染 --></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ===== INVITE FRIENDS ===== -->
|
||
<!-- screen #invite removed for split -->
|
||
|
||
<!-- ===== COMPARISON RESULT ===== -->
|
||
<!-- screen #compresult removed for split -->
|
||
|
||
<!-- ===== WITHDRAWAL / 提现(参考图二) ===== -->
|
||
<!-- screen #withdrawal removed for split -->
|
||
|
||
<div id="wechatBindSheet" class="wechat-bind-layer" aria-hidden="true">
|
||
<div class="wechat-bind-mask" onclick="closeWechatBindSheet()"></div>
|
||
<div class="wechat-bind-sheet" onclick="event.stopPropagation()">
|
||
<button class="wechat-bind-close" onclick="closeWechatBindSheet()" aria-label="关闭">×</button>
|
||
<div class="wechat-bind-amount-label">提现金额</div>
|
||
<div class="wechat-bind-amount"><span id="wechatBindAmount">0.3</span><small>元</small></div>
|
||
<div class="wechat-bind-card">
|
||
<span class="wechat-bind-card-logo" aria-hidden="true">
|
||
<svg viewBox="0 0 32 32" fill="none" aria-hidden="true">
|
||
<path d="M13.7 7.2C8 7.2 3.5 10.8 3.5 15.3c0 2.6 1.5 4.9 3.8 6.4l-.9 2.9 3.3-1.7c1.2.3 2.5.5 4 .5 5.6 0 10.2-3.6 10.2-8.1S19.3 7.2 13.7 7.2Z" fill="#fff"/>
|
||
<path d="M21 13.2c4.3.5 7.5 3.4 7.5 7 0 2.2-1.2 4.1-3.2 5.4l.7 2.4-2.8-1.5c-.9.2-1.9.4-3 .4-3.9 0-7.2-2.1-8.2-5.1.6.1 1.2.2 1.8.2 6.2 0 11.2-4 11.2-8.9v-.2Z" fill="#fff" opacity=".86"/>
|
||
<circle cx="10.1" cy="13.8" r="1" fill="#07C160"/>
|
||
<circle cx="16.7" cy="13.8" r="1" fill="#07C160"/>
|
||
</svg>
|
||
</span>
|
||
<div>
|
||
<div class="wechat-bind-card-title">暂未绑定微信账户</div>
|
||
<div class="wechat-bind-card-sub">绑定后才可提现,可以更换和解绑</div>
|
||
</div>
|
||
</div>
|
||
<button class="wechat-bind-cta" onclick="showPrototypeToast('原型演示:跳转微信授权绑定')">去微信绑定并提现</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ===== COIN HISTORY / 收益明细 ===== -->
|
||
<!-- screen #coinhistory removed for split -->
|
||
|
||
<div id="exchangeSheet" class="exchange-layer" aria-hidden="true">
|
||
<div class="exchange-mask" onclick="closeExchangeSheet()"></div>
|
||
<div class="exchange-sheet" onclick="event.stopPropagation()">
|
||
<button class="exchange-close" onclick="closeExchangeSheet()" aria-label="关闭">×</button>
|
||
<div class="exchange-title">金币兑换现金</div>
|
||
<div class="exchange-balance">金币余额:<strong id="exchangeBalanceText">28,967</strong></div>
|
||
<div class="exchange-convert-card">
|
||
<div class="exchange-coin-side">
|
||
<span class="exchange-coin-icon">¥</span>
|
||
<span class="exchange-coin-num" id="exchangeCoinAmount">28,967</span>
|
||
</div>
|
||
<div class="exchange-cash-num">= <span id="exchangeCashAmount">2.89</span><small>元</small></div>
|
||
</div>
|
||
<div class="exchange-presets">
|
||
<button class="exchange-preset" onclick="selectExchangeAmount(1000, this)">1000</button>
|
||
<button class="exchange-preset" onclick="selectExchangeAmount(2000, this)">2000</button>
|
||
<button class="exchange-preset" onclick="selectExchangeAmount(3000, this)">3000</button>
|
||
<button class="exchange-preset active" id="exchangePresetAll" onclick="selectExchangeAmount('all', this)">全部兑换</button>
|
||
</div>
|
||
<div class="exchange-error" id="exchangeError"></div>
|
||
<div class="exchange-rule">最低 100 金币,不足 100 的金币将原路返回</div>
|
||
<button class="exchange-submit" onclick="confirmExchange()">立即兑换</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ===== PURCHASE RECORDS ===== -->
|
||
<!-- screen #records removed for split -->
|
||
|
||
<!-- ===== SETTINGS ===== -->
|
||
<!-- screen #settings removed for split -->
|
||
|
||
<!-- 退出登录确认弹窗 -->
|
||
<div id="logoutConfirm" style="display: none;position: absolute;top: 0;left: 0;right: 0;bottom: 0;z-index: 260;background: rgba(0,0,0,.45);align-items: center;justify-content: center;padding: 40px 32px;overflow: hidden;">
|
||
<div style="background: #fff;border-radius: 18px;max-width: 295px;width: 100%;padding: 24px 24px 16px;text-align: center;">
|
||
<div style="font-size: 18px;font-weight: 700;color: var(--gray-900);margin-bottom: 8px;">退出登录</div>
|
||
<div style="font-size: 14px;color: var(--gray-500);line-height: 22px;margin-bottom: 24px;">退出后将无法继续累积金币收益</div>
|
||
<div style="display: flex;gap: 12px;">
|
||
<button onclick="closeLogoutConfirm()" style="flex: 1;padding: 12px;border-radius: 12px;border: 1px solid var(--gray-300);background: #fff;font-size: 15px;font-weight: 600;color: var(--gray-700);cursor: pointer;">取消</button>
|
||
<button onclick="doLogout()" style="flex: 1;padding: 12px;border-radius: 12px;border: none;background: var(--error);font-size: 15px;font-weight: 600;color: #fff;cursor: pointer;">确认退出</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 注销账号确认弹窗 -->
|
||
<div id="deleteConfirm" style="display: none;position: absolute;top: 0;left: 0;right: 0;bottom: 0;z-index: 260;background: rgba(0,0,0,.45);align-items: center;justify-content: center;padding: 40px 32px;overflow: hidden;">
|
||
<div style="background: #fff;border-radius: 18px;max-width: 295px;width: 100%;padding: 24px 24px 16px;text-align: center;">
|
||
<div style="font-size: 48px;margin-bottom: 12px;">⚠️</div>
|
||
<div style="font-size: 18px;font-weight: 700;color: var(--error);margin-bottom: 8px;">确认注销账号?</div>
|
||
<div style="font-size: 14px;color: var(--gray-500);line-height: 22px;margin-bottom: 8px;">注销后以下数据将<span style="color: var(--error);font-weight: 600;">永久删除且无法恢复</span>:</div>
|
||
<div style="text-align: left;background: var(--gray-50);border-radius: 8px;padding: 12px 16px;margin-bottom: 24px;font-size: 13px;color: var(--gray-600);line-height: 22px;">
|
||
· 全部金币余额和现金收益<br>
|
||
· 比价记录和购买战绩<br>
|
||
· 邀请好友关系和返佣收益
|
||
</div>
|
||
<div style="display: flex;gap: 12px;">
|
||
<button onclick="closeDeleteConfirm()" style="flex: 1;padding: 12px;border-radius: 12px;border: 1px solid var(--gray-300);background: #fff;font-size: 15px;font-weight: 600;color: var(--gray-700);cursor: pointer;">我再想想</button>
|
||
<button onclick="doDeleteAccount()" style="flex: 1;padding: 12px;border-radius: 12px;border: none;background: var(--error);font-size: 15px;font-weight: 600;color: #fff;cursor: pointer;">确认注销</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ===== FEEDBACK ===== -->
|
||
<!-- screen #feedback removed for split -->
|
||
|
||
<!-- ===== 领券流程屏(与新手引导同款,复用 demoSteps 的前 6 步:弹窗 → agentFlow → 完成 toast) ===== -->
|
||
<!-- screen #comparing removed for split -->
|
||
|
||
<!-- ===== 一键领券 · 完成 toast(提到 device 级别,让结算弹窗显示在首页背景上而非 agent 流的截图上) ===== -->
|
||
<div id="demoCouponDoneToast" style="display: none;position: absolute;inset: 0;z-index: 200;">
|
||
<div class="coupon-done-k-mask"></div>
|
||
<div class="coupon-done-k">
|
||
<div class="coupon-done-logo">
|
||
<span class="logo-mark">
|
||
<span style="font-size: 12px;font-weight: 900;color: #1a1a1a;line-height: 1.05;text-align: center;letter-spacing: 0;">傻瓜<br>比价</span>
|
||
</span>
|
||
</div>
|
||
<div class="v6-sparkle s1"></div>
|
||
<div class="v6-sparkle s2"></div>
|
||
<div class="v6-sparkle s3"></div>
|
||
<div class="v6-sparkle s4"></div>
|
||
<div class="v6-head">
|
||
<div class="lead-line lead-line-inline">今日已从<span class="lg-inline"><img src="../../assets/shared/logos/meituan.png" alt=""></span><span class="lg-inline"><img src="../../assets/shared/logos/taobao.png" alt=""></span>帮您领取</div>
|
||
<div class="num-line"><span class="rest" style="margin-right: 6px;">共</span><span class="num" id="demoCouponDoneCount">0</span><span class="rest">张优惠券</span></div>
|
||
</div>
|
||
<div class="v6-pocket">
|
||
<div class="v6-pocket-notch"></div>
|
||
<div class="v6-expiry">
|
||
<span class="time-box" id="cdH">23</span>:<span class="time-box" id="cdM">58</span>:<span class="time-box" id="cdS">27</span> 后失效
|
||
</div>
|
||
<button class="v6-cta" onclick="demoNext()">开心收下,立即使用</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ===== 签到弹窗 ===== -->
|
||
<style>
|
||
@keyframes checkinPopIn { 0%{transform: translateY(18px) scale(.96);opacity: 0;} 100%{transform: translateY(0) scale(1);opacity: 1;} }
|
||
.checkin-popup-layer {
|
||
display: none;
|
||
position: absolute;
|
||
inset: 0;
|
||
z-index: 200;
|
||
background: rgba(0,0,0,.55);
|
||
backdrop-filter: blur(1px);
|
||
align-items: center;
|
||
justify-content: center;
|
||
padding: 0 16px;
|
||
overflow: hidden;
|
||
}
|
||
.checkin-popup-card {
|
||
width: 100%;
|
||
border-radius: 18px;
|
||
padding: 16px 12px 12px;
|
||
background: linear-gradient(180deg, #FFE0B2 0%, #FFFDE7 30%, #FFFFFF 72%);
|
||
box-shadow: 0 20px 40px rgba(0,0,0,.12);
|
||
position: relative;
|
||
overflow: visible;
|
||
animation: checkinPopIn .26s cubic-bezier(.22,1,.36,1);
|
||
}
|
||
.checkin-close {
|
||
position: absolute;
|
||
left: 50%;
|
||
bottom: -52px;
|
||
width: 34px;
|
||
height: 34px;
|
||
transform: translateX(-50%);
|
||
border: none;
|
||
border-radius: 50%;
|
||
background: rgba(255,255,255,.58);
|
||
color: rgba(0,0,0,.46);
|
||
box-shadow: 0 6px 18px rgba(0,0,0,.08);
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
font-size: 22px;
|
||
line-height: 1;
|
||
cursor: pointer;
|
||
z-index: 4;
|
||
}
|
||
.checkin-banner {
|
||
position: relative;
|
||
z-index: 2;
|
||
width: 206px;
|
||
height: 16px;
|
||
margin: -4px auto 8px;
|
||
border-radius: 999px;
|
||
background: rgba(255,255,255,.92);
|
||
box-shadow: 0 4px 14px rgba(255,174,0,.14);
|
||
border: 1px solid rgba(255,184,0,.24);
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
gap: 4px;
|
||
color: #7A4F00;
|
||
font-size: 10px;
|
||
font-weight: 600;
|
||
white-space: nowrap;
|
||
}
|
||
.checkin-banner .star {
|
||
width: 9px;
|
||
height: 9px;
|
||
background: #FFB300;
|
||
clip-path: polygon(50% 0%, 62% 37%, 100% 50%, 62% 63%, 50% 100%, 38% 63%, 0% 50%, 38% 37%);
|
||
flex-shrink: 0;
|
||
}
|
||
.checkin-title {
|
||
position: relative;
|
||
z-index: 2;
|
||
margin: 0;
|
||
text-align: center;
|
||
color: #1A1A1A;
|
||
font-size: 20px;
|
||
line-height: 1.1;
|
||
font-weight: 900;
|
||
letter-spacing: 0;
|
||
}
|
||
.checkin-sub {
|
||
position: relative;
|
||
z-index: 2;
|
||
margin-top: 8px;
|
||
text-align: center;
|
||
color: #666;
|
||
font-size: 11px;
|
||
line-height: 1.2;
|
||
font-weight: 500;
|
||
white-space: nowrap;
|
||
}
|
||
.checkin-sub b {
|
||
color: #FF6A00;
|
||
font-weight: 600;
|
||
}
|
||
.checkin-rewards {
|
||
position: relative;
|
||
z-index: 2;
|
||
margin-top: 12px;
|
||
display: grid;
|
||
grid-template-columns: repeat(5, 1fr);
|
||
gap: 6px;
|
||
}
|
||
.checkin-reward-card {
|
||
position: relative;
|
||
min-height: 64px;
|
||
border-radius: 8px;
|
||
background: rgba(255,255,255,.88);
|
||
border: 1px solid #F0F0F0;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content: center;
|
||
gap: 6px;
|
||
padding: 8px 2px 6px;
|
||
color: #1A1A1A;
|
||
font-weight: 600;
|
||
box-shadow: inset 0 1px 0 rgba(255,255,255,.75);
|
||
}
|
||
.checkin-reward-card.claimed {
|
||
background: rgba(247,247,247,.96);
|
||
border-color: #E5E5E5;
|
||
box-shadow: none;
|
||
color: #999999;
|
||
}
|
||
.checkin-reward-card.current {
|
||
border-color: #FFB300;
|
||
box-shadow: 0 8px 15px rgba(255,184,0,.14);
|
||
background: rgba(255,255,255,.96);
|
||
}
|
||
.checkin-reward-icon {
|
||
min-height: 26px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
color: #999999;
|
||
font-size: 10px;
|
||
line-height: 1;
|
||
font-weight: 850;
|
||
white-space: nowrap;
|
||
}
|
||
.checkin-reward-card img {
|
||
width: 29px;
|
||
height: 29px;
|
||
object-fit: contain;
|
||
display: block;
|
||
}
|
||
.checkin-reward-card .icon-chest {
|
||
width: 36px;
|
||
height: 33px;
|
||
}
|
||
.checkin-reward-amount {
|
||
color: #1A1A1A;
|
||
font-size: 12px;
|
||
line-height: 1;
|
||
font-weight: 850;
|
||
}
|
||
.checkin-reward-card.claimed .checkin-reward-amount {
|
||
color: #999999;
|
||
}
|
||
.checkin-progress {
|
||
margin: 12px 0 0;
|
||
position: relative;
|
||
height: 42px;
|
||
display: grid;
|
||
grid-template-columns: repeat(5, 1fr);
|
||
gap: 6px;
|
||
align-items: start;
|
||
}
|
||
.checkin-progress-lines {
|
||
position: absolute;
|
||
top: 4.5px;
|
||
left: 0;
|
||
right: 0;
|
||
height: 3px;
|
||
pointer-events: none;
|
||
z-index: 0;
|
||
}
|
||
.checkin-segment {
|
||
position: absolute;
|
||
top: 0;
|
||
height: 3px;
|
||
border-radius: 32px;
|
||
}
|
||
.checkin-segment.solid {
|
||
background: var(--line-color);
|
||
}
|
||
.checkin-segment.dashed {
|
||
background-repeat: no-repeat;
|
||
}
|
||
.checkin-node {
|
||
position: relative;
|
||
z-index: 1;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
gap: 8px;
|
||
color: #666;
|
||
font-size: 10px;
|
||
line-height: 1;
|
||
white-space: nowrap;
|
||
}
|
||
.checkin-dot {
|
||
box-sizing: border-box;
|
||
width: 12px;
|
||
height: 12px;
|
||
border-radius: 50%;
|
||
background: #FFFFFF;
|
||
border: 2px solid #DDDDDD;
|
||
}
|
||
.checkin-node.done .checkin-dot {
|
||
background: #FFB300;
|
||
border-color: #FFB300;
|
||
}
|
||
.checkin-node.current .checkin-dot {
|
||
background: #FFFFFF;
|
||
border: 2.5px solid #FFB300;
|
||
}
|
||
.checkin-popup-cta {
|
||
position: relative;
|
||
z-index: 2;
|
||
margin: 8px auto 0;
|
||
width: 252px;
|
||
height: 40px;
|
||
border: none;
|
||
border-radius: 24px;
|
||
background: linear-gradient(180deg, #FFE066 0%, #FFB300 100%);
|
||
color: #1A1A1A;
|
||
font-size: 17px;
|
||
font-weight: 900;
|
||
box-shadow: 0 14px 28px rgba(255,184,0,.22);
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
gap: 4px;
|
||
cursor: pointer;
|
||
font-family: inherit;
|
||
}
|
||
.checkin-popup-cta img {
|
||
width: 18px;
|
||
height: 18px;
|
||
object-fit: contain;
|
||
display: block;
|
||
}
|
||
.checkin-popup-cta b {
|
||
color: #FF6A00;
|
||
font-size: 22px;
|
||
line-height: 1;
|
||
}
|
||
</style>
|
||
<div id="checkinPopup" class="checkin-popup-layer">
|
||
<div class="checkin-popup-card" onclick="event.stopPropagation()">
|
||
<button class="checkin-close" onclick="closeCheckinPopup()" aria-label="关闭">×</button>
|
||
<div class="checkin-banner" id="checkinBanner"><span class="star"></span>连续签到14天 最高可领2888金币</div>
|
||
<h2 class="checkin-title" id="checkinPopupTitle">签到领取今日金币</h2>
|
||
<div class="checkin-sub" id="checkinPopupSub">已连续签到 <b>2</b> 天,今天可领 <b>220</b> 金币</div>
|
||
|
||
<div class="checkin-rewards" id="checkinRewards" aria-label="连续签到奖励">
|
||
<div class="checkin-reward-card claimed">
|
||
<div class="checkin-reward-icon">已领取</div>
|
||
<div class="checkin-reward-amount">180</div>
|
||
</div>
|
||
<div class="checkin-reward-card claimed">
|
||
<div class="checkin-reward-icon">已领取</div>
|
||
<div class="checkin-reward-amount">380</div>
|
||
</div>
|
||
<div class="checkin-reward-card current">
|
||
<div class="checkin-reward-icon"><img src="../../assets/welfare/index/checkin-coin-single.png" alt=""></div>
|
||
<div class="checkin-reward-amount">220</div>
|
||
</div>
|
||
<div class="checkin-reward-card">
|
||
<div class="checkin-reward-icon"><img src="../../assets/welfare/index/checkin-coin-single.png" alt=""></div>
|
||
<div class="checkin-reward-amount">260</div>
|
||
</div>
|
||
<div class="checkin-reward-card">
|
||
<div class="checkin-reward-icon"><img src="../../assets/welfare/index/checkin-coins-600.png" alt=""></div>
|
||
<div class="checkin-reward-amount">888</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="checkin-progress" id="checkinProgress" aria-label="签到进度">
|
||
<div class="checkin-progress-lines" id="checkinProgressLines"></div>
|
||
<div class="checkin-node done" data-day="1"><span class="checkin-dot"></span><span>第1天</span></div>
|
||
<div class="checkin-node done" data-day="2"><span class="checkin-dot"></span><span>第2天</span></div>
|
||
<div class="checkin-node current" data-day="3"><span class="checkin-dot"></span><span>今天</span></div>
|
||
<div class="checkin-node" data-day="4"><span class="checkin-dot"></span><span>明天</span></div>
|
||
<div class="checkin-node" data-day="7"><span class="checkin-dot"></span><span>第7天</span></div>
|
||
</div>
|
||
|
||
<button id="checkinBtn" class="checkin-popup-cta" onclick="doCheckin()">签到领 <img src="../../assets/welfare/index/checkin-coin-single.png" alt=""><b>220</b></button>
|
||
<button id="checkinReminderBtn" class="checkin-popup-cta" onclick="doCheckinReminder()" style="display: none;">打开签到提醒</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ===== 签到提醒权限弹窗 ===== -->
|
||
<div id="calendarPermPopup" style="display: none;position: absolute;top: 0;left: 0;right: 0;bottom: 0;z-index: 250;background: rgba(0,0,0,.55);align-items: center;justify-content: center;padding: 40px 24px;overflow: hidden;">
|
||
<div style="background: #fff;border-radius: 18px;max-width: 327px;width: 100%;padding: 24px 24px;position: relative;">
|
||
<div onclick="closeCalendarPerm()" style="position: absolute;top: 14px;right: 14px;width: 28px;height: 28px;border-radius: 14px;background: var(--gray-100);display: flex;align-items: center;justify-content: center;cursor: pointer;font-size: 14px;color: var(--gray-500);">✕</div>
|
||
<div style="text-align: center;">
|
||
<div style="font-size: 20px;font-weight: 700;color: var(--gray-900);margin-bottom: 8px;">日历权限未开启</div>
|
||
<div style="font-size: 14px;color: var(--gray-500);line-height: 1.6;">开启提醒失败,请前往设置-傻瓜比价打开日历权限后重试</div>
|
||
</div>
|
||
<button onclick="closeCalendarPerm()" style="width: 100%;margin-top: 16px;background: linear-gradient(180deg,#FFE066 0%,#FFC400 100%);color: #1A1A1A;border: none;padding: 12px;border-radius: 24px;font-size: 17px;font-weight: 700;cursor: pointer;box-shadow: inset 0 1px 0 rgba(255,255,255,.7), 0 2px 6px rgba(255,179,0,.35);">去开启</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 页面导航提示 -->
|
||
|
||
<!-- ===== 全部权限开启完成 · 祝贺弹窗(A/B/C 内容动态注入) ===== -->
|
||
<div id="celebrationModal" onclick="closeCelebrationModal()" style="display: none;position: absolute;top: 0;left: 0;right: 0;bottom: 0;z-index: 260;background: rgba(0,0,0,.55);align-items: center;justify-content: center;padding: 0 24px;overflow: hidden;">
|
||
<div onclick="event.stopPropagation()" id="celebrationModalCard" style="background: #fff;border-radius: 24px;width: 100%;max-width: 327px;padding: 24px 24px 24px;position: relative;animation: safetyPopIn .3s cubic-bezier(.22,1,.36,1);"></div>
|
||
</div>
|
||
|
||
<!-- ===== 权限未开启提示弹窗(居中卡片式,复用于无障碍/悬浮窗) ===== -->
|
||
<div id="safetyModal" onclick="closeSafetyModal()" style="display: none;position: absolute;top: 0;left: 0;right: 0;bottom: 0;z-index: 250;background: rgba(0,0,0,.55);align-items: center;justify-content: center;padding: 0 24px;overflow: hidden;">
|
||
<div onclick="event.stopPropagation()" style="background: #fff;border-radius: 24px;width: 100%;max-width: 327px;padding: 24px 24px 24px;position: relative;animation: safetyPopIn .3s cubic-bezier(.22,1,.36,1);">
|
||
<!-- 关闭按钮 -->
|
||
<button onclick="closeSafetyModal()" aria-label="关闭" style="position: absolute;top: 14px;right: 14px;width: 28px;height: 28px;border-radius: 14px;background: #f0f0f0;border: none;cursor: pointer;font-size: 16px;line-height: 1;color: #666;display: flex;align-items: center;justify-content: center;padding: 0;z-index: 2;">×</button>
|
||
<!-- 警示图标 -->
|
||
<div style="width: 60px;height: 60px;border-radius: 32px;background: #FFF3E0;display: flex;align-items: center;justify-content: center;margin: 0 auto 12px;font-size: 28px;">⚠️</div>
|
||
<!-- 标题 -->
|
||
<div id="safetyModalTitle" style="font-size: 20px;font-weight: 800;color: var(--gray-900);text-align: center;margin-bottom: 8px;">比价功能未开启</div>
|
||
<div style="font-size: 13px; color: rgb(0, 0, 0); line-height: 20px; text-align: center; margin-bottom: 16px; white-space: nowrap;">
|
||
<span id="safetyModalBody">在「已安装的应用」中找到「傻瓜比价」并开启</span><span id="safetyModalPermName" style="display: none;">无障碍</span>
|
||
</div>
|
||
<!-- 安全承诺区(压缩版) -->
|
||
<div id="safetyPromiseBlock" style="background: var(--gray-100);border-radius: 14px;padding: 12px 12px 12px;margin-bottom: 16px;">
|
||
<div style="font-size: 14px;font-weight: 700;color: var(--gray-700);margin-bottom: 8px;">我们的安全承诺</div>
|
||
<ul style="list-style: disc;padding-left: 16px;margin: 0;font-size: 12px;color: var(--gray-500);line-height: 19px;">
|
||
<li style="margin-bottom: 6px;">仅在您开启比价时启用,用完即停</li>
|
||
<li style="margin-bottom: 6px;">全程端侧加密,全方位守护您的隐私</li>
|
||
<li>您随时可在设置中关闭</li>
|
||
</ul>
|
||
</div>
|
||
<!-- 底部按钮 -->
|
||
<button class="btn btn-primary btn-lg" style="border-radius: 24px;font-size: 16px;height: 48px;" onclick="goToPermFromSafetyModal()">继续开启</button>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
<!-- ===== 反馈底部半屏面板 ===== -->
|
||
<style>
|
||
@keyframes sheetUp { from { transform: translateY(100%); } to { transform: translateY(0); } }
|
||
.feedback-sheet { animation: sheetUp .3s ease-out; }
|
||
.fb-platform.selected { border-color: #FF5722 !important; background: #FFF3E0; color: #FF5722; }
|
||
</style>
|
||
<div id="feedbackSheet" style="display: none;position: absolute;top: 0;left: 0;right: 0;bottom: 0;z-index: 260;overflow: hidden;">
|
||
<!-- 遮罩 -->
|
||
<div onclick="closeFeedbackSheet()" style="position: absolute;inset: 0;background: rgba(0,0,0,.4);"></div>
|
||
<!-- 面板 -->
|
||
<div class="feedback-sheet" style="position: absolute;bottom: 0;left: 0;right: 0;background: #fff;border-radius: 18px 18px 0 0;max-height: 75%;overflow-y: auto;">
|
||
<!-- 拖动条 -->
|
||
<div style="padding: 12px 0 0;text-align: center;"><div style="width: 40px;height: 4px;border-radius: 4px;background: var(--gray-300);margin: 0 auto;"></div></div>
|
||
<!-- 标题 -->
|
||
<div style="padding: 16px 16px 12px;">
|
||
<div style="font-size: 18px;font-weight: 700;">比价结果反馈</div>
|
||
<div style="font-size: 13px;color: var(--gray-500);margin-top: 4px;">审核通过可获得 <span style="color: #FF5722;font-weight: 600;">2,000 金币</span> 奖励</div>
|
||
</div>
|
||
<!-- 步骤1:选择反馈类型 -->
|
||
<div id="fbStep1" style="padding: 0 16px 16px;">
|
||
<div style="font-size: 14px;font-weight: 600;color: var(--gray-700);margin-bottom: 12px;">选择反馈类型</div>
|
||
<div onclick="selectFbType('lower_price')" style="display: flex;align-items: center;gap: 12px;padding: 16px;border: 1.5px solid var(--gray-200);border-radius: 14px;cursor: pointer;margin-bottom: 8px;transition: all .15s;" id="fbTypeLower">
|
||
<div style="width: 44px;height: 44px;border-radius: 12px;background: linear-gradient(135deg,#FFF3E0,#FFE0B2);display: flex;align-items: center;justify-content: center;font-size: 22px;flex-shrink: 0;">💰</div>
|
||
<div><div style="font-size: 15px;font-weight: 600;">我发现了更低价格</div><div style="font-size: 12px;color: var(--gray-500);margin-top: 2px;">在其他平台找到了同款更便宜的</div></div>
|
||
<span style="margin-left: auto;font-size: 18px;color: var(--gray-400);">›</span>
|
||
</div>
|
||
<div onclick="selectFbType('wrong_match')" style="display: flex;align-items: center;gap: 12px;padding: 16px;border: 1.5px solid var(--gray-200);border-radius: 14px;cursor: pointer;transition: all .15s;" id="fbTypeWrong">
|
||
<div style="width: 44px;height: 44px;border-radius: 12px;background: linear-gradient(135deg,#E3F2FD,#E3F2FD);display: flex;align-items: center;justify-content: center;font-size: 22px;flex-shrink: 0;">❌</div>
|
||
<div><div style="font-size: 15px;font-weight: 600;">外卖不是同一家</div><div style="font-size: 12px;color: var(--gray-500);margin-top: 2px;">比价结果中有外卖匹配错误</div></div>
|
||
<span style="margin-left: auto;font-size: 18px;color: var(--gray-400);">›</span>
|
||
</div>
|
||
</div>
|
||
<!-- 步骤2A:更低价格表单 -->
|
||
<div id="fbFormLower" style="display: none;padding: 0 16px 24px;">
|
||
<div style="display: flex;align-items: center;gap: 8px;margin-bottom: 16px;">
|
||
<button class="btn-back" onclick="backToFbStep1()" aria-label="返回上一步"><svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M15 6L9 12L15 18" stroke="#1A1A1A" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/></svg></button>
|
||
<div style="font-size: 15px;font-weight: 600;">我发现了更低价格</div>
|
||
</div>
|
||
<div style="font-size: 14px;font-weight: 600;color: var(--gray-700);margin-bottom: 8px;">粘贴外卖链接</div>
|
||
<input type="text" placeholder="粘贴更低价外卖的链接" style="width: 100%;border: 1.5px solid var(--gray-200);border-radius: 12px;padding: 12px;font-size: 14px;outline: none;margin-bottom: 16px;">
|
||
<div style="font-size: 14px;font-weight: 600;color: var(--gray-700);margin-bottom: 8px;">上传截图 <span style="font-weight: 400;color: var(--gray-400);">(含价格信息)</span></div>
|
||
<div style="display: flex;gap: 8px;margin-bottom: 16px;">
|
||
<div style="width: 80px;height: 80px;border: 1.5px dashed var(--gray-300);border-radius: 12px;display: flex;align-items: center;justify-content: center;font-size: 24px;color: var(--gray-400);cursor: pointer;">+</div>
|
||
<div style="width: 80px;height: 80px;border: 1.5px dashed var(--gray-300);border-radius: 12px;display: flex;align-items: center;justify-content: center;font-size: 24px;color: var(--gray-400);cursor: pointer;">+</div>
|
||
</div>
|
||
<button onclick="submitFeedback()" style="width: 100%;background: var(--primary);border: none;padding: 12px;border-radius: 14px;font-size: 16px;font-weight: 700;color: #1a1a1a;cursor: pointer;">提交反馈</button>
|
||
</div>
|
||
<!-- 步骤2B:非同款表单 -->
|
||
<div id="fbFormWrong" style="display: none;padding: 0 16px 24px;">
|
||
<div style="display: flex;align-items: center;gap: 8px;margin-bottom: 16px;">
|
||
<button class="btn-back" onclick="backToFbStep1()" aria-label="返回上一步"><svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M15 6L9 12L15 18" stroke="#1A1A1A" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/></svg></button>
|
||
<div style="font-size: 15px;font-weight: 600;">外卖不是同一家</div>
|
||
</div>
|
||
<div style="font-size: 14px;font-weight: 600;color: var(--gray-700);margin-bottom: 8px;">哪个平台的结果有误?</div>
|
||
<div id="fbPlatformList" style="display: flex;flex-wrap: wrap;gap: 8px;margin-bottom: 16px;"></div>
|
||
<div style="font-size: 14px;font-weight: 600;color: var(--gray-700);margin-bottom: 8px;">上传截图或描述问题</div>
|
||
<div style="display: flex;gap: 8px;margin-bottom: 12px;">
|
||
<div style="width: 80px;height: 80px;border: 1.5px dashed var(--gray-300);border-radius: 12px;display: flex;align-items: center;justify-content: center;font-size: 24px;color: var(--gray-400);cursor: pointer;">+</div>
|
||
</div>
|
||
<textarea placeholder="描述哪里不同(可选)" style="width: 100%;border: 1.5px solid var(--gray-200);border-radius: 12px;padding: 12px;font-size: 14px;outline: none;height: 60px;resize: none;font-family: inherit;margin-bottom: 16px;"></textarea>
|
||
<button onclick="submitFeedback()" style="width: 100%;background: var(--primary);border: none;padding: 12px;border-radius: 14px;font-size: 16px;font-weight: 700;color: #1a1a1a;cursor: pointer;">提交反馈</button>
|
||
</div>
|
||
<!-- 提交成功 -->
|
||
<div id="fbSuccess" style="display: none;padding: 24px 16px 32px;text-align: center;">
|
||
<div style="font-size: 48px;margin-bottom: 12px;">✅</div>
|
||
<div style="font-size: 18px;font-weight: 700;margin-bottom: 4px;">反馈已提交</div>
|
||
<div style="font-size: 14px;color: var(--gray-500);line-height: 22px;">系统正在验证,审核通过后<br><span style="color: #FF5722;font-weight: 600;">2,000 金币</span> 将自动到账</div>
|
||
<div style="font-size: 12px;color: var(--gray-400);margin-top: 12px;">审核结果将通过推送通知告知您</div>
|
||
<button onclick="closeFeedbackSheet()" style="margin-top: 16px;width: 100%;background: var(--primary);border: none;padding: 12px;border-radius: 14px;font-size: 16px;font-weight: 700;color: #1a1a1a;cursor: pointer;">知道了</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="nav-hint" id="navHint" style="display: none;"></div>
|
||
|
||
<!-- 结果页预览浮层 -->
|
||
<div id="resultPreviewOverlay" onclick="hideResultPreview()" style="display: none;position: absolute;inset: 0;z-index: 300;background: #fff;cursor: pointer;">
|
||
<img id="resultPreviewImg" src="" style="width: 100%;height: 100%;object-fit: cover;object-position: top;">
|
||
</div>
|
||
|
||
<!-- ===== 新手礼包弹窗 ===== -->
|
||
<div class="gift-overlay" id="welcomeGiftPopup">
|
||
<div class="gift-card" id="welcomeGiftCard">
|
||
<button class="gift-close" onclick="closeWelcomeGift(true)">✕</button>
|
||
<div class="gift-stage-a">
|
||
<div class="gift-confetti">🎉🎊✨🎊🎉</div>
|
||
<div class="gift-title">新手大礼包</div>
|
||
<div class="gift-subtitle">专享新客福利,开启领取</div>
|
||
</div>
|
||
<div class="gift-chest-wrap">
|
||
<div class="gift-chest-glow"></div>
|
||
<div class="gift-burst">
|
||
<div class="gift-burst-ray"></div>
|
||
<div class="gift-burst-ray"></div>
|
||
<div class="gift-burst-ray"></div>
|
||
<div class="gift-burst-ray"></div>
|
||
<div class="gift-burst-ray"></div>
|
||
<div class="gift-burst-ray"></div>
|
||
</div>
|
||
<div class="gift-chest-emoji" id="giftChestEmoji">🎁</div>
|
||
</div>
|
||
<div class="gift-amount" id="giftAmount">+5,000<span class="gift-amount-suffix">金币</span></div>
|
||
<div class="gift-amount-hint">已存入「福利」,随时可提现</div>
|
||
<button class="gift-btn" id="giftMainBtn" onclick="openGiftBox()">✨ 开启礼包</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 福利 tab 上方 +5000 飘字(device 级,z-index 高于 overlay) -->
|
||
<div class="tab-coin-badge" id="welfareTabBadge" style="z-index: 260;">+5,000 金币</div>
|
||
|
||
</div>
|
||
|
||
|
||
<script>
|
||
function showResultPreview(imgSrc) {
|
||
if (!imgSrc) return;
|
||
document.getElementById('resultPreviewImg').src = imgSrc;
|
||
document.getElementById('resultPreviewOverlay').style.display = 'block';
|
||
}
|
||
function hideResultPreview() {
|
||
document.getElementById('resultPreviewOverlay').style.display = 'none';
|
||
}
|
||
// 结果数据
|
||
// [WAIMAI-ONLY] 外卖比价结果数据 — 真实窑鸡王订单
|
||
const results = [
|
||
{
|
||
status: 'found',
|
||
platform: '淘宝',
|
||
platformIcon: '../../assets/shared/logos/taobao.png',
|
||
shop: '窑鸡王(康营店)',
|
||
delivery: '商家自配',
|
||
lowest: true,
|
||
items: [
|
||
{ name: '招牌窑鸡★★ 整只-原味', spec: '原味 × 1', price: 69.9, original: 99.9 }
|
||
],
|
||
fees: [
|
||
{ label: '打包费', amount: 5 },
|
||
{ label: '配送费', amount: 5, original: 12, note: '惊喜减7元' }
|
||
],
|
||
discounts: [
|
||
{ label: '店铺活动/券', amount: 1 },
|
||
{ label: '平台红包(超级吃货卡)', amount: 21 }
|
||
],
|
||
totalPrice: 57.9,
|
||
totalSaved: 59,
|
||
bonuses: [{ label: '下单返豆', detail: '返110吃货豆' }],
|
||
resultImage: '../../assets/onboarding/index/platform-flows/taobao/result.jpg'
|
||
},
|
||
{
|
||
status: 'found',
|
||
platform: '美团',
|
||
platformIcon: '../../assets/shared/logos/meituan.png',
|
||
shop: '窑鸡王(康营店)',
|
||
delivery: '商家自配',
|
||
lowest: false,
|
||
items: [
|
||
{ name: '招牌窑鸡(整只)', spec: '1只, 招牌整只原味 × 1', price: 69.9 }
|
||
],
|
||
fees: [
|
||
{ label: '打包费', amount: 5 },
|
||
{ label: '配送费', amount: 5.8, original: 12, note: '活动减6.2元' }
|
||
],
|
||
discounts: [
|
||
{ label: '美团红包(神券包)', amount: 18 }
|
||
],
|
||
totalPrice: 62.7,
|
||
totalSaved: 24.2,
|
||
bonuses: [],
|
||
resultImage: '../../assets/onboarding/index/platform-flows/meituan/result.jpg'
|
||
},
|
||
{
|
||
status: 'not-found',
|
||
platform: '京东',
|
||
platformIcon: '../../assets/shared/logos/jd.png',
|
||
reason: '未找到店铺'
|
||
}
|
||
];
|
||
|
||
// --- 同价 corner case 备用数据(取消注释可切换演示)---
|
||
// results[1].status = 'same-price';
|
||
// results[1].totalPrice = 57.9;
|
||
|
||
function renderFoundCard(r, idx, ctx) {
|
||
const isLowest = r.lowest;
|
||
const isUserOrig = ctx && ctx.userOrigId && r._id === ctx.userOrigId;
|
||
const borderColor = isLowest ? 'var(--primary)' : 'var(--gray-200)';
|
||
const cardBorder = isLowest ? '2px' : '1.5px';
|
||
const cardClass = isLowest ? 'card with-ribbon lowest' : 'card';
|
||
|
||
// 标识:最低价 → M2 斜挂红 ribbon(右上角);用户原选 → 描边方角 chip(店名旁 inline)
|
||
const lowestRibbon = isLowest ? '<img class="ribbon-vi" src="../../assets/shared/badges/lowest-price.png" alt="全网最低">' : '';
|
||
const userOrigChip = isUserOrig ? '<span class="badge-userorig">原选择</span>' : '';
|
||
|
||
// 收集所有 AI 帮领的优惠(配送费减免 + 优惠券 + 店铺活动)
|
||
const aiDiscountItems = [];
|
||
r.fees.forEach(f => {
|
||
if (f.note) aiDiscountItems.push({ label: f.note, amount: f.original - f.amount });
|
||
});
|
||
r.discounts.forEach(d => {
|
||
aiDiscountItems.push({ label: d.label, amount: d.amount });
|
||
});
|
||
|
||
// AI 优惠标签
|
||
const aiTagsHtml = aiDiscountItems.map(d =>
|
||
`<span style="display: inline-flex;align-items: center;gap: 2px;background: #E8F5E9;border-radius: 4px;padding: 2px 8px;font-size: 11px;color: #2E7D32;white-space: nowrap;">${d.label} <b>-¥${d.amount}</b></span>`
|
||
).join('');
|
||
|
||
// N2 chip:仅最低价 + 有正向价差时显示
|
||
let chipHtml = '';
|
||
if (isLowest && ctx && ctx.savings > 0) {
|
||
chipHtml = `<span class="save-chip-red"><span class="small">比原选择省</span>¥${ctx.savings}</span>`;
|
||
}
|
||
|
||
// CTA:新手引导里弱化购买入口,所有卡片统一使用"查看"浅灰次级胶囊
|
||
const ctaHtml = `<button class="result-cta" onclick="event.stopPropagation();showResultPreview('${r.resultImage || ''}')">查看<span class="arrow">›</span></button>`;
|
||
|
||
return `
|
||
<div class="${cardClass}" style="background: #fff;border-radius: 14px;padding: 12px 16px;border:${cardBorder} solid ${borderColor};position: relative;">
|
||
${lowestRibbon}
|
||
<!-- 头部:平台 logo + 店铺名 + 原选择 chip -->
|
||
<div style="display: flex;align-items: center;gap: 6px;${isLowest?'padding-right: 92px;':''}">
|
||
<img src="${r.platformIcon}" style="width: 28px;height: 28px;border-radius: 8px;flex-shrink: 0;" onerror="this.style.display='none'">
|
||
<span style="font-size: 14px;font-weight: 600;color: var(--gray-800);min-width: 0;overflow: hidden;text-overflow: ellipsis;white-space: nowrap;">${r.shop}</span>
|
||
${userOrigChip}
|
||
</div>
|
||
<!-- 傻瓜比价 AI 优惠 -->
|
||
<div style="margin-top: 8px;">
|
||
<div style="font-size: 12px;color: var(--gray-500);margin-bottom: 6px;">🤖 傻瓜比价已帮您领取以下优惠:</div>
|
||
<div style="display: flex;flex-wrap: wrap;gap: 4px;">
|
||
${aiTagsHtml}
|
||
</div>
|
||
</div>
|
||
<!-- 价格 + chip + CTA -->
|
||
<div style="display: flex;justify-content: space-between;align-items: center;margin-top: 12px;gap: 8px;">
|
||
<div style="display: flex;align-items: baseline;gap: 6px;flex-wrap: wrap;">
|
||
<span style="font-size: 13px;font-weight: 700;color: #FF5722;">¥</span>
|
||
<span style="font-size: 24px;font-weight: 800;color: #FF5722;line-height: 1;">${r.totalPrice}</span>
|
||
${chipHtml}
|
||
</div>
|
||
${ctaHtml}
|
||
</div>
|
||
</div>
|
||
`;
|
||
}
|
||
|
||
function renderNotFoundCard(r) {
|
||
// 从其他 found 结果中取店铺名
|
||
const shopName = (results.find(x => x.status === 'found') || {}).shop || '';
|
||
return `
|
||
<div style="background: #fff;border-radius: 14px;padding: 12px 16px;border: 1.5px solid var(--gray-200);position: relative;">
|
||
<!-- 头部:平台 -->
|
||
<div style="display: flex;align-items: center;gap: 8px;">
|
||
<img src="${r.platformIcon}" style="width: 28px;height: 28px;border-radius: 8px;" onerror="this.style.display='none'">
|
||
<span style="font-size: 14px;font-weight: 600;color: var(--gray-800);">${r.platform}</span>
|
||
</div>
|
||
<!-- 未找到提示 -->
|
||
<div style="margin-top: 12px;padding: 16px;background: var(--gray-50);border-radius: 8px;text-align: center;">
|
||
<div style="font-size: 13px;color: var(--gray-500);line-height: 20px;">该平台未找到「${shopName}」</div>
|
||
</div>
|
||
</div>
|
||
`;
|
||
}
|
||
|
||
function renderResults(containerId) {
|
||
const c = document.getElementById(containerId);
|
||
// 给每条结果赋稳定 id,便于 ctx 引用
|
||
results.forEach((r, i) => { if (r._id == null) r._id = '_r' + i; });
|
||
|
||
// 计算"用户原选"= 找到的非最低里最贵那条;savings = userOrig 价 - lowest 价
|
||
const foundResults = results.filter(r => r.status === 'found' || r.status === 'same-price');
|
||
const lowestResult = results.find(r => r.lowest);
|
||
const otherFound = foundResults.filter(r => !r.lowest);
|
||
const userResult = otherFound.length ? otherFound.reduce((a, b) => a.totalPrice >= b.totalPrice ? a : b) : null;
|
||
const savings = (lowestResult && userResult && userResult.totalPrice > lowestResult.totalPrice)
|
||
? (userResult.totalPrice - lowestResult.totalPrice).toFixed(1)
|
||
: 0;
|
||
const ctx = {
|
||
userOrigId: userResult ? userResult._id : null,
|
||
savings: Number(savings),
|
||
};
|
||
|
||
// 排序:lowest → found 按价格升序 → same-price → not-found
|
||
const order = { 'found': 1, 'same-price': 2, 'not-found': 3 };
|
||
const sorted = [...results].sort((a, b) => {
|
||
if (a.lowest && !b.lowest) return -1;
|
||
if (!a.lowest && b.lowest) return 1;
|
||
const oa = order[a.status] || 9, ob = order[b.status] || 9;
|
||
if (oa !== ob) return oa - ob;
|
||
if (a.totalPrice && b.totalPrice) return a.totalPrice - b.totalPrice;
|
||
return 0;
|
||
});
|
||
c.innerHTML = sorted.map((r, i) => {
|
||
if (r.status === 'not-found') return renderNotFoundCard(r);
|
||
return renderFoundCard(r, i, ctx);
|
||
}).join('');
|
||
}
|
||
|
||
function renderCelebrationSavings() {
|
||
const card = document.getElementById('celebSavingsCard');
|
||
if (!card) return;
|
||
card.innerHTML = `
|
||
<img src="../../assets/onboarding/index/first-banner.png" alt="恭喜您完成首次比价" style="display: block;width: 100%;height: auto;">
|
||
`;
|
||
}
|
||
|
||
// 无障碍全屏引导流程
|
||
const accessibilityImages = ['../../assets/onboarding/index/guide-1.jpg', '../../assets/onboarding/index/guide-2.jpg', '../../assets/onboarding/index/guide-3.jpg', '../../assets/onboarding/index/guide-4.jpg'];
|
||
let accessibilityIdx = 0;
|
||
|
||
function startAccessibilityFlow() {
|
||
accessibilityIdx = 0;
|
||
document.getElementById('accessFlowImg').src = accessibilityImages[0];
|
||
document.getElementById('accessStep4Overlay').style.display = 'none';
|
||
go('accessibility-flow');
|
||
}
|
||
|
||
function nextAccessibilityStep() {
|
||
accessibilityIdx++;
|
||
if (accessibilityIdx < accessibilityImages.length) {
|
||
document.getElementById('accessFlowImg').src = accessibilityImages[accessibilityIdx];
|
||
// 无障碍4(index=3)显示允许/拒绝覆盖层,禁用全屏点击
|
||
if (accessibilityIdx === 3) {
|
||
document.getElementById('accessStep4Overlay').style.display = 'block';
|
||
}
|
||
}
|
||
}
|
||
|
||
function onAllowClick(e) {
|
||
e.stopPropagation();
|
||
document.getElementById('accessStep4Overlay').style.display = 'none';
|
||
go('permission-step2');
|
||
}
|
||
|
||
function onRejectClick(e) {
|
||
e.stopPropagation();
|
||
document.getElementById('accessStep4Overlay').style.display = 'none';
|
||
go('permission-step1');
|
||
// 权限未开启 → 弹出提示弹窗
|
||
setTimeout(function() { openSafetyModal('无障碍'); }, 300);
|
||
}
|
||
|
||
function openSafetyModal(permName) {
|
||
document.getElementById('safetyModalPermName').textContent = permName;
|
||
document.getElementById('safetyModalTitle').textContent =
|
||
permName === '悬浮窗' ? '比价按钮未开启' : '比价功能未开启';
|
||
// 文案随权限上下文切换:无障碍 → 在「已安装的应用」中找;悬浮窗 → 直接在列表中找
|
||
var bodyEl = document.getElementById('safetyModalBody');
|
||
if (bodyEl) {
|
||
bodyEl.textContent = permName === '悬浮窗'
|
||
? '在列表中找到「傻瓜比价」并开启'
|
||
: '在「已安装的应用」中找到「傻瓜比价」并开启';
|
||
}
|
||
// 仅无障碍弹窗显示安全承诺,悬浮窗弹窗隐藏
|
||
var promise = document.getElementById('safetyPromiseBlock');
|
||
if (promise) promise.style.display = (permName === '悬浮窗') ? 'none' : 'block';
|
||
document.getElementById('safetyModal').style.display = 'flex';
|
||
}
|
||
|
||
function closeSafetyModal() {
|
||
document.getElementById('safetyModal').style.display = 'none';
|
||
}
|
||
|
||
// 「继续开启」按钮:关弹窗 + 直接进入对应权限设置页
|
||
function goToPermFromSafetyModal() {
|
||
const permName = document.getElementById('safetyModalPermName').textContent;
|
||
closeSafetyModal();
|
||
if (permName === '悬浮窗') {
|
||
startOverlayFlow();
|
||
} else {
|
||
startAccessibilityFlow();
|
||
}
|
||
}
|
||
|
||
// 悬浮窗引导流程
|
||
function startOverlayFlow() {
|
||
go('overlay-flow');
|
||
}
|
||
|
||
function onOverlayAllowClick(e) {
|
||
e.stopPropagation();
|
||
go('productselect');
|
||
openCelebrationModal();
|
||
}
|
||
|
||
// ===== 祝贺弹窗(多版本) =====
|
||
var celebrationVariants = {
|
||
// V1 「轻收尾·重期待」:承上小灰,起下大黑,行为按钮含次要引导
|
||
v1: '' +
|
||
'<div style="display: flex;align-items: center;justify-content: center;gap: 6px;font-size: 12px;color: var(--gray-500);margin-bottom: 8px;"><span style="display: inline-flex;align-items: center;justify-content: center;width: 16px;height: 16px;border-radius: 8px;background: #22C55E;color: #fff;font-size: 11px;font-weight: 700;">✓</span>全部设置已完成</div>' +
|
||
'<div style="font-size: 24px;font-weight: 800;color: var(--gray-900);text-align: center;line-height: 1.3;margin-bottom: 8px;">下一步,体验<br>傻瓜式一键比价</div>' +
|
||
'<div style="font-size: 14px;color: var(--gray-600);text-align: center;margin-bottom: 24px;">先选一个你常用的外卖平台</div>' +
|
||
'<button class="btn btn-primary btn-lg" style="border-radius: 24px;font-size: 16px;height: 48px;" onclick="closeCelebrationModal()">选个常用平台开始体验</button>',
|
||
|
||
// V2 「分割式」:顶部承上小条 + 中部起下标题 + 底部行为引导,节奏分明
|
||
v2: '' +
|
||
'<div style="text-align: center;margin-bottom: 12px;"><span style="display: inline-flex;align-items: center;gap: 6px;padding: 4px 12px;border-radius: 32px;background: #E8F5E9;color: #2E7D32;font-size: 12px;font-weight: 600;">✓ 已完成全部设置</span></div>' +
|
||
'<div style="font-size: 22px;font-weight: 800;color: var(--gray-900);text-align: center;line-height: 1.35;margin-bottom: 16px;">来体验傻瓜式<br>一键比价</div>' +
|
||
'<div style="height: 1px;background: var(--gray-200);margin-bottom: 16px;"></div>' +
|
||
'<div style="font-size: 13px;color: var(--gray-500);text-align: center;margin-bottom: 8px;">第一步</div>' +
|
||
'<div style="font-size: 15px;font-weight: 700;color: var(--gray-900);text-align: center;margin-bottom: 16px;">选择一个常用的外卖平台</div>' +
|
||
'<button class="btn btn-primary btn-lg" style="border-radius: 24px;font-size: 16px;height: 48px;" onclick="closeCelebrationModal()">选个常用平台开始体验</button>',
|
||
|
||
// V3 「叙事流」:递进式三行,承上→起下→行为,逐级加重(采用 V5 的绿圆勾徽章)
|
||
v3: '' +
|
||
'<div style="display: flex;align-items: center;gap: 8px;margin-bottom: 16px;">' +
|
||
'<span style="display: inline-flex;align-items: center;justify-content: center;width: 20px;height: 20px;border-radius: 50%;background: #22C55E;box-shadow: 0 0 0 3px rgba(34,197,94,.18);flex-shrink: 0;"><svg width="11" height="11" viewBox="0 0 10 10"><path d="M2.2 5.2l2 2 3.8-4.6" stroke="#fff" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" fill="none"/></svg></span>' +
|
||
'<span style="font-size: 13px;color: var(--gray-700);font-weight: 600;">设置已完成</span>' +
|
||
'</div>' +
|
||
'<div style="background: linear-gradient(135deg,#FFFDE7,#FFF8E1);border-radius: 14px;padding: 16px 16px;margin-bottom: 16px;text-align: center;">' +
|
||
'<div style="font-size: 12px;color: #F9A825;font-weight: 600;margin-bottom: 6px;">下一步</div>' +
|
||
'<div style="font-size: 18px;font-weight: 800;color: var(--gray-900);">用傻瓜比价,找全网底价</div>' +
|
||
'</div>' +
|
||
'<button class="btn btn-primary btn-lg" style="border-radius: 24px;font-size: 16px;height: 48px;width: 100%;" onclick="closeCelebrationModal()">选外卖平台开始体验</button>',
|
||
|
||
// V4 「行为优先」:承上完全收为一行小提示,起下并入按钮上方副文,主舞台让给行为
|
||
v4: '' +
|
||
'<div style="font-size: 11px;color: var(--gray-500);letter-spacing: 1px;text-align: center;margin-bottom: 8px;text-transform: uppercase;">SETUP COMPLETE</div>' +
|
||
'<div style="font-size: 24px;font-weight: 800;color: var(--gray-900);text-align: center;line-height: 1.25;margin-bottom: 8px;">选一个常用<br>外卖平台</div>' +
|
||
'<div style="font-size: 13px;color: var(--gray-600);text-align: center;margin-bottom: 24px;">即可开启傻瓜式一键比价</div>' +
|
||
'<button class="btn btn-primary btn-lg" style="border-radius: 24px;font-size: 16px;height: 48px;" onclick="closeCelebrationModal()">现在选择</button>',
|
||
|
||
// V5 「徽章+行动卡」:左对齐绿圆勾徽章承上,黄色行动卡承载"下一步 + 体验傻瓜式一键比价"
|
||
v5: '' +
|
||
'<div style="display: flex;align-items: center;gap: 8px;margin-bottom: 16px;">' +
|
||
'<span style="display: inline-flex;align-items: center;justify-content: center;width: 20px;height: 20px;border-radius: 50%;background: #22C55E;box-shadow: 0 0 0 3px rgba(34,197,94,.18);flex-shrink: 0;"><svg width="11" height="11" viewBox="0 0 10 10"><path d="M2.2 5.2l2 2 3.8-4.6" stroke="#fff" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" fill="none"/></svg></span>' +
|
||
'<span style="font-size: 13px;color: var(--gray-700);font-weight: 600;">设置已完成</span>' +
|
||
'</div>' +
|
||
'<div style="position: relative;background: linear-gradient(135deg,#FFFDE7,#FFF3C4);border-radius: 14px;padding: 24px 16px 16px;margin: 12px 0 16px;border: 1.5px solid #FFE082;text-align: center;">' +
|
||
'<div style="position: absolute;top: -12px;left: 50%;transform: translateX(-50%);font-size: 11px;color: #F57F17;font-weight: 800;background: #fff;padding: 4px 12px;border-radius: 32px;letter-spacing: .6px;border: 1.5px solid #FFE082;white-space: nowrap;">下一步</div>' +
|
||
'<div style="font-size: 20px;font-weight: 800;color: var(--gray-900);line-height: 1.3;">用傻瓜比价,找全网底价</div>' +
|
||
'</div>' +
|
||
'<button class="btn btn-primary btn-lg" style="border-radius: 24px;font-size: 16px;height: 48px;width: 100%;" onclick="closeCelebrationModal()">选外卖平台开始体验</button>',
|
||
|
||
// V6 「进度条」:完成段绿+待办段黄色脉动,强化推进感
|
||
v6: '' +
|
||
'<div style="display: flex;align-items: center;gap: 8px;margin-bottom: 12px;">' +
|
||
'<span style="display: inline-flex;align-items: center;justify-content: center;width: 20px;height: 20px;border-radius: 50%;background: #22C55E;box-shadow: 0 0 0 3px rgba(34,197,94,.18);flex-shrink: 0;"><svg width="11" height="11" viewBox="0 0 10 10"><path d="M2.2 5.2l2 2 3.8-4.6" stroke="#fff" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" fill="none"/></svg></span>' +
|
||
'<span style="font-size: 13px;color: var(--gray-700);font-weight: 600;">设置已完成</span>' +
|
||
'</div>' +
|
||
'<div style="display: flex;align-items: center;gap: 6px;margin-bottom: 24px;">' +
|
||
'<div style="flex: 1;height: 6px;border-radius: 4px;background: #22C55E;"></div>' +
|
||
'<div style="flex: 1;height: 6px;border-radius: 4px;background: linear-gradient(90deg,#FFD600,#FFB300);box-shadow: 0 0 10px rgba(255,214,0,.55);animation: gvBob 1.6s ease-in-out infinite;"></div>' +
|
||
'</div>' +
|
||
'<div style="font-size: 13px;color: #F57F17;font-weight: 800;text-align: center;margin-bottom: 6px;letter-spacing: .5px;">最后一步</div>' +
|
||
'<div style="font-size: 22px;font-weight: 800;color: var(--gray-900);text-align: center;line-height: 1.3;margin-bottom: 24px;">选个常用平台</div>' +
|
||
'<button class="btn btn-primary btn-lg" style="border-radius: 24px;font-size: 16px;height: 48px;width: 100%;" onclick="closeCelebrationModal()">立即选择</button>',
|
||
|
||
// V7 「数字步骤」:① 已完成 → ② 当前 双步骤连线,明确流程位置
|
||
v7: '' +
|
||
'<div style="display: flex;align-items: center;justify-content: center;gap: 8px;margin-bottom: 24px;">' +
|
||
'<div style="display: flex;align-items: center;gap: 6px;opacity: .85;">' +
|
||
'<span style="display: inline-flex;align-items: center;justify-content: center;width: 20px;height: 20px;border-radius: 50%;background: #22C55E;flex-shrink: 0;"><svg width="11" height="11" viewBox="0 0 10 10"><path d="M2.2 5.2l2 2 3.8-4.6" stroke="#fff" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" fill="none"/></svg></span>' +
|
||
'<span style="font-size: 12px;color: var(--gray-500);font-weight: 600;">设置完成</span>' +
|
||
'</div>' +
|
||
'<div style="width: 20px;height: 2px;background: var(--gray-200);border-radius: 4px;"></div>' +
|
||
'<div style="display: flex;align-items: center;gap: 6px;">' +
|
||
'<span style="display: inline-flex;align-items: center;justify-content: center;width: 20px;height: 20px;border-radius: 50%;background: var(--primary);color: #1a1a1a;font-size: 12px;font-weight: 800;flex-shrink: 0;box-shadow: 0 0 0 3px rgba(255,214,0,.25);">2</span>' +
|
||
'<span style="font-size: 12px;color: var(--gray-900);font-weight: 700;">选平台</span>' +
|
||
'</div>' +
|
||
'</div>' +
|
||
'<div style="font-size: 22px;font-weight: 800;color: var(--gray-900);text-align: center;line-height: 1.3;margin-bottom: 8px;">选个常用外卖平台</div>' +
|
||
'<div style="font-size: 13px;color: var(--gray-600);text-align: center;margin-bottom: 24px;">即可开启傻瓜式一键比价</div>' +
|
||
'<button class="btn btn-primary btn-lg" style="border-radius: 24px;font-size: 16px;height: 48px;display: flex;align-items: center;justify-content: center;gap: 6px;width: 100%;" onclick="closeCelebrationModal()">选择平台<span style="font-size: 18px;line-height: 1;">→</span></button>',
|
||
|
||
// V8 「极简专注」:单行小绿勾承上,舞台全部让给主标题
|
||
v8: '' +
|
||
'<div style="display: flex;align-items: center;gap: 8px;margin-bottom: 24px;">' +
|
||
'<span style="display: inline-flex;align-items: center;justify-content: center;width: 20px;height: 20px;border-radius: 50%;background: #22C55E;box-shadow: 0 0 0 3px rgba(34,197,94,.18);flex-shrink: 0;"><svg width="11" height="11" viewBox="0 0 10 10"><path d="M2.2 5.2l2 2 3.8-4.6" stroke="#fff" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" fill="none"/></svg></span>' +
|
||
'<span style="font-size: 13px;color: var(--gray-600);font-weight: 500;">设置已完成</span>' +
|
||
'</div>' +
|
||
'<div style="font-size: 24px;font-weight: 800;color: var(--gray-900);text-align: center;line-height: 1.25;margin-bottom: 8px;letter-spacing: -.3px;">选个常用平台</div>' +
|
||
'<div style="font-size: 14px;color: var(--gray-600);text-align: center;margin-bottom: 24px;line-height: 1.5;">现在体验<span style="font-weight: 700;color: var(--gray-900);background: linear-gradient(to top,var(--primary) 40%,transparent 40%);padding: 0 2px;">傻瓜式一键比价</span></div>' +
|
||
'<button class="btn btn-primary btn-lg" style="border-radius: 24px;font-size: 16px;height: 48px;width: 100%;" onclick="closeCelebrationModal()">开始体验</button>',
|
||
|
||
// V9 「iOS 极简·一图一字一按钮」:80px 大圆勾 + 大字标题 + 单按钮,零嵌套盒子
|
||
v9: '' +
|
||
'<div style="display: flex;justify-content: center;margin: 6px 0 16px;">' +
|
||
'<div style="width: 80px;height: 80px;border-radius: 50%;background: linear-gradient(135deg,#34D399,#10B981);display: flex;align-items: center;justify-content: center;box-shadow: 0 10px 28px rgba(16,185,129,.35), 0 0 0 8px rgba(16,185,129,.10);animation: gvPop .5s cubic-bezier(.34,1.56,.64,1) both;">' +
|
||
'<svg width="42" height="42" viewBox="0 0 42 42" fill="none">' +
|
||
'<path d="M11 21.5 L18 28.5 L31.5 14.5" stroke="#fff" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/>' +
|
||
'</svg>' +
|
||
'</div>' +
|
||
'</div>' +
|
||
'<div style="font-size: 24px;font-weight: 800;color: var(--gray-900);text-align: center;line-height: 1.3;margin-bottom: 8px;letter-spacing: -.3px;">就差最后一步</div>' +
|
||
'<div style="font-size: 14px;color: var(--gray-600);text-align: center;line-height: 1.55;margin-bottom: 24px;">选个常用平台 · 立刻体验傻瓜式一键比价</div>' +
|
||
'<button class="btn btn-primary btn-lg" style="border-radius: 24px;font-size: 16px;height: 50px;width: 100%;font-weight: 700;" onclick="closeCelebrationModal()">选外卖平台开始体验</button>',
|
||
|
||
// V10 「Stripe / Linear 风」:左对齐、小绿勾 + 大字 + 黑底按钮,冷峻 SaaS 调性
|
||
v10: '' +
|
||
'<div style="display: flex;align-items: center;gap: 8px;margin-bottom: 24px;">' +
|
||
'<span style="display: inline-flex;align-items: center;justify-content: center;width: 18px;height: 18px;border-radius: 50%;background: #10B981;flex-shrink: 0;"><svg width="10" height="10" viewBox="0 0 10 10"><path d="M2.2 5.2l2 2 3.8-4.6" stroke="#fff" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" fill="none"/></svg></span>' +
|
||
'<span style="font-size: 12px;color: var(--gray-500);font-weight: 500;letter-spacing: .3px;">Setup complete</span>' +
|
||
'</div>' +
|
||
'<div style="font-size: 28px;font-weight: 800;color: var(--gray-900);line-height: 1.2;margin-bottom: 8px;letter-spacing: -.6px;">选个常用<br>外卖平台</div>' +
|
||
'<div style="font-size: 14px;color: var(--gray-600);line-height: 1.55;margin-bottom: 24px;">即可开启傻瓜式一键比价 — AI 会自动跨平台比价、领券、下单。</div>' +
|
||
'<button style="background: #1A1A1A;color: #fff;border: none;border-radius: 14px;font-size: 15px;height: 50px;width: 100%;font-weight: 600;display: flex;align-items: center;justify-content: center;gap: 8px;cursor: pointer;" onclick="closeCelebrationModal()">' +
|
||
'<span>开始体验</span>' +
|
||
'<svg width="14" height="14" viewBox="0 0 14 14" fill="none"><path d="M3 7h8m0 0l-3.5-3.5M11 7l-3.5 3.5" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/></svg>' +
|
||
'</button>',
|
||
|
||
// V11 「沉浸彩屏 hero」:负 margin 把顶部 bleed 成黄色渐变 hero,礼包大图标占主舞台,电商喜庆调性
|
||
v11: '' +
|
||
'<div style="margin: -28px -22px 16px;border-radius: 24px 24px 0 0;background: linear-gradient(180deg,#FFE066 0%,#FFF3C4 55%,#fff 100%);padding: 32px 24px 16px;text-align: center;position: relative;overflow: hidden;">' +
|
||
'<div style="position: absolute;top: -30px;left: -30px;width: 120px;height: 120px;border-radius: 50%;background: radial-gradient(circle,rgba(255,255,255,.6),transparent 70%);"></div>' +
|
||
'<div style="position: absolute;bottom: -40px;right: -30px;width: 140px;height: 140px;border-radius: 50%;background: radial-gradient(circle,rgba(255,179,0,.25),transparent 70%);"></div>' +
|
||
'<div style="width: 96px;height: 96px;margin: 0 auto 12px;position: relative;animation: gvPop .55s cubic-bezier(.34,1.56,.64,1) both;">' +
|
||
'<div style="position: absolute;inset: 0;border-radius: 50%;background: radial-gradient(circle,rgba(255,255,255,.85) 0%,rgba(255,255,255,0) 70%);"></div>' +
|
||
'<div style="position: absolute;inset: 6px;border-radius: 50%;background: linear-gradient(135deg,#FFD600 0%,#FF9800 100%);display: flex;align-items: center;justify-content: center;box-shadow: 0 14px 32px rgba(255,152,0,.45), inset 0 -6px 14px rgba(0,0,0,.08);">' +
|
||
'<span style="font-size: 46px;line-height: 1;filter: drop-shadow(0 2px 4px rgba(0,0,0,.15));">🎁</span>' +
|
||
'</div>' +
|
||
'</div>' +
|
||
'<div style="display: inline-block;font-size: 11px;font-weight: 800;color: #D84315;letter-spacing: 1.2px;background: #fff;padding: 4px 12px;border-radius: 32px;margin-bottom: 8px;box-shadow: 0 2px 6px rgba(216,67,21,.18);">SETUP COMPLETE</div>' +
|
||
'<div style="font-size: 24px;font-weight: 900;color: var(--gray-900);line-height: 1.25;letter-spacing: -.3px;">傻瓜比价 · 准备就绪</div>' +
|
||
'</div>' +
|
||
'<div style="font-size: 14px;color: var(--gray-600);text-align: center;line-height: 1.55;margin-bottom: 16px;">选个常用平台 · 立刻领券一键比价</div>' +
|
||
'<button class="btn btn-primary btn-lg" style="border-radius: 24px;font-size: 16px;height: 52px;width: 100%;font-weight: 700;box-shadow: 0 8px 22px rgba(255,179,0,.42);display: flex;align-items: center;justify-content: center;gap: 6px;" onclick="closeCelebrationModal()">' +
|
||
'<span>选外卖平台开始体验</span><span style="font-size: 18px;line-height: 1;">→</span>' +
|
||
'</button>',
|
||
|
||
// V12 「步骤推进 2/2」:顶部细进度条 100% + 双步骤指示,强化"最后一步"流程感
|
||
v12: '' +
|
||
'<div style="display: flex;align-items: center;gap: 8px;margin-bottom: 8px;">' +
|
||
'<div style="font-size: 11px;font-weight: 700;color: var(--gray-500);letter-spacing: .4px;">2 / 2</div>' +
|
||
'<div style="flex: 1;height: 5px;border-radius: 4px;background: var(--gray-200);overflow: hidden;display: flex;">' +
|
||
'<div style="flex: 1;background: #10B981;border-radius: 4px 0 0 4px;"></div>' +
|
||
'<div style="flex: 1;background: linear-gradient(90deg,var(--primary),#FFB300);border-radius: 0 4px 4px 0;box-shadow: 0 0 8px rgba(255,179,0,.5);animation: gvBob 1.6s ease-in-out infinite;"></div>' +
|
||
'</div>' +
|
||
'</div>' +
|
||
'<div style="display: flex;align-items: center;gap: 6px;margin-bottom: 24px;font-size: 11px;">' +
|
||
'<span style="display: inline-flex;align-items: center;justify-content: center;width: 13px;height: 13px;border-radius: 50%;background: #10B981;flex-shrink: 0;"><svg width="8" height="8" viewBox="0 0 10 10"><path d="M2.2 5.2l2 2 3.8-4.6" stroke="#fff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" fill="none"/></svg></span>' +
|
||
'<span style="color: var(--gray-500);font-weight: 500;">设置完成</span>' +
|
||
'<span style="color: var(--gray-300);margin: 0 2px;">›</span>' +
|
||
'<span style="color: var(--coin);font-weight: 800;letter-spacing: .2px;">现在选平台</span>' +
|
||
'</div>' +
|
||
'<div style="font-size: 24px;font-weight: 800;color: var(--gray-900);text-align: center;line-height: 1.25;margin-bottom: 8px;letter-spacing: -.3px;">就差最后一步</div>' +
|
||
'<div style="font-size: 14px;color: var(--gray-600);text-align: center;line-height: 1.55;margin-bottom: 24px;">选个常用平台开启<span style="font-weight: 700;color: var(--gray-900);">傻瓜式一键比价</span></div>' +
|
||
'<button class="btn btn-primary btn-lg" style="border-radius: 24px;font-size: 16px;height: 50px;width: 100%;font-weight: 700;display: flex;align-items: center;justify-content: center;gap: 6px;" onclick="closeCelebrationModal()">' +
|
||
'<span>立即选择</span><span style="font-size: 18px;line-height: 1;">→</span>' +
|
||
'</button>'
|
||
};
|
||
var currentCelebrationVariant = 'v1';
|
||
var celebrationModalHTML = celebrationVariants[currentCelebrationVariant];
|
||
|
||
function openCelebrationModal() {
|
||
document.getElementById('celebrationModalCard').innerHTML = celebrationVariants[currentCelebrationVariant] || celebrationVariants.v1;
|
||
document.getElementById('celebrationModal').style.display = 'flex';
|
||
if (typeof fireConfetti === 'function') {
|
||
fireConfetti();
|
||
}
|
||
}
|
||
|
||
function closeCelebrationModal() {
|
||
document.getElementById('celebrationModal').style.display = 'none';
|
||
}
|
||
|
||
function onOverlayRejectClick(e) {
|
||
e.stopPropagation();
|
||
go('permission-step2');
|
||
// 权限未开启 → 弹出提示弹窗
|
||
setTimeout(function() { openSafetyModal('悬浮窗'); }, 300);
|
||
}
|
||
|
||
// 礼花彩纸特效 — 从顶部散落的彩色纸片
|
||
function fireConfetti() {
|
||
var container = document.getElementById('app');
|
||
var colors = ['#FFD600', '#FF5722', '#4CAF50', '#2196F3', '#E91E63', '#FF9800', '#9C27B0', '#00BCD4'];
|
||
for (var i = 0; i < 60; i++) {
|
||
var particle = document.createElement('div');
|
||
var color = colors[Math.floor(Math.random() * colors.length)];
|
||
var w = Math.random() * 6 + 4;
|
||
var h = Math.random() * 14 + 8;
|
||
var left = Math.random() * 100;
|
||
var dx = (Math.random() - 0.5) * 100;
|
||
var dy = 700 + Math.random() * 200;
|
||
var spin = (Math.random() - 0.5) * 1440;
|
||
var delay = Math.random() * 0.6;
|
||
var duration = Math.random() * 1.5 + 1.5;
|
||
particle.style.cssText = 'position:absolute;width:' + w + 'px;height:' + h + 'px;background:' + color + ';border-radius:1px;left:' + left + '%;top:-20px;z-index:9999;pointer-events:none;opacity:1;animation:confettiFloat ' + duration + 's ease-in ' + delay + 's forwards;--dx:' + dx + 'px;--dy:' + dy + 'px;--spin:' + spin + 'deg;';
|
||
container.appendChild(particle);
|
||
(function(p, t) { setTimeout(function() { p.remove(); }, t); })(particle, (duration + delay) * 1000 + 100);
|
||
}
|
||
}
|
||
|
||
// 权限检测 → 两个都开启才能进入下一步
|
||
function checkPermAndGo() {
|
||
var accDone = document.getElementById('accessibilityBtn').disabled;
|
||
var ovlDone = document.getElementById('overlayBtn').disabled;
|
||
if (accDone && ovlDone) {
|
||
go('productselect');
|
||
} else {
|
||
showToast('请先完成前置步骤再继续');
|
||
}
|
||
}
|
||
|
||
// Toast 提示:对齐 DESIGN.md patterns.toast
|
||
function showCenteredToast(msg) {
|
||
var existing = document.getElementById('globalToast');
|
||
if (existing) existing.remove();
|
||
var toast = document.createElement('div');
|
||
toast.id = 'globalToast';
|
||
toast.textContent = msg;
|
||
toast.style.cssText = 'position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);max-width:310px;background:rgba(0,0,0,.78);color:#fff;font-size:14px;font-weight:400;line-height:20px;padding:12px 20px;border-radius:10px;z-index:9999;text-align:center;pointer-events:none;opacity:1;transition:opacity .25s;white-space:nowrap;';
|
||
document.getElementById('app').appendChild(toast);
|
||
setTimeout(function() { toast.style.opacity = '0'; }, 1500);
|
||
setTimeout(function() { toast.remove(); }, 1800);
|
||
}
|
||
|
||
function showToast(msg) { showCenteredToast(msg); }
|
||
|
||
function showFeedbackReturnToast(msg) { showCenteredToast(msg); }
|
||
|
||
// 从意见反馈页提交后回流:在「我的」页落地弹一次 toast
|
||
// 用 pageshow 是因为 history/back-forward cache 恢复时 DOMContentLoaded 不会重跑
|
||
window.addEventListener('pageshow', function() {
|
||
var submitted = /(?:\?|&)feedback=1(?:&|$)/.test(window.location.search);
|
||
try { submitted = submitted || localStorage.getItem('proto_feedbackSubmitted') === '1'; } catch(e) {}
|
||
if (!submitted) return;
|
||
try { localStorage.removeItem('proto_feedbackSubmitted'); } catch(e) {}
|
||
if (window.history && typeof window.history.replaceState === 'function') {
|
||
window.history.replaceState(null, '', window.location.pathname + window.location.hash);
|
||
}
|
||
setTimeout(function() {
|
||
showFeedbackReturnToast('提交成功,感谢反馈');
|
||
}, 350);
|
||
});
|
||
|
||
// 登录状态 —— webview 改造:优先取原生桥登录态,无桥(浏览器调试)回退 localStorage
|
||
let isLoggedIn = (window.SGBridge ? !!SGBridge.getAuthState().loggedIn
|
||
: (typeof localStorage !== 'undefined' && localStorage.getItem('proto_isLoggedIn') !== 'false'));
|
||
|
||
// ===== webview 改造(阶段0):我的页真实数据接入 =====
|
||
// 战绩卡(累计可省/完成比价/赚取金币)从 app-server 真接口拉;无桥/无后端环境静默降级,保留原型 mock 展示。
|
||
function sgFmtYuan(cents){ return (Number(cents||0)/100).toLocaleString('zh-CN',{minimumFractionDigits:2,maximumFractionDigits:2}); }
|
||
// 【临时调试浮层 — 诊断数据接通,定位后删】顶部黑条显示登录态/token/各接口结果
|
||
// sgDbg:诊断输出改走 console.log → WebChromeClient 落 logcat "[H5]",不再在屏上画黑底绿字浮层。
|
||
// (顶部满屏后该浮层会顶到屏幕最上沿露脸;排 #1「数据没显示」仍可凭 logcat 里的 [sgDbg] 行诊断。)
|
||
function sgDbg(m){ try{ console.log('[sgDbg] '+m); }catch(e){} }
|
||
// 路①修重复刷新:切回本 tab 时 onResume 有多个触发源(NavBackStackEntry lifecycle + 宿主 LaunchedEffect),
|
||
// 真机实测 ~27ms 内连调 loadMineData 2 次(重复拉 3 接口 + 刷 DOM)。这里加时间去重:800ms 内重复调用只跑一次;
|
||
// 正常切回/回前台(间隔 >800ms)不受影响,仍会刷新最新数据。
|
||
var _loadMineLast = 0;
|
||
function loadMineData(){
|
||
var _now = Date.now();
|
||
if (_now - _loadMineLast < 800) { sgDbg('loadMineData 去重跳过('+(_now-_loadMineLast)+'ms)'); return; }
|
||
_loadMineLast = _now;
|
||
if (!window.SGApi || !window.SGBridge) { sgDbg('无 SGApi/SGBridge(非 webview 环境)'); return; }
|
||
var auth = SGBridge.getAuthState();
|
||
sgDbg('loggedIn='+(auth&&auth.loggedIn)+' nick='+(auth&&auth.nickname)+' token='+((SGBridge.getToken()||'(空)').slice(0,12))+'...');
|
||
if (!auth || !auth.loggedIn) { sgDbg('→ 未登录,停止拉数据'); return; }
|
||
if (auth.nickname){ var n=document.getElementById('profName'); if(n){ n.textContent=auth.nickname; n.setAttribute('data-fullname', auth.nickname); } }
|
||
// 真实头像(仅 http(s) 远程;本地 content:// URI WebView 加载受限 → 保留默认卡通头像)
|
||
if (auth.avatarUrl && /^https?:/.test(auth.avatarUrl)){ var av=document.querySelector('#profileLogged .prof-avatar'); if(av){ av.innerHTML='<img src="'+auth.avatarUrl+'" style="width:100%;height:100%;border-radius:50%;object-fit:cover" onerror="this.style.display=\'none\'">'; } }
|
||
// 累计发现可省(主额) + 完成比价次数 + 锁定态 ← /compare/stats(comparison_record 比价口径,
|
||
// 对齐原生 ProfileViewModel:比价就计、不要求下单。原 /savings/* 是下单成交口径,会误锁,已换。
|
||
SGApi.get('/compare/stats').then(function(s){
|
||
sgDbg('compare/stats OK compare_count='+(s&&s.compare_count)+' discovered_saved='+(s&&s.discovered_saved_cents));
|
||
if(!s) return;
|
||
var amt=document.querySelector('#profSavingsCard .prof-amount');
|
||
if(amt) amt.innerHTML='<span class="prof-currency">¥</span>'+sgFmtYuan(s.discovered_saved_cents);
|
||
var nums=document.querySelectorAll('#profSavingsCard .prof-stat-num'); // [0]领券 [1]完成比价 [2]赚取金币
|
||
if(nums[1]) nums[1].innerHTML=(s.compare_count||0)+'<span class="prof-stat-unit">次</span>';
|
||
if(typeof applySavingsLock==='function') applySavingsLock((s.compare_count||0)===0);
|
||
}).catch(function(e){ sgDbg('compare/stats ERR: '+(e&&e.message)); });
|
||
// 累计赚取金币
|
||
SGApi.get('/wallet/account').then(function(a){
|
||
if(!a) return;
|
||
var nums=document.querySelectorAll('#profSavingsCard .prof-stat-num');
|
||
if(nums[2]) nums[2].innerHTML=(a.total_coin_earned||0)+'<span class="prof-stat-unit">个</span>';
|
||
}).catch(function(){});
|
||
// 领取优惠券张数
|
||
SGApi.get('/coupon/stats').then(function(c){
|
||
if(!c) return;
|
||
var nums=document.querySelectorAll('#profSavingsCard .prof-stat-num');
|
||
if(nums[0]) nums[0].innerHTML=(c.coupon_count||0)+'<span class="prof-stat-unit">张</span>';
|
||
}).catch(function(){});
|
||
}
|
||
document.addEventListener('DOMContentLoaded', loadMineData);
|
||
if (window.SGBridge){
|
||
SGBridge.on('onResume', loadMineData); // 回前台重拉
|
||
SGBridge.on('onBalanceChange', loadMineData); // 余额变重拉
|
||
SGBridge.on('onAuthChange', function(){ try{ location.reload(); }catch(e){} }); // 登录态变整页刷新
|
||
// 未登录态 CTA 走原生登录:把 go('login') 接到极光一键登录(不改各处 onclick)
|
||
var _origGo=window.go;
|
||
window.go=function(id){ if(id==='login'){ SGBridge.requestLogin(); return; } if(typeof _origGo==='function') return _origGo.apply(this, arguments); };
|
||
}
|
||
// webview 样式校正(真 webview 或浏览器加 ?wv=1 预览):撑掉原型"手机壳"(.device 固定 375×812 居中)铺满 + 隐藏自带底栏。
|
||
// .device 用 position:fixed 钉满视口(不依赖 100vh,更稳);body 不动(fixed 脱离文档流,原 flex 居中对它无效)。
|
||
if (window.SGBridge || /[?&]wv=1/.test(location.search)){
|
||
var _wvCss=document.createElement('style');
|
||
_wvCss.textContent='html,body{background-color:#fff!important}.device{position:fixed!important;top:0!important;left:0!important;right:0!important;bottom:0!important;width:auto!important;height:auto!important;border-radius:0!important;box-shadow:none!important}.tab-bar{display:none!important}.prof-statusbar{display:none!important}.variant-panel{display:none!important}#debugBack{display:none!important}';
|
||
(document.head||document.documentElement).appendChild(_wvCss);
|
||
}
|
||
let loginFrom = (typeof localStorage !== 'undefined' && localStorage.getItem('proto_loginFrom')) || 'home';
|
||
let welfareVisited = (typeof localStorage !== 'undefined' && localStorage.getItem('proto_welfareVisited') === 'true');
|
||
let profileVisited = (typeof localStorage !== 'undefined' && localStorage.getItem('proto_profileVisited') === 'true');
|
||
|
||
// 新手礼包流程
|
||
let welcomeGiftShown = (typeof localStorage !== 'undefined' && localStorage.getItem('proto_welcomeGiftShown') === 'true');
|
||
let welcomeGiftClaimed = false;
|
||
let welfareCoinBalance = 28967;
|
||
let welfareCashBalance = 2.89;
|
||
let recordComparisonRewardClaimed = false;
|
||
let messageReminderRewardClaimed = false;
|
||
let videoRewardClaimed = false;
|
||
|
||
// 导航
|
||
// ===== 方案切换系统 =====
|
||
// 配置:在这里注册需要多方案对比的模块
|
||
// 格式:screenId: { current: 'a', options: { a: '方案名', b: '方案名' } }
|
||
// 方案A的screen id = 原id(如 productselect)
|
||
// 方案B的screen id = 原id--b(如 productselect--b)
|
||
// 方案C的screen id = 原id--c(如 productselect--c)
|
||
// inPlace 模块:不换 screen,只跑 onChange 回调(用于原地切类名/样式)
|
||
const variants = {
|
||
'省钱战绩': {
|
||
inPlace: true,
|
||
current: 'unlocked',
|
||
options: { locked: '锁定', unlocked: '未锁定' },
|
||
onChange: function(v) { applySavingsLock(v === 'locked'); }
|
||
}
|
||
};
|
||
|
||
// 省钱战绩卡锁定/解锁:locked=盖不透明蒙层(未比价),unlocked=显示真实战绩
|
||
function applySavingsLock(locked) {
|
||
var card = document.getElementById('profSavingsCard');
|
||
if (!card) return;
|
||
card.classList.toggle('locked', !!locked);
|
||
}
|
||
|
||
function resolveScreenId(id) {
|
||
if (variants[id] && !variants[id].inPlace) {
|
||
const v = variants[id].current;
|
||
return v === 'a' ? id : id + '--' + v;
|
||
}
|
||
return id;
|
||
}
|
||
|
||
function switchVariant(moduleId, variant) {
|
||
if (!variants[moduleId]) return;
|
||
variants[moduleId].current = variant;
|
||
renderVariantPanel();
|
||
if (typeof variants[moduleId].onChange === 'function') {
|
||
variants[moduleId].onChange(variant);
|
||
}
|
||
if (variants[moduleId].inPlace) return;
|
||
// 如果当前正在看这个模块的某个方案,立即切换
|
||
const allScreens = document.querySelectorAll('.screen');
|
||
let isViewing = false;
|
||
allScreens.forEach(s => {
|
||
if (s.classList.contains('active') && (s.id === moduleId || s.id.startsWith(moduleId + '--'))) {
|
||
isViewing = true;
|
||
}
|
||
});
|
||
if (isViewing) go(moduleId);
|
||
}
|
||
|
||
function toggleVariantPanel() {
|
||
const p = document.getElementById('variantPanel');
|
||
p.classList.toggle('open');
|
||
if (p.classList.contains('open')) renderVariantPanel();
|
||
}
|
||
|
||
function renderVariantPanel() {
|
||
const list = document.getElementById('variantList');
|
||
const keys = Object.keys(variants);
|
||
if (keys.length === 0) {
|
||
list.innerHTML = '<div class="variant-empty">暂无多方案模块<br><span style="font-size: 11px;">在 variants 配置中添加模块即可</span></div>';
|
||
return;
|
||
}
|
||
list.innerHTML = keys.map(id => {
|
||
const v = variants[id];
|
||
const opts = Object.entries(v.options).map(([key, label]) =>
|
||
`<div class="variant-opt ${v.current===key?'active':''}" onclick="switchVariant('${id}','${key}')">${label}</div>`
|
||
).join('');
|
||
return `<div class="variant-module"><div class="variant-module-label">${id}</div><div class="variant-options">${opts}</div></div>`;
|
||
}).join('');
|
||
}
|
||
|
||
// 页面加载时初始化面板
|
||
document.addEventListener('DOMContentLoaded', renderVariantPanel);
|
||
|
||
// 调试:URL hash 直跳(如 #home / #welfare / #profile)
|
||
document.addEventListener('DOMContentLoaded', function() {
|
||
var h = (location.hash || '').replace(/^#/, '');
|
||
if (h && document.getElementById(h)) {
|
||
setTimeout(function(){ try { go(h); } catch(e){} }, 80);
|
||
}
|
||
});
|
||
|
||
// ===== 用户案例翻页横幅 =====
|
||
var FLIP_AVATARS = ['🦊','🐱','🐶','🐻','🐼','🐨','🐯','🦁','🐮','🐷','🐸','🐵','🐔','🐧','🦆','🦅','🦉','🐺','🐗','🦄','🐝','🦋','🐞','🦜','🦩','🐢','🐙','🦀','🐠','🐬','🐳','🦈','🌸','🌻','🌺','🌷','🍎','🍑','🍓','🍉','🍊','🥭','🍇','🥝','🌶','🌮','🍔','🍕','🍜','🥟'];
|
||
var FLIP_BG = ['#FFE0B2','#FFCCBC','#FFAB91','#F8BBD0','#E1BEE7','#C5CAE9','#B3E5FC','#B2EBF2','#B2DFDB','#C8E6C9','#DCEDC8','#F0F4C3','#FFF59D','#FFE082','#FFCC80','#FFAB91','#BCAAA4','#CFD8DC','#FFCDD2','#D1C4E9'];
|
||
var FLIP_NAMES = [
|
||
'省钱小达人','抠门大魔王','优惠券猎人','比价老司机','折扣专家',
|
||
'拼单狂魔','薅羊毛达人','一只小鹿','花猫不喝酒','天天吃辣条',
|
||
'想变有钱人','哈哈哈是我','安静的咸鱼','奶茶续命中','干饭人本人',
|
||
'云上漫步者','向日葵不晒','糖醋排骨饭','北漂十年','打工累了',
|
||
'不熬夜星人','早睡早起队','宇宙小行星','深夜放毒','贪吃的橘子',
|
||
'永远不胖派','减肥进行时','咖啡因爱好者','下班想躺平','键盘侠本侠',
|
||
'佛系青年','努力上进鸡','摸鱼小能手','加班狗一只','周一不想动',
|
||
'周五最快乐','双十一战神','凑单小能手','满减狂魔','省一块是一块',
|
||
'外卖红包党','比价才下单','看完三家再买','不冲动消费','理智剁手党',
|
||
'存钱罐已满','月光警告','钱包瘦身中','大脑买买买','手刹车住'
|
||
];
|
||
var FLIP_VERBS = [
|
||
'通过比价省了','点外卖省了','刚省了','单笔省了','下单时省了',
|
||
'比价后省了','用券省了','薅到了','这单省了'
|
||
];
|
||
|
||
function buildFlipCases() {
|
||
var cases = [];
|
||
for (var i = 0; i < FLIP_NAMES.length; i++) {
|
||
var amount = (Math.random() * 27 + 3).toFixed(1); // 3.0 - 30.0
|
||
cases.push({
|
||
avatar: FLIP_AVATARS[i % FLIP_AVATARS.length],
|
||
bg: FLIP_BG[i % FLIP_BG.length],
|
||
name: FLIP_NAMES[i],
|
||
verb: FLIP_VERBS[i % FLIP_VERBS.length],
|
||
amount: amount,
|
||
});
|
||
}
|
||
// 洗牌一下避免按顺序露馅
|
||
for (var j = cases.length - 1; j > 0; j--) {
|
||
var k = Math.floor(Math.random() * (j + 1));
|
||
var t = cases[j]; cases[j] = cases[k]; cases[k] = t;
|
||
}
|
||
return cases;
|
||
}
|
||
|
||
function flipCaseHTML(c) {
|
||
return '<span class="flip-banner-avatar" style="background: ' + c.bg + '">' + c.avatar + '</span>'
|
||
+ '<span class="flip-banner-text"><span class="flip-name">' + c.name + '</span>' + c.verb + '<em>¥' + c.amount + '</em></span>';
|
||
}
|
||
|
||
var flipCases = [];
|
||
var flipIdx = 0;
|
||
var flipping = false;
|
||
function startFlipBanner() {
|
||
var banner = document.getElementById('flipBanner');
|
||
var front = document.getElementById('flipBannerFront');
|
||
var back = document.getElementById('flipBannerBack');
|
||
if (!banner || !front || !back) return;
|
||
flipCases = buildFlipCases();
|
||
front.innerHTML = flipCaseHTML(flipCases[0]);
|
||
back.innerHTML = flipCaseHTML(flipCases[1 % flipCases.length]);
|
||
setInterval(function() {
|
||
if (flipping) return;
|
||
flipping = true;
|
||
banner.classList.add('flipping');
|
||
setTimeout(function() {
|
||
flipIdx = (flipIdx + 1) % flipCases.length;
|
||
// 翻转完成后,把当前 back 内容搬到 front,瞬时复位(无 transition)
|
||
front.innerHTML = flipCaseHTML(flipCases[flipIdx]);
|
||
var stage = document.getElementById('flipBannerStage');
|
||
stage.style.transition = 'none';
|
||
banner.classList.remove('flipping');
|
||
void stage.offsetWidth; // 强制重排
|
||
stage.style.transition = '';
|
||
back.innerHTML = flipCaseHTML(flipCases[(flipIdx + 1) % flipCases.length]);
|
||
flipping = false;
|
||
}, 560);
|
||
}, 2800);
|
||
}
|
||
document.addEventListener('DOMContentLoaded', startFlipBanner);
|
||
|
||
// 页面历史栈(同时驱动左下角调试按钮和页面内的「← 返回」按钮)
|
||
var screenHistory = ['splash'];
|
||
|
||
// 统一返回:pop 一格回到上一步,不再 push
|
||
function goBack() {
|
||
if (screenHistory.length <= 1) return; // 已经在起点,无效
|
||
screenHistory.pop();
|
||
var prev = screenHistory[screenHistory.length - 1];
|
||
_activateScreen(prev, /*pushHistory=*/false);
|
||
}
|
||
|
||
// 调试按钮(左下角)走同一逻辑
|
||
function debugGoBack() { goBack(); }
|
||
|
||
function openProfileCompareHistory() {
|
||
location.href = '../history/index.html?from=profile';
|
||
}
|
||
|
||
// 仅切换 DOM active 态(不触发登录拦截、不入栈),供 goBack 复用
|
||
function _activateScreen(resolvedId, pushHistory) {
|
||
document.querySelectorAll('.screen').forEach(function(s) { s.classList.remove('active'); });
|
||
document.getElementById(resolvedId).classList.add('active');
|
||
if (pushHistory && screenHistory[screenHistory.length - 1] !== resolvedId) {
|
||
screenHistory.push(resolvedId);
|
||
}
|
||
}
|
||
|
||
function go(id) {
|
||
// 未登录 + 首次进入福利/我的 → 先跳登录页
|
||
if (!isLoggedIn && id === 'welfare' && !welfareVisited) {
|
||
welfareVisited = true; try{localStorage.setItem('proto_welfareVisited','true');}catch(e){}
|
||
loginFrom='welfare'; try{localStorage.setItem('proto_loginFrom','welfare');}catch(e){}
|
||
id = 'login';
|
||
}
|
||
if (!isLoggedIn && id === 'profile' && !profileVisited) {
|
||
profileVisited = true; try{localStorage.setItem('proto_profileVisited','true');}catch(e){}
|
||
loginFrom='profile'; try{localStorage.setItem('proto_loginFrom','profile');}catch(e){}
|
||
id = 'login';
|
||
}
|
||
|
||
// 方案切换:解析实际 screen id
|
||
var resolvedId = resolveScreenId(id);
|
||
|
||
_activateScreen(resolvedId, /*pushHistory=*/true);
|
||
|
||
// 切换福利页登录态
|
||
if (id === 'welfare') {
|
||
document.getElementById('welfareUnlogged').style.display = isLoggedIn ? 'none' : 'block';
|
||
document.getElementById('welfareLogged').style.display = isLoggedIn ? 'block' : 'none';
|
||
updateWelfareCheckinTask();
|
||
if (isLoggedIn) {
|
||
animateWelfareAssetIntro();
|
||
}
|
||
if (isLoggedIn && !checkinDone && !checkinShown && !checkinPending) {
|
||
checkinPending = true;
|
||
setTimeout(function() {
|
||
checkinPending = false;
|
||
var active = document.querySelector('.screen.active');
|
||
if (isLoggedIn && !checkinDone && !checkinShown && active && active.id === 'welfare') {
|
||
checkinShown = true; try{localStorage.setItem('proto_checkinShown','true');}catch(e){}
|
||
showCheckinPopup();
|
||
}
|
||
}, 500);
|
||
}
|
||
}
|
||
// 切换我的页登录态
|
||
if (id === 'profile') {
|
||
document.getElementById('profileUnlogged').style.display = isLoggedIn ? 'none' : 'block';
|
||
document.getElementById('profileLogged').style.display = isLoggedIn ? 'block' : 'none';
|
||
}
|
||
|
||
if (id === 'productselect') { startPlatformScan(); }
|
||
if (id === 'celebResults' || id === 'celebration') { renderCelebrationSavings(); renderResults('celebResults'); startConfetti(); }
|
||
if (id === 'compresult') { renderResults('compResultList'); }
|
||
if (id === 'comparing') { startComparison(); }
|
||
if (id === 'home') { if (typeof renderTriClaim === 'function') renderTriClaim(); }
|
||
}
|
||
|
||
// 登录页返回 → 走统一的 goBack(pop 历史栈)
|
||
function loginGoBack() { goBack(); }
|
||
|
||
// ===== 签到弹窗 =====
|
||
const CHECKIN_MAX_DAY = 14;
|
||
const CHECKIN_REWARD_RULES = [
|
||
{ day: 1, amount: 180 },
|
||
{ day: 2, amount: 380 },
|
||
{ day: 3, amount: 220 },
|
||
{ day: 4, amount: 260 },
|
||
{ day: 5, amount: 320 },
|
||
{ day: 6, amount: 420 },
|
||
{ day: 7, amount: 888 },
|
||
{ day: 8, amount: 360 },
|
||
{ day: 9, amount: 460 },
|
||
{ day: 10, amount: 520 },
|
||
{ day: 11, amount: 680 },
|
||
{ day: 12, amount: 1088 },
|
||
{ day: 13, amount: 1688 },
|
||
{ day: 14, amount: 2888 },
|
||
];
|
||
const CHECKIN_REWARD_ASSETS = {
|
||
coin: '../../assets/welfare/index/checkin-coin-single.png',
|
||
coins: '../../assets/welfare/index/checkin-coins-600.png',
|
||
bigCoins: '../../assets/welfare/index/checkin-coins-3888.png',
|
||
chest: '../../assets/welfare/index/checkin-chest-8888.png'
|
||
};
|
||
let checkinShown = (typeof localStorage !== 'undefined' && localStorage.getItem('proto_checkinShown') === 'true');
|
||
let checkinPending = false;
|
||
let checkinDone = false;
|
||
let checkinCompletedBeforeToday = 2;
|
||
|
||
function getCheckinTodayDay() {
|
||
return Math.min(checkinCompletedBeforeToday + 1, CHECKIN_MAX_DAY);
|
||
}
|
||
|
||
function getCheckinCurrentStreak() {
|
||
return Math.min(checkinCompletedBeforeToday + (checkinDone ? 1 : 0), CHECKIN_MAX_DAY);
|
||
}
|
||
|
||
function getCheckinReward(day) {
|
||
var found = CHECKIN_REWARD_RULES.find(function(item) { return item.day === day; });
|
||
return found ? found.amount : 0;
|
||
}
|
||
|
||
function getCheckinMaxReward() {
|
||
return CHECKIN_REWARD_RULES.reduce(function(max, item) {
|
||
return Math.max(max, item.amount);
|
||
}, 0);
|
||
}
|
||
|
||
function getCheckinRewardAsset(day) {
|
||
var amount = getCheckinReward(day);
|
||
if (day === CHECKIN_MAX_DAY) return CHECKIN_REWARD_ASSETS.chest;
|
||
if (amount >= 1000) return CHECKIN_REWARD_ASSETS.bigCoins;
|
||
if (amount >= 680) return CHECKIN_REWARD_ASSETS.coins;
|
||
return CHECKIN_REWARD_ASSETS.coin;
|
||
}
|
||
|
||
function getCheckinLabel(day) {
|
||
var today = getCheckinTodayDay();
|
||
if (day === today) return '今天';
|
||
if (day === today + 1) return '明天';
|
||
return '第' + day + '天';
|
||
}
|
||
|
||
function getCheckinVisibleDays() {
|
||
var today = getCheckinTodayDay();
|
||
var days = [];
|
||
var start = Math.max(1, today - 2);
|
||
for (var day = start; day <= today; day++) days.push(day);
|
||
if (today < CHECKIN_MAX_DAY) days.push(today + 1);
|
||
|
||
[7, 14].some(function(milestone) {
|
||
if (milestone > today + 1) {
|
||
days.push(milestone);
|
||
return true;
|
||
}
|
||
return false;
|
||
});
|
||
|
||
for (var next = today + 2; next <= CHECKIN_MAX_DAY && days.length < 5; next++) {
|
||
days.push(next);
|
||
}
|
||
days = Array.from(new Set(days)).sort(function(a, b) { return a - b; });
|
||
while (days.length < 5 && days[0] > 1) {
|
||
days.unshift(days[0] - 1);
|
||
}
|
||
return days.slice(-5);
|
||
}
|
||
|
||
function getCheckinStep(day) {
|
||
var today = getCheckinTodayDay();
|
||
var completed = getCheckinCurrentStreak();
|
||
var isToday = day === today;
|
||
var isTomorrow = day === today + 1;
|
||
var isDone = day <= completed;
|
||
var isNextTarget = (!checkinDone && isToday) || (checkinDone && isTomorrow);
|
||
return {
|
||
day: day,
|
||
amount: getCheckinReward(day),
|
||
label: getCheckinLabel(day),
|
||
isDone: isDone,
|
||
isToday: isToday,
|
||
isTomorrow: isTomorrow,
|
||
isCurrent: isNextTarget,
|
||
isJustDone: checkinDone && isToday,
|
||
isMilestone: day === 7 || day === CHECKIN_MAX_DAY,
|
||
img: getCheckinRewardAsset(day)
|
||
};
|
||
}
|
||
|
||
function getCheckinSteps() {
|
||
return getCheckinVisibleDays().map(getCheckinStep);
|
||
}
|
||
|
||
function renderWelfareCheckinTimeline() {
|
||
var timeline = document.getElementById('r8CheckinTimeline');
|
||
if (!timeline) return;
|
||
|
||
timeline.innerHTML = getCheckinSteps().map(function(step) {
|
||
var classes = ['r8-checkin-step'];
|
||
if (step.isDone) classes.push('done');
|
||
if (step.isCurrent) classes.push('current');
|
||
if (step.isJustDone) classes.push('just-done');
|
||
if (step.day === CHECKIN_MAX_DAY) classes.push('most');
|
||
|
||
var top = step.isCurrent
|
||
? '<div class="r8-checkin-step-badge">' + (step.isTomorrow ? '明天' : '今天领') + '</div>'
|
||
: '<div class="r8-checkin-step-label">' + step.label + '</div>';
|
||
var icon = step.isDone
|
||
? '<div class="r8-checkin-step-icon"></div>'
|
||
: '<div class="r8-checkin-step-icon"><img src="' + step.img + '" alt=""></div>';
|
||
|
||
return '<div class="' + classes.join(' ') + '">' + top + icon + '<div class="r8-checkin-step-amount">' + step.amount + '</div></div>';
|
||
}).join('');
|
||
}
|
||
|
||
function renderCheckinPopupRewards() {
|
||
var rewards = document.getElementById('checkinRewards');
|
||
if (!rewards) return;
|
||
|
||
rewards.innerHTML = getCheckinSteps().map(function(step) {
|
||
var classes = ['checkin-reward-card'];
|
||
if (step.isDone) classes.push('claimed');
|
||
if (!step.isDone && step.isToday && !checkinDone) classes.push('current');
|
||
var icon = step.isDone
|
||
? '<div class="checkin-reward-icon">已领取</div>'
|
||
: '<div class="checkin-reward-icon"><img' + (step.day === CHECKIN_MAX_DAY ? ' class="icon-chest"' : '') + ' src="' + step.img + '" alt=""></div>';
|
||
|
||
return '<div class="' + classes.join(' ') + '">' + icon + '<div class="checkin-reward-amount">' + step.amount + '</div></div>';
|
||
}).join('');
|
||
}
|
||
|
||
function renderCheckinPopupProgress() {
|
||
var progress = document.getElementById('checkinProgress');
|
||
if (!progress) return;
|
||
|
||
progress.innerHTML = '<div class="checkin-progress-lines" id="checkinProgressLines"></div>' + getCheckinSteps().map(function(step) {
|
||
var classes = ['checkin-node'];
|
||
if (step.isDone) classes.push('done');
|
||
if (step.isCurrent) classes.push('current');
|
||
return '<div class="' + classes.join(' ') + '" data-day="' + step.day + '"><span class="checkin-dot"></span><span>' + step.label + '</span></div>';
|
||
}).join('');
|
||
}
|
||
|
||
function updateCheckinPopupCopy() {
|
||
var banner = document.getElementById('checkinBanner');
|
||
var title = document.getElementById('checkinPopupTitle');
|
||
var sub = document.getElementById('checkinPopupSub');
|
||
var btn = document.getElementById('checkinBtn');
|
||
var reminderBtn = document.getElementById('checkinReminderBtn');
|
||
var today = getCheckinTodayDay();
|
||
var streak = getCheckinCurrentStreak();
|
||
var todayReward = getCheckinReward(today);
|
||
var nextDay = Math.min(today + 1, CHECKIN_MAX_DAY);
|
||
var nextReward = getCheckinReward(nextDay);
|
||
|
||
if (banner) banner.innerHTML = '<span class="star"></span>连续签到14天 最高可领' + getCheckinMaxReward() + '金币';
|
||
if (title) title.textContent = checkinDone ? '今日金币已领取' : '签到领取今日金币';
|
||
if (sub) {
|
||
if (checkinDone && today >= CHECKIN_MAX_DAY) {
|
||
sub.innerHTML = '已完成 <b>14</b> 天签到,今日大奖已领取';
|
||
} else if (checkinDone) {
|
||
sub.innerHTML = '已连续签到 <b>' + streak + '</b> 天,明天可领 <b>' + nextReward + '</b> 金币';
|
||
} else {
|
||
sub.innerHTML = '已连续签到 <b>' + streak + '</b> 天,今天可领 <b>' + todayReward + '</b> 金币';
|
||
}
|
||
}
|
||
if (btn) {
|
||
btn.innerHTML = '签到领 <img src="' + CHECKIN_REWARD_ASSETS.coin + '" alt=""><b>' + todayReward + '</b>';
|
||
btn.style.display = checkinDone ? 'none' : 'flex';
|
||
}
|
||
if (reminderBtn) reminderBtn.style.display = checkinDone ? 'flex' : 'none';
|
||
}
|
||
|
||
function renderCheckinPopup() {
|
||
updateCheckinPopupCopy();
|
||
renderCheckinPopupRewards();
|
||
renderCheckinPopupProgress();
|
||
requestAnimationFrame(renderCheckinProgressLines);
|
||
}
|
||
|
||
function updateWelfareCheckinTask() {
|
||
var taskCard = document.getElementById('r8TaskCard');
|
||
var row = document.getElementById('r8CheckinTaskRow');
|
||
var recordBlock = document.getElementById('r8RecordTaskBlock');
|
||
var title = document.getElementById('r8CheckinTaskTitle');
|
||
var sub = document.getElementById('r8CheckinTaskSub');
|
||
var cta = document.getElementById('r8CheckinTaskCta');
|
||
var headline = document.getElementById('r8CheckinHeadline');
|
||
var cardCta = document.getElementById('r8CheckinCardCta');
|
||
if (!taskCard || !row || !recordBlock) return;
|
||
|
||
var today = getCheckinTodayDay();
|
||
var streak = getCheckinCurrentStreak();
|
||
var todayReward = getCheckinReward(today);
|
||
var nextDay = Math.min(today + 1, CHECKIN_MAX_DAY);
|
||
var nextReward = getCheckinReward(nextDay);
|
||
|
||
row.classList.toggle('is-done', checkinDone);
|
||
taskCard.insertBefore(row, recordBlock);
|
||
if (title) title.textContent = '新人签到领金币';
|
||
if (sub) {
|
||
sub.textContent = checkinDone
|
||
? (today >= CHECKIN_MAX_DAY ? '已完成14天签到,今日大奖已领取' : '已连续签到 ' + streak + ' 天,明天可领 ' + nextReward + ' 金币')
|
||
: '已连续签到 ' + streak + ' 天,今日可领 ' + todayReward + ' 金币';
|
||
}
|
||
if (cta) cta.textContent = checkinDone ? '去查看' : '去签到';
|
||
renderWelfareCheckinTimeline();
|
||
if (checkinDone) {
|
||
if (headline) headline.innerHTML = '已连续签到<span class="num">' + streak + '</span>天';
|
||
if (cardCta) cardCta.innerHTML = '<span class="check-tick">✓</span>今日已签';
|
||
} else {
|
||
if (headline) headline.textContent = '今日签到领金币';
|
||
if (cardCta) cardCta.textContent = '去签到';
|
||
}
|
||
}
|
||
|
||
function openCheckinTask() {
|
||
showCheckinPopup();
|
||
}
|
||
|
||
function renderCheckinProgressLines() {
|
||
var progress = document.getElementById('checkinProgress');
|
||
var lines = document.getElementById('checkinProgressLines');
|
||
if (!progress || !lines) return;
|
||
var nodes = Array.prototype.slice.call(progress.querySelectorAll('.checkin-node'));
|
||
if (nodes.length < 2) return;
|
||
lines.innerHTML = '';
|
||
var progressRect = progress.getBoundingClientRect();
|
||
var completed = getCheckinCurrentStreak();
|
||
var targetDay = checkinDone ? Math.min(getCheckinTodayDay() + 1, CHECKIN_MAX_DAY) : getCheckinTodayDay();
|
||
|
||
nodes.forEach(function(node, index) {
|
||
var next = nodes[index + 1];
|
||
if (!next) return;
|
||
var dot = node.querySelector('.checkin-dot');
|
||
var nextDot = next.querySelector('.checkin-dot');
|
||
if (!dot || !nextDot) return;
|
||
|
||
var dotRect = dot.getBoundingClientRect();
|
||
var nextDotRect = nextDot.getBoundingClientRect();
|
||
var x1Center = dotRect.left + dotRect.width / 2 - progressRect.left;
|
||
var x2Center = nextDotRect.left + nextDotRect.width / 2 - progressRect.left;
|
||
var dotRadius = dotRect.width / 2;
|
||
var nextDotRadius = nextDotRect.width / 2;
|
||
var day = Number(node.dataset.day || 0);
|
||
var nextDay = Number(next.dataset.day || 0);
|
||
var isDashed = nextDay - day > 1;
|
||
var x1 = isDashed ? x1Center + dotRadius : x1Center;
|
||
var x2 = isDashed ? x2Center - nextDotRadius : x2Center;
|
||
var width = Math.max(0, x2 - x1);
|
||
var color = (nextDay <= completed || nextDay === targetDay) ? '#FFB800' : '#D9D9D9';
|
||
|
||
var segment = document.createElement('span');
|
||
segment.className = 'checkin-segment ' + (isDashed ? 'dashed' : 'solid');
|
||
segment.style.left = x1 + 'px';
|
||
segment.style.width = width + 'px';
|
||
segment.style.setProperty('--line-color', color);
|
||
if (isDashed) {
|
||
var dashCount = 4;
|
||
var gap = Math.max(4, Math.min(5, width / 10));
|
||
var dash = Math.max(4, (width - gap * (dashCount + 1)) / dashCount);
|
||
for (var i = 0; i < dashCount; i++) {
|
||
var dashEl = document.createElement('i');
|
||
dashEl.style.cssText = 'position:absolute;top:0;height:3px;border-radius:99px;background:' + color + ';left:' + (gap + i * (dash + gap)) + 'px;width:' + dash + 'px;';
|
||
segment.appendChild(dashEl);
|
||
}
|
||
}
|
||
lines.appendChild(segment);
|
||
});
|
||
}
|
||
|
||
window.addEventListener('resize', function() {
|
||
var popup = document.getElementById('checkinPopup');
|
||
if (popup && getComputedStyle(popup).display !== 'none') renderCheckinProgressLines();
|
||
});
|
||
|
||
function showCheckinPopup() {
|
||
var popup = document.getElementById('checkinPopup');
|
||
if (!popup) return;
|
||
popup.style.display = 'flex';
|
||
renderCheckinPopup();
|
||
}
|
||
|
||
function closeCheckinPopup() {
|
||
document.getElementById('checkinPopup').style.display = 'none';
|
||
}
|
||
|
||
function doCheckin() {
|
||
if (checkinDone) return;
|
||
var todayReward = getCheckinReward(getCheckinTodayDay());
|
||
checkinDone = true;
|
||
updateWelfareCheckinTask();
|
||
renderCheckinPopup();
|
||
claimTaskReward('签到奖励', todayReward);
|
||
}
|
||
|
||
function doCheckinReminder() {
|
||
// 模拟权限弹窗
|
||
document.getElementById('calendarPermPopup').style.display = 'flex';
|
||
}
|
||
|
||
function closeCalendarPerm() {
|
||
document.getElementById('calendarPermPopup').style.display = 'none';
|
||
closeCheckinPopup();
|
||
}
|
||
|
||
|
||
// ===== 新手礼包 + 优惠券流程 =====
|
||
function showWelcomeGiftPopup() {
|
||
document.getElementById('welcomeGiftPopup').classList.add('show');
|
||
}
|
||
|
||
function openGiftBox() {
|
||
if (welcomeGiftClaimed) return;
|
||
var card = document.getElementById('welcomeGiftCard');
|
||
var chest = document.getElementById('giftChestEmoji');
|
||
var btn = document.getElementById('giftMainBtn');
|
||
|
||
// 阶段 A → B:宝箱开盖
|
||
card.classList.add('opening');
|
||
setTimeout(function() {
|
||
chest.textContent = '📦';
|
||
card.classList.remove('opening');
|
||
card.classList.add('opened');
|
||
flyCoinsToWelfareTab();
|
||
// 福利 tab 数字滚动 + badge + pulse
|
||
setTimeout(function() {
|
||
var tabItem = document.getElementById('homeTabWelfare');
|
||
var tabIcon = document.getElementById('homeTabWelfareIcon');
|
||
if (tabItem) {
|
||
// 临时提升 z-index 让 tab 浮在 overlay 之上
|
||
tabItem.style.position = 'relative';
|
||
tabItem.style.zIndex = '260';
|
||
}
|
||
if (tabIcon) {
|
||
tabIcon.classList.remove('tab-pulse');
|
||
// 触发重排以重启动画
|
||
void tabIcon.offsetWidth;
|
||
tabIcon.classList.add('tab-pulse');
|
||
}
|
||
var badge = document.getElementById('welfareTabBadge');
|
||
badge.classList.remove('show');
|
||
void badge.offsetWidth;
|
||
badge.classList.add('show');
|
||
// 余额在当前 mock 基数上累加新手礼包。
|
||
var coinStart = welfareCoinBalance;
|
||
var coinEnd = coinStart + 5000;
|
||
var cashEl = document.getElementById('welfareCashBalance');
|
||
var cashStart = parseFloat((cashEl && cashEl.textContent || '0').replace(/,/g, '')) || 0;
|
||
var cashEnd = cashStart + 0.5;
|
||
welfareCoinBalance = coinEnd;
|
||
welfareCashBalance = cashEnd;
|
||
animateNumber(document.getElementById('welfareCoinBalance'), coinStart, coinEnd, 1200, function(v) {
|
||
return v.toLocaleString();
|
||
});
|
||
animateNumber(cashEl, cashStart, cashEnd, 1200, function(v) {
|
||
return v.toFixed(2);
|
||
});
|
||
}, 600);
|
||
// 主按钮切换
|
||
btn.textContent = '开心收下,立即使用';
|
||
btn.onclick = claimGift;
|
||
}, 300);
|
||
}
|
||
|
||
function flyCoinsToWelfareTab() {
|
||
var card = document.getElementById('welcomeGiftCard');
|
||
var device = document.getElementById('app');
|
||
var tabIcon = document.getElementById('homeTabWelfareIcon');
|
||
if (!card || !device || !tabIcon) return;
|
||
|
||
var deviceRect = device.getBoundingClientRect();
|
||
var cardRect = card.getBoundingClientRect();
|
||
var tabRect = tabIcon.getBoundingClientRect();
|
||
|
||
// 宝箱中心相对于 device 的坐标
|
||
var startX = (cardRect.left + cardRect.width / 2) - deviceRect.left;
|
||
var startY = (cardRect.top + cardRect.height / 2) - deviceRect.top;
|
||
// 福利 tab 图标中心
|
||
var endX = (tabRect.left + tabRect.width / 2) - deviceRect.left;
|
||
var endY = (tabRect.top + tabRect.height / 2) - deviceRect.top;
|
||
|
||
var COIN_COUNT = 16;
|
||
for (var i = 0; i < COIN_COUNT; i++) {
|
||
var coin = document.createElement('div');
|
||
coin.className = 'fly-coin';
|
||
coin.textContent = '🪙';
|
||
// 起点定位(绝对定位 in device)
|
||
coin.style.left = startX + 'px';
|
||
coin.style.top = startY + 'px';
|
||
// burst 散射点(爆开瞬间)
|
||
var angle = (Math.PI * 2 * i) / COIN_COUNT + Math.random() * 0.4;
|
||
var burstDist = 60 + Math.random() * 60;
|
||
var bx = Math.cos(angle) * burstDist;
|
||
var by = Math.sin(angle) * burstDist - 30; // 略偏上
|
||
// 终点偏移(相对起点)
|
||
var tx = endX - startX + (Math.random() - 0.5) * 16;
|
||
var ty = endY - startY + (Math.random() - 0.5) * 8;
|
||
coin.style.setProperty('--bx', bx + 'px');
|
||
coin.style.setProperty('--by', by + 'px');
|
||
coin.style.setProperty('--tx', tx + 'px');
|
||
coin.style.setProperty('--ty', ty + 'px');
|
||
coin.style.setProperty('--d', (i * 18) + 'ms');
|
||
device.appendChild(coin);
|
||
// 动画结束后移除
|
||
coin.addEventListener('animationend', function() {
|
||
this.remove();
|
||
});
|
||
}
|
||
}
|
||
|
||
function animateWelfareAssetIntro() {
|
||
animateNumber(document.getElementById('welfareCoinBalance'), 0, welfareCoinBalance, 760, function(v) {
|
||
return Math.round(v).toLocaleString();
|
||
});
|
||
animateNumber(document.getElementById('welfareCashBalance'), 0, welfareCashBalance, 760, function(v) {
|
||
return v.toFixed(2);
|
||
});
|
||
}
|
||
|
||
function claimTaskReward(title, amount) {
|
||
var start = welfareCoinBalance;
|
||
welfareCoinBalance += amount;
|
||
animateNumber(document.getElementById('welfareCoinBalance'), start, welfareCoinBalance, amount >= 1000 ? 860 : 680, function(v) {
|
||
return Math.round(v).toLocaleString();
|
||
});
|
||
showRewardToast(title, amount);
|
||
}
|
||
|
||
function showRewardToast(title, amount) {
|
||
var existing = document.getElementById('rewardToast');
|
||
if (existing) existing.remove();
|
||
|
||
var toast = document.createElement('div');
|
||
toast.id = 'rewardToast';
|
||
toast.className = 'reward-toast';
|
||
|
||
var icon = document.createElement('img');
|
||
icon.className = 'reward-toast-icon';
|
||
icon.src = '../../assets/welfare/index/checkin-coins-600.png';
|
||
icon.alt = '';
|
||
|
||
var amountEl = document.createElement('div');
|
||
amountEl.className = 'reward-toast-amount';
|
||
amountEl.textContent = '+' + Math.round(amount).toLocaleString();
|
||
|
||
var titleEl = document.createElement('div');
|
||
titleEl.className = 'reward-toast-title';
|
||
titleEl.textContent = title;
|
||
|
||
toast.appendChild(icon);
|
||
toast.appendChild(amountEl);
|
||
toast.appendChild(titleEl);
|
||
document.getElementById('app').appendChild(toast);
|
||
|
||
setTimeout(function() {
|
||
toast.classList.add('is-leaving');
|
||
}, 1450);
|
||
setTimeout(function() {
|
||
if (toast.parentNode) toast.remove();
|
||
}, 1700);
|
||
}
|
||
|
||
function claimVideoReward() {
|
||
if (videoRewardClaimed) return;
|
||
videoRewardClaimed = true;
|
||
claimTaskReward('任务奖励', 1859);
|
||
var cta = document.getElementById('r8VideoTaskCta');
|
||
if (cta) {
|
||
cta.textContent = '已领取';
|
||
cta.classList.add('is-done');
|
||
cta.disabled = true;
|
||
}
|
||
}
|
||
|
||
function claimMessageReminderReward() {
|
||
if (messageReminderRewardClaimed) return;
|
||
messageReminderRewardClaimed = true;
|
||
claimTaskReward('任务奖励', 10000);
|
||
var cta = document.getElementById('r8MessageTaskCta');
|
||
var sub = document.getElementById('r8MessageTaskSub');
|
||
if (sub) sub.textContent = '消息提醒已开启';
|
||
if (cta) {
|
||
cta.textContent = '已开启';
|
||
cta.classList.add('is-done');
|
||
cta.disabled = true;
|
||
}
|
||
}
|
||
|
||
function claimRecordComparisonReward() {
|
||
if (recordComparisonRewardClaimed) return;
|
||
recordComparisonRewardClaimed = true;
|
||
|
||
var activeBox = document.querySelector('#r8RecordTaskBlock .r8-record-reward-box.active');
|
||
if (activeBox) {
|
||
activeBox.classList.remove('active');
|
||
activeBox.classList.add('done');
|
||
var status = activeBox.querySelector('.r8-record-status');
|
||
if (status) status.textContent = '已领取';
|
||
var coin = activeBox.querySelector('.r8-record-coin');
|
||
if (coin) coin.remove();
|
||
if (activeBox.tagName === 'BUTTON') {
|
||
activeBox.disabled = true;
|
||
activeBox.setAttribute('aria-label', '第2次记录比价奖励已领取180金币');
|
||
}
|
||
}
|
||
|
||
claimTaskReward('比价奖励', 180);
|
||
}
|
||
|
||
function animateNumber(el, from, to, duration, formatter) {
|
||
if (!el) return;
|
||
el.__animateNumberToken = (el.__animateNumberToken || 0) + 1;
|
||
var token = el.__animateNumberToken;
|
||
var start = performance.now();
|
||
function frame(now) {
|
||
if (token !== el.__animateNumberToken) return;
|
||
var t = Math.min(1, (now - start) / duration);
|
||
var eased = 1 - Math.pow(1 - t, 3); // ease-out cubic
|
||
var v = from + (to - from) * eased;
|
||
el.textContent = formatter ? formatter(v) : Math.round(v).toString();
|
||
if (t < 1) requestAnimationFrame(frame);
|
||
else el.textContent = formatter ? formatter(to) : to.toString();
|
||
}
|
||
requestAnimationFrame(frame);
|
||
}
|
||
|
||
function claimGift() {
|
||
welcomeGiftClaimed = true;
|
||
closeWelcomeGift(false);
|
||
}
|
||
|
||
function closeWelcomeGift(skipped) {
|
||
document.getElementById('welcomeGiftPopup').classList.remove('show');
|
||
// 还原 tab 的 z-index
|
||
var tabItem = document.getElementById('homeTabWelfare');
|
||
if (tabItem) {
|
||
tabItem.style.position = '';
|
||
tabItem.style.zIndex = '';
|
||
}
|
||
if (skipped) {
|
||
// 重置卡片为初始状态以备重弹(但目前 welcomeGiftShown 已 true,不会重弹)
|
||
var card = document.getElementById('welcomeGiftCard');
|
||
card.classList.remove('opened');
|
||
document.getElementById('giftChestEmoji').textContent = '🎁';
|
||
var btn = document.getElementById('giftMainBtn');
|
||
btn.textContent = '✨ 开启礼包';
|
||
btn.onclick = openGiftBox;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
// ===== 登录流程 =====
|
||
let pendingLoginAction = null; // 记录待执行的登录动作
|
||
|
||
function showToast(msg) {
|
||
var t = document.getElementById('loginToast');
|
||
t.textContent = msg;
|
||
t.style.display = 'block';
|
||
setTimeout(function(){ t.style.display = 'none'; }, 2000);
|
||
}
|
||
|
||
function toggleAgreeCheck() {
|
||
var chk = document.getElementById('agreeCheck');
|
||
chk.classList.toggle('checked');
|
||
var hint = document.getElementById('agreeHint');
|
||
if (hint) hint.style.display = chk.classList.contains('checked') ? 'none' : 'block';
|
||
}
|
||
|
||
function toggleAgreeCheckCeleb() {
|
||
var chk = document.getElementById('agreeCheckCeleb');
|
||
chk.classList.toggle('checked');
|
||
}
|
||
function isAgreedCeleb() {
|
||
return document.getElementById('agreeCheckCeleb').classList.contains('checked');
|
||
}
|
||
function celebOnboardingLogin() {
|
||
if (!isAgreedCeleb()) { showAgreeModal('celeb-quick'); return; }
|
||
doLogin();
|
||
}
|
||
|
||
function togglePhoneAgree() {
|
||
var chk = document.getElementById('agreeCheckPhone');
|
||
chk.classList.toggle('checked');
|
||
}
|
||
|
||
function isAgreed() {
|
||
return document.getElementById('agreeCheck').classList.contains('checked');
|
||
}
|
||
|
||
function isPhoneAgreed() {
|
||
return document.getElementById('agreeCheckPhone').classList.contains('checked');
|
||
}
|
||
|
||
function showAgreeModal(action) {
|
||
pendingLoginAction = action;
|
||
document.getElementById('agreeModal').style.display = 'flex';
|
||
}
|
||
|
||
function closeAgreeModal() {
|
||
document.getElementById('agreeModal').style.display = 'none';
|
||
pendingLoginAction = null;
|
||
}
|
||
|
||
function agreeAndLogin() {
|
||
// 入口页(一键登录):勾选入口页协议并继续
|
||
var chk = document.getElementById('agreeCheck');
|
||
if (chk && !chk.classList.contains('checked')) chk.classList.add('checked');
|
||
// 祝贺页内嵌登录的协议同步勾选
|
||
var chkCeleb = document.getElementById('agreeCheckCeleb');
|
||
if (chkCeleb && !chkCeleb.classList.contains('checked')) chkCeleb.classList.add('checked');
|
||
document.getElementById('agreeModal').style.display = 'none';
|
||
if (pendingLoginAction === 'quick' || pendingLoginAction === 'celeb-quick') {
|
||
doLogin();
|
||
} else if (pendingLoginAction === 'phone') {
|
||
doPhoneLogin();
|
||
}
|
||
pendingLoginAction = null;
|
||
}
|
||
|
||
function showAgreePhoneModal() {
|
||
document.getElementById('agreePhoneModal').style.display = 'flex';
|
||
}
|
||
function closeAgreePhoneModal() {
|
||
document.getElementById('agreePhoneModal').style.display = 'none';
|
||
}
|
||
function agreeAndContinuePhone() {
|
||
var chkP = document.getElementById('agreeCheckPhone');
|
||
if (chkP && !chkP.classList.contains('checked')) chkP.classList.add('checked');
|
||
document.getElementById('agreePhoneModal').style.display = 'none';
|
||
doSendSms();
|
||
}
|
||
|
||
function doLogin() {
|
||
isLoggedIn = true; try{localStorage.setItem('proto_isLoggedIn','true');}catch(e){}
|
||
var target = loginFrom || 'home';
|
||
go(target);
|
||
// 主路径登录(不是从福利/我的回流的) + 首次 → 弹新手礼包
|
||
if (!welcomeGiftShown && target === 'home') {
|
||
welcomeGiftShown = true; try{localStorage.setItem('proto_welcomeGiftShown','true');}catch(e){}
|
||
setTimeout(showWelcomeGiftPopup, 400);
|
||
}
|
||
}
|
||
|
||
function onboardingLogin() {
|
||
if (!isAgreed()) { showAgreeModal('quick'); return; }
|
||
doLogin();
|
||
}
|
||
|
||
function showPhoneLogin() {
|
||
// 进入独立手机号登录页(Step1)
|
||
document.getElementById('lpStep1').style.display = 'block';
|
||
document.getElementById('lpStep2').style.display = 'none';
|
||
go('loginPhone');
|
||
setTimeout(function(){
|
||
var inp = document.getElementById('phoneInput');
|
||
if (inp) inp.focus();
|
||
}, 80);
|
||
}
|
||
|
||
function showQuickLogin() {
|
||
// 用于其他位置返回入口页(保留兼容)
|
||
if (smsTimer) { clearInterval(smsTimer); smsTimer = null; }
|
||
go('login');
|
||
}
|
||
|
||
function updatePhoneCta() {
|
||
var inp = document.getElementById('phoneInput');
|
||
var cta = document.getElementById('lpCta');
|
||
if (!inp || !cta) return;
|
||
if (inp.value.length >= 11) cta.classList.remove('disabled');
|
||
else cta.classList.add('disabled');
|
||
}
|
||
|
||
function backToPhoneStep1() {
|
||
document.getElementById('lpStep2').style.display = 'none';
|
||
document.getElementById('lpStep1').style.display = 'block';
|
||
if (smsTimer) { clearInterval(smsTimer); smsTimer = null; }
|
||
}
|
||
|
||
let smsTimer = null;
|
||
function doSendSms() {
|
||
var phone = document.getElementById('phoneInput').value;
|
||
if (phone.length < 11) { showToast('请输入正确的手机号'); return; }
|
||
// 显示手机号提示(脱敏)
|
||
var masked = phone.substring(0,3) + '****' + phone.substring(7);
|
||
document.getElementById('smsPhoneHint').textContent = '验证码已发送至 ' + masked;
|
||
// 切换到 Step2
|
||
document.getElementById('lpStep1').style.display = 'none';
|
||
document.getElementById('lpStep2').style.display = 'block';
|
||
// 清空验证码输入框
|
||
var boxes = document.getElementById('smsCodeBoxes').querySelectorAll('input');
|
||
boxes.forEach(function(b){ b.value = ''; });
|
||
boxes[0].focus();
|
||
// 倒计时
|
||
var btn = document.getElementById('smsBtn');
|
||
var sec = 60;
|
||
btn.style.color = 'var(--gray-400)';
|
||
btn.style.cursor = 'default';
|
||
btn.onclick = null;
|
||
btn.textContent = sec + 's 后重发';
|
||
smsTimer = setInterval(function(){
|
||
sec--;
|
||
if (sec <= 0) {
|
||
clearInterval(smsTimer);
|
||
smsTimer = null;
|
||
btn.style.color = '#FFD600';
|
||
btn.style.cursor = 'pointer';
|
||
btn.textContent = '重新发送';
|
||
btn.onclick = function(){ doSendSms(); };
|
||
} else {
|
||
btn.textContent = sec + 's 后重发';
|
||
}
|
||
}, 1000);
|
||
}
|
||
|
||
function sendSmsCode() {
|
||
// 手机号页有独立的协议勾选状态 + 独立居中弹窗
|
||
if (!isPhoneAgreed()) { showAgreePhoneModal(); return; }
|
||
doSendSms();
|
||
}
|
||
|
||
function smsCodeComplete() {
|
||
// 6位验证码全部填完,自动登录
|
||
var boxes = document.getElementById('smsCodeBoxes').querySelectorAll('input');
|
||
var code = '';
|
||
boxes.forEach(function(b){ code += b.value; });
|
||
if (code.length === 6) {
|
||
isLoggedIn = true; try{localStorage.setItem('proto_isLoggedIn','true');}catch(e){}
|
||
go(loginFrom || 'home');
|
||
}
|
||
}
|
||
|
||
// ===== 平台选择流程 =====
|
||
// 全量平台列表,外卖版优先;同系优先外卖版,有外卖版则隐藏主站版
|
||
const allApps = [
|
||
{ id: 'meituan-waimai', name: '美团', icon: '../../assets/shared/logos/meituan.png', color: '#FF6B00', bg: '#FFF3E0', desc: '外卖·美食·买菜', installed: true, replaces: 'meituan' },
|
||
{ id: 'taobao-shanguang', name: '淘宝', icon: '../../assets/shared/logos/taobao.png', color: '#FF6A00', bg: '#FFF3E0', desc: '外卖·超市·买药', installed: true, replaces: 'taobao' },
|
||
{ id: 'jd-waimai', name: '京东', icon: '../../assets/shared/logos/jd.png', color: '#E1251B', bg: '#FFEBEE', desc: '品质外卖·新人立减', installed: false, replaces: 'jd' },
|
||
{ id: 'meituan', name: '美团', icon: '../../assets/shared/logos/meituan.png', color: '#FFD600', bg: '#FFFDE7', desc: '团购·到店·买菜', installed: true },
|
||
{ id: 'taobao', name: '淘宝', icon: '../../assets/shared/logos/taobao.png', color: '#FF5000', bg: '#FFF3E0', desc: '网购·百亿补贴', installed: true },
|
||
{ id: 'jd', name: '京东', icon: '../../assets/shared/logos/jd.png', color: '#E1251B', bg: '#FFEBEE', desc: '又好又便宜', installed: true },
|
||
];
|
||
|
||
// 外卖版是这个产品的画布:只要 allApps 里有外卖版条目,就隐藏对应主站版(不论主站是否安装)。
|
||
// 未安装的外卖版仍然在列表里以 disabled 形态展示,强调"我们能比 3 个平台,但你少了 1 个"。
|
||
function getVisibleApps() {
|
||
const replacedIds = new Set(allApps.filter(a => a.replaces).map(a => a.replaces));
|
||
return allApps.filter(a => !replacedIds.has(a.id));
|
||
}
|
||
|
||
// 进入 productselect 时渲染平台列表
|
||
let platformScanDone = false;
|
||
function startPlatformScan() {
|
||
if (platformScanDone) return;
|
||
platformScanDone = true;
|
||
renderPlatformList();
|
||
startRewardCountdown();
|
||
}
|
||
|
||
function renderPlatformList() {
|
||
const visible = getVisibleApps();
|
||
|
||
// 已装 + 未装合并到同一列表,外形对齐,用样式区分 disabled 态
|
||
document.getElementById('installedApps').innerHTML = visible.map((app, i) => {
|
||
if (app.installed) {
|
||
return '' +
|
||
'<div onclick="selectPlatform(\'' + app.id + '\')" data-pcard="' + i + '" class="platform-card" style="background: #fff;border-radius: 14px;padding: 16px 16px;cursor: pointer;display: flex;align-items: center;gap: 12px;border: 1.5px solid var(--gray-200);margin-bottom: 8px;position: relative;transition: border-color .25s,box-shadow .25s,transform .15s;">' +
|
||
'<img src="' + app.icon + '" style="width: 48px;height: 48px;border-radius: 12px;flex-shrink: 0;object-fit: cover;" />' +
|
||
'<div style="flex: 1;min-width: 0;">' +
|
||
'<div style="font-size: 20px;font-weight: 700;color: var(--gray-900);letter-spacing: -.2px;">' + app.name + '</div>' +
|
||
'</div>' +
|
||
'<svg width="20" height="20" viewBox="0 0 20 20" fill="none" style="flex-shrink: 0;color: var(--gray-300);"><path d="M7.5 4.5l5.5 5.5-5.5 5.5" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>' +
|
||
'</div>';
|
||
}
|
||
return '' +
|
||
'<div class="platform-card-disabled" aria-disabled="true" onclick="onPlatformInstallClick(\'' + app.id + '\')" style="background: #FAFAFA;border-radius: 14px;padding: 16px 16px;cursor: pointer;display: flex;align-items: center;gap: 12px;border: 1.5px solid #ECECEC;margin-bottom: 8px;position: relative;">' +
|
||
'<img src="' + app.icon + '" style="width: 48px;height: 48px;border-radius: 12px;flex-shrink: 0;object-fit: cover;filter: grayscale(.7);opacity: .55;" />' +
|
||
'<div style="flex: 1;min-width: 0;">' +
|
||
'<div style="font-size: 20px;font-weight: 700;color: var(--gray-400);letter-spacing: -.2px;">' + app.name + '</div>' +
|
||
'</div>' +
|
||
'<span style="flex-shrink: 0;display: inline-flex;align-items: center;gap: 8px;">' +
|
||
'<span style="font-size: 15px;font-weight: 700;color: var(--gray-900);line-height: 1;">去安装</span>' +
|
||
'<svg width="20" height="20" viewBox="0 0 20 20" fill="none" style="color: var(--gray-300);"><path d="M7.5 4.5l5.5 5.5-5.5 5.5" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>' +
|
||
'</span>' +
|
||
'</div>';
|
||
}).join('');
|
||
|
||
// 旧的次级"未安装"分区不再使用
|
||
document.getElementById('notInstalledSection').style.display = 'none';
|
||
}
|
||
|
||
// 领券浮窗 / 比价浮窗顶部的平台进度 mini icons —— 只渲染已安装的平台
|
||
// states: { 'platform-id': 'done' | 'active' | 'pending' }
|
||
function renderFloatPlatforms(containerId, states) {
|
||
const container = document.getElementById(containerId);
|
||
if (!container) return;
|
||
const installed = getVisibleApps().filter(a => a.installed);
|
||
container.innerHTML = installed.map(app => {
|
||
const state = (states && states[app.id]) || 'pending';
|
||
return '<div class="cmp-platform-mini ' + state + '"><img src="' + app.icon + '" alt="' + app.name + '"/></div>';
|
||
}).join('');
|
||
}
|
||
|
||
// 一键领券弹窗 · 3 平台卡片渲染。已装:黄边 + ✓;未装(方案 C):灰底 + 黄圆 ↓ 角标
|
||
function couponChipShortName(name) {
|
||
return name.replace(/外卖$|闪购$/, '');
|
||
}
|
||
function renderCouponPromptPlatforms() {
|
||
const grid = document.getElementById('couponPlatformGrid');
|
||
if (!grid) return;
|
||
const platforms = getVisibleApps(); // 3 张外卖版卡片
|
||
grid.innerHTML = platforms.map(app => {
|
||
const shortName = couponChipShortName(app.name);
|
||
if (app.installed) {
|
||
return '<div data-checked="true" onclick="toggleCouponPlatform(this)" class="cp-card cp-card-yellow" style="background: #fff;border: 2px solid #FFB300;border-radius: 14px;padding: 12px 4px 8px;position: relative;">' +
|
||
'<img src="' + app.icon + '" style="width: 42px;height: 42px;border-radius: 8px;margin: 0 auto;display: block;"/>' +
|
||
'<div style="font-size: 12px;font-weight: 700;color: var(--gray-900);margin-top: 8px;">' + shortName + '</div>' +
|
||
'<span class="cp-check" style="position: absolute;top: 6px;right: 6px;width: 18px;height: 18px;border-radius: 50%;background: #FFB300;display: flex;align-items: center;justify-content: center;">' +
|
||
'<svg width="10" height="10" viewBox="0 0 9 9"><path d="M2 4.5l1.5 1.5 3-4" stroke="#fff" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" fill="none"/></svg>' +
|
||
'</span>' +
|
||
'</div>';
|
||
}
|
||
return '<div class="cp-card-uninstalled" aria-disabled="true" style="background: #FAFAFA;border: 1.5px solid #ECECEC;border-radius: 14px;padding: 12px 4px 8px;position: relative;">' +
|
||
'<img src="' + app.icon + '" style="width: 42px;height: 42px;border-radius: 8px;margin: 0 auto;display: block;filter: grayscale(.7);opacity: .55;"/>' +
|
||
'<div style="font-size: 12px;font-weight: 700;color: #BBB;margin-top: 8px;">' + shortName + '</div>' +
|
||
'<span style="position: absolute;top: 6px;right: 6px;width: 18px;height: 18px;border-radius: 50%;background: #FFD600;box-shadow: 0 0 0 1.5px rgba(255,179,0,.35);display: flex;align-items: center;justify-content: center;">' +
|
||
'<svg width="10" height="10" viewBox="0 0 10 10" fill="none"><path d="M5 1.5v5.5m0 0L2.5 4.5M5 7l2.5-2.5M2 9h6" stroke="#1a1a1a" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round"/></svg>' +
|
||
'</span>' +
|
||
'</div>';
|
||
}).join('');
|
||
}
|
||
|
||
let selectedAppForBubble = null;
|
||
function selectPlatform(platformId) {
|
||
const app = allApps.find(a => a.id === platformId);
|
||
if (!app) return;
|
||
selectedAppForBubble = app;
|
||
go('comparing');
|
||
}
|
||
|
||
// 未安装平台 → 跳应用市场(原型 stub)
|
||
function onPlatformInstallClick(platformId) {
|
||
const app = allApps.find(a => a.id === platformId);
|
||
if (!app) return;
|
||
console.log('[install] 跳应用市场下载:', app.name);
|
||
}
|
||
|
||
/* ===== 去点餐选平台弹窗(省钱战绩锁定态「立即开始」触发)===== */
|
||
function renderComparePickerPlatforms() {
|
||
var grid = document.getElementById('comparePickerGrid');
|
||
if (!grid || typeof getVisibleApps !== 'function') return;
|
||
grid.innerHTML = getVisibleApps().map(function(app) {
|
||
if (app.installed) {
|
||
return '<div class="home-picker-item" data-platform="' + app.name + '">' +
|
||
'<div class="home-picker-logo"><img src="' + app.icon + '" alt=""></div>' +
|
||
'<div class="home-picker-name">' + app.name + '</div></div>';
|
||
}
|
||
return '<div class="home-picker-item uninstalled" data-platform="' + app.name + '" data-uninstalled="true">' +
|
||
'<div class="home-picker-logo"><img src="' + app.icon + '" alt=""></div>' +
|
||
'<div class="home-picker-name">' + app.name + '</div>' +
|
||
'<span class="home-picker-install-chip">' +
|
||
'<svg width="10" height="10" viewBox="0 0 10 10" fill="none"><path d="M5 1.5v5.5m0 0L2.5 4.5M5 7l2.5-2.5M2 9h6" stroke="#1a1a1a" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round"/></svg>' +
|
||
'</span></div>';
|
||
}).join('');
|
||
}
|
||
function openComparePicker() {
|
||
renderComparePickerPlatforms();
|
||
var mask = document.getElementById('comparePickerMask');
|
||
if (mask) mask.classList.add('show');
|
||
}
|
||
function closeComparePicker() {
|
||
var mask = document.getElementById('comparePickerMask');
|
||
if (mask) mask.classList.remove('show');
|
||
}
|
||
(function() {
|
||
var mask = document.getElementById('comparePickerMask');
|
||
if (!mask) return;
|
||
mask.addEventListener('click', function(e) {
|
||
if (e.target === mask) { closeComparePicker(); return; }
|
||
var item = e.target.closest('.home-picker-item');
|
||
if (!item) return;
|
||
var nameEl = item.querySelector('.home-picker-name');
|
||
var name = nameEl ? nameEl.textContent : '';
|
||
closeComparePicker();
|
||
if (item.dataset.uninstalled === 'true') {
|
||
if (typeof showToast === 'function') showToast('请先安装「' + name + '」APP');
|
||
var app = (typeof allApps !== 'undefined') ? allApps.find(function(a){return a.name === name;}) : null;
|
||
if (app && typeof onPlatformInstallClick === 'function') onPlatformInstallClick(app.id);
|
||
} else {
|
||
if (typeof showToast === 'function') showToast('已跳「' + name + '」');
|
||
}
|
||
});
|
||
})();
|
||
|
||
// 省钱战绩锁定态初始化:按 variants['省钱战绩'].current 应用(默认未比价=锁定)
|
||
// 切换入口:左上角 ⚙ 方案切换面板 → 省钱战绩 → 锁定 / 未锁定
|
||
(function() {
|
||
function init() {
|
||
var mod = (typeof variants !== 'undefined') && variants['省钱战绩'];
|
||
applySavingsLock(mod ? mod.current === 'locked' : true);
|
||
}
|
||
if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', init);
|
||
else init();
|
||
})();
|
||
|
||
function showWelcomeBubble() {
|
||
const mask = document.getElementById('welcomeMask');
|
||
const bubble = document.getElementById('welcomeBubble');
|
||
const title = document.getElementById('welcomeTitle');
|
||
const app = selectedAppForBubble || { name: '美团' };
|
||
|
||
title.textContent = '已为您唤起' + app.name;
|
||
|
||
mask.style.display = 'block';
|
||
bubble.style.display = 'block';
|
||
// 强制重排,让初始 opacity:0 / scale .92 生效
|
||
void bubble.offsetWidth;
|
||
|
||
requestAnimationFrame(() => {
|
||
mask.style.opacity = '1';
|
||
bubble.style.opacity = '1';
|
||
bubble.style.transform = 'translate(-50%,-50%) scale(1)';
|
||
});
|
||
|
||
setTimeout(() => {
|
||
mask.style.opacity = '0';
|
||
bubble.style.opacity = '0';
|
||
setTimeout(() => {
|
||
mask.style.display = 'none';
|
||
bubble.style.display = 'none';
|
||
}, 450);
|
||
}, 2000);
|
||
}
|
||
|
||
// 红包倒计时
|
||
let countdownInterval;
|
||
let rewardPhase = 0; // 0=首次, 1=已过期, 2=二次机会
|
||
|
||
function startRewardCountdown() {
|
||
let total = 300; // 5分钟
|
||
rewardPhase = 0;
|
||
updateRewardCard('active');
|
||
runCountdown(total);
|
||
}
|
||
|
||
function runCountdown(totalSeconds) {
|
||
let remaining = totalSeconds * 10; // 1/10秒为单位
|
||
const el = document.getElementById('rewardCountdown');
|
||
if (!el) return;
|
||
clearInterval(countdownInterval);
|
||
countdownInterval = setInterval(() => {
|
||
remaining--;
|
||
if (remaining <= 0) {
|
||
clearInterval(countdownInterval);
|
||
remaining = 0;
|
||
onCountdownEnd();
|
||
}
|
||
const totalSec = Math.floor(remaining / 10);
|
||
const tenths = remaining % 10;
|
||
const m = String(Math.floor(totalSec / 60)).padStart(2, '0');
|
||
const s = String(totalSec % 60).padStart(2, '0');
|
||
el.textContent = m + ':' + s + '.' + tenths;
|
||
}, 100);
|
||
}
|
||
|
||
function onCountdownEnd() {
|
||
if (rewardPhase === 0) {
|
||
// 首次过期 → 显示过期状态
|
||
rewardPhase = 1;
|
||
updateRewardCard('expired');
|
||
// 2秒后给二次机会
|
||
setTimeout(() => {
|
||
rewardPhase = 2;
|
||
updateRewardCard('second-chance');
|
||
runCountdown(180); // 二次机会 3分钟
|
||
}, 2000);
|
||
} else {
|
||
// 二次也过期 → 最终过期
|
||
updateRewardCard('final-expired');
|
||
}
|
||
}
|
||
|
||
function updateRewardCard(state) {
|
||
const card = document.getElementById('rewardCard');
|
||
if (!card) return;
|
||
if (state === 'active') {
|
||
card.style.background = 'linear-gradient(135deg,#FFF8E1,#FFECB3)';
|
||
card.style.opacity = '1';
|
||
card.innerHTML = `
|
||
<div style="flex-shrink: 0;font-size: 36px;line-height: 1;">🧧</div>
|
||
<div style="flex: 1;">
|
||
<div style="font-size: 14px;font-weight: 700;color: var(--gray-900);">完成首次比价领红包奖励</div>
|
||
</div>`;
|
||
} else if (state === 'expired') {
|
||
card.style.background = 'var(--gray-100)';
|
||
card.style.opacity = '.6';
|
||
card.innerHTML = `
|
||
<div style="flex-shrink: 0;font-size: 36px;line-height: 1;filter: grayscale(1);">🧧</div>
|
||
<div style="flex: 1;">
|
||
<div style="font-size: 14px;font-weight: 700;color: var(--gray-500);">红包已过期</div>
|
||
<div style="font-size: 12px;color: var(--gray-400);margin-top: 2px;">很遗憾,活动已结束</div>
|
||
</div>`;
|
||
} else if (state === 'second-chance') {
|
||
card.style.background = 'linear-gradient(135deg,#FFEBEE,#FFCDD2)';
|
||
card.style.opacity = '1';
|
||
card.innerHTML = `
|
||
<div style="flex-shrink: 0;font-size: 36px;line-height: 1;">🎁</div>
|
||
<div style="flex: 1;">
|
||
<div style="font-size: 14px;font-weight: 700;color: #E53935;">再给你一次机会!</div>
|
||
<div style="font-size: 12px;color: #FF5722;font-weight: 600;margin-top: 2px;">最后 <span id="rewardCountdown">03:00.0</span></div>
|
||
</div>`;
|
||
} else if (state === 'final-expired') {
|
||
card.style.background = 'var(--gray-100)';
|
||
card.style.opacity = '.5';
|
||
card.innerHTML = `
|
||
<div style="flex-shrink: 0;font-size: 36px;line-height: 1;filter: grayscale(1);">🧧</div>
|
||
<div style="flex: 1;">
|
||
<div style="font-size: 14px;font-weight: 600;color: var(--gray-400);">新人红包奖励已过期</div>
|
||
</div>`;
|
||
}
|
||
}
|
||
|
||
// 卡片轮流高亮
|
||
let cardRotationInterval;
|
||
function startCardRotation(count) {
|
||
let active = 0;
|
||
function highlight() {
|
||
document.querySelectorAll('[data-pcard]').forEach((el, i) => {
|
||
if (i === active) {
|
||
el.style.borderColor = '#FF5722';
|
||
el.style.boxShadow = '0 0 0 1px #FF5722';
|
||
el.querySelector('.tap-hand-icon').style.opacity = '1';
|
||
el.querySelector('.tap-hand-icon').classList.add('tap-hand');
|
||
} else {
|
||
el.style.borderColor = 'var(--gray-200)';
|
||
el.style.boxShadow = 'none';
|
||
el.querySelector('.tap-hand-icon').style.opacity = '0';
|
||
el.querySelector('.tap-hand-icon').classList.remove('tap-hand');
|
||
}
|
||
});
|
||
active = (active + 1) % count;
|
||
}
|
||
highlight();
|
||
clearInterval(cardRotationInterval);
|
||
cardRotationInterval = setInterval(highlight, 2100);
|
||
}
|
||
|
||
// 省钱数字滚动动画(已弃用但保留兼容)
|
||
function animateSavingCounter() {
|
||
const el = document.getElementById('savingCounter');
|
||
const target = 12847;
|
||
const duration = 1500;
|
||
const start = performance.now();
|
||
function tick(now) {
|
||
const p = Math.min((now - start) / duration, 1);
|
||
const ease = 1 - Math.pow(1 - p, 3);
|
||
el.textContent = Math.floor(target * ease).toLocaleString();
|
||
if (p < 1) requestAnimationFrame(tick);
|
||
}
|
||
requestAnimationFrame(tick);
|
||
}
|
||
|
||
// 商品点击 → 过渡提示 → 进入比价(兼容旧调用)
|
||
function startProductCompare() {
|
||
selectPlatform('meituan-waimai');
|
||
}
|
||
|
||
// ===== 反馈面板 =====
|
||
function openFeedbackSheet() {
|
||
const sheet = document.getElementById('feedbackSheet');
|
||
// 重置到步骤1
|
||
document.getElementById('fbStep1').style.display = 'block';
|
||
document.getElementById('fbFormLower').style.display = 'none';
|
||
document.getElementById('fbFormWrong').style.display = 'none';
|
||
document.getElementById('fbSuccess').style.display = 'none';
|
||
// 动态生成平台选项(仅显示 found/same-price 的平台)
|
||
const pl = document.getElementById('fbPlatformList');
|
||
if (pl) {
|
||
pl.innerHTML = results.filter(r => r.status !== 'not-found').map(r =>
|
||
`<div class="fb-platform" onclick="this.classList.toggle('selected')" style="padding: 8px 16px;border: 1.5px solid var(--gray-200);border-radius: 32px;font-size: 13px;font-weight: 600;cursor: pointer;display: flex;align-items: center;gap: 4px;"><img src="${r.platformIcon}" style="width: 16px;height: 16px;border-radius: 4px;"> ${r.platform}</div>`
|
||
).join('');
|
||
}
|
||
sheet.style.display = 'block';
|
||
}
|
||
|
||
function closeFeedbackSheet() {
|
||
document.getElementById('feedbackSheet').style.display = 'none';
|
||
}
|
||
|
||
function selectFbType(type) {
|
||
document.getElementById('fbStep1').style.display = 'none';
|
||
if (type === 'lower_price') {
|
||
document.getElementById('fbFormLower').style.display = 'block';
|
||
} else {
|
||
document.getElementById('fbFormWrong').style.display = 'block';
|
||
}
|
||
}
|
||
|
||
function backToFbStep1() {
|
||
document.getElementById('fbFormLower').style.display = 'none';
|
||
document.getElementById('fbFormWrong').style.display = 'none';
|
||
document.getElementById('fbStep1').style.display = 'block';
|
||
}
|
||
|
||
function submitFeedback() {
|
||
document.getElementById('fbFormLower').style.display = 'none';
|
||
document.getElementById('fbFormWrong').style.display = 'none';
|
||
document.getElementById('fbSuccess').style.display = 'block';
|
||
}
|
||
|
||
// 提现金额选择
|
||
function selectWd(el) {
|
||
document.querySelectorAll('.wd-opt').forEach(e => { e.style.borderColor='var(--gray-200)'; e.style.background='#fff'; });
|
||
el.style.borderColor='#FF5722'; el.style.background='#FFF3E0';
|
||
}
|
||
|
||
function showPrototypeToast(msg) {
|
||
var existing = document.getElementById('prototypeToast');
|
||
if (existing) existing.remove();
|
||
var toast = document.createElement('div');
|
||
toast.id = 'prototypeToast';
|
||
toast.textContent = msg;
|
||
toast.style.cssText = 'position:absolute;left:50%;bottom:118px;transform:translateX(-50%);max-width:310px;background:rgba(0,0,0,.78);color:#fff;font-size:13px;font-weight:600;line-height:18px;padding:10px 16px;border-radius:12px;z-index:9999;text-align:center;pointer-events:none;opacity:1;transition:opacity .25s;white-space:nowrap;';
|
||
document.getElementById('app').appendChild(toast);
|
||
setTimeout(function() { toast.style.opacity = '0'; }, 1500);
|
||
setTimeout(function() { if (toast.parentNode) toast.remove(); }, 1800);
|
||
}
|
||
|
||
function selectWithdrawAmount(el) {
|
||
document.querySelectorAll('.withdraw-amount').forEach(function(item) {
|
||
item.classList.remove('active');
|
||
});
|
||
el.classList.add('active');
|
||
openWechatBindSheet(el.dataset.amount || el.textContent.replace('元', '').trim());
|
||
}
|
||
|
||
function openWechatBindSheet(amount) {
|
||
var layer = document.getElementById('wechatBindSheet');
|
||
var amountEl = document.getElementById('wechatBindAmount');
|
||
if (amountEl) amountEl.textContent = amount || '0.3';
|
||
if (!layer) return;
|
||
layer.classList.add('open');
|
||
layer.setAttribute('aria-hidden', 'false');
|
||
}
|
||
|
||
function closeWechatBindSheet() {
|
||
var layer = document.getElementById('wechatBindSheet');
|
||
if (!layer) return;
|
||
layer.classList.remove('open');
|
||
layer.setAttribute('aria-hidden', 'true');
|
||
}
|
||
|
||
var incomeCurrentTab = 'coin';
|
||
|
||
function openIncomeHistory(tab) {
|
||
go('coinhistory');
|
||
setIncomeTab(tab);
|
||
}
|
||
|
||
function setIncomeTab(tab) {
|
||
incomeCurrentTab = tab === 'cash' ? 'cash' : 'coin';
|
||
var tabs = document.getElementById('incomeTabs');
|
||
var coinTab = document.getElementById('incomeTabCoin');
|
||
var cashTab = document.getElementById('incomeTabCash');
|
||
var track = document.getElementById('incomeRecordTrack');
|
||
var note = document.getElementById('incomeFooterNote');
|
||
var btn = document.getElementById('incomeFooterBtn');
|
||
if (tabs) tabs.dataset.active = incomeCurrentTab;
|
||
if (coinTab) coinTab.classList.toggle('active', incomeCurrentTab === 'coin');
|
||
if (cashTab) cashTab.classList.toggle('active', incomeCurrentTab === 'cash');
|
||
if (track) track.classList.toggle('cash-active', incomeCurrentTab === 'cash');
|
||
if (note) {
|
||
note.innerHTML = incomeCurrentTab === 'coin'
|
||
? '累计收益 <strong>2.18 元</strong>'
|
||
: '累计到账 <strong>2.36 元</strong>';
|
||
}
|
||
if (btn) btn.textContent = incomeCurrentTab === 'coin' ? '立即提现' : '去提现';
|
||
}
|
||
|
||
function initIncomeSwipe() {
|
||
var shell = document.getElementById('incomeRecordShell');
|
||
if (!shell) return;
|
||
var startX = 0;
|
||
var startY = 0;
|
||
var tracking = false;
|
||
|
||
function begin(x, y) {
|
||
startX = x;
|
||
startY = y;
|
||
tracking = true;
|
||
}
|
||
|
||
function finish(x, y) {
|
||
if (!tracking) return;
|
||
tracking = false;
|
||
var dx = x - startX;
|
||
var dy = y - startY;
|
||
if (Math.abs(dx) < 46 || Math.abs(dx) < Math.abs(dy) * 1.1) return;
|
||
if (dx < 0 && incomeCurrentTab === 'coin') setIncomeTab('cash');
|
||
if (dx > 0 && incomeCurrentTab === 'cash') setIncomeTab('coin');
|
||
}
|
||
|
||
shell.addEventListener('touchstart', function(e) {
|
||
if (!e.touches || !e.touches[0]) return;
|
||
begin(e.touches[0].clientX, e.touches[0].clientY);
|
||
}, { passive: true });
|
||
shell.addEventListener('touchend', function(e) {
|
||
var touch = e.changedTouches && e.changedTouches[0];
|
||
if (!touch) return;
|
||
finish(touch.clientX, touch.clientY);
|
||
}, { passive: true });
|
||
shell.addEventListener('mousedown', function(e) {
|
||
begin(e.clientX, e.clientY);
|
||
});
|
||
shell.addEventListener('mouseup', function(e) {
|
||
finish(e.clientX, e.clientY);
|
||
});
|
||
}
|
||
|
||
var EXCHANGE_COIN_BALANCE = 28967;
|
||
var currentExchangeAmount = EXCHANGE_COIN_BALANCE;
|
||
|
||
function exchangeCashText(coins) {
|
||
return (Math.floor(coins / 100) / 100).toFixed(2);
|
||
}
|
||
|
||
function selectExchangeAmount(amount, el) {
|
||
currentExchangeAmount = amount === 'all' ? EXCHANGE_COIN_BALANCE : Number(amount);
|
||
document.querySelectorAll('.exchange-preset').forEach(function(item) {
|
||
item.classList.remove('active');
|
||
});
|
||
if (el) el.classList.add('active');
|
||
var coinAmount = document.getElementById('exchangeCoinAmount');
|
||
var cashAmount = document.getElementById('exchangeCashAmount');
|
||
var error = document.getElementById('exchangeError');
|
||
if (coinAmount) coinAmount.textContent = currentExchangeAmount.toLocaleString('zh-CN');
|
||
if (cashAmount) cashAmount.textContent = exchangeCashText(currentExchangeAmount);
|
||
if (error) {
|
||
if (currentExchangeAmount > EXCHANGE_COIN_BALANCE) {
|
||
error.textContent = '超过已拥有金币数';
|
||
} else if (currentExchangeAmount < 100) {
|
||
error.textContent = '最低 100 金币起兑';
|
||
} else {
|
||
error.textContent = '';
|
||
}
|
||
}
|
||
}
|
||
|
||
function openExchangeSheet() {
|
||
var layer = document.getElementById('exchangeSheet');
|
||
if (!layer) return;
|
||
layer.classList.add('open');
|
||
layer.setAttribute('aria-hidden', 'false');
|
||
selectExchangeAmount('all', document.getElementById('exchangePresetAll'));
|
||
}
|
||
|
||
function closeExchangeSheet() {
|
||
var layer = document.getElementById('exchangeSheet');
|
||
if (!layer) return;
|
||
layer.classList.remove('open');
|
||
layer.setAttribute('aria-hidden', 'true');
|
||
}
|
||
|
||
function confirmExchange() {
|
||
if (currentExchangeAmount > EXCHANGE_COIN_BALANCE || currentExchangeAmount < 100) return;
|
||
closeExchangeSheet();
|
||
showPrototypeToast('兑换申请已提交,现金到账可能会有延迟');
|
||
}
|
||
|
||
document.addEventListener('DOMContentLoaded', function() {
|
||
initIncomeSwipe();
|
||
setIncomeTab('coin');
|
||
updateWelfareCheckinTask();
|
||
});
|
||
|
||
// ===== 退出登录 / 注销账号 =====
|
||
function showLogoutConfirm() {
|
||
document.getElementById('logoutConfirm').style.display = 'flex';
|
||
}
|
||
function closeLogoutConfirm() {
|
||
document.getElementById('logoutConfirm').style.display = 'none';
|
||
}
|
||
function doLogout() {
|
||
closeLogoutConfirm();
|
||
isLoggedIn = false; try{localStorage.setItem('proto_isLoggedIn','false');}catch(e){}
|
||
welfareVisited = false; try{localStorage.setItem('proto_welfareVisited','false');}catch(e){}
|
||
profileVisited = false; try{localStorage.setItem('proto_profileVisited','false');}catch(e){}
|
||
checkinShown = false; try{localStorage.setItem('proto_checkinShown','false');}catch(e){}
|
||
go('home');
|
||
}
|
||
function showDeleteConfirm() {
|
||
document.getElementById('deleteConfirm').style.display = 'flex';
|
||
}
|
||
function closeDeleteConfirm() {
|
||
document.getElementById('deleteConfirm').style.display = 'none';
|
||
}
|
||
function doDeleteAccount() {
|
||
closeDeleteConfirm();
|
||
isLoggedIn = false; try{localStorage.setItem('proto_isLoggedIn','false');}catch(e){}
|
||
welfareVisited = false; try{localStorage.setItem('proto_welfareVisited','false');}catch(e){}
|
||
profileVisited = false; try{localStorage.setItem('proto_profileVisited','false');}catch(e){}
|
||
checkinShown = false; try{localStorage.setItem('proto_checkinShown','false');}catch(e){}
|
||
go('home');
|
||
}
|
||
|
||
// Splash 不再自动跳转,等用户点击 CTA "开始体验"
|
||
// (旧的 splashCounter 累计数字动画已移除 — Option C 设计无大数字)
|
||
|
||
// Video 模拟
|
||
// ============ Video tutorial 状态机 (vt-) ============
|
||
const vt = {
|
||
status: 'initial', // initial | playing | paused | ended
|
||
elapsed: 0, // 已播毫秒
|
||
duration: 5000, // 5s 模拟一分钟,真实视频接入后改成视频时长
|
||
intervalId: null,
|
||
hasFinished: false,
|
||
isDragging: false,
|
||
};
|
||
const VT_PLAY = '<path d="M8 5v14l11-7z"/>';
|
||
const VT_PAUSE = '<path d="M6 19h4V5H6v14zm8-14v14h4V5h-4z"/>';
|
||
const VT_REPLAY = '<path d="M12 5V1L7 6l5 5V7c3.31 0 6 2.69 6 6s-2.69 6-6 6-6-2.69-6-6H4c0 4.42 3.58 8 8 8s8-3.58 8-8-3.58-8-8-8z"/>';
|
||
|
||
function vtRender() {
|
||
const player = document.getElementById('vt-video');
|
||
if (!player) return;
|
||
const fill = document.getElementById('vt-fill');
|
||
const cur = document.getElementById('vt-current');
|
||
const cta = document.getElementById('vt-cta');
|
||
const cIco = document.getElementById('vt-center-icon');
|
||
const bIco = document.getElementById('vt-bottom-icon');
|
||
|
||
player.className = 'vt-video-player ' + vt.status;
|
||
|
||
const progress = Math.min(vt.elapsed / vt.duration, 1);
|
||
fill.style.width = (progress * 100) + '%';
|
||
|
||
// 5s 真时长 → 显示成 1 分钟视频
|
||
const totalSec = Math.floor(progress * 60);
|
||
const min = Math.floor(totalSec / 60);
|
||
const sec = totalSec % 60;
|
||
cur.textContent = min + ':' + (sec < 10 ? '0' : '') + sec;
|
||
|
||
cIco.innerHTML = (vt.status === 'ended') ? VT_REPLAY : VT_PLAY;
|
||
bIco.innerHTML = (vt.status === 'playing') ? VT_PAUSE : VT_PLAY;
|
||
|
||
if (vt.hasFinished) {
|
||
cta.classList.remove('disabled');
|
||
cta.textContent = '进入快速设置';
|
||
} else {
|
||
cta.classList.add('disabled');
|
||
cta.textContent = '看完后继续';
|
||
}
|
||
}
|
||
|
||
function vtStopTimer() {
|
||
if (vt.intervalId !== null) { clearInterval(vt.intervalId); vt.intervalId = null; }
|
||
}
|
||
function vtStartTimer() {
|
||
vtStopTimer();
|
||
vt.intervalId = setInterval(() => {
|
||
vt.elapsed += 50;
|
||
if (vt.elapsed >= vt.duration) {
|
||
vt.elapsed = vt.duration;
|
||
vt.status = 'ended';
|
||
vt.hasFinished = true;
|
||
vtStopTimer();
|
||
}
|
||
vtRender();
|
||
}, 50);
|
||
}
|
||
function vtToggle() {
|
||
if (vt.status === 'playing') {
|
||
vtStopTimer();
|
||
vt.status = 'paused';
|
||
} else if (vt.status === 'ended') {
|
||
vt.elapsed = 0;
|
||
vt.status = 'playing';
|
||
vtStartTimer();
|
||
} else {
|
||
vt.status = 'playing';
|
||
vtStartTimer();
|
||
}
|
||
vtRender();
|
||
}
|
||
function vtNext() {
|
||
if (!vt.hasFinished) return;
|
||
vtStopTimer();
|
||
go('permission-step1');
|
||
}
|
||
|
||
let vtInited = false;
|
||
function vtInit() {
|
||
if (vtInited) return;
|
||
const player = document.getElementById('vt-video');
|
||
if (!player) return;
|
||
const track = document.getElementById('vt-track');
|
||
vtInited = true;
|
||
|
||
// 1. 点视频本身切换播放/暂停(排除 controls 与 center-play 的内联 onclick)
|
||
player.addEventListener('click', (e) => {
|
||
if (e.target.closest('.vt-controls')) return;
|
||
if (e.target.closest('.vt-center-play')) return;
|
||
vtToggle();
|
||
});
|
||
|
||
// 2. 进度条拖动(playing / paused 都支持)
|
||
function vtSeekFromX(clientX) {
|
||
const rect = track.getBoundingClientRect();
|
||
const ratio = Math.max(0, Math.min((clientX - rect.left) / rect.width, 1));
|
||
vt.elapsed = ratio * vt.duration;
|
||
if (ratio >= 1) {
|
||
vt.status = 'ended';
|
||
vt.hasFinished = true;
|
||
vtStopTimer();
|
||
} else if (vt.status === 'ended') {
|
||
vt.status = 'paused';
|
||
}
|
||
vtRender();
|
||
}
|
||
track.addEventListener('mousedown', (e) => {
|
||
e.preventDefault(); e.stopPropagation();
|
||
vt.isDragging = true; vtSeekFromX(e.clientX);
|
||
});
|
||
document.addEventListener('mousemove', (e) => { if (vt.isDragging) vtSeekFromX(e.clientX); });
|
||
document.addEventListener('mouseup', () => { vt.isDragging = false; });
|
||
track.addEventListener('touchstart', (e) => {
|
||
e.stopPropagation();
|
||
vt.isDragging = true; vtSeekFromX(e.touches[0].clientX);
|
||
}, {passive: true});
|
||
document.addEventListener('touchmove', (e) => { if (vt.isDragging) vtSeekFromX(e.touches[0].clientX); }, {passive: true});
|
||
document.addEventListener('touchend', () => { vt.isDragging = false; });
|
||
}
|
||
|
||
// startVideo 由"进入教程"触发:进入即自动播放
|
||
function startVideo() {
|
||
vtInit();
|
||
vt.elapsed = 0;
|
||
vt.hasFinished = false;
|
||
vtStopTimer();
|
||
vt.status = 'playing';
|
||
vtStartTimer();
|
||
vtRender();
|
||
}
|
||
// startVideo 由用户点击"进入教程"触发
|
||
|
||
// 商品选择
|
||
function selectProduct(el) {
|
||
document.querySelectorAll('.product-option').forEach(e => { e.style.borderColor='transparent'; e.style.background='var(--gray-50)'; });
|
||
el.style.borderColor='var(--primary)'; el.style.background='var(--primary-bg)';
|
||
document.getElementById('selectBtn').style.display='block';
|
||
}
|
||
|
||
// 比价模拟
|
||
// ===== 截图演示比价流程 =====
|
||
// spotlight: { top, left, width, height } 相对于375x812设备
|
||
// finger: { top, left } 手指位置
|
||
// guidePos: { top, left } 文案位置, 'above' = 聚光灯上方居中
|
||
const demoSteps = [
|
||
// ===== 一键领券前置流程 =====
|
||
{
|
||
img: '../../assets/onboarding/index/platform-flows/meituan/1-home.jpg',
|
||
mode: 'couponPrompt',
|
||
},
|
||
// TODO: 替换为真实的美团神券中心 / 饿了么神券中心截图
|
||
{
|
||
img: '../../assets/onboarding/index/platform-flows/meituan/1-home.jpg',
|
||
mode: 'agentFlow',
|
||
agentText: '正在打开美团神券中心...',
|
||
platforms: { 'meituan-waimai': 'active' },
|
||
},
|
||
{
|
||
img: '../../assets/onboarding/index/platform-flows/meituan/1-home.jpg',
|
||
mode: 'agentFlow',
|
||
agentText: '已领取美团红包',
|
||
couponDelta: 8,
|
||
platforms: { 'meituan-waimai': 'done' },
|
||
},
|
||
{
|
||
img: '../../assets/onboarding/index/platform-flows/taobao/2-coupon-center.jpg',
|
||
mode: 'agentFlow',
|
||
agentText: '正在领取淘宝神券...',
|
||
platforms: { 'meituan-waimai': 'done', 'taobao-shanguang': 'active' },
|
||
},
|
||
{
|
||
img: '../../assets/onboarding/index/platform-flows/taobao/3-coupon-claimed.jpg',
|
||
mode: 'agentFlow',
|
||
agentText: '已领取淘宝神券',
|
||
couponDelta: 12,
|
||
platforms: { 'meituan-waimai': 'done', 'taobao-shanguang': 'done' },
|
||
},
|
||
{
|
||
img: '../../assets/onboarding/index/platform-flows/meituan/1-home.jpg',
|
||
mode: 'couponDone',
|
||
},
|
||
// ===== 比价引导流程 =====
|
||
{
|
||
img: '../../assets/onboarding/index/platform-flows/meituan/1-home.jpg',
|
||
guide: '• 点击下方店铺,并找到商品准备比价',
|
||
guideTitle: '找到待比价的商品',
|
||
kickoff: true,
|
||
spotlight: { top: 517, left: 7, width: 361, height: 125 },
|
||
finger: { top: 590, left: 312 },
|
||
},
|
||
{
|
||
img: '../../assets/onboarding/index/platform-flows/meituan/2-shop-top.jpg',
|
||
guide: '下滑找到待比价的商品',
|
||
mode: 'swipe',
|
||
},
|
||
{
|
||
img: '../../assets/onboarding/index/waimai-guide/add-to-cart.png',
|
||
guide: '点击「+」加入购物车',
|
||
spotlight: { top: 174, left: 70, width: 301, height: 152 },
|
||
plusFocus: { top: 295, left: 352 },
|
||
finger: { top: 306, left: 274, size: 60, plusGuide: true },
|
||
guideTop: 344,
|
||
guideLeft: 187.5,
|
||
clickTarget: 'plus',
|
||
spotlightRadius: 8,
|
||
spotlightOpacity: .62,
|
||
},
|
||
{
|
||
img: '../../assets/onboarding/index/waimai-guide/missing-required.png',
|
||
guide: '点击添加必选品',
|
||
spotlight: { top: 719, left: 0, width: 375, height: 93 },
|
||
plusFocus: { top: 755, left: 311, width: 128, height: 54, shape: 'rect' },
|
||
finger: { top: 771, left: 236, size: 60, plusGuide: true },
|
||
guideTop: 664,
|
||
guideLeft: 187.5,
|
||
clickTarget: 'plus',
|
||
spotlightRadius: 0,
|
||
spotlightOpacity: .62,
|
||
},
|
||
{
|
||
img: '../../assets/onboarding/index/waimai-guide/add-required-item.png',
|
||
guide: '点击「+」添加',
|
||
spotlight: { top: 306, left: 76, width: 296, height: 134 },
|
||
plusFocus: { top: 403, left: 352, width: 46, height: 46, shape: 'circle' },
|
||
finger: { top: 414, left: 274, size: 60, plusGuide: true },
|
||
guideTop: 458,
|
||
guideLeft: 187.5,
|
||
clickTarget: 'plus',
|
||
spotlightRadius: 8,
|
||
spotlightOpacity: .62,
|
||
},
|
||
{
|
||
img: '../../assets/onboarding/index/platform-flows/meituan/5-shop-cart.jpg',
|
||
guide: '点击去结算',
|
||
spotlight: { top: 719, left: 0, width: 375, height: 93 },
|
||
plusFocus: { top: 790, left: 315, width: 112, height: 46, shape: 'pill' },
|
||
finger: { top: 735, left: 320, size: 60, imgTransform: 'rotate(-90deg)' },
|
||
guideTop: 660,
|
||
guideLeft: 187.5,
|
||
clickTarget: 'plus',
|
||
spotlightRadius: 0,
|
||
spotlightOpacity: .62,
|
||
},
|
||
{
|
||
img: '../../assets/onboarding/index/platform-flows/meituan/6-checkout.jpg',
|
||
guide: '请选择待使用的红包',
|
||
spotlight: { top: 636, left: 14, width: 347, height: 48 },
|
||
finger: { top: 660, left: 315, size: 60, imgTransform: 'rotate(6deg)' },
|
||
guideTop: 580,
|
||
guideLeft: 187.5,
|
||
spotlightRadius: 20,
|
||
spotlightOpacity: .62,
|
||
},
|
||
{
|
||
img: '../../assets/onboarding/index/platform-flows/meituan/7-coupon-select.jpg',
|
||
guide: '点击确认',
|
||
spotlight: { top: 752, left: 9, width: 354, height: 55 },
|
||
plusFocus: { top: 780, left: 312, width: 104, height: 52, shape: 'confirm' },
|
||
finger: { top: 729, left: 313, size: 60, imgTransform: 'rotate(-90deg)' },
|
||
guideTop: 696,
|
||
guideLeft: 187.5,
|
||
clickTarget: 'plus',
|
||
spotlightRadius: 24,
|
||
spotlightOpacity: .62,
|
||
},
|
||
{
|
||
img: '../../assets/onboarding/index/platform-flows/meituan/8-checkout-coupon.jpg',
|
||
mode: 'startCompare',
|
||
},
|
||
// ===== 淘宝 Agent 自动比价流程 =====
|
||
// 比价阶段:美团已用作起点(done),淘宝为当前 active 平台
|
||
{
|
||
img: '../../assets/onboarding/index/platform-flows/taobao/1-home.jpg',
|
||
mode: 'agentFlow',
|
||
agentText: '正在打开淘宝...',
|
||
retentionPercent: 11,
|
||
platforms: { 'meituan-waimai': 'done', 'taobao-shanguang': 'active' },
|
||
},
|
||
{
|
||
img: '../../assets/onboarding/index/platform-flows/taobao/4-search.jpg',
|
||
mode: 'agentFlow',
|
||
agentText: '正在搜索「窑鸡王」...',
|
||
retentionPercent: 26,
|
||
platforms: { 'meituan-waimai': 'done', 'taobao-shanguang': 'active' },
|
||
},
|
||
{
|
||
img: '../../assets/onboarding/index/platform-flows/taobao/5-shop-top.jpg',
|
||
mode: 'agentFlow',
|
||
agentText: '正在浏览菜单...',
|
||
retentionPercent: 40,
|
||
platforms: { 'meituan-waimai': 'done', 'taobao-shanguang': 'active' },
|
||
},
|
||
{
|
||
img: '../../assets/onboarding/index/platform-flows/taobao/6-shop-item.jpg',
|
||
mode: 'agentFlow',
|
||
agentText: '搜索同款商品中...',
|
||
retentionPercent: 55,
|
||
platforms: { 'meituan-waimai': 'done', 'taobao-shanguang': 'active' },
|
||
},
|
||
{
|
||
img: '../../assets/onboarding/index/platform-flows/taobao/7-spec.jpg',
|
||
mode: 'agentFlow',
|
||
agentText: '正在确认商品规格...',
|
||
retentionPercent: 70,
|
||
platforms: { 'meituan-waimai': 'done', 'taobao-shanguang': 'active' },
|
||
},
|
||
{
|
||
img: '../../assets/onboarding/index/platform-flows/taobao/8-checkout.jpg',
|
||
mode: 'agentFlow',
|
||
agentText: '正在应用所有优惠...',
|
||
retentionPercent: 85,
|
||
platforms: { 'meituan-waimai': 'done', 'taobao-shanguang': 'active' },
|
||
},
|
||
{
|
||
img: '../../assets/onboarding/index/platform-flows/taobao/result.jpg',
|
||
mode: 'agentFlow',
|
||
agentText: '正在获取淘宝最终价格',
|
||
retentionPercent: 100,
|
||
last: true,
|
||
platforms: { 'meituan-waimai': 'done', 'taobao-shanguang': 'active' },
|
||
},
|
||
];
|
||
let demoStep = 0;
|
||
let couponTotal = 0;
|
||
let pendingDemoStartStep = null;
|
||
|
||
function startComparison() {
|
||
demoStep = pendingDemoStartStep != null ? pendingDemoStartStep : 0;
|
||
pendingDemoStartStep = null;
|
||
couponTotal = 0;
|
||
const numEl = document.getElementById('demoCouponNum');
|
||
if (numEl) numEl.textContent = '0';
|
||
renderDemoStep();
|
||
}
|
||
|
||
// 距下一个 0 点倒计时(每秒更新 v6-expiry 三个 time-box)
|
||
let __midnightTimer = null;
|
||
function startMidnightCountdown() {
|
||
function pad(n) { return n < 10 ? '0' + n : '' + n; }
|
||
function tick() {
|
||
var hEl = document.getElementById('cdH');
|
||
var mEl = document.getElementById('cdM');
|
||
var sEl = document.getElementById('cdS');
|
||
if (!hEl || !mEl || !sEl) { stopMidnightCountdown(); return; }
|
||
var now = new Date();
|
||
var midnight = new Date(now);
|
||
midnight.setHours(24, 0, 0, 0);
|
||
var diff = Math.max(0, Math.floor((midnight - now) / 1000));
|
||
var h = Math.floor(diff / 3600);
|
||
var m = Math.floor((diff % 3600) / 60);
|
||
var s = diff % 60;
|
||
hEl.textContent = pad(h);
|
||
mEl.textContent = pad(m);
|
||
sEl.textContent = pad(s);
|
||
}
|
||
stopMidnightCountdown();
|
||
tick();
|
||
__midnightTimer = setInterval(tick, 1000);
|
||
}
|
||
function stopMidnightCountdown() {
|
||
if (__midnightTimer) { clearInterval(__midnightTimer); __midnightTimer = null; }
|
||
}
|
||
|
||
// 高频弹跳:N 次连续 +1,每次都触发数字弹跳 + 多向粒子喷射(F2 样式)
|
||
// K 方案:从 0 缓出到目标值(用于"领券完成"弹窗的总数和分平台数)
|
||
function runKCountUp(elId, target, duration, delay) {
|
||
const el = document.getElementById(elId);
|
||
if (!el) return;
|
||
el.textContent = '0';
|
||
setTimeout(() => {
|
||
let start = null;
|
||
const step = ts => {
|
||
if (!start) start = ts;
|
||
const p = Math.min((ts - start) / duration, 1);
|
||
const eased = 1 - Math.pow(1 - p, 3);
|
||
el.textContent = Math.round(target * eased);
|
||
if (p < 1) requestAnimationFrame(step);
|
||
};
|
||
requestAnimationFrame(step);
|
||
}, delay || 0);
|
||
}
|
||
|
||
function playCouponDelta(delta) {
|
||
const numEl = document.getElementById('demoCouponNum');
|
||
const numBlock = document.getElementById('demoCouponNumBlock');
|
||
if (!numEl || !numBlock) return;
|
||
const tickInterval = 130;
|
||
for (let i = 0; i < delta; i++) {
|
||
setTimeout(() => {
|
||
couponTotal += 1;
|
||
numEl.textContent = couponTotal;
|
||
numEl.classList.remove('coupon-num-pop');
|
||
void numEl.offsetWidth;
|
||
numEl.classList.add('coupon-num-pop');
|
||
const particleCount = 1 + Math.floor(Math.random() * 2);
|
||
for (let k = 0; k < particleCount; k++) {
|
||
const angle = -Math.PI / 2 + (Math.random() - 0.5) * 1.6;
|
||
const dist = 26 + Math.random() * 18;
|
||
const p = document.createElement('div');
|
||
p.className = 'coupon-plus-particle';
|
||
p.textContent = '+1';
|
||
p.style.setProperty('--dx', Math.cos(angle) * dist + 'px');
|
||
p.style.setProperty('--dy', Math.sin(angle) * dist + 'px');
|
||
numBlock.appendChild(p);
|
||
setTimeout(() => p.remove(), 900);
|
||
}
|
||
}, i * tickInterval);
|
||
}
|
||
}
|
||
|
||
function renderDemoStep() {
|
||
const s = demoSteps[demoStep];
|
||
document.getElementById('demoScreenshot').src = s.img;
|
||
// AI 接管橘黄光晕:仅在 agentFlow 阶段(块 1 一键领券 + 块 3 自动比价)开启
|
||
const aiGlow = document.getElementById('aiTakeoverGlow');
|
||
if (aiGlow) aiGlow.classList.toggle('active', s.mode === 'agentFlow');
|
||
// 进度条已移除(原 demoProgressBar),不再做按 step 计算宽度的逻辑
|
||
|
||
const spot = document.getElementById('demoSpotlight');
|
||
const plusFocus = document.getElementById('demoPlusFocus');
|
||
const finger = document.getElementById('demoFinger');
|
||
const guide = document.getElementById('demoGuide');
|
||
const guideText = document.getElementById('demoGuideText');
|
||
const kickoff = document.getElementById('demoKickoff');
|
||
const swipeOverlay = document.getElementById('demoSwipeOverlay');
|
||
const startOverlay = document.getElementById('demoStartOverlay');
|
||
|
||
const agentOverlay = document.getElementById('demoAgentOverlay');
|
||
const couponPrompt = document.getElementById('demoCouponPrompt');
|
||
const couponDoneToast = document.getElementById('demoCouponDoneToast');
|
||
|
||
// 先全部隐藏
|
||
swipeOverlay.style.display = 'none';
|
||
startOverlay.style.display = 'none';
|
||
agentOverlay.style.display = 'none';
|
||
couponPrompt.style.display = 'none';
|
||
couponDoneToast.style.display = 'none';
|
||
kickoff.style.display = 'none';
|
||
plusFocus.style.display = 'none';
|
||
plusFocus.className = 'demo-plus-focus';
|
||
plusFocus.style.width = '46px';
|
||
plusFocus.style.height = '46px';
|
||
finger.classList.remove('demo-plus-finger');
|
||
finger.style.width = '58px';
|
||
finger.style.height = '58px';
|
||
finger.style.zIndex = '15';
|
||
const fingerImg = finger.querySelector('.gesture-hand-img');
|
||
fingerImg.style.transform = '';
|
||
|
||
// ===== 一键领券弹窗 =====
|
||
if (s.mode === 'couponPrompt') {
|
||
spot.style.display = 'none';
|
||
finger.style.display = 'none';
|
||
guide.style.display = 'none';
|
||
renderCouponPromptPlatforms();
|
||
couponPrompt.style.display = 'flex';
|
||
return;
|
||
}
|
||
|
||
// ===== 一键领券完成 toast =====
|
||
if (s.mode === 'couponDone') {
|
||
spot.style.display = 'none';
|
||
finger.style.display = 'none';
|
||
guide.style.display = 'none';
|
||
// home 模式:toast 应展示在首页背景之上,先切回 home 再弹
|
||
if (homeClaimMode) {
|
||
go('home');
|
||
}
|
||
couponDoneToast.style.display = 'block';
|
||
// 0 → N 计数动画;不自动消失,等用户点击 CTA 才推进
|
||
runKCountUp('demoCouponDoneCount', couponTotal || 20, 1500, 200);
|
||
// 启动距 0 点倒计时(每秒滴答)
|
||
startMidnightCountdown();
|
||
return;
|
||
}
|
||
|
||
if (s.mode === 'swipe') {
|
||
spot.style.display = 'none';
|
||
finger.style.display = 'none';
|
||
guide.style.display = 'none';
|
||
swipeOverlay.style.display = 'flex';
|
||
swipeOverlay.querySelector('.swipe-text').textContent = s.guide;
|
||
return;
|
||
}
|
||
|
||
if (s.mode === 'startCompare') {
|
||
spot.style.display = 'none';
|
||
finger.style.display = 'none';
|
||
guide.style.display = 'none';
|
||
startOverlay.style.display = 'block';
|
||
return;
|
||
}
|
||
|
||
if (s.mode === 'agentFlow') {
|
||
spot.style.display = 'none';
|
||
finger.style.display = 'none';
|
||
guide.style.display = 'none';
|
||
agentOverlay.style.display = 'block';
|
||
// 块 1(领券) vs 块 3(比价)切换浮窗形态
|
||
const firstSpotlightIdx = demoSteps.findIndex(d => d.spotlight || d.mode === 'swipe' || d.mode === 'startCompare');
|
||
const inCouponPhase = firstSpotlightIdx > 0 && demoStep < firstSpotlightIdx;
|
||
const agentFloat = document.getElementById('demoAgentFloat');
|
||
const comparingFloat = document.getElementById('demoComparingFloat');
|
||
if (inCouponPhase) {
|
||
// 块 1:领券阶段 → 显示已领券计数浮窗(显式 flex,避免清掉 inline display:flex)
|
||
if (agentFloat) agentFloat.style.display = 'flex';
|
||
if (comparingFloat) comparingFloat.style.display = 'none';
|
||
document.getElementById('demoAgentText').textContent = s.agentText;
|
||
if (s.couponDelta) playCouponDelta(s.couponDelta);
|
||
renderFloatPlatforms('demoAgentPlatforms', s.platforms);
|
||
} else {
|
||
// 块 3:比价阶段 → 显示合并比价浮窗(无已领券计数,红包激励融入副文案动效)
|
||
if (agentFloat) agentFloat.style.display = 'none';
|
||
if (comparingFloat) comparingFloat.style.display = 'block';
|
||
document.getElementById('demoComparingText').textContent = s.agentText;
|
||
if (s.retentionPercent != null) {
|
||
const fill = document.getElementById('demoComparingFill');
|
||
if (fill) fill.style.width = s.retentionPercent + '%';
|
||
}
|
||
renderFloatPlatforms('demoComparingPlatforms', s.platforms);
|
||
}
|
||
return;
|
||
}
|
||
|
||
// 默认:聚光灯模式
|
||
spot.style.display = 'block';
|
||
spot.style.top = s.spotlight.top + 'px';
|
||
spot.style.left = s.spotlight.left + 'px';
|
||
spot.style.width = s.spotlight.width + 'px';
|
||
spot.style.height = s.spotlight.height + 'px';
|
||
spot.style.borderRadius = (s.spotlightRadius ? s.spotlightRadius + 'px' : '12px');
|
||
spot.style.boxShadow = '0 0 0 9999px rgba(0,0,0,' + (s.spotlightOpacity != null ? s.spotlightOpacity : .5) + ')';
|
||
spot.style.pointerEvents = s.clickTarget === 'plus' ? 'none' : 'auto';
|
||
spot.style.cursor = s.clickTarget === 'plus' ? 'default' : 'pointer';
|
||
|
||
if (s.plusFocus) {
|
||
plusFocus.style.display = 'block';
|
||
plusFocus.style.top = s.plusFocus.top + 'px';
|
||
plusFocus.style.left = s.plusFocus.left + 'px';
|
||
plusFocus.style.width = (s.plusFocus.width || 46) + 'px';
|
||
plusFocus.style.height = (s.plusFocus.height || 46) + 'px';
|
||
plusFocus.classList.add(s.plusFocus.shape || 'circle');
|
||
if (s.clickTarget === 'plus') plusFocus.classList.add('clickable');
|
||
}
|
||
|
||
if (s.finger) {
|
||
finger.style.display = 'block';
|
||
finger.style.top = s.finger.top + 'px';
|
||
finger.style.left = s.finger.left + 'px';
|
||
finger.style.width = (s.finger.size || 58) + 'px';
|
||
finger.style.height = (s.finger.size || 58) + 'px';
|
||
if (s.finger.plusGuide) {
|
||
finger.classList.add('demo-plus-finger');
|
||
finger.style.transform = 'none';
|
||
} else {
|
||
finger.style.transform = s.finger.mirror ? 'scaleX(-1)' : 'none';
|
||
if (s.finger.imgTransform) {
|
||
fingerImg.style.transform = s.finger.imgTransform;
|
||
}
|
||
}
|
||
} else {
|
||
finger.style.display = 'none';
|
||
}
|
||
|
||
if (s.kickoff && s.guide) {
|
||
// Kickoff 黄卡:标题 + 虚线 + 圆形箭头 + 引线
|
||
guide.style.display = 'none';
|
||
document.getElementById('demoKickoffTitle').textContent = s.guideTitle || '下一步,比出全网最低价';
|
||
document.getElementById('demoKickoffText').textContent = s.guide;
|
||
kickoff.style.display = 'block';
|
||
// 让卡片底部到引线落点正好对齐 spotlight 顶部
|
||
const cardEl = kickoff.querySelector('.kickoff-card');
|
||
const leaderH = 36;
|
||
const cardH = cardEl.offsetHeight;
|
||
kickoff.style.top = (s.spotlight.top - leaderH - cardH) + 'px';
|
||
} else if (s.guide) {
|
||
guide.style.display = 'block';
|
||
guideText.textContent = s.guide;
|
||
var bubbleTopY = null;
|
||
if (s.guideTop != null) {
|
||
guide.style.top = s.guideTop + 'px';
|
||
guide.style.left = (s.guideLeft != null ? s.guideLeft + 'px' : '50%');
|
||
guide.style.right = 'auto';
|
||
guide.style.transform = 'translateX(-50%)';
|
||
bubbleTopY = s.guideTop;
|
||
} else if (s.guidePos === 'above') {
|
||
const offset = s.guideOffset || -50;
|
||
guide.style.top = (s.spotlight.top + offset) + 'px';
|
||
bubbleTopY = s.spotlight.top + offset;
|
||
if (s.guideAlign === 'spotlight') {
|
||
var cx = s.spotlight.left + s.spotlight.width / 2;
|
||
// 渲染后检查是否超出屏幕,先设置位置
|
||
guide.style.left = cx + 'px';
|
||
guide.style.transform = 'translateX(-50%)';
|
||
// 延迟检查边界并修正
|
||
setTimeout(function() {
|
||
var rect = guide.getBoundingClientRect();
|
||
var device = document.getElementById('app').getBoundingClientRect();
|
||
if (rect.right > device.right - 8) {
|
||
guide.style.left = 'auto';
|
||
guide.style.right = '8px';
|
||
guide.style.transform = 'none';
|
||
}
|
||
}, 10);
|
||
} else {
|
||
guide.style.left = '50%';
|
||
guide.style.right = 'auto';
|
||
guide.style.transform = 'translateX(-50%)';
|
||
}
|
||
}
|
||
// 动态定位 leader:dot 中心贴在 spotlight 最近的边缘上
|
||
var leader = guide.querySelector('.demo-guide-leader');
|
||
if (leader) {
|
||
leader.classList.remove('dir-down', 'dir-up');
|
||
leader.style.height = '';
|
||
leader.style.display = '';
|
||
if (bubbleTopY != null && s.spotlight) {
|
||
var bubbleH = guideText.offsetHeight;
|
||
var bubbleBottomY = bubbleTopY + bubbleH;
|
||
var targetTop = s.spotlight.top;
|
||
var targetBottom = s.spotlight.top + s.spotlight.height;
|
||
if (bubbleBottomY <= targetTop) {
|
||
leader.classList.add('dir-down');
|
||
leader.style.height = Math.max(0, targetTop - bubbleBottomY + 1) + 'px';
|
||
} else if (bubbleTopY >= targetBottom) {
|
||
leader.classList.add('dir-up');
|
||
leader.style.height = Math.max(0, bubbleTopY - targetBottom + 1) + 'px';
|
||
} else {
|
||
leader.style.display = 'none';
|
||
}
|
||
} else {
|
||
leader.style.display = 'none';
|
||
}
|
||
}
|
||
} else {
|
||
guide.style.display = 'none';
|
||
}
|
||
}
|
||
|
||
function demoPlusHit(event) {
|
||
event.stopPropagation();
|
||
const el = event.currentTarget;
|
||
const rect = el.getBoundingClientRect();
|
||
const x = event.clientX - rect.left;
|
||
const y = event.clientY - rect.top;
|
||
if (el.classList.contains('circle')) {
|
||
const radius = Math.min(rect.width, rect.height) / 2;
|
||
const dx = x - rect.width / 2;
|
||
const dy = y - rect.height / 2;
|
||
if ((dx * dx + dy * dy) > radius * radius) {
|
||
return;
|
||
}
|
||
}
|
||
if (el.classList.contains('pill')) {
|
||
const radius = rect.height / 2;
|
||
const leftCap = radius;
|
||
const rightCap = rect.width - radius;
|
||
const inCenter = x >= leftCap && x <= rightCap && y >= 0 && y <= rect.height;
|
||
const dx = x < leftCap ? x - leftCap : x - rightCap;
|
||
const dy = y - radius;
|
||
if (!inCenter && (dx * dx + dy * dy) > radius * radius) {
|
||
return;
|
||
}
|
||
}
|
||
if (el.classList.contains('confirm')) {
|
||
const leftRadius = 4;
|
||
const rightRadius = rect.height / 2;
|
||
const inMiddle = y >= 0 && y <= rect.height && x >= leftRadius && x <= rect.width - rightRadius;
|
||
const inLeft = x >= 0 && x < leftRadius && y >= leftRadius && y <= rect.height - leftRadius;
|
||
const inRight = x > rect.width - rightRadius && x <= rect.width && y >= 0 && y <= rect.height;
|
||
const dx = x - (rect.width - rightRadius);
|
||
const dy = y - rightRadius;
|
||
if (!inMiddle && !inLeft && (!inRight || (dx * dx + dy * dy) > rightRadius * rightRadius)) {
|
||
return;
|
||
}
|
||
}
|
||
demoNext();
|
||
}
|
||
|
||
function demoNext() {
|
||
// 离开 couponDone 弹窗时关掉倒计时
|
||
stopMidnightCountdown();
|
||
const s = demoSteps[demoStep];
|
||
// home 一键领券模式:couponDone toast CTA → 回首页并切换"已领"态
|
||
if (homeClaimMode && s && s.mode === 'couponDone') {
|
||
onHomeCouponClaimDone();
|
||
return;
|
||
}
|
||
if (s.last) {
|
||
renderCelebrationSavings();
|
||
renderResults('celebResults');
|
||
go('celebration');
|
||
return;
|
||
}
|
||
if (demoStep < demoSteps.length - 1) {
|
||
demoStep++;
|
||
renderDemoStep();
|
||
}
|
||
}
|
||
|
||
// ===== 一键领券弹窗按钮 =====
|
||
function onClaimCouponConfirm() {
|
||
// 首页卡片入口:先在首页弹确认,确认后再进入平台领券 agent flow。
|
||
const prompt = document.getElementById('demoCouponPrompt');
|
||
if (prompt) prompt.style.display = 'none';
|
||
const comparing = document.getElementById('comparing');
|
||
if (homeClaimMode && comparing && !comparing.classList.contains('active')) {
|
||
const firstAgentIdx = demoSteps.findIndex(d => d.mode === 'agentFlow');
|
||
pendingDemoStartStep = firstAgentIdx > 0 ? firstAgentIdx : 1;
|
||
go('comparing');
|
||
return;
|
||
}
|
||
demoNext();
|
||
}
|
||
|
||
// ===== 首页"一键领优惠"卡片:去领取 → 弹窗 → agent 领券 → 完成 → 回首页 =====
|
||
let homeClaimMode = false;
|
||
let homeCouponClaimed = false;
|
||
let homeCouponClaimSummary = null; // { total, platforms: [{ id, name, icon }] }
|
||
|
||
function onTriClaimClick() {
|
||
// 已领取过:tile 仅作展示,再次点击不重启流程
|
||
if (homeCouponClaimed) return;
|
||
homeClaimMode = true;
|
||
demoStep = 0;
|
||
couponTotal = 0;
|
||
const numEl = document.getElementById('demoCouponNum');
|
||
if (numEl) numEl.textContent = '0';
|
||
renderCouponPromptPlatforms();
|
||
const prompt = document.getElementById('demoCouponPrompt');
|
||
const app = document.getElementById('app');
|
||
if (prompt && app) {
|
||
app.appendChild(prompt);
|
||
prompt.style.display = 'flex';
|
||
}
|
||
}
|
||
|
||
function closeHomeCouponClaim() {
|
||
// 关闭弹窗 → 回首页(保持未领状态)
|
||
document.getElementById('demoCouponPrompt').style.display = 'none';
|
||
homeClaimMode = false;
|
||
stopMidnightCountdown();
|
||
go('home');
|
||
}
|
||
|
||
function onCouponPromptMaskClick(e) {
|
||
// 点击弹窗外侧蒙层关闭(home 模式才生效;点中卡片不关)
|
||
if (!homeClaimMode) return;
|
||
if (e.target && e.target.id === 'demoCouponPrompt') closeHomeCouponClaim();
|
||
}
|
||
|
||
function onHomeCouponClaimDone() {
|
||
homeClaimMode = false;
|
||
homeCouponClaimed = true;
|
||
stopMidnightCountdown();
|
||
// toast 现在是 device 级 overlay,跳页时不会自动消失,需要手动关
|
||
const toast = document.getElementById('demoCouponDoneToast');
|
||
if (toast) toast.style.display = 'none';
|
||
// 汇总:领券数(demoSteps couponDelta 累加得到的 couponTotal) + 已安装平台
|
||
const platforms = (typeof getVisibleApps === 'function' ? getVisibleApps() : [])
|
||
.filter(a => a.installed)
|
||
.map(a => ({ id: a.id, name: a.name, icon: a.icon }));
|
||
homeCouponClaimSummary = {
|
||
total: couponTotal || 20,
|
||
platforms: platforms,
|
||
};
|
||
go('home');
|
||
renderTriClaim();
|
||
}
|
||
|
||
function renderTriClaim() {
|
||
const def = document.getElementById('triClaimDefault');
|
||
const done = document.getElementById('triClaimDone');
|
||
if (!def || !done) return;
|
||
if (!homeCouponClaimed || !homeCouponClaimSummary) {
|
||
def.style.display = '';
|
||
done.style.display = 'none';
|
||
return;
|
||
}
|
||
def.style.display = 'none';
|
||
done.style.display = '';
|
||
const numEl = document.getElementById('triClaimDoneNum');
|
||
if (numEl) numEl.textContent = homeCouponClaimSummary.total;
|
||
const logosEl = document.getElementById('triClaimDoneLogos');
|
||
if (logosEl) {
|
||
// 取前 3 个 logo(一行内放得下),更多则用 +N 表示
|
||
const ps = homeCouponClaimSummary.platforms || [];
|
||
const shown = ps.slice(0, 3);
|
||
let html = shown.map(p => '<img src="' + p.icon + '" alt="' + p.name + '">').join('');
|
||
if (ps.length > shown.length) {
|
||
html += '<span style="font-size: 10px;font-weight: 700;color: #fff;margin-left: 2px;">+' + (ps.length - shown.length) + '</span>';
|
||
}
|
||
logosEl.innerHTML = html;
|
||
}
|
||
}
|
||
|
||
// ===== 一键领券弹窗 · 多版本(平台选择中部 + 视觉风格切换)=====
|
||
function toggleCouponPlatform(el) {
|
||
if (!el) return;
|
||
el.dataset.checked = el.dataset.checked === 'true' ? 'false' : 'true';
|
||
}
|
||
|
||
const couponPromptVariants = {
|
||
// V2 「快手糖果风」粉橙渐变外卡 + 白色内卡 3 列网格
|
||
v2: '' +
|
||
'<div style="background: linear-gradient(180deg,#FF6B9E 0%,#FF8FAB 55%,#FFAA8C 100%);border-radius: 24px;padding: 16px 16px 16px;width: 100%;box-shadow: 0 16px 48px rgba(255,80,120,.45);text-align: center;">' +
|
||
'<div style="width: 52px;height: 52px;border-radius: 13px;margin: 0 auto 8px;background: #FFD600;display: flex;align-items: center;justify-content: center;box-shadow: 0 4px 14px rgba(255,179,0,.5);"><span style="font-size: 17px;font-weight: 900;color: #1a1a1a;line-height: 1.05;text-align: center;">傻瓜<br>比价</span></div>' +
|
||
'<div style="font-size: 17px;font-weight: 900;color: #fff;line-height: 1.4;margin-bottom: 12px;text-shadow: 0 1px 2px rgba(0,0,0,.08);">您今日还有大额优惠券可领</div>' +
|
||
'<div style="background: linear-gradient(180deg,#fff 70%,#FFF1F4 100%);border-radius: 18px;padding: 12px 12px;margin-bottom: 16px;">' +
|
||
'<div style="font-size: 11px;color: var(--gray-600);font-weight: 600;margin-bottom: 12px;">已为您发现 <span style="color: #FF4081;font-weight: 800;">3</span> 个平台都有大额优惠</div>' +
|
||
'<div style="display: grid;grid-template-columns: repeat(3,1fr);gap: 8px;">' +
|
||
['美团', '../../assets/shared/logos/meituan.png', '淘宝', '../../assets/shared/logos/taobao.png', '京东', '../../assets/shared/logos/jd.png'].reduce(function(acc, _, i, arr){ if (i % 2) return acc; return acc + '<div data-checked="true" onclick="toggleCouponPlatform(this)" class="cp-card cp-card-pink" style="background: #fff;border: 2px solid #FF6B9E;border-radius: 12px;padding: 8px 4px 8px;position: relative;"><img src="' + arr[i+1] + '" style="width: 36px;height: 36px;border-radius: 8px;margin: 0 auto;display: block;"/><div style="font-size: 11px;font-weight: 700;color: var(--gray-900);margin-top: 6px;">' + arr[i] + '</div><span class="cp-check" style="position: absolute;top: 4px;right: 4px;width: 16px;height: 16px;border-radius: 50%;background: #FF4081;display: flex;align-items: center;justify-content: center;"><svg width="9" height="9" viewBox="0 0 9 9"><path d="M2 4.5l1.5 1.5 3-4" stroke="#fff" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" fill="none"/></svg></span></div>'; }, '') +
|
||
'</div>' +
|
||
'</div>' +
|
||
'<button class="btn btn-primary btn-lg" style="border-radius: 24px;font-size: 16px;height: 48px;width: 100%;background: linear-gradient(180deg,#FFE066,#FFD600);color: #1a1a1a;font-weight: 900;box-shadow: 0 6px 16px rgba(255,179,0,.5);" onclick="onClaimCouponConfirm()">一键自动领取</button>' +
|
||
'</div>',
|
||
|
||
// V3 「品牌黄横向选择卡」黄→白渐变外卡 + 3 张并排选择卡(琥珀边框态)+ 黄色品牌按钮(加深收尾保对比)
|
||
v3: '' +
|
||
'<div style="background: linear-gradient(180deg,#FFE066 0%,#FFF3C4 50%,#FFFDF5 100%);border-radius: 24px;padding: 24px 16px 16px;width: 100%;box-shadow: 0 16px 48px rgba(255,193,7,.4);text-align: center;">' +
|
||
'<div style="width: 52px;height: 52px;border-radius: 13px;margin: 0 auto 8px;background: #FFD600;display: flex;align-items: center;justify-content: center;box-shadow: 0 4px 14px rgba(255,179,0,.5);"><span style="font-size: 17px;font-weight: 900;color: #1a1a1a;line-height: 1.05;text-align: center;">傻瓜<br>比价</span></div>' +
|
||
'<div style="font-size: 18px;font-weight: 900;color: var(--gray-900);line-height: 1.4;margin-bottom: 12px;">您今日还有大额优惠券可领</div>' +
|
||
'<div style="background: #fff;border-radius: 18px;padding: 12px 8px;margin-bottom: 8px;box-shadow: 0 2px 12px rgba(255,193,7,.15);">' +
|
||
'<div style="display: grid;grid-template-columns: repeat(3,1fr);gap: 8px;">' +
|
||
['美团', '../../assets/shared/logos/meituan.png', '淘宝', '../../assets/shared/logos/taobao.png', '京东', '../../assets/shared/logos/jd.png'].reduce(function(acc, _, i, arr){ if (i % 2) return acc; return acc + '<div data-checked="true" onclick="toggleCouponPlatform(this)" class="cp-card cp-card-yellow" style="background: #fff;border: 2px solid #FFB300;border-radius: 14px;padding: 12px 4px 8px;position: relative;"><img src="' + arr[i+1] + '" style="width: 42px;height: 42px;border-radius: 8px;margin: 0 auto;display: block;"/><div style="font-size: 12px;font-weight: 700;color: var(--gray-900);margin-top: 8px;">' + arr[i] + '</div><span class="cp-check" style="position: absolute;top: 6px;right: 6px;width: 18px;height: 18px;border-radius: 50%;background: #FFB300;display: flex;align-items: center;justify-content: center;"><svg width="10" height="10" viewBox="0 0 9 9"><path d="M2 4.5l1.5 1.5 3-4" stroke="#fff" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" fill="none"/></svg></span></div>'; }, '') +
|
||
'</div>' +
|
||
'</div>' +
|
||
'<div style="font-size: 12px;color: var(--gray-500);font-weight: 500;margin-bottom: 12px;">将在以上平台领取</div>' +
|
||
'<button class="btn btn-lg" style="border-radius: 24px;font-size: 16px;height: 50px;width: 100%;background: linear-gradient(180deg,#FFD600 0%,#FFA000 100%);color: #1a1a1a;font-weight: 900;box-shadow: 0 8px 22px rgba(255,140,0,.5);border: none;" onclick="onClaimCouponConfirm()">一键自动领取</button>' +
|
||
'</div>',
|
||
|
||
// V4 「黄色品牌风」白底外卡 + 纵向 3 行平台列表 + 黄色 toggle 开关
|
||
v4: '' +
|
||
'<div style="background: #fff;border-radius: 24px;padding: 24px 16px 16px;width: 100%;text-align: center;box-shadow: 0 16px 48px rgba(0,0,0,.3);border-top: 6px solid #FFD600;">' +
|
||
'<div style="width: 56px;height: 56px;border-radius: 14px;margin: 0 auto 12px;background: #FFD600;display: flex;align-items: center;justify-content: center;box-shadow: 0 4px 14px rgba(255,179,0,.5);"><span style="font-size: 18px;font-weight: 900;color: #1a1a1a;line-height: 1.05;text-align: center;">傻瓜<br>比价</span></div>' +
|
||
'<div style="font-size: 18px;font-weight: 800;color: var(--gray-900);line-height: 1.4;margin-bottom: 12px;">您今日还有大额优惠券可领</div>' +
|
||
'<div style="background: var(--gray-100);border-radius: 14px;padding: 8px;margin-bottom: 16px;display: flex;flex-direction: column;gap: 6px;">' +
|
||
['美团', '../../assets/shared/logos/meituan.png', '淘宝', '../../assets/shared/logos/taobao.png', '京东', '../../assets/shared/logos/jd.png'].reduce(function(acc, _, i, arr){ if (i % 2) return acc; return acc + '<div data-checked="true" onclick="toggleCouponPlatform(this)" class="cp-card cp-card-yellow" style="background: #fff;border: 1.5px solid #FFD600;border-radius: 12px;padding: 8px 12px;display: flex;align-items: center;gap: 8px;text-align: left;"><img src="' + arr[i+1] + '" style="width: 36px;height: 36px;border-radius: 8px;flex-shrink: 0;"/><div style="flex: 1;font-size: 14px;font-weight: 700;color: var(--gray-900);">' + arr[i] + '</div><span class="cp-toggle" style="position: relative;width: 36px;height: 20px;border-radius: 8px;background: #FFD600;flex-shrink: 0;transition: background .2s;"><span style="position: absolute;top: 2px;left: 2px;width: 16px;height: 16px;border-radius: 50%;background: #fff;box-shadow: 0 1px 3px rgba(0,0,0,.2);transform: translateX(16px);transition: transform .2s;"></span></span></div>'; }, '') +
|
||
'</div>' +
|
||
'<button class="btn btn-primary btn-lg" style="border-radius: 24px;font-size: 16px;height: 48px;width: 100%;" onclick="onClaimCouponConfirm()">一键自动领取</button>' +
|
||
'</div>',
|
||
|
||
// ===== V3 副标题处理方案 a~e(仅副标题区域不同,其他与 V3 一致)=====
|
||
// V3a 「机制副标题」副标题改讲"AI 自动 · 跨平台"机制,13px / 600 / 暗金
|
||
v3a: '' +
|
||
'<div style="background: linear-gradient(180deg,#FFE066 0%,#FFF3C4 50%,#FFFDF5 100%);border-radius: 24px;padding: 24px 16px 16px;width: 100%;box-shadow: 0 16px 48px rgba(255,193,7,.4);text-align: center;">' +
|
||
'<div style="width: 52px;height: 52px;border-radius: 13px;margin: 0 auto 8px;background: #FFD600;display: flex;align-items: center;justify-content: center;box-shadow: 0 4px 14px rgba(255,179,0,.5);"><span style="font-size: 17px;font-weight: 900;color: #1a1a1a;line-height: 1.05;text-align: center;">傻瓜<br>比价</span></div>' +
|
||
'<div style="font-size: 18px;font-weight: 900;color: var(--gray-900);line-height: 1.4;margin-bottom: 6px;">您今日还有大额优惠券可领</div>' +
|
||
'<div style="font-size: 13px;font-weight: 600;color: #8B6914;line-height: 1.5;margin-bottom: 12px;">AI 跨平台一键领取,无需手动切换 APP</div>' +
|
||
'<div style="background: #fff;border-radius: 18px;padding: 12px 8px;margin-bottom: 8px;box-shadow: 0 2px 12px rgba(255,193,7,.15);">' +
|
||
'<div style="display: grid;grid-template-columns: repeat(3,1fr);gap: 8px;">' +
|
||
['美团', '../../assets/shared/logos/meituan.png', '淘宝', '../../assets/shared/logos/taobao.png', '京东', '../../assets/shared/logos/jd.png'].reduce(function(acc, _, i, arr){ if (i % 2) return acc; return acc + '<div data-checked="true" onclick="toggleCouponPlatform(this)" class="cp-card cp-card-yellow" style="background: #fff;border: 2px solid #FFB300;border-radius: 14px;padding: 12px 4px 8px;position: relative;"><img src="' + arr[i+1] + '" style="width: 42px;height: 42px;border-radius: 8px;margin: 0 auto;display: block;"/><div style="font-size: 12px;font-weight: 700;color: var(--gray-900);margin-top: 8px;">' + arr[i] + '</div><span class="cp-check" style="position: absolute;top: 6px;right: 6px;width: 18px;height: 18px;border-radius: 50%;background: #FFB300;display: flex;align-items: center;justify-content: center;"><svg width="10" height="10" viewBox="0 0 9 9"><path d="M2 4.5l1.5 1.5 3-4" stroke="#fff" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" fill="none"/></svg></span></div>'; }, '') +
|
||
'</div>' +
|
||
'</div>' +
|
||
'<div style="font-size: 12px;color: var(--gray-500);font-weight: 500;margin-bottom: 12px;">将在以上平台领取</div>' +
|
||
'<button class="btn btn-lg" style="border-radius: 24px;font-size: 16px;height: 50px;width: 100%;background: linear-gradient(180deg,#FFD600 0%,#FFA000 100%);color: #1a1a1a;font-weight: 900;box-shadow: 0 8px 22px rgba(255,140,0,.5);border: none;" onclick="onClaimCouponConfirm()">一键自动领取</button>' +
|
||
'</div>',
|
||
|
||
// V3b 「黄色胶囊标签」副标题文案不变,但用黄色 pill 包裹 + 🎁 emoji
|
||
v3b: '' +
|
||
'<div style="background: linear-gradient(180deg,#FFE066 0%,#FFF3C4 50%,#FFFDF5 100%);border-radius: 24px;padding: 24px 16px 16px;width: 100%;box-shadow: 0 16px 48px rgba(255,193,7,.4);text-align: center;">' +
|
||
'<div style="width: 52px;height: 52px;border-radius: 13px;margin: 0 auto 8px;background: #FFD600;display: flex;align-items: center;justify-content: center;box-shadow: 0 4px 14px rgba(255,179,0,.5);"><span style="font-size: 17px;font-weight: 900;color: #1a1a1a;line-height: 1.05;text-align: center;">傻瓜<br>比价</span></div>' +
|
||
'<div style="font-size: 18px;font-weight: 900;color: var(--gray-900);line-height: 1.4;margin-bottom: 8px;">您今日还有大额优惠券可领</div>' +
|
||
'<div style="display: inline-block;background: rgba(255,179,0,.18);color: #8B6914;font-size: 12px;font-weight: 700;padding: 4px 12px;border-radius: 32px;margin-bottom: 12px;">🎁 领取后立享更低好价</div>' +
|
||
'<div style="background: #fff;border-radius: 18px;padding: 12px 8px;margin-bottom: 8px;box-shadow: 0 2px 12px rgba(255,193,7,.15);">' +
|
||
'<div style="display: grid;grid-template-columns: repeat(3,1fr);gap: 8px;">' +
|
||
['美团', '../../assets/shared/logos/meituan.png', '淘宝', '../../assets/shared/logos/taobao.png', '京东', '../../assets/shared/logos/jd.png'].reduce(function(acc, _, i, arr){ if (i % 2) return acc; return acc + '<div data-checked="true" onclick="toggleCouponPlatform(this)" class="cp-card cp-card-yellow" style="background: #fff;border: 2px solid #FFB300;border-radius: 14px;padding: 12px 4px 8px;position: relative;"><img src="' + arr[i+1] + '" style="width: 42px;height: 42px;border-radius: 8px;margin: 0 auto;display: block;"/><div style="font-size: 12px;font-weight: 700;color: var(--gray-900);margin-top: 8px;">' + arr[i] + '</div><span class="cp-check" style="position: absolute;top: 6px;right: 6px;width: 18px;height: 18px;border-radius: 50%;background: #FFB300;display: flex;align-items: center;justify-content: center;"><svg width="10" height="10" viewBox="0 0 9 9"><path d="M2 4.5l1.5 1.5 3-4" stroke="#fff" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" fill="none"/></svg></span></div>'; }, '') +
|
||
'</div>' +
|
||
'</div>' +
|
||
'<div style="font-size: 12px;color: var(--gray-500);font-weight: 500;margin-bottom: 12px;">将在以上平台领取</div>' +
|
||
'<button class="btn btn-lg" style="border-radius: 24px;font-size: 16px;height: 50px;width: 100%;background: linear-gradient(180deg,#FFD600 0%,#FFA000 100%);color: #1a1a1a;font-weight: 900;box-shadow: 0 8px 22px rgba(255,140,0,.5);border: none;" onclick="onClaimCouponConfirm()">一键自动领取</button>' +
|
||
'</div>',
|
||
|
||
// V3c 「特性 chip 行」三枚迷你 pill:AI 自动 · 30 秒 · 安全
|
||
v3c: '' +
|
||
'<div style="background: linear-gradient(180deg,#FFE066 0%,#FFF3C4 50%,#FFFDF5 100%);border-radius: 24px;padding: 24px 16px 16px;width: 100%;box-shadow: 0 16px 48px rgba(255,193,7,.4);text-align: center;">' +
|
||
'<div style="width: 52px;height: 52px;border-radius: 13px;margin: 0 auto 8px;background: #FFD600;display: flex;align-items: center;justify-content: center;box-shadow: 0 4px 14px rgba(255,179,0,.5);"><span style="font-size: 17px;font-weight: 900;color: #1a1a1a;line-height: 1.05;text-align: center;">傻瓜<br>比价</span></div>' +
|
||
'<div style="font-size: 18px;font-weight: 900;color: var(--gray-900);line-height: 1.4;margin-bottom: 8px;">您今日还有大额优惠券可领</div>' +
|
||
'<div style="display: flex;justify-content: center;gap: 6px;flex-wrap: wrap;margin-bottom: 12px;">' +
|
||
'<span style="background: rgba(255,179,0,.18);color: #8B6914;font-size: 11px;font-weight: 700;padding: 4px 8px;border-radius: 32px;">🤖 AI 自动</span>' +
|
||
'<span style="background: rgba(255,179,0,.18);color: #8B6914;font-size: 11px;font-weight: 700;padding: 4px 8px;border-radius: 32px;">⚡ 30 秒完成</span>' +
|
||
'<span style="background: rgba(255,179,0,.18);color: #8B6914;font-size: 11px;font-weight: 700;padding: 4px 8px;border-radius: 32px;">🛡️ 安全无感</span>' +
|
||
'</div>' +
|
||
'<div style="background: #fff;border-radius: 18px;padding: 12px 8px;margin-bottom: 8px;box-shadow: 0 2px 12px rgba(255,193,7,.15);">' +
|
||
'<div style="display: grid;grid-template-columns: repeat(3,1fr);gap: 8px;">' +
|
||
['美团', '../../assets/shared/logos/meituan.png', '淘宝', '../../assets/shared/logos/taobao.png', '京东', '../../assets/shared/logos/jd.png'].reduce(function(acc, _, i, arr){ if (i % 2) return acc; return acc + '<div data-checked="true" onclick="toggleCouponPlatform(this)" class="cp-card cp-card-yellow" style="background: #fff;border: 2px solid #FFB300;border-radius: 14px;padding: 12px 4px 8px;position: relative;"><img src="' + arr[i+1] + '" style="width: 42px;height: 42px;border-radius: 8px;margin: 0 auto;display: block;"/><div style="font-size: 12px;font-weight: 700;color: var(--gray-900);margin-top: 8px;">' + arr[i] + '</div><span class="cp-check" style="position: absolute;top: 6px;right: 6px;width: 18px;height: 18px;border-radius: 50%;background: #FFB300;display: flex;align-items: center;justify-content: center;"><svg width="10" height="10" viewBox="0 0 9 9"><path d="M2 4.5l1.5 1.5 3-4" stroke="#fff" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" fill="none"/></svg></span></div>'; }, '') +
|
||
'</div>' +
|
||
'</div>' +
|
||
'<div style="font-size: 12px;color: var(--gray-500);font-weight: 500;margin-bottom: 12px;">将在以上平台领取</div>' +
|
||
'<button class="btn btn-lg" style="border-radius: 24px;font-size: 16px;height: 50px;width: 100%;background: linear-gradient(180deg,#FFD600 0%,#FFA000 100%);color: #1a1a1a;font-weight: 900;box-shadow: 0 8px 22px rgba(255,140,0,.5);border: none;" onclick="onClaimCouponConfirm()">一键自动领取</button>' +
|
||
'</div>',
|
||
|
||
// V3d 「顶部小标签 + 单标题」副标题取消,logo 下方加「今日福利」黄色小 pill
|
||
v3d: '' +
|
||
'<div style="background: linear-gradient(180deg,#FFE066 0%,#FFF3C4 50%,#FFFDF5 100%);border-radius: 24px;padding: 24px 16px 16px;width: 100%;box-shadow: 0 16px 48px rgba(255,193,7,.4);text-align: center;">' +
|
||
'<div style="width: 52px;height: 52px;border-radius: 13px;margin: 0 auto 8px;background: #FFD600;display: flex;align-items: center;justify-content: center;box-shadow: 0 4px 14px rgba(255,179,0,.5);"><span style="font-size: 17px;font-weight: 900;color: #1a1a1a;line-height: 1.05;text-align: center;">傻瓜<br>比价</span></div>' +
|
||
'<div style="display: inline-block;background: #FFD600;color: #1a1a1a;font-size: 11px;font-weight: 800;letter-spacing: .5px;padding: 2px 8px;border-radius: 32px;margin-bottom: 8px;">今日福利</div>' +
|
||
'<div style="font-size: 18px;font-weight: 900;color: var(--gray-900);line-height: 1.4;margin-bottom: 12px;">发现您有未领取的大额优惠券</div>' +
|
||
'<div style="background: #fff;border-radius: 18px;padding: 12px 8px;margin-bottom: 8px;box-shadow: 0 2px 12px rgba(255,193,7,.15);">' +
|
||
'<div style="display: grid;grid-template-columns: repeat(3,1fr);gap: 8px;">' +
|
||
['美团', '../../assets/shared/logos/meituan.png', '淘宝', '../../assets/shared/logos/taobao.png', '京东', '../../assets/shared/logos/jd.png'].reduce(function(acc, _, i, arr){ if (i % 2) return acc; return acc + '<div data-checked="true" onclick="toggleCouponPlatform(this)" class="cp-card cp-card-yellow" style="background: #fff;border: 2px solid #FFB300;border-radius: 14px;padding: 12px 4px 8px;position: relative;"><img src="' + arr[i+1] + '" style="width: 42px;height: 42px;border-radius: 8px;margin: 0 auto;display: block;"/><div style="font-size: 12px;font-weight: 700;color: var(--gray-900);margin-top: 8px;">' + arr[i] + '</div><span class="cp-check" style="position: absolute;top: 6px;right: 6px;width: 18px;height: 18px;border-radius: 50%;background: #FFB300;display: flex;align-items: center;justify-content: center;"><svg width="10" height="10" viewBox="0 0 9 9"><path d="M2 4.5l1.5 1.5 3-4" stroke="#fff" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" fill="none"/></svg></span></div>'; }, '') +
|
||
'</div>' +
|
||
'</div>' +
|
||
'<div style="font-size: 12px;color: var(--gray-500);font-weight: 500;margin-bottom: 12px;">将在以上平台领取</div>' +
|
||
'<button class="btn btn-lg" style="border-radius: 24px;font-size: 16px;height: 50px;width: 100%;background: linear-gradient(180deg,#FFD600 0%,#FFA000 100%);color: #1a1a1a;font-weight: 900;box-shadow: 0 8px 22px rgba(255,140,0,.5);border: none;" onclick="onClaimCouponConfirm()">一键自动领取</button>' +
|
||
'</div>',
|
||
|
||
// V3e 「紧迫感副标题」副标题强调时效,⏰ + 暖红色,13px / 700
|
||
v3e: '' +
|
||
'<div style="background: linear-gradient(180deg,#FFE066 0%,#FFF3C4 50%,#FFFDF5 100%);border-radius: 24px;padding: 24px 16px 16px;width: 100%;box-shadow: 0 16px 48px rgba(255,193,7,.4);text-align: center;">' +
|
||
'<div style="width: 52px;height: 52px;border-radius: 13px;margin: 0 auto 8px;background: #FFD600;display: flex;align-items: center;justify-content: center;box-shadow: 0 4px 14px rgba(255,179,0,.5);"><span style="font-size: 17px;font-weight: 900;color: #1a1a1a;line-height: 1.05;text-align: center;">傻瓜<br>比价</span></div>' +
|
||
'<div style="font-size: 18px;font-weight: 900;color: var(--gray-900);line-height: 1.4;margin-bottom: 6px;">您今日还有大额优惠券可领</div>' +
|
||
'<div style="font-size: 13px;font-weight: 700;color: #D9534F;line-height: 1.5;margin-bottom: 12px;">⏰ 仅今日有效,错过自动失效</div>' +
|
||
'<div style="background: #fff;border-radius: 18px;padding: 12px 8px;margin-bottom: 8px;box-shadow: 0 2px 12px rgba(255,193,7,.15);">' +
|
||
'<div style="display: grid;grid-template-columns: repeat(3,1fr);gap: 8px;">' +
|
||
['美团', '../../assets/shared/logos/meituan.png', '淘宝', '../../assets/shared/logos/taobao.png', '京东', '../../assets/shared/logos/jd.png'].reduce(function(acc, _, i, arr){ if (i % 2) return acc; return acc + '<div data-checked="true" onclick="toggleCouponPlatform(this)" class="cp-card cp-card-yellow" style="background: #fff;border: 2px solid #FFB300;border-radius: 14px;padding: 12px 4px 8px;position: relative;"><img src="' + arr[i+1] + '" style="width: 42px;height: 42px;border-radius: 8px;margin: 0 auto;display: block;"/><div style="font-size: 12px;font-weight: 700;color: var(--gray-900);margin-top: 8px;">' + arr[i] + '</div><span class="cp-check" style="position: absolute;top: 6px;right: 6px;width: 18px;height: 18px;border-radius: 50%;background: #FFB300;display: flex;align-items: center;justify-content: center;"><svg width="10" height="10" viewBox="0 0 9 9"><path d="M2 4.5l1.5 1.5 3-4" stroke="#fff" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" fill="none"/></svg></span></div>'; }, '') +
|
||
'</div>' +
|
||
'</div>' +
|
||
'<div style="font-size: 12px;color: var(--gray-500);font-weight: 500;margin-bottom: 12px;">将在以上平台领取</div>' +
|
||
'<button class="btn btn-lg" style="border-radius: 24px;font-size: 16px;height: 50px;width: 100%;background: linear-gradient(180deg,#FFD600 0%,#FFA000 100%);color: #1a1a1a;font-weight: 900;box-shadow: 0 8px 22px rgba(255,140,0,.5);border: none;" onclick="onClaimCouponConfirm()">一键自动领取</button>' +
|
||
'</div>',
|
||
|
||
// V3f 「流程植入副标题」副标题植入产品流程:先领券 → AI 比价 → 找底价
|
||
v3f: '' +
|
||
'<div style="background: linear-gradient(180deg,#FFE066 0%,#FFF3C4 50%,#FFFDF5 100%);border-radius: 24px;padding: 24px 16px 16px;width: 100%;box-shadow: 0 16px 48px rgba(255,193,7,.4);text-align: center;">' +
|
||
'<div style="width: 52px;height: 52px;border-radius: 13px;margin: 0 auto 8px;background: #FFD600;display: flex;align-items: center;justify-content: center;box-shadow: 0 4px 14px rgba(255,179,0,.5);"><span style="font-size: 17px;font-weight: 900;color: #1a1a1a;line-height: 1.05;text-align: center;">傻瓜<br>比价</span></div>' +
|
||
'<div style="font-size: 18px;font-weight: 900;color: var(--gray-900);line-height: 1.4;margin-bottom: 8px;">您今日还有大额优惠券可领</div>' +
|
||
'<div style="display: inline-flex;align-items: center;gap: 6px;background: rgba(255,179,0,.18);color: #8B6914;font-size: 12px;font-weight: 700;padding: 4px 12px;border-radius: 32px;margin-bottom: 12px;"><svg width="14" height="12" viewBox="0 0 22 18" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><path d="M2 7.2 V10.8 A1.4 1.4 0 0 0 3.4 12.2 H5.4 L11.2 16.4 A0.8 0.8 0 0 0 12.5 15.7 V2.3 A0.8 0.8 0 0 0 11.2 1.6 L5.4 5.8 H3.4 A1.4 1.4 0 0 0 2 7.2 Z" fill="#8B6914"/><path d="M14.6 4.4 C16 6 16 12 14.6 13.6" stroke="#8B6914" stroke-width="1.4" stroke-linecap="round" fill="none"/><path d="M16.8 2.6 C19.2 5.2 19.2 12.8 16.8 15.4" stroke="#8B6914" stroke-width="1.4" stroke-linecap="round" fill="none" opacity=".55"/><circle cx="6.2" cy="14.4" r="1.5" fill="#8B6914"/></svg>先领券再比价</div>' +
|
||
'<div style="background: #fff;border-radius: 18px;padding: 12px 8px;margin-bottom: 8px;box-shadow: 0 2px 12px rgba(255,193,7,.15);">' +
|
||
'<div style="display: grid;grid-template-columns: repeat(3,1fr);gap: 8px;">' +
|
||
['美团', '../../assets/shared/logos/meituan.png', '淘宝', '../../assets/shared/logos/taobao.png', '京东', '../../assets/shared/logos/jd.png'].reduce(function(acc, _, i, arr){ if (i % 2) return acc; return acc + '<div data-checked="true" onclick="toggleCouponPlatform(this)" class="cp-card cp-card-yellow" style="background: #fff;border: 2px solid #FFB300;border-radius: 14px;padding: 12px 4px 8px;position: relative;"><img src="' + arr[i+1] + '" style="width: 42px;height: 42px;border-radius: 8px;margin: 0 auto;display: block;"/><div style="font-size: 12px;font-weight: 700;color: var(--gray-900);margin-top: 8px;">' + arr[i] + '</div><span class="cp-check" style="position: absolute;top: 6px;right: 6px;width: 18px;height: 18px;border-radius: 50%;background: #FFB300;display: flex;align-items: center;justify-content: center;"><svg width=\"10\" height=\"10\" viewBox=\"0 0 9 9\"><path d=\"M2 4.5l1.5 1.5 3-4\" stroke=\"#fff\" stroke-width=\"1.6\" stroke-linecap=\"round\" stroke-linejoin=\"round\" fill=\"none\"/></svg></span></div>'; }, '') +
|
||
'</div>' +
|
||
'</div>' +
|
||
'<div style="font-size: 12px;color: var(--gray-500);font-weight: 500;margin-bottom: 12px;">将在以上平台领取</div>' +
|
||
'<button class="btn btn-lg" style="border-radius: 24px;font-size: 16px;height: 50px;width: 100%;background: linear-gradient(180deg,#FFD600 0%,#FFA000 100%);color: #1a1a1a;font-weight: 900;box-shadow: 0 8px 22px rgba(255,140,0,.5);border: none;" onclick="onClaimCouponConfirm()">一键自动领取</button>' +
|
||
'</div>'
|
||
};
|
||
|
||
function applyCouponPromptVariant(v) {
|
||
const card = document.getElementById('demoCouponPromptCard');
|
||
if (!card || !couponPromptVariants[v]) return;
|
||
card.style.cssText = 'width:100%;max-width:330px;animation:fadeInUp .45s cubic-bezier(.34,1.56,.64,1);';
|
||
card.innerHTML = couponPromptVariants[v];
|
||
}
|
||
|
||
function showCouponPromptForPreview() {
|
||
// 预览模式:直接强制显示弹窗,不走 demo flow
|
||
document.querySelectorAll('.screen').forEach(function(s){ s.classList.remove('active'); s.style.display = ''; });
|
||
const cmp = document.getElementById('comparing');
|
||
if (cmp) { cmp.classList.add('active'); cmp.style.display = 'flex'; }
|
||
const prompt = document.getElementById('demoCouponPrompt');
|
||
if (prompt) prompt.style.display = 'flex';
|
||
}
|
||
|
||
function onClaimCouponDecline() {
|
||
// 残忍放弃:跳过领券,直接进入比价引导第一步
|
||
document.getElementById('demoCouponPrompt').style.display = 'none';
|
||
const firstSpotlightIdx = demoSteps.findIndex(d => d.spotlight || d.mode === 'swipe' || d.mode === 'startCompare');
|
||
if (firstSpotlightIdx > 0) {
|
||
demoStep = firstSpotlightIdx;
|
||
renderDemoStep();
|
||
} else {
|
||
demoNext();
|
||
}
|
||
}
|
||
|
||
// 跳过新人体验流程 → 召回弹窗(居中卡片式)
|
||
function onSkipExperienceRequest() {
|
||
const modal = document.getElementById('skipConfirmModal');
|
||
if (modal) modal.style.display = 'flex';
|
||
}
|
||
function closeSkipConfirmModal() {
|
||
const modal = document.getElementById('skipConfirmModal');
|
||
if (modal) modal.style.display = 'none';
|
||
}
|
||
function confirmSkipExperience() {
|
||
closeSkipConfirmModal();
|
||
// 真的跳过 → 直接进入 login(不走 demo 比价 + celebration)
|
||
go('login');
|
||
}
|
||
|
||
// [ECOM-ONLY] 盲盒解锁 + 滑动引擎 removed for waimai V1
|
||
|
||
// ===== 礼花爆炸特效 =====
|
||
function startConfetti() {
|
||
const canvas = document.getElementById('confettiCanvas');
|
||
if (!canvas) return;
|
||
const ctx = canvas.getContext('2d');
|
||
canvas.width = 375;
|
||
canvas.height = 812;
|
||
const colors = ['#FF5722','#FFD600','#4CAF50','#2196F3','#E91E63','#FF9800','#9C27B0','#00BCD4','#FF4081'];
|
||
const pieces = [];
|
||
const shapes = ['rect','circle','strip'];
|
||
|
||
// 从两侧底部发射两簇礼花
|
||
function burst(originX, originY, count) {
|
||
for (let i = 0; i < count; i++) {
|
||
const angle = -Math.PI/2 + (Math.random() - 0.5) * 1.2; // 向上扇形
|
||
const speed = Math.random() * 8 + 5;
|
||
pieces.push({
|
||
x: originX,
|
||
y: originY,
|
||
vx: Math.cos(angle) * speed * (originX < 187 ? 1 : -1) * (0.3 + Math.random() * 0.7),
|
||
vy: Math.sin(angle) * speed - Math.random() * 3,
|
||
w: Math.random() * 10 + 4,
|
||
h: Math.random() * 6 + 2,
|
||
color: colors[Math.floor(Math.random() * colors.length)],
|
||
rot: Math.random() * 360,
|
||
vr: (Math.random() - 0.5) * 12,
|
||
gravity: 0.12 + Math.random() * 0.06,
|
||
friction: 0.98,
|
||
opacity: 1,
|
||
shape: shapes[Math.floor(Math.random() * shapes.length)],
|
||
wobble: Math.random() * 10,
|
||
wobbleSpeed: 0.05 + Math.random() * 0.1,
|
||
});
|
||
}
|
||
}
|
||
|
||
// 左右两侧各爆一簇
|
||
burst(60, 350, 50);
|
||
burst(315, 350, 50);
|
||
// 稍后中间再爆一簇
|
||
setTimeout(() => burst(187, 300, 40), 300);
|
||
|
||
let frame = 0;
|
||
function draw() {
|
||
ctx.clearRect(0, 0, 375, 812);
|
||
let alive = 0;
|
||
pieces.forEach(p => {
|
||
if (p.opacity <= 0) return;
|
||
alive++;
|
||
p.vx *= p.friction;
|
||
p.vy *= p.friction;
|
||
p.vy += p.gravity;
|
||
p.vx += Math.sin(p.wobble) * 0.3;
|
||
p.wobble += p.wobbleSpeed;
|
||
p.x += p.vx;
|
||
p.y += p.vy;
|
||
p.rot += p.vr;
|
||
p.vr *= 0.99;
|
||
// 慢慢淡出
|
||
if (frame > 80) p.opacity = Math.max(0, p.opacity - 0.006);
|
||
|
||
ctx.save();
|
||
ctx.translate(p.x, p.y);
|
||
ctx.rotate(p.rot * Math.PI / 180);
|
||
ctx.globalAlpha = p.opacity;
|
||
ctx.fillStyle = p.color;
|
||
if (p.shape === 'circle') {
|
||
ctx.beginPath();
|
||
ctx.arc(0, 0, p.w/2, 0, Math.PI*2);
|
||
ctx.fill();
|
||
} else if (p.shape === 'strip') {
|
||
ctx.fillRect(-p.w/2, -1, p.w, 2.5);
|
||
} else {
|
||
ctx.fillRect(-p.w/2, -p.h/2, p.w, p.h);
|
||
}
|
||
ctx.restore();
|
||
});
|
||
frame++;
|
||
if (alive > 0 && frame < 400) requestAnimationFrame(draw);
|
||
else ctx.clearRect(0, 0, 375, 812);
|
||
}
|
||
draw();
|
||
}
|
||
|
||
// ===== 新人礼包方案切换(URL 参数驱动,用于 gift-variants 对比页) =====
|
||
const giftVariantTemplates = {
|
||
A: '<div class="gv-base gv-a"><div class="gv-icon">🎁</div><div><div class="gv-title">新人专享礼包</div><div class="gv-sub">完成体验立即到账</div></div></div>',
|
||
B: '<div class="gv-base gv-b"><div class="gv-stamp">价值 ¥88</div><div class="gv-icon">🎁</div><div><div class="gv-title">新人专享礼包</div><div class="gv-sub">完成体验立即到账</div></div></div>',
|
||
C: '<div class="gv-base gv-c"><div class="gv-icon">🎁</div><div><div class="gv-title">新人专享礼包</div><div class="gv-cd"><span>⏱</span><span id="gvCd">23:45<span class="gv-blink">:</span>12</span><span>后失效</span></div></div></div>',
|
||
D: '<div class="gv-base gv-d"><div class="gv-iconwrap"><div class="gv-icon">🎁</div></div><div class="gv-text"><div class="gv-title">新人专享礼包</div><div class="gv-sub">完成体验立即到账</div></div></div>',
|
||
E: '<div class="gift-coupon"><div class="gc-icon">🎁</div><div style="flex: 1;min-width: 0;"><div class="gc-title">新人专享礼包</div><div class="gc-sub">完成体验立即到账</div></div></div>',
|
||
F: '<div class="gv-base gv-f"><div class="gv-rays"></div><div class="gv-iconwrap"><div class="gv-icon">🎁</div></div><div class="gv-title">新人专享礼包</div><div class="gv-sub">完成体验立即到账</div></div>',
|
||
G: '<div class="gv-base gv-g"><div class="gv-iconwrap"><span class="gv-spark gv-s1"></span><span class="gv-spark gv-s2"></span><span class="gv-spark gv-s3"></span><div class="gv-icon">🎁</div></div><div><div class="gv-title">新人专享<em>大礼包</em></div><div class="gv-sub">完成体验立即到账</div></div></div>'
|
||
};
|
||
let __gvCdTimer = null;
|
||
function __gvStartCountdown() {
|
||
let total = 23 * 3600 + 45 * 60 + 12;
|
||
if (__gvCdTimer) clearInterval(__gvCdTimer);
|
||
const tick = () => {
|
||
total = Math.max(0, total - 1);
|
||
const h = String(Math.floor(total / 3600)).padStart(2, '0');
|
||
const m = String(Math.floor((total % 3600) / 60)).padStart(2, '0');
|
||
const s = String(total % 60).padStart(2, '0');
|
||
const el = document.getElementById('gvCd');
|
||
if (el) el.innerHTML = h + ':' + m + '<span class="gv-blink">:</span>' + s;
|
||
};
|
||
tick();
|
||
__gvCdTimer = setInterval(tick, 1000);
|
||
}
|
||
function applyGiftVariant(letter) {
|
||
const container = document.getElementById('giftCardContainer');
|
||
if (!container) return;
|
||
const key = (letter || 'E').toUpperCase();
|
||
const tpl = giftVariantTemplates[key] || giftVariantTemplates.E;
|
||
container.innerHTML = tpl;
|
||
if (key === 'C') __gvStartCountdown();
|
||
}
|
||
(function applyGiftVariantURLParams() {
|
||
try {
|
||
const params = new URLSearchParams(location.search);
|
||
const variant = params.get('giftvariant');
|
||
const celebVariant = params.get('celebrationvariant');
|
||
const celebrate = params.get('celebrate') === '1';
|
||
const couponVariant = params.get('couponvariant');
|
||
const showCoupon = params.get('showcoupon') === '1';
|
||
const ctaVariantParam = params.get('ctavariant');
|
||
const screen = params.get('screen');
|
||
const embed = params.get('embed') === '1';
|
||
const run = function() {
|
||
if (embed) document.body.classList.add('gv-embed');
|
||
if (variant) applyGiftVariant(variant);
|
||
if (celebVariant && celebrationVariants[celebVariant]) {
|
||
currentCelebrationVariant = celebVariant;
|
||
}
|
||
if (screen) { try { go(screen); } catch (e) {} }
|
||
if (celebrate) {
|
||
try { openCelebrationModal(); } catch (e) {}
|
||
}
|
||
if (couponVariant && typeof applyCouponPromptVariant === 'function') {
|
||
try { applyCouponPromptVariant(couponVariant); } catch (e) {}
|
||
}
|
||
if (showCoupon && typeof showCouponPromptForPreview === 'function') {
|
||
try { showCouponPromptForPreview(); } catch (e) {}
|
||
}
|
||
if (ctaVariantParam && typeof applyCtaVariant === 'function') {
|
||
try { applyCtaVariant(parseInt(ctaVariantParam, 10)); } catch (e) {}
|
||
}
|
||
};
|
||
if (document.readyState === 'loading') {
|
||
document.addEventListener('DOMContentLoaded', run);
|
||
} else {
|
||
run();
|
||
}
|
||
} catch (e) {}
|
||
})();
|
||
|
||
// 我的页展示完整测试昵称,方便检视长用户名排版
|
||
(function () {
|
||
function renderProfileNickname() {
|
||
var el = document.getElementById('profName');
|
||
if (!el) return;
|
||
var full = el.getAttribute('data-fullname') || el.textContent || '';
|
||
var chars = Array.from(full);
|
||
el.textContent = chars.length > 19 ? chars.slice(0, 18).join('') + '...' : full;
|
||
el.setAttribute('title', full);
|
||
}
|
||
if (document.readyState === 'loading') {
|
||
document.addEventListener('DOMContentLoaded', renderProfileNickname);
|
||
} else {
|
||
renderProfileNickname();
|
||
}
|
||
})();
|
||
</script>
|
||
|
||
|
||
<!-- ===== Tweaks Panel ===== -->
|
||
<div id="tweaksPanel" class="tweaks-panel">
|
||
<button class="tweaks-close" onclick="closeTweaks()">×</button>
|
||
<h3>「开启省钱之旅」按钮样式</h3>
|
||
<div class="tweaks-sub">点击切换,预览不同方案</div>
|
||
<div class="tweaks-grid">
|
||
<div class="tweaks-opt" data-v="1">红橙渐变<small>当前</small></div>
|
||
<div class="tweaks-opt" data-v="2">黄底黑字<small>品牌主色</small></div>
|
||
<div class="tweaks-opt" data-v="3">黑底黄字<small>高对比</small></div>
|
||
<div class="tweaks-opt" data-v="4">金色光泽<small>动态扫光</small></div>
|
||
<div class="tweaks-opt" data-v="5">玻璃质感<small>立体黄</small></div>
|
||
<div class="tweaks-opt" data-v="6">描边偏移<small>克制款</small></div>
|
||
<div class="tweaks-opt" data-v="7">红包喜庆<small>红+金</small></div>
|
||
<div class="tweaks-opt" data-v="8">呼吸跳动<small>动效款</small></div>
|
||
<div class="tweaks-opt" data-v="9">蜜糖渐变<small>黄→琥珀</small></div>
|
||
<div class="tweaks-opt" data-v="10">金币描边<small>深金细边</small></div>
|
||
</div>
|
||
|
||
<div style="height: 1px;background: #E5E5E5;margin: 16px 0 12px;"></div>
|
||
<h3>领券弹窗副标题样式</h3>
|
||
<div class="tweaks-sub">主标题下那行小字,强化"收益"信号</div>
|
||
<div class="tweaks-grid">
|
||
<div class="tweaks-opt sub-opt" data-sv="1">基线灰<small>当前最弱</small></div>
|
||
<div class="tweaks-opt sub-opt" data-sv="2">金币胶囊<small>品牌黄徽章</small></div>
|
||
<div class="tweaks-opt sub-opt" data-sv="3">关键词高亮<small>黄色荧光笔</small></div>
|
||
<div class="tweaks-opt sub-opt" data-sv="4">优惠券小票<small>齿边+朱红</small></div>
|
||
<div class="tweaks-opt sub-opt" data-sv="5">数字徽章<small>预计立省¥</small></div>
|
||
<div class="tweaks-opt sub-opt" data-sv="6">双行节奏<small>预告+承诺</small></div>
|
||
<div class="tweaks-opt sub-opt" data-sv="7">V2b 金币翻转<small>动效活力</small></div>
|
||
<div class="tweaks-opt sub-opt" data-sv="8">V2c 双色分段<small>黑黄拼接</small></div>
|
||
<div class="tweaks-opt sub-opt" data-sv="9">V2d 闪光描边<small>轻盈款</small></div>
|
||
<div class="tweaks-opt sub-opt" data-sv="10">V2e 数字嵌入<small>¥18+ 内嵌</small></div>
|
||
<div class="tweaks-opt sub-opt" data-sv="11">V2f 双图标<small>金币+闪电</small></div>
|
||
<div class="tweaks-opt sub-opt" data-sv="12">V2g 立体浮起<small>金属高光</small></div>
|
||
<div class="tweaks-opt sub-opt" data-sv="13">流程植入<small>领券→比价→底价</small></div>
|
||
</div>
|
||
|
||
<div style="height: 1px;background: #E5E5E5;margin: 16px 0 12px;"></div>
|
||
<h3>「完成设置」弹窗版式</h3>
|
||
<div class="tweaks-sub">点击切换,下次进入弹窗即生效</div>
|
||
<div class="tweaks-grid">
|
||
<div class="tweaks-opt celeb-opt" data-cv="v1">轻收尾·重期待<small>承上小,起下大</small></div>
|
||
<div class="tweaks-opt celeb-opt" data-cv="v2">分割式<small>三段节奏</small></div>
|
||
<div class="tweaks-opt celeb-opt" data-cv="v3">叙事流<small>递进式</small></div>
|
||
<div class="tweaks-opt celeb-opt" data-cv="v4">行为优先<small>主舞台让给行为</small></div>
|
||
<div class="tweaks-opt celeb-opt" data-cv="v5">徽章+行动卡<small>chip 强调最后一步</small></div>
|
||
<div class="tweaks-opt celeb-opt" data-cv="v6">进度条推进<small>脉动黄推进感</small></div>
|
||
<div class="tweaks-opt celeb-opt" data-cv="v7">数字步骤<small>① ✓ → ② 当前</small></div>
|
||
<div class="tweaks-opt celeb-opt" data-cv="v8">极简专注<small>大字承担引导</small></div>
|
||
</div>
|
||
<button onclick="previewCelebration()" style="margin-top: 12px;width: 100%;padding: 8px;border-radius: 8px;border: 1px solid #ddd;background: #fff;font-size: 13px;font-weight: 600;cursor: pointer;">▶ 预览当前版式</button>
|
||
</div>
|
||
<script>
|
||
const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
|
||
"ctaVariant": 5,
|
||
"celebVariant": "v3",
|
||
"couponSubVariant": 13
|
||
}/*EDITMODE-END*/;
|
||
let currentCtaVariant = TWEAK_DEFAULTS.ctaVariant || 1;
|
||
let currentCouponSubVariant = TWEAK_DEFAULTS.couponSubVariant || 1;
|
||
currentCelebrationVariant = TWEAK_DEFAULTS.celebVariant || 'v1';
|
||
const couponSubMarkup = {
|
||
1: '<div class="cps cps-v1">领取后将为您解锁更低好价</div>',
|
||
2: '<div class="cps cps-v2"><span class="cps-coin">¥</span>领取后解锁今日最低价</div>',
|
||
3: '<div class="cps cps-v3">领取后将为您解锁<em>全网最低价</em></div>',
|
||
4: '<div class="cps cps-v4">已为您锁定 <span class="cps-amt">¥18+</span> 神券</div>',
|
||
5: '<div class="cps cps-v5">领取后预计立省<span class="cps-pill">¥8<small>~</small>25</span></div>',
|
||
6: '<div class="cps cps-v6"><span class="cps-top">· 预计 3 秒完成 ·</span><span class="cps-bot">领券解锁<em>今日最低价</em></span></div>',
|
||
7: '<div class="cps cps-v2b"><span class="cps-coin">¥</span>领取后解锁今日最低价</div>',
|
||
8: '<div class="cps cps-v2c"><span class="cps-tag">立省</span><span class="cps-text">解锁今日最低价</span></div>',
|
||
9: '<div class="cps cps-v2d"><span class="cps-coin">¥</span>领取后解锁今日最低价</div>',
|
||
10: '<div class="cps cps-v2e"><span class="cps-amount">¥18<small>+</small></span>解锁今日最低价</div>',
|
||
11: '<div class="cps cps-v2f"><span class="cps-coin">¥</span>领取后解锁<span class="cps-bolt"><svg width="10" height="11" viewBox="0 0 10 11"><path d="M6 0L0 6h3l-1 5 6-6H5z" fill="#1a1a1a"/></svg></span>今日最低价</div>',
|
||
12: '<div class="cps cps-v2g"><span class="cps-coin">¥</span>领取后解锁今日最低价</div>',
|
||
13: '<div class="cps cps-v3f"><span class="cps-coin"><svg width="15" height="13" viewBox="0 0 22 18" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><path d="M2 7.2 V10.8 A1.4 1.4 0 0 0 3.4 12.2 H5.4 L11.2 16.4 A0.8 0.8 0 0 0 12.5 15.7 V2.3 A0.8 0.8 0 0 0 11.2 1.6 L5.4 5.8 H3.4 A1.4 1.4 0 0 0 2 7.2 Z" fill="#8B6914"/><path d="M14.6 4.4 C16 6 16 12 14.6 13.6" stroke="#8B6914" stroke-width="1.4" stroke-linecap="round" fill="none"/><path d="M16.8 2.6 C19.2 5.2 19.2 12.8 16.8 15.4" stroke="#8B6914" stroke-width="1.4" stroke-linecap="round" fill="none" opacity=".55"/><circle cx="6.2" cy="14.4" r="1.5" fill="#8B6914"/></svg></span>先领券,再比价</div>'
|
||
};
|
||
function applyCouponSubVariant(v) {
|
||
currentCouponSubVariant = v;
|
||
const slot = document.getElementById('demoCouponSubtitleSlot');
|
||
if (slot) slot.innerHTML = couponSubMarkup[v] || couponSubMarkup[1];
|
||
document.querySelectorAll('#tweaksPanel .sub-opt').forEach(el => {
|
||
el.classList.toggle('active', String(el.dataset.sv) === String(v));
|
||
});
|
||
}
|
||
function applyCelebVariant(cv) {
|
||
currentCelebrationVariant = cv;
|
||
document.querySelectorAll('#tweaksPanel .celeb-opt').forEach(el => {
|
||
el.classList.toggle('active', el.dataset.cv === cv);
|
||
});
|
||
}
|
||
function previewCelebration() {
|
||
if (typeof openCelebrationModal === 'function') openCelebrationModal();
|
||
}
|
||
function applyCtaVariant(v) {
|
||
currentCtaVariant = v;
|
||
const btn = document.getElementById('splashCTA');
|
||
if (!btn) return;
|
||
btn.className = 'splash-cta splash-cta-v' + v;
|
||
document.querySelectorAll('#tweaksPanel .tweaks-opt').forEach(el => {
|
||
el.classList.toggle('active', String(el.dataset.v) === String(v));
|
||
});
|
||
}
|
||
function closeTweaks() {
|
||
document.getElementById('tweaksPanel').classList.remove('open');
|
||
try { window.parent.postMessage({type:'__edit_mode_dismissed'},'*'); } catch(e){}
|
||
}
|
||
window.addEventListener('message', (e) => {
|
||
const d = e.data || {};
|
||
if (d.type === '__activate_edit_mode') document.getElementById('tweaksPanel').classList.add('open');
|
||
if (d.type === '__deactivate_edit_mode') document.getElementById('tweaksPanel').classList.remove('open');
|
||
});
|
||
document.addEventListener('DOMContentLoaded', () => {
|
||
document.querySelectorAll('#tweaksPanel .tweaks-opt:not(.celeb-opt):not(.sub-opt)').forEach(el => {
|
||
el.addEventListener('click', () => {
|
||
const v = parseInt(el.dataset.v, 10);
|
||
applyCtaVariant(v);
|
||
try { window.parent.postMessage({type:'__edit_mode_set_keys', edits:{ctaVariant: v}}, '*'); } catch(e){}
|
||
});
|
||
});
|
||
document.querySelectorAll('#tweaksPanel .sub-opt').forEach(el => {
|
||
el.addEventListener('click', () => {
|
||
const v = parseInt(el.dataset.sv, 10);
|
||
applyCouponSubVariant(v);
|
||
try { window.parent.postMessage({type:'__edit_mode_set_keys', edits:{couponSubVariant: v}}, '*'); } catch(e){}
|
||
});
|
||
});
|
||
document.querySelectorAll('#tweaksPanel .celeb-opt').forEach(el => {
|
||
el.addEventListener('click', () => {
|
||
const cv = el.dataset.cv;
|
||
applyCelebVariant(cv);
|
||
try { window.parent.postMessage({type:'__edit_mode_set_keys', edits:{celebVariant: cv}}, '*'); } catch(e){}
|
||
});
|
||
});
|
||
applyCtaVariant(currentCtaVariant);
|
||
applyCouponSubVariant(currentCouponSubVariant);
|
||
applyCelebVariant(currentCelebrationVariant);
|
||
try { window.parent.postMessage({type:'__edit_mode_available'},'*'); } catch(e){}
|
||
});
|
||
</script>
|
||
|
||
|
||
<script>
|
||
(function() {
|
||
var ID_TO_PATH = {
|
||
"login": "app/login/inapp.html",
|
||
"loginPhone": "app/login/phone.html",
|
||
"home": "app/home",
|
||
"welfare": "app/welfare",
|
||
"welfareRules": "app/welfare/rules.html",
|
||
"profile": "app/profile",
|
||
"invite": "app/welfare/invite.html",
|
||
"compresult": "app/compare",
|
||
"withdrawal": "app/welfare/withdrawal.html",
|
||
"coinhistory": "app/welfare/coinhistory.html",
|
||
"reports": "app/profile/reports.html",
|
||
"settings": "app/profile/settings.html",
|
||
"feedback": "app/profile/feedback.html",
|
||
"comparing": "app/compare",
|
||
"history": "app/history"
|
||
};
|
||
var PREFIX = '../../';
|
||
function navigate(id) {
|
||
// 抢救 inline onclick 设置的 window.loginFrom(隐式 global,不会进 let 绑定)
|
||
if (window.loginFrom && typeof window.loginFrom === 'string') {
|
||
try { localStorage.setItem('proto_loginFrom', window.loginFrom); } catch(e) {}
|
||
}
|
||
var p = ID_TO_PATH[id];
|
||
if (!p) { console.warn('[nav] unknown id:', id); return; }
|
||
location.href = PREFIX + p + (p.indexOf('.html') !== -1 ? '' : '/index.html');
|
||
}
|
||
window.go = navigate;
|
||
window._activateScreen = function(id) { navigate(id); };
|
||
window.goBack = function() { if (history.length > 1) history.back(); else navigate('home'); };
|
||
window.debugGoBack = window.goBack;
|
||
})();
|
||
</script>
|
||
|
||
<script>
|
||
// ============================================
|
||
// V3: 页面级初始化
|
||
// 替代原 go(id) 切到本屏时跑的逻辑
|
||
// ============================================
|
||
document.addEventListener('DOMContentLoaded', function() {
|
||
var isLogged = false;
|
||
try { isLogged = localStorage.getItem('proto_isLoggedIn') !== 'false'; } catch(e) {}
|
||
|
||
var activeScreen = document.querySelector('.screen.active');
|
||
if (!activeScreen) return;
|
||
var id = activeScreen.id;
|
||
|
||
// welfare 登录态切换
|
||
if (id === 'welfare') {
|
||
var wu = document.getElementById('welfareUnlogged');
|
||
var wl = document.getElementById('welfareLogged');
|
||
if (wu) wu.style.display = isLogged ? 'none' : 'block';
|
||
if (wl) wl.style.display = isLogged ? 'block' : 'none';
|
||
// 已登录 + 没显示过签到弹窗 → 弹一次
|
||
if (isLogged && typeof showCheckinPopup === 'function') {
|
||
var checkinShown = false;
|
||
try { checkinShown = localStorage.getItem('proto_checkinShown') === 'true'; } catch(e) {}
|
||
if (!checkinShown) setTimeout(showCheckinPopup, 500);
|
||
}
|
||
}
|
||
|
||
// profile 登录态切换
|
||
if (id === 'profile') {
|
||
var pu = document.getElementById('profileUnlogged');
|
||
var pl = document.getElementById('profileLogged');
|
||
if (!isLogged) {
|
||
// 未登录默认自动跳登录页;URL 带 ?view=unlogged 表示从 login 返回,显示未登录态
|
||
var profParams = new URLSearchParams(window.location.search);
|
||
if (profParams.get('view') === 'unlogged') {
|
||
if (pu) pu.style.display = 'block';
|
||
if (pl) pl.style.display = 'none';
|
||
} else {
|
||
try { localStorage.setItem('proto_loginFrom', 'profile'); } catch(e) {}
|
||
location.replace('../login/inapp.html');
|
||
return;
|
||
}
|
||
} else {
|
||
if (pu) pu.style.display = 'none';
|
||
if (pl) pl.style.display = 'block';
|
||
}
|
||
}
|
||
|
||
// productselect 自动开始平台扫描
|
||
if (id === 'productselect') {
|
||
if (typeof startPlatformScan === 'function') {
|
||
try { startPlatformScan(); } catch(e) { console.warn(e); }
|
||
}
|
||
}
|
||
|
||
// celebration 动画 + 数据
|
||
if (id === 'celebration') {
|
||
if (typeof renderCelebrationSavings === 'function') try { renderCelebrationSavings(); } catch(e){}
|
||
if (typeof renderResults === 'function') try { renderResults('celebResults'); } catch(e){}
|
||
if (typeof startConfetti === 'function') try { startConfetti(); } catch(e){}
|
||
}
|
||
|
||
// comparing 自动开始比价动画
|
||
if (id === 'comparing') {
|
||
if (typeof startCompareAnimation === 'function') try { startCompareAnimation(); } catch(e){}
|
||
if (typeof startComparing === 'function') try { startComparing(); } catch(e){}
|
||
}
|
||
});
|
||
</script>
|
||
|
||
|
||
<script>
|
||
// === 调试用:右下角"重置"按钮,仅 file:// 本地预览可见 ===
|
||
(function() {
|
||
if (location.protocol !== 'file:') return;
|
||
if (document.getElementById('debugReset')) return;
|
||
function mount() {
|
||
var btn = document.createElement('div');
|
||
btn.id = 'debugReset';
|
||
btn.textContent = '↻ 重置'; // ↻ 重置
|
||
btn.title = '清空 localStorage 并刷新(仅本地预览可见)';
|
||
btn.style.cssText = 'position:fixed;right:0;bottom:0;z-index:99999;background:#000;color:#fff;font-size:11px;font-weight:700;padding:8px;border-radius:4px 0 0 0;cursor:pointer;opacity:.7;line-height:1;letter-spacing:1px;font-family:inherit;';
|
||
btn.onclick = function() {
|
||
try { localStorage.clear(); } catch(e) {}
|
||
location.reload();
|
||
};
|
||
document.body.appendChild(btn);
|
||
}
|
||
if (document.body) mount();
|
||
else document.addEventListener('DOMContentLoaded', mount);
|
||
})();
|
||
</script>
|
||
<script>
|
||
(function() {
|
||
function getTodayKey() {
|
||
var d = new Date();
|
||
return d.getFullYear() + '-' + String(d.getMonth() + 1).padStart(2, '0') + '-' + String(d.getDate()).padStart(2, '0');
|
||
}
|
||
function updateWelfareCheckinTabDot() {
|
||
var tab = document.getElementById('homeTabWelfare');
|
||
if (!tab) return;
|
||
var done = false;
|
||
try { done = localStorage.getItem('proto_checkinDoneDate') === getTodayKey(); } catch(e) {}
|
||
tab.classList.toggle('has-welfare-dot', !done);
|
||
}
|
||
if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', updateWelfareCheckinTabDot);
|
||
else updateWelfareCheckinTabDot();
|
||
})();
|
||
</script>
|
||
</body>
|
||
</html>
|