界面优化
This commit is contained in:
parent
9344fb9b6c
commit
2590a76cfd
424
frontend/assets/dashboard-enhancements.css
Normal file
424
frontend/assets/dashboard-enhancements.css
Normal file
@ -0,0 +1,424 @@
|
||||
/* Modern Dashboard Enhancements - Glassmorphism Design */
|
||||
|
||||
/* Metrics Card Redesign */
|
||||
.metrics-card {
|
||||
background: var(--surface);
|
||||
backdrop-filter: var(--blur);
|
||||
-webkit-backdrop-filter: var(--blur);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 20px;
|
||||
padding: 24px;
|
||||
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
box-shadow: var(--shadow);
|
||||
height: 180px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.metrics-card::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 2px;
|
||||
background: linear-gradient(90deg, transparent, var(--primary), transparent);
|
||||
opacity: 0;
|
||||
transition: opacity 0.4s ease;
|
||||
}
|
||||
|
||||
.metrics-card:hover {
|
||||
transform: translateY(-4px) scale(1.02);
|
||||
box-shadow: var(--shadow-xl);
|
||||
border-color: var(--primary);
|
||||
}
|
||||
|
||||
.metrics-card:hover::before {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/* Card Header */
|
||||
.metrics-card-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 16px;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.metrics-card-title {
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
color: var(--text-2);
|
||||
letter-spacing: 0.3px;
|
||||
}
|
||||
|
||||
.metrics-card-icon {
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
border-radius: 14px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: all 0.3s ease;
|
||||
box-shadow: var(--shadow-sm);
|
||||
}
|
||||
|
||||
.metrics-card:hover .metrics-card-icon {
|
||||
transform: scale(1.1) rotate(5deg);
|
||||
box-shadow: var(--shadow);
|
||||
}
|
||||
|
||||
/* Card Value */
|
||||
.metrics-card-value {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.metrics-value-main {
|
||||
font-size: 36px;
|
||||
font-weight: 800;
|
||||
color: var(--text);
|
||||
letter-spacing: -1.5px;
|
||||
line-height: 1;
|
||||
margin-bottom: 8px;
|
||||
font-family: 'Poppins', sans-serif;
|
||||
}
|
||||
|
||||
.metrics-value-unit {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: var(--text-4);
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
/* Card Trend */
|
||||
.metrics-card-trend {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.trend-value {
|
||||
font-size: 15px;
|
||||
font-weight: 700;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.trend-value.up {
|
||||
color: var(--success);
|
||||
}
|
||||
|
||||
.trend-value.down {
|
||||
color: var(--danger);
|
||||
}
|
||||
|
||||
.trend-label {
|
||||
font-size: 13px;
|
||||
color: var(--text-4);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* Background Wave Pattern */
|
||||
.metrics-card-wave {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 70px;
|
||||
z-index: 1;
|
||||
pointer-events: none;
|
||||
opacity: 0.6;
|
||||
transition: opacity 0.3s ease;
|
||||
}
|
||||
|
||||
.metrics-card:hover .metrics-card-wave {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
/* Chart Container Enhancements */
|
||||
.chart-container {
|
||||
background: var(--surface);
|
||||
backdrop-filter: var(--blur);
|
||||
-webkit-backdrop-filter: var(--blur);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 20px;
|
||||
padding: 28px;
|
||||
box-shadow: var(--shadow);
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.chart-container::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 1px;
|
||||
background: linear-gradient(90deg, transparent, var(--primary-light), transparent);
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
.chart-container:hover {
|
||||
box-shadow: var(--shadow-lg);
|
||||
border-color: var(--primary);
|
||||
}
|
||||
|
||||
.chart-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.chart-title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: var(--text);
|
||||
font-family: 'Poppins', sans-serif;
|
||||
letter-spacing: -0.3px;
|
||||
}
|
||||
|
||||
.chart-controls {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.chart-control-btn {
|
||||
padding: 8px 16px;
|
||||
border-radius: 8px;
|
||||
border: 1px solid var(--border);
|
||||
background: var(--surface-glass);
|
||||
color: var(--text-3);
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.chart-control-btn:hover {
|
||||
background: var(--surface-glass-hover);
|
||||
color: var(--text);
|
||||
border-color: var(--primary);
|
||||
}
|
||||
|
||||
.chart-control-btn.active {
|
||||
background: var(--primary);
|
||||
color: white;
|
||||
border-color: var(--primary);
|
||||
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
|
||||
}
|
||||
|
||||
/* Data Table Enhancements */
|
||||
.data-table {
|
||||
width: 100%;
|
||||
border-collapse: separate;
|
||||
border-spacing: 0;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.data-table thead {
|
||||
background: var(--surface-glass);
|
||||
backdrop-filter: var(--blur);
|
||||
-webkit-backdrop-filter: var(--blur);
|
||||
}
|
||||
|
||||
.data-table th {
|
||||
padding: 14px 16px;
|
||||
text-align: left;
|
||||
font-weight: 600;
|
||||
color: var(--text-2);
|
||||
font-size: 13px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
border-bottom: 2px solid var(--border);
|
||||
}
|
||||
|
||||
.data-table tbody tr {
|
||||
transition: all 0.2s ease;
|
||||
border-bottom: 1px solid var(--border-light);
|
||||
}
|
||||
|
||||
.data-table tbody tr:hover {
|
||||
background: var(--surface-glass-hover);
|
||||
transform: scale(1.01);
|
||||
}
|
||||
|
||||
.data-table td {
|
||||
padding: 14px 16px;
|
||||
color: var(--text);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* Status Indicators */
|
||||
.status-indicator {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
padding: 6px 12px;
|
||||
border-radius: 8px;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.3px;
|
||||
}
|
||||
|
||||
.status-indicator::before {
|
||||
content: '';
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 50%;
|
||||
animation: pulse-dot 2s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.status-indicator.online {
|
||||
background: var(--success-bg);
|
||||
color: var(--success);
|
||||
}
|
||||
|
||||
.status-indicator.online::before {
|
||||
background: var(--success);
|
||||
}
|
||||
|
||||
.status-indicator.offline {
|
||||
background: var(--danger-bg);
|
||||
color: var(--danger);
|
||||
}
|
||||
|
||||
.status-indicator.offline::before {
|
||||
background: var(--danger);
|
||||
}
|
||||
|
||||
.status-indicator.pending {
|
||||
background: var(--warning-bg);
|
||||
color: var(--warning);
|
||||
}
|
||||
|
||||
.status-indicator.pending::before {
|
||||
background: var(--warning);
|
||||
}
|
||||
|
||||
@keyframes pulse-dot {
|
||||
0%, 100% {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
50% {
|
||||
opacity: 0.5;
|
||||
transform: scale(1.2);
|
||||
}
|
||||
}
|
||||
|
||||
/* Quick Stats Bar */
|
||||
.quick-stats {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
padding: 20px;
|
||||
background: var(--surface);
|
||||
backdrop-filter: var(--blur);
|
||||
-webkit-backdrop-filter: var(--blur);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 16px;
|
||||
margin-bottom: 24px;
|
||||
box-shadow: var(--shadow-sm);
|
||||
}
|
||||
|
||||
.quick-stat-item {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
padding: 12px;
|
||||
border-right: 1px solid var(--border-light);
|
||||
}
|
||||
|
||||
.quick-stat-item:last-child {
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
.quick-stat-label {
|
||||
font-size: 12px;
|
||||
color: var(--text-3);
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
.quick-stat-value {
|
||||
font-size: 24px;
|
||||
font-weight: 700;
|
||||
color: var(--text);
|
||||
font-family: 'Poppins', sans-serif;
|
||||
letter-spacing: -0.5px;
|
||||
}
|
||||
|
||||
/* Loading States */
|
||||
.skeleton {
|
||||
background: linear-gradient(90deg, var(--surface) 25%, var(--surface-glass-hover) 50%, var(--surface) 75%);
|
||||
background-size: 200% 100%;
|
||||
animation: skeleton-loading 1.5s ease-in-out infinite;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
@keyframes skeleton-loading {
|
||||
0% {
|
||||
background-position: 200% 0;
|
||||
}
|
||||
100% {
|
||||
background-position: -200% 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Responsive Adjustments */
|
||||
@media (max-width: 1024px) {
|
||||
.metrics-card {
|
||||
height: 160px;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.metrics-value-main {
|
||||
font-size: 32px;
|
||||
}
|
||||
|
||||
.chart-container {
|
||||
padding: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.metrics-card {
|
||||
height: 140px;
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.metrics-value-main {
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
.quick-stats {
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.quick-stat-item {
|
||||
border-right: none;
|
||||
border-bottom: 1px solid var(--border-light);
|
||||
padding-bottom: 12px;
|
||||
}
|
||||
|
||||
.quick-stat-item:last-child {
|
||||
border-bottom: none;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
}
|
||||
@ -1,16 +1,182 @@
|
||||
:root{--bg:#0f1216;--surface:#151922;--surface-2:#1b2030;--primary:#4f8cff;--primary-600:#3b71db;--text:#e6e8ee;--text-2:#b3b8c6;--border:#2a3244;--success:#22c55e;--warning:#f59e0b;--danger:#ef4444;--info:#60a5fa;--info-bg:#1e3a5f;--success-bg:#14532d;--warning-bg:#422006}
|
||||
[data-theme="light"]{--bg:#f5f7fa;--surface:#ffffff;--surface-2:#f8f9fb;--primary:#4f8cff;--primary-600:#3b71db;--text:#1a1d23;--text-2:#6b7280;--border:#e5e7eb;--success:#22c55e;--warning:#f59e0b;--danger:#ef4444;--info:#2196f3;--info-bg:#e3f2fd;--success-bg:#e8f5e9;--warning-bg:#fff3e0}
|
||||
:root {
|
||||
/* Modern Dark Theme - Glassmorphism Inspired */
|
||||
--bg: #0a0e1a;
|
||||
--bg-secondary: #0f1419;
|
||||
--surface: rgba(30, 41, 59, 0.7);
|
||||
--surface-2: rgba(51, 65, 85, 0.6);
|
||||
--surface-glass: rgba(255, 255, 255, 0.05);
|
||||
--surface-glass-hover: rgba(255, 255, 255, 0.08);
|
||||
|
||||
/* Primary Colors - Trust Blue */
|
||||
--primary: #3b82f6;
|
||||
--primary-600: #2563eb;
|
||||
--primary-700: #1d4ed8;
|
||||
--primary-light: #60a5fa;
|
||||
--primary-lighter: #93c5fd;
|
||||
|
||||
/* Accent Colors */
|
||||
--accent: #f97316;
|
||||
--accent-light: #fb923c;
|
||||
|
||||
/* Text Colors */
|
||||
--text: #f1f5f9;
|
||||
--text-2: #cbd5e1;
|
||||
--text-3: #94a3b8;
|
||||
--text-4: #64748b;
|
||||
|
||||
/* Borders & Dividers */
|
||||
--border: rgba(148, 163, 184, 0.12);
|
||||
--border-light: rgba(148, 163, 184, 0.08);
|
||||
--divider: rgba(148, 163, 184, 0.1);
|
||||
|
||||
/* Status Colors */
|
||||
--success: #10b981;
|
||||
--success-light: #34d399;
|
||||
--warning: #f59e0b;
|
||||
--warning-light: #fbbf24;
|
||||
--danger: #ef4444;
|
||||
--danger-light: #f87171;
|
||||
--info: #60a5fa;
|
||||
|
||||
/* Background Overlays */
|
||||
--info-bg: rgba(59, 130, 246, 0.1);
|
||||
--success-bg: rgba(16, 185, 129, 0.1);
|
||||
--warning-bg: rgba(245, 158, 11, 0.1);
|
||||
--danger-bg: rgba(239, 68, 68, 0.1);
|
||||
|
||||
/* Chart Colors */
|
||||
--chart-blue: #3b82f6;
|
||||
--chart-green: #10b981;
|
||||
--chart-orange: #f97316;
|
||||
--chart-red: #ef4444;
|
||||
--chart-purple: #a855f7;
|
||||
--chart-cyan: #06b6d4;
|
||||
|
||||
/* Shadows */
|
||||
--shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.3);
|
||||
--shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.4), 0 2px 4px -1px rgba(0, 0, 0, 0.3);
|
||||
--shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.5), 0 4px 6px -2px rgba(0, 0, 0, 0.4);
|
||||
--shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.6), 0 10px 10px -5px rgba(0, 0, 0, 0.4);
|
||||
|
||||
/* Backdrop Blur */
|
||||
--blur: blur(12px);
|
||||
--blur-lg: blur(20px);
|
||||
}
|
||||
|
||||
[data-theme="light"] {
|
||||
/* Modern Light Theme - Clean & Professional */
|
||||
--bg: #f8fafc;
|
||||
--bg-secondary: #f1f5f9;
|
||||
--surface: rgba(255, 255, 255, 0.9);
|
||||
--surface-2: rgba(248, 250, 252, 0.9);
|
||||
--surface-glass: rgba(255, 255, 255, 0.7);
|
||||
--surface-glass-hover: rgba(255, 255, 255, 0.85);
|
||||
|
||||
/* Primary Colors */
|
||||
--primary: #2563eb;
|
||||
--primary-600: #1d4ed8;
|
||||
--primary-700: #1e40af;
|
||||
--primary-light: #3b82f6;
|
||||
--primary-lighter: #60a5fa;
|
||||
|
||||
/* Accent Colors */
|
||||
--accent: #f97316;
|
||||
--accent-light: #fb923c;
|
||||
|
||||
/* Text Colors */
|
||||
--text: #0f172a;
|
||||
--text-2: #475569;
|
||||
--text-3: #64748b;
|
||||
--text-4: #94a3b8;
|
||||
|
||||
/* Borders & Dividers */
|
||||
--border: rgba(226, 232, 240, 0.8);
|
||||
--border-light: rgba(226, 232, 240, 0.5);
|
||||
--divider: rgba(226, 232, 240, 0.6);
|
||||
|
||||
/* Status Colors */
|
||||
--success: #10b981;
|
||||
--success-light: #34d399;
|
||||
--warning: #f59e0b;
|
||||
--warning-light: #fbbf24;
|
||||
--danger: #ef4444;
|
||||
--danger-light: #f87171;
|
||||
--info: #3b82f6;
|
||||
|
||||
/* Background Overlays */
|
||||
--info-bg: rgba(59, 130, 246, 0.08);
|
||||
--success-bg: rgba(16, 185, 129, 0.08);
|
||||
--warning-bg: rgba(245, 158, 11, 0.08);
|
||||
--danger-bg: rgba(239, 68, 68, 0.08);
|
||||
|
||||
/* Chart Colors */
|
||||
--chart-blue: #3b82f6;
|
||||
--chart-green: #10b981;
|
||||
--chart-orange: #f97316;
|
||||
--chart-red: #ef4444;
|
||||
--chart-purple: #a855f7;
|
||||
--chart-cyan: #06b6d4;
|
||||
|
||||
/* Shadows */
|
||||
--shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
|
||||
--shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
||||
--shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
|
||||
--shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
|
||||
|
||||
/* Backdrop Blur */
|
||||
--blur: blur(12px);
|
||||
--blur-lg: blur(20px);
|
||||
}
|
||||
*{box-sizing:border-box}
|
||||
html,body{height:100%;overflow:hidden}
|
||||
body{margin:0;background:var(--bg);color:var(--text);font-family:Inter,system-ui,-apple-system,Segoe UI,Roboto,Helvetica,Arial,"Noto Sans",sans-serif;line-height:1.5}
|
||||
body {
|
||||
margin: 0;
|
||||
background: var(--bg);
|
||||
color: var(--text);
|
||||
font-family: 'Open Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
||||
line-height: 1.6;
|
||||
font-weight: 400;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
/* Typography - Poppins for headings */
|
||||
h1, h2, h3, h4, h5, h6, .heading {
|
||||
font-family: 'Poppins', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
||||
font-weight: 600;
|
||||
line-height: 1.3;
|
||||
letter-spacing: -0.02em;
|
||||
}
|
||||
#app{display:flex;height:100vh;overflow:hidden}
|
||||
.sidebar{position:relative;width:240px;min-width:240px;background:linear-gradient(180deg,var(--surface),var(--surface-2));border-right:1px solid var(--border);display:flex;flex-direction:column;height:100vh;overflow:visible;transition:width 0.3s ease,min-width 0.3s ease}
|
||||
.sidebar.collapsed{width:60px;min-width:60px}
|
||||
.brand-container{position:relative;display:flex;align-items:center;justify-content:space-between;padding:12px 16px;gap:8px}
|
||||
.loader-wrapper{position:relative;display:flex;align-items:center;gap:10px;height:40px;width:auto;user-select:none;flex:1;min-width:0}
|
||||
.sidebar {
|
||||
position: relative;
|
||||
width: 260px;
|
||||
min-width: 260px;
|
||||
background: var(--surface);
|
||||
backdrop-filter: var(--blur);
|
||||
-webkit-backdrop-filter: var(--blur);
|
||||
border-right: 1px solid var(--border);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100vh;
|
||||
overflow: visible;
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
box-shadow: var(--shadow);
|
||||
}
|
||||
.sidebar.collapsed {
|
||||
width: 72px;
|
||||
min-width: 72px;
|
||||
}
|
||||
.brand-container{position:relative;display:flex;align-items:center;justify-content:space-between;padding:12px 16px;gap:8px;animation:fadeIn 0.5s ease-in-out}
|
||||
.loader-wrapper{position:relative;display:flex;align-items:center;gap:10px;height:40px;width:auto;user-select:none;flex:1;min-width:0;animation:slideUp 0.5s ease-in-out}
|
||||
.brand-logo{width:32px;height:32px;display:flex;align-items:center;justify-content:center;background:linear-gradient(135deg,var(--primary) 0%,var(--primary-600) 100%);border-radius:8px;flex-shrink:0;box-shadow:0 2px 8px rgba(79,140,255,0.3)}
|
||||
.brand-logo svg{width:18px;height:18px;color:#fff}
|
||||
.brand-logo.dollar-spinner{border-top:2px solid #eab308;background:#fde047;animation:spin 1s linear infinite;border-radius:50%;color:#a16207;font-weight:700;font-size:16px}
|
||||
@keyframes fadeIn{0%{opacity:0}100%{opacity:1}}
|
||||
@keyframes slideUp{0%{opacity:0;transform:translateY(20px)}100%{opacity:1;transform:translateY(0)}}
|
||||
@keyframes slideInRight{0%{opacity:0;transform:translateX(20px)}100%{opacity:1;transform:translateX(0)}}
|
||||
@keyframes pulse{0%,100%{opacity:1}50%{opacity:0.5}}
|
||||
@keyframes spin{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}
|
||||
.coin-wrapper{width:32px;height:32px;perspective:500px;flex-shrink:0}
|
||||
.coin{width:32px;height:32px;position:relative;animation:rotate_coin 7s infinite linear;transform-style:preserve-3d}
|
||||
@ -51,9 +217,46 @@ body{margin:0;background:var(--bg);color:var(--text);font-family:Inter,system-ui
|
||||
.nav{flex:1;overflow-y:auto;overflow-x:hidden;padding:8px 8px 16px;min-height:0}
|
||||
.nav-group{margin:8px 0}
|
||||
.nav-group-title{padding:8px 12px;color:var(--text-2);font-size:12px;letter-spacing:.04em;text-transform:uppercase}
|
||||
.nav-item{display:flex;align-items:center;gap:10px;padding:10px 12px;margin:4px;border-radius:8px;color:var(--text);text-decoration:none;font-size:14px}
|
||||
.nav-item:hover{background:rgba(79,140,255,.12)}
|
||||
.nav-item.active{background:rgba(79,140,255,.18);outline:1px solid rgba(79,140,255,.4)}
|
||||
.nav-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
padding: 12px 16px;
|
||||
margin: 4px 8px;
|
||||
border-radius: 12px;
|
||||
color: var(--text);
|
||||
text-decoration: none;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.nav-item:hover {
|
||||
background: var(--surface-glass-hover);
|
||||
color: var(--primary-light);
|
||||
transform: translateX(4px);
|
||||
}
|
||||
|
||||
.nav-item.active {
|
||||
background: var(--info-bg);
|
||||
color: var(--primary-light);
|
||||
border: 1px solid var(--primary);
|
||||
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
|
||||
}
|
||||
|
||||
.nav-item.active::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
width: 3px;
|
||||
height: 60%;
|
||||
background: var(--primary);
|
||||
border-radius: 0 2px 2px 0;
|
||||
}
|
||||
.nav-item .icon{width:20px;text-align:center}
|
||||
.nav-item.has-children{flex-direction:column;gap:0;padding:0;background:transparent}
|
||||
.nav-item-btn{width:100%;display:flex;align-items:center;gap:10px;padding:10px 12px;margin:4px;border-radius:8px;background:transparent;border:0;color:var(--text);cursor:pointer;font-size:14px;font-family:inherit}
|
||||
@ -69,27 +272,229 @@ body{margin:0;background:var(--bg);color:var(--text);font-family:Inter,system-ui
|
||||
|
||||
.theme-toggle-container{padding:16px;border-top:1px solid var(--border);margin-top:auto;display:flex;justify-content:center}
|
||||
|
||||
.btn{border:0;border-radius:8px;padding:8px 12px;font-weight:600;cursor:pointer;background:var(--primary);color:#ffffff}
|
||||
.btn:hover{background:var(--primary-600)}
|
||||
.btn {
|
||||
border: 0;
|
||||
border-radius: 10px;
|
||||
padding: 12px 24px;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-600) 100%);
|
||||
color: #ffffff;
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
font-size: 14px;
|
||||
letter-spacing: 0.3px;
|
||||
box-shadow: 0 4px 12px rgba(59, 130, 246, 0.3);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.btn::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -100%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
|
||||
transition: left 0.5s ease;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
background: linear-gradient(135deg, var(--primary-light) 0%, var(--primary) 100%);
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 8px 20px rgba(59, 130, 246, 0.4);
|
||||
}
|
||||
|
||||
.btn:hover::before {
|
||||
left: 100%;
|
||||
}
|
||||
|
||||
.btn:active {
|
||||
transform: translateY(0);
|
||||
box-shadow: 0 4px 12px rgba(59, 130, 246, 0.3);
|
||||
}
|
||||
.btn-secondary{background:#253045;color:var(--text)}
|
||||
.btn-secondary:hover{background:#2b3750}
|
||||
[data-theme="light"] .btn-secondary{background:#e5e7eb;color:var(--text)}
|
||||
[data-theme="light"] .btn-secondary:hover{background:#d1d5db}
|
||||
.content{flex:1;min-width:0;display:flex;flex-direction:column;height:100vh;overflow:hidden;background:var(--bg)}
|
||||
.content-header{display:flex;align-items:center;justify-content:space-between;padding:14px 20px;border-bottom:1px solid var(--border);background:var(--bg) !important;flex-shrink:0;position:relative;z-index:10}
|
||||
[data-theme="light"] .content-header{background:#f5f7fa !important}
|
||||
#breadcrumb{color:var(--text-2)}
|
||||
.content-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 20px 32px;
|
||||
border-bottom: 1px solid var(--border);
|
||||
background: var(--surface);
|
||||
backdrop-filter: var(--blur);
|
||||
-webkit-backdrop-filter: var(--blur);
|
||||
flex-shrink: 0;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 100;
|
||||
box-shadow: var(--shadow-sm);
|
||||
}
|
||||
|
||||
[data-theme="light"] .content-header {
|
||||
background: var(--surface);
|
||||
}
|
||||
#breadcrumb {
|
||||
color: var(--text-2);
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
#actions{position:relative;z-index:999;display:flex;align-items:center;gap:8px}
|
||||
.view{position:relative;padding:20px;flex:1;overflow-y:auto;overflow-x:hidden;background:var(--bg);min-height:0}
|
||||
.card{background:var(--surface-2);border:1px solid var(--border);border-radius:12px;padding:16px}
|
||||
.grid{display:grid;gap:12px}
|
||||
.grid.cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}
|
||||
.grid.cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}
|
||||
.field{display:flex;flex-direction:column;gap:6px;margin-bottom:12px}
|
||||
.field label{color:var(--text-2);font-size:13px}
|
||||
.input,select{background:#0c0f14;color:var(--text);border:1px solid var(--border);border-radius:8px;padding:10px}
|
||||
.input:focus,select:focus{outline:1px solid var(--primary)}
|
||||
[data-theme="light"] .input,[data-theme="light"] select{background:#ffffff;color:var(--text)}
|
||||
.view {
|
||||
position: relative;
|
||||
padding: 32px;
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
background: var(--bg);
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
@media (max-width: 1024px) {
|
||||
.view {
|
||||
padding: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.view {
|
||||
padding: 16px;
|
||||
}
|
||||
}
|
||||
.card {
|
||||
background: var(--surface);
|
||||
backdrop-filter: var(--blur);
|
||||
-webkit-backdrop-filter: var(--blur);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 16px;
|
||||
padding: 24px;
|
||||
box-shadow: var(--shadow);
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.card::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 1px;
|
||||
background: linear-gradient(90deg, transparent, var(--primary-light), transparent);
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s ease;
|
||||
}
|
||||
|
||||
.card:hover {
|
||||
box-shadow: var(--shadow-lg);
|
||||
transform: translateY(-2px);
|
||||
border-color: var(--primary);
|
||||
}
|
||||
|
||||
.card:hover::before {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
[data-theme="light"] .card {
|
||||
background: var(--surface);
|
||||
box-shadow: var(--shadow);
|
||||
}
|
||||
|
||||
[data-theme="light"] .card:hover {
|
||||
box-shadow: var(--shadow-lg);
|
||||
}
|
||||
.grid {
|
||||
display: grid;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.grid.cols-2 {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.grid.cols-3 {
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.grid.cols-4 {
|
||||
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
@media (max-width: 1280px) {
|
||||
.grid.cols-4 {
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1024px) {
|
||||
.grid.cols-3, .grid.cols-4 {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
.grid {
|
||||
gap: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.grid.cols-2, .grid.cols-3, .grid.cols-4 {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
.grid {
|
||||
gap: 12px;
|
||||
}
|
||||
}
|
||||
.field {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.field label {
|
||||
color: var(--text-2);
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.3px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.input, select {
|
||||
background: var(--surface);
|
||||
backdrop-filter: var(--blur);
|
||||
-webkit-backdrop-filter: var(--blur);
|
||||
color: var(--text);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 10px;
|
||||
padding: 12px 16px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
box-shadow: var(--shadow-sm);
|
||||
}
|
||||
|
||||
.input:focus, select:focus {
|
||||
outline: none;
|
||||
border-color: var(--primary);
|
||||
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1), var(--shadow);
|
||||
background: var(--surface-glass-hover);
|
||||
}
|
||||
|
||||
.input::placeholder {
|
||||
color: var(--text-4);
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
[data-theme="light"] .input,
|
||||
[data-theme="light"] select {
|
||||
background: var(--surface);
|
||||
color: var(--text);
|
||||
}
|
||||
/* Input with prefix icon */
|
||||
.input-wrapper{position:relative;display:flex;align-items:center}
|
||||
.input-wrapper .input-prefix{position:absolute;left:12px;color:var(--text-2);font-size:16px;pointer-events:none;display:flex;align-items:center}
|
||||
@ -141,16 +546,64 @@ input[type="date"]::-webkit-calendar-picker-indicator:hover{
|
||||
.row{display:flex;gap:12px;flex-wrap:wrap}
|
||||
.row .col{flex:1;min-width:240px}
|
||||
.actions{display:flex;gap:8px}
|
||||
.badge{display:inline-flex;align-items:center;gap:6px;border-radius:999px;padding:4px 10px;font-size:12px;background:#1f2535;color:var(--text-2)}
|
||||
.badge.success{background:rgba(34,197,94,.15);color:#8be59f}
|
||||
.badge.warning{background:rgba(245,158,11,.15);color:#f8cf88}
|
||||
.badge.danger{background:rgba(239,68,68,.15);color:#f4a3a3}
|
||||
[data-theme="light"] .badge{background:#e5e7eb;color:#374151}
|
||||
[data-theme="light"] .badge.success{background:rgba(34,197,94,.15);color:#16a34a}
|
||||
[data-theme="light"] .badge.warning{background:rgba(245,158,11,.15);color:#d97706}
|
||||
[data-theme="light"] .badge.danger{background:rgba(239,68,68,.15);color:#dc2626}
|
||||
.badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
border-radius: 8px;
|
||||
padding: 6px 12px;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
background: var(--surface-glass);
|
||||
color: var(--text-3);
|
||||
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
letter-spacing: 0.3px;
|
||||
border: 1px solid var(--border-light);
|
||||
backdrop-filter: var(--blur);
|
||||
-webkit-backdrop-filter: var(--blur);
|
||||
}
|
||||
|
||||
.badge.success {
|
||||
background: var(--success-bg);
|
||||
color: var(--success-light);
|
||||
border-color: var(--success);
|
||||
}
|
||||
|
||||
.badge.warning {
|
||||
background: var(--warning-bg);
|
||||
color: var(--warning-light);
|
||||
border-color: var(--warning);
|
||||
}
|
||||
|
||||
.badge.danger {
|
||||
background: var(--danger-bg);
|
||||
color: var(--danger-light);
|
||||
border-color: var(--danger);
|
||||
}
|
||||
|
||||
[data-theme="light"] .badge {
|
||||
background: var(--surface-glass);
|
||||
color: var(--text-3);
|
||||
}
|
||||
|
||||
[data-theme="light"] .badge.success {
|
||||
background: var(--success-bg);
|
||||
color: var(--success);
|
||||
}
|
||||
|
||||
[data-theme="light"] .badge.warning {
|
||||
background: var(--warning-bg);
|
||||
color: var(--warning);
|
||||
}
|
||||
|
||||
[data-theme="light"] .badge.danger {
|
||||
background: var(--danger-bg);
|
||||
color: var(--danger);
|
||||
}
|
||||
.list{list-style:none;padding:0;margin:0}
|
||||
.list li{display:flex;justify-content:space-between;padding:8px 10px;border-bottom:1px dashed var(--border)}
|
||||
.list li{display:flex;justify-content:space-between;padding:11px 14px;border-bottom:1px solid var(--border);transition:all 0.2s ease;border-radius:4px;margin-bottom:2px}
|
||||
.list li:hover{background:rgba(59,130,246,0.06);border-left:2px solid var(--primary);padding-left:12px}
|
||||
.list li:last-child{border-bottom:none;margin-bottom:0}
|
||||
.list::-webkit-scrollbar,.nav::-webkit-scrollbar,.view::-webkit-scrollbar{width:8px;height:8px}
|
||||
.list::-webkit-scrollbar-track,.nav::-webkit-scrollbar-track,.view::-webkit-scrollbar-track{background:transparent}
|
||||
.list::-webkit-scrollbar-thumb,.nav::-webkit-scrollbar-thumb,.view::-webkit-scrollbar-thumb{background:rgba(255,255,255,.1);border-radius:4px}
|
||||
@ -357,28 +810,29 @@ input[type="date"]::-webkit-calendar-picker-indicator:hover{
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 6px;
|
||||
padding: 8px 16px;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
padding: 9px 16px;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-600) 100%);
|
||||
color: white !important;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
box-shadow: 0 2px 8px rgba(102, 126, 234, 0.3);
|
||||
transition: all 0.2s ease;
|
||||
box-shadow: 0 2px 6px rgba(59, 130, 246, 0.3);
|
||||
white-space: nowrap;
|
||||
letter-spacing: 0.3px;
|
||||
}
|
||||
|
||||
.btn-summary:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4);
|
||||
background: linear-gradient(135deg, #5a6fd8 0%, #6a4190 100%);
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 4px 12px rgba(59, 130, 246, 0.4);
|
||||
background: linear-gradient(135deg, var(--primary-light) 0%, var(--primary) 100%);
|
||||
}
|
||||
|
||||
.btn-summary:active {
|
||||
transform: translateY(0);
|
||||
box-shadow: 0 2px 6px rgba(102, 126, 234, 0.3);
|
||||
box-shadow: 0 2px 4px rgba(59, 130, 246, 0.25);
|
||||
}
|
||||
|
||||
.btn-summary svg {
|
||||
@ -948,21 +1402,325 @@ input[type="date"]::-webkit-calendar-picker-indicator:hover{
|
||||
.dashboard-metrics-4col {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||
gap: 8px;
|
||||
gap: 12px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
/* Modern metrics card redesign */
|
||||
.metrics-card {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
background: var(--surface);
|
||||
border-radius: 12px;
|
||||
border: 1px solid var(--border);
|
||||
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
cursor: pointer;
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.06), 0 1px 3px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.metrics-card:hover {
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 4px 12px rgba(59, 130, 246, 0.15), 0 2px 6px rgba(0, 0, 0, 0.1);
|
||||
border-color: var(--primary-light);
|
||||
}
|
||||
|
||||
[data-theme="light"] .metrics-card {
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04), 0 1px 3px rgba(0, 0, 0, 0.06);
|
||||
background: #ffffff;
|
||||
}
|
||||
|
||||
[data-theme="light"] .metrics-card:hover {
|
||||
box-shadow: 0 4px 12px rgba(59, 130, 246, 0.12), 0 2px 6px rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
|
||||
/* Modern card styling */
|
||||
.modern-card {
|
||||
background: var(--surface);
|
||||
border-radius: 12px;
|
||||
border: 1px solid var(--border);
|
||||
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.06), 0 1px 3px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.modern-card:hover {
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
|
||||
[data-theme="light"] .modern-card {
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
|
||||
[data-theme="light"] .modern-card:hover {
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);
|
||||
}
|
||||
|
||||
/* Dashboard container improvements */
|
||||
.dashboard-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
/* 现代化图表工具提示 */
|
||||
#chart-tooltip {
|
||||
position: absolute;
|
||||
background: linear-gradient(135deg, rgba(59, 130, 246, 0.95) 0%, rgba(37, 99, 235, 0.95) 100%);
|
||||
color: #ffffff;
|
||||
padding: 10px 14px;
|
||||
border-radius: 10px;
|
||||
font-size: 12px;
|
||||
pointer-events: none;
|
||||
display: none;
|
||||
white-space: nowrap;
|
||||
box-shadow: 0 8px 24px rgba(59, 130, 246, 0.4), 0 4px 12px rgba(0, 0, 0, 0.3);
|
||||
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||
z-index: 1000;
|
||||
backdrop-filter: blur(10px);
|
||||
font-weight: 500;
|
||||
letter-spacing: 0.3px;
|
||||
}
|
||||
|
||||
#chart-tooltip::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: -4px;
|
||||
left: -4px;
|
||||
right: -4px;
|
||||
bottom: -4px;
|
||||
background: linear-gradient(135deg, rgba(96, 165, 250, 0.3), rgba(59, 130, 246, 0.3));
|
||||
border-radius: 12px;
|
||||
z-index: -1;
|
||||
filter: blur(8px);
|
||||
}
|
||||
|
||||
[data-theme="light"] #chart-tooltip {
|
||||
background: linear-gradient(135deg, rgba(59, 130, 246, 0.98) 0%, rgba(37, 99, 235, 0.98) 100%);
|
||||
box-shadow: 0 8px 24px rgba(59, 130, 246, 0.35), 0 4px 12px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
/* 环形图工具提示 */
|
||||
#donut-tooltip,
|
||||
#shipment-donut-tooltip {
|
||||
position: absolute;
|
||||
background: linear-gradient(135deg, rgba(30, 41, 59, 0.98) 0%, rgba(15, 23, 42, 0.98) 100%);
|
||||
color: #fff;
|
||||
padding: 10px 14px;
|
||||
border-radius: 10px;
|
||||
font-size: 12px;
|
||||
pointer-events: none;
|
||||
display: none;
|
||||
white-space: nowrap;
|
||||
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4), 0 4px 12px rgba(59, 130, 246, 0.2);
|
||||
border: 1px solid rgba(255, 255, 255, 0.15);
|
||||
z-index: 1000;
|
||||
backdrop-filter: blur(12px);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
[data-theme="light"] #donut-tooltip,
|
||||
[data-theme="light"] #shipment-donut-tooltip {
|
||||
background: linear-gradient(135deg, rgba(255, 255, 255, 0.98) 0%, rgba(248, 250, 252, 0.98) 100%);
|
||||
color: #1e293b;
|
||||
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15), 0 4px 12px rgba(59, 130, 246, 0.1);
|
||||
border: 1px solid rgba(59, 130, 246, 0.2);
|
||||
}
|
||||
|
||||
/* Trend chart card enhancements */
|
||||
.trend-chart-card {
|
||||
background: var(--surface);
|
||||
border-radius: 12px;
|
||||
border: 1px solid var(--border);
|
||||
overflow: hidden;
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.06), 0 1px 3px rgba(0, 0, 0, 0.1);
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
[data-theme="light"] .trend-chart-card {
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04), 0 1px 3px rgba(0, 0, 0, 0.06);
|
||||
background: #ffffff;
|
||||
}
|
||||
|
||||
/* Chart statistics bar */
|
||||
.chart-stats-bar {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
border-top: 1px solid var(--border);
|
||||
background: var(--surface);
|
||||
}
|
||||
|
||||
.chart-stat-item {
|
||||
padding: 14px 16px;
|
||||
text-align: center;
|
||||
border-right: 1px solid var(--border);
|
||||
transition: all 0.2s ease;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.chart-stat-item:last-child {
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
.chart-stat-item:hover {
|
||||
background: rgba(59, 130, 246, 0.06);
|
||||
}
|
||||
|
||||
.chart-stat-item::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 2px;
|
||||
background: var(--primary);
|
||||
transform: scaleX(0);
|
||||
transition: transform 0.2s ease;
|
||||
}
|
||||
|
||||
.chart-stat-item:hover::before {
|
||||
transform: scaleX(1);
|
||||
}
|
||||
|
||||
.chart-stat-label {
|
||||
font-size: 11px;
|
||||
color: var(--text-3);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.8px;
|
||||
margin-bottom: 6px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.chart-stat-value {
|
||||
font-size: 20px;
|
||||
font-weight: 700;
|
||||
line-height: 1.2;
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
/* Donut chart improvements */
|
||||
.donut-chart-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.donut-chart-title {
|
||||
font-size: 12px;
|
||||
color: var(--text-2);
|
||||
margin-bottom: 12px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.donut-legend {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 20px;
|
||||
margin-top: 12px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.donut-legend-item {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.donut-legend-value {
|
||||
font-size: 20px;
|
||||
font-weight: 700;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.donut-legend-label {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
font-size: 11px;
|
||||
color: var(--text-2);
|
||||
margin-top: 4px;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.donut-legend-dot {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
/* Audit board card */
|
||||
.audit-board-card {
|
||||
background: var(--surface);
|
||||
border-radius: 12px;
|
||||
border: 1px solid var(--border);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 0;
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.06), 0 1px 3px rgba(0, 0, 0, 0.1);
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.audit-board-card:hover {
|
||||
box-shadow: 0 4px 12px rgba(59, 130, 246, 0.1), 0 2px 6px rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
|
||||
[data-theme="light"] .audit-board-card {
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04), 0 1px 3px rgba(0, 0, 0, 0.06);
|
||||
background: #ffffff;
|
||||
}
|
||||
|
||||
[data-theme="light"] .audit-board-card:hover {
|
||||
box-shadow: 0 4px 12px rgba(59, 130, 246, 0.08), 0 2px 6px rgba(0, 0, 0, 0.06);
|
||||
}
|
||||
|
||||
/* Trend tabs styling */
|
||||
.trend-tab {
|
||||
padding: 6px 12px;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
color: var(--text-3);
|
||||
letter-spacing: 0.3px;
|
||||
}
|
||||
|
||||
.trend-tab:hover {
|
||||
background: rgba(59, 130, 246, 0.12);
|
||||
color: var(--text-2);
|
||||
}
|
||||
|
||||
.trend-tab.active {
|
||||
background: var(--primary);
|
||||
color: #ffffff;
|
||||
box-shadow: 0 2px 4px rgba(59, 130, 246, 0.3);
|
||||
}
|
||||
|
||||
@media(max-width: 768px) {
|
||||
.dashboard-metrics-4col {
|
||||
gap: 6px;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.dashboard-container {
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.dashboard-metrics-4col .card {
|
||||
padding: 8px !important;
|
||||
padding: 12px !important;
|
||||
}
|
||||
|
||||
.dashboard-metrics-4col .badge {
|
||||
font-size: 14px !important;
|
||||
padding: 4px 8px !important;
|
||||
.chart-stats-bar {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
|
||||
.chart-stat-item:nth-child(2) {
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
.chart-stat-item:nth-child(3) {
|
||||
border-top: 1px solid var(--border);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -5,11 +5,12 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>韬智生产管理系统</title>
|
||||
<link rel="icon" type="image/svg+xml" href="./assets/favicon.svg" />
|
||||
<!-- 暂时注释掉Google Fonts以提高加载速度 -->
|
||||
<!-- <link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<!-- Modern Professional Typography -->
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Poppins:wght@600&display=swap" rel="stylesheet" /> -->
|
||||
<link href="https://fonts.googleapis.com/css2?family=Open+Sans:wght@300;400;500;600;700&family=Poppins:wght@400;500;600;700&display=swap" rel="stylesheet" />
|
||||
<link rel="stylesheet" href="./assets/styles.css?v=20251122" />
|
||||
<link rel="stylesheet" href="./assets/dashboard-enhancements.css" />
|
||||
<link rel="stylesheet" href="./assets/mod.css" />
|
||||
</head>
|
||||
<body>
|
||||
@ -224,7 +225,8 @@
|
||||
</div>
|
||||
|
||||
<div class="sidebar-actions">
|
||||
<label class="switch">
|
||||
<!-- 主题切换按钮已隐藏 -->
|
||||
<label class="switch" style="display: none;">
|
||||
<input id="theme-toggle-checkbox" type="checkbox" />
|
||||
<span class="slider">
|
||||
<div class="star star_1"></div>
|
||||
|
||||
@ -659,9 +659,11 @@ const Dashboard = (() => {
|
||||
ctx.fillStyle = colors.bg;
|
||||
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
||||
|
||||
// 绘制网格线
|
||||
// 绘制网格线(增强版 - 虚线样式)
|
||||
ctx.strokeStyle = colors.grid;
|
||||
ctx.lineWidth = 1;
|
||||
ctx.globalAlpha = 0.5;
|
||||
ctx.setLineDash([4, 4]);
|
||||
for(let i = 0; i <= 4; i++){
|
||||
const y = padding.top + (chartHeight / 4) * i;
|
||||
ctx.beginPath();
|
||||
@ -669,6 +671,8 @@ const Dashboard = (() => {
|
||||
ctx.lineTo(rect.width - padding.right, y);
|
||||
ctx.stroke();
|
||||
}
|
||||
ctx.setLineDash([]);
|
||||
ctx.globalAlpha = 1;
|
||||
|
||||
// 绘制Y轴刻度(大数值格式化显示)
|
||||
const formatNumber = (n) => {
|
||||
@ -706,20 +710,23 @@ const Dashboard = (() => {
|
||||
// 绘制带填充区域的曲线(参考图样式)
|
||||
const today = new Date().toISOString().split('T')[0];
|
||||
|
||||
// 创建线条渐变
|
||||
// 创建线条渐变(增强版 - Aurora UI 风格)
|
||||
const createLineGradient = (gradientColors) => {
|
||||
const gradient = ctx.createLinearGradient(padding.left, 0, rect.width - padding.right, 0);
|
||||
gradient.addColorStop(0, gradientColors[0]);
|
||||
gradient.addColorStop(0.5, gradientColors[1]);
|
||||
gradient.addColorStop(1, gradientColors[2] || gradientColors[1]);
|
||||
gradient.addColorStop(0.3, gradientColors[1]);
|
||||
gradient.addColorStop(0.5, gradientColors[2] || gradientColors[1]);
|
||||
gradient.addColorStop(0.7, gradientColors[1]);
|
||||
gradient.addColorStop(1, gradientColors[0]);
|
||||
return gradient;
|
||||
};
|
||||
|
||||
// 创建填充区域渐变(从上到下)
|
||||
// 创建填充区域渐变(从上到下 - 增强版)
|
||||
const createFillGradient = (fillColors) => {
|
||||
const gradient = ctx.createLinearGradient(0, padding.top, 0, padding.top + chartHeight);
|
||||
gradient.addColorStop(0, fillColors[0]);
|
||||
gradient.addColorStop(1, fillColors[1]);
|
||||
gradient.addColorStop(0.5, fillColors[1] || fillColors[0].replace(/[\d.]+\)/, '0.15)'));
|
||||
gradient.addColorStop(1, fillColors[1] || 'rgba(0,0,0,0)');
|
||||
return gradient;
|
||||
};
|
||||
|
||||
@ -760,7 +767,23 @@ const Dashboard = (() => {
|
||||
ctx.fill();
|
||||
ctx.restore();
|
||||
|
||||
// 2. 绘制主线条
|
||||
// 2. 绘制发光效果(外层)
|
||||
ctx.save();
|
||||
ctx.shadowColor = gradientColors[1];
|
||||
ctx.shadowBlur = 12;
|
||||
ctx.shadowOffsetX = 0;
|
||||
ctx.shadowOffsetY = 0;
|
||||
ctx.strokeStyle = createLineGradient(gradientColors);
|
||||
ctx.lineWidth = 3;
|
||||
ctx.lineCap = 'round';
|
||||
ctx.lineJoin = 'round';
|
||||
ctx.globalAlpha = 0.6;
|
||||
ctx.beginPath();
|
||||
drawCurvePath(points);
|
||||
ctx.stroke();
|
||||
ctx.restore();
|
||||
|
||||
// 3. 绘制主线条(内层 - 更清晰)
|
||||
ctx.save();
|
||||
ctx.strokeStyle = createLineGradient(gradientColors);
|
||||
ctx.lineWidth = 2.5;
|
||||
@ -771,7 +794,7 @@ const Dashboard = (() => {
|
||||
ctx.stroke();
|
||||
ctx.restore();
|
||||
|
||||
// 3. 绘制数据点(只在今日或最后一个点显示)
|
||||
// 4. 绘制数据点(只在今日或最后一个点显示 - 增强版)
|
||||
const mainColor = gradientColors[1];
|
||||
counts.forEach((count, i) => {
|
||||
const x = points[i].x;
|
||||
@ -780,17 +803,34 @@ const Dashboard = (() => {
|
||||
const isLast = i === counts.length - 1;
|
||||
|
||||
if(isToday || isLast) {
|
||||
// 高亮点
|
||||
// 外层发光圆环
|
||||
ctx.save();
|
||||
ctx.shadowColor = mainColor;
|
||||
ctx.shadowBlur = 15;
|
||||
ctx.beginPath();
|
||||
ctx.arc(x, y, 6, 0, Math.PI * 2);
|
||||
ctx.arc(x, y, 8, 0, Math.PI * 2);
|
||||
ctx.fillStyle = mainColor.replace(')', ', 0.3)');
|
||||
ctx.fill();
|
||||
ctx.restore();
|
||||
|
||||
// 中层彩色圆
|
||||
ctx.save();
|
||||
ctx.shadowColor = mainColor;
|
||||
ctx.shadowBlur = 8;
|
||||
ctx.beginPath();
|
||||
ctx.arc(x, y, 5, 0, Math.PI * 2);
|
||||
ctx.fillStyle = mainColor;
|
||||
ctx.fill();
|
||||
ctx.restore();
|
||||
|
||||
// 内层白色圆点
|
||||
ctx.save();
|
||||
ctx.beginPath();
|
||||
ctx.arc(x, y, 3, 0, Math.PI * 2);
|
||||
ctx.arc(x, y, 2.5, 0, Math.PI * 2);
|
||||
ctx.fillStyle = '#fff';
|
||||
ctx.fill();
|
||||
ctx.restore();
|
||||
|
||||
if(isToday) todayLabels.push({x, y, count, color: mainColor, key: labelKey});
|
||||
}
|
||||
});
|
||||
|
||||
Loading…
Reference in New Issue
Block a user