feat(theme): 专业主题系统重构 — Warp/Linear 设计参考,深色/浅色完整适配
参考设计系统: - Warp: 温暖暗色调、自然层次、克制配色 - Linear: 亮度阶梯层次、半透明边框、精确排版 核心改进: - app-theme.ts: 完整重写深色/浅色调色板 (+surface-hover/active, border-subtle/focus, feedback-bg, placeholder) - useTheme.ts: 修复硬编码 return 'dark',支持 dark/light/system 完整切换 - index.css: 消除硬编码颜色,全部使用 CSS 变量 - tailwind.config.js: 新增 txt/content/surface/border/ph/feedback 语义 token - 44 文件批量迁移: 292 处 text-gray/bg-gray/text-white/placeholder-gray → 主题感知语义 token | 44 files +611/-482 | tsc零错误 | 96/96 tests passing
This commit is contained in:
1 parent
07c4a5b14f
commit
e9a0d21758
44 files changed
+593
-464
No files matched your search
+53
-30
@@ -3,55 +3,78 @@
|
||||
@tailwind utilities;
|
||||
|
||||
/* ===================================================================
|
||||
* OpsXShell v1.3.0 — Theme CSS Variables
|
||||
* OpsXShell v1.4.0 — Professional Theme System
|
||||
*
|
||||
* The default (no data-theme attribute) keeps dark mode as before so
|
||||
* that the very first paint looks correct even before React hydrates.
|
||||
* useTheme.ts will immediately set data-theme + override vars on mount.
|
||||
* Default (no data-theme) is dark mode for correct first paint.
|
||||
* useTheme.ts immediately sets data-theme + overrides vars on mount.
|
||||
*
|
||||
* Design: Warp-inspired warm dark + Linear luminance stacking
|
||||
* =================================================================== */
|
||||
|
||||
:root {
|
||||
/* ---- Dark (default, matches original hard-coded values) ---- */
|
||||
/* ---- Dark (default, matches warm slate-navy palette) ---- */
|
||||
--color-dark-900: #0f172a;
|
||||
--color-dark-800: #1e293b;
|
||||
--color-dark-700: #334155;
|
||||
--color-dark-600: #475569;
|
||||
|
||||
/* Semantic tokens (dark default) */
|
||||
--color-surface-base: #0f172a;
|
||||
--color-surface-raised: #1e293b;
|
||||
/* Semantic surface tokens */
|
||||
--color-surface-base: #0f172a;
|
||||
--color-surface-raised: #1e293b;
|
||||
--color-surface-overlay: #334155;
|
||||
--color-surface-inset: #475569;
|
||||
--color-surface-inset: #475569;
|
||||
--color-surface-hover: #374151;
|
||||
--color-surface-active: #4b5563;
|
||||
|
||||
--color-text-primary: #e2e8f0;
|
||||
/* Text */
|
||||
--color-text-primary: #f1f5f9;
|
||||
--color-text-secondary: #cbd5e1;
|
||||
--color-text-muted: #94a3b8;
|
||||
--color-text-faint: #64748b;
|
||||
--color-text-dim: #475569;
|
||||
|
||||
--color-content-primary: #e2e8f0;
|
||||
/* Content */
|
||||
--color-content-primary: #f1f5f9;
|
||||
--color-content-secondary: #cbd5e1;
|
||||
--color-content-tertiary: #94a3b8;
|
||||
--color-content-inverse: #0f172a;
|
||||
--color-content-tertiary: #94a3b8;
|
||||
--color-content-inverse: #0f172a;
|
||||
|
||||
--color-border: #334155;
|
||||
--color-border-strong: #475569;
|
||||
/* Border */
|
||||
--color-border: #1e293b;
|
||||
--color-border-subtle: #1e293b;
|
||||
--color-border-default: #334155;
|
||||
--color-border-strong: #475569;
|
||||
--color-border-focus: #3b82f6;
|
||||
|
||||
--color-accent-blue: #3b82f6;
|
||||
--color-accent-green: #10b981;
|
||||
--color-accent-purple: #8b5cf6;
|
||||
--color-accent-orange: #f97316;
|
||||
--color-accent-red: #ef4444;
|
||||
/* Accent */
|
||||
--color-accent-blue: #3b82f6;
|
||||
--color-accent-blue-hover: #60a5fa;
|
||||
--color-accent-green: #10b981;
|
||||
--color-accent-purple: #8b5cf6;
|
||||
--color-accent-orange: #f97316;
|
||||
--color-accent-red: #ef4444;
|
||||
|
||||
--color-feedback-success: #10b981;
|
||||
--color-feedback-warning: #f59e0b;
|
||||
--color-feedback-error: #ef4444;
|
||||
--color-feedback-info: #3b82f6;
|
||||
/* Feedback */
|
||||
--color-feedback-success: #10b981;
|
||||
--color-feedback-success-bg: #064e3b;
|
||||
--color-feedback-warning: #f59e0b;
|
||||
--color-feedback-warning-bg: #78350f;
|
||||
--color-feedback-error: #ef4444;
|
||||
--color-feedback-error-bg: #7f1d1d;
|
||||
--color-feedback-info: #3b82f6;
|
||||
--color-feedback-info-bg: #1e3a5f;
|
||||
|
||||
--color-scrollbar-track: #1e293b;
|
||||
--color-scrollbar-thumb: #475569;
|
||||
--color-scrollbar-thumb-h: #64748b;
|
||||
/* Placeholder */
|
||||
--color-placeholder: #64748b;
|
||||
--color-placeholder-disabled: #475569;
|
||||
|
||||
/* UI chrome */
|
||||
--color-scrollbar-track: #1e293b;
|
||||
--color-scrollbar-thumb: #475569;
|
||||
--color-scrollbar-thumb-h: #64748b;
|
||||
--color-shadow-color: rgba(0, 0, 0, 0.4);
|
||||
|
||||
/* Terminal */
|
||||
--color-terminal-bg: #0f172a;
|
||||
}
|
||||
|
||||
@@ -67,8 +90,8 @@ html, body {
|
||||
sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
background-color: #0f172a !important;
|
||||
color: #e2e8f0;
|
||||
background-color: var(--color-surface-base) !important;
|
||||
color: var(--color-text-primary);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
@@ -217,7 +240,7 @@ button {
|
||||
100% { background-position: 200% 0; }
|
||||
}
|
||||
.animate-shimmer {
|
||||
background: linear-gradient(90deg, var(--color-dark-800) 25%, var(--color-dark-700) 50%, var(--color-dark-800) 75%);
|
||||
background: linear-gradient(90deg, var(--color-surface-raised) 25%, var(--color-surface-overlay) 50%, var(--color-surface-raised) 75%);
|
||||
background-size: 200% 100%;
|
||||
animation: shimmer 1.5s ease-in-out infinite;
|
||||
}
|
||||
Reference in new issue
Block a user