theme
This commit is contained in:
+51
-16
@@ -1,41 +1,76 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { ref, onMounted, shallowRef, markRaw, type Component } from 'vue'
|
||||
import TitleBar from '@/components/layout/TitleBar.vue'
|
||||
import Sidebar from '@/components/layout/Sidebar.vue'
|
||||
import ModuleContainer from '@/components/layout/ModuleContainer.vue'
|
||||
import ProxyModule from '@/modules/proxy/ProxyModule.vue'
|
||||
import ClipboardModule from '@/modules/clipboard/ClipboardModule.vue'
|
||||
import ScreenshotModule from '@/modules/screenshot/ScreenshotModule.vue'
|
||||
import MonitorModule from '@/modules/monitor/MonitorModule.vue'
|
||||
import DownloaderModule from '@/modules/downloader/DownloaderModule.vue'
|
||||
import FinderModule from '@/modules/finder/FinderModule.vue'
|
||||
import GeneralSettings from '@/modules/general/GeneralSettings.vue'
|
||||
import { useAppStore } from '@/stores/appStore'
|
||||
import { TooltipProvider } from '@/components/ui/tooltip'
|
||||
|
||||
const appStore = useAppStore()
|
||||
|
||||
const modules = [
|
||||
{ id: 'proxy', name: '代理管理', icon: 'proxy', component: ProxyModule },
|
||||
{ id: 'clipboard', name: '剪贴板', icon: 'clipboard', component: ClipboardModule },
|
||||
{ id: 'screenshot', name: '截图', icon: 'screenshot', component: ScreenshotModule },
|
||||
{ id: 'monitor', name: '硬件监控', icon: 'monitor', component: MonitorModule },
|
||||
{ id: 'downloader', name: '下载器', icon: 'downloader', component: DownloaderModule },
|
||||
{ id: 'finder', name: '文件搜索', icon: 'finder', component: FinderModule },
|
||||
{ id: 'settings', name: '常规设置', icon: 'settings', component: GeneralSettings }
|
||||
interface ModuleMeta {
|
||||
id: string
|
||||
name: string
|
||||
icon: string
|
||||
// 同步加载的模块直接传 Component;懒加载的传 import 工厂
|
||||
loader?: () => Promise<{ default: Component }>
|
||||
component?: Component
|
||||
}
|
||||
|
||||
// 常规设置是默认可见且轻量的,直接同步引入
|
||||
// 其他业务模块较大且首屏不一定需要,懒加载
|
||||
const modules: ModuleMeta[] = [
|
||||
{ id: 'proxy', name: '代理管理', icon: 'proxy', loader: () => import('@/modules/proxy/ProxyModule.vue') },
|
||||
{ id: 'clipboard', name: '剪贴板', icon: 'clipboard', loader: () => import('@/modules/clipboard/ClipboardModule.vue') },
|
||||
{ id: 'screenshot', name: '截图', icon: 'screenshot', loader: () => import('@/modules/screenshot/ScreenshotModule.vue') },
|
||||
{ id: 'monitor', name: '硬件监控', icon: 'monitor', loader: () => import('@/modules/monitor/MonitorModule.vue') },
|
||||
{ id: 'downloader', name: '下载器', icon: 'downloader', loader: () => import('@/modules/downloader/DownloaderModule.vue') },
|
||||
{ id: 'finder', name: '文件搜索', icon: 'finder', loader: () => import('@/modules/finder/FinderModule.vue') },
|
||||
{ id: 'settings', name: '常规设置', icon: 'settings', component: markRaw(GeneralSettings) }
|
||||
]
|
||||
|
||||
const activeModule = ref('proxy')
|
||||
|
||||
// 当前激活的组件实例(shallowRef 适合大组件)
|
||||
const activeComponent = shallowRef<Component | null>(null)
|
||||
|
||||
// 加载模块组件
|
||||
const loadModule = async (moduleId: string) => {
|
||||
const m = modules.find(mod => mod.id === moduleId)
|
||||
if (!m) {
|
||||
activeComponent.value = null
|
||||
return
|
||||
}
|
||||
if (m.component) {
|
||||
activeComponent.value = m.component
|
||||
return
|
||||
}
|
||||
if (m.loader) {
|
||||
try {
|
||||
const mod = await m.loader()
|
||||
// 缓存到 component,避免重复加载
|
||||
m.component = markRaw(mod.default)
|
||||
activeComponent.value = m.component
|
||||
} catch (e) {
|
||||
console.error(`Failed to load module ${moduleId}:`, e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const handleModuleChange = (moduleId: string) => {
|
||||
activeModule.value = moduleId
|
||||
loadModule(moduleId)
|
||||
}
|
||||
|
||||
const handleSearch = (moduleId: string) => {
|
||||
activeModule.value = moduleId
|
||||
loadModule(moduleId)
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
// 首次加载默认模块
|
||||
loadModule(activeModule.value)
|
||||
appStore.init().catch(e => console.error('App init error:', e))
|
||||
})
|
||||
</script>
|
||||
@@ -50,7 +85,7 @@ onMounted(() => {
|
||||
:active-module="activeModule"
|
||||
@change="handleModuleChange"
|
||||
/>
|
||||
<ModuleContainer :modules="modules" :active-module="activeModule" />
|
||||
<ModuleContainer :active-component="activeComponent" :active-module="activeModule" />
|
||||
</div>
|
||||
</div>
|
||||
</TooltipProvider>
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="37.07" height="36" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 198"><path fill="#41B883" d="M204.8 0H256L128 220.8L0 0h97.92L128 51.2L157.44 0h47.36Z"></path><path fill="#41B883" d="m0 0l128 220.8L256 0h-51.2L128 132.48L50.56 0H0Z"></path><path fill="#35495E" d="M50.56 0L128 133.12L204.8 0h-47.36L128 51.2L97.92 0H50.56Z"></path></svg>
|
||||
|
Before Width: | Height: | Size: 496 B |
@@ -1,33 +1,28 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import type { Component } from 'vue'
|
||||
import { ScrollArea } from '@/components/ui/scroll-area'
|
||||
|
||||
const props = defineProps<{
|
||||
modules: Array<{ id: string; name: string; icon: string; component: unknown }>
|
||||
defineProps<{
|
||||
activeComponent: Component | null
|
||||
activeModule: string
|
||||
}>()
|
||||
|
||||
const activeComponent = computed(() => {
|
||||
const module = props.modules.find(m => m.id === props.activeModule)
|
||||
return module?.component || null
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<main
|
||||
<main
|
||||
class="flex-1"
|
||||
:style="{ backgroundColor: 'var(--effect-bg)', backdropFilter: 'var(--effect-blur)' }"
|
||||
>
|
||||
<ScrollArea class="h-full w-full">
|
||||
<Transition name="fade-slide" mode="out-in">
|
||||
<div
|
||||
v-if="activeComponent"
|
||||
<div
|
||||
v-if="activeComponent"
|
||||
:key="activeModule"
|
||||
class="min-h-full w-full"
|
||||
>
|
||||
<component :is="activeComponent" />
|
||||
</div>
|
||||
<div
|
||||
<div
|
||||
v-else
|
||||
class="h-full w-full flex items-center justify-center text-muted-foreground"
|
||||
>
|
||||
@@ -53,4 +48,4 @@ const activeComponent = computed(() => {
|
||||
opacity: 0;
|
||||
transform: translateX(-20px);
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
+5
-4
@@ -2,14 +2,15 @@ import { createApp } from 'vue'
|
||||
import { createPinia } from 'pinia'
|
||||
import App from './App.vue'
|
||||
import './style.css'
|
||||
import { useSearchStore } from './stores/searchStore'
|
||||
|
||||
const app = createApp(App)
|
||||
const pinia = createPinia()
|
||||
|
||||
app.use(pinia)
|
||||
|
||||
const searchStore = useSearchStore()
|
||||
searchStore.initGlobalIndex()
|
||||
app.mount('#app')
|
||||
|
||||
app.mount('#app')
|
||||
// 应用挂载后再初始化搜索索引,不阻塞首屏渲染
|
||||
void import('./stores/searchStore').then(({ useSearchStore }) => {
|
||||
useSearchStore().initGlobalIndex()
|
||||
})
|
||||
@@ -7,12 +7,20 @@ import { Button } from '@/components/ui/button'
|
||||
import { useAppStore, type Theme, type EffectType } from '@/stores/appStore'
|
||||
import { useSearchStore } from '@/stores/searchStore'
|
||||
import { invoke } from '@tauri-apps/api/core'
|
||||
import { onMounted } from 'vue'
|
||||
import { computed, onMounted, onUnmounted, ref } from 'vue'
|
||||
|
||||
const appStore = useAppStore()
|
||||
const searchStore = useSearchStore()
|
||||
|
||||
// 始终反映系统真实的深浅色偏好,用于“跟随系统”卡片色块
|
||||
const systemDark = ref(window.matchMedia('(prefers-color-scheme: dark)').matches)
|
||||
const systemMediaQuery = window.matchMedia('(prefers-color-scheme: dark)')
|
||||
const handleSystemMediaChange = (e: MediaQueryListEvent) => {
|
||||
systemDark.value = e.matches
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
systemMediaQuery.addEventListener('change', handleSystemMediaChange)
|
||||
searchStore.registerAction('settings', 0, () => appStore.setTheme('light'))
|
||||
searchStore.registerAction('settings', 1, () => appStore.setTheme('dark'))
|
||||
searchStore.registerAction('settings', 2, () => appStore.setTheme('system'))
|
||||
@@ -22,21 +30,50 @@ onMounted(() => {
|
||||
searchStore.registerAction('settings', 6, () => appStore.toggleAutoStart())
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
systemMediaQuery.removeEventListener('change', handleSystemMediaChange)
|
||||
})
|
||||
|
||||
const themes: Array<{ id: Theme; name: string; color: string; icon: typeof Sun }> = [
|
||||
{ id: 'light', name: '浅色模式', color: '#f8fafc', icon: Sun },
|
||||
{ id: 'dark', name: '深色模式', color: '#1e293b', icon: Moon },
|
||||
{ id: 'system', name: '跟随系统', color: '#64748b', icon: Monitor }
|
||||
]
|
||||
|
||||
const effects: Array<{ id: EffectType; name: string; color: string; description: string }> = [
|
||||
{ id: 'normal', name: '普通模式', color: '#ffffff', description: '标准背景效果' },
|
||||
{ id: 'mica', name: 'Win 云母', color: '#e2e8f0', description: 'Windows 11 云母效果' },
|
||||
{ id: 'acrylic', name: 'Win 亚克力', color: '#cbd5e1', description: 'Windows 11 亚克力效果' }
|
||||
const effects: Array<{ id: EffectType; name: string; color: string; darkColor: string; description: string }> = [
|
||||
{ id: 'normal', name: '普通模式', color: '#ffffff', darkColor: '#0f172a', description: '标准背景效果' },
|
||||
{ id: 'mica', name: 'Win 云母', color: '#f1f5f9', darkColor: '#1e293b', description: 'Windows 11 云母效果' },
|
||||
{ id: 'acrylic', name: 'Win 亚克力', color: '#cbd5e1', darkColor: '#18181b', description: '仅跟随系统主题可用' }
|
||||
]
|
||||
|
||||
// 亚克力仅在"跟随系统"主题下能正确同步深浅色(无深浅枚举,依赖系统级主题广播刷新)
|
||||
const isAcrylicDisabled = () => appStore.theme !== 'system'
|
||||
|
||||
// 应用当前是否为深色模式(响应式,随主题与系统偏好变化)
|
||||
const isAppDark = computed(() => {
|
||||
if (appStore.theme === 'dark') return true
|
||||
if (appStore.theme === 'light') return false
|
||||
return systemDark.value
|
||||
})
|
||||
|
||||
// 色块阴影:浅色主题用黑色阴影;深色主题黑色阴影不可见,改用微弱亮色高光模拟凸起感
|
||||
const blockShadow = computed(() =>
|
||||
isAppDark.value
|
||||
? '0 4px 10px rgba(255, 255, 255, 0.08)'
|
||||
: '0 4px 10px rgba(0, 0, 0, 0.2)'
|
||||
)
|
||||
|
||||
// 效果卡片色块预览色:根据当前深浅模式返回对应颜色,尽量接近实际材质效果
|
||||
const getEffectColor = (effectId: EffectType) => {
|
||||
const eff = effects.find(e => e.id === effectId)
|
||||
if (!eff) return '#ffffff'
|
||||
return isAppDark.value ? eff.darkColor : eff.color
|
||||
}
|
||||
|
||||
const getThemeColor = (themeId: Theme) => {
|
||||
if (themeId === 'system') {
|
||||
return appStore.theme === 'dark' ? '#1e293b' : '#f8fafc'
|
||||
// 始终使用系统真实的深浅色,而非应用当前主题
|
||||
return systemDark.value ? '#1e293b' : '#f8fafc'
|
||||
}
|
||||
const theme = themes.find(t => t.id === themeId)
|
||||
return theme?.color || '#f8fafc'
|
||||
@@ -87,24 +124,27 @@ const quitApp = async () => {
|
||||
:class="appStore.theme === theme.id ? 'border-primary shadow-md' : 'border-border hover:border-primary/50'"
|
||||
@click="appStore.setTheme(theme.id)"
|
||||
>
|
||||
<div
|
||||
<div
|
||||
class="h-16 w-full flex items-center justify-center transition-all duration-300"
|
||||
:style="{ backgroundColor: getThemeColor(theme.id) }"
|
||||
:style="{
|
||||
backgroundColor: getThemeColor(theme.id),
|
||||
boxShadow: blockShadow
|
||||
}"
|
||||
>
|
||||
<component
|
||||
:is="theme.icon"
|
||||
<component
|
||||
:is="theme.icon"
|
||||
class="h-8 w-8 transition-colors duration-300"
|
||||
:class="theme.id === 'dark' || (theme.id === 'system' && appStore.theme === 'dark') ? 'text-white' : 'text-gray-800'"
|
||||
:class="theme.id === 'dark' || (theme.id === 'system' && systemDark) ? 'text-white' : 'text-gray-800'"
|
||||
/>
|
||||
</div>
|
||||
<div class="h-10 flex items-center justify-center bg-card">
|
||||
<div class="h-10 flex items-center justify-center">
|
||||
<span class="text-sm font-medium">{{ theme.name }}</span>
|
||||
</div>
|
||||
<div
|
||||
v-if="appStore.theme === theme.id"
|
||||
class="absolute top-2 right-2 w-5 h-5 bg-primary rounded-full flex items-center justify-center"
|
||||
class="absolute top-2 right-2 w-5 h-5 bg-primary dark:bg-white rounded-full flex items-center justify-center"
|
||||
>
|
||||
<svg class="w-3 h-3 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<svg class="w-3 h-3 text-white dark:text-slate-900" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="3" d="M5 13l4 4L19 7"></path>
|
||||
</svg>
|
||||
</div>
|
||||
@@ -125,34 +165,32 @@ const quitApp = async () => {
|
||||
<button
|
||||
v-for="effect in effects"
|
||||
:key="effect.id"
|
||||
class="group relative rounded-lg overflow-hidden border-2 transition-all duration-300 hover:shadow-lg"
|
||||
:class="appStore.effect === effect.id ? 'border-primary shadow-md' : 'border-border hover:border-primary/50'"
|
||||
:disabled="effect.id === 'acrylic' && isAcrylicDisabled()"
|
||||
class="group relative rounded-lg overflow-hidden border-2 transition-all duration-300"
|
||||
:class="[
|
||||
appStore.effect === effect.id ? 'border-primary shadow-md' : 'border-border',
|
||||
effect.id === 'acrylic' && isAcrylicDisabled()
|
||||
? 'opacity-50 cursor-not-allowed'
|
||||
: 'hover:shadow-lg hover:border-primary/50'
|
||||
]"
|
||||
@click="appStore.setEffect(effect.id)"
|
||||
>
|
||||
<div
|
||||
class="h-16 w-full flex items-center justify-center transition-all duration-300"
|
||||
:style="{
|
||||
backgroundColor: effect.id === 'normal' ? '#ffffff' : effect.id === 'mica' ? '#e2e8f040' : '#cbd5e120',
|
||||
backdropFilter: effect.id === 'mica' ? 'blur(12px)' : effect.id === 'acrylic' ? 'blur(20px)' : 'none'
|
||||
<div
|
||||
class="h-16 w-full transition-all duration-300"
|
||||
:style="{
|
||||
backgroundColor: getEffectColor(effect.id),
|
||||
boxShadow: blockShadow
|
||||
}"
|
||||
>
|
||||
<div
|
||||
class="w-12 h-12 rounded-lg border border-border/50"
|
||||
:style="{
|
||||
backgroundColor: effect.color,
|
||||
backdropFilter: effect.id === 'mica' ? 'blur(8px)' : effect.id === 'acrylic' ? 'blur(16px)' : 'none'
|
||||
}"
|
||||
></div>
|
||||
</div>
|
||||
<div class="h-14 flex flex-col items-center justify-center bg-card p-2">
|
||||
></div>
|
||||
<div class="h-14 flex flex-col items-center justify-center p-2">
|
||||
<span class="text-sm font-medium">{{ effect.name }}</span>
|
||||
<span class="text-xs text-muted-foreground">{{ effect.description }}</span>
|
||||
</div>
|
||||
<div
|
||||
v-if="appStore.effect === effect.id"
|
||||
class="absolute top-2 right-2 w-5 h-5 bg-primary rounded-full flex items-center justify-center"
|
||||
class="absolute top-2 right-2 w-5 h-5 bg-primary dark:bg-white rounded-full flex items-center justify-center"
|
||||
>
|
||||
<svg class="w-3 h-3 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<svg class="w-3 h-3 text-white dark:text-slate-900" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="3" d="M5 13l4 4L19 7"></path>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
+34
-13
@@ -1,6 +1,6 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { ref } from 'vue'
|
||||
import { getCurrentWindow, Effect } from '@tauri-apps/api/window'
|
||||
import { getCurrentWindow, Effect, EffectState } from '@tauri-apps/api/window'
|
||||
|
||||
export type Theme = 'light' | 'dark' | 'system'
|
||||
export type EffectType = 'normal' | 'mica' | 'acrylic'
|
||||
@@ -41,6 +41,11 @@ export const useAppStore = defineStore('app', () => {
|
||||
|
||||
const setTheme = async (newTheme: Theme) => {
|
||||
theme.value = newTheme
|
||||
// (仅系统级主题广播或更换效果时才刷新)。因此亚克力限制为仅"跟随系统"可用。
|
||||
// 切到非系统主题时若当前为亚克力,自动回退到云母,避免深浅色不同步。
|
||||
if (newTheme !== 'system' && effect.value === 'acrylic') {
|
||||
effect.value = 'mica'
|
||||
}
|
||||
await applyTheme()
|
||||
saveSettings()
|
||||
}
|
||||
@@ -88,23 +93,31 @@ export const useAppStore = defineStore('app', () => {
|
||||
|
||||
try {
|
||||
const tauriWindow = getCurrentWindow()
|
||||
|
||||
const isDark = root.classList.contains('dark')
|
||||
|
||||
// 先清除旧效果
|
||||
await tauriWindow.clearEffects()
|
||||
|
||||
if (effect.value === 'normal') {
|
||||
// 普通模式:不使用原生效果,用不透明背景色
|
||||
await tauriWindow.setBackgroundColor(isDark ? '#0f172a' : '#ffffff')
|
||||
} else if (effect.value === 'mica') {
|
||||
// 浅色用 micaLight,深色用 micaDark。
|
||||
// 注意:micaDark 仅在系统处于深色模式时才会渲染为深色(Windows 限制)。
|
||||
const micaEffect = (isDark ? 'micaDark' : 'micaLight') as unknown as Effect
|
||||
await tauriWindow.setEffects({
|
||||
effects: [Effect.Mica],
|
||||
color: isDark ? '#1e293b' : '#f1f5f9'
|
||||
effects: [micaEffect],
|
||||
state: EffectState.FollowsWindowActiveState,
|
||||
color: isDark ? [30, 41, 59, 0] : [248, 250, 252, 0]
|
||||
})
|
||||
// 窗口背景必须透明,原生效果才能显示
|
||||
await tauriWindow.setBackgroundColor('#00000000')
|
||||
} else if (effect.value === 'acrylic') {
|
||||
// Acrylic:亚克力效果,color 使用半透明 RGBA
|
||||
await tauriWindow.setEffects({
|
||||
effects: [Effect.Acrylic],
|
||||
color: isDark ? '#1e293b' : '#f1f5f9'
|
||||
state: EffectState.FollowsWindowActiveState,
|
||||
color: isDark ? [30, 41, 59, 0] : [248, 250, 252, 0]
|
||||
})
|
||||
await tauriWindow.setBackgroundColor('#00000000')
|
||||
}
|
||||
@@ -134,14 +147,22 @@ export const useAppStore = defineStore('app', () => {
|
||||
}
|
||||
|
||||
const init = async () => {
|
||||
loadSettings()
|
||||
await applyTheme()
|
||||
await applyEffect()
|
||||
|
||||
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)')
|
||||
mediaQuery.addEventListener('change', handleSystemThemeChange)
|
||||
|
||||
isInitialized.value = true
|
||||
try {
|
||||
loadSettings()
|
||||
// applyTheme 内部已调用 applyEffect,无需重复调用
|
||||
await applyTheme()
|
||||
|
||||
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)')
|
||||
mediaQuery.addEventListener('change', handleSystemThemeChange)
|
||||
|
||||
isInitialized.value = true
|
||||
} finally {
|
||||
try {
|
||||
await getCurrentWindow().show()
|
||||
} catch (e) {
|
||||
console.error('Failed to show window:', e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
+15
-21
@@ -1,5 +1,3 @@
|
||||
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');
|
||||
|
||||
@import "tailwindcss";
|
||||
@import "tw-animate-css";
|
||||
|
||||
@@ -116,30 +114,32 @@
|
||||
}
|
||||
|
||||
.effect-mica {
|
||||
--effect-bg: rgba(248, 250, 252, 0.75);
|
||||
--effect-blur: blur(16px);
|
||||
--effect-bg: transparent;
|
||||
--effect-blur: none;
|
||||
}
|
||||
|
||||
.dark.effect-mica {
|
||||
--effect-bg: rgba(15, 23, 42, 0.8);
|
||||
--effect-bg: transparent;
|
||||
--effect-blur: none;
|
||||
}
|
||||
|
||||
.effect-acrylic {
|
||||
--effect-bg: rgba(248, 250, 252, 0.55);
|
||||
--effect-blur: blur(24px);
|
||||
--effect-bg: transparent;
|
||||
--effect-blur: none;
|
||||
}
|
||||
|
||||
.dark.effect-acrylic {
|
||||
--effect-bg: rgba(15, 23, 42, 0.65);
|
||||
--effect-bg: transparent;
|
||||
--effect-blur: none;
|
||||
}
|
||||
|
||||
.effect-normal {
|
||||
--effect-bg: rgba(255, 255, 255, 0.98);
|
||||
--effect-blur: blur(0px);
|
||||
--effect-bg: rgba(255, 255, 255, 0.99);
|
||||
--effect-blur: none;
|
||||
}
|
||||
|
||||
.dark.effect-normal {
|
||||
--effect-bg: rgba(15, 23, 42, 0.98);
|
||||
--effect-bg: rgba(11, 17, 31, 0.99);
|
||||
}
|
||||
|
||||
@layer base {
|
||||
@@ -147,12 +147,15 @@
|
||||
@apply border-border outline-ring/50;
|
||||
}
|
||||
html, body {
|
||||
background: transparent;
|
||||
background: transparent !important;
|
||||
@apply text-foreground antialiased;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
font-feature-settings: 'tnum', 'lnum';
|
||||
}
|
||||
body {
|
||||
@apply bg-background text-foreground;
|
||||
}
|
||||
}
|
||||
|
||||
#app {
|
||||
@@ -161,13 +164,4 @@
|
||||
overflow: hidden;
|
||||
background: transparent;
|
||||
@apply antialiased;
|
||||
}
|
||||
|
||||
@layer base {
|
||||
* {
|
||||
@apply border-border outline-ring/50;
|
||||
}
|
||||
body {
|
||||
@apply bg-background text-foreground;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user