From 167d328116b28be00035f9251fdd1440bd557c1b Mon Sep 17 00:00:00 2001 From: djteang <935037887@qq.com> Date: Sun, 21 Sep 2025 01:19:44 +0800 Subject: [PATCH] =?UTF-8?q?added:=E6=B7=BB=E5=8A=A0=E5=86=85=E7=BD=AE?= =?UTF-8?q?=E4=B8=BB=E9=A2=98=EF=BC=8C=E6=94=AF=E6=8C=81=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E8=87=AA=E5=AE=9A=E4=B9=89CSS=20changed:=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E6=90=9C=E7=B4=A2=E9=A1=B5=E9=9D=A2=E7=BC=93=E5=AD=98=E6=9C=BA?= =?UTF-8?q?=E5=88=B6=20fixed:=E9=95=9C=E5=83=8F=E5=81=A5=E5=BA=B7=E6=A3=80?= =?UTF-8?q?=E6=9F=A5=E9=97=AE=E9=A2=98=EF=BC=8C=E5=BC=B9=E5=B9=95=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=E9=80=82=E9=85=8D=E7=A7=BB=E5=8A=A8=E7=AB=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG | 10 + Dockerfile | 38 +- VERSION.txt | 2 +- public/theme-init.js | 48 + src/app/admin/page.tsx | 19 +- src/app/api/admin/site/route.ts | 12 +- src/app/api/admin/theme/route.ts | 139 +++ src/app/api/theme/route.ts | 31 + src/app/globals.css | 1376 ++++++++++++++++++++++++++ src/app/layout.tsx | 5 + src/app/login/page.tsx | 2 + src/app/page.tsx | 3 + src/app/play/page.tsx | 81 +- src/app/search/page.tsx | 455 +++++++-- src/components/ChatModal.tsx | 30 +- src/components/GlobalThemeLoader.tsx | 102 ++ src/components/ThemeManager.tsx | 749 ++++++++++++++ src/components/ThemeToggle.tsx | 49 +- src/components/VideoCard.tsx | 10 + src/hooks/useTheme.ts | 88 ++ src/lib/admin.types.ts | 9 + src/lib/changelog.ts | 14 + src/middleware.ts | 2 +- tailwind.config.ts | 34 +- 24 files changed, 3176 insertions(+), 132 deletions(-) create mode 100644 public/theme-init.js create mode 100644 src/app/api/admin/theme/route.ts create mode 100644 src/app/api/theme/route.ts create mode 100644 src/components/GlobalThemeLoader.tsx create mode 100644 src/components/ThemeManager.tsx create mode 100644 src/hooks/useTheme.ts diff --git a/CHANGELOG b/CHANGELOG index 270a6ce..9405e03 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,13 @@ +## [8.9.5] - 2025-09-21 + +### Added +- 添加内置主题,支持用户自定义CSS +### Changed +- 优化搜索页面缓存机制 +### Fixed +- 镜像健康检查问题 +- 弹幕功能适配移动端 + ## [8.9.0] - 2025-09-15 ### Added diff --git a/Dockerfile b/Dockerfile index ac2cfc9..eb2ec89 100644 --- a/Dockerfile +++ b/Dockerfile @@ -95,9 +95,45 @@ USER nextjs # 暴露HTTP和WebSocket端口 EXPOSE 3000 3001 +# 创建健康检查脚本 +RUN echo '#!/usr/bin/env node\n\ +const http = require("http");\n\ +const options = {\n\ + hostname: "localhost",\n\ + port: 3000,\n\ + path: "/api/health",\n\ + method: "GET",\n\ + timeout: 5000\n\ +};\n\ +\n\ +const req = http.request(options, (res) => {\n\ + if (res.statusCode === 200) {\n\ + console.log("Health check passed");\n\ + process.exit(0);\n\ + } else {\n\ + console.log(`Health check failed with status: ${res.statusCode}`);\n\ + process.exit(1);\n\ + }\n\ +});\n\ +\n\ +req.on("error", (err) => {\n\ + console.log(`Health check error: ${err.message}`);\n\ + process.exit(1);\n\ +});\n\ +\n\ +req.on("timeout", () => {\n\ + console.log("Health check timeout");\n\ + req.destroy();\n\ + process.exit(1);\n\ +});\n\ +\n\ +req.setTimeout(5000);\n\ +req.end();' > /app/healthcheck.js && \ + chmod +x /app/healthcheck.js + # 添加健康检查 HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \ - CMD curl -f http://localhost:3000/api/health || exit 1 + CMD node /app/healthcheck.js # 设置WebSocket端口环境变量 ENV WS_PORT=3001 diff --git a/VERSION.txt b/VERSION.txt index 3ecb398..a37b21d 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -8.9.0 \ No newline at end of file +8.9.5 \ No newline at end of file diff --git a/public/theme-init.js b/public/theme-init.js new file mode 100644 index 0000000..3a8a1c9 --- /dev/null +++ b/public/theme-init.js @@ -0,0 +1,48 @@ +// 主题初始化脚本 - 立即执行,避免主题闪烁 +(function () { + try { + // 应用主题函数 + function applyTheme(themeId, css) { + const html = document.documentElement; + + // 移除所有主题属性 + html.removeAttribute('data-theme'); + + // 应用主题 + if (themeId !== 'default') { + html.setAttribute('data-theme', themeId); + } + + // 应用自定义CSS + if (css) { + let customStyleEl = document.getElementById('init-theme-css'); + if (!customStyleEl) { + customStyleEl = document.createElement('style'); + customStyleEl.id = 'init-theme-css'; + document.head.appendChild(customStyleEl); + } + customStyleEl.textContent = css; + } + } + + // 从localStorage获取保存的主题 + const savedTheme = localStorage.getItem('app-theme'); + const savedCustomCSS = localStorage.getItem('app-custom-css') || ''; + + // 立即应用已保存的主题(如果有) + if (savedTheme) { + applyTheme(savedTheme, savedCustomCSS); + console.log('主题已初始化(本地设置):', savedTheme); + } else { + // 没有用户设置时,先应用默认主题 + applyTheme('default', ''); + console.log('主题已初始化(默认)'); + } + + // 注意:GlobalThemeLoader会在React组件挂载后进一步处理全站配置 + } catch (error) { + console.error('主题初始化失败:', error); + } +})(); + + diff --git a/src/app/admin/page.tsx b/src/app/admin/page.tsx index b43ac83..9c21c92 100644 --- a/src/app/admin/page.tsx +++ b/src/app/admin/page.tsx @@ -38,7 +38,7 @@ import { Users, Video, } from 'lucide-react'; -import { GripVertical } from 'lucide-react'; +import { GripVertical, Palette } from 'lucide-react'; import Image from 'next/image'; import { Suspense, useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { createPortal } from 'react-dom'; @@ -47,6 +47,7 @@ import { AdminConfig, AdminConfigResult } from '../../lib/admin.types'; import { getAuthInfoFromBrowserCookie } from '@/lib/auth'; import DataMigration from '@/components/DataMigration'; +import ThemeManager from '@/components/ThemeManager'; import PageLayout from '@/components/PageLayout'; // 统一按钮样式系统 @@ -5210,6 +5211,7 @@ function AdminPageClient() { categoryConfig: false, configFile: false, dataMigration: false, + themeManager: false, }); // 机器码管理状态 @@ -5447,6 +5449,21 @@ function AdminPageClient() { )} + + {/* 主题定制标签 */} + + } + isExpanded={expandedTabs.themeManager} + onToggle={() => toggleTab('themeManager')} + > + + diff --git a/src/app/api/admin/site/route.ts b/src/app/api/admin/site/route.ts index aedbe73..ce69f8a 100644 --- a/src/app/api/admin/site/route.ts +++ b/src/app/api/admin/site/route.ts @@ -40,6 +40,7 @@ export async function POST(request: NextRequest) { DisableYellowFilter, FluidSearch, RequireDeviceCode, + CustomTheme, } = body as { SiteName: string; Announcement: string; @@ -52,6 +53,10 @@ export async function POST(request: NextRequest) { DisableYellowFilter: boolean; FluidSearch: boolean; RequireDeviceCode: boolean; + CustomTheme?: { + selectedTheme: string; + customCSS: string; + }; }; // 参数校验 @@ -66,7 +71,11 @@ export async function POST(request: NextRequest) { typeof DoubanImageProxy !== 'string' || typeof DisableYellowFilter !== 'boolean' || typeof FluidSearch !== 'boolean' || - typeof RequireDeviceCode !== 'boolean' + typeof RequireDeviceCode !== 'boolean' || + (CustomTheme && ( + typeof CustomTheme.selectedTheme !== 'string' || + typeof CustomTheme.customCSS !== 'string' + )) ) { return NextResponse.json({ error: '参数格式错误' }, { status: 400 }); } @@ -97,6 +106,7 @@ export async function POST(request: NextRequest) { DisableYellowFilter, FluidSearch, RequireDeviceCode, + CustomTheme, }; // 写入数据库 diff --git a/src/app/api/admin/theme/route.ts b/src/app/api/admin/theme/route.ts new file mode 100644 index 0000000..5130bfa --- /dev/null +++ b/src/app/api/admin/theme/route.ts @@ -0,0 +1,139 @@ +import { NextResponse } from 'next/server'; +import { getAuthInfoFromCookie } from '@/lib/auth'; +import { db } from '@/lib/db'; +import { AdminConfig } from '@/lib/admin.types'; +import { headers, cookies } from 'next/headers'; + +export async function GET() { + try { + // 创建一个模拟的NextRequest对象来使用getAuthInfoFromCookie + const cookieStore = cookies(); + const authCookie = cookieStore.get('auth'); + + if (!authCookie) { + return NextResponse.json({ error: '未授权' }, { status: 401 }); + } + + let authData; + try { + const decoded = decodeURIComponent(authCookie.value); + authData = JSON.parse(decoded); + } catch (error) { + return NextResponse.json({ error: '认证信息无效' }, { status: 401 }); + } + + const config = await db.getAdminConfig(); + const themeConfig = config?.ThemeConfig || { + defaultTheme: 'default' as const, + customCSS: '', + allowUserCustomization: true, + }; + + return NextResponse.json({ + success: true, + data: themeConfig, + }); + } catch (error) { + console.error('获取主题配置失败:', error); + return NextResponse.json( + { error: '获取主题配置失败' }, + { status: 500 } + ); + } +} + +export async function POST(request: Request) { + try { + // 获取认证信息 + const cookieStore = cookies(); + const authCookie = cookieStore.get('auth'); + + if (!authCookie) { + return NextResponse.json({ error: '未授权' }, { status: 401 }); + } + + let authData; + try { + const decoded = decodeURIComponent(authCookie.value); + authData = JSON.parse(decoded); + } catch (error) { + return NextResponse.json({ error: '认证信息无效' }, { status: 401 }); + } + + // 检查是否为管理员 + if (authData.role !== 'admin' && authData.role !== 'owner') { + return NextResponse.json({ error: '权限不足,仅管理员可设置全局主题' }, { status: 403 }); + } + + const body = await request.json(); + const { defaultTheme, customCSS, allowUserCustomization } = body; + + // 验证主题名称 + const validThemes = ['default', 'minimal', 'warm', 'fresh']; + if (!validThemes.includes(defaultTheme)) { + return NextResponse.json({ error: '无效的主题名称' }, { status: 400 }); + } + + // 获取当前配置 + const currentConfig = await db.getAdminConfig(); + + // 如果没有配置,创建一个基础配置 + let baseConfig: AdminConfig; + if (!currentConfig) { + baseConfig = { + ConfigSubscribtion: { + URL: "", + AutoUpdate: false, + LastCheck: "", + }, + ConfigFile: "", + SiteConfig: { + SiteName: "OrangeTV", + Announcement: "", + SearchDownstreamMaxPage: 10, + SiteInterfaceCacheTime: 30, + DoubanProxyType: "direct", + DoubanProxy: "", + DoubanImageProxyType: "direct", + DoubanImageProxy: "", + DisableYellowFilter: false, + FluidSearch: true, + RequireDeviceCode: false, + }, + UserConfig: { + Users: [], + }, + SourceConfig: [], + CustomCategories: [], + }; + } else { + baseConfig = currentConfig; + } + + // 更新主题配置 + const updatedConfig: AdminConfig = { + ...baseConfig, + ThemeConfig: { + defaultTheme: defaultTheme as 'default' | 'minimal' | 'warm' | 'fresh', + customCSS: customCSS || '', + allowUserCustomization: allowUserCustomization !== false, + }, + }; + + console.log('保存主题配置:', updatedConfig.ThemeConfig); + await db.saveAdminConfig(updatedConfig); + console.log('主题配置保存成功'); + + return NextResponse.json({ + success: true, + message: '主题配置已更新', + data: updatedConfig.ThemeConfig, + }); + } catch (error) { + console.error('更新主题配置失败:', error); + return NextResponse.json( + { error: '更新主题配置失败', details: error instanceof Error ? error.message : '未知错误' }, + { status: 500 } + ); + } +} diff --git a/src/app/api/theme/route.ts b/src/app/api/theme/route.ts new file mode 100644 index 0000000..a0393ea --- /dev/null +++ b/src/app/api/theme/route.ts @@ -0,0 +1,31 @@ +import { NextResponse } from 'next/server'; +import { db } from '@/lib/db'; + +export async function GET() { + try { + const config = await db.getAdminConfig(); + const themeConfig = config?.ThemeConfig || { + defaultTheme: 'default' as const, + customCSS: '', + allowUserCustomization: true, + }; + + return NextResponse.json({ + success: true, + data: themeConfig, + }); + } catch (error) { + console.error('获取主题配置失败:', error); + return NextResponse.json( + { + success: false, + data: { + defaultTheme: 'default' as const, + customCSS: '', + allowUserCustomization: true, + } + }, + { status: 200 } // 返回默认配置而不是错误 + ); + } +} diff --git a/src/app/globals.css b/src/app/globals.css index 879ba30..e730ab7 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -36,6 +36,1294 @@ :root { --foreground-rgb: 255, 255, 255; + + /* 默认主题(当前蓝色系主题) */ + --color-primary-50: 240, 249, 255; + --color-primary-100: 224, 242, 254; + --color-primary-200: 186, 230, 253; + --color-primary-300: 125, 211, 252; + --color-primary-400: 56, 189, 248; + --color-primary-500: 14, 165, 233; + --color-primary-600: 2, 132, 199; + --color-primary-700: 3, 105, 161; + --color-primary-800: 7, 89, 133; + --color-primary-900: 12, 74, 110; + --color-dark: 34, 34, 34; + + /* 主题颜色变量(默认使用蓝色系) */ + --color-theme-bg: 255, 255, 255; + --color-theme-surface: 249, 250, 251; + --color-theme-accent: 14, 165, 233; + --color-theme-text: 17, 24, 39; + --color-theme-text-secondary: 107, 114, 128; + --color-theme-border: 229, 231, 235; + --color-theme-success: 34, 197, 94; + --color-theme-warning: 245, 158, 11; + --color-theme-error: 239, 68, 68; + --color-theme-info: 59, 130, 246; +} + +.dark { + /* 默认深色主题 */ + --color-theme-bg: 17, 24, 39; + --color-theme-surface: 31, 41, 55; + --color-theme-accent: 56, 189, 248; + --color-theme-text: 243, 244, 246; + --color-theme-text-secondary: 156, 163, 175; + --color-theme-border: 75, 85, 99; + --color-theme-success: 74, 222, 128; + --color-theme-warning: 251, 191, 36; + --color-theme-error: 248, 113, 113; + --color-theme-info: 96, 165, 250; +} + +/* 视频卡片播放按钮hover填充颜色适配 */ + +/* 极简主题视频卡片播放按钮适配 */ +[data-theme="minimal"] .hover\:fill-blue-500:hover { + fill: rgb(82, 82, 82) !important; +} + +[data-theme="minimal"].dark .hover\:fill-blue-500:hover { + fill: rgb(163, 163, 163) !important; +} + +/* 暖色主题视频卡片播放按钮适配 */ +[data-theme="warm"] .hover\:fill-blue-500:hover { + fill: rgb(234, 88, 12) !important; +} + +[data-theme="warm"].dark .hover\:fill-blue-500:hover { + fill: rgb(251, 146, 60) !important; +} + +/* 视频卡片hover时资源名称和视频名称适配 */ + +/* 极简主题视频卡片文字适配 */ +[data-theme="minimal"] .group-hover\:text-blue-600:hover, +[data-theme="minimal"] .group:hover .group-hover\:text-blue-600 { + color: rgb(64, 64, 64) !important; +} +[data-theme="minimal"] .group-hover\:text-blue-400:hover, +[data-theme="minimal"] .group:hover .group-hover\:text-blue-400 { + color: rgb(163, 163, 163) !important; +} +[data-theme="minimal"] .group-hover\:border-blue-500\/60:hover, +[data-theme="minimal"] .group:hover .group-hover\:border-blue-500\/60 { + border-color: rgb(82, 82, 82, 0.6) !important; +} + +[data-theme="minimal"].dark .group-hover\:text-blue-600:hover, +[data-theme="minimal"].dark .group:hover .group-hover\:text-blue-600 { + color: rgb(163, 163, 163) !important; +} +[data-theme="minimal"].dark .group-hover\:text-blue-400:hover, +[data-theme="minimal"].dark .group:hover .group-hover\:text-blue-400 { + color: rgb(163, 163, 163) !important; +} + +/* 暖色主题视频卡片文字适配 */ +[data-theme="warm"] .group-hover\:text-blue-600:hover, +[data-theme="warm"] .group:hover .group-hover\:text-blue-600 { + color: rgb(194, 65, 12) !important; +} +[data-theme="warm"] .group-hover\:text-blue-400:hover, +[data-theme="warm"] .group:hover .group-hover\:text-blue-400 { + color: rgb(251, 146, 60) !important; +} +[data-theme="warm"] .group-hover\:border-blue-500\/60:hover, +[data-theme="warm"] .group:hover .group-hover\:border-blue-500\/60 { + border-color: rgb(234, 88, 12, 0.6) !important; +} + +[data-theme="warm"].dark .group-hover\:text-blue-600:hover, +[data-theme="warm"].dark .group:hover .group-hover\:text-blue-600 { + color: rgb(251, 146, 60) !important; +} +[data-theme="warm"].dark .group-hover\:text-blue-400:hover, +[data-theme="warm"].dark .group:hover .group-hover\:text-blue-400 { + color: rgb(251, 146, 60) !important; +} + +/* 清新主题视频卡片文字适配 */ +[data-theme="fresh"] .group-hover\:text-blue-600:hover, +[data-theme="fresh"] .group:hover .group-hover\:text-blue-600 { + color: rgb(22, 163, 74) !important; +} +[data-theme="fresh"] .group-hover\:text-blue-400:hover, +[data-theme="fresh"] .group:hover .group-hover\:text-blue-400 { + color: rgb(22, 163, 74) !important; +} +[data-theme="fresh"] .group-hover\:border-blue-500\/60:hover, +[data-theme="fresh"] .group:hover .group-hover\:border-blue-500\/60 { + border-color: rgb(63, 204, 113, 0.6) !important; +} + +[data-theme="fresh"].dark .group-hover\:text-blue-600:hover, +[data-theme="fresh"].dark .group:hover .group-hover\:text-blue-600 { + color: rgb(74, 222, 128) !important; +} +[data-theme="fresh"].dark .group-hover\:text-blue-400:hover, +[data-theme="fresh"].dark .group:hover .group-hover\:text-blue-400 { + color: rgb(74, 222, 128) !important; +} + +/* 侧边栏hover颜色适配 */ + +/* 极简主题侧边栏适配 */ +[data-theme="minimal"] .hover\:text-blue-600:hover { + color: rgb(82, 82, 82) !important; +} +[data-theme="minimal"] .hover\:text-blue-700:hover { + color: rgb(64, 64, 64) !important; +} +[data-theme="minimal"] .group-hover\:text-blue-600:hover, +[data-theme="minimal"] .group:hover .group-hover\:text-blue-600 { + color: rgb(82, 82, 82) !important; +} +[data-theme="minimal"] .group-data-\[active\=true\]\:text-blue-700, +[data-theme="minimal"] .group[data-active="true"] .group-data-\[active\=true\]\:text-blue-700 { + color: rgb(64, 64, 64) !important; +} +[data-theme="minimal"] .data-\[active\=true\]\:text-blue-700[data-active="true"] { + color: rgb(64, 64, 64) !important; +} +[data-theme="minimal"] .data-\[active\=true\]\:bg-blue-500\/20[data-active="true"] { + background-color: rgb(82, 82, 82, 0.2) !important; +} + +[data-theme="minimal"].dark .hover\:text-blue-400:hover { + color: rgb(163, 163, 163) !important; +} +[data-theme="minimal"].dark .hover\:text-blue-300:hover { + color: rgb(163, 163, 163) !important; +} +[data-theme="minimal"].dark .group-hover\:text-blue-400:hover, +[data-theme="minimal"].dark .group:hover .group-hover\:text-blue-400 { + color: rgb(163, 163, 163) !important; +} +[data-theme="minimal"].dark .group-data-\[active\=true\]\:text-blue-400, +[data-theme="minimal"].dark .group[data-active="true"] .group-data-\[active\=true\]\:text-blue-400 { + color: rgb(163, 163, 163) !important; +} +[data-theme="minimal"].dark .data-\[active\=true\]\:text-blue-400[data-active="true"] { + color: rgb(163, 163, 163) !important; +} +[data-theme="minimal"].dark .data-\[active\=true\]\:bg-blue-500\/10[data-active="true"] { + background-color: rgb(163, 163, 163, 0.1) !important; +} + +/* 暖色主题侧边栏适配 */ +[data-theme="warm"] .hover\:text-blue-600:hover { + color: rgb(234, 88, 12) !important; +} +[data-theme="warm"] .hover\:text-blue-700:hover { + color: rgb(194, 65, 12) !important; +} +[data-theme="warm"] .group-hover\:text-blue-600:hover, +[data-theme="warm"] .group:hover .group-hover\:text-blue-600 { + color: rgb(234, 88, 12) !important; +} +[data-theme="warm"] .group-data-\[active\=true\]\:text-blue-700, +[data-theme="warm"] .group[data-active="true"] .group-data-\[active\=true\]\:text-blue-700 { + color: rgb(194, 65, 12) !important; +} +[data-theme="warm"] .data-\[active\=true\]\:text-blue-700[data-active="true"] { + color: rgb(194, 65, 12) !important; +} +[data-theme="warm"] .data-\[active\=true\]\:bg-blue-500\/20[data-active="true"] { + background-color: rgb(234, 88, 12, 0.2) !important; +} + +[data-theme="warm"].dark .hover\:text-blue-400:hover { + color: rgb(251, 146, 60) !important; +} +[data-theme="warm"].dark .hover\:text-blue-300:hover { + color: rgb(251, 146, 60) !important; +} +[data-theme="warm"].dark .group-hover\:text-blue-400:hover, +[data-theme="warm"].dark .group:hover .group-hover\:text-blue-400 { + color: rgb(251, 146, 60) !important; +} +[data-theme="warm"].dark .group-data-\[active\=true\]\:text-blue-400, +[data-theme="warm"].dark .group[data-active="true"] .group-data-\[active\=true\]\:text-blue-400 { + color: rgb(251, 146, 60) !important; +} +[data-theme="warm"].dark .data-\[active\=true\]\:text-blue-400[data-active="true"] { + color: rgb(251, 146, 60) !important; +} +[data-theme="warm"].dark .data-\[active\=true\]\:bg-blue-500\/10[data-active="true"] { + background-color: rgb(251, 146, 60, 0.1) !important; +} + +/* 搜索页面聚焦状态和加载元素适配 */ + +/* 极简主题搜索页面适配 */ +[data-theme="minimal"] .focus\:ring-blue-400:focus { + box-shadow: 0 0 0 3px rgb(115, 115, 115, 0.5) !important; +} +[data-theme="minimal"] .focus\:ring-blue-400\/50:focus { + box-shadow: 0 0 0 3px rgb(115, 115, 115, 0.25) !important; +} +[data-theme="minimal"] .border-t-blue-500 { + border-top-color: rgb(115, 115, 115) !important; +} +[data-theme="minimal"] .border-b-2.border-blue-500 { + border-bottom-color: rgb(115, 115, 115) !important; +} +[data-theme="minimal"] .hover\:shadow-blue-500\/50:hover { + box-shadow: 0 25px 50px -12px rgb(115, 115, 115, 0.5) !important; +} + +[data-theme="minimal"].dark .focus\:ring-blue-400:focus { + box-shadow: 0 0 0 3px rgb(163, 163, 163, 0.5) !important; +} +[data-theme="minimal"].dark .focus\:ring-blue-400\/50:focus { + box-shadow: 0 0 0 3px rgb(163, 163, 163, 0.25) !important; +} +[data-theme="minimal"].dark .border-t-blue-500 { + border-top-color: rgb(163, 163, 163) !important; +} +[data-theme="minimal"].dark .border-b-2.border-blue-500 { + border-bottom-color: rgb(163, 163, 163) !important; +} +[data-theme="minimal"].dark .hover\:shadow-blue-500\/50:hover { + box-shadow: 0 25px 50px -12px rgb(163, 163, 163, 0.5) !important; +} + +/* 暖色主题搜索页面适配 */ +[data-theme="warm"] .focus\:ring-blue-400:focus { + box-shadow: 0 0 0 3px rgb(249, 115, 22, 0.5) !important; +} +[data-theme="warm"] .focus\:ring-blue-400\/50:focus { + box-shadow: 0 0 0 3px rgb(249, 115, 22, 0.25) !important; +} +[data-theme="warm"] .border-t-blue-500 { + border-top-color: rgb(249, 115, 22) !important; +} +[data-theme="warm"] .border-b-2.border-blue-500 { + border-bottom-color: rgb(249, 115, 22) !important; +} +[data-theme="warm"] .hover\:shadow-blue-500\/50:hover { + box-shadow: 0 25px 50px -12px rgb(249, 115, 22, 0.5) !important; +} + +[data-theme="warm"].dark .focus\:ring-blue-400:focus { + box-shadow: 0 0 0 3px rgb(251, 146, 60, 0.5) !important; +} +[data-theme="warm"].dark .focus\:ring-blue-400\/50:focus { + box-shadow: 0 0 0 3px rgb(251, 146, 60, 0.25) !important; +} +[data-theme="warm"].dark .border-t-blue-500 { + border-top-color: rgb(251, 146, 60) !important; +} +[data-theme="warm"].dark .border-b-2.border-blue-500 { + border-bottom-color: rgb(251, 146, 60) !important; +} +[data-theme="warm"].dark .hover\:shadow-blue-500\/50:hover { + box-shadow: 0 25px 50px -12px rgb(251, 146, 60, 0.5) !important; +} + +/* 播放页视频加载元素适配 */ + +/* 极简主题播放页加载适配 */ +[data-theme="minimal"] .from-blue-500 { + --tw-gradient-from: rgb(115, 115, 115) !important; +} +[data-theme="minimal"] .to-blue-600 { + --tw-gradient-to: rgb(82, 82, 82) !important; +} + +[data-theme="minimal"].dark .from-blue-500 { + --tw-gradient-from: rgb(163, 163, 163) !important; +} +[data-theme="minimal"].dark .to-blue-600 { + --tw-gradient-to: rgb(212, 212, 212) !important; +} + +/* 暖色主题播放页加载适配 */ +[data-theme="warm"] .from-blue-500 { + --tw-gradient-from: rgb(249, 115, 22) !important; +} +[data-theme="warm"] .to-blue-600 { + --tw-gradient-to: rgb(234, 88, 12) !important; +} + +[data-theme="warm"].dark .from-blue-500 { + --tw-gradient-from: rgb(251, 146, 60) !important; +} +[data-theme="warm"].dark .to-blue-600 { + --tw-gradient-to: rgb(253, 186, 116) !important; +} + +/* 清新主题搜索页面适配 */ +[data-theme="fresh"] .focus\:ring-blue-400:focus { + box-shadow: 0 0 0 3px rgb(63, 204, 113, 0.5) !important; +} +[data-theme="fresh"] .focus\:ring-blue-400\/50:focus { + box-shadow: 0 0 0 3px rgb(63, 204, 113, 0.25) !important; +} +[data-theme="fresh"] .border-t-blue-500 { + border-top-color: rgb(63, 204, 113) !important; +} +[data-theme="fresh"] .border-b-2.border-blue-500 { + border-bottom-color: rgb(63, 204, 113) !important; +} +[data-theme="fresh"] .hover\:shadow-blue-500\/50:hover { + box-shadow: 0 25px 50px -12px rgb(63, 204, 113, 0.5) !important; +} + +[data-theme="fresh"].dark .focus\:ring-blue-400:focus { + box-shadow: 0 0 0 3px rgb(74, 222, 128, 0.5) !important; +} +[data-theme="fresh"].dark .focus\:ring-blue-400\/50:focus { + box-shadow: 0 0 0 3px rgb(74, 222, 128, 0.25) !important; +} +[data-theme="fresh"].dark .border-t-blue-500 { + border-top-color: rgb(74, 222, 128) !important; +} +[data-theme="fresh"].dark .border-b-2.border-blue-500 { + border-bottom-color: rgb(74, 222, 128) !important; +} +[data-theme="fresh"].dark .hover\:shadow-blue-500\/50:hover { + box-shadow: 0 25px 50px -12px rgb(74, 222, 128, 0.5) !important; +} + +/* 清新主题播放页加载适配 */ +[data-theme="fresh"] .from-blue-500 { + --tw-gradient-from: rgb(63, 204, 113) !important; +} +[data-theme="fresh"] .to-blue-600 { + --tw-gradient-to: rgb(22, 163, 74) !important; +} + +[data-theme="fresh"].dark .from-blue-500 { + --tw-gradient-from: rgb(74, 222, 128) !important; +} +[data-theme="fresh"].dark .to-blue-600 { + --tw-gradient-to: rgb(134, 239, 172) !important; +} + +/* 极简主题 */ +[data-theme="minimal"] { + --color-primary-50: 250, 250, 250; + --color-primary-100: 245, 245, 245; + --color-primary-200: 229, 229, 229; + --color-primary-300: 212, 212, 212; + --color-primary-400: 163, 163, 163; + --color-primary-500: 115, 115, 115; + --color-primary-600: 82, 82, 82; + --color-primary-700: 64, 64, 64; + --color-primary-800: 38, 38, 38; + --color-primary-900: 23, 23, 23; + + --color-theme-bg: 255, 255, 255; + --color-theme-surface: 252, 252, 252; + --color-theme-accent: 82, 82, 82; + --color-theme-text: 23, 23, 23; + --color-theme-text-secondary: 115, 115, 115; + --color-theme-border: 229, 229, 229; + --color-theme-success: 34, 197, 94; + --color-theme-warning: 245, 158, 11; + --color-theme-error: 239, 68, 68; + --color-theme-info: 115, 115, 115; +} + +/* 极简主题蓝色元素覆盖 */ +[data-theme="minimal"] .text-blue-600 { + color: rgb(82, 82, 82) !important; +} +[data-theme="minimal"] .text-blue-700 { + color: rgb(64, 64, 64) !important; +} +[data-theme="minimal"] .text-blue-400 { + color: rgb(163, 163, 163) !important; +} +[data-theme="minimal"] .bg-blue-500\/20 { + background-color: rgb(82, 82, 82, 0.2) !important; +} +[data-theme="minimal"] .bg-blue-500\/10 { + background-color: rgb(82, 82, 82, 0.1) !important; +} +[data-theme="minimal"] .bg-blue-500 { + background-color: rgb(82, 82, 82) !important; +} +[data-theme="minimal"] .fill-blue-500, +[data-theme="minimal"] .hover\\:fill-blue-500:hover { + fill: rgb(82, 82, 82) !important; +} +[data-theme="minimal"] .border-blue-500\/30 { + border-color: rgb(82, 82, 82, 0.3) !important; +} +[data-theme="minimal"] .hover\\:text-blue-600:hover { + color: rgb(82, 82, 82) !important; +} +[data-theme="minimal"] .bg-blue-100 { + background-color: rgb(245, 245, 245) !important; +} +[data-theme="minimal"] .text-blue-800 { + color: rgb(38, 38, 38) !important; +} +[data-theme="minimal"] .hover\\:bg-blue-200:hover { + background-color: rgb(229, 229, 229) !important; +} + +[data-theme="minimal"].dark { + --color-theme-bg: 18, 18, 18; + --color-theme-surface: 28, 28, 28; + --color-theme-accent: 163, 163, 163; + --color-theme-text: 250, 250, 250; + --color-theme-text-secondary: 163, 163, 163; + --color-theme-border: 64, 64, 64; + --color-theme-success: 74, 222, 128; + --color-theme-warning: 251, 191, 36; + --color-theme-error: 248, 113, 113; + --color-theme-info: 163, 163, 163; +} + +/* 极简主题深色模式蓝色元素覆盖 */ +[data-theme="minimal"].dark .text-blue-600 { + color: rgb(163, 163, 163) !important; +} +[data-theme="minimal"].dark .text-blue-700 { + color: rgb(212, 212, 212) !important; +} +[data-theme="minimal"].dark .text-blue-400 { + color: rgb(163, 163, 163) !important; +} +[data-theme="minimal"].dark .bg-blue-500\/20 { + background-color: rgb(163, 163, 163, 0.2) !important; +} +[data-theme="minimal"].dark .bg-blue-500\/10 { + background-color: rgb(163, 163, 163, 0.1) !important; +} +[data-theme="minimal"].dark .bg-blue-500 { + background-color: rgb(163, 163, 163) !important; +} +[data-theme="minimal"].dark .fill-blue-500, +[data-theme="minimal"].dark .hover\\:fill-blue-500:hover { + fill: rgb(163, 163, 163) !important; +} +[data-theme="minimal"].dark .border-blue-500\/30 { + border-color: rgb(163, 163, 163, 0.3) !important; +} +[data-theme="minimal"].dark .hover\\:text-blue-400:hover { + color: rgb(163, 163, 163) !important; +} +[data-theme="minimal"].dark .bg-blue-900\/40 { + background-color: rgb(38, 38, 38, 0.4) !important; +} +[data-theme="minimal"].dark .hover\\:bg-blue-900\/60:hover { + background-color: rgb(38, 38, 38, 0.6) !important; +} +[data-theme="minimal"].dark .text-blue-200 { + color: rgb(212, 212, 212) !important; +} + +/* 暖色主题 */ +[data-theme="warm"] { + --color-primary-50: 255, 247, 237; + --color-primary-100: 255, 237, 213; + --color-primary-200: 254, 215, 170; + --color-primary-300: 253, 186, 116; + --color-primary-400: 251, 146, 60; + --color-primary-500: 249, 115, 22; + --color-primary-600: 234, 88, 12; + --color-primary-700: 194, 65, 12; + --color-primary-800: 154, 52, 18; + --color-primary-900: 124, 45, 18; + + --color-theme-bg: 255, 253, 247; + --color-theme-surface: 254, 250, 240; + --color-theme-accent: 234, 88, 12; + --color-theme-text: 124, 45, 18; + --color-theme-text-secondary: 154, 52, 18; + --color-theme-border: 253, 230, 138; + --color-theme-success: 22, 163, 74; + --color-theme-warning: 217, 119, 6; + --color-theme-error: 220, 38, 38; + --color-theme-info: 194, 65, 12; +} + +/* 暖色主题蓝色元素覆盖 */ +[data-theme="warm"] .text-blue-600 { + color: rgb(234, 88, 12) !important; +} +[data-theme="warm"] .text-blue-700 { + color: rgb(194, 65, 12) !important; +} +[data-theme="warm"] .text-blue-400 { + color: rgb(251, 146, 60) !important; +} +[data-theme="warm"] .bg-blue-500\/20 { + background-color: rgb(234, 88, 12, 0.2) !important; +} +[data-theme="warm"] .bg-blue-500\/10 { + background-color: rgb(234, 88, 12, 0.1) !important; +} +[data-theme="warm"] .bg-blue-500 { + background-color: rgb(234, 88, 12) !important; +} +[data-theme="warm"] .fill-blue-500, +[data-theme="warm"] .hover\\:fill-blue-500:hover { + fill: rgb(234, 88, 12) !important; +} +[data-theme="warm"] .border-blue-500\/30 { + border-color: rgb(234, 88, 12, 0.3) !important; +} +[data-theme="warm"] .hover\\:text-blue-600:hover { + color: rgb(234, 88, 12) !important; +} +[data-theme="warm"] .bg-blue-100 { + background-color: rgb(255, 237, 213) !important; +} +[data-theme="warm"] .text-blue-800 { + color: rgb(154, 52, 18) !important; +} +[data-theme="warm"] .hover\\:bg-blue-200:hover { + background-color: rgb(254, 215, 170) !important; +} + +[data-theme="warm"].dark { + --color-theme-bg: 28, 25, 23; + --color-theme-surface: 41, 37, 36; + --color-theme-accent: 251, 146, 60; + --color-theme-text: 254, 243, 199; + --color-theme-text-secondary: 214, 158, 46; + --color-theme-border: 87, 83, 78; + --color-theme-success: 74, 222, 128; + --color-theme-warning: 251, 191, 36; + --color-theme-error: 248, 113, 113; + --color-theme-info: 251, 146, 60; +} + +/* 暖色主题深色模式蓝色元素覆盖 */ +[data-theme="warm"].dark .text-blue-600 { + color: rgb(251, 146, 60) !important; +} +[data-theme="warm"].dark .text-blue-700 { + color: rgb(253, 186, 116) !important; +} +[data-theme="warm"].dark .text-blue-400 { + color: rgb(251, 146, 60) !important; +} +[data-theme="warm"].dark .bg-blue-500\/20 { + background-color: rgb(251, 146, 60, 0.2) !important; +} +[data-theme="warm"].dark .bg-blue-500\/10 { + background-color: rgb(251, 146, 60, 0.1) !important; +} +[data-theme="warm"].dark .bg-blue-500 { + background-color: rgb(251, 146, 60) !important; +} +[data-theme="warm"].dark .fill-blue-500, +[data-theme="warm"].dark .hover\\:fill-blue-500:hover { + fill: rgb(251, 146, 60) !important; +} +[data-theme="warm"].dark .border-blue-500\/30 { + border-color: rgb(251, 146, 60, 0.3) !important; +} +[data-theme="warm"].dark .hover\\:text-blue-400:hover { + color: rgb(251, 146, 60) !important; +} +[data-theme="warm"].dark .bg-blue-900\/40 { + background-color: rgb(154, 52, 18, 0.4) !important; +} +[data-theme="warm"].dark .hover\\:bg-blue-900\/60:hover { + background-color: rgb(154, 52, 18, 0.6) !important; +} +[data-theme="warm"].dark .text-blue-200 { + color: rgb(253, 186, 116) !important; +} + +/* 通用蓝色样式覆盖 - 用于其他可能的蓝色元素 */ + +/* 清新主题 */ +[data-theme="fresh"] { + --color-primary-50: 240, 253, 244; + --color-primary-100: 220, 252, 231; + --color-primary-200: 187, 247, 208; + --color-primary-300: 134, 239, 172; + --color-primary-400: 74, 222, 128; + --color-primary-500: 63, 204, 113; + --color-primary-600: 22, 163, 74; + --color-primary-700: 21, 128, 61; + --color-primary-800: 22, 101, 52; + --color-primary-900: 20, 83, 45; + + --color-theme-bg: 247, 253, 249; + --color-theme-surface: 240, 253, 244; + --color-theme-accent: 63, 204, 113; + --color-theme-text: 20, 83, 45; + --color-theme-text-secondary: 22, 101, 52; + --color-theme-border: 187, 247, 208; + --color-theme-success: 34, 197, 94; + --color-theme-warning: 245, 158, 11; + --color-theme-error: 239, 68, 68; + --color-theme-info: 63, 204, 113; +} + +/* 清新主题蓝色元素覆盖 */ +/* 注意:移除了通用的 .text-blue-* 覆盖,只保留有条件的状态覆盖 */ +[data-theme="fresh"] .bg-blue-500\/20 { + background-color: rgb(63, 204, 113, 0.2) !important; +} +[data-theme="fresh"] .bg-blue-500\/10 { + background-color: rgb(63, 204, 113, 0.1) !important; +} +[data-theme="fresh"] .bg-blue-500 { + background-color: rgb(63, 204, 113) !important; +} +[data-theme="fresh"] .hover\:fill-blue-500:hover { + fill: rgb(63, 204, 113) !important; +} +[data-theme="fresh"] .border-blue-500\/30 { + border-color: rgb(63, 204, 113, 0.3) !important; +} +[data-theme="fresh"] .hover\:text-blue-600:hover { + color: rgb(22, 163, 74) !important; +} +[data-theme="fresh"] .bg-blue-100 { + background-color: rgb(220, 252, 231) !important; +} +/* 注意:移除了 .text-blue-800 的通用覆盖 */ +[data-theme="fresh"] .hover\:bg-blue-200:hover { + background-color: rgb(187, 247, 208) !important; +} +[data-theme="fresh"] .border-blue-200 { + border-color: rgb(187, 247, 208) !important; +} +[data-theme="fresh"] .border-blue-300 { + border-color: rgb(134, 239, 172) !important; +} +[data-theme="fresh"] .border-blue-500 { + border-color: rgb(63, 204, 113) !important; +} +[data-theme="fresh"] .bg-blue-600 { + background-color: rgb(22, 163, 74) !important; +} +[data-theme="fresh"] .hover\:bg-blue-600:hover { + background-color: rgb(21, 128, 61) !important; +} +[data-theme="fresh"] .hover\:bg-blue-700:hover { + background-color: rgb(21, 128, 61) !important; +} +[data-theme="fresh"] .focus\:ring-blue-500:focus { + box-shadow: 0 0 0 3px rgb(63, 204, 113, 0.1) !important; +} +/* 版本面板和品牌元素适配 */ +[data-theme="fresh"] .bg-blue-100 { + background-color: rgb(220, 252, 231) !important; +} +[data-theme="fresh"] .text-blue-800 { + color: rgb(22, 101, 52) !important; +} +[data-theme="fresh"] .text-blue-700 { + color: rgb(21, 128, 61) !important; +} +[data-theme="fresh"] .text-blue-600 { + color: rgb(22, 163, 74) !important; +} +[data-theme="fresh"] .text-blue-500 { + color: rgb(34, 197, 94) !important; +} +/* 登录页面和按钮适配 */ +[data-theme="fresh"] .bg-blue-600 { + background-color: rgb(22, 163, 74) !important; +} +[data-theme="fresh"] .focus\:ring-blue-500:focus { + --tw-ring-color: rgb(34, 197, 94) !important; +} +[data-theme="fresh"] .bg-blue-50 { + background-color: rgb(240, 253, 244) !important; +} +[data-theme="fresh"] .border-blue-200 { + border-color: rgb(187, 247, 208) !important; +} +[data-theme="fresh"] .peer-focus\:text-blue-600:focus { + color: rgb(22, 163, 74) !important; +} +[data-theme="fresh"] .peer:focus ~ .peer-focus\:text-blue-600 { + color: rgb(22, 163, 74) !important; +} + +[data-theme="fresh"].dark { + --color-theme-bg: 20, 29, 24; + --color-theme-surface: 31, 41, 35; + --color-theme-accent: 74, 222, 128; + --color-theme-text: 240, 253, 244; + --color-theme-text-secondary: 187, 247, 208; + --color-theme-border: 75, 85, 79; + --color-theme-success: 74, 222, 128; + --color-theme-warning: 251, 191, 36; + --color-theme-error: 248, 113, 113; + --color-theme-info: 74, 222, 128; +} + +/* 清新主题深色模式蓝色元素覆盖 */ +/* 注意:移除了通用的 .text-blue-* 覆盖,只保留有条件的状态覆盖 */ +[data-theme="fresh"].dark .bg-blue-500\/20 { + background-color: rgb(74, 222, 128, 0.2) !important; +} +[data-theme="fresh"].dark .bg-blue-500\/10 { + background-color: rgb(74, 222, 128, 0.1) !important; +} +[data-theme="fresh"].dark .bg-blue-500 { + background-color: rgb(74, 222, 128) !important; +} +[data-theme="fresh"].dark .hover\:fill-blue-500:hover { + fill: rgb(74, 222, 128) !important; +} +[data-theme="fresh"].dark .border-blue-500\/30 { + border-color: rgb(74, 222, 128, 0.3) !important; +} +[data-theme="fresh"].dark .hover\:text-blue-400:hover { + color: rgb(74, 222, 128) !important; +} +[data-theme="fresh"].dark .bg-blue-900\/40 { + background-color: rgb(22, 101, 52, 0.4) !important; +} +[data-theme="fresh"].dark .hover\:bg-blue-900\/60:hover { + background-color: rgb(22, 101, 52, 0.6) !important; +} +/* 注意:移除了 .text-blue-200 的通用覆盖 */ +[data-theme="fresh"].dark .border-blue-200 { + border-color: rgb(22, 101, 52) !important; +} +[data-theme="fresh"].dark .border-blue-300 { + border-color: rgb(22, 163, 74) !important; +} +[data-theme="fresh"].dark .border-blue-500 { + border-color: rgb(74, 222, 128) !important; +} +[data-theme="fresh"].dark .bg-blue-600 { + background-color: rgb(74, 222, 128) !important; +} +[data-theme="fresh"].dark .hover\:bg-blue-600:hover { + background-color: rgb(134, 239, 172) !important; +} +[data-theme="fresh"].dark .hover\:bg-blue-700:hover { + background-color: rgb(134, 239, 172) !important; +} +[data-theme="fresh"].dark .focus\:ring-blue-500:focus { + box-shadow: 0 0 0 3px rgb(74, 222, 128, 0.1) !important; +} +/* 深色模式版本面板和品牌元素适配 */ +[data-theme="fresh"].dark .bg-blue-900\/30 { + background-color: rgb(22, 101, 52, 0.3) !important; +} +[data-theme="fresh"].dark .text-blue-300 { + color: rgb(134, 239, 172) !important; +} +[data-theme="fresh"].dark .text-blue-400 { + color: rgb(74, 222, 128) !important; +} +[data-theme="fresh"].dark .text-blue-500 { + color: rgb(74, 222, 128) !important; +} +/* 深色模式登录页面适配 */ +[data-theme="fresh"].dark .bg-blue-600 { + background-color: rgb(34, 197, 94) !important; +} +[data-theme="fresh"].dark .bg-blue-900\/20 { + background-color: rgb(20, 83, 45, 0.2) !important; +} +[data-theme="fresh"].dark .border-blue-800 { + border-color: rgb(22, 101, 52) !important; +} +[data-theme="fresh"].dark .peer-focus\:dark\:text-blue-400:focus { + color: rgb(74, 222, 128) !important; +} +[data-theme="fresh"].dark .peer:focus ~ .peer-focus\:dark\:text-blue-400 { + color: rgb(74, 222, 128) !important; +} +[data-theme="fresh"].dark .text-blue-200 { + color: rgb(134, 239, 172) !important; +} +[data-theme="fresh"].dark .bg-blue-800\/40 { + background-color: rgb(22, 101, 52, 0.4) !important; +} + +/* 极简主题额外覆盖 */ +[data-theme="minimal"] .bg-blue-50 { + background-color: rgb(250, 250, 250) !important; +} +[data-theme="minimal"] .hover\\:bg-blue-50:hover { + background-color: rgb(250, 250, 250) !important; +} +[data-theme="minimal"] .text-blue-500 { + color: rgb(115, 115, 115) !important; +} +/* 极简主题登录页面适配 */ +[data-theme="minimal"] .bg-blue-600 { + background-color: rgb(82, 82, 82) !important; +} +[data-theme="minimal"] .focus\:ring-blue-500:focus { + --tw-ring-color: rgb(115, 115, 115) !important; +} +[data-theme="minimal"] .bg-blue-50 { + background-color: rgb(250, 250, 250) !important; +} +[data-theme="minimal"] .border-blue-200 { + border-color: rgb(229, 229, 229) !important; +} +[data-theme="minimal"] .peer-focus\:text-blue-600:focus { + color: rgb(82, 82, 82) !important; +} +[data-theme="minimal"] .peer:focus ~ .peer-focus\:text-blue-600 { + color: rgb(82, 82, 82) !important; +} +[data-theme="minimal"] .hover\\:text-blue-500:hover { + color: rgb(115, 115, 115) !important; +} + +[data-theme="minimal"].dark .bg-blue-50 { + background-color: rgb(28, 28, 28) !important; +} +[data-theme="minimal"].dark .hover\\:bg-blue-50:hover { + background-color: rgb(28, 28, 28) !important; +} +[data-theme="minimal"].dark .text-blue-500 { + color: rgb(163, 163, 163) !important; +} +/* 极简主题深色模式登录页面适配 */ +[data-theme="minimal"].dark .bg-blue-600 { + background-color: rgb(115, 115, 115) !important; +} +[data-theme="minimal"].dark .bg-blue-900\/20 { + background-color: rgb(64, 64, 64, 0.2) !important; +} +[data-theme="minimal"].dark .border-blue-800 { + border-color: rgb(82, 82, 82) !important; +} +[data-theme="minimal"].dark .peer-focus\:dark\:text-blue-400:focus { + color: rgb(163, 163, 163) !important; +} +[data-theme="minimal"].dark .peer:focus ~ .peer-focus\:dark\:text-blue-400 { + color: rgb(163, 163, 163) !important; +} +[data-theme="minimal"].dark .hover\\:text-blue-500:hover { + color: rgb(163, 163, 163) !important; +} + +/* 暖色主题额外覆盖 */ +[data-theme="warm"] .bg-blue-50 { + background-color: rgb(255, 247, 237) !important; +} +[data-theme="warm"] .hover\\:bg-blue-50:hover { + background-color: rgb(255, 247, 237) !important; +} +[data-theme="warm"] .text-blue-500 { + color: rgb(249, 115, 22) !important; +} +[data-theme="warm"] .hover\\:text-blue-500:hover { + color: rgb(249, 115, 22) !important; +} + +[data-theme="warm"].dark .bg-blue-50 { + background-color: rgb(41, 37, 36) !important; +} +[data-theme="warm"].dark .hover\\:bg-blue-50:hover { + background-color: rgb(41, 37, 36) !important; +} +[data-theme="warm"].dark .text-blue-500 { + color: rgb(251, 146, 60) !important; +} +/* 暖色主题深色模式登录页面适配 */ +[data-theme="warm"].dark .bg-blue-600 { + background-color: rgb(251, 146, 60) !important; +} +[data-theme="warm"].dark .bg-blue-900\/20 { + background-color: rgb(154, 52, 18, 0.2) !important; +} +[data-theme="warm"].dark .border-blue-800 { + border-color: rgb(194, 65, 12) !important; +} +[data-theme="warm"].dark .peer-focus\:dark\:text-blue-400:focus { + color: rgb(251, 146, 60) !important; +} +[data-theme="warm"].dark .peer:focus ~ .peer-focus\:dark\:text-blue-400 { + color: rgb(251, 146, 60) !important; +} +[data-theme="warm"].dark .hover\\:text-blue-500:hover { + color: rgb(251, 146, 60) !important; +} + +/* 清新主题额外覆盖 */ +[data-theme="fresh"] .bg-blue-50 { + background-color: rgb(240, 253, 244) !important; +} +[data-theme="fresh"] .hover\\:bg-blue-50:hover { + background-color: rgb(240, 253, 244) !important; +} +/* 保留hover状态的覆盖 */ +[data-theme="fresh"] .hover\\:text-blue-500:hover { + color: rgb(63, 204, 113) !important; +} + +[data-theme="fresh"].dark .bg-blue-50 { + background-color: rgb(31, 41, 35) !important; +} +[data-theme="fresh"].dark .hover\\:bg-blue-50:hover { + background-color: rgb(31, 41, 35) !important; +} +/* 保留hover状态的覆盖 */ +[data-theme="fresh"].dark .hover\\:text-blue-500:hover { + color: rgb(74, 222, 128) !important; +} + +/* VideoCard 和其他组件的蓝色样式覆盖 */ + +/* 极简主题组件样式覆盖 */ +[data-theme="minimal"] .border-blue-200 { + border-color: rgb(229, 229, 229) !important; +} +[data-theme="minimal"] .text-blue-300 { + color: rgb(163, 163, 163) !important; +} + +[data-theme="minimal"].dark .bg-blue-900\/20 { + background-color: rgb(23, 23, 23, 0.2) !important; +} +[data-theme="minimal"].dark .border-blue-800 { + border-color: rgb(38, 38, 38) !important; +} +[data-theme="minimal"].dark .bg-blue-900\/30 { + background-color: rgb(23, 23, 23, 0.3) !important; +} + +/* 暖色主题组件样式覆盖 */ +[data-theme="warm"] .border-blue-200 { + border-color: rgb(253, 230, 138) !important; +} +[data-theme="warm"] .peer-focus\:text-blue-600:focus { + color: rgb(234, 88, 12) !important; +} +[data-theme="warm"] .peer:focus ~ .peer-focus\:text-blue-600 { + color: rgb(234, 88, 12) !important; +} +[data-theme="warm"] .text-blue-300 { + color: rgb(251, 146, 60) !important; +} + +[data-theme="warm"].dark .bg-blue-900\/20 { + background-color: rgb(124, 45, 18, 0.2) !important; +} +[data-theme="warm"].dark .border-blue-800 { + border-color: rgb(154, 52, 18) !important; +} +[data-theme="warm"].dark .bg-blue-900\/30 { + background-color: rgb(124, 45, 18, 0.3) !important; +} + +/* 补充更多蓝色元素覆盖 */ + +/* 极简主题补充覆盖 */ +[data-theme="minimal"] .text-blue-900 { + color: rgb(23, 23, 23) !important; +} +[data-theme="minimal"] .bg-blue-200 { + background-color: rgb(229, 229, 229) !important; +} +[data-theme="minimal"] .bg-blue-300 { + background-color: rgb(212, 212, 212) !important; +} +[data-theme="minimal"] .bg-blue-600 { + background-color: rgb(82, 82, 82) !important; +} +[data-theme="minimal"] .bg-blue-700 { + background-color: rgb(64, 64, 64) !important; +} +[data-theme="minimal"] .border-blue-100 { + border-color: rgb(245, 245, 245) !important; +} +[data-theme="minimal"] .border-blue-300 { + border-color: rgb(212, 212, 212) !important; +} +[data-theme="minimal"] .border-blue-500 { + border-color: rgb(115, 115, 115) !important; +} +[data-theme="minimal"] .hover\\:border-blue-300:hover { + border-color: rgb(212, 212, 212) !important; +} +[data-theme="minimal"] .hover\\:bg-blue-700:hover { + background-color: rgb(64, 64, 64) !important; +} +[data-theme="minimal"] .focus\\:ring-blue-500:focus { + box-shadow: 0 0 0 3px rgb(115, 115, 115, 0.1) !important; +} + +[data-theme="minimal"].dark .text-blue-900 { + color: rgb(250, 250, 250) !important; +} +[data-theme="minimal"].dark .bg-blue-200 { + background-color: rgb(64, 64, 64) !important; +} +[data-theme="minimal"].dark .bg-blue-300 { + background-color: rgb(82, 82, 82) !important; +} +[data-theme="minimal"].dark .bg-blue-600 { + background-color: rgb(163, 163, 163) !important; +} +[data-theme="minimal"].dark .bg-blue-700 { + background-color: rgb(212, 212, 212) !important; +} +[data-theme="minimal"].dark .border-blue-100 { + border-color: rgb(38, 38, 38) !important; +} +[data-theme="minimal"].dark .border-blue-300 { + border-color: rgb(82, 82, 82) !important; +} +[data-theme="minimal"].dark .border-blue-500 { + border-color: rgb(163, 163, 163) !important; +} +[data-theme="minimal"].dark .hover\\:border-blue-300:hover { + border-color: rgb(82, 82, 82) !important; +} +[data-theme="minimal"].dark .hover\\:bg-blue-700:hover { + background-color: rgb(212, 212, 212) !important; +} +[data-theme="minimal"].dark .focus\\:ring-blue-500:focus { + box-shadow: 0 0 0 3px rgb(163, 163, 163, 0.1) !important; +} + +/* 暖色主题补充覆盖 */ +[data-theme="warm"] .text-blue-900 { + color: rgb(124, 45, 18) !important; +} +[data-theme="warm"] .bg-blue-200 { + background-color: rgb(254, 215, 170) !important; +} +[data-theme="warm"] .bg-blue-300 { + background-color: rgb(253, 186, 116) !important; +} +[data-theme="warm"] .bg-blue-600 { + background-color: rgb(234, 88, 12) !important; +} +[data-theme="warm"] .bg-blue-700 { + background-color: rgb(194, 65, 12) !important; +} +[data-theme="warm"] .border-blue-100 { + border-color: rgb(255, 237, 213) !important; +} +[data-theme="warm"] .border-blue-300 { + border-color: rgb(253, 186, 116) !important; +} +[data-theme="warm"] .border-blue-500 { + border-color: rgb(249, 115, 22) !important; +} +[data-theme="warm"] .hover\\:border-blue-300:hover { + border-color: rgb(253, 186, 116) !important; +} +[data-theme="warm"] .hover\\:bg-blue-700:hover { + background-color: rgb(194, 65, 12) !important; +} +[data-theme="warm"] .focus\\:ring-blue-500:focus { + box-shadow: 0 0 0 3px rgb(249, 115, 22, 0.1) !important; +} + +[data-theme="warm"].dark .text-blue-900 { + color: rgb(254, 243, 199) !important; +} +[data-theme="warm"].dark .bg-blue-200 { + background-color: rgb(154, 52, 18) !important; +} +[data-theme="warm"].dark .bg-blue-300 { + background-color: rgb(194, 65, 12) !important; +} +[data-theme="warm"].dark .bg-blue-600 { + background-color: rgb(251, 146, 60) !important; +} +[data-theme="warm"].dark .bg-blue-700 { + background-color: rgb(253, 186, 116) !important; +} +[data-theme="warm"].dark .border-blue-100 { + border-color: rgb(87, 83, 78) !important; +} +[data-theme="warm"].dark .border-blue-300 { + border-color: rgb(194, 65, 12) !important; +} +[data-theme="warm"].dark .border-blue-500 { + border-color: rgb(251, 146, 60) !important; +} +[data-theme="warm"].dark .hover\\:border-blue-300:hover { + border-color: rgb(194, 65, 12) !important; +} +[data-theme="warm"].dark .hover\\:bg-blue-700:hover { + background-color: rgb(253, 186, 116) !important; +} +[data-theme="warm"].dark .focus\\:ring-blue-500:focus { + box-shadow: 0 0 0 3px rgb(251, 146, 60, 0.1) !important; +} + +/* 导航组件蓝色元素覆盖 - 直接覆盖具体元素,避免复杂选择器 */ + +/* 极简主题导航覆盖 */ +/* 选中状态背景和文字颜色 */ +[data-theme="minimal"] *[data-active="true"] { + background-color: rgb(82, 82, 82, 0.2) !important; + color: rgb(64, 64, 64) !important; +} +[data-theme="minimal"] .group[data-active="true"] svg { + color: rgb(64, 64, 64) !important; +} + +[data-theme="minimal"].dark *[data-active="true"] { + background-color: rgb(163, 163, 163, 0.1) !important; + color: rgb(163, 163, 163) !important; +} +[data-theme="minimal"].dark .group[data-active="true"] svg { + color: rgb(163, 163, 163) !important; +} + +/* hover状态文字颜色 */ +[data-theme="minimal"] .hover\\:text-blue-300:hover { + color: rgb(115, 115, 115) !important; +} +[data-theme="minimal"].dark .dark\\:hover\\:text-blue-300:hover { + color: rgb(163, 163, 163) !important; +} + +/* 暖色主题导航覆盖 */ +[data-theme="warm"] *[data-active="true"] { + background-color: rgb(234, 88, 12, 0.2) !important; + color: rgb(194, 65, 12) !important; +} +[data-theme="warm"] .group[data-active="true"] svg { + color: rgb(194, 65, 12) !important; +} + +[data-theme="warm"].dark *[data-active="true"] { + background-color: rgb(251, 146, 60, 0.1) !important; + color: rgb(251, 146, 60) !important; +} +[data-theme="warm"].dark .group[data-active="true"] svg { + color: rgb(251, 146, 60) !important; +} + +[data-theme="warm"] .hover\\:text-blue-300:hover { + color: rgb(234, 88, 12) !important; +} +[data-theme="warm"].dark .dark\\:hover\\:text-blue-300:hover { + color: rgb(251, 146, 60) !important; +} + +/* 清新主题侧边栏hover颜色适配 */ +[data-theme="fresh"] .hover\:text-blue-600:hover { + color: rgb(22, 163, 74) !important; +} +[data-theme="fresh"] .hover\:text-blue-700:hover { + color: rgb(21, 128, 61) !important; +} +[data-theme="fresh"] .group-hover\:text-blue-600:hover, +[data-theme="fresh"] .group:hover .group-hover\:text-blue-600 { + color: rgb(22, 163, 74) !important; +} +[data-theme="fresh"] .group-data-\[active\=true\]\:text-blue-700, +[data-theme="fresh"] .group[data-active="true"] .group-data-\[active\=true\]\:text-blue-700 { + color: rgb(21, 128, 61) !important; +} +[data-theme="fresh"] .data-\[active\=true\]\:text-blue-700[data-active="true"] { + color: rgb(21, 128, 61) !important; +} +[data-theme="fresh"] .data-\[active\=true\]\:bg-blue-500\20[data-active="true"] { + background-color: rgb(63, 204, 113, 0.2) !important; +} + +[data-theme="fresh"].dark .hover\:text-blue-400:hover { + color: rgb(74, 222, 128) !important; +} +[data-theme="fresh"].dark .hover\:text-blue-300:hover { + color: rgb(74, 222, 128) !important; +} +[data-theme="fresh"].dark .group-hover\:text-blue-400:hover, +[data-theme="fresh"].dark .group:hover .group-hover\:text-blue-400 { + color: rgb(74, 222, 128) !important; +} +[data-theme="fresh"].dark .group-data-\[active\=true\]\:text-blue-400, +[data-theme="fresh"].dark .group[data-active="true"] .group-data-\[active\=true\]\:text-blue-400 { + color: rgb(74, 222, 128) !important; +} +[data-theme="fresh"].dark .data-\[active\=true\]\:text-blue-400[data-active="true"] { + color: rgb(74, 222, 128) !important; +} +[data-theme="fresh"].dark .data-\[active\=true\]\:bg-blue-500\10[data-active="true"] { + background-color: rgb(74, 222, 128, 0.1) !important; +} +[data-theme="fresh"].dark .dark\\:hover\\:text-blue-300:hover { + color: rgb(74, 222, 128) !important; +} + +/* 清新主题导航覆盖 */ +/* 选中状态背景和文字颜色 */ +[data-theme="fresh"] *[data-active="true"] { + background-color: rgb(63, 204, 113, 0.2) !important; + color: rgb(21, 128, 61) !important; +} + +[data-theme="fresh"].dark *[data-active="true"] { + background-color: rgb(74, 222, 128, 0.1) !important; + color: rgb(74, 222, 128) !important; +} + +/* 视频卡片播放按钮和标签元素覆盖 */ + +/* 极简主题视频卡片覆盖 */ +[data-theme="minimal"] .fill-blue-500, +[data-theme="minimal"] .hover\\:fill-blue-500:hover { + fill: rgb(82, 82, 82) !important; +} +[data-theme="minimal"] .bg-blue-400 { + background-color: rgb(115, 115, 115) !important; +} +[data-theme="minimal"] .hover\\:bg-blue-600:hover { + background-color: rgb(64, 64, 64) !important; +} + +[data-theme="minimal"].dark .fill-blue-500, +[data-theme="minimal"].dark .hover\\:fill-blue-500:hover { + fill: rgb(163, 163, 163) !important; +} +[data-theme="minimal"].dark .hover\\:bg-blue-600:hover { + background-color: rgb(212, 212, 212) !important; +} + +/* 暖色主题视频卡片覆盖 */ +[data-theme="warm"] .fill-blue-500, +[data-theme="warm"] .hover\\:fill-blue-500:hover { + fill: rgb(234, 88, 12) !important; +} +[data-theme="warm"] .bg-blue-400 { + background-color: rgb(249, 115, 22) !important; +} +[data-theme="warm"] .hover\\:bg-blue-600:hover { + background-color: rgb(194, 65, 12) !important; +} + +[data-theme="warm"].dark .fill-blue-500, +[data-theme="warm"].dark .hover\\:fill-blue-500:hover { + fill: rgb(251, 146, 60) !important; +} +[data-theme="warm"].dark .hover\\:bg-blue-600:hover { + background-color: rgb(253, 186, 116) !important; +} + +/* 清新主题视频卡片覆盖 */ +[data-theme="fresh"] .hover\\:fill-blue-500:hover { + fill: rgb(63, 204, 113) !important; +} +[data-theme="fresh"] .bg-blue-400 { + background-color: rgb(74, 222, 128) !important; +} +[data-theme="fresh"] .hover\\:bg-blue-600:hover { + background-color: rgb(21, 128, 61) !important; +} + +[data-theme="fresh"].dark .hover\\:fill-blue-500:hover { + fill: rgb(74, 222, 128) !important; +} +[data-theme="fresh"].dark .hover\\:bg-blue-600:hover { + background-color: rgb(134, 239, 172) !important; } html, @@ -63,6 +1351,73 @@ html:not(.dark) body { background-attachment: fixed; } +/* 主题背景渐变覆盖 */ +[data-theme="minimal"]:not(.dark) body { + background: linear-gradient( + 180deg, + #fafafa 0%, + #f5f5f5 25%, + #f0f0f0 50%, + #ebebeb 75%, + #e5e5e5 100% + ); + background-attachment: fixed; +} + +[data-theme="warm"]:not(.dark) body { + background: linear-gradient( + 180deg, + #fffdf7 0%, + #fefaf0 25%, + #fef7e0 50%, + #fef3c7 75%, + #fde68a 100% + ); + background-attachment: fixed; +} + +[data-theme="fresh"]:not(.dark) body { + background: linear-gradient( + 180deg, + #f7fdf9 0%, + #f0fdf4 25%, + #ecfdf5 50%, + #d1fae5 75%, + #a7f3d0 100% + ); + background-attachment: fixed; +} + +.dark body { + background: linear-gradient( + 180deg, + rgb(var(--color-theme-bg)) 0%, + rgb(var(--color-theme-surface)) 100% + ); + background-attachment: fixed; +} + +/* 通用主题类 */ +.theme-transition { + transition: background-color 0.3s ease, border-color 0.3s ease, color 0.3s ease; +} + +.theme-card { + @apply bg-theme-surface border border-theme-border rounded-lg shadow-sm theme-transition; +} + +.theme-button { + @apply bg-theme-accent text-white border border-theme-accent rounded-lg px-4 py-2 hover:opacity-90 theme-transition; +} + +.theme-button-secondary { + @apply bg-theme-surface text-theme-text border border-theme-border rounded-lg px-4 py-2 hover:bg-theme-accent/10 theme-transition; +} + +.theme-input { + @apply bg-theme-surface text-theme-text border border-theme-border rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-theme-accent/50 theme-transition; +} + /* 自定义滚动条样式 */ ::-webkit-scrollbar { width: 8px; @@ -168,6 +1523,27 @@ html:not(.dark)::view-transition-new(root) { animation-name: slide-from-bottom; } +/* 确保自定义主题色类在所有主题下正确显示 */ +.bg-theme-accent { + background-color: rgb(var(--color-theme-accent)) !important; +} + +.text-theme-accent { + color: rgb(var(--color-theme-accent)) !important; +} + +.border-theme-accent { + border-color: rgb(var(--color-theme-accent)) !important; +} + +.hover\:bg-theme-accent\/5:hover { + background-color: rgb(var(--color-theme-accent), 0.05) !important; +} + +.hover\:bg-theme-accent\/10:hover { + background-color: rgb(var(--color-theme-accent), 0.1) !important; +} + /* 强制播放器内部的 video 元素高度为 100%,并保持内容完整显示 */ div[data-media-provider] video { height: 100%; diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 8fb5d66..9f72b19 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -11,6 +11,7 @@ import { GlobalErrorIndicator } from '../components/GlobalErrorIndicator'; import { SiteProvider } from '../components/SiteProvider'; import { ThemeProvider } from '../components/ThemeProvider'; import { ToastProvider } from '../components/Toast'; +import GlobalThemeLoader from '../components/GlobalThemeLoader'; const inter = Inter({ subsets: ['latin'] }); export const dynamic = 'force-dynamic'; @@ -110,6 +111,9 @@ export default async function RootLayout({ __html: `window.RUNTIME_CONFIG = ${JSON.stringify(runtimeConfig)};`, }} /> + + {/* 主题初始化脚本 - 立即执行避免主题闪烁 */} +