diff --git a/frontend/assets/css/tailwind.css b/frontend/assets/css/tailwind.css index d913f32..2aea714 100644 --- a/frontend/assets/css/tailwind.css +++ b/frontend/assets/css/tailwind.css @@ -2,33 +2,6 @@ @tailwind components; @tailwind utilities; -/* Fusion Pixel Font - 像素字体 @font-face 声明 */ -/* 下载地址: https://github.com/TakWolf/fusion-pixel-font/releases */ - -@font-face { - font-family: 'Fusion Pixel 12'; - src: url('/fonts/fusion-pixel-12px-monospaced-zh_hans.otf.woff2') format('woff2'); - font-weight: normal; - font-style: normal; - font-display: swap; -} - -@font-face { - font-family: 'Fusion Pixel 10'; - src: url('/fonts/fusion-pixel-10px-monospaced-zh_hans.otf.woff2') format('woff2'); - font-weight: normal; - font-style: normal; - font-display: swap; -} - -@font-face { - font-family: 'Fusion Pixel 8'; - src: url('/fonts/fusion-pixel-8px-monospaced-zh_hans.otf.woff2') format('woff2'); - font-weight: normal; - font-style: normal; - font-display: swap; -} - /* 自定义全局样式 - 微信配色主题 */ @layer base { :root { @@ -69,11 +42,6 @@ /* 统一消息圆角(聊天所有消息共用) */ --message-radius: 4px; - - /* Wrapped 年度总结 - 像素字体 */ - --font-pixel-12: 'Fusion Pixel 12', 'Microsoft YaHei', sans-serif; - --font-pixel-10: 'Fusion Pixel 10', 'Microsoft YaHei', sans-serif; - --font-pixel-8: 'Fusion Pixel 8', 'Microsoft YaHei', sans-serif; } body { @@ -169,8 +137,7 @@ animation: noise-jitter 0.5s steps(3) infinite; } - /* Wrapped 像素字体类 */ - /* Wrapped typography: default is modern; `.wrapped-retro` enables pixel font + CRT vibe. */ + /* Wrapped typography */ .wrapped-title { font-weight: 700; letter-spacing: 0.02em; @@ -195,94 +162,6 @@ font-variant-numeric: tabular-nums; } - .wrapped-retro .wrapped-title { - font-family: var(--font-pixel-12); - font-weight: normal; - letter-spacing: 0.05em; - image-rendering: pixelated; - -webkit-font-smoothing: none; - } - - .wrapped-retro .wrapped-title-en { - font-family: var(--font-pixel-12); - font-weight: normal; - letter-spacing: 0.08em; - image-rendering: pixelated; - -webkit-font-smoothing: none; - } - - .wrapped-retro .wrapped-body { - font-family: var(--font-pixel-10); - font-weight: normal; - line-height: 1.8; - image-rendering: pixelated; - -webkit-font-smoothing: none; - } - - .wrapped-retro .wrapped-label { - font-family: var(--font-pixel-8); - font-weight: normal; - letter-spacing: 0.15em; - text-transform: uppercase; - image-rendering: pixelated; - -webkit-font-smoothing: none; - } - - .wrapped-retro .wrapped-number { - font-family: var(--font-pixel-12); - font-weight: normal; - font-variant-numeric: tabular-nums; - image-rendering: pixelated; - -webkit-font-smoothing: none; - } - - /* CRT 扫描线 - 水平线条(明显可见) */ - .crt-scanlines { - background: repeating-linear-gradient( - to bottom, - transparent 0px, - transparent 3px, - rgba(0, 0, 0, 0.15) 3px, - rgba(0, 0, 0, 0.15) 4px - ); - background-size: 100% 4px; - animation: scanline-scroll 12s linear infinite; - } - - /* CRT RGB 子像素 - 垂直彩色条纹 */ - .crt-rgb-pixels { - background-image: repeating-linear-gradient( - to right, - rgba(255, 0, 0, 0.06) 0px, - rgba(255, 0, 0, 0.06) 1px, - rgba(0, 255, 0, 0.06) 1px, - rgba(0, 255, 0, 0.06) 2px, - rgba(0, 0, 255, 0.06) 2px, - rgba(0, 0, 255, 0.06) 3px - ); - } - - /* CRT 闪烁 - 亮度波动 */ - .crt-flicker { - background-color: rgba(255, 255, 255, 0.01); - animation: crt-flicker 0.15s infinite alternate; - } - - /* CRT 暗角 - 边缘渐暗(更强) */ - .crt-vignette { - box-shadow: inset 0 0 250px 80px rgba(0, 0, 0, 0.15); - } - - /* CRT 屏幕曲率效果 */ - .crt-curvature { - background: radial-gradient( - ellipse at center, - transparent 0%, - transparent 40%, - rgba(0, 0, 0, 0.1) 100% - ); - } - /* 输入框样式 */ .input { @apply w-full px-4 py-3 bg-[#f7f8fa] border border-transparent rounded-xl focus:outline-none focus:ring-2 focus:ring-[#07c160] focus:bg-white focus:border-[#07c160] transition-all duration-200; @@ -1224,24 +1103,7 @@ } } -/* CRT 和 Wrapped 动画关键帧 */ -@keyframes scanline-scroll { - 0% { - background-position: 0 0; - } - 100% { - background-position: 0 100vh; - } -} - -@keyframes crt-flicker { - 0%, 100% { - opacity: 1; - } - 50% { - opacity: 0.985; - } -} +/* Wrapped 动画关键帧 */ @keyframes noise-jitter { 0% { @@ -1273,348 +1135,3 @@ .wrapped-animate-in { animation: wrapped-fade-in 0.6s ease-out forwards; } - -/* ============================================ - Wrapped 主题系统 - Game Boy / DOS - ============================================ */ - -/* 复古模式共享基础样式 */ -.wrapped-retro { - /* 共享 CSS 变量(各主题覆盖) */ - --wrapped-bg: #9bbc0f; - --wrapped-card-bg: #8bac0f; - --wrapped-text: #0f380f; - --wrapped-text-secondary: #306230; - --wrapped-accent: #0f380f; - --wrapped-border: #306230; - --wrapped-warning: #0f380f; -} - -/* ============================================ - Theme 1: Game Boy - 复古绿色系 - ============================================ */ -.wrapped-theme-gameboy { - /* Game Boy 4色调色板 */ - --wrapped-bg: #9bbc0f; /* 最亮绿 */ - --wrapped-card-bg: #8bac0f; /* 次亮绿 */ - --wrapped-text: #0f380f; /* 最深绿 */ - --wrapped-text-secondary: #306230; /* 中深绿 */ - --wrapped-accent: #0f380f; - --wrapped-border: #306230; - --wrapped-warning: #306230; - - /* 像素化渲染 */ - image-rendering: pixelated; - -webkit-font-smoothing: none; -} - -/* Game Boy 像素化边框 */ -.wrapped-theme-gameboy .wrapped-card-shell, -.wrapped-theme-gameboy [class*="rounded"] { - border-radius: 0 !important; - box-shadow: - inset -4px -4px 0 0 #306230, - inset 4px 4px 0 0 #9bbc0f, - 0 0 0 4px #0f380f; -} - -/* Game Boy 步进动画 */ -.wrapped-theme-gameboy * { - animation-timing-function: steps(8) !important; -} - -/* Game Boy 按钮样式 */ -.wrapped-theme-gameboy button { - border-radius: 0 !important; - box-shadow: - inset -2px -2px 0 0 #306230, - inset 2px 2px 0 0 #9bbc0f; - transition: none !important; -} - -.wrapped-theme-gameboy button:active { - box-shadow: - inset 2px 2px 0 0 #306230, - inset -2px -2px 0 0 #9bbc0f; -} - -/* ============================================ - Theme 2: DOS Terminal - 黑底绿字/琥珀字 - ============================================ */ -.wrapped-theme-dos { - --wrapped-bg: #000000; - --wrapped-card-bg: #0a0a0a; - --wrapped-text: #33ff33; /* 磷光绿 */ - --wrapped-text-secondary: #22aa22; - --wrapped-accent: #33ff33; - --wrapped-border: #33ff33; - --wrapped-warning: #ffaa00; /* 琥珀警告色 */ - - background-color: #000000 !important; - /* 使用现有 Fusion Pixel 10px 字体 */ - font-family: var(--font-pixel-10), 'Courier New', monospace !important; - -webkit-font-smoothing: none; - image-rendering: pixelated; -} - -/* DOS 文字发光效果 */ -.wrapped-theme-dos .wrapped-title, -.wrapped-theme-dos .wrapped-body, -.wrapped-theme-dos .wrapped-label, -.wrapped-theme-dos .wrapped-number { - color: #33ff33 !important; - /* 从 4 层减少到 2 层,降低发光强度 */ - text-shadow: - 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 ASCII 边框 */ -.wrapped-theme-dos .wrapped-card-shell, -.wrapped-theme-dos [class*="border"] { - border: 2px solid #33ff33 !important; - border-radius: 0 !important; - box-shadow: - 0 0 5px #33ff33, - inset 0 0 5px rgba(51, 255, 51, 0.1); -} - -/* DOS 磷光残影效果 */ -.wrapped-theme-dos * { - transition: text-shadow 0.1s ease-out !important; -} - -/* DOS 扫描线(细化) */ -.wrapped-theme-dos .crt-scanlines { - background: repeating-linear-gradient( - to bottom, - transparent 0px, - transparent 1px, - rgba(0, 0, 0, 0.15) 1px, - rgba(0, 0, 0, 0.15) 2px - ) !important; - opacity: 0.5; -} - -/* DOS 按钮样式 */ -.wrapped-theme-dos button { - background-color: transparent !important; - border: 1px solid #33ff33 !important; - color: #33ff33 !important; - border-radius: 0 !important; - text-shadow: 0 0 5px #33ff33; - box-shadow: 0 0 5px rgba(51, 255, 51, 0.3); -} - -.wrapped-theme-dos button:hover { - background-color: #33ff33 !important; - color: #000000 !important; - text-shadow: none; -} - -/* ============================================ - Theme 3: Windows 95/98 - Win98 - ============================================ */ -.wrapped-theme-win98 { - /* System-like colors (approx.) */ - --win98-face: #c0c0c0; /* ButtonFace */ - --win98-hi: #ffffff; /* ButtonHighlight */ - --win98-shadow: #808080; /* ButtonShadow */ - --win98-dkshadow: #000000; /* Black */ - --win98-outline: #dedede; /* Extra light line (common in Win95 clones) */ - --win98-dither: repeating-conic-gradient(#bdbebd 0% 25%, #ffffff 0% 50%) 50% / 2px 2px; - - --win98-title: #000080; /* ActiveCaption */ - --win98-title2: #1084d0; /* Caption gradient (approx.) */ - --win98-title-text: #ffffff; - --win98-title-inactive: #7b7d7b; - --win98-title-inactive-text: #e6e6e6; - - /* Map to Wrapped theme variables */ - --wrapped-bg: #ffffff; /* fields/content */ - --wrapped-card-bg: var(--win98-face); - --wrapped-text: #000000; - --wrapped-text-secondary: #404040; - --wrapped-accent: var(--win98-title); - --wrapped-border: var(--win98-shadow); - --wrapped-warning: #800000; - - font-family: "MS Sans Serif", Tahoma, "Microsoft Sans Serif", "Segoe UI", sans-serif !important; -} - -/* Win98: hard edges */ -.wrapped-theme-win98 [class*="rounded"] { - border-radius: 0 !important; -} - -/* Win98: baseline typography (override Tailwind inline colors via !important) */ -.wrapped-theme-win98 .wrapped-title { - color: var(--wrapped-text) !important; -} - -.wrapped-theme-win98 .wrapped-body, -.wrapped-theme-win98 .wrapped-label { - color: var(--wrapped-text-secondary) !important; -} - -.wrapped-theme-win98 .wrapped-number { - color: var(--wrapped-accent) !important; -} - -/* Win98: generic raised button */ -.wrapped-theme-win98 button { - background: var(--win98-face) !important; - color: #000000 !important; - border-radius: 0 !important; - text-shadow: none !important; - - /* Win95-ish bevel: light (top/left) + shadow (bottom/right) + hard drop */ - border-top: 1px solid var(--win98-hi) !important; - border-left: 1px solid var(--win98-hi) !important; - border-right: 1px solid var(--win98-shadow) !important; - border-bottom: 1px solid var(--win98-shadow) !important; - box-shadow: 1px 1px 0 var(--win98-dkshadow) !important; -} - -.wrapped-theme-win98 button:active:not(:disabled) { - background: var(--win98-face) !important; - box-shadow: none !important; - border-top: 1px solid var(--win98-dkshadow) !important; - border-left: 1px solid var(--win98-dkshadow) !important; - border-right: 1px solid var(--win98-hi) !important; - border-bottom: 1px solid var(--win98-hi) !important; -} - -.wrapped-theme-win98 button:disabled { - opacity: 0.65; - cursor: not-allowed; -} - -/* Win98: dotted focus rectangle (classic) */ -.wrapped-theme-win98 button:focus-visible { - outline: 1px dotted var(--win98-dkshadow); - outline-offset: -4px; -} - -/* Win98 helper: checkered/dither fill for "pressed/toggled" UI (taskbar active, start menu pressed, etc.) */ -.wrapped-theme-win98 .win98-dither { - background: var(--win98-dither) !important; -} - -/* Win98: text-ish inputs / selects get a sunken look (avoid checkbox/radio etc.) */ -.wrapped-theme-win98 textarea, -.wrapped-theme-win98 select, -.wrapped-theme-win98 input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="color"]) { - background: var(--wrapped-bg) !important; - color: var(--wrapped-text) !important; - border-radius: 0 !important; - border: 1px solid var(--win98-shadow) !important; - box-shadow: - inset 1px 1px 0 var(--win98-dkshadow), - inset -1px -1px 0 var(--win98-hi); -} - -/* Win98: window primitives (98.css-like semantics) */ -.wrapped-theme-win98 .window { - background: var(--win98-face); - - /* Stronger Win95-ish window frame (inspired by /win95/assets/css/windows/window.css) */ - border-top: 2px solid var(--win98-hi); - border-left: 2px solid var(--win98-hi); - border-right: 1.5px solid var(--win98-shadow); - border-bottom: 1.5px solid var(--win98-shadow); - box-shadow: 1.5px 1.5px 0 var(--win98-dkshadow); - outline: 1px solid var(--win98-outline); -} - -.wrapped-theme-win98 .title-bar { - display: flex; - align-items: center; - justify-content: space-between; - gap: 8px; - padding: 3px 4px; - - /* Win95 is typically solid; Win98 sometimes gradients. Keep solid by default. */ - background: var(--win98-title); - color: var(--win98-title-text); - font-weight: 700; - user-select: none; -} - -.wrapped-theme-win98 .title-bar-text { - display: flex; - align-items: center; - gap: 6px; - min-width: 0; - font-size: 11px; - line-height: 1; -} - -.wrapped-theme-win98 .title-bar-icon { - width: 16px; - height: 16px; - flex: none; - image-rendering: pixelated; -} - -.wrapped-theme-win98 .title-bar-text span { - min-width: 0; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} - -.wrapped-theme-win98 .title-bar-controls { - display: inline-flex; - gap: 2px; -} - -.wrapped-theme-win98 .title-bar-controls button { - width: 18px; - height: 16px; - padding: 0; - display: inline-flex; - align-items: center; - justify-content: center; - position: relative; - font-weight: 700; - line-height: 1; -} - -.wrapped-theme-win98 .title-bar-controls button::before { - content: ""; - display: block; -} - -/* Win95-ish glyphs (avoid relying on fonts for the line/square). */ -.wrapped-theme-win98 .title-bar-controls button[aria-label="Minimize"]::before { - width: 6px; - height: 2px; - background: #000000; - transform: translateY(4px); -} - -.wrapped-theme-win98 .title-bar-controls button[aria-label="Maximize"]::before { - width: 9px; - height: 8px; - box-sizing: border-box; - border: 1px solid #000000; - border-top-width: 2px; - background: transparent; -} - -.wrapped-theme-win98 .title-bar-controls button[aria-label="Close"]::before { - content: "×"; - font-size: 14px; - line-height: 1; - transform: translateY(-1px); -} - -.wrapped-theme-win98 .window-body { - padding: 8px; - background: var(--win98-face); - border-top: 1px solid var(--win98-shadow); - box-shadow: inset 0 1px 0 var(--win98-hi); -} diff --git a/frontend/components/wrapped/cards/Card03ReplySpeed.vue b/frontend/components/wrapped/cards/Card03ReplySpeed.vue index d196b72..542f159 100644 --- a/frontend/components/wrapped/cards/Card03ReplySpeed.vue +++ b/frontend/components/wrapped/cards/Card03ReplySpeed.vue @@ -95,7 +95,7 @@
-
+
最佳聊天搭子
Lucky Block -
+
年度聊天排行(总消息数)
-
+
{{ raceDate }} · 0.1秒/天
@@ -190,21 +188,19 @@
{{ item.rank }}
-
+
{{ item.displayName }}
@@ -229,7 +225,7 @@ {{ formatInt(item.value) }}
-
+
import { computed, onBeforeUnmount, reactive, ref, watch } from 'vue' -import { useWrappedTheme } from '~/composables/useWrappedTheme' const props = defineProps({ card: { type: Object, required: true }, variant: { type: String, default: 'panel' } // 'panel' | 'slide' }) -const { theme } = useWrappedTheme() -const isGameboy = computed(() => theme.value === 'gameboy') -const isModern = computed(() => theme.value === 'off') -const isRetro = computed(() => isGameboy.value) - const nfInt = new Intl.NumberFormat('zh-CN', { maximumFractionDigits: 0 }) const formatInt = (n) => nfInt.format(Math.round(Number(n) || 0)) diff --git a/frontend/components/wrapped/shared/WrappedCRTOverlay.vue b/frontend/components/wrapped/shared/WrappedCRTOverlay.vue deleted file mode 100644 index b376187..0000000 --- a/frontend/components/wrapped/shared/WrappedCRTOverlay.vue +++ /dev/null @@ -1,27 +0,0 @@ - - - diff --git a/frontend/components/wrapped/shared/WrappedCardShell.vue b/frontend/components/wrapped/shared/WrappedCardShell.vue index 862b045..bb94490 100644 --- a/frontend/components/wrapped/shared/WrappedCardShell.vue +++ b/frontend/components/wrapped/shared/WrappedCardShell.vue @@ -1,5 +1,5 @@ @@ -83,62 +49,4 @@ defineProps({ narrative: { type: String, default: '' }, variant: { type: String, default: 'panel' } // 'panel' | 'slide' }) - -const { theme } = useWrappedTheme() -const isWin98 = computed(() => theme.value === 'win98') -const isGameboy = computed(() => theme.value === 'gameboy') -const isCompactSlide = computed(() => isGameboy.value) - -const slideTitleClass = computed(() => ( - isCompactSlide.value ? 'text-xl sm:text-2xl' : 'text-2xl sm:text-3xl' -)) - -// Keep as a computed so we can tune per-theme spacing later without touching template. -const slideNarrativeWrapClass = computed(() => '') - -const slideContentWrapClass = computed(() => ( - isCompactSlide.value ? 'mt-4 sm:mt-5' : 'mt-6 sm:mt-8' -)) - -const slideContainerClass = computed(() => ( - isWin98.value - ? 'relative h-full max-w-5xl mx-auto px-6 pt-2 pb-4 sm:px-8 sm:pt-3 sm:pb-6 flex flex-col' - : (isCompactSlide.value - ? 'relative h-full max-w-5xl mx-auto px-6 pt-5 pb-6 sm:px-8 sm:pt-6 sm:pb-7 flex flex-col' - : 'relative h-full max-w-5xl mx-auto px-6 py-10 sm:px-8 sm:py-12 flex flex-col') -)) - - diff --git a/frontend/components/wrapped/shared/WrappedDeckBackground.vue b/frontend/components/wrapped/shared/WrappedDeckBackground.vue index e8b8024..7e621c6 100644 --- a/frontend/components/wrapped/shared/WrappedDeckBackground.vue +++ b/frontend/components/wrapped/shared/WrappedDeckBackground.vue @@ -1,6 +1,6 @@ - - - - diff --git a/frontend/components/wrapped/shared/WrappedGameboyDither.vue b/frontend/components/wrapped/shared/WrappedGameboyDither.vue deleted file mode 100644 index 5be2021..0000000 --- a/frontend/components/wrapped/shared/WrappedGameboyDither.vue +++ /dev/null @@ -1,98 +0,0 @@ - - - diff --git a/frontend/components/wrapped/shared/WrappedHero.vue b/frontend/components/wrapped/shared/WrappedHero.vue index 66c7ed4..2c545fb 100644 --- a/frontend/components/wrapped/shared/WrappedHero.vue +++ b/frontend/components/wrapped/shared/WrappedHero.vue @@ -9,57 +9,7 @@