ChatGPT Black-Gold (v3.4.4, black bg + gold text selection + global AI toolbar & header share)

基于 v3.4 的稳定版:用户气泡黑金(短消息也亮);发送/语音/停止按钮黑金;输入框与 AI 消息选中文本=黑底金字;Alt+G 开关。新增:AI 消息下方工具栏(Copy/Like/Dislike/Read/Canvas/Share/Try again)默认黑金,悬停金色高亮;右上 Share 与弹窗 Create link 黑金。严格排除代码块 Copy 与 Canvas 预览 Copy,保持默认。

// ==UserScript==
// @name         ChatGPT Black-Gold (v3.4.4, black bg + gold text selection + global AI toolbar & header share)
// @namespace    lukas.tools
// @version      3.4.4
// @description  基于 v3.4 的稳定版:用户气泡黑金(短消息也亮);发送/语音/停止按钮黑金;输入框与 AI 消息选中文本=黑底金字;Alt+G 开关。新增:AI 消息下方工具栏(Copy/Like/Dislike/Read/Canvas/Share/Try again)默认黑金,悬停金色高亮;右上 Share 与弹窗 Create link 黑金。严格排除代码块 Copy 与 Canvas 预览 Copy,保持默认。
// @license      MIT
// @match        https://chat.openai.com/*
// @match        https://chatgpt.com/*
// @run-at       document-start
// @grant        none
// ==/UserScript==

