/** * 生成"背景开启时哪些浅色表面类要变半透明"的 CSS。 * * # 为什么要生成而不是手写 * * 手写清单必然烂:2026-09-13 用户报「很多界面是不透明的,导致壁纸露不出来」, * 一查代码里在用的浅色表面类有 gray-100(24 处)、blue-50(17)、red-50(13)、 * gray-200(8)、green-50(8)… 而当时的接管清单只有 white / gray-50 / slate-100 —— * 漏掉的那些全是实心的,正好盖住壁纸。 * * 所以清单从**源码里实际出现的类**推导:出现什么就接管什么。新增一个 * `bg-purple-50` 而忘了同步,`test/background.test.mjs` 里那条判据会红。 * * 只接管"表面段"(50/100/200):它们是面板底、提示条、卡片这类大面积浅色。 * 600/700 那一段是按钮与徽标(小控件、要读得清),**故意保持不透明** —— 见 * index.css 里 chrome-600/700 那段注释(实测可读性从 4.46:1 掉到 AA 以下)。 */ import { readdir, readFile, writeFile } from 'node:fs/promises'; import { join, dirname } from 'node:path'; import { fileURLToPath } from 'node:url'; const HERE = dirname(fileURLToPath(import.meta.url)); const SRC = join(HERE, '..', 'src'); const OUT = join(SRC, 'background-takeover.generated.css'); /** 表面段:浅色大类 + 50/100/200 三档。 */ const SURFACE = /^bg-([a-z]+)-(50|100|200)$/; /** * 页面底:**必须完全透明**(背景开启时),不能进这份"半透明"清单。 * * 它们铺满整屏,给它们 0.3 的不透明度等于在壁纸上盖一层白纱;而 index.css 里 * 已经把它们设成 transparent —— 谁后加载谁生效,生成物在 index.css 之后引入, * 所以漏了这条排除就会把"完全透明"悄悄改回"半透明"。 */ const PAGE_BASE = new Set(['bg-gray-50', 'bg-slate-100']); async function walk(dir) { const out = []; for (const e of await readdir(dir, { withFileTypes: true })) { const p = join(dir, e.name); if (e.isDirectory()) out.push(...(await walk(p))); else if (/\.(tsx?|jsx?)$/.test(e.name)) out.push(p); } return out; } const found = new Set(); for (const file of await walk(SRC)) { const text = await readFile(file, 'utf8'); for (const m of text.matchAll(/bg-[a-z]+-\d{2,3}/g)) { if (SURFACE.test(m[0]) && !PAGE_BASE.has(m[0])) found.add(m[0]); } } const classes = [...found].sort(); const body = classes .map( (cls) => `html[data-bg='on'] .${cls} {\n` + ` background-color: rgb(var(--c-${cls.slice(3)}) / var(--bg-glass-inner));\n` + ` backdrop-filter: none; /* 外层已经模糊过,嵌套层再糊一次会把图案糊成灰块 */\n` + ` -webkit-backdrop-filter: none;\n}`, ) .join('\n\n'); await writeFile( OUT, `/* 由 scripts/gen-background-takeover.mjs 生成 —— 不要手改。\n` + ` * 背景开启时把源码里在用的浅色表面类改成半透明(清单来自 src/**/*.tsx 的实际用法)。\n` + ` * 共 ${classes.length} 个类:${classes.join(', ')}\n */\n\n${body}\n`, ); console.log(` 生成 ${classes.length} 个类 → ${OUT}`);