Files
Migu2.0/frontends/apps/simple-platform-vue/src/styles/themes.ts
T
zhaowei.huangandCursor 42978930ca feat: 迁入 MiGu.Server、平台前端与车辆列表 reflection 回退
从 Simple-FR 拆出 Platform.Server 并重命名为 MiGu.Server;frontends 源码与构建脚本迁入本仓库。地图监控在 projection/cars 失败或为空时回退 reflection 车辆列表;Simple 仓库已移除旧 Platform.Server。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-29 18:16:34 +08:00

337 lines
11 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 主题色板预设
*
* 设计原则:
* - 每个主题提供一组 CSS 变量,运行时通过 document.documentElement.style.setProperty 注入
* - 命名遵循 theme.css 中既有的 --mg-* 体系
* - 工业紫色 (industrial-purple) 为默认主题:紫蓝渐变,深蓝底 + 天蓝高光
*/
export interface ThemePreset {
id: string
name: string
description: string
/** 用于 UI 预览的代表色 */
preview: string
/** 强调高光,用于 UI 预览的次代表色 */
previewAccent: string
vars: Record<string, string>
}
export const DEFAULT_THEME_ID = 'fame-lavender'
export const THEMES: ThemePreset[] = [
{
id: 'fame-lavender',
name: '迷毂浅紫',
description: '参考 FAME 系统:深紫侧栏 + 浅紫白主区,柔和耐看,长时间使用不刺眼',
preview: '#7c3aed',
previewAccent: '#a855f7',
vars: {
// 主色保留紫色(与 FAME 一致),但 hover/accent 使用更明亮的 violet/purple
'--mg-primary': '#7c3aed',
'--mg-primary-rgb': '124, 58, 237',
'--mg-primary-hover': '#8b5cf6',
'--mg-primary-hover-rgb': '139, 92, 246',
'--mg-primary-active': '#5b21b6',
'--mg-accent': '#a855f7',
'--mg-accent-rgb': '168, 85, 247',
'--mg-primary-light-3': '#a78bfa',
'--mg-primary-light-5': '#c4b5fd',
'--mg-primary-light-7': '#ddd6fe',
'--mg-primary-light-8': '#ede9fe',
'--mg-primary-light-9': '#f5f3ff',
'--mg-primary-dark-2': '#6d28d9',
// 主区背景:浅紫白色(FAME content #f0eaf6 风格)
'--mg-bg-app-1': '#f5f0fb',
'--mg-bg-app-2': '#f0eaf6',
'--mg-bg-app-3': '#faf7fd',
'--mg-bg-app-deep-rgb': '240, 234, 246',
// 侧栏:FAME 深紫渐变 #2d1b69 -> #1a1040
'--mg-bg-aside-1': '#2d1b69',
'--mg-bg-aside-2': '#1a1040',
'--mg-bg-aside-rgb': '45, 27, 105',
// 卡片:白底(在 fame-lavender 专属规则中走纯 #fff
'--mg-bg-card-rgb': '255, 255, 255',
'--mg-bg-card-hi-rgb': '249, 246, 255',
'--mg-bg-card-darker-rgb':'245, 240, 251',
'--mg-shadow-rgb': '124, 58, 237',
// 文字:深紫标题 #2d1b69, 中灰正文 #606266
'--mg-text-tint-rgb': '45, 27, 105',
'--mg-text-hi-rgb': '96, 98, 102',
// 关闭装饰性 orb
'--mg-orb-a-opacity': '0',
'--mg-orb-b-opacity': '0',
'--mg-orb-c-opacity': '0'
}
},
{
id: 'industrial-purple',
name: '星云紫',
description: '科幻紫主色,辅以蓝紫渐变,磨砂玻璃 · 霓虹辉光',
preview: '#7c3aed',
previewAccent: '#c4b5fd',
vars: {
// ── 主色:明亮 violet(紫),主导整个画面 ──
'--mg-primary': '#7c3aed',
'--mg-primary-rgb': '124, 58, 237',
// hover/辉光:偏蓝紫 indigo,带来氛围流动感
'--mg-primary-hover': '#8b5cf6',
'--mg-primary-hover-rgb': '139, 92, 246',
'--mg-primary-active': '#5b21b6',
// accent:浅紫高光,边缘霓虹与点缀
'--mg-accent': '#c4b5fd',
'--mg-accent-rgb': '196, 181, 253',
'--mg-primary-light-3': '#9d6cf2',
'--mg-primary-light-5': '#b594f7',
'--mg-primary-light-7': '#6f4eab',
'--mg-primary-light-8': '#4c357a',
'--mg-primary-light-9': '#2d1f55',
'--mg-primary-dark-2': '#4c1d95',
// ── 背景:深紫黑底,带 indigo 余晖 ──
'--mg-bg-app-1': '#0e0a24',
'--mg-bg-app-2': '#1f1147',
'--mg-bg-app-3': '#06031a',
'--mg-bg-app-deep-rgb': '6, 3, 26',
'--mg-bg-aside-1': '#0c0820',
'--mg-bg-aside-2': '#03020e',
'--mg-bg-aside-rgb': '10, 6, 30',
'--mg-bg-card-rgb': '38, 24, 78',
'--mg-bg-card-hi-rgb': '58, 38, 110',
'--mg-bg-card-darker-rgb': '20, 12, 48',
'--mg-shadow-rgb': '8, 2, 24',
'--mg-text-tint-rgb': '242, 232, 255',
'--mg-text-hi-rgb': '220, 200, 252',
'--mg-orb-a-opacity': '0.55',
'--mg-orb-b-opacity': '0.50',
'--mg-orb-c-opacity': '0.40'
}
},
{
id: 'deep-azure',
name: '深邃蓝',
description: '科技感深蓝,沉静稳重',
preview: '#1565c0',
previewAccent: '#82b1ff',
vars: {
'--mg-primary': '#1565c0',
'--mg-primary-rgb': '21, 101, 192',
'--mg-primary-hover': '#1976d2',
'--mg-primary-hover-rgb': '25, 118, 210',
'--mg-primary-active': '#0d47a1',
'--mg-accent': '#82b1ff',
'--mg-accent-rgb': '130, 177, 255',
'--mg-primary-light-3': '#5a8fce',
'--mg-primary-light-5': '#83aedb',
'--mg-primary-light-7': '#adcde7',
'--mg-primary-light-8': '#c4dbed',
'--mg-primary-light-9': '#e3eef8',
'--mg-primary-dark-2': '#0d47a1',
'--mg-bg-app-1': '#051a3a',
'--mg-bg-app-2': '#0a2f6b',
'--mg-bg-app-3': '#020a1f',
'--mg-bg-app-deep-rgb': '2, 8, 26',
'--mg-bg-aside-1': '#06122a',
'--mg-bg-aside-2': '#02060f',
'--mg-bg-aside-rgb': '8, 18, 42',
'--mg-bg-card-rgb': '12, 36, 80',
'--mg-bg-card-hi-rgb': '18, 50, 110',
'--mg-bg-card-darker-rgb': '6, 18, 44',
'--mg-shadow-rgb': '2, 4, 14',
'--mg-text-tint-rgb': '218, 234, 252',
'--mg-text-hi-rgb': '170, 200, 240'
}
},
{
id: 'emerald-forge',
name: '翡翠绿',
description: '机械翡翠绿,沉稳活力',
preview: '#00796b',
previewAccent: '#80cbc4',
vars: {
'--mg-primary': '#00796b',
'--mg-primary-rgb': '0, 121, 107',
'--mg-primary-hover': '#00897b',
'--mg-primary-hover-rgb': '0, 137, 123',
'--mg-primary-active': '#004d40',
'--mg-accent': '#80cbc4',
'--mg-accent-rgb': '128, 203, 196',
'--mg-primary-light-3': '#4ca094',
'--mg-primary-light-5': '#79b9b0',
'--mg-primary-light-7': '#a6d2cc',
'--mg-primary-light-8': '#bfdfdb',
'--mg-primary-light-9': '#e1f0ee',
'--mg-primary-dark-2': '#004d40',
'--mg-bg-app-1': '#06241f',
'--mg-bg-app-2': '#0a4538',
'--mg-bg-app-3': '#020f0c',
'--mg-bg-app-deep-rgb': '2, 12, 10',
'--mg-bg-aside-1': '#061a16',
'--mg-bg-aside-2': '#020a08',
'--mg-bg-aside-rgb': '8, 26, 22',
'--mg-bg-card-rgb': '10, 50, 42',
'--mg-bg-card-hi-rgb': '14, 66, 56',
'--mg-bg-card-darker-rgb': '6, 28, 24',
'--mg-shadow-rgb': '2, 10, 8',
'--mg-text-tint-rgb': '220, 244, 240',
'--mg-text-hi-rgb': '170, 220, 210'
}
},
{
id: 'crimson-iron',
name: '熔铁赤',
description: '熔铁炉火般的暗红工业风',
preview: '#b71c1c',
previewAccent: '#ff8a80',
vars: {
'--mg-primary': '#b71c1c',
'--mg-primary-rgb': '183, 28, 28',
'--mg-primary-hover': '#d32f2f',
'--mg-primary-hover-rgb': '211, 47, 47',
'--mg-primary-active': '#8a0c0c',
'--mg-accent': '#ff8a80',
'--mg-accent-rgb': '255, 138, 128',
'--mg-primary-light-3': '#c95a5a',
'--mg-primary-light-5': '#d68585',
'--mg-primary-light-7': '#e4afaf',
'--mg-primary-light-8': '#edc8c8',
'--mg-primary-light-9': '#f7e6e6',
'--mg-primary-dark-2': '#8a0c0c',
'--mg-bg-app-1': '#2a0606',
'--mg-bg-app-2': '#4a0c0c',
'--mg-bg-app-3': '#150303',
'--mg-bg-app-deep-rgb': '20, 4, 4',
'--mg-bg-aside-1': '#200505',
'--mg-bg-aside-2': '#0c0202',
'--mg-bg-aside-rgb': '36, 6, 6',
'--mg-bg-card-rgb': '60, 10, 10',
'--mg-bg-card-hi-rgb': '80, 14, 14',
'--mg-bg-card-darker-rgb': '34, 5, 5',
'--mg-shadow-rgb': '10, 1, 1',
'--mg-text-tint-rgb': '252, 220, 220',
'--mg-text-hi-rgb': '240, 175, 175'
}
},
{
id: 'graphite-steel',
name: '石墨钢',
description: '中性冷灰,纯粹工业',
preview: '#455a64',
previewAccent: '#b0bec5',
vars: {
'--mg-primary': '#455a64',
'--mg-primary-rgb': '69, 90, 100',
'--mg-primary-hover': '#607d8b',
'--mg-primary-hover-rgb': '96, 125, 139',
'--mg-primary-active': '#263238',
'--mg-accent': '#b0bec5',
'--mg-accent-rgb': '176, 190, 197',
'--mg-primary-light-3': '#7a8a92',
'--mg-primary-light-5': '#9aa6ac',
'--mg-primary-light-7': '#bac2c7',
'--mg-primary-light-8': '#ccd2d6',
'--mg-primary-light-9': '#e8ebed',
'--mg-primary-dark-2': '#263238',
'--mg-bg-app-1': '#161e24',
'--mg-bg-app-2': '#243038',
'--mg-bg-app-3': '#0a0e12',
'--mg-bg-app-deep-rgb': '10, 14, 18',
'--mg-bg-aside-1': '#11181d',
'--mg-bg-aside-2': '#060a0d',
'--mg-bg-aside-rgb': '18, 26, 32',
'--mg-bg-card-rgb': '30, 42, 50',
'--mg-bg-card-hi-rgb': '42, 56, 66',
'--mg-bg-card-darker-rgb': '16, 22, 28',
'--mg-shadow-rgb': '4, 6, 10',
'--mg-text-tint-rgb': '226, 232, 238',
'--mg-text-hi-rgb': '186, 198, 210'
}
},
{
id: 'amber-forge',
name: '琥珀金',
description: '高对比的橙金调,警示与活力并存',
preview: '#e65100',
previewAccent: '#ffb74d',
vars: {
'--mg-primary': '#e65100',
'--mg-primary-rgb': '230, 81, 0',
'--mg-primary-hover': '#f57c00',
'--mg-primary-hover-rgb': '245, 124, 0',
'--mg-primary-active': '#bf360c',
'--mg-accent': '#ffb74d',
'--mg-accent-rgb': '255, 183, 77',
'--mg-primary-light-3': '#ec8344',
'--mg-primary-light-5': '#f2a474',
'--mg-primary-light-7': '#f7c4a3',
'--mg-primary-light-8': '#fad6bc',
'--mg-primary-light-9': '#fdeadd',
'--mg-primary-dark-2': '#bf360c',
'--mg-bg-app-1': '#2a1404',
'--mg-bg-app-2': '#4a2a0c',
'--mg-bg-app-3': '#150a02',
'--mg-bg-app-deep-rgb': '20, 10, 4',
'--mg-bg-aside-1': '#200f04',
'--mg-bg-aside-2': '#0c0602',
'--mg-bg-aside-rgb': '34, 16, 6',
'--mg-bg-card-rgb': '62, 32, 8',
'--mg-bg-card-hi-rgb': '82, 44, 12',
'--mg-bg-card-darker-rgb': '34, 16, 4',
'--mg-shadow-rgb': '10, 4, 1',
'--mg-text-tint-rgb': '252, 232, 210',
'--mg-text-hi-rgb': '240, 196, 140'
}
}
]
export function findTheme(id: string | undefined | null): ThemePreset {
if (!id) return THEMES[0]
return THEMES.find((t) => t.id === id) ?? THEMES[0]
}
/** 把主题变量写入 :root;多次调用幂等,会覆盖同名属性 */
export function applyThemeVars(preset: ThemePreset): void {
const root = document.documentElement
for (const [key, value] of Object.entries(preset.vars)) {
root.style.setProperty(key, value)
}
root.setAttribute('data-theme', preset.id)
}