// ==UserScript== // @name GitHub Latte // @namespace github-latte-pure-theme // @version 2.2.0 // @description GitHub 浅色护眼主题 // @tag github theme // @author deran // @grant GM_addStyle // @run-at document-start // @license MIT // @match *://*.github.com/* // ==/UserScript== (function () { 'use strict'; /* ========== Catppuccin Latte 官方色板 ========== */ const lattePalette = { rosewater: '#dc8a78', flamingo: '#dd7878', pink: '#ea76cb', mauve: '#8839ef', red: '#d20f39', maroon: '#e64553', peach: '#fe640b', yellow: '#df8e1d', green: '#40a02b', teal: '#179299', sky: '#04a5e5', sapphire: '#209fb5', blue: '#1e66f5', lavender: '#7287fd', text: '#4c4f69', subtext1: '#5c5f77', subtext0: '#6c6f85', overlay2: '#7c7f93', overlay1: '#8c8fa1', overlay0: '#9ca0b0', surface2: '#acb0be', surface1: '#bcc0cc', surface0: '#ccd0da', base: '#eff1f5', mantle: '#e6e9ef', crust: '#dce0e8' }; /* ========== 主题核心配置 ========== */ const theme = { bg: lattePalette.base, text: lattePalette.text, selection: lattePalette.surface2, link: '#203c75', border: lattePalette.crust, inputBg: '#ffffff', codeBg: lattePalette.mantle }; /* ========== 样式注入 ========== */ function injectAllStyles() { GM_addStyle(` /* 1. 页面背景统一 */ html, body, #js-repo-pjax-container, #repo-content-pjax-container, main, .application-main, .repository-content, .pagehead, section, article, aside, nav, header, footer, table, tr, td, th, ul, ol, li, blockquote, figure, figcaption { background-color: ${theme.bg} !important; background-image: none !important; } /* 2. 正文文本颜色(不包含 span,不破坏语法高亮) */ html, body, p, label, legend, caption, h1, h2, h3, h4, h5, h6, li, dd, dt, blockquote, cite, table, tr, td, th, thead, tbody { color: ${theme.text} !important; } /* 3. 文本选中高亮 */ ::selection { background-color: ${theme.selection} !important; color: ${theme.text} !important; } ::-moz-selection { background-color: ${theme.selection} !important; color: ${theme.text} !important; } /* 4. 链接颜色(深绀色) */ a, a:link, a:visited { color: ${theme.link} !important; text-decoration: none; } a:hover, a:active { text-decoration: underline; } /* 5. 表单元素适配 */ input, textarea, select, button { background-color: ${theme.inputBg} !important; color: ${theme.text} !important; border: 1px solid ${theme.border} !important; outline: none; } input:focus, textarea:focus, select:focus { border-color: ${theme.link} !important; } /* 6. 边框柔和化 */ div, section, article, aside, nav, header, footer, table, tr, td, th, input, textarea, select, button, ul, ol, li, pre, blockquote { border-color: ${theme.border} !important; } /* 7. 媒体与原生图标保护 */ img, video, svg, canvas, emoji, picture, source, [class*="icon"], [class*="logo"], [style*="background-image"] { background-color: transparent !important; filter: none !important; } /* 8. 代码块背景强制纯色不透明,杜绝透色重影 */ pre, .blob-code, .blob-num, .react-code-lines, .highlight, .highlight pre, .file-box pre { background-color: ${theme.codeBg} !important; background-image: none !important; opacity: 1 !important; } /* 9. 代码文本渲染优化,消除模糊感 */ pre, code, samp, kbd, .blob-code-inner, .blob-code-content, .react-code-lines, .pl-c, .pl-k, .pl-s, .pl-e { -webkit-font-smoothing: antialiased !important; -moz-osx-font-smoothing: grayscale !important; text-rendering: optimizeLegibility !important; text-shadow: none !important; filter: none !important; opacity: 1 !important; } /* 10. 行号区域单独优化,保持清晰锐利 */ .blob-num, .line-numbers, .gutter { background-color: ${theme.codeBg} !important; -webkit-font-smoothing: antialiased !important; text-shadow: none !important; opacity: 1 !important; } /* 11. 确保代码内联元素背景透明,不叠加色块 */ pre span, code span, .blob-code-inner span, .pl-s, .pl-k, .pl-c, .pl-e, .pl-pds, .pl-en { background-color: transparent !important; background-image: none !important; } /* 12. 功能组件样式保护 */ [class*="btn-"], [class*="Label--"], [class*="StateLabel"], [class*="Counter"], [class*="badge"], [class*="flash-"] { background-color: var(--color-btn-bg, initial) !important; color: var(--color-btn-text, initial) !important; } `); } /* ========== 主入口 ========== */ function init() { injectAllStyles(); } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); } })();