- web/: React + Vite + TypeScript 前端 - backend/: Django + DRF + SimpleJWT 后端 - prototype/: HTML 设计原型 - docs/: PRD 和设计评审文档 - test: 单元测试 + E2E 极限测试
118 lines
2.0 KiB
CSS
118 lines
2.0 KiB
CSS
.page {
|
|
max-width: 1200px;
|
|
}
|
|
|
|
.title {
|
|
font-size: 22px;
|
|
font-weight: 600;
|
|
color: var(--color-text-primary);
|
|
margin-bottom: 24px;
|
|
}
|
|
|
|
.statsGrid {
|
|
display: grid;
|
|
grid-template-columns: repeat(4, 1fr);
|
|
gap: 16px;
|
|
margin-bottom: 24px;
|
|
}
|
|
|
|
.statCard {
|
|
background: var(--color-bg-card);
|
|
border: 1px solid var(--color-border-card);
|
|
border-radius: var(--radius-card);
|
|
padding: 20px;
|
|
}
|
|
|
|
.statLabel {
|
|
color: var(--color-text-secondary);
|
|
font-size: 13px;
|
|
margin-bottom: 8px;
|
|
}
|
|
|
|
.statValue {
|
|
color: var(--color-text-primary);
|
|
font-size: 28px;
|
|
font-weight: 700;
|
|
line-height: 1.2;
|
|
}
|
|
|
|
.statChange {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 4px;
|
|
font-size: 12px;
|
|
margin-top: 8px;
|
|
padding: 2px 6px;
|
|
border-radius: 4px;
|
|
}
|
|
|
|
.positive {
|
|
color: var(--color-success);
|
|
background: rgba(0, 184, 148, 0.1);
|
|
}
|
|
|
|
.negative {
|
|
color: var(--color-danger);
|
|
background: rgba(231, 76, 60, 0.1);
|
|
}
|
|
|
|
.chartSection {
|
|
margin-bottom: 24px;
|
|
}
|
|
|
|
.sectionTitle {
|
|
font-size: 16px;
|
|
font-weight: 600;
|
|
color: var(--color-text-primary);
|
|
margin-bottom: 12px;
|
|
}
|
|
|
|
.chartWrapper {
|
|
background: var(--color-bg-card);
|
|
border: 1px solid var(--color-border-card);
|
|
border-radius: var(--radius-card);
|
|
padding: 16px;
|
|
}
|
|
|
|
/* Skeleton loading */
|
|
.skeleton {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 24px;
|
|
}
|
|
|
|
.skeletonCards {
|
|
display: grid;
|
|
grid-template-columns: repeat(4, 1fr);
|
|
gap: 16px;
|
|
}
|
|
|
|
.skeletonCard {
|
|
height: 100px;
|
|
background: var(--color-bg-card);
|
|
border: 1px solid var(--color-border-card);
|
|
border-radius: var(--radius-card);
|
|
animation: pulse 1.5s ease-in-out infinite;
|
|
}
|
|
|
|
.skeletonChart {
|
|
height: 320px;
|
|
background: var(--color-bg-card);
|
|
border: 1px solid var(--color-border-card);
|
|
border-radius: var(--radius-card);
|
|
animation: pulse 1.5s ease-in-out infinite;
|
|
}
|
|
|
|
@keyframes pulse {
|
|
0%, 100% { opacity: 1; }
|
|
50% { opacity: 0.5; }
|
|
}
|
|
|
|
@media (max-width: 1024px) {
|
|
.statsGrid { grid-template-columns: repeat(2, 1fr); }
|
|
}
|
|
|
|
@media (max-width: 640px) {
|
|
.statsGrid { grid-template-columns: 1fr; }
|
|
}
|