diff --git a/frontend/assets/css/tailwind.css b/frontend/assets/css/tailwind.css index 8f5b90a..84a4645 100644 --- a/frontend/assets/css/tailwind.css +++ b/frontend/assets/css/tailwind.css @@ -264,8 +264,8 @@ /* CRT 闪烁 - 亮度波动 */ .crt-flicker { - background-color: rgba(255, 255, 255, 0.015); - animation: crt-flicker 0.08s infinite alternate; + background-color: rgba(255, 255, 255, 0.01); + animation: crt-flicker 0.15s infinite alternate; } /* CRT 暗角 - 边缘渐暗(更强) */ @@ -1113,7 +1113,7 @@ opacity: 1; } 50% { - opacity: 0.98; + opacity: 0.985; } } @@ -1149,7 +1149,7 @@ } /* ============================================ - Wrapped 三主题系统 - Game Boy / DOS / VHS + Wrapped 主题系统 - Game Boy / DOS ============================================ */ /* 复古模式共享基础样式 */ @@ -1225,7 +1225,10 @@ --wrapped-warning: #ffaa00; /* 琥珀警告色 */ background-color: #000000 !important; - font-family: 'Courier New', 'Consolas', monospace !important; + /* 使用现有 Fusion Pixel 10px 字体 */ + font-family: var(--font-pixel-10), 'Courier New', monospace !important; + -webkit-font-smoothing: none; + image-rendering: pixelated; } /* DOS 文字发光效果 */ @@ -1234,34 +1237,14 @@ .wrapped-theme-dos .wrapped-label, .wrapped-theme-dos .wrapped-number { color: #33ff33 !important; + /* 从 4 层减少到 2 层,降低发光强度 */ text-shadow: - 0 0 5px #33ff33, - 0 0 10px #33ff33, - 0 0 20px #33ff33, - 0 0 40px #22aa22; - font-family: 'Courier New', 'Consolas', monospace !important; + 0 0 4px rgba(51, 255, 51, 0.8), + 0 0 8px rgba(34, 170, 34, 0.4); + font-family: var(--font-pixel-10), 'Courier New', monospace !important; -webkit-font-smoothing: none; } -/* DOS 闪烁光标 */ -.wrapped-theme-dos::after { - content: '█'; - color: #33ff33; - animation: dos-cursor-blink 530ms steps(1) infinite; - position: fixed; - bottom: 20px; - right: 20px; - font-size: 1.5rem; - text-shadow: 0 0 10px #33ff33; - z-index: 100; - pointer-events: none; -} - -@keyframes dos-cursor-blink { - 0%, 50% { opacity: 1; } - 51%, 100% { opacity: 0; } -} - /* DOS ASCII 边框 */ .wrapped-theme-dos .wrapped-card-shell, .wrapped-theme-dos [class*="border"] { @@ -1277,16 +1260,16 @@ transition: text-shadow 0.1s ease-out !important; } -/* DOS 扫描线(更明显) */ +/* DOS 扫描线(细化) */ .wrapped-theme-dos .crt-scanlines { background: repeating-linear-gradient( to bottom, transparent 0px, - transparent 2px, - rgba(0, 0, 0, 0.4) 2px, - rgba(0, 0, 0, 0.4) 4px + transparent 1px, + rgba(0, 0, 0, 0.15) 1px, + rgba(0, 0, 0, 0.15) 2px ) !important; - opacity: 0.8; + opacity: 0.5; } /* DOS 按钮样式 */ @@ -1304,205 +1287,3 @@ color: #000000 !important; text-shadow: none; } - -/* ============================================ - Theme 3: VHS Tape - 色彩溢出与信号干扰 - ============================================ */ -.wrapped-theme-vhs { - --wrapped-bg: #1a1a2e; - --wrapped-card-bg: #16213e; - --wrapped-text: #eaeaea; - --wrapped-text-secondary: #a0a0a0; - --wrapped-accent: #e94560; - --wrapped-border: #0f3460; - --wrapped-warning: #f39c12; - - background-color: #1a1a2e !important; -} - -/* VHS 色彩溢出(Chromatic Aberration) */ -.wrapped-theme-vhs .wrapped-title, -.wrapped-theme-vhs .wrapped-number { - position: relative; - color: #eaeaea !important; -} - -.wrapped-theme-vhs .wrapped-title::before, -.wrapped-theme-vhs .wrapped-number::before { - content: attr(data-text); - position: absolute; - left: -2px; - top: 0; - color: #00fff7; - opacity: 0.7; - z-index: -1; - pointer-events: none; -} - -.wrapped-theme-vhs .wrapped-title::after, -.wrapped-theme-vhs .wrapped-number::after { - content: attr(data-text); - position: absolute; - left: 2px; - top: 0; - color: #ff00ff; - opacity: 0.7; - z-index: -1; - pointer-events: none; -} - -/* VHS 水平条纹滚动 */ -.wrapped-theme-vhs::before { - content: ''; - position: fixed; - top: 0; - left: 0; - right: 0; - bottom: 0; - background: repeating-linear-gradient( - to bottom, - transparent 0px, - transparent 4px, - rgba(255, 255, 255, 0.03) 4px, - rgba(255, 255, 255, 0.03) 8px - ); - animation: vhs-scanlines 8s linear infinite; - pointer-events: none; - z-index: 50; -} - -@keyframes vhs-scanlines { - 0% { transform: translateY(0); } - 100% { transform: translateY(100px); } -} - -/* VHS 信号干扰/故障动画 */ -.wrapped-theme-vhs .wrapped-card-shell { - animation: vhs-glitch 3s infinite; -} - -@keyframes vhs-glitch { - 0%, 95%, 100% { - transform: translate(0); - filter: none; - } - 96% { - transform: translate(-2px, 1px); - filter: hue-rotate(90deg); - } - 97% { - transform: translate(2px, -1px); - filter: hue-rotate(-90deg) saturate(1.5); - } - 98% { - transform: translate(-1px, 2px); - filter: brightness(1.2); - } - 99% { - transform: translate(1px, -2px); - filter: contrast(1.2); - } -} - -/* VHS 降低对比度和饱和度 */ -.wrapped-theme-vhs img, -.wrapped-theme-vhs svg { - filter: saturate(0.8) contrast(0.9); -} - -/* VHS 时间戳样式 */ -.wrapped-theme-vhs .vhs-timestamp { - position: fixed; - bottom: 20px; - right: 20px; - font-family: 'VCR OSD Mono', 'Courier New', monospace; - font-size: 1rem; - color: #ffffff; - background: rgba(0, 0, 0, 0.6); - padding: 4px 8px; - text-shadow: 2px 2px 0 #ff0000, -2px -2px 0 #00ffff; - z-index: 100; - pointer-events: none; -} - -/* VHS 跟踪线效果 */ -.wrapped-theme-vhs .vhs-tracking { - position: fixed; - left: 0; - right: 0; - height: 3px; - background: linear-gradient( - to right, - transparent 0%, - rgba(255, 255, 255, 0.8) 50%, - transparent 100% - ); - animation: vhs-tracking 2s ease-in-out infinite; - pointer-events: none; - z-index: 60; -} - -@keyframes vhs-tracking { - 0%, 100% { - top: -10px; - opacity: 0; - } - 10% { - opacity: 1; - } - 90% { - opacity: 1; - } - 95% { - top: calc(100vh + 10px); - opacity: 0; - } -} - -/* VHS 边框样式 */ -.wrapped-theme-vhs [class*="border"] { - border-color: #0f3460 !important; -} - -.wrapped-theme-vhs [class*="rounded"] { - border-radius: 2px !important; -} - -/* VHS 按钮样式 */ -.wrapped-theme-vhs button { - background: linear-gradient(135deg, #e94560 0%, #0f3460 100%) !important; - border: none !important; - color: #ffffff !important; - text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5); - box-shadow: 0 2px 10px rgba(233, 69, 96, 0.3); -} - -.wrapped-theme-vhs button:hover { - filter: brightness(1.1); - box-shadow: 0 4px 15px rgba(233, 69, 96, 0.5); -} - -/* VHS REC 指示器 */ -.wrapped-theme-vhs .vhs-rec { - position: fixed; - top: 20px; - left: 20px; - display: flex; - align-items: center; - gap: 8px; - font-family: 'VCR OSD Mono', 'Courier New', monospace; - font-size: 0.875rem; - color: #ff0000; - z-index: 100; - pointer-events: none; -} - -.wrapped-theme-vhs .vhs-rec::before { - content: '●'; - animation: vhs-rec-blink 1s steps(1) infinite; -} - -@keyframes vhs-rec-blink { - 0%, 50% { opacity: 1; } - 51%, 100% { opacity: 0; } -} diff --git a/frontend/components/wrapped/shared/WrappedCRTOverlay.vue b/frontend/components/wrapped/shared/WrappedCRTOverlay.vue index 7d43dae..40af685 100644 --- a/frontend/components/wrapped/shared/WrappedCRTOverlay.vue +++ b/frontend/components/wrapped/shared/WrappedCRTOverlay.vue @@ -1,62 +1,38 @@ -// VHS 时间戳(实时更新) -const vhsTimestamp = ref('') - -const updateTimestamp = () => { - const now = new Date() - const month = String(now.getMonth() + 1).padStart(2, '0') - const day = String(now.getDate()).padStart(2, '0') - const year = now.getFullYear() - const hours = String(now.getHours()).padStart(2, '0') - const minutes = String(now.getMinutes()).padStart(2, '0') - const seconds = String(now.getSeconds()).padStart(2, '0') - vhsTimestamp.value = `${month}/${day}/${year} ${hours}:${minutes}:${seconds}` + diff --git a/frontend/components/wrapped/shared/WrappedCardShell.vue b/frontend/components/wrapped/shared/WrappedCardShell.vue index 3e48474..d86256a 100644 --- a/frontend/components/wrapped/shared/WrappedCardShell.vue +++ b/frontend/components/wrapped/shared/WrappedCardShell.vue @@ -118,39 +118,4 @@ defineProps({ .wrapped-theme-dos .border-\[\#F3F3F3\] { border-color: #33ff33 !important; } - -/* ========== VHS 主题 ========== */ - -/* 卡片背景 */ -.wrapped-theme-vhs .bg-white { - background: #16213e !important; - border-color: #0f3460 !important; -} - -/* 标题 */ -.wrapped-theme-vhs .wrapped-title { - color: #eaeaea !important; - text-shadow: - -1px 0 rgba(0, 255, 247, 0.4), - 1px 0 rgba(255, 0, 255, 0.4); -} - -/* 描述文字 */ -.wrapped-theme-vhs .wrapped-body { - color: #a0a0a0 !important; -} - -/* 数字高亮 */ -.wrapped-theme-vhs .wrapped-number { - color: #e94560 !important; - text-shadow: - -1px 0 rgba(0, 255, 247, 0.5), - 1px 0 rgba(255, 0, 255, 0.5); -} - -/* 边框 */ -.wrapped-theme-vhs .border-\[\#EDEDED\], -.wrapped-theme-vhs .border-\[\#F3F3F3\] { - border-color: #0f3460 !important; -} diff --git a/frontend/components/wrapped/shared/WrappedControls.vue b/frontend/components/wrapped/shared/WrappedControls.vue index f62c58c..2dc4dbb 100644 --- a/frontend/components/wrapped/shared/WrappedControls.vue +++ b/frontend/components/wrapped/shared/WrappedControls.vue @@ -154,28 +154,4 @@ const yearOptions = computed(() => { .wrapped-theme-dos .controls-btn:hover:not(:disabled) { background-color: #44ff44; } - -/* VHS 特殊样式 */ -.wrapped-theme-vhs .controls-panel { - border-radius: 4px; - background: linear-gradient(180deg, #16213e 0%, #1a1a2e 100%); - border-color: #0f3460; -} - -.wrapped-theme-vhs .controls-select { - border-radius: 2px; - background: #1a1a2e; - border-color: #0f3460; - color: #eaeaea; -} - -.wrapped-theme-vhs .controls-btn { - border-radius: 4px; - background: linear-gradient(135deg, #e94560 0%, #0f3460 100%); - color: #ffffff; -} - -.wrapped-theme-vhs .controls-btn:hover:not(:disabled) { - box-shadow: 0 4px 15px rgba(233, 69, 96, 0.5); -} diff --git a/frontend/components/wrapped/shared/WrappedThemeSwitcher.vue b/frontend/components/wrapped/shared/WrappedThemeSwitcher.vue index bf31e6d..a142fcb 100644 --- a/frontend/components/wrapped/shared/WrappedThemeSwitcher.vue +++ b/frontend/components/wrapped/shared/WrappedThemeSwitcher.vue @@ -10,8 +10,7 @@ const themeSwitcherComponent = computed(() => { const map = { off: resolveComponent('WrappedThemeSwitcherModern'), gameboy: resolveComponent('WrappedThemeSwitcherGameboy'), - dos: resolveComponent('WrappedThemeSwitcherDos'), - vhs: resolveComponent('WrappedThemeSwitcherVhs') + dos: resolveComponent('WrappedThemeSwitcherDos') } return map[theme.value] || map.off }) diff --git a/frontend/components/wrapped/shared/WrappedThemeSwitcherDos.vue b/frontend/components/wrapped/shared/WrappedThemeSwitcherDos.vue index 9166ce4..545a93a 100644 --- a/frontend/components/wrapped/shared/WrappedThemeSwitcherDos.vue +++ b/frontend/components/wrapped/shared/WrappedThemeSwitcherDos.vue @@ -15,7 +15,7 @@
- Press F1-F4 to switch theme + Press F1-F3 to switch theme
@@ -26,8 +26,7 @@ const { theme, setTheme } = useWrappedTheme() const themes = [ { value: 'off', label: 'Modern' }, { value: 'gameboy', label: 'GameBoy' }, - { value: 'dos', label: 'DOS' }, - { value: 'vhs', label: 'VHS' } + { value: 'dos', label: 'DOS' } ] diff --git a/frontend/components/wrapped/shared/WrappedThemeSwitcherGameboy.vue b/frontend/components/wrapped/shared/WrappedThemeSwitcherGameboy.vue index c33798b..904f6c8 100644 --- a/frontend/components/wrapped/shared/WrappedThemeSwitcherGameboy.vue +++ b/frontend/components/wrapped/shared/WrappedThemeSwitcherGameboy.vue @@ -25,8 +25,7 @@ const { theme, setTheme } = useWrappedTheme() const themes = [ { value: 'off', label: 'MODERN' }, { value: 'gameboy', label: 'GAME BOY' }, - { value: 'dos', label: 'DOS' }, - { value: 'vhs', label: 'VHS' } + { value: 'dos', label: 'DOS' } ] const selectTheme = (value) => { diff --git a/frontend/components/wrapped/shared/WrappedThemeSwitcherModern.vue b/frontend/components/wrapped/shared/WrappedThemeSwitcherModern.vue index 52f401b..c65b74d 100644 --- a/frontend/components/wrapped/shared/WrappedThemeSwitcherModern.vue +++ b/frontend/components/wrapped/shared/WrappedThemeSwitcherModern.vue @@ -20,12 +20,11 @@ diff --git a/frontend/components/wrapped/shared/WrappedThemeSwitcherVhs.vue b/frontend/components/wrapped/shared/WrappedThemeSwitcherVhs.vue deleted file mode 100644 index ae1cf62..0000000 --- a/frontend/components/wrapped/shared/WrappedThemeSwitcherVhs.vue +++ /dev/null @@ -1,126 +0,0 @@ - - - - - diff --git a/frontend/components/wrapped/shared/WrappedYearSelector.vue b/frontend/components/wrapped/shared/WrappedYearSelector.vue index 1ddec9b..00e3873 100644 --- a/frontend/components/wrapped/shared/WrappedYearSelector.vue +++ b/frontend/components/wrapped/shared/WrappedYearSelector.vue @@ -1,34 +1,7 @@ @@ -263,72 +240,4 @@ onBeforeUnmount(() => { min-width: 50px; text-align: center; } - -/* ========== VHS 风格 ========== */ -.year-vhs { - display: flex; - align-items: center; - gap: 6px; - padding: 6px 10px; - background: linear-gradient(180deg, #2a2a3e 0%, #1a1a2e 100%); - border-radius: 4px; - border: 1px solid #3a3a5e; -} - -.vhs-transport-btn { - display: flex; - align-items: center; - justify-content: center; - width: 28px; - height: 22px; - background: linear-gradient(180deg, #4a4a5e 0%, #2a2a3e 50%, #3a3a4e 100%); - border: 1px solid #5a5a7e; - border-radius: 3px; - color: #cccccc; - font-size: 8px; - cursor: pointer; - box-shadow: - 0 2px 0 #1a1a2e, - inset 0 1px 0 rgba(255,255,255,0.2); - transition: all 0.05s; -} - -.vhs-transport-btn:hover:not(:disabled) { - background: linear-gradient(180deg, #5a5a6e 0%, #3a3a4e 50%, #4a4a5e 100%); -} - -.vhs-transport-btn:active:not(:disabled) { - transform: translateY(2px); - box-shadow: - 0 0 0 #1a1a2e, - inset 0 1px 2px rgba(0,0,0,0.3); -} - -.vhs-transport-btn:disabled { - opacity: 0.3; - cursor: not-allowed; -} - -.vhs-icon { - letter-spacing: -2px; -} - -.vhs-led-display { - background: #0a0a0a; - border: 1px solid #3a3a3a; - padding: 4px 10px; - border-radius: 2px; - box-shadow: inset 0 1px 3px rgba(0,0,0,0.5); -} - -.vhs-led-digit { - font-family: 'Courier New', monospace; - font-size: 14px; - font-weight: bold; - color: #ff3333; - text-shadow: - 0 0 4px #ff3333, - 0 0 8px #ff3333; - letter-spacing: 2px; -} diff --git a/frontend/components/wrapped/visualizations/ChatReplayAnimation.vue b/frontend/components/wrapped/visualizations/ChatReplayAnimation.vue index 81d9173..173d90e 100644 --- a/frontend/components/wrapped/visualizations/ChatReplayAnimation.vue +++ b/frontend/components/wrapped/visualizations/ChatReplayAnimation.vue @@ -391,19 +391,4 @@ watch( font-family: 'Courier New', monospace; text-shadow: 0 0 3px rgba(51, 255, 51, 0.6); } - -/* ========== VHS 主题 ========== */ -.wrapped-theme-vhs .wrapped-chat-replay { - --wr-chat-frame-bg: #16213e; - --wr-chat-top-bg: #0f3460; - --wr-chat-chat-bg: #1a1a2e; - --wr-chat-border: #0f3460; - - --wr-chat-bubble-bg: linear-gradient(135deg, #e94560 0%, #0f3460 100%); - --wr-chat-bubble-tail: #0f3460; - --wr-chat-bubble-text: #ffffff; - - --wr-chat-typing-bg: rgba(255, 255, 255, 0.08); - --wr-chat-typing-dot: rgba(255, 255, 255, 0.85); -} diff --git a/frontend/components/wrapped/visualizations/GlobalOverviewChart.vue b/frontend/components/wrapped/visualizations/GlobalOverviewChart.vue index dd5ab79..aa64d54 100644 --- a/frontend/components/wrapped/visualizations/GlobalOverviewChart.vue +++ b/frontend/components/wrapped/visualizations/GlobalOverviewChart.vue @@ -377,56 +377,4 @@ const labels = computed(() => { color: #33ff33 !important; text-shadow: 0 0 5px #33ff33; } - -/* ========== VHS 主题 ========== */ - -.wrapped-theme-vhs .overview-card { - background: #16213e !important; - border: 1px solid #0f3460 !important; - backdrop-filter: none; -} - -.wrapped-theme-vhs .overview-grid-line { - stroke: #0f3460; - stroke-opacity: 0.6; -} - -.wrapped-theme-vhs .overview-axis-line { - stroke: #0f3460; - stroke-opacity: 0.8; -} - -.wrapped-theme-vhs .overview-data-polygon { - fill: rgba(233, 69, 96, 0.2); - stroke: #e94560; -} - -.wrapped-theme-vhs .overview-data-node { - fill: #e94560; - stroke: #16213e; -} - -.wrapped-theme-vhs .overview-label { - fill: #a0a0a0; -} - -.wrapped-theme-vhs .overview-progress-bg { - background: #0f3460 !important; -} - -.wrapped-theme-vhs .overview-progress-fill { - background: linear-gradient(90deg, #e94560, #0f3460) !important; -} - -.wrapped-theme-vhs .wrapped-label, -.wrapped-theme-vhs .wrapped-body { - color: #a0a0a0 !important; -} - -.wrapped-theme-vhs .wrapped-number { - color: #e94560 !important; - text-shadow: - -1px 0 rgba(0, 255, 247, 0.5), - 1px 0 rgba(255, 0, 255, 0.5); -} diff --git a/frontend/components/wrapped/visualizations/MessageCharsChart.vue b/frontend/components/wrapped/visualizations/MessageCharsChart.vue index 9e99624..159f4eb 100644 --- a/frontend/components/wrapped/visualizations/MessageCharsChart.vue +++ b/frontend/components/wrapped/visualizations/MessageCharsChart.vue @@ -1321,218 +1321,6 @@ const getLabelStyle = (code) => { text-shadow: 0 0 5px #ff3333; } -/* ========== VHS 录像带主题 - 复古视频风格键盘 ========== */ - -.wrapped-theme-vhs .keyboard-outer { - border-radius: 4px; - background: linear-gradient(180deg, #2a2a4e 0%, #1a1a2e 100%); - border: 2px solid #0f3460; - padding: 4px; - box-shadow: - 0 4px 20px rgba(233, 69, 96, 0.2), - inset 0 1px 0 rgba(255, 255, 255, 0.1); -} - -.wrapped-theme-vhs .keyboard-inner { - border-radius: 2px; - background: linear-gradient(180deg, #16213e 0%, #0f0f23 100%); - border: 1px solid #0f3460; - padding: 6px; -} - -.wrapped-theme-vhs .keyboard-header { - border-bottom: 1px solid #0f3460; - padding-bottom: 6px; - margin-bottom: 6px; -} - -.wrapped-theme-vhs .dot { - border-radius: 50%; - width: 8px; - height: 8px; -} -.wrapped-theme-vhs .dot-red { - background: #e94560; - box-shadow: 0 0 8px #e94560; - animation: vhs-dot-flicker 0.1s infinite; -} -.wrapped-theme-vhs .dot-yellow { background: #f39c12; box-shadow: 0 0 5px #f39c12; } -.wrapped-theme-vhs .dot-green { background: #27ae60; box-shadow: 0 0 5px #27ae60; } - -@keyframes vhs-dot-flicker { - 0%, 90%, 100% { opacity: 1; } - 92% { opacity: 0.7; } - 95% { opacity: 1; } - 97% { opacity: 0.8; } -} - -.wrapped-theme-vhs .keyboard-stats, -.wrapped-theme-vhs .keyboard-hint { - font-family: 'Courier New', monospace; - color: #eaeaea; - text-shadow: - -1px 0 #00fff7, - 1px 0 #ff00ff; -} - -.wrapped-theme-vhs .keyboard-body { - border-radius: 2px; - background: #0a0a1a; - box-shadow: inset 0 2px 10px rgba(0, 0, 0, 0.5); -} - -.wrapped-theme-vhs .kb-key::before { - border-radius: 2px; - background: #1a1a2e; -} - -.wrapped-theme-vhs .kb-key-top { - border-radius: 2px; - border: 1px solid #0f3460 !important; - background: linear-gradient(180deg, #2a2a4e 0%, #1a1a2e 100%) !important; - box-shadow: - inset 0 1px 0 rgba(255, 255, 255, 0.1), - 0 2px 4px rgba(0, 0, 0, 0.3) !important; -} - -.wrapped-theme-vhs .kb-label { - font-family: 'Courier New', monospace; - color: #eaeaea !important; - text-shadow: - -1px 0 rgba(0, 255, 247, 0.5), - 1px 0 rgba(255, 0, 255, 0.5); - filter: none !important; -} - -.wrapped-theme-vhs .kb-sub { - font-family: 'Courier New', monospace; - color: #a0a0a0 !important; - filter: none !important; -} - -.wrapped-theme-vhs .kb-space-bar { - border-radius: 2px; - background: linear-gradient(90deg, #e94560 0%, #0f3460 100%); - height: 3px; -} - -.wrapped-theme-vhs .keyboard-brand { - font-family: 'Courier New', monospace; - color: #e94560; - text-shadow: - -1px 0 #00fff7, - 1px 0 #ff00ff; - letter-spacing: 3px; -} - -/* VHS 磨损效果 - 色彩溢出增强 */ -.wrapped-theme-vhs .kb-level-1 .kb-label, -.wrapped-theme-vhs .kb-level-2 .kb-label { - text-shadow: - -1px 0 rgba(0, 255, 247, 0.6), - 1px 0 rgba(255, 0, 255, 0.6); -} -.wrapped-theme-vhs .kb-level-3 .kb-label, -.wrapped-theme-vhs .kb-level-4 .kb-label { - text-shadow: - -2px 0 rgba(0, 255, 247, 0.7), - 2px 0 rgba(255, 0, 255, 0.7); -} -.wrapped-theme-vhs .kb-level-5 .kb-label, -.wrapped-theme-vhs .kb-level-6 .kb-label { - text-shadow: - -2px 0 rgba(0, 255, 247, 0.8), - 2px 0 rgba(255, 0, 255, 0.8); - animation: vhs-text-glitch 3s infinite; -} -.wrapped-theme-vhs .kb-level-7 .kb-key-top, -.wrapped-theme-vhs .kb-level-8 .kb-key-top { - animation: vhs-key-glitch 2s infinite; -} -.wrapped-theme-vhs .kb-level-9 .kb-key-top { - animation: vhs-key-glitch 1s infinite; - border-color: #e94560 !important; -} - -@keyframes vhs-text-glitch { - 0%, 95%, 100% { transform: translateX(0); } - 96% { transform: translateX(-1px); } - 97% { transform: translateX(1px); } - 98% { transform: translateX(-1px); } - 99% { transform: translateX(0); } -} - -@keyframes vhs-key-glitch { - 0%, 92%, 100% { - transform: translate(0); - filter: none; - } - 93% { - transform: translate(-1px, 0); - filter: hue-rotate(90deg); - } - 95% { - transform: translate(1px, 0); - filter: hue-rotate(-90deg); - } - 97% { - transform: translate(0, -1px); - filter: saturate(1.5); - } -} - -.wrapped-theme-vhs .kb-level-10 .kb-key-top { - opacity: 0 !important; -} -.wrapped-theme-vhs .kb-level-10::before { - background: linear-gradient( - 45deg, - #1a1a2e 25%, - #0f3460 25%, - #0f3460 50%, - #1a1a2e 50%, - #1a1a2e 75%, - #0f3460 75% - ) !important; - background-size: 4px 4px; - animation: vhs-static 0.5s infinite; -} - -@keyframes vhs-static { - 0% { background-position: 0 0; } - 100% { background-position: 4px 4px; } -} - -.wrapped-theme-vhs .kb-level-10::after { - content: ''; - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - width: 6px; - height: 6px; - background: #e94560; - border-radius: 50%; - box-shadow: 0 0 10px #e94560; - animation: vhs-dot-flicker 0.2s infinite; -} - -/* VHS 聊天气泡主题适配 */ -.wrapped-theme-vhs .bubble-left, -.wrapped-theme-vhs .bubble-right { - background: #16213e; - border: 1px solid #0f3460; -} -.wrapped-theme-vhs .bubble-left::before { - border-right-color: #16213e; -} -.wrapped-theme-vhs .bubble-right { - background: linear-gradient(135deg, #e94560 0%, #0f3460 100%); -} -.wrapped-theme-vhs .bubble-right::after { - border-left-color: #0f3460; -} - /* DOS 聊天气泡主题适配 */ .wrapped-theme-dos .bubble-left, .wrapped-theme-dos .bubble-right { @@ -1560,12 +1348,6 @@ const getLabelStyle = (code) => { stroke: #33ff33; } -/* VHS 头像适配 */ -.wrapped-theme-vhs .avatar-box { - background: #16213e; - border-color: #0f3460; -} - /* ========== Game Boy 主题 - 聊天气泡适配 ========== */ /* 聊天区域背景 */ @@ -1655,28 +1437,4 @@ const getLabelStyle = (code) => { text-shadow: 0 0 3px #33ff33; font-family: 'Courier New', monospace; } - -/* ========== VHS 主题 - 聊天气泡文字适配 ========== */ - -.wrapped-theme-vhs .bubble-left .wrapped-label, -.wrapped-theme-vhs .bubble-right .wrapped-label { - color: #a0a0a0 !important; -} - -.wrapped-theme-vhs .bubble-left .wrapped-number, -.wrapped-theme-vhs .bubble-right .wrapped-number { - color: #eaeaea !important; - text-shadow: - -1px 0 rgba(0, 255, 247, 0.5), - 1px 0 rgba(255, 0, 255, 0.5); -} - -.wrapped-theme-vhs .bubble-left .wrapped-body, -.wrapped-theme-vhs .bubble-right .wrapped-body { - color: #a0a0a0 !important; -} - -.wrapped-theme-vhs .avatar-box svg { - stroke: #e94560; -} diff --git a/frontend/components/wrapped/visualizations/WeekdayHourHeatmap.vue b/frontend/components/wrapped/visualizations/WeekdayHourHeatmap.vue index 5e9df16..2b611f9 100644 --- a/frontend/components/wrapped/visualizations/WeekdayHourHeatmap.vue +++ b/frontend/components/wrapped/visualizations/WeekdayHourHeatmap.vue @@ -157,18 +157,4 @@ const originFor = (weekdayIndex, hour) => { .wrapped-theme-dos .heatmap-legend-cell { border-radius: 0 !important; } - -/* ========== VHS 主题 ========== */ - -.wrapped-theme-vhs .wrapped-label, -.wrapped-theme-vhs .wrapped-body { - color: #a0a0a0 !important; -} - -.wrapped-theme-vhs .wrapped-number { - color: #e94560 !important; - text-shadow: - -1px 0 rgba(0, 255, 247, 0.5), - 1px 0 rgba(255, 0, 255, 0.5); -} diff --git a/frontend/composables/useWrappedTheme.js b/frontend/composables/useWrappedTheme.js index 3b949b8..ed54aeb 100644 --- a/frontend/composables/useWrappedTheme.js +++ b/frontend/composables/useWrappedTheme.js @@ -1,10 +1,10 @@ /** * 年度总结页面主题管理 composable - * 支持四种主题:modern(现代)、gameboy(Game Boy)、dos(DOS终端)、vhs(VHS录像带) + * 支持三种主题:modern(现代)、gameboy(Game Boy)、dos(DOS终端) */ const STORAGE_KEY = 'wrapped-theme' -const VALID_THEMES = ['off', 'gameboy', 'dos', 'vhs'] +const VALID_THEMES = ['off', 'gameboy', 'dos'] // 全局响应式状态(跨组件共享) const theme = ref('off') @@ -62,13 +62,12 @@ export function useWrappedTheme() { const names = { off: 'Modern', gameboy: 'Game Boy', - dos: 'DOS Terminal', - vhs: 'VHS Tape' + dos: 'DOS Terminal' } return names[theme.value] || 'Modern' }) - // 全局 F1-F4 快捷键切换主题(仅初始化一次) + // 全局 F1-F3 快捷键切换主题(仅初始化一次) const initKeyboardShortcuts = () => { if (keyboardInitialized || !import.meta.client) return keyboardInitialized = true @@ -89,9 +88,6 @@ export function useWrappedTheme() { } else if (e.key === 'F3') { e.preventDefault() setTheme('dos') - } else if (e.key === 'F4') { - e.preventDefault() - setTheme('vhs') } } diff --git a/frontend/pages/wrapped/index.vue b/frontend/pages/wrapped/index.vue index c4ea32d..25f6880 100644 --- a/frontend/pages/wrapped/index.vue +++ b/frontend/pages/wrapped/index.vue @@ -183,8 +183,8 @@ const year = ref(Number(route.query?.year) || new Date().getFullYear()) // 分享视图不展示账号信息:默认让后端自动选择;需要指定时可用 query ?account=wxid_xxx const account = ref(typeof route.query?.account === 'string' ? route.query.account : '') -// 主题管理:modern / gameboy / dos / vhs -const { theme, setTheme, cycleTheme, isRetro, themeClass } = useWrappedTheme() +// 主题管理:modern / gameboy / dos +const { theme, cycleTheme, isRetro, themeClass } = useWrappedTheme() const accounts = ref([]) const accountsLoading = ref(true) @@ -219,8 +219,7 @@ let navUnlockTimer = null const THEME_BG = { off: '#F3FFF8', // Modern: 浅绿 gameboy: '#9bbc0f', // Game Boy: 亮绿 - dos: '#0a0a0a', // DOS: 黑色 - vhs: '#0a0a14' // VHS: 深蓝黑 + dos: '#0a0a0a' // DOS: 黑色 } const slides = computed(() => { diff --git a/frontend/utils/wrapped/heatmap.js b/frontend/utils/wrapped/heatmap.js index 0d5d19c..b58e135 100644 --- a/frontend/utils/wrapped/heatmap.js +++ b/frontend/utils/wrapped/heatmap.js @@ -58,15 +58,6 @@ export const themedHeatColor = (value, max, theme) => { const light = 20 + 60 * t return `hsl(120 100% ${light.toFixed(1)}%)` } - case 'vhs': { - // VHS: from dark blue to pink/magenta - if (t === 0) return 'rgba(15, 52, 96, 0.3)' - // Interpolate from #0f3460 (dark blue) to #e94560 (pink) - const r = Math.round(15 + (233 - 15) * t) - const g = Math.round(52 + (69 - 52) * t) - const b = Math.round(96 + (96 - 96) * t) - return `rgb(${r}, ${g}, ${b})` - } default: // Modern (off) - use original heatColor return heatColor(value, max) @@ -79,4 +70,3 @@ export const formatHourRange = (hour) => { const hh = String(h).padStart(2, '0') return `${hh}:00-${hh}:59` } -