/** * 控制台页面 - V21 设计系统样式 * KPI 卡片网格 + 快速入口 + 最近任务卡片列表 + 使用统计图表 + 公告 * 统一使用 CSS 变量,支持深色/浅色主题 */ @import "../../styles/global.css"; /* ============================================================ 页面容器 ============================================================ */ .xx-dashboard-page { min-height: 100%; padding: var(--space-xl); } /* ============================================================ 欢迎头部 ============================================================ */ .xx-dashboard-welcome { margin-bottom: var(--space-lg); } .xx-dashboard-welcome h2 { margin: 0 0 var(--space-xs); font-size: var(--font-size-xl); font-weight: var(--font-weight-bold); color: var(--text-primary); } .xx-dashboard-welcome p { margin: 0; font-size: var(--font-size-sm); color: var(--text-secondary); } /* ============================================================ KPI 卡片网格 ============================================================ */ .xx-kpi-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--space-md); margin-bottom: var(--space-lg); } .xx-kpi-card { background: linear-gradient(180deg, var(--bg-primary), var(--bg-secondary)); border: 1px solid var(--border-color); border-radius: var(--radius-lg); padding: 20px; transition: 0.18s ease; position: relative; overflow: hidden; } .xx-kpi-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-sm); } .xx-kpi-icon { width: 40px; height: 40px; border-radius: var(--radius-md); display: flex; align-items: center; justify-content: center; font-size: var(--font-size-lg); margin-bottom: var(--space-sm); } .xx-kpi-value { font-size: 30px; font-weight: 800; color: var(--text-primary); line-height: 1.2; margin-bottom: var(--space-xs); } .xx-kpi-label { font-size: var(--font-size-sm); color: var(--text-secondary); margin-bottom: var(--space-sm); } .xx-kpi-trend { font-size: 12px; margin-top: 8px; display: inline-flex; align-items: center; gap: 4px; } .xx-kpi-trend--up { color: var(--success-color); } .xx-kpi-trend--down { color: var(--error-color); } .xx-kpi-trend--neutral { color: var(--text-tertiary); } /* ============================================================ 主内容区两栏布局 ============================================================ */ .xx-dashboard-main { display: grid; grid-template-columns: 1fr 320px; gap: var(--space-md); margin-bottom: var(--space-lg); } /* ============================================================ 区块卡片 ============================================================ */ .xx-dashboard-section { background: var(--bg-primary); border: 1px solid var(--border-color); border-radius: var(--radius-lg); padding: var(--space-md); } .xx-dashboard-section-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--space-md); } .xx-dashboard-section-header h3 { margin: 0; font-size: var(--font-size-base); font-weight: var(--font-weight-semibold); color: var(--text-primary); } .xx-dashboard-section-header a, .xx-dashboard-section-header button { font-size: var(--font-size-sm); color: var(--primary-color); cursor: pointer; background: none; border: none; padding: 0; text-decoration: none; transition: var(--transition-color); } .xx-dashboard-section-header a:hover, .xx-dashboard-section-header button:hover { color: var(--primary-hover); text-decoration: underline; } .xx-dashboard-section-header a:active, .xx-dashboard-section-header button:active { opacity: 0.7; } /* ============================================================ 最近任务卡片列表 ============================================================ */ .xx-task-list { display: flex; flex-direction: column; gap: var(--space-sm); } .xx-task-item { background: var(--bg-primary); border: 1px solid var(--border-color); border-radius: var(--radius-md); padding: var(--space-sm) var(--space-md); display: grid; grid-template-columns: 1fr auto auto auto; gap: var(--space-md); align-items: center; transition: var(--transition-all); } .xx-task-item:hover { border-color: var(--primary-color); box-shadow: var(--shadow-sm); } .xx-task-info h4 { margin: 0 0 var(--space-xs); font-size: var(--font-size-sm); font-weight: 600; color: var(--text-primary); } .xx-task-info span { font-size: var(--font-size-xs); color: var(--text-secondary); } .xx-task-status { display: inline-flex; align-items: center; gap: var(--space-xs); padding: 3px 10px; border-radius: var(--radius-sm); font-size: var(--font-size-xs); font-weight: 500; white-space: nowrap; } .xx-task-status--completed { color: var(--success-color); background: var(--success-soft); border: 1px solid var(--success-border); } .xx-task-status--processing { color: var(--info-color); background: var(--primary-soft); border: 1px solid var(--color-primary-200); } .xx-task-status--pending { color: var(--text-secondary); background: var(--bg-secondary); border: 1px solid var(--border-color); } .xx-task-status--failed { color: var(--error-color); background: var(--error-soft); border: 1px solid var(--error-border); } .xx-task-time { text-align: right; font-size: var(--font-size-xs); color: var(--text-secondary); min-width: 100px; } .xx-task-time span { display: block; margin-bottom: var(--space-xxs); } .xx-task-action { font-size: var(--font-size-xs); } /* ============================================================ 使用统计图表(纯 CSS 柱状图) ============================================================ */ .xx-chart-container { padding: var(--space-sm) 0; } .xx-chart-bars { display: flex; align-items: flex-end; gap: var(--space-sm); height: 160px; padding-top: var(--space-sm); } .xx-chart-bar-wrapper { flex: 1; display: flex; flex-direction: column; align-items: center; height: 100%; justify-content: flex-end; } .xx-chart-bar { width: 100%; max-width: 36px; border-radius: var(--radius-sm) var(--radius-sm) 0 0; background: var(--gradient-primary); transition: height 0.6s cubic-bezier(0.34, 1.56, 0.64, 1); position: relative; min-height: 4px; cursor: pointer; } .xx-chart-bar:hover { opacity: 0.85; } .xx-chart-bar:active { opacity: 0.7; transform: scaleY(0.97); transform-origin: bottom; } .xx-chart-bar-value { position: absolute; top: -20px; left: 50%; transform: translateX(-50%); font-size: var(--font-size-xs); font-weight: 600; color: var(--text-primary); white-space: nowrap; opacity: 0; transition: var(--transition-opacity); } .xx-chart-bar:hover .xx-chart-bar-value { opacity: 1; } .xx-chart-labels { display: flex; gap: var(--space-sm); margin-top: var(--space-sm); } .xx-chart-label { flex: 1; text-align: center; font-size: var(--font-size-xs); color: var(--text-secondary); } /* ============================================================ 快速入口卡片网格 ============================================================ */ .xx-quick-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--space-md); margin-bottom: var(--space-lg); } .xx-quick-card { background: var(--bg-primary); border: 1px solid var(--border-color); border-radius: var(--radius-lg); padding: var(--space-lg); cursor: pointer; transition: var(--transition-all); text-align: center; } .xx-quick-card:hover { border-color: var(--primary-color); box-shadow: var(--shadow-md); transform: translateY(-2px); } .xx-quick-card:active { transform: translateY(0) scale(0.98); box-shadow: var(--shadow-sm); transition-duration: 0.1s; } .xx-quick-card-icon { width: 52px; height: 52px; border-radius: var(--radius-md); display: flex; align-items: center; justify-content: center; font-size: var(--font-size-xl); margin: 0 auto var(--space-md); color: var(--text-inverse); } .xx-quick-card h3 { margin: 0 0 var(--space-sm); font-size: var(--font-size-md); font-weight: var(--font-weight-semibold); color: var(--text-primary); } .xx-quick-card p { margin: 0; color: var(--text-secondary); font-size: var(--font-size-sm); } /* ============================================================ 公告区域 ============================================================ */ .xx-announcement-list { display: flex; flex-direction: column; gap: var(--space-sm); } .xx-announcement-item { display: flex; gap: var(--space-sm); padding: var(--space-sm); border-radius: var(--radius-md); background: var(--bg-secondary); border: 1px solid var(--border-color); transition: var(--transition-all); } .xx-announcement-item:hover { border-color: var(--primary-color); background: var(--primary-soft); } .xx-announcement-item:active { transform: scale(0.99); } .xx-announcement-tag { flex-shrink: 0; padding: var(--space-xxs) var(--space-sm); border-radius: var(--radius-sm); font-size: var(--font-size-xs); font-weight: 500; height: fit-content; } .xx-announcement-tag--update { color: var(--primary-color); background: var(--primary-soft); } .xx-announcement-tag--notice { color: var(--warning-color); background: var(--warning-soft); } .xx-announcement-tag--activity { color: var(--success-color); background: var(--success-soft); } .xx-announcement-content { flex: 1; min-width: 0; } .xx-announcement-content h4 { margin: 0 0 var(--space-xs); font-size: var(--font-size-sm); font-weight: 500; color: var(--text-primary); line-height: 1.4; } .xx-announcement-content time { font-size: var(--font-size-xs); color: var(--text-secondary); } /* ============================================================ 存储用量条 ============================================================ */ .xx-storage-bar { margin-top: var(--space-sm); } .xx-storage-bar-track { height: var(--space-sm); background: var(--bg-secondary); border-radius: var(--space-xs); overflow: hidden; } .xx-storage-bar-fill { height: 100%; border-radius: var(--space-xs); background: var(--gradient-primary); transition: width 0.6s ease; } .xx-storage-bar-label { display: flex; justify-content: space-between; font-size: var(--font-size-xs); color: var(--text-secondary); margin-top: var(--space-xs); } /* ============================================================ 迁移自内联样式的工具类 ============================================================ */ .xx-dashboard-left-col { display: flex; flex-direction: column; gap: var(--space-md); } .xx-chart-total { font-size: var(--font-size-xs); color: var(--text-secondary); } .xx-dashboard-section--start { align-self: start; } .xx-storage-section { margin-top: var(--space-md); } .xx-storage-section-title { font-size: 13px; font-weight: 500; color: var(--text-primary); margin-bottom: 4px; } .xx-quick-entry-section { margin-bottom: var(--space-md); } .xx-quick-entry-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--space-md); } .xx-quick-entry-title { margin: 0; font-size: var(--font-size-base); font-weight: var(--font-weight-semibold); color: var(--text-primary); } /* ============================================================ 响应式 ============================================================ */ @media (max-width: 1200px) { .xx-dashboard-main { grid-template-columns: 1fr; } .xx-kpi-grid { grid-template-columns: repeat(2, 1fr); } .xx-quick-grid { grid-template-columns: repeat(2, 1fr); } } @media (max-width: 768px) { .xx-dashboard-page { padding: var(--space-md); } .xx-kpi-grid { grid-template-columns: 1fr; } .xx-quick-grid { grid-template-columns: 1fr; } .xx-task-item { grid-template-columns: 1fr; gap: var(--space-sm); } .xx-task-time { text-align: left; } .xx-chart-bars { height: 120px; } }