/** @type {import('tailwindcss').Config} */ // Linear-style dark theme. All values hand-picked to mirror Linear's actual UI. // All foreground colors validated >= AA (4.5:1) against their surface. // // 主题机制:所有 color token 走 CSS variables(`rgb(var(--xxx-rgb) / )`), // `:root` 默认深色,`:root.light` 切换到浅色 —— 这样不动 109 处 `bg-bg` / `text-fg` // 工具类就能换肤。 module.exports = { darkMode: 'class', content: ['./src/renderer/**/*.{html,ts,tsx}'], theme: { extend: { // 系统字体栈(不依赖网络字体;CSP 默认 'self',连 Google Fonts 也会被阻挡)。 // 桌面 Electron 应用一律 fallback 到本地已装字体,体验一致且离线可用。 fontFamily: { sans: [ '-apple-system', 'BlinkMacSystemFont', 'Segoe UI Variable', 'Segoe UI', 'Microsoft YaHei', 'PingFang SC', 'sans-serif' ], mono: ['Cascadia Code', 'SF Mono', 'Menlo', 'Consolas', 'Courier New', 'monospace'] }, // 字号标度 —— 七档,按「实际渲染出来的样子」定,不是按理想值定。 // // 改动前这份标度声明了 12/13/15/17/20/28 六档并注了「用户偏好:桌面端 >= 15px」, // 但全代码库对它的引用数是 0:131 处全在写 text-[Npx] 硬编码,散落 14 个字号, // 其中 12px/12.5px 各 51/25 处、13px/13.5px 各 24/3 处 —— 那 0.5px 的差不是 // 设计决策,是漂移。所以这次按现状收敛:把邻近的 0.5px 差合并成一档, // 声明的档位就是正文 12–13px 的真实现状,不再声明一个没人用的 15px 正文。 // // 故意不带 lineHeight:正文行高由 globals.css 的 body { line-height: 1.55 } 继承, // 需要收紧的地方(大号数字)本来就显式写了 leading-tight / leading-none。 // 若在这里配上 lineHeight,那 89 处原本继承 1.55 的元素会被改成别的值 —— // 这次 sweep 只想动字号,不想顺手改全局行高。 fontSize: { '2xs': '11px', // 微型:kbd、uppercase 小标签、图例、表头 xs: '12px', // 密集 UI 与次要文字(最主力档,76 处) sm: '13px', // 正文、数据(27 处) base: '15px', // 强调正文:h1、卡片/分区标题、主按钮 lg: '18px', // 大号指标数字 xl: '20px', // h2 '2xl': '26px' // hero 数字 }, // Letter spacing tighter for display; matches Linear's headline treatment letterSpacing: { tight: '-0.01em', tighter: '-0.015em' }, // 所有 color 引用 `--xxx-rgb` 三元组,由 globals.css 定义(深 / 浅两套), // `` 让 Tailwind 自带的 `bg-bg/50`、`text-fg/70` 透明修饰继续可用。 colors: { // Linear surfaces — near-black, hairline borders bg: 'rgb(var(--bg-rgb) / )', surface: { 1: 'rgb(var(--surface-1-rgb) / )', 2: 'rgb(var(--surface-2-rgb) / )', 3: 'rgb(var(--surface-3-rgb) / )' }, border: { DEFAULT: 'rgb(var(--border-rgb) / )', strong: 'rgb(var(--border-strong-rgb) / )' }, // Foreground — 三档都对 bg 通过 WCAG AA,且阶梯均匀 // secondary/muted 提亮之前用户反馈"过灰"——保持原档位以保住"次重要"语义。 fg: { DEFAULT: 'rgb(var(--fg-rgb) / )', secondary: 'rgb(var(--fg-secondary-rgb) / )', muted: 'rgb(var(--fg-muted-rgb) / )', inverse: 'rgb(var(--fg-inverse-rgb) / )', // 在 accent 实心块上显示的文字(按钮文字等),固定白(亮色主题下也用白,因为 accent 是 Linear 紫) 'on-accent': 'rgb(var(--fg-on-accent-rgb) / )' }, // Linear purple — the single accent(亮色主题下保持同色,仅 hover 加深) accent: { DEFAULT: 'rgb(var(--accent-rgb) / )', hover: 'rgb(var(--accent-hover-rgb) / )', soft: 'var(--accent-soft)', ring: 'var(--accent-ring)' }, // Severity — reserved, never decorative sev: { high: 'rgb(var(--sev-high-rgb) / )', med: 'rgb(var(--sev-med-rgb) / )', low: 'rgb(var(--sev-low-rgb) / )' }, // 警告色(原本 MinimalRunConfig 用 Tailwind 默认 amber)。亮色主题下需要更深 // 才能在白底上 AA —— 收口到 token 层。 warning: 'rgb(var(--warning-rgb) / )' }, // Subtle, restrained radius — Linear uses 6-8px max borderRadius: { sm: '4px', DEFAULT: '6px', md: '8px', lg: '10px' }, // Hairline borders, no shadows on cards boxShadow: { // Used sparingly: only for the floating detail panel & dropdown pop: '0 0 0 1px rgba(255,255,255,0.04), 0 8px 24px rgba(0,0,0,0.32)', ring: '0 0 0 1px #5E6AD2' } } }, plugins: [] }