Compare commits

..

3 Commits

Author SHA1 Message Date
cd4754cba5 feat: 增强系统身份标识和登录注册界面的视觉效果,优化用户体验 2026-08-28 11:23:51 +08:00
84568d5cd8 Merge pull request 'feat: 更新样式并增强深色主题的图表配置' (#1) from anhei into cyberpunk
Reviewed-on: http://192.168.28.10:18088/zhanghao/CMVR-BID/pulls/1
2026-08-27 11:44:31 +08:00
181cff4277 feat: 更新样式并增强深色主题的图表配置
- 调整了StatCards.vue中的字母间距,以提高可读性。
- 更新了RightBottomCharts.vue和RightTopCharts.vue中的图表样式,通过新的调色板和背景设置增强了视觉吸引力。
- 修改了图表中的工具提示和轴样式,以提高对比度和可见性。
- 将流程编辑器中的背景颜色更改为使用CSS变量,以保持一致性。
- 引入了新的网络主题风格,包括渐变和阴影,以提供沉浸式的暗色模式体验。
- 为各种组件添加了深色覆盖,以确保与新主题的兼容性。
2026-08-27 11:43:58 +08:00
25 changed files with 1716 additions and 89 deletions

View File

@ -0,0 +1,952 @@
// Immersive Dark Tech layer. Tokens live in variables.module.scss; this file
// is responsible for depth, glow, motion and component interaction states.
html.dark {
background: #0a0e17;
body,
#app,
.app-wrapper,
.main-container,
.app-main {
background-color: #0a0e17;
}
.app-wrapper,
.app-main {
background-image:
linear-gradient(rgba(6, 182, 212, 0.035) 1px, transparent 1px),
linear-gradient(90deg, rgba(6, 182, 212, 0.035) 1px, transparent 1px),
radial-gradient(circle at 78% 12%, rgba(168, 85, 247, 0.07), transparent 34%);
background-size: 48px 48px, 48px 48px, 100% 100%;
}
.app-main {
isolation: isolate;
}
.app-main::before {
position: absolute;
top: 0;
right: 0;
left: 0;
z-index: -1;
height: 1px;
content: "";
pointer-events: none;
background: linear-gradient(90deg, transparent, rgba(34, 211, 238, 0.55), rgba(168, 85, 247, 0.34), transparent);
box-shadow: 0 0 14px rgba(6, 182, 212, 0.35);
animation: cyber-scan 9s linear infinite;
}
.sidebar-container {
-webkit-backdrop-filter: blur(20px) saturate(125%);
backdrop-filter: blur(20px) saturate(125%);
background: rgba(10, 14, 23, 0.86) !important;
border-right: 1px solid rgba(6, 182, 212, 0.24);
box-shadow: 10px 0 34px rgba(0, 0, 0, 0.34), 1px 0 18px rgba(6, 182, 212, 0.08) !important;
}
.sidebar-logo-container {
background: rgba(10, 14, 23, 0.9) !important;
border-bottom: 1px solid rgba(6, 182, 212, 0.2);
}
.sidebar-logo-container .sidebar-logo {
filter: drop-shadow(0 0 7px rgba(34, 211, 238, 0.42));
}
.sidebar-logo-container .sidebar-title {
color: rgba(255, 255, 255, 0.9) !important;
text-shadow: 0 0 14px rgba(6, 182, 212, 0.22);
}
.sidebar-container .el-menu,
.sidebar-container .el-scrollbar,
.sidebar-container .scrollbar-wrapper {
background: transparent !important;
}
.sidebar-container .el-menu-item,
.sidebar-container .el-sub-menu__title {
min-height: 48px;
margin: 3px 10px;
border: 1px solid transparent;
border-radius: 5px;
transition: color 0.3s ease, background-color 0.3s ease, border-color 0.3s ease, box-shadow 0.3s ease;
}
.sidebar-container .el-menu-item:hover,
.sidebar-container .el-sub-menu__title:hover {
color: rgba(255, 255, 255, 0.9) !important;
background: rgba(6, 182, 212, 0.08) !important;
border-color: rgba(6, 182, 212, 0.18);
}
.sidebar-container .el-menu-item.is-active {
color: #a5f3fc !important;
background: linear-gradient(90deg, rgba(6, 182, 212, 0.18), rgba(168, 85, 247, 0.08)) !important;
border-color: rgba(34, 211, 238, 0.38);
box-shadow: inset 3px 0 0 #22d3ee, 0 0 18px rgba(6, 182, 212, 0.1);
text-shadow: 0 0 10px rgba(34, 211, 238, 0.32);
}
.navbar {
-webkit-backdrop-filter: blur(20px) saturate(125%);
backdrop-filter: blur(20px) saturate(125%);
background: rgba(10, 14, 23, 0.72) !important;
border-bottom: 1px solid rgba(6, 182, 212, 0.22);
box-shadow: 0 8px 30px rgba(0, 0, 0, 0.3), 0 1px 14px rgba(6, 182, 212, 0.08) !important;
}
.navbar .right-menu-item:hover,
.navbar .hamburger-container:hover {
color: #67e8f9;
background: rgba(6, 182, 212, 0.1) !important;
text-shadow: 0 0 12px rgba(6, 182, 212, 0.5);
}
.tags-view-container {
-webkit-backdrop-filter: blur(20px);
backdrop-filter: blur(20px);
background: rgba(10, 14, 23, 0.68) !important;
border-bottom-color: rgba(168, 85, 247, 0.2) !important;
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.22) !important;
}
.tags-view-container .tags-view-item {
background: rgba(20, 27, 45, 0.72) !important;
border-color: rgba(100, 116, 139, 0.24) !important;
transition: color 0.3s ease, border-color 0.3s ease, box-shadow 0.3s ease;
}
.tags-view-container .tags-view-item:hover {
color: rgba(255, 255, 255, 0.9) !important;
border-color: rgba(6, 182, 212, 0.42) !important;
}
.tags-view-container .tags-view-item.active {
color: #e6fbff !important;
background: linear-gradient(105deg, rgba(6, 182, 212, 0.88), rgba(93, 92, 226, 0.82)) !important;
border-color: rgba(103, 232, 249, 0.72) !important;
box-shadow: 0 0 16px rgba(6, 182, 212, 0.24), inset 0 1px 0 rgba(255, 255, 255, 0.18);
}
.app-container,
.el-card,
.el-dialog,
.el-drawer,
.el-popover,
.dashboard-panel,
.metric-card,
.row-cards .card,
.main-workspace .workspace-container > .left,
.main-workspace .workspace-container > .right,
.task-log,
.page-container > .left,
.page-container > .right {
-webkit-backdrop-filter: blur(20px) saturate(125%);
backdrop-filter: blur(20px) saturate(125%);
background-color: rgba(20, 27, 45, 0.78) !important;
background-image:
linear-gradient(145deg, rgba(6, 182, 212, 0.035), rgba(168, 85, 247, 0.025)),
repeating-linear-gradient(180deg, rgba(255, 255, 255, 0.012) 0, rgba(255, 255, 255, 0.012) 1px, transparent 1px, transparent 5px) !important;
border-color: rgba(6, 182, 212, 0.22) !important;
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.035), 0 16px 36px rgba(0, 0, 0, 0.2), 0 4px 15px rgba(6, 182, 212, 0.06) !important;
}
.metric-card,
.dashboard-panel,
.el-card,
.app-container {
transition: transform 0.3s ease, border-color 0.3s ease, box-shadow 0.3s ease;
}
.metric-card:hover,
.dashboard-panel:hover,
.el-card:hover {
border-color: rgba(34, 211, 238, 0.46) !important;
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.05), 0 18px 42px rgba(0, 0, 0, 0.26), 0 0 24px rgba(6, 182, 212, 0.1) !important;
}
.el-button--primary {
--el-button-text-color: #f5fdff;
--el-button-border-color: rgba(103, 232, 249, 0.64);
--el-button-hover-border-color: rgba(216, 180, 254, 0.76);
background: linear-gradient(110deg, #0891b2, #4f46c8) !important;
box-shadow: 0 0 16px rgba(6, 182, 212, 0.2), inset 0 1px 0 rgba(255, 255, 255, 0.18);
}
.el-button--primary:hover,
.el-button--primary:focus {
background: linear-gradient(110deg, #06b6d4, #7c3aed) !important;
box-shadow: 0 0 22px rgba(6, 182, 212, 0.28), 0 0 16px rgba(168, 85, 247, 0.12);
}
.el-table::before,
.el-table__inner-wrapper::before {
background-color: rgba(6, 182, 212, 0.18) !important;
}
.el-table th.el-table__cell {
color: rgba(255, 255, 255, 0.78) !important;
background: rgba(20, 27, 45, 0.94) !important;
border-bottom-color: rgba(6, 182, 212, 0.22) !important;
}
.el-table td.el-table__cell {
border-bottom-color: rgba(100, 116, 139, 0.16) !important;
transition: background-color 0.3s ease, box-shadow 0.3s ease;
}
.el-table__body tr:hover > td.el-table__cell {
background-color: rgba(6, 182, 212, 0.075) !important;
background-image: linear-gradient(90deg, rgba(6, 182, 212, 0.02), rgba(168, 85, 247, 0.08), rgba(6, 182, 212, 0.025)) !important;
box-shadow: inset 0 1px 0 rgba(34, 211, 238, 0.09), inset 0 -1px 0 rgba(168, 85, 247, 0.07);
}
.el-tabs__active-bar {
background: linear-gradient(90deg, #06b6d4, #a855f7);
box-shadow: 0 0 12px rgba(6, 182, 212, 0.48);
}
.el-dialog,
.el-drawer,
.el-popover,
.el-dropdown-menu {
border-color: rgba(6, 182, 212, 0.28) !important;
box-shadow: 0 22px 60px rgba(0, 0, 0, 0.48), 0 0 28px rgba(6, 182, 212, 0.1), 0 0 34px rgba(168, 85, 247, 0.06) !important;
}
.el-overlay {
background-color: rgba(3, 6, 14, 0.68);
-webkit-backdrop-filter: blur(6px);
backdrop-filter: blur(6px);
}
.state-dot,
.task-status-dot,
.status-dot,
.el-badge__content.is-dot {
box-shadow: 0 0 0 4px rgba(16, 185, 129, 0.08), 0 0 14px currentColor;
animation: cyber-pulse 2.4s ease-in-out infinite;
}
.control-point {
border-color: rgba(230, 251, 255, 0.9) !important;
background: rgba(6, 182, 212, 0.88) !important;
box-shadow: 0 0 0 4px rgba(6, 182, 212, 0.1), 0 0 18px rgba(6, 182, 212, 0.62) !important;
animation: cyber-marker-pulse 2.2s ease-in-out infinite;
}
.control-point.active {
background: rgba(168, 85, 247, 0.92) !important;
box-shadow: 0 0 0 5px rgba(168, 85, 247, 0.12), 0 0 22px rgba(168, 85, 247, 0.66) !important;
}
.home-dashboard .hero-panel {
border: 1px solid rgba(6, 182, 212, 0.28);
box-shadow: 0 20px 48px rgba(0, 0, 0, 0.34), 0 0 30px rgba(6, 182, 212, 0.08);
}
.home-dashboard .hero-panel::before {
background: linear-gradient(105deg, rgba(5, 9, 20, 0.94), rgba(10, 14, 23, 0.8) 55%, rgba(35, 18, 61, 0.68)) !important;
}
.home-dashboard .section-kicker {
color: #67e8f9;
text-shadow: 0 0 12px rgba(6, 182, 212, 0.42);
}
.home-dashboard .metric-icon--blue { color: #22d3ee !important; background: rgba(6, 182, 212, 0.12) !important; }
.home-dashboard .metric-icon--green { color: #34d399 !important; background: rgba(16, 185, 129, 0.12) !important; }
.home-dashboard .metric-icon--orange { color: #fbbf24 !important; background: rgba(251, 191, 36, 0.1) !important; }
.home-dashboard .metric-icon--red { color: #fb7185 !important; background: rgba(251, 113, 133, 0.1) !important; }
[data-echarts-instance] canvas,
div[_echarts_instance_] canvas {
filter: drop-shadow(0 0 5px rgba(6, 182, 212, 0.16));
}
::-webkit-scrollbar-track { background: rgba(10, 14, 23, 0.72); }
::-webkit-scrollbar-thumb {
background: linear-gradient(180deg, rgba(6, 182, 212, 0.72), rgba(168, 85, 247, 0.58));
border: 2px solid rgba(10, 14, 23, 0.82);
border-radius: 4px;
box-shadow: 0 0 8px rgba(6, 182, 212, 0.24);
}
.login,
.register {
position: relative;
isolation: isolate;
padding: 24px;
background-color: #0a0e17 !important;
background-image:
linear-gradient(105deg, rgba(3, 6, 14, 0.88), rgba(10, 14, 23, 0.76) 54%, rgba(40, 20, 68, 0.7)),
repeating-linear-gradient(180deg, rgba(103, 232, 249, 0.018) 0, rgba(103, 232, 249, 0.018) 1px, transparent 1px, transparent 5px),
url("../images/login-background.jpg") !important;
background-position: center;
background-size: cover, auto, cover;
}
.login::before,
.register::before {
display: none !important;
}
.login .login-form,
.register .register-form {
width: min(400px, 100%);
padding: 30px 34px 16px;
-webkit-backdrop-filter: blur(24px) saturate(135%);
backdrop-filter: blur(24px) saturate(135%);
background: linear-gradient(145deg, rgba(6, 182, 212, 0.06), rgba(168, 85, 247, 0.045)), rgba(10, 14, 23, 0.84) !important;
border: 1px solid rgba(6, 182, 212, 0.38);
border-radius: 8px !important;
box-shadow: 0 26px 80px rgba(0, 0, 0, 0.52), 0 0 32px rgba(6, 182, 212, 0.12), 0 0 42px rgba(168, 85, 247, 0.08);
}
.login .title,
.register .title {
color: rgba(255, 255, 255, 0.92) !important;
text-shadow: 0 0 18px rgba(6, 182, 212, 0.22);
}
.login .el-login-footer,
.register .el-register-footer {
color: rgba(203, 213, 225, 0.62) !important;
letter-spacing: 0 !important;
}
}
@keyframes cyber-scan {
0% { transform: translateY(0); opacity: 0; }
8% { opacity: 0.44; }
82% { opacity: 0.26; }
100% { transform: translateY(calc(100vh - 104px)); opacity: 0; }
}
@keyframes cyber-pulse {
0%, 100% { opacity: 0.78; filter: brightness(0.95); }
50% { opacity: 1; filter: brightness(1.3); }
}
@keyframes cyber-marker-pulse {
0%, 100% { opacity: 0.82; filter: brightness(0.94); }
50% { opacity: 1; filter: brightness(1.28); }
}
@media (max-width: 520px) {
html.dark .login,
html.dark .register { padding: 20px; }
html.dark .login .login-form,
html.dark .register .register-form { padding: 28px 24px 12px; }
}
@media (prefers-reduced-motion: reduce) {
html.dark .app-main::before,
html.dark .state-dot,
html.dark .task-status-dot,
html.dark .status-dot,
html.dark .el-badge__content.is-dot,
html.dark .control-point { animation: none; }
}
/* Global CMVR NEXUS shell. These selectors intentionally live outside the
* dark-mode scope so a stored light-mode preference still receives the same
* cyberpunk product language. */
:root {
color-scheme: dark;
--main-fill-bg: #070b14;
--surface-0: rgba(16, 23, 39, 0.9);
--surface-1: rgba(21, 31, 52, 0.92);
--surface-2: rgba(29, 42, 68, 0.94);
--line-subtle: rgba(34, 211, 238, 0.2);
--el-bg-color-page: #070b14;
--el-bg-color: #101727;
--el-bg-color-overlay: #151f34;
--el-fill-color-blank: #101727;
--el-fill-color: rgba(25, 38, 62, 0.92);
--el-fill-color-light: rgba(35, 52, 82, 0.82);
--el-fill-color-lighter: rgba(41, 60, 92, 0.62);
--el-color-primary: #22d3ee;
--el-color-primary-light-3: #67e8f9;
--el-color-primary-light-5: #a5f3fc;
--el-color-primary-light-9: rgba(34, 211, 238, 0.12);
--el-color-success: #34d399;
--el-color-warning: #fbbf24;
--el-color-danger: #fb7185;
--el-text-color-primary: rgba(241, 248, 255, 0.94);
--el-text-color-regular: rgba(211, 225, 242, 0.78);
--el-text-color-secondary: rgba(170, 192, 219, 0.62);
--el-text-color-placeholder: rgba(143, 169, 200, 0.5);
--el-border-color: rgba(34, 211, 238, 0.28);
--el-border-color-light: rgba(34, 211, 238, 0.2);
--el-border-color-lighter: rgba(109, 139, 177, 0.2);
--el-border-color-extra-light: rgba(109, 139, 177, 0.14);
--el-box-shadow-light: 0 14px 36px rgba(0, 0, 0, 0.34), 0 0 18px rgba(34, 211, 238, 0.08);
--sidebar-bg: rgba(7, 11, 20, 0.94);
--sidebar-text: rgba(211, 225, 242, 0.72);
--sidebar-logo-text: rgba(241, 248, 255, 0.95);
--navbar-bg: rgba(7, 11, 20, 0.78);
--navbar-text: rgba(211, 225, 242, 0.76);
--tags-bg: rgba(7, 11, 20, 0.72);
--tags-item-bg: rgba(16, 23, 39, 0.88);
--tags-item-border: rgba(34, 211, 238, 0.2);
--tags-item-text: rgba(211, 225, 242, 0.7);
--tags-item-hover: rgba(34, 211, 238, 0.12);
--tags-close-hover: rgba(244, 114, 182, 0.6);
}
html.dark {
--main-fill-bg: #070b14;
--el-bg-color-page: #070b14;
--el-bg-color: #101727;
--el-bg-color-overlay: #151f34;
}
html,
body,
#app {
min-height: 100%;
background: #070b14;
}
body {
color: var(--el-text-color-primary);
background-image:
linear-gradient(rgba(34, 211, 238, 0.025) 1px, transparent 1px),
linear-gradient(90deg, rgba(34, 211, 238, 0.025) 1px, transparent 1px),
radial-gradient(circle at 82% 4%, rgba(168, 85, 247, 0.12), transparent 32%),
radial-gradient(circle at 5% 90%, rgba(34, 211, 238, 0.07), transparent 28%);
background-size: 44px 44px, 44px 44px, 100% 100%, 100% 100%;
}
.app-wrapper {
isolation: isolate;
overflow: hidden;
background: transparent !important;
}
.app-wrapper::before {
position: fixed;
inset: 0;
z-index: -1;
pointer-events: none;
content: "";
background: linear-gradient(90deg, rgba(34, 211, 238, 0.03) 1px, transparent 1px), linear-gradient(rgba(34, 211, 238, 0.03) 1px, transparent 1px);
background-size: 88px 88px;
mask-image: linear-gradient(to bottom, black, transparent 90%);
}
.cyber-scanline {
position: fixed;
top: 0;
left: 0;
z-index: 1200;
width: 100%;
height: 1px;
pointer-events: none;
background: linear-gradient(90deg, transparent, rgba(34, 211, 238, 0.7), rgba(244, 114, 182, 0.45), transparent);
box-shadow: 0 0 14px rgba(34, 211, 238, 0.42);
animation: cyber-scanline 12s linear infinite;
}
.cyber-corner {
position: fixed;
z-index: 1100;
width: 82px;
height: 82px;
pointer-events: none;
opacity: 0.72;
}
.cyber-corner::before,
.cyber-corner::after {
position: absolute;
content: "";
background: #22d3ee;
box-shadow: 0 0 10px rgba(34, 211, 238, 0.65);
}
.cyber-corner--top { top: 16px; right: 18px; border-top: 1px solid rgba(34, 211, 238, 0.25); border-right: 1px solid rgba(34, 211, 238, 0.25); }
.cyber-corner--top::before { top: -1px; right: 0; width: 28px; height: 2px; }
.cyber-corner--top::after { top: 0; right: -1px; width: 2px; height: 28px; }
.cyber-corner--bottom { right: 18px; bottom: 16px; border-right: 1px solid rgba(244, 114, 182, 0.26); border-bottom: 1px solid rgba(244, 114, 182, 0.26); }
.cyber-corner--bottom::before { right: -1px; bottom: 0; width: 28px; height: 2px; background: #f472b6; box-shadow: 0 0 10px rgba(244, 114, 182, 0.65); }
.cyber-corner--bottom::after { right: -1px; bottom: 0; width: 2px; height: 28px; background: #f472b6; box-shadow: 0 0 10px rgba(244, 114, 182, 0.65); }
.main-container { background: transparent !important; }
.app-main {
background: transparent !important;
padding: 26px 30px 30px !important;
}
.fixed-header + .app-main { padding-top: 78px !important; }
.hasTagsView .fixed-header + .app-main { padding-top: 118px !important; }
.app-container {
position: relative;
padding: 22px !important;
overflow: hidden;
background: linear-gradient(145deg, rgba(16, 23, 39, 0.92), rgba(12, 19, 34, 0.84)) !important;
border: 1px solid rgba(34, 211, 238, 0.2) !important;
border-radius: 8px !important;
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04), 0 18px 44px rgba(0, 0, 0, 0.2) !important;
}
.app-container::before,
.el-card::before {
position: absolute;
top: 0;
left: 18px;
width: 46px;
height: 2px;
content: "";
background: #22d3ee;
box-shadow: 0 0 12px rgba(34, 211, 238, 0.8);
}
.el-card,
.el-dialog,
.el-drawer,
.el-popover,
.el-dropdown-menu {
position: relative;
color: var(--el-text-color-primary);
background: linear-gradient(145deg, rgba(19, 29, 48, 0.96), rgba(14, 22, 38, 0.94)) !important;
border: 1px solid rgba(34, 211, 238, 0.2) !important;
border-radius: 7px !important;
box-shadow: 0 18px 46px rgba(0, 0, 0, 0.28), 0 0 20px rgba(34, 211, 238, 0.06) !important;
}
.el-card__header,
.el-dialog__header,
.el-drawer__header {
color: var(--el-text-color-primary) !important;
background: rgba(34, 211, 238, 0.035) !important;
border-bottom-color: rgba(34, 211, 238, 0.16) !important;
}
.el-card__body { color: var(--el-text-color-regular); }
.el-button {
border-radius: 4px !important;
font-family: inherit;
letter-spacing: 0.02em;
}
.el-button--primary {
color: #06131a !important;
background: linear-gradient(105deg, #22d3ee, #a78bfa) !important;
border-color: #67e8f9 !important;
box-shadow: 0 0 18px rgba(34, 211, 238, 0.2), inset 0 1px 0 rgba(255, 255, 255, 0.36) !important;
}
.el-button--primary:hover,
.el-button--primary:focus { background: linear-gradient(105deg, #67e8f9, #c4b5fd) !important; box-shadow: 0 0 24px rgba(34, 211, 238, 0.34) !important; }
.el-button:not([class*="el-button--"]) { color: var(--el-text-color-regular); background: rgba(26, 41, 66, 0.58); border-color: rgba(109, 139, 177, 0.3); }
.el-button:not([class*="el-button--"]):hover { color: var(--el-color-primary-light-3); border-color: rgba(34, 211, 238, 0.55); background: rgba(34, 211, 238, 0.1); }
.el-input__wrapper,
.el-textarea__inner,
.el-select .el-input__wrapper,
.el-date-editor.el-input__wrapper {
color: var(--el-text-color-primary) !important;
background: rgba(8, 15, 28, 0.72) !important;
border: 1px solid rgba(109, 139, 177, 0.28) !important;
box-shadow: inset 0 0 0 1px transparent, 0 0 0 transparent !important;
}
.el-input__wrapper:hover,
.el-input__wrapper.is-focus,
.el-textarea__inner:focus { border-color: rgba(34, 211, 238, 0.68) !important; box-shadow: 0 0 0 1px rgba(34, 211, 238, 0.18), 0 0 16px rgba(34, 211, 238, 0.1) !important; }
.el-input__inner,
.el-textarea__inner { color: var(--el-text-color-primary) !important; }
.el-table {
color: var(--el-text-color-regular) !important;
background: rgba(10, 17, 30, 0.5) !important;
--el-table-header-bg-color: rgba(34, 211, 238, 0.07);
--el-table-tr-bg-color: transparent;
--el-table-row-hover-bg-color: rgba(34, 211, 238, 0.08);
--el-table-border-color: rgba(109, 139, 177, 0.18);
}
.el-table th.el-table__cell { color: #a5f3fc !important; background: rgba(34, 211, 238, 0.08) !important; border-bottom-color: rgba(34, 211, 238, 0.24) !important; font-family: "JetBrains Mono", Consolas, monospace; font-size: 11px; letter-spacing: 0.04em; text-transform: uppercase; }
.el-table td.el-table__cell { border-bottom-color: rgba(109, 139, 177, 0.14) !important; }
.el-table__body tr:hover > td.el-table__cell { background: rgba(34, 211, 238, 0.08) !important; }
.el-tag { border-radius: 3px !important; font-family: "JetBrains Mono", Consolas, monospace; font-size: 11px; }
.el-tabs__item { color: var(--el-text-color-secondary); }
.el-tabs__item.is-active,
.el-tabs__item:hover { color: var(--el-color-primary-light-3); }
.el-tabs__active-bar { background: linear-gradient(90deg, #22d3ee, #f472b6) !important; box-shadow: 0 0 10px rgba(34, 211, 238, 0.5); }
.el-pagination { --el-pagination-bg-color: transparent; --el-pagination-text-color: var(--el-text-color-secondary); --el-pagination-button-bg-color: rgba(16, 26, 44, 0.8); --el-pagination-hover-color: #67e8f9; }
.el-pagination button,
.el-pagination .el-pager li { border: 1px solid rgba(109, 139, 177, 0.2); border-radius: 3px; }
.el-pagination .el-pager li.is-active { color: #06131a; background: #22d3ee; border-color: #67e8f9; box-shadow: 0 0 12px rgba(34, 211, 238, 0.4); }
.el-form-item__label { color: var(--el-text-color-secondary) !important; }
.el-checkbox__label,
.el-radio__label { color: var(--el-text-color-regular) !important; }
.el-switch.is-checked .el-switch__core { background: #22d3ee !important; border-color: #67e8f9 !important; box-shadow: 0 0 12px rgba(34, 211, 238, 0.45); }
.el-breadcrumb__inner,
.el-breadcrumb__separator { color: var(--el-text-color-secondary) !important; }
.el-breadcrumb__inner.is-link:hover { color: var(--el-color-primary-light-3) !important; }
.navbar {
border-bottom: 1px solid rgba(34, 211, 238, 0.22) !important;
background: rgba(7, 11, 20, 0.78) !important;
box-shadow: 0 12px 30px rgba(0, 0, 0, 0.24), 0 1px 18px rgba(34, 211, 238, 0.08) !important;
}
.sidebar-container {
border-right: 1px solid rgba(34, 211, 238, 0.22) !important;
background: rgba(7, 11, 20, 0.94) !important;
box-shadow: 10px 0 40px rgba(0, 0, 0, 0.32), 1px 0 18px rgba(34, 211, 238, 0.08) !important;
}
.sidebar-container .el-menu-item,
.sidebar-container .el-sub-menu__title {
min-height: 46px !important;
margin: 4px 10px !important;
border: 1px solid transparent;
border-radius: 4px !important;
color: var(--sidebar-text) !important;
font-family: "JetBrains Mono", Consolas, monospace;
font-size: 12px;
letter-spacing: 0.02em;
transition: color 160ms ease, background 160ms ease, border-color 160ms ease, box-shadow 160ms ease;
}
.sidebar-container .el-menu-item:hover,
.sidebar-container .el-sub-menu__title:hover {
color: #a5f3fc !important;
background: rgba(34, 211, 238, 0.08) !important;
border-color: rgba(34, 211, 238, 0.22) !important;
}
.sidebar-container .el-menu-item.is-active {
color: #06131a !important;
background: linear-gradient(100deg, #22d3ee, #a78bfa) !important;
border-color: rgba(103, 232, 249, 0.8) !important;
box-shadow: 0 0 18px rgba(34, 211, 238, 0.26), inset 0 1px 0 rgba(255, 255, 255, 0.28);
}
.sidebar-container .el-menu-item.is-active .svg-icon,
.sidebar-container .el-menu-item.is-active .menu-title { color: #06131a !important; }
.sidebar-logo-container {
height: 78px !important;
line-height: 78px !important;
text-align: left !important;
padding: 0 18px;
border-bottom: 1px solid rgba(34, 211, 238, 0.2) !important;
background: linear-gradient(140deg, rgba(34, 211, 238, 0.08), transparent 72%) !important;
}
.sidebar-container.has-logo .el-scrollbar { height: calc(100% - 78px) !important; }
.sidebar-logo-container .sidebar-logo-link { display: flex !important; align-items: center; }
.sidebar-logo-container .sidebar-logo { width: 36px !important; height: 36px !important; margin-right: 12px !important; filter: drop-shadow(0 0 9px rgba(34, 211, 238, 0.6)); }
.sidebar-logo-container .sidebar-title { color: var(--el-text-color-primary) !important; font-family: "JetBrains Mono", Consolas, monospace !important; font-size: 13px !important; letter-spacing: 0.08em; }
.hideSidebar .sidebar-logo-container { padding: 0 !important; }
.hideSidebar .sidebar-logo-container .sidebar-logo-link { justify-content: center; }
.hideSidebar .sidebar-logo-container .sidebar-logo { margin-right: 0 !important; }
.tags-view-container {
height: 42px !important;
background: rgba(7, 11, 20, 0.72) !important;
border-bottom-color: rgba(34, 211, 238, 0.17) !important;
}
.tags-view-container .tags-view-item { height: 28px !important; line-height: 26px !important; color: var(--el-text-color-secondary) !important; background: rgba(16, 26, 44, 0.82) !important; border-color: rgba(109, 139, 177, 0.22) !important; border-radius: 3px !important; }
.tags-view-container .tags-view-item.active { color: #06131a !important; background: linear-gradient(100deg, #22d3ee, #a78bfa) !important; border-color: #67e8f9 !important; box-shadow: 0 0 14px rgba(34, 211, 238, 0.28); }
.home-dashboard .hero-panel {
border: 1px solid rgba(34, 211, 238, 0.42);
border-radius: 8px;
box-shadow: 0 24px 58px rgba(0, 0, 0, 0.38), 0 0 30px rgba(34, 211, 238, 0.12);
}
.home-dashboard .hero-panel::after {
position: absolute;
right: 22px;
bottom: 18px;
width: 180px;
height: 42px;
content: "01 // READY 02 // SYNC 03 // DEPLOY";
color: rgba(165, 243, 252, 0.5);
font-family: "JetBrains Mono", Consolas, monospace;
font-size: 9px;
letter-spacing: 0.08em;
line-height: 1.5;
text-align: right;
}
.home-dashboard .hero-content h1 { text-shadow: 0 0 22px rgba(34, 211, 238, 0.22); }
.home-dashboard .section-kicker { font-family: "JetBrains Mono", Consolas, monospace; letter-spacing: 0.14em; text-shadow: 0 0 12px rgba(34, 211, 238, 0.44); }
.home-dashboard .metric-card,
.home-dashboard .dashboard-panel { border-color: rgba(34, 211, 238, 0.22) !important; background: linear-gradient(145deg, rgba(20, 31, 52, 0.94), rgba(13, 22, 38, 0.9)) !important; }
.home-dashboard .metric-card:hover,
.home-dashboard .dashboard-panel:hover { border-color: rgba(103, 232, 249, 0.58) !important; box-shadow: 0 16px 34px rgba(0, 0, 0, 0.3), 0 0 22px rgba(34, 211, 238, 0.12) !important; }
.home-dashboard .metric-icon { border: 1px solid rgba(34, 211, 238, 0.24); box-shadow: inset 0 0 18px rgba(34, 211, 238, 0.08); }
.home-dashboard .task-list { padding: 0 !important; background: transparent !important; border: 0 !important; }
.contextmenu { color: var(--el-text-color-regular) !important; background: #111b2e !important; border-color: rgba(34, 211, 238, 0.3) !important; box-shadow: 0 18px 44px rgba(0, 0, 0, 0.4) !important; }
.contextmenu li:hover { color: #67e8f9; background: rgba(34, 211, 238, 0.1) !important; }
.login,
.register {
position: relative;
isolation: isolate;
background-color: #070b14 !important;
background-image: linear-gradient(105deg, rgba(5, 10, 20, 0.88), rgba(7, 11, 20, 0.72) 50%, rgba(37, 16, 63, 0.72)), repeating-linear-gradient(180deg, rgba(103, 232, 249, 0.02) 0, rgba(103, 232, 249, 0.02) 1px, transparent 1px, transparent 5px), url("../images/login-background.jpg") !important;
background-size: cover, auto, cover;
justify-content: flex-end !important;
padding: 42px clamp(42px, 9vw, 150px) 42px 48px;
}
.login::before,
.register::before { display: none !important; }
.login::after,
.register::after {
position: absolute;
inset: 24px;
z-index: -1;
pointer-events: none;
content: "SYSTEM ACCESS // AUTHORIZATION REQUIRED";
color: rgba(103, 232, 249, 0.3);
font-family: "JetBrains Mono", Consolas, monospace;
font-size: 10px;
letter-spacing: 0.16em;
}
.login .login-form,
.register .register-form {
width: min(410px, calc(100% - 32px)) !important;
padding: 34px 34px 18px !important;
background: linear-gradient(145deg, rgba(34, 211, 238, 0.08), rgba(167, 139, 250, 0.06)), rgba(10, 17, 30, 0.9) !important;
border: 1px solid rgba(34, 211, 238, 0.42) !important;
border-radius: 7px !important;
box-shadow: 0 28px 90px rgba(0, 0, 0, 0.6), 0 0 34px rgba(34, 211, 238, 0.14) !important;
}
.access-brand {
position: absolute;
top: 50%;
left: clamp(48px, 8vw, 136px);
width: min(560px, 44vw);
transform: translateY(-50%);
color: var(--el-text-color-primary);
}
.access-state,
.access-code,
.access-metrics,
.form-kicker {
font-family: "JetBrains Mono", Consolas, monospace;
letter-spacing: 0.1em;
}
.access-state {
display: inline-flex;
align-items: center;
gap: 9px;
margin-bottom: 32px;
color: #34d399;
font-size: 10px;
}
.access-state span {
width: 7px;
height: 7px;
border-radius: 50%;
background: #34d399;
box-shadow: 0 0 14px rgba(52, 211, 153, 0.8);
animation: cyber-pulse 2.4s ease-in-out infinite;
}
.access-code { margin: 0 0 12px; color: #67e8f9; font-size: 11px; }
.access-brand h1 { margin: 0; color: rgba(241, 248, 255, 0.96); font-size: clamp(48px, 6.2vw, 88px); font-weight: 300; line-height: 0.9; text-shadow: 0 0 30px rgba(34, 211, 238, 0.16); }
.access-brand h1 strong { color: transparent; font-weight: 800; -webkit-text-stroke: 1px rgba(165, 243, 252, 0.9); text-shadow: 0 0 24px rgba(34, 211, 238, 0.18); }
.access-description { max-width: 520px; margin: 28px 0; color: rgba(211, 225, 242, 0.64); font-size: 14px; line-height: 1.8; }
.access-metrics { display: flex; gap: 22px; color: rgba(165, 243, 252, 0.42); font-size: 9px; }
.form-kicker { margin-bottom: 12px; color: rgba(103, 232, 249, 0.62); font-size: 9px; }
.login .title,
.register .title { color: var(--el-text-color-primary) !important; font-family: "JetBrains Mono", Consolas, monospace; letter-spacing: 0.05em; text-shadow: 0 0 18px rgba(34, 211, 238, 0.38); }
.login .el-login-footer,
.register .el-register-footer { color: rgba(170, 192, 219, 0.56) !important; font-family: "JetBrains Mono", Consolas, monospace; letter-spacing: 0.08em !important; }
@keyframes cyber-scanline {
0% { transform: translateY(0); opacity: 0; }
10% { opacity: 0.72; }
90% { opacity: 0.2; }
100% { transform: translateY(100vh); opacity: 0; }
}
@media (max-width: 1100px) {
.login,
.register { justify-content: center !important; padding: 28px; }
.access-brand { display: none; }
}
@media (max-width: 768px) {
.app-main { padding: 18px !important; }
.fixed-header + .app-main,
.hasTagsView .fixed-header + .app-main { padding-top: 72px !important; }
.cyber-corner { display: none; }
.login,
.register { justify-content: center !important; padding: 20px; }
.access-brand { display: none; }
}
@media (prefers-reduced-motion: reduce) {
.cyber-scanline,
.access-state span { animation: none; }
}
/* Legacy business surfaces that still carry light-mode literals in their
* scoped component styles. Keep their data and interaction untouched while
* bringing the rendered surfaces into the NEXUS shell. */
.tree-sidebar,
.tree-panel,
.tree-container,
.category-tree,
.corpus-list,
.task-list,
.right-panel,
.left-panel,
.status-strip,
.robot-container,
.head-control,
.microphone-container,
.audio-player,
.page-container > .left,
.page-container > .right,
.evaluation-metrics > .left,
.evaluation-metrics > .right,
.schemaList,
.info,
.btn-container {
color: var(--el-text-color-regular) !important;
background: linear-gradient(145deg, rgba(19, 29, 48, 0.94), rgba(12, 20, 35, 0.9)) !important;
border-color: rgba(34, 211, 238, 0.2) !important;
}
.tree-header,
.collapse-button-container,
.task-item,
.task,
.schema,
.preset-panel,
.current-display,
.speaker-container,
.audioItem,
.audio-item,
.voice-btn,
.output-row,
.queue-step,
.input__container,
.condition-summary,
.condition-summary__item {
color: var(--el-text-color-regular) !important;
background: rgba(21, 31, 52, 0.92) !important;
border-color: rgba(109, 139, 177, 0.22) !important;
}
.tree-node,
.node-label,
.task-title,
.notice-title,
.notice-item-title,
.flow-heading__name,
.node-name,
.title_container,
.subTitle { color: var(--el-text-color-primary) !important; }
.tree-wrap .el-tree-node__content:hover,
.task-item:hover,
.task:hover,
.schema:hover,
.audio-item:hover,
.notice-item:hover { background: rgba(34, 211, 238, 0.1) !important; }
.flow-node-card,
.node__container,
.node__box,
.group__container,
.outer-node,
.component-library,
.library-header,
.single-node-station-tools,
.custom-table,
.popup-main,
.popup-result {
color: var(--el-text-color-regular) !important;
background: rgba(16, 25, 43, 0.94) !important;
border-color: rgba(34, 211, 238, 0.2) !important;
}
.flow-node-card input,
.flow-node-card textarea,
.node__box input,
.node__box textarea,
.custom-table input,
.custom-table textarea { color: var(--el-text-color-primary) !important; background: rgba(7, 14, 26, 0.72) !important; border-color: rgba(109, 139, 177, 0.28) !important; }
.notice-popover .notice-header,
.notice-popover .notice-item { background: rgba(16, 25, 43, 0.96) !important; border-color: rgba(34, 211, 238, 0.16) !important; color: var(--el-text-color-primary) !important; }
.notice-popover .notice-item-title { color: var(--el-text-color-primary) !important; }
.notice-popover .notice-item-date,
.notice-popover .notice-loading,
.notice-popover .notice-empty { color: var(--el-text-color-secondary) !important; }
/* Flow designer chrome uses a self-contained Element layout and therefore
* needs an explicit shell treatment in addition to the generic card rules. */
.page .page__container,
.page .page__container .container,
.page .page__container .el-main { background: #080f1d !important; }
.page .page__container .el-header {
color: var(--el-text-color-primary) !important;
background: linear-gradient(100deg, rgba(16, 28, 48, 0.98), rgba(10, 18, 33, 0.96)) !important;
border-bottom-color: rgba(34, 211, 238, 0.28) !important;
}
.page .page__container .el-aside {
color: var(--el-text-color-regular) !important;
background: rgba(12, 21, 37, 0.98) !important;
border-right-color: rgba(34, 211, 238, 0.2) !important;
}
.page .page__container .canvas-toolbar,
.page .page__container .vue-flow__controls {
color: var(--el-text-color-regular) !important;
background: rgba(13, 23, 40, 0.94) !important;
border-color: rgba(34, 211, 238, 0.32) !important;
box-shadow: 0 12px 30px rgba(0, 0, 0, 0.38), 0 0 18px rgba(34, 211, 238, 0.1) !important;
}
.page .page__container .canvas-toolbar .el-button { color: var(--el-text-color-regular) !important; }
.page .page__container .canvas-toolbar .el-button:hover { color: #67e8f9 !important; background: rgba(34, 211, 238, 0.12) !important; }
.page .page__container .flow__container .vue-flow__background { background: #080f1d !important; }
.page .page__container .flow__container .vue-flow__edge-path,
.page .page__container .flow__container .vue-flow__connection-path { stroke: #22d3ee !important; filter: drop-shadow(0 0 3px rgba(34, 211, 238, 0.58)); }
::-webkit-scrollbar { width: 7px; height: 7px; }
::-webkit-scrollbar-track { background: rgba(7, 11, 20, 0.72); }
::-webkit-scrollbar-thumb { background: linear-gradient(180deg, rgba(34, 211, 238, 0.72), rgba(167, 139, 250, 0.72)); border: 2px solid rgba(7, 11, 20, 0.82); border-radius: 4px; }
.el-loading-mask { background: rgba(7, 11, 20, 0.78) !important; }
.el-loading-spinner .path { stroke: #22d3ee !important; }
.el-message-box { background: #111b2e !important; border-color: rgba(34, 211, 238, 0.34) !important; }
.el-message-box__title,
.el-message-box__message { color: var(--el-text-color-primary) !important; }
@media (max-width: 560px) {
.sidebar-logo-container { padding: 0 14px; }
.sidebar-logo-container .sidebar-copy small { display: none; }
}

View File

@ -0,0 +1,300 @@
// Scoped compatibility for business views that still contain light literals.
html.dark {
.tree-sidebar,
.tree-panel,
.tree-container,
.category-tree,
.corpus-list,
.task-list,
.right-panel,
.left-panel {
color: var(--el-text-color-regular);
background: var(--surface-0) !important;
border-color: var(--line-subtle) !important;
}
.tree-header,
.collapse-button-container,
.tree-sidebar.collapsed .collapse-button-container {
color: var(--el-text-color-regular) !important;
background: var(--surface-1) !important;
border-color: var(--line-subtle) !important;
}
.tree-title,
.tree-node,
.node-label { color: var(--el-text-color-primary) !important; }
.tree-action-icon:hover,
.collapse-button:hover,
.tree-wrap .el-tree-node__content:hover {
color: var(--el-color-primary) !important;
background: var(--surface-2) !important;
}
.tree-wrap .el-tree-node.is-current > .el-tree-node__content {
color: #67e8f9 !important;
background: rgba(6, 182, 212, 0.12) !important;
}
// Flow editor chrome, palette and nodes.
.page .page__container .vue-flow,
.lf-canvas-overlay { background: #090d16 !important; }
.page .page__container > .el-container > .el-header,
.page .page__container .el-header,
.page .page__container .el-aside,
.component-library,
.library-header,
.component-library .el-collapse-item__header,
.component-library .el-collapse-item__wrap,
.single-node-station-tools {
color: var(--el-text-color-regular) !important;
background: var(--surface-0) !important;
border-color: var(--line-subtle) !important;
}
.page .page__container .canvas-toolbar,
.page .page__container .vue-flow__controls {
background: rgba(10, 14, 23, 0.9) !important;
border-color: var(--line-subtle) !important;
box-shadow: 0 10px 28px rgba(0, 0, 0, 0.3), 0 0 18px rgba(6, 182, 212, 0.08) !important;
}
.page .page__container .canvas-toolbar .el-button,
.page .page__container .vue-flow__controls button {
color: var(--el-text-color-regular) !important;
background: transparent !important;
border-color: var(--line-subtle) !important;
}
.component-library .node-item,
.flow-node-card,
.group__container,
.node__container,
.node__box,
.condition-summary,
.queue-step,
.output-row,
.flow-node-card .terminal-node__icon {
color: var(--el-text-color-regular) !important;
background: var(--surface-0) !important;
border-color: var(--line-subtle) !important;
box-shadow: none !important;
}
.node-title__icon,
.node-title__type,
.node-state,
.group__container .child__container,
.condition-summary__item,
.contract-header,
.input__container {
color: var(--el-text-color-regular) !important;
background: var(--surface-1) !important;
border-color: var(--line-subtle) !important;
}
.node-title__name,
.condition-summary__title,
.flow-heading__name,
.library-title,
.node-name { color: var(--el-text-color-primary) !important; }
.node-desc,
.library-subtitle,
.flow-node-executor,
.node-title__description,
.condition-summary__text { color: var(--el-text-color-secondary) !important; }
// Corpus, speech and operational workspaces.
.row-cards .card,
.main-workspace .workspace-container > .left,
.main-workspace .workspace-container > .right,
.task-list,
.corpus-list,
.category-tree,
.page-container > .left,
.page-container > .right {
color: var(--el-text-color-regular) !important;
background: var(--surface-0) !important;
border: 1px solid var(--line-subtle) !important;
border-radius: 6px !important;
}
.page-container .taskList-container .task-item,
.page-container > .right .task {
color: var(--el-text-color-regular) !important;
background: var(--surface-1) !important;
box-shadow: inset 0 0 0 1px var(--line-subtle) !important;
border-radius: 5px !important;
}
.page-container .taskList-container .task-item.is-selected {
background: rgba(6, 182, 212, 0.1) !important;
box-shadow: inset 0 0 0 1px #06b6d4, 0 0 16px rgba(6, 182, 212, 0.1) !important;
}
.task-log {
color: var(--el-text-color-regular) !important;
background: var(--surface-0) !important;
border-color: var(--line-subtle) !important;
border-radius: 6px !important;
}
.task-log__group-header:hover,
.task-log__details,
.task-log__iteration-header,
.task-log__analysis,
.task-log__analysis-details,
.task-log__output,
.task-log__business-summary { background: var(--surface-1) !important; }
.task-log__heading,
.task-log__order,
.task-log__time,
.page-container .robot,
.page-container .progress-label { color: var(--el-text-color-secondary) !important; }
// Device list and direct control surfaces.
.robot-device-page { background: transparent !important; }
.robot-device-page .status-strip {
background: var(--surface-0) !important;
border-color: var(--line-subtle) !important;
}
.robot-device-page .page-heading h2,
.robot-device-page .status-strip strong,
.robot-device-page .device-name b { color: var(--el-text-color-primary) !important; }
.robot-device-page .page-heading p,
.robot-device-page .robot-selector,
.robot-device-page .status-strip span,
.robot-device-page .device-name small { color: var(--el-text-color-secondary) !important; }
.robot-device-page .device-icon {
color: #67e8f9 !important;
background: rgba(6, 182, 212, 0.14) !important;
}
.head-control,
.microphone-container,
.audio-player,
.container:has(> .left-panel > .hand-container) {
color: var(--el-text-color-regular) !important;
background: var(--surface-0) !important;
border: 1px solid var(--line-subtle) !important;
border-radius: 6px !important;
}
.head-control .preset-panel,
.head-control .current-display,
.microphone-container .speaker-container,
.microphone-container .audioItem,
.audio-player .audio-item,
.voice-container .voice-btn {
color: var(--el-text-color-regular) !important;
background: var(--surface-1) !important;
border-color: var(--line-subtle) !important;
}
.microphone-container .title,
.audio-player .title,
.voice-container .duration { color: var(--el-text-color-primary) !important; }
.audio-player .audio-item:hover,
.audio-player .audio-item.active,
.voice-container .voice-btn.playing {
color: #e6fbff !important;
background: linear-gradient(90deg, rgba(6, 182, 212, 0.12), rgba(168, 85, 247, 0.09)) !important;
}
// Evaluation workspaces.
.container:has(> .test-container) > .info,
.container:has(> .test-container) .btn-container,
.container:has(> .test-container) .context-container > .left > .title,
.container:has(> .test-container) .schemaList,
.evaluation-metrics > .left,
.evaluation-metrics > .right,
.evaluation-metrics .indicator-container {
color: var(--el-text-color-regular) !important;
background: var(--surface-0) !important;
border-color: var(--line-subtle) !important;
}
.container:has(> .test-container) .activeItem,
.container:has(> .test-container) .schema:hover {
color: #e6fbff !important;
background: linear-gradient(105deg, rgba(6, 182, 212, 0.12), rgba(168, 85, 247, 0.1)) !important;
border-color: rgba(6, 182, 212, 0.48) !important;
}
// Robot layout editor and context menu.
#robot-interface {
background: rgba(7, 11, 20, 0.78) !important;
border: 1px solid var(--line-subtle);
border-radius: 6px !important;
}
#robot-interface .tree-panel,
#robot-interface .robot-panel,
#robot-interface .popup,
#robot-interface .drag-handle,
#robot-interface .toggle-button,
#robot-interface .control-icon,
.context-menu {
color: var(--el-text-color-regular) !important;
background: rgba(20, 27, 45, 0.92) !important;
border-color: var(--line-subtle) !important;
}
#robot-interface .popup,
.context-menu {
border-radius: 6px !important;
box-shadow: 0 16px 42px rgba(0, 0, 0, 0.46), 0 0 20px rgba(6, 182, 212, 0.1) !important;
}
#robot-interface .toggle-button:hover,
#robot-interface .control-icon:hover,
.context-menu .menu-item:hover {
color: #67e8f9 !important;
background: rgba(6, 182, 212, 0.12) !important;
}
.context-menu .menu-item,
#robot-interface .popup-title { color: var(--el-text-color-regular) !important; }
// Utility tables, icon chooser and cron editor.
.custom-table {
color: var(--el-text-color-regular) !important;
background: rgba(10, 14, 23, 0.54) !important;
}
.custom-table th,
.custom-table td { border-color: var(--line-subtle) !important; }
.custom-table th { color: var(--el-text-color-primary) !important; background: var(--surface-1) !important; }
.custom-table tbody tr:hover,
.custom-table .dragging-row { background: linear-gradient(90deg, rgba(6, 182, 212, 0.1), rgba(168, 85, 247, 0.08)) !important; }
.icon-body .icon-item:hover,
.icon-body .icon-item.active {
color: #67e8f9 !important;
background: rgba(6, 182, 212, 0.1) !important;
border-radius: 4px !important;
}
.popup-main,
.popup-result,
.popup-result .title,
.popup-result table span {
color: var(--el-text-color-regular) !important;
background: var(--surface-0) !important;
border-color: var(--line-subtle) !important;
}
.popup-title { color: var(--el-text-color-primary) !important; background: var(--surface-1) !important; }
.pagination-container { background: transparent !important; }
.el-empty__description p,
.el-upload__tip { color: var(--el-text-color-secondary); }
}

View File

@ -6,6 +6,8 @@
@use './btn.scss';
@use './ruoyi.scss';
@use './legacy-layout.scss';
@use './dark-overrides.scss';
@use './cyber-theme.scss';
body {
height: 100%;
@ -13,7 +15,9 @@ body {
-moz-osx-font-smoothing: grayscale;
-webkit-font-smoothing: antialiased;
text-rendering: optimizeLegibility;
font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif;
font-family: "Segoe UI Variable", Inter, "SF Pro Display", "PingFang SC", "Microsoft YaHei", Arial, sans-serif;
color: var(--el-text-color-primary);
background: var(--main-fill-bg);
}
label {
@ -100,24 +104,25 @@ div:focus {
}
aside {
background: #eef1f6;
padding: 8px 24px;
margin-bottom: 20px;
border-radius: 2px;
background: var(--surface-1);
padding: 10px 16px;
margin-bottom: 16px;
border: 1px solid var(--line-subtle);
border-radius: 6px;
display: block;
line-height: 32px;
font-size: 16px;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;
color: #2c3e50;
color: var(--el-text-color-regular);
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
a {
color: #337ab7;
color: var(--el-color-primary);
cursor: pointer;
&:hover {
color: rgb(32, 160, 255);
color: var(--el-color-primary-light-3);
}
}
}
@ -125,9 +130,10 @@ aside {
//main-container全局样式
.app-container {
width: 100%;
padding: 20px;
background-color: var(--el-bg-color);
border-radius: 4px;
padding: 24px;
background-color: var(--surface-0);
border: 1px solid var(--line-subtle);
border-radius: 6px;
}
.components-container {
@ -169,14 +175,78 @@ aside {
.link-type,
.link-type:focus {
color: #337ab7;
color: var(--el-color-primary);
cursor: pointer;
&:hover {
color: rgb(32, 160, 255);
color: var(--el-color-primary-light-3);
}
}
.el-card {
border-radius: 6px;
border-color: var(--line-subtle);
background: var(--surface-0);
box-shadow: none;
}
.el-card__header {
padding: 16px 20px !important;
border-bottom-color: var(--line-subtle);
color: var(--el-text-color-primary);
}
.el-card__body {
padding: 20px !important;
}
.el-button {
min-height: 34px;
border-radius: 5px;
font-weight: 600;
letter-spacing: 0;
transition: color 0.3s ease, background-color 0.3s ease, border-color 0.3s ease, box-shadow 0.3s ease, transform 0.3s ease;
}
.el-button--small { min-height: 30px; border-radius: 4px; }
.el-button--large { min-height: 40px; border-radius: 6px; }
.el-form-item__label { color: var(--el-text-color-regular); }
.el-form-item { margin-bottom: 18px; }
.el-table {
border-radius: 6px;
overflow: hidden;
background: var(--surface-0);
}
.el-table th.el-table__cell { height: 44px; font-weight: 650; }
.el-table td.el-table__cell { height: 48px; }
.el-dialog {
border-radius: 8px;
overflow: hidden;
}
.el-dialog__header {
margin: 0;
padding: 20px 24px 16px;
border-bottom: 1px solid var(--line-subtle);
}
.el-dialog__body { padding: 22px 24px; }
.el-dialog__footer { padding: 14px 24px 20px; border-top: 1px solid var(--line-subtle); }
.el-drawer__header { margin-bottom: 0; padding: 20px 24px; border-bottom: 1px solid var(--line-subtle); }
.el-drawer__body { padding: 22px 24px; }
.el-dropdown-menu, .el-popover { border-radius: 6px; box-shadow: var(--el-box-shadow-light); }
.el-tag { border-radius: 4px; font-weight: 600; }
.el-message, .el-notification { border-radius: 6px; border-color: var(--line-subtle); background: var(--surface-0); }
html.dark ::selection {
color: #041016;
background: #67e8f9;
}
.filter-container {
padding-bottom: 10px;

View File

@ -47,7 +47,7 @@
&.has-logo {
.el-scrollbar {
height: calc(100% - 50px);
height: calc(100% - 64px);
}
}
@ -114,11 +114,11 @@
.hideSidebar {
.sidebar-container {
width: 54px !important;
width: 68px !important;
}
.main-container {
margin-left: 54px;
margin-left: 68px;
}
.sub-menu-title-noDropdown {
@ -129,7 +129,7 @@
padding: 0 !important;
.svg-icon {
margin-left: 20px;
margin-left: 26px;
}
}
}
@ -141,7 +141,7 @@
padding: 0 !important;
.svg-icon {
margin-left: 20px;
margin-left: 26px;
}
}

View File

@ -9,10 +9,10 @@ $yellow: #fec171;
$panGreen: #30b08f;
// 默认主题变量
$menuText: #bfcbd9;
$menuActiveText: #409eff;
$menuBg: #304156;
$menuHover: #263445;
$menuText: rgba(255, 255, 255, 0.68);
$menuActiveText: #67e8f9;
$menuBg: #0a0e17;
$menuHover: rgba(6, 182, 212, 0.1);
// 浅色主题theme-light
$menuLightBg: #ffffff;
@ -21,18 +21,18 @@ $menuLightText: #303133;
$menuLightActiveText: #409eff;
// 基础变量
$base-sidebar-width: 200px;
$sideBarWidth: 200px;
$base-sidebar-width: 232px;
$sideBarWidth: 232px;
// 菜单暗色变量
$base-menu-color: #bfcbd9;
$base-menu-color-active: #f4f4f5;
$base-menu-background: #304156;
$base-sub-menu-background: #1f2d3d;
$base-sub-menu-hover: #001528;
$base-menu-background: #0a0e17;
$base-sub-menu-background: #101827;
$base-sub-menu-hover: rgba(6, 182, 212, 0.1);
// 组件变量
$--color-primary: #409eff;
$--color-primary: #06b6d4;
$--color-success: #67c23a;
$--color-warning: #e6a23c;
$--color-danger: #f56c6c;
@ -79,6 +79,11 @@ $--color-info: #909399;
--splitpanes-default-bg: #ffffff;
--main-fill-bg: rgb(242, 243, 245);
--surface-0: #ffffff;
--surface-1: #f6f8fb;
--surface-2: #eef2f7;
--line-subtle: rgba(15, 23, 42, 0.12);
--flow-grid-color: rgba(51, 65, 85, 0.18);
}
// 暗黑模式变量
@ -284,3 +289,70 @@ html.dark {
background: #3e3e3e !important;
}
}
// Dark Tech design tokens. Kept after legacy compatibility rules so these
// values remain authoritative across Element Plus and custom business views.
html.dark {
color-scheme: dark;
--main-fill-bg: #0a0e17;
--surface-0: rgba(20, 27, 45, 0.82);
--surface-1: rgba(26, 34, 54, 0.9);
--surface-2: rgba(34, 45, 68, 0.9);
--line-subtle: rgba(6, 182, 212, 0.22);
--flow-grid-color: rgba(6, 182, 212, 0.14);
--el-bg-color-page: #0a0e17;
--el-bg-color: #141b2d;
--el-bg-color-overlay: #1a2236;
--el-fill-color-blank: #141b2d;
--el-fill-color: rgba(30, 41, 62, 0.94);
--el-fill-color-light: rgba(35, 47, 70, 0.9);
--el-fill-color-lighter: rgba(39, 53, 78, 0.7);
--el-fill-color-extra-light: rgba(43, 57, 82, 0.54);
--el-fill-color-dark: #101827;
--el-fill-color-darker: #0d1422;
--el-color-primary: #06b6d4;
--el-color-primary-rgb: 6, 182, 212;
--el-color-primary-light-3: #22d3ee;
--el-color-primary-light-5: #67e8f9;
--el-color-primary-light-7: rgba(34, 211, 238, 0.42);
--el-color-primary-light-8: rgba(34, 211, 238, 0.26);
--el-color-primary-light-9: rgba(6, 182, 212, 0.12);
--el-color-primary-dark-2: #0891b2;
--el-color-success: #10b981;
--el-text-color-primary: rgba(255, 255, 255, 0.85);
--el-text-color-regular: rgba(255, 255, 255, 0.68);
--el-text-color-secondary: rgba(255, 255, 255, 0.52);
--el-text-color-placeholder: rgba(203, 213, 225, 0.42);
--el-text-color-disabled: rgba(203, 213, 225, 0.3);
--el-border-color: rgba(6, 182, 212, 0.3);
--el-border-color-light: rgba(6, 182, 212, 0.2);
--el-border-color-lighter: rgba(100, 116, 139, 0.22);
--el-border-color-extra-light: rgba(100, 116, 139, 0.14);
--el-border-color-dark: rgba(34, 211, 238, 0.38);
--el-border-color-darker: rgba(34, 211, 238, 0.48);
--el-box-shadow: 0 4px 15px rgba(6, 182, 212, 0.15);
--el-box-shadow-light: 0 14px 38px rgba(0, 0, 0, 0.34), 0 0 18px rgba(6, 182, 212, 0.1);
--el-box-shadow-lighter: 0 8px 24px rgba(0, 0, 0, 0.26);
--el-box-shadow-dark: 0 24px 60px rgba(0, 0, 0, 0.48), 0 0 28px rgba(168, 85, 247, 0.1);
--sidebar-bg: rgba(10, 14, 23, 0.86);
--sidebar-text: rgba(255, 255, 255, 0.68);
--sidebar-logo-text: rgba(255, 255, 255, 0.9);
--menu-hover: rgba(6, 182, 212, 0.1);
--menu-active-text: #67e8f9;
--navbar-bg: rgba(10, 14, 23, 0.72);
--navbar-text: rgba(255, 255, 255, 0.72);
--navbar-hover: rgba(6, 182, 212, 0.1);
--tags-bg: rgba(10, 14, 23, 0.7);
--tags-item-bg: rgba(20, 27, 45, 0.76);
--tags-item-border: rgba(6, 182, 212, 0.18);
--tags-item-text: rgba(255, 255, 255, 0.6);
--tags-item-hover: rgba(6, 182, 212, 0.1);
--tags-close-hover: rgba(168, 85, 247, 0.52);
--splitpanes-default-bg: #0a0e17;
}

View File

@ -38,9 +38,8 @@ function addIframe() {
<style lang="scss" scoped>
@use "@/assets/styles/variables.module" as *;
.app-main {
/* 50= navbar 50 */
height: calc(100% - 84px);
padding: 20px;
height: calc(100% - 104px);
padding: 24px;
width: 100%;
position: relative;
overflow: hidden;
@ -50,17 +49,22 @@ function addIframe() {
}
.fixed-header + .app-main {
padding-top: 50px;
padding-top: 64px;
}
.hasTagsView {
.app-main {
/* 84 = navbar + tags-view = 50 + 34 */
height: calc(100% - 84px);
height: calc(100% - 104px);
}
.fixed-header + .app-main {
padding-top: 84px;
padding-top: 104px;
}
}
@media (max-width: 768px) {
.app-main {
padding: 16px;
}
}
</style>

View File

@ -155,7 +155,7 @@ defineExpose({
color: var(--notice-title-color, #1a202c);
line-height: 1.45;
margin: 0 0 16px;
letter-spacing: -0.2px;
letter-spacing: 0;
}
.notice-meta {

View File

@ -1,6 +1,12 @@
<template>
<div class="navbar" :class="'nav' + settingsStore.navType">
<hamburger id="hamburger-container" :is-active="appStore.sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar" />
<div v-if="settingsStore.navType == 1" class="system-identity" aria-label="CMVR system identity">
<span class="identity-mark">CMVR</span>
<span class="identity-divider">//</span>
<span class="identity-name">NEXUS CONTROL</span>
<span class="identity-status"><i></i> ONLINE</span>
</div>
<breadcrumb v-if="settingsStore.navType == 1" id="breadcrumb-container" class="breadcrumb-container" />
<top-nav v-if="settingsStore.navType == 2" id="topmenu-container" class="topmenu-container" />
<template v-if="settingsStore.navType == 3">
@ -175,14 +181,14 @@ async function toggleTheme(event) {
<style lang='scss' scoped>
.navbar {
height: 50px;
height: 64px;
overflow: hidden;
position: relative;
background: var(--navbar-bg);
box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
.hamburger-container {
line-height: 46px;
line-height: 60px;
height: 100%;
float: left;
cursor: pointer;
@ -194,13 +200,54 @@ async function toggleTheme(event) {
}
}
.system-identity {
float: left;
height: 100%;
display: inline-flex;
align-items: center;
gap: 8px;
margin-left: 8px;
color: var(--el-text-color-secondary);
font-family: "JetBrains Mono", "SFMono-Regular", Consolas, monospace;
font-size: 11px;
letter-spacing: 0.08em;
white-space: nowrap;
.identity-mark {
color: var(--el-color-primary-light-3);
font-weight: 800;
letter-spacing: 0.16em;
text-shadow: 0 0 12px rgba(34, 211, 238, 0.5);
}
.identity-divider { color: var(--el-color-primary); opacity: 0.65; }
.identity-name { color: var(--el-text-color-regular); }
.identity-status {
display: inline-flex;
align-items: center;
gap: 5px;
margin-left: 8px;
color: #34d399;
font-size: 10px;
}
.identity-status i {
width: 6px;
height: 6px;
border-radius: 50%;
background: #34d399;
box-shadow: 0 0 10px rgba(52, 211, 153, 0.8);
}
}
.breadcrumb-container {
float: left;
}
.topmenu-container {
position: absolute;
left: 50px;
left: 64px;
}
.errLog-container {
@ -211,7 +258,7 @@ async function toggleTheme(event) {
.right-menu {
float: right;
height: 100%;
line-height: 50px;
line-height: 64px;
display: flex;
&:focus {
@ -253,14 +300,14 @@ async function toggleTheme(event) {
margin-right: 40px;
.avatar-wrapper {
margin-top: 5px;
margin-top: 12px;
position: relative;
.user-avatar {
cursor: pointer;
width: 40px;
height: 40px;
border-radius: 10px;
border-radius: 6px;
}
i {
@ -274,4 +321,13 @@ async function toggleTheme(event) {
}
}
}
@media (max-width: 768px) {
.system-identity { display: none !important; }
}
@media (max-width: 1200px) {
.system-identity .identity-name,
.system-identity .identity-divider { display: none; }
}
</style>

View File

@ -24,6 +24,18 @@
<div class="setting-drawer-title">
<h3 class="drawer-title">主题风格设置</h3>
</div>
<div class="drawer-item cyber-mode-toggle">
<span>深色科技模式</span>
<span class="comp-style">
<el-switch
:model-value="settingsStore.isDark"
inline-prompt
active-text="暗"
inactive-text="亮"
@change="settingsStore.toggleTheme"
/>
</span>
</div>
<div class="setting-drawer-block-checbox">
<div class="setting-drawer-block-checbox-item" @click="handleTheme('theme-dark')">
<img src="@/assets/images/dark.svg" alt="dark" />
@ -139,7 +151,7 @@ const theme = ref(settingsStore.theme)
const sideTheme = ref(settingsStore.sideTheme)
const tagsViewPersist = ref(settingsStore.tagsViewPersist)
const storeSettings = computed(() => settingsStore)
const predefineColors = ref(["#409EFF", "#ff4500", "#ff8c00", "#ffd700", "#90ee90", "#00ced1", "#1e90ff", "#c71585"])
const predefineColors = ref(["#06B6D4", "#22D3EE", "#A855F7", "#10B981", "#3B82F6", "#FBBF24", "#FB7185"])
/** 是否需要dynamicTitle */
function dynamicTitleChange() {
@ -278,4 +290,4 @@ defineExpose({
margin: -3px 8px 0px 0px;
}
}
</style>
</style>

View File

@ -7,7 +7,10 @@
</router-link>
<router-link v-else key="expand" class="sidebar-logo-link" to="/">
<img v-if="logo" :src="logo" class="sidebar-logo" />
<h1 class="sidebar-title">{{ title }}</h1>
<span class="sidebar-copy">
<h1 class="sidebar-title">{{ title }}</h1>
<small>NEURAL OPERATIONS GRID</small>
</span>
</router-link>
</transition>
</div>
@ -67,8 +70,8 @@ const getLogoTextColor = computed(() => {
.sidebar-logo-container {
position: relative;
width: 100%;
height: 50px;
line-height: 50px;
height: 64px;
line-height: 64px;
background: v-bind(getLogoBackground);
text-align: center;
overflow: hidden;
@ -89,11 +92,29 @@ const getLogoTextColor = computed(() => {
margin: 0;
color: v-bind(getLogoTextColor);
font-weight: 600;
line-height: 50px;
line-height: 64px;
font-size: 14px;
font-family: Avenir, Helvetica Neue, Arial, Helvetica, sans-serif;
vertical-align: middle;
}
& .sidebar-copy {
display: inline-flex;
flex-direction: column;
justify-content: center;
vertical-align: middle;
text-align: left;
line-height: 1;
}
& .sidebar-copy small {
margin-top: 6px;
color: rgba(103, 232, 249, 0.58);
font-family: "JetBrains Mono", Consolas, monospace;
font-size: 8px;
letter-spacing: 0.08em;
white-space: nowrap;
}
}
&.collapse {

View File

@ -259,7 +259,7 @@ function handleScroll() {
<style lang="scss" scoped>
.tags-view-container {
height: 34px;
height: 40px;
width: 100%;
background: var(--tags-bg, #fff);
border-bottom: 1px solid var(--tags-item-border, #d8dce5);
@ -270,15 +270,16 @@ function handleScroll() {
display: inline-block;
position: relative;
cursor: pointer;
height: 26px;
height: 28px;
line-height: 26px;
border-radius: 4px;
border: 1px solid var(--tags-item-border, #d8dce5);
color: var(--tags-item-text, #495060);
background: var(--tags-item-bg, #fff);
padding: 0 8px;
font-size: 12px;
margin-left: 5px;
margin-top: 4px;
margin-top: 6px;
&:first-of-type {
margin-left: 15px;

View File

@ -65,9 +65,9 @@ onMounted(() => {
.topbar-menu.el-menu--horizontal > .el-menu-item {
float: left;
height: 50px !important;
line-height: 50px !important;
color: #303133 !important;
height: 64px !important;
line-height: 64px !important;
color: var(--navbar-text) !important;
padding: 0 5px !important;
margin: 0 10px !important;
}
@ -79,8 +79,8 @@ onMounted(() => {
/* sub-menu item */
.topbar-menu.el-menu--horizontal > .el-sub-menu .el-sub-menu__title {
float: left;
line-height: 50px !important;
color: #303133 !important;
line-height: 64px !important;
color: var(--navbar-text) !important;
margin: 0 15px -3px!important;
}
@ -94,6 +94,6 @@ onMounted(() => {
/* menu__title el-menu-item */
.topbar-menu.el-menu--horizontal .el-sub-menu__title, .topbar-menu.el-menu--horizontal .el-menu-item {
height: 60px;
height: 64px;
}
</style>

View File

@ -172,37 +172,37 @@ onMounted(() => {
<style lang="scss">
.topmenu-container.el-menu--horizontal {
height: 50px !important;
height: 64px !important;
border-bottom: none;
}
.topmenu-container.el-menu--horizontal > .el-menu-item {
float: left;
height: 50px !important;
line-height: 50px !important;
color: #303133 !important;
height: 64px !important;
line-height: 64px !important;
color: var(--navbar-text) !important;
padding: 0 5px !important;
margin: 0 10px !important;
}
.topmenu-container.el-menu--horizontal > .el-menu-item.is-active, .el-menu--horizontal > .el-sub-menu.is-active .el-submenu__title {
border-bottom: 2px solid #{'var(--theme)'} !important;
color: #303133;
color: var(--navbar-text);
}
/* sub-menu item */
.topmenu-container.el-menu--horizontal > .el-sub-menu .el-sub-menu__title {
float: left;
height: 50px !important;
line-height: 50px !important;
color: #303133 !important;
height: 64px !important;
line-height: 64px !important;
color: var(--navbar-text) !important;
padding: 0 5px !important;
margin: 0 10px !important;
}
/* 背景色隐藏 */
.topmenu-container.el-menu--horizontal>.el-menu-item:not(.is-disabled):focus, .topmenu-container.el-menu--horizontal>.el-menu-item:not(.is-disabled):hover, .topmenu-container.el-menu--horizontal>.el-submenu .el-submenu__title:hover {
background-color: #ffffff;
background-color: var(--navbar-hover);
}
/* 图标右间距 */

View File

@ -1,5 +1,8 @@
<template>
<div :class="classObj" class="app-wrapper" :style="{ '--current-color': theme, '--current-color-light': theme + '1a', '--current-color-dark-bg': theme + '33' }">
<div class="cyber-corner cyber-corner--top" aria-hidden="true"></div>
<div class="cyber-corner cyber-corner--bottom" aria-hidden="true"></div>
<div class="cyber-scanline" aria-hidden="true"></div>
<div v-if="device === 'mobile' && sidebar.opened" class="drawer-bg" @click="handleClickOutside"/>
<sidebar v-if="!sidebar.hide" class="sidebar-container" />
<div :class="{ hasTagsView: needTagsView, sidebarHide: sidebar.hide }" class="main-container">
@ -98,7 +101,7 @@ function setLayout() {
}
.hideSidebar .fixed-header {
width: calc(100% - 54px);
width: calc(100% - 68px);
}
.sidebarHide .fixed-header {

View File

@ -42,7 +42,7 @@ export default {
/**
* 是否固定头部
*/
fixedHeader: false,
fixedHeader: true,
/**
* 是否显示logo

View File

@ -3,19 +3,26 @@ import { useDark, useToggle } from '@vueuse/core'
import { useDynamicTitle } from '@/utils/dynamicTitle'
import { handleThemeStyle } from '@/utils/theme'
const isDark = useDark()
const isDark = useDark({
storageKey: 'cmvr-color-scheme',
initialValue: 'dark'
})
const toggleDark = useToggle(isDark)
const { sideTheme, showSettings, navType, tagsView, tagsViewPersist, tagsIcon, tagsViewStyle, fixedHeader, sidebarLogo, dynamicTitle, footerVisible, footerContent } = defaultSettings
const storageSetting = JSON.parse(localStorage.getItem('layout-setting')) || ''
const legacyPrimaryColors = ['#409EFF', '#43C6A4']
const initialTheme = storageSetting.theme && !legacyPrimaryColors.includes(storageSetting.theme.toUpperCase())
? storageSetting.theme
: '#06B6D4'
const useSettingsStore = defineStore(
'settings',
{
state: () => ({
title: '',
theme: storageSetting.theme || '#409EFF',
theme: initialTheme,
sideTheme: storageSetting.sideTheme || sideTheme,
showSettings: showSettings,
navType: storageSetting.navType === undefined ? navType : storageSetting.navType,

View File

@ -1,7 +1,6 @@
// 处理主题样式
export function handleThemeStyle(theme) {
const isDark = typeof document !== 'undefined' && document.documentElement.classList.contains('dark')
const primary = isDark ? softenPrimaryForDark(theme) : theme
const primary = theme
document.documentElement.style.setProperty('--el-color-primary', primary)
for (let i = 1; i <= 9; i++) {
document.documentElement.style.setProperty(`--el-color-primary-light-${i}`, `${getLightColor(primary, i / 10)}`)

View File

@ -129,7 +129,7 @@ onMounted(() => {
.stat-number {
font-size: 24px;
font-weight: 700;
letter-spacing: -0.02em;
letter-spacing: 0;
color: #0f172a;
}
@ -158,4 +158,4 @@ onMounted(() => {
}
}
}
</style>
</style>

View File

@ -139,7 +139,7 @@ onMounted(() => {
.stat-number {
font-size: 24px;
font-weight: 700;
letter-spacing: -0.02em;
letter-spacing: 0;
color: #0f172a;
}
@ -168,4 +168,4 @@ onMounted(() => {
}
}
}
</style>
</style>

View File

@ -75,6 +75,9 @@ const initChart = () => {
}
myChart = echarts.init(chart.value);
const option = {
backgroundColor: 'transparent',
color: ['#06B6D4', '#10B981', '#A855F7', '#3B82F6', '#FBBF24'],
textStyle: { color: 'rgba(255, 255, 255, 0.72)' },
title: { text: '手指触觉数据' },
tooltip: { trigger: 'axis', axisPointer: { type: 'shadow' } },
legend: { data: ['指端', '指尖', '指中', '指腹', '手掌触觉'] },
@ -93,6 +96,36 @@ const initChart = () => {
{ name: '手掌触觉', type: 'bar', barGap: '1%', barCategoryGap: '10%', itemStyle: { color: '#FFD700' }, label: { show: true, position: 'top' }, emphasis: { focus: 'series' }, data: [] }
]
};
Object.assign(option.title, { textStyle: { color: 'rgba(255, 255, 255, 0.88)', fontWeight: 650 } });
Object.assign(option.tooltip, {
backgroundColor: 'rgba(10, 14, 23, 0.94)',
borderColor: 'rgba(6, 182, 212, 0.48)',
textStyle: { color: 'rgba(255, 255, 255, 0.88)' }
});
Object.assign(option.legend, { textStyle: { color: 'rgba(255, 255, 255, 0.62)' } });
Object.assign(option.xAxis, {
axisLine: { lineStyle: { color: 'rgba(6, 182, 212, 0.36)' } },
axisTick: { show: false },
axisLabel: { color: 'rgba(255, 255, 255, 0.64)' },
splitArea: { show: true, areaStyle: { color: ['rgba(6, 182, 212, 0.02)', 'rgba(168, 85, 247, 0.025)'] } }
});
option.yAxis.forEach((axis) => Object.assign(axis, {
axisLine: { show: true, lineStyle: { color: 'rgba(6, 182, 212, 0.3)' } },
axisLabel: { color: 'rgba(255, 255, 255, 0.62)' },
nameTextStyle: { color: 'rgba(255, 255, 255, 0.68)' },
splitLine: { lineStyle: { color: 'rgba(148, 163, 184, 0.12)', type: 'dashed' } }
}));
const seriesColors = ['#06B6D4', '#10B981', '#A855F7', '#3B82F6', '#FBBF24'];
option.series.forEach((series, index) => {
series.itemStyle = {
...series.itemStyle,
color: seriesColors[index],
borderRadius: [3, 3, 0, 0],
shadowBlur: 12,
shadowColor: `${seriesColors[index]}66`
};
series.label = { ...series.label, color: 'rgba(255, 255, 255, 0.74)' };
});
myChart.setOption(option);
};
@ -212,18 +245,20 @@ onUnmounted(() => {
margin: 0 10px;
cursor: pointer;
font-size: 16px;
color: #333;
color: var(--el-text-color-regular);
border-bottom: 3px solid transparent;
transition: all 0.3s ease;
}
.tab:hover {
background-color: #f5f5f5;
color: #67e8f9;
background-color: rgba(6, 182, 212, 0.1);
border-radius: 5px;
}
.tab.active {
border-bottom: 3px solid #007bff;
color: #007bff;
border-bottom: 3px solid #06b6d4;
color: #67e8f9;
text-shadow: 0 0 12px rgba(6, 182, 212, 0.48);
}
</style>
</style>

View File

@ -72,6 +72,43 @@ const topChartData = ref({
series: [{ data: props.topSeriesData, type: 'bar' }],
});
Object.assign(topChartData.value, {
backgroundColor: 'transparent',
tooltip: {
trigger: 'axis',
axisPointer: { type: 'shadow', shadowStyle: { color: 'rgba(6, 182, 212, 0.08)' } },
backgroundColor: 'rgba(10, 14, 23, 0.94)',
borderColor: 'rgba(6, 182, 212, 0.48)',
textStyle: { color: 'rgba(255, 255, 255, 0.88)' },
},
grid: { left: 54, right: 20, top: 24, bottom: 42 },
});
Object.assign(topChartData.value.xAxis, {
axisLine: { lineStyle: { color: 'rgba(6, 182, 212, 0.36)' } },
axisTick: { show: false },
axisLabel: { color: 'rgba(255, 255, 255, 0.68)', interval: 0 },
});
Object.assign(topChartData.value.yAxis, {
axisLine: { show: true, lineStyle: { color: 'rgba(6, 182, 212, 0.36)' } },
axisLabel: { formatter: '{value} g', color: 'rgba(255, 255, 255, 0.62)' },
axisTick: { show: true, lineStyle: { color: 'rgba(6, 182, 212, 0.3)' } },
splitLine: { lineStyle: { color: 'rgba(148, 163, 184, 0.12)', type: 'dashed' } },
nameTextStyle: { color: 'rgba(255, 255, 255, 0.68)' },
});
Object.assign(topChartData.value.series[0], {
barMaxWidth: 34,
itemStyle: {
borderRadius: [4, 4, 0, 0],
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: '#67E8F9' },
{ offset: 0.5, color: '#06B6D4' },
{ offset: 1, color: 'rgba(168, 85, 247, 0.5)' },
]),
shadowBlur: 14,
shadowColor: 'rgba(6, 182, 212, 0.42)',
},
});
const data = ref({
resizeObserver: null,
debouncedResize: null,
@ -159,4 +196,4 @@ watch(
margin: 10px 0;
min-height: 200px; /* 确保图表有足够的高度 */
}
</style>
</style>

View File

@ -173,7 +173,7 @@
<template #edge-flow-edge="edgeProps">
<FlowEdge v-bind="edgeProps" />
</template>
<Background color="#d9dee8" :gap="24" :size="1" />
<Background color="var(--flow-grid-color)" :gap="24" :size="1" />
<Controls position="bottom-right" />
</VueFlow>
</el-main>

View File

@ -1,6 +1,18 @@
<template>
<div class="login">
<section class="access-brand" aria-hidden="true">
<div class="access-state"><span></span> SYSTEM ONLINE</div>
<p class="access-code">CMVR // ROBOT INTELLIGENCE PLATFORM</p>
<h1>MISSION<br><strong>CONTROL</strong></h1>
<p class="access-description">Unified device orchestration, autonomous inspection and intelligent evaluation.</p>
<div class="access-metrics">
<span>NODE 01</span>
<span>LINK SECURE</span>
<span>LAT 22.533</span>
</div>
</section>
<el-form ref="loginRef" :model="loginForm" :rules="loginRules" class="login-form">
<div class="form-kicker">AUTHORIZATION GATEWAY // 01</div>
<h3 class="title">{{ title }}</h3>
<el-form-item prop="username">
<el-input

View File

@ -68,6 +68,7 @@
import { getCache } from '@/api/monitor/cache'
import * as echarts from 'echarts'
const cyberPalette = ['#06B6D4', '#A855F7', '#10B981', '#3B82F6', '#FBBF24', '#FB7185']
const cache = ref([])
const commandstats = ref(null)
const usedmemory = ref(null)
@ -79,11 +80,16 @@ function getList() {
proxy.$modal.closeLoading()
cache.value = response.data
const commandstatsIntance = echarts.init(commandstats.value, "macarons")
const commandstatsIntance = echarts.init(commandstats.value)
commandstatsIntance.setOption({
backgroundColor: 'transparent',
color: cyberPalette,
tooltip: {
trigger: "item",
formatter: "{a} <br/>{b} : {c} ({d}%)"
formatter: "{a} <br/>{b} : {c} ({d}%)",
backgroundColor: 'rgba(10, 14, 23, 0.94)',
borderColor: 'rgba(6, 182, 212, 0.48)',
textStyle: { color: 'rgba(255, 255, 255, 0.88)' }
},
series: [
{
@ -93,15 +99,28 @@ function getList() {
radius: [15, 95],
center: ["50%", "38%"],
data: response.data.commandStats,
label: { color: 'rgba(255, 255, 255, 0.72)' },
labelLine: { lineStyle: { color: 'rgba(6, 182, 212, 0.34)' } },
itemStyle: {
borderColor: '#0A0E17',
borderWidth: 2,
shadowBlur: 14,
shadowColor: 'rgba(6, 182, 212, 0.28)'
},
emphasis: { itemStyle: { shadowBlur: 26, shadowColor: 'rgba(168, 85, 247, 0.52)' } },
animationEasing: "cubicInOut",
animationDuration: 1000
}
]
})
const usedmemoryInstance = echarts.init(usedmemory.value, "macarons")
const usedmemoryInstance = echarts.init(usedmemory.value)
usedmemoryInstance.setOption({
backgroundColor: 'transparent',
tooltip: {
formatter: "{b} <br/>{a} : " + cache.value.info.used_memory_human
formatter: "{b} <br/>{a} : " + cache.value.info.used_memory_human,
backgroundColor: 'rgba(10, 14, 23, 0.94)',
borderColor: 'rgba(6, 182, 212, 0.48)',
textStyle: { color: 'rgba(255, 255, 255, 0.88)' }
},
series: [
{
@ -109,9 +128,24 @@ function getList() {
type: "gauge",
min: 0,
max: 1000,
detail: {
formatter: cache.value.info.used_memory_human
progress: {
show: true,
width: 14,
roundCap: true,
itemStyle: { color: '#06B6D4', shadowBlur: 18, shadowColor: 'rgba(6, 182, 212, 0.58)' }
},
pointer: { itemStyle: { color: '#67E8F9' } },
anchor: { show: true, size: 11, itemStyle: { color: '#A855F7', borderColor: '#E9D5FF', borderWidth: 2 } },
axisLine: { lineStyle: { width: 14, color: [[0.65, 'rgba(6, 182, 212, 0.34)'], [0.85, 'rgba(168, 85, 247, 0.42)'], [1, 'rgba(251, 113, 133, 0.48)']] } },
axisTick: { distance: -20, lineStyle: { color: 'rgba(255, 255, 255, 0.34)' } },
splitLine: { distance: -22, lineStyle: { color: 'rgba(255, 255, 255, 0.5)' } },
axisLabel: { color: 'rgba(255, 255, 255, 0.58)', distance: 24 },
detail: {
formatter: cache.value.info.used_memory_human,
color: 'rgba(255, 255, 255, 0.9)',
offsetCenter: [0, '62%']
},
title: { color: 'rgba(255, 255, 255, 0.62)', offsetCenter: [0, '82%'] },
data: [
{
value: parseFloat(cache.value.info.used_memory_human),

View File

@ -1,6 +1,18 @@
<template>
<div class="register">
<section class="access-brand" aria-hidden="true">
<div class="access-state"><span></span> ENROLLMENT CHANNEL</div>
<p class="access-code">CMVR // IDENTITY PROVISIONING</p>
<h1>CREATE<br><strong>ACCESS</strong></h1>
<p class="access-description">Register a verified operator identity for the intelligent test network.</p>
<div class="access-metrics">
<span>NODE 01</span>
<span>CHANNEL SECURE</span>
<span>AUTH READY</span>
</div>
</section>
<el-form ref="registerRef" :model="registerForm" :rules="registerRules" class="register-form">
<div class="form-kicker">IDENTITY ENROLLMENT // 02</div>
<h3 class="title">{{ title }}</h3>
<el-form-item prop="username">
<el-input