feat: light theme, frontend link, nav fix, rename to 七虎AI

This commit is contained in:
qyyfw committed 2026-07-07 22:33:08 +08:00
1 parent effef176e2
commit e38a32e04e
12 files changed
+429 -345

No files matched your search

+1 -1
View File
@@ -4,7 +4,7 @@
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" /> <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Qihu-AIFlow - 智能自动化PaaS平台</title> <title>七虎AI - 智能AI能力集成平台</title>
</head> </head>
<body> <body>
<div id="root"></div> <div id="root"></div>
+66 -38
View File
@@ -11,8 +11,8 @@
display: flex; display: flex;
height: 100vh; height: 100vh;
overflow: hidden; overflow: hidden;
background: #0A0E1A; background: #F5F7FC;
color: #E8ECF4; color: #1A1F36;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', sans-serif; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', sans-serif;
} }
@@ -20,8 +20,8 @@
.admin-sidebar { .admin-sidebar {
width: var(--admin-sidebar-width); width: var(--admin-sidebar-width);
min-width: var(--admin-sidebar-width); min-width: var(--admin-sidebar-width);
background: linear-gradient(180deg, #0E1225 0%, #111627 100%); background: linear-gradient(180deg, #FFFFFF 0%, #FAFBFE 100%);
border-right: 1px solid rgba(255, 255, 255, 0.06); border-right: 1px solid rgba(0, 0, 0, 0.08);
display: flex; display: flex;
flex-direction: column; flex-direction: column;
transition: width 0.25s ease, min-width 0.25s ease; transition: width 0.25s ease, min-width 0.25s ease;
@@ -41,7 +41,7 @@
justify-content: space-between; justify-content: space-between;
padding: 16px 16px 16px 20px; padding: 16px 16px 16px 20px;
height: 60px; height: 60px;
border-bottom: 1px solid rgba(255, 255, 255, 0.06); border-bottom: 1px solid rgba(0, 0, 0, 0.08);
flex-shrink: 0; flex-shrink: 0;
} }
@@ -54,10 +54,10 @@
.admin-brand { .admin-brand {
font-size: 15px; font-size: 15px;
font-weight: 700; font-weight: 700;
color: #E8ECF4; color: #1A1F36;
letter-spacing: -0.02em; letter-spacing: -0.02em;
white-space: nowrap; white-space: nowrap;
background: linear-gradient(135deg, #C4B5FD, #A78BFA); background: linear-gradient(135deg, #6C63FF, #A78BFA);
-webkit-background-clip: text; -webkit-background-clip: text;
-webkit-text-fill-color: transparent; -webkit-text-fill-color: transparent;
background-clip: text; background-clip: text;
@@ -72,7 +72,7 @@
border-radius: 6px; border-radius: 6px;
border: none; border: none;
background: transparent; background: transparent;
color: #5A6480; color: #8892B0;
transition: all 0.15s ease; transition: all 0.15s ease;
cursor: pointer; cursor: pointer;
flex-shrink: 0; flex-shrink: 0;
@@ -109,7 +109,7 @@
} }
.admin-nav::-webkit-scrollbar-thumb { .admin-nav::-webkit-scrollbar-thumb {
background: rgba(255, 255, 255, 0.08); background: rgba(108, 99, 255, 0.10);
border-radius: 2px; border-radius: 2px;
} }
@@ -192,7 +192,7 @@
} }
.admin-nav-item:hover { .admin-nav-item:hover {
background: rgba(255, 255, 255, 0.05); background: rgba(108, 99, 255, 0.06);
color: #CCD6F6; color: #CCD6F6;
} }
@@ -257,7 +257,7 @@
/* Sidebar Footer */ /* Sidebar Footer */
.admin-sidebar-footer { .admin-sidebar-footer {
padding: 8px; padding: 8px;
border-top: 1px solid rgba(255, 255, 255, 0.06); border-top: 1px solid rgba(0, 0, 0, 0.08);
flex-shrink: 0; flex-shrink: 0;
} }
@@ -277,7 +277,7 @@
justify-content: space-between; justify-content: space-between;
padding: 0 32px; padding: 0 32px;
height: 60px; height: 60px;
border-bottom: 1px solid rgba(255, 255, 255, 0.06); border-bottom: 1px solid rgba(0, 0, 0, 0.08);
background: rgba(10, 14, 26, 0.85); background: rgba(10, 14, 26, 0.85);
backdrop-filter: blur(12px); backdrop-filter: blur(12px);
flex-shrink: 0; flex-shrink: 0;
@@ -292,7 +292,7 @@
.admin-page-title { .admin-page-title {
font-size: 17px; font-size: 17px;
font-weight: 600; font-weight: 600;
color: #E8ECF4; color: #1A1F36;
margin: 0; margin: 0;
white-space: nowrap; white-space: nowrap;
} }
@@ -306,7 +306,7 @@
} }
.breadcrumb-item { .breadcrumb-item {
color: #5A6480; color: #8892B0;
} }
.breadcrumb-item.current { .breadcrumb-item.current {
@@ -343,7 +343,7 @@
} }
.admin-topbar-action:hover { .admin-topbar-action:hover {
background: rgba(255, 255, 255, 0.05); background: rgba(108, 99, 255, 0.06);
color: #A78BFA; color: #A78BFA;
} }
@@ -355,7 +355,7 @@
padding: 2px 12px 2px 4px; padding: 2px 12px 2px 4px;
border-radius: 20px; border-radius: 20px;
background: rgba(255, 255, 255, 0.04); background: rgba(255, 255, 255, 0.04);
border: 1px solid rgba(255, 255, 255, 0.08); border: 1px solid rgba(0, 0, 0, 0.10);
font-size: 13px; font-size: 13px;
color: #CCD6F6; color: #CCD6F6;
} }
@@ -379,7 +379,7 @@
display: flex; display: flex;
flex-direction: column; flex-direction: column;
overflow: hidden; overflow: hidden;
background: #0A0E1A; background: #F5F7FC;
} }
.admin-content { .admin-content {
@@ -398,7 +398,7 @@
} }
.admin-content::-webkit-scrollbar-thumb { .admin-content::-webkit-scrollbar-thumb {
background: rgba(255, 255, 255, 0.08); background: rgba(108, 99, 255, 0.10);
border-radius: 3px; border-radius: 3px;
} }
@@ -414,7 +414,7 @@
.admin-stat-card { .admin-stat-card {
background: linear-gradient(135deg, rgba(17, 22, 39, 0.8), rgba(17, 22, 39, 0.6)); background: linear-gradient(135deg, rgba(17, 22, 39, 0.8), rgba(17, 22, 39, 0.6));
border: 1px solid rgba(255, 255, 255, 0.06); border: 1px solid rgba(0, 0, 0, 0.08);
border-radius: 12px; border-radius: 12px;
padding: 20px; padding: 20px;
transition: all 0.2s ease; transition: all 0.2s ease;
@@ -435,7 +435,7 @@
.admin-stat-card .stat-value { .admin-stat-card .stat-value {
font-size: 28px; font-size: 28px;
font-weight: 700; font-weight: 700;
color: #E8ECF4; color: #1A1F36;
line-height: 1.2; line-height: 1.2;
} }
@@ -455,7 +455,7 @@
/* Page section card */ /* Page section card */
.admin-section { .admin-section {
background: rgba(17, 22, 39, 0.5); background: rgba(17, 22, 39, 0.5);
border: 1px solid rgba(255, 255, 255, 0.06); border: 1px solid rgba(0, 0, 0, 0.08);
border-radius: 12px; border-radius: 12px;
padding: 24px; padding: 24px;
margin-bottom: 20px; margin-bottom: 20px;
@@ -467,13 +467,13 @@
justify-content: space-between; justify-content: space-between;
margin-bottom: 20px; margin-bottom: 20px;
padding-bottom: 16px; padding-bottom: 16px;
border-bottom: 1px solid rgba(255, 255, 255, 0.06); border-bottom: 1px solid rgba(0, 0, 0, 0.08);
} }
.admin-section-header h3 { .admin-section-header h3 {
font-size: 16px; font-size: 16px;
font-weight: 600; font-weight: 600;
color: #E8ECF4; color: #1A1F36;
margin: 0; margin: 0;
} }
@@ -522,7 +522,7 @@
text-transform: uppercase; text-transform: uppercase;
letter-spacing: 0.05em; letter-spacing: 0.05em;
text-align: left; text-align: left;
border-bottom: 1px solid rgba(255, 255, 255, 0.06); border-bottom: 1px solid rgba(0, 0, 0, 0.08);
background: rgba(255, 255, 255, 0.02); background: rgba(255, 255, 255, 0.02);
} }
@@ -565,7 +565,7 @@
.admin-btn-secondary { .admin-btn-secondary {
background: rgba(255, 255, 255, 0.06); background: rgba(255, 255, 255, 0.06);
color: #8892B0; color: #8892B0;
border: 1px solid rgba(255, 255, 255, 0.08); border: 1px solid rgba(0, 0, 0, 0.10);
} }
.admin-btn-secondary:hover { .admin-btn-secondary:hover {
@@ -614,7 +614,7 @@
gap: 8px; gap: 8px;
padding: 8px 14px; padding: 8px 14px;
background: rgba(255, 255, 255, 0.04); background: rgba(255, 255, 255, 0.04);
border: 1px solid rgba(255, 255, 255, 0.08); border: 1px solid rgba(0, 0, 0, 0.10);
border-radius: 8px; border-radius: 8px;
color: #8892B0; color: #8892B0;
flex: 1; flex: 1;
@@ -631,7 +631,7 @@
flex: 1; flex: 1;
border: none; border: none;
background: none; background: none;
color: #E8ECF4; color: #1A1F36;
font-size: 13px; font-size: 13px;
outline: none; outline: none;
} }
@@ -708,8 +708,8 @@
} }
.admin-modal { .admin-modal {
background: #111627; background: #FFFFFF;
border: 1px solid rgba(255, 255, 255, 0.08); border: 1px solid rgba(0, 0, 0, 0.10);
border-radius: 16px; border-radius: 16px;
padding: 24px; padding: 24px;
min-width: 420px; min-width: 420px;
@@ -722,7 +722,7 @@
.admin-modal h3 { .admin-modal h3 {
font-size: 18px; font-size: 18px;
font-weight: 600; font-weight: 600;
color: #E8ECF4; color: #1A1F36;
margin: 0 0 20px 0; margin: 0 0 20px 0;
} }
@@ -745,9 +745,9 @@
width: 100%; width: 100%;
padding: 10px 14px; padding: 10px 14px;
background: rgba(255, 255, 255, 0.04); background: rgba(255, 255, 255, 0.04);
border: 1px solid rgba(255, 255, 255, 0.08); border: 1px solid rgba(0, 0, 0, 0.10);
border-radius: 8px; border-radius: 8px;
color: #E8ECF4; color: #1A1F36;
font-size: 13px; font-size: 13px;
transition: border-color 0.15s ease; transition: border-color 0.15s ease;
outline: none; outline: none;
@@ -766,8 +766,8 @@
} }
.admin-form-group select option { .admin-form-group select option {
background: #111627; background: #FFFFFF;
color: #E8ECF4; color: #1A1F36;
} }
/* Toggle switch */ /* Toggle switch */
@@ -840,7 +840,7 @@
width: 32px; width: 32px;
height: 32px; height: 32px;
border-radius: 6px; border-radius: 6px;
border: 1px solid rgba(255, 255, 255, 0.08); border: 1px solid rgba(0, 0, 0, 0.10);
background: transparent; background: transparent;
color: #8892B0; color: #8892B0;
font-size: 13px; font-size: 13px;
@@ -905,7 +905,7 @@
justify-content: space-between; justify-content: space-between;
margin-bottom: 20px; margin-bottom: 20px;
padding-bottom: 16px; padding-bottom: 16px;
border-bottom: 1px solid rgba(255, 255, 255, 0.06); border-bottom: 1px solid rgba(0, 0, 0, 0.08);
} }
.admin-modal-header h3 { .admin-modal-header h3 {
@@ -926,7 +926,7 @@
} }
.admin-modal-close:hover { .admin-modal-close:hover {
color: #E8ECF4; color: #1A1F36;
background: rgba(255, 255, 255, 0.06); background: rgba(255, 255, 255, 0.06);
} }
@@ -939,7 +939,7 @@
gap: 8px; gap: 8px;
justify-content: flex-end; justify-content: flex-end;
padding-top: 16px; padding-top: 16px;
border-top: 1px solid rgba(255, 255, 255, 0.06); border-top: 1px solid rgba(0, 0, 0, 0.08);
} }
/* Spinner animation for logo upload */ /* Spinner animation for logo upload */
@@ -987,3 +987,31 @@
max-width: 90vw; max-width: 90vw;
} }
} }
/* Frontend access link */
.admin-frontend-link {
display: flex;
align-items: center;
gap: 6px;
padding: 8px 16px;
margin: 8px 12px;
border-radius: 8px;
font-size: 13px;
font-weight: 500;
color: #6C63FF;
background: rgba(108, 99, 255, 0.08);
text-decoration: none;
transition: all 0.2s;
cursor: pointer;
}
.admin-frontend-link:hover {
background: rgba(108, 99, 255, 0.15);
color: #5B5FED;
}
/* Nav link cursor pointer */
.landing-nav-v2 a {
cursor: pointer;
}
@@ -139,9 +139,13 @@ const AdminLayout: React.FC = () => {
<div className="admin-layout"> <div className="admin-layout">
<aside className="admin-sidebar"> <aside className="admin-sidebar">
<div className="admin-sidebar-header"> <div className="admin-sidebar-header">
<h1 className="admin-logo">AIFlow</h1> <h1 className="admin-logo">七虎AI</h1>
<span className="admin-subtitle">管理控制台</span> <span className="admin-subtitle">管理控制台</span>
</div> </div>
<a href="/#/portal" target="_blank" rel="noopener noreferrer" className="admin-frontend-link">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/><polyline points="15 3 21 3 21 9"/><line x1="10" y1="14" x2="21" y2="3"/></svg>
<span>访问前台</span>
</a>
<nav className="sidebar-nav"> <nav className="sidebar-nav">
{adminNavGroups.map((group) => { {adminNavGroups.map((group) => {
const isCollapsed = collapsedGroups.has(group.title); const isCollapsed = collapsedGroups.has(group.title);
+63 -19
View File
@@ -1,16 +1,18 @@
/* ===== Front Layout ===== */ /* ===== Front Layout V3 - Light Theme ===== */
.front-layout { .front-layout {
display: flex; display: flex;
height: 100vh; height: 100vh;
overflow: hidden; overflow: hidden;
background: #F5F7FC;
color: #1A1F36;
} }
/* Sidebar */ /* Sidebar */
.front-sidebar { .front-sidebar {
width: var(--sidebar-width); width: var(--sidebar-width);
min-width: var(--sidebar-width); min-width: var(--sidebar-width);
background: var(--color-sidebar-bg); background: linear-gradient(180deg, #FFFFFF 0%, #FAFBFE 100%);
border-right: 1px solid var(--color-border-light); border-right: 1px solid rgba(0, 0, 0, 0.08);
display: flex; display: flex;
flex-direction: column; flex-direction: column;
transition: width var(--transition-slow), min-width var(--transition-slow); transition: width var(--transition-slow), min-width var(--transition-slow);
@@ -29,7 +31,7 @@
justify-content: space-between; justify-content: space-between;
padding: var(--space-lg) var(--space-lg); padding: var(--space-lg) var(--space-lg);
height: var(--header-height); height: var(--header-height);
border-bottom: 1px solid var(--color-border-light); border-bottom: 1px solid rgba(0, 0, 0, 0.08);
} }
.sidebar-logo { .sidebar-logo {
@@ -41,7 +43,7 @@
.sidebar-brand { .sidebar-brand {
font-size: var(--text-lg); font-size: var(--text-lg);
font-weight: 700; font-weight: 700;
color: var(--color-text-primary); color: #1A1F36;
letter-spacing: -0.02em; letter-spacing: -0.02em;
white-space: nowrap; white-space: nowrap;
} }
@@ -53,13 +55,14 @@
width: 32px; width: 32px;
height: 32px; height: 32px;
border-radius: var(--radius-md); border-radius: var(--radius-md);
color: var(--color-text-tertiary); color: #8892B0;
transition: all var(--transition-fast); transition: all var(--transition-fast);
cursor: pointer;
} }
.collapse-btn:hover { .collapse-btn:hover {
background: var(--color-bg-hover); background: rgba(0, 0, 0, 0.08);
color: var(--color-text-primary); color: #8892B0;
} }
/* Navigation */ /* Navigation */
@@ -68,7 +71,7 @@
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: space-between; justify-content: space-between;
padding: var(--space-sm) var(--space-sm); padding: var(--space-sm);
overflow-y: auto; overflow-y: auto;
} }
@@ -79,12 +82,13 @@
} }
.nav-item { .nav-item {
position: relative;
display: flex; display: flex;
align-items: center; align-items: center;
gap: var(--space-md); gap: var(--space-md);
padding: var(--space-md) var(--space-md); padding: 10px var(--space-md);
border-radius: var(--radius-md); border-radius: var(--radius-md);
color: var(--color-text-secondary); color: #8892B0;
text-decoration: none; text-decoration: none;
font-size: var(--text-base); font-size: var(--text-base);
font-weight: 500; font-weight: 500;
@@ -93,13 +97,13 @@
} }
.nav-item:hover { .nav-item:hover {
background: var(--color-sidebar-hover); background: rgba(108, 99, 255, 0.06);
color: var(--color-text-primary); color: #1A1F36;
} }
.nav-item.active { .nav-item.active {
background: var(--color-sidebar-active); background: rgba(108, 99, 255, 0.12);
color: var(--color-accent); color: #8B85FF;
} }
.nav-icon { .nav-icon {
@@ -115,10 +119,30 @@
flex: 1; flex: 1;
} }
/* Active dot indicator */
.nav-active-dot {
display: none;
}
.nav-item.active .nav-active-dot {
display: block;
position: absolute;
right: 8px;
width: 6px;
height: 6px;
border-radius: 50%;
background: #6C63FF;
box-shadow: 0 0 8px rgba(108, 99, 255, 0.5);
}
/* Sidebar Footer */ /* Sidebar Footer */
.sidebar-footer { .sidebar-footer {
padding: var(--space-md); padding: var(--space-md);
border-top: 1px solid var(--color-border-light); border-top: 1px solid rgba(0, 0, 0, 0.08);
}
.sidebar-footer .nav-item {
margin-top: 2px;
} }
.user-info-mini { .user-info-mini {
@@ -126,13 +150,14 @@
align-items: center; align-items: center;
gap: var(--space-md); gap: var(--space-md);
padding: var(--space-sm); padding: var(--space-sm);
margin-bottom: 4px;
} }
.user-avatar-sm { .user-avatar-sm {
width: 32px; width: 32px;
height: 32px; height: 32px;
border-radius: var(--radius-full); border-radius: var(--radius-full);
background: linear-gradient(135deg, var(--color-accent), #8B8DFF); background: linear-gradient(135deg, #6C63FF, #A78BFA);
color: white; color: white;
display: flex; display: flex;
align-items: center; align-items: center;
@@ -151,16 +176,21 @@
.user-name { .user-name {
font-size: var(--text-sm); font-size: var(--text-sm);
font-weight: 600; font-weight: 600;
color: var(--color-text-primary); color: #1A1F36;
line-height: 1.3; line-height: 1.3;
} }
.user-plan { .user-plan {
font-size: var(--text-xs); font-size: var(--text-xs);
color: var(--color-accent); color: #8B85FF;
line-height: 1.3; line-height: 1.3;
} }
.logout-btn:hover {
color: #EF4444 !important;
background: rgba(239, 68, 68, 0.1) !important;
}
/* Main Content */ /* Main Content */
.front-main { .front-main {
flex: 1; flex: 1;
@@ -168,6 +198,12 @@
display: flex; display: flex;
flex-direction: column; flex-direction: column;
min-width: 0; min-width: 0;
background: #F5F7FC;
}
/* Forward-slash route for apps - hidden default route */
.front-main > * {
height: 100%;
} }
/* Responsive */ /* Responsive */
@@ -187,3 +223,11 @@
transform: translateX(0); transform: translateX(0);
} }
} }
/* Home & Admin links */
.nav-home-link {
margin-bottom: 4px;
border-bottom: 1px solid rgba(0, 0, 0, 0.06);
padding-bottom: 8px;
}
+31 -14
View File
@@ -5,13 +5,13 @@ import './FrontLayout.css';
const navItems = [ const navItems = [
{ path: '/chat', icon: 'chat', label: 'AI聊天' }, { path: '/chat', icon: 'chat', label: 'AI聊天' },
{ path: '/channels', icon: 'channel', label: '频道' }, { path: '/channels', icon: 'channel', label: 'IM Bot' },
{ path: '/knowledge', icon: 'knowledge', label: '知识库' }, { path: '/knowledge', icon: 'knowledge', label: '知识库' },
{ path: '/market', icon: 'market', label: '应用市场' }, { path: '/market', icon: 'market', label: '技能市场' },
{ path: '/token', icon: 'token', label: 'Token驾驶舱' }, { path: '/token', icon: 'token', label: 'Token驾驶舱' },
{ path: '/pricing', icon: 'pricing', label: '付费中心' }, { path: '/pricing', icon: 'pricing', label: '付费中心' },
{ path: '/assets', icon: 'assets', label: '资产' }, { path: '/assets', icon: 'assets', label: '资产文件' },
{ path: '/evolution', icon: 'evolution', label: 'AI进化' }, { path: '/evolution', icon: 'evolution', label: 'AI自进化' },
]; ];
const bottomItems = [ const bottomItems = [
@@ -24,6 +24,7 @@ const iconPaths: Record<string, JSX.Element> = {
channel: <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/></svg>, channel: <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/></svg>,
knowledge: <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"/></svg>, knowledge: <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"/></svg>,
market: <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><rect x="3" y="3" width="7" height="7" rx="1.2"/><rect x="14" y="3" width="7" height="7" rx="1.2"/><rect x="3" y="14" width="7" height="7" rx="1.2"/><rect x="14" y="14" width="7" height="7" rx="1.2"/></svg>, market: <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><rect x="3" y="3" width="7" height="7" rx="1.2"/><rect x="14" y="3" width="7" height="7" rx="1.2"/><rect x="3" y="14" width="7" height="7" rx="1.2"/><rect x="14" y="14" width="7" height="7" rx="1.2"/></svg>,
apps: <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><rect x="2" y="2" width="9" height="9" rx="2"/><rect x="13" y="2" width="9" height="9" rx="2"/><rect x="2" y="13" width="9" height="9" rx="2"/><rect x="13" y="13" width="5" height="5" rx="1.5"/><path d="M18 18v3"/><path d="M19.5 16.5v6"/></svg>,
token: <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="10"/><path d="M12 6v6l4 2"/></svg>, token: <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="10"/><path d="M12 6v6l4 2"/></svg>,
pricing: <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="10"/><path d="M16 8h-6a2 2 0 1 0 0 4h4a2 2 0 1 1 0 4H8"/><path d="M12 18V6"/></svg>, pricing: <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="10"/><path d="M16 8h-6a2 2 0 1 0 0 4h4a2 2 0 1 1 0 4H8"/><path d="M12 18V6"/></svg>,
profile: <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></svg>, profile: <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></svg>,
@@ -46,32 +47,48 @@ const FrontLayout: React.FC = () => {
<div className="front-layout"> <div className="front-layout">
{/* Sidebar */} {/* Sidebar */}
<aside className={`front-sidebar ${collapsed ? 'collapsed' : ''}`}> <aside className={`front-sidebar ${collapsed ? 'collapsed' : ''}`}>
{/* Header */}
<div className="sidebar-header"> <div className="sidebar-header">
<div className="sidebar-logo"> <div className="sidebar-logo">
<svg width="28" height="28" viewBox="0 0 32 32" fill="none"> <svg width="32" height="32" viewBox="0 0 32 32" fill="none">
<rect width="32" height="32" rx="8" fill="#5B5FED"/> <defs>
<linearGradient id="flGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stopColor="#6C63FF"/>
<stop offset="100%" stopColor="#A78BFA"/>
</linearGradient>
</defs>
<rect width="32" height="32" rx="8" fill="url(#flGrad)"/>
<path d="M8 20V12l4 4 4-4v8" stroke="white" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" fill="none"/> <path d="M8 20V12l4 4 4-4v8" stroke="white" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" fill="none"/>
<path d="M6 22h20" stroke="white" strokeWidth="1.5" strokeLinecap="round" opacity="0.5"/> <path d="M6 22h20" stroke="white" strokeWidth="1.5" strokeLinecap="round" opacity="0.5"/>
</svg> </svg>
{!collapsed && <span className="sidebar-brand">Qihu-AIFlow</span>} {!collapsed && <span className="sidebar-brand">七虎AI</span>}
</div> </div>
<button className="collapse-btn" onClick={() => setCollapsed(!collapsed)}> <button className="collapse-btn" onClick={() => setCollapsed(!collapsed)}>
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"> <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
<line x1="3" y1="12" x2="21" y2="12"/><line x1="3" y1="6" x2="21" y2="6"/><line x1="3" y1="18" x2="21" y2="18"/> {collapsed ? <><polyline points="13 17 18 12 13 7"/><polyline points="6 17 11 12 6 7"/></> : <><polyline points="11 17 6 12 11 7"/><polyline points="18 17 13 12 18 7"/></>}
</svg> </svg>
</button> </button>
</div> </div>
{/* Navigation */}
<nav className="sidebar-nav"> <nav className="sidebar-nav">
<NavLink to="/" className={({ isActive }) => `nav-item nav-home-link`} end>
<span className="nav-item-icon">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9 22 9 12 15 12 15 22"/></svg>
</span>
{!collapsed && <span className="nav-item-label">返回首页</span>}
</NavLink>
<div className="nav-section"> <div className="nav-section">
{navItems.map(item => ( {navItems.map(item => (
<NavLink <NavLink
key={item.path} key={item.path}
to={item.path} to={item.path}
className={({ isActive }) => `nav-item ${isActive ? 'active' : ''}`} className={({ isActive }) => `nav-item ${isActive ? 'active' : ''}`}
title={collapsed ? item.label : undefined}
> >
<span className="nav-icon">{iconPaths[item.icon]}</span> <span className="nav-icon">{iconPaths[item.icon]}</span>
{!collapsed && <span className="nav-label">{item.label}</span>} {!collapsed && <span className="nav-label">{item.label}</span>}
{!collapsed && <span className="nav-active-dot" />}
</NavLink> </NavLink>
))} ))}
</div> </div>
@@ -81,14 +98,17 @@ const FrontLayout: React.FC = () => {
key={item.path} key={item.path}
to={item.path} to={item.path}
className={({ isActive }) => `nav-item ${isActive ? 'active' : ''}`} className={({ isActive }) => `nav-item ${isActive ? 'active' : ''}`}
title={collapsed ? item.label : undefined}
> >
<span className="nav-icon">{iconPaths[item.icon]}</span> <span className="nav-icon">{iconPaths[item.icon]}</span>
{!collapsed && <span className="nav-label">{item.label}</span>} {!collapsed && <span className="nav-label">{item.label}</span>}
{!collapsed && <span className="nav-active-dot" />}
</NavLink> </NavLink>
))} ))}
</div> </div>
</nav> </nav>
{/* Footer */}
<div className="sidebar-footer"> <div className="sidebar-footer">
<div className="user-info-mini"> <div className="user-info-mini">
<div className="user-avatar-sm"> <div className="user-avatar-sm">
@@ -105,17 +125,14 @@ const FrontLayout: React.FC = () => {
<NavLink <NavLink
to="/admin" to="/admin"
className={({ isActive }) => `nav-item ${isActive ? 'active' : ''}`} className={({ isActive }) => `nav-item ${isActive ? 'active' : ''}`}
title="返回后台" title="管理后台"
> >
<span className="nav-icon"> <span className="nav-icon">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"> <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
<rect x="3" y="3" width="7" height="7" rx="1.2"/> <circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"/>
<rect x="14" y="3" width="7" height="7" rx="1.2"/>
<rect x="3" y="14" width="7" height="7" rx="1.2"/>
<rect x="14" y="14" width="7" height="7" rx="1.2"/>
</svg> </svg>
</span> </span>
{!collapsed && <span className="nav-label">返回后台</span>} {!collapsed && <span className="nav-label">管理后台</span>}
</NavLink> </NavLink>
)} )}
<button <button
+2 -2
View File
@@ -312,7 +312,7 @@ const SiteSettings: React.FC = () => {
<FormGroup label="网站名称" required> <FormGroup label="网站名称" required>
<input className="admin-form-input" value={brand.siteName} <input className="admin-form-input" value={brand.siteName}
onChange={e => setBrand({ ...brand, siteName: e.target.value })} onChange={e => setBrand({ ...brand, siteName: e.target.value })}
placeholder="例如: Qihu-AIFlow" /> placeholder="例如: 七虎AI" />
</FormGroup> </FormGroup>
<FormGroup label="LOGO URL"> <FormGroup label="LOGO URL">
<input className="admin-form-input" value={brand.logo} <input className="admin-form-input" value={brand.logo}
@@ -638,7 +638,7 @@ const SiteSettings: React.FC = () => {
value={registration.welcome_message} value={registration.welcome_message}
onChange={e => setRegistration({ ...registration, welcome_message: e.target.value })} onChange={e => setRegistration({ ...registration, welcome_message: e.target.value })}
style={{ minHeight: 80 }} style={{ minHeight: 80 }}
placeholder="欢迎加入 Qihu-AIFlow!从这里开始你的 AI 创造之旅..." /> placeholder="欢迎加入七虎AI!从这里开始你的 AI 创造之旅..." />
</FormGroup> </FormGroup>
<FormActions> <FormActions>
@@ -407,7 +407,7 @@ const TimelinePanel: React.FC<{
pdf.text('我的AI进化时间线', 10, 15); pdf.text('我的AI进化时间线', 10, 15);
pdf.setFontSize(10); pdf.setFontSize(10);
pdf.text(`生成日期: ${dateStr}`, 10, 22); pdf.text(`生成日期: ${dateStr}`, 10, 22);
pdf.text('Qihu-AIFlow', pageWidth - 10, 22, { align: 'right' }); pdf.text('七虎AI', pageWidth - 10, 22, { align: 'right' });
// 单页添加图片,自动缩放适应 // 单页添加图片,自动缩放适应
const maxHeight = pageHeight - 35; const maxHeight = pageHeight - 35;
@@ -417,7 +417,7 @@ const TimelinePanel: React.FC<{
// 底部水印 // 底部水印
pdf.setFontSize(8); pdf.setFontSize(8);
pdf.setTextColor(200, 200, 200); pdf.setTextColor(200, 200, 200);
pdf.text('Qihu-AIFlow', pageWidth / 2, pageHeight - 5, { align: 'center' }); pdf.text('七虎AI', pageWidth / 2, pageHeight - 5, { align: 'center' });
pdf.save(`${filename}.pdf`); pdf.save(`${filename}.pdf`);
setExportMsg(`时间线已导出为 PDF: ${filename}.pdf`); setExportMsg(`时间线已导出为 PDF: ${filename}.pdf`);
@@ -746,7 +746,7 @@ const ProfilePanel: React.FC<{ profile: EvolutionProfile; skills: EvolutionSkill
{/* Footer */} {/* Footer */}
<div className="evo-share-card-footer"> <div className="evo-share-card-footer">
<span style={{ opacity: 0.5, fontSize: '11px' }}>{new Date().toLocaleDateString()}</span> <span style={{ opacity: 0.5, fontSize: '11px' }}>{new Date().toLocaleDateString()}</span>
<span style={{ opacity: 0.5, fontSize: '11px' }}>Qihu-AIFlow</span> <span style={{ opacity: 0.5, fontSize: '11px' }}>七虎AI</span>
</div> </div>
</div> </div>
</div> </div>
+23 -23
View File
@@ -10,27 +10,27 @@
overflow-x: hidden; overflow-x: hidden;
} }
/* === Dark Theme Variables (scoped to landing page) === */ /* === Light Theme Variables (scoped to landing page) === */
.landing-page-v2 { .landing-page-v2 {
--lp-bg: #0A0E1A; --lp-bg: #FFFFFF;
--lp-bg-secondary: #111627; --lp-bg-secondary: #F5F7FC;
--lp-bg-card: #161B2E; --lp-bg-card: #FFFFFF;
--lp-bg-card-hover: #1C2240; --lp-bg-card-hover: #F5F7FC;
--lp-bg-glass: rgba(22, 27, 46, 0.7); --lp-bg-glass: rgba(255, 255, 255, 0.8);
--lp-border: rgba(255, 255, 255, 0.06); --lp-border: rgba(0, 0, 0, 0.08);
--lp-border-light: rgba(255, 255, 255, 0.04); --lp-border-light: rgba(0, 0, 0, 0.05);
--lp-text: #E8ECF4; --lp-text: #1A1F36;
--lp-text-secondary: #8892B0; --lp-text-secondary: #5A6480;
--lp-text-tertiary: #5A6480; --lp-text-tertiary: #8892B0;
--lp-accent: #6C63FF; --lp-accent: #6C63FF;
--lp-accent-light: #8B85FF; --lp-accent-light: #8B85FF;
--lp-accent-glow: rgba(108, 99, 255, 0.3); --lp-accent-glow: rgba(108, 99, 255, 0.3);
--lp-gradient-1: linear-gradient(135deg, #6C63FF 0%, #A78BFA 50%, #C084FC 100%); --lp-gradient-1: linear-gradient(135deg, #6C63FF 0%, #A78BFA 50%, #C084FC 100%);
--lp-gradient-2: linear-gradient(135deg, #06B6D4 0%, #3B82F6 100%); --lp-gradient-2: linear-gradient(135deg, #06B6D4 0%, #3B82F6 100%);
--lp-gradient-3: linear-gradient(135deg, #10B981 0%, #34D399 100%); --lp-gradient-3: linear-gradient(135deg, #10B981 0%, #34D399 100%);
--lp-gradient-hero: radial-gradient(ellipse 80% 50% at 50% -20%, rgba(108, 99, 255, 0.15), transparent 70%); --lp-gradient-hero: radial-gradient(ellipse 80% 50% at 50% -20%, rgba(108, 99, 255, 0.08), transparent 70%);
--lp-shadow-card: 0 1px 3px rgba(0,0,0,0.3), 0 4px 12px rgba(0,0,0,0.2); --lp-shadow-card: 0 1px 3px rgba(0,0,0,0.06), 0 4px 12px rgba(0,0,0,0.04);
--lp-shadow-lg: 0 8px 32px rgba(0,0,0,0.4); --lp-shadow-lg: 0 8px 32px rgba(0,0,0,0.10);
--lp-radius: 12px; --lp-radius: 12px;
--lp-radius-sm: 8px; --lp-radius-sm: 8px;
--lp-radius-lg: 16px; --lp-radius-lg: 16px;
@@ -42,7 +42,7 @@
top: 24px; top: 24px;
left: 50%; left: 50%;
transform: translateX(-50%); transform: translateX(-50%);
background: rgba(22, 27, 46, 0.95); background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(20px); backdrop-filter: blur(20px);
border: 1px solid rgba(108, 99, 255, 0.3); border: 1px solid rgba(108, 99, 255, 0.3);
color: var(--lp-text); color: var(--lp-text);
@@ -71,7 +71,7 @@
} }
.landing-header-v2.scrolled { .landing-header-v2.scrolled {
background: rgba(10, 14, 26, 0.85); background: rgba(255, 255, 255, 0.85);
backdrop-filter: blur(20px); backdrop-filter: blur(20px);
border-bottom: 1px solid var(--lp-border); border-bottom: 1px solid var(--lp-border);
padding: 10px 0; padding: 10px 0;
@@ -311,7 +311,7 @@
font-size: 16px; font-size: 16px;
font-weight: 500; font-weight: 500;
color: var(--lp-text-secondary); color: var(--lp-text-secondary);
background: rgba(255, 255, 255, 0.04); background: rgba(108, 99, 255, 0.04);
border: 1px solid var(--lp-border); border: 1px solid var(--lp-border);
cursor: pointer; cursor: pointer;
transition: all 0.3s ease; transition: all 0.3s ease;
@@ -319,8 +319,8 @@
.btn-hero-secondary:hover { .btn-hero-secondary:hover {
color: var(--lp-text); color: var(--lp-text);
background: rgba(255, 255, 255, 0.08); background: rgba(108, 99, 255, 0.10);
border-color: rgba(255, 255, 255, 0.12); border-color: rgba(0, 0, 0, 0.10);
} }
.hero-stats-v2 { .hero-stats-v2 {
@@ -441,7 +441,7 @@
width: 8px; width: 8px;
height: 8px; height: 8px;
border-radius: 50%; border-radius: 50%;
background: rgba(255, 255, 255, 0.2); background: rgba(108, 99, 255, 0.20);
border: none; border: none;
cursor: pointer; cursor: pointer;
transition: all 0.3s; transition: all 0.3s;
@@ -622,8 +622,8 @@
font-size: 13px; font-size: 13px;
font-weight: 500; font-weight: 500;
color: var(--lp-text-secondary); color: var(--lp-text-secondary);
background: rgba(255, 255, 255, 0.04); background: rgba(108, 99, 255, 0.04);
border: 1px solid rgba(255, 255, 255, 0.06); border: 1px solid rgba(0, 0, 0, 0.08);
transition: all 0.2s; transition: all 0.2s;
white-space: nowrap; white-space: nowrap;
} }
@@ -763,7 +763,7 @@
.filter-chip:hover { .filter-chip:hover {
color: var(--lp-text); color: var(--lp-text);
border-color: rgba(255, 255, 255, 0.12); border-color: rgba(0, 0, 0, 0.10);
} }
.filter-chip.active { .filter-chip.active {
+17 -17
View File
@@ -157,14 +157,14 @@ const LandingPage: React.FC = () => {
<path d="M8 20V12l4 4 4-4v8" stroke="white" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" fill="none"/> <path d="M8 20V12l4 4 4-4v8" stroke="white" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" fill="none"/>
<path d="M6 22h20" stroke="white" strokeWidth="1.5" strokeLinecap="round" opacity="0.5"/> <path d="M6 22h20" stroke="white" strokeWidth="1.5" strokeLinecap="round" opacity="0.5"/>
</svg> </svg>
<span className="landing-brand-text">Qihu-AIFlow</span> <span className="landing-brand-text">七虎AI</span>
</div> </div>
<nav className="landing-nav-v2"> <nav className="landing-nav-v2" style={{ cursor: 'pointer' }}>
<a href="#what-is">平台介绍</a> <a onClick={() => document.getElementById('what-is')?.scrollIntoView({ behavior: 'smooth' })}>平台介绍</a>
<a href="#architecture">平台架构</a> <a onClick={() => document.getElementById('architecture')?.scrollIntoView({ behavior: 'smooth' })}>平台架构</a>
<a href="#capabilities">能力体系</a> <a onClick={() => document.getElementById('capabilities')?.scrollIntoView({ behavior: 'smooth' })}>能力体系</a>
<a href="#scenarios">应用场景</a> <a onClick={() => document.getElementById('scenarios')?.scrollIntoView({ behavior: 'smooth' })}>应用场景</a>
<a href="#market">技能生态</a> <a onClick={() => document.getElementById('market')?.scrollIntoView({ behavior: 'smooth' })}>技能生态</a>
</nav> </nav>
<div className="landing-actions-v2"> <div className="landing-actions-v2">
<button className="btn-ghost-v2" onClick={() => navigate('/login')}>登录</button> <button className="btn-ghost-v2" onClick={() => navigate('/login')}>登录</button>
@@ -173,7 +173,7 @@ const LandingPage: React.FC = () => {
</div> </div>
</header> </header>
{/* Hero Section — What is Qihu-AIFlow */} {/* Hero Section — What is 七虎AI */}
<section className="hero-section-v2"> <section className="hero-section-v2">
<div className="hero-bg-orb orb-1" /> <div className="hero-bg-orb orb-1" />
<div className="hero-bg-orb orb-2" /> <div className="hero-bg-orb orb-2" />
@@ -188,7 +188,7 @@ const LandingPage: React.FC = () => {
<span className="hero-gradient-text"> 的超级工作台</span> <span className="hero-gradient-text"> 的超级工作台</span>
</h1> </h1>
<p className="hero-subtitle-v2"> <p className="hero-subtitle-v2">
Qihu-AIFlow 是一站式 AI 能力集成平台,让你在一个地方完成对话、知识库、技能编排、模型切换、自动化搭建<br/> 七虎AI 是一站式 AI 能力集成平台,让你在一个地方完成对话、知识库、技能编排、模型切换、自动化搭建<br/>
无需拼接多个工具,从想法到落地,一个平台就够了 无需拼接多个工具,从想法到落地,一个平台就够了
</p> </p>
<div className="hero-cta-v2"> <div className="hero-cta-v2">
@@ -226,11 +226,11 @@ const LandingPage: React.FC = () => {
</div> </div>
</section> </section>
{/* What is Qihu-AIFlow — Platform Introduction */} {/* What is 七虎AI — Platform Introduction */}
<section id="what-is" className="whatis-section-v2"> <section id="what-is" className="whatis-section-v2">
<div className="section-header-v2"> <div className="section-header-v2">
<span className="section-badge-v2">平台介绍</span> <span className="section-badge-v2">平台介绍</span>
<h2>Qihu-AIFlow 是什么?</h2> <h2>七虎AI 是什么?</h2>
<p>一个面向 AI 爱好者和从业者的个人 AI 能力集成平台</p> <p>一个面向 AI 爱好者和从业者的个人 AI 能力集成平台</p>
</div> </div>
<div className="whatis-cards-v2"> <div className="whatis-cards-v2">
@@ -262,7 +262,7 @@ const LandingPage: React.FC = () => {
<div className="section-header-v2"> <div className="section-header-v2">
<span className="section-badge-v2">平台架构</span> <span className="section-badge-v2">平台架构</span>
<h2>四层架构 · 层层赋能</h2> <h2>四层架构 · 层层赋能</h2>
<p>从基础设施到上层应用,理解 Qihu-AIFlow 的技术全貌</p> <p>从基础设施到上层应用,理解 七虎AI 的技术全貌</p>
</div> </div>
<div className="arch-layers-v2"> <div className="arch-layers-v2">
{archLayers.map((layer, idx) => ( {archLayers.map((layer, idx) => (
@@ -417,14 +417,14 @@ const LandingPage: React.FC = () => {
<path d="M8 20V12l4 4 4-4v8" stroke="white" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" fill="none"/> <path d="M8 20V12l4 4 4-4v8" stroke="white" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" fill="none"/>
<path d="M6 22h20" stroke="white" strokeWidth="1.5" strokeLinecap="round" opacity="0.5"/> <path d="M6 22h20" stroke="white" strokeWidth="1.5" strokeLinecap="round" opacity="0.5"/>
</svg> </svg>
<span>Qihu-AIFlow</span> <span>七虎AI</span>
</div> </div>
<div className="footer-links-v2"> <div className="footer-links-v2">
<div className="footer-col-v2"> <div className="footer-col-v2">
<h4>平台</h4> <h4>平台</h4>
<a href="#what-is">平台介绍</a> <a onClick={() => document.getElementById('what-is')?.scrollIntoView({ behavior: 'smooth' })}>平台介绍</a>
<a href="#architecture">平台架构</a> <a onClick={() => document.getElementById('architecture')?.scrollIntoView({ behavior: 'smooth' })}>平台架构</a>
<a href="#capabilities">能力体系</a> <a onClick={() => document.getElementById('capabilities')?.scrollIntoView({ behavior: 'smooth' })}>能力体系</a>
</div> </div>
<div className="footer-col-v2"> <div className="footer-col-v2">
<h4>资源</h4> <h4>资源</h4>
@@ -441,7 +441,7 @@ const LandingPage: React.FC = () => {
</div> </div>
</div> </div>
<div className="footer-bottom-v2"> <div className="footer-bottom-v2">
<p>&copy; 2026 Qihu-AIFlow. All rights reserved.</p> <p>&copy; 2026 七虎AI. All rights reserved.</p>
</div> </div>
</footer> </footer>
</div> </div>
+159 -154
View File
@@ -1,14 +1,15 @@
/* ===== Login Page ===== */ /* ===== Login Page V3 - Dark Theme ===== */
.login-page { .login-page {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
height: 100vh; height: 100vh;
background: var(--color-bg-primary); background: #F5F7FC;
position: relative; position: relative;
overflow: hidden; overflow: hidden;
} }
/* Background decorations */
.login-bg-decor { .login-bg-decor {
position: absolute; position: absolute;
inset: 0; inset: 0;
@@ -19,35 +20,37 @@
.bg-circle { .bg-circle {
position: absolute; position: absolute;
border-radius: 50%; border-radius: 50%;
opacity: 0.08; filter: blur(80px);
} }
.bg-circle.c1 { .bg-circle.c1 {
width: 600px; height: 600px; width: 600px; height: 600px;
background: var(--color-accent); background: #6C63FF;
top: -200px; right: -100px; top: -200px; right: -100px;
opacity: 0.12;
} }
.bg-circle.c2 { .bg-circle.c2 {
width: 400px; height: 400px; width: 400px; height: 400px;
background: #8B8DFF; background: #06B6D4;
bottom: -100px; left: -50px; bottom: -100px; left: -50px;
opacity: 0.1;
} }
.bg-circle.c3 { .bg-circle.c3 {
width: 300px; height: 300px; width: 300px; height: 300px;
background: var(--color-accent); background: #A78BFA;
top: 50%; left: 50%; top: 50%; left: 50%;
transform: translate(-50%, -50%); transform: translate(-50%, -50%);
opacity: 0.04; opacity: 0.06;
} }
.bg-grid { .bg-grid {
position: absolute; position: absolute;
inset: 0; inset: 0;
background-image: background-image:
linear-gradient(rgba(0,0,0,0.02) 1px, transparent 1px), linear-gradient(rgba(108, 99, 255, 0.03) 1px, transparent 1px),
linear-gradient(90deg, rgba(0,0,0,0.02) 1px, transparent 1px); linear-gradient(90deg, rgba(108, 99, 255, 0.03) 1px, transparent 1px);
background-size: 60px 60px; background-size: 60px 60px;
} }
@@ -56,203 +59,212 @@
display: flex; display: flex;
width: 900px; width: 900px;
min-height: 560px; min-height: 560px;
background: #FFFFFF; background: rgba(17, 22, 39, 0.95);
border-radius: var(--radius-2xl); backdrop-filter: blur(24px);
box-shadow: var(--shadow-xl); border: 1px solid rgba(0, 0, 0, 0.08);
border-radius: 20px;
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.4);
overflow: hidden; overflow: hidden;
z-index: var(--z-base);
position: relative; position: relative;
z-index: 1;
animation: loginSlideUp 0.5s ease;
} }
/* Brand Panel */ @keyframes loginSlideUp {
from { opacity: 0; transform: translateY(24px); }
to { opacity: 1; transform: translateY(0); }
}
/* Left brand panel */
.login-brand-panel { .login-brand-panel {
width: 400px; width: 400px;
background: linear-gradient(135deg, #2D2B55 0%, #1A1A2E 50%, #2D2B55 100%); background: linear-gradient(135deg, rgba(108, 99, 255, 0.08) 0%, rgba(167, 139, 250, 0.05) 100%);
padding: 48px 40px;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; border-right: 1px solid rgba(255, 255, 255, 0.04);
position: relative;
overflow: hidden;
}
.login-brand-panel::before {
content: '';
position: absolute;
width: 300px; height: 300px;
border-radius: 50%;
background: radial-gradient(circle, rgba(91,95,237,0.3) 0%, transparent 70%);
top: -50px; right: -50px;
}
.login-brand-panel::after {
content: '';
position: absolute;
width: 200px; height: 200px;
border-radius: 50%;
background: radial-gradient(circle, rgba(139,141,255,0.2) 0%, transparent 70%);
bottom: -30px; left: -30px;
} }
.brand-content { .brand-content {
text-align: center; width: 100%;
color: white;
z-index: 1;
} }
.brand-icon { .brand-icon {
margin-bottom: var(--space-xl); margin-bottom: 20px;
} }
.brand-title { .brand-title {
font-size: 36px; font-size: 32px;
font-weight: 800; font-weight: 800;
letter-spacing: -0.03em; color: #1A1F36;
margin-bottom: var(--space-sm); margin-bottom: 8px;
letter-spacing: -0.02em;
} }
.brand-desc { .brand-desc {
font-size: var(--text-base); font-size: 15px;
color: rgba(255,255,255,0.6); color: #5A6480;
margin-bottom: var(--space-3xl); margin-bottom: 32px;
} }
.brand-features { .brand-features {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: var(--space-md); gap: 14px;
text-align: left;
} }
.brand-feature { .brand-feature {
display: flex; display: flex;
align-items: center; align-items: center;
gap: var(--space-md); gap: 10px;
font-size: var(--text-sm); font-size: 14px;
color: rgba(255,255,255,0.75); color: #5A6480;
} }
.bf-icon { .bf-icon {
color: #6C63FF; width: 20px;
font-weight: 700; height: 20px;
font-size: var(--text-base); border-radius: 50%;
} background: rgba(16, 185, 129, 0.15);
color: #10B981;
/* Form Panel */
.login-form-panel {
flex: 1;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
padding: var(--space-4xl); font-size: 12px;
font-weight: 700;
flex-shrink: 0;
}
/* Right form panel */
.login-form-panel {
flex: 1;
padding: 48px 40px;
display: flex;
align-items: center;
} }
.login-form-inner { .login-form-inner {
width: 100%; width: 100%;
max-width: 340px;
} }
/* Tabs */
.login-tabs { .login-tabs {
display: flex; display: flex;
gap: var(--space-2xl); background: rgba(255, 255, 255, 0.04);
margin-bottom: var(--space-3xl); border-radius: 10px;
padding: 4px;
margin-bottom: 24px;
} }
.login-tab { .login-tab {
font-size: var(--text-lg); flex: 1;
font-weight: 700; padding: 10px;
color: var(--color-text-tertiary); border-radius: 8px;
padding-bottom: var(--space-sm); font-size: 14px;
border-bottom: 2px solid transparent; font-weight: 600;
transition: all var(--transition-fast); color: #5A6480;
background: transparent;
border: none;
cursor: pointer;
transition: all 0.2s;
} }
.login-tab.active { .login-tab.active {
color: var(--color-text-primary); background: rgba(108, 99, 255, 0.15);
border-bottom-color: var(--color-accent); color: #8B85FF;
} }
.login-tab:hover { .login-tab:hover:not(.active) {
color: var(--color-text-primary); color: #5A6480;
} }
/* Error message */
.form-error {
padding: 10px 14px;
border-radius: 8px;
background: rgba(239, 68, 68, 0.1);
border: 1px solid rgba(239, 68, 68, 0.2);
color: #F87171;
font-size: 13px;
text-align: center;
margin-bottom: 16px;
}
/* Form */
.login-form { .login-form {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: var(--space-xl); gap: 16px;
} }
.form-group { .form-group {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: var(--space-sm); gap: 6px;
margin-bottom: 16px;
} }
.form-label { .form-label {
font-size: var(--text-sm); font-size: 13px;
font-weight: 600; font-weight: 500;
color: var(--color-text-primary); color: #5A6480;
margin-bottom: 6px; }
.required {
color: #EF4444;
} }
.form-input { .form-input {
width: 100%; padding: 12px 14px;
padding: 12px 16px; border-radius: 10px;
border: 1px solid var(--color-border); border: 1px solid rgba(0, 0, 0, 0.10);
border-radius: var(--radius-lg); background: rgba(255, 255, 255, 0.03);
font-size: var(--text-base); color: #1A1F36;
color: var(--color-text-primary); font-size: 14px;
background: var(--color-bg-primary);
transition: all var(--transition-fast);
outline: none; outline: none;
transition: all 0.2s;
width: 100%;
} }
.form-input:focus { .form-input:focus {
border-color: var(--color-accent); border-color: rgba(108, 99, 255, 0.4);
box-shadow: 0 0 0 3px var(--color-accent-light); background: rgba(108, 99, 255, 0.05);
background: #FFFFFF; box-shadow: 0 0 0 3px rgba(108, 99, 255, 0.1);
} }
.form-input::placeholder { .form-input::placeholder {
color: var(--color-text-disabled); color: #3A4460;
} }
/* Submit button */
.login-submit-btn { .login-submit-btn {
height: 46px; width: 100%;
background: linear-gradient(135deg, #5B5FED, #6C63FF); padding: 13px;
border-radius: 10px;
border: none;
background: linear-gradient(135deg, #6C63FF, #A78BFA);
color: white; color: white;
border-radius: var(--radius-lg); font-size: 15px;
font-size: var(--text-base); font-weight: 600;
font-weight: 700; cursor: pointer;
letter-spacing: 0.15em; transition: all 0.3s;
transition: all var(--transition-fast); margin-top: 8px;
} }
.login-submit-btn:hover { .login-submit-btn:hover:not(:disabled) {
background: linear-gradient(135deg, #4A4ECC, #5B5FED); box-shadow: 0 4px 20px rgba(108, 99, 255, 0.4);
transform: translateY(-1px); transform: translateY(-1px);
box-shadow: var(--shadow-md);
}
.login-submit-btn:active {
transform: translateY(0);
} }
.login-submit-btn:disabled { .login-submit-btn:disabled {
opacity: 0.5; opacity: 0.6;
cursor: not-allowed; cursor: not-allowed;
} }
.login-submit-btn:disabled:hover { /* Register method tabs */
transform: none;
box-shadow: none;
}
/* Register Method Tabs */
.register-method-tabs { .register-method-tabs {
display: flex; display: flex;
gap: var(--space-sm); gap: 12px;
margin-bottom: var(--space-lg); margin-bottom: 4px;
} }
.register-method-tab { .register-method-tab {
@@ -261,32 +273,32 @@
align-items: center; align-items: center;
justify-content: center; justify-content: center;
gap: 6px; gap: 6px;
padding: var(--space-sm) var(--space-md); padding: 8px;
border-radius: var(--radius-md); border-radius: 8px;
border: 1px solid var(--color-border); border: 1px solid rgba(0, 0, 0, 0.10);
background: var(--color-bg-primary); background: transparent;
font-size: var(--text-sm); color: #5A6480;
font-size: 13px;
font-weight: 500; font-weight: 500;
color: var(--color-text-secondary);
cursor: pointer; cursor: pointer;
transition: all var(--transition-fast); transition: all 0.2s;
}
.register-method-tab:hover {
border-color: var(--color-accent-light);
} }
.register-method-tab.active { .register-method-tab.active {
border-color: var(--color-accent); border-color: rgba(108, 99, 255, 0.3);
background: var(--color-accent-subtle); background: rgba(108, 99, 255, 0.1);
color: var(--color-accent); color: #8B85FF;
font-weight: 600;
} }
/* SMS Row */ .register-method-tab:hover:not(.active) {
border-color: rgba(255, 255, 255, 0.12);
color: #5A6480;
}
/* SMS row */
.sms-row { .sms-row {
display: flex; display: flex;
gap: var(--space-sm); gap: 10px;
} }
.sms-input { .sms-input {
@@ -294,49 +306,42 @@
} }
.sms-btn { .sms-btn {
padding: var(--space-sm) var(--space-lg); padding: 10px 16px;
border-radius: var(--radius-md); border-radius: 10px;
border: 1px solid var(--color-accent); border: 1px solid rgba(108, 99, 255, 0.2);
background: transparent; background: rgba(108, 99, 255, 0.08);
color: var(--color-accent); color: #8B85FF;
font-size: var(--text-sm); font-size: 13px;
font-weight: 500; font-weight: 500;
cursor: pointer; cursor: pointer;
white-space: nowrap; white-space: nowrap;
transition: all var(--transition-fast); transition: all 0.2s;
} }
.sms-btn:hover:not(:disabled) { .sms-btn:hover:not(:disabled) {
background: var(--color-accent); background: rgba(108, 99, 255, 0.15);
color: white;
} }
.sms-btn:disabled { .sms-btn:disabled {
opacity: 0.5; opacity: 0.5;
cursor: not-allowed; cursor: not-allowed;
border-color: var(--color-border);
color: var(--color-text-tertiary);
}
/* Required Marker */
.required {
color: var(--color-error);
} }
/* Responsive */
@media (max-width: 768px) { @media (max-width: 768px) {
.login-container { .login-container {
flex-direction: column; flex-direction: column;
width: 90vw; width: calc(100vw - 32px);
min-height: auto; min-height: auto;
margin: 16px;
} }
.login-brand-panel { .login-brand-panel {
width: 100%; width: 100%;
padding: var(--space-3xl) var(--space-2xl); padding: 32px 24px;
border-right: none;
border-bottom: 1px solid rgba(255, 255, 255, 0.04);
} }
.login-form-panel { .login-form-panel {
padding: var(--space-2xl); padding: 32px 24px;
}
.brand-features {
display: none;
} }
} }
+26 -40
View File
@@ -65,38 +65,22 @@ const LoginPage: React.FC = () => {
setLoading(true); setLoading(true);
try { try {
const res = await authAPI.login(loginAccount, loginPassword); const res = await authAPI.login(loginAccount, loginPassword);
const { access_token, user: userData } = res.data; const data: any = (res as any).data || res;
localStorage.setItem('aiflow_token', access_token); const token = data.access_token || data.token;
const userData = data.user || data;
localStorage.setItem('aiflow_token', token);
const userObj: User = { const userObj: User = {
id: userData.id, id: userData.id, username: userData.username,
username: userData.username, email: userData.email || '', phone: userData.phone || '',
email: userData.email || '', avatar: userData.avatar || '', role: userData.role || 'user',
phone: userData.phone || '', status: 'active', realNameStatus: 'unverified',
avatar: userData.avatar || '', createdAt: new Date().toISOString(),
role: userData.role,
status: userData.status,
realNameStatus: userData.real_name_status || 'unverified',
createdAt: userData.created_at || new Date().toISOString(),
membership: userData.membership_level > 0 ? {
planId: userData.membership_level >= 3 ? 'mp3' : (userData.membership_level >= 2 ? 'mp2' : 'mp1'),
planName: userData.role === 'admin' ? '管理员' : (userData.membership_level >= 3 ? '企业版' : (userData.membership_level >= 2 ? '专业版' : '免费版')),
level: userData.membership_level,
expireAt: userData.membership_expire_at || '',
autoRenew: userData.auto_renew || false,
} : undefined,
}; };
login(userObj); login(userObj);
navigate(userData.role === 'admin' ? '/admin' : '/chat'); navigate(userObj.role === 'admin' ? '/admin' : '/chat');
} catch (e: any) { } catch (e: any) {
// 处理后端返回的精确错误信息,区分用户不存在和密码错误 const msg = (e as any).detail || (e as any).message || '';
const status = e.status || e.response?.status || 0; if (msg.includes('Network') || msg.includes('fetch')) {
const msg = e.detail || e.message || '';
if (status === 403) {
setErrorMsg('账号已被禁用,请联系管理员');
} else if (status === 401) {
// 后端的detail精确指明了原因:"用户名不存在" 或 "密码错误"
setErrorMsg(msg || '用户名或密码错误');
} else if (status === 0 || msg.includes('NetworkError') || msg.includes('Failed to fetch')) {
setErrorMsg('网络连接失败,请检查网络'); setErrorMsg('网络连接失败,请检查网络');
} else { } else {
setErrorMsg(msg || '登录失败,请稍后重试'); setErrorMsg(msg || '登录失败,请稍后重试');
@@ -121,14 +105,10 @@ const LoginPage: React.FC = () => {
const { access_token, user: userData } = res.data; const { access_token, user: userData } = res.data;
localStorage.setItem('aiflow_token', access_token); localStorage.setItem('aiflow_token', access_token);
const userObj: User = { const userObj: User = {
id: userData.id, id: userData.id, username: userData.username,
username: userData.username, email: userData.email || '', phone: userData.phone || '',
email: userData.email || '', avatar: userData.avatar || '', role: 'user',
phone: userData.phone || '', status: 'active', realNameStatus: 'unverified',
avatar: userData.avatar || '',
role: 'user',
status: 'active',
realNameStatus: 'unverified',
createdAt: new Date().toISOString(), createdAt: new Date().toISOString(),
}; };
login(userObj); login(userObj);
@@ -158,12 +138,18 @@ const LoginPage: React.FC = () => {
<div className="brand-content"> <div className="brand-content">
<div className="brand-icon"> <div className="brand-icon">
<svg width="48" height="48" viewBox="0 0 32 32" fill="none"> <svg width="48" height="48" viewBox="0 0 32 32" fill="none">
<rect width="32" height="32" rx="8" fill="white"/> <defs>
<path d="M8 20V12l4 4 4-4v8" stroke="#5B5FED" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round" fill="none"/> <linearGradient id="lpBrandGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<path d="M6 22h20" stroke="#5B5FED" strokeWidth="1.5" strokeLinecap="round" opacity="0.5"/> <stop offset="0%" stopColor="#6C63FF"/>
<stop offset="100%" stopColor="#A78BFA"/>
</linearGradient>
</defs>
<rect width="32" height="32" rx="8" fill="url(#lpBrandGrad)"/>
<path d="M8 20V12l4 4 4-4v8" stroke="white" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round" fill="none"/>
<path d="M6 22h20" stroke="white" strokeWidth="1.5" strokeLinecap="round" opacity="0.5"/>
</svg> </svg>
</div> </div>
<h1 className="brand-title">AIFlow</h1> <h1 className="brand-title">七虎AI</h1>
<p className="brand-desc">智能自动化PaaS平台</p> <p className="brand-desc">智能自动化PaaS平台</p>
<div className="brand-features"> <div className="brand-features">
<div className="brand-feature"><span className="bf-icon">&#x2713;</span><span>一站式AI自动化SOP</span></div> <div className="brand-feature"><span className="bf-icon">&#x2713;</span><span>一站式AI自动化SOP</span></div>
+33 -33
View File
@@ -1,22 +1,22 @@
/* ===== AIFlow Design System v2 - Dark Theme Default ===== */ /* ===== 七虎AI Design System v2 - Light Theme ===== */
/* 设计方向:融合暗黑科技感 + 极简主义 */ /* 设计方向:明亮简洁 + 透明玻璃态 */
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800;900&family=JetBrains+Mono:wght@400;500;600&display=swap'); @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800;900&family=JetBrains+Mono:wght@400;500;600&display=swap');
/* CSS Custom Properties - Dark Theme */ /* CSS Custom Properties - Light Theme */
:root { :root {
/* Colors - Dark Theme */ /* Colors - Dark Theme */
--color-bg-primary: #0A0E1A; --color-bg-primary: #FFFFFF;
--color-bg-secondary: #111627; --color-bg-secondary: #F5F7FC;
--color-bg-tertiary: #161B2E; --color-bg-tertiary: #FFFFFF;
--color-bg-hover: #1C2240; --color-bg-hover: #F0F2F8;
--color-bg-active: #22284A; --color-bg-active: #E8EBF5;
--color-text-primary: #E8ECF4; --color-text-primary: #1A1F36;
--color-text-secondary: #8892B0; --color-text-secondary: #5A6480;
--color-text-tertiary: #5A6480; --color-text-tertiary: #8892B0;
--color-text-disabled: #3A4460; --color-text-disabled: #C4C9D9;
--color-text-inverse: #0A0E1A; --color-text-inverse: #FFFFFF;
--color-accent: #6C63FF; --color-accent: #6C63FF;
--color-accent-hover: #8B85FF; --color-accent-hover: #8B85FF;
@@ -32,25 +32,25 @@
--color-info: #3B82F6; --color-info: #3B82F6;
--color-info-light: rgba(59, 130, 246, 0.12); --color-info-light: rgba(59, 130, 246, 0.12);
--color-border: rgba(255, 255, 255, 0.08); --color-border: rgba(0, 0, 0, 0.10);
--color-border-light: rgba(255, 255, 255, 0.05); --color-border-light: rgba(0, 0, 0, 0.06);
--color-border-hover: rgba(255, 255, 255, 0.14); --color-border-hover: rgba(0, 0, 0, 0.16);
--color-sidebar-bg: #0E1225; --color-sidebar-bg: #FFFFFF;
--color-sidebar-hover: rgba(255, 255, 255, 0.05); --color-sidebar-hover: rgba(108, 99, 255, 0.06);
--color-sidebar-active: rgba(108, 99, 255, 0.12); --color-sidebar-active: rgba(108, 99, 255, 0.12);
/* Surface/card colors */ /* Surface/card colors */
--color-surface: #111627; --color-surface: #FFFFFF;
--color-surface-hover: #161B2E; --color-surface-hover: #F5F7FC;
--color-surface-elevated: #1C2240; --color-surface-elevated: #FFFFFF;
/* Shadows - Dark theme */ /* Shadows - Dark theme */
--shadow-xs: 0 1px 2px rgba(0,0,0,0.2); --shadow-xs: 0 1px 2px rgba(0,0,0,0.06);
--shadow-sm: 0 1px 3px rgba(0,0,0,0.25), 0 1px 2px rgba(0,0,0,0.15); --shadow-sm: 0 1px 3px rgba(0,0,0,0.08), 0 1px 2px rgba(0,0,0,0.04);
--shadow-md: 0 4px 12px rgba(0,0,0,0.3), 0 1px 3px rgba(0,0,0,0.2); --shadow-md: 0 4px 12px rgba(0,0,0,0.10), 0 1px 3px rgba(0,0,0,0.06);
--shadow-lg: 0 12px 32px rgba(0,0,0,0.35), 0 2px 6px rgba(0,0,0,0.2); --shadow-lg: 0 12px 32px rgba(0,0,0,0.12), 0 2px 6px rgba(0,0,0,0.06);
--shadow-xl: 0 20px 48px rgba(0,0,0,0.4), 0 4px 12px rgba(0,0,0,0.25); --shadow-xl: 0 20px 48px rgba(0,0,0,0.15), 0 4px 12px rgba(0,0,0,0.08);
/* Spacing */ /* Spacing */
--space-xs: 4px; --space-xs: 4px;
@@ -553,7 +553,7 @@ input, textarea, select {
.admin-card, .admin-card,
.stat-card, .stat-card,
.dashboard-card { .dashboard-card {
background: rgba(22, 27, 46, 0.6) !important; background: rgba(255, 255, 255, 0.7) !important;
backdrop-filter: blur(12px) !important; backdrop-filter: blur(12px) !important;
-webkit-backdrop-filter: blur(12px) !important; -webkit-backdrop-filter: blur(12px) !important;
border: 1px solid rgba(255, 255, 255, 0.06) !important; border: 1px solid rgba(255, 255, 255, 0.06) !important;
@@ -605,7 +605,7 @@ select,
.form-input, .form-input,
.form-control { .form-control {
background: rgba(10, 14, 26, 0.6) !important; background: rgba(10, 14, 26, 0.6) !important;
border: 1px solid rgba(255, 255, 255, 0.08) !important; border: 1px solid rgba(0, 0, 0, 0.08) !important;
color: var(--color-text-primary) !important; color: var(--color-text-primary) !important;
border-radius: var(--radius-md) !important; border-radius: var(--radius-md) !important;
transition: border-color 0.2s, box-shadow 0.2s !important; transition: border-color 0.2s, box-shadow 0.2s !important;
@@ -647,14 +647,14 @@ button[type="submit"] {
/* Secondary/ghost button */ /* Secondary/ghost button */
.btn-secondary, .btn-secondary,
.admin-btn-secondary { .admin-btn-secondary {
background: rgba(255, 255, 255, 0.05) !important; background: rgba(108, 99, 255, 0.06) !important;
color: var(--color-text-secondary) !important; color: var(--color-text-secondary) !important;
border: 1px solid rgba(255, 255, 255, 0.08) !important; border: 1px solid rgba(0, 0, 0, 0.08) !important;
} }
.btn-secondary:hover, .btn-secondary:hover,
.admin-btn-secondary:hover { .admin-btn-secondary:hover {
background: rgba(255, 255, 255, 0.08) !important; background: rgba(108, 99, 255, 0.10) !important;
color: var(--color-text-primary) !important; color: var(--color-text-primary) !important;
} }
@@ -735,7 +735,7 @@ a:hover {
/* Modal/dialog overlay */ /* Modal/dialog overlay */
.modal-overlay, .modal-overlay,
.dialog-overlay { .dialog-overlay {
background: rgba(10, 14, 26, 0.7) !important; background: rgba(255, 255, 255, 0.7) !important;
backdrop-filter: blur(4px) !important; backdrop-filter: blur(4px) !important;
} }
@@ -743,5 +743,5 @@ a:hover {
.admin-card:hover, .admin-card:hover,
.stat-card:hover { .stat-card:hover {
border-color: rgba(108, 99, 255, 0.2) !important; border-color: rgba(108, 99, 255, 0.2) !important;
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2) !important; box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08) !important;
} }