本次提交完成多项核心更新: 1. 新增闲情逸致功能模块,包含时间线、收藏标注、季节主题等基础框架 2. 替换hive为社区维护的hive_ce包,修复依赖兼容问题 3. 统一替换"开发中"提示为"当前设备不支持",优化用户提示文案 4. 新增多项功能开关与特性标志,统一管理不可用功能提示 5. 完善用户账户洞察系统,新增头像审核中状态检测 6. 优化TTS语音朗读服务,修复Android端引擎初始化问题 7. 重构知识图谱缩放手势逻辑,解决缩放不跟手问题 8. 新增精灵头像组件,替换默认聊天头像样式 9. 新增外部链接跳转确认弹窗,提升使用安全性 10. 升级后端API接口,新增签到配置获取与补签积分规则动态读取 11. 完善多语言翻译覆盖率限制,非中文语言仅显示最高50%进度 12. 新增HTTP缓存拦截器,优化网络请求性能 13. 新增恢复出厂设置选项,完善数据管理功能 同时修复了多处代码细节问题:简化字符串拼接、优化布局代码、移除多余代码等。
1372 lines
39 KiB
HTML
1372 lines
39 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||
<title>闲情逸致 — 时间线主页面</title>
|
||
<style>
|
||
:root {
|
||
--primary: #6C63FF;
|
||
--primary-light: #8B83FF;
|
||
--accent: #4ECDC4;
|
||
--secondary: #FF6B6B;
|
||
--success: #10B981;
|
||
--warning: #F59E0B;
|
||
--error: #EF4444;
|
||
--info: #3B82F6;
|
||
|
||
--bg-primary: #FAFAFA;
|
||
--bg-secondary: #F5F5F5;
|
||
--bg-card: #FFFFFF;
|
||
--bg-elevated: #FFFFFF;
|
||
|
||
--text-primary: #1A1A2E;
|
||
--text-secondary: #6B7280;
|
||
--text-hint: #9CA3AF;
|
||
|
||
--radius-sm: 4px;
|
||
--radius-md: 8px;
|
||
--radius-lg: 12px;
|
||
--radius-xl: 16px;
|
||
|
||
--shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
|
||
--shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1);
|
||
--shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1);
|
||
|
||
--space-xs: 4px;
|
||
--space-sm: 8px;
|
||
--space-md: 16px;
|
||
--space-lg: 24px;
|
||
--space-xl: 32px;
|
||
|
||
--spring: #4ECDC4;
|
||
--summer: #FF6B6B;
|
||
--autumn: #F59E0B;
|
||
--winter: #3B82F6;
|
||
}
|
||
|
||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||
|
||
body {
|
||
font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Display', 'SF Pro Text', 'Helvetica Neue', sans-serif;
|
||
background: var(--bg-primary);
|
||
color: var(--text-primary);
|
||
-webkit-font-smoothing: antialiased;
|
||
overflow-x: hidden;
|
||
}
|
||
|
||
.phone-frame {
|
||
max-width: 430px;
|
||
margin: 0 auto;
|
||
min-height: 100vh;
|
||
position: relative;
|
||
background: var(--bg-primary);
|
||
}
|
||
|
||
/* ===== AppBar ===== */
|
||
.appbar {
|
||
position: sticky;
|
||
top: 0;
|
||
z-index: 100;
|
||
backdrop-filter: blur(20px);
|
||
-webkit-backdrop-filter: blur(20px);
|
||
background: rgba(250, 250, 250, 0.78);
|
||
border-bottom: 0.5px solid rgba(0,0,0,0.08);
|
||
padding: 12px var(--space-md);
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
}
|
||
|
||
.appbar-left {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
}
|
||
|
||
.appbar-back {
|
||
width: 32px;
|
||
height: 32px;
|
||
border-radius: 50%;
|
||
background: var(--bg-secondary);
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
font-size: 16px;
|
||
cursor: pointer;
|
||
border: none;
|
||
color: var(--text-primary);
|
||
}
|
||
|
||
.appbar-title {
|
||
font-size: 17px;
|
||
font-weight: 600;
|
||
letter-spacing: -0.2px;
|
||
}
|
||
|
||
.appbar-subtitle {
|
||
font-size: 12px;
|
||
color: var(--text-hint);
|
||
margin-top: 1px;
|
||
}
|
||
|
||
.appbar-right {
|
||
display: flex;
|
||
gap: 8px;
|
||
}
|
||
|
||
.appbar-btn {
|
||
width: 36px;
|
||
height: 36px;
|
||
border-radius: 10px;
|
||
background: var(--bg-secondary);
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
font-size: 16px;
|
||
cursor: pointer;
|
||
border: none;
|
||
color: var(--text-secondary);
|
||
transition: all 0.2s;
|
||
}
|
||
|
||
.appbar-btn:active {
|
||
transform: scale(0.92);
|
||
background: rgba(0,0,0,0.06);
|
||
}
|
||
|
||
/* ===== Swap Button (Fixed) ===== */
|
||
.swap-btn-fixed {
|
||
position: fixed;
|
||
top: 72px;
|
||
left: 50%;
|
||
transform: translateX(-50%);
|
||
z-index: 99;
|
||
width: 44px;
|
||
height: 44px;
|
||
border-radius: 50%;
|
||
background: var(--primary);
|
||
color: white;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
font-size: 18px;
|
||
cursor: pointer;
|
||
border: none;
|
||
box-shadow: 0 4px 12px rgba(108, 99, 255, 0.35);
|
||
transition: all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
|
||
}
|
||
|
||
.swap-btn-fixed:active {
|
||
transform: translateX(-50%) scale(0.88);
|
||
}
|
||
|
||
.swap-btn-fixed .swap-icon {
|
||
transition: transform 0.3s;
|
||
}
|
||
|
||
.swap-btn-fixed.swapped .swap-icon {
|
||
transform: rotate(180deg);
|
||
}
|
||
|
||
/* ===== Timeline ===== */
|
||
.timeline {
|
||
padding: 20px var(--space-md) 100px;
|
||
position: relative;
|
||
}
|
||
|
||
.timeline-line {
|
||
position: absolute;
|
||
left: 50%;
|
||
top: 0;
|
||
bottom: 100px;
|
||
width: 2px;
|
||
background: linear-gradient(to bottom, transparent, var(--primary) 5%, var(--primary) 95%, transparent);
|
||
transform: translateX(-50%);
|
||
opacity: 0.2;
|
||
}
|
||
|
||
/* ===== Date Node ===== */
|
||
.date-node {
|
||
position: relative;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
margin-bottom: 8px;
|
||
}
|
||
|
||
.date-node-dot {
|
||
width: 14px;
|
||
height: 14px;
|
||
border-radius: 50%;
|
||
background: var(--primary);
|
||
border: 3px solid var(--bg-primary);
|
||
box-shadow: 0 0 0 2px var(--primary), 0 2px 8px rgba(108,99,255,0.3);
|
||
z-index: 2;
|
||
position: relative;
|
||
}
|
||
|
||
.date-node-dot.today {
|
||
width: 18px;
|
||
height: 18px;
|
||
background: var(--accent);
|
||
box-shadow: 0 0 0 2px var(--accent), 0 2px 12px rgba(78,205,196,0.4);
|
||
animation: pulse-dot 2s infinite;
|
||
}
|
||
|
||
@keyframes pulse-dot {
|
||
0%, 100% { box-shadow: 0 0 0 2px var(--accent), 0 2px 12px rgba(78,205,196,0.4); }
|
||
50% { box-shadow: 0 0 0 4px var(--accent), 0 2px 16px rgba(78,205,196,0.6); }
|
||
}
|
||
|
||
.date-node-label {
|
||
margin-top: 6px;
|
||
text-align: center;
|
||
}
|
||
|
||
.date-node-month {
|
||
font-size: 13px;
|
||
font-weight: 600;
|
||
color: var(--text-primary);
|
||
}
|
||
|
||
.date-node-weekday {
|
||
font-size: 11px;
|
||
color: var(--text-hint);
|
||
}
|
||
|
||
.date-node-weekday.weekend {
|
||
color: var(--secondary);
|
||
font-weight: 600;
|
||
}
|
||
|
||
.date-node-season {
|
||
font-size: 10px;
|
||
padding: 2px 8px;
|
||
border-radius: 10px;
|
||
margin-top: 3px;
|
||
font-weight: 500;
|
||
}
|
||
|
||
.season-spring { background: rgba(78,205,196,0.12); color: var(--spring); }
|
||
.season-summer { background: rgba(255,107,107,0.12); color: var(--summer); }
|
||
.season-autumn { background: rgba(245,158,11,0.12); color: var(--autumn); }
|
||
.season-winter { background: rgba(59,130,246,0.12); color: var(--winter); }
|
||
|
||
/* ===== Today Divider ===== */
|
||
.today-divider {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 12px;
|
||
margin: 12px 0 16px;
|
||
padding: 0 8px;
|
||
}
|
||
|
||
.today-divider-line {
|
||
flex: 1;
|
||
height: 1.5px;
|
||
background: linear-gradient(to right, transparent, var(--accent), transparent);
|
||
}
|
||
|
||
.today-divider-text {
|
||
font-size: 13px;
|
||
font-weight: 600;
|
||
color: var(--accent);
|
||
white-space: nowrap;
|
||
letter-spacing: 1px;
|
||
}
|
||
|
||
/* ===== Card Row (Left + Right) ===== */
|
||
.card-row {
|
||
display: flex;
|
||
gap: 10px;
|
||
margin-bottom: 6px;
|
||
position: relative;
|
||
}
|
||
|
||
.card-row .card-col {
|
||
flex: 1;
|
||
min-width: 0;
|
||
}
|
||
|
||
/* ===== Timeline Card ===== */
|
||
.tl-card {
|
||
background: var(--bg-card);
|
||
border-radius: var(--radius-lg);
|
||
box-shadow: var(--shadow-sm);
|
||
overflow: hidden;
|
||
cursor: pointer;
|
||
transition: all 0.25s cubic-bezier(0.34, 1.56, 0.64, 1);
|
||
border: 0.5px solid rgba(0,0,0,0.04);
|
||
position: relative;
|
||
}
|
||
|
||
.tl-card:active {
|
||
transform: scale(0.97);
|
||
box-shadow: var(--shadow-md);
|
||
}
|
||
|
||
.tl-card.food-card {
|
||
border-left: 3px solid var(--warning);
|
||
}
|
||
|
||
.tl-card.play-card {
|
||
border-left: 3px solid var(--accent);
|
||
}
|
||
|
||
.tl-card .card-header {
|
||
padding: 10px 12px 6px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
}
|
||
|
||
.card-type-badge {
|
||
font-size: 10px;
|
||
padding: 2px 8px;
|
||
border-radius: 10px;
|
||
font-weight: 600;
|
||
}
|
||
|
||
.badge-food {
|
||
background: rgba(245,158,11,0.12);
|
||
color: var(--warning);
|
||
}
|
||
|
||
.badge-play {
|
||
background: rgba(78,205,196,0.12);
|
||
color: var(--accent);
|
||
}
|
||
|
||
.card-price-badge {
|
||
font-size: 9px;
|
||
padding: 1px 6px;
|
||
border-radius: 6px;
|
||
font-weight: 600;
|
||
}
|
||
|
||
.price-free { background: rgba(16,185,129,0.12); color: var(--success); }
|
||
.price-paid { background: rgba(245,158,11,0.12); color: var(--warning); }
|
||
.price-commercial { background: rgba(255,107,107,0.12); color: var(--secondary); }
|
||
.price-unknown { background: rgba(156,163,175,0.12); color: var(--text-hint); }
|
||
|
||
.tl-card .card-body {
|
||
padding: 0 12px 10px;
|
||
}
|
||
|
||
.card-title {
|
||
font-size: 14px;
|
||
font-weight: 600;
|
||
color: var(--text-primary);
|
||
line-height: 1.3;
|
||
margin-bottom: 4px;
|
||
}
|
||
|
||
.card-desc {
|
||
font-size: 12px;
|
||
color: var(--text-secondary);
|
||
line-height: 1.4;
|
||
}
|
||
|
||
.card-location {
|
||
font-size: 11px;
|
||
color: var(--text-hint);
|
||
margin-top: 6px;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 3px;
|
||
}
|
||
|
||
.card-risk {
|
||
font-size: 10px;
|
||
padding: 2px 6px;
|
||
border-radius: 4px;
|
||
background: rgba(239,68,68,0.1);
|
||
color: var(--error);
|
||
font-weight: 600;
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 2px;
|
||
margin-top: 4px;
|
||
}
|
||
|
||
.card-sun-info {
|
||
font-size: 10px;
|
||
color: var(--text-hint);
|
||
margin-top: 4px;
|
||
display: flex;
|
||
gap: 8px;
|
||
}
|
||
|
||
.card-actions {
|
||
padding: 6px 12px 8px;
|
||
display: flex;
|
||
gap: 6px;
|
||
border-top: 0.5px solid rgba(0,0,0,0.04);
|
||
}
|
||
|
||
.card-action-btn {
|
||
font-size: 11px;
|
||
padding: 3px 8px;
|
||
border-radius: 8px;
|
||
background: var(--bg-secondary);
|
||
color: var(--text-secondary);
|
||
border: none;
|
||
cursor: pointer;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 3px;
|
||
transition: all 0.2s;
|
||
}
|
||
|
||
.card-action-btn:active {
|
||
transform: scale(0.95);
|
||
background: rgba(0,0,0,0.06);
|
||
}
|
||
|
||
.card-action-btn.bookmarked {
|
||
background: rgba(108,99,255,0.1);
|
||
color: var(--primary);
|
||
}
|
||
|
||
/* ===== Checkbox items in card ===== */
|
||
.card-checklist {
|
||
padding: 4px 12px 8px;
|
||
}
|
||
|
||
.checklist-item {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 6px;
|
||
padding: 3px 0;
|
||
font-size: 12px;
|
||
color: var(--text-secondary);
|
||
}
|
||
|
||
.checklist-item input[type="checkbox"] {
|
||
width: 16px;
|
||
height: 16px;
|
||
accent-color: var(--primary);
|
||
}
|
||
|
||
.checklist-item.checked {
|
||
color: var(--text-hint);
|
||
text-decoration: line-through;
|
||
}
|
||
|
||
/* ===== Bottom Multi-select Bar ===== */
|
||
.bottom-bar {
|
||
position: fixed;
|
||
bottom: 0;
|
||
left: 50%;
|
||
transform: translateX(-50%);
|
||
width: 100%;
|
||
max-width: 430px;
|
||
z-index: 100;
|
||
backdrop-filter: blur(20px);
|
||
-webkit-backdrop-filter: blur(20px);
|
||
background: rgba(250,250,250,0.85);
|
||
border-top: 0.5px solid rgba(0,0,0,0.08);
|
||
padding: 10px var(--space-md);
|
||
padding-bottom: calc(10px + env(safe-area-inset-bottom, 0px));
|
||
}
|
||
|
||
.bottom-bar-label {
|
||
font-size: 11px;
|
||
color: var(--text-hint);
|
||
margin-bottom: 6px;
|
||
font-weight: 500;
|
||
}
|
||
|
||
.bottom-bar-chips {
|
||
display: flex;
|
||
gap: 8px;
|
||
overflow-x: auto;
|
||
padding-bottom: 2px;
|
||
}
|
||
|
||
.bottom-chip {
|
||
font-size: 12px;
|
||
padding: 5px 12px;
|
||
border-radius: 16px;
|
||
background: var(--bg-secondary);
|
||
color: var(--text-secondary);
|
||
border: 1px solid transparent;
|
||
cursor: pointer;
|
||
white-space: nowrap;
|
||
transition: all 0.2s;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 4px;
|
||
}
|
||
|
||
.bottom-chip.active {
|
||
background: rgba(108,99,255,0.1);
|
||
color: var(--primary);
|
||
border-color: rgba(108,99,255,0.3);
|
||
}
|
||
|
||
.bottom-chip:active {
|
||
transform: scale(0.95);
|
||
}
|
||
|
||
/* ===== Search External Button ===== */
|
||
.search-ext-btn {
|
||
position: fixed;
|
||
bottom: 80px;
|
||
right: 16px;
|
||
width: 48px;
|
||
height: 48px;
|
||
border-radius: 50%;
|
||
background: var(--bg-card);
|
||
box-shadow: var(--shadow-lg);
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
font-size: 20px;
|
||
cursor: pointer;
|
||
border: 0.5px solid rgba(0,0,0,0.06);
|
||
z-index: 99;
|
||
transition: all 0.3s;
|
||
}
|
||
|
||
.search-ext-btn:active {
|
||
transform: scale(0.9);
|
||
}
|
||
|
||
/* ===== Season Color Themes ===== */
|
||
.theme-spring { --season-color: var(--spring); }
|
||
.theme-summer { --season-color: var(--summer); }
|
||
.theme-autumn { --season-color: var(--autumn); }
|
||
.theme-winter { --season-color: var(--winter); }
|
||
|
||
/* ===== Dark Mode ===== */
|
||
@media (prefers-color-scheme: dark) {
|
||
:root {
|
||
--bg-primary: #1A1A2E;
|
||
--bg-secondary: #16213E;
|
||
--bg-card: #2D2D44;
|
||
--bg-elevated: #333355;
|
||
--text-primary: #E5E5E5;
|
||
--text-secondary: #9CA3AF;
|
||
--text-hint: #6B7280;
|
||
}
|
||
|
||
.appbar {
|
||
background: rgba(26,26,46,0.78);
|
||
border-bottom-color: rgba(255,255,255,0.06);
|
||
}
|
||
|
||
.tl-card {
|
||
border-color: rgba(255,255,255,0.06);
|
||
}
|
||
|
||
.bottom-bar {
|
||
background: rgba(26,26,46,0.85);
|
||
border-top-color: rgba(255,255,255,0.06);
|
||
}
|
||
|
||
.search-ext-btn {
|
||
background: var(--bg-card);
|
||
border-color: rgba(255,255,255,0.06);
|
||
}
|
||
}
|
||
|
||
/* ===== Decision Bar ===== */
|
||
.decision-bar {
|
||
padding: 10px var(--space-md) 6px;
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 8px;
|
||
background: var(--bg-primary);
|
||
border-bottom: 0.5px solid rgba(0,0,0,0.06);
|
||
}
|
||
|
||
.decision-row {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 6px;
|
||
}
|
||
|
||
.decision-label {
|
||
font-size: 11px;
|
||
color: var(--text-hint);
|
||
font-weight: 500;
|
||
white-space: nowrap;
|
||
min-width: 52px;
|
||
}
|
||
|
||
.decision-btns {
|
||
display: flex;
|
||
gap: 4px;
|
||
flex: 1;
|
||
}
|
||
|
||
.decision-btn {
|
||
font-size: 11px;
|
||
padding: 4px 10px;
|
||
border-radius: 14px;
|
||
background: var(--bg-secondary);
|
||
color: var(--text-secondary);
|
||
border: 1px solid transparent;
|
||
cursor: pointer;
|
||
white-space: nowrap;
|
||
transition: all 0.2s;
|
||
}
|
||
|
||
.decision-btn.active {
|
||
background: rgba(108,99,255,0.1);
|
||
color: var(--primary);
|
||
border-color: rgba(108,99,255,0.3);
|
||
font-weight: 600;
|
||
}
|
||
|
||
.decision-btn:active {
|
||
transform: scale(0.95);
|
||
}
|
||
|
||
.season-btn {
|
||
width: 28px;
|
||
height: 28px;
|
||
border-radius: 50%;
|
||
border: 2px solid transparent;
|
||
cursor: pointer;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
font-size: 13px;
|
||
transition: all 0.2s;
|
||
background: var(--bg-secondary);
|
||
}
|
||
|
||
.season-btn.active {
|
||
border-color: var(--primary);
|
||
box-shadow: 0 0 0 2px rgba(108,99,255,0.2);
|
||
transform: scale(1.1);
|
||
}
|
||
|
||
.season-btn:active {
|
||
transform: scale(0.9);
|
||
}
|
||
|
||
.dark-toggle {
|
||
width: 28px;
|
||
height: 28px;
|
||
border-radius: 50%;
|
||
background: var(--bg-secondary);
|
||
border: 1px solid rgba(0,0,0,0.06);
|
||
cursor: pointer;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
font-size: 14px;
|
||
transition: all 0.3s;
|
||
}
|
||
|
||
.dark-toggle:active {
|
||
transform: scale(0.9);
|
||
}
|
||
|
||
.dark-toggle.active {
|
||
background: #1A1A2E;
|
||
border-color: rgba(108,99,255,0.3);
|
||
}
|
||
|
||
/* ===== Search Panel ===== */
|
||
.search-panel-overlay {
|
||
position: fixed;
|
||
top: 0;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
background: rgba(0,0,0,0.3);
|
||
z-index: 200;
|
||
opacity: 0;
|
||
pointer-events: none;
|
||
transition: opacity 0.3s;
|
||
}
|
||
|
||
.search-panel-overlay.show {
|
||
opacity: 1;
|
||
pointer-events: auto;
|
||
}
|
||
|
||
.search-panel {
|
||
position: fixed;
|
||
top: 50%;
|
||
left: 50%;
|
||
transform: translate(-50%, -50%) scale(0.9);
|
||
z-index: 201;
|
||
background: var(--bg-card);
|
||
border-radius: var(--radius-xl);
|
||
padding: var(--space-lg);
|
||
box-shadow: var(--shadow-lg);
|
||
width: 320px;
|
||
opacity: 0;
|
||
pointer-events: none;
|
||
transition: all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
|
||
}
|
||
|
||
.search-panel.show {
|
||
opacity: 1;
|
||
pointer-events: auto;
|
||
transform: translate(-50%, -50%) scale(1);
|
||
}
|
||
|
||
.search-panel-title {
|
||
font-size: 16px;
|
||
font-weight: 600;
|
||
text-align: center;
|
||
margin-bottom: var(--space-md);
|
||
}
|
||
|
||
.search-panel-grid {
|
||
display: grid;
|
||
grid-template-columns: repeat(3, 1fr);
|
||
gap: 10px;
|
||
}
|
||
|
||
.search-option {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
gap: 6px;
|
||
padding: 14px 8px;
|
||
border-radius: var(--radius-lg);
|
||
background: var(--bg-secondary);
|
||
cursor: pointer;
|
||
transition: all 0.2s;
|
||
border: 1px solid transparent;
|
||
}
|
||
|
||
.search-option:active {
|
||
transform: scale(0.95);
|
||
background: rgba(108,99,255,0.08);
|
||
border-color: rgba(108,99,255,0.2);
|
||
}
|
||
|
||
.search-option-icon {
|
||
font-size: 28px;
|
||
}
|
||
|
||
.search-option-name {
|
||
font-size: 12px;
|
||
font-weight: 500;
|
||
color: var(--text-secondary);
|
||
}
|
||
|
||
/* ===== Card Style Variants ===== */
|
||
.card-style-flat .tl-card {
|
||
box-shadow: none;
|
||
border: 1px solid rgba(0,0,0,0.06);
|
||
border-radius: var(--radius-md);
|
||
}
|
||
|
||
.card-style-flat .tl-card .card-header {
|
||
padding: 8px 10px 4px;
|
||
}
|
||
|
||
.card-style-flat .tl-card .card-body {
|
||
padding: 0 10px 8px;
|
||
}
|
||
|
||
.card-style-image .tl-card {
|
||
border-radius: var(--radius-xl);
|
||
}
|
||
|
||
.card-style-image .tl-card .card-header {
|
||
padding: 0;
|
||
position: relative;
|
||
}
|
||
|
||
.card-style-image .tl-card .card-header .card-type-badge {
|
||
position: absolute;
|
||
top: 8px;
|
||
left: 8px;
|
||
z-index: 2;
|
||
}
|
||
|
||
.card-style-image .tl-card .card-header .card-price-badge {
|
||
position: absolute;
|
||
top: 8px;
|
||
right: 8px;
|
||
z-index: 2;
|
||
}
|
||
|
||
.card-style-image .tl-card .card-img-placeholder {
|
||
height: 80px;
|
||
width: 100%;
|
||
}
|
||
|
||
.card-style-image .tl-card.food-card .card-img-placeholder {
|
||
background: linear-gradient(135deg, #FFF3E0, #FFE0B2);
|
||
}
|
||
|
||
.card-style-image .tl-card.play-card .card-img-placeholder {
|
||
background: linear-gradient(135deg, #E0F7FA, #B2EBF2);
|
||
}
|
||
|
||
/* ===== Layout: Left Line Right Card ===== */
|
||
.layout-left-line .timeline-line {
|
||
left: 24px;
|
||
}
|
||
|
||
.layout-left-line .date-node {
|
||
align-items: flex-start;
|
||
flex-direction: row;
|
||
gap: 12px;
|
||
padding-left: 0;
|
||
}
|
||
|
||
.layout-left-line .date-node-dot {
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
.layout-left-line .date-node-label {
|
||
margin-top: 0;
|
||
text-align: left;
|
||
}
|
||
|
||
.layout-left-line .card-row {
|
||
padding-left: 48px;
|
||
}
|
||
|
||
/* ===== Dark Mode Manual ===== */
|
||
body.dark-mode {
|
||
--bg-primary: #1A1A2E;
|
||
--bg-secondary: #16213E;
|
||
--bg-card: #2D2D44;
|
||
--bg-elevated: #333355;
|
||
--text-primary: #E5E5E5;
|
||
--text-secondary: #9CA3AF;
|
||
--text-hint: #6B7280;
|
||
}
|
||
|
||
body.dark-mode .appbar {
|
||
background: rgba(26,26,46,0.78);
|
||
border-bottom-color: rgba(255,255,255,0.06);
|
||
}
|
||
|
||
body.dark-mode .tl-card {
|
||
border-color: rgba(255,255,255,0.06);
|
||
}
|
||
|
||
body.dark-mode .bottom-bar {
|
||
background: rgba(26,26,46,0.85);
|
||
border-top-color: rgba(255,255,255,0.06);
|
||
}
|
||
|
||
body.dark-mode .search-ext-btn {
|
||
background: var(--bg-card);
|
||
border-color: rgba(255,255,255,0.06);
|
||
}
|
||
|
||
body.dark-mode .decision-bar {
|
||
border-bottom-color: rgba(255,255,255,0.06);
|
||
}
|
||
|
||
body.dark-mode .search-panel {
|
||
background: var(--bg-card);
|
||
}
|
||
|
||
body.dark-mode .search-option {
|
||
background: var(--bg-secondary);
|
||
}
|
||
|
||
body.dark-mode .toggle {
|
||
background: #3A3A5C;
|
||
}
|
||
|
||
/* ===== Animations ===== */
|
||
.fade-in {
|
||
animation: fadeIn 0.5s ease-out;
|
||
}
|
||
|
||
@keyframes fadeIn {
|
||
from { opacity: 0; transform: translateY(12px); }
|
||
to { opacity: 1; transform: translateY(0); }
|
||
}
|
||
|
||
.slide-left {
|
||
animation: slideLeft 0.4s ease-out;
|
||
}
|
||
|
||
@keyframes slideLeft {
|
||
from { opacity: 0; transform: translateX(-20px); }
|
||
to { opacity: 1; transform: translateX(0); }
|
||
}
|
||
|
||
.slide-right {
|
||
animation: slideRight 0.4s ease-out;
|
||
}
|
||
|
||
@keyframes slideRight {
|
||
from { opacity: 0; transform: translateX(20px); }
|
||
to { opacity: 1; transform: translateX(0); }
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div class="phone-frame">
|
||
|
||
<!-- AppBar -->
|
||
<div class="appbar">
|
||
<div class="appbar-left">
|
||
<button class="appbar-back">‹</button>
|
||
<div>
|
||
<div class="appbar-title">🌸 闲情逸致</div>
|
||
<div class="appbar-subtitle">闲时与你立黄昏,灶前笑问粥可温</div>
|
||
</div>
|
||
</div>
|
||
<div class="appbar-right">
|
||
<button class="appbar-btn" title="外部搜索" onclick="showSearchPanel()">🔍</button>
|
||
<button class="appbar-btn" title="设置" onclick="window.location.href='leisure_settings.html'">⚙️</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Swap Button (Fixed) -->
|
||
<button class="swap-btn-fixed" id="swapBtn" title="交换左右位置" onclick="toggleSwap()">
|
||
<span class="swap-icon">⇄</span>
|
||
</button>
|
||
|
||
<!-- Decision Bar -->
|
||
<div class="decision-bar">
|
||
<div class="decision-row">
|
||
<span class="decision-label">卡片样式</span>
|
||
<div class="decision-btns">
|
||
<button class="decision-btn active" onclick="setCardStyle(this, 'fancy')">精致卡片</button>
|
||
<button class="decision-btn" onclick="setCardStyle(this, 'flat')">扁平简约</button>
|
||
<button class="decision-btn" onclick="setCardStyle(this, 'image')">图文卡片</button>
|
||
</div>
|
||
</div>
|
||
<div class="decision-row">
|
||
<span class="decision-label">布局方向</span>
|
||
<div class="decision-btns">
|
||
<button class="decision-btn active" onclick="setLayout(this, 'center')">中轴对称</button>
|
||
<button class="decision-btn" onclick="setLayout(this, 'left')">左线右卡</button>
|
||
</div>
|
||
</div>
|
||
<div class="decision-row">
|
||
<span class="decision-label">季节色</span>
|
||
<div class="decision-btns">
|
||
<button class="season-btn active" onclick="setSeason(this, 'spring')" title="春">🌿</button>
|
||
<button class="season-btn" onclick="setSeason(this, 'summer')" title="夏">☀️</button>
|
||
<button class="season-btn" onclick="setSeason(this, 'autumn')" title="秋">🍂</button>
|
||
<button class="season-btn" onclick="setSeason(this, 'winter')" title="冬">❄️</button>
|
||
</div>
|
||
<span class="decision-label" style="margin-left:8px">暗色</span>
|
||
<button class="dark-toggle" id="darkToggle" onclick="toggleDarkMode()" title="暗色模式">🌙</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Timeline -->
|
||
<div class="timeline">
|
||
<div class="timeline-line"></div>
|
||
|
||
<!-- ===== Yesterday Node ===== -->
|
||
<div class="date-node fade-in">
|
||
<div class="date-node-dot"></div>
|
||
<div class="date-node-label">
|
||
<div class="date-node-month">5月26日</div>
|
||
<div class="date-node-weekday">星期二</div>
|
||
<div class="date-node-season season-summer">☀️ 夏</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card-row">
|
||
<div class="card-col slide-left">
|
||
<div class="tl-card food-card" onclick="window.location.href='leisure_card_detail.html'">
|
||
<div class="card-header">
|
||
<span class="card-type-badge badge-food">🍜 吃</span>
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="card-title">云南野生菌火锅</div>
|
||
<div class="card-desc">雨季第一波菌子,牛肝菌·鸡枞·松茸</div>
|
||
<div class="card-location">📍 云南·昆明</div>
|
||
<div class="card-risk">⚠️ 高原反应 · 野生菌中毒风险</div>
|
||
<div class="card-sun-info">
|
||
<span>🌅 06:20</span>
|
||
<span>🌇 19:48</span>
|
||
</div>
|
||
</div>
|
||
<div class="card-actions">
|
||
<button class="card-action-btn" onclick="toggleBookmark(this)">🔖 收藏</button>
|
||
<button class="card-action-btn" onclick="event.stopPropagation(); window.location.href='leisure_share_card.html'">📤 分享</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="card-col slide-right">
|
||
<div class="tl-card play-card" onclick="window.location.href='leisure_card_detail.html'">
|
||
<div class="card-header">
|
||
<span class="card-type-badge badge-play">🎯 玩</span>
|
||
<span class="card-price-badge price-free">免费</span>
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="card-title">翠湖公园赏荷</div>
|
||
<div class="card-desc">初夏荷花渐开,红嘴鸥已北迁</div>
|
||
<div class="card-location">📍 云南·昆明·翠湖</div>
|
||
<div class="card-sun-info">
|
||
<span>🌅 06:20</span>
|
||
<span>🌇 19:48</span>
|
||
</div>
|
||
</div>
|
||
<div class="card-actions">
|
||
<button class="card-action-btn" onclick="toggleBookmark(this)">🔖 收藏</button>
|
||
<button class="card-action-btn" onclick="event.stopPropagation(); window.location.href='leisure_share_card.html'">📤 分享</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ===== Today Divider ===== -->
|
||
<div class="today-divider fade-in">
|
||
<div class="today-divider-line"></div>
|
||
<div class="today-divider-text">✨ 今天 · 5月27日</div>
|
||
<div class="today-divider-line"></div>
|
||
</div>
|
||
|
||
<!-- ===== Today Node ===== -->
|
||
<div class="date-node fade-in">
|
||
<div class="date-node-dot today"></div>
|
||
<div class="date-node-label">
|
||
<div class="date-node-month">5月27日</div>
|
||
<div class="date-node-weekday weekend">星期三</div>
|
||
<div class="date-node-season season-summer">☀️ 夏</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Today Card Row 1 -->
|
||
<div class="card-row">
|
||
<div class="card-col slide-left">
|
||
<div class="tl-card food-card" onclick="window.location.href='leisure_card_detail.html'">
|
||
<div class="card-header">
|
||
<span class="card-type-badge badge-food">🍜 吃</span>
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="card-title">杨梅季 🍇</div>
|
||
<div class="card-desc">仙居杨梅·东魁·荸荠种,酸甜多汁</div>
|
||
<div class="card-location">📍 浙江·仙居</div>
|
||
<div class="card-sun-info">
|
||
<span>🌅 05:12</span>
|
||
<span>🌇 19:02</span>
|
||
</div>
|
||
</div>
|
||
<div class="card-checklist">
|
||
<label class="checklist-item"><input type="checkbox"> 买杨梅</label>
|
||
<label class="checklist-item"><input type="checkbox"> 做杨梅酒</label>
|
||
</div>
|
||
<div class="card-actions">
|
||
<button class="card-action-btn" onclick="toggleBookmark(this)">🔖 收藏</button>
|
||
<button class="card-action-btn" onclick="event.stopPropagation(); window.location.href='leisure_share_card.html'">📤 分享</button>
|
||
<button class="card-action-btn" onclick="event.stopPropagation(); alert('添加到笔记')">📝 笔记</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="card-col slide-right">
|
||
<div class="tl-card play-card" onclick="window.location.href='leisure_card_detail.html'">
|
||
<div class="card-header">
|
||
<span class="card-type-badge badge-play">🎯 玩</span>
|
||
<span class="card-price-badge price-paid">付费</span>
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="card-title">西湖夜游 🌙</div>
|
||
<div class="card-desc">印象西湖演出·断桥残雪·曲院风荷</div>
|
||
<div class="card-location">📍 浙江·杭州·西湖</div>
|
||
<div class="card-sun-info">
|
||
<span>🌅 05:12</span>
|
||
<span>🌇 19:02</span>
|
||
</div>
|
||
</div>
|
||
<div class="card-checklist">
|
||
<label class="checklist-item"><input type="checkbox"> 买门票</label>
|
||
<label class="checklist-item"><input type="checkbox"> 看演出</label>
|
||
</div>
|
||
<div class="card-actions">
|
||
<button class="card-action-btn" onclick="toggleBookmark(this)">🔖 收藏</button>
|
||
<button class="card-action-btn" onclick="event.stopPropagation(); window.location.href='leisure_share_card.html'">📤 分享</button>
|
||
<button class="card-action-btn" onclick="event.stopPropagation(); alert('添加到笔记')">📝 笔记</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Today Card Row 2 (Multiple cards per node) -->
|
||
<div class="card-row">
|
||
<div class="card-col slide-left">
|
||
<div class="tl-card food-card" onclick="window.location.href='leisure_card_detail.html'">
|
||
<div class="card-header">
|
||
<span class="card-type-badge badge-food">🍜 吃</span>
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="card-title">小龙虾 🦞</div>
|
||
<div class="card-desc">盱眙十三香·潜江油焖·麻辣蒜蓉</div>
|
||
<div class="card-location">📍 江苏·盱眙</div>
|
||
</div>
|
||
<div class="card-actions">
|
||
<button class="card-action-btn" onclick="toggleBookmark(this)">🔖 收藏</button>
|
||
<button class="card-action-btn" onclick="event.stopPropagation(); window.location.href='leisure_share_card.html'">📤 分享</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="card-col slide-right">
|
||
<div class="tl-card play-card" onclick="window.location.href='leisure_card_detail.html'">
|
||
<div class="card-header">
|
||
<span class="card-type-badge badge-play">🎯 玩</span>
|
||
<span class="card-price-badge price-commercial">商业化</span>
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="card-title">薰衣草花海 💜</div>
|
||
<div class="card-desc">伊犁河谷薰衣草初开,紫色花海</div>
|
||
<div class="card-location">📍 新疆·伊犁</div>
|
||
<div class="card-risk">⚠️ 高海拔 · 强紫外线</div>
|
||
</div>
|
||
<div class="card-actions">
|
||
<button class="card-action-btn" onclick="toggleBookmark(this)">🔖 收藏</button>
|
||
<button class="card-action-btn" onclick="event.stopPropagation(); window.location.href='leisure_share_card.html'">📤 分享</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ===== Tomorrow Node ===== -->
|
||
<div class="date-node fade-in">
|
||
<div class="date-node-dot"></div>
|
||
<div class="date-node-label">
|
||
<div class="date-node-month">5月28日</div>
|
||
<div class="date-node-weekday">星期四</div>
|
||
<div class="date-node-season season-summer">☀️ 夏</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card-row">
|
||
<div class="card-col slide-left">
|
||
<div class="tl-card food-card" onclick="window.location.href='leisure_card_detail.html'">
|
||
<div class="card-header">
|
||
<span class="card-type-badge badge-food">🍜 吃</span>
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="card-title">荔枝初上市 🫒</div>
|
||
<div class="card-desc">妃子笑·桂味·糯米糍,岭南佳果</div>
|
||
<div class="card-location">📍 广东·从化</div>
|
||
<div class="card-sun-info">
|
||
<span>🌅 05:48</span>
|
||
<span>🌇 19:18</span>
|
||
</div>
|
||
</div>
|
||
<div class="card-actions">
|
||
<button class="card-action-btn" onclick="toggleBookmark(this)">🔖 收藏</button>
|
||
<button class="card-action-btn" onclick="event.stopPropagation(); window.location.href='leisure_share_card.html'">📤 分享</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="card-col slide-right">
|
||
<div class="tl-card play-card" onclick="window.location.href='leisure_card_detail.html'">
|
||
<div class="card-header">
|
||
<span class="card-type-badge badge-play">🎯 玩</span>
|
||
<span class="card-price-badge price-unknown">未知</span>
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="card-title">纳木错观星 ✨</div>
|
||
<div class="card-desc">银河拱桥·星空露营·日出金山</div>
|
||
<div class="card-location">📍 西藏·纳木错 · 海拔4718m</div>
|
||
<div class="card-risk">⚠️ 高海拔 · 高原反应 · 低温</div>
|
||
<div class="card-sun-info">
|
||
<span>🌅 07:32</span>
|
||
<span>🌇 21:05</span>
|
||
</div>
|
||
</div>
|
||
<div class="card-actions">
|
||
<button class="card-action-btn" onclick="toggleBookmark(this)">🔖 收藏</button>
|
||
<button class="card-action-btn" onclick="event.stopPropagation(); window.location.href='leisure_share_card.html'">📤 分享</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ===== Day After Tomorrow ===== -->
|
||
<div class="date-node fade-in">
|
||
<div class="date-node-dot"></div>
|
||
<div class="date-node-label">
|
||
<div class="date-node-month">5月29日</div>
|
||
<div class="date-node-weekday weekend">星期五</div>
|
||
<div class="date-node-season season-summer">☀️ 夏</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card-row">
|
||
<div class="card-col slide-left">
|
||
<div class="tl-card food-card" onclick="window.location.href='leisure_card_detail.html'">
|
||
<div class="card-header">
|
||
<span class="card-type-badge badge-food">🍜 吃</span>
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="card-title">青岛啤酒节 🍺</div>
|
||
<div class="card-desc">鲜啤·扎啤·精酿,海鲜配啤酒</div>
|
||
<div class="card-location">📍 山东·青岛</div>
|
||
</div>
|
||
<div class="card-actions">
|
||
<button class="card-action-btn" onclick="toggleBookmark(this)">🔖 收藏</button>
|
||
<button class="card-action-btn" onclick="event.stopPropagation(); window.location.href='leisure_share_card.html'">📤 分享</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="card-col slide-right">
|
||
<div class="tl-card play-card" onclick="window.location.href='leisure_card_detail.html'">
|
||
<div class="card-header">
|
||
<span class="card-type-badge badge-play">🎯 玩</span>
|
||
<span class="card-price-badge price-free">免费</span>
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="card-title">呼伦贝尔草原 🌿</div>
|
||
<div class="card-desc">草原骑马·蒙古包·篝火晚会</div>
|
||
<div class="card-location">📍 内蒙古·呼伦贝尔 · 海拔650m</div>
|
||
<div class="card-risk">⚠️ 边境地区 · 注意安全</div>
|
||
</div>
|
||
<div class="card-actions">
|
||
<button class="card-action-btn" onclick="toggleBookmark(this)">🔖 收藏</button>
|
||
<button class="card-action-btn" onclick="event.stopPropagation(); window.location.href='leisure_share_card.html'">📤 分享</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
</div><!-- /timeline -->
|
||
|
||
<!-- External Search FAB -->
|
||
<button class="search-ext-btn" onclick="showSearchPanel()">🔎</button>
|
||
|
||
<!-- Search Panel Overlay -->
|
||
<div class="search-panel-overlay" id="searchOverlay" onclick="hideSearchPanel()"></div>
|
||
<div class="search-panel" id="searchPanel">
|
||
<div class="search-panel-title">🔍 选择搜索平台</div>
|
||
<div class="search-panel-grid">
|
||
<div class="search-option" onclick="openSearch('baidu')">
|
||
<span class="search-option-icon">🔵</span>
|
||
<span class="search-option-name">百度</span>
|
||
</div>
|
||
<div class="search-option" onclick="openSearch('amap')">
|
||
<span class="search-option-icon">🗺️</span>
|
||
<span class="search-option-name">高德</span>
|
||
</div>
|
||
<div class="search-option" onclick="openSearch('dianping')">
|
||
<span class="search-option-icon">⭐</span>
|
||
<span class="search-option-name">大众点评</span>
|
||
</div>
|
||
<div class="search-option" onclick="openSearch('xiaohongshu')">
|
||
<span class="search-option-icon">📕</span>
|
||
<span class="search-option-name">小红书</span>
|
||
</div>
|
||
<div class="search-option" onclick="openSearch('douyin')">
|
||
<span class="search-option-icon">🎵</span>
|
||
<span class="search-option-name">抖音</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Bottom Multi-select Bar -->
|
||
<div class="bottom-bar">
|
||
<div class="bottom-bar-label">标注筛选</div>
|
||
<div class="bottom-bar-chips">
|
||
<button class="bottom-chip active" onclick="toggleChip(this)">🌸 花期</button>
|
||
<button class="bottom-chip" onclick="toggleChip(this)">🦞 美食</button>
|
||
<button class="bottom-chip" onclick="toggleChip(this)">🏔️ 高海拔</button>
|
||
<button class="bottom-chip" onclick="toggleChip(this)">⚠️ 风险</button>
|
||
<button class="bottom-chip" onclick="toggleChip(this)">🆓 免费</button>
|
||
<button class="bottom-chip" onclick="toggleChip(this)">💰 付费</button>
|
||
<button class="bottom-chip" onclick="toggleChip(this)">🌅 日出</button>
|
||
<button class="bottom-chip" onclick="toggleChip(this)">🌊 观海</button>
|
||
</div>
|
||
</div>
|
||
|
||
</div><!-- /phone-frame -->
|
||
|
||
<script>
|
||
let swapped = false;
|
||
|
||
function toggleSwap() {
|
||
swapped = !swapped;
|
||
const btn = document.getElementById('swapBtn');
|
||
btn.classList.toggle('swapped', swapped);
|
||
|
||
document.querySelectorAll('.card-row').forEach(row => {
|
||
const cols = row.querySelectorAll('.card-col');
|
||
if (cols.length === 2) {
|
||
if (swapped) {
|
||
row.style.flexDirection = 'row-reverse';
|
||
} else {
|
||
row.style.flexDirection = 'row';
|
||
}
|
||
}
|
||
});
|
||
}
|
||
|
||
function toggleBookmark(btn) {
|
||
btn.classList.toggle('bookmarked');
|
||
if (btn.classList.contains('bookmarked')) {
|
||
btn.innerHTML = '🔖 已收藏';
|
||
} else {
|
||
btn.innerHTML = '🔖 收藏';
|
||
}
|
||
}
|
||
|
||
function toggleChip(chip) {
|
||
chip.classList.toggle('active');
|
||
}
|
||
|
||
function setCardStyle(btn, style) {
|
||
btn.parentElement.querySelectorAll('.decision-btn').forEach(b => b.classList.remove('active'));
|
||
btn.classList.add('active');
|
||
const frame = document.querySelector('.phone-frame');
|
||
frame.classList.remove('card-style-flat', 'card-style-image');
|
||
if (style === 'flat') frame.classList.add('card-style-flat');
|
||
if (style === 'image') frame.classList.add('card-style-image');
|
||
}
|
||
|
||
function setLayout(btn, layout) {
|
||
btn.parentElement.querySelectorAll('.decision-btn').forEach(b => b.classList.remove('active'));
|
||
btn.classList.add('active');
|
||
const timeline = document.querySelector('.timeline');
|
||
timeline.classList.remove('layout-left-line');
|
||
if (layout === 'left') timeline.classList.add('layout-left-line');
|
||
}
|
||
|
||
function setSeason(btn, season) {
|
||
btn.parentElement.querySelectorAll('.season-btn').forEach(b => b.classList.remove('active'));
|
||
btn.classList.add('active');
|
||
const colors = { spring: '#4ECDC4', summer: '#FF6B6B', autumn: '#F59E0B', winter: '#3B82F6' };
|
||
document.documentElement.style.setProperty('--primary', colors[season]);
|
||
document.documentElement.style.setProperty('--primary-light', colors[season] + 'CC');
|
||
}
|
||
|
||
function toggleDarkMode() {
|
||
const toggle = document.getElementById('darkToggle');
|
||
toggle.classList.toggle('active');
|
||
document.body.classList.toggle('dark-mode');
|
||
toggle.innerHTML = document.body.classList.contains('dark-mode') ? '☀️' : '🌙';
|
||
}
|
||
|
||
function showSearchPanel() {
|
||
document.getElementById('searchOverlay').classList.add('show');
|
||
document.getElementById('searchPanel').classList.add('show');
|
||
}
|
||
|
||
function hideSearchPanel() {
|
||
document.getElementById('searchOverlay').classList.remove('show');
|
||
document.getElementById('searchPanel').classList.remove('show');
|
||
}
|
||
|
||
function openSearch(platform) {
|
||
const urls = {
|
||
baidu: 'https://www.baidu.com',
|
||
amap: 'https://www.amap.com',
|
||
dianping: 'https://www.dianping.com',
|
||
xiaohongshu: 'https://www.xiaohongshu.com',
|
||
douyin: 'https://www.douyin.com'
|
||
};
|
||
hideSearchPanel();
|
||
alert('跳转到 ' + platform + ': ' + urls[platform]);
|
||
}
|
||
</script>
|
||
</body>
|
||
</html>
|