Minimal Twitter

Refine and clean up the Twitter interface, and customize your experience. A clean and minimal theme for Twitter/X. Userscript adaptation of the Chrome extension from https://github.com/typefully/minimal-twitter (by Typefully), implemented by whywhathow.

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name         Minimal Twitter
// @name:zh       Minimal Twitter — X/Twitter 极简主题
// @namespace    https://github.com/WhyWhatHow/
// @homepage     https://github.com/WhyWhatHow/powertoys4browser
// @supportURL   https://github.com/WhyWhatHow/powertoys4browser/issues
// @version      1.0.19
// @description  Refine and clean up the Twitter interface, and customize your experience. A clean and minimal theme for Twitter/X. Userscript adaptation of the Chrome extension from https://github.com/typefully/minimal-twitter (by Typefully), implemented by whywhathow.
// @description:zh  为 X/Twitter 打造极简主题:图标化左侧导航(悬停显示标签)、时间线限宽、Premium/Grok/Creator Studio 等导航项逐项显隐、Grok 页面零干扰、内置中/英/繁三语设置面板、自定义 CSS 注入。Typefully 同名 Chrome 插件的轻量油猴翻版,MIT 开源免费。
// @author       whywhathow
// @match        https://twitter.com/*
// @match        https://x.com/*
// @grant        GM_getValue
// @grant        GM_setValue
// @grant        GM_addStyle
// @grant        GM_registerMenuCommand
// @grant        GM_openInTab
// @run-at       document-idle
// @noframes
// @license MIT
// ==/UserScript==

