diff --git a/frontend/src/app.tsx b/frontend/src/app.tsx index f9c0e35..84acf44 100644 --- a/frontend/src/app.tsx +++ b/frontend/src/app.tsx @@ -1,4 +1,5 @@ import { defineApp } from 'umi'; import './global.less'; +import './styles/dazzle.less'; export default defineApp({}); \ No newline at end of file diff --git a/frontend/src/pages/aiChat/index.less b/frontend/src/pages/aiChat/index.less index a28a95b..9f11727 100644 --- a/frontend/src/pages/aiChat/index.less +++ b/frontend/src/pages/aiChat/index.less @@ -229,4 +229,49 @@ .ai-bubble { max-width: 86%; } -} \ No newline at end of file +} +/* ================= 绚丽增强(AI 对话专属) ================= */ + +/* 机器人头像呼吸光环 */ +.ai-robot-avatar { + animation: dazzle-ai-robot 3s ease-in-out infinite; +} + +@keyframes dazzle-ai-robot { + 0%, 100% { box-shadow: 0 0 14px rgba(34, 211, 238, 0.24); } + 50% { box-shadow: 0 0 30px rgba(34, 211, 238, 0.5), 0 0 44px rgba(139, 92, 246, 0.28); } +} + +/* 在线状态点脉冲 */ +.ai-status-dot { + animation: dazzle-ai-dot 1.8s ease-in-out infinite; +} + +@keyframes dazzle-ai-dot { + 0%, 100% { box-shadow: 0 0 8px rgba(34, 197, 94, 0.7); transform: scale(1); } + 50% { box-shadow: 0 0 16px rgba(34, 197, 94, 1); transform: scale(1.25); } +} + +/* 消息气泡进入动效 + 悬浮微光 */ +.ai-message-row { + animation: dazzle-ai-msg-in 0.3s ease both; +} + +@keyframes dazzle-ai-msg-in { + from { opacity: 0; transform: translateY(8px); } + to { opacity: 1; transform: translateY(0); } +} + +.ai-bubble-content { + transition: border-color 0.25s ease, box-shadow 0.25s ease; +} + +.ai-bubble:hover .ai-bubble-content { + border-color: rgba(103, 232, 249, 0.42); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.06), 0 0 22px rgba(34, 211, 238, 0.14); +} + +.is-user .ai-bubble:hover .ai-bubble-content { + border-color: rgba(147, 197, 253, 0.6); + box-shadow: 0 0 22px rgba(59, 130, 246, 0.28); +} diff --git a/frontend/src/pages/login/index.module.less b/frontend/src/pages/login/index.module.less index 68b6ad3..bf5e35e 100644 --- a/frontend/src/pages/login/index.module.less +++ b/frontend/src/pages/login/index.module.less @@ -199,4 +199,83 @@ .loginFooter { gap: 12px; } -} \ No newline at end of file +} +/* ================= 绚丽增强(登录页专属) ================= */ + +/* 登录面板:旋转霓虹描边(conic 渐变环,尊重 reduced-motion 全局降级) */ +.loginPanel { + position: relative; + overflow: hidden; +} + +.loginPanel::selection { + background: rgba(34, 211, 238, 0.35); +} + +.panelTitle span { + animation: dazzle-login-titlebar 2.6s ease-in-out infinite; +} + +@keyframes dazzle-login-titlebar { + 0%, 100% { box-shadow: 0 0 10px rgba(34, 211, 238, 0.7); } + 50% { box-shadow: 0 0 22px rgba(34, 211, 238, 1), 0 0 34px rgba(139, 92, 246, 0.5); } +} + +.brandRow img { + animation: dazzle-login-logo 3.4s ease-in-out infinite; +} + +@keyframes dazzle-login-logo { + 0%, 100% { filter: drop-shadow(0 0 12px rgba(34, 211, 238, 0.6)); transform: scale(1); } + 50% { filter: drop-shadow(0 0 26px rgba(34, 211, 238, 0.95)); transform: scale(1.05); } +} + +.loginButton { + position: relative; + overflow: hidden; +} + +.loginButton::after { + content: ""; + position: absolute; + top: 0; + bottom: 0; + left: -60%; + width: 42%; + pointer-events: none; + background: linear-gradient(100deg, transparent, rgba(255, 255, 255, 0.4), transparent); + transform: skewX(-18deg); + animation: dazzle-login-sheen 3s ease-in-out infinite; +} + +@keyframes dazzle-login-sheen { + 0% { left: -60%; } + 60%, 100% { left: 135%; } +} + +/* 第三颗小光斑,丰富背景层次 */ +.orbThree { + position: absolute; + width: 160px; + height: 160px; + right: 24%; + bottom: 16%; + border: 1px solid rgba(59, 130, 246, 0.34); + border-radius: 50%; + filter: blur(2px); + opacity: 0.6; + animation: floatThree 16s ease-in-out infinite alternate; +} + +@keyframes floatThree { + to { transform: translate(20px, -30px) scale(1.12); } +} + +.loginFooter span { + transition: color 0.25s ease, text-shadow 0.25s ease; +} + +.loginFooter span:hover { + color: #a5f3fc; + text-shadow: 0 0 14px rgba(34, 211, 238, 0.75); +} diff --git a/frontend/src/pages/monitScreen/index.module.less b/frontend/src/pages/monitScreen/index.module.less index fcbb020..be5591a 100644 --- a/frontend/src/pages/monitScreen/index.module.less +++ b/frontend/src/pages/monitScreen/index.module.less @@ -9,3 +9,18 @@ object-fit: cover; background: #020617; } + +/* ================= 绚丽增强(监控大屏专属) ================= */ + +.video { + border: 1px solid rgba(103, 232, 249, 0.22); + border-radius: 12px; + box-shadow: inset 0 0 0 1px rgba(2, 8, 23, 0.4), 0 0 18px rgba(34, 211, 238, 0.08); + transition: border-color 0.3s ease, box-shadow 0.3s ease, transform 0.3s ease; +} + +.video:hover { + border-color: rgba(34, 211, 238, 0.7); + box-shadow: 0 0 26px rgba(34, 211, 238, 0.28); + transform: scale(1.01); +} diff --git a/frontend/src/pages/overview/index.less b/frontend/src/pages/overview/index.less index f24f565..b507989 100644 --- a/frontend/src/pages/overview/index.less +++ b/frontend/src/pages/overview/index.less @@ -352,3 +352,171 @@ .overview-panels { grid-template-columns: 1fr; } .overview-header { flex-direction: column; gap: 10px; align-items: flex-start; } } + +/* ================= 绚丽增强(概览大屏专属) ================= */ + +/* 头部横幅:流动的极光底色 + 顶部高光扫过 */ +.overview-header { + position: relative; + overflow: hidden; +} + +.overview-header::before { + content: ""; + position: absolute; + inset: 0; + pointer-events: none; + background: + radial-gradient(circle at 18% 20%, rgba(34, 211, 238, 0.2), transparent 42%), + radial-gradient(circle at 82% 30%, rgba(139, 92, 246, 0.18), transparent 46%); + animation: dazzle-ov-header-drift 16s ease-in-out infinite alternate; +} + +@keyframes dazzle-ov-header-drift { + from { transform: translate3d(-3%, 0, 0) scale(1); } + to { transform: translate3d(3%, -4%, 0) scale(1.06); } +} + +.overview-header::after { + content: ""; + position: absolute; + top: 0; + right: 12%; + left: 12%; + height: 1px; + pointer-events: none; + background: linear-gradient(90deg, transparent, rgba(103, 232, 249, 0.85), transparent); + background-repeat: no-repeat; + background-size: 45% 100%; + animation: dazzle-ov-topline 5.5s linear infinite; +} + +@keyframes dazzle-ov-topline { + from { background-position: -45% 0; } + to { background-position: 145% 0; } +} + +/* 标题图标呼吸 + 副标题字母微光 */ +.overview-title-icon { + animation: dazzle-ov-icon-breathe 3s ease-in-out infinite; +} + +@keyframes dazzle-ov-icon-breathe { + 0%, 100% { text-shadow: 0 0 14px rgba(34, 211, 238, 0.7); transform: scale(1); } + 50% { text-shadow: 0 0 26px rgba(34, 211, 238, 1), 0 0 40px rgba(139, 92, 246, 0.5); transform: scale(1.08); } +} + +/* 时钟数字霓虹 */ +.overview-clock { + text-shadow: 0 0 12px rgba(34, 211, 238, 0.45); + animation: dazzle-ov-clock 2.4s ease-in-out infinite; +} + +@keyframes dazzle-ov-clock { + 0%, 100% { text-shadow: 0 0 10px rgba(34, 211, 238, 0.35); } + 50% { text-shadow: 0 0 20px rgba(34, 211, 238, 0.7); } +} + +/* KPI 卡片:进入浮起 + 图标光晕脉冲 + 数值渐变发光 */ +.kpi-card { + animation: dazzle-ov-card-in 0.5s ease both; +} + +.kpi-card:nth-child(1) { animation-delay: 0.02s; } +.kpi-card:nth-child(2) { animation-delay: 0.08s; } +.kpi-card:nth-child(3) { animation-delay: 0.14s; } +.kpi-card:nth-child(4) { animation-delay: 0.2s; } +.kpi-card:nth-child(5) { animation-delay: 0.26s; } + +@keyframes dazzle-ov-card-in { + from { opacity: 0; transform: translateY(10px); } + to { opacity: 1; transform: translateY(0); } +} + +.kpi-icon { + position: relative; + box-shadow: 0 0 18px rgba(34, 211, 238, 0.12); + animation: dazzle-ov-icon-halo 3.2s ease-in-out infinite; +} + +@keyframes dazzle-ov-icon-halo { + 0%, 100% { box-shadow: 0 0 10px rgba(34, 211, 238, 0.1); } + 50% { box-shadow: 0 0 24px rgba(34, 211, 238, 0.32); } +} + +.kpi-value { + color: #d9f6ff; + animation: dazzle-ov-kpi-glow 3.4s ease-in-out infinite; +} + +@keyframes dazzle-ov-kpi-glow { + 0%, 100% { text-shadow: 0 0 10px rgba(34, 211, 238, 0.35); } + 50% { text-shadow: 0 0 22px rgba(34, 211, 238, 0.65), 0 0 36px rgba(139, 92, 246, 0.3); } +} + +.kpi-corner { + animation: dazzle-ov-corner 3.6s ease-in-out infinite; +} + +@keyframes dazzle-ov-corner { + 0%, 100% { opacity: 0.35; } + 50% { opacity: 0.85; } +} + +/* 面板:顶部高光线 + 标题条流光 */ +.ov-panel { + position: relative; + overflow: hidden; +} + +.ov-panel::after { + content: ""; + position: absolute; + top: 0; + right: 16%; + left: 16%; + height: 1px; + pointer-events: none; + background: linear-gradient(90deg, transparent, rgba(103, 232, 249, 0.7), transparent); +} + +.panel-title-bar { + background: linear-gradient(180deg, #22d3ee, #3b82f6, #8b5cf6); + animation: dazzle-ov-titlebar 2.8s ease-in-out infinite; +} + +@keyframes dazzle-ov-titlebar { + 0%, 100% { box-shadow: 0 0 8px rgba(34, 211, 238, 0.7); } + 50% { box-shadow: 0 0 18px rgba(34, 211, 238, 1), 0 0 30px rgba(139, 92, 246, 0.45); } +} + +/* 趋势图与环图:发光滤镜 */ +.trend-chart svg { + filter: drop-shadow(0 0 8px rgba(34, 211, 238, 0.28)); +} + +.donut-svg { + animation: dazzle-ov-donut-spin 40s linear infinite; + filter: drop-shadow(0 0 10px rgba(139, 92, 246, 0.3)); +} + +@keyframes dazzle-ov-donut-spin { + from { transform: rotate(0deg); } + to { transform: rotate(360deg); } +} + +/* 最新动态列表:行进入交错 */ +.latest-list li { + animation: dazzle-ov-row-in 0.4s ease both; +} + +.latest-list li:nth-child(1) { animation-delay: 0.05s; } +.latest-list li:nth-child(2) { animation-delay: 0.1s; } +.latest-list li:nth-child(3) { animation-delay: 0.15s; } +.latest-list li:nth-child(4) { animation-delay: 0.2s; } +.latest-list li:nth-child(5) { animation-delay: 0.25s; } + +@keyframes dazzle-ov-row-in { + from { opacity: 0; transform: translateX(8px); } + to { opacity: 1; transform: translateX(0); } +} diff --git a/frontend/src/styles/dazzle.less b/frontend/src/styles/dazzle.less new file mode 100644 index 0000000..67de0a4 --- /dev/null +++ b/frontend/src/styles/dazzle.less @@ -0,0 +1,221 @@ +/* ========================================================================== + 绚丽增强层(Dazzle Layer) + 在玻璃面板基座之上叠加动态极光、扫描光束、旋转渐变描边、呼吸辉光、 + 定制滚动条等纯装饰效果。只增强氛围,不改变文字颜色与对比度; + 全部动效遵循 prefers-reduced-motion(见 global.less 统一降级)。 + ========================================================================== */ + +/* ---------- 0. 旋转描边专用自定义属性(不支持的浏览器自动退化为静态描边) ---------- */ +@property --dazzle-angle { + syntax: ""; + initial-value: 0deg; + inherits: false; +} + +/* ---------- 1. 动态极光背景:三团彩色光斑缓慢漂移 ---------- */ +body::after { + background: + radial-gradient(circle at 22% 24%, rgba(34, 211, 238, 0.16), transparent 32%), + radial-gradient(circle at 78% 30%, rgba(139, 92, 246, 0.15), transparent 34%), + radial-gradient(circle at 50% 80%, rgba(59, 130, 246, 0.17), transparent 38%); + animation: dazzle-aurora 36s ease-in-out infinite alternate; + will-change: transform; +} + +@keyframes dazzle-aurora { + 0% { transform: translate3d(-2.5%, 0, 0) scale(1); } + 50% { transform: translate3d(1.5%, -2.5%, 0) scale(1.08); } + 100% { transform: translate3d(2.5%, 2%, 0) scale(1.03); } +} + +/* 网格缓慢漂移,营造“数据空间”感 */ +body::before { + animation: dazzle-grid-drift 70s linear infinite; +} + +@keyframes dazzle-grid-drift { + from { background-position: 0 0, 0 0; } + to { background-position: 36px 36px, 36px 36px; } +} + +/* ---------- 2. 顶栏底部:一缕霓虹光束循环扫过 ---------- */ +.glass-header { + position: relative; + overflow: hidden; +} + +.glass-header::after { + content: ""; + position: absolute; + right: 0; + bottom: 0; + left: 0; + height: 2px; + pointer-events: none; + background: linear-gradient( + 90deg, + transparent, + rgba(34, 211, 238, 0.95) 42%, + rgba(139, 92, 246, 0.95) 58%, + transparent + ); + background-repeat: no-repeat; + background-size: 38% 100%; + animation: dazzle-header-sweep 7s linear infinite; +} + +@keyframes dazzle-header-sweep { + from { background-position: -38% 0; } + to { background-position: 138% 0; } +} + +/* 品牌标题呼吸辉光 */ +.brand-title { + animation: dazzle-title-glow 4.2s ease-in-out infinite; +} + +@keyframes dazzle-title-glow { + 0%, 100% { text-shadow: 0 0 14px rgba(34, 211, 238, 0.35); } + 50% { text-shadow: 0 0 26px rgba(34, 211, 238, 0.6), 0 0 44px rgba(139, 92, 246, 0.35); } +} + +/* ---------- 3. 卡片:悬浮时浮现旋转渐变描边 ---------- */ +.ant-card { + position: relative; +} + +.ant-card::before { + content: ""; + position: absolute; + inset: 0; + z-index: 0; + padding: 1px; + border-radius: inherit; + pointer-events: none; + background: conic-gradient( + from var(--dazzle-angle, 0deg), + rgba(34, 211, 238, 0) 0%, + rgba(34, 211, 238, 0.65) 12%, + rgba(139, 92, 246, 0.65) 22%, + rgba(34, 211, 238, 0) 34% + ); + -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); + -webkit-mask-composite: xor; + mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); + mask-composite: exclude; + opacity: 0.22; + transition: opacity 0.3s ease; + animation: dazzle-ring-spin 7s linear infinite; +} + +.ant-card:hover::before { + opacity: 1; +} + +@keyframes dazzle-ring-spin { + to { --dazzle-angle: 360deg; } +} + +/* ---------- 4. 主按钮:周期扫光 ---------- */ +.ant-btn-primary { + position: relative; + overflow: hidden; +} + +.ant-btn-primary::after { + content: ""; + position: absolute; + top: 0; + bottom: 0; + left: -60%; + width: 42%; + pointer-events: none; + background: linear-gradient(100deg, transparent, rgba(255, 255, 255, 0.38), transparent); + transform: skewX(-18deg); + animation: dazzle-btn-sheen 3.4s ease-in-out infinite; +} + +@keyframes dazzle-btn-sheen { + 0% { left: -60%; } + 60%, 100% { left: 135%; } +} + +/* ---------- 5. 侧边菜单:选中项左侧发光指示条 ---------- */ +.glass-sider .ant-menu-item-selected { + position: relative; +} + +.glass-sider .ant-menu-item-selected::before { + content: ""; + position: absolute; + top: 8px; + bottom: 8px; + left: 2px; + width: 3px; + border-radius: 2px; + background: linear-gradient(180deg, #22d3ee, #8b5cf6); + box-shadow: 0 0 12px rgba(34, 211, 238, 0.9); + animation: dazzle-indicator-pulse 2.6s ease-in-out infinite; +} + +@keyframes dazzle-indicator-pulse { + 0%, 100% { box-shadow: 0 0 8px rgba(34, 211, 238, 0.7); } + 50% { box-shadow: 0 0 18px rgba(34, 211, 238, 1), 0 0 28px rgba(139, 92, 246, 0.5); } +} + +/* ---------- 6. 表格:行悬浮时左缘霓虹指示 ---------- */ +.ant-table-tbody > tr.ant-table-row > td { + transition: background 0.25s ease, box-shadow 0.25s ease; +} + +.ant-table-tbody > tr.ant-table-row:hover > td:first-child { + box-shadow: inset 3px 0 0 rgba(34, 211, 238, 0.75); +} + +/* ---------- 7. 霓虹滚动条 ---------- */ +.panel-content::-webkit-scrollbar, +.ai-message-list::-webkit-scrollbar, +.latest-list::-webkit-scrollbar, +.ant-table-body::-webkit-scrollbar { + width: 8px; + height: 8px; +} + +.panel-content::-webkit-scrollbar-thumb, +.ai-message-list::-webkit-scrollbar-thumb, +.latest-list::-webkit-scrollbar-thumb, +.ant-table-body::-webkit-scrollbar-thumb { + border-radius: 8px; + background: linear-gradient(180deg, rgba(34, 211, 238, 0.55), rgba(139, 92, 246, 0.55)); + box-shadow: inset 0 0 6px rgba(34, 211, 238, 0.35); +} + +.panel-content::-webkit-scrollbar-thumb:hover, +.ai-message-list::-webkit-scrollbar-thumb:hover, +.latest-list::-webkit-scrollbar-thumb:hover, +.ant-table-body::-webkit-scrollbar-thumb:hover { + background: linear-gradient(180deg, rgba(34, 211, 238, 0.85), rgba(139, 92, 246, 0.85)); +} + +.panel-content::-webkit-scrollbar-track, +.ai-message-list::-webkit-scrollbar-track, +.latest-list::-webkit-scrollbar-track, +.ant-table-body::-webkit-scrollbar-track { + background: rgba(4, 13, 30, 0.35); +} + +/* ---------- 8. 文本选中色 ---------- */ +::selection { + color: #ecfeff; + background: rgba(34, 211, 238, 0.38); + text-shadow: none; +} + +/* ---------- 9. 输入聚焦:霓虹外发光 ---------- */ +.ant-input:focus, +.ant-input-focused, +.ant-input-affix-wrapper-focused, +.ant-select-focused .ant-select-selector, +.ant-picker-focused { + box-shadow: 0 0 0 2px rgba(34, 211, 238, 0.16), 0 0 20px rgba(34, 211, 238, 0.22) !important; +}