// ==UserScript== // @name 洛谷深色模式 · Luogu Dark // @namespace https://www.luogu.com.cn/ // @version 5.4.5 // @description 给洛谷全部页面(题目/列表/比赛/排行榜/记录/个人中心/团队/讨论/题解/提交)的卡片赋予 #383838 半透明深色效果;统一色板变量、修复残留白块(下拉浮层、弹窗、编辑器、分页、上传框)、适配 Prism 与 CodeMirror 代码配色,并支持一键开关与半透明度调节 // @author You // @match https://www.luogu.com.cn/* // @match https://*.luogu.com.cn/* // @match https://*.luogu.com/* // @match https://*.luogu.me/* // @grant GM_registerMenuCommand // @grant GM_unregisterMenuCommand // @grant GM_setValue // @grant GM_getValue // @run-at document-end // ==/UserScript== /* ============================================================================= * 设计理念(与原 luogu-dark.txt 保持一致,只是做得更彻底) * ----------------------------------------------------------------------------- * 1. 只改「卡片」,不强制整页变黑。页面底色仍交给洛谷自己的主题, * 我们只在卡片上铺一层 #383838 @ 55% 的半透明深色,让站点主题透出来。 * 2. 一切颜色走 token。所有色值集中在「色板」一节,并同时以 CSS 变量 * --ld-* 暴露在 :root 上,方便用 Stylus 或 DevTools 单独微调, * 不必再进脚本里全文搜索色值。 * 3. 优先复用洛谷自带的主题变量。高亮色一律用 * var(--lcolor--primary, 52,152,219) 这类变量兜底,站点换主题时自动跟随。 * 4. 尊重站点原有的「内联颜色」。用户的等级色、题目难度色等是站点用 * style="color:..." 写死的,我们一律用 :not([style*="color"]) 放行, * 不做「统一刷白」这种破坏信息的覆盖。 * 5. 半透明 + 低对比层次。文字分三档(主/次/弱),边框 8% 白,阴影柔和, * 避免在深色卡片上出现纯白大色块(下拉浮层、弹窗、编辑器是重灾区)。 * 6. 不靠 DOM 硬改来做视觉。除「给站点内联色补 alpha」这一处必要修补外, * 全部用 CSS 完成;JS 只负责注入、路由分包与性能控制,尽量不影响页面逻辑。 * ========================================================================== */ (function () { 'use strict'; /* ========================================================================= * ① 可调配置(改这里就够了) * ====================================================================== */ // 卡片底色与透明度:CARD_ALPHA 越小越透,1 表示不透明 var CARD_RGB = '56, 56, 56'; // #383838 // ★ 默认取 0.85:P13501 实测 0.55 在白底宿主上会合成为 rgb(146,146,146) 中灰, // 全页会有 144 个元素对比度低于 2.2(标题 2.14、侧栏小字 1.19)。 // 0.85 合成成 rgb(56,56,56),实测可用;滑条可随时调回 0.55 或更低。 var CARD_ALPHA = 0.55; var CARD_ALPHA_MIN = 0.55; // 「原脚本观感档」,面板里给一个快捷按钮 // ★ 设置面板 var PANEL_KEY = 'Alt+L'; // 打开/关闭设置面板(可改 'Alt+Shift+L') var ALPHA_MIN = 0.30; // 允许调到很透(浅色宿主下会偏灰,用户自选) var ALPHA_MAX = 1.00; var UI_FONT = '-apple-system, "Segoe UI", "Microsoft YaHei", sans-serif'; var UI_BG = '#2a2a2a'; // 面板底色:不透明,避免和页面半透明层叠加 var UI_BG_SOFT = '#333333'; var UI_BORDER = '#555555'; var UI_FG = '#f0f0f0'; // 站点内联色(题目标签、难度条、进度格)统一补到的透明度 var TAG_ALPHA = 0.55; // 输入框 / 浮层 / 按钮底的透明度(比卡片更浅一点,保持层次) var PANEL_RGB = '0, 0, 0'; var PANEL_ALPHA = 0.25; // 代码框底色:站点默认透明,叠在半透明卡片上几乎看不出边界。 // 改成不透明深色底(与提交框编辑器同色),边界清楚,也和截图一致。 var CODE_RGB = '30, 30, 30'; // #1e1e1e var CODE_ALPHA = 1; // 圆角 var RADIUS = '6px'; // ★ 层级透明度:都按「卡片 alpha × 百分比」派生,保证永远是「比卡片略深的半透明」, // 而不是死黑实色。样例框 80%、引用框 70%。 var SAMPLE_RATIO = 0.80; var QUOTE_RATIO = 0.70; var QUOTE_RGB = '0, 0, 0'; // 引用框叠加用的基色(半透明,不是实色底) // 是否把整页背景也压暗(默认关闭,保持原脚本「只改卡片」的理念) var COVER_PAGE = false; // ★ 代码框斜度:卡片 alpha × 该倍率 → 比卡片略深的半透明底(不是死黑实色)。 // CODE_RGB/CODE_ALPHA 保留作后备,但代码框优先走这个倍率。 var CODE_RATIO = 0.85; // ★ 样例区代码框单独一档:比普通代码框更透,避免在样例框(0.68)里再陷出一层。 // = 卡片 alpha × 0.40(默认 0.85 → 0.34) var SAMPLE_CODE_RATIO = 0.40; // 是否把 #383838 之类的中性色内联样式也补 alpha(默认关闭,只处理彩色) var ALPHA_NEUTRAL = false; // ★ 底栏:文字统一白色;可整块隐藏(面板里切换,默认展示) var HIDE_FOOTER = true; // 多个脚本副本同时注入时,只让第一个生效 if (window.__LUOGU_DARK_CARD__) return; window.__LUOGU_DARK_CARD__ = true; /* ========================================================================= * ② 色板:唯一色值来源 * 改动这里会同时影响 CSS 变量与全部规则 * ====================================================================== */ var PALETTE = { fg: '#ffffff', // 卡片内主文字 fgSoft: '#d6d6d6', // 正文 fgMuted: '#a0a0a0', // 次要说明、时间、计数 fgFaint: '#888888', // 占位符、极弱信息 fgHeading: '#f0f0f0', // 标题 link: '#7fc4ff', linkHover: '#b8ddff', primary: 'rgb(var(--lcolor--primary, 52, 152, 219))', primaryDark: '#2980b9', primarySoft: '#5dade2', vip: '#d1af60', inlineCode: '#ffc4c4', code: '#d4d4d4', // 代码文字 codeBg: 'rgba(' + CODE_RGB + ', ' + CODE_ALPHA + ')', // 代码块底色 // 浮层 / 输入类控件(不透明,避免透过内容) surface: '#2a2a2a', surfaceHi: '#333333', surfaceDeep: '#2b2b2b', border: '#555555', borderHi: '#888888', // 边框与分隔(白 + 透明度) hairline: 'rgba(255, 255, 255, 0.08)', hairlineSoft:'rgba(255, 255, 255, 0.06)', track: '#252526', thumb: '#555555', thumbHi: '#777777', // ★ VS Code One Dark Pro 代码配色(键名保持不变,只换值) synKeyword: '#c678dd', // 关键字 int / for / if / using / namespace synControl: '#56b6c2', // 预处理 #include / #define synFunction: '#61afef', // 函数名 work / min / max synNumber: '#d19a66', // 数字 1003 / 0 / -1 synString: '#98c379', // 字符串 synComment: '#5c6370', // 注释 // 更新两次 synType: '#e5c07b', // 类型名 long long / size_t // One Dark Pro 的「变量 / 属性」红,以及运算符浅灰;Dark+ 表里没有这两项 synVariable: '#e06c75', // 变量 / 属性 synOperator: '#abb2bf', // 运算符 // 编辑器结构色 editorBg: '#1e1e1e', editorGutter:'#858585', editorActive:'#2a2a2a', editorSelect:'#264f78', // 语义色 success: '#a5dc86', // 卡片本体不在这里定义:--ld-card 由 4.1 直接写在 :root 上 // (放在色板里会变成 var(--ld-card, var(--ld-card…)) 自引用,整条声明会失效) // 样例框:按原脚本设计保持透明,只靠卡片底色托着。 // 不要再给它独立背景色 —— 否则「输入输出样例」下面会套出三层框。 layerFallback1: 'transparent', layerFallback2: 'transparent', panel: 'rgba(' + PANEL_RGB + ', ' + PANEL_ALPHA + ')', shadow: 'rgba(0, 0, 0, 0.4)', shadowDeep: 'rgba(0, 0, 0, 0.6)' }; // 暴露成 CSS 变量:--ld-fg、--ld-surface…… var ROOT_VARS = (function () { var out = ':root{'; Object.keys(PALETTE).forEach(function (k) { // card / panel / code 等组合值也一并暴露,便于外部覆盖 out += '\n --ld-' + k.replace(/[A-Z]/g, function (c) { return '-' + c.toLowerCase(); }) + ': ' + PALETTE[k] + ';'; }); return out + '\n}'; })(); /* ========================================================================= * ③ 选择器片段(集中管理,方便补新组件) * ====================================================================== */ // 浮层类:下拉菜单、语言选择、Popper 弹层…… var SEL_POPOVER = 'body .dropdown, body .v-popper__popper, body .v-popper__inner, ' + 'body .v-popper--theme-dropdown, body [class*="lang-select"], ' + 'body [class*="language-select"], body [class*="select-menu"], ' + 'body .lfe-dropdown, body .lfe-select, body .combo-wrapper.full'; // 站点「带内联颜色」的元素一律放行(等级色、难度色、题目状态色) var NOT_INLINE_COLOR = ':not([style*="color"])'; /* ========================================================================= * ④ 样式表 * ====================================================================== */ var CSS_PARTS = []; /* ---------- 4.1 色板变量与「只用于注入,不影响页面」的初始化 -------------- */ CSS_PARTS.push(ROOT_VARS + '\n' + [ '/* 让 color-scheme 走深色,原生控件(滚动条、日期选择)自动跟随 */', ':root { color-scheme: dark !important; }', '/* ★ 卡片透明度:沿用原脚本设计(rgba + alpha),不做任何颜色加深。', ' 滑条写 --ld-layer-alpha;浅色宿主额外加一个补偿量(默认 0.55+0.30=0.85),', ' 这是原脚本缺的「宿主主题检测」,深色宿主仍严格等于滑条值。 */', ':root {', ' --ld-layer-alpha: ' + CARD_ALPHA + ';', ' --ld-card-alpha: var(--ld-layer-alpha);', ' --ld-card: rgba(' + CARD_RGB + ', var(--ld-card-alpha, ' + CARD_ALPHA + '));', ' /* ★ 样例框 / 引用框:卡片 alpha × 百分比 → 比卡片略深,但仍是半透明,不是死黑 */', ' --ld-sample-alpha: calc(var(--ld-layer-alpha) * ' + SAMPLE_RATIO + ');', ' --ld-quote-alpha: calc(var(--ld-layer-alpha) * ' + QUOTE_RATIO + ');', ' /* ★ 代码框:卡片 alpha × 0.85,半透明比卡片略深,不再是死黑实色 */', ' --ld-code-alpha: calc(var(--ld-layer-alpha) * ' + CODE_RATIO + ');', ' --ld-sample: rgba(' + CARD_RGB + ', var(--ld-sample-alpha));', ' --ld-quote: rgba(' + QUOTE_RGB + ', var(--ld-quote-alpha));', ' --ld-code-bg: rgba(' + CARD_RGB + ', var(--ld-code-alpha));', ' /* ★ 样例区代码框专用(更透,避免在样例框里再陷出第三层);', ' 题解页 markdown 代码框与提交页 CodeMirror 继续用 --ld-code-bg,不受影响 */', ' --ld-sample-code-alpha: calc(var(--ld-layer-alpha) * ' + SAMPLE_CODE_RATIO + ');', ' --ld-sample-code-bg: rgba(' + CARD_RGB + ', var(--ld-sample-code-alpha));', ' /* ★ 测试点方块专属透明度(Alt+L 面板可调)。', ' 站点用 .lcolor-bg-green-3 等语义类把底色写死为不透明 rgb(),', ' 所以这里不重写颜色(保住色相),只调整个方块的不透明度。 */', ' --ld-testcase-alpha: 1;', ' /* ★ 全局「淡度」:由 Alt+L 面板滑块写入 --ld-saturate(默认 100%,即不修改)。', ' 作用在 html 上做 saturate() 降饱和,用于「颜色太艳、看久了眼睛累」的场景。', ' 放在 html 上不会改变 position:fixed 的包含块(根元素的包含块本就是视口)。 */', ' --ld-saturate: 100%;', ' --ld-layer-1: var(--ld-sample);', ' --ld-layer-2: var(--ld-code-bg);', ' /* 语法高亮:与截图一致的统一色值,Prism 与 CodeMirror 共用同一套 */', ' --ld-syn-keyword: ' + PALETTE.synKeyword + ';', ' --ld-syn-control: ' + PALETTE.synControl + ';', ' --ld-syn-function: ' + PALETTE.synFunction + ';', ' --ld-syn-number: ' + PALETTE.synNumber + ';', ' --ld-syn-string: ' + PALETTE.synString + ';', ' --ld-syn-comment: ' + PALETTE.synComment + ';', ' --ld-syn-type: ' + PALETTE.synType + ';', ' --ld-syn-variable: ' + PALETTE.synVariable + ';', ' --ld-syn-operator: ' + PALETTE.synOperator + ';', ' --ld-syn-plain: ' + PALETTE.code + ';', '}', 'html { filter: saturate(var(--ld-saturate, 100%)) !important; }', '/* ★ 卡片本体兜底文字色:站点默认 #404040,在深色卡上几乎不可见 */', '.l-card { color: var(--ld-fg-soft) !important; }' ].join('\n')); /* ---------- 4.2 卡片本体 ------------------------------------------------- */ CSS_PARTS.push([ '/* ========== 卡片背景 ========== */', '.theme-page {', ' --theme-card-background: var(--ld-card) !important;', ' --theme-card-backdrop-filter: none !important;', '}', '.l-card,', '.l-card::before,', '.l-card::after {', ' background: var(--ld-card) !important;', ' backdrop-filter: none !important;', ' -webkit-backdrop-filter: none !important;', ' border: 1px solid var(--ld-hairline) !important;', ' box-shadow: 0 4px 20px var(--ld-shadow) !important;', '}', '/* 卡片内的分区不再叠第二层底色,避免越套越黑 */', '.l-card .l-card { background: transparent !important; box-shadow: none !important; }' ].join('\n')); /* ---------- 4.3 文字层次 ------------------------------------------------- */ CSS_PARTS.push([ '/* ========== 文字层次 ========== */', '.l-card .stat .stat-text, .l-card .stat .name, .l-card .stat .value,', '.l-card .header-card .stat-text,', '.l-card .l-flex-info-row > a.name,', '.l-card .l-flex-info-row time,', '.l-card .menu .entry,', 'footer, footer p, footer a, footer span, footer .copyright, footer .copyright a {', ' color: var(--ld-fg) !important;', '}', '.l-card .l-flex-info-row > span:last-child:not([class*="lcolor"]) {', ' color: var(--ld-fg) !important;', '}', '.l-card p,', '.l-card .lfe-marked, .l-card .lfe-marked p, .l-card .lfe-marked li,', '.l-card .lfe-marked strong, .l-card .lfe-marked em,', '.l-card .lfe-marked td, .l-card .lfe-marked th,', '.l-card .attachments, .l-card .attachments .item, .l-card .attachments span,', '.l-card .attachments svg,', '.l-card .lfe-h2, .l-card .lfe-h3, .l-card .lfe-h4,', '.l-card section .title { color: var(--ld-fg-soft) !important; }', '.l-card .lfe-h1, .l-card .lfe-h5, .l-card .lfe-h6 { color: var(--ld-fg-heading) !important; }', '.l-card .lfe-caption, .l-card .lfe-caption time,', '.l-card .selected-tags .lcolor--grey-3,', '.l-card .result .count,', '.l-card .page-bar .total,', '.l-card .attachments .light-text { color: var(--ld-fg-muted) !important; }', '/* ★ 记录详情右侧信息行的「标签」(所属题目/评测状态/评测分数/提交时间)→ 白色。', ' 原来和上面那组共用 var(--ld-fg-muted)(灰 rgb(160,160,160)),按要求改为白色。 */', '.l-card .l-flex-info-row > span:first-child { color: var(--ld-fg) !important; }', /* 链接:非内联色的才是我们自己的链接 */ '.l-card .lfe-marked a,', '.l-card .attachments a,', '.l-card .l-flex-info-row a' + NOT_INLINE_COLOR + ',', '.l-card .solution-list .row a' + NOT_INLINE_COLOR + ',', '.l-card .row .title a, .l-card .row .pid a,', '.l-card .selected-tags a,', '.l-card .result a.lfe-caption,', '.l-card .header-container a,', '.l-card .table .row .username a, .l-card .table .row .title a,', 'footer a { color: var(--ld-link) !important; }', '.l-card .lfe-marked a:hover, .l-card .attachments a:hover,', '.l-card .row .title a:hover, .l-card .table .row .username a:hover,', '.l-card .table .row .title a:hover,', '.l-card .l-flex-info-row a' + NOT_INLINE_COLOR + ':hover,', '.l-card .solution-list .row a' + NOT_INLINE_COLOR + ':hover,', 'footer a:hover { color: var(--ld-link-hover) !important; }', '.l-card .lfe-marked hr, .l-card .l-flex-info-row,', '.l-card .table .row-wrap, .l-card .table .row,', '.l-card .list-wrap .row-wrap, .l-card .list-wrap .row {', ' border-color: var(--ld-hairline) !important;', '}', '.l-card .lfe-marked :not(pre) > code,', '.l-card .announcement code, .l-card .bulletin code, .l-card .notice code,', '.l-card .feed-card-content code, .l-card .markdown-body :not(pre) > code {', ' background: rgba(255, 255, 255, 0.08) !important;', ' color: var(--ld-inline-code) !important;', ' border: none !important;', '}' ].join('\n')); /* ---------- 4.4 标题去横线 ------------------------------------------------- */ CSS_PARTS.push([ '/* ★ 去掉正文标题下面自带的横线 */', '.l-card .lfe-marked h1, .l-card .lfe-marked h2, .l-card .lfe-marked h3,', '.l-card .lfe-marked h4, .l-card .lfe-marked h5, .l-card .lfe-marked h6,', '.l-card .lfe-h1, .l-card .lfe-h2, .l-card .lfe-h3,', '.l-card .lfe-h4, .l-card .lfe-h5, .l-card .lfe-h6 {', ' border-bottom: none !important;', ' padding-bottom: 0 !important;', ' box-shadow: none !important;', '}' ].join('\n')); /* ---------- 4.5 代码块(样例框 / 题解 / 预览) ----------------------------- */ CSS_PARTS.push([ '.l-card .io-sample { background: transparent !important; }', '.l-card .io-sample-block { background: transparent !important; }', '/* ★ 「输入输出样例」大标题下不要再套框:这两个容器不参与任何边框/阴影,', ' 只有里面的代码框自己有框。 */', '.l-card .io-sample, .l-card .io-sample-block,', '.l-card .io-sample > div, .l-card .io-sample-block > div {', ' border: none !important;', ' box-shadow: none !important;', '}', '/* ★ 代码显示框:原脚本那套独立深色底 rgba(0,0,0,0.35),比卡片深 */', '.l-card .io-sample pre, .l-card .io-sample pre.lfe-code,', '.l-card pre.lfe-code, .l-card .lfe-code,', '.l-card .lfe-marked pre, .l-card .markdown-body pre,', '.l-card .preview pre, .l-card .code-block pre {', ' background: var(--ld-layer-2) !important;', ' color: ' + PALETTE.code + ' !important;', ' border: 1px solid var(--ld-hairline) !important;', ' border-radius: ' + RADIUS + ' !important;', ' padding: 1em !important;', ' overflow-x: auto !important;', ' box-sizing: border-box !important;', ' margin: 1em 0 !important;', '}', '.l-card .io-sample pre code, .l-card pre.lfe-code code,', '.l-card .lfe-code code, .l-card .lfe-marked pre code,', '.l-card .markdown-body pre code, .l-card .preview pre code {', ' background: transparent !important; /* 内部透明,彻底解决双层背景 */', ' border: none !important;', ' padding: 0 !important;', ' color: ' + PALETTE.code + ' !important;', ' display: block !important;', " font-family: 'Consolas', 'Monaco', 'Courier New', monospace !important;", '}', '/* ★ 只覆盖「样例区」代码框的底色:更透,与样例框(0.68)接近,不陷出第三层。', ' 题解页 markdown 代码框 / 提交页 CodeMirror 不在此选择器内,保持 --ld-code-bg 不变。 */', '.l-card .io-sample pre, .l-card .io-sample pre.lfe-code {', ' background: var(--ld-sample-code-bg) !important;', '}', '.l-card .io-sample .lfe-caption, .l-card .io-sample .lfe-caption b {', ' background: transparent !important;', ' color: var(--ld-fg-soft) !important;', ' border-color: transparent !important;', '}', '.l-card .io-sample .lfe-caption button {', ' color: var(--ld-primary) !important;', ' border-color: var(--ld-primary) !important;', ' background: transparent !important;', '}', '.l-card .io-sample .lfe-caption button:hover { background: rgba(52, 152, 219, 0.15) !important; }' ].join('\n')); /* ---------- 4.6 复制按钮 ------------------------------------------------ */ CSS_PARTS.push([ 'html body button.copy-button, html body .copy-button,', 'html body .lfe-marked button.copy-button,', 'html body [class*="copy"] > button, html body button[class*="copy"] {', ' color: ' + PALETTE.fg + ' !important;', ' fill: ' + PALETTE.fg + ' !important;', ' stroke: none !important;', ' opacity: 1 !important;', ' visibility: visible !important;', ' background: transparent !important;', ' background-color: transparent !important;', ' border: none !important;', ' box-shadow: none !important;', '}', '/* hover:只有极淡白底,字/图标保持白色 */', 'html body button.copy-button:hover, html body .copy-button:hover,', 'html body [class*="copy"] > button:hover, html body button[class*="copy"]:hover {', ' color: ' + PALETTE.fg + ' !important;', ' fill: ' + PALETTE.fg + ' !important;', ' background: rgba(255, 255, 255, 0.1) !important;', ' background-color: rgba(255, 255, 255, 0.1) !important;', ' border: none !important;', '}', 'html body button.copy-button svg, html body button.copy-button path,', 'html body .copy-button svg, html body .copy-button path,', 'html body [class*="copy"] > button svg, html body button[class*="copy"] svg {', ' color: var(--ld-fg) !important;', ' fill: var(--ld-fg) !important;', ' stroke: none !important;', '}' ].join('\n')); /* ---------- 4.7 按钮 / 标签 / 输入控件 ------------------------------------ */ CSS_PARTS.push([ '/* ========== 按钮统一样式 ========== */', '.l-card .button-transparent,', '.l-card.burger .body button.solid,', '.l-card button.transparent,', '.l-card .menu .button {', ' color: var(--ld-fg) !important;', ' border: 1px solid rgba(255, 255, 255, 0.7) !important;', ' background: transparent !important;', '}', '.l-card .button-transparent:hover,', '.l-card.burger .body button.solid:hover,', '.l-card button.transparent:hover {', ' color: var(--ld-fg) !important;', ' border-color: var(--ld-fg) !important;', ' background: rgba(255, 255, 255, 0.1) !important;', '}', '/* 实心按钮:跟随站点主题色。', ' ★ 排除 .lcolor-var-red-3(语义红按钮,如文章编辑页的「删除文章」)——', ' 否则会被强制成蓝底白字无边框,丢掉它的语义红。 */', '.l-card button.solid:not(.lcolor-var-red-3), .l-card a.solid:not(.lcolor-var-red-3),', '.l-card .result button.solid:not(.lcolor-var-red-3),', '.l-card .inquiry-header .solid:not(.lcolor-var-red-3),', '.l-card .inquiry-header a.solid:not(.lcolor-var-red-3) {', ' background-color: var(--ld-primary) !important;', ' color: var(--ld-fg) !important;', ' border-width: 0 !important;', ' border-style: none !important;', '}', '.l-card button.solid:hover, .l-card a.solid:hover,', '.l-card .result button.solid:hover,', '.l-card .inquiry-header .solid:hover { background-color: var(--ld-primary-dark) !important; }', ':is(html) body .l-card .right a.solid.l-button,', ':is(html) body .l-card .right button.solid {', ' background-color: transparent !important;', ' color: ' + PALETTE.fg + ' !important;', ' border-width: 0.571429px !important;', ' border-style: solid !important;', ' border-color: rgba(255, 255, 255, 0.7) !important;', '}', ':is(html) body .l-card .drop, :is(html) body .drop {', ' background-color: var(--ld-surface) !important;', ' border-top-color: var(--ld-hairline) !important;', ' border-right-color: var(--ld-hairline) !important;', ' border-bottom-color: var(--ld-hairline) !important;', ' border-left-color: var(--ld-hairline) !important;', '}', ':is(html) body .l-card .image-block, :is(html) body .image-block {', ' background-color: var(--ld-surface) !important;', ' border-top-color: var(--ld-hairline) !important;', ' border-right-color: var(--ld-hairline) !important;', ' border-bottom-color: var(--ld-hairline) !important;', ' border-left-color: var(--ld-hairline) !important;', '}', ':is(html) body .image-block time,', ':is(html) body .image-block span,', ':is(html) body .image-block .lfe-caption {', ' color: var(--ld-fg-muted) !important;', '}', 'html body .top-bar {', ' /* 用 --ld-surface-hi(#333333) 而不是 --ld-surface(#2a2a2a):', ' 后者与 .theme-page 页面底同色,会让顶栏失去层次(用户反馈)。 */', ' background-color: var(--ld-surface-hi) !important;', ' /* 站点这条 bar 的文字是 rgb(51,51,51) 深色,压暗底后必须同时提亮字色 */', ' color: ' + PALETTE.fg + ' !important;', '}', 'html body .ticket-card .left.row span,', 'html body .l-card .ticket-card .left.row span {', ' background-color: var(--ld-panel) !important;', ' color: var(--ld-fg-soft) !important;', '}', 'html body div.title {', ' color: ' + PALETTE.fg + ' !important;', '}', ':is(html) body button.lcolor-var-blue-4 {', ' color: rgb(var(--lcolor--blue-3)) !important;', ' border-top-color: rgb(var(--lcolor--blue-3)) !important;', ' border-right-color: rgb(var(--lcolor--blue-3)) !important;', ' border-bottom-color: rgb(var(--lcolor--blue-3)) !important;', ' border-left-color: rgb(var(--lcolor--blue-3)) !important;', '}', 'html body .l-card.error-background,', 'html body .error-background,', 'html body .l-card .error-background {', ' background-color: var(--ld-card) !important;', '}', 'html body .l-card.error-background *,', 'html body .error-background * {', ' color: ' + PALETTE.fg + ' !important;', '}', 'html body pre.lfe-marked-original:empty,', 'html body .lfe-marked-original:empty {', ' background-color: transparent !important;', ' border-top-color: transparent !important;', ' border-right-color: transparent !important;', ' border-bottom-color: transparent !important;', ' border-left-color: transparent !important;', '}', 'html body:has(.error-background) nav.sidebar,', 'html body:has(.error-background) .sidebar.lside,', 'html body:has(.error-background) .user-nav {', ' background-color: var(--ld-surface-hi) !important;', '}', 'html body:has(.error-background) nav.sidebar span,', 'html body:has(.error-background) nav.sidebar a,', 'html body:has(.error-background) .sidebar.lside span,', 'html body:has(.error-background) .sidebar.lside a,', 'html body:has(.error-background) .user-nav span,', 'html body:has(.error-background) .user-nav a {', ' color: ' + PALETTE.fg + ' !important;', '}', 'html body nav.sidebar,', 'html body .sidebar.lside,', 'html body .user-nav {', ' background-color: var(--ld-surface-hi) !important;', '}', 'html body nav.sidebar :not(svg):not(path):not([style*="color"]):not([class*="lcolor"]),', 'html body .sidebar.lside :not(svg):not(path):not([style*="color"]):not([class*="lcolor"]),', 'html body .user-nav :not(svg):not(path):not([style*="color"]):not([class*="lcolor"]) {', ' color: ' + PALETTE.fg + ' !important;', '}', 'html body nav.sidebar a:focus,', 'html body nav.sidebar button:focus,', 'html body .sidebar.lside a:focus,', 'html body .sidebar.lside button:focus,', 'html body .user-nav a:focus,', 'html body .user-nav button:focus,', 'html body nav.sidebar a:focus-visible,', 'html body nav.sidebar button:focus-visible,', 'html body .sidebar.lside a:focus-visible,', 'html body .sidebar.lside button:focus-visible,', 'html body .user-nav a:focus-visible,', 'html body .user-nav button:focus-visible {', ' outline-style: none !important;', '}', 'html body .l-card .menu-container,', 'html body .menu-container {', ' border-bottom-color: var(--ld-hairline) !important;', '}', 'html body .l-card .section,', 'html body .section {', ' border-bottom-color: var(--ld-hairline) !important;', '}', 'html body main.wrapped.lfe-body,', 'html body .wrapper.wrapped,', 'html body .main-container {', ' background-color: var(--ld-surface) !important;', '}', 'html body .card.message {', ' background-color: var(--ld-card) !important;', ' color: ' + PALETTE.fg + ' !important;', '}', 'html body .card.message *,', 'html body .wrapper.wrapped .header span,', 'html body .wrapper.wrapped .header a,', 'html body .wrapper.wrapped .header .user-nav {', ' color: ' + PALETTE.fg + ' !important;', '}', 'html body .wrapper.wrapped .header .user-nav,', 'html body .wrapper.wrapped .header {', ' background-color: transparent !important;', '}', 'html body .cs-dialog,', 'html body .cs-dialog-header,', 'html body .cs-dialog-body,', 'html body .cs-dialog-footer,', 'html body .cs-dialog-content {', ' background-color: var(--ld-card) !important;', ' color: ' + PALETTE.fg + ' !important;', '}', 'html body .cs-dialog :not(a):not(button):not([class*="lcolor"]):not([class*="token"]):not(svg):not(path) {', ' color: ' + PALETTE.fg + ' !important;', '}', 'html body .cs-dialog-container {', ' background-color: rgba(0, 0, 0, 0.5) !important;', '}', '/* ★★ 编辑器「设置 / 更多」等其它内联浮层:统一给深色底(teleport 到 body,不带 .l-card) */', 'html body .l-card.container.type-burger,', 'html body .l-card.container {', ' background-color: var(--ld-card) !important;', ' color: ' + PALETTE.fg + ' !important;', '}', '/* 工单创建页左侧说明栏的白竖线(div.side-info border-left rgb(232,232,232)) */', 'html body .side-info {', ' border-left-color: var(--ld-hairline) !important;', '}', 'html body:not(:has(.lfe-body)) {', ' background-color: var(--ld-surface) !important;', ' color: ' + PALETTE.fg + ' !important;', '}', 'html body:not(:has(.lfe-body)) .card,', 'html body:not(:has(.lfe-body)) [class*="dialog"],', 'html body:not(:has(.lfe-body)) [class*="modal"],', 'html body:not(:has(.lfe-body)) [class*="panel"] {', ' background-color: var(--ld-card) !important;', ' color: ' + PALETTE.fg + ' !important;', '}', 'html body:not(:has(.lfe-body)) input,', 'html body:not(:has(.lfe-body)) textarea {', ' background-color: var(--ld-surface) !important;', ' color: ' + PALETTE.fg + ' !important;', ' border-top-color: var(--ld-border) !important;', ' border-right-color: var(--ld-border) !important;', ' border-bottom-color: var(--ld-border) !important;', ' border-left-color: var(--ld-border) !important;', '}', '/* ★★ 外链安全拦截页里那个「白框」的真身:
(用户提供的 DOM 片段)。',
        '   它不是 input/textarea,而是 