(function () {
  'use strict';

  const STORAGE_KEY = 'minimal_twitter_settings';
  const SELECTORS = {
    mainWrapper: 'main[role="main"]',
    mainColumn: '[data-testid="primaryColumn"]',
    topHeader: '[data-testid="primaryColumn"] > div > div:nth-of-type(1)',
    timelineTabs: '[data-testid="primaryColumn"] > div:first-child > div:first-child > div:first-child > div:only-child > nav:only-child',
    leftSidebar: 'header[role="banner"]',
    leftSidebarLinks: 'header[role="banner"] nav[role="navigation"]',
    leftSidebarUnreadBadge: 'header[role="banner"] nav[role="navigation"] a svg + div[aria-label]:only-of-type',
    sidebarLinks: {
      logo: 'header[role="banner"] div:first-child > div:first-child div:first-child > div:first-child > h1:only-child[role="heading"]',
      home: 'header[role="banner"] [data-testid="AppTabBar_Home_Link"]',
      explore: 'header[role="banner"] [data-testid="AppTabBar_Explore_Link"]',
      notifications: 'header[role="banner"] [data-testid="AppTabBar_Notifications_Link"]',
      messages: 'header[role="banner"] [data-testid="AppTabBar_DirectMessage_Link"]',
      bookmarks: 'header[role="banner"] a[href*="bookmarks"]',
      jobs: 'header[role="banner"] a[href*="jobs"]',
      articles: 'header[role="banner"] a[href="/compose/articles"]',
      topics: 'header[role="banner"] a[href*=topics]',
      circles: 'header[role="banner"] a[href*=circles]',
      communities: 'header[role="banner"] a[href*=communities]',
      profile: 'header[role="banner"] [data-testid="AppTabBar_Profile_Link"]',
      lists: 'header[role="banner"] a[href*="lists"][role="link"][aria-label]',
      xPremium: 'header[role="banner"] a[href*="premium"][role="link"][aria-label]:not([href*="premium_signups"])',
      verifiedOrgs: 'header[role="banner"] a[href*="verified-orgs"][role="link"][aria-label]',
      creatorCenter: 'header[role="banner"] a[href*="creator"], header[role="banner"] [data-testid="creatorStudioButton"], header[role="banner"] [data-testid="creator-studio-button"], header[role="banner"] [data-testid="creatorCenterButton"], header[role="banner"] [data-testid="creator-center-button"]',
      analytics: '.mt-sidebar-button[aria-label="Analytics"]',
      accountSwitcher: '[data-testid="SideNav_AccountSwitcher_Button"]',
      grok: 'header[role="banner"] a[href*="grok"][role="link"][aria-label]',
    },
    accountSwitcherButton: '[data-testid="SideNav_AccountSwitcher_Button"]',
    leftSidebarLabel: 'header[role="banner"] nav[role="navigation"] > * > div > div + div:last-child',
    accountSwitcherLabel: '[data-testid="SideNav_AccountSwitcher_Button"] > div:not(:first-child)',
    leftSidebarLabel_hover: 'header[role="banner"] nav[role="navigation"]:hover > * > div > div + div:last-child',
    accountSwitcherLabel_hover: '[data-testid="SideNav_AccountSwitcher_Button"]:hover > div:not(:first-child)',
    rightSidebar: '[data-testid="sidebarColumn"]',
    grokDrawer: '[data-testid="GrokDrawer"]',
    grokDrawerHeader: 'div[data-testid="GrokDrawerHeader"]',
    timelineTablist: 'div[data-testid="ScrollSnap-List"][role="tablist"]',
    timelineTab: 'div[role="tab"]',
    timelineTabPresentation: 'div[role="presentation"]',
    timelineTabSelected: 'div[role="tab"][aria-selected="true"]',
    timelineTabText: 'div[dir="ltr"] > span',
    timelineOptions: 'div[aria-label="Timeline options"]',
    topTweetsOn: 'div[aria-label="Top Tweets on"]',
    menuItem: 'div[role="menuitem"][tabindex="0"]',
    tweetCounts: '[role="group"][id*="id__"]:only-child',
    viewCount: '[role="group"][id*="id__"]:only-child a[href*="/analytics"]',
    tweet: '[data-testid="tweet"][role="article"]',
    tweetSpan: '[data-testid="tweet"][role="article"] div > div:only-child > span:only-child > span',
    grokSvg: 'svg:has(path[d="M12.745 20.54l10.97-8.19c.539-.4 1.307-.244 1.564.38 1.349 3.288.746 7.241-1.938 9.955-2.683 2.714-6.417 3.31-9.83 1.954l-3.728 1.745c5.347 3.697 11.84 2.782 15.898-1.324 3.219-3.255 4.216-7.692 3.284-11.693l.008.009c-1.351-5.878.332-8.227 3.782-13.031L33 0l-4.54 4.59v-.014L12.743 20.544m-2.263 1.987c-3.837-3.707-3.175-9.446.1-12.755 2.42-2.449 6.388-3.448 9.852-1.979l3.72-1.737c-.67-.49-1.53-1.017-2.515-1.387-4.455-1.854-9.789-.931-13.41 2.728-3.483 3.523-4.579 8.94-2.697 13.561 1.405 3.454-.899 5.898-3.22 8.364C1.49 30.2.666 31.074 0 32l10.478-9.466"])',
    searchBox: '[data-testid="sidebarColumn"] form[role="search"]',
    searchBoxInput: '[data-testid="sidebarColumn"] form[role="search"] input:only-child',
    searchListBox: '[data-testid="sidebarColumn"] form[role="search"] div[role="listbox"]',
    modalExternalWrapper: 'div[role="group"]',
    modalBackground: 'div[role="group"] > div:empty',
    modalWrapper: 'div[aria-labelledby="modal-header"][role="dialog"]',
    modalUi: 'div[aria-labelledby="modal-header"][role="dialog"] > div',
    tweetButton: '[data-testid="SideNav_NewTweet_Button"]',
    securityAndAccountAccess: '[data-testid="accountAccessScreen"]',
  };

  const DEFAULT_SETTINGS = {
    extensionStatus: 'on',
    timelineWidth: 700,
    timelineBorders: 'off',
    tweetBorders: 'off',
    stickyHeader: 'on',
    writerMode: 'off',
    followingTimeline: 'off',
    hideViewCount: 'off',
    recentMedia: 'off',
    trendsHomeTimeline: 'off',
    removePromotedPosts: 'on',
    removeTopicsToFollow: 'on',
    removeTimelineTabs: 'off',
    typefullyEnhancementsButtons: 'on',
    followCount: 'show',
    replyCount: 'show',
    retweetCount: 'show',
    likeCount: 'show',
    sidebarLogo: 'off',
    navigationButtonsLabels: 'never',
    navigationCenter: 'off',
    unreadCountBadge: 'off',
    accountSwitcherButton: 'on',
    hideGrokDrawer: 'on',
    interFont: 'off',
    searchBar: 'on',
    transparentSearch: 'off',
    titleNotifications: 'on',
    tweetButton: 'on',
    homeButton: 'on',
    exploreButton: 'on',
    notificationsButton: 'on',
    messagesButton: 'on',
    grokButton: 'on',
    xPremiumButton: 'off',
    listsButton: 'on',
    bookmarksButton: 'on',
    jobsButton: 'off',
    communitiesButton: 'on',
    articles: 'off',
    topicsButton: 'off',
    verifiedOrgsButton: 'off',
    creatorCenterButton: 'on',
    accountSwitcherButton: 'on',
    showFloatingButton: 'on',
    panelLanguage: 'auto',
    typefullyGrowTab: 'on',
    profileButton: 'on',
    customCss: '',
  };

  const STORAGE_KEYS = Object.keys(DEFAULT_SETTINGS);

  // 设置面板多语言(flat key;新增语言只需加一个词典)
  const I18N = {
    en: {
      'panel.title': 'Minimal Twitter Settings',
      'section.general': 'General',
      'section.timeline': 'Timeline',
      'section.content': 'Content',
      'section.navigation': 'Navigation',
      'section.interface': 'Interface',
      'section.customCss': 'Custom CSS',
      'row.panelLanguage': 'Language',
      'row.showFloatingButton': 'Settings Button',
      'row.timelineWidth': 'Timeline Width',
      'row.timelineBorders': 'Remove Timeline Borders',
      'row.tweetBorders': 'Remove Tweet Borders',
      'row.stickyHeader': 'Sticky Header',
      'row.followingTimeline': 'Default to Following Timeline',
      'row.removeTimelineTabs': 'Remove Timeline Tabs',
      'row.writerMode': 'Writer Mode',
      'row.removePromotedPosts': 'Remove Promoted Posts',
      'row.removeTopicsToFollow': 'Remove Topics to Follow',
      'row.hideViewCount': 'Hide View Count',
      'row.followCount': 'Hide Follow Count',
      'row.replyCount': 'Hide Reply Count',
      'row.retweetCount': 'Hide Retweet Count',
      'row.likeCount': 'Hide Like Count',
      'row.navigationLabels': 'Navigation Labels',
      'row.homeButton': 'Home',
      'row.exploreButton': 'Explore',
      'row.notificationsButton': 'Notifications',
      'row.messagesButton': 'Messages',
      'row.grokButton': 'Grok',
      'row.xPremiumButton': 'Premium',
      'row.verifiedOrgsButton': 'Verified Orgs',
      'row.communitiesButton': 'Communities',
      'row.profileButton': 'Profile',
      'row.bookmarksButton': 'Bookmarks',
      'row.listsButton': 'Lists',
      'row.jobsButton': 'Jobs',
      'row.topicsButton': 'Topics',
      'row.articles': 'Articles',
      'row.creatorCenterButton': 'Creator Center',
      'row.accountSwitcherButton': 'Account Switcher',
      'row.navigationCenter': 'Center Navigation',
      'row.unreadCountBadge': 'Unread Badge',
      'row.hideGrokDrawer': 'Hide Grok Drawer',
      'row.searchBar': 'Search Bar',
      'row.transparentSearch': 'Transparent Search Bar',
      'row.tweetButton': 'Tweet Button',
      'row.interFont': 'Use Inter Font',
      'option.never': 'Never',
      'option.always': 'Always',
      'option.hover': 'On Hover',
      'placeholder.customCss': 'Paste custom CSS here...',
    },
    'zh-CN': {
      'panel.title': 'Minimal Twitter 设置',
      'section.general': '通用',
      'section.timeline': '时间线',
      'section.content': '内容',
      'section.navigation': '导航',
      'section.interface': '界面',
      'section.customCss': '自定义 CSS',
      'row.panelLanguage': '面板语言',
      'row.showFloatingButton': '悬浮设置按钮',
      'row.timelineWidth': '时间线宽度',
      'row.timelineBorders': '移除时间线边框',
      'row.tweetBorders': '移除推文边框',
      'row.stickyHeader': '固定顶部栏',
      'row.followingTimeline': '默认 Following 时间线',
      'row.removeTimelineTabs': '移除时间线标签页',
      'row.writerMode': '写作模式',
      'row.removePromotedPosts': '移除推广帖',
      'row.removeTopicsToFollow': '移除推荐话题',
      'row.hideViewCount': '隐藏浏览数',
      'row.followCount': '隐藏关注数',
      'row.replyCount': '隐藏回复数',
      'row.retweetCount': '隐藏转推数',
      'row.likeCount': '隐藏点赞数',
      'row.navigationLabels': '导航文字标签',
      'row.homeButton': '首页',
      'row.exploreButton': '探索',
      'row.notificationsButton': '通知',
      'row.messagesButton': '私信',
      'row.grokButton': 'Grok',
      'row.xPremiumButton': 'Premium',
      'row.verifiedOrgsButton': '认证企业',
      'row.communitiesButton': '社区',
      'row.profileButton': '个人主页',
      'row.bookmarksButton': '书签',
      'row.listsButton': '列表',
      'row.jobsButton': '职位',
      'row.topicsButton': '话题',
      'row.articles': '文章',
      'row.creatorCenterButton': '创作者中心',
      'row.accountSwitcherButton': '账户头像/切换器',
      'row.navigationCenter': '导航居中',
      'row.unreadCountBadge': '未读角标',
      'row.hideGrokDrawer': '隐藏 Grok 抽屉',
      'row.searchBar': '搜索框',
      'row.transparentSearch': '透明搜索框',
      'row.tweetButton': '发推按钮',
      'row.interFont': '使用 Inter 字体',
      'option.never': '从不',
      'option.always': '总是',
      'option.hover': '悬停时',
      'placeholder.customCss': '在此粘贴自定义 CSS…',
    },
    'zh-TW': {
      'panel.title': 'Minimal Twitter 設定',
      'section.general': '一般',
      'section.timeline': '時間線',
      'section.content': '內容',
      'section.navigation': '導覽',
      'section.interface': '介面',
      'section.customCss': '自訂 CSS',
      'row.panelLanguage': '面板語言',
      'row.showFloatingButton': '懸浮設定按鈕',
      'row.timelineWidth': '時間線寬度',
      'row.timelineBorders': '移除時間線邊框',
      'row.tweetBorders': '移除推文邊框',
      'row.stickyHeader': '固定頂部欄',
      'row.followingTimeline': '預設 Following 時間線',
      'row.removeTimelineTabs': '移除時間線標籤',
      'row.writerMode': '寫作模式',
      'row.removePromotedPosts': '移除推廣貼文',
      'row.removeTopicsToFollow': '移除推薦話題',
      'row.hideViewCount': '隱藏瀏覽數',
      'row.followCount': '隱藏追蹤數',
      'row.replyCount': '隱藏回覆數',
      'row.retweetCount': '隱藏轉推數',
      'row.likeCount': '隱藏喜歡數',
      'row.navigationLabels': '導覽文字標籤',
      'row.homeButton': '首頁',
      'row.exploreButton': '探索',
      'row.notificationsButton': '通知',
      'row.messagesButton': '私訊',
      'row.grokButton': 'Grok',
      'row.xPremiumButton': 'Premium',
      'row.verifiedOrgsButton': '認證企業',
      'row.communitiesButton': '社群',
      'row.profileButton': '個人主頁',
      'row.bookmarksButton': '書籤',
      'row.listsButton': '列表',
      'row.jobsButton': '職位',
      'row.topicsButton': '話題',
      'row.articles': '文章',
      'row.creatorCenterButton': '創作者中心',
      'row.accountSwitcherButton': '帳號頭像/切換器',
      'row.navigationCenter': '導覽置中',
      'row.unreadCountBadge': '未讀標記',
      'row.hideGrokDrawer': '隱藏 Grok 抽屜',
      'row.searchBar': '搜尋框',
      'row.transparentSearch': '透明搜尋框',
      'row.tweetButton': '發推按鈕',
      'row.interFont': '使用 Inter 字型',
      'option.never': '從不',
      'option.always': '總是',
      'option.hover': '懸停時',
      'placeholder.customCss': '貼上自訂 CSS…',
    },
  };

  function panelLang() {
    const pref = settings.panelLanguage || 'auto';
    if (pref !== 'auto' && I18N[pref]) return pref;
    const nav = (typeof navigator !== 'undefined' && navigator.language || 'en').toLowerCase();
    if (nav.startsWith('zh')) {
      return (nav.includes('tw') || nav.includes('hk') || nav.includes('hant')) ? 'zh-TW' : 'zh-CN';
    }
    return 'en';
  }

  function t(key) {
    const lang = panelLang();
    return (I18N[lang] && I18N[lang][key]) || I18N.en[key] || key;
  }

  let settings = {};
  let styleElements = {};
  let observer = null;
  let titleObserver = null;
  let isInitialized = false;

  function getStorage(key) {
    if (typeof key === 'string') {
      return GM_getValue(key, DEFAULT_SETTINGS[key]);
    } else if (Array.isArray(key)) {
      const result = {};
      key.forEach(k => {
        result[k] = GM_getValue(k, DEFAULT_SETTINGS[k]);
      });
      return result;
    }
    return GM_getValue(STORAGE_KEY, DEFAULT_SETTINGS);
  }

  function setStorage(key, value) {
    if (typeof key === 'object') {
      Object.entries(key).forEach(([k, v]) => {
        GM_setValue(k, v);
        settings[k] = v;
      });
    } else {
      GM_setValue(key, value);
      settings[key] = value;
    }
    if (isInitialized) {
      applyAllFeatures();
    }
  }

  function loadAllSettings() {
    STORAGE_KEYS.forEach(key => {
      settings[key] = GM_getValue(key, DEFAULT_SETTINGS[key]);
    });
  }

  function addStyles(id, css) {
    removeStyles(id);
    const head = document.querySelector('head');
    if (!head) return;
    const style = document.createElement('style');
    style.id = 'mt-style-' + id;
    style.textContent = css.trim().split('\n').join('');
    head.appendChild(style);
    styleElements[id] = style;
  }

  function removeStyles(id) {
    const existing = document.getElementById('mt-style-' + id);
    if (existing) {
      existing.remove();
      delete styleElements[id];
    }
  }

  function stylesExist(id) {
    return document.getElementById('mt-style-' + id);
  }

  // Grok 页面路由检测(/i/grok 及其子路由)。Grok 布局与三栏时间线差异大,
  // 冲突的布局规则需在其下豁免:给根元素打标记类,配合 html:not(.mt-grok-page) 作用域。
  function isGrokRoute() {
    return /(^|\/)i\/grok($|\/)/.test(window.location.pathname);
  }

  function syncGrokRouteFlag() {
    document.documentElement.classList.toggle('mt-grok-page', isGrokRoute());
  }

  function debounce(func, timeout = 300) {
    let timer;
    return (...args) => {
      clearTimeout(timer);
      timer = setTimeout(() => func.apply(this, args), timeout);
    };
  }

  function throttle(func, limit) {
    let lastFunc;
    let lastRan;
    return function () {
      const context = this;
      const args = arguments;
      if (!lastRan) {
        func.apply(context, args);
        lastRan = Date.now();
      } else {
        clearTimeout(lastFunc);
        lastFunc = setTimeout(function () {
          if (Date.now() - lastRan >= limit) {
            func.apply(context, args);
            lastRan = Date.now();
          }
        }, limit - (Date.now() - lastRan));
      }
    };
  }

  function extractColorsAsRootVars() {
    const extractColor = (selector, varName) => {
      const element = document.querySelector(selector);
      if (element) {
        let color;
        if (varName.includes('bg')) {
          color = window.getComputedStyle(element).backgroundColor;
        } else if (varName.includes('border')) {
          color = window.getComputedStyle(element).borderColor;
        } else {
          color = window.getComputedStyle(element).color;
        }
        const root = document.documentElement;
        if (!color) return;
        const colorRgb = color.replace('rgb(', '').replace(')', '');
        root.style.setProperty(`--${varName}-color`, color);
        root.style.setProperty(`--${varName}-color-rgb`, colorRgb);
      }
    };

    extractColor('body', 'body-bg');
    extractColor('[data-testid="primaryColumn"]', 'border');
    extractColor('h2 > span', 'main-text');
    extractColor('div > span', 'main-text');
    extractColor('a > time', 'secondary-text');
    extractColor("[data-testid='primaryColumn'] div[aria-haspopup='menu'] > div > div > svg", 'secondary-text');
    extractColor('a', 'accent');
    extractColor('div > svg', 'glyphs');
  }

  // 原 isMutationSkippable 已足够,保留不变
  function isMutationSkippable(mutationsList) {
    const a = mutationsList[0]?.addedNodes[0];
    const r = mutationsList[0]?.removedNodes[0];
    const t = mutationsList[0]?.target;
    const el = a || r;

    try {
      if (el?.id?.startsWith('mt-') || t?.id?.startsWith('mt-') ||
          el?.id?.startsWith('typefully-') || t?.className?.startsWith('mt-')) {
        return true;
      }
      if (t.closest('[data-testid="like"]') || t.closest('[data-testid="retweet"]') || t.closest('[data-testid="reply"]')) {
        return true;
      }
      if (t.closest('nav[role="navigation"]')) return true;
      if (t?.nodeName === 'NAV' && t?.getAttribute('role') === 'navigation') return true;
      if (t.closest('head')) return true;
      if (el?.closest("[data-testid^='UserAvatar-Container']") || t?.closest("[data-testid^='UserAvatar-Container']")) return true;
      if (el?.closest("[data-testid='tweetPhoto']")) return true;
      if (el?.nodeName === 'IMG' || t?.nodeName === 'IMG' || el?.nodeName === 'VIDEO' ||
          el?.firstChild?.nodeName === 'VIDEO' || el?.querySelector(':scope > img') ||
          el?.getAttribute('data-testid') === 'tweetPhoto' ||
          el?.parentNode?.getAttribute('data-testid') === 'tweetPhoto' ||
          t?.closest("[data-testid='videoPlayer']")) {
        return true;
      }
      if (el?.closest("[data-testid='card.wrapper']")) return true;
      if (el?.nodeName === 'SCRIPT') return true;
      if (el?.nodeName === 'STYLE') return true;
      if (el?.closest("[data-testid='DMDrawer']") || t?.closest("[data-testid='DMDrawer']")) return true;
      if (el?.closest("[data-testid='sidebarColumn']") || t?.closest("[data-testid='sidebarColumn']")) return true;
      if (el?.nodeName === '#text') return true;
      if (el?.nodeName === 'DIV' && el?.firstChild?.firstChild?.firstChild?.getAttribute('data-testid') === 'caret') {
        return true;
      }
      if (el?.nodeName === 'path') return true;
      return false;
    } catch (e) {}
    return false;
  }

  function changeTimelineWidth(width) {
    if (isGrokRoute()) {
      // Grok 页主列是聊天面板,强制宽度会破坏排版:豁免
      removeStyles('timelineWidth');
      return;
    }
    if (width && !isNaN(width)) {
      addStyles('timelineWidth', `
          @media only screen and (min-width: 988px) {
            ${SELECTORS.mainColumn} {
              width: ${width}px;
              max-width: ${width}px;
            }
          }
        `);
    }
  }

  function changeTimelineBorders(value) {
    if (value === 'on') {
      addStyles('timelineBorders', `
        @media only screen and (min-width: 988px) {
          div${SELECTORS.mainColumn} {
            border-style: hidden;
          }
        }
      `);
    } else {
      removeStyles('timelineBorders');
    }
  }

  function changeTweetBorders(value) {
    if (value === 'on') {
      addStyles('tweetBorders', `
        ${SELECTORS.mainWrapper} section > div > div > div > div[role="separator"] {
          display: none;
        }
        ${SELECTORS.mainColumn} > div > div:empty {
          background: transparent;
        }
      `);
    } else {
      removeStyles('tweetBorders');
    }
  }

  function changeStickyHeader(value) {
    if (value === 'off') {
      addStyles('stickyHeader', `
        ${SELECTORS.mainColumn} > div > div {
          position: unset;
        }
      `);
    } else {
      removeStyles('stickyHeader');
    }
  }

  function changePromotedPosts(value) {
    if (value === 'off') {
      addStyles('removePromotedPosts', `
        [data-testid="placementTracking"] article {
          display: flex;
        }
      `);
    } else {
      removeStyles('removePromotedPosts');
    }
  }

  function changeTopicsToFollow(value) {
    if (value === 'on') {
      addStyles('removeTopicsToFollow', `
        ${SELECTORS.mainColumn} section[aria-labelledby^="accessible-list-"] > div[aria-label$="Carousel"],
        ${SELECTORS.mainColumn} a[href*="/i/flow/topics_selector"],
        ${SELECTORS.mainColumn} a[href*="/i/topics/picker/home"] {
          display: none;
        }
        [aria-label="Lists timeline"] section[aria-labelledby^="accessible-list-"] > div[aria-label$="Carousel"] {
          display: flex;
        }
      `);
    } else {
      removeStyles('removeTopicsToFollow');
    }
  }

  function changeTimelineTabs(value, writerMode) {
    const isHome = window.location.pathname === '/' || window.location.pathname.includes('/home');
    if (writerMode === 'on' || window.location.pathname.includes('compose/tweet') || !isHome) {
      removeStyles('removeTimelineTabs');
      return;
    }
    if (value === 'on') {
      if (!stylesExist('removeTimelineTabs')) {
        addStyles('removeTimelineTabs', `
          ${SELECTORS.timelineTabs} {
            display: none;
          }
        `);
      }
    } else {
      removeStyles('removeTimelineTabs');
    }
  }

  function changeFollowingTimeline() {
    if (getStorage('followingTimeline') !== 'on') return;
    const tablist = document.querySelector(SELECTORS.timelineTablist);
    const selectedTab = document.querySelector(`${SELECTORS.timelineTablist} ${SELECTORS.timelineTabSelected}`);
    if (!tablist || !selectedTab) return;
    const followingTabSpan = tablist.querySelector(`${SELECTORS.timelineTabPresentation}:nth-of-type(2) span`);
    if (!followingTabSpan) return;
    const followingTabText = followingTabSpan.textContent.toLowerCase();
    const selectedTabSpan = selectedTab.querySelector(SELECTORS.timelineTabText);
    if (!selectedTabSpan) return;
    const selectedTabText = selectedTabSpan.textContent.toLowerCase();
    if (selectedTabText === followingTabText) return;
    const secondTab = tablist.querySelector(`${SELECTORS.timelineTabPresentation}:nth-child(2) ${SELECTORS.timelineTab}`);
    if (!secondTab) return;
    secondTab.click();
  }

  // 改为纯 CSS 实现,不再需要遍历 DOM,大幅提升性能
  function changeHideViewCounts(value) {
    if (value === 'on') {
      addStyles('hideViewCount', `
        [role="group"][id*="id__"]:only-child a[href*="/analytics"] {
          display: none !important;
        }
      `);
    } else {
      removeStyles('hideViewCount');
    }
  }

  function hideRightSidebar() {
    const isSearchPage = window.location.pathname === '/search';
    if (isSearchPage) {
      removeStyles('hide-sidebar');
      removeOtherSections();
      setTimeout(() => removeOtherSections(), 500);
    } else {
      if (!stylesExist('hide-sidebar')) {
        addStyles('hide-sidebar', `
          ${SELECTORS.rightSidebar} {
            visibility: hidden;
            width: 0;
            margin: 0;
            padding: 0;
            z-index: 1;
          }
        `);
      }
    }
  }

  function removeOtherSections() {
    const sidebar = document.querySelector(SELECTORS.rightSidebar);
    if (!sidebar) return;
    sidebar.querySelector('aside[role="complementary"]')?.parentElement?.remove();
    sidebar.querySelector('section[role="region"]')?.parentElement?.parentElement?.remove();
  }

  function updateLeftSidebarPositioning() {
    if (isGrokRoute()) {
      // Grok 布局对 header 定位/body 内边距敏感:豁免
      removeStyles('navigation-position');
      return;
    }
    addStyles('navigation-position', `
      @media only screen and (min-width: 1000px) {
        ${SELECTORS.leftSidebar} {
          position: fixed;
          left: 0;
        }
      }
      @media only screen and (min-width: 1000px) and (max-width: 1265px) {
        body {
          padding-left: 88px;
        }
      }
    `);
  }

  function addSmallerSearchBarStyle() {
    const searchInput = document.querySelector('form[role="search"] input:only-child');
    if (!searchInput) return;
    // 搜索结果页:输入框需完整显示已输入的查询词,不做窄化
    if (window.location.pathname.includes('/search') || window.location.pathname.includes('/explore')) {
      removeStyles('searchInputWidth');
      addStyles('searchPageInput', `
        form[role="search"] input:only-child {
          width: 100% !important;
          min-width: 0 !important;
          text-overflow: ellipsis;
        }
      `);
      return;
    } else {
      removeStyles('searchPageInput');
    }
    if (document.activeElement === searchInput) return;
    const searchBarPlaceholderWidth = searchInput.getAttribute('placeholder')?.length || 0;
    if (searchBarPlaceholderWidth > 0) {
      addStyles('searchInputWidth', `
        form[role="search"] input:only-child {
          width: ${searchBarPlaceholderWidth + 4}ch;
          min-width: ${searchBarPlaceholderWidth + 4}ch;
        }
      `);
    }
  }

  function changeHideSearchBar(value) {
    if (value === 'off') {
      addStyles('searchBar', `
        form[role="search"] {
          display: none !important;
          visibility: hidden !important;
        }
      `);
      addStyles('trendsHomeTimeline-more', `
        @media only screen and (min-width: 1265px) {
          ${SELECTORS.rightSidebar} section[aria-labelledby^="accessible-list-"] {
            top: 12px !important;
          }
          .mt-recentMedia-photoGrid {
            top: 12px !important;
          }
        }
      `);
    } else {
      removeStyles('searchBar');
      addStyles('trendsHomeTimeline-more', `
        @media only screen and (min-width: 1265px) {
          ${SELECTORS.rightSidebar} section[aria-labelledby^="accessible-list-"] {
            top: unset;
          }
          .mt-recentMedia-photoGrid {
            top: unset !important;
          }
        }
      `);
    }
  }

  /**
   * 搜索框固定在右上角(不移动 DOM,避免破坏 React 状态)。
   * q1 固定不动、q2 独立悬浮、q3 避免与 post 返回栏同行重叠、q4 仅 on/off。
   */
  function applySearchBarPosition() {
    if (settings.searchBar === 'off') {
      removeStyles('searchBarPosition');
      return;
    }
    // 搜索页/探索页保留原生布局,不做固定定位
    if (window.location.pathname === '/search' || window.location.pathname.includes('/explore')) {
      removeStyles('searchBarPosition');
      return;
    }
    addStyles('searchBarPosition', `
      @media only screen and (min-width: 1100px) {
        ${SELECTORS.searchBox} {
          visibility: visible !important;
          position: fixed !important;
          top: 12px !important;
          right: 16px !important;
          z-index: 5 !important;
          width: 320px !important;
          max-width: 32vw !important;
          pointer-events: auto !important;
          cursor: text !important;
        }
        ${SELECTORS.searchBox}:focus-within {
          width: 360px !important;
          max-width: 36vw !important;
        }
        ${SELECTORS.searchBox} input:only-child {
          pointer-events: auto !important;
          cursor: text !important;
          width: 100% !important;
          min-width: 0 !important;
        }
        ${SELECTORS.searchBox} > div:first-child {
          cursor: text !important;
          pointer-events: auto !important;
        }
      }
      @media only screen and (max-width: 1099px) {
        ${SELECTORS.searchBox} {
          position: static !important;
          visibility: visible !important;
          width: auto !important;
        }
      }
    `);
    // 点击表单空白处也能聚焦输入框(输入框窄化时后半区原本点不到)
    const _form = document.querySelector(SELECTORS.searchBox);
    if (_form && !_form._mtClickBound) {
      _form._mtClickBound = true;
      _form.addEventListener('click', (e) => {
        const _input = _form.querySelector('input:only-child');
        if (_input && e.target !== _input && document.activeElement !== _input) _input.focus();
      });
    }
  }

  function changeTransparentSearchBar(value) {
    if (value === 'on') {
      addStyles('transparentSearch', `
        form[role="search"] > div:nth-child(1) > div {
          background-color: transparent;
        }
        form[role="search"] input:only-child {
          transform: translateX(2ch);
          margin-left: -2.5ch;
        }
      `);
    } else {
      removeStyles('transparentSearch');
    }
  }

  function changeTweetButton(value) {
    if (value === 'off') {
      addStyles('tweetButton', `
        ${SELECTORS.tweetButton} {
          visibility: hidden;
        }
      `);
    } else {
      removeStyles('tweetButton');
    }
  }

  function changeTitleNotifications(value) {
    const run = () => {
      const favicon = document.querySelector('link[rel="shortcut icon"]');
      if (!favicon) return;
      if (value === 'on') {
        favicon.setAttribute('href', favicon.href.replace('twitter.ico', 'twitter-pip.2.ico'));
      } else {
        if (document.title.charAt(0) === '(') {
          document.title = document.title.split(' ').slice(1).join(' ');
        }
      }
    };
    run();
    // 复用同一个观察器,避免重复创建导致内存泄漏
    if (!titleObserver) {
      titleObserver = new MutationObserver(() => run());
      const target = document.querySelector('title');
      if (target) titleObserver.observe(target, { subtree: true, characterData: true, childList: true });
    }
  }

  function changeReplyCount(value) {
    if (value === 'hide') {
      addStyles('replyCount', `
        [data-testid="reply"] span {
          visibility: hidden;
        }
      `);
    } else {
      removeStyles('replyCount');
    }
  }

  function changeRetweetCount(value) {
    if (value === 'hide') {
      addStyles('retweetCount', `
        [href$="/retweets"],
        [href$="/retweets/with_comments"],
        [data-testid="retweet"] span,
        [data-testid="unretweet"] span {
          visibility: hidden;
        }
      `);
    } else {
      removeStyles('retweetCount');
    }
  }

  function changeLikeCount(value) {
    if (value === 'hide') {
      addStyles('likeCount', `
        [href$="/likes"][href*="/status/"],
        [data-testid="like"] span,
        [data-testid="unlike"] span {
           visibility: hidden;
        }
      `);
    } else {
      removeStyles('likeCount');
    }
  }

  function changeFollowingAndFollowersCounts(value) {
    if (value === 'hide') {
      addStyles('followCount', `
        [href$="following"][dir][role="link"],
        [href$="followers"][dir][role="link"] {
          display: none;
        }
      `);
    } else {
      removeStyles('followCount');
    }
  }

  function changeSidebarSetting(selector, state) {
    const sidebarSelector = SELECTORS.sidebarLinks[selector];
    if (!sidebarSelector) return;
    if (state === 'off') {
      addStyles(selector, `
        ${sidebarSelector} {
          display: none;
        }
      `);
    } else {
      removeStyles(selector);
    }
  }

  function changeUnreadCountBadge(value) {
    if (value === 'off') {
      addStyles('unreadCountBadge', `
        ${SELECTORS.leftSidebarUnreadBadge} {
          display: none;
        }
        ${SELECTORS.accountSwitcherButton} > div > svg+div[aria-label] {
          display: none;
        }
      `);
    } else {
      removeStyles('unreadCountBadge');
    }
  }

  function changeNavigationButtonsLabels(setting) {
    const isMessagesPage = window.location.pathname.startsWith('/messages');
    // 仅对私信页做特殊处理,搜索页不再进入此分支
    if (isMessagesPage) {
      removeStyles('navigation-position');
      addStyles('customDMsAndSearchStyle', `
        ${SELECTORS.leftSidebar} {
          flex: 0.5 1 auto;
        }
        @media only screen and (min-width: 1200px) {
          ${SELECTORS.leftSidebar} {
            flex: 0.3 1 auto;
          }
        }
        ${SELECTORS.mainWrapper} {
          align-items: flex-start;
        }
      `);
    } else {
      removeStyles('customDMsAndSearchStyle');
    }
    switch (setting) {
      case 'never':
        addStyles('removeLabels', `
          ${SELECTORS.leftSidebarLinks} > * > div > div + div:last-child {
            display: none;
          }
          ${SELECTORS.accountSwitcherLabel} {
            display: none;
          }
          #mt-sidebar-lists > div[dir] > div:last-child {
            display: none !important;
          }
        `);
        removeStyles('hideLabels');
        removeStyles('showLabelsOnHover');
        break;
      case 'always':
        removeStyles('hideLabels');
        removeStyles('removeLabels');
        removeStyles('showLabelsOnHover');
        break;
      case 'hover':
        removeStyles('removeLabels');
        addStyles('hideLabels', `
          ${SELECTORS.leftSidebarLabel},
          ${SELECTORS.accountSwitcherLabel} {
            display: inline-block;
            opacity: 0;
            transition: 0.4s cubic-bezier(0.2, 0.8, 0.2, 1);
          }
          #mt-sidebar-lists > div[dir] > div:last-child {
            display: inline-block;
            opacity: 0;
            transition: 0.4s cubic-bezier(0.2, 0.8, 0.2, 1);
          }
        `);
        addStyles('showLabelsOnHover', `
          ${SELECTORS.leftSidebarLabel_hover},
          ${SELECTORS.accountSwitcherLabel_hover} {
            opacity: 1;
          }
          header[role="banner"] nav[role="navigation"]:hover #mt-sidebar-lists > div[dir] > div:last-child {
            opacity: 1;
          }
        `);
        break;
    }
  }

  function changeNavigationCenter(value) {
    if (value === 'on') {
      addStyles('navigationCenter', `
        ${SELECTORS.leftSidebar} > div > div > div {
          justify-content: center;
          padding-top: 0;
        }
      `);
    } else {
      removeStyles('navigationCenter');
    }
  }

  function hideGrokDrawer(value) {
    if (value === 'on') {
      addStyles('grokDrawer', `
        ${SELECTORS.grokDrawer}:not(.typefully-grok-drawer-enabled) {
          display: none !important;
        }
      `);
    } else {
      removeStyles('grokDrawer');
    }
  }

  function changeCustomCss(css) {
    let styleEl = document.getElementById('custom-css');
    if (!styleEl) {
      // 本脚本没有 mt-external-stylesheet,直接创建并追加到 head
      styleEl = document.createElement('style');
      styleEl.id = 'custom-css';
      document.head.appendChild(styleEl);
    }
    styleEl.textContent = css;
  }

  function changeWriterMode(value) {
    if (!window.location.pathname.includes('/home') && window.location.pathname !== '/' &&
        !window.location.pathname.includes('/compose/tweet')) {
      removeStyles('writerMode');
      return;
    }
    if (value === 'on') {
      if (stylesExist('writerMode')) return;
      addStyles('writerMode', `
        body {
          padding-left: 0;
          overflow: hidden;
        }
        ${SELECTORS.mainColumn} {
          border-style: hidden;
          padding-top: 3vh;
          margin: 0 auto;
        }
        ${SELECTORS.mainWrapper} {
          flex-basis: 100%;
        }
        ${SELECTORS.mainWrapper} > div {
          width: 100%;
          max-width: 100%;
        }
        ${SELECTORS.leftSidebar},
        ${SELECTORS.rightSidebar},
        ${SELECTORS.mainColumn} > div > div:not(:nth-of-type(1)):not(:nth-of-type(2)):not(:nth-of-type(3)) {
          overflow: hidden;
          visibility: hidden;
          opacity: 0;
          width: 0;
          height: 0;
        }
        ${SELECTORS.topHeader} {
          visibility: hidden;
        }
        ${SELECTORS.modalWrapper} {
          width: 100vw;
          max-width: 100vw;
          top: 0;
          border-radius: 0;
        }
        div[role="group"] > div:empty {
          background-color: var(--body-bg-color);
        }
        ${SELECTORS.modalUi} {
          border-radius: 0;
        }
        ${SELECTORS.modalWrapper} > div > div > div {
          padding-bottom: 10vh;
        }
      `);
    } else {
      removeStyles('writerMode');
    }
  }

  function applyStaticFeatures() {
    changeTimelineWidth(settings.timelineWidth);
    changeTimelineBorders(settings.timelineBorders);
    changeTweetBorders(settings.tweetBorders);
    changeStickyHeader(settings.stickyHeader);
    changeWriterMode(settings.writerMode);
    changeFollowingTimeline();
    changeHideViewCounts(settings.hideViewCount);
    changeTrendsHomeTimeline();
    changePromotedPosts(settings.removePromotedPosts);
    changeTopicsToFollow(settings.removeTopicsToFollow);
    changeTimelineTabs(settings.removeTimelineTabs, settings.writerMode);
    changeFollowingAndFollowersCounts(settings.followCount);
    changeReplyCount(settings.replyCount);
    changeRetweetCount(settings.retweetCount);
    changeLikeCount(settings.likeCount);
    changeSidebarSetting('logo', settings.sidebarLogo);
    changeNavigationButtonsLabels(settings.navigationButtonsLabels);
    changeNavigationCenter(settings.navigationCenter);
    changeUnreadCountBadge(settings.unreadCountBadge);
    hideGrokDrawer(settings.hideGrokDrawer);
    changeInterFont();
    changeHideSearchBar(settings.searchBar);
    applySearchBarPosition();
    changeTransparentSearchBar(settings.transparentSearch);
    changeTitleNotifications(settings.titleNotifications);
    changeTweetButton(settings.tweetButton);
    changeHomeButton();
    changeExploreButton();
    changeNotificationsButton();
    changeMessagesButton();
    changeBookmarksButton();
    changeJobsButton();
    changeCommunitiesButton();
    changeListsButton();
    pinListsToSidebar();
    moveProfileLinkToBottom();
    hideIconlessNavEntries();
    changeProfileButton();
    changeGrokButton();
    changeXPremiumButton();
    changeVerifiedOrgsButton();
    changeTopicsButton();
    changeArticlesButton();
    changeCreatorCenterButton();
    applyCreatorStudioFallback();
    changeAccountSwitcherButton();
    changeCustomCss(settings.customCss);
    createFloatingButton();
  }

  function changeTrendsHomeTimeline() {
    const isHome = window.location.pathname === '/' || window.location.pathname.includes('/home');
    if (settings.writerMode === 'on' || window.location.pathname.includes('compose/tweet') || !isHome) {
      removeStyles('trendsHomeTimeline');
      return;
    }
    if (settings.trendsHomeTimeline === 'on') {
      if (!stylesExist('trendsHomeTimeline')) {
        addStyles('trendsHomeTimeline', `
          @keyframes render {
            from {
              opacity: 0;
            }
            to {
              opacity: 1;
              transform: none;
            }
          }
          @media only screen and (min-width: 1265px) {
            ${SELECTORS.rightSidebar} section[aria-labelledby^="accessible-list-"] {
              visibility: visible;
              position: fixed;
              right: 16px;
              top: 66px;
              max-height: 78vh;
              overflow: auto;
              width: 300px;
              border-radius: 16px;
              border-color: var(--border-color);
              border-width: 1px;
              background-color: var(--body-bg-color);
              opacity: 0;
              will-change: opacity;
              animation-name: render;
              animation-duration: 0s;
              animation-fill-mode: forwards;
              animation-delay: 500ms;
              margin-top: 4px;
            }
            [data-testid="primaryColumn"] {
              transform: translateX(-64px);
            }
          }
        `);
      }
    } else {
      removeStyles('trendsHomeTimeline');
    }
  }

  function changeInterFont() {
    if (settings.interFont === 'on') {
      addStyles('interFont', `
        @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');
        div, span, input, textarea {
          font-family: Inter, TwitterChirp, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif !important;
        }
      `);
    } else {
      removeStyles('interFont');
    }
  }

  function changeHomeButton() { changeSidebarSetting('home', settings.homeButton); }
  function changeExploreButton() { changeSidebarSetting('explore', settings.exploreButton); }
  function changeNotificationsButton() { changeSidebarSetting('notifications', settings.notificationsButton); }
  function changeMessagesButton() { changeSidebarSetting('messages', settings.messagesButton); }
  function changeBookmarksButton() { changeSidebarSetting('bookmarks', settings.bookmarksButton); }
  function changeJobsButton() { changeSidebarSetting('jobs', settings.jobsButton); }
  function changeCommunitiesButton() { changeSidebarSetting('communities', settings.communitiesButton); }
  function changeListsButton() { changeSidebarSetting('lists', settings.listsButton); }
  function changeProfileButton() { changeSidebarSetting('profile', settings.profileButton); }
  function changeGrokButton() { changeSidebarSetting('grok', settings.grokButton); }
  function changeXPremiumButton() { changeSidebarSetting('xPremium', settings.xPremiumButton); }
  function changeVerifiedOrgsButton() { changeSidebarSetting('verifiedOrgs', settings.verifiedOrgsButton); }
  function changeTopicsButton() { changeSidebarSetting('topics', settings.topicsButton); }
  function changeArticlesButton() { changeSidebarSetting('articles', settings.articles); }
  function changeCreatorCenterButton() { changeSidebarSetting('creatorCenter', settings.creatorCenterButton); }

  // Creator Studio/Center 条目可能无稳定 href/testid(真机反馈 CSS 选择器未命中),
  // 用 aria-label + 可见文本兑底识别,直接内联隐藏;开启时仅清除本脚本标记的隐藏
  const CREATOR_STUDIO_TEXT_RE = /creator\s*(studio|center|centre)|创作者中心|創作者中心/i;
  function findCreatorStudioEntry() {
    const nav = document.querySelector(SELECTORS.leftSidebarLinks);
    if (!nav) return null;
    return nav.querySelector('[data-testid*="reator"], a[href*="creator"]')
      || Array.from(nav.querySelectorAll('a[role="link"]')).find(a =>
        CREATOR_STUDIO_TEXT_RE.test((a.getAttribute('aria-label') || '') + ' ' + (a.textContent || '')));
  }
  function applyCreatorStudioFallback() {
    const el = findCreatorStudioEntry();
    if (!el) return;
    if (getStorage('creatorCenterButton') === 'off') {
      el.dataset.mtCreatorHidden = '1';
      el.style.display = 'none';
    } else if (el.dataset.mtCreatorHidden === '1') {
      delete el.dataset.mtCreatorHidden;
      el.style.display = '';
    }
  }
  function changeAccountSwitcherButton() { changeSidebarSetting('accountSwitcher', settings.accountSwitcherButton); }

  // X 的 Lists 页面链接是 /{username}/lists,而不是 /lists,需要动态生成
  function getListsHref() {
    const profileLink = document.querySelector('[data-testid="AppTabBar_Profile_Link"]');
    if (profileLink) {
      const path = new URL(profileLink.getAttribute('href') || '', window.location.origin).pathname;
      const usernamePath = path.replace(/\/+$/, '');
      if (usernamePath) return usernamePath + '/lists';
    }
    // 回退:复用页面中已存在的 Lists 链接(例如 More 菜单里的)
    const existingLink = document.querySelector('a[href*="/lists"][role="link"][aria-label]:not(#mt-sidebar-lists)');
    if (existingLink) return existingLink.getAttribute('href');
    return '/lists';
  }

  // 将 Lists 直接固定到左侧竖向导航栏(X 默认把它收在 More 菜单里)
  function pinListsToSidebar() {
    const nav = document.querySelector(SELECTORS.leftSidebarLinks);
    if (!nav) return;
    // 关闭时立即移除已固定的 Lists 项(不能只靠 CSS 隐藏,ID 优先级会覆盖隐藏规则)
    if (settings.listsButton !== 'on') {
      document.getElementById('mt-sidebar-lists')?.remove();
      return;
    }
    const listsHref = getListsHref();

    // 已固定:切换账号后更新链接
    const existing = document.getElementById('mt-sidebar-lists');
    if (existing) {
      if (existing.getAttribute('href') !== listsHref) existing.setAttribute('href', listsHref);
      return;
    }
    // 导航栏里已有原生 Lists,不重复添加
    if (nav.querySelector('a[href*="lists"][role="link"][aria-label]')) return;

    const item = document.createElement('a');
    item.id = 'mt-sidebar-lists';
    item.href = listsHref;
    item.setAttribute('role', 'link');
    item.setAttribute('aria-label', 'Lists');
    // 结构与其他导航项一致(icon 包裹层 + 标签层),hover 显示标签的 CSS 会自动生效
    item.innerHTML = `
      <div dir="ltr">
        <div>
          <svg viewBox="0 0 24 24" aria-hidden="true">
            <path d="M3 4.5C3 3.12 4.12 2 5.5 2h13C19.88 2 21 3.12 21 4.5v15c0 1.38-1.12 2.5-2.5 2.5h-13C4.12 22 3 20.88 3 19.5v-15zM5.5 4c-.28 0-.5.22-.5.5v15c0 .28.22.5.5.5h13c.28 0 .5-.22.5-.5v-15c0-.28-.22-.5-.5-.5h-13zM7 6h10v2H7V6zm0 4h10v2H7v-2zm0 4h6v2H7v-2z"></path>
          </svg>
        </div>
        <div>
          <span dir="ltr">Lists</span>
        </div>
      </div>
    `;

    // 插到 More 按钮之前;找不到则插到账户切换器之前,再不行就追加到末尾
    const moreButton = nav.querySelector('[data-testid="SideNav_MoreButton"], button[aria-label="More"]');
    if (moreButton) {
      nav.insertBefore(item, moreButton);
    } else {
      const switcher = nav.querySelector('[data-testid="SideNav_AccountSwitcher_Button"]');
      if (switcher) {
        nav.insertBefore(item, switcher);
      } else {
        nav.appendChild(item);
      }
    }
  }

  // 左侧导航默认排序:启用项保持原生位置,仅把个人主页(Profile)移到最下。
  // 直接操作 DOM,与 pinListsToSidebar 同模式;MutationObserver 驱动的
  // runDynamicFeatures 会在 SPA 重渲染后重新应用(isMutationSkippable 跳过 nav 变动,无死循环)。
  function moveProfileLinkToBottom() {
    const nav = document.querySelector(SELECTORS.leftSidebarLinks);
    if (!nav) return;
    const profile = nav.querySelector('[data-testid="AppTabBar_Profile_Link"]');
    if (!profile || profile.parentElement !== nav) return;
    const switcher = document.querySelector(SELECTORS.accountSwitcherButton);
    const anchor = (switcher && switcher.parentElement === nav && switcher !== profile) ? switcher : null;
    if (anchor) {
      if (profile.nextElementSibling === anchor) return; // 已就位
      nav.insertBefore(profile, anchor);
    } else {
      if (!profile.nextElementSibling) return; // 已在末尾
      nav.appendChild(profile);
    }
  }

  // 去掉左侧导航中没有图标的条目(如“文章/Articles”):
  // 仅处理 nav 直接子级的 <a> 链接,无 svg/img 图标则内联隐藏并打标记;
  // 若之后 X 为其补上图标,则自动恢复。幂等,SPA 重渲染后由 runDynamicFeatures 重放。
  function hideIconlessNavEntries() {
    const nav = document.querySelector(SELECTORS.leftSidebarLinks);
    if (!nav) return;
    Array.from(nav.children).forEach(el => {
      if (el.tagName !== 'A' || el.id === 'mt-sidebar-lists') return;
      if (el.querySelector('svg, img')) {
        if (el.dataset.mtIconless === '1') {
          delete el.dataset.mtIconless;
          el.style.display = '';
        }
        return;
      }
      el.dataset.mtIconless = '1';
      el.style.display = 'none';
    });
  }

  // 移除了 changeHideViewCounts 的调用,它现在完全由 CSS 控制
  // Grok 路由切换时同步:打标记类 + 双向豁免/恢复冲突布局规则
  function applyGrokScopedLayouts() {
    syncGrokRouteFlag();
    if (isGrokRoute()) {
      removeStyles('timelineWidth');
      removeStyles('navigation-position');
    } else if (window.location.pathname.startsWith('/messages')) {
      // 私信页由 customDMsAndSearchStyle 接管侧栏布局(flex 弹性宽度、非固定)。
      // 这里若把 navigation-position 加回去,会与 flex 规则叠加导致左侧导航排版错乱。
      removeStyles('navigation-position');
    } else {
      changeTimelineWidth(settings.timelineWidth);
      updateLeftSidebarPositioning();
    }
  }

  const runDynamicFeatures = throttle(() => {
    if (settings.extensionStatus === 'off') return;
    applyGrokScopedLayouts();
    applySearchBarPosition();
    hideRightSidebar();
    addSmallerSearchBarStyle();
    changeTimelineTabs(settings.removeTimelineTabs, settings.writerMode);
    changeWriterMode(settings.writerMode);
    hideGrokDrawer(settings.hideGrokDrawer);
    pinListsToSidebar();
    applyCreatorStudioFallback();
    moveProfileLinkToBottom();
    hideIconlessNavEntries();
  }, 80); // 稍微放宽节流时间

  function injectMainStyles() {
    const css = `
      [data-testid="placementTracking"] article,
      a[href*="quick_promote_web"] {
        display: none;
      }
      [data-testid="DMDrawer"] {
        visibility: hidden;
      }
      @media only screen and (min-width: 1000px) {
        /* 以下主列布局规则仅作用于非 Grok 页:Grok 聊天布局下会错位(html:not(.mt-grok-page) 豁免) */
        html:not(.mt-grok-page) main[role="main"] {
          align-items: center;
          overflow-x: clip;
        }
        html:not(.mt-grok-page) [data-testid="primaryColumn"] {
          margin: 0 auto;
        }
        html:not(.mt-grok-page) [data-testid="primaryColumn"] > div > div:last-child,
        html:not(.mt-grok-page) [data-testid="primaryColumn"] > div > div:last-child div {
          max-width: unset;
        }
        header[role="banner"] {
          align-items: flex-start;
        }
        h1[role="heading"] {
          padding-top: 4px;
        }
        header[role="banner"] nav[role="navigation"]:hover > * > div {
          backdrop-filter: blur(12px);
        }
        header[role="banner"] > div > div > div > div:last-child {
          margin-bottom: 0px !important;
        }
        [data-testid="SideNav_AccountSwitcher_Button"] {
          bottom: 12px;
        }
        header[role="banner"] > div > div > div > div:first-child {
          flex-shrink: 1;
          overflow-y: auto;
        }
        html:not(.mt-grok-page) [data-testid="SideNav_NewTweet_Button"] {
          position: fixed;
          right: 16px;
          bottom: 24px;
        }
        /* Grok 页左侧导航不需要 Post 按钮 */
        html.mt-grok-page [data-testid="SideNav_NewTweet_Button"] {
          display: none;
        }
        header[role="banner"] > div > div > div {
          overflow: visible;
        }
      }
      [data-testid="sidebarColumn"] {
        margin-left: 12px;
      }
      /* 搜索框基础样式(原位 fixed 定位在 applySearchBarPosition 中按配置开启) */
      @media only screen and (min-width: 1100px) {
        [data-testid="sidebarColumn"] input[placeholder="Search Twitter"],
        [data-testid="sidebarColumn"] input[placeholder="Search X"] {
          width: 150px;
        }
        [data-testid="sidebarColumn"] form[role="search"]:focus-within {
          width: 374px;
          backdrop-filter: blur(12px);
        }
        [data-testid="sidebarColumn"] form[role="search"] input:focus {
          width: 100% !important;
        }
        /* 搜索建议下拉框跟随搜索框定位 */
        [data-testid="sidebarColumn"] form[role="search"] div[role="listbox"] {
          left: unset !important;
          width: 374px !important;
        }
        /* 搜索下拉定位 hack 仅作用于非 Grok 页,避免干扰聊天布局内同 inline-style 元素 */
        html:not(.mt-grok-page) div[style*="left: -12px"] {
          left: unset;
        }
        html:not(.mt-grok-page) div[style="left: -8px; width: 306px;"] {
          left: unset;
          width: 374px;
        }
      }
      .mt-sidebar-button > div > div[dir] {
        font-weight: 400;
      }
      .mt-sidebar-button:hover > div {
        background-color: rgba(var(--glyphs-color-rgb, 29, 155, 240), 0.1);
      }
      @media only screen and (max-width: 1264px) {
        .mt-sidebar-button > div > div[dir] {
          display: none;
        }
      }
      .mt-tooltip {
        position: absolute;
        display: flex;
        flex-direction: column;
        align-items: flex-start;
        justify-content: center;
        gap: 2px;
        background: var(--body-bg-color);
        color: var(--main-text-color);
        padding: 6px 8px;
        max-width: 250px;
        border-radius: 5px;
        box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08), 0 2px 14px rgba(0, 0, 0, 0.08);
        z-index: 9999;
        font-family: TwitterChirp, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
        transition: opacity 0.15s cubic-bezier(0.3, 0, 0.1, 1), transform 0.15s cubic-bezier(0.3, 0, 0.1, 1);
      }
      .mt-tooltip.hidden {
        opacity: 0;
        transform: translateY(3px);
        pointer-events: none;
      }
      .mt-tooltip .title {
        font-weight: 500;
        color: var(--main-text-color);
        font-size: 13px;
      }
      .mt-tooltip .description {
        color: var(--secondary-text-color);
        font-size: 12.5px;
      }

      /* 发推按钮强制蓝色背景 + 白色图标 */
      [data-testid="SideNav_NewTweet_Button"] {
        background-color: #1d9bf0 !important;
        color: #fff !important;
      }
      [data-testid="SideNav_NewTweet_Button"] svg {
        fill: #fff !important;
      }

      /* 固定到侧栏的 Lists 项 */
      #mt-sidebar-lists {
        display: flex;
        align-items: center;
        margin: 4px 0;
        padding: 12px;
        border-radius: 9999px;
        color: var(--main-text-color);
        transition: background-color 0.2s;
      }
      #mt-sidebar-lists:hover {
        background-color: rgba(var(--glyphs-color-rgb, 29, 155, 240), 0.1);
      }
      #mt-sidebar-lists > div[dir] {
        display: flex;
        align-items: center;
      }
      #mt-sidebar-lists svg {
        width: 26.25px;
        height: 26.25px;
        fill: currentColor;
      }
      #mt-sidebar-lists span {
        font-size: 20px;
        font-weight: 400;
        line-height: 24px;
        margin-left: 20px;
        color: var(--main-text-color);
      }
      @media only screen and (max-width: 1264px) {
        #mt-sidebar-lists > div[dir] > div:last-child {
          display: none !important;
        }
      }
    `;
    GM_addStyle(css);
  }

  // 省略 createSettingsPanel、createFloatingButton 等 UI 函数,与原版完全相同
  function createSettingsPanel() {
    const existingPanel = document.getElementById('mt-settings-panel');
    if (existingPanel) {
      existingPanel.remove();
      document.getElementById('mt-settings-overlay')?.remove();
      return;
    }

    const isDark = document.documentElement.style.backgroundColor === 'rgb(0, 0, 0)'
      || document.querySelector('meta[name="theme-color"]')?.content === '#000000';

    const colors = isDark ? {
      bg: '#000000',
      border: '#2f3336',
      text: '#e7e9ea',
      secondary: '#71767b',
      inputBg: '#16181c',
      shadow: 'rgba(255,255,255,0.08)',
    } : {
      bg: '#ffffff',
      border: '#cfd9de',
      text: '#0f1419',
      secondary: '#536471',
      inputBg: '#f7f9f9',
      shadow: 'rgba(0,0,0,0.08)',
    };

    const styleId = 'mt-settings-panel-styles';
    if (!document.getElementById(styleId)) {
      const styleEl = document.createElement('style');
      styleEl.id = styleId;
      styleEl.textContent = `
        #mt-settings-overlay{position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(91,112,131,0.4);z-index:9999;}
        #mt-settings-panel{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);width:92%;max-width:520px;max-height:84vh;background:${colors.bg};border:1px solid ${colors.border};border-radius:16px;z-index:10000;overflow:hidden;display:flex;flex-direction:column;box-shadow:0 0 0 1px ${colors.shadow},0 8px 40px ${isDark ? 'rgba(0,0,0,0.6)' : 'rgba(0,0,0,0.12)'};}
        #mt-settings-panel *{box-sizing:border-box;}
        #mt-settings-header{display:flex;justify-content:space-between;align-items:center;padding:14px 20px;border-bottom:1px solid ${colors.border};background:${colors.bg};flex-shrink:0;}
        #mt-settings-header h2{margin:0;font-size:17px;font-weight:700;color:${colors.text};}
        #mt-settings-close{background:none;border:none;cursor:pointer;padding:6px 10px;color:${colors.secondary};font-size:22px;line-height:1;border-radius:999px;transition:background 0.2s;}
        #mt-settings-close:hover{background:${isDark ? 'rgba(239,243,244,0.1)' : 'rgba(15,20,25,0.08)'};color:${colors.text};}
        #mt-settings-content{overflow-y:auto;flex:1;padding:12px 20px 20px;}
        .mt-settings-section{margin-bottom:20px;}
        .mt-settings-section h3{font-size:13px;font-weight:700;color:${colors.secondary};margin:0 0 10px 0;text-transform:uppercase;letter-spacing:0.3px;}
        .mt-row{display:flex;justify-content:space-between;align-items:center;padding:10px 0;border-bottom:1px solid ${colors.border};}
        .mt-row:last-child{border-bottom:none;}
        .mt-label{font-size:14px;color:${colors.text};line-height:1.4;flex:1;padding-right:12px;}
        .mt-toggle{position:relative;width:44px;height:26px;background:${isDark ? '#536471' : '#cfd9de'};border-radius:13px;cursor:pointer;transition:background 0.2s;flex-shrink:0;}
        .mt-toggle.on,.mt-toggle.hide{background:#1d9bf0;}
        .mt-toggle::after{content:'';position:absolute;top:3px;left:3px;width:20px;height:20px;background:#fff;border-radius:50%;transition:transform 0.2s;box-shadow:0 1px 2px rgba(0,0,0,0.15);}
        .mt-toggle.on::after,.mt-toggle.hide::after{transform:translateX(18px);}
        .mt-select{padding:6px 28px 6px 12px;border-radius:6px;border:1px solid ${colors.border};background:${colors.inputBg};color:${colors.text};font-size:13px;cursor:pointer;appearance:none;-webkit-appearance:none;background-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 width=%2712%27 height=%2712%27 viewBox=%270 0 12 12%27%3E%3Cpath fill=%27${encodeURIComponent(colors.secondary)}%27 d=%27M6 8.825L1.175 4 2.238 2.938 6 6.7 9.763 2.937 10.825 4z%27/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 8px center;flex-shrink:0;}
        .mt-select:focus{outline:none;border-color:#1d9bf0;}
        .mt-custom-css{width:100%;min-height:100px;padding:12px;border-radius:8px;border:1px solid ${colors.border};background:${colors.inputBg};color:${colors.text};font-family:monospace;font-size:12px;line-height:1.5;resize:vertical;}
        .mt-custom-css:focus{outline:none;border-color:#1d9bf0;}
        .mt-custom-css::placeholder{color:${colors.secondary};}
      `.replace(/\s+/g, ' ').trim();
      document.head.appendChild(styleEl);
    }

    const overlay = document.createElement('div');
    overlay.id = 'mt-settings-overlay';

    const panel = document.createElement('div');
    panel.id = 'mt-settings-panel';

    panel.innerHTML = `
      <div id="mt-settings-header">
        <h2>Minimal Twitter Settings</h2>
        <button id="mt-settings-close">\u00d7</button>
      </div>
      <div id="mt-settings-content">
        <div class="mt-settings-section">
          <h3 data-i18n="section.general">General</h3>
          <div class="mt-row">
            <span class="mt-label">Language</span>
            <select class="mt-select" data-setting="panelLanguage">
              <option value="auto">Auto</option>
              <option value="en">English</option>
              <option value="zh-CN">简体中文</option>
              <option value="zh-TW">繁體中文</option>
            </select>
          </div>
          <div class="mt-row">
            <span class="mt-label">Settings Button</span>
            <div class="mt-toggle" data-setting="showFloatingButton"></div>
          </div>
        </div>
        <div class="mt-settings-section">
          <h3 data-i18n="section.timeline">Timeline</h3>
          <div class="mt-row">
            <span class="mt-label">Timeline Width</span>
            <select class="mt-select" data-setting="timelineWidth">
              <option value="600">600px</option>
              <option value="650">650px</option>
              <option value="700">700px</option>
              <option value="750">750px</option>
              <option value="800">800px</option>
              <option value="900">900px</option>
              <option value="1000">1000px</option>
              <option value="1100">1100px</option>
              <option value="1200">1200px</option>
            </select>
          </div>
          <div class="mt-row">
            <span class="mt-label">Remove Timeline Borders</span>
            <div class="mt-toggle" data-setting="timelineBorders"></div>
          </div>
          <div class="mt-row">
            <span class="mt-label">Remove Tweet Borders</span>
            <div class="mt-toggle" data-setting="tweetBorders"></div>
          </div>
          <div class="mt-row">
             <span class="mt-label">Sticky Header</span>
             <div class="mt-toggle" data-setting="stickyHeader"></div>
           </div>
          <div class="mt-row">
            <span class="mt-label">Default to Following Timeline</span>
            <div class="mt-toggle" data-setting="followingTimeline"></div>
          </div>
          <div class="mt-row">
            <span class="mt-label">Remove Timeline Tabs</span>
            <div class="mt-toggle" data-setting="removeTimelineTabs"></div>
          </div>
          <div class="mt-row">
            <span class="mt-label">Writer Mode</span>
            <div class="mt-toggle" data-setting="writerMode"></div>
          </div>
        </div>
        <div class="mt-settings-section">
          <h3 data-i18n="section.content">Content</h3>
          <div class="mt-row">
            <span class="mt-label">Remove Promoted Posts</span>
            <div class="mt-toggle" data-setting="removePromotedPosts"></div>
          </div>
          <div class="mt-row">
            <span class="mt-label">Remove Topics to Follow</span>
            <div class="mt-toggle" data-setting="removeTopicsToFollow"></div>
          </div>
          <div class="mt-row">
            <span class="mt-label">Hide View Count</span>
             <div class="mt-toggle" data-setting="hideViewCount"></div>
          </div>
          <div class="mt-row">
            <span class="mt-label">Hide Follow Count</span>
            <div class="mt-toggle" data-setting="followCount"></div>
          </div>
          <div class="mt-row">
            <span class="mt-label">Hide Reply Count</span>
            <div class="mt-toggle" data-setting="replyCount"></div>
          </div>
          <div class="mt-row">
            <span class="mt-label">Hide Retweet Count</span>
            <div class="mt-toggle" data-setting="retweetCount"></div>
          </div>
          <div class="mt-row">
            <span class="mt-label">Hide Like Count</span>
            <div class="mt-toggle" data-setting="likeCount"></div>
          </div>
        </div>
        <div class="mt-settings-section">
          <h3 data-i18n="section.navigation">Navigation</h3>
          <div class="mt-row">
            <span class="mt-label">Navigation Labels</span>
            <select class="mt-select" data-setting="navigationButtonsLabels">
              <option value="never">Never</option>
              <option value="always">Always</option>
              <option value="hover">On Hover</option>
            </select>
          </div>
          <div class="mt-row">
            <span class="mt-label">Home</span>
            <div class="mt-toggle" data-setting="homeButton"></div>
          </div>
          <div class="mt-row">
            <span class="mt-label">Explore</span>
            <div class="mt-toggle" data-setting="exploreButton"></div>
          </div>
          <div class="mt-row">
            <span class="mt-label">Notifications</span>
            <div class="mt-toggle" data-setting="notificationsButton"></div>
          </div>
          <div class="mt-row">
            <span class="mt-label">Messages</span>
            <div class="mt-toggle" data-setting="messagesButton"></div>
          </div>
          <div class="mt-row">
            <span class="mt-label">Grok</span>
            <div class="mt-toggle" data-setting="grokButton"></div>
          </div>
          <div class="mt-row">
            <span class="mt-label">Premium</span>
            <div class="mt-toggle" data-setting="xPremiumButton"></div>
          </div>
          <div class="mt-row">
            <span class="mt-label">Verified Orgs</span>
            <div class="mt-toggle" data-setting="verifiedOrgsButton"></div>
          </div>
          <div class="mt-row">
            <span class="mt-label">Communities</span>
            <div class="mt-toggle" data-setting="communitiesButton"></div>
          </div>
          <div class="mt-row">
            <span class="mt-label">Profile</span>
            <div class="mt-toggle" data-setting="profileButton"></div>
          </div>
          <div class="mt-row">
            <span class="mt-label">Bookmarks</span>
            <div class="mt-toggle" data-setting="bookmarksButton"></div>
          </div>
          <div class="mt-row">
            <span class="mt-label">Lists</span>
            <div class="mt-toggle" data-setting="listsButton"></div>
          </div>
          <div class="mt-row">
            <span class="mt-label">Jobs</span>
            <div class="mt-toggle" data-setting="jobsButton"></div>
          </div>
          <div class="mt-row">
            <span class="mt-label">Topics</span>
            <div class="mt-toggle" data-setting="topicsButton"></div>
          </div>
          <div class="mt-row">
            <span class="mt-label">Articles</span>
            <div class="mt-toggle" data-setting="articles"></div>
          </div>
          <div class="mt-row">
            <span class="mt-label">Creator Center</span>
            <div class="mt-toggle" data-setting="creatorCenterButton"></div>
          </div>
          <div class="mt-row">
            <span class="mt-label">Center Navigation</span>
            <div class="mt-toggle" data-setting="navigationCenter"></div>
          </div>
          <div class="mt-row">
            <span class="mt-label">Unread Badge</span>
            <div class="mt-toggle" data-setting="unreadCountBadge"></div>
          </div>
          <div class="mt-row">
            <span class="mt-label">Account Switcher</span>
            <div class="mt-toggle" data-setting="accountSwitcherButton"></div>
          </div>
          <div class="mt-row">
            <span class="mt-label">Hide Grok Drawer</span>
            <div class="mt-toggle" data-setting="hideGrokDrawer"></div>
          </div>
        </div>
        <div class="mt-settings-section">
          <h3 data-i18n="section.interface">Interface</h3>
          <div class="mt-row">
            <span class="mt-label">Search Bar</span>
             <div class="mt-toggle" data-setting="searchBar"></div>
          </div>
          <div class="mt-row">
            <span class="mt-label">Transparent Search Bar</span>
            <div class="mt-toggle" data-setting="transparentSearch"></div>
          </div>
          <div class="mt-row">
            <span class="mt-label">Tweet Button</span>
             <div class="mt-toggle" data-setting="tweetButton"></div>
          </div>
          <div class="mt-row">
            <span class="mt-label">Use Inter Font</span>
            <div class="mt-toggle" data-setting="interFont"></div>
          </div>
        </div>
        <div class="mt-settings-section">
          <h3 data-i18n="section.customCss">Custom CSS</h3>
          <textarea class="mt-custom-css" data-setting="customCss" placeholder="Paste custom CSS here..."></textarea>
        </div>
      </div>
    `;

    // 按 panelLanguage 填充面板文案(模板内英文文案作为回退)
    const applyPanelI18n = () => {
      panel.querySelector('#mt-settings-header h2').textContent = t('panel.title');
      panel.querySelectorAll('h3[data-i18n]').forEach(h => { h.textContent = t(h.dataset.i18n); });
      panel.querySelectorAll('.mt-label[data-i18n]').forEach(l => { l.textContent = t(l.dataset.i18n); });
      panel.querySelectorAll('button[data-i18n]').forEach(b => { b.textContent = t(b.dataset.i18n); });
      panel.querySelectorAll('.mt-row').forEach(row => {
        const control = row.querySelector('[data-setting]');
        const label = row.querySelector('.mt-label');
        if (control && label) label.textContent = t('row.' + control.dataset.setting);
      });
      const labelsSelect = panel.querySelector('select[data-setting="navigationButtonsLabels"]');
      if (labelsSelect) {
        const optionKeys = ['never', 'always', 'hover'];
        labelsSelect.querySelectorAll('option').forEach((opt, i) => {
          opt.textContent = t('option.' + optionKeys[i]);
        });
      }
      const cssArea = panel.querySelector('.mt-custom-css');
      if (cssArea) cssArea.placeholder = t('placeholder.customCss');
    };
    applyPanelI18n();

    // 导航排序编辑器:上下移即时保存并生效(setStorage → applyAllFeatures → applyNavOrder)
    const toggleNext = (setting) => {
      const cur = getStorage(setting);
      if (cur === 'on' || cur === 'hide') return 'off';
      if (cur === 'off' || cur === 'show') return 'on';
      return 'on';
    };

    const toggleActiveClass = (setting) => {
      const val = getStorage(setting);
      return val === 'on' || val === 'hide';
    };

    panel.querySelectorAll('.mt-toggle').forEach(toggle => {
      const setting = toggle.dataset.setting;

      if (toggleActiveClass(setting)) {
        toggle.classList.add(getStorage(setting));
      }

      toggle.addEventListener('click', () => {
        const current = getStorage(setting);
        let next;

        if (setting === 'followCount' || setting === 'replyCount' || setting === 'retweetCount' || setting === 'likeCount') {
          next = current === 'hide' ? 'show' : 'hide';
        } else if (setting === 'stickyHeader') {
          next = current === 'on' ? 'off' : 'on';
        } else {
          next = toggleNext(setting);
        }

        setStorage(setting, next);

        toggle.className = 'mt-toggle';
        if (next === 'on' || next === 'hide') {
          toggle.classList.add(next);
        }
      });
    });

    panel.querySelectorAll('.mt-select').forEach(select => {
      const setting = select.dataset.setting;
      select.value = String(getStorage(setting));
      select.addEventListener('change', () => {
        setStorage(setting, select.value);
        if (setting === 'panelLanguage') {
          // 切换语言后重建面板以刷新全部文案
          panel.remove();
          overlay.remove();
          createSettingsPanel();
        }
      });
    });

    const customCssArea = panel.querySelector('.mt-custom-css');
    customCssArea.value = getStorage('customCss') || '';
    customCssArea.addEventListener('input', debounce(() => {
      setStorage('customCss', customCssArea.value);
    }, 400));

    const closePanel = () => {
      panel.remove();
      overlay.remove();
    };

    overlay.addEventListener('click', closePanel);
    document.body.appendChild(overlay);
    document.body.appendChild(panel);
    panel.querySelector('#mt-settings-close').addEventListener('click', closePanel);
  }

  function createFloatingButton() {
    // 用户可配置:关闭时不创建并移除已有按钮(仍可通过油猴菜单打开设置)
    if (settings.showFloatingButton === 'off') {
      document.getElementById('mt-floating-button')?.remove();
      return;
    }
    if (document.getElementById('mt-floating-button')) return;
    const button = document.createElement('div');
    button.id = 'mt-floating-button';
    button.innerHTML = `
      <style>
        #mt-floating-button {
          position: fixed;
          bottom: 80px;
          right: 16px;
          width: 48px;
          height: 48px;
          background: #1d9bf0;
          border-radius: 50%;
          cursor: pointer;
          z-index: 9998;
          display: flex;
          align-items: center;
          justify-content: center;
          box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
          transition: transform 0.2s, box-shadow 0.2s;
        }
        #mt-floating-button:hover {
          transform: scale(1.1);
          box-shadow: 0 6px 16px rgba(0, 0, 0, 0.2);
        }
        #mt-floating-button svg {
          width: 24px;
          height: 24px;
          fill: white;
        }
      </style>
      <svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
        <path d="M12 3C7.02944 3 3 7.02944 3 12C3 16.9706 7.02944 21 12 21C16.9706 21 21 16.9706 21 12C21 7.02944 16.9706 3 12 3ZM8 12C8 10.3431 9.34315 9 11 9H13C14.6569 9 16 10.3431 16 12C16 13.6569 14.6569 15 13 15H11C9.34315 15 8 13.6569 8 12ZM18.291 17.2907C17.0873 16.6758 14.8694 16 12 16C9.13056 16 6.91272 16.6758 5.70897 17.2907C5.15563 17.5412 5 17.9678 5 18.2061C5 19.3023 8.82484 20 12 20C15.1752 20 19 19.3023 19 18.2061C19 17.9678 18.8444 17.5412 18.291 17.2907Z"/>
      </svg>
    `;
    button.title = 'Minimal Twitter Settings';
    button.addEventListener('click', createSettingsPanel);
    document.body.appendChild(button);
  }

  function applyAllFeatures() {
    if (settings.extensionStatus === 'off') {
      Object.keys(styleElements).forEach(id => removeStyles(id));
      return;
    }
    applyStaticFeatures();
  }

  function init() {
    loadAllSettings();

    if (settings.extensionStatus === 'off') return;

    injectMainStyles();
    applyGrokScopedLayouts();
    applyAllFeatures();
    createFloatingButton();
    extractColorsAsRootVars();

    setTimeout(extractColorsAsRootVars, 3000);

    observer = new MutationObserver((mutations) => {
      if (!mutations.length || isMutationSkippable(mutations)) return;
      runDynamicFeatures();
    });

    // 缩小观察范围到 body,减少无关的 DOM 变动回调(仍监听整个 body,因为需要捕捉右侧栏等)
    observer.observe(document.body, {
      childList: true,
      subtree: true,
    });

    document.addEventListener('DOMContentLoaded', () => {
      runDynamicFeatures();
    });

    window.addEventListener('resize', debounce(() => {
      runDynamicFeatures();
    }, 100));

    GM_registerMenuCommand(t('panel.title'), createSettingsPanel);

    isInitialized = true;
  }

  if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', init);
  } else {
    init();
  }

  // SPA 路由感知:X 点击左侧导航(如私信/chat 按钮)走 pushState/replaceState,
  // 不会触发 popstate;而 MutationObserver 又会跳过 nav 内部的变动(isMutationSkippable),
  // 导致路由相关样式(私信页布局)与导航栏修复在点击导航后不生效。包装 history API 兜底。
  let lastRoutePath = window.location.pathname;
  function handleRouteChange() {
    if (!isInitialized || settings.extensionStatus === 'off') return;
    if (window.location.pathname === lastRoutePath) return;
    lastRoutePath = window.location.pathname;
    changeNavigationButtonsLabels(settings.navigationButtonsLabels); // 私信页专属布局/标签样式
    runDynamicFeatures();
    // X 渲染新页面有延迟,补两次兜底(各函数均幂等)
    setTimeout(runDynamicFeatures, 400);
    setTimeout(runDynamicFeatures, 1200);
  }
  ['pushState', 'replaceState'].forEach((type) => {
    const orig = history[type];
    if (typeof orig !== 'function') return;
    history[type] = function (...args) {
      const ret = orig.apply(this, args);
      handleRouteChange();
      return ret;
    };
  });

  window.addEventListener('popstate', debounce(() => {
    if (isInitialized && settings.extensionStatus !== 'off') {
      lastRoutePath = window.location.pathname; // 同步记录,避免后续同路径 pushState 被误判为未变化
      setTimeout(() => {
        applyAllFeatures();
        runDynamicFeatures();
      }, 500);
    }
  }, 100));

})();