Perplexity Widescreen & Compact & Code Collapser

v1.9.3: 折疊時青線消失;+新建移至logo正右方獨立顯示

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         Perplexity Widescreen & Compact & Code Collapser
// @namespace    http://tampermonkey.net/
// @version      1.9.3
// @description  v1.9.3: 折疊時青線消失;+新建移至logo正右方獨立顯示
// @author       ford933
// @license      All Rights Reserved
// @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 */
        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}

        /* 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],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: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:space-around!important;
            gap:0px!important;
            width:calc(100% - 82px)!important;
            z-index:9000!important;
            pointer-events:auto!important;
            visibility:visible!important;opacity:1!important;
        }

        /* ── 快捷鈕本體 ── */
        a.pplx-hdr-btn{
            display:inline-flex!important;align-items:center!important;justify-content:center!important;
            flex:1!important;
            height:22px!important;
            max-height:22px!important;min-height:22px!important;
            min-width:18px!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}

        /* 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: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 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: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 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;
    }

    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 = '展開 / 折疊代碼';
            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);
            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();
})();