mirror of
https://github.com/hicccc77/WeFlow.git
synced 2026-05-13 15:10:05 +00:00
refactor(ui): ChatGPT-style visual overhaul for app shell and analytics pages
This commit is contained in:
98
src/App.scss
98
src/App.scss
@@ -3,56 +3,15 @@
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background: var(--bg-primary);
|
||||
animation: appFadeIn 0.35s ease-out;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
// 繁花如梦:底色层(::before)+ 光晕层(::after)分离,避免 blur 吃掉边缘
|
||||
[data-theme="blossom-dream"] .app-container {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
// ::before 纯底色,不模糊
|
||||
[data-theme="blossom-dream"] .app-container::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
pointer-events: none;
|
||||
z-index: -2;
|
||||
background: var(--bg-primary);
|
||||
}
|
||||
|
||||
// ::after 光晕层,模糊叠加在底色上
|
||||
[data-theme="blossom-dream"] .app-container::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
pointer-events: none;
|
||||
z-index: -1;
|
||||
background:
|
||||
radial-gradient(ellipse 55% 45% at 15% 20%, var(--blossom-pink) 0%, transparent 70%),
|
||||
radial-gradient(ellipse 50% 40% at 85% 75%, var(--blossom-peach) 0%, transparent 65%),
|
||||
radial-gradient(ellipse 45% 50% at 80% 10%, var(--blossom-blue) 0%, transparent 60%);
|
||||
filter: blur(80px);
|
||||
opacity: 0.75;
|
||||
}
|
||||
|
||||
// 深色模式光晕更克制
|
||||
[data-theme="blossom-dream"][data-mode="dark"] .app-container::after {
|
||||
background:
|
||||
radial-gradient(ellipse 55% 45% at 15% 20%, var(--blossom-pink) 0%, transparent 70%),
|
||||
radial-gradient(ellipse 50% 40% at 85% 75%, var(--blossom-purple) 0%, transparent 65%),
|
||||
radial-gradient(ellipse 45% 50% at 80% 10%, var(--blossom-blue) 0%, transparent 60%);
|
||||
filter: blur(100px);
|
||||
opacity: 0.2;
|
||||
}
|
||||
|
||||
.window-drag-region {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 150px; // 预留系统最小化/最大化/关闭按钮区域
|
||||
right: 150px;
|
||||
height: 40px;
|
||||
-webkit-app-region: drag;
|
||||
pointer-events: auto;
|
||||
@@ -68,8 +27,9 @@
|
||||
.content {
|
||||
flex: 1;
|
||||
overflow: auto;
|
||||
padding: 24px;
|
||||
padding: 24px 32px;
|
||||
position: relative;
|
||||
background: var(--bg-primary);
|
||||
}
|
||||
|
||||
.export-keepalive-page {
|
||||
@@ -84,18 +44,7 @@
|
||||
display: none;
|
||||
}
|
||||
|
||||
@keyframes appFadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(8px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
// 更新提示条
|
||||
// ---- Update banner ----
|
||||
.update-banner {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -107,7 +56,7 @@
|
||||
|
||||
.update-text {
|
||||
flex: 1;
|
||||
|
||||
|
||||
strong {
|
||||
font-weight: 600;
|
||||
}
|
||||
@@ -124,7 +73,7 @@
|
||||
color: white;
|
||||
font-size: 13px;
|
||||
cursor: pointer;
|
||||
transition: background 0.2s;
|
||||
transition: background 0.15s;
|
||||
|
||||
&:hover {
|
||||
background: rgba(255, 255, 255, 0.3);
|
||||
@@ -143,7 +92,7 @@
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
opacity: 0.7;
|
||||
transition: opacity 0.2s;
|
||||
transition: opacity 0.15s;
|
||||
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
@@ -178,29 +127,31 @@
|
||||
}
|
||||
}
|
||||
|
||||
// 用户协议弹窗
|
||||
// ---- Agreement modal ----
|
||||
.agreement-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: rgba(0, 0, 0, 0.6);
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 1000;
|
||||
backdrop-filter: blur(4px);
|
||||
}
|
||||
|
||||
.agreement-modal {
|
||||
width: 520px;
|
||||
max-height: 80vh;
|
||||
background: var(--bg-primary);
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 16px;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
|
||||
box-shadow: 0 24px 48px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.agreement-header {
|
||||
@@ -241,8 +192,8 @@
|
||||
margin-bottom: 16px;
|
||||
padding: 12px 14px;
|
||||
border-radius: 10px;
|
||||
border: 1px solid rgba(255, 160, 0, 0.35);
|
||||
background: rgba(255, 160, 0, 0.12);
|
||||
border: 1px solid rgba(245, 158, 11, 0.3);
|
||||
background: rgba(245, 158, 11, 0.08);
|
||||
color: var(--text-primary);
|
||||
|
||||
strong {
|
||||
@@ -291,19 +242,6 @@
|
||||
color: var(--text-secondary);
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-thumb {
|
||||
background: var(--border-color);
|
||||
border-radius: 3px;
|
||||
}
|
||||
}
|
||||
|
||||
.agreement-footer {
|
||||
@@ -347,21 +285,21 @@
|
||||
border-radius: 8px;
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
transition: background 0.2s;
|
||||
transition: background 0.15s;
|
||||
|
||||
&:hover {
|
||||
background: var(--border-color);
|
||||
background: var(--bg-hover);
|
||||
}
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background: var(--primary);
|
||||
color: white;
|
||||
color: var(--on-primary);
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
transition: opacity 0.2s;
|
||||
transition: opacity 0.15s;
|
||||
|
||||
&:disabled {
|
||||
opacity: 0.5;
|
||||
|
||||
26
src/App.tsx
26
src/App.tsx
@@ -30,7 +30,7 @@ import AccountManagementPage from './pages/AccountManagementPage'
|
||||
import BackupPage from './pages/BackupPage'
|
||||
|
||||
import { useAppStore } from './stores/appStore'
|
||||
import { themes, useThemeStore, type ThemeId, type ThemeMode } from './stores/themeStore'
|
||||
import { useThemeStore, type ThemeMode } from './stores/themeStore'
|
||||
import * as configService from './services/config'
|
||||
import * as cloudControl from './services/cloudControl'
|
||||
import { Download, X, Shield } from 'lucide-react'
|
||||
@@ -74,7 +74,7 @@ function App() {
|
||||
setLocked
|
||||
} = useAppStore()
|
||||
|
||||
const { currentTheme, themeMode, setTheme, setThemeMode } = useThemeStore()
|
||||
const { themeMode, setThemeMode } = useThemeStore()
|
||||
const isAgreementWindow = location.pathname === '/agreement-window'
|
||||
const isOnboardingWindow = location.pathname === '/onboarding-window'
|
||||
const isVideoPlayerWindow = location.pathname === '/video-player-window'
|
||||
@@ -149,12 +149,11 @@ function App() {
|
||||
}
|
||||
}, [isOnboardingWindow, isNotificationWindow, isAnnualReportWindow, isDualReportWindow])
|
||||
|
||||
// 应用主题
|
||||
// 应用主题模式 (light / dark / system)
|
||||
useEffect(() => {
|
||||
const mq = window.matchMedia('(prefers-color-scheme: dark)')
|
||||
const applyMode = (mode: ThemeMode, systemDark?: boolean) => {
|
||||
const effectiveMode = mode === 'system' ? (systemDark ?? mq.matches ? 'dark' : 'light') : mode
|
||||
document.documentElement.setAttribute('data-theme', currentTheme)
|
||||
document.documentElement.setAttribute('data-mode', effectiveMode)
|
||||
}
|
||||
|
||||
@@ -168,19 +167,13 @@ function App() {
|
||||
}
|
||||
mq.addEventListener('change', handler)
|
||||
return () => mq.removeEventListener('change', handler)
|
||||
}, [currentTheme, themeMode, isOnboardingWindow, isNotificationWindow, isAnnualReportWindow, isDualReportWindow])
|
||||
}, [themeMode, isOnboardingWindow, isNotificationWindow, isAnnualReportWindow, isDualReportWindow])
|
||||
|
||||
// 读取已保存的主题设置
|
||||
useEffect(() => {
|
||||
const loadTheme = async () => {
|
||||
try {
|
||||
const [savedThemeId, savedThemeMode] = await Promise.all([
|
||||
configService.getThemeId(),
|
||||
configService.getTheme()
|
||||
])
|
||||
if (savedThemeId && themes.some((theme) => theme.id === savedThemeId)) {
|
||||
setTheme(savedThemeId as ThemeId)
|
||||
}
|
||||
const savedThemeMode = await configService.getTheme()
|
||||
if (savedThemeMode === 'light' || savedThemeMode === 'dark' || savedThemeMode === 'system') {
|
||||
setThemeMode(savedThemeMode)
|
||||
}
|
||||
@@ -191,23 +184,20 @@ function App() {
|
||||
}
|
||||
}
|
||||
loadTheme()
|
||||
}, [setTheme, setThemeMode])
|
||||
}, [setThemeMode])
|
||||
|
||||
// 保存主题设置
|
||||
useEffect(() => {
|
||||
if (!themeHydrated) return
|
||||
const saveTheme = async () => {
|
||||
try {
|
||||
await Promise.all([
|
||||
configService.setThemeId(currentTheme),
|
||||
configService.setTheme(themeMode)
|
||||
])
|
||||
await configService.setTheme(themeMode)
|
||||
} catch (e) {
|
||||
console.error('保存主题配置失败:', e)
|
||||
}
|
||||
}
|
||||
saveTheme()
|
||||
}, [currentTheme, themeMode, themeHydrated])
|
||||
}, [themeMode, themeHydrated])
|
||||
|
||||
// 检查是否已同意协议
|
||||
useEffect(() => {
|
||||
|
||||
@@ -4,28 +4,29 @@
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 16px;
|
||||
min-height: 28px;
|
||||
min-height: 32px;
|
||||
padding: 4px 0;
|
||||
background: transparent;
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.chat-analysis-back {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
padding: 0;
|
||||
gap: 4px;
|
||||
padding: 4px 8px 4px 4px;
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
background: transparent;
|
||||
color: var(--text-secondary);
|
||||
color: var(--text-tertiary);
|
||||
cursor: pointer;
|
||||
transition: color 0.2s ease;
|
||||
transition: background 0.15s ease, color 0.15s ease;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
font-weight: 500;
|
||||
|
||||
&:hover {
|
||||
background: var(--bg-hover);
|
||||
color: var(--text-primary);
|
||||
}
|
||||
}
|
||||
@@ -33,12 +34,13 @@
|
||||
.chat-analysis-breadcrumb {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
gap: 4px;
|
||||
font-size: 13px;
|
||||
color: var(--text-secondary);
|
||||
color: var(--text-tertiary);
|
||||
|
||||
.chat-analysis-breadcrumb-separator {
|
||||
opacity: 0.6;
|
||||
opacity: 0.5;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,25 +51,27 @@
|
||||
.chat-analysis-current-trigger {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
padding: 0;
|
||||
gap: 4px;
|
||||
padding: 4px 8px;
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
background: transparent;
|
||||
color: var(--text-secondary);
|
||||
color: var(--text-tertiary);
|
||||
cursor: pointer;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
transition: color 0.2s ease;
|
||||
transition: background 0.15s ease, color 0.15s ease;
|
||||
|
||||
.current {
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
svg {
|
||||
transition: transform 0.2s ease;
|
||||
transition: transform 0.15s ease;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: var(--bg-hover);
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
@@ -78,34 +82,33 @@
|
||||
|
||||
.chat-analysis-menu {
|
||||
position: absolute;
|
||||
top: calc(100% + 10px);
|
||||
top: calc(100% + 6px);
|
||||
right: 0;
|
||||
min-width: 120px;
|
||||
padding: 6px;
|
||||
background: var(--card-bg);
|
||||
padding: 4px;
|
||||
background: var(--bg-secondary-solid, var(--bg-secondary));
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 12px 28px rgba(0, 0, 0, 0.12);
|
||||
border-radius: 10px;
|
||||
box-shadow: var(--shadow-md);
|
||||
z-index: 20;
|
||||
}
|
||||
|
||||
.chat-analysis-menu-item {
|
||||
width: 100%;
|
||||
display: block;
|
||||
padding: 9px 12px;
|
||||
padding: 8px 12px;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
border-radius: 6px;
|
||||
background: transparent;
|
||||
color: var(--text-primary);
|
||||
text-align: left;
|
||||
cursor: pointer;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
transition: background 0.2s ease, color 0.2s ease;
|
||||
transition: background 0.15s ease;
|
||||
|
||||
&:hover {
|
||||
background: var(--bg-hover);
|
||||
color: var(--primary);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
// ChatGPT-style sidebar
|
||||
.sidebar {
|
||||
width: 220px;
|
||||
background: var(--bg-secondary);
|
||||
border-right: 1px solid var(--border-color);
|
||||
width: var(--sidebar-width, 260px);
|
||||
background: var(--bg-sidebar, var(--bg-secondary));
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 16px 0;
|
||||
transition: width 0.25s ease;
|
||||
padding: 8px 0;
|
||||
transition: width 0.2s ease;
|
||||
flex-shrink: 0;
|
||||
overflow: hidden;
|
||||
|
||||
&.collapsed {
|
||||
width: 64px;
|
||||
width: 68px;
|
||||
|
||||
.sidebar-user-card-wrap {
|
||||
margin: 0 8px 8px;
|
||||
@@ -40,156 +42,15 @@
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar-user-card-wrap {
|
||||
position: relative;
|
||||
margin: 0 12px 10px;
|
||||
--sidebar-user-menu-width: 172px;
|
||||
}
|
||||
|
||||
.sidebar-user-menu {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: auto;
|
||||
bottom: calc(100% + 8px);
|
||||
width: max(100%, var(--sidebar-user-menu-width));
|
||||
z-index: 12;
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 12px;
|
||||
background: var(--bg-secondary-solid, var(--bg-primary));
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
padding: 6px;
|
||||
box-shadow: 0 8px 20px rgba(15, 23, 42, 0.12);
|
||||
opacity: 0;
|
||||
transform: translateY(8px) scale(0.95);
|
||||
pointer-events: none;
|
||||
transition: opacity 0.2s ease, transform 0.2s ease;
|
||||
|
||||
&.open {
|
||||
opacity: 1;
|
||||
transform: translateY(0) scale(1);
|
||||
pointer-events: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar-user-menu-item {
|
||||
width: 100%;
|
||||
border: none;
|
||||
border-radius: 10px;
|
||||
background: transparent;
|
||||
color: var(--text-primary);
|
||||
padding: 9px 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
text-align: left;
|
||||
transition: background 0.2s ease, color 0.2s ease;
|
||||
|
||||
&:hover {
|
||||
background: var(--bg-tertiary);
|
||||
}
|
||||
|
||||
&.danger {
|
||||
color: #d93025;
|
||||
|
||||
&:hover {
|
||||
background: rgba(255, 59, 48, 0.08);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar-user-card {
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 12px;
|
||||
background: var(--bg-secondary);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
min-height: 56px;
|
||||
cursor: pointer;
|
||||
transition: border-color 0.2s ease, background 0.2s ease, box-shadow 0.2s ease;
|
||||
|
||||
&:hover {
|
||||
border-color: rgba(99, 102, 241, 0.32);
|
||||
background: var(--bg-tertiary);
|
||||
}
|
||||
|
||||
&.menu-open {
|
||||
border-color: rgba(99, 102, 241, 0.44);
|
||||
box-shadow: 0 0 0 2px rgba(99, 102, 241, 0.12);
|
||||
}
|
||||
|
||||
.user-avatar {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
background: linear-gradient(135deg, var(--primary), var(--primary-hover));
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
span {
|
||||
color: var(--on-primary);
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
.user-meta {
|
||||
min-width: 0;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.user-name {
|
||||
font-size: 13px;
|
||||
color: var(--text-primary);
|
||||
font-weight: 600;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.user-wxid {
|
||||
margin-top: 2px;
|
||||
font-size: 11px;
|
||||
color: var(--text-tertiary);
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.user-menu-caret {
|
||||
color: var(--text-tertiary);
|
||||
display: inline-flex;
|
||||
transition: transform 0.2s ease, color 0.2s ease;
|
||||
|
||||
&.open {
|
||||
transform: rotate(180deg);
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ---- Navigation ----
|
||||
.nav-menu {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
gap: 2px;
|
||||
padding: 0 12px;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.nav-item {
|
||||
@@ -197,24 +58,26 @@
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
padding: 10px 12px;
|
||||
border-radius: 9999px;
|
||||
border-radius: 8px;
|
||||
color: var(--text-secondary);
|
||||
text-decoration: none;
|
||||
transition: all 0.2s ease;
|
||||
transition: background 0.15s ease, color 0.15s ease;
|
||||
white-space: nowrap;
|
||||
border: none;
|
||||
background: transparent;
|
||||
cursor: pointer;
|
||||
font-family: inherit;
|
||||
font-size: 14px;
|
||||
|
||||
&:hover {
|
||||
background: var(--bg-tertiary);
|
||||
background: var(--bg-hover);
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
&.active {
|
||||
background: var(--primary);
|
||||
color: var(--on-primary);
|
||||
background: var(--bg-hover);
|
||||
color: var(--text-primary);
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -242,7 +105,7 @@
|
||||
height: 20px;
|
||||
border-radius: 999px;
|
||||
padding: 0 6px;
|
||||
background: #ff3b30;
|
||||
background: #ef4444;
|
||||
color: #ffffff;
|
||||
font-size: 11px;
|
||||
font-weight: 700;
|
||||
@@ -250,7 +113,6 @@
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
line-height: 1;
|
||||
box-shadow: 0 0 0 2px rgba(255, 59, 48, 0.18);
|
||||
}
|
||||
|
||||
.nav-badge.icon-badge {
|
||||
@@ -262,42 +124,158 @@
|
||||
height: 16px;
|
||||
padding: 0 4px;
|
||||
font-size: 10px;
|
||||
box-shadow: 0 0 0 2px var(--bg-secondary);
|
||||
box-shadow: 0 0 0 2px var(--bg-sidebar, var(--bg-secondary));
|
||||
}
|
||||
|
||||
// ---- Footer ----
|
||||
.sidebar-footer {
|
||||
padding: 0 12px;
|
||||
border-top: 1px solid var(--border-color);
|
||||
padding-top: 12px;
|
||||
margin-top: 8px;
|
||||
padding-top: 8px;
|
||||
margin-top: 4px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
gap: 2px;
|
||||
}
|
||||
|
||||
// 繁花如梦主题:侧边栏毛玻璃 + 激活项用主品牌色
|
||||
[data-theme="blossom-dream"] .sidebar {
|
||||
background: rgba(255, 255, 255, 0.6);
|
||||
backdrop-filter: blur(20px);
|
||||
-webkit-backdrop-filter: blur(20px);
|
||||
border-right: 1px solid rgba(255, 255, 255, 0.4);
|
||||
// ---- User card ----
|
||||
.sidebar-user-card-wrap {
|
||||
position: relative;
|
||||
margin: 0 12px 8px;
|
||||
--sidebar-user-menu-width: 172px;
|
||||
}
|
||||
|
||||
[data-theme="blossom-dream"][data-mode="dark"] .sidebar {
|
||||
background: rgba(34, 30, 36, 0.75);
|
||||
backdrop-filter: blur(20px);
|
||||
-webkit-backdrop-filter: blur(20px);
|
||||
border-right: 1px solid rgba(255, 255, 255, 0.06);
|
||||
.sidebar-user-menu {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: auto;
|
||||
bottom: calc(100% + 8px);
|
||||
width: max(100%, var(--sidebar-user-menu-width));
|
||||
z-index: 12;
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 10px;
|
||||
background: var(--bg-secondary-solid, var(--bg-secondary));
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2px;
|
||||
padding: 4px;
|
||||
box-shadow: var(--shadow-md);
|
||||
opacity: 0;
|
||||
transform: translateY(6px) scale(0.97);
|
||||
pointer-events: none;
|
||||
transition: opacity 0.15s ease, transform 0.15s ease;
|
||||
|
||||
&.open {
|
||||
opacity: 1;
|
||||
transform: translateY(0) scale(1);
|
||||
pointer-events: auto;
|
||||
}
|
||||
}
|
||||
|
||||
// 激活项:主品牌色纵向微渐变
|
||||
[data-theme="blossom-dream"] .nav-item.active {
|
||||
background: linear-gradient(180deg, #D4849A 0%, #C4748A 100%);
|
||||
.sidebar-user-menu-item {
|
||||
width: 100%;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
background: transparent;
|
||||
color: var(--text-primary);
|
||||
padding: 8px 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
text-align: left;
|
||||
transition: background 0.15s ease;
|
||||
|
||||
&:hover {
|
||||
background: var(--bg-hover);
|
||||
}
|
||||
|
||||
&.danger {
|
||||
color: #ef4444;
|
||||
|
||||
&:hover {
|
||||
background: rgba(239, 68, 68, 0.08);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 深色激活项:用藕粉色,背景深灰底 + 粉色文字/图标(高阶玩法)
|
||||
[data-theme="blossom-dream"][data-mode="dark"] .nav-item.active {
|
||||
background: rgba(209, 158, 187, 0.15);
|
||||
color: #D19EBB;
|
||||
border: 1px solid rgba(209, 158, 187, 0.2);
|
||||
.sidebar-user-card {
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
border-radius: 10px;
|
||||
background: transparent;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
min-height: 52px;
|
||||
cursor: pointer;
|
||||
border: none;
|
||||
transition: background 0.15s ease;
|
||||
|
||||
&:hover {
|
||||
background: var(--bg-hover);
|
||||
}
|
||||
|
||||
&.menu-open {
|
||||
background: var(--bg-hover);
|
||||
}
|
||||
|
||||
.user-avatar {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 50%;
|
||||
overflow: hidden;
|
||||
background: var(--primary);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
span {
|
||||
color: var(--on-primary);
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
.user-meta {
|
||||
min-width: 0;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.user-name {
|
||||
font-size: 13px;
|
||||
color: var(--text-primary);
|
||||
font-weight: 600;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.user-wxid {
|
||||
margin-top: 1px;
|
||||
font-size: 11px;
|
||||
color: var(--text-tertiary);
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.user-menu-caret {
|
||||
color: var(--text-tertiary);
|
||||
display: inline-flex;
|
||||
transition: transform 0.15s ease;
|
||||
|
||||
&.open {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
.title-bar {
|
||||
height: 41px;
|
||||
background: var(--bg-secondary);
|
||||
height: 48px;
|
||||
background: transparent;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding-left: 16px;
|
||||
padding-right: 16px;
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
padding-right: 8px;
|
||||
-webkit-app-region: drag;
|
||||
flex-shrink: 0;
|
||||
gap: 8px;
|
||||
@@ -14,12 +13,6 @@
|
||||
z-index: 2101;
|
||||
}
|
||||
|
||||
// 繁花如梦:标题栏毛玻璃
|
||||
[data-theme="blossom-dream"] .title-bar {
|
||||
backdrop-filter: blur(20px);
|
||||
-webkit-backdrop-filter: blur(20px);
|
||||
}
|
||||
|
||||
.title-brand {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
@@ -33,16 +26,15 @@
|
||||
}
|
||||
|
||||
.titles {
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: var(--text-secondary);
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
letter-spacing: -0.01em;
|
||||
}
|
||||
|
||||
.title-sidebar-toggle {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
padding: 0;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
@@ -52,11 +44,11 @@
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
transition: background 0.2s ease, color 0.2s ease;
|
||||
transition: background 0.15s ease, color 0.15s ease;
|
||||
-webkit-app-region: no-drag;
|
||||
|
||||
&:hover {
|
||||
background: var(--bg-tertiary);
|
||||
background: var(--bg-hover);
|
||||
color: var(--text-primary);
|
||||
}
|
||||
}
|
||||
@@ -64,26 +56,26 @@
|
||||
.title-window-controls {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
gap: 2px;
|
||||
-webkit-app-region: no-drag;
|
||||
}
|
||||
|
||||
.title-window-control-btn {
|
||||
width: 28px;
|
||||
width: 36px;
|
||||
height: 28px;
|
||||
padding: 0;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
border-radius: 6px;
|
||||
background: transparent;
|
||||
color: var(--text-tertiary);
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
transition: background 0.2s ease, color 0.2s ease;
|
||||
transition: background 0.15s ease, color 0.15s ease;
|
||||
|
||||
&:hover {
|
||||
background: var(--bg-tertiary);
|
||||
background: var(--bg-hover);
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
@@ -107,14 +99,14 @@
|
||||
color: var(--text-secondary);
|
||||
cursor: pointer;
|
||||
padding: 6px;
|
||||
border-radius: 4px;
|
||||
border-radius: 6px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: all 0.2s;
|
||||
transition: all 0.15s;
|
||||
|
||||
&:hover {
|
||||
background: var(--bg-tertiary);
|
||||
background: var(--bg-hover);
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
@@ -124,8 +116,8 @@
|
||||
}
|
||||
|
||||
&.live-play-btn.active {
|
||||
background: rgba(var(--primary-rgb, 76, 132, 255), 0.16);
|
||||
color: var(--primary, #4c84ff);
|
||||
background: var(--primary-light);
|
||||
color: var(--primary);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
// 加载和错误状态
|
||||
// Loading and error states
|
||||
.loading-container,
|
||||
.error-container {
|
||||
display: flex;
|
||||
@@ -23,7 +23,7 @@
|
||||
color: var(--text-secondary);
|
||||
|
||||
.spin {
|
||||
animation: spin 1s linear infinite;
|
||||
animation: analyticsSpin 1s linear infinite;
|
||||
}
|
||||
|
||||
p.loading-status {
|
||||
@@ -33,13 +33,12 @@
|
||||
}
|
||||
|
||||
.progress-bar-wrapper {
|
||||
width: 300px;
|
||||
height: 8px;
|
||||
width: 280px;
|
||||
height: 4px;
|
||||
background: var(--bg-tertiary);
|
||||
border-radius: 999px;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
border: 1px solid var(--border-color);
|
||||
}
|
||||
|
||||
.progress-bar-fill {
|
||||
@@ -47,9 +46,9 @@
|
||||
left: 0;
|
||||
top: 0;
|
||||
height: 100%;
|
||||
background: var(--primary-gradient);
|
||||
transition: width 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
box-shadow: 0 0 10px rgba(139, 115, 85, 0.3);
|
||||
background: var(--primary);
|
||||
transition: width 0.3s ease;
|
||||
border-radius: 999px;
|
||||
}
|
||||
|
||||
.progress-percent {
|
||||
@@ -65,57 +64,82 @@
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
@keyframes analyticsSpin {
|
||||
from { transform: rotate(0deg); }
|
||||
to { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
// Page scroll content
|
||||
.page-scroll {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 24px;
|
||||
}
|
||||
|
||||
.page-section {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.section-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
h2 {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: var(--text-primary);
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
// 统计卡片
|
||||
// Stats overview cards
|
||||
.stats-overview {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 16px;
|
||||
margin-bottom: 24px;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.stat-card {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
padding: 20px;
|
||||
gap: 14px;
|
||||
padding: 18px 16px;
|
||||
background: var(--card-bg);
|
||||
border-radius: 12px;
|
||||
border: 1px solid var(--border-color);
|
||||
|
||||
.stat-icon {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: var(--primary-light);
|
||||
border-radius: 12px;
|
||||
border-radius: 10px;
|
||||
color: var(--primary);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.stat-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
gap: 2px;
|
||||
|
||||
.stat-value {
|
||||
font-size: 24px;
|
||||
font-weight: 600;
|
||||
font-size: 22px;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
letter-spacing: -0.5px;
|
||||
}
|
||||
|
||||
.stat-label {
|
||||
font-size: 13px;
|
||||
font-size: 12px;
|
||||
color: var(--text-tertiary);
|
||||
}
|
||||
}
|
||||
@@ -125,23 +149,23 @@
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 12px 16px;
|
||||
padding: 10px 14px;
|
||||
background: var(--bg-tertiary);
|
||||
border-radius: 8px;
|
||||
margin-bottom: 24px;
|
||||
font-size: 13px;
|
||||
color: var(--text-secondary);
|
||||
|
||||
svg {
|
||||
color: var(--text-tertiary);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Charts
|
||||
.charts-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 16px;
|
||||
margin-bottom: 24px;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.chart-card {
|
||||
@@ -155,30 +179,30 @@
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: var(--text-primary);
|
||||
margin: 0 0 16px;
|
||||
margin: 0 0 12px;
|
||||
}
|
||||
}
|
||||
|
||||
// Rankings
|
||||
.rankings-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.ranking-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
padding: 12px 16px;
|
||||
background: var(--bg-primary);
|
||||
padding: 10px 14px;
|
||||
border-radius: 8px;
|
||||
transition: background 0.2s;
|
||||
transition: background 0.15s ease;
|
||||
|
||||
&:hover {
|
||||
background: var(--bg-tertiary);
|
||||
background: var(--bg-hover);
|
||||
}
|
||||
|
||||
.rank {
|
||||
@@ -196,13 +220,13 @@
|
||||
|
||||
&.top {
|
||||
background: var(--primary);
|
||||
color: white;
|
||||
color: var(--on-primary);
|
||||
}
|
||||
}
|
||||
|
||||
.contact-avatar {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
flex-shrink: 0;
|
||||
position: relative;
|
||||
|
||||
@@ -228,8 +252,8 @@
|
||||
position: absolute;
|
||||
right: -4px;
|
||||
bottom: -4px;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
@@ -239,24 +263,21 @@
|
||||
&.medal-1 {
|
||||
background: linear-gradient(135deg, #ffd700, #ffb800);
|
||||
color: #fff;
|
||||
box-shadow: 0 2px 4px rgba(255, 184, 0, 0.4);
|
||||
}
|
||||
|
||||
&.medal-2 {
|
||||
background: linear-gradient(135deg, #c0c0c0, #a8a8a8);
|
||||
color: #fff;
|
||||
box-shadow: 0 2px 4px rgba(168, 168, 168, 0.4);
|
||||
}
|
||||
|
||||
&.medal-3 {
|
||||
background: linear-gradient(135deg, #cd7f32, #b87333);
|
||||
color: #fff;
|
||||
box-shadow: 0 2px 4px rgba(184, 115, 51, 0.4);
|
||||
}
|
||||
|
||||
svg {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -265,7 +286,7 @@
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2px;
|
||||
gap: 1px;
|
||||
min-width: 0;
|
||||
|
||||
.contact-name {
|
||||
@@ -284,14 +305,14 @@
|
||||
}
|
||||
|
||||
.message-count {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
color: var(--primary);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
}
|
||||
|
||||
// 响应式
|
||||
// Responsive
|
||||
@media (max-width: 1200px) {
|
||||
.stats-overview {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
@@ -312,11 +333,11 @@
|
||||
}
|
||||
}
|
||||
|
||||
// 排除好友弹窗
|
||||
// Exclude friends modal
|
||||
.exclude-modal-overlay {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
background: rgba(0, 0, 0, 0.45);
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
@@ -325,13 +346,13 @@
|
||||
}
|
||||
|
||||
.exclude-modal {
|
||||
width: 560px;
|
||||
width: 520px;
|
||||
max-width: calc(100vw - 48px);
|
||||
background: var(--card-bg);
|
||||
background: var(--bg-secondary-solid, var(--bg-secondary));
|
||||
border-radius: 16px;
|
||||
border: 1px solid var(--border-color);
|
||||
padding: 20px;
|
||||
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.2);
|
||||
box-shadow: 0 24px 48px rgba(0, 0, 0, 0.2);
|
||||
|
||||
.exclude-modal-header {
|
||||
display: flex;
|
||||
@@ -342,6 +363,7 @@
|
||||
h3 {
|
||||
margin: 0;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
}
|
||||
@@ -349,14 +371,14 @@
|
||||
.modal-close {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 50%;
|
||||
border-radius: 8px;
|
||||
border: none;
|
||||
background: var(--bg-tertiary);
|
||||
background: transparent;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
color: var(--text-secondary);
|
||||
color: var(--text-tertiary);
|
||||
transition: all 0.15s;
|
||||
|
||||
&:hover {
|
||||
@@ -370,7 +392,7 @@
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 8px 12px;
|
||||
border-radius: 10px;
|
||||
border-radius: 8px;
|
||||
border: 1px solid var(--border-color);
|
||||
background: var(--bg-primary);
|
||||
margin-bottom: 12px;
|
||||
@@ -399,7 +421,7 @@
|
||||
}
|
||||
|
||||
.exclude-modal-body {
|
||||
max-height: 420px;
|
||||
max-height: 380px;
|
||||
overflow: auto;
|
||||
padding-right: 4px;
|
||||
}
|
||||
@@ -419,7 +441,7 @@
|
||||
.exclude-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.exclude-item {
|
||||
@@ -427,23 +449,23 @@
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
padding: 8px 10px;
|
||||
border-radius: 10px;
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
border: 1px solid transparent;
|
||||
transition: all 0.15s;
|
||||
background: var(--bg-primary);
|
||||
|
||||
&:hover {
|
||||
background: var(--bg-tertiary);
|
||||
background: var(--bg-hover);
|
||||
}
|
||||
|
||||
&.active {
|
||||
border-color: rgba(7, 193, 96, 0.4);
|
||||
background: rgba(7, 193, 96, 0.08);
|
||||
border-color: rgba(16, 163, 127, 0.3);
|
||||
background: rgba(16, 163, 127, 0.06);
|
||||
}
|
||||
|
||||
input {
|
||||
margin: 0;
|
||||
accent-color: var(--primary);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -455,7 +477,7 @@
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-width: 0;
|
||||
gap: 2px;
|
||||
gap: 1px;
|
||||
}
|
||||
|
||||
.exclude-name {
|
||||
@@ -479,7 +501,7 @@
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-top: 16px;
|
||||
margin-top: 14px;
|
||||
}
|
||||
|
||||
.exclude-footer-left {
|
||||
|
||||
@@ -1,146 +1,116 @@
|
||||
.analytics-entry-page {
|
||||
.analytics-welcome-shell {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
.analytics-welcome-container {
|
||||
.analytics-welcome-body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-height: 0;
|
||||
padding: 40px;
|
||||
background: var(--bg-primary);
|
||||
padding: 40px 24px;
|
||||
animation: welcomeFadeIn 0.4s ease-out;
|
||||
}
|
||||
|
||||
.analytics-welcome-content {
|
||||
text-align: center;
|
||||
max-width: 480px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.analytics-welcome-icon {
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
margin: 0 auto 20px;
|
||||
background: var(--primary-light);
|
||||
border-radius: 14px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
.analytics-welcome-content h1 {
|
||||
font-size: 24px;
|
||||
font-weight: 700;
|
||||
margin: 0 0 10px;
|
||||
color: var(--text-primary);
|
||||
animation: fadeIn 0.4s ease-out;
|
||||
overflow-y: auto;
|
||||
letter-spacing: -0.3px;
|
||||
}
|
||||
|
||||
&.analytics-welcome-container--mode {
|
||||
border-radius: 20px;
|
||||
border: 1px solid var(--border-color);
|
||||
background:
|
||||
radial-gradient(circle at top, rgba(7, 193, 96, 0.06), transparent 48%),
|
||||
var(--bg-primary);
|
||||
.analytics-welcome-content p {
|
||||
color: var(--text-secondary);
|
||||
margin: 0 0 32px;
|
||||
font-size: 14px;
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
.analytics-welcome-actions {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.analytics-welcome-card {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 14px;
|
||||
padding: 16px 18px;
|
||||
background: var(--card-bg);
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 12px;
|
||||
cursor: pointer;
|
||||
text-align: left;
|
||||
color: var(--text-secondary);
|
||||
transition: background 0.15s ease, border-color 0.15s ease;
|
||||
|
||||
&:hover {
|
||||
background: var(--bg-hover);
|
||||
border-color: var(--text-tertiary);
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
.welcome-content {
|
||||
text-align: center;
|
||||
max-width: 600px;
|
||||
|
||||
.icon-wrapper {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
margin: 0 auto 24px;
|
||||
background: rgba(7, 193, 96, 0.1);
|
||||
border-radius: 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #07c160;
|
||||
|
||||
svg {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 28px;
|
||||
margin-bottom: 12px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
p {
|
||||
color: var(--text-secondary);
|
||||
margin-bottom: 40px;
|
||||
font-size: 16px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.action-cards {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 20px;
|
||||
margin-top: 20px;
|
||||
|
||||
button {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 30px 20px;
|
||||
background: var(--bg-secondary);
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 12px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
text-align: center;
|
||||
|
||||
&:hover:not(:disabled) {
|
||||
transform: translateY(-2px);
|
||||
border-color: #07c160;
|
||||
box-shadow: 0 4px 12px rgba(7, 193, 96, 0.1);
|
||||
|
||||
.card-icon {
|
||||
color: #07c160;
|
||||
background: rgba(7, 193, 96, 0.1);
|
||||
}
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
opacity: 0.6;
|
||||
cursor: not-allowed;
|
||||
filter: grayscale(100%);
|
||||
}
|
||||
|
||||
.card-icon {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
border-radius: 12px;
|
||||
background: var(--bg-tertiary);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 16px;
|
||||
color: var(--text-secondary);
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 18px;
|
||||
margin-bottom: 8px;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
span {
|
||||
font-size: 13px;
|
||||
color: var(--text-tertiary);
|
||||
}
|
||||
}
|
||||
}
|
||||
svg {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.analytics-welcome-container {
|
||||
padding: 28px 18px;
|
||||
.analytics-welcome-card-text {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2px;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.welcome-content {
|
||||
.action-cards {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
.analytics-welcome-card-title {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.analytics-welcome-card-meta {
|
||||
font-size: 12px;
|
||||
color: var(--text-tertiary);
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
@media (max-width: 540px) {
|
||||
.analytics-welcome-actions {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
@keyframes welcomeFadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(10px);
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
|
||||
@@ -6,12 +6,6 @@ import './AnalyticsWelcomePage.scss'
|
||||
|
||||
function AnalyticsWelcomePage() {
|
||||
const navigate = useNavigate()
|
||||
// 检查是否有任何缓存数据加载或基本的存储状态表明它已准备好。
|
||||
// 实际上,如果 store 没有持久化,`isLoaded` 可能会在应用刷新时重置。
|
||||
// 如果用户点击“加载缓存”但缓存为空,AnalyticsPage 的逻辑(loadData 不带 force)将尝试从后端缓存加载。
|
||||
// 如果后端缓存也为空,则会重新计算。
|
||||
|
||||
// 我们也可以检查 `lastLoadTime` 来显示“上次更新:xxx”(如果已持久化)。
|
||||
const { lastLoadTime } = useAnalyticsStore()
|
||||
|
||||
const handleLoadCache = () => {
|
||||
@@ -28,35 +22,37 @@ function AnalyticsWelcomePage() {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="analytics-entry-page">
|
||||
<div className="analytics-welcome-shell">
|
||||
<ChatAnalysisHeader currentMode="private" />
|
||||
|
||||
<div className="analytics-welcome-container analytics-welcome-container--mode">
|
||||
<div className="welcome-content">
|
||||
<div className="icon-wrapper">
|
||||
<BarChart2 size={40} />
|
||||
<div className="analytics-welcome-body">
|
||||
<div className="analytics-welcome-content">
|
||||
<div className="analytics-welcome-icon">
|
||||
<BarChart2 size={32} />
|
||||
</div>
|
||||
<h1>私聊数据分析</h1>
|
||||
<p>
|
||||
WeFlow 可以分析你的好友聊天记录,生成详细的统计报表。<br />
|
||||
你可以选择加载上次的分析结果,或者重新开始一次新的私聊分析。
|
||||
分析你的好友聊天记录,生成详细统计报表。<br />
|
||||
选择加载上次结果或开始新分析。
|
||||
</p>
|
||||
|
||||
<div className="action-cards">
|
||||
<button onClick={handleLoadCache}>
|
||||
<div className="card-icon">
|
||||
<History size={24} />
|
||||
<div className="analytics-welcome-actions">
|
||||
<button className="analytics-welcome-card" onClick={handleLoadCache} type="button">
|
||||
<History size={20} />
|
||||
<div className="analytics-welcome-card-text">
|
||||
<span className="analytics-welcome-card-title">加载缓存</span>
|
||||
<span className="analytics-welcome-card-meta">
|
||||
上次更新: {formatLastTime(lastLoadTime)}
|
||||
</span>
|
||||
</div>
|
||||
<h3>加载缓存</h3>
|
||||
<span>查看上次分析结果<br />(上次更新: {formatLastTime(lastLoadTime)})</span>
|
||||
</button>
|
||||
|
||||
<button onClick={handleNewAnalysis}>
|
||||
<div className="card-icon">
|
||||
<RefreshCcw size={24} />
|
||||
<button className="analytics-welcome-card" onClick={handleNewAnalysis} type="button">
|
||||
<RefreshCcw size={20} />
|
||||
<div className="analytics-welcome-card-text">
|
||||
<span className="analytics-welcome-card-title">新的分析</span>
|
||||
<span className="analytics-welcome-card-meta">重新扫描并计算数据</span>
|
||||
</div>
|
||||
<h3>新的分析</h3>
|
||||
<span>重新扫描并计算数据<br />(可能需要几分钟)</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.chat-analytics-hub-page {
|
||||
.analytics-hub {
|
||||
min-height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -6,118 +6,128 @@
|
||||
padding: 40px 24px;
|
||||
}
|
||||
|
||||
.chat-analytics-hub-content {
|
||||
width: min(860px, 100%);
|
||||
.analytics-hub-inner {
|
||||
width: min(720px, 100%);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
animation: analyticsHubFadeIn 0.4s ease-out;
|
||||
}
|
||||
|
||||
.chat-analytics-hub-badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 8px 14px;
|
||||
border-radius: 999px;
|
||||
background: var(--primary-light);
|
||||
color: var(--primary);
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.chat-analytics-hub-content h1 {
|
||||
margin: 20px 0 12px;
|
||||
font-size: 32px;
|
||||
line-height: 1.2;
|
||||
.analytics-hub-title {
|
||||
font-size: 28px;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
margin: 0 0 12px;
|
||||
letter-spacing: -0.5px;
|
||||
}
|
||||
|
||||
.chat-analytics-hub-desc {
|
||||
max-width: 620px;
|
||||
margin: 0 0 32px;
|
||||
.analytics-hub-desc {
|
||||
max-width: 520px;
|
||||
margin: 0 0 36px;
|
||||
color: var(--text-secondary);
|
||||
font-size: 15px;
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
.chat-analytics-hub-grid {
|
||||
.analytics-hub-grid {
|
||||
width: 100%;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
gap: 20px;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.chat-analytics-entry-card {
|
||||
.analytics-hub-card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
text-align: left;
|
||||
gap: 14px;
|
||||
min-height: 260px;
|
||||
padding: 28px;
|
||||
gap: 16px;
|
||||
padding: 24px;
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 20px;
|
||||
background:
|
||||
linear-gradient(180deg, rgba(7, 193, 96, 0.08) 0%, rgba(7, 193, 96, 0.02) 100%),
|
||||
var(--card-bg);
|
||||
border-radius: 12px;
|
||||
background: var(--card-bg);
|
||||
color: var(--text-primary);
|
||||
cursor: pointer;
|
||||
transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
|
||||
transition: background 0.15s ease, border-color 0.15s ease;
|
||||
|
||||
&:hover {
|
||||
transform: translateY(-4px);
|
||||
border-color: rgba(7, 193, 96, 0.35);
|
||||
box-shadow: 0 20px 36px rgba(7, 193, 96, 0.12);
|
||||
}
|
||||
background: var(--bg-hover);
|
||||
border-color: var(--text-tertiary);
|
||||
|
||||
.entry-card-icon {
|
||||
width: 52px;
|
||||
height: 52px;
|
||||
border-radius: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: rgba(7, 193, 96, 0.12);
|
||||
color: #07c160;
|
||||
|
||||
&.group {
|
||||
background: rgba(24, 119, 242, 0.12);
|
||||
color: #1877f2;
|
||||
.analytics-hub-card-arrow {
|
||||
transform: translateX(3px);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.entry-card-header {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
.analytics-hub-card-icon {
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
border-radius: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: var(--primary-light);
|
||||
color: var(--primary);
|
||||
|
||||
&--group {
|
||||
background: rgba(59, 130, 246, 0.1);
|
||||
color: #3b82f6;
|
||||
}
|
||||
}
|
||||
|
||||
[data-mode="dark"] .analytics-hub-card-icon--group {
|
||||
background: rgba(96, 165, 250, 0.12);
|
||||
color: #60a5fa;
|
||||
}
|
||||
|
||||
.analytics-hub-card-body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.analytics-hub-card-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
h2 {
|
||||
margin: 0;
|
||||
font-size: 24px;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
color: var(--text-secondary);
|
||||
font-size: 14px;
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
.entry-card-cta {
|
||||
margin-top: auto;
|
||||
color: var(--primary);
|
||||
font-size: 13px;
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
line-height: 1.2;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 900px) {
|
||||
.chat-analytics-hub-grid {
|
||||
.analytics-hub-card-arrow {
|
||||
color: var(--text-tertiary);
|
||||
transition: transform 0.15s ease;
|
||||
}
|
||||
|
||||
.analytics-hub-card-body p {
|
||||
margin: 0;
|
||||
color: var(--text-secondary);
|
||||
font-size: 13px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.analytics-hub-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes analyticsHubFadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(10px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ArrowRight, BarChart3, MessageSquare, Users } from 'lucide-react'
|
||||
import { ArrowRight, MessageSquare, Users } from 'lucide-react'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import './ChatAnalyticsHubPage.scss'
|
||||
|
||||
@@ -6,49 +6,46 @@ function ChatAnalyticsHubPage() {
|
||||
const navigate = useNavigate()
|
||||
|
||||
return (
|
||||
<div className="chat-analytics-hub-page">
|
||||
<div className="chat-analytics-hub-content">
|
||||
<div className="chat-analytics-hub-badge">
|
||||
<BarChart3 size={16} />
|
||||
<span>聊天分析</span>
|
||||
</div>
|
||||
|
||||
<h1>选择你要进入的分析视角</h1>
|
||||
<p className="chat-analytics-hub-desc">
|
||||
私聊分析更适合看好友聊天统计和趋势,群聊分析则用于查看群成员、发言排行和活跃时段。
|
||||
<div className="analytics-hub">
|
||||
<div className="analytics-hub-inner">
|
||||
<h1 className="analytics-hub-title">聊天分析</h1>
|
||||
<p className="analytics-hub-desc">
|
||||
选择你要进入的分析视角。私聊分析适合查看好友聊天统计,群聊分析则用于查看群成员活跃度。
|
||||
</p>
|
||||
|
||||
<div className="chat-analytics-hub-grid">
|
||||
<div className="analytics-hub-grid">
|
||||
<button
|
||||
type="button"
|
||||
className="chat-analytics-entry-card"
|
||||
className="analytics-hub-card"
|
||||
onClick={() => navigate('/analytics/private')}
|
||||
>
|
||||
<div className="entry-card-icon">
|
||||
<MessageSquare size={24} />
|
||||
<div className="analytics-hub-card-icon">
|
||||
<MessageSquare size={22} />
|
||||
</div>
|
||||
<div className="entry-card-header">
|
||||
<h2>私聊分析</h2>
|
||||
<ArrowRight size={18} />
|
||||
<div className="analytics-hub-card-body">
|
||||
<div className="analytics-hub-card-header">
|
||||
<h2>私聊分析</h2>
|
||||
<ArrowRight size={16} className="analytics-hub-card-arrow" />
|
||||
</div>
|
||||
<p>查看好友聊天统计、消息趋势、活跃时段与联系人排名。</p>
|
||||
</div>
|
||||
<p>查看好友聊天统计、消息趋势、活跃时段与联系人排名。</p>
|
||||
<span className="entry-card-cta">进入私聊分析</span>
|
||||
</button>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
className="chat-analytics-entry-card"
|
||||
className="analytics-hub-card"
|
||||
onClick={() => navigate('/analytics/group')}
|
||||
>
|
||||
<div className="entry-card-icon group">
|
||||
<Users size={24} />
|
||||
<div className="analytics-hub-card-icon analytics-hub-card-icon--group">
|
||||
<Users size={22} />
|
||||
</div>
|
||||
<div className="entry-card-header">
|
||||
<h2>群聊分析</h2>
|
||||
<ArrowRight size={18} />
|
||||
<div className="analytics-hub-card-body">
|
||||
<div className="analytics-hub-card-header">
|
||||
<h2>群聊分析</h2>
|
||||
<ArrowRight size={16} className="analytics-hub-card-arrow" />
|
||||
</div>
|
||||
<p>查看群成员信息、发言排行、活跃时段和媒体内容统计。</p>
|
||||
</div>
|
||||
<p>查看群成员信息、发言排行、活跃时段和媒体内容统计。</p>
|
||||
<span className="entry-card-cta">进入群聊分析</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
.home-page {
|
||||
height: 100%;
|
||||
background: var(--bg-primary);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
@@ -8,105 +7,94 @@
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.home-bg-blobs {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
filter: blur(80px);
|
||||
z-index: 0;
|
||||
opacity: 0.6;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.blob {
|
||||
position: absolute;
|
||||
border-radius: 50%;
|
||||
animation: moveBlob 20s infinite alternate ease-in-out;
|
||||
}
|
||||
|
||||
.blob-1 {
|
||||
width: 400px;
|
||||
height: 400px;
|
||||
background: rgba(var(--primary-rgb), 0.25);
|
||||
top: -100px;
|
||||
left: -50px;
|
||||
animation-duration: 25s;
|
||||
}
|
||||
|
||||
.blob-2 {
|
||||
width: 350px;
|
||||
height: 350px;
|
||||
background: rgba(var(--primary-rgb), 0.15);
|
||||
bottom: -50px;
|
||||
right: -50px;
|
||||
animation-duration: 30s;
|
||||
animation-delay: -5s;
|
||||
}
|
||||
|
||||
.blob-3 {
|
||||
width: 300px;
|
||||
height: 300px;
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
top: 40%;
|
||||
left: 30%;
|
||||
animation-duration: 22s;
|
||||
animation-delay: -10s;
|
||||
}
|
||||
|
||||
[data-mode="dark"] .blob-3 {
|
||||
background: rgba(255, 255, 255, 0.03);
|
||||
}
|
||||
|
||||
.home-content {
|
||||
z-index: 1;
|
||||
animation: fadeScaleUp 1s cubic-bezier(0.2, 0.8, 0.2, 1);
|
||||
}
|
||||
|
||||
.hero {
|
||||
text-align: center;
|
||||
max-width: 640px;
|
||||
width: 100%;
|
||||
padding: 0 24px;
|
||||
animation: homeFadeIn 0.5s ease-out;
|
||||
}
|
||||
|
||||
.hero-title {
|
||||
font-size: 64px;
|
||||
font-weight: 800;
|
||||
margin: 0 0 16px;
|
||||
.home-title {
|
||||
font-size: 48px;
|
||||
font-weight: 700;
|
||||
margin: 0 0 12px;
|
||||
color: var(--text-primary);
|
||||
letter-spacing: -2px;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, rgba(var(--primary-rgb), 0.6) 100%);
|
||||
background-clip: text;
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
letter-spacing: -1.5px;
|
||||
}
|
||||
|
||||
.hero-subtitle {
|
||||
font-size: 18px;
|
||||
.home-subtitle {
|
||||
font-size: 16px;
|
||||
color: var(--text-secondary);
|
||||
max-width: 520px;
|
||||
margin: 0 auto;
|
||||
margin: 0 0 48px;
|
||||
line-height: 1.6;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
@keyframes moveBlob {
|
||||
from {
|
||||
transform: translate(0, 0) scale(1);
|
||||
.home-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.home-feature-card {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 14px;
|
||||
padding: 16px 18px;
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 12px;
|
||||
background: var(--card-bg);
|
||||
cursor: pointer;
|
||||
text-align: left;
|
||||
transition: background 0.15s ease, border-color 0.15s ease;
|
||||
color: var(--text-secondary);
|
||||
|
||||
&:hover {
|
||||
background: var(--bg-hover);
|
||||
border-color: var(--text-tertiary);
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
to {
|
||||
transform: translate(100px, 50px) scale(1.1);
|
||||
svg {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fadeScaleUp {
|
||||
.home-feature-text {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2px;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.home-feature-label {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.home-feature-desc {
|
||||
font-size: 12px;
|
||||
color: var(--text-tertiary);
|
||||
}
|
||||
|
||||
@keyframes homeFadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: scale(0.95) translateY(20px);
|
||||
transform: translateY(12px);
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: scale(1) translateY(0);
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.home-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.home-title {
|
||||
font-size: 36px;
|
||||
}
|
||||
}
|
||||
@@ -1,20 +1,40 @@
|
||||
import { FolderOpen, ShieldCheck, Sparkles, Waves } from 'lucide-react'
|
||||
import { useAppStore } from '../stores/appStore'
|
||||
import { MessageSquare, BarChart3, Download, Aperture, Footprints, FolderClosed } from 'lucide-react'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import './HomePage.scss'
|
||||
|
||||
function HomePage() {
|
||||
const navigate = useNavigate()
|
||||
|
||||
const features = [
|
||||
{ icon: MessageSquare, label: '聊天', desc: '浏览聊天记录', path: '/chat' },
|
||||
{ icon: Aperture, label: '朋友圈', desc: '查看朋友圈动态', path: '/sns' },
|
||||
{ icon: BarChart3, label: '聊天分析', desc: '分析聊天统计数据', path: '/analytics' },
|
||||
{ icon: FolderClosed, label: '资源浏览', desc: '管理媒体文件', path: '/resources' },
|
||||
{ icon: Footprints, label: '我的足迹', desc: '回顾你的轨迹', path: '/footprint' },
|
||||
{ icon: Download, label: '导出', desc: '导出聊天记录', path: '/export' },
|
||||
]
|
||||
|
||||
return (
|
||||
<div className="home-page">
|
||||
<div className="home-bg-blobs">
|
||||
<div className="blob blob-1"></div>
|
||||
<div className="blob blob-2"></div>
|
||||
<div className="blob blob-3"></div>
|
||||
</div>
|
||||
|
||||
<div className="home-content">
|
||||
<div className="hero">
|
||||
<h1 className="hero-title">WeFlow</h1>
|
||||
<p className="hero-subtitle">每一条消息的背后,都藏着一段温暖的时光</p>
|
||||
<h1 className="home-title">WeFlow</h1>
|
||||
<p className="home-subtitle">每一条消息的背后,都藏着一段温暖的时光</p>
|
||||
|
||||
<div className="home-grid">
|
||||
{features.map((f) => (
|
||||
<button
|
||||
key={f.path}
|
||||
className="home-feature-card"
|
||||
onClick={() => navigate(f.path)}
|
||||
type="button"
|
||||
>
|
||||
<f.icon size={20} />
|
||||
<div className="home-feature-text">
|
||||
<span className="home-feature-label">{f.label}</span>
|
||||
<span className="home-feature-desc">{f.desc}</span>
|
||||
</div>
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,400 +1,106 @@
|
||||
// CSS 变量 - 主题
|
||||
// WeFlow — ChatGPT-inspired design token system
|
||||
// Only light/dark/system modes. No per-theme variants.
|
||||
// All legacy variable names preserved for backward compatibility.
|
||||
@use './chat-patterns.scss';
|
||||
|
||||
:root {
|
||||
// 颜色
|
||||
--primary: #8B7355;
|
||||
--primary-hover: #7A6548;
|
||||
--primary-light: rgba(139, 115, 85, 0.1);
|
||||
--danger: #dc3545;
|
||||
--warning: #ffc107;
|
||||
// =============================================
|
||||
// Light mode (default)
|
||||
// =============================================
|
||||
:root,
|
||||
[data-mode="light"] {
|
||||
// ---- Accent / Brand ----
|
||||
--primary: #10a37f;
|
||||
--primary-rgb: 16, 163, 127;
|
||||
--primary-hover: #0d8a6c;
|
||||
--primary-light: rgba(16, 163, 127, 0.1);
|
||||
--primary-gradient: linear-gradient(135deg, #10a37f 0%, #1ab893 100%);
|
||||
|
||||
// 背景
|
||||
--bg-primary: #F0EEE9;
|
||||
--bg-secondary: rgba(255, 255, 255, 0.7);
|
||||
--bg-tertiary: rgba(0, 0, 0, 0.03);
|
||||
--bg-hover: rgba(0, 0, 0, 0.05);
|
||||
--danger: #ef4444;
|
||||
--warning: #f59e0b;
|
||||
|
||||
// 文字
|
||||
--text-primary: #3d3d3d;
|
||||
--text-secondary: #666666;
|
||||
--text-tertiary: #999999;
|
||||
|
||||
// 边框
|
||||
--border-color: rgba(0, 0, 0, 0.08);
|
||||
--border-radius: 9999px;
|
||||
|
||||
// 阴影
|
||||
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
|
||||
--shadow-md: 0 4px 12px rgba(0, 0, 0, 0.08);
|
||||
|
||||
// 侧边栏
|
||||
--sidebar-width: 220px;
|
||||
|
||||
// 主题渐变
|
||||
--bg-gradient: linear-gradient(135deg, #F0EEE9 0%, #E8E6E1 100%);
|
||||
--primary-gradient: linear-gradient(135deg, #8B7355 0%, #A68B5B 100%);
|
||||
|
||||
// 卡片背景
|
||||
--card-bg: rgba(255, 255, 255, 0.7);
|
||||
--card-inner-bg: #FAFAF7;
|
||||
--sent-card-bg: var(--primary);
|
||||
|
||||
// primary 色上方的前景文字色(大多数主题为白色)
|
||||
--on-primary: white;
|
||||
}
|
||||
|
||||
// ==================== 浅色主题 ====================
|
||||
|
||||
// 云上舞白主题 (默认)
|
||||
[data-theme="cloud-dancer"][data-mode="light"],
|
||||
[data-theme="cloud-dancer"]:not([data-mode]) {
|
||||
--primary: #8B7355;
|
||||
--primary-rgb: 139, 115, 85;
|
||||
--primary-hover: #7A6548;
|
||||
--primary-light: rgba(139, 115, 85, 0.1);
|
||||
--bg-primary: #F0EEE9;
|
||||
--bg-secondary: rgba(255, 255, 255, 0.7);
|
||||
--bg-tertiary: rgba(0, 0, 0, 0.03);
|
||||
--bg-hover: rgba(0, 0, 0, 0.05);
|
||||
--text-primary: #3d3d3d;
|
||||
--text-secondary: #666666;
|
||||
--text-tertiary: #999999;
|
||||
--border-color: rgba(0, 0, 0, 0.08);
|
||||
--bg-gradient: linear-gradient(135deg, #F0EEE9 0%, #E8E6E1 100%);
|
||||
--primary-gradient: linear-gradient(135deg, #8B7355 0%, #A68B5B 100%);
|
||||
--card-bg: rgba(255, 255, 255, 0.7);
|
||||
--card-inner-bg: #FAFAF7;
|
||||
--sent-card-bg: var(--primary);
|
||||
}
|
||||
|
||||
// 刚玉蓝主题
|
||||
[data-theme="corundum-blue"][data-mode="light"],
|
||||
[data-theme="corundum-blue"]:not([data-mode]) {
|
||||
--primary: #4A6670;
|
||||
--primary-rgb: 74, 102, 112;
|
||||
--primary-hover: #3D565E;
|
||||
--primary-light: rgba(74, 102, 112, 0.1);
|
||||
--bg-primary: #E8EEF0;
|
||||
--bg-secondary: rgba(255, 255, 255, 0.7);
|
||||
--bg-tertiary: rgba(0, 0, 0, 0.03);
|
||||
--bg-hover: rgba(0, 0, 0, 0.05);
|
||||
--text-primary: #3d3d3d;
|
||||
--text-secondary: #666666;
|
||||
--text-tertiary: #999999;
|
||||
--border-color: rgba(0, 0, 0, 0.08);
|
||||
--bg-gradient: linear-gradient(135deg, #E8EEF0 0%, #D8E4E8 100%);
|
||||
--primary-gradient: linear-gradient(135deg, #4A6670 0%, #5A7A86 100%);
|
||||
--card-bg: rgba(255, 255, 255, 0.7);
|
||||
--card-inner-bg: #F8FAFB;
|
||||
--sent-card-bg: var(--primary);
|
||||
}
|
||||
|
||||
// 冰猕猴桃汁绿主题
|
||||
[data-theme="kiwi-green"][data-mode="light"],
|
||||
[data-theme="kiwi-green"]:not([data-mode]) {
|
||||
--primary: #7A9A5C;
|
||||
--primary-rgb: 122, 154, 92;
|
||||
--primary-hover: #6A8A4C;
|
||||
--primary-light: rgba(122, 154, 92, 0.1);
|
||||
--bg-primary: #E8F0E4;
|
||||
--bg-secondary: rgba(255, 255, 255, 0.7);
|
||||
--bg-tertiary: rgba(0, 0, 0, 0.03);
|
||||
--bg-hover: rgba(0, 0, 0, 0.05);
|
||||
--text-primary: #3d3d3d;
|
||||
--text-secondary: #666666;
|
||||
--text-tertiary: #999999;
|
||||
--border-color: rgba(0, 0, 0, 0.08);
|
||||
--bg-gradient: linear-gradient(135deg, #E8F0E4 0%, #D8E8D0 100%);
|
||||
--primary-gradient: linear-gradient(135deg, #7A9A5C 0%, #8AAA6C 100%);
|
||||
--card-bg: rgba(255, 255, 255, 0.7);
|
||||
--card-inner-bg: #F8FBF6;
|
||||
--sent-card-bg: var(--primary);
|
||||
}
|
||||
|
||||
// 辛辣红主题
|
||||
[data-theme="spicy-red"][data-mode="light"],
|
||||
[data-theme="spicy-red"]:not([data-mode]) {
|
||||
--primary: #8B4049;
|
||||
--primary-rgb: 139, 64, 73;
|
||||
--primary-hover: #7A3540;
|
||||
--primary-light: rgba(139, 64, 73, 0.1);
|
||||
--bg-primary: #F0E8E8;
|
||||
--bg-secondary: rgba(255, 255, 255, 0.7);
|
||||
--bg-tertiary: rgba(0, 0, 0, 0.03);
|
||||
--bg-hover: rgba(0, 0, 0, 0.05);
|
||||
--text-primary: #3d3d3d;
|
||||
--text-secondary: #666666;
|
||||
--text-tertiary: #999999;
|
||||
--border-color: rgba(0, 0, 0, 0.08);
|
||||
--bg-gradient: linear-gradient(135deg, #F0E8E8 0%, #E8D8D8 100%);
|
||||
--primary-gradient: linear-gradient(135deg, #8B4049 0%, #A05058 100%);
|
||||
--card-bg: rgba(255, 255, 255, 0.7);
|
||||
--card-inner-bg: #FAF8F8;
|
||||
--sent-card-bg: var(--primary);
|
||||
}
|
||||
|
||||
// 明水鸭色主题
|
||||
[data-theme="teal-water"][data-mode="light"],
|
||||
[data-theme="teal-water"]:not([data-mode]) {
|
||||
--primary: #5A8A8A;
|
||||
--primary-rgb: 90, 138, 138;
|
||||
--primary-hover: #4A7A7A;
|
||||
--primary-light: rgba(90, 138, 138, 0.1);
|
||||
--bg-primary: #E4F0F0;
|
||||
--bg-secondary: rgba(255, 255, 255, 0.7);
|
||||
--bg-tertiary: rgba(0, 0, 0, 0.03);
|
||||
--bg-hover: rgba(0, 0, 0, 0.05);
|
||||
--text-primary: #3d3d3d;
|
||||
--text-secondary: #666666;
|
||||
--text-tertiary: #999999;
|
||||
--border-color: rgba(0, 0, 0, 0.08);
|
||||
--bg-gradient: linear-gradient(135deg, #E4F0F0 0%, #D4E8E8 100%);
|
||||
--primary-gradient: linear-gradient(135deg, #5A8A8A 0%, #6A9A9A 100%);
|
||||
--card-bg: rgba(255, 255, 255, 0.7);
|
||||
--card-inner-bg: #F6FBFB;
|
||||
--sent-card-bg: var(--primary);
|
||||
}
|
||||
|
||||
// 繁花如梦 - 浅色(晨曦花境)
|
||||
[data-theme="blossom-dream"][data-mode="light"],
|
||||
[data-theme="blossom-dream"]:not([data-mode]) {
|
||||
// 三色定义(供伪元素光晕使用,饱和度提高以便在底色上可见)
|
||||
--blossom-pink: #F0A0B8;
|
||||
--blossom-peach: #FFB07A;
|
||||
--blossom-blue: #90B8E0;
|
||||
|
||||
// 主品牌色:Pantone 粉晶 Rose Quartz
|
||||
--primary: #D4849A;
|
||||
--primary-rgb: 212, 132, 154;
|
||||
--primary-hover: #C4748A;
|
||||
--primary-light: rgba(212, 132, 154, 0.12);
|
||||
|
||||
// 背景三层:主背景最深(相对),面板次之,卡片最白
|
||||
--bg-primary: #F5EDF2;
|
||||
--bg-secondary: rgba(255, 255, 255, 0.82);
|
||||
--bg-tertiary: rgba(212, 132, 154, 0.06);
|
||||
--bg-hover: rgba(212, 132, 154, 0.09);
|
||||
|
||||
// 文字:提高对比度,主色接近纯黑只带微弱紫调
|
||||
--text-primary: #1E1A22;
|
||||
--text-secondary: #6B5F70;
|
||||
--text-tertiary: #9A8A9E;
|
||||
// 边框:粉色半透明,有存在感但不强硬
|
||||
--border-color: rgba(212, 132, 154, 0.18);
|
||||
|
||||
--bg-gradient: linear-gradient(150deg, #F5EDF2 0%, #F0EAF6 50%, #EAF0F8 100%);
|
||||
--primary-gradient: linear-gradient(135deg, #D4849A 0%, #E8A8B8 100%);
|
||||
|
||||
// 卡片:高不透明度白,与背景形成明显层次
|
||||
--card-bg: rgba(255, 255, 255, 0.88);
|
||||
--card-inner-bg: rgba(255, 255, 255, 0.95);
|
||||
|
||||
--sent-card-bg: var(--primary);
|
||||
}
|
||||
|
||||
// Geist · 极简黑白 - 浅色
|
||||
[data-theme="geist"][data-mode="light"],
|
||||
[data-theme="geist"]:not([data-mode]) {
|
||||
--primary: #444444;
|
||||
--primary-rgb: 68, 68, 68;
|
||||
--primary-hover: #333333;
|
||||
--primary-light: rgba(68, 68, 68, 0.08);
|
||||
// ---- Backgrounds ----
|
||||
--bg-primary: #ffffff;
|
||||
--bg-secondary: rgba(250, 250, 250, 0.95);
|
||||
--bg-tertiary: rgba(0, 0, 0, 0.03);
|
||||
--bg-hover: rgba(0, 0, 0, 0.05);
|
||||
--text-primary: #111111;
|
||||
--text-secondary: #666666;
|
||||
--text-tertiary: #999999;
|
||||
--border-color: #eaeaea;
|
||||
--border-radius: 6px;
|
||||
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.08);
|
||||
--shadow-md: 0 4px 12px rgba(0, 0, 0, 0.12);
|
||||
--bg-gradient: linear-gradient(135deg, #ffffff 0%, #fafafa 100%);
|
||||
--primary-gradient: linear-gradient(135deg, #444444 0%, #666666 100%);
|
||||
--card-bg: rgba(250, 250, 250, 0.95);
|
||||
--card-inner-bg: #f5f5f5;
|
||||
--sent-card-bg: #444444;
|
||||
}
|
||||
--bg-secondary: #f9f9f9;
|
||||
--bg-secondary-solid: #f9f9f9;
|
||||
--bg-tertiary: #f0f0f0;
|
||||
--bg-hover: #ececec;
|
||||
--bg-sidebar: #f9f9f9;
|
||||
--bg-gradient: linear-gradient(180deg, #ffffff 0%, #f7f7f8 100%);
|
||||
|
||||
// ==================== 深色主题 ====================
|
||||
// ---- Text ----
|
||||
--text-primary: #0d0d0d;
|
||||
--text-secondary: #6e6e80;
|
||||
--text-tertiary: #8e8ea0;
|
||||
|
||||
// 云上舞白 - 深色
|
||||
[data-theme="cloud-dancer"][data-mode="dark"] {
|
||||
--primary: #C9A86C;
|
||||
--primary-rgb: 201, 168, 108;
|
||||
--primary-hover: #D9B87C;
|
||||
--primary-light: rgba(201, 168, 108, 0.15);
|
||||
--bg-primary: #1a1816;
|
||||
--bg-secondary: rgba(40, 36, 32, 0.9);
|
||||
--bg-secondary-solid: #282420;
|
||||
--bg-tertiary: rgba(255, 255, 255, 0.05);
|
||||
--bg-hover: rgba(255, 255, 255, 0.08);
|
||||
--text-primary: #F0EEE9;
|
||||
--text-secondary: #b3b0aa;
|
||||
--text-tertiary: #807d78;
|
||||
--border-color: rgba(255, 255, 255, 0.1);
|
||||
--bg-gradient: linear-gradient(135deg, #1a1816 0%, #252220 100%);
|
||||
--primary-gradient: linear-gradient(135deg, #8B7355 0%, #C9A86C 100%);
|
||||
--card-bg: rgba(40, 36, 32, 0.9);
|
||||
--card-inner-bg: #27231F;
|
||||
// ---- Borders ----
|
||||
--border-color: rgba(0, 0, 0, 0.08);
|
||||
--border-radius: 12px;
|
||||
|
||||
// ---- Shadows ----
|
||||
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.04);
|
||||
--shadow-md: 0 4px 12px rgba(0, 0, 0, 0.06);
|
||||
|
||||
// ---- Cards ----
|
||||
--card-bg: #f7f7f8;
|
||||
--card-inner-bg: #ffffff;
|
||||
--sent-card-bg: var(--primary);
|
||||
|
||||
// ---- On-primary foreground ----
|
||||
--on-primary: #ffffff;
|
||||
|
||||
// ---- Layout ----
|
||||
--sidebar-width: 260px;
|
||||
}
|
||||
|
||||
// 刚玉蓝 - 深色
|
||||
[data-theme="corundum-blue"][data-mode="dark"] {
|
||||
--primary: #6A9AAA;
|
||||
--primary-rgb: 106, 154, 170;
|
||||
--primary-hover: #7AAABA;
|
||||
--primary-light: rgba(106, 154, 170, 0.15);
|
||||
--bg-primary: #141a1c;
|
||||
--bg-secondary: rgba(30, 40, 44, 0.9);
|
||||
--bg-secondary-solid: #1e282c;
|
||||
--bg-tertiary: rgba(255, 255, 255, 0.05);
|
||||
--bg-hover: rgba(255, 255, 255, 0.08);
|
||||
--text-primary: #E8EEF0;
|
||||
--text-secondary: #a8b4b8;
|
||||
--text-tertiary: #6a7a80;
|
||||
--border-color: rgba(255, 255, 255, 0.1);
|
||||
--bg-gradient: linear-gradient(135deg, #141a1c 0%, #1e282c 100%);
|
||||
--primary-gradient: linear-gradient(135deg, #4A6670 0%, #6A9AAA 100%);
|
||||
--card-bg: rgba(30, 40, 44, 0.9);
|
||||
--card-inner-bg: #1D272A;
|
||||
// =============================================
|
||||
// Dark mode
|
||||
// =============================================
|
||||
[data-mode="dark"] {
|
||||
// ---- Accent / Brand ----
|
||||
--primary: #10a37f;
|
||||
--primary-rgb: 16, 163, 127;
|
||||
--primary-hover: #1ab893;
|
||||
--primary-light: rgba(16, 163, 127, 0.15);
|
||||
--primary-gradient: linear-gradient(135deg, #10a37f 0%, #1ab893 100%);
|
||||
|
||||
--danger: #f87171;
|
||||
--warning: #fbbf24;
|
||||
|
||||
// ---- Backgrounds ----
|
||||
--bg-primary: #212121;
|
||||
--bg-secondary: #2f2f2f;
|
||||
--bg-secondary-solid: #2f2f2f;
|
||||
--bg-tertiary: #383838;
|
||||
--bg-hover: #383838;
|
||||
--bg-sidebar: #171717;
|
||||
--bg-gradient: linear-gradient(180deg, #212121 0%, #1a1a1a 100%);
|
||||
|
||||
// ---- Text ----
|
||||
--text-primary: #ececec;
|
||||
--text-secondary: #b4b4b4;
|
||||
--text-tertiary: #676767;
|
||||
|
||||
// ---- Borders ----
|
||||
--border-color: rgba(255, 255, 255, 0.08);
|
||||
|
||||
// ---- Shadows ----
|
||||
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.3);
|
||||
--shadow-md: 0 4px 12px rgba(0, 0, 0, 0.4);
|
||||
|
||||
// ---- Cards ----
|
||||
--card-bg: #2f2f2f;
|
||||
--card-inner-bg: #353535;
|
||||
--sent-card-bg: var(--primary);
|
||||
|
||||
// ---- On-primary foreground ----
|
||||
--on-primary: #ffffff;
|
||||
|
||||
--primary-gradient: linear-gradient(135deg, #10a37f 0%, #1ab893 100%);
|
||||
}
|
||||
|
||||
// 冰猕猴桃汁绿 - 深色
|
||||
[data-theme="kiwi-green"][data-mode="dark"] {
|
||||
--primary: #9ABA7C;
|
||||
--primary-rgb: 154, 186, 124;
|
||||
--primary-hover: #AACA8C;
|
||||
--primary-light: rgba(154, 186, 124, 0.15);
|
||||
--bg-primary: #161a14;
|
||||
--bg-secondary: rgba(34, 42, 30, 0.9);
|
||||
--bg-secondary-solid: #222a1e;
|
||||
--bg-tertiary: rgba(255, 255, 255, 0.05);
|
||||
--bg-hover: rgba(255, 255, 255, 0.08);
|
||||
--text-primary: #E8F0E4;
|
||||
--text-secondary: #a8b4a0;
|
||||
--text-tertiary: #6a7a60;
|
||||
--border-color: rgba(255, 255, 255, 0.1);
|
||||
--bg-gradient: linear-gradient(135deg, #161a14 0%, #222a1e 100%);
|
||||
--primary-gradient: linear-gradient(135deg, #7A9A5C 0%, #9ABA7C 100%);
|
||||
--card-bg: rgba(34, 42, 30, 0.9);
|
||||
--card-inner-bg: #21281D;
|
||||
--sent-card-bg: var(--primary);
|
||||
}
|
||||
|
||||
// 辛辣红 - 深色
|
||||
[data-theme="spicy-red"][data-mode="dark"] {
|
||||
--primary: #C06068;
|
||||
--primary-rgb: 192, 96, 104;
|
||||
--primary-hover: #D07078;
|
||||
--primary-light: rgba(192, 96, 104, 0.15);
|
||||
--bg-primary: #1a1416;
|
||||
--bg-secondary: rgba(42, 32, 34, 0.9);
|
||||
--bg-secondary-solid: #2a2022;
|
||||
--bg-tertiary: rgba(255, 255, 255, 0.05);
|
||||
--bg-hover: rgba(255, 255, 255, 0.08);
|
||||
--text-primary: #F0E8E8;
|
||||
--text-secondary: #b4a8aa;
|
||||
--text-tertiary: #7a6a6c;
|
||||
--border-color: rgba(255, 255, 255, 0.1);
|
||||
--bg-gradient: linear-gradient(135deg, #1a1416 0%, #2a2022 100%);
|
||||
--primary-gradient: linear-gradient(135deg, #8B4049 0%, #C06068 100%);
|
||||
--card-bg: rgba(42, 32, 34, 0.9);
|
||||
--card-inner-bg: #281F21;
|
||||
--sent-card-bg: var(--primary);
|
||||
}
|
||||
|
||||
// 明水鸭色 - 深色
|
||||
[data-theme="teal-water"][data-mode="dark"] {
|
||||
--primary: #7ABAAA;
|
||||
--primary-rgb: 122, 186, 170;
|
||||
--primary-hover: #8ACABA;
|
||||
--primary-light: rgba(122, 186, 170, 0.15);
|
||||
--bg-primary: #121a1a;
|
||||
--bg-secondary: rgba(28, 42, 42, 0.9);
|
||||
--bg-secondary-solid: #1c2a2a;
|
||||
--bg-tertiary: rgba(255, 255, 255, 0.05);
|
||||
--bg-hover: rgba(255, 255, 255, 0.08);
|
||||
--text-primary: #E4F0F0;
|
||||
--text-secondary: #a0b4b4;
|
||||
--text-tertiary: #607a7a;
|
||||
--border-color: rgba(255, 255, 255, 0.1);
|
||||
--bg-gradient: linear-gradient(135deg, #121a1a 0%, #1c2a2a 100%);
|
||||
--primary-gradient: linear-gradient(135deg, #5A8A8A 0%, #7ABAAA 100%);
|
||||
--card-bg: rgba(28, 42, 42, 0.9);
|
||||
--card-inner-bg: #1B2828;
|
||||
--sent-card-bg: var(--primary);
|
||||
}
|
||||
|
||||
// 繁花如梦 - 深色(夜阑幽梦)
|
||||
[data-theme="blossom-dream"][data-mode="dark"] {
|
||||
// 光晕色(供伪元素使用,降低饱和度避免刺眼)
|
||||
--blossom-pink: #C670C3;
|
||||
--blossom-purple: #5F4B8B;
|
||||
--blossom-blue: #3A2A50;
|
||||
|
||||
// 主品牌色:藕粉/烟紫粉,降饱和度不刺眼
|
||||
--primary: #D19EBB;
|
||||
--primary-rgb: 209, 158, 187;
|
||||
--primary-hover: #DDB0C8;
|
||||
--primary-light: rgba(209, 158, 187, 0.15);
|
||||
|
||||
// 背景三层:极深黑灰底(去掉紫薯色),面板略浅,卡片再浅一级
|
||||
--bg-primary: #151316;
|
||||
--bg-secondary: rgba(34, 30, 36, 0.92);
|
||||
--bg-secondary-solid: #221E24;
|
||||
--bg-tertiary: rgba(255, 255, 255, 0.04);
|
||||
--bg-hover: rgba(209, 158, 187, 0.1);
|
||||
|
||||
// 文字
|
||||
--text-primary: #F0EAF4;
|
||||
--text-secondary: #A898AE;
|
||||
--text-tertiary: #6A5870;
|
||||
// 边框:极细白色内发光,剥离层级
|
||||
--border-color: rgba(255, 255, 255, 0.07);
|
||||
|
||||
--bg-gradient: linear-gradient(150deg, #151316 0%, #1A1620 50%, #131018 100%);
|
||||
--primary-gradient: linear-gradient(135deg, #D19EBB 0%, #A878A8 100%);
|
||||
|
||||
// 卡片:比面板更亮一档,用深灰而非紫色
|
||||
--card-bg: rgba(42, 38, 46, 0.92);
|
||||
--card-inner-bg: rgba(52, 48, 56, 0.96);
|
||||
|
||||
--sent-card-bg: var(--primary);
|
||||
}
|
||||
|
||||
// Geist · 极简黑白 - 深色
|
||||
[data-theme="geist"][data-mode="dark"] {
|
||||
--primary: #ededed;
|
||||
--primary-rgb: 237, 237, 237;
|
||||
--primary-hover: #d5d5d5;
|
||||
--primary-light: rgba(237, 237, 237, 0.1);
|
||||
--bg-primary: #1a1a1a;
|
||||
--bg-secondary: rgba(34, 34, 34, 0.95);
|
||||
--bg-secondary-solid: #222222;
|
||||
--bg-tertiary: rgba(255, 255, 255, 0.04);
|
||||
--bg-hover: rgba(255, 255, 255, 0.07);
|
||||
--text-primary: #ededed;
|
||||
--text-secondary: #999999;
|
||||
--text-tertiary: #666666;
|
||||
--border-color: #2e2e2e;
|
||||
--border-radius: 6px;
|
||||
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
|
||||
--shadow-md: 0 4px 16px rgba(0, 0, 0, 0.5);
|
||||
--bg-gradient: linear-gradient(135deg, #1a1a1a 0%, #222222 100%);
|
||||
--primary-gradient: linear-gradient(135deg, #ededed 0%, #cccccc 100%);
|
||||
--card-bg: rgba(34, 34, 34, 0.95);
|
||||
--card-inner-bg: #2a2a2a;
|
||||
--sent-card-bg: #3a3a3a;
|
||||
// primary 是浅灰色,上方文字需要用深色
|
||||
--on-primary: #111111;
|
||||
}
|
||||
|
||||
// 重置样式
|
||||
// =============================================
|
||||
// Global reset
|
||||
// =============================================
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
@@ -412,12 +118,13 @@ body {
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
|
||||
#app {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
// 滚动条样式
|
||||
// =============================================
|
||||
// Scrollbar
|
||||
// =============================================
|
||||
::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
@@ -436,17 +143,21 @@ body {
|
||||
}
|
||||
}
|
||||
|
||||
// 按钮基础样式
|
||||
// =============================================
|
||||
// Button base
|
||||
// =============================================
|
||||
.btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 6px;
|
||||
padding: 8px 16px;
|
||||
border: none;
|
||||
border-radius: var(--border-radius);
|
||||
border-radius: 8px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
transition: background 0.15s ease, opacity 0.15s ease;
|
||||
|
||||
&-primary {
|
||||
background: var(--primary);
|
||||
@@ -455,6 +166,11 @@ body {
|
||||
&:hover {
|
||||
background: var(--primary-hover);
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
|
||||
&-secondary {
|
||||
@@ -462,20 +178,28 @@ body {
|
||||
color: var(--text-primary);
|
||||
|
||||
&:hover {
|
||||
background: var(--border-color);
|
||||
background: var(--bg-hover);
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 卡片样式
|
||||
// =============================================
|
||||
// Card base
|
||||
// =============================================
|
||||
.card {
|
||||
background: var(--bg-secondary);
|
||||
border-radius: 16px;
|
||||
box-shadow: var(--shadow-sm);
|
||||
background: var(--card-bg);
|
||||
border-radius: 12px;
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
// 全局 Switch 开关样式
|
||||
// =============================================
|
||||
// Switch toggle
|
||||
// =============================================
|
||||
.switch {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
@@ -525,7 +249,6 @@ body {
|
||||
}
|
||||
}
|
||||
|
||||
// 禁用状态
|
||||
input:disabled+.switch-slider {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
|
||||
Reference in New Issue
Block a user