// ==UserScript== // @name 【伟哥自用】ZeroClaw 文档 强制浅色(去黑底刺眼主题) // @namespace user/zeroclaw // @version 1.0.0 // @description docs.zeroclawlabs.ai 是 mdBook 套了一层自研 pc-* 主题,默认 default-dark(近黑底 + 刺眼青/紫字)。本脚本只用 GM_addStyle 注入 CSS,把暗色变量盖成浅色——不动 html 的主题 class、不用 observer(实测这站是整页跳转,userscript 每次加载都会重跑,无需重注入)。配色直接照搬站点自带的 default-light 调色板,所以代码高亮、侧栏、搜索、表格、引用块、mermaid 图会全部跟着变量自动变浅,零生硬硬编码。 // @author 朱焱伟 // @match https://docs.zeroclawlabs.ai/* // @run-at document-start // @grant GM_addStyle // ==/UserScript== (function () { 'use strict'; /* ============ 配置:想换点缀色改这里 ============ */ // 点缀色(链接、行内代码、侧栏激活项、mermaid 主色等)。默认 #0891b2 = 站点自带 // default-light 的原色,所以默认就是 100% 原生观感。想换别的色直接改这一行,例如: // 蓝 '#2563eb' / 靛 '#4f46e5' / 紫 '#7c3aed' / 绿 '#16a34a' // 改后下方会自动派生出 accent-light / links / 边框光晕等一整套配色。 const BRAND = '#0891b2'; const NATIVE = '#0891b2'; // 与站点 default-light 一致;等于此值时跳过派生、用原生字面量 /* ============================================== */ function shade(hex, amt) { // amt > 0 提亮, < 0 加深 let h = hex.replace('#', ''); if (h.length === 3) h = h.split('').map(c => c + c).join(''); const n = parseInt(h, 16); let r = (n >> 16) & 255, g = (n >> 8) & 255, b = n & 255; const f = v => Math.max(0, Math.min(255, Math.round(amt >= 0 ? v + (255 - v) * amt : v * (1 + amt)))); return '#' + [f(r), f(g), f(b)].map(v => v.toString(16).padStart(2, '0')).join(''); } function rgba(hex, a) { let h = hex.replace('#', ''); if (h.length === 3) h = h.split('').map(c => c + c).join(''); const n = parseInt(h, 16); return `rgba(${(n >> 16) & 255}, ${(n >> 8) & 255}, ${n & 255}, ${a})`; } function triplet(hex) { let h = hex.replace('#', ''); if (h.length === 3) h = h.split('').map(c => c + c).join(''); const n = parseInt(h, 16); return `${(n >> 16) & 255}, ${(n >> 8) & 255}, ${n & 255}`; } // 关键:不摘 html 的 default-dark / *-dark 主题类。用 html:not(#_) 前缀把特异性拉满 // (:not(#_) 计 id 特异性 (1,0,0)),再给每个值挂 !important,稳压 pc-themes.css 里所有 // html.<主题id> { --xxx } 规则(那些规则不带 !important)。这样无论当前落在 40 个主题里的 // 哪一个,都一律被盖成浅色。pc-themes 的变量不带 !important,故本脚本的 !important 必胜。 const X = 'html:not(#_) '; // 这一套值 = 站点 themes.json 里 default-light 的原值(逐字照搬,不是另起一套)。 // custom.css 把 mdBook 原生变量(--bg/--fg/--sidebar-bg/...)和 hljs 代码高亮变量 // (--pc-hl-*)都用 var() 桥接到了 --pc-* 上,所以这里改完,整页连代码块一起自动变浅。 const css = ` ${X}{ --color-scheme: light !important; --pc-bg-base: #f4f4f5 !important; --pc-bg-surface: #ffffff !important; --pc-bg-elevated: #e4e4e7 !important; --pc-bg-input: #ffffff !important; --pc-bg-code: #f4f4f5 !important; --pc-bg-sidebar: #fffffff2 !important; --pc-text-primary: #18181b !important; --pc-text-secondary: #3f3f46 !important; --pc-text-muted: #71717a !important; --pc-text-faint: #a1a1aa !important; --pc-accent: #0891b2 !important; --pc-accent-light: #06b6d4 !important; --pc-accent-dim: rgba(8,145,178,.25) !important; --pc-accent-glow: rgba(8,145,178,.08) !important; --pc-accent-rgb: 8,145,178 !important; --pc-border: rgba(0,0,0,.08) !important; --pc-border-strong: rgba(0,0,0,.12) !important; --pc-hover: rgba(0,0,0,.04) !important; --pc-hover-strong: rgba(0,0,0,.07) !important; --pc-separator: rgba(0,0,0,.06) !important; --pc-scrollbar-thumb: #a1a1aa !important; --pc-scrollbar-thumb-hover: #71717a !important; --pc-scrollbar-track: #e4e4e7 !important; --bg: #f4f4f5 !important; --fg: #18181b !important; --sidebar-bg: #fffffff2 !important; --sidebar-fg: #3f3f46 !important; --sidebar-non-existant: #a1a1aa !important; --sidebar-active: #0891b2 !important; --sidebar-spacer: rgba(0,0,0,.06) !important; --scrollbar: #a1a1aa !important; --icons: #71717a !important; --icons-hover: #0891b2 !important; --links: #06b6d4 !important; --inline-code-color: #06b6d4 !important; --theme-popup-bg: #e4e4e7 !important; --theme-popup-border: rgba(0,0,0,.12) !important; --theme-hover: rgba(0,0,0,.07) !important; --quote-bg: #ffffff !important; --quote-border: rgba(8,145,178,.25) !important; --table-border-color: rgba(0,0,0,.08) !important; --table-header-bg: #e4e4e7 !important; --table-alternate-bg: #ffffff !important; --searchbar-border-color: rgba(0,0,0,.12) !important; --searchbar-bg: #ffffff !important; --searchbar-fg: #18181b !important; --searchbar-shadow-color: rgba(8,145,178,.25) !important; --searchresults-header-fg: #71717a !important; --searchresults-border-color: rgba(0,0,0,.08) !important; --searchresults-li-bg: #e4e4e7 !important; --search-mark-bg: rgba(8,145,178,.25) !important; color-scheme: light !important; } `; // 若改了 BRAND,再追加一条规则覆盖点缀色家族(accent / links / 行内代码 / 光晕 / 边框)。 // 默认 BRAND === NATIVE 时这块不生成,保持 100% 原生 default-light 观感。 let brandCss = ''; if (BRAND.trim().toLowerCase() !== NATIVE.toLowerCase()) { const light = shade(BRAND, 0.16); brandCss = ` ${X}{ --pc-accent: ${BRAND} !important; --pc-accent-light: ${light} !important; --pc-accent-rgb: ${triplet(BRAND)} !important; --pc-accent-dim: ${rgba(BRAND, .25)} !important; --pc-accent-glow: ${rgba(BRAND, .08)} !important; --sidebar-active: ${BRAND} !important; --icons-hover: ${BRAND} !important; --links: ${light} !important; --inline-code-color: ${light} !important; --quote-border: ${rgba(BRAND, .25)} !important; --searchbar-shadow-color: ${rgba(BRAND, .25)} !important; --search-mark-bg: ${rgba(BRAND, .25)} !important; } `; } // 唯一副作用:注入样式。document-start 注入,既避免暗色闪烁,又让 mermaid-init.js // 在初始化时读到 --color-scheme: light(它按这个变量决定图用浅色还是深色调色板)。 const full = css + brandCss; if (typeof GM_addStyle === 'function') { GM_addStyle(full); } else { const apply = () => { const s = document.createElement('style'); s.id = '__zeroclaw_light_theme'; s.textContent = full; (document.head || document.documentElement).appendChild(s); }; if (document.head) apply(); else document.addEventListener('DOMContentLoaded', apply); } })();