/* ============================================================ * DevPerf 2.0 设计令牌系统 * 审美方向: Editorial Data Console (Linear/Stripe 精致感 + 数据密度) * 反 AI 味: 不用 Inter/Roboto、不用紫蓝渐变、不用 glassmorphism * 色彩: OKLCH 感知均匀, 中性色带 0.005-0.012 暖色调 * ============================================================ */ @import url('https://fonts.googleapis.com/css2?family=Newsreader:opsz,wght@6..72,400;6..72,500;6..72,600;6..72,700&family=Geist:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500;700&display=swap'); :root { /* ─────────── 色彩系统 (OKLCH) ─────────── */ /* 主色 — 深墨青(克制信任, 不是 Tailwind blue) */ --color-primary: oklch(0.32 0.05 200); --color-primary-hover: oklch(0.27 0.05 200); --color-primary-press: oklch(0.23 0.05 200); --color-primary-soft: oklch(0.94 0.018 200); /* 强调色 — 暖琥珀(数据高亮 / CTA) */ --color-accent: oklch(0.72 0.16 65); --color-accent-hover: oklch(0.66 0.17 60); --color-accent-soft: oklch(0.96 0.04 75); /* 语义色 */ --color-success: oklch(0.58 0.13 155); --color-success-soft: oklch(0.95 0.04 155); --color-warning: oklch(0.72 0.16 65); --color-warning-soft: oklch(0.96 0.04 75); --color-error: oklch(0.55 0.18 25); --color-error-soft: oklch(0.96 0.03 25); --color-info: oklch(0.52 0.11 240); --color-info-soft: oklch(0.95 0.03 240); /* 中性色阶(暖灰, chroma 0.005~0.012, 不是死灰) */ --color-bg: oklch(0.985 0.003 80); /* 页面背景 */ --color-bg-card: oklch(1.000 0.000 0); /* 卡片 */ --color-bg-subtle: oklch(0.965 0.004 80); /* 浅灰区块 */ --color-bg-hover: oklch(0.955 0.005 80); /* hover */ --color-bg-sidebar: oklch(0.18 0.012 230); /* 侧边栏深底带蓝绿 */ --color-bg-sidebar-2: oklch(0.21 0.013 230); /* 侧边栏次级 */ --color-border-subtle: oklch(0.935 0.006 80); --color-border: oklch(0.88 0.008 80); --color-border-strong: oklch(0.78 0.010 80); --color-text-muted: oklch(0.58 0.009 80); --color-text-secondary: oklch(0.42 0.011 80); --color-text-primary: oklch(0.22 0.012 80); --color-text-onDark: oklch(0.92 0.005 80); --color-text-onDarkMuted:oklch(0.65 0.010 220); /* 兼容老变量 (保持现有组件不破) */ --color-primary-hex: #1f3a45; --color-accent-hex: #c47918; --color-text-secondary-legacy: var(--color-text-secondary); /* ─────────── 图表色板(OKLCH 衍生, 8 色, 中等饱和) ─────────── */ --chart-1: oklch(0.32 0.05 200); /* 墨青 */ --chart-2: oklch(0.58 0.13 155); /* 翠绿 */ --chart-3: oklch(0.72 0.16 65); /* 琥珀 */ --chart-4: oklch(0.50 0.15 280); /* 紫罗兰 */ --chart-5: oklch(0.55 0.18 25); /* 朱砂 */ --chart-6: oklch(0.62 0.13 105); /* 橄榄 */ --chart-7: oklch(0.50 0.10 220); /* 钢蓝 */ --chart-8: oklch(0.65 0.12 320); /* 玫瑰 */ /* ─────────── 字体 ─────────── */ /* Display: Newsreader 衬线(editorial 标题) */ --font-display: 'Newsreader', 'Source Serif 4', 'Songti SC', 'STSong', Georgia, serif; /* Sans: Geist(Vercel 现代无衬线, 替代 Inter) + PingFang */ --font-sans: 'Geist', 'PingFang SC', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Helvetica Neue', sans-serif; /* Mono: JetBrains Mono(等宽 KPI 数字) */ --font-mono: 'JetBrains Mono', 'SF Mono', 'Cascadia Code', Menlo, Consolas, monospace; /* 兼容老变量 */ --font-heading: var(--font-sans); --font-body: var(--font-sans); --font-code: var(--font-mono); /* ─────────── 字号比例尺(ratio 1.25, base 14px) ─────────── */ --text-xs: 11px; /* caption */ --text-sm: 12px; /* secondary */ --text-base: 14px; /* body */ --text-md: 16px; /* lead */ --text-lg: 18px; /* small heading */ --text-xl: 22px; /* section title */ --text-2xl: 28px; /* page title */ --text-3xl: 36px; /* KPI medium */ --text-4xl: 46px; /* KPI hero */ --text-display: clamp(24px, 1.6vw + 0.6rem, 32px); /* 中文友好的页头字号 */ /* ─────────── 行高 ─────────── */ --leading-tight: 1.2; --leading-snug: 1.35; --leading-normal: 1.55; --leading-relaxed:1.7; /* ─────────── 字重 ─────────── */ --weight-regular: 400; --weight-medium: 500; --weight-semibold: 600; --weight-bold: 700; /* ─────────── 字间距 ─────────── */ --tracking-tight: -0.02em; --tracking-normal: 0; --tracking-wide: 0.04em; /* ─────────── 空间(4px 基础) ─────────── */ --space-0_5: 2px; --space-1: 4px; --space-2: 8px; --space-3: 12px; --space-4: 16px; --space-5: 20px; --space-6: 24px; --space-7: 28px; --space-8: 32px; --space-10: 40px; --space-12: 48px; --space-14: 56px; --space-16: 64px; --space-20: 80px; --space-24: 96px; /* ─────────── 圆角 ─────────── */ --radius-xs: 4px; --radius-sm: 6px; --radius-md: 8px; --radius-lg: 10px; --radius-xl: 14px; --radius-2xl: 18px; --radius-full:9999px; /* 兼容老变量 */ --radius-btn: var(--radius-md); --radius-card: var(--radius-xl); --radius-modal: var(--radius-2xl); --radius-pill: var(--radius-full); /* ─────────── 阴影(多层柔和叠加) ─────────── */ --shadow-xs: 0 1px 1px oklch(0.22 0.01 80 / 0.03); --shadow-sm: 0 1px 2px oklch(0.22 0.01 80 / 0.05), 0 1px 1px oklch(0.22 0.01 80 / 0.03); --shadow-md: 0 2px 4px oklch(0.22 0.01 80 / 0.04), 0 4px 8px oklch(0.22 0.01 80 / 0.04), 0 1px 1px oklch(0.22 0.01 80 / 0.03); --shadow-lg: 0 4px 8px oklch(0.22 0.01 80 / 0.04), 0 8px 24px oklch(0.22 0.01 80 / 0.06), 0 1px 1px oklch(0.22 0.01 80 / 0.03); --shadow-xl: 0 8px 16px oklch(0.22 0.01 80 / 0.04), 0 16px 48px oklch(0.22 0.01 80 / 0.08), 0 1px 1px oklch(0.22 0.01 80 / 0.03); --shadow-focus: 0 0 0 3px oklch(0.32 0.05 200 / 0.18); --shadow-focus-error: 0 0 0 3px oklch(0.55 0.18 25 / 0.18); /* ─────────── 缓动 + 时长(exponential easing, 反 bounce) ─────────── */ --ease-out: cubic-bezier(0.25, 1, 0.5, 1); --ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1); --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1); --ease-default: var(--ease-out); /* 老变量兼容 */ --ease-entrance: var(--ease-out-expo); --duration-instant: 100ms; --duration-fast: 150ms; --duration-base: 200ms; --duration-medium: 300ms; --duration-slow: 500ms; --duration-hover: var(--duration-fast); --duration-entrance:var(--duration-slow); --duration-collapse:var(--duration-medium); /* ─────────── Z-index ─────────── */ --z-base: 1; --z-dropdown: 100; --z-sticky: 200; --z-modal: 300; --z-toast: 9999; /* ─────────── Layout ─────────── */ --sidebar-width: 240px; --sidebar-collapsed-width: 64px; --content-max: 1440px; } /* ─────────── Reset ─────────── */ *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; } html, body { margin: 0; padding: 0; overflow-x: hidden; } html { font-family: var(--font-sans); font-size: var(--text-base); line-height: var(--leading-normal); color: var(--color-text-primary); background-color: var(--color-bg); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-rendering: optimizeLegibility; font-feature-settings: 'ss01', 'cv01', 'cv11'; } body { min-height: 100vh; } /* 标题: 中文用 sans(PingFang)更协调, 衬线只用在英文 eyebrow */ h1, h2, h3 { font-family: var(--font-sans); font-weight: var(--weight-semibold); line-height: var(--leading-tight); letter-spacing: var(--tracking-tight); color: var(--color-text-primary); } h4, h5, h6 { font-family: var(--font-sans); font-weight: var(--weight-semibold); line-height: var(--leading-snug); } code, pre, kbd { font-family: var(--font-mono); font-feature-settings: 'zero', 'ss01'; } /* 数字: tabular nums (KPI 用) */ .tabular-nums { font-variant-numeric: tabular-nums; font-family: var(--font-mono); letter-spacing: -0.01em; } /* editorial 副标题 */ .eyebrow { font-family: var(--font-sans); font-size: var(--text-xs); font-weight: var(--weight-medium); text-transform: uppercase; letter-spacing: var(--tracking-wide); color: var(--color-text-muted); } a { color: var(--color-primary); text-decoration: none; transition: color var(--duration-fast) var(--ease-out); } a:hover { color: var(--color-primary-hover); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; } /* focus-visible(键盘用户) */ :focus-visible { outline: none; box-shadow: var(--shadow-focus); border-radius: var(--radius-sm); } /* Scrollbar */ ::-webkit-scrollbar { width: 8px; height: 8px; } ::-webkit-scrollbar-track { background: transparent; } ::-webkit-scrollbar-thumb { background: var(--color-border); border-radius: var(--radius-full); border: 2px solid transparent; background-clip: padding-box; } ::-webkit-scrollbar-thumb:hover { background: var(--color-border-strong); background-clip: padding-box; } /* 减少动效偏好 */ @media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; } } /* utility */ .surface { background: var(--color-bg-card); border: 1px solid var(--color-border-subtle); border-radius: var(--radius-xl); } .hairline { border-bottom: 1px solid var(--color-border-subtle); } /* 表格容器统一 wrapper:白底 + 边框 + 圆角,跟 list-card / DataCard 视觉一致 */ .table-shell { background: var(--color-bg-card); border: 1px solid var(--color-border-subtle); border-radius: var(--radius-xl); overflow: hidden; } /* ============================================================ * 全局表格基线 (Naive UI NDataTable 统一样式) * Editorial Data Console 风格:浅灰表头 + dashed 行分隔 + hover 高亮 * ============================================================ */ .n-data-table .n-data-table-th { background: var(--color-bg-subtle) !important; color: var(--color-text-secondary) !important; font-family: var(--font-sans) !important; font-size: 12px !important; font-weight: var(--weight-medium) !important; letter-spacing: 0.02em !important; padding: 10px 16px !important; border-bottom: 1px solid var(--color-border) !important; border-right: none !important; } .n-data-table .n-data-table-td { padding: 12px 16px !important; border-bottom: 1px solid var(--color-border-subtle) !important; border-right: none !important; font-size: var(--text-sm); color: var(--color-text-primary); transition: background var(--duration-fast) var(--ease-out); } .n-data-table .n-data-table-tr:hover .n-data-table-td { background: var(--color-bg-subtle) !important; } .n-data-table .n-data-table-tr:last-child .n-data-table-td { border-bottom: none !important; } /* 数字单元格自动等宽 (用 .tabular-nums class 或 td 内 .tabular-nums span) */ .n-data-table .n-data-table-td .tabular-nums { font-variant-numeric: tabular-nums; } /* 空状态贴齐主题 */ .n-data-table .n-data-table-empty { padding: var(--space-10) var(--space-4) !important; color: var(--color-text-muted); }