(function () {
  'use strict';

  /* ======================= CSS ======================= */
  const CSS = `
:root{
  --deep:#07080a;
  --deep2:#0f1013;
  --gold-hi:#ffd95a;    /* 高光金(更黄) */
  --gold:#ffc93a;       /* 正金 */
  --gold-mid:#e9b030;
  --gold-edge:#956a0a;
  --ivory:#fff7e6;      /* 用户气泡内文字更亮 */
  --ivory-2:#f0e6c5;
  --edge:#2a2c31;
}

.chat-bgb-on *{ transition: background-color .15s, color .15s, border-color .15s, box-shadow .15s, opacity .15s; }

/* ===== 按钮:发送 / 语音 / 停止 与 通用工具按钮 ===== */
.chat-bgb-on .bgb-action{
  color:var(--gold-hi) !important;
  background:
    linear-gradient(18deg, rgba(255,232,140,.36) 0%, rgba(255,232,140,0) 14%),
    radial-gradient(120% 160% at 30% -20%, rgba(255,217,90,.42), transparent 58%),
    linear-gradient(180deg, var(--deep2), var(--deep)) !important;
  border:1px solid var(--gold) !important;
  border-radius:9999px !important;
  box-shadow:0 0 0 1px rgba(149,106,10,.35) inset, 0 10px 24px rgba(255,217,90,.18);
}
.chat-bgb-on .bgb-action:hover{
  background:linear-gradient(180deg, var(--gold-hi), var(--gold)) !important;
  color:#151515 !important;
}
.chat-bgb-on .bgb-action svg{ color:inherit !important; fill:currentColor !important; }

/* ===== 仅用户气泡(AI 不改外观) ===== */
.chat-bgb-on .bgb-user{
  position:relative; color:var(--ivory);
  background:
    linear-gradient(16deg, rgba(255,232,140,.22) 0%, rgba(255,232,140,0) 12%),
    radial-gradient(200px 120px at 22% 6%, rgba(255,217,90,.28), rgba(255,217,90,0) 60%),
    radial-gradient(85% 120% at 16% -18%, rgba(255,201,58,.16), rgba(255,201,58,0) 62%),
    linear-gradient(180deg, #14161b, #0a0b0e) !important;
  border-radius:22px; box-shadow:0 12px 28px rgba(255,217,90,.08); overflow:hidden;
}
.chat-bgb-on .bgb-user::before{
  content:""; position:absolute; inset:0; border-radius:inherit; padding:1.25px;
  background:linear-gradient(135deg, var(--gold-hi) 0%, var(--gold) 42%, var(--gold-edge) 72%, var(--gold-hi) 100%);
  -webkit-mask:linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite:xor; mask-composite:exclude; pointer-events:none;
}
.chat-bgb-on .bgb-user::after{
  content:""; position:absolute; inset:2px; border-radius:inherit;
  background:
    linear-gradient(180deg, rgba(255,255,255,.12), rgba(255,255,255,0) 14%),
    linear-gradient(180deg, rgba(0,0,0,0) 68%, rgba(0,0,0,.26) 100%);
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.02); pointer-events:none;
}
.chat-bgb-on .bgb-user :is(p,span,li,div){ text-shadow:0 1px 0 rgba(0,0,0,.22); }
.chat-bgb-on .bgb-user a{ color:var(--gold-hi) !important; }
.chat-bgb-on .bgb-user code, .chat-bgb-on .bgb-user pre{
  background:#0f1114 !important; color:var(--ivory) !important; border:1px solid var(--edge) !important;
}
.chat-bgb-on .bgb-user svg{ color:var(--ivory-2); fill:currentColor; }

/* ===== 选中(Selection):黑底金字 ===== */
.chat-bgb-on .bgb-composer::selection, .chat-bgb-on .bgb-composer *::selection{ background: var(--deep) !important; color: var(--gold-hi) !important; }
.chat-bgb-on .bgb-assistSel::selection, .chat-bgb-on .bgb-assistSel *::selection{ background: var(--deep) !important; color: var(--gold-hi) !important; }
`;

  const STYLE_ID = 'bgb-style-v344';

  function injectCSS(){
    if (!document.getElementById(STYLE_ID)){
      const s = document.createElement('style');
      s.id = STYLE_ID; s.textContent = CSS; document.documentElement.appendChild(s);
    }
    document.documentElement.classList.add('chat-bgb-on');
  }

  /* ======================= 用户气泡定位(仅用户) ======================= */
  function findBubble(turn){
    const divs = turn.querySelectorAll('div');
    let best=null, score=-1;
    for (const el of divs){
      if (el.closest('form')) continue;
      const cs = getComputedStyle(el);
      if (cs.display==='inline') continue;
      const r = ['borderTopLeftRadius','borderTopRightRadius','borderBottomLeftRadius','borderBottomRightRadius']
        .map(k=>parseFloat(cs[k])||0).reduce((a,b)=>a+b,0);
      if (r < 20) continue;
      const bg = cs.backgroundColor; if (!bg || /rgba?\(0,\s*0,\s*0,\s*0\)/.test(bg)) continue;
      const pad = ['paddingTop','paddingRight','paddingBottom','paddingLeft']
        .map(k=>parseFloat(cs[k])||0).reduce((a,b)=>a+b,0);
      const rect = el.getBoundingClientRect();
      const sc = pad + r + Math.min(rect.width, 900) + Math.min(rect.height, 600);
      if (sc > score){ best = el; score = sc; }
    }
    return best;
  }
  function styleUserTurn(turn){
    if (turn.dataset.messageStyled==='1') return;
    if (turn.getAttribute('data-message-author-role')!=='user') return;
    const bubble = findBubble(turn); if (!bubble) return;
    bubble.classList.add('bgb-user');
    turn.dataset.messageStyled='1';
  }
  function styleAllUserTurns(){ document.querySelectorAll('[data-message-author-role]').forEach(styleUserTurn); }

  /* ======================= 选中区域标记 ======================= */
  function markComposer(){
    const el = document.querySelector('form textarea, form [contenteditable="true"][role="textbox"]');
    const box = el ? (el.closest('form') || el) : null;
    if (box && !box.classList.contains('bgb-composer')) box.classList.add('bgb-composer');
  }
  function markAssistantSelection(){
    document.querySelectorAll('[data-message-author-role="assistant"]').forEach(el=>{
      if (!el.classList.contains('bgb-assistSel')) el.classList.add('bgb-assistSel');
    });
  }

  /* ======================= 发送/语音/停止 ======================= */
  function isVoice(btn){
    const t=(btn.getAttribute('aria-label')||btn.title||'').toLowerCase();
    const id=(btn.getAttribute('data-testid')||'').toLowerCase();
    return /voice|microphone|mic|语音|麦克/.test(t) || /voice|microphone|mic/.test(id);
  }
  function isSend(btn){
    const t=(btn.getAttribute('aria-label')||'').toLowerCase();
    const id=(btn.getAttribute('data-testid')||'').toLowerCase();
    return /send|发送/.test(t) || /send/.test(id);
  }
  function isStop(btn){
    const t=(btn.getAttribute('aria-label')||'').toLowerCase();
    const id=(btn.getAttribute('data-testid')||'').toLowerCase();
    return /stop|停止|cancel|中止/.test(t) || /stop/.test(id);
  }
  function markActions(){
    document.querySelectorAll('form button').forEach(b=>{
      if (b.classList.contains('bgb-action')) return;
      if (isSend(b) || isVoice(b) || isStop(b)) b.classList.add('bgb-action');
    });
  }

  /* ======================= 工具栏(全局扫描) ======================= */
  function bgb_isExcluded(btn){
    const label=(btn.getAttribute('aria-label')||btn.title||btn.innerText||'').toLowerCase();
    const testid=(btn.getAttribute('data-testid')||'').toLowerCase();
    // 代码/编辑器区的 Copy(保持默认)
    if (/copy\s*code|复制代码|代码|code/.test(label) || /copy.*code|copy-code|code-copy/.test(testid)) return true;
    if (btn.closest('pre, code, [data-testid*="code" i], [data-testid*="copy-code" i], .cm-editor, .monaco-editor')) return true;
    // Canvas 预览(未展开)右上角 Copy(保持默认)
    if (/copy/.test(label) && btn.closest('[data-kind*="canvas" i], [data-testid*="canvas" i], figure')) return true;
    return false;
  }
  function bgb_isToolbarButton(btn){
    const lab=(btn.getAttribute('aria-label')||btn.title||btn.innerText||'').toLowerCase();
    const id =(btn.getAttribute('data-testid')||'').toLowerCase();
    let hit = /\b(copy|share|like|dislike|good|bad|read|朗读|speak|audio|canvas|try\s*again|retry|regenerate|more|更多|反馈|feedback|赞|踩|复制|分享|画布)\b/.test(lab)
           || /(copy|share|like|dislike|read|speak|audio|canvas|retry|regenerate|more|overflow|feedback)/.test(id);
    if (!hit){
      const svg = btn.querySelector('[aria-label],[title]');
      const svgl = (svg && (svg.getAttribute('aria-label')||svg.getAttribute('title')||'').toLowerCase()) || '';
      hit = /\b(copy|share|like|dislike|read|speak|audio|canvas|retry|regenerate|more|feedback)\b/.test(svgl);
    }
    return hit;
  }
  function markGlobalToolbar(){
    const CAND=':is(button,[role="button"],a[href])';
    document.querySelectorAll(CAND).forEach(btn=>{
      if (btn.classList.contains('bgb-action')) return;
      if (bgb_isExcluded(btn)) return;
      if (!bgb_isToolbarButton(btn)) return;
      btn.classList.add('bgb-action');
    });
    // 顶部 Share(右上角)
    document.querySelectorAll('header ' + CAND).forEach(b=>{
      const t=(b.getAttribute('aria-label')||b.title||'').toLowerCase();
      const id=(b.getAttribute('data-testid')||'').toLowerCase();
      if (/share|分享/.test(t) || /share/.test(id)) b.classList.add('bgb-action');
    });
    // Share 弹窗里的 Create link
    document.querySelectorAll('[role="dialog"] ' + CAND).forEach(b=>{
      const t=(b.getAttribute('aria-label')||b.title||b.innerText||'').toLowerCase();
      const id=(b.getAttribute('data-testid')||'').toLowerCase();
      if (/create.*link/.test(t) || (/create|link/.test(id) && /share|link/.test(id))) b.classList.add('bgb-action');
    });
  }

  /* ======================= Init & Observe ======================= */
  function runAll(){
    injectCSS();
    styleAllUserTurns();
    markComposer();
    markAssistantSelection();
    markActions();
    markGlobalToolbar();
  }

  runAll();

  const mo = new MutationObserver(()=>{ runAll(); });
  mo.observe(document.documentElement, {subtree:true, childList:true});

  // Alt+G 开关(持久化)
  window.addEventListener('keydown', e=>{
    if (e.altKey && (e.key==='g' || e.key==='G')){
      e.preventDefault();
      const on = document.documentElement.classList.toggle('chat-bgb-on');
      localStorage.setItem('bgb_on', on ? 'on' : 'off');
    }
  }, true);
  if (localStorage.getItem('bgb_on')==='off'){
    document.documentElement.classList.remove('chat-bgb-on');
  }
})();
长期地址
遇到问题?请前往 GitHub 提 Issues。