,所以上面那条规则覆盖不到 ——',
        '   页面主体已经深色(深灰底/白字/蓝按钮),只有这个 pre 仍是纯白。',
        '   这里直接按 id 精准命中(id="url" 是该页专有,不写 .lfe-body 限定,',
        '   以防该页结构变体;作用范围极小、无误伤风险)。 */',
        'html body pre#url,',
        'html body #url {',
        '    background-color: var(--ld-surface) !important;',
        '    color: ' + PALETTE.fg + ' !important;',
        '    border-top-color: var(--ld-border) !important;',
        '    border-right-color: var(--ld-border) !important;',
        '    border-bottom-color: var(--ld-border) !important;',
        '    border-left-color: var(--ld-border) !important;',
        '}',
        'html body .am-comment,',
        'html body .am-comment-main {',
        '    background-color: transparent !important;',
        '}',
        'html body .am-comment-hd {',
        '    background-color: var(--ld-panel) !important;',
        '    color: ' + PALETTE.fg + ' !important;',
        '    border-bottom-color: var(--ld-border) !important;',
        '}',
        'html body .am-comment-bd {',
        '    background-color: var(--ld-surface) !important;',
        '    color: ' + PALETTE.fg + ' !important;',
        '}',
        'html body .am-comment-hd :not(a):not([style*="color"]):not([class*="lcolor"]):not(svg):not(path),',
        'html body .am-comment-bd :not(a):not([style*="color"]):not([class*="lcolor"]):not(svg):not(path) {',
        '    color: ' + PALETTE.fg + ' !important;',
        '}',
        '/* 尾巴:外圈跟随气泡边框(站点蓝),内芯跟随气泡底色 */',
        'html body .am-comment-main::before {',
        '    border-right-color: var(--ld-primary) !important;',
        '}',
        'html body .am-comment-main::after {',
        '    border-right-color: var(--ld-surface) !important;',
        '}',
        'html body:has(.lg-index-content),',
        'html body:has(.lg-index-content) .main-container,',
        'html body:has(.lg-index-content) main {',
        '    background-color: var(--ld-surface) !important;',
        '}',
        'html body:has(.lg-index-content) .lg-article,',
        'html body:has(.lg-index-content) .am-panel,',
        'html body:has(.lg-index-content) .am-slider,',
        'html body:has(.lg-index-content) .am-slider-slide,',
        'html body:has(.lg-index-content) .am-slider-desc {',
        '    background-color: var(--ld-card) !important;',
        '}',
        'html body:has(.lg-index-content) .am-comment-hd,',
        'html body:has(.lg-index-content) .am-comment-bd {',
        '    background-color: var(--ld-panel) !important;',
        '}',
        'html body:has(.lg-index-content) input.am-form-field,',
        'html body:has(.lg-index-content) .am-form-field,',
        'html body:has(.lg-index-content) textarea {',
        '    background-color: var(--ld-surface) !important;',
        '    color: ' + PALETTE.fg + ' !important;',
        '    border-top-color: var(--ld-border) !important;',
        '    border-right-color: var(--ld-border) !important;',
        '    border-bottom-color: var(--ld-border) !important;',
        '    border-left-color: var(--ld-border) !important;',
        '}',
        'html body:has(.lg-index-content) main :not(a):not(button):not(input):not(textarea):not(select):not([class*="am-btn"]):not([class*="am-panel-"]):not([class*="lg-fg-"]):not([class*="lg-bg-"]) {',
        '    color: ' + PALETTE.fg + ' !important;',
        '}',
        '/* SVG  用的是 fill 而非 color,单独处理 */',
        'html body:has(.lg-index-content) main svg text,',
        'html body:has(.lg-index-content) main text {',
        '    fill: ' + PALETTE.fg + ' !important;',
        '}',
        '/* 语义色 .lg-fg-bluedark(rgb(52,73,94) 深蓝,深卡上不可读):保留蓝色相、提亮 */',
        'html body:has(.lg-index-content) .lg-fg-bluedark {',
        '    color: var(--ld-link) !important;',
        '}',
        'html body .highcharts-tooltip path,',
        'html body .highcharts-tooltip > path,',
        'html body .highcharts-tooltip path:first-child,',
        'html body .highcharts-tooltip path:last-child {',
        '    fill: var(--ld-surface) !important;',
        '    stroke: var(--ld-border) !important;',
        '}',
        'html body .highcharts-tooltip text,',
        'html body .highcharts-tooltip tspan {',
        '    fill: ' + PALETTE.fg + ' !important;',
        '}',
        '/* 图表自身的网格线 / 轴线:Highcharts 默认是浅灰,深底上刺眼 → 改用 hairline */',
        'html body .highcharts-grid-line,',
        'html body .highcharts-axis-line,',
        'html body .highcharts-tick {',
        '    stroke: var(--ld-hairline) !important;',
        '}',
        'html body .highcharts-axis-labels text,',
        'html body .highcharts-legend-item text,',
        'html body .highcharts-title text,',
        'html body .highcharts-subtitle text,',
        'html body .highcharts-yaxis-title text,',
        'html body .highcharts-xaxis-title text {',
        '    fill: ' + PALETTE.fg + ' !important;',
        '}',
        'html body .category-card {',
        '    /* ★ 不能设 transparent:这几张卡位于页面「云彩背景图」之上,',
        '       透明会让亮色背景图透出,白字不可读(实测回归)。给实心深色底。 */',
        '    background-color: var(--ld-surface) !important;',
        '    color: ' + PALETTE.fg + ' !important;',
        '    border-top-color: var(--ld-hairline) !important;',
        '    border-right-color: var(--ld-hairline) !important;',
        '    border-bottom-color: var(--ld-hairline) !important;',
        '    border-left-color: var(--ld-hairline) !important;',
        '}',
        'html body .category-card.active {',
        '    background-color: var(--ld-surface-hi) !important;',
        '    color: ' + PALETTE.fg + ' !important;',
        '    border-top-color: var(--ld-border) !important;',
        '    border-right-color: var(--ld-border) !important;',
        '    border-bottom-color: var(--ld-border) !important;',
        '    border-left-color: var(--ld-border) !important;',
        '}',
        'html body .training-card {',
        '    background-color: var(--ld-surface) !important;',
        '    border-top-color: var(--ld-hairline) !important;',
        '    border-right-color: var(--ld-hairline) !important;',
        '    border-bottom-color: var(--ld-hairline) !important;',
        '    border-left-color: var(--ld-hairline) !important;',
        '}',
        '/* ★ 环形进度条的底轨:SVG (.liquid-chart 内,共 18 个)。',
        '   fill="#fff" 是「呈现属性」,优先级最低,普通 CSS 即可覆盖(无需 !important,仍加上保险)。',
        '   改成比卡片底(--ld-surface #2a2a2a)浅一档的 --ld-surface-hi(#333333)。 */',
        'html body .liquid-chart circle[fill="#fff"],',
        'html body .liquid-chart circle[fill="#FFF"],',
        'html body .liquid-chart circle[fill="#ffffff"] {',
        '    fill: var(--ld-surface-hi) !important;',
        '}',
        'html body .training-card .card-title,',
        'html body .category-card .card-title {',
        '    color: ' + PALETTE.fg + ' !important;',
        '}',
        'html body .training-card .card-desc,',
        'html body .category-card .card-desc,',
        'html body .training-card span,',
        'html body .category-card span {',
        '    color: var(--ld-fg-muted) !important;',
        '}',
        'html body main.main h1.title,',
        'html body .ticket-banner h1,',
        'html body .ticket-banner .title {',
        '    color: ' + PALETTE.fg + ' !important;',
        '}',
        '/* 分割线:只改 border-top-color,不动宽度 */',
        'html body main.main hr,',
        'html body .l-card hr {',
        '    border-top-color: var(--ld-hairline) !important;',
        '    border-bottom-color: var(--ld-hairline) !important;',
        '}',
        'html body .l-card .upload-card {',
        '    background-color: var(--ld-surface) !important;',
        '    border-top-color: var(--ld-hairline) !important;',
        '    border-right-color: var(--ld-hairline) !important;',
        '    border-bottom-color: var(--ld-hairline) !important;',
        '    border-left-color: var(--ld-hairline) !important;',
        '    color: var(--ld-fg-muted) !important;',
        '}',
        ':is(html) body .l-card .btn-actions a.solid:hover,',
        ':is(html) body .l-card .btn-actions button.solid:hover,',
        ':is(html) body .l-card .right a.solid.l-button:hover,',
        ':is(html) body .l-card .right button.solid:hover {',
        '    background-color: rgba(255, 255, 255, 0.1) !important;',
        '    color: ' + PALETTE.fg + ' !important;',
        '    border-color: rgba(255, 255, 255, 0.9) !important;',
        '}',

        '/* ========== 内联式表单控件 ========== */',
        '.l-card .combo-wrapper,',
        '.l-card .combo-wrapper.combo,',
        '.l-card .combo-wrapper.form-item,',
        '.l-card .combo-wrapper.form-item.block-item.combo,',
        '.l-card.burger .combo-wrapper.lang-select,',
        '.l-card.burger .combo-wrapper.light-black {',
        '    background-color: var(--ld-surface) !important;',
        '    border: 1px solid var(--ld-border) !important;',
        '    color: var(--ld-fg) !important;',
        '}',
        '.l-card .combo-wrapper .text, .l-card .combo-wrapper .text *:not([class*="lcolor"]):not([style*="color"]),',
        '.l-card .combo-wrapper input, .l-card .combo-wrapper input[type="text"],',
        '.l-card .combo-wrapper .text input,',
        '.l-card.burger .combo-wrapper .text {',
        '    background-color: transparent !important;',
        '    color: var(--ld-fg) !important;',
        '    border-style: none !important;',
        '    box-shadow: none !important;',
        '}',
        '.l-card .combo-wrapper .placeholder, .l-card input.search-text::placeholder,',
        '.l-card .refined-input input::placeholder { color: var(--ld-fg-faint) !important; }',
        '.l-card .combo-wrapper .arrow svg,',
        '.l-card .refined-input .east, .l-card .refined-input .search-icon,',
        '.l-card .refined-input .west, .l-card .refined-input .west svg { color: var(--ld-fg-soft) !important; }',
        '.l-card .combo-wrapper .ruler { background-color: transparent !important; border-color: var(--ld-border) !important; }',

        '/* 关键词 / 搜索框:外层浅底 + 内层完全透明,避免深色圆角套娃 */',
        '.l-card .refined-input, .l-card .refined-input.search-text {',
        '    background: rgba(255, 255, 255, 0.06) !important;',
        '    border: 1px solid var(--ld-hairline) !important;',
        '    border-radius: 4px !important;',
        '    box-shadow: none !important;',
        '    color: var(--ld-fg) !important;',
        '}',
        '.l-card .refined-input > *, .l-card .refined-input * { background: transparent !important; }',
        '.l-card .refined-input input, .l-card .refined-input input.search-text,',
        '.l-card input.search-text, .l-card input.scoreboard-search,',
        '.l-card .refined-input.scoreboard-search input,',
        '.l-card input[placeholder*="UID"], .l-card input[placeholder*="用户名"],',
        '.l-card input[placeholder*="关键词"], .l-card input[placeholder*="搜索"],',
        '.l-card .tag-select-area .search-box input {',
        '    background: transparent !important;',
        '    border: none !important;',
        '    border-radius: 0 !important;',
        '    box-shadow: none !important;',
        '    outline: none !important;',
        '    color: var(--ld-fg) !important;',
        '}',
        '.l-card .refined-input.scoreboard-search {',
        '    background: rgba(255, 255, 255, 0.06) !important;',
        '    border: 1px solid var(--ld-hairline) !important;',
        '    border-radius: 4px !important;',
        '    box-shadow: none !important;',
        '}',
        '.l-card input[placeholder*="UID"]::placeholder,',
        '.l-card input[placeholder*="用户名"]::placeholder,',
        '.l-card input[placeholder*="关键词"]::placeholder,',
        '.l-card input[placeholder*="搜索"]::placeholder,',
        '.l-card .refined-input.scoreboard-search input::placeholder { color: var(--ld-fg-muted) !important; }',

        '.l-card button.tag-button:not(.selected), .l-card .toggle-tag:not(.selected),',
        '.l-card .tag-select-area .toggle-tag:not(.selected) {',
        '    background-color: var(--ld-surface) !important;',
        '    background-image: none !important;',
        '    border-color: var(--ld-border) !important;',
        '    border-style: solid !important;',
        '    border-width: 1px !important;',
        '    color: var(--ld-fg-soft) !important;',
        '}',
        '.l-card button.tag-button:not(.selected):hover, .l-card .toggle-tag:not(.selected):hover {',
        '    background-color: var(--ld-surface-hi) !important;',
        '    border-color: var(--ld-border-hi) !important;',
        '    color: var(--ld-fg) !important;',
        '}',
        '/* 已选中的语义色 chip:不给它换色,悬浮只整体压暗一档(保留色相) */',
        '.l-card .toggle-tag.selected:hover { filter: brightness(0.9) !important; }',
        ':is(html) body .l-card .tag:not(:has(*)):not([style*="background-color"]):hover,',
        ':is(html) body .l-card [class*="tag"]:not(:has(*)):not([style*="background-color"]):hover,',
        ':is(html) body .l-card button.tag-button:not(.selected):hover,',
        ':is(html) body .l-card .toggle-tag:not(.selected):hover {',
        '    background-color: var(--ld-panel) !important;',
        '    color: ' + PALETTE.fg + ' !important;',
        '}',
        ':is(html) body .l-card .tag[style*="background-color"]:not(:has(*)):hover,',
        ':is(html) body .l-card .tag[style*="background-color"]:not(:has(*)):active,',
        ':is(html) body .l-card [class*="tag"][style*="background-color"]:not(:has(*)):hover,',
        ':is(html) body .l-card [class*="tag"][style*="background-color"]:not(:has(*)):active {',
        '    filter: brightness(0.85) !important;',
        '}',
        '.l-card .search-option label, .l-card .search-option svg { color: var(--ld-fg-soft) !important; }',
        '.l-card .tag-select-area .title { color: var(--ld-fg-heading) !important; }',
        '.l-card .lfe-marked h1, .l-card .lfe-marked h2, .l-card .lfe-marked h3 { color: var(--ld-fg-heading) !important; }',
        '.l-card .lfe-marked blockquote {',
        '    /* ★ 卡片 alpha × 70%,半透明略深,不是死黑实色 */',
        '    background: var(--ld-quote) !important;',
        '    border-left: 4px solid rgba(255, 255, 255, 0.2) !important;',
        '    color: var(--ld-fg-soft) !important;',
        '    padding: 0.5em 1em !important;',
        '    margin: 1em 0 !important;',
        '}'
    ].join('\n'));

    /* ---------- 4.8 页内 tab / 菜单 ------------------------------------------- */
    CSS_PARTS.push([
        '/* ========== 页内 tab / 菜单 ========== */',
        '.l-card .menu .entry, .l-card .menu .items li .entry,',
        '.l-card .rank-tabs a, .l-card .rank-tabs span { color: var(--ld-fg-soft) !important; }',
        '.l-card .menu .entry.selected, .l-card .menu .items li .entry.selected,',
        '.l-card .rank-tabs a.active, .l-card .rank-tabs .selected,',
        '.l-card .scoreboard-header nav li.selected { color: var(--ld-primary) !important; }'
    ].join('\n'));

    /* ---------- 4.9 浮层:下拉 / Popper / 弹窗 -------------------------------- */
    CSS_PARTS.push([
        '/* =========================================================',
        '   ★★★ 下拉框、语言切换等浮层:必须用不透明底色,',
        '        半透明会让下面的正文透上来,可读性直接崩掉',
        '   ========================================================= */',
        'html ' + SEL_POPOVER + ' {',
        '    /* ★ 只用 background-color 长写:background 简写会重置 background-image,',
        '       把 popover 里的封面图(内联 background-image)一并清成 none。 */',
        '    background-color: var(--ld-surface) !important;',
        '    border: 1px solid var(--ld-border) !important;',
        '    border-radius: 4px !important;',
        '    box-shadow: 0 4px 12px var(--ld-shadow-deep) !important;',
        '    color: var(--ld-code) !important;',
        '}',
        'html body [class*="lang-select"], html body [class*="language-select"],',
        'html body .l-card.burger .combo-wrapper.lang-select,',
        'html body .dropdown.shown:has(.dropdown-operations) {',
        '    /* ★ 同样改长写,避免简写重置 background-image(同类隐患统一处理) */',
        '    background-color: var(--ld-code-bg) !important;',
        '}',
        'html body .dropdown ul, html body .v-popper__popper ul,',
        'html body .v-popper__inner ul, html body .v-popper--theme-dropdown ul,',
        'html body [class*="lang-select"] ul, html body [class*="dropdown"] ul,',
        'html body .lfe-dropdown ul { background: transparent !important; }',
        'html body .dropdown li, html body .dropdown a, html body .dropdown div,',
        'html body .v-popper__popper li, html body .v-popper__popper a, html body .v-popper__popper div,',
        'html body .v-popper__inner li, html body .v-popper__inner a, html body .v-popper__inner div,',
        'html body .v-popper--theme-dropdown li, html body .v-popper--theme-dropdown a,',
        'html body .v-popper--theme-dropdown div,',
        'html body [class*="lang-select"] li, html body [class*="lang-select"] a,',
        'html body [class*="dropdown"] li, html body [class*="dropdown"] a,',
        'html body .lfe-dropdown li, html body .lfe-dropdown a {',
        '    color: ' + PALETTE.code + ' !important;',
        '    /* ★ 长写:简写 background 会把 popover 内 div 的 background-image 清成 none */',
        '    background-color: transparent !important;',
        '}',
        'html body .dropdown li:hover, html body .dropdown a:hover,',
        'html body .v-popper__popper li:hover, html body .v-popper__popper a:hover,',
        'html body .v-popper__inner li:hover, html body .v-popper__inner a:hover,',
        'html body .v-popper--theme-dropdown li:hover, html body .v-popper--theme-dropdown a:hover,',
        'html body [class*="lang-select"] li:hover,',
        'html body [class*="dropdown"] li:hover, html body [class*="dropdown"] a:hover,',
        'html body .lfe-dropdown li:hover, html body .lfe-dropdown a:hover {',
        '    background-color: #3a3a3a !important;',
        '    color: var(--ld-fg) !important;',
        '}',
        'html body .v-popper__arrow-container .v-popper__arrow-inner,',
        'html body .v-popper__arrow-container .v-popper__arrow-outer {',
        '    border-color: var(--ld-surface) !important;',
        '    background: var(--ld-surface) !important;',
        '}',

        '.swal2-popup:not(:has(.swal2-image)),',
        '.swal2-popup.swal2-toast,',
        '.swal2-popup:has(.swal2-title):not([style*="transparent"]) {',
        '    background-color: var(--ld-surface-deep) !important;',
        '    color: var(--ld-fg) !important;',
        '    border: 1px solid rgba(255, 255, 255, 0.1) !important;',
        '    box-shadow: 0 4px 20px var(--ld-shadow-deep) !important;',
        '}',
        '.swal2-title { color: var(--ld-fg) !important; }',
        '.swal2-html-container { color: ' + PALETTE.code + ' !important; }',
        '.swal2-success-circular-line-left, .swal2-success-circular-line-right,',
        '.swal2-success-fix { background-color: var(--ld-surface-deep) !important; }',
        '.swal2-icon.swal2-success { border-color: var(--ld-success) !important; color: var(--ld-success) !important; }',
        '.swal2-icon.swal2-success [class^=swal2-success-line] { background-color: var(--ld-success) !important; }',
        '.swal2-icon.swal2-success .swal2-success-ring { border: 4px solid rgba(165, 220, 134, 0.3) !important; }',
        '.swal2-styled.swal2-confirm { background-color: var(--ld-primary) !important; }',
        '.swal2-styled.swal2-cancel { background-color: var(--ld-surface-hi) !important; color: var(--ld-fg) !important; }',

        '/* 通用模态框 / 遮罩 */',
        '.lfe-modal .lfe-modal-body, .lfe-modal .lfe-modal-content, .lfe-dialog,',
        '.modal .modal-content, .modal-content, .popup-content {',
        '    background: var(--ld-surface) !important;',
        '    color: var(--ld-fg) !important;',
        '    border: 1px solid var(--ld-hairline) !important;',
        '}',
        '.lfe-modal .lfe-modal-header, .lfe-modal .lfe-modal-footer {',
        '    background: transparent !important;',
        '    border-color: var(--ld-hairline) !important;',
        '    color: var(--ld-fg) !important;',
        '}'
    ].join('\n'));

    /* ---------- 4.10 页脚、列表、分页、进度 ---------------------------------- */
    CSS_PARTS.push([
        '/* ========== 页脚链接悬停 ========== */',
        'footer a:hover { color: var(--ld-link-hover) !important; }',

        '/* ========== 列表 / 表格骨架 ========== */',
        '.l-card .list-wrap, .l-card .list-wrap.table, .l-card .list-wrap.table.border,',
        '.l-card .table, .l-card .table.border {',
        '    background: transparent !important;',
        '    border-color: var(--ld-hairline) !important;',
        '}',
        '.l-card .list .header-wrap, .l-card .list .header,',
        '.l-card .list-wrap .header-wrap, .l-card .list-wrap .header,',
        '.l-card .table .header-wrap, .l-card .table .header {',
        '    background: transparent !important;',
        '    border: none !important;',
        '    box-shadow: none !important;',
        '}',
        '.l-card .header-container, .l-card .header-container .sortable,',
        '.l-card .header-container span, .l-card .table .header-container .sortable { color: var(--ld-fg-soft) !important; }',
        '.l-card .table .header-container .lfe-caption { color: var(--ld-fg-muted) !important; }',
        '.l-card .list-wrap .row-wrap, .l-card .list-wrap .row,',
        '.l-card .table .row-wrap, .l-card .table .row {',
        '    background: transparent !important;',
        '    border-color: var(--ld-hairline-soft) !important;',
        '}',
        '/* ★ 行 hover 不再在这里统一给背景:表格页保留,列表页完全交给站点原生悬停 */',
        '.l-card .table .row:hover { background: rgba(255, 255, 255, 0.06) !important; }',
        '/* ★ .list-wrap:not(.table):记录列表容器是 `.list-wrap.table`(同时带两个类),',
        '   若不加 :not(.table),这条透明规则会以「同特异性、源码更靠后」压掉上面',
        '   `.l-card .table .row:hover` 的浅色高亮,导致评测记录行 hover 时背景变空。 */',
        '.l-card .list-wrap:not(.table) .row:hover,',
        '.l-card.solution-list .row:hover, .l-card.solution-list .row-wrap:hover,',
        '.l-card .solution-list .row:hover, .l-card .solution-list .row-wrap:hover {',
        '    background: transparent !important;',
        '    background-color: transparent !important;',
        '}',
        '.l-card .row .pid, .l-card .table .row .rank, .l-card .table .row .user,',
        '.l-card .table .row .total { color: var(--ld-fg-soft) !important; }',
        '.l-card .table .row [class*="time"], .l-card .table .row .light-text,',
        '.l-card .table .row .secondary, .l-card .table .row .total .td-runtime { color: var(--ld-fg-muted) !important; }',
        '/* ★ 分数 span 必须排除语义色类 .lcolor--*:站点用 .lcolor--green-3 / red-3 / orange-3',
        '   给分数上 AC/WA 语义色,被这条白字规则命中就全变白(丢失绿/红语义)。',
        '   收窄后站点自己的 .lcolor--* 规则自然生效 —— 零硬编码,站点换色自动跟随。',
        '   容器(.status / .score / .full-score / .total .td-score)不排除,保持 var(--ld-fg)。 */',
        '.l-card .table .row .status, .l-card .table .row .status span:not([class*="lcolor"]),',
        '.l-card .table .row .score:not([class*="lcolor"]), .l-card .table .row .score span:not([class*="lcolor"]),',
        '.l-card .table .row .full-score, .l-card .table .row .full-score *,',
        '.l-card .table .row [class*="full-score"],',
        '.l-card .table .row .total .td-score { color: var(--ld-fg) !important; }',

        '/* ========== 进度框 ========== */',
        '.l-card .progress-frame {',
        '    background: rgba(0, 0, 0, 0.5) !important;',
        '    border: 1px solid rgba(255, 255, 255, 0.25) !important;',
        '    box-shadow: none !important;',
        '    box-sizing: border-box !important;',
        '    padding: 0 !important;',
        '}',
        '.l-card .progress-frame > .square { border: none !important; margin: 0 !important; }',

        '/* ========== 底部工具条 / 分页 ========== */',
        '.l-card .bottom-wrap, .l-card .toolbar {',
        '    background: transparent !important;',
        '    border-color: var(--ld-hairline) !important;',
        '}',
        '.l-card .bottom-wrap.float {',
        '    background: #383838 !important;',
        '    border-top: 1px solid rgba(255, 255, 255, 0.1) !important;',
        '    box-shadow: 0 -4px 12px rgba(0, 0, 0, 0.35) !important;',
        '}',
        '.l-card .toolbar .btn-checkbox { color: var(--ld-link) !important; }',
        '.l-card .page-bar .total strong { color: var(--ld-fg) !important; }',
        '.l-card .page-bar button {',
        '    background: transparent !important;',
        '    border: 1px solid rgba(255, 255, 255, 0.15) !important;',
        '    color: var(--ld-fg-soft) !important;',
        '}',
        '.l-card .page-bar button:hover { border-color: rgba(255, 255, 255, 0.4) !important; color: var(--ld-fg) !important; }',
        '.l-card .page-bar button.selected {',
        '    background: var(--ld-primary) !important;',
        '    border-color: var(--ld-primary) !important;',
        '    color: var(--ld-fg) !important;',
        '}',
        '.l-card .selected-tags .lfe-caption { color: var(--ld-fg-muted) !important; }'
    ].join('\n'));

    /* ---------- 4.10b 比赛列表页(contest/list)------------------------------ */
    CSS_PARTS.push([
        '/* =========================================================',
        '   比赛列表页(原脚本没覆盖这块)',
        '   ========================================================= */',
        '/* ★ 结果计数 .filter-result-count .number 是站点内联色 rgba(0,0,0,0.75)',
        '   (黑字配白底),在深色卡上几乎不可见,纠正为跟随卡片文字色。',
        '   只改计数本身,不动旁边作者名的等级色。 */',
        '.l-card .filter-result-count,',
        '.l-card .filter-result-count .number,',
        '.l-card .result .count .number,',
        '.l-card .row .number, .l-card .list-wrap .row .number {',
        '    color: var(--ld-fg-soft) !important;',
        '}',
        '.l-card .filter-result-count a, .l-card .filter-result-count strong {',
        '    color: var(--ld-fg) !important;',
        '}',
        '.l-card .row .name, .l-card .list-wrap .row .name,',
        '.l-card .row .provider-display, .l-card .list-wrap .row .provider-display,',
        '.l-card .row .provider, .l-card .list-wrap .row .provider {',
        '    color: var(--ld-fg-soft) !important;',
        '}',
        '.l-card .row .icon-status:not([style*="color"]),',
        '.l-card .list-wrap .row .icon-status:not([style*="color"]) {',
        '    color: var(--ld-fg-muted) !important;',
        '}',
        '/* 比赛类型标签保留站点本身的色底,只保证文字可读 */',
        '.l-card .row .tag, .l-card .list-wrap .row .tag { color: var(--ld-fg) !important; }',
        '/* ★★★ 比赛列表页的筛选卡片(.l-card.filter-card):',
        '   未选中态原来是 rgb(87,87,87) + 透明底,在深色卡上对比度 1.02,整排隐形。',
        '   现在改成与「题目列表页 主题库/洛谷/CF/AT 选项卡」同一套设计:',
        '   未选中 = 主题蓝文字 + 主题蓝边框 + 透明底 + 3px 圆角 + 1px 8px 内边距;',
        '   选中 = 主题蓝实底 + 白字。站点样式带 data-v-* 作用域,所以用 html body 压特异性。 */',
        'html body .l-card.filter-card button.option,',
        'html body .l-card.filter-card .l-options button.option,',
        'html body .l-card.filter-card button[class~="option"],',
        'html body .l-card button.option {',
        '    background: transparent !important;',
        '    background-color: transparent !important;',
        '    border: none !important;',
        '    /* ★ 未选中字色对齐题目列表页:白字(原为 var(--ld-primary) 蓝字) */',
        '    color: ' + PALETTE.fg + ' !important;',
        '    border-radius: 3px !important;',
        '    padding: 1px 8px !important;',
        '    /* 与题目列表「主题库/洛谷/CF/AT」选项卡逐项对齐。',
        '       注意 display 不设:contest 的父级 .l-options 是 flex,flex 子项必然 blockify,',
        '       覆盖 display 也无效,且会造成两页无意义的差异。 */',
        '    font-size: 16px !important;',
        '    font-weight: 400 !important;',
        '    line-height: 24px !important;',
        '    margin: 0 8px 0 0 !important;',
        '    cursor: pointer !important;',
        '    transition: 0.3s !important;',
        '}',
        'html body .l-card.filter-card button.option:hover,',
        'html body .l-card button.option:hover {',
        '    /* ★ hover:极淡白底,不加边框、不改字色(字已是白色) */',
        '    background: rgba(255, 255, 255, 0.12) !important;',
        '    background-color: rgba(255, 255, 255, 0.12) !important;',
        '    border: none !important;',
        '    color: ' + PALETTE.fg + ' !important;',
        '    cursor: pointer !important;',
        '}',
        '/* 选中态:主题蓝实底 + 白字(与题目列表选项卡一致,无边框、cursor default) */',
        'html body .l-card.filter-card button.option.active,',
        'html body .l-card.filter-card button.option.selected,',
        'html body .l-card button.option.active,',
        'html body .l-card button.option.selected {',
        '    background: var(--ld-primary) !important;',
        '    background-color: var(--ld-primary) !important;',
        '    border: none !important;',
        '    color: ' + PALETTE.fg + ' !important;',
        '    cursor: default !important;',
        '}',
        '/* 卡片内部的 .row 子容器(.title-row / .left.row / .right.row / .info-row)始终保持透明 */',
        'html body .l-card .row .row:hover,',
        'html body .l-card .row .row,',
        'html body .l-card [class*="title-row"]:hover,',
        'html body .l-card [class*="info-row"]:hover {',
        '    background: transparent !important;',
        '    background-color: transparent !important;',
        '}',
        'html body .l-card .row .name:hover, html body .l-card .row .title:hover,',
        'html body .l-card .row time:hover, html body .l-card .row .time:hover,',
        'html body .l-card .row [class*="time"]:hover,',
        'html body .l-card .row .provider-display:hover,',
        'html body .l-card .row a:not(.l-button):not(.solid):not([class*="button"]):not([style*="background-color"]):hover,',
        'html body .l-card .row span:not(.l-button):not(.solid):not([class*="button"]):not([style*="background-color"]):hover,',
        'html body .l-card .list-wrap .row .name:hover,',
        'html body .l-card .list-wrap .row [class*="time"]:hover,',
        'html body .l-card .list-wrap .row a:not(.l-button):not(.solid):not([class*="button"]):not([style*="background-color"]):hover {',
        '    background: transparent !important;',
        '    background-color: transparent !important;',
        '    box-shadow: none !important;',
        '}',
        '/* 子元素自身的底色也清掉,避免出现「框里还有框」 */',
        'html body .l-card .row .name, html body .l-card .row .title,',
        'html body .l-card .row time, html body .l-card .row [class*="time"],',
        'html body .l-card .list-wrap .row .name, html body .l-card .list-wrap .row [class*="time"] {',
        '    background: transparent !important;',
        '    background-color: transparent !important;',
        '}',
        '/* 筛选卡的标签文字(比赛分类 / 比赛赛制) */',
        'html body .l-card.filter-card .filter-label, html body .l-card.filter .filter-label {',
        '    color: var(--ld-fg-muted) !important;',
        '}',
        '/* 筛选卡里可能出现的下拉框 / 复选项也一并跟随 */',
        'html body .l-card.filter-card .combo-wrapper { background: ' + PALETTE.surface + ' !important; }',
        '/* 列表头 / 分页 / 筛选沿用统一骨架,这里只补比赛页特有的容器 */',
        '.l-card .row .name a, .l-card .list-wrap .row .name a { color: var(--ld-link) !important; }',
        '.l-card .row .name a:hover, .l-card .list-wrap .row .name a:hover { color: var(--ld-link-hover) !important; }'
    ].join('\n'));

    /* ---------- 4.11 题目列表页 ---------------------------------------------- */
    CSS_PARTS.push([
        '/* =========================================================',
        '   题目列表页',
        '   ========================================================= */',
        '.l-card section .title { color: var(--ld-fg-heading) !important; }',
        '.l-card .block-item.category ul,',
        '.l-card .block-item.category ul.luogu,',
        '.l-card .block-item.category ul.rmj {',
        '    background: transparent !important;',
        '    border: none !important;',
        '    box-shadow: none !important;',
        '    padding: 0 !important;',
        '}',
        '.l-card .block-item.category ul li {',
        '    background: transparent !important;',
        '    border: none !important;',
        '    color: var(--ld-fg) !important;',
        '    opacity: 1 !important;',
        '}',
        '.l-card .block-item.category ul li:hover {',
        '    background: rgba(255, 255, 255, 0.1) !important;',
        '    color: var(--ld-fg) !important;',
        '}',
        '.l-card .block-item.category ul li.selected {',
        '    background: var(--ld-primary) !important;',
        '    color: var(--ld-fg) !important;',
        '    opacity: 1 !important;',
        '    border-radius: 3px !important;',
        '}',
        '.l-card .result .count .number { color: var(--ld-fg) !important; font-weight: bold !important; }',

        '/* ★ 最优解高亮:只对带 green-1 背景的 .problem 生效 */',
        '.l-card .table .row .problem[style*="green-1"],',
        '.l-card .table .row [style*="--lfe-color--green-1"] {',
        '    background-color: rgba(83, 196, 26, 0.12) !important;',
        '}',
        '/* 当前用户高亮的纠偏放在常驻样式表里(见 CSS_FIXES),关闭深色后也要生效 */'
    ].join('\n'));

    /* ---------- 4.12 题解页 ------------------------------------------------- */
    CSS_PARTS.push([
        '/* =========================================================',
        '   题解页面',
        '   ========================================================= */',
        '/* ★ 取消鼠标悬停在题解上的整个文本框亮起效果(规则已在 4.10 统一定义,此处不重复) */',
        '.l-card.solution-list .header nav ul li { color: var(--ld-fg-soft) !important; }',
        '.l-card.solution-list .header nav ul li.selected { color: var(--ld-primary) !important; }',
        '.l-card.solution-list .header b { color: var(--ld-fg) !important; }',
        '.l-card.solution-list .lfe-caption, .l-card.solution-list .lfe-caption time { color: var(--ld-fg-muted) !important; }',

        '/* ★ 题解底部吸附操作栏 */',
        '.l-card .float.operations {',
        '    background: var(--ld-surface-deep) !important;',
        '    border-top: 1px solid rgba(255, 255, 255, 0.15) !important;',
        '    box-shadow: 0 -4px 12px var(--ld-shadow-deep) !important;',
        '    padding: 10px 16px !important;',
        '    z-index: 100 !important;',
        '}',
        '.l-card .float.operations .button { color: var(--ld-fg-soft) !important; fill: var(--ld-fg-soft) !important; }',
        '.l-card .float.operations .button:hover { color: var(--ld-fg) !important; fill: var(--ld-fg) !important; }',
        '.l-card .float.operations .thumb-up.active,',
        '.l-card .float.operations .thumb-up.voted,',
        '.l-card .float.operations .thumb-up.enable,',
        '.l-card .operations .thumb-up.active, .l-card .operations .thumb-up.voted,',
        '.l-card .operations .thumb-up.enable { color: var(--ld-primary) !important; fill: var(--ld-primary) !important; }',
        '.l-card .float.operations .thumb-up.active:hover,',
        '.l-card .float.operations .thumb-up.voted:hover,',
        '.l-card .float.operations .thumb-up.enable:hover { color: var(--ld-primary-soft) !important; fill: var(--ld-primary-soft) !important; }',

        '/* ★ 题解 / 文章正文:文字全部白色。',
        '   注意实际类名是 .lfe-marked-wrap,不能只写 .lfe-marked;',
        '   :not([style*="color"]) 用来放行用户名/等级标识的内联色。 */',
        '.l-card .lfe-marked, .l-card .lfe-marked-wrap, .l-card .marked,',
        '.l-card .lfe-marked p, .l-card .lfe-marked-wrap p, .l-card .marked p,',
        '.l-card .lfe-marked li, .l-card .lfe-marked-wrap li, .l-card .marked li,',
        '.l-card .lfe-marked strong, .l-card .lfe-marked-wrap strong,',
        '.l-card .lfe-marked em, .l-card .lfe-marked-wrap em,',
        '.l-card .lfe-marked td, .l-card .lfe-marked-wrap td,',
        '.l-card .lfe-marked th, .l-card .lfe-marked-wrap th,',
        '.l-card .lfe-marked h1, .l-card .lfe-marked h2, .l-card .lfe-marked h3,',
        '.l-card .lfe-marked h4, .l-card .lfe-marked h5, .l-card .lfe-marked h6,',
        '.l-card .lfe-marked-wrap h1, .l-card .lfe-marked-wrap h2, .l-card .lfe-marked-wrap h3,',
        '.l-card .solution-article, .l-card .article-content, .l-card .markdown-body {',
        '    color: ' + PALETTE.fg + ' !important;',
        '}',
        'html body main.main > div:not([class]):has(> .article-content) {',
        '    background-color: var(--ld-card) !important;',
        '}',
        '/* =========================================================',
        '   文章页(/article/*)专项:这些元素全都在 .l-card 之外,',
        '   所以脚本里那批 `.l-card …` 规则一律够不着,必须用 main.main 作用域。',
        '   ========================================================= */',
        '/* ① 文章页不可读文字 → 浅色(实测均为站点浅色主题的深字) */',
        'html body main.main .article-banner h1.title {',
        '    color: ' + PALETTE.fg + ' !important;',
        '}',
        'html body main.main .article-banner .label {',
        '    color: var(--ld-fg-muted) !important;',
        '}',
        'html body main.main .article-banner .label + * {',
        '    color: ' + PALETTE.fg + ' !important;',
        '}',
        'html body main.main .article-comment h3.lfe-h3.section-title,',
        'html body main.main .article-comment h4.lfe-h4 {',
        '    color: ' + PALETTE.fg + ' !important;',
        '}',
        'html body main.main .comment-filter-line > span {',
        '    color: var(--ld-fg-muted) !important;',
        '}',
        'html body main.main .article-content .actions {',
        '    background-color: transparent !important;',
        '}',
        'html body .l-card.reply-item .meta {',
        '    background-color: var(--ld-panel) !important;',
        '}',
        '/* ★ 评论/回复里的「回复于 xxx」时间文字:站点原值 rgba(0,0,0,0.5)(浅色主题的',
        '   半透明黑),落在深色底上几乎不可见,而脚本从未覆盖它。',
        '   用 .time 类(不是 time 标签)统一修 —— 横幅里「发布时间」的值是裸