Perplexity Widescreen & Compact & Code Collapser

v1.9.14: 穩定修正版號同步;箭頭僅保留icon與tooltip

Voor het installeren van scripts heb je een extensie nodig, zoals Tampermonkey, Greasemonkey of Violentmonkey.

Voor het installeren van scripts heb je een extensie nodig, zoals {tampermonkey_link:Tampermonkey}.

Voor het installeren van scripts heb je een extensie nodig, zoals Tampermonkey of Violentmonkey.

Voor het installeren van scripts heb je een extensie nodig, zoals Tampermonkey of Userscripts.

Voor het installeren van scripts heb je een extensie nodig, zoals {tampermonkey_link:Tampermonkey}.

Voor het installeren van scripts heb je een gebruikersscriptbeheerder nodig.

(Ik heb al een user script manager, laat me het downloaden!)

Voor het installeren van gebruikersstijlen heb je een extensie nodig, zoals {stylus_link:Stylus}.

Voor het installeren van gebruikersstijlen heb je een extensie nodig, zoals {stylus_link:Stylus}.

Voor het installeren van gebruikersstijlen heb je een extensie nodig, zoals {stylus_link:Stylus}.

Voor het installeren van gebruikersstijlen heb je een gebruikersstijlbeheerder nodig.

Voor het installeren van gebruikersstijlen heb je een gebruikersstijlbeheerder nodig.

Voor het installeren van gebruikersstijlen heb je een gebruikersstijlbeheerder nodig.

(Ik heb al een beheerder - laat me doorgaan met de installatie!)

