Perplexity Widescreen & Compact & Code Collapser

V1.7.8: 聊天間距極致壓縮 | toolbar改絕對定位不覆蓋文字

As of 26. 03. 2026. See the latest version.

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 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         Perplexity Widescreen & Compact & Code Collapser
// @namespace    http://tampermonkey.net/
// @version      1.7.8
// @description  V1.7.8: 聊天間距極致壓縮 | toolbar改絕對定位不覆蓋文字
// @author       Custom
// @match        https://www.perplexity.ai/*
// @grant        GM_addStyle
// @grant        GM_setValue
// @grant        GM_getValue
// @run-at       document-end
// ==/UserScript==

(function () {
    'use strict';

    const MIN_W = 140, MAX_W = 380;
    let savedWidth = 185;
    try { savedWidth = Math.min(Math.max(GM_getValue('pplx_sidebar_width', 185), MIN_W), MAX_W); } catch(e){}

    const css = `
        /* SCROLLBAR */
        *::-webkit-scrollbar{display:none!important;width:0!important;height:0!important}
        *{scrollbar-width:none!important;-ms-overflow-style:none!important}
        .scrollable-container::-webkit-scrollbar{display:block!important;width:4px!important}
        .scrollable-container::-webkit-scrollbar-thumb{background:rgba(128,128,128,.25)!important;border-radius:2px!important}
        .scrollable-container{scrollbar-width:thin!important;-ms-overflow-style:auto!important}

        /* WIDESCREEN */
        html,body{max-width:100%!important;overflow-x:hidden!important}
        .scrollable-container{max-width:100%!important;width:100%!important;padding-left:16px!important;padding-right:12px!important}
        .scrollable-container>div{max-width:100%!important;width:100%!important}
        .scrollable-container div[class*="max-w-"],
        .scrollable-container section[class*="max-w-"],
        .scrollable-container article[class*="max-w-"],
        .scrollable-container main[class*="max-w-"]{max-width:100%!important}
        .scrollable-container .container,.scrollable-container .container.isolate{max-width:100%!important;width:100%!important;padding-left:0!important;padding-right:0!important}
        .scrollable-container .erp-sidecar,.scrollable-container [class*="erp-sidecar"]{max-width:100%!important;width:100%!important}
        .prose,.prose>*{max-width:100%!important;width:100%!important}

        /* HEADER */
        [class*="h-headerHeight"]{height:auto!important;min-height:0!important}
        [class*="containerheader"],[class*="container"][class*="header"]{height:auto!important;min-height:0!important;max-height:none!important}
        [role="tablist"] button[role="tab"]{padding-top:2px!important;padding-bottom:2px!important}
        [role="tablist"]{height:auto!important;gap:12px!important}

        /* PILL V0 極窄 */
        div[data-ask-input-container="true"]{max-width:520px!important;margin-left:auto!important;margin-right:auto!important}
        #ask-input{max-height:30vh!important;overflow-y:auto!important}
        div:has(>div[data-ask-input-container="true"]){padding-top:2px!important;padding-bottom:2px!important;margin-top:0!important;margin-bottom:0!important}

        /* ============================================================
           v1.7.8 CHAT SPACING — 黃框極致壓縮
           針對 scrollable-container 內的 flex gap 與 prose 間距
           ============================================================ */

        /* Q&A 區塊之間的縱向間距 */
        .scrollable-container .gap-y-lg{row-gap:6px!important}
        .scrollable-container .gap-y-md{row-gap:4px!important}
        .scrollable-container .gap-y-sm{row-gap:2px!important}

        /* 回答內部 flex 子項目間距 */
        .scrollable-container .gap-5{gap:6px!important}
        .scrollable-container .gap-4{gap:4px!important}
        .scrollable-container .gap-md{gap:4px!important}
        .scrollable-container .gap-sm{gap:2px!important}

        /* User query bubble 內距壓縮 */
        .scrollable-container .bg-subtle.rounded-2xl{padding:4px 10px!important}

        /* 回答 action bar (分享/複製/…) 上下距離 */
        .scrollable-container .flex.items-center.justify-between{padding-top:0!important;margin-top:0!important}

        /* 「已完成 X 個步驟」按鈕列 */
        .scrollable-container button.flex.items-center[class*="gap-sm"][class*="text-quiet"]{margin-top:0!important;margin-bottom:0!important;padding-top:0!important;padding-bottom:0!important}

        /* 「已使用 ... 準備」文字列 */
        .scrollable-container .text-sm.text-quiet[class*="font-sans"]{margin-top:0!important;margin-bottom:0!important;line-height:1.2!important}

        /* PROSE */
        .prose p,.prose li,.prose blockquote{line-height:1.35!important;margin-top:0!important;margin-bottom:2px!important;margin-block-start:0!important;margin-block-end:2px!important;padding-top:0!important;padding-bottom:0!important}
        .prose{margin-top:2px!important}
        .prose h1,.prose h2,.prose h3,.prose h4{margin-top:4px!important;margin-bottom:2px!important;line-height:1.25!important}
        .prose ul,.prose ol{margin-top:0!important;margin-bottom:2px!important;padding-left:1.2em!important}
        .prose li{margin:0!important}
        .prose hr{margin-top:4px!important;margin-bottom:4px!important}

        /* USER BUBBLE */
        main [class*="justify-end"]{position:relative!important}
        main [class*="justify-end"]>[class*="invisible"]{position:absolute!important;right:4px!important;top:4px!important;left:auto!important;z-index:20!important}
        main [class*="justify-end"]>div:last-child,
        main [class*="justify-end"]>*:last-child:not(button):not(svg){width:100%!important;max-width:100%!important;text-align:left!important}
        main [class*="ml-auto"]:not(button):not(svg):not(input){max-width:100%!important}
        main [class*="ms-auto"]:not(button):not(svg):not(input){max-width:100%!important}
        [class*="UserQuery"],[class*="user-query"],[class*="human"]{max-width:100%!important}

        /* SIDEBAR */
        div.w-sideBarWidth{flex-shrink:0!important;transition:width .05s!important}
        nav.groupsidebar,nav[class*="groupsidebar"]{overflow-x:hidden!important}
        nav span.w-full.overflow-hidden{display:block!important;white-space:nowrap!important;overflow:hidden!important;-webkit-mask-image:none!important;mask-image:none!important;line-height:1.3!important;max-height:1.3em!important}
        nav [class*="-ml-md"][class*="px-12px"]{width:9999px!important;min-width:unset!important;max-width:unset!important}

        /* COMPACT NAV */
        nav .flex.flex-none.flex-col{height:auto!important;min-height:0!important;gap:0!important;padding:0!important}
        nav a,nav button{padding-top:0!important;padding-bottom:0!important;margin-top:0!important;margin-bottom:0!important;min-height:0!important}
        nav a[href],nav button{height:auto!important;max-height:22px!important;line-height:1.2!important}
        nav a svg,nav button svg{width:14px!important;height:14px!important}
        nav [class*="gap-"]{gap:0!important}
        nav [class*="py-"]{padding-top:0!important;padding-bottom:0!important}
        nav [class*="my-"]{margin-top:0!important;margin-bottom:0!important}
        nav [class*="mt-"]{margin-top:0!important}
        nav [class*="mb-"]{margin-bottom:0!important}
        nav [class*="pt-"]{padding-top:0!important}
        nav [class*="pb-"]{padding-bottom:0!important}
        nav [class*="space-y"]>*{margin-top:1px!important}
        nav [class*="px-md"]{padding-left:4px!important;padding-right:4px!important}
        nav [class*="px-12px"]{padding-left:4px!important;padding-right:4px!important}
        nav [class*="pl-14px"]{padding-left:6px!important}
        nav [class*="ml-26px"]{margin-left:10px!important}
        nav [class*="-ml-md"]{margin-left:-4px!important}
        nav [class*="border-t"]{margin-top:0!important;margin-bottom:0!important}

        /* CODE */
        pre,code{max-width:100%!important;word-break:break-all!important;white-space:pre-wrap!important}

        /* ============================================================
           v1.7.8 CODE COLLAPSER — 紅框修正
           toolbar 改為 position:absolute 嵌入 .pplx-pre-container 內部
           pre 加 padding-top:36px 推開首行,toolbar 不再蓋到任何文字
           ============================================================ */
        .pplx-pre-container{
            position:relative!important;
            display:block!important;
            margin-top:2px!important;
            margin-bottom:2px!important}
        .pplx-code-wrapper{
            position:absolute!important;
            top:0!important;
            right:0!important;
            left:0!important;
            height:36px!important;
            width:100%!important;
            display:flex!important;
            justify-content:flex-end!important;
            align-items:center!important;
            z-index:10!important;
            pointer-events:none!important;
            overflow:visible!important}
        .pplx-pre-container>pre{
            padding-top:36px!important;  /* 首行推開,toolbar 不覆蓋任何代碼 */
            margin-top:0!important}
        .pplx-code-toolbar{
            pointer-events:auto!important;
            margin-right:6px!important;
            display:flex!important;
            flex-direction:row!important;
            align-items:center!important;
            gap:5px!important;
            background:var(--background-base-color,#ffffff)!important;
            border:1px solid rgba(14,165,233,.22)!important;
            padding:3px 6px 3px 8px!important;
            border-radius:20px!important;
            box-shadow:0 2px 8px rgba(14,165,233,.12)!important;
            max-width:calc(100% - 40px)!important;
            min-width:100px!important}
        .pplx-tb-left{display:flex!important;align-items:center!important;gap:4px!important;overflow:hidden!important;flex:1!important;min-width:0!important}
        .pplx-code-name{font-size:11px!important;font-weight:700!important;white-space:nowrap!important;overflow:hidden!important;text-overflow:ellipsis!important;color:#0ea5e9!important;user-select:none!important;background:rgba(14,165,233,.10)!important;padding:1px 7px 1px 5px!important;border-radius:10px!important;line-height:1.6!important;cursor:default!important}
        .pplx-code-name::before{content:'●';margin-right:4px;font-size:7px;vertical-align:middle;opacity:.7}
        .pplx-code-ver{font-size:10px!important;font-weight:500!important;white-space:nowrap!important;flex-shrink:0!important;color:#64748b!important;user-select:none!important;background:rgba(100,116,139,.10)!important;padding:1px 6px!important;border-radius:8px!important;line-height:1.6!important;cursor:default!important}
        .pplx-code-arrow{flex-shrink:0!important;cursor:pointer!important;color:#fff!important;font-size:10px!important;padding:2px 8px!important;border-radius:10px!important;background:#0ea5e9!important;transition:background .15s!important;user-select:none!important;line-height:1.5!important;font-weight:bold!important}
        .pplx-code-arrow:hover{background:#0284c7!important}
        .pplx-code-arrow.pplx-expanded{background:#0284c7!important}
        .pplx-code-copy{flex-shrink:0!important;cursor:pointer!important;font-size:13px!important;padding:2px 6px!important;border-radius:8px!important;line-height:1.4!important;transition:background .15s,transform .1s!important;user-select:none!important;margin-left:2px!important}
        .pplx-code-copy:hover{background:rgba(14,165,233,.15)!important;transform:scale(1.12)!important}
        .pplx-code-collapsed{max-height:0!important;min-height:0!important;overflow:hidden!important;opacity:.75!important;cursor:pointer!important;border-bottom:3px dashed #0ea5e9!important;padding:0!important;margin:0!important;transition:max-height .3s ease,opacity .2s!important}
        .pplx-code-collapsed:hover{opacity:1!important}

        /* DRAG HANDLE */
        #pplx-resize-handle{width:8px;height:100vh;position:fixed;top:0;left:var(--pplx-sidebar-width,185px);z-index:9999999;cursor:col-resize;background:transparent}
        #pplx-resize-handle::after{content:'';position:absolute;left:50%;top:0;bottom:0;width:1px;background:#22d3ee;transform:translateX(-50%)}
        #pplx-resize-handle:hover::after,#pplx-resize-handle.active::after{background:#06b6d4;width:2px}
        #pplx-drag-curtain{position:fixed;top:0;left:0;width:100vw;height:100vh;z-index:9999998;cursor:col-resize;display:none}
        body.pplx-resizing #pplx-drag-curtain{display:block}
        body.pplx-resizing *{user-select:none!important}

        /* GLOBAL COLLAPSE BTN */
        #pplx-global-collapse-btn{position:fixed!important;right:18px!important;bottom:60px!important;z-index:9999999!important;background:#0ea5e9!important;color:#fff!important;border:none!important;border-radius:20px!important;width:32px!important;height:32px!important;font-size:15px!important;cursor:pointer!important;box-shadow:0 3px 8px rgba(0,0,0,.25)!important;display:flex!important;align-items:center!important;justify-content:center!important;transition:transform .2s,background .2s!important;user-select:none!important}
        #pplx-global-collapse-btn:hover{transform:scale(1.08)!important;background:#0284c7!important}
    `;

    if (typeof GM_addStyle !== 'undefined') { GM_addStyle(css); }
    else { const s=document.createElement('style'); s.textContent=css; document.documentElement.appendChild(s); }

    // ============================================================
    // SIDEBAR
    // ============================================================
    function applySidebarWidth(px) {
        savedWidth = px;
        document.documentElement.style.setProperty('--pplx-sidebar-width', px + 'px');
        ['div.w-sideBarWidth','nav.groupsidebar','nav[class*="groupsidebar"]'].forEach(sel => {
            document.querySelectorAll(sel).forEach(el => {
                el.style.setProperty('width', px+'px','important');
                el.style.setProperty('min-width', px+'px','important');
                el.style.setProperty('max-width', px+'px','important');
            });
        });
        const h=document.getElementById('pplx-resize-handle');
        if(h)h.style.left=px+'px';
    }
    function watchSidebarElement(){
        const el=document.querySelector('div.w-sideBarWidth');
        if(!el||el._pplxWatched)return; el._pplxWatched=true;
        new MutationObserver(()=>{if(parseInt(el.style.width)!==savedWidth)applySidebarWidth(savedWidth);}).observe(el,{attributes:true,attributeFilter:['style']});
    }
    function fixThreadSectionWidth(){
        document.querySelectorAll('nav [style*="width: 200"]').forEach(el=>el.style.setProperty('width','9999px','important'));
        document.querySelectorAll('nav span[style*="mask-image"]').forEach(el=>{el.style.removeProperty('mask-image');el.style.removeProperty('-webkit-mask-image');});
    }
    function fixPageContentWidth(){
        document.querySelectorAll('[style*="--page-content-width"]').forEach(el=>{
            if(el.style.getPropertyValue('--page-content-width')!=='9999px')
                el.style.setProperty('--page-content-width','9999px');
        });
        document.querySelectorAll('[class*="bg-subtle"][class*="rounded-2xl"][style*="max-width"]').forEach(el=>{
            el.style.removeProperty('max-width');
        });
    }

    applySidebarWidth(savedWidth);
    setInterval(()=>{
        const el=document.querySelector('div.w-sideBarWidth');
        if(el&&parseInt(el.style.width)!==savedWidth)applySidebarWidth(savedWidth);
        fixThreadSectionWidth();
    },400);

    // ============================================================
    // 置底
    // ============================================================
    let scrollToBottomTimers=[];
    function scheduleScrollToBottom(){
        scrollToBottomTimers.forEach(t=>clearTimeout(t));
        scrollToBottomTimers=[];
        [300,700,1300,2500,4000].forEach(delay=>{
            scrollToBottomTimers.push(setTimeout(()=>{
                const sc=document.querySelector('.scrollable-container');
                if(sc)sc.scrollTop=sc.scrollHeight;
            },delay));
        });
    }

    let lastUrl=location.href, lastBubbleScan=0;
    function checkUrlChange(){
        if(location.href===lastUrl)return;
        lastUrl=location.href;
        lastBubbleScan=0;
        setTimeout(fixPageContentWidth,300);
        setTimeout(fixPageContentWidth,800);
        scheduleScrollToBottom();
    }

    function expandUserBubbles(){
        const now=Date.now();
        if(now-lastBubbleScan<600)return;
        lastBubbleScan=now;
        const sc=document.querySelector('.scrollable-container');
        if(!sc||sc.getBoundingClientRect().width<10)return;
        sc.querySelectorAll('[class*="justify-end"]').forEach(row=>{
            if(row._pplxRowFixed||row.children.length<2)return;
            const children=Array.from(row.children);
            const bubble=children[children.length-1];
            const ac=children.slice(0,-1).filter(c=>{
                const cls=typeof c.className==='string'?c.className:'';
                return cls.includes('invisible')||cls.includes('opacity-0')||c.querySelectorAll('button').length>0;
            });
            if(!ac.length)return;
            row._pplxRowFixed=true;row.style.position='relative';
            ac.forEach(el=>{el.style.position='absolute';el.style.right='4px';el.style.left='auto';el.style.top='4px';el.style.zIndex='20';});
            bubble.style.setProperty('width','100%','important');
            bubble.style.setProperty('max-width','100%','important');
            bubble.style.setProperty('text-align','left','important');
        });
    }

    function compressNavIcons(){
        ['32px','28px'].forEach(px=>{
            document.querySelectorAll(`nav [style*="width: ${px}"]`).forEach(el=>{
                if(el.style.width===px||el.style.minWidth===px){
                    el.style.setProperty('width','20px','important');
                    el.style.setProperty('min-width','20px','important');
                }
            });
        });
    }

    // ============================================================
    // CODE — 複製排除 language label
    // ============================================================
    const LANG_RE=/^(javascript|typescript|python|java|css|html|sql|bash|sh|shell|json|yaml|xml|go|rust|c\+\+|cpp|c#|ruby|php|swift|kotlin|r|matlab|scala|perl|lua|dart|vue|jsx|tsx|sass|scss|less|toml|ini|dockerfile|makefile|plaintext|text)$/i;
    function getCleanCode(pre){
        const codeEl=pre.querySelector('code');
        if(codeEl)return codeEl.innerText;
        const clone=pre.cloneNode(true);
        clone.querySelectorAll('[data-testid="code-language-indicator"]').forEach(el=>el.remove());
        clone.querySelectorAll('.pplx-code-toolbar,.pplx-code-wrapper').forEach(el=>el.remove());
        const raw=clone.innerText.trim();
        const lines=raw.split('\n');
        if(LANG_RE.test((lines[0]||'').trim()))return lines.slice(1).join('\n').trimStart();
        return raw;
    }

    let isGlobalCollapsed=true;
    function ensureGlobalBtn(){
        if(document.getElementById('pplx-global-collapse-btn')||!document.body)return;
        const btn=document.createElement('div');
        btn.id='pplx-global-collapse-btn';btn.textContent='⏬';btn.title='全域折疊/展開代碼';
        btn.onclick=()=>{
            isGlobalCollapsed=!isGlobalCollapsed;
            btn.textContent=isGlobalCollapsed?'⏬':'⏫';
            document.querySelectorAll('pre.pplx-processed').forEach(pre=>{
                const arrow=pre._pplxArrow;
                if(isGlobalCollapsed){pre.classList.add('pplx-code-collapsed');if(arrow){arrow.textContent='▼ 展開';arrow.classList.remove('pplx-expanded');}}
                else{pre.classList.remove('pplx-code-collapsed');if(arrow){arrow.textContent='▲ 折疊';arrow.classList.add('pplx-expanded');}}
            });
        };
        document.body.appendChild(btn);
    }

    // ============================================================
    // v1.7.8 processCodeBlocks — 使用 .pplx-pre-container 包裹 pre
    // toolbar 絕對定位於容器頂部,pre 加 padding-top:36px 推開首行
    // ============================================================
    function processCodeBlocks(){
        document.querySelectorAll('pre:not(.pplx-processed)').forEach(pre=>{
            pre.classList.add('pplx-processed');
            if(!pre.parentNode)return;

            const txt=pre.innerText||'';
            const nmMatch=txt.match(/@name\s+([^\n]+)/i);
            const vmMatch=txt.match(/@version\s+([^\n]+)/i);

            // 建立外層容器(包裹 toolbar + pre)
            const container=document.createElement('div');
            container.className='pplx-pre-container';

            // 建立 toolbar wrapper(absolute 定位,嵌入容器頂部)
            const wrap=document.createElement('div');
            wrap.className='pplx-code-wrapper';

            const tbar=document.createElement('div');
            tbar.className='pplx-code-toolbar';
            const left=document.createElement('div');
            left.className='pplx-tb-left';

            if(nmMatch){const n=document.createElement('span');n.className='pplx-code-name';n.textContent=nmMatch[1].trim();n.title=nmMatch[1].trim();left.appendChild(n);}
            if(vmMatch){const v=document.createElement('span');v.className='pplx-code-ver';v.textContent='v'+vmMatch[1].trim();left.appendChild(v);}

            const arrow=document.createElement('span');
            arrow.className='pplx-code-arrow';
            arrow.title='展開 / 折疊代碼';
            if(isGlobalCollapsed){arrow.textContent='▼ 展開';pre.classList.add('pplx-code-collapsed');}
            else{arrow.textContent='▲ 折疊';arrow.classList.add('pplx-expanded');}
            arrow.onclick=e=>{
                e.preventDefault();e.stopPropagation();
                const collapsed=pre.classList.toggle('pplx-code-collapsed');
                arrow.textContent=collapsed?'▼ 展開':'▲ 折疊';
                arrow.classList.toggle('pplx-expanded',!collapsed);
            };
            left.appendChild(arrow);

            const copyBtn=document.createElement('span');
            copyBtn.className='pplx-code-copy';copyBtn.textContent='📋';copyBtn.title='複製代碼';
            copyBtn.onclick=e=>{
                e.preventDefault();e.stopPropagation();
                const code=getCleanCode(pre);
                const fb=()=>{copyBtn.textContent='✅';setTimeout(()=>copyBtn.textContent='📋',2000);};
                if(navigator.clipboard)navigator.clipboard.writeText(code).then(fb).catch(()=>{const ta=document.createElement('textarea');ta.value=code;document.body.appendChild(ta);ta.select();document.execCommand('copy');document.body.removeChild(ta);fb();});
                else{const ta=document.createElement('textarea');ta.value=code;document.body.appendChild(ta);ta.select();document.execCommand('copy');document.body.removeChild(ta);fb();}
            };
            pre.onclick=()=>{if(pre.classList.contains('pplx-code-collapsed')){pre.classList.remove('pplx-code-collapsed');arrow.textContent='▲ 折疊';arrow.classList.add('pplx-expanded');}};

            tbar.appendChild(left);
            tbar.appendChild(copyBtn);
            wrap.appendChild(tbar);

            // 插入容器,將 wrap 與 pre 都放入容器中
            pre.parentNode.insertBefore(container, pre);
            container.appendChild(wrap);   // toolbar(absolute 定位在容器頂部)
            container.appendChild(pre);    // pre(有 padding-top:36px 推開首行)
            pre._pplxArrow=arrow;
        });
    }

    let isResizing=false,animId=null;
    function ensureResizeHandle(){
        if(document.getElementById('pplx-resize-handle')||!document.body)return;
        const h=document.createElement('div');h.id='pplx-resize-handle';h.title='拖曳側欄寬度 | 雙擊還原';
        const c=document.createElement('div');c.id='pplx-drag-curtain';
        document.body.appendChild(h);document.body.appendChild(c);
        h.addEventListener('mousedown',e=>{isResizing=true;h.classList.add('active');document.body.classList.add('pplx-resizing');e.preventDefault();});
        window.addEventListener('mousemove',e=>{if(!isResizing)return;if(animId)cancelAnimationFrame(animId);animId=requestAnimationFrame(()=>applySidebarWidth(Math.min(Math.max(e.clientX,MIN_W),MAX_W)));});
        window.addEventListener('mouseup',()=>{if(!isResizing)return;isResizing=false;h.classList.remove('active');document.body.classList.remove('pplx-resizing');try{GM_setValue('pplx_sidebar_width',savedWidth);}catch(_){}});
        h.addEventListener('dblclick',()=>{applySidebarWidth(185);try{GM_setValue('pplx_sidebar_width',185);}catch(_){}});
    }

    let originalTitle=document.title,tabState='IDLE',wasGenerating=false;
    function setTabState(s){let t=originalTitle;if(s==='GENERATING')t='【⏳】 '+originalTitle;else if(s==='DONE')t='【✅】 '+originalTitle;if(document.title!==t)document.title=t;}
    window.addEventListener('focus',()=>{if(tabState==='DONE'){tabState='IDLE';setTabState('IDLE');}});
    window.addEventListener('click',()=>{if(tabState==='DONE'){tabState='IDLE';setTabState('IDLE');}});
    function detectGenerating(){
        const stop=document.querySelector('button[aria-label*="Stop"],button[aria-label*="停止"]');
        const gen=!!(stop&&stop.offsetParent!==null);
        if(gen&&!wasGenerating){tabState='GENERATING';setTabState(tabState);wasGenerating=true;if(!originalTitle.includes('【'))originalTitle=document.title;}
        else if(!gen&&wasGenerating){tabState='DONE';setTabState(tabState);wasGenerating=false;}
        if(tabState==='IDLE'&&!document.title.includes('【'))originalTitle=document.title;
    }

    function maintainUI(){
        ensureResizeHandle();
        watchSidebarElement();
        ensureGlobalBtn();
        processCodeBlocks();
        detectGenerating();
        checkUrlChange();
        expandUserBubbles();
        compressNavIcons();
        fixPageContentWidth();
    }
    setInterval(maintainUI,300);
    maintainUI();
    scheduleScrollToBottom();
})();