// ==UserScript==
// @name         Perplexity Widescreen & Compact & Code Collapser
// @namespace    http://tampermonkey.net/
// @version      1.9.14
// @description  v1.9.14: 穩定修正版號同步;箭頭僅保留icon與tooltip
// @author       ford933
// @license      All Rights Reserved
// @match        https://www.perplexity.ai/*
// @grant        GM_addStyle
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_info
// @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{max-width:100%!important}
        body{max-width:100%!important;overflow-x:clip!important}
        .scrollable-container{max-width:100%!important;width:100%!important;padding-left:16px!important;padding-right:12px!important}
        .scrollable-container>div:not([data-radix-popper-content-wrapper]):not([data-radix-dropdown-menu-content]):not([style*="position: fixed"]):not([style*="position:fixed"]){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:not([data-radix-popper-content-wrapper] .prose),.prose>*:not([data-radix-popper-content-wrapper] *){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 */
        div[data-ask-input-container="true"]{max-width:520px!important;margin-left:auto!important;margin-right:auto!important}
        div:has(>div[data-ask-input-container="true"]){max-width:520px!important;margin-left:auto!important;margin-right:auto!important;contain:layout style!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}

        /* CHAT SPACING */
        .scrollable-container .gap-y-lg{row-gap:4px!important}
        .scrollable-container .gap-y-md{row-gap:2px!important}
        .scrollable-container .gap-y-sm{row-gap:1px!important}
        .scrollable-container .gap-5{gap:4px!important}
        .scrollable-container .gap-4{gap:2px!important}
        .scrollable-container .gap-md{gap:2px!important}
        .scrollable-container .gap-sm{gap:1px!important}
        .scrollable-container .mt-md:not(nav .mt-md):not(.prose .mt-md){margin-top:2px!important}
        .scrollable-container .mt-xs:not(nav .mt-xs):not(.prose .mt-xs){margin-top:0!important}
        .scrollable-container [class*="pt-md"]:not(nav [class*="pt-md"]):not(.prose [class*="pt-md"]){padding-top:2px!important}
        .scrollable-container [class*="pt-lg"]:not(nav [class*="pt-lg"]):not(.prose [class*="pt-lg"]){padding-top:2px!important}
        .scrollable-container .flex.items-center.justify-between{padding-top:0!important;margin-top:0!important}
        .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}

        /* TABLE */
        .scrollable-container table{border-collapse:separate!important;border-spacing:0!important}
        .scrollable-container table th{padding:3px 6px!important;min-width:40px!important;vertical-align:bottom!important;white-space:normal!important;word-break:break-word!important}
        .scrollable-container table td{padding:2px 6px!important;min-width:40px!important;vertical-align:top!important;white-space:normal!important;word-break:break-word!important}
        .scrollable-container .overflow-auto[class*="rounded"]{overflow-x:auto!important;max-width:100%!important;display:block!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}
        .scrollable-container [class*="grouptitle"]{display:flex!important;width:100%!important;max-width:100%!important;flex-direction:column!important}
        .scrollable-container [class*="groupquery"]{width:100%!important;max-width:100%!important}
        .scrollable-container [class*="rounded-tl-2xl"][class*="bg-subtle"]{max-width:100%!important;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 .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]:not([role="option"]):not([role="menuitem"]):not([data-radix-collection-item]):not([cmdk-item]),nav button:not([role="option"]):not([role="menuitem"]):not([data-radix-collection-item]):not([cmdk-item]){height:auto!important;max-height:22px!important;line-height:1.2!important}
        nav a:not([role="option"]):not([data-radix-collection-item]) svg,nav button:not([role="option"]):not([role="menuitem"]):not([data-radix-collection-item]) svg{width:14px!important;height:14px!important}

        nav [class*="gap-"]:not([role="listbox"]):not([role="menu"]):not([data-radix-popper-content-wrapper]):not([data-radix-select-content]){gap:0!important}
        nav [class*="py-"]:not([role="option"]):not([role="menuitem"]):not([data-radix-collection-item]):not([cmdk-item]){padding-top:0!important;padding-bottom:0!important}
        nav [class*="my-"]:not([role="option"]):not([role="menuitem"]):not([data-radix-collection-item]){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:2px!important;margin-bottom:2px!important}

        nav [class*="group"][class*="sidebar-sub-menu"] > div[class*="h-10"],
        nav [class*="group\/sidebar-sub-menu"] > div[class*="h-10"]{height:24px!important;min-height:24px!important;max-height:24px!important;padding-top:0!important;padding-bottom:0!important}
        nav [class*="group"][class*="sidebar-sub-menu"] > div[class*="h-7"],
        nav [class*="group\/sidebar-sub-menu"] > div[class*="h-7"]{height:20px!important;min-height:20px!important;max-height:20px!important;padding-top:0!important;padding-bottom:0!important}
        nav [class*="group"][class*="sidebar-sub-menu"] [class*="size-6"],
        nav [class*="group\/sidebar-sub-menu"] [class*="size-6"]{width:16px!important;height:16px!important;min-width:16px!important;min-height:16px!important}
        nav [class*="group"][class*="sidebar-sub-menu"] svg[width="18"],
        nav [class*="group\/sidebar-sub-menu"] svg[width="18"]{width:14px!important;height:14px!important}
        nav [class*="group"][class*="sidebar-sub-menu"] [class*="text-sm"],
        nav [class*="group\/sidebar-sub-menu"] [class*="text-sm"]{line-height:24px!important;font-size:11.5px!important}
        nav [class*="group"][class*="sidebar-sub-menu"] [class*="text-xs"],
        nav [class*="group\/sidebar-sub-menu"] [class*="text-xs"]{line-height:20px!important;font-size:11px!important}
        nav [class*="group"][class*="sidebar-sub-menu"] > div[class*="rounded-xl"],
        nav [class*="group\/sidebar-sub-menu"] > div[class*="rounded-xl"]{border-radius:6px!important}
        nav [class*="group"][class*="sidebar-sub-menu"] [class*="pl-sm"],
        nav [class*="group\/sidebar-sub-menu"] [class*="pl-sm"]{padding-left:4px!important}
        nav [class*="group"][class*="sidebar-sub-menu"] [class*="px-sm"],
        nav [class*="group\/sidebar-sub-menu"] [class*="px-sm"]{padding-left:4px!important;padding-right:4px!important}
        nav [class*="group"][class*="sidebar-sub-menu"] [class*="pr-3"]{padding-right:4px!important}
        nav [class*="group"][class*="sidebar-sub-menu"] button[class*="h-6"],
        nav [class*="group\/sidebar-sub-menu"] button[class*="h-6"]{height:18px!important;min-height:18px!important;padding:0!important}
        nav > div{gap:0!important}
        nav [class*="flex-col"]{gap:0!important}

        /* 隱藏被快捷鈕取代的 nav 列 */
        .pplx-hidden-nav-row{display:none!important}

        /* ── 新建行 position:relative,讓快捷鈕可 absolute 定位 ── */
        /* v1.9.3:+新建 icon 鈕,在 logo 正右方,獨立不融合 */
        #pplx-new-btn-header{
            display:inline-flex!important;align-items:center!important;justify-content:center!important;
            width:26px!important;height:26px!important;
            min-width:26px!important;min-height:26px!important;
            border-radius:6px!important;border:none!important;cursor:pointer!important;
            background:transparent!important;
            color:var(--text-quiet,currentColor)!important;
            opacity:.7!important;flex-shrink:0!important;
            text-decoration:none!important;
            margin-left:3px!important;margin-right:0!important;
            padding:0!important;
            transition:background 130ms,opacity 130ms!important;
            vertical-align:middle!important;
        }
        #pplx-new-btn-header:hover{background:rgba(128,128,128,.15)!important;opacity:1!important}
        #pplx-new-btn-header svg{width:15px!important;height:15px!important;display:block!important;stroke:currentColor!important;fill:none!important;pointer-events:none!important;}
        .pplx-newbtn-anchor{position:relative!important;overflow:visible!important}

        /* ── 快捷鈕群組:absolute 釘在行右端 ── */
        .pplx-hdr-shortcuts{
            position:absolute!important;
            right:2px!important;top:50%!important;
            transform:translateY(-50%)!important;
            display:flex!important;align-items:center!important;
            justify-content:flex-end!important;
            gap:0px!important;
            width:auto!important;
            max-width:calc(100% - 60px)!important;
            z-index:100!important;
            pointer-events:none!important;
            visibility:visible!important;opacity:1!important;
        }

        /* ── 快捷鈕本體 ── */
        a.pplx-hdr-btn{
            display:inline-flex!important;align-items:center!important;justify-content:center!important;
            flex:0 0 auto!important;
            height:22px!important;
            max-height:22px!important;min-height:22px!important;
            width:24px!important;min-width:24px!important;
            border-radius:5px!important;
            background:transparent!important;border:none!important;cursor:pointer!important;
            color:var(--text-quiet,currentColor)!important;
            opacity:.7!important;flex-shrink:0!important;
            text-decoration:none!important;
            padding:0!important;margin:0!important;
            line-height:1!important;
            transition:background 130ms,opacity 130ms!important;
            visibility:visible!important;pointer-events:auto!important;
            overflow:visible!important;box-sizing:border-box!important;
        }
        a.pplx-hdr-btn:hover{background:rgba(128,128,128,.15)!important;opacity:1!important}

        /* SVG 固定 14px — 覆蓋所有 nav svg 規則 */
        a.pplx-hdr-btn svg{
            width:14px!important;height:14px!important;
            min-width:14px!important;min-height:14px!important;
            max-width:14px!important;max-height:14px!important;
            display:block!important;pointer-events:none!important;
            stroke:currentColor!important;fill:none!important;
            overflow:visible!important;
        }

        /* Tooltip */
        a.pplx-hdr-btn::after{
            content:attr(data-tip);display:none;
            position:absolute;top:calc(100% + 4px);left:50%;
            transform:translateX(-50%);
            background:rgba(0,0,0,.82);color:#fff;
            font-size:11px;padding:2px 7px;border-radius:4px;
            white-space:nowrap;pointer-events:none;z-index:99999;
            font-family:sans-serif;font-weight:normal;
        }
        a.pplx-hdr-btn:hover::after{display:block}

        /* DROPDOWN RESET — 保護 Perplexity 原生彈層不被 nav rules 影響 */
        .bg-raised.shadow-overlay{max-width:none!important;width:auto!important;contain:none!important}
        .bg-raised.shadow-overlay *{max-width:none!important}
        [data-radix-popper-content-wrapper]{overflow:visible!important;max-height:none!important;height:auto!important;width:auto!important;max-width:none!important;transform-origin:unset!important}
        [role="listbox"],[role="menu"],[role="dialog"],[data-radix-select-content],[data-radix-dropdown-menu-content],[cmdk-root]{max-height:80vh!important;height:auto!important;overflow-y:auto!important;overflow-x:visible!important;width:auto!important;min-width:160px!important}
        [role="listbox"] *,[role="menu"] *,[data-radix-popper-content-wrapper] *,[data-radix-select-content] *,[data-radix-dropdown-menu-content] *{max-height:none!important;height:auto!important;line-height:normal!important;padding-top:revert!important;padding-bottom:revert!important;margin-top:revert!important;margin-bottom:revert!important;gap:revert!important;max-width:none!important;width:auto!important}
        [role="option"],[role="menuitem"],[data-radix-collection-item],[cmdk-item]{max-height:none!important;height:auto!important;min-height:28px!important;line-height:1.4!important;padding-top:4px!important;padding-bottom:4px!important;white-space:nowrap!important}

        /* CODE */
        pre,code{max-width:100%!important;word-break:break-all!important;white-space:pre-wrap!important}
        .pplx-pre-container{position:relative!important;display:block!important;overflow:visible!important;margin-top:2px!important;margin-bottom:2px!important}
        .pplx-code-wrapper{position:sticky!important;top:0!important;height:0!important;width:100%!important;display:flex!important;justify-content:flex-end!important;align-items:flex-start!important;z-index:200!important;pointer-events:none!important;overflow:visible!important}
        .pplx-pre-container>pre{padding-top:38px!important;margin-top:0!important}
        .pplx-code-toolbar{pointer-events:auto!important;margin-right:6px!important;margin-top:3px!important;display:flex!important;flex-direction:row!important;align-items:center!important;gap:0!important;background:var(--background-base-color,#ffffff)!important;border:1px solid rgba(14,165,233,.22)!important;padding:3px 4px 3px 8px!important;border-radius:20px!important;box-shadow:0 2px 10px rgba(14,165,233,.18)!important;max-width:calc(100% - 40px)!important;min-width:100px!important}
        .pplx-tb-left{display:flex!important;align-items:center!important;gap:2px!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,.pplx-code-copy,.pplx-code-download{flex-shrink:0!important;cursor:pointer!important;display:inline-flex!important;align-items:center!important;justify-content:center!important;width:24px!important;min-width:24px!important;height:24px!important;padding:0!important;margin-left:0!important;border-radius:8px!important;line-height:1!important;transition:background .15s,transform .1s!important;user-select:none!important}.pplx-code-arrow{color:#fff!important;background:#0ea5e9!important;font-weight:bold!important;font-size:12px!important}
        .pplx-code-arrow:hover{background:#0284c7!important;transform:scale(1.08)!important}
        .pplx-code-arrow.pplx-expanded{background:#0284c7!important}
        .pplx-code-copy,.pplx-code-download{font-size:13px!important;background:transparent!important}
        .pplx-code-copy:hover,.pplx-code-download: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 Width ──
    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');
                // 不強制 min-width,讓 Perplexity 原生折疊鈕可自由縮小
                el.style.removeProperty('min-width');
                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(() => { const _wm = parseInt(el.style.width); if (!isNaN(_wm) && _wm > 60 && _wm !== 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'); });
        document.querySelectorAll('[class*="bg-subtle"][class*="rounded-tl-2xl"][style*="max-width"]').forEach(el => { el.style.removeProperty('max-width'); });
        document.querySelectorAll('[class*="grouptitle"]').forEach(el => {
            if (getComputedStyle(el).display === 'inline-flex') {
                el.style.setProperty('display', 'flex', 'important');
                el.style.setProperty('width', '100%', 'important');
            }
        });
    }

    // ── 快捷鈕定義 ──
    const SHORTCUT_DEFS = [
        {
            label: '空間', href: '/spaces',
            svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 7c0-1.1.9-2 2-2h4l2 2h8a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><line x1="9" y1="13" x2="15" y2="13"/><line x1="12" y1="10" x2="12" y2="16"/></svg>`
        },
        {
            label: '成品', href: '/computer/artifacts',
            svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="8" height="8" rx="1.5"/><rect x="13" y="3" width="8" height="8" rx="1.5"/><rect x="3" y="13" width="8" height="8" rx="1.5"/><rect x="13" y="13" width="8" height="8" rx="1.5"/></svg>`
        },
        {
            label: '自訂', href: '/computer/connectors',
            svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06-.06a2 2 0 0 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"/></svg>`
        },
    ];

    const HIDDEN_LABELS = new Set(['空間', '成品', '自訂']);
    let shortcutsInjected = false;

    // ── v1.8.6 核心:找「新建」所在的 collapsible-sidebar-section
    //   對它加 position:relative,然後 append 一個 absolute 定位的快捷列
    //   完全不改變父層 flex 方向,不影響 nav 結構
    // ── v1.9.2:把 +新建 注入到 sidebar 頂部 header 列(logo 右方)──
    function injectNewBtnToHeader() {
        if (document.getElementById('pplx-new-btn-header')) return true;
        // 找 sidebar header:nav 第一個直接子 div
        const nav = document.querySelector('nav[class*="groupsidebar"]')
                 || document.querySelector('nav[class*="sidebar"]')
                 || document.querySelector('div.w-sideBarWidth nav');
        if (!nav) return false;
        const headerDiv = nav.firstElementChild;
        if (!headerDiv) return false;

        // 找 logo(第一個 a 元素)
        const logoA = headerDiv.querySelector('a');
        if (!logoA) return false;

        const newBtn = document.createElement('a');
        newBtn.id = 'pplx-new-btn-header';
        newBtn.href = '/';
        newBtn.setAttribute('aria-label', '新建');
        newBtn.title = '新建對話';
        // 只有 + 圖示,不加文字,保持 icon 風格一致
        newBtn.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>`;
        // 插在 logo 的正後方(logo nextSibling 前)
        if (logoA.nextSibling) {
            headerDiv.insertBefore(newBtn, logoA.nextSibling);
        } else {
            headerDiv.appendChild(newBtn);
        }
        return true;
    }

    // ── v1.9.1:多選擇器找 section,完全不動 nav flex 結構 ──
    function findAnchorSection() {
        // 嘗試各種可能的「新建」aria-label(中英文,有無 draggable)
        const selectors = [
            'a[draggable="false"][aria-label="新建"]',
            'a[aria-label="新建"]',
            'a[aria-label="New"]',
            'a[aria-label="新增"]',
            'a[draggable="false"][href="/"]',
        ];
        for (const sel of selectors) {
            const link = document.querySelector(sel);
            if (!link) continue;
            let el = link;
            for (let i = 0; i < 10; i++) {
                el = el.parentElement;
                if (!el) break;
                if ((el.className || '').includes('collapsible-sidebar-section')) return el;
            }
        }
        // 最後備援:取第一個 collapsible-sidebar-section
        return document.querySelector('div[class*="collapsible-sidebar-section"]') || null;
    }
    function injectSidebarShortcuts() {
        if (document.querySelector('.pplx-newbtn-anchor')) return true;  // 已注入
        const sectionEl = findAnchorSection();
        if (!sectionEl) return false;
        if (sectionEl.dataset.pplxDone) return true;
        sectionEl.dataset.pplxDone = '1';

        // 加 position:relative,讓快捷鈕 absolute 相對此 section 定位(不動 flex)
        sectionEl.classList.add('pplx-newbtn-anchor');

        // 建立快捷鈕群組
        const wrap = document.createElement('div');
        wrap.className = 'pplx-hdr-shortcuts';

        SHORTCUT_DEFS.forEach(({ label, href, svg }) => {
            const a = document.createElement('a');
            a.href = href;
            a.className = 'pplx-hdr-btn';
            a.setAttribute('data-tip', label);
            a.setAttribute('aria-label', label);
            a.innerHTML = svg;
            wrap.appendChild(a);
        });

        sectionEl.appendChild(wrap);
        hideOriginalNavRows();
        return true;
    }

    function hideOriginalNavRows() {
        document.querySelectorAll('div[class*="collapsible-sidebar-section"]').forEach(section => {
            if (section.classList.contains('pplx-hidden-nav-row')) return;
            const link = section.querySelector('a[aria-label]');
            if (link && HIDDEN_LABELS.has(link.getAttribute('aria-label'))) {
                section.classList.add('pplx-hidden-nav-row');
            }
        });
    }

    applySidebarWidth(savedWidth);
    setInterval(() => {
        const el = document.querySelector('div.w-sideBarWidth');
        const _w191 = parseInt(el ? el.style.width : '0');
        if (el && !isNaN(_w191) && _w191 > 60 && _w191 !== savedWidth) applySidebarWidth(savedWidth);
        // 折疊時隱藏青色 resize handle
        const rh = document.getElementById('pplx-resize-handle');
        if (rh) rh.style.display = (!isNaN(_w191) && _w191 < 60) ? 'none' : '';
        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;
        shortcutsInjected = false;
        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');
                }
            });
        });
    }

    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;
    }
    function sanitizeFilename(name) {
        return String(name || 'code')
            .replace(/[\/:*?"<>|]+/g, '-')
            .replace(/\s+/g, ' ')
            .trim()
            .replace(/[. ]+$/g, '')
            .slice(0, 160) || 'code';
    }
    function getDownloadInfo(pre) {
        const txt = pre.innerText || '';
        const nmMatch = txt.match(/@name\s+([^\n]+)/i);
        const name = sanitizeFilename(nmMatch ? nmMatch[1].trim() : 'code');
        const currentVersion = getCurrentScriptVersion();
        const version = currentVersion.toLowerCase().startsWith('v') ? currentVersion : ('v' + currentVersion);
        return { name, version, filename: `${name} ${version}.txt` };
    }
    function getCurrentScriptVersion() {
        try {
            if (typeof GM_info !== 'undefined' && GM_info && GM_info.script && GM_info.script.version) {
                return String(GM_info.script.version).trim();
            }
        } catch (_) {}
        return '1.9.14';
    }
    function syncVersionInCode(code) {
        const currentVersion = getCurrentScriptVersion();
        let out = String(code || '');
        out = out.replace(/^([ 	]*\/\/\s*@version\s+).+$/gmi, `$1${currentVersion}`);
        return out;
    }
    function downloadTextFile(filename, content) {
        const blob = new Blob([content], { type: 'text/plain;charset=utf-8' });
        const a = document.createElement('a');
        a.href = URL.createObjectURL(blob);
        a.download = filename;
        document.body.appendChild(a);
        a.click();
        setTimeout(() => {
            URL.revokeObjectURL(a.href);
            a.remove();
        }, 1000);
    }

    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);
    }

    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);
            const container = document.createElement('div'); container.className = 'pplx-pre-container';
            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 = '展開代碼或收縮代碼'; arrow.setAttribute('aria-label', '展開代碼或收縮代碼');
            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(); }
            };
            const downloadBtn = document.createElement('span');
            downloadBtn.className = 'pplx-code-download'; downloadBtn.textContent = '💾'; downloadBtn.title = '下載代碼';
            downloadBtn.onclick = e => {
                e.preventDefault(); e.stopPropagation();
                const code = getCleanCode(pre);
                const info = getDownloadInfo(pre);
                downloadTextFile(info.filename, code);
                downloadBtn.textContent = '✅';
                setTimeout(() => downloadBtn.textContent = '💾', 2000);
            };
            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); tbar.appendChild(downloadBtn); wrap.appendChild(tbar);
            pre.parentNode.insertBefore(container, pre);
            container.appendChild(wrap); container.appendChild(pre);
            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();
        if (!shortcutsInjected) shortcutsInjected = injectSidebarShortcuts();
        injectNewBtnToHeader();
        hideOriginalNavRows();
    }
    setInterval(maintainUI, 300);
    maintainUI();
    scheduleScrollToBottom();
})();