    :root {
        --font: system-ui, -apple-system, "Segoe UI", "PingFang SC", "Microsoft YaHei", Roboto, Helvetica, Arial, sans-serif;
        --mono: ui-monospace, "SFMono-Regular", Consolas, "Cascadia Code", monospace;

        --bg: #f5f7fa;
        --surface: #ffffff;
        --surface-2: #f0f3f7;
        --surface-3: #e9eef4;
        --border: #e6eaf0;
        --border-2: #d7dee7;

        --text: #16212e;
        --text-2: #55636f;
        --muted: #6a7480;        /* 文字级次要色：白底对比 ≈4.6:1（WCAG AA）。来源/日期/caveat 等小字统一用它 */
        --muted-soft: #94a1af;   /* 仅装饰用途（箭头/圆点/图标符），不承载文字信息、不要求 AA */

        --accent: #0d9488;
        --accent-ink: #0b7c72;
        --accent-weak: #e6f5f3;
        --accent-line: #b8e6e0;
        --bar-line: rgba(13, 148, 136, 0.16);   /* 底栏纵横切割线（青调，纵横同色→相交式网格） */

        --ok: #0a875a;      --ok-weak: #e6f5ee;
        --no: #c2523a;      --no-weak: #fbeee9;
        --unknown: #8a97a4; --unknown-weak: #eef1f4;
        /* 警示/partial 语义色（.reach-* 可达性 ramp 是独立色阶，刻意不并入） */
        --warn: #b4540a;            --warn-weak: #fff3e6;        --warn-line: #f0c38e;
        --warn-row: #fff8f1;        --warn-row-line: #f0c9a0;
        --warn-row-hover: #fff2e6;  --warn-line-strong: #eab784;
        --caution: #9a6b12;         --caution-pill: #c98a1a;

        /* 动效令牌：全站缓动/时长单一真源；GSAP defaults 与之同族（power3.out）。 */
        --ease-spring: cubic-bezier(.22, 1, .36, 1);
        --dur-fast: 140ms;
        --dur-med: 240ms;
        --dur-slow: 420ms;
        --caution-weak: #fdf7ec;    --caution-line: #ecdcbf;     --caution-row-line: #f0e6d2;
        --caution-head: #9a7b3c;
        --caution-chip: #f3e6c9;    --caution-chip-line: #e2cfa3;  --caution-chip-ink: #7a5c22;

        /* 国内可达性徽章 ramp（.reach-*，独立色阶、非实测推断） */
        --reach-good-bg: #e7f6ec;     --reach-good-line: #bfe3ca;     --reach-good-ink: #2f7d47;
        --reach-variable-bg: #fdf3e0; --reach-variable-line: #f0d9ac; --reach-variable-ink: #8a5d1a;
        --reach-slow-bg: #fdeede;     --reach-slow-line: #f2cda0;     --reach-slow-ink: #9a5320;
        --reach-proxy-bg: #fdeaea;    --reach-proxy-line: #f2c0c0;    --reach-proxy-ink: #9a2b2b;

        --ink-inverse: #16212e;   /* 深底浮层（tooltip/toast）底色；其上文字用 --surface */

        --shadow-sm: 0 1px 2px rgba(16, 33, 46, 0.06);
        --shadow: 0 6px 22px rgba(16, 33, 46, 0.09);
        --shadow-lg: 0 14px 40px rgba(16, 33, 46, 0.14);
        --shadow-focus: 0 8px 28px rgba(13, 148, 136, 0.14);   /* 控制台 focus-within 青光 */

        --radius-sm: 9px;
        --radius-md: 12px;
        --radius: 14px;
        --radius-lg: 20px;

        /* 间距/字级阶梯（新代码优先用令牌，不再新写裸值） */
        --space-1: 4px;  --space-2: 8px;  --space-3: 12px;  --space-4: 16px;  --space-5: 24px;
        /* 信息文字下限 10.5px（--fs-micro）；更小的字号只允许纯装饰用途 */
        --fs-micro: 10.5px;  --fs-xs: 11.5px;  --fs-sm: 12.5px;  --fs-md: 14px;
        --fs-lg: 15.5px;     --fs-xl: 22px;    --fs-hero: 30px;

        /* 全局层叠阶梯：跨组件 z-index 一律走令牌；组件内部的 1/2/3 局部层序不在此列 */
        --z-dropdown: 30;         /* .sf-panel 选择器面板 */
        --z-fab: 55;              /* .side-fab 收起态 logo */
        --z-backdrop: 58;         /* .side-backdrop 移动端遮罩 */
        --z-sidebar: 60;          /* .sidebar 桌面侧栏 */
        --z-sidebar-mobile: 120;  /* 移动端抽屉态侧栏 */
        --z-floatwin: 90;         /* .hist-win 档案浮窗：与主界面同层（非模态），高于桌面侧栏便于随处拖动。
                                     移动抽屉（--z-sidebar-mobile:120）比它高，移动端的「浮窗 > 抽屉」由媒体
                                     查询内的 .hist-win 覆盖规则局部恢复——不全局抬令牌：桌面
                                     .ds-split 全屏对比层(120)盖住浮窗(90)是既有语义，不能跟着反转 */
        --z-overlay: 150;         /* .overlay 设置抽屉遮罩 */
        --z-drawer: 200;          /* .drawer 设置抽屉 */
        --z-modal: 250;           /* .modal-backdrop 弹窗 */
        --z-tooltip: 260;         /* .strategy-tooltip */
        --z-toast: 300;           /* .toast */
        --z-tour-ring: 999;       /* .onboarding-focus-ring 导览高亮环 */
        --z-tour: 1000;           /* .onboarding 导览面板（原 2147483000/2147482999 魔法数收编） */

        --side-w: 300px;                        /* 左侧悬浮 tab 栏宽度（导航改两列后加宽，给下方「数据细化」卡更多面积、免横向滚动） */
    }

    * { margin: 0; padding: 0; box-sizing: border-box; }
    /* `hidden` 属性必须真的隐藏。浏览器默认表里 `[hidden]{display:none}` 属**用户代理**样式，
       任何作者样式里的 display 都压过它 —— 本项目的 `.btn{display:inline-flex}` 正是如此，
       于是 `feasibilityBtn.hidden = true` / `taskPackBtn.hidden = true` 全部空转：
       零结果、规则弃权、澄清态的屏幕上照样挂着「可行性概览」和「下载这批数据」两个主按钮，
       点下去只能拿到一个空包。JS 那边写的是对的，是 CSS 把它作废了。
       此前的补法是一个组件一条 `.X[hidden]{display:none}`（已累计 6 条），漏一个就再犯一次；
       这里改成一条全局兜底，`!important` 是为了压过任何后来新增的 display 规则。 */
    [hidden] { display: none !important; }
    .sr-only { position: absolute !important; width: 1px !important; height: 1px !important; padding: 0 !important; margin: -1px !important; overflow: hidden !important; clip: rect(0, 0, 0, 0) !important; white-space: nowrap !important; border: 0 !important; }

    body {
        font-family: var(--font);
        background: var(--bg);
        color: var(--text);
        min-height: 100vh;
        line-height: 1.55;
        -webkit-font-smoothing: antialiased;
    }
    a { color: inherit; text-decoration: none; }
    ::selection { background: rgba(13, 148, 136, 0.16); }

    /* ---------------- 左侧悬浮 tab 栏（ChatGPT 式）：展开＝浮动圆角面板；收起＝左上角一枚 logo ---------------- */
    .sidebar {
        position: fixed; top: 14px; left: 14px; bottom: 14px; z-index: var(--z-sidebar);
        width: var(--side-w); display: flex; flex-direction: column; gap: 12px;
        transition: transform .32s cubic-bezier(.22, 1, .36, 1), opacity .22s ease;
    }
    /* 侧栏内两张独立圆角浮窗：导航卡（常驻）+ 数据细化卡（有分面时）——分离更清爽 */
    .side-card {
        background: var(--surface); border: 1px solid var(--border);
        border-radius: var(--radius-lg); box-shadow: var(--shadow); padding: 12px 10px;
    }
    body.side-closed .sidebar { transform: translateX(calc(-100% - 22px)); opacity: 0; pointer-events: none; }
    .side-resizer {
        position: absolute; top: 18px; right: -8px; bottom: 18px; width: 16px; z-index: 3;
        display: flex; align-items: center; justify-content: center; cursor: ew-resize; touch-action: none; outline: none;
    }
    .side-resizer span { width: 3px; height: 52px; border-radius: 999px; background: var(--border-2); box-shadow: 0 0 0 3px var(--bg); transition: height .16s, background .16s; }
    .side-resizer:hover span, .side-resizer:focus-visible span, body.side-resizing .side-resizer span { height: 76px; background: var(--accent); }
    .side-resizer:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; border-radius: 8px; }
    body.side-resizing { cursor: ew-resize; user-select: none; }
    body.side-resizing, body.side-resizing .sidebar { transition: none !important; }
    .side-head { display: flex; align-items: center; gap: 8px; padding: 4px 6px 8px; }
    .side-head .wordmark { font-size: 19px; }
    .side-toggle {
        margin-left: auto; width: 32px; height: 32px; border-radius: 9px; flex: none;
        border: none; background: transparent; color: var(--text-2); cursor: pointer;
        display: grid; place-items: center; transition: background .15s, color .15s;
    }
    .side-toggle:hover { background: var(--surface-2); color: var(--text); }
    .side-toggle svg { width: 19px; height: 19px; }
    /* 纯文字 wordmark：Bio 青 + Data Agent 墨；"o" 画成带螺旋线的环（DNA 意象），
       SVG 用 currentColor 继承 .wm-bio 的青色。无外部字体/图片，完全自包含。 */
    /* 衬线 logotype（系统自带，无外部字体）：编辑级 / 科学期刊质感，配无衬线 UI 更精致。 */
    .wordmark {
        font-family: "Palatino Linotype", "Book Antiqua", Palatino, "Iowan Old Style",
            Cambria, Constantia, Georgia, "Songti SC", "STSong", serif;
        font-size: 22px; font-weight: 500; letter-spacing: 0.2px;
        color: var(--text); white-space: nowrap; user-select: none;
        display: inline-flex; align-items: center;
        font-feature-settings: "kern" 1, "liga" 1;
        -webkit-font-smoothing: antialiased;
    }
    .wordmark .wm-bio { color: var(--accent); }
    .wordmark .wm-o {
        display: inline-block; width: 0.58em; height: 0.58em;
        vertical-align: -0.02em; margin: 0 0.03em 0 0.02em;
    }

    /* 导航默认单列（无检索结果时的原始构造）；填满导航卡以便「设置」钉底 */
    .side-nav { display: flex; flex-direction: column; gap: 2px; flex: 1 1 auto; }
    .side-nav #settingsBtn { margin-top: auto; }   /* 单列时把「设置」推到卡底（承接原 .side-foot 定位）；两列 grid 下此 margin 被忽略、设置成为普通格 */
    /* 有分面（出结果）即导航切两列：压低导航卡、给下方数据细化卡腾纵向面积；6 项（5 视图 + 设置）匀齐 3×2，无整行独占、无落单空格。
       只挂 facets-active（不含 on-query）且跨视图残留；由下方 `body:not(.on-query)` 规则把非查询视图
       压回单列填满——两列压缩实际只在查询视图（数据细化卡真正可见）生效，离开查询页不再留半截空白。
       2026-08-24 side-duo（用户点图）：双窗口（导航卡 + 侧栏工作卡并立，board.js swSync 按 #sideWork
       可见性维护）同样两列——此前只认 facets-active，无活跃分面的「继续对话」窗口态导航傻大单列。 */
    body.facets-active .side-nav, body.side-duo .side-nav { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; flex: 0 0 auto; align-content: start; }   /* flex:0 0 auto + align-content:start：两列态导航为内容高且行顶对齐 → 卡高动画期间各项位置恒定，位移 FLIP 端点才稳 */
    .nav-item {
        display: flex; align-items: center; gap: 10px; width: 100%; text-align: left;
        padding: 9px 11px; border-radius: 10px; border: none; background: transparent;
        color: var(--text-2); font-family: var(--font); font-size: 14px; font-weight: 500; cursor: pointer;
        transition: background 0.15s ease, color 0.15s ease;
    }
    .nav-item svg { width: 18px; height: 18px; flex: none; opacity: .82; }
    .nav-item .lbl { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
    .nav-item:hover { background: var(--surface-2); color: var(--text); }
    .nav-item.active { background: var(--accent-weak); color: var(--accent-ink); }
    .nav-item.active svg { opacity: 1; }

    /* ---- 账号 chip + 弹出菜单（保持登录 + 快捷切换；2026-08-03 起住设置·账户块）---- */
    .acct-zone { position: relative; flex: 0 0 auto; }
    .acct-chip {
        display: flex; align-items: center; gap: 8px; max-width: 180px;
        padding: 5px 10px 5px 6px; border: 1px solid var(--border-2); border-radius: 999px;
        background: var(--surface); cursor: pointer; font-family: var(--font);
        color: var(--text-2); transition: color .15s, background .15s, border-color .15s;
    }
    .acct-chip:hover { color: var(--text); background: var(--surface-2); border-color: var(--border); }
    .acct-avatar {
        flex: none; width: 24px; height: 24px; border-radius: 50%;
        display: grid; place-items: center;
        background: var(--accent-weak); color: var(--accent-ink);
        font-size: 12px; font-weight: 700;
    }
    .acct-avatar.small { width: 20px; height: 20px; font-size: 10.5px; }
    .acct-name { flex: 1 1 auto; min-width: 0; text-align: left; font-size: 13px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
    .acct-chev { width: 14px; height: 14px; flex: none; opacity: .6; transition: transform .18s; }
    .acct-chip[aria-expanded="true"] .acct-chev { transform: rotate(180deg); }
    .acct-menu {
        position: absolute; right: 0; min-width: 220px; bottom: calc(100% + 6px); z-index: var(--z-dropdown);
        background: var(--surface); border: 1px solid var(--border); border-radius: 12px;
        box-shadow: var(--shadow); padding: 5px;
        display: flex; flex-direction: column; gap: 1px;
        /* 账号多时菜单曾越出抽屉顶——限高 + 内部滚动兜底（方向选择见 accounts.js）。 */
        max-height: min(300px, calc(100dvh - 96px)); overflow-y: auto;
    }
    .acct-menu.drop-down { bottom: auto; top: calc(100% + 6px); }
    .acct-menu-item {
        display: flex; align-items: center; gap: 8px; width: 100%; text-align: left;
        padding: 7px 9px; border: none; border-radius: 8px; background: transparent;
        font-family: var(--font); font-size: 12.5px; font-weight: 500; color: var(--text-2); cursor: pointer;
        transition: background .14s, color .14s;
    }
    .acct-menu-item:hover:not(:disabled) { background: var(--surface-2); color: var(--text); }
    .acct-menu-item.is-current { color: var(--accent-ink); cursor: default; }
    .acct-menu-item.danger:hover { background: var(--warn-weak); color: var(--warn); }
    .acct-menu-name { flex: 1 1 auto; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
    .acct-menu-mark { flex: none; font-size: 10.5px; color: var(--accent); font-weight: 700; }
    .acct-menu-div { height: 1px; background: var(--border-2); margin: 4px 6px; }

    /* ---- 侧栏双卡片：导航卡（.side-nav-card，常驻）+ 数据细化卡（.side-facets，有可细化维度时出现） ---- */
    .side-nav-card { display: flex; flex-direction: column; gap: 6px; flex: 1 0 auto; min-height: 0; }   /* 2026-08-05：shrink 改 0——导航项数固定、内容定高，不许被工作卡挤到裁掉「帮助/设置」；挤压由带内部滚动的 .side-work 吸收 */
    .side-facets { display: none; flex-direction: column; min-height: 0; flex: 1 1 auto; }
    /* facets-active（有分面内容 + 侧栏展开 + 桌面，由 placeFacetBar/setFacetsActive 维护、跨视图保持）：导航卡从"填满"收缩到"内容高"
       （向上收拢，过渡由 GSAP FLIP 播），数据细化卡占下方余量并 display:flex。其「可见性」另由 syncFacetsCard 按是否在查询视图淡入/淡出——
       离开查询页只淡出它；导航卡布局也由下方 `body:not(.on-query)` 规则压回单列填满（不再保持两列）。 */
    body.facets-active .side-nav-card, body.side-duo .side-nav-card { flex: 0 0 auto; }
    body.facets-active .side-facets { display: flex; }
    /* 2026-08-22：非查询视图强制导航卡单列填满——facets-active 跨视图残留 + 工作卡 hidden
       曾致侧栏只剩内容高小卡、下方整段空白；两列压缩只在查询视图（细化卡真正可见）生效。 */
    body:not(.on-query) .side-nav { display: flex; flex-direction: column; gap: 2px; flex: 1 1 auto; }
    body:not(.on-query) .side-nav-card { flex: 1 0 auto; }
    .side-facet-body { flex: 1 1 auto; overflow-y: auto; padding: 0 4px 2px; min-height: 120px; scroll-padding-bottom: 48px; }   /* 2026-08-05：min-height 治矮窗塌成 2px；scroll-padding-bottom 治 sticky 提交条压分组头 */
    /* 侧栏「数据细化」= 全宽对齐列表：取值行值左对齐、计数锁右列成一条可扫描的数字列；
       「查询条件」原始命中/细化行统一成全宽同节奏。长取值省略号截断（title 存全文，见 renderFacets）。
       纯 CSS 作用于现有 markup；结果区上方回退态（.facetbar 不在 .side-facets 内）不受影响、仍用基础 chip 云。 */
    .side-facets .facetbar { margin: 0; }
    /* 查询条件：纵向堆叠成全宽行，忽略/恢复/× 一律右对齐；「查询条件：」作小节标题 */
    .side-facets .facet-active { flex-direction: column; align-items: stretch; gap: 5px; margin-bottom: 15px; }
    .side-facets .facet-applied-label { padding: 0 3px 3px; font-size: 11px; font-weight: 700; letter-spacing: .03em; color: var(--muted); }
    .side-facets .fa-chip { width: 100%; padding: 6px 8px 6px 11px; border-radius: 9px; gap: 7px; }
    .side-facets .fa-chip .fa-v { flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }   /* 值填满、长值省略号，把忽略/恢复/× 顶到行右端 */
    .side-facets .fa-chip .fa-toggle { margin-left: auto; flex: 0 0 auto; }
    /* 取值维度：维度名独占一行小标题；取值为全宽行——值左对齐、计数右对齐成列 */
    .side-facets .facet-groups { gap: 16px; }
    .side-facets .fg-row { flex-direction: column; align-items: stretch; min-width: 0; gap: 3px; }
    .side-facets .fg-label { min-width: 0; padding: 0 3px 3px; font-size: 11px; font-weight: 700; letter-spacing: .03em; color: var(--muted); }
    .side-facets .fg-vals { width: 100%; min-width: 0; flex: 0 0 auto; flex-direction: column; gap: 1px; }   /* 纵向堆叠、钉在卡片宽（min-width:0 令长取值 fc-t 省略号、不越出卡片） */
    .side-facets .facet-chip { display: flex; width: 100%; max-width: 100%; min-width: 0; justify-content: flex-start; gap: 8px; padding: 6px 10px; border-radius: 8px; border-color: transparent; background: transparent; }   /* 全宽行：无边框透明底，hover/选中态 + 右端 chevron 共同表达可点 */
    .side-facets .facet-chip .fc-t { flex: 1 1 auto; text-align: left; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; color: var(--text-2); }
    .side-facets .facet-chip .fc-n { flex: 0 0 auto; margin-left: 8px; min-width: 20px; text-align: right; font-weight: 600; color: var(--muted); }   /* 计数锁右列、tabular-nums（继承基础）对齐成一条数字列 */
    /* 纯文本行看不出可点（移动端无 hover 完全没有暗示）——右端恒显低调 chevron，
       hover/选中着色微移，与结果区 chip 云同一套「可点」语言；计数列仍在 chevron 左侧锁齐。 */
    .side-facets .facet-chip::after { content: "›"; flex: 0 0 auto; align-self: center; color: var(--muted); opacity: .5; font-size: 13px; line-height: 1; transition: transform .16s, color .16s, opacity .16s; }
    .side-facets .facet-chip:hover::after { color: var(--accent-ink); opacity: 1; transform: translateX(2px); }
    .side-facets .facet-chip.is-staged::after { color: var(--accent-ink); opacity: .9; }
    @media (prefers-reduced-motion: reduce) { .side-facets .facet-chip::after { transition: none; } .side-facets .facet-chip:hover::after { transform: none; } }
    .side-facets .facet-chip:hover { transform: none; border-color: transparent; background: var(--surface-2); color: var(--text); }
    .side-facets .facet-chip:hover .fc-t { color: var(--text); }
    .side-facets .facet-chip:hover .fc-n { color: var(--text-2); }

    /* ---- 侧栏工作卡：同一张卡承载「数据细化 / 对话记录」，顶部开关切换---- */
    /* 整卡可见性由 board.js swSync 用 hidden 属性控制（两块都没内容就整卡收起）；
       两块面板的显隐也走 hidden。`.side-facets` 原有的 display:none / facets-active 规则保持不变，
       与 hidden 是 AND 关系：hidden 一票否决，不 hidden 时仍要 facets-active 才 display:flex。 */
    .side-work { display: flex; flex-direction: column; min-height: 0; flex: 1 1 auto; gap: 8px; }
    /* 入场动画（2026-08-02 用户4）：检索中侧栏不弹出（swAvailable 门），完成后整卡随结果一起
       滑入。hidden→显示会重放本动画；页签切换只动 pane、不会误触发。 */
    .side-work:not([hidden]) { animation: swIn .34s cubic-bezier(.22, 1, .36, 1); }
    @keyframes swIn { from { opacity: 0; transform: translateX(-12px); } to { opacity: 1; transform: none; } }
    @media (prefers-reduced-motion: reduce) { .side-work:not([hidden]) { animation: none; } }
    /* 2026-08-16：行内加第三格——视图交换钮 #swSwapBtn（28px 定宽，两页签仍各 1fr 等分）。 */
    .sw-switch { display: grid; grid-template-columns: 1fr 1fr auto; gap: 3px; padding: 3px; border-radius: 10px; background: var(--surface-2); flex: 0 0 auto; position: relative; }
    /* 页签滑动指示块：跟在激活页签底下平滑滑动；选中态底色移到滑块上，按钮只留字色。
       三格后页签区 = 100% − 6px 内边距 − 2×3px 间距 − 28px 交换钮 → 单页签宽 calc(50% − 20px)，
       滑块宽与其一致；translateX(calc(100% + 3px)) 语义不变（恰走一格 + 一个间距）。 */
    .sw-glide {
        position: absolute; top: 3px; bottom: 3px; left: 3px; width: calc(50% - 20px);
        border-radius: 8px; background: var(--surface); box-shadow: 0 1px 2px rgb(0 0 0 / .06);
        transition: transform var(--dur-med) var(--ease-spring); pointer-events: none;
    }
    @media (prefers-reduced-motion: reduce) { .sw-glide { transition: none; } }
    .sw-tab {
        display: flex; align-items: center; justify-content: center; gap: 6px;
        padding: 6px 4px; border: 0; border-radius: 8px; cursor: pointer;
        background: transparent; color: var(--muted); font-size: 12.5px; font-weight: 700;
        transition: color .16s; position: relative; z-index: 1;
    }
    .sw-tab svg { width: 14px; height: 14px; flex: none; opacity: .85; }
    .sw-tab:hover:not(:disabled) { color: var(--text-2); }
    .sw-tab.is-on { color: var(--text); }
    /* 没内容的那一侧禁用而不是隐藏：位置恒定，用户知道另一块存在、只是这次没东西可看。 */
    .sw-tab:disabled { opacity: .4; cursor: default; }
    .sw-pane { min-height: 0; }
    /* 对话记录面板（微信式）：上＝常驻查询条件栏(#swHits)；中＝对话记录+条件板(#sideBoardScroll，主区、可滚)
       ＋撤销/重做步进条；下＝统一输入条（#chatComposer，范围 chip + 输入框 + 发送键，图7）。
       #sideBoardPane 本身不裁剪，范围合并弹层 #scopePop 才不被 overflow 裁掉。 */
    #sideBoardPane { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; overflow: visible; gap: 8px; }
    .sw-board-scroll { flex: 1 1 auto; min-height: 60px; overflow-y: auto; padding-top: 6px; }   /* padding-top：超长气泡首行不再被页签条下沿裁半行 */
    /* 常驻「查询条件」栏 = facets 的 #facetActive 整块搬来（**不另造栏**）。这里镜像 .side-facets .facet-active
       那套侧栏排版（全宽行 / 长值省略号），让它在两模式看起来一致。
       底色框（用户 2026-07-23 反馈）：一层浅底 + 细边把「已命中查询条件」圈成一块，
       与下方对话记录（透明底气泡流）一眼可分。空时 host 被 hidden，框不占位。 */
    .sw-hits { flex: 0 0 auto; background: var(--surface-2); border: 1px solid var(--border-2); border-radius: 10px; padding: 9px 10px; }
    .sw-hits .facet-active { flex-direction: column; align-items: stretch; gap: 5px; margin: 0; }
    .sw-hits .facet-applied-label { padding: 0 3px 3px; font-size: 11px; font-weight: 700; letter-spacing: .03em; color: var(--muted); }
    .sw-hits .fa-chip { width: 100%; box-sizing: border-box; }
    .sw-hits .fa-chip .fa-v { flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
    /* 范围控件搬进侧栏面板后，主控制台底栏（只剩 1px 分隔线）隐藏——同一套控件不两处同时出现；圆角由 .console 兜底。
       注意：主检索框 .console **本身不再隐藏**——2026-08-01 统一对话窗口后 #queryInput 是唯一输入框，
       telegram 态也不许把它藏起来（旧版曾因侧栏有独立对话框而 display:none 整块 .console）。 */
    body.scope-in-side .console-bar { display: none; }

    /* —— 统一输入条（#chatComposer，图7 重做 2026-08-03 点5 改版）——
       一条圆角容器（.cb-bar）= 范围圆钮（.scope-btn，与发送键同形）+ 输入框 + 发送键：
       边框/底色在容器上，textarea 裸在容器里，焦点环走 focus-within。
       范围合并弹层 #scopePop 锚在容器上方（向上弹、spring 入场）。 */
    .cb-composer { position: relative; padding: 8px 8px 8px 12px; border-top: 1px solid var(--border-2); }
    .cb-composer:empty { display: none; }
    .cb-bar {
        display: flex; align-items: flex-end; gap: 6px;
        background: var(--surface-2); border: 1px solid var(--border-2); border-radius: 14px;
        padding: 5px 5px 5px 6px; transition: border-color .15s, box-shadow .15s;
    }
    .cb-bar:focus-within { border-color: var(--accent-line, var(--accent)); box-shadow: 0 0 0 3px var(--accent-weak); }
    .cb-composer textarea {
        flex: 1 1 auto; min-width: 0; resize: none; box-sizing: border-box;
        min-height: 30px; max-height: 123px; padding: 5px 4px;   /* 上限 6 行（12.5×1.5×6+10=122.5），autogrow 的 CSS 兜底 */
        font: inherit; font-size: 12.5px; line-height: 1.5; color: var(--text);
        background: transparent; border: none; outline: none;
    }
    .cb-send {
        flex: none; width: 34px; height: 34px; border-radius: 50%; border: none; cursor: pointer;
        display: inline-flex; align-items: center; justify-content: center;
        background: var(--accent, #0d9488); color: #fff; transition: filter .15s, transform .1s;
        box-shadow: 0 3px 10px rgba(13, 148, 136, .35);
    }
    .cb-send:hover { filter: brightness(1.08); }
    .cb-send:active { transform: scale(.94); }
    .cb-send svg { width: 15px; height: 15px; }
    /* 发送中：2026-08-13 起百分比挪进系统回复气泡，发送键只留静态弱化（不再藏图标滚数字）。 */
    .cb-send.loading { pointer-events: none; opacity: .6; }
    /* 「范围」圆钮（点5 2026-08-03 点7 改版）：与发送键同形的 34px 圆钮，坐在输入框与发送键之间。
       两项都在智能识别 → is-auto：**整钮染色**作开启标识（accent 弱底 + 描边 + 图标着色 + 弱光环），
       不再是角标（用户判定角标像通知徽标）；任一自定义 → 朴素灰钮。 */
    .scope-btn {
        flex: none; position: relative; width: 34px; height: 34px; border-radius: 50%; cursor: pointer;
        display: inline-flex; align-items: center; justify-content: center;
        background: var(--surface); border: 1px solid var(--border-2); color: var(--text-2);
        transition: color .15s, background .15s, border-color .15s, box-shadow .2s;
    }
    .scope-btn:hover { color: var(--text); border-color: var(--accent-line, var(--accent)); }
    .scope-btn:active { transform: scale(.94); }
    .scope-btn svg { width: 15px; height: 15px; }
    .scope-btn[aria-expanded="true"] { background: var(--accent-weak); color: var(--accent-ink); border-color: var(--accent-line, var(--accent)); }
    .scope-btn.is-auto {
        background: var(--accent-weak); color: var(--accent-ink);
        border-color: var(--accent-line, var(--accent));
        box-shadow: 0 0 0 3px var(--accent-weak);
    }
    /* 范围合并弹层：数据来源 + 发表时间两块整节点搬入（零复制）；面板恒展开。
       点7：toggle 在弹层内隐藏——当前生效的范围由**控件状态本身**呈现（模式键 + chips + 年份下拉
       恒可见、全部可点可改），不再单列一行「只能看不能点」的摘要（它正是「只能查看不能修改」的观感来源）。
       2026-08-05 用户点图：重排为「右坞双圆钮 + 单面板」——两枚圆钮竖排在右，点谁显示谁的选项；
       自动识别态从简（只留模式键 + 一行说明；chips/年份输入只在自定义态出现）。 */
    .scope-pop {
        position: absolute; left: 8px; right: 8px; bottom: calc(100% + 6px); z-index: var(--z-dropdown);
        background: var(--surface); border: 1px solid var(--border); border-radius: 14px;
        box-shadow: var(--shadow); padding: 10px 12px;
        display: flex; flex-direction: row; gap: 10px; align-items: flex-start;
        max-height: min(46vh, 420px); overflow-y: auto;
        transform-origin: 24px 100%;
    }
    .scope-pop[hidden] { display: none; }
    .scope-pop:not([hidden]) { animation: scopePopIn .18s cubic-bezier(.22, 1, .36, 1); }
    @keyframes scopePopIn { from { opacity: 0; transform: translateY(6px) scale(.97); } to { opacity: 1; transform: none; } }
    @media (prefers-reduced-motion: reduce) { .scope-pop:not([hidden]) { animation: none; } }
    .scope-panels { flex: 1 1 auto; min-width: 0; }
    .scope-pop .cbar-cell { display: none; flex-direction: column; gap: 6px; padding: 0; }
    .scope-pop .cbar-cell.is-on { display: flex; }   /* 单面板：右坞选谁显示谁 */
    .scope-pop .cbar-label { font-size: 11px; font-weight: 700; color: var(--muted); }
    .scope-pop .cbar-div { display: none; }
    .scope-pop .sf-select { width: 100%; }
    .scope-pop .sf-toggle { display: none; }
    .scope-pop .sf-panel {
        position: static; display: block; width: 100%;
        border: none; box-shadow: none; padding: 0; background: transparent;
    }
    /* 自动识别态从简：来源 chips 与年份输入只在自定义态出现（2026-08-05 用户） */
    .scope-pop .sf-panel.mode-auto .sf-chips { display: none; }
    .scope-pop .sf-panel.mode-auto .tf-range { display: none; }
    /* 自定义模式的来源 chips 在窄弹层里两枚一行刚好放得下 */
    .scope-pop .sf-chips { gap: 6px; }
    .scope-pop .src-chip { padding: 5px 9px; font-size: 12px; }
    /* 右坞维度圆钮：与输入条发送键/范围钮同族；is-on=当前面板；is-custom 小点=该维已被自定义 */
    .scope-dock { display: flex; flex-direction: column; gap: 8px; flex: 0 0 auto; padding-top: 2px; }
    .scope-dock-btn {
        position: relative; width: 30px; height: 30px; border-radius: 50%; cursor: pointer;
        border: 1px solid var(--border-2); background: var(--surface); color: var(--muted);
        display: grid; place-items: center; transition: border-color .15s, color .15s, background .15s, box-shadow .15s;
    }
    .scope-dock-btn svg { width: 15px; height: 15px; }
    .scope-dock-btn:hover { border-color: var(--accent-line); color: var(--accent-ink); }
    .scope-dock-btn.is-on { border-color: var(--accent-line); background: var(--accent-weak); color: var(--accent-ink); box-shadow: var(--shadow-sm); }
    .scope-dock-btn.is-custom::after {
        content: ""; position: absolute; top: -2px; right: -2px; width: 8px; height: 8px;
        border-radius: 50%; background: var(--accent); box-shadow: 0 0 0 2px var(--surface);
    }

    /* —— 聊天 + 细化记录（#cbHistory）· telegram 双行版（用户 2026-07-24·点2/3；2026-08-02 点3/4；08-03 点6）——
       每个 turn 两行：**上＝用户消息气泡（右对齐）**，**下＝系统回复（左对齐）**：系统回复一律进气泡——
       执行回执（「已…」注记）与「结果区正显示这句的结果」都是灰气泡；非当前帧给「查看历史回复」气泡按钮
       （形状颜色一致、静默变按钮，点了只展示那一帧的历史结果；分支/回退在输入条变形成的双键上）。
       「当前」标志＝最新系统回复气泡的高亮环（替代旧绿点徽标），用户消息气泡不再描环。 */
    .cb-history { display: flex; flex-direction: column; padding: 2px; font-size: 12px; line-height: 1.45; }   /* 正文 12px 统一基准（工具卡正文字号），meta 小字 ≤11.5px */
    /* 点9telegram 分组：轮距从 gap 改成逐轮 margin——**同一方的连续消息**收紧到 6px
       （.cbh-grp），跨方才给完整 18px；间距本身表达「这是一组」（用户图：查看历史回复与检索完成那类
       同方连发应更显聚拢）。 */
    .cbh-turn { margin-top: 18px; }
    .cbh-turn:first-child { margin-top: 0; }
    .cbh-turn.cbh-grp { margin-top: 6px; }
    /* 新消息入场：只给刚追加的最后一条 turn 播（board.js cbLogPush 挂 .cbh-enter）；
       回放/重画不播——「新消息滑上来」的语义只属于真新消息。 */
    .cbh-turn.cbh-enter { animation: cbhIn .22s var(--ease-spring); }
    @keyframes cbhIn { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
    @media (prefers-reduced-motion: reduce) { .cbh-turn.cbh-enter { animation: none; } }
    .cbh-turn { display: flex; flex-direction: column; gap: 8px; }
    .cbh-msg-row { display: flex; align-items: flex-end; justify-content: flex-end; gap: 6px; }
    /* 三类消息（说 / 细化 / 执行）**统一用同一副气泡**（用户 2026-08-01）：
       用户对话、细化操作等一切用户侧消息气泡一律采用同一设计——
       accent-weak 填充 + accent-ink 文字 + 13px/4px 圆角，不再按类型改字色/字重/去框。
       沿革：（07-29 点2）曾用字色/字重区分、（08-01）曾连框一起去掉，
       用户最终判断混搭反而凌乱，统一才整齐。类型语义仍在（cbh-say/cbh-refine/cbh-action
       class 保留供 JS/测试挂钩），区分交给下方系统回复：高亮环 / 查看结果按钮 / 执行回执气泡 / 回退至此。 */
    .cbh-bubble { padding: 7px 11px; border-radius: 13px; border-bottom-right-radius: 4px; overflow-wrap: anywhere; max-width: 85%;
        background: var(--accent-weak); color: var(--accent-ink); font-weight: 500; }
    /* 点7：当前帧没有任何特殊标识（高亮描环/状态气泡已退役——描环让气泡看起来比别的大一圈）。 */
    /* 系统回复行（左对齐）：查看结果按钮 / 回执·状态气泡。 */
    .cbh-reply-row { display: flex; align-items: center; gap: 6px; padding-left: 2px; }
    /* （2026-08-01 批注）：左侧回应元素与右侧消息气泡**同一副气泡形**——13px 圆角 + 角缺 4px、
       同内边距同字重；右侧＝用户发出的（accent 绿），左侧＝系统回应（灰：surface-2 底 + text 字），
       角缺左右镜像（右气泡缺右下、左气泡缺左下）。可点 vs 状态的区分不靠描边：
       .cbh-view hover 灰阶加深（＝可点）；回执/状态气泡（.cbh-sys-bubble）无 hover（＝系统的话）。 */
    .cbh-view { font-size: 12px; font-weight: 500; padding: 7px 11px; border: none;
        border-radius: 13px; border-bottom-left-radius: 4px; background: var(--surface-2); color: var(--text);
        white-space: nowrap; }
    .cbh-view { font-family: var(--font); cursor: pointer; transition: background .15s, color .15s; }
    .cbh-view:hover { background: var(--border-2); color: var(--text); }
    /* 系统回音（统一对话窗口：路由回音 / 取消回音 / clarify 回音）——左对齐灰气泡，
       与左侧回应元素同一副气泡形（surface-2 底 + text 字、角缺左下镜像）；不带帧按钮。 */
    .cbh-sys-row { display: flex; justify-content: flex-start; }
    .cbh-sys-bubble { padding: 7px 11px; border-radius: 13px; border-bottom-left-radius: 4px; overflow-wrap: anywhere; max-width: 85%;
        background: var(--surface-2); color: var(--text); font-weight: 500; }
    /* 回执断行更聪明（避免「已更/新。」式孤字）；不支持的浏览器维持原断行，无功能影响。 */
    @supports (text-wrap: pretty) { .cbh-sys-bubble { text-wrap: pretty; } }
    /* 降级气泡：「AI 执行」关时规则检出操作指令的那颗回音——accent 浅底 +
       左侧 3px accent 条（可行动的信号，不是错误红）；下方挂同色系指路按钮「去开启 AI 执行」。
       与灰泡同一副气泡形，只用色彩区分「这句能带你去开关」。 */
    .cbh-sys-bubble.cbh-agent-bubble { background: var(--accent-weak); color: var(--accent-ink);
        border-left: 3px solid var(--accent); }
    /* 错误回音：传输/服务异常（非「没听懂」）的那颗 sys——琥珀族（--warn，
       与 .file-warn/.up-warn 同族：「需要留意」而非致命红），左侧 3px warn 条。
       与降级气泡同一套「色彩+侧条」语言：accent=可去开关，warn=出了故障。 */
    .cbh-sys-bubble.cbh-err-bubble { background: var(--warn-weak); color: var(--warn);
        border-left: 3px solid var(--warn-line-strong); }
    .cbh-agent-cta { font-family: var(--font); font-size: 12px; font-weight: 600; padding: 7px 13px; border: none;
        border-radius: 13px; border-bottom-left-radius: 4px; background: var(--accent); color: #fff;
        cursor: pointer; white-space: nowrap; transition: filter .15s, transform .15s; }
    .cbh-agent-cta:hover { filter: brightness(1.06); }
    .cbh-agent-cta:active { transform: translateY(1px); }
    .cbh-agent-cta:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
    /* 对话记录的主区静态家（hero 内、统一框下方）：自己滚动；telegram 态由外层 #sideBoardScroll 统一滚动（见 .cb-in-side）。 */
    .cb-history.cbh-main { max-height: min(32vh, 280px); overflow-y: auto; margin-top: 10px; }
    .cb-in-side .cb-history { max-height: none; overflow: visible; }
    /* 「查看历史回复」统一低调文本链接（2026-08-03 点1 二轮定稿）：泡内 footer（有系统泡的帧）
       与独立行（无系统泡的帧：分面点击细化等）**同一副字体颜色**——muted 小字、无箭头、
       不抢眼，hover 才出 accent 与下划线。此前的 accent 粗字 + 箭头微动与独立气泡按钮
       两种形态全部退役（用户判定：太显眼、两副面孔）。 */
    .cbh-view-link { border: none; background: none; font-family: var(--font); font-size: 11.5px;
        font-weight: 500; color: var(--muted); cursor: pointer; text-align: left; padding: 0;
        transition: color .15s; }
    .cbh-view-link:hover { color: var(--accent-ink); text-decoration: underline; text-underline-offset: 3px; }
    .cbh-view-link:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; border-radius: 4px; }
    /* 泡内 footer 形态：并入系统回复泡——上边框细分隔（结构分区，不是第二套视觉语言）。 */
    .cbh-sys-bubble .cbh-view-link { display: block; width: 100%; margin-top: 5px; padding-top: 5px;
        border-top: 1px solid var(--border-2); border-radius: 0; }
    /* 独立行形态：无系统泡的帧在用户消息下方的左对齐小字链接。 */
    .cbh-reply-row > .cbh-view-link { display: inline-block; margin: 1px 0 0 6px; }
    /* （2026-08-28）：每条系统回复气泡**外下侧**的反馈操作条（赞/倒赞/评论/分支）。
       纯图标小键（标注靠 hover 的 title 浮窗表达）——muted 色、不抢眼；常态只比正文弱半档
       （能被注意到），hover 才出 accent 底色药丸。
       选中态（赞/倒赞 is-on）用 accent-ink 色 + 图标实心填充表达「已表态」，不加背景块。 */
    .cbh-actbar { display: flex; align-items: center; gap: 2px; padding-left: 4px; margin-top: -3px; }
    .cbh-act { display: inline-flex; align-items: center; justify-content: center; border: none; background: none;
        color: var(--muted); cursor: pointer; padding: 4px 6px; border-radius: 7px;
        transition: color .15s, background .15s, opacity .15s; }
    .cbh-act svg { width: 13px; height: 13px; flex: none; display: block; }
    .cbh-act:hover { color: var(--accent-ink); background: var(--accent-weak); }
    .cbh-act:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
    .cbh-act.is-on { color: var(--accent-ink); }
    .cbh-act.is-on svg { fill: currentColor; }
    .cbh-act.is-off { opacity: .45; }
    .cbh-act.is-off:hover { background: none; color: var(--muted); }
    /* 评论原地编辑器：气泡正下方的小输入区，与气泡同一左基线；圆角细边框，不抢气泡的戏。 */
    .cbh-cmt { display: flex; flex-direction: column; gap: 6px; max-width: 85%; margin-top: 2px; }
    .cbh-cmt-ta { font-family: var(--font); font-size: 12.5px; line-height: 1.5; color: var(--text);
        background: var(--surface); border: 1px solid var(--border-2); border-radius: 10px;
        padding: 7px 10px; resize: none; overflow-y: auto; outline: none; transition: border-color .15s; }
    .cbh-cmt-ta:focus { border-color: var(--accent); }
    .cbh-cmt-row { display: flex; align-items: center; gap: 8px; }
    .cbh-cmt-send { font-family: var(--font); font-size: 12px; font-weight: 600; border: none; cursor: pointer;
        padding: 5px 14px; border-radius: 9px; background: var(--accent); color: #fff; transition: filter .15s;
        white-space: nowrap; }
    .cbh-cmt-send:hover { filter: brightness(1.06); }
    .cbh-cmt-send:disabled { opacity: .6; cursor: default; }
    .cbh-cmt-send:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
    .cbh-cmt-cancel { font-family: var(--font); font-size: 12px; font-weight: 500; border: none; background: none;
        color: var(--muted); cursor: pointer; padding: 5px 8px; border-radius: 9px; transition: color .15s;
        white-space: nowrap; }
    .cbh-cmt-cancel:hover { color: var(--text); }
    /* 思考行（点8 2026-08-03 立，2026-08-24 重定）：流式期间「正在运作」的呼吸信号。
       两处重定——① 位置：挪到**流式输出最底部**（board.js 渲染序 turns → 行动流 → 轨迹 → 本块，
       视线动线：过程在上、当前正在做的事在最下）；② 形态：**去气泡化**——过程=弱视觉铁律，
       它不是消息，只是一行无框小字（与 .ft-trace 同一左基线、同一灰阶），靠动效表达「活着」。
       真实回复落地时原位渐变成文字气泡（.cbh-morph，蜕变语义不变）。 */
    .cbh-pending { padding-left: 2px; }
    /* (0,3,0) 特异性压过文件后部的 .chat-stage .cbh-sys-bubble padding 覆盖。
       (2026-08-24)：去气泡化还要剥边框/投影——`.chat-main .cbh-sys-bubble`
       (0,2,0，app.css:2516) 的 `border: 1px solid var(--border-2)` 此前没被这条覆盖，
       思考行「规划中…」外面残留一圈框（全站仅此一处，用户截图确认）；border:none/
       box-shadow:none 在此补剥，保证主区/侧栏两种挂载点都无框。 */
    .cbh-pending .cbh-sys-bubble.cbh-prog { display: inline-flex; align-items: center; gap: 8px;
        padding: 0; border-radius: 0; border-bottom-left-radius: 0; max-width: none;
        background: none; border: none; box-shadow: none; color: var(--muted); font-weight: 500; }
    /* 入场（board.js 一次性 cbh-prog-in 旗标）：fade-rise 一次，流式重画不重播。 */
    .cbh-sys-bubble.cbh-prog.cbh-prog-in { animation: cbhProgIn .24s var(--ease-spring); }
    @keyframes cbhProgIn { from { opacity: 0; transform: translateY(3px); } to { opacity: 1; transform: none; } }
    /* 不确定态文案：微光扫过（accent 亮带从左到右掠过灰字）——「AI 正在想」的现代通用形，
       用 background-clip:text 实现，不引外部资源；reduced-motion 退回纯灰静字。 */
    .cbh-prog-num { font-weight: 600; font-size: var(--fs-xs); letter-spacing: .02em;
        background: linear-gradient(90deg, var(--muted) 0%, var(--muted) 38%, var(--accent-ink) 50%, var(--muted) 62%, var(--muted) 100%);
        background-size: 200% 100%; -webkit-background-clip: text; background-clip: text;
        -webkit-text-fill-color: transparent; color: transparent;
        animation: cbhShimmer 1.9s linear infinite; }
    @keyframes cbhShimmer { from { background-position: 200% 0; } to { background-position: -200% 0; } }
    /* 进度泡蜕变成文字回音后检索仍在路上：三点挪到那颗回音泡右端继续跳（#cbLivePct，渲染期注入不落盘）。 */
    .cbh-live-dots { margin-left: 7px; }
    .cbh-live-dots i { background: var(--accent); }
    /* 三点：accent 色、带微弹跳（位移+缩放），与 .ft-run 脉冲点 / .arx-ico-run 同族节奏、更立体。 */
    .cbh-prog-dots { display: inline-flex; align-items: center; gap: 3.5px; }
    .cbh-prog-dots i { width: 5px; height: 5px; border-radius: 50%; background: var(--accent); animation: cbhDot 1.15s ease-in-out infinite; }
    .cbh-prog-dots i + i { animation-delay: .16s; }
    .cbh-prog-dots i + i + i { animation-delay: .32s; }
    @keyframes cbhDot { 0%, 60%, 100% { opacity: .3; transform: translateY(0) scale(.82); } 30% { opacity: 1; transform: translateY(-2.5px) scale(1); } }
    /* 思考行 → 文字回复的原位渐变（点8）：不播滑入（那不是新消息，是同一颗泡的蜕变）——就地淡入 + 微缩放 + 去模糊。 */
    .cbh-turn.cbh-morph { animation: cbhMorph .3s var(--ease-spring); }
    @keyframes cbhMorph { from { opacity: .1; transform: scale(.96); filter: blur(1.5px); } to { opacity: 1; transform: none; filter: none; } }
    @media (prefers-reduced-motion: reduce) {
        .cbh-prog-dots i { animation: none; }
        .cbh-turn.cbh-morph { animation: none; }
        .cbh-sys-bubble.cbh-prog.cbh-prog-in { animation: none; }
        .cbh-prog-num { animation: none; background: none; -webkit-text-fill-color: currentColor; color: var(--muted); }
    }
    /* 输入条变形三键条（点6/7）：查看历史回复时替换 .cb-bar——
       回到最新（朴素）/ 从这里建立分支（accent 描边）/ 回退至此（警示色，二段确认）。 */
    .cb-fork { display: flex; gap: 8px; }
    .cb-fork[hidden] { display: none; }
    .cb-fork .btn { flex: 1 1 0; padding: 9px 6px; font-size: 12.5px; border-radius: 12px; white-space: nowrap; }
    .cb-fork-top { color: var(--text-2); }
    .cb-fork-top:hover { color: var(--text); background: var(--surface-2); }
    .cb-fork-branch { border-color: var(--accent-line); color: var(--accent-ink); background: var(--accent-weak); font-weight: 600; }
    .cb-fork-branch:hover { background: var(--accent-line); }
    .cb-fork-revert { color: var(--muted); }
    .cb-fork-revert:hover { color: var(--warn); border-color: var(--warn-line-strong); background: var(--warn-weak); }
    .cb-fork-revert.armed { color: var(--warn); border-color: var(--warn-line-strong); background: var(--warn-weak); font-weight: 600; }

    /* —— 条件板在 telegram 态（.cb-in-side）：只留聊天记录 + 预览 + 撤销/重做；隐藏经典行/摘要/说明 —— */
    .cond-board.cb-in-side { margin: 0; border: 0; background: transparent; padding: 0; box-shadow: none; display: flex; flex-direction: column; min-height: 0; }
    .cb-in-side .cb-summary { display: none; }                                  /* 折叠条：telegram 态不要（常驻查询条件栏已在上方） */
    /* 覆盖 hidden：telegram 态恒展开；并解除基础 .cb-body 的 max-height:min(32vh,280px)+overflow（那是旧折叠板的，
       telegram 态会把聊天流嵌套二次裁剪、且让自动滚到底落到错误容器）——改由外层 #sideBoardScroll 统一滚动。 */
    .cb-in-side .cb-body { display: flex !important; flex-direction: column; min-height: 0; gap: 6px; max-height: none; overflow: visible; border-top: 0; }   /* border-top 也去掉：telegram 态聊天流已搬出 condBoard，空壳 cb-body 的那道线就是「气泡下方的横条」（用户点2） */
    .cb-in-side .cb-rows { display: none; }                                     /* 经典条件行：telegram 态隐藏（靠常驻栏 + 对话改） */
    .cb-in-side .cb-hint, .cb-in-side .cb-about { display: none; }
    .cb-in-side .cb-history { flex: 1 1 auto; }
    .cb-in-side .cb-preview { font-size: 12px; }
    /* 引导式放宽预览（results.js applyRelaxation 给 #condBoard 挂 .cb-relax-preview）：只藏「原严格条件」
       展示层（摘要 + 经典条件行），聊天记录 #cbHistory 留着——telegram 态整块条件板即聊天窗，藏整块会连带
       抹掉用户整段对话（点1 反馈）。顶层规则、两模式都生效；hero 态本会显示的摘要/条件行也一并临时收起。
       任何真实重画（renderCondBoard 顶部）会移除这个类，让展示层按新数据重新出现。 */
    .cond-board.cb-relax-preview .cb-summary,
    .cond-board.cb-relax-preview .cb-rows { display: none; }
    /* 撤销/重做步进条已退役（点7：游标移动只有「查看历史回复」气泡按钮一个入口；回栈顶用「回到最新」）。 */

    .icon-btn {
        width: 38px; height: 38px; border-radius: 10px; border: 1px solid var(--border-2);
        background: var(--surface); color: var(--text-2); cursor: pointer; font-size: 17px;
        display: grid; place-items: center; transition: border-color 0.15s, color 0.15s, background 0.15s;
    }
    .icon-btn:hover { border-color: var(--accent-line); color: var(--accent-ink); background: var(--accent-weak); }

    /* 收起后：左上角悬浮 logo（点击展开侧栏） */
    .side-fab {
        position: fixed; top: 16px; left: 16px; z-index: var(--z-fab);
        display: inline-flex; align-items: center; gap: 8px; padding: 9px 14px; border-radius: 12px;
        background: var(--surface); border: 1px solid var(--border); box-shadow: var(--shadow);
        cursor: pointer; opacity: 0; transform: translateX(-10px); pointer-events: none;
        transition: opacity .2s ease .04s, transform .28s cubic-bezier(.22, 1, .36, 1) .04s, border-color .15s;
    }
    .side-fab .wordmark { font-size: 18px; }
    .side-fab:hover { border-color: var(--accent-line); }
    body.side-closed .side-fab { opacity: 1; transform: none; pointer-events: auto; }
    /* ≤780px 向下滚动阅读时固钉淡出（shell.js initFabTuck 切类）；进/退同走
       side-fab 既有 transition。只在窄屏生效——桌面 fab 与内容无冲突。 */
    @media (max-width: 780px) {
        body.fab-tucked .side-fab { opacity: 0; transform: translateX(-10px); pointer-events: none; }
    }

    /* 移动端抽屉遮罩（仅移动端生效，见媒体查询） */
    .side-backdrop { display: none; position: fixed; inset: 0; z-index: var(--z-backdrop);
        background: rgba(16, 33, 46, 0.4); opacity: 0; pointer-events: none; transition: opacity .2s ease; }

    /* ---------------- Layout ---------------- */
    /* 侧栏展开时把内容整体右推，让居中的 hero 在剩余空间里居中；收起时铺满。悬浮侧栏落在左侧留白里。
       **`:not(.dataset-page-body)`**：详情页 /dataset 无侧栏，必须排除在此留白之外——否则内容整体右移一个侧栏宽。
       这里用「排除法」而非在详情页反向归零：本环境实测里，`.dataset-page-body`(0,1,0) 乃至
       `body.dataset-page-body`(0,1,1) 甚至内联 !important 都压不过本条（一个无法从层叠规则解释、可复现的反常，
       且 `body` 上 `transition: padding-left` 会让同步读到过渡起始值 328 误导排查）。改成本条根本不命中详情页 body，
       是确定性匹配、绕开该反常。 */
    body:not(.dataset-page-body) { padding-left: calc(var(--side-w) + 28px); transition: padding-left .32s cubic-bezier(.22, 1, .36, 1); }
    body.side-closed { padding-left: 0; }
    .main { max-width: 1140px; margin: 0 auto; padding: 30px 24px 90px; }
    .view { display: none; }
    .view.active { display: block; animation: fade 0.34s cubic-bezier(.22, 1, .36, 1); }
    @keyframes fade { from { opacity: 0; transform: translateY(7px); } to { opacity: 1; transform: none; } }

    /* 智能查询：初始 hero 垂直居中占满视口余高；出结果后（.has-results）回归顶部布局，给结果腾位置。
       居中↔顶部的位移由 JS 用 FLIP（transform）平滑过渡。 */
    .view.active[data-view="query"] {
        display: flex; flex-direction: column; justify-content: center;
        min-height: calc(100vh - 120px);           /* 老浏览器 fallback */
        min-height: calc(100dvh - 120px);   /* 视口 − main上下内边距(30+90)；dvh 让移动端动态工具栏收起时不溢出 */
    }
    .view.active[data-view="query"].has-results { justify-content: flex-start; min-height: 0; }
    /* 结果态 slim hero：只留查询入口（console），大标题/副文案/输入提示/示例 chips/记忆建议退场，
       结果列表成为首屏主体；chips 不再渲染也根治了「示例 chips 与结果头重叠」。
       display:none 不动画（reduced-motion 天然安全）；hero 的位移沿用 enterResultsLayout 的既有 FLIP。 */
    .view[data-view="query"].has-results .hero .hero-rot,
    .view[data-view="query"].has-results .hero .chips,
    .view[data-view="query"].has-results .hero .memory-suggestions { display: none; }
    .view[data-view="query"].has-results .hero { padding: 0; }
    /* 结果态搜索框保持水平居中（margin auto），不再左对齐——与初始态同轴，视觉更稳。
       出结果后不再单独限宽——控制台已按内容自适应（见 .console 的 fit-content），pill 摘要在任何状态都不折行、不超框。 */
    .view[data-view="query"].has-results .console { margin: 8px auto 0; }
    /* （2026-08-02 用户）：结果态 + 侧栏开着时，主区**不再有输入框**——
       唯一「继续说」入口是侧栏工作卡最下方的微信式输入行（#chatInput）。
       侧栏收起 / 移动端（.side-closed，≤780px  drawer 关闭）主 console 保留可见：
       那时侧栏够不着，它是唯一输入入口。 */
    @media (min-width: 781px) {
        body:not(.side-closed) .view[data-view="query"].has-results .hero .console { display: none; }
    }

    .page-head { margin-bottom: 22px; }
    .page-head h2 { font-size: 22px; font-weight: 700; }
    .page-head p { color: var(--text-2); font-size: 14.5px; margin-top: 5px; }

    /* ---------------- Query hero ---------------- */
    .hero { text-align: center; padding: 26px 0 6px; }
    .hero h1 { font-size: 30px; font-weight: 700; letter-spacing: -0.3px; }
    .hero p { color: var(--text-2); font-size: 15.5px; margin-top: 11px; }

    /* hero 轮播：三条文案占同一网格位叠放，交叉淡化 + 进场上浮（视觉 spec §8） */
    .hero-rot { display: grid; }
    .hero-rot > .hero-slide { grid-area: 1 / 1; opacity: 0; visibility: hidden;
        transform: translateY(12px);
        transition: opacity var(--dur-slow) var(--ease-spring),
                    transform var(--dur-slow) var(--ease-spring),
                    visibility 0s linear var(--dur-slow); }
    .hero-rot > .hero-slide.is-on { opacity: 1; visibility: visible; transform: none;
        transition: opacity var(--dur-slow) var(--ease-spring),
                    transform var(--dur-slow) var(--ease-spring); }
    .hero-rot > .hero-slide.is-done { transform: translateY(-10px); }
    .hero-rot > .hero-slide-sub { font-size: var(--fs-xl); font-weight: 600; line-height: 1.5;
        letter-spacing: -0.2px; color: var(--text); max-width: 720px; margin: 0 auto; }
    @media (max-width: 780px) {
        .hero-rot > .hero-slide-sub { font-size: 17px; }
    }
    @media (prefers-reduced-motion: reduce) {
        .hero-rot > .hero-slide { transition: none; }
    }

    /* ---- 统一搜索控制台（2026-08-30 pill 化）：一条大圆角长条 = 文本框 + 范围圆钮 + 圆形发送键，
           与侧栏 #chatComposer 同族。来源/时间两枚筛选的静态家收进下方弹层 #heroScopePop（点范围圆钮展开）；
           出结果后照旧零复制搬去侧栏 #scopePop。 ---- */
    .console {
        position: relative; z-index: 2;   /* 整块高于其后的示例 chips：弹层随之盖在 chips 之上 */
        width: fit-content; min-width: min(520px, 100%); max-width: min(880px, 100%);
        margin: 24px auto 0; background: var(--surface);
        border: 1px solid var(--border-2); border-radius: 26px;
        box-shadow: var(--shadow); display: flex; align-items: flex-end; gap: 4px;
        padding: 7px 7px 7px 20px;
        transition: border-color 0.15s ease, box-shadow 0.15s ease;
    }
    .console:focus-within { border-color: var(--accent-line); box-shadow: var(--shadow-focus); }
    .console-main { flex: 1; min-width: 0; display: flex; flex-direction: column; position: relative; }
    .console-main textarea {
        /* flex-basis auto：让 autogrow 的 inline height 真正生效（真机验证发现——
           `flex: 1`（basis 0%）下 flex 布局接管高度，文本再多也不长，超长内容被压在
           min-height 里滚动；改 0 1 auto 后高度由内容驱动、上限仍是 6 行）。 */
        flex: 0 1 auto; border: none; outline: none; resize: none; background: transparent;
        font-family: var(--font); font-size: 15.5px; color: var(--text);
        padding: 11px 6px 9px 0; line-height: 1.5; min-height: 46px; max-height: 167px;   /* 上限 6 行，autogrow 的 CSS 兜底 */
    }
    .console-main textarea::placeholder { color: var(--muted); }
    /* 范围圆钮与发送键：与侧栏 .scope-btn/.cb-send 同形，按 hero 尺寸放大到 40px；
       flex-end 钉底，autogrow 长高时不随文本行漂移。
       （2026-08-30）：单行态 textarea 46px vs 钮 40px，纯钉底使钮心比文本框心低 3px
       （实测 btn_cy=434 / textarea_cy=431）。margin-bottom:3px 让单行态钮与文本框同心
       （= 钮在 60px pill 内上下各 10px 正好居中）；多行生长时仍贴底，钉底语义不变。 */
    .console-scope-btn, .console-send { width: 40px; height: 40px; margin-bottom: 3px; }
    .console-scope-btn svg, .console-send svg { width: 17px; height: 17px; }
    /* 范围弹层（首页态）：锚在 pill 正下方（与侧栏 #scopePop 向上弹相反），两枚筛选纵向堆叠、
       恒展开可改；复用 .scope-pop 的卡片材质与弹层面板规则（toggle 隐藏/面板去盒）。 */
    .console-scope-pop {
        left: 0; right: 0; bottom: auto; top: calc(100% + 8px);
        flex-direction: column; gap: 10px; transform-origin: 24px 0;
    }
    .console-scope-pop:not([hidden]) { animation: consoleScopePopIn .18s cubic-bezier(.22, 1, .36, 1); }
    @keyframes consoleScopePopIn { from { opacity: 0; transform: translateY(-6px) scale(.98); } to { opacity: 1; transform: none; } }
    @media (prefers-reduced-motion: reduce) { .console-scope-pop:not([hidden]) { animation: none; } }
    .console-scope-pop .console-bar { display: flex; flex-direction: column; gap: 12px; }
    .console-scope-pop .cbar-cell { display: flex; }   /* 无右坞：两块面板都直接可见 */
    /* 识别落地提醒：停笔识别成功且真有收窄时，范围圆钮一圈柔光脉冲 + pill 上方浮出
       一粒识别摘要（2.2s 自动淡去）。不碍眼、不打断输入；reduced-motion 只留静态摘要行。 */
    .console-scope-btn.detect-pulse { animation: detectPulse 1.15s cubic-bezier(.22, 1, .36, 1); }
    @keyframes detectPulse {
        0% { box-shadow: 0 0 0 0 var(--accent-weak), 0 0 0 0 var(--accent-line); }
        55% { box-shadow: 0 0 0 5px var(--accent-weak), 0 0 0 9px transparent; }
        100% { box-shadow: 0 0 0 0 transparent, 0 0 0 0 transparent; }
    }
    @media (prefers-reduced-motion: reduce) { .console-scope-btn.detect-pulse { animation: none; } }
    .detect-note {
        position: absolute; bottom: calc(100% + 8px); right: 10px; z-index: var(--z-dropdown);
        max-width: min(420px, 86%); overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
        background: var(--surface); border: 1px solid var(--accent-line); color: var(--accent-ink);
        border-radius: 999px; padding: 5px 12px; font-size: 12px; font-weight: 600;
        box-shadow: var(--shadow-sm); pointer-events: none;
        animation: detectNote 2.2s ease forwards;
    }
    @keyframes detectNote {
        0% { opacity: 0; transform: translateY(4px); }
        12% { opacity: 1; transform: none; }
        78% { opacity: 1; }
        100% { opacity: 0; transform: translateY(-3px); }
    }
    @media (prefers-reduced-motion: reduce) { .detect-note { animation-duration: .01s; animation-delay: 2.2s; } }
    /* pill 态发送键：圆形纸飞机（文案「发送」保留在 aria/title，视觉隐藏） */
    .console #submitBtn { align-self: flex-end; flex: none; min-width: 0; padding: 0; border-radius: 50%; }
    .console #submitBtn .sb-label { flex-direction: row; gap: 0; }
    .console #submitBtn .sb-txt { display: none; }
    /* 旧底栏横条样式退役（2026-08-30 pill 化）：#consoleBar 整棵搬进 #heroScopePop，
       旧 grid/切割线/浅绿填充只在弹层语义外才有意义——此处清零，弹层内由 .console-scope-pop 规则接管。 */
    .console-bar { padding: 0; }
    .cbar-cell { position: relative; display: flex; align-items: center; gap: 8px; min-width: 0; }
    .cbar-label { font-size: 12px; font-weight: 600; color: var(--text-2); white-space: nowrap; }
    .cbar-div { display: none; }
    .btn {
        border: 1px solid var(--border-2); background: var(--surface); color: var(--text-2);
        font-family: var(--font); font-size: 14px; font-weight: 600; cursor: pointer;
        padding: 10px 16px; border-radius: 11px;
        transition: border-color 0.15s, color 0.15s, background 0.15s, transform 0.1s;
        display: inline-flex; align-items: center; gap: 7px; white-space: nowrap;
    }
    .btn:hover { border-color: var(--accent-line); color: var(--accent-ink); }
    /* 全站 disabled 统一灰阶配方（与 .cta-disabled / .file-dl.disabled / auto-owned 同族），
       不再 opacity 半透；:hover 变体压住 .btn-primary:hover，禁用态不再被悬停点亮。 */
    .btn:disabled, .btn:disabled:hover {
        background: var(--surface-2); color: var(--muted); border-color: var(--border);
        box-shadow: none; opacity: 1; cursor: not-allowed;
    }
    .btn-primary { border: none; background: var(--accent); color: var(--surface); box-shadow: var(--shadow-sm); }
    .btn-primary:hover { background: var(--accent-ink); color: var(--surface); }

    /* ---------------- 「发送」按钮 · 品牌青 + 纸飞机 ----------------
       静置＝纯品牌青（--accent）；hover 只提亮文字/边框/投影（克制、无光斑、无漂移）。
       检索中＝静态 loading（数字里程表已退役，进度交给系统回复气泡三点动画）；
       reduced-motion / forced-colors 降级。 */
    #submitBtn {
        position: relative; isolation: isolate; overflow: hidden;
        justify-content: center;                         /* 文字变化时恒居中 */
        background: var(--accent);
        color: #f0fdfa;
        border: 1px solid rgba(255,255,255,.14);
        border-radius: var(--radius-md); font-weight: 700; letter-spacing: .01em; text-shadow: 0 1px 2px rgba(4,40,45,.25);
        box-shadow: 0 6px 18px rgba(13,148,136,.28);     /* 青色投影，在浅底上自然抬起 */
        transition: color .3s ease, border-color .3s ease, box-shadow .3s ease, transform .18s ease;
    }
    #submitBtn .sb-label {
        position: relative; z-index: 2;
        display: flex; flex-direction: column; align-items: center; gap: 4px;
        transition: opacity .3s ease, transform .35s cubic-bezier(.2,.8,.2,1);
    }
    #submitBtn .sb-ico { width: 22px; height: 22px; display: block; }
    #submitBtn .sb-txt { font-size: 13px; font-weight: 700; letter-spacing: .06em; }
    #submitBtn:not(:disabled):hover { color: var(--surface); border-color: rgba(178,230,224,.7); box-shadow: 0 8px 22px rgba(13,148,136,.34); }
    #submitBtn:not(:disabled):active { transform: translateY(1px); }
    #submitBtn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

    /* 检索中（loading 时按钮 disabled，:hover 不触发，故单列 .loading 规则）：
       数字里程表已全面退役——进度表达交给系统回复气泡里的三点动画（progress.js →
       #cbProgPct/#cbLivePct），按钮只保留静态 loading 态：「发送」字样不动、opacity:1 盖过
       .btn:disabled 的灰阶配方。.sb-od 残留规则随机器一并清除。 */
    #submitBtn.loading {
        opacity: 1; color: var(--surface); cursor: progress;
        border-color: rgba(178,230,224,.85);
    }

    @media (prefers-reduced-motion: reduce) {
        #submitBtn, #submitBtn .sb-label { transition: none; }
        /* 减少动效：中和新加的悬停位移/旋转/视图入场，只保留颜色反馈 */
        .chip, .card, .sf-caret { transition: none; }
        .chip:hover, .card:hover { transform: none; }
        .view.active { animation: none; }
    }
    @media (forced-colors: active) {              /* Windows 高对比：交系统色，保可读可点 */
        #submitBtn { background: ButtonFace; color: ButtonText; box-shadow: none; border: 1px solid ButtonText; }
        #submitBtn .sb-label { text-decoration: underline; }
        /* 装饰色块/圆点在系统色模式下保持可辨——柱体、开关、来源点、FASTQ 圆点 */
        .timeline-bar i { background: CanvasText; }
        .timeline-bar.active i { background: Highlight; }
        .switch .slider { border: 1px solid ButtonText; }
        .switch input:checked + .slider { background: Highlight; }
        .sf-dot { background: Highlight; box-shadow: none; }
        .fastq { border: 1px solid currentColor; }
        .fastq::before { background: currentColor; }
    }

    .chips { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; margin: 16px auto 0; max-width: 720px; }
    .memory-suggestions { width: min(720px, 94vw); margin: 12px auto 0; padding: 10px 11px; border: 1px solid var(--border); border-radius: 12px; background: var(--surface); }
    .memory-suggestions-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 7px; color: var(--muted); font-size: 11px; font-weight: 700; }
    .memory-suggestions-head button { border: 0; background: transparent; color: var(--accent-ink); font: inherit; cursor: pointer; }
    .memory-suggestion-list { display: flex; gap: 7px; overflow-x: auto; }
    .memory-suggestion { min-width: 0; flex: 1 1 0; padding: 8px 9px; border: 1px solid var(--border); border-radius: 9px; background: var(--surface); text-align: left; cursor: pointer; }
    .memory-suggestion span { display: block; color: var(--muted); font-size: var(--fs-micro); }
    .memory-suggestion strong { display: block; margin-top: 2px; color: var(--text-2); font-size: 11.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
    .memory-suggestion:hover { border-color: var(--accent-line); }
    .memory-suggestion:focus-visible { border-color: var(--accent-line); outline: 2px solid var(--accent); outline-offset: 2px; }
    .chip {
        border: 1px solid var(--border-2); border-radius: 999px; background: var(--surface);
        color: var(--text-2); font-size: 12.5px; padding: 7px 14px; cursor: pointer; font-family: var(--font);
        transition: border-color .15s ease, color .15s ease, background .15s ease, transform .2s cubic-bezier(.22,1,.36,1);
    }
    .chip:hover { border-color: var(--accent-line); color: var(--accent-ink); background: var(--accent-weak); transform: translateY(-1px); }
    .chip:active { transform: translateY(0); }

    /* ---------------- Results / lists ---------------- */
    .results-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin: 34px 0 16px; }
    .results-title { font-size: 17px; font-weight: 700; }
    /* 「初步结果」徽标——agent 环在跑、屏上是 pre-loop 先行结果；最终落地即摘。
       胶囊小标：随 #resultsHead 两态搬家（正常态主区 / 交换态侧栏）都可见。 */
    .prelim-badge { display: inline-block; margin-left: 8px; padding: 2px 8px; border-radius: 999px;
        background: var(--accent-weak); color: var(--accent-ink); border: 1px solid var(--accent-line);
        font-size: 11px; font-weight: 600; line-height: 1.4; vertical-align: 2px; letter-spacing: .3px; }
    /* 结果头右侧只剩可行性概览（次级小按钮）——旧计数行 .results-meta 与「记住这次需求」按钮已并入/移除 */
    .results-head-acts { margin-left: auto; display: flex; align-items: center; gap: 8px; }
    .feasibility-btn { padding: 7px 12px; font-size: 12.5px; }
    /* 按钮内双 span 文案的默认态——只显完整文案（正常态像素级不变）；短文案由交换态窄栏规则接管 */
    .results-head-acts .bt-short { display: none; }

    /* 2026-08-17：批次切换器 pill 组——>1 批时由 results.js 渲染进 #batchBar
       （.res-overview 内、标题行之下，随交换两态搬家）。概览卡内改 segmented 控件造型
       （规则见下方「结果区头部重设计」段，scoped 覆盖）；本基础规则仅兜底。批次多横向滚动（thin scrollbar，不抢卡片视线）。
       负边距已退役（-8px 0 14px → 10px 0 14px），概览卡内由 scoped 规则接管。 */
    .batch-bar {
        display: flex; align-items: center; gap: 6px; margin: 10px 0 14px; padding: 2px;
        overflow-x: auto; scrollbar-width: thin;
    }
    .batch-bar[hidden] { display: none; }
    .batch-pill {
        flex: none; max-width: 220px; padding: 5px 12px; border-radius: 999px; cursor: pointer;
        background: var(--surface); border: 1px solid var(--border-2); color: var(--text-2);
        font-size: 12px; font-family: inherit; line-height: 1.4;
        white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
        transition: color .15s, background .15s, border-color .15s, box-shadow .2s;
    }
    .batch-pill:hover { color: var(--text); border-color: var(--accent-line); }
    .batch-pill:active { transform: scale(.97); }
    .batch-pill.is-on {
        background: var(--accent-weak); color: var(--accent-ink); border-color: var(--accent-line);
        box-shadow: 0 0 0 3px var(--accent-weak); font-weight: 600;
    }
    .batch-pill:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

    .grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: var(--space-4); }   /* 卡片最小宽 324→300：抵消侧栏加宽 +64px 对主内容的挤压，让 1024/1366 等常见宽度的列数不掉档（同列数下卡片实际宽由 1fr 撑满、观感不变）；行内等高靠 grid 默认 stretch */

    .card {
        position: relative; background: var(--surface); border: 1px solid var(--border);
        border-radius: var(--radius); padding: 18px 18px 16px; box-shadow: var(--shadow-sm);
        display: flex; flex-direction: column;
        transition: border-color .18s ease, box-shadow .22s ease, transform .24s cubic-bezier(.22,1,.36,1);
    }
    .card:hover { border-color: var(--border-2); box-shadow: var(--shadow); transform: translateY(-3px); }

    .fav {
        position: absolute; top: 13px; right: 13px; width: 34px; height: 34px;
        border: none; background: transparent; color: var(--muted); cursor: pointer;
        display: grid; place-items: center; border-radius: 9px; transition: background 0.15s, color 0.15s;
    }
    .fav:hover { background: var(--surface-2); color: var(--accent); }
    .fav.active { color: var(--accent); }
    .fav svg { width: 19px; height: 19px; fill: none; stroke: currentColor; stroke-width: 1.9; }
    .fav.active svg { fill: currentColor; }
    /* —— 收藏动效（2026-07-29 点4）——
       「收进去了」这件事此前只有一次 0.6→1 的缩放，弱到看不出来。改成：心跳式回弹 + 一圈扩散消失的光环；
       取消收藏**不给光环**（光环是「加入成功」的语汇，用在移除上会读反），只回落一下。
       纯 CSS（不依赖 GSAP → 离线随包也有），`prefers-reduced-motion` 下整体关闭、功能一字不变。
       动画类由 JS 在动画结束后摘掉，故同一颗心形可以反复触发。 */
    .fav.fav-pop svg { animation: favPop .46s cubic-bezier(.22, 1, .36, 1); }
    .fav.fav-pop::after {
        content: ""; position: absolute; top: 50%; left: 50%; width: 22px; height: 22px; margin: -11px 0 0 -11px;
        border-radius: 50%; border: 2px solid var(--accent); pointer-events: none;
        animation: favRing .5s ease-out forwards;
    }
    .fav.fav-unpop svg { animation: favUnpop .32s ease-out; }
    @keyframes favPop { 0% { transform: scale(.6); } 55% { transform: scale(1.22); } 100% { transform: scale(1); } }
    @keyframes favRing { 0% { opacity: .5; transform: scale(.45); } 100% { opacity: 0; transform: scale(2.1); } }
    @keyframes favUnpop { 0% { transform: scale(1); } 45% { transform: scale(.72); } 100% { transform: scale(1); } }
    /* 侧栏「我的收藏」入口跟着弹一下：告诉用户这条**去了哪里**（心形自己弹只说明「点到了」）。 */
    .nav-item.fav-landed svg { animation: favLanded .66s cubic-bezier(.22, 1, .36, 1); color: var(--accent); }
    @keyframes favLanded { 0% { transform: scale(1); } 32% { transform: scale(1.34); } 100% { transform: scale(1); } }
    /* 心形 popover 入场：从心形那一角展开，别凭空闪现（定位由 JS 写 left/top，故只动 transform/opacity）。 */
    .fav-popover { animation: favPopoverIn .16s cubic-bezier(.22, 1, .36, 1); transform-origin: top right; }
    @keyframes favPopoverIn { from { opacity: 0; transform: scale(.94) translateY(-4px); } to { opacity: 1; transform: none; } }
    @media (prefers-reduced-motion: reduce) {
        .fav.fav-pop svg, .fav.fav-unpop svg, .nav-item.fav-landed svg, .fav-popover { animation: none; }
        .fav.fav-pop::after { display: none; }
    }

    /* 徽章区固定两行档：2×≈23px pill 行 + 7px 行距 = 53px；无 reach 徽章的卡同占高（标题顶对齐），超出两行截断 */
    .badges { display: flex; align-items: center; align-content: flex-start; gap: 7px; flex-wrap: wrap;
        min-height: 53px; max-height: 53px; overflow: hidden; margin-bottom: 11px; padding-right: 34px; }
    .rank { font-family: var(--mono); font-size: 12px; font-weight: 700; color: var(--accent-ink); }
    /* 平台 / 来源：降为静音文字（去 pill 色噪），让 FASTQ 语义色 pill 成为顶部唯一亮点、平息杂乱 */
    .card-meta { font-size: 12px; font-weight: 500; color: var(--muted); }
    .card-meta .dot { opacity: .5; margin: 0 6px; }
    .fastq { font-size: 11.5px; font-weight: 600; border-radius: 7px; padding: 3px 9px; display: inline-flex; align-items: center; gap: 5px; }
    .fastq::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
    .fastq.ok { color: var(--ok); background: var(--ok-weak); }
    .fastq.no { color: var(--unknown); background: var(--unknown-weak); }   /* 「无 FASTQ」是中性事实、不是缺陷——去告警红，归中性灰 */
    .fastq.unknown { color: var(--unknown); background: var(--unknown-weak); }

    /* 标题两行档：clamp 2 行 + min-height 两行（15.5×1.4×2=43.4），一行标题的卡也占同样高度 */
    .card-title { font-size: 15.5px; font-weight: 600; line-height: 1.4; min-height: 43.4px; margin-bottom: 9px;
        display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
    /* 推荐理由两行档：clamp 2 行 + min-height 两行（12.5×1.5×2=37.5），一行理由不再把 tags 区顶高 */
    .card-why { font-size: 12.5px; color: var(--text-2); line-height: 1.5; min-height: 37.5px; margin-bottom: 11px;
        display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
    .card-why b { color: var(--accent-ink); font-weight: 600; }

    /* tags 区限高 2 行截断；完整值在各 .tag 的 title 属性兜底。
       .tag 钉固定高 24px（inline-flex 垂直居中），max-height 精确等于「2 行 + 1 个行距」54px——
       此前 50px 不是行高（24px）整数倍，第二行被拦腰切一半；现在第二行要么完整显示、要么整行藏进 title。
       单个 .tag 值超长（如多病种串）时在 24px 钉高里换行、字溢出芯片上下缘盖住邻行——
       钉 nowrap + max-width:100% + overflow:hidden，超长值在芯片内单行截断（title 兜全文，同上行惯例）。 */
    .card-tags { display: flex; flex-wrap: wrap; align-content: flex-start; gap: 6px; max-height: calc(2 * 24px + 6px); overflow: hidden; margin-bottom: 13px; }
    .tag { display: inline-flex; align-items: center; box-sizing: border-box; height: 24px; font-size: 11.5px; color: var(--text-2); background: var(--surface-2); border-radius: 6px; padding: 3px 9px; white-space: nowrap; max-width: 100%; overflow: hidden; }
    .tag-k { font-size: var(--fs-micro); font-weight: 600; color: var(--muted); margin-right: 4px; }   /* 组织/疾病等裸灰块的前缀小标签 */

    /* 卡片脚：只剩样本量（「数据集详情」已升格为 CTA 行下的独立全宽按钮，不再挤在此行右侧）。 */
    .card-foot { margin-top: auto; display: flex; align-items: baseline; justify-content: space-between; gap: 10px; padding-top: 12px; border-top: 1px solid var(--border); }
    .sample { font-size: 12px; color: var(--muted); }
    .sample b { color: var(--text-2); font-weight: 600; }
    /* meta 行折行只许发生在「 · 」分隔符上，单段（如「发表 2025」）内部不拆——
       此前年份孤挂下一行。 */
    .sample .sample-bit { white-space: nowrap; }
    /* 主 CTA 行：两枚等宽按钮。数据集页面=填充(主) 权重 ≥ 下载数据=柔和(强次)；无独立页面时下载升为填充 */
    .card-cta { display: flex; gap: 8px; margin-top: 12px; }
    .cta { flex: 1 1 0; min-width: 0; display: inline-flex; align-items: center; justify-content: center; gap: 6px;
        padding: 9px 12px; border-radius: 10px; font: 600 13px/1 var(--font); white-space: nowrap; cursor: pointer;
        border: 1px solid transparent; text-decoration: none;
        transition: background .15s ease, color .15s ease, border-color .15s ease; }
    .cta-primary { background: var(--accent); color: var(--surface); border-color: var(--accent); }
    .cta-primary:hover { background: var(--accent-ink); border-color: var(--accent-ink); }
    .cta-primary:focus-visible { background: var(--accent-ink); border-color: var(--accent-ink); outline: 2px solid var(--accent); outline-offset: 2px; }
    .cta-soft { background: var(--accent-weak); color: var(--accent-ink); border-color: var(--accent-line); }
    .cta-soft:hover { background: var(--accent); color: var(--surface); border-color: var(--accent); }
    .cta-soft:focus-visible { background: var(--accent); color: var(--surface); border-color: var(--accent); outline: 2px solid var(--accent); outline-offset: 2px; }
    .cta-disabled { background: var(--surface-2); color: var(--muted); border-color: var(--border); cursor: not-allowed; }

    /* 「数据集详情 ↗」独立全宽按钮行（原 .btn-intro-link 文字链升格）——cta-soft 血统但占整卡宽，
       位于主 CTA 行之下、文件行之上；权重刻意低于填充主钮「打开数据集页」，与「下载数据」同档略弱。 */
    .btn-detail { display: flex; align-items: center; justify-content: center; gap: 6px; width: 100%;
        box-sizing: border-box; margin-top: 8px; padding: 8px 12px; border-radius: 10px;
        background: var(--accent-weak); color: var(--accent-ink); border: 1px solid var(--accent-line);
        font: 600 12.5px/1 var(--font); white-space: nowrap; cursor: pointer; text-decoration: none;
        transition: background .15s ease, color .15s ease, border-color .15s ease; }
    .btn-detail:hover { background: var(--accent); color: var(--surface); border-color: var(--accent); }
    .btn-detail:focus-visible { background: var(--accent); color: var(--surface); border-color: var(--accent); outline: 2px solid var(--accent); outline-offset: 2px; }

    /* ---------------- Card: all-files entry ---------------- */
    .files-open {
        width: 100%; margin-top: 11px; text-align: left;
        display: inline-flex; align-items: center; gap: 8px;
        font-size: 12px; font-weight: 500; color: var(--text-2);
        background: var(--surface-2); border: 1px solid var(--border);
        border-radius: 9px; padding: 8px 11px; cursor: pointer;
        transition: border-color 0.15s, color 0.15s, background 0.15s;
    }
    .files-open:hover { border-color: var(--accent-line); color: var(--accent-ink); background: var(--accent-weak); }
    /* 占位槽：无文件按钮的卡补同盒尺寸槽（结构同真按钮 → 高度恒等），钉齐同行 CTA 行；不可见不响应 */
    .files-open-slot { visibility: hidden; pointer-events: none; }
    .files-open .fo-ico { font-size: 12px; line-height: 1; opacity: 0.75; }
    .files-open .fo-arrow { margin-left: auto; opacity: 0.55; transition: transform 0.18s ease, opacity 0.18s ease; }
    .files-open:hover .fo-arrow { transform: translateX(3px); opacity: 1; }

    /* ---------------- Files modal ---------------- */
    body.modal-lock { overflow: hidden; }
    /* grid 轨道必须显式 minmax(0,1fr)：缺省时隐式 auto 轨道按内容 max-content 撑大（如 .memory-modal 的
       700px），.modal 的 max-width:100% 相对**撑大后的轨道**解析 → 钳制失效，移动端全系弹窗宽出视口
       （500px 下实测 628–700px）。轨道钉死为容器内容宽后，max-width:100% 才相对真实可用宽解析。 */
    .modal-backdrop {
        position: fixed; inset: 0; z-index: var(--z-modal); display: grid; grid-template-columns: minmax(0, 1fr);
        place-items: center; padding: 24px;
        background: rgba(16, 33, 46, 0.42);
        -webkit-backdrop-filter: blur(6px) saturate(1.1); backdrop-filter: blur(6px) saturate(1.1);
    }
    .modal-backdrop[hidden] { display: none; }
    .modal {
        width: 640px; max-width: 100%; max-height: min(78vh, 720px);
        background: var(--surface); border: 1px solid var(--border-2); border-radius: var(--radius-lg);
        box-shadow: var(--shadow-lg); display: flex; flex-direction: column; overflow: hidden;
    }
    .modal-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px;
        padding: 20px 22px 15px; border-bottom: 1px solid var(--border); }
    .modal-title { font-size: 16px; font-weight: 700; line-height: 1.35;
        display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
    .modal-sub { font-size: 12.5px; color: var(--muted); margin-top: 4px; }
    .modal-body { padding: 12px 14px 16px; overflow-y: auto; }
    /* 介绍弹窗的模态几何样式（外壳、常驻操作栏、推挤下拉、上下半窗、分屏容器）已随弹窗退役删除——
       「查看介绍」改为**独立浏览器标签页** /dataset（详情页样式见文件末「数据集详情页」段）。
       介绍**内容**样式（摘要 / 关键事实 / FAIR / 兼容 / DAS / 对比选择器等）保留在下方，被详情页各子标签页复用。 */
    /* 兼容卡网格：兼容卡=全检索卡（buildCard 缺省），容器直接用标准 .grid；此处只留每卡底部「兼容依据」行样式 */
    .compat-basis-line { margin-top: 8px; color: var(--text-2); font-size: 10.5px; line-height: 1.45; }
    .compare-hint { margin-bottom: 10px; color: var(--text-2); font-size: 12.5px; line-height: 1.55; }
    /* 对比目标的 bare 正文直链行（下载/来源页；主弹窗直链在 tab 栏） */
    .intro-bare-actions { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 16px;
        padding-top: 14px; border-top: 1px solid var(--border); }
    /* 心形 popover 全局层级抬到 modal 之上：下半窗兼容卡里点心形时浮层不能被弹窗盖住（卡片区体验不变） */
    .fav-popover { z-index: 265; }
    .intro-summary { padding: 15px 16px; border: 1px solid var(--accent-line); border-radius: 12px; background: var(--accent-weak); }
    .intro-source { display: inline-flex; margin-bottom: 7px; padding: 3px 8px; border-radius: 999px; background: var(--surface); color: var(--accent-ink); font-size: 11px; font-weight: 700; }
    .intro-summary p, .intro-reason p { color: var(--text-2); font-size: 13px; line-height: 1.72; }
    /* LLM 中文导读（实验性）：与确定性 summary 明确区分——虚线框 + 「实验性」标签，暗示「据元数据生成、可能有误」 */
    .intro-llm { margin-top: 12px; padding: 13px 14px; border: 1px dashed var(--accent-line); border-radius: 11px; background: var(--surface-2); }
    .intro-llm p { color: var(--text-2); font-size: 13px; line-height: 1.72; }
    .intro-llm .intro-source { background: var(--accent-weak); }
    .intro-llm-note { margin-top: 8px; color: var(--muted); font-size: 11px; line-height: 1.55; }
    .intro-llm-off p { color: var(--muted); font-size: 12px; }
    .intro-reason { margin-top: 14px; padding: 13px 14px; border: 1px solid var(--accent-line); border-radius: 10px; background: var(--surface-2); }
    .intro-reason h4, .intro-facts h4 { margin-bottom: 6px; font-size: 13px; }
    .intro-facts { margin-top: 17px; }
    .intro-facts dl { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
    .intro-fact { min-width: 0; padding: 10px 11px; border: 1px solid var(--border); border-radius: 9px; background: var(--surface); }
    .intro-fact dt { color: var(--muted); font-size: 10.5px; font-weight: 700; }
    .intro-fact dd { margin-top: 2px; color: var(--text); font-size: 12.5px; line-height: 1.45; overflow-wrap: anywhere; }
    .intro-caveat { margin-top: 14px; color: var(--muted); font-size: 11.5px; line-height: 1.6; }
    /* 样本量语义提醒：细胞数≠生物学重复 / 文件数≠样本数 / 单位不明不横向比较 / 仅元数据不判统计功效 */
    .intro-ss-caveats { margin-top: 14px; padding: 10px 12px; border: 1px solid var(--border); border-radius: 9px; background: var(--surface); }
    .intro-ss-caveats h4 { margin-bottom: 5px; font-size: 12px; color: var(--muted); }
    .intro-ss-caveats ul { margin: 0; padding-left: 16px; color: var(--muted); font-size: 11.5px; line-height: 1.65; }
    .intro-ss-caveats li { overflow-wrap: anywhere; }
    /* 元数据兼容分组（诚实边界：只回兼容、非可整合，caveat 常显） */
    .cite-acts { display: flex; gap: 8px; flex-wrap: wrap; }
    .compat-h { margin: 0 0 6px; font-size: 12.5px; font-weight: 700; }
    .compat-caveat { margin-bottom: 9px; padding: 8px 10px; border: 1px solid var(--border); border-radius: 8px; background: var(--surface); color: var(--muted); font-size: 11px; line-height: 1.6; }
    /* 可行性概览（入口按钮已收进结果头行 .results-head-acts，独立横带废除；面板留原位） */
    .feasibility-panel { margin: 0 0 14px; padding: 12px 14px; border: 1px solid var(--border); border-radius: 10px; background: var(--surface); }
    .feas-head { font-size: 13px; margin-bottom: 8px; }
    .feas-metrics { display: flex; flex-wrap: wrap; gap: 6px 16px; font-size: 12px; color: var(--text-2); margin-bottom: 10px; }
    .feas-dist { margin: 6px 0; font-size: 11.5px; }
    .feas-dist-h { color: var(--muted); font-weight: 700; margin-right: 6px; }
    .feas-chip { display: inline-block; margin: 2px 3px; padding: 1px 8px; border-radius: 8px; border: 1px solid var(--border); background: var(--bg, transparent); font-size: 11px; }
    .feas-gaps { margin: 10px 0 0; padding-left: 16px; color: var(--text-2); font-size: 11.5px; line-height: 1.6; }
    .feas-caveat { margin-top: 10px; color: var(--muted); font-size: 11px; line-height: 1.6; }
    /* 国内可达性徽章（按托管位置推断、非实测；未识别 host 不显示） */
    .reach { display: inline-flex; align-items: center; gap: 3px; padding: 1px 8px; border-radius: 8px; font-size: 10.5px; font-weight: 600; border: 1px solid var(--border); cursor: help; }
    .reach-good { background: var(--reach-good-bg); border-color: var(--reach-good-line); color: var(--reach-good-ink); }
    .reach-variable { background: var(--reach-variable-bg); border-color: var(--reach-variable-line); color: var(--reach-variable-ink); }
    .reach-slow { background: var(--reach-slow-bg); border-color: var(--reach-slow-line); color: var(--reach-slow-ink); }
    .reach-proxy { background: var(--reach-proxy-bg); border-color: var(--reach-proxy-line); color: var(--reach-proxy-ink); }
    /* ---- 「复用公开数据」声明 + 复用就绪度面板（介绍弹窗下半窗）----
       受众是**复用者**：本工具语料 100% 是别人已公开的数据。文案只写复用者能做的事，
       不下达「请改进你的数据」这类结构上不可能执行的指令。 */
    .das-box, .fair-box { background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius); padding: 13px 14px; }
    .das-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 8px; }
    .das-head h4, .fair-group h5 { font-size: 12.5px; font-weight: 700; }
    .das-copy { height: 30px; padding: 0 12px; font-size: 12px; }
    .das-text { margin: 0; padding: 10px 12px; background: var(--surface); border: 1px solid var(--border); border-radius: 9px; font-size: 12.5px; line-height: 1.6; color: var(--text); overflow-wrap: anywhere; }
    /* 体裁边界，不是免责声明套话：这段决定用户会不会误以为整条 DAS 都替他写好了。 */
    .das-scope-note { margin-top: 8px; color: var(--text-2); font-size: 11px; line-height: 1.55; }
    .das-scope-note strong { color: var(--text); font-weight: 700; }
    .das-notes { margin-top: 8px; color: var(--text-2); font-size: 11px; line-height: 1.55; }
    .das-missing { margin: 6px 0 0 16px; color: var(--muted); font-size: 11px; line-height: 1.5; }
    .fair-summary { display: flex; align-items: center; gap: 12px; margin-bottom: 10px; }
    /* 大数字降层（不喧宾夺主）；「非质量评价」声明升到正文级 12px、不再是最弱一档 */
    .fair-score { flex: none; font-size: 16px; font-weight: 600; color: var(--text-2); }
    .fair-summary-text { color: var(--text-2); font-size: 11.5px; line-height: 1.5; }
    .fair-groups { display: grid; gap: 12px; }
    .fair-group ul { list-style: none; display: grid; gap: 6px; margin-top: 6px; }
    .fair-check { display: flex; gap: 9px; align-items: flex-start; }
    .fair-pill { flex: none; width: 18px; height: 18px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; font-size: 11px; font-weight: 700; color: var(--surface); margin-top: 1px; }
    .fair-check.ok .fair-pill { background: var(--ok); }
    .fair-check.partial .fair-pill { background: var(--caution-pill); }
    .fair-check.unknown .fair-pill { background: var(--unknown); }
    .fair-check-label { font-size: 12px; font-weight: 600; }
    .fair-check-ev { color: var(--text-2); font-size: 11px; line-height: 1.45; overflow-wrap: anywhere; }
    .fair-action { margin-top: 2px; color: var(--caution); font-size: 10.5px; line-height: 1.45; }
    .fair-disclaim { margin-top: 10px; color: var(--text-2); font-size: 12px; line-height: 1.5; }   /* 声明不小于正文档（≥12px），不再用 10.5px 最弱档 */
    /* ---- 复用出处清单（收藏视图：N 个公开数据集 → 投稿材料）----
       受众同为**复用者**：产物只覆盖别人已公开的数据；用户自己产出的数据那一句
       本工具不写、也不接收相关输入。这条边界原本有一块置顶陈述（.rp-boundary），
       2026-07-29 按产品方要求整段删除，样式随之移除。 */
    .reuse-bar { display: flex; align-items: center; justify-content: space-between; gap: 14px; flex-wrap: wrap;
        margin-bottom: 14px; padding: 13px 15px; background: var(--accent-weak); border: 1px solid var(--accent-line); border-radius: var(--radius); }
    .reuse-bar-text { color: var(--text-2); font-size: 12px; line-height: 1.55; }
    .reuse-bar-text strong { color: var(--accent-ink); font-weight: 700; }
    .reuse-panel { margin-bottom: 16px; }
    .rp-box { background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius); padding: 14px 15px; }
    /* 复现出处：检索日期 + 数据集目录快照 ID + 条数 */
    .rp-retrieval { margin: 0 0 13px; color: var(--muted); font-size: 11px; line-height: 1.6; }
    .rp-retrieval code { padding: 1px 5px; border-radius: 5px; background: var(--surface); border: 1px solid var(--border); font-size: 10.5px; }
    .rp-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; margin-bottom: 8px; }
    .rp-head h4, .rp-sub { font-size: 12.5px; font-weight: 700; }
    .rp-sub { margin: 16px 0 7px; }
    .rp-acts { display: flex; gap: 7px; flex-wrap: wrap; }
    .rp-acts .btn { height: 30px; padding: 0 12px; font-size: 12px; }
    .rp-para { margin: 0; padding: 10px 12px; background: var(--surface); border: 1px solid var(--border);
        border-radius: 9px; font-size: 12.5px; line-height: 1.6; color: var(--text); overflow-wrap: anywhere; }
    /* 宽表在自己的容器里横向滚动，页面本身永不横向滚动。 */
    .rp-table-wrap { overflow-x: auto; border: 1px solid var(--border); border-radius: 9px; background: var(--surface); }
    .rp-table { width: 100%; border-collapse: collapse; font-size: 11.5px; }
    .rp-table th, .rp-table td { padding: 8px 10px; text-align: left; vertical-align: top; border-bottom: 1px solid var(--border); }
    .rp-table th { font-weight: 700; color: var(--text-2); white-space: nowrap; background: var(--surface-2); }
    .rp-table tr:last-child td { border-bottom: none; }
    .rp-table td { color: var(--text); line-height: 1.45; overflow-wrap: anywhere; }
    .rp-ident-kind { color: var(--muted); font-size: var(--fs-micro); text-transform: uppercase; letter-spacing: .04em; }
    .rp-none { color: var(--muted); }
    .rp-raw { display: inline-block; font-size: 10.5px; line-height: 1.4; }
    .rp-raw.ok { color: var(--ok); }
    .rp-raw.partial { color: var(--caution); }
    .rp-raw.unknown { color: var(--unknown); }
    .rp-gaps { margin: 0 0 0 16px; color: var(--text-2); font-size: 11.5px; line-height: 1.65; }
    .rp-gaps li { margin-top: 4px; }
    .rp-clean { margin-top: 12px; color: var(--muted); font-size: 11.5px; }
    /* ---- 本地账户（登录/注册模态 + 设置抽屉账户块）---- */
    /* 2026-08-26：账户块说明 <p> 已随卡片精简移除（只留用户名 chip +「数据按账号隔离」一句）。 */
    .account-modal { width: 420px; max-width: 100%; }
    .account-modal-body { padding: 18px; }
    .account-modal-body label { display: block; margin: 12px 0 5px; font-size: 12px; font-weight: 700; }
    .account-modal-body label:first-child { margin-top: 0; }
    .account-modal-body input { width: 100%; height: 40px; padding: 9px 11px; border: 1px solid var(--border-2); border-radius: 9px; font: 13px var(--font); }
    .account-modal-body input:focus { outline: 2px solid var(--accent-line); border-color: var(--accent); }
    .account-error { margin-top: 11px; padding: 8px 11px; background: var(--no-weak); color: var(--no); border: 1px solid var(--no); border-radius: 8px; font-size: 12px; }
    .account-actions { display: flex; gap: 10px; margin-top: 16px; }
    .account-actions .btn { flex: 1; justify-content: center; }
    .account-note { margin-top: 12px; color: var(--muted); font-size: 10.5px; line-height: 1.55; }
    /* 记住我：行内横排轻量勾选，覆盖上面 label 的块级粗体默认 */
    .account-modal-body label.account-remember { display: flex; align-items: center; gap: 7px; margin: 10px 0 0; font-size: 12px; font-weight: 500; color: var(--text-2); cursor: pointer; }
    .account-modal-body label.account-remember input { width: auto; height: auto; margin: 0; accent-color: var(--accent); }
    /* 登录锁定：护栏模式无会话时整页只留登录模态与 toast。
       visibility 而非 display——布局不跳、模态定位不受影响。 */
    body.auth-locked > *:not(.modal-backdrop):not(.toast):not(script):not(style):not(link) { visibility: hidden; }
    /* 使用反馈：产物是一段**可编辑**的纯文本 —— 用户看到什么，复制出去的就是什么。
       所以主体就是一个大 textarea，不做花哨的分区渲染：任何「渲染得好看但和实际发出去的
       内容不完全一致」的设计，在这个功能上都是诚实性缺陷。 */
    .onboarding-choice { display: flex; gap: 10px; margin-top: 14px; flex-wrap: wrap; }
    .onboarding-choice .btn { flex: 1; min-width: 140px; justify-content: center; }

    .usage-modal { width: 640px; }
    .usage-modal-body { padding: 18px; }
    .usage-actions { display: flex; gap: 10px; margin-top: 14px; }
    .usage-actions .btn { flex: 1; justify-content: center; }
    .usage-clear { color: var(--no); }
    .usage-note { margin-top: 12px; color: var(--muted); font-size: 10.5px; line-height: 1.55; }
    .usage-setting .btn { width: 100%; justify-content: center; margin-top: 12px; }
    /* 设置页「本机编号」行（请求删除已上传数据时提供给项目所有者）——与 .usage-note 同族小字。 */
    .usage-install { display: block; margin-top: 8px; color: var(--muted); font-size: 10.5px; line-height: 1.55; }
    .usage-install code { font-family: var(--mono); font-size: 11px; background: var(--surface-2); padding: 1px 6px; border-radius: 5px; color: var(--accent-ink); }

    /* 每轮一张独立评分卡（卡挂对话流本轮系统回复下方与结果区顶部 hero 槽位，微信式、低调、系统侧）。
       2026-08-20：展示收敛 + 进一步缩小——none/error 轮不再渲染（记录照攒，纯埋点）
       2026-08-22：会话降频（主动完整卡每会话 ≤2 张，连续忽略 2 次不再主动出，被拦轮次给折叠
       「评价」按钮）；完成度三选 + 原因 chips 取代星行。卡体高度约为原来一半：标题与说明并排、
       三选行与按钮行并排、字号/间距收敛，仍与对话气泡同族（圆角 10px、1px 边框、紧凑留白），不抢视觉焦点。 */
    .benchfb-summary { margin: 0; padding-left: 18px; font-size: var(--fs-sm); line-height: 1.8; }
    .benchfb-honesty { margin-top: 12px; padding: 10px 12px; border: 1px solid var(--border-2); border-radius: 10px; background: var(--bg); font-size: var(--fs-xs); line-height: 1.7; color: var(--text-2); display: grid; gap: 6px; }
    .benchfb-preview { margin-top: 10px; }
    .benchfb-preview summary { cursor: pointer; font-size: var(--fs-xs); color: var(--muted); }
    .benchfb-preview textarea { width: 100%; min-height: 180px; max-height: 40vh; margin-top: 8px; padding: 10px 12px; border: 1px solid var(--border-2); border-radius: 10px; background: var(--bg); font: 11px/1.6 var(--mono); white-space: pre; overflow: auto; }
    /* 向开发者发送意见对话框——与 benchfb 同族 modal 组件语言（变量全复用）。 */
    .fb-label { display: block; margin: 2px 0 6px; font-size: 12.5px; font-weight: 600; color: var(--text); }
    .fb-text { width: 100%; min-height: 130px; padding: 10px 12px; border: 1px solid var(--border-2); border-radius: 10px; background: var(--bg); font-family: var(--font); font-size: 12.5px; line-height: 1.6; color: var(--text); resize: vertical; box-sizing: border-box; }
    .fb-text::placeholder { color: var(--muted); }
    .fb-text:focus { outline: 2px solid var(--accent-line); border-color: var(--accent); }
    .fb-count { margin-top: 4px; text-align: right; color: var(--muted); font-size: 10.5px; }
    .fb-diag { display: flex; align-items: center; gap: 7px; margin-top: 10px; font-size: 12.5px; font-weight: 600; cursor: pointer; user-select: none; }
    .fb-diag input { accent-color: var(--accent); }
    .fb-diag-summary { margin-top: 5px; color: var(--muted); font-size: 10.5px; line-height: 1.55; }
    .fb-fail { margin-top: 12px; padding: 10px 12px; border: 1px solid var(--warn-line); border-radius: 10px; background: var(--warn-weak); }
    .fb-fail .fb-status { color: var(--warn); }
    .fb-status { margin: 12px 0 0; font-size: 12px; line-height: 1.55; color: var(--text-2); }
    /* 评分卡挂载点（对话轮 [data-bf-mount] / hero 槽位 .bf-hero-mount）——空时不占位
       （卡收起 / 记录被清 / 该轮无卡可显时留空 div 会挤出空白）。hero 槽位横跨结果区整行
       （.grid 是 auto-fill 多列，不跨行会被压进单格）。 */
    .bf-mount:empty { display: none; }
    .bf-hero-mount { grid-column: 1 / -1; }

    .bf-rate { margin: 6px 0 2px; padding: 7px 10px; border: 1px dashed var(--border-2); border-radius: 10px; background: var(--surface); max-width: 340px; font-size: var(--fs-xs); }
    .bf-rate-head { font-weight: 600; color: var(--text); }
    .bf-rate-sub { display: inline; margin-left: 5px; font-weight: 400; font-size: var(--fs-micro); color: var(--muted); }
    /* （2026-08-22）：完成度三选 + 可选原因 chips 取代星级行——控件沿用 .bf-tool 的
       细边框 pill 语言，选中态用 --accent-weak/--accent-line/--accent-ink 既有令牌。 */
    .bf-rate-line { display: flex; margin-top: 5px; gap: 4px 8px; flex-wrap: wrap; align-items: center; }
    .bf-rate-comp { display: inline-flex; gap: 4px; }
    .bf-comp { border: 1px solid var(--border-2); background: var(--bg); color: var(--text-2); border-radius: 999px; padding: 2px 9px; font-size: var(--fs-xs); cursor: pointer; }
    .bf-comp:hover { border-color: var(--accent); color: var(--accent); }
    .bf-comp.on { border-color: var(--accent-line); background: var(--accent-weak); color: var(--accent-ink); font-weight: 600; }
    .bf-rate-reasons { display: flex; margin-top: 5px; gap: 4px; flex-wrap: wrap; }
    .bf-chip { border: 1px solid var(--border-2); background: var(--bg); color: var(--muted); border-radius: 999px; padding: 1px 7px; font-size: var(--fs-micro); cursor: pointer; }
    .bf-chip:hover { border-color: var(--accent); color: var(--accent); }
    .bf-chip.on { border-color: var(--accent-line); background: var(--accent-weak); color: var(--accent-ink); }
    .bf-rate-tools { display: inline-flex; gap: 5px; flex-wrap: wrap; align-items: center; }
    .bf-tool { border: 1px solid var(--border-2); background: var(--bg); color: var(--text-2); border-radius: 999px; padding: 2px 8px; font-size: var(--fs-micro); cursor: pointer; }
    .bf-tool:hover { border-color: var(--accent); color: var(--accent); }
    .bf-tool.bf-skip { color: var(--muted); }
    .bf-rate-comment { margin-top: 6px; }
    .bf-rate-comment textarea { width: 100%; padding: 6px 8px; border: 1px solid var(--border-2); border-radius: 8px; background: var(--bg); font-size: var(--fs-xs); line-height: 1.5; resize: none; max-height: 101px; overflow-y: auto; }   /* resize 交给 autogrow（上限 5 行）；max-height 是 CSS 兜底，超出内部滚动 */
    .bf-rate-comment textarea:focus { outline: 2px solid var(--accent-line); border-color: var(--accent); }
    .bf-rate-comment .bf-tool { margin-top: 5px; }
    /* none/error 轮（纯埋点、不出完整卡）在系统回复气泡下方的低调「评价」按钮——
       折叠态零外框零底色，与 .cbh-view-link 同族（11.5px --muted 小字、hover 才出 accent 与下划线），
       不抢视觉焦点；展开后是完整评分卡（上方 .bf-rate 既有紧凑样式），再点「收起」回到这颗按钮。 */
    .bf-rate-toggle { border: none; background: none; padding: 0; margin: 6px 0 2px; max-width: none; }
    .bf-rate-toggle-btn { border: none; background: none; font-family: var(--font); font-size: 11.5px;
        font-weight: 500; color: var(--muted); cursor: pointer; text-align: left; padding: 2px 0;
        transition: color .15s; }
    .bf-rate-toggle-btn:hover { color: var(--accent-ink); text-decoration: underline; text-underline-offset: 3px; }
    .bf-rate-toggle-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; border-radius: 4px; }

    /* 标注模式：结果区整体进「点选」态；标中的卡片给 --ok 描边+角标。 */
    #resultsGrid.bf-marking article.card { cursor: pointer; }
    #resultsGrid.bf-marking article.card:hover { outline: 2px dashed var(--accent); outline-offset: 2px; }
    #resultsGrid article.card.bf-marked { outline: 2px solid var(--ok); outline-offset: 2px; position: relative; }
    #resultsGrid article.card.bf-marked::after { content: "有用 ✓"; position: absolute; top: 8px; right: 8px; padding: 2px 8px; border-radius: 999px; background: var(--ok); color: #fff; font-size: var(--fs-micro); font-weight: 600; }
    .bf-mark-bar { position: fixed; left: 50%; bottom: 22px; transform: translateX(-50%); z-index: 90; display: flex; align-items: center; gap: 12px; padding: 9px 14px; border-radius: 999px; background: var(--surface); border: 1px solid var(--accent); box-shadow: var(--shadow); font-size: var(--fs-sm); }
    .bf-mark-bar[hidden] { display: none; }
    .bf-mark-bar strong { color: var(--ok); }

    /* consent 首次告知：与既有 modal 完全同族（同一 backdrop
       圆角/边框/阴影令牌）；无 ✕、遮罩点击不关闭——只有两个明确按钮，不点确认不发送。
       比普通弹窗略窄，居中不抢主界面焦点。 */
    .consent-dialog { width: 520px; }
    .consent-dialog .modal-body { padding: 16px 22px 20px; }
    .consent-dialog .modal-body p { margin: 0 0 10px; font-size: var(--fs-sm); color: var(--text-2); line-height: 1.75; }
    .consent-dialog .modal-body p strong { color: var(--text); }
    .consent-training { display: flex; align-items: flex-start; gap: 9px; margin-top: 12px; padding: 11px 12px; border: 1px solid var(--line); border-radius: 10px; background: var(--surface-2); color: var(--text-2); font-size: var(--fs-sm); line-height: 1.55; cursor: pointer; }
    .consent-training input { flex: 0 0 auto; margin-top: 3px; }
    .consent-acts { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 16px; }
    .consent-acts .btn { min-height: 38px; padding: 7px 18px; }
    .consent-note { margin-top: 12px; font-size: var(--fs-micro); color: var(--muted); line-height: 1.6; }


    .memory-modal { width: 700px; }
    .memory-modal-body { padding: 18px; }
    .memory-add label { display: block; margin-bottom: 6px; font-size: 12px; font-weight: 700; }
    .memory-add > div { display: flex; gap: 8px; }
    .memory-add input { flex: 1; min-width: 0; height: 40px; padding: 9px 11px; border: 1px solid var(--border-2); border-radius: 9px; font: 13px var(--font); }
    .memory-add input:focus { outline: 2px solid var(--accent-line); border-color: var(--accent); }
    .memory-list-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin: 18px 0 9px; padding-top: 14px; border-top: 1px solid var(--border); font-size: 12px; }
    /* ---- dream 记忆块（手动整理，预览勾选后才写入） ---- */
    .dream-block { margin-bottom: 16px; padding: 12px 14px; background: var(--accent-weak); border: 1px solid var(--accent-line); border-radius: 12px; }
    .dream-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
    .dream-title { display: grid; gap: 2px; }
    .dream-title strong { font-size: 13.5px; }
    .dream-title small { font-size: 11px; color: var(--text-2); line-height: 1.5; }
    .dream-consent { margin-top: 10px; }
    .dream-consent p { margin: 0 0 10px; font-size: 12px; line-height: 1.65; color: var(--text); }
    .dream-consent-acts { display: flex; gap: 8px; }
    .dream-status { margin-top: 10px; font-size: 12px; line-height: 1.6; color: var(--text-2); }
    .dream-status.is-error { color: var(--no); }
    .dream-preview { margin-top: 10px; display: grid; gap: 8px; }
    .dream-preview-head { display: grid; gap: 2px; }
    .dream-preview-head strong { font-size: 12.5px; }
    .dream-preview-head small { font-size: 11px; color: var(--text-2); }
    .dream-preview-list { display: grid; gap: 6px; max-height: 240px; overflow-y: auto; }
    .dream-cand { display: flex; align-items: flex-start; gap: 8px; padding: 8px 10px; background: var(--surface); border: 1px solid var(--border-2); border-radius: 9px; cursor: pointer; }
    .dream-cand input { margin-top: 3px; accent-color: var(--accent); }
    .dream-cand-copy { display: grid; gap: 2px; min-width: 0; }
    .dream-cand-copy strong { font-size: 12.5px; font-weight: 600; overflow-wrap: anywhere; }
    .dream-cand-copy small { font-size: 11px; color: var(--muted); overflow-wrap: anywhere; }
    .dream-preview-acts { display: flex; gap: 8px; }
    .memory-clear { color: var(--no); }
    .memory-list { display: grid; gap: 8px; }
    .memory-item { display: flex; align-items: center; justify-content: space-between; gap: 13px; padding: 11px 12px; border: 1px solid var(--border); border-radius: 10px; }
    .memory-item-copy { min-width: 0; }
    .memory-item-copy > span { color: var(--accent-ink); font-size: var(--fs-micro); font-weight: 700; }
    .memory-item-copy strong { display: block; margin-top: 2px; font-size: 12.5px; overflow-wrap: anywhere; }
    .memory-item-copy p { margin-top: 3px; color: var(--text-2); font-size: 11px; line-height: 1.45; }
    .memory-item-copy small { display: block; margin-top: 4px; color: var(--muted); font-size: var(--fs-micro); }
    .memory-item-actions { display: flex; flex: none; gap: 6px; }
    .memory-delete { color: var(--no); }
    .memory-empty { padding: 28px 12px; border: 1px dashed var(--border-2); border-radius: 10px; color: var(--muted); font-size: 12px; text-align: center; }

    .files-hint { font-size: 12.5px; color: var(--muted); padding: 22px 6px; text-align: center; }
    .files-list { list-style: none; display: flex; flex-direction: column; gap: 4px; }
    .file-row {
        display: flex; align-items: center; gap: 12px; padding: 10px 12px; border-radius: 10px;
        background: var(--surface-2); border: 1px solid transparent;
        transition: border-color 0.14s, background 0.14s;
    }
    .file-row:hover { background: var(--surface-3); border-color: var(--border); }
    .file-row.primary { background: var(--accent-weak); border-color: var(--accent-line); }
    .file-type {
        flex-shrink: 0; min-width: 48px; text-align: center;
        font-family: var(--mono); font-size: var(--fs-micro); font-weight: 700; letter-spacing: 0.02em;
        color: var(--text-2); background: var(--surface); border: 1px solid var(--border-2);
        border-radius: 6px; padding: 5px 6px;
    }
    .file-row.primary .file-type { color: var(--accent-ink); border-color: var(--accent-line); background: var(--surface); }
    .file-info { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
    .file-name { font-size: 13px; color: var(--text); font-weight: 500; display: flex; align-items: center; gap: 7px; }
    .file-fn { font-size: 11px; color: var(--muted); font-family: var(--mono); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
    .file-badge { font-size: var(--fs-micro); font-weight: 600; color: var(--accent-ink); background: var(--surface);
        border: 1px solid var(--accent-line); border-radius: 5px; padding: 1px 6px; white-space: nowrap; }
    /* 活台账「存疑」文件（链接失效 / 大小不一致）：琥珀色警示，悬停 title 看原因。 */
    .file-warn { font-size: var(--fs-micro); font-weight: 700; color: var(--warn); background: var(--warn-weak);
        border: 1px solid var(--warn-line); border-radius: 5px; padding: 1px 6px; white-space: nowrap; cursor: help; }
    .file-row.warn { background: var(--warn-row); border-color: var(--warn-row-line); }
    .file-row.warn:hover { background: var(--warn-row-hover); border-color: var(--warn-line-strong); }
    .file-row.warn .file-type { color: var(--warn); border-color: var(--warn-line); }
    .file-meta { display: inline-flex; align-items: center; gap: 14px; flex-shrink: 0; }
    .file-size { font-size: 11px; color: var(--muted); font-family: var(--mono); white-space: nowrap; }
    .file-dl {
        font-size: 12.5px; font-weight: 600; color: var(--accent-ink);
        background: var(--accent-weak); border: 1px solid var(--accent-line);
        border-radius: 8px; padding: 6px 12px; white-space: nowrap; text-decoration: none;
        transition: background 0.14s, color 0.14s;
    }
    .file-dl:hover { background: var(--accent); color: var(--surface); }
    .file-dl.disabled { color: var(--muted); background: var(--surface-2); border-color: var(--border); cursor: not-allowed; }

    .muted-block { color: var(--muted); font-size: 14px; padding: 30px 6px; text-align: center; }
    /* 空态提示并入 .info-bar 信息条语言（容器 chrome 见下）；仍占满 grid 整行 */
    .noresult { grid-column: 1 / -1; }
    .noresult strong { font-size: 15.5px; }
    .noresult p { color: var(--text-2); font-size: 13.5px; margin-top: 7px; }
    .noresult pre { margin-top: 12px; padding: 12px 14px; background: var(--surface-2); border-radius: 10px;
        font-family: var(--mono); font-size: 12px; color: var(--text-2); white-space: pre-wrap; max-height: 220px; overflow: auto; }
    /* 引导式放宽：0 结果时的一键放宽芯片 */
    .relax { margin-top: 16px; }
    .relax-h { font-size: 13px; font-weight: 600; color: var(--text-2); margin-bottom: 9px; }
    .relax-chips { display: flex; flex-wrap: wrap; gap: 8px; }
    .relax-chip { display: inline-flex; align-items: center; gap: 8px; padding: 8px 13px; border-radius: 10px;
        border: 1px solid var(--bar-line); background: var(--surface-2); color: var(--text); font-size: 13px; cursor: pointer;
        transition: transform .16s cubic-bezier(.22,1,.36,1), border-color .16s ease, background .16s ease; }
    .relax-chip:hover { transform: translateY(-1px); border-color: var(--accent); background: var(--surface); }
    .relax-chip:active { transform: translateY(0); }
    .relax-chip .rc-n { font-weight: 700; color: var(--accent-ink); font-variant-numeric: tabular-nums; }
    /* 多策略分组（2026-07-29 点3）：两档策略各自成组、组名旁一句话说清它到底放开了什么，
       默认只铺开前 3 个芯片，其余（含整组）折在「更多放宽方式（N）」后面。 */
    .relax-group + .relax-group { margin-top: 12px; }
    .relax-gh { display: flex; align-items: baseline; gap: 8px; margin-bottom: 7px; font-size: 12.5px; font-weight: 600; color: var(--text-2); }
    .relax-gh-note { font-weight: 400; font-size: 12px; color: var(--muted); }
    .relax:not(.is-open) .relax-extra { display: none; }
    .relax-more { margin-top: 11px; padding: 6px 12px; border-radius: 999px; border: 1px dashed var(--bar-line);
        background: transparent; color: var(--accent-ink); font-family: var(--font); font-size: 12.5px; cursor: pointer; }
    .relax-more:hover { border-style: solid; border-color: var(--accent); background: var(--surface); }
    .relax-more:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
    /* 未收录词降级：芯片下面那行「忽略之后实际在筛什么」。只有条数、没有条件，
       用户没法判断这几千条是不是垃圾——这行字是这个选项能否诚实存在的前提。 */
    .relax-note { margin: 9px 0 0; font-size: 12.5px; line-height: 1.6; color: var(--muted); }
    .relax-note b { color: var(--text-2); }
    .relax-banner { grid-column: 1 / -1; display: flex; align-items: center; justify-content: space-between; gap: 12px;
        padding: 10px 14px; margin-bottom: 4px; border-radius: 10px; background: var(--surface);
        border: 1px solid var(--bar-line); font-size: 13px; color: var(--text-2); }
    .relax-back { padding: 5px 11px; border-radius: 8px; border: 1px solid var(--bar-line); background: var(--surface);
        color: var(--accent-ink); font-size: 12.5px; cursor: pointer; white-space: nowrap; }
    .relax-back:hover { border-color: var(--accent); }
    @media (prefers-reduced-motion: reduce) { .relax-chip { transition: none; } .relax-chip:hover { transform: none; } }

    /* 信息条统一语言：覆盖缺口（诚实降级琥珀）/ 未用查询词 / 标识符反查 / 空态提示
       共用同一容器规范——左 3px 色条 + 统一 padding/radius/字号档；文案一字不动。 */
    .info-bar { margin: 0 0 14px; padding: 11px 14px; border: 1px solid var(--border); border-left: 3px solid var(--border-2);
        border-radius: var(--radius); background: var(--surface); font-size: 13px; }
    /* 诚实降级层变体：缺元数据/静默丢词是「需要留意」而非报错——保留琥珀语义（信息性、不用告警红） */
    .info-bar-caution { background: var(--caution-weak); border-color: var(--caution-line); border-left-color: var(--caution); }
    /* 静默丢词：无对应筛选维度、被静默丢弃的实义描述词回显。 */
    .unused-query-terms { color: var(--text-2); line-height: 1.8; }
    .unused-query-terms .uqt-txt b { color: var(--text); font-weight: 700; }
    .unused-query-terms .uqt-term { display: inline-block; margin: 0 2px; padding: 1px 9px; border-radius: 8px; background: var(--caution-chip); border: 1px solid var(--caution-chip-line); color: var(--caution-chip-ink); font-weight: 600; font-size: 12.5px; }
    /* 标识符精确反查：直达记录 / 诚实 fail-closed 指路（容器 chrome 在 .info-bar） */
    .identifier-lookup .idlk-msg { font-size: 13px; color: var(--text-2); line-height: 1.7; }
    .identifier-lookup .idlk-msg b { color: var(--text); font-weight: 700; }
    .identifier-lookup .idlk-ext { margin-top: 9px; }
    .identifier-lookup .idlk-card { margin-top: 11px; }
    .identifier-lookup .idlk-cands { margin-top: 11px; }   /* 共享标识符候选清单（复用 arx-card 行样式） */
    /* .cov-h 覆盖缺口表头已删（用户判冗余，各 .cov-row 自含诚实语义）。 */
    .cov-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 5px 0; }
    .cov-row + .cov-row { border-top: 1px solid var(--caution-row-line); }
    .cov-txt { font-size: 13px; color: var(--text-2); line-height: 1.5; }
    .cov-txt b { color: var(--text); font-weight: 700; }
    /* （2026-08-01）：「放宽方式」展开开关——小字描边按钮，语汇照 .cbh-view（描边＝可点）。
       它替代误读版「看看是哪些」记录预览：用户要的是**多档放宽策略选择**，不是看谁会进来。 */
    .cov-expand { flex: 0 0 auto; border: 1px solid var(--border-2); background: var(--surface); color: var(--text-2);
        font-family: var(--font); font-size: 11px; padding: 3px 9px; border-radius: 7px; cursor: pointer;
        white-space: nowrap; transition: border-color .15s, color .15s, background .15s; }
    .cov-expand:hover { border-color: var(--accent-line); color: var(--accent-ink); background: var(--accent-weak); }
    /* 展开后是该行维度的**两档放宽策略**（整行按钮：粗体标题 + 一句后果说明，两档方向相反、文案各自成立）。
       夹在两条 cov-row 之间时把分隔线续上（.cov-row + .cov-row 的相邻选择器跨不过它）。 */
    .cov-detail { margin: 2px 0 4px; padding: 4px 0 4px 10px; display: flex; flex-direction: column; gap: 6px;
        border-left: 2px solid var(--caution-row-line); }
    .cov-detail + .cov-row { border-top: 1px solid var(--caution-row-line); }
    .cov-strat { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; text-align: left;
        padding: 7px 11px; border-radius: 9px; border: 1px solid var(--border-2); background: var(--surface);
        color: var(--text); font: inherit; font-size: 12.5px; cursor: pointer; transition: border-color .15s, background .15s; }
    .cov-strat b { font-weight: 600; }
    .cov-strat span { font-size: 11.5px; color: var(--muted); line-height: 1.45; }
    .cov-strat:hover { border-color: var(--accent-line); background: var(--accent-weak); }
    .cov-applied { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 9px; }
    .cov-undo { display: inline-flex; align-items: center; gap: 6px; padding: 5px 11px; border-radius: 999px; border: 1px solid var(--accent-line); background: var(--accent-weak); color: var(--accent-ink); font: inherit; font-size: 12px; font-weight: 600; cursor: pointer; }
    .cov-undo:hover { background: var(--surface); border-color: var(--accent); }

    /* ---------------- 分面细化（结果上方按维度收窄） ---------------- */
    /* 关键词审核改写横幅：仅在真采纳了改写时显示「我把问题理解成了 XX」，让 drift 对用户可见、可判对错 */
    .audit-banner { margin: 0 0 14px; padding: 10px 13px; background: var(--accent-weak); border: 1px solid var(--accent-line);
        border-radius: 10px; font-size: 13px; line-height: 1.55; color: var(--text); }
    .audit-banner b { color: var(--accent-ink); font-weight: 700; }
    .audit-banner[hidden] { display: none; }
    .facetbar { margin: 2px 0 18px; }
    /* 「查询条件」：原始命中 + 后加细化合并一排，**同款 chip**（accent 底 + 「忽略」钮）——
       不再以 ❝ 标记/× 按钮/底色区分来源（用户 2026-08-04 圈2）；只剩 ⊘ 排除 / ↑ 软偏好两枚行为标记。 */
    .facet-active { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-bottom: 12px; }
    .facet-applied-label { font-size: 12.5px; color: var(--muted); }
    .fa-chip { display: inline-flex; align-items: center; gap: 6px; padding: 4px 5px 4px 11px; border-radius: 9px;
        border: 1px solid var(--border); background: var(--surface-2); font-size: 12.5px; }
    .fa-chip .fa-k { color: var(--muted); font-size: 11px; font-weight: 600; }
    .fa-chip .fa-v { color: var(--text); font-weight: 500; }
    /* 条件 chip 统一态：accent 底（原始命中与后加细化同款）；负向/软偏好另有行为态（下方 is-exclude / is-prefer） */
    .fa-chip.is-query { background: var(--accent-weak); border-color: var(--accent-line); }
    .fa-chip.is-query .fa-k { color: var(--accent-ink); opacity: .75; }
    .fa-chip.is-query .fa-v { color: var(--accent-ink); }
    .fa-mark { color: var(--accent-ink); opacity: .85; font-size: 12px; font-weight: 700; line-height: 1; }
    /* chip 的「忽略/恢复」切换：文字小药丸，accent 色邀请点按（后加细化同钮＝去掉这条） */
    .fa-toggle { flex: 0 0 auto; border: none; border-radius: 6px; background: transparent;
        padding: 3px 7px; font-size: 11px; font-weight: 600; line-height: 1; cursor: pointer;
        color: var(--accent-ink); opacity: .72; transition: opacity .15s ease, background .15s ease, color .15s ease; }
    .fa-toggle:hover { opacity: 1; background: rgba(13,148,136,.14); }
    /* 被忽略的命中（off 态）：去 accent → 灰底虚框 + 值删除线，一眼看出「未生效」；「恢复」按钮仍 accent */
    .fa-chip.is-query.is-off { background: var(--surface-2); border-color: var(--border); border-style: dashed; }
    .fa-chip.is-query.is-off .fa-k { color: var(--muted); }
    .fa-chip.is-query.is-off .fa-v { color: var(--muted); text-decoration: line-through; text-decoration-thickness: 1px; }
    .fa-chip.is-query.is-off .fa-mark { color: var(--muted); opacity: .55; }
    /* 负向命中（排除类）：区别于正向 accent 的玫瑰调，⊘ 标记 + surface-2 底，避免与"需要"混淆 */
    .fa-chip.is-query.is-exclude { background: var(--surface-2); border-color: var(--border); }
    .fa-chip.is-query.is-exclude .fa-mark { color: var(--no); opacity: 1; }
    .fa-chip.is-query.is-exclude .fa-k { color: var(--text-2); opacity: .8; }
    .fa-chip.is-query.is-exclude .fa-v { color: var(--text); }
    .fa-chip.is-query.is-exclude.is-off .fa-mark { color: var(--muted); opacity: .55; }
    /* 软偏好（「优先 X」）：**没有筛掉任何数据**，只影响先后。所以它不能长成 accent 实心的硬条件样，
       用中性底 + 虚线框 + ↑ 标记，让「这条不是筛选」在看一眼的时候就成立，而不是要读 title 才知道。 */
    .fa-chip.is-query.is-prefer { background: var(--surface-2); border-color: var(--border); border-style: dashed; }
    .fa-chip.is-query.is-prefer .fa-mark { color: var(--accent-ink); opacity: .9; }
    .fa-chip.is-query.is-prefer .fa-k { color: var(--muted); }
    .fa-chip.is-query.is-prefer .fa-v { color: var(--text); }
    .fa-chip.is-query.is-prefer.is-off .fa-mark { color: var(--muted); opacity: .55; }
    /* 澄清态两个选项按钮 */
    .clarify-opts { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 13px; }
    .clarify-opt { padding: 9px 14px; border-radius: 10px; border: 1px solid var(--accent-line); background: var(--accent-weak);
        color: var(--accent-ink); font-size: 13.5px; font-weight: 600; cursor: pointer; transition: transform .15s ease, background .15s ease; }
    .clarify-opt:hover { transform: translateY(-1px); background: var(--surface); }
    .clarify-opt:active { transform: translateY(0); }
    @media (prefers-reduced-motion: reduce) { .clarify-opt { transition: none; } .clarify-opt:hover { transform: none; } }
    .facet-groups { display: flex; flex-direction: column; gap: 9px; }
    .fg-row { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px; }
    .fg-label { flex: 0 0 auto; min-width: 52px; font-size: 12px; font-weight: 600; color: var(--text-2); padding-top: 2px; }
    .fg-vals { display: flex; flex-wrap: wrap; gap: 7px; flex: 1 1 0; min-width: 0; }   /* flex:1 1 0 + min-width:0：取值容器填满标签右侧剩余宽、在自己列里换行；否则取值过多时整块会换到标签下一行、贴到行左缘，与其它组的取值列错位（如「组织」） */
    .facet-chip { display: inline-flex; align-items: center; gap: 7px; padding: 5px 11px; border-radius: 9px;
        border: 1px solid var(--bar-line); background: var(--surface); color: var(--text); font-size: 12.5px; cursor: pointer;
        transition: transform .16s cubic-bezier(.22,1,.36,1), border-color .16s ease, background .16s ease, color .16s ease; }
    .facet-chip:hover { transform: translateY(-1px); border-color: var(--accent); background: var(--accent-weak); color: var(--accent-ink); }
    .facet-chip:active { transform: translateY(0); }
    .facet-chip .fc-n { font-weight: 700; color: var(--muted); font-variant-numeric: tabular-nums; font-size: 11.5px; }
    .facet-chip:hover .fc-n { color: var(--accent-ink); }
    @media (prefers-reduced-motion: reduce) { .facet-chip { transition: border-color .16s ease, background .16s ease; } .facet-chip:hover { transform: none; } }
    /* 暂存选中态（点4）：数据细化模式下勾了、还没「提交」的分面取值——实心品牌青，与 hover 区分开。 */
    .facet-chip.is-staged { border-color: var(--accent-line); background: var(--accent-weak); color: var(--accent-ink); font-weight: 600; }
    .facet-chip.is-staged .fc-n { color: var(--accent-ink); }
    /* 「提交/取消」条（点4）：改动数 + 两颗按钮，贴在分面 grid 下方；_facetStage 脏时露出。
       **常驻吸底**——分面清单一长，此前要翻到最底才摸得到提交。
       position:sticky;bottom:0 在两个宿主里都成立：侧栏「数据细化」卡（#sideFacetBody 是滚动容器）
       与结果区原位 / 移动端（页面滚动）——条贴着各自滚动口下缘驻留，facetBar 滚到底才放行。
       底色 + 上缘阴影把驻留条与下方滚过的分面行分隔（阴影只朝上打，不糊面板自身）。 */
    .facet-stage-bar { display: flex; align-items: center; gap: 8px; margin-top: 10px; padding: 10px 4px 4px;
        border-top: 1px solid var(--border-2);
        position: sticky; bottom: 0; z-index: 4;
        background: var(--bg); box-shadow: 0 -10px 14px -12px rgba(16, 33, 46, .45); }
    .facet-stage-bar[hidden] { display: none; }
    /* 侧栏宿主是白卡（--surface），吸底条底色随宿主换，否则白卡上贴一块灰底。 */
    .side-facets .facet-stage-bar { background: var(--surface); }
    .fsb-count { flex: 1 1 auto; min-width: 0; font-size: 12px; color: var(--accent-ink); font-weight: 600; }
    .facet-stage-bar .fsb-cancel, .facet-stage-bar .fsb-submit { flex: 0 0 auto; padding: 5px 14px; font-size: 12.5px; }

    /* ---------------- Filters (browse) ---------------- */
    .toolbar {
        display: flex; flex-wrap: wrap; gap: 10px 18px; align-items: center; justify-content: space-between;
        background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
        padding: 14px; margin-bottom: 10px; box-shadow: var(--shadow-sm);
    }
    /* 按功能分组——「筛选操作」（搜索/来源/物种/平台/FASTQ）与「显示控制」（每页条数）；
       桌面一行收拢（筛选组占余宽，显示组靠右），窄屏自然折行。 */
    .toolbar .tb-group { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; flex: 1; min-width: 0; }
    .toolbar .tb-display { flex: 0 0 auto; justify-content: flex-end; }
    .toolbar .tb-pagesize { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; color: var(--text-2); white-space: nowrap; }
    .toolbar .search-input, .toolbar .select {
        border: 1px solid var(--border-2); background: var(--surface); color: var(--text);
        border-radius: 10px; padding: 9px 12px; font-size: 13.5px; font-family: var(--font); height: 40px;
    }
    .toolbar .search-input { flex: 1; min-width: 180px; }
    /* 定宽：不再被最长选项撑乱布局（原生 select 对超长选项文本自行截断） */
    .toolbar .select { width: 150px; min-width: 0; cursor: pointer; text-overflow: ellipsis; }
    .toolbar #fPageSize { width: auto; min-width: 64px; }
    .toolbar .search-input:focus, .toolbar .select:focus { outline: 2px solid var(--accent); outline-offset: 1px; border-color: var(--accent-line); }
    .browse-timeline { margin-bottom: 20px; padding: 14px 15px 12px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); box-shadow: var(--shadow-sm); }
    .timeline-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; }
    .timeline-head h3 { font-size: 13.5px; }
    .timeline-head p { margin-top: 1px; color: var(--accent-ink); font-size: 11.5px; font-weight: 700; }
    .timeline-range { display: flex; align-items: center; justify-content: flex-end; flex-wrap: wrap; gap: 7px; color: var(--muted); font-size: 11.5px; }
    .timeline-range label { display: inline-flex; align-items: center; gap: 5px; }
    .timeline-range select { height: 32px; padding: 4px 8px; border: 1px solid var(--border-2); border-radius: 8px; background: var(--surface); color: var(--text-2); font: 12px var(--font); }
    .timeline-clear { min-height: 32px; padding: 5px 9px; font-size: 11.5px; }
    .timeline-bars { display: flex; align-items: flex-end; gap: 4px; height: 104px; margin-top: 10px; padding: 4px 2px 0; overflow-x: auto; overflow-y: hidden; scrollbar-width: thin; }
    .timeline-bar { position: relative; flex: 1 0 38px; min-width: 38px; max-width: 54px; height: 92px; display: grid; grid-template-rows: 16px 1fr 18px; align-items: end; justify-items: center; border: 0; border-radius: 7px; background: transparent; color: var(--muted); font-family: var(--font); cursor: pointer; }
    .timeline-bar:hover, .timeline-bar:focus-visible { background: var(--surface-2); color: var(--accent-ink); outline: none; }
    .timeline-bar.active { background: var(--accent-weak); color: var(--accent-ink); }
    /* 计数默认可见（不再靠 hover/focus 才现身）；年份标签本就 --fs-micro 10.5px + muted（≈4.6:1 达标） */
    .timeline-count { align-self: center; font: 600 var(--fs-micro)/1 var(--mono); }
    .timeline-bar:hover .timeline-count, .timeline-bar:focus-visible .timeline-count { color: var(--accent-ink); }
    .timeline-bar i { display: block; align-self: end; width: 70%; height: var(--bar-h); max-height: 62px; min-height: 8px; border-radius: 5px 5px 2px 2px; background: var(--border-2); }
    .timeline-bar.active i { background: var(--accent); }
    .timeline-bar em { align-self: center; font: 600 var(--fs-micro)/1 var(--mono); font-style: normal; }
    .timeline-note { margin-top: 7px; color: var(--muted); font-size: 10.5px; }
    .timeline-empty { align-self: center; width: 100%; color: var(--muted); font-size: 12px; text-align: center; }

    .switch { display: inline-flex; align-items: center; gap: 8px; cursor: pointer; user-select: none; font-size: 13px; color: var(--text-2); white-space: nowrap; }
    .switch input { display: none; }
    .switch .slider { width: 40px; height: 23px; border-radius: 999px; background: var(--border-2); position: relative; transition: background 0.16s; flex-shrink: 0; }
    .switch .slider::after { content: ""; position: absolute; width: 17px; height: 17px; border-radius: 50%; background: var(--surface); top: 3px; left: 3px; transition: transform 0.16s; box-shadow: var(--shadow-sm); }
    .switch input:checked + .slider { background: var(--accent); }
    .switch input:checked + .slider::after { transform: translateX(17px); }

    .pager { display: flex; align-items: center; justify-content: center; gap: 14px; margin-top: 24px; }
    .pager-info { font-size: 13px; color: var(--text-2); font-family: var(--mono); }

    /* ---------------- Upload ---------------- */
    .up-card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 16px; margin-bottom: 20px; box-shadow: var(--shadow-sm); }
    .up-row { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
    .upzone {
        flex: 1; min-width: 240px; border: 1.5px dashed var(--border-2); border-radius: 12px;
        padding: 14px 18px; cursor: pointer; background: var(--surface-2); font-size: 13px; color: var(--text-2);
        transition: border-color 0.15s, background 0.15s;
    }
    .upzone:hover, .upzone.drag { border-color: var(--accent-line); background: var(--accent-weak); color: var(--accent-ink); }
    .upzone b { color: var(--accent-ink); }
    .up-status { font-size: 12.5px; color: var(--muted); }
    .up-source {
        flex: 0 0 200px; min-width: 160px; height: 40px;
        border: 1px solid var(--border-2); background: var(--surface); color: var(--text);
        border-radius: 10px; padding: 9px 12px; font-size: 13.5px; font-family: var(--font);
    }
    .up-source:focus { outline: 2px solid var(--accent); outline-offset: 1px; border-color: var(--accent-line); }
    .up-source::placeholder { color: var(--muted); }
    .up-help { margin-top: 12px; padding-top: 12px; border-top: 1px dashed var(--border); font-size: 12.5px; color: var(--text-2); line-height: 1.65; }
    .up-help code { font-family: var(--mono); font-size: 12px; background: var(--surface-2); padding: 1px 6px; border-radius: 5px; color: var(--accent-ink); }
    .up-help strong { color: var(--text); }
    .up-example { margin: 8px 0; padding: 10px 12px; background: var(--surface-2); border-radius: 8px;
        font-family: var(--mono); font-size: 11.5px; color: var(--text-2); overflow-x: auto; white-space: pre; }
    .up-tip { margin-top: 2px; }
    .up-spec-link { display: inline-block; margin-top: 8px; font-size: 12.5px; font-weight: 600; color: var(--accent-ink); }
    .up-spec-link:hover { text-decoration: underline; }
    /* 上传校验提示是「需要留意」而非「错误」——告警红改琥珀，与 .file-warn / .coverage-caveats 同族。 */
    .up-warn { margin-top: 12px; padding: 10px 12px; background: var(--warn-weak); border: 1px solid var(--warn-line);
        border-radius: 8px; font-size: 12.5px; color: var(--text); line-height: 1.6; }
    .up-warn div + div { margin-top: 4px; }

    /* ---------------- History（弹出式浮窗） ---------------- */
    /* 与主界面同层的非模态浮窗：fixed 定位（left/top 由 JS 拖动写入），默认尺寸可读、可缩。 */
    .hist-win { position: fixed; z-index: var(--z-floatwin); width: 580px; max-width: calc(100vw - 24px);
        height: min(520px, calc(100vh - 60px)); display: flex; flex-direction: column;
        background: var(--surface); border: 1px solid var(--border); border-radius: 16px;
        box-shadow: 0 18px 50px rgba(16, 33, 46, .18), 0 3px 10px rgba(16, 33, 46, .08); overflow: hidden; }
    .hist-win[hidden] { display: none; }
    /* 浮窗开合动效：从主界面轻微浮起——fade + 上浮 + 微缩放，弹簧缓动。 */
    .hist-win:not([hidden]) { animation: histWinIn .22s var(--ease-spring); }
    @keyframes histWinIn { from { opacity: 0; transform: translateY(10px) scale(.98); } to { opacity: 1; transform: none; } }
    /* 退出动效：与入场对称的下沉淡出——closeHistWin 挂类、动画播完才 hidden。
       与 :not([hidden]) 入场规则同特异度、靠源码顺序（在后）胜出。 */
    .hist-win.hist-win-out { animation: histWinOut .18s ease-in forwards; }
    @keyframes histWinOut { from { opacity: 1; transform: none; } to { opacity: 0; transform: translateY(8px) scale(.98); } }
    @media (prefers-reduced-motion: reduce) { .hist-win:not([hidden]) { animation: none; } .hist-win.hist-win-out { animation: none; } }
    .hw-head { display: flex; align-items: center; gap: 10px; padding: 12px 14px; cursor: grab;
        background: var(--surface-2); border-bottom: 1px solid var(--border-2); user-select: none; flex: none; }
    .hw-head:active { cursor: grabbing; }
    .hw-title { font-size: 14px; font-weight: 700; }
    .hw-sub { font-size: 11.5px; color: var(--muted); flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
    .hw-acts { display: flex; gap: 6px; flex: none; }
    .hw-btn { padding: 4px 10px; font-size: 12px; color: var(--text-2); background: var(--surface);
        border: 1px solid var(--border); border-radius: 8px; cursor: pointer; transition: color .15s, border-color .15s; }
    .hw-btn:hover { color: var(--text); border-color: var(--border-2); }
    .hw-btn:disabled { opacity: .45; cursor: default; }
    .hw-close { padding: 4px 9px; }
    .hw-body { flex: 1 1 auto; overflow-y: auto; padding: 12px 14px; }
    .hw-empty { text-align: center; padding: 48px 16px; color: var(--muted); }
    .hw-empty .hw-ei { font-size: 28px; }
    .hw-empty p { margin-top: 10px; font-size: 13.5px; }
    /* 右下角缩放手把：斜纹小三角（与拖拽头同型暗示「可动」） */
    .hw-resize { position: absolute; right: 0; bottom: 0; width: 22px; height: 22px; cursor: nwse-resize;
        background: linear-gradient(135deg, transparent 55%, var(--border-2) 55%, var(--border-2) 62%, transparent 62%,
            transparent 70%, var(--border-2) 70%, var(--border-2) 77%, transparent 77%); border-bottom-right-radius: 16px; }
    .hw-resize:hover { background-color: var(--accent-weak); }
    /* 档案浮窗双 tab（2026-08-22 历史记录 + 我的课题合并单窗）：页签条挂在头与体之间；
       data-lib-active 由 shell.js setLibTab 写入，挂点按钮按页签归属显隐。 */
    .arc-tabs { display: flex; gap: 4px; padding: 6px 14px 0; background: var(--surface-2); border-bottom: 1px solid var(--border-2); flex: none; }
    .arc-tab { padding: 6px 14px; font-size: 12.5px; font-weight: 600; color: var(--muted); background: transparent; border: none; border-bottom: 2px solid transparent; cursor: pointer; }
    .arc-tab:hover { color: var(--text-2); }
    .arc-tab.is-on { color: var(--accent-ink); border-bottom-color: var(--accent); }
    .arc-tab:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; border-radius: 6px; }
    .arc-pane[hidden] { display: none; }
    /* 我的库浮窗——收藏页签藏 #artifactsWinP4Mount 挂点（追踪页签才显示「检查 N 个追踪的更新」）；窄窗页签可横滑 */
    #libWin[data-lib-active="favs"] #artifactsWinP4Mount { display: none; }
    .arc-tabs { overflow-x: auto; }
    .hist-row { display: flex; align-items: center; gap: 12px; padding: 12px 14px; background: var(--surface);
        border: 1px solid var(--border); border-radius: var(--radius); margin-bottom: 10px; box-shadow: var(--shadow-sm); }
    /* 行本体＝主按钮（2026-08-03 用户）：点行即在本标签页找回这条对话，不再单列「本标签页显示」按钮 */
    .hist-main { flex: 1 1 auto; min-width: 0; text-align: left; background: transparent; border: none; padding: 0;
        font-family: var(--font); color: var(--text); cursor: pointer; border-radius: 8px; }
    .hist-main .hist-txt { display: block; }
    .hist-main .hist-q { display: block; font-size: 13.5px; font-weight: 500; word-break: break-word; transition: color .14s; }
    .hist-main:hover .hist-q, .hist-main:focus-visible .hist-q { color: var(--accent-ink); }
    .hist-main .hist-meta { display: block; font-size: 11.5px; color: var(--muted); font-family: var(--mono); margin-top: 3px; }
    .hist-acts { display: flex; gap: 6px; flex: none; flex-wrap: wrap; justify-content: flex-end; }
    .hist-acts .btn { padding: 6px 11px; font-size: 12px; }
    /* 删除二段确认（仿 #histClear armed）：armed 态用琥珀警示（非红：只是防误触） */
    .hist-del.armed { color: var(--warn); border-color: var(--warn-line-strong); background: var(--warn-weak); }
    /* 清空历史二段确认——armed 态用琥珀警示（非红：可逆操作、只是防误触） */
    #histClear.armed { color: var(--warn); border-color: var(--warn-line-strong); background: var(--warn-weak); }

    .empty { text-align: center; padding: 60px 20px; color: var(--muted); }
    .empty .ei { font-size: 30px; }
    .empty p { margin-top: 12px; font-size: 14.5px; }
    .empty .btn { margin-top: 18px; }

    /* ---------------- Help ---------------- */
    .prose { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg); padding: 30px 32px; box-shadow: var(--shadow-sm); max-width: 820px; }
    .prose h3 { font-size: 16px; margin: 22px 0 8px; }
    .prose h3:first-child { margin-top: 0; }
    .prose p, .prose li { font-size: 14px; color: var(--text-2); line-height: 1.75; }
    .prose ul, .prose ol { padding-left: 20px; }
    .prose .help-steps { margin: 6px 0 4px; }
    .prose .help-steps li { margin: 2px 0; }
    .prose code { font-family: var(--mono); font-size: 12.5px; background: var(--surface-2); padding: 1px 6px; border-radius: 5px; color: var(--accent-ink); }
    .prose strong { color: var(--text); }

    /* ---------------- Settings drawer ---------------- */
    .drawer {
        position: fixed; inset: 0 0 0 auto; width: 400px; max-width: 94vw; height: 100vh; z-index: var(--z-drawer);
        background: var(--surface); border-left: 1px solid var(--border); box-shadow: var(--shadow-lg);
        transform: translateX(100%); transition: transform 0.24s ease; display: flex; flex-direction: column;
    }
    .drawer.open { transform: translateX(0); }
    .drawer-head { display: flex; align-items: center; justify-content: space-between; padding: 20px 22px; border-bottom: 1px solid var(--border); }
    .drawer-head h3 { font-size: 16px; font-weight: 700; }
    .drawer-body { flex: 1; overflow-y: auto; padding: 20px 22px; }
    .drawer-foot { padding: 16px 22px; border-top: 1px solid var(--border); display: grid; gap: 10px; }

    /* API 是低频前置条件：默认折叠，让高频排序设置直接进入抽屉首屏。 */
    .api-config { border: 1px solid var(--border); border-radius: 12px; margin-bottom: 14px; background: var(--surface); overflow: hidden; }
    /* 2026-08-04 指路直达的短暂高亮：shell.js revealSetting 加上、1.6s 后摘掉。
       用 box-shadow 环而非底色——不遮内容、对 <details> 与开关行都成立。 */
    @keyframes settingFlash {
        0%, 100% { box-shadow: 0 0 0 0 rgba(13, 148, 136, 0); }
        20%, 70% { box-shadow: 0 0 0 3px rgba(13, 148, 136, .45); }
    }
    .setting-flash { animation: settingFlash 1.5s ease-out 1; border-radius: 12px; }
    @media (prefers-reduced-motion: reduce) {
        .setting-flash { animation: none; box-shadow: 0 0 0 3px rgba(13, 148, 136, .45); }
    }
    .api-config summary {
        list-style: none; cursor: pointer; min-height: 64px; padding: 10px 12px;
        display: grid; grid-template-columns: minmax(0, 1fr) auto 26px; align-items: center; gap: 9px;
        color: var(--text); transition: background .18s cubic-bezier(.22,1,.36,1);
    }
    .api-config summary::-webkit-details-marker { display: none; }
    .api-config summary:hover { background: var(--surface-2); }
    .api-config summary:focus-visible { outline: 2px solid var(--accent); outline-offset: -3px; }
    .api-config-main { display: flex; align-items: center; gap: 10px; min-width: 0; }
    .api-config-main > span:last-child { min-width: 0; }
    .api-config-main strong { display: block; font-size: 13.5px; }
    .api-config-main small { display: block; margin-top: 1px; color: var(--muted); font-size: 11.5px; line-height: 1.4; }
    .api-config-ico {
        width: 32px; height: 32px; flex: none; display: grid; place-items: center; border-radius: 9px;
        background: var(--surface-2); color: var(--text-2); font: 700 9px/1 var(--mono); letter-spacing: .03em;
    }
    .api-config-status {
        max-width: 92px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
        border-radius: 999px; padding: 3px 8px; background: var(--surface-2); color: var(--text-2); font-size: 10.5px; font-weight: 600;
    }
    .api-config-chevron {
        width: 26px; height: 26px; display: grid; place-items: center; border-radius: 8px;
        background: var(--surface-2); color: var(--text-2);
        transition: background .18s cubic-bezier(.22,1,.36,1), color .18s cubic-bezier(.22,1,.36,1);
    }
    .api-config-chevron svg {
        width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 1.75;
        stroke-linecap: round; stroke-linejoin: round;
        transition: transform .2s cubic-bezier(.22,1,.36,1);
    }
    .api-config summary:hover .api-config-chevron { background: var(--accent-weak); color: var(--accent-ink); }
    .api-config[open] .api-config-chevron { background: var(--accent-weak); color: var(--accent-ink); }
    .api-config[open] .api-config-chevron svg { transform: rotate(180deg); }
    .api-config[open] summary { border-bottom: 1px solid var(--border); }
    .api-config-body { padding: 14px; animation: apiConfigReveal .18s cubic-bezier(.22,1,.36,1); }
    @keyframes apiConfigReveal { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: translateY(0); } }

    .set-block { padding: 14px; border: 1px solid var(--border); border-radius: 12px; margin-bottom: 14px; background: var(--surface); }
    .set-note { margin: 10px 0 0; font-size: 11.5px; color: var(--muted); line-height: 1.55; }   /* 「在本浏览器记住设置」的 API Key 连带说明 */
    .memory-setting .label strong, .memory-setting .label small,
    .usage-setting .label strong, .usage-setting .label small,
    .account-box .label strong, .account-box .label small { display: block; }
    .memory-setting .label small, .usage-setting .label small,
    .account-box .label small { margin-top: 2px; color: var(--muted); font-size: 10.5px; font-weight: 500; }
    .memory-setting p { margin: 9px 0 10px; color: var(--muted); font-size: 11px; line-height: 1.55; }
    .memory-setting .btn { width: 100%; justify-content: center; margin-top: 12px; }
    .set-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
    .set-row .label { font-size: 14px; font-weight: 600; }
    .set-hint { font-size: 12.5px; color: var(--muted); margin-top: 8px; line-height: 1.55; }
    .set-label { display: block; font-size: 12.5px; font-weight: 600; color: var(--text-2); margin: 12px 0 6px; }
    /* 限量试用额度卡：trial 预设专属——剩余轮数大字 + 细进度条，
       低余额（≤15% 或 ≤3 轮）转暖橙提醒；主题色与 accent 体系一致。 */
    .trial-quota {
        margin-top: 12px; padding: 12px 14px; border: 1px solid var(--accent-line);
        border-radius: 12px; background: var(--accent-weak);
    }
    .trial-quota-top { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
    .trial-quota-title { font-size: 12.5px; font-weight: 600; color: var(--accent-ink); }
    .trial-quota-title strong { font-size: 17px; font-weight: 700; color: var(--accent-ink); margin: 0 2px; }
    .trial-quota-reset { font-size: 11px; color: var(--muted); flex: none; }
    .trial-quota-track {
        margin-top: 8px; height: 6px; border-radius: 999px;
        background: rgba(13, 148, 136, .14); overflow: hidden;
    }
    .trial-quota-fill {
        height: 100%; border-radius: 999px; background: var(--accent);
        transition: width .45s cubic-bezier(.22,1,.36,1);
    }
    .trial-quota-fill.low { background: #d97706; }
    .input {
        width: 100%; border: 1px solid var(--border-2); background: var(--surface); color: var(--text);
        border-radius: 10px; padding: 10px 12px; font-size: 14px; font-family: var(--font);
    }
    .input:focus { outline: 2px solid var(--accent); outline-offset: 1px; border-color: var(--accent-line); }
    /* 推荐数量与重排候选数使用同一种紧凑数字输入。 */
    .set-num {
        width: 96px; border: 1px solid var(--border-2); background: var(--surface);
        color: var(--text); border-radius: 10px; padding: 8px 10px; font-size: 14px; font-family: var(--font);
    }
    .set-num:focus { outline: 2px solid var(--accent); outline-offset: 1px; border-color: var(--accent-line); }

    /* ---------------- Settings controls ---------------- */
    .pipe { display: flex; flex-direction: column; gap: 10px; padding: 0 0 4px; }
    .node { border: 1px solid var(--border); border-radius: 12px; background: var(--surface); padding: 11px 13px; box-shadow: var(--shadow-sm); transition: border-color .18s, background .18s; }
    .node-row { display: flex; align-items: center; gap: 11px; }
    .node-ico { width: 29px; height: 29px; flex-shrink: 0; display: grid; place-items: center; border-radius: 9px; background: var(--surface-2); color: var(--text-2); font-size: 15px; line-height: 1; }
    .node-body { flex: 1; min-width: 0; }
    .node-name { font-size: 13.5px; font-weight: 700; }
    .node-desc { font-size: 11.5px; color: var(--muted); margin-top: 1px; }
    .setting-item.active { border-color: var(--accent-line); background: var(--accent-weak); }
    .setting-item.active .node-name { color: var(--accent-ink); }

    /* 排序策略完整链路：规则始终开启，自动选择决定是否叠加本地与 AI 重排。 */
    .strategy-panel { border: 1px solid var(--border-2); border-radius: 14px; background: var(--surface); box-shadow: var(--shadow-sm); overflow: hidden; }
    .strategy-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 13px 14px 10px; }
    .strategy-heading { display: flex; align-items: center; gap: 10px; min-width: 0; }
    .strategy-heading > span:last-child { min-width: 0; }
    .strategy-heading strong { display: block; font-size: 14px; }
    .strategy-heading small { display: block; margin-top: 1px; color: var(--muted); font-size: 11.5px; }
    .strategy-auto { display: inline-flex; align-items: center; gap: 8px; flex: none; color: var(--text-2); font-size: 12px; font-weight: 600; cursor: pointer; }
    .strategy-mode { margin: 0 14px 11px; color: var(--text-2); font-size: 11.5px; line-height: 1.45; }
    .strategy-choice-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 7px; padding: 0 14px 14px; }
    .strategy-choice {
        position: relative; display: flex; align-items: center;
        min-width: 0; min-height: 58px; padding: 9px 20px 9px 9px; border: 1px solid var(--border); border-radius: 10px; background: var(--surface);
        cursor: pointer; transition: border-color .18s, background .18s, color .18s;
    }
    .strategy-choice > input { position: absolute; inline-size: 1px; block-size: 1px; opacity: 0; pointer-events: none; }
    .strategy-choice:has(input:focus-visible) { outline: 2px solid var(--accent); outline-offset: 2px; }
    .strategy-choice-copy { min-width: 0; }
    .strategy-choice-copy strong { display: block; font-size: 11.5px; line-height: 1.25; white-space: nowrap; }
    .strategy-choice-copy small { display: block; margin-top: 2px; color: var(--muted); font-size: 10.5px; }
    .strategy-choice-state { position: absolute; top: 9px; right: 8px; width: 14px; height: 14px; display: grid; place-items: center; border: 1.5px solid var(--border-2); border-radius: 50%; }
    .ranking-control:not(.auto-owned) .strategy-choice:hover { border-color: var(--accent-line); background: var(--accent-weak); }
    .ranking-control:not(.auto-owned) .strategy-choice.active { border-color: var(--accent); background: var(--accent-weak); color: var(--accent-ink); }
    .ranking-control:not(.auto-owned) .strategy-choice.active .strategy-choice-state { border-color: var(--accent); background: var(--accent); }
    .ranking-control:not(.auto-owned) .strategy-choice.active .strategy-choice-state::after { content: ""; width: 5px; height: 3px; border: solid var(--surface); border-width: 0 0 1.5px 1.5px; transform: rotate(-45deg) translateY(-1px); }
    .ranking-control.auto-owned .strategy-choice { background: var(--surface-2); color: var(--text-2); cursor: default; }
    .ranking-control.auto-owned .strategy-choice-state { border-style: dashed; }
    .strategy-choice-rule, .ranking-control.auto-owned .strategy-choice-rule {
        border-color: var(--accent-line); background: var(--accent-weak); color: var(--accent-ink); cursor: help;
    }
    .strategy-choice-rule .strategy-choice-state, .ranking-control.auto-owned .strategy-choice-rule .strategy-choice-state { border-color: var(--accent); border-style: solid; background: var(--accent); }
    .strategy-choice-rule .strategy-choice-state::after { content: ""; width: 5px; height: 3px; border: solid var(--surface); border-width: 0 0 1.5px 1.5px; transform: rotate(-45deg) translateY(-1px); }
    .strategy-tip { position: relative; }
    .strategy-tooltip {
        position: fixed; z-index: var(--z-tooltip); width: min(286px, calc(100vw - 24px)); padding: 10px 11px;
        border: 1px solid var(--border-2); border-radius: 10px; background: var(--ink-inverse); color: var(--surface);
        box-shadow: var(--shadow-lg); font-size: 12px; line-height: 1.55; pointer-events: none;
    }
    .strategy-auto-ai, .strategy-rerank-detail { border-top: 1px solid var(--border); background: var(--surface-2); }
    .strategy-auto-ai { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 10px 14px; }
    .strategy-auto-ai > span, .strategy-inline-toggle > span { min-width: 0; }
    .strategy-auto-ai strong, .strategy-inline-toggle strong { display: block; font-size: 12px; }
    .strategy-auto-ai small, .strategy-inline-toggle small { display: block; margin-top: 1px; color: var(--muted); font-size: 10.5px; }
    .strategy-auto-ai.off, .strategy-rerank-detail.off { display: none; }
    .strategy-rerank-detail { padding: 2px 14px; }
    .local-model-install {
        position: relative; display: flex; align-items: center; justify-content: space-between; gap: 12px;
        padding: 10px 14px; border-top: 1px solid var(--border); background: var(--surface-2); overflow: hidden;
    }
    .local-model-copy { min-width: 0; }
    .local-model-copy strong { display: block; color: var(--text); font-size: 12px; }
    .local-model-copy small { display: block; margin-top: 2px; color: var(--muted); font-size: 10.5px; line-height: 1.45; }
    .local-model-actions { display: flex; align-items: center; gap: 6px; flex: none; }
    .local-model-actions .btn { min-height: 30px; padding: 5px 10px; font-size: 11px; }
    .local-model-install-btn { border-color: var(--accent-line); color: var(--accent-ink); background: var(--accent-weak); }
    .local-model-progress { position: absolute; left: 0; right: 0; bottom: 0; height: 2px; background: var(--border); overflow: hidden; }
    .local-model-progress span { display: block; width: 38%; height: 100%; background: var(--accent); animation: localModelProgress 1.4s ease-in-out infinite; }
    @keyframes localModelProgress { from { transform: translateX(-110%); } to { transform: translateX(300%); } }
    @media (prefers-reduced-motion: reduce) { .local-model-progress span { width: 100%; animation: none; } }
    @media (max-width: 520px) {
        .local-model-install { align-items: stretch; flex-direction: column; }
        .local-model-actions { justify-content: flex-end; }
    }
    .strategy-inline-field, .strategy-inline-toggle { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 10px 0; }
    .strategy-inline-field + .strategy-inline-toggle { border-top: 1px solid var(--border); }
    .strategy-inline-field label { color: var(--text); font-size: 12px; font-weight: 600; }
    .strategy-inline-field label small { color: var(--muted); font-size: 10.5px; font-weight: 500; }

    /* 设置三维度：B（自动选择）开 → 隐藏 A 的手动项；
       B 关 → 隐藏「允许自动使用 AI」行。显隐唯一收口在 .auto-owned，不再逐个 disabled。
       2026-08-04（用户）：自动模式下「AI 重排候选数」保留可调——后端 auto 分支本就消费 rerank_top_n
       （只覆盖 recall/rerank 的后端选择，不碰候选数），藏它只是 UI 层误伤。 */
    .ranking-control.auto-owned .strategy-choice-grid { display: none; }
    .ranking-control:not(.auto-owned) .strategy-auto-ai { display: none; }
    /* AI 门控标注：LLM 依赖开关的统一「需 API / 已暂停」小标（未配 key 禁点的视觉语言）。 */
    .gate-tag { display: inline-block; margin-left: 5px; padding: 1px 6px; border-radius: 999px;
        background: var(--surface-2); border: 1px solid var(--border-2); color: var(--muted);
        font-size: 10px; font-weight: 600; vertical-align: 1px; }
    .ai-gated { opacity: .55; }
    .ai-degraded .gate-tag { color: var(--warn-ink, #8a5a00); border-color: var(--warn-line, #e3c47a);
        background: var(--warn-weak, #fdf3d7); }
    /* 「?」帮助钮：技术细节的 tooltip 触发器（strategy-tip 体系），不抢主文案。 */
    .help-dot { display: inline-grid; place-items: center; width: 16px; height: 16px; margin-left: 5px;
        border: 1px solid var(--border-2); border-radius: 50%; background: var(--surface);
        color: var(--muted); font-size: 10.5px; font-weight: 700; line-height: 1; cursor: help;
        vertical-align: -2px; padding: 0; }
    .help-dot:hover { color: var(--accent-ink); border-color: var(--accent-line); }

    @media (max-width: 380px) {
        .strategy-choice-grid { grid-template-columns: 1fr; }
    }
    /* 检索进度：后端单次阻塞、拿不到真实分段——用不确定态加载（系统回复气泡三点动画），
       按钮只留静态 loading；进度不再占独立一行。 */
    /* 发表时间范围筛选（可选、默认不限）—— 「时间维度」 */
    /* 数据来源/发表时间选择器：折叠成 pill（自动识别 / 自定义），点开的面板落在控制台底栏下方、
       锚在 .sf-select（pill 包裹层）并左对齐（见 .sf-panel），避免窄屏溢出。 */
    .sf-select { position: relative; }
    .sf-toggle {
        display: inline-flex; align-items: center; gap: 8px; white-space: nowrap;   /* 摘要不折行 */
        border: 1px solid var(--border-2); border-radius: 10px; background: var(--surface);   /* 圆角矩形，与搜索控制台同族（原 999px 胶囊→改） */
        color: var(--text); font-size: 12.5px; font-weight: 600; font-family: var(--font);
        padding: 6px 11px 6px 12px; cursor: pointer;
        transition: border-color .15s, box-shadow .15s, background .15s;
    }
    .sf-toggle:hover { border-color: var(--accent-line); }
    .sf-toggle[aria-expanded="true"] { border-color: var(--accent-line); box-shadow: 0 0 0 3px var(--accent-weak); }
    .sf-toggle .sf-cur { color: var(--accent-ink); display: inline-block; max-width: 168px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; vertical-align: bottom; }   /* 摘要过长时省略号收尾（nowrap 才会触发省略），绝不溢出到相邻格 */
    .sf-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--accent); box-shadow: 0 0 0 3px var(--accent-weak); flex: none; }
    .sf-select.is-custom .sf-dot { background: var(--muted-soft); box-shadow: 0 0 0 3px var(--surface-2); }
    .sf-caret { width: 0; height: 0; border-left: 4px solid transparent; border-right: 4px solid transparent; border-top: 5px solid var(--muted-soft); transition: transform .24s cubic-bezier(.22,1,.36,1); }
    .sf-toggle[aria-expanded="true"] .sf-caret { transform: rotate(180deg); }
    .sf-panel {
        position: absolute; top: calc(100% + 12px); left: 0;
        z-index: var(--z-dropdown); width: min(320px, 86vw);
        background: var(--surface); border: 1px solid var(--border-2); border-radius: 14px;
        box-shadow: var(--shadow); padding: 12px; text-align: left; cursor: default;
    }
    /* 自适应翻向：interactions.js fitPopover 在底部越界时加 .drop-up，
       面板改向上展开，不再被屏幕下缘截断（chat-in-main 态控制台贴着视口底部）。 */
    .sf-panel.drop-up { top: auto; bottom: calc(100% + 12px); }
    .sf-panel[hidden] { display: none; }
    .sf-modes { display: flex; gap: 4px; background: var(--surface-2); border-radius: 10px; padding: 3px; }
    .sf-mode {
        flex: 1; border: none; background: transparent; border-radius: 8px; cursor: pointer;
        font-family: var(--font); font-size: 12.5px; font-weight: 600; color: var(--text-2); padding: 7px 10px;
        transition: background .15s, color .15s, box-shadow .15s;
    }
    .sf-mode:hover { color: var(--accent-ink); }
    .sf-mode.active { background: var(--surface); color: var(--accent-ink); box-shadow: var(--shadow-sm); }
    .sf-hint { margin: 10px 3px 0; font-size: 12px; line-height: 1.5; color: var(--muted); }
    .sf-chips { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 10px; }
    .sf-panel.mode-auto .sf-chips { display: none; }
    .src-chip {
        border: 1px solid var(--border-2); border-radius: 10px; background: var(--surface);   /* 与 pill/控制台同族圆角矩形 */
        color: var(--text-2); font-size: 12.5px; padding: 6px 13px; cursor: pointer; font-family: var(--font);
        display: inline-flex; align-items: center; gap: 7px;
        transition: border-color 0.15s, color 0.15s, background 0.15s;
    }
    .src-chip::before { content: ""; width: 9px; height: 9px; border-radius: 50%; border: 1.5px solid currentColor; background: transparent; transition: background 0.15s; }
    .src-chip.active { border-color: var(--accent-line); background: var(--accent-weak); color: var(--accent-ink); font-weight: 600; }
    .src-chip.active::before { background: currentColor; }
    .src-chip .c { font-size: 11px; opacity: 0.7; }
    .tf-range { display: flex; align-items: center; gap: 8px; margin-top: 10px; }
    .sf-panel.mode-auto .tf-range { display: none; }   /* 自动识别模式隐藏年份下拉（与来源 chips 同理） */
    .tf-select { border: 1px solid var(--border-2); border-radius: 8px; padding: 5px 9px; font-size: 13px; background: var(--surface); color: var(--text); font-family: var(--font); cursor: pointer; }
    input.tf-select { width: 8ch; cursor: text; }   /* 2026-08-05：年份改可输入（datalist 快捷项 + 手输），宽度按四位数字定 */
    .tf-select:focus-visible { outline: 2px solid var(--accent-line); outline-offset: 1px; }
    .tf-select.set { border-color: var(--accent-line); color: var(--accent-ink); font-weight: 600; }
    .tf-sep { color: var(--muted); }

    details.dev { border: 1px solid var(--border); border-radius: 12px; margin-top: 6px; }
    details.dev summary { cursor: pointer; padding: 12px 14px; font-size: 13.5px; font-weight: 600; color: var(--text-2); list-style: none; }
    details.dev summary::-webkit-details-marker { display: none; }
    details.dev summary::before { content: "▸ "; color: var(--muted-soft); }
    details.dev[open] summary::before { content: "▾ "; }
    details.dev[open] summary { border-bottom: 1px solid var(--border); }
    .dev-body { padding: 14px; }
    .kv { display: flex; justify-content: space-between; gap: 12px; padding: 6px 0; border-bottom: 1px dashed var(--border); font-size: 12.5px; }
    .kv:last-of-type { border-bottom: none; }
    .kv .k { color: var(--muted); font-family: var(--mono); }
    .kv .v { color: var(--text-2); font-family: var(--mono); text-align: right; word-break: break-word; }
    .kv .v.ok { color: var(--ok); font-weight: 700; }
    .kv .v.no { color: var(--no); font-weight: 700; }
    .raw-md { margin-top: 12px; padding: 12px; background: var(--surface-2); border-radius: 10px; font-family: var(--mono);
        font-size: 11.5px; line-height: 1.55; color: var(--text-2); white-space: pre-wrap; max-height: 240px; overflow: auto; }

    .overlay { position: fixed; inset: 0; background: rgba(16, 33, 46, 0.35); z-index: var(--z-overlay); opacity: 0; pointer-events: none; transition: opacity 0.2s; }
    .overlay.on { opacity: 1; pointer-events: auto; }

    .toast {
        position: fixed; left: 50%; bottom: 26px; transform: translate(-50%, 140%); z-index: var(--z-toast);
        background: var(--ink-inverse); color: var(--surface); border-radius: 11px; padding: 11px 18px; font-size: 13.5px;
        box-shadow: var(--shadow-lg); opacity: 0; transition: transform 0.24s ease, opacity 0.24s ease; max-width: 90vw;
    }
    .toast.show { transform: translate(-50%, 0); opacity: 1; }

    /* ---------------- 结果摘要卡（计数行 + 方法句 + 覆盖缺口合一；逐步 trace 折叠已删） ----------------
       中性卡承载一段自然语言方法句（.rs-text）；覆盖缺口（.rs-coverage，琥珀语义）内嵌在卡内。 */
    .result-summary { margin: 0 0 18px; padding: 13px 16px; border: 1px solid var(--border); border-radius: var(--radius-lg); background: var(--surface); }
    .rs-text { font-size: 13.5px; line-height: 1.7; color: var(--text-2); }
    .rs-text b { color: var(--accent-ink); font-weight: 700; font-variant-numeric: tabular-nums; }
    /* （2026-08-16 用户）：摘要句方法层关键词（规则排序/本地精准重排/AI 重排）行内高光——
       荧光笔感（下半截底色 + accent 字色 + 微加粗），嵌在长句里一眼定位方法层而不抢眼；
       不做粗重 pill。行内盒无宽高，交换态 300px 窄栏换行/2 行截断下不破行、不溢出。 */
    .rs-text .sum-layer {
        background: linear-gradient(transparent 62%, var(--accent-weak) 62%);
        color: var(--accent-ink); font-weight: 650; font-style: normal; padding: 0 1px; border-radius: 2px;
    }
    /* 内嵌覆盖缺口：琥珀底 + 圆角，与中性卡区分「这是需要留意的诚实降级信息」；.cov-* 内部样式复用既有全局规则。 */
    .rs-coverage { margin-top: 11px; padding: 10px 12px; border-radius: 10px; background: var(--caution-weak); }
    .rs-coverage[hidden] { display: none; }

    /* ---------------- 首次进入轻量导览 ---------------- */
    .onboarding {
        /* 每次开始都以视口中心为默认位置；用户可从标题栏拖到不遮挡目标的位置。 */
        /* 导览独立紫（oklch hue 274）收敛为站内品牌青族，与全局 accent 同一语义来源。 */
        --tour-accent: var(--accent);
        --tour-accent-hover: var(--accent-ink);
        --tour-width: 440px;
        position: fixed; left: 50%; top: 50%; right: auto; bottom: auto; transform: translate(-50%, -50%); z-index: var(--z-tour);
        width: min(var(--tour-width), calc(100vw - 36px));
    }
    .onboarding[data-size="compact"] { --tour-width: 400px; }
    .onboarding[data-size="medium"] { --tour-width: 480px; }
    .onboarding[data-size="wide"] { --tour-width: 620px; }
    .onboarding-surface {
        width: 100%; max-height: calc(100dvh - 36px); overflow-y: auto;
        border: 1px solid var(--accent-line); border-radius: var(--radius-lg);
        /* 超大 spread 阴影 = 全视口压暗（不新增元素、不拦截点击、非模态语义不变）——
           此前桌面无压暗，面板与首屏标题文字互相干扰。面板自身投影照旧（第二位）。 */
        background: var(--accent-weak); box-shadow: 0 0 0 150vmax rgba(16, 33, 46, .26), 0 18px 48px rgba(11, 124, 114, .20); padding: 15px;
        transform-origin: top left;
    }
    /* 桌面非设置步骤的默认落点从视口正中央下移到**底部居中**——正中央必压
       垂直居中的 hero 首屏标题（实测面板边缘裁切标题字）；底部落点让出标题与控制台，
       目标高亮环（focus-ring）照常指目标。设置步骤维持居中（与右侧抽屉配合）。移动端不动。 */
    @media (min-width: 781px) {
        .onboarding:not(.onboarding-settings) { top: auto; bottom: 26px; transform: translateX(-50%); }
    }
    .onboarding.onboarding-settings { left: 50%; right: auto; }
    .onboarding.onboarding-dragging { transform: none; }
    .onboarding.onboarding-dragging .onboarding-surface { cursor: grabbing; }
    .onboarding-head { display: flex; align-items: center; justify-content: space-between; cursor: grab; touch-action: none; user-select: none; }
    .onboarding-head-main { display: inline-flex; align-items: center; gap: 7px; min-width: 0; }
    .onboarding-drag-hint { color: var(--muted); font-size: 11px; font-weight: 600; }
    .onboarding-progress { color: var(--accent-ink); font: 700 12px/1 var(--mono); }
    .onboarding-close { width: 30px; height: 30px; cursor: pointer; touch-action: auto; }
    .onboarding-copy { padding: 8px 2px 14px; }
    .onboarding-copy h3 { font-size: 17px; line-height: 1.35; margin-bottom: 7px; }
    .onboarding-copy > p { color: var(--text-2); font-size: 13px; line-height: 1.65; max-width: 72ch; }
    /* 第0步反馈强化版专属样式（仅 BENCHFB_BUILD=true 分支经 onboarding.js 挂类）——
       标题用教程卡自身的主题色别名 --tour-accent（= var(--accent)，同一语义来源），正文整体加粗。 */
    .onboarding-copy h3.onboarding-title-accent { color: var(--tour-accent); }
    .onboarding-copy > p.onboarding-text-bold { font-weight: 700; }
    .onboarding .btn-primary { background: var(--tour-accent); border-color: var(--tour-accent); }
    .onboarding .btn-primary:hover { background: var(--tour-accent-hover); border-color: var(--tour-accent-hover); }
    .onboarding .btn:focus-visible, .onboarding .icon-btn:focus-visible { outline-color: var(--tour-accent); }

    /* 每一步使用与真实控件同语义的内联示意图，不依赖外部视频或网络；唯一的图片是
       随包捆绑的详情页实拍截图（/static/assets/，同源、离线可用）。 */
    .onboarding-visuals { margin-top: 13px; }
    .tour-visual {
        border: 1px solid var(--accent-line); border-radius: var(--radius-md);
        background: var(--surface); padding: 12px; color: var(--text);
        animation: tour-visual-in .18s cubic-bezier(.22, 1, .36, 1);
    }
    .tour-visual[hidden] { display: none !important; }
    @keyframes tour-visual-in { from { opacity: 0; transform: translateY(5px); } to { opacity: 1; transform: none; } }
    .tour-arrow { color: var(--tour-accent); font-size: 14px; line-height: 1; text-align: center; margin: 7px 0; }
    .tour-query-line {
        border: 1px solid var(--accent-line); border-radius: 9px; background: var(--surface);
        padding: 9px 11px; font-size: 12.5px; color: var(--text-2);
    }
    .tour-react .tour-query-line + .tour-query-line { margin-top: 8px; }
    .tour-token-row { display: flex; flex-wrap: wrap; gap: 6px; }
    .tour-token-row span {
        display: inline-flex; gap: 5px; padding: 5px 8px; border-radius: 999px;
        background: var(--accent-weak); color: var(--accent-ink); font-size: 11px;
    }
    .tour-token-row b { font-weight: 700; }
    .tour-token-row .tour-token-negative { background: var(--no-weak); color: var(--no); }
    .tour-scope { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
    .tour-scope div { min-width: 0; padding: 9px 10px; border-radius: 9px; background: var(--surface); border: 1px solid var(--border); }
    .tour-scope small, .tour-scope strong { display: block; }
    .tour-scope small { color: var(--muted); font-size: 10.5px; }
    .tour-scope strong { margin-top: 3px; color: var(--text-2); font-size: 11.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
    .tour-provider-brands { display: flex; flex-wrap: wrap; justify-content: center; gap: 6px; }
    .tour-provider-brand {
        padding: 5px 8px; border: 1px solid transparent; border-radius: 8px;
        background: var(--accent-weak); color: var(--accent-ink); font: 700 10.5px/1.2 var(--font);
        cursor: pointer;
    }
    .tour-provider-brand:hover:not([aria-pressed="true"]) { border-color: var(--accent); }
    .tour-provider-brand[aria-pressed="true"] { border-color: var(--accent); background: var(--accent); color: var(--surface); }
    .tour-provider-brand:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
    .tour-provider-fill { display: grid; grid-template-columns: auto 1fr auto 1fr; align-items: center; gap: 5px 8px; font-size: 10.5px; }
    .tour-provider-fill span { color: var(--muted); }
    .tour-provider-fill strong { padding: 5px 7px; border: 1px solid var(--border); border-radius: 7px; background: var(--surface); color: var(--text-2); font-size: 10.5px; }
    .tour-ranking { display: grid; grid-template-columns: 1fr auto 1fr auto 1fr; gap: 8px; align-items: stretch; }
    .tour-rank-stage { position: relative; min-width: 0; padding: 10px 8px 9px; border-radius: 10px; background: var(--surface); border: 1px solid var(--border); text-align: center; }
    .tour-rank-stage.is-required { border-color: var(--accent-line); background: var(--accent-weak); }
    .tour-rank-stage strong, .tour-rank-stage small { display: block; }
    .tour-rank-stage strong { margin-top: 3px; font-size: 12px; }
    .tour-rank-stage small { margin-top: 4px; color: var(--text-2); font-size: 10.5px; line-height: 1.45; }
    .tour-rank-num { display: grid; place-items: center; width: 20px; height: 20px; margin: 0 auto; border-radius: 50%; background: var(--accent-weak); color: var(--accent-ink); font: 700 var(--fs-micro)/1 var(--mono); }
    .tour-rank-link { align-self: center; color: var(--tour-accent); font-size: 15px; }
    .tour-rank-guard { grid-column: 1 / -1; display: flex; align-items: center; justify-content: center; gap: 6px; padding-top: 2px; color: var(--ok); font-size: 10.5px; font-weight: 600; text-align: center; }
    .tour-polish { display: grid; grid-template-columns: 1fr auto 1fr; gap: 9px; align-items: center; }
    .tour-polish-copy { padding: 9px; border: 1px solid var(--border); border-radius: 9px; background: var(--surface); }
    .tour-polish-copy small, .tour-polish-copy span { display: block; }
    .tour-polish-copy small { color: var(--muted); font-size: 10px; }
    .tour-polish-copy span { margin-top: 4px; color: var(--text-2); font-size: 10.5px; line-height: 1.45; }
    .tour-polish-copy.is-polished { border-color: var(--accent-line); background: var(--accent-weak); }
    .tour-polish-arrow { color: var(--tour-accent); }
    .tour-polish-lock { grid-column: 1 / -1; justify-self: center; padding: 4px 8px; border-radius: 999px; background: var(--ok-weak); color: var(--ok); font-size: 10.5px; font-weight: 700; }
    .tour-trace { display: grid; gap: 7px; }
    .tour-trace > div { display: grid; grid-template-columns: 22px 1fr; align-items: start; gap: 8px; }
    .tour-trace-mark { display: grid; place-items: center; width: 20px; height: 20px; border-radius: 50%; background: var(--ok-weak); color: var(--ok); font: 700 var(--fs-micro)/1 var(--mono); }
    .tour-trace-mark.is-fallback { background: oklch(94% 0.035 85); color: oklch(48% 0.12 65); }
    .tour-trace p { min-width: 0; }
    .tour-trace strong, .tour-trace small { display: block; }
    .tour-trace strong { font-size: 11.5px; }
    .tour-trace small { color: var(--text-2); font-size: 10.5px; }
    .tour-refine { display: grid; grid-template-columns: minmax(120px, .8fr) minmax(180px, 1.2fr); gap: 9px; }
    .tour-refine-facets, .tour-refine-card { padding: 9px; border-radius: 9px; background: var(--surface); border: 1px solid var(--border); }
    .tour-refine-facets { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; }
    .tour-refine-facets small { color: var(--muted); font-size: 10px; font-weight: 700; }
    .tour-refine-facets span { max-width: 100%; padding: 4px 7px; border-radius: 999px; background: var(--accent-weak); color: var(--accent-ink); font-size: 10px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
    .tour-refine-card { display: grid; gap: 4px; }
    .tour-refine-kicker { color: var(--muted); font-size: var(--fs-micro); }
    .tour-refine-card strong { font-size: 11.5px; }
    .tour-refine-card small { color: var(--text-2); font-size: 10px; }
    .tour-refine-button { justify-self: start; margin-top: 4px; padding: 5px 8px; border-radius: 7px; border: 1px solid var(--accent-line); color: var(--accent-ink); background: var(--accent-weak); font-size: 10px; font-weight: 700; }
    /* 详情页步骤的实拍截图——细边框 + 轻投影，让它读作「界面截图」而非装饰图；
       双向上限（容器宽 / 44dvh）保面板整体不超 max-height，窄屏同样成立。 */
    .tour-detail { padding: 6px; }
    .tour-detail img {
        display: block; max-width: 100%; max-height: 44dvh; width: auto; height: auto; margin: 0 auto;
        border: 1px solid var(--border); border-radius: 8px; background: var(--surface);
        box-shadow: 0 6px 18px rgba(11, 124, 114, .14);
    }
    .tour-detail img[hidden] { display: none !important; }
    .tour-detail-fallback {
        max-width: 100%; margin: 0 auto; padding: 12px 10px; border: 1px solid var(--border);
        border-radius: 8px; background: var(--surface); color: var(--text-2);
        font-size: 10.5px; line-height: 1.5; text-align: left;
    }
    .tour-detail-fallback[hidden] { display: none !important; }
    .onboarding-actions {
        position: sticky; bottom: 0; z-index: 1; display: flex; align-items: center; gap: 8px;
        padding-top: 12px; border-top: 1px solid var(--accent-line); background: var(--accent-weak);
    }
    .onboarding-spacer { flex: 1; }
    .onboarding-skip { color: var(--text-2); }
    /* 目标自身的 outline 会被相邻 flex/grid 控件盖住；独立 fixed 轮廓层只负责绘制，不改变控件层级或点击。 */
    .onboarding-focus { outline: none !important; }
    .onboarding-focus-ring {
        position: fixed; z-index: var(--z-tour-ring); box-sizing: border-box; pointer-events: none;
        border: 3px solid var(--accent);
        box-shadow: 0 0 0 2px rgba(230, 245, 243, .9), 0 8px 24px rgba(11, 124, 114, .16);
    }
    .help-tour-btn { margin: 4px 0 12px; }
    /* 帮助页「接入 AI 助手」块——按钮行沿用 .btn 体系，锚按钮去下划线；说明小字同 .prose 字级。 */
    .help-agent-acts { display: flex; gap: 10px; flex-wrap: wrap; margin: 4px 0 8px; }
    .help-agent-acts .btn { padding: 8px 14px; font-size: 13px; text-decoration: none; }
    .help-agent-note { font-size: 12px; color: var(--muted); }
    /* 在线 MCP 接入：方式一块在本机形态 hidden；令牌输出 = 警示小字 + 等宽配置块。 */
    .help-agent-online h4, .prose h4 { margin: 14px 0 4px; font-size: 14px; }
    .mcp-token-out { margin: 8px 0 4px; }
    .mcp-token-warn { font-size: 12px; color: var(--warn); margin: 0 0 6px; }
    .mcp-token-config {
        font-family: var(--mono); font-size: 12px; line-height: 1.5;
        background: var(--surface-2); border: 1px solid var(--border);
        border-radius: 8px; padding: 10px 12px; margin: 0 0 8px; overflow-x: auto; white-space: pre; user-select: all;
    }
    .mcp-token-list { margin-top: 6px; }
    .mcp-token-list-title { margin: 10px 0 4px; font-size: 13px; }
    .mcp-token-row {
        display: flex; align-items: center; justify-content: space-between; gap: 10px;
        padding: 6px 0; border-bottom: 1px dashed var(--border);
    }
    .mcp-token-row:last-child { border-bottom: none; }
    .mcp-token-meta { font-size: 12px; color: var(--muted); font-family: var(--mono); }
    .mcp-token-revoke { padding: 3px 10px; font-size: 12px; }

    /* ---------------- 收藏夹（我的收藏：tab 条 / 分组 / 管理面板 / 心形 popover）---------------- */
    .fav-folder-bar { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); margin-bottom: var(--space-3); }
    .fav-folder-tabs { display: flex; gap: 6px; overflow-x: auto; padding-bottom: 2px; }   /* 夹多横向滚动 */
    .fav-tab {
        flex: none; border: 1px solid var(--border-2); border-radius: 999px; background: var(--surface);
        color: var(--text-2); font-family: var(--font); font-size: var(--fs-sm); padding: 5px 12px; cursor: pointer;
        transition: border-color .15s, color .15s, background .15s;
    }
    .fav-tab:hover { border-color: var(--accent-line); color: var(--accent-ink); }
    .fav-tab.active { border-color: var(--accent-line); background: var(--accent-weak); color: var(--accent-ink); font-weight: 600; }
    .fav-tab-n { font-size: var(--fs-micro); opacity: .7; }
    .fav-folder-manage { margin-bottom: var(--space-3); background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius); padding: var(--space-2) var(--space-3); }
    .fav-mng-row { display: flex; align-items: center; gap: var(--space-2); padding: 7px 0; }
    .fav-mng-row + .fav-mng-row { border-top: 1px solid var(--border); }
    .fav-mng-name { font-weight: 600; color: var(--text); font-size: var(--fs-sm); }
    .fav-mng-hint { color: var(--muted); font-size: var(--fs-xs); }
    .fav-mng-rename, .fav-mng-new-input {
        flex: 1; min-width: 0; border: 1px solid var(--border-2); border-radius: 8px; padding: 6px 10px;
        font-family: var(--font); font-size: var(--fs-sm); background: var(--surface); color: var(--text);
    }
    .fav-mng-rename:focus-visible, .fav-mng-new-input:focus-visible { outline: 2px solid var(--accent-line); outline-offset: 1px; }
    /* 删除二段确认：armed 态用琥珀警示（与 histClear 同语言：可逆操作、只防误触） */
    .fav-mng-del.armed { color: var(--warn); border-color: var(--warn-line-strong); background: var(--warn-weak); }
    .fav-group { margin-bottom: var(--space-4); }
    .fav-group-title { margin: 0 0 var(--space-2); font-size: var(--fs-md); color: var(--text); }
    .fav-group-n { color: var(--muted); font-size: var(--fs-xs); font-weight: 400; }
    /* 心形 popover：轻量浮层（fixed 定位锚心形），复用 dropdown 层级与卡片质感，不进 modal 焦点体系 */
    .fav-popover {
        position: fixed; z-index: var(--z-dropdown); min-width: 176px; max-width: 240px;
        background: var(--surface); border: 1px solid var(--border-2); border-radius: 12px;
        box-shadow: var(--shadow); padding: 6px;
    }
    .fav-pop-title { padding: 5px 10px 3px; color: var(--muted); font-size: var(--fs-xs); }
    .fav-pop-item {
        display: block; width: 100%; text-align: left; border: none; background: transparent; cursor: pointer;
        font-family: var(--font); font-size: var(--fs-sm); color: var(--text); padding: 7px 10px; border-radius: 8px;
        overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    }
    .fav-pop-item:hover, .fav-pop-item:focus-visible { background: var(--accent-weak); color: var(--accent-ink); outline: none; }
    .fav-pop-check { color: var(--accent); margin-right: 6px; }
    .fav-pop-new { margin-top: 4px; padding-top: 6px; border-top: 1px solid var(--border); }
    .fav-pop-new-input {
        width: 100%; box-sizing: border-box; border: 1px solid var(--border-2); border-radius: 8px; padding: 6px 10px;
        font-family: var(--font); font-size: var(--fs-sm); background: var(--surface); color: var(--text);
    }
    .fav-pop-new-input:focus-visible { outline: 2px solid var(--accent-line); outline-offset: 1px; }
    /* 复用条范围下拉：与按钮同排；范围名只用于展示，不进 POST 体 */
    .reuse-bar-acts { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }
    .reuse-scope {
        max-width: 168px; border: 1px solid var(--border-2); border-radius: 8px; padding: 6px 9px;
        font-family: var(--font); font-size: var(--fs-sm); background: var(--surface); color: var(--text); cursor: pointer;
    }
    .reuse-scope:focus-visible { outline: 2px solid var(--accent-line); outline-offset: 1px; }
    .rp-scope { margin: 0 0 13px; color: var(--muted); font-size: var(--fs-xs); line-height: 1.6; }

    @media (prefers-reduced-motion: reduce) {
        .api-config-chevron svg { transition: none; }
        .api-config-body { animation: none; }
        .tour-visual { animation: none; }
        /* 位移类过渡一并中和——侧栏滑入/抽屉/遮罩/toast/主体留白即刻到位，不做滑动 */
        body { transition: none; }
        .sidebar, .drawer { transition: none; }
        .overlay, .toast { transition: none; }
    }

    /* forced-colors：数据集详情页子标签激活态与卡上「并排对比」交系统色，保可读可点 */
    @media (forced-colors: active) {
        .ds-tab[aria-selected="true"] { background: Highlight; color: HighlightText; border-color: Highlight; }
        .ds-tab:focus-visible, .ds-compare-go-card:focus-visible { outline: 2px solid ButtonText; }
    }

    /* ---------------- 数据集详情页（「查看介绍」独立浏览器标签页 /dataset）----------------
       独立页面 dataset.html，无侧栏；居中列 + 页头（标题/徽章/来源·日期/主操作/收藏）+ 子标签页导航（下划线式）
       + 面板区。介绍/兼容/FAIR/引文正文样式复用既有 .intro-*/.compat-*/.fair-*/.das-* 内容样式。 */
    /* 详情页无侧栏留白由上方 `body:not(.dataset-page-body)` 的排除法保证（不在此反向归零，见那条注释）。此处只设背景。 */
    body.dataset-page-body { background: var(--bg); }
    .ds-page { max-width: 1000px; margin: 0 auto; padding: 18px 24px 64px; }
    .ds-topbar { margin-bottom: 16px; }
    .ds-back { display: inline-flex; align-items: center; gap: 8px; color: var(--muted); text-decoration: none;
        font-weight: 600; font-size: 13px; padding: 6px 10px 6px 4px; border-radius: 10px; transition: color .15s, background .15s; }
    .ds-back:hover { color: var(--accent-ink); background: var(--accent-weak); }
    .ds-back svg { width: 18px; height: 18px; flex: none; }
    .ds-back .wordmark { font-size: 15px; }

    .ds-head { padding-bottom: 18px; border-bottom: 1px solid var(--border); }
    .ds-head-row { display: flex; align-items: flex-start; gap: 14px; }
    .ds-title { flex: 1; min-width: 0; font-size: 23px; font-weight: 700; line-height: 1.3; letter-spacing: -0.2px; }
    /* 收藏心形复用 .fav（class="fav ds-fav"）取其配色/描边/active 填充，本处只把绝对定位改为页头内联按钮样式 */
    /* position:relative（不是 static）：收藏动效的光环是 .fav::after 的绝对定位子元素，
       static 会让它逃到最近的定位祖先上去、环出现在页面别处。 */
    .ds-fav { position: relative; flex: none; width: 38px; height: 38px; border: 1px solid var(--border-2);
        background: var(--surface); border-radius: 11px; }
    .ds-fav svg { width: 20px; height: 20px; }
    .ds-fav:hover { border-color: var(--accent-line); }
    .ds-badges { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 13px; }
    .ds-badges .ds-meta { color: var(--muted); font-size: 12.5px; }
    .ds-badges .ds-meta .dot { margin: 0 5px; color: var(--border-2); }
    .ds-sub { margin-top: 10px; color: var(--text-2); font-size: 13px; line-height: 1.75; }
    .ds-sub .dot { margin: 0 6px; color: var(--border-2); }
    .ds-actions { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 16px; }
    .ds-actions .cta { border-radius: 11px; padding: 10px 18px; }

    /* 一键同步（§7，2026-08-22）：页头下方的同步条——三态（空闲/进行中/结果摘要）
       全由 sync_button.js 渲染进 #dsSync。视觉沿用详情页既有 token 与 .cta 组件语言。 */
    .ds-sync { margin-top: 14px; padding: 13px 15px; background: var(--surface);
        border: 1px solid var(--border); border-radius: var(--radius-md); }
    .ds-sync-row { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 14px; }
    .ds-sync-row .cta { border-radius: 11px; padding: 9px 17px; }
    .ds-sync-row .cta[disabled] { opacity: .55; cursor: default; pointer-events: none; }
    .ds-sync-sub { color: var(--muted); font-size: 12.5px; line-height: 1.5; }
    .ds-sync-status { margin-top: 9px; color: var(--text-2); font-size: 13px; line-height: 1.6; }
    .ds-sync-status.ds-sync-busy { color: var(--warn); }
    .ds-sync-status.ds-sync-error { color: var(--no); }
    .ds-sync-status.ds-sync-ok { color: var(--ok); }
    .ds-sync-detail { margin-top: 5px; color: var(--muted); font-size: 12px; line-height: 1.6; }
    .ds-sync-result { margin-top: 11px; padding-top: 11px; border-top: 1px dashed var(--border-2); }
    .ds-sync-summary { color: var(--text); font-size: 13.5px; font-weight: 700; }
    .ds-sync-fails { margin: 8px 0 0; padding: 0; list-style: none; display: grid; gap: 5px; }
    .ds-sync-fails li { color: var(--no); font-size: 12.5px; line-height: 1.55; }
    .ds-sync-fails li b { font-weight: 600; }
    .ds-sync-more { margin-top: 5px; color: var(--muted); font-size: 12px; }
    .ds-sync-acts { display: flex; flex-wrap: wrap; gap: 9px; margin-top: 11px; }
    .ds-sync-acts .btn { border-radius: 10px; padding: 8px 14px; font-size: 13px; }
    .ds-sync-acts .btn[disabled] { opacity: .55; cursor: default; pointer-events: none; }

    .ds-tabs { display: flex; align-items: stretch; gap: 2px; margin-top: 22px; border-bottom: 1px solid var(--border);
        overflow-x: auto; scrollbar-width: thin; }
    .ds-tab { flex: none; border: 0; background: transparent; color: var(--text-2); cursor: pointer;
        font-family: var(--font); font-size: 13.5px; font-weight: 600; padding: 11px 14px; white-space: nowrap;
        border-bottom: 2px solid transparent; margin-bottom: -1px; transition: color .15s ease, border-color .15s ease; }
    .ds-tab:hover { color: var(--accent-ink); }
    .ds-tab[aria-selected="true"] { color: var(--accent-ink); border-bottom-color: var(--accent); }
    .ds-tab:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; border-radius: 6px; }

    .ds-panels { padding-top: 22px; }
    .ds-panel[hidden] { display: none; }
    .ds-llm-cta { margin-top: 18px; }
    .ds-llm-btn { border-style: dashed; }

    /* 数据集对比 = 启动器：挑一条 → 全屏并排。
       2026-07-29 点5：候选从 `<select>` 下拉改成**铺开的检索结果卡**（复用 .grid + buildCard，
       与检索页逐像素同构），每张卡底部一条全宽的「并排对比」——与「查看全部 N 个文件」同一档位，
       不去挤 .card-cta 那两颗。旧的 .ds-compare-pick / -select / -go 三条已随下拉一起删除。 */
    .ds-compare-n { margin: 14px 0 10px; color: var(--muted); font-size: 12.5px; font-weight: 600; }
    .ds-compare-grid { grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); }
    .ds-compare-go-card {
        width: 100%; margin-top: 9px; display: inline-flex; align-items: center; gap: 8px;
        font-family: var(--font); font-size: 12.5px; font-weight: 700; color: var(--surface);
        background: var(--accent); border: 1px solid var(--accent); border-radius: 9px; padding: 8px 11px; cursor: pointer;
        transition: background .15s ease;
    }
    .ds-compare-go-card:hover { background: var(--accent-ink); border-color: var(--accent-ink); }
    .ds-compare-go-card:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
    .ds-compare-go-card .dcg-arrow { margin-left: auto; opacity: .8; }

    /* 全屏并排对比浮层：两侧各一个完整 /dataset iframe（embed 态），可关掉一侧保留另一侧（撑满） */
    body.ds-split-open { overflow: hidden; }
    .ds-embedded .ds-topbar { display: none; }   /* 分屏 iframe 内隐藏自己的返回主页链接（冗余） */
    .ds-split { position: fixed; inset: 0; z-index: 120; display: flex; flex-direction: column; background: var(--bg); }
    .ds-split-top { display: flex; align-items: center; gap: 12px; flex: none;
        padding: 8px 16px; border-bottom: 1px solid var(--border); background: var(--surface-2); }
    /* 「返回 BioData Agent」在对比态只出现这一次（顶栏），两侧 iframe 各自的 topbar 已隐藏 */
    .ds-split-home { display: inline-flex; align-items: center; gap: 6px; flex: none; color: var(--muted);
        text-decoration: none; font-weight: 600; font-size: 13px; padding: 5px 9px 5px 5px; border-radius: 9px;
        transition: color .15s, background .15s; }
    .ds-split-home:hover { color: var(--accent-ink); background: var(--accent-weak); }
    .ds-split-home:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
    .ds-split-home svg { width: 17px; height: 17px; flex: none; }
    .ds-split-title { font-weight: 700; font-size: 14px; color: var(--text); }
    .ds-split-exit { margin-left: auto; border: 1px solid var(--border-2); background: var(--surface); color: var(--text-2);
        font-family: var(--font); font-size: 13px; font-weight: 600; padding: 6px 12px; border-radius: 9px; cursor: pointer;
        transition: color .15s, background .15s, border-color .15s; }
    .ds-split-exit:hover { color: var(--accent-ink); background: var(--accent-weak); border-color: var(--accent); }
    .ds-split-exit:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
    .ds-split-panes { flex: 1; display: flex; min-height: 0; }
    .ds-split-pane { flex: 1 1 50%; min-width: 0; display: flex; flex-direction: column; border-right: 1px solid var(--border); }
    .ds-split-pane:last-child { border-right: 0; }
    .ds-split-bar { display: flex; align-items: center; gap: 10px; flex: none; padding: 8px 14px;
        border-bottom: 1px solid var(--border); background: var(--surface); }
    .ds-split-role { flex: none; font-size: 11px; font-weight: 700; letter-spacing: .3px; color: var(--accent-ink);
        background: var(--accent-weak); padding: 3px 9px; border-radius: 999px; }
    .ds-split-name { flex: 1; min-width: 0; font-weight: 700; font-size: 13px; color: var(--text);
        overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
    .ds-split-x { flex: none; border: 1px solid var(--border-2); background: var(--surface); color: var(--text-2);
        width: 28px; height: 28px; border-radius: 8px; cursor: pointer; font-size: 12px; line-height: 1;
        transition: color .15s, background .15s, border-color .15s; }
    .ds-split-x:hover { color: var(--text); background: var(--surface-2); border-color: var(--border); }
    .ds-split-x:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
    .ds-split-frame { flex: 1; width: 100%; border: 0; min-height: 0; background: var(--bg); }

    /* ---------------- Responsive ---------------- */
    @media (max-width: 780px) {
        /* 移动端：侧栏改抽屉浮层，不推挤内容；打开时铺遮罩。
           选择器必须写成 body:not(.dataset-page-body)（特异度 0,1,1）：桌面布局条
           `body:not(.dataset-page-body){padding-left:calc(var(--side-w)+28px)}` 同为 0,1,1，
           若此处只写 body（0,0,1）会战败——实测 500px 下抽屉开着主区仍被右推 328px。
           同特异度靠源码顺序（本规则在后）合法胜出，不用 !important（它只留给 [hidden] 这类
           防未来规则的全局兜底，见文件头注释）。 */
        body:not(.dataset-page-body) { padding-left: 0; }
        /* 侧栏收起（fab 固钉左上）时主区顶部让位——首屏内容（放宽横幅/控制台顶边）
           不再从 fab 底下穿过；滚动阅读中的遮挡由 fab-tucked 淡出（shell.js）接管。 */
        body.side-closed:not(.dataset-page-body) .main { padding-top: 60px; }
        .sidebar { z-index: var(--z-sidebar-mobile); width: min(280px, 82vw); }   /* 卡片各自带阴影，容器透明 */
        /* 移动抽屉（120）高于桌面令牌的 --z-floatwin(90)，会盖住历史浮窗（抽屉内开
           浮窗左半被遮、按钮不可点）。这里局部把浮窗抬回抽屉之上，恢复令牌注释的既定秩序
           「浮窗 > 抽屉 > 主区 > 遮罩」；只在移动端覆盖——桌面保持 90，.ds-split 全屏
           对比层(120)盖浮窗的桌面语义不动；仍远低于 --z-overlay(150)，非模态层级不变。 */
        .hist-win { z-index: calc(var(--z-sidebar-mobile) + 1); }
        .side-card { box-shadow: var(--shadow-lg); }           /* 抽屉里卡片用更强阴影 */
        /* 移动抽屉恒单列：facets-active 只在桌面（innerWidth>780）置位；缩窗过 780px 时 board.js 的
           resize 监听（placeFacetBar(false)）会清掉该类，本覆盖是防御性双保险——与
           body.facets-active .side-nav 同特指度(0,2,1)但更靠后 → 稳压其 grid、强制单列。 */
        body.facets-active .side-nav { display: flex; flex-direction: column; gap: 2px; }
        .side-backdrop { display: block; }
        body:not(.side-closed) .side-backdrop { opacity: 1; pointer-events: auto; }
        .hero h1 { font-size: 24px; }
        /* 移动端：控制台回到全宽堆叠（覆盖桌面 fit-content 自适应宽度）；齿轮仍绝对定位在文本行右上角 */
        .console { width: auto; min-width: 0; max-width: 94vw; flex-direction: column; align-items: stretch; }
        /* 竖排堆叠：底栏由两列 grid 收成单列 → 去掉左下圆角；两 cell 间用横线分隔（纵切割线隐藏） */
        .console-bar { grid-template-columns: 1fr; border-radius: 0; }
        .cbar-div { display: none; }
        .cbar-div + .cbar-cell { border-top: 1px solid var(--bar-line); }
        /* 窄屏面板改锚 .cbar-cell（近控制台左缘）而非被 label 右推的 pill：配合 width:min(320px,86vw)，右缘不再越出视口 */
        .sf-select { position: static; }
        .console #submitBtn { min-height: 48px; flex-direction: row; border-radius: 0 0 calc(var(--radius-lg) - 1px) calc(var(--radius-lg) - 1px); }
        .console #submitBtn .sb-label { flex-direction: row; gap: 8px; }
        .side-resizer { display: none; }
        /* 窄屏同样默认居中；保留安全边距和较大的可读高度。 */
        .onboarding, .onboarding.onboarding-settings {
            left: 12px; right: 12px; top: 50%; bottom: auto; width: auto; transform: translateY(-50%);
        }
        .onboarding-surface { max-height: min(78dvh, 620px); }
        .tour-ranking { gap: 5px; }
        .tour-rank-stage { padding-inline: 5px; }
        .tour-rank-stage small { font-size: var(--fs-micro); }
        .tour-polish { grid-template-columns: 1fr; }
        .tour-polish-arrow { transform: rotate(90deg); justify-self: center; }
        .tour-refine { grid-template-columns: .85fr 1.15fr; }
        .api-config summary { grid-template-columns: minmax(0, 1fr) 26px; }
        .api-config-status { display: none; }
        .intro-facts dl { grid-template-columns: 1fr; }
        .timeline-head { flex-direction: column; }
        .timeline-range { justify-content: flex-start; }
        .memory-suggestion { min-width: 180px; }
        /* 窄屏动作组不再纵排全宽，改横向折行、按钮均分（概览卡内视觉随「结果区头部重设计」段） */
        .results-head-acts { flex-wrap: wrap; width: auto; }
        .results-head-acts .btn { flex: 1 1 auto; justify-content: center; }
        .ds-tabs { flex-wrap: nowrap; overflow-x: auto; }   /* 窄屏子标签横向滚动、不折行 */
        .ds-actions { flex-direction: column; align-items: stretch; }
        .ds-split-panes { flex-direction: column; }   /* 窄屏并排对比改上下堆叠 */
        .ds-split-pane { flex-basis: auto; border-right: 0; border-bottom: 1px solid var(--border); }
        .memory-item { align-items: flex-start; flex-direction: column; }
    }

    /* ---------------- Print----------------
       复用清单 / FAIR 面板等投稿材料可打印：藏导航与交互件、去背景阴影、主体占满页宽。 */
    @media print {
        .sidebar, .side-fab, .side-backdrop, .drawer, .overlay, .toast, .onboarding, .onboarding-focus-ring { display: none !important; }
        body { padding-left: 0; }
        body.modal-lock { overflow: visible; }
        .modal-backdrop[hidden] { display: none !important; }
        .card, .das-box, .fair-box, .reuse-panel, .set-block { box-shadow: none; }
        /* 数据集详情页：藏顶栏与子标签导航（交互件），当前面板正文（FAIR/DAS 等投稿材料）直接打印 */
        .ds-topbar, .ds-tabs { display: none !important; }
    }

/* ============================================================================
   条件板：出结果后列在搜索框下面的「系统实际在用的筛选条件」
   ----------------------------------------------------------------------------
   体量受控是硬要求：它在文档流上位于结果区之前，展开态过高会把结果整屏推下去。
   默认只有一行摘要，展开态限高 + 内部滚动。
   注意上方结果态隐藏 hero 内容的那组规则是逐个选择器写的，不匹配 .cond-board；
   若日后改成 .hero > * 一把隐藏，这块会跟着一起消失。
   ========================================================================== */
.cond-board {
    width: 100%;
    max-width: 880px;
    margin: 14px auto 0;
    border: 1px solid var(--border);
    border-radius: 14px;
    background: var(--surface);
    text-align: left;
    overflow: hidden;
}
.cb-summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    width: 100%;
    padding: 10px 14px;
    border: 0;
    background: none;
    color: inherit;
    font: inherit;
    font-size: 13.5px;
    cursor: pointer;
    text-align: left;
}
.cb-summary:focus-visible { outline: 1px solid var(--accent); outline-offset: -2px; }
.cb-caret {
    width: 8px; height: 8px; flex: none;
    border-right: 1.5px solid currentColor;
    border-bottom: 1.5px solid currentColor;
    transform: rotate(45deg);
    opacity: .55;
}
.cond-board.collapsed .cb-caret { transform: rotate(-135deg); }
.cb-body {
    /* 硬上限而不只是 vh：条件板排在结果区**前面**，太高会把首屏的结果整屏推下去。
       实测 720px 高的窗口下，不设这个上限首张结果卡会掉到折线以下。 */
    max-height: min(32vh, 280px);
    overflow-y: auto;
    padding: 4px 14px 12px;
    border-top: 1px solid var(--border);
}
.cb-zone { margin: 10px 0 0; }
.cb-zone-head { font-size: 12.5px; font-weight: 600; opacity: .75; margin-bottom: 5px; }
.cb-row {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px;
    padding: 5px 0;
}
.cb-name { font-size: 13px; opacity: .72; min-width: 3.6em; }
.cb-vals { font-size: 13.5px; font-weight: 600; }
.cb-acts { margin-left: auto; display: flex; gap: 6px; flex-wrap: wrap; }
.cb-act {
    border: 1px solid var(--border);
    background: none;
    color: inherit;
    border-radius: 999px;
    padding: 2px 10px;
    font: inherit;
    font-size: 12px;
    cursor: pointer;
    opacity: .85;
}
.cb-act:hover { opacity: 1; border-color: var(--accent); }
.cb-act:focus-visible { outline: 1px solid var(--accent); outline-offset: 2px; }
.cb-note, .cb-hint, .cb-step-hint, .cb-msg-detail { font-size: 12px; opacity: .62; margin: 4px 0 0; line-height: 1.55; }
.cb-empty { font-size: 13px; opacity: .7; margin: 8px 0; }
.cb-preview {
    margin: 12px 0 0;
    padding: 10px 12px;
    border: 1px solid var(--border);
    border-radius: 10px;
}
.cb-msg { font-size: 13.5px; margin: 0; line-height: 1.6; }
/* .cb-final / .cb-final-label（needs_confirm 可编辑预览的样式）已随「发送后不再有确认界面」删除。 */
.cb-choices { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
/* 侧栏窄宽度下的三选一按钮——纵向堆叠、整行宽、文字可折行（不再横向裁字）。 */
#sideBoardScroll .cb-choices { flex-direction: column; }
#sideBoardScroll .cb-choices .cb-choice { width: 100%; white-space: normal; text-align: left; line-height: 1.45; }
.cb-about { margin-top: 10px; }
.cb-about summary { font-size: 12px; opacity: .62; cursor: pointer; }
.cb-about p { font-size: 12px; opacity: .62; margin: 6px 0 0; line-height: 1.6; }

@media (max-width: 780px) {
    .cond-board { margin-top: 10px; }
    .cb-body { max-height: 46vh; padding: 4px 10px 12px; }
    .cb-row { align-items: flex-start; }
    .cb-acts { margin-left: 0; width: 100%; }
}

/* 导览插图：条件板那一步 */
.tour-board { display: flex; flex-direction: column; gap: 8px; }
.tour-board-summary {
    display: flex; justify-content: space-between; gap: 10px;
    font-size: 12.5px; opacity: .8;
    padding: 7px 10px; border: 1px solid var(--border); border-radius: 9px;
}
.tour-board-row {
    display: flex; align-items: center; gap: 8px;
    font-size: 12.5px;
    padding: 6px 10px; border: 1px solid var(--border); border-radius: 9px;
}
.tour-board-row small { opacity: .6; min-width: 3em; }
.tour-board-row strong { font-weight: 600; }
.tour-board-row span {
    margin-left: auto; border: 1px solid var(--border); border-radius: 999px;
    padding: 1px 8px; font-size: 11.5px; opacity: .8;
}
.tour-board-row span + span { margin-left: 0; }
.tour-board-say {
    font-size: 12.5px; opacity: .75;
    padding: 7px 10px; border: 1px dashed var(--border); border-radius: 9px;
}

/* ============================================================================
   一句话任务包面板：坏消息在最前，勾选清单在中间，产包按钮在最后
   ========================================================================== */
.task-pack-panel {
    margin: 12px 0;
    padding: 14px 16px;
    border: 1px solid var(--border);
    border-radius: 14px;
    background: var(--surface);
}
.tp-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 8px; }
.tp-head strong { font-size: 14.5px; }
.tp-loading, .tp-msg { font-size: 13px; margin: 6px 0; }
.tp-msg-detail { font-size: 12px; opacity: .62; margin: 2px 0 0; }
.tp-cannot {
    margin: 8px 0;
    padding: 9px 12px;
    border: 1px solid var(--border);
    border-radius: 10px;
}
.tp-cannot strong { font-size: 13px; }
.tp-cannot ul { margin: 6px 0 0; padding-left: 18px; }
.tp-cannot li { font-size: 12.5px; line-height: 1.6; opacity: .82; }
.tp-primary { font-size: 13px; line-height: 1.65; margin: 8px 0; }
.tp-tiers { display: flex; flex-wrap: wrap; gap: 6px; margin: 8px 0; }
.tp-tier-chip {
    font-size: 12px;
    padding: 3px 10px;
    border: 1px solid var(--border);
    border-radius: 999px;
    opacity: .85;
}
.tp-rows { margin: 10px 0; max-height: 34vh; overflow-y: auto; }
.tp-row {
    display: flex;
    align-items: baseline;
    gap: 8px;
    padding: 5px 0;
    font-size: 13px;
    cursor: pointer;
    border-bottom: 1px solid var(--border);
}
.tp-row:last-child { border-bottom: 0; }
.tp-row-name { font-weight: 600; }
.tp-row-meta { margin-left: auto; font-size: 11.5px; opacity: .6; text-align: right; word-break: keep-all; }   /* keep-all：CJK 短语不在「本/次」中间断词，只从标点处折行 */
.tp-todo { margin: 8px 0; }
.tp-todo summary { font-size: 12.5px; opacity: .7; cursor: pointer; }
.tp-todo ul { margin: 6px 0 0; padding-left: 18px; }
.tp-todo li { font-size: 12px; line-height: 1.65; opacity: .78; margin-bottom: 4px; }
.tp-actions { display: flex; gap: 8px; margin-top: 10px; }
.tp-build-btn { font-size: 13px; }
.tp-foot { font-size: 11.5px; opacity: .55; margin: 8px 0 0; line-height: 1.6; }
/* 2026-08-30 统一下载队列：一切浏览器下载（数据文件/引文/任务包/
   导出/反馈包）同进 downloads.js 的队列面板。行 = kind 章 + 文件名 + 尺寸 + 状态 + 行内动作
   （取消/重下）；「已交给浏览器」的进度与取消在浏览器下载管理（Ctrl+J），面板脚注如实标注。 */
.dlq { margin-top: 10px; border-top: 1px dashed var(--border); padding-top: 8px; }
.dlq-head { display: flex; align-items: center; gap: 8px; margin-bottom: 4px; }
.dlq-head strong { font-size: 13px; }
.dlq-count {
    font-size: 11px; padding: 1px 8px;
    border: 1px solid var(--border); border-radius: 999px; opacity: .7;
}
.dlq-head-acts { margin-left: auto; display: flex; gap: 6px; }
.dlq-btn { font-size: 12px; padding: 4px 10px; }
.dlq-list { margin: 4px 0; padding: 0; list-style: none; max-height: 30vh; overflow-y: auto; }
.dlq-row {
    display: flex; align-items: baseline; gap: 8px;
    padding: 4px 0; font-size: 12.5px;
    border-bottom: 1px solid var(--border);
}
.dlq-row:last-child { border-bottom: 0; }
.dlq-kind {
    flex: none; font-size: 11px; padding: 1px 8px;
    border: 1px solid var(--border); border-radius: 999px; opacity: .8;
}
.dlq-name { font-weight: 600; word-break: break-all; }
.dlq-size { flex: none; font-size: 11.5px; opacity: .6; }
.dlq-status { margin-left: auto; flex: none; font-size: 11.5px; opacity: .7; text-align: right; }
.dlq-x {
    flex: none; font-size: 11.5px; padding: 2px 8px; cursor: pointer;
    border: 1px solid var(--border); border-radius: 999px;
    background: transparent; color: inherit;
}
.dlq-x:hover { border-color: var(--accent, #16a34a); }
.dlq-fired .dlq-status { color: var(--accent, #16a34a); opacity: .9; }
.dlq-error .dlq-status, .dlq-unsupported .dlq-status { color: #b45309; opacity: .95; }
.dlq-cancelled .dlq-name, .dlq-cancelled .dlq-status { opacity: .45; }
.dlq-foot { font-size: 11.5px; opacity: .55; margin: 6px 0 0; line-height: 1.6; }
.dlq-uns { font-size: 12.5px; line-height: 1.65; margin: 8px 0 2px; }
.dlq-uns-why { margin: 2px 0 0; }
.dlq-uns-why summary { font-size: 12px; opacity: .7; cursor: pointer; }
.dlq-uns-why ul { margin: 6px 0 0; padding-left: 18px; }
.dlq-uns-why li { font-size: 12px; line-height: 1.65; opacity: .78; }
.dlq-acts { display: flex; gap: 8px; margin-top: 8px; }
.results-head-acts { flex-wrap: wrap; }

@media (max-width: 780px) {
    .task-pack-panel { padding: 12px; }
    .tp-row { flex-wrap: wrap; }
    .tp-row-meta { margin-left: 0; width: 100%; text-align: left; }
    .dlq-row { flex-wrap: wrap; }
    .dlq-status { margin-left: 0; width: 100%; text-align: left; }
}

/* ============================================================================
   2026-08-03（用户图2 指令）执行形态：行动流（arx-*）+ 主区对话模式（chat-main）。
   结果区回执卡（.act-receipt/.act-card/.act-row 等）退役，
   只留 .act-fix/.act-chip（纠错 chips 现在长在对话流的总结泡里）。
   2026-08-03：问卷决策弹窗（sv-*）随执行侧全自动化退役。
   ========================================================================== */

/* —— 主区对话模式（chat-in-main）：无检索结果而有对话时，对话记录住 hero 内的 #chatMain —— */
.view[data-view="query"].chat-main-on { justify-content: flex-start; }
.view[data-view="query"].chat-main-on .hero { display: flex; flex-direction: column; flex: 1; min-height: 0; padding: 4px 0 0; text-align: left; }
.view[data-view="query"].chat-main-on .hero .hero-rot,
.view[data-view="query"].chat-main-on .hero .chips,
.view[data-view="query"].chat-main-on .hero .memory-suggestions { display: none; }
.chat-main { width: 100%; max-width: 760px; margin: 0 auto; }
.chat-main-on .chat-main { display: flex; flex-direction: column; flex: 1; min-height: 0; order: 1; }
.chat-main-on .hero .console { order: 2; width: 100%; max-width: 760px; margin: 10px auto 0; }   /* 移动端/侧栏收起 chat-main-on：hero 大框仍是唯一输入（composer 不搬） */
/* （2026-08-18 输入栏统一）：桌面对话态主区输入换成统一圆角长条 #chatComposer（由 placeChatLog
   从侧栏 #sideWork 搬进 hero），hero 大框让位；守卫与 JS composerInHero 同源（桌面 + 侧栏未收起）。 */
@media (min-width: 781px) {
    body:not(.side-closed) .chat-main-on .hero .console { display: none; }
    body:not(.side-closed) .chat-main-on .hero .cb-composer {
        order: 3; width: 100%; max-width: 760px; margin: 10px auto 0; padding: 0; border-top: 0;
    }
}
.chat-main-on .chat-main #cbHistory.cbh-main { max-height: none; flex: 1; min-height: 0; margin-top: 0; padding: 14px 4px; }
/* 主区底色（--bg #f5f7fa）上 --surface-2 灰泡对比度过低、几乎隐形——主区对话的系统侧泡泡
   一律白底 + 细边（与 console 卡同一视觉语言）；侧栏白卡上的灰泡保持不变。 */
.chat-main .cbh-sys-bubble, .chat-main .cbh-view { background: var(--surface); border: 1px solid var(--border-2); }
.chat-main .cbh-view:hover { background: var(--surface-2); }
/* 错误回音在主区也保住琥珀区分（上一条白底规则的比特例）：特异度三层 > 两层，不依赖源码顺序。 */
.chat-main .cbh-sys-bubble.cbh-err-bubble { background: var(--warn-weak); border: 1px solid var(--warn-line); border-left: 3px solid var(--warn-line-strong); color: var(--warn); }

/* —— 行动流（arx-*）：对话流尾部的执行播报块（完成时整块折叠撤下，总结泡留在原地） —— */
.arx-run { width: 100%; max-width: 560px; border: 1px solid var(--border); border-radius: var(--radius);
    background: var(--surface); padding: 10px 12px; overflow: hidden; max-height: 480px;
    transition: max-height var(--dur-slow) var(--ease-spring), opacity var(--dur-med), padding var(--dur-slow) var(--ease-spring); }
.arx-run.arx-collapsing { max-height: 0; opacity: 0; padding-top: 0; padding-bottom: 0; border-width: 0; }
.arx-head { display: flex; align-items: center; gap: 6px; font-size: 11.5px; font-weight: 600; color: var(--muted); letter-spacing: .2px; }
.arx-head-ico { color: var(--accent); }
/* 行动流头部秒表 / 收尾弱信息行（· 用时 Ns · N 步）——灰小字，不抢步骤行。 */
.arx-elapsed { margin-left: 2px; font-size: 11px; font-weight: 500; color: var(--muted); opacity: .8; font-variant-numeric: tabular-nums; }
.arx-elapsed-done { opacity: .65; }
.arx-steps { display: flex; flex-direction: column; gap: 6px; margin-top: 8px; }
.arx-step { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px; font-size: 12px; color: var(--text-2); }
.arx-step.arx-last.arx-running, .arx-step.arx-decision { color: var(--text); }
.arx-ico { flex: 0 0 14px; text-align: center; font-size: 11px; }
.arx-ico-done { color: var(--accent); }
.arx-ico-fail { color: var(--no); font-weight: 700; }
.arx-ico-decide { color: var(--accent); }
.arx-ico-run { display: inline-flex; gap: 2.5px; align-items: center; justify-content: center; }
.arx-ico-run i { width: 3.5px; height: 3.5px; border-radius: 50%; background: var(--accent); animation: cbhDot 1.1s ease-in-out infinite; }
.arx-ico-run i + i { animation-delay: .18s; }
.arx-ico-run i + i + i { animation-delay: .36s; }
.arx-detail { flex-basis: 100%; margin-left: 22px; font-size: 11.5px; color: var(--muted); }

/* ---------- 信息流 · 过程轨迹 .ft-*：无框、小字、灰阶、低存在感 ----------
   层级铁律：轨迹=过程（弱视觉）/ 气泡=回执（强视觉）/ 结果 pill=产物（完整展示）。
   轨迹块借 .cbh-turn.cbh-sys 的轮距与左对齐，自身零外框零底色；字号/配色全部走既有阶梯
   （11.5px --fs-xs + --muted，与 .cbh-view-link 同族），不造新色。 */
.ft-trace { padding-left: 2px; max-width: 92%; }
.chat-main .ft-trace { max-width: 560px; }   /* 主区对话态与 .cbh-sys-extra 同宽上限 */
.ft-stages, .ft-expand { display: flex; flex-direction: column; gap: 3px; }
.ft-stage { display: flex; align-items: baseline; gap: 6px;
    font-size: var(--fs-xs); line-height: 1.5; color: var(--muted); }
.ft-mark { flex: 0 0 12px; display: inline-flex; align-items: center; justify-content: center;
    font-size: 10px; line-height: 1; color: var(--muted-soft); transform: translateY(-.5px); }
.ft-done .ft-mark { color: var(--accent); opacity: .75; }   /* ✓：accent 弱化成装饰级，不抢气泡 */
.ft-failed .ft-mark { color: var(--warn); opacity: 1; font-weight: 600; }   /* ✗：克制的警示色（琥珀族，非致命红） */
.ft-failed .ft-text { color: var(--text-2); }
.ft-text { min-width: 0; overflow-wrap: anywhere; }
/* 运行中阶段：文字略提亮（当前正在做的事）+ 微脉冲点（替代静态「…」，与 .arx-ico-run 同族节奏） */
.ft-run .ft-text { color: var(--text-2); }
.ft-run .ft-mark { font-size: 0; }   /* 隐藏「…」字符，由 ::after 脉冲点取代（结构零改动） */
.ft-run .ft-mark::after { content: ""; width: 5px; height: 5px; border-radius: 50%;
    background: var(--accent); animation: ftPulse 1.2s ease-in-out infinite; }
@keyframes ftPulse { 0%, 100% { opacity: .35; transform: scale(.8); } 50% { opacity: 1; transform: scale(1); } }

/* 终态压缩摘要：一行可展开的灰字（与 .cbh-view-link 同一副「低调文本链接」语言——
   muted 小字、hover 才出 accent 与下划线；▸ 自制标记，展开时转 90°）。 */
.ft-summary { font-size: var(--fs-xs); line-height: 1.5; color: var(--muted); }
.ft-summary > summary { display: inline-flex; align-items: baseline; gap: 5px; cursor: pointer;
    list-style: none; font-weight: 500; transition: color .15s; }
.ft-summary > summary::-webkit-details-marker { display: none; }
.ft-summary > summary::before { content: "▸"; font-size: 9px; color: var(--muted);
    transition: transform var(--dur-fast) var(--ease-spring); transform-origin: center; }
.ft-summary[open] > summary::before { transform: rotate(90deg); }
.ft-summary > summary:hover { color: var(--accent-ink); text-decoration: underline; text-underline-offset: 3px; }
.ft-summary > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; border-radius: 4px; }
.ft-expand { margin-top: 5px; padding-left: 15px; }   /* 回看全量阶段：相对摘要行微缩进，表达「属于这条摘要」 */

/* 展开/收起过渡（2026-08-23 起 Edge/Chrome 131+ 原生支持 details 内容动画；
   不支持的浏览器回退为瞬时开合，功能不变）。 */
@supports (interpolate-size: allow-keywords) {
    .ft-summary { interpolate-size: allow-keywords; }
    .ft-summary::details-content { height: 0; opacity: 0; overflow: clip;
        transition: height var(--dur-med) var(--ease-spring), opacity var(--dur-med) var(--ease-spring),
            content-visibility var(--dur-med) allow-discrete; }
    .ft-summary[open]::details-content { height: auto; opacity: 1; }
}

/* 压缩落帧过渡（board.js ft-compressed 两帧余量计数，只播一轮）：过程小字已在同一帧内移除
   （DOM 快照重画，无法对已移除节点播退场），摘要**原地**淡入微升——位置不跳变、视线焦点不移动。 */
.ft-trace.ft-compressed .ft-summary { animation: ftSumIn var(--dur-med) var(--ease-spring); }
@keyframes ftSumIn { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }

/* 回执三段的上下两件——压缩摘要块（气泡上方）与结果 pill 组（气泡内部/文字下方）。
   .ft-pill 是 .batch-pill 的小号同族（同胶囊语言、同 accent 激活态），字号降档适配对话流；
   一个 query 一个 pill，点击在结果区切换到对应批（数据批 id 在 data-ft-pill）。 */
.cbh-turn > .ft-trace { margin: 0 0 4px; }
.ft-pills { display: flex; flex-wrap: wrap; gap: 6px; margin: 6px 0 0 2px; max-width: 92%; }
.chat-main .ft-pills { max-width: 560px; }
/* 结果 pill 挪进回执气泡内部（文字下方）——容器改走 span、贴合气泡内边距。
   只针对**在气泡内**的 pill 组收紧上边距、放宽到满宽（气泡自身 85% max-width 已限宽），
   以免外挂式 92%/边距 在气泡 padding 内二次挤压。胶囊底色与激活态沿用 .ft-pill 既定样式。 */
.cbh-sys-bubble .ft-pills { margin: 7px 0 0; max-width: 100%; }
/* 2026-08-24：max-width 改 min(240px, 100%)——气泡窄于 240px 时 pill 跟随收窄
   （关键词段 .ft-pill-q 省略号截断），不再硬顶 240px 溢出气泡右缘；宽气泡下 240px 上限不变。
   min-width:0 允许 flex 收缩生效（默认 auto 会以 min-content 兜底，长关键词不换行时撑爆容器）。 */
.ft-pill { display: inline-flex; align-items: baseline; gap: 6px; min-width: 0; max-width: min(240px, 100%);
    padding: 3px 10px; border-radius: 999px; cursor: pointer;
    background: var(--surface); border: 1px solid var(--border-2); color: var(--text-2);
    font-size: var(--fs-xs); font-family: inherit; line-height: 1.4;
    transition: color .15s, background .15s, border-color .15s, box-shadow .2s; }
.ft-pill:hover { color: var(--text); border-color: var(--accent-line); }
.ft-pill:active { transform: scale(.97); }
.ft-pill.is-on { background: var(--accent-weak); color: var(--accent-ink);
    border-color: var(--accent-line); font-weight: 600; }
.ft-pill:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.ft-pill-q { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ft-pill-n { flex: none; font-size: var(--fs-micro); color: var(--muted); }
.ft-pill.is-on .ft-pill-n { color: var(--accent-ink); opacity: .8; }
/* 零命中 pill 与常规 pill 视觉明确区分——琥珀色调 + 虚线描边（常规是 accent 实线胶囊）。
   「点击处理」徽标只在该批是最新结果（最近一个回执 entry 的活跃批）时出现；不再最新时
   该 pill 无徽标、点击也无任何反应（连换批也不响应——救回链已退役）。 */
.ft-pill--zero { border-style: dashed; border-color: var(--warn-line);
    background: var(--warn-weak); color: var(--warn); }
.ft-pill--zero:hover { border-color: var(--warn-line-strong); color: var(--warn); background: var(--warn-row-hover); }
.ft-pill--zero.is-on { border-style: dashed; border-color: var(--warn-line-strong);
    background: var(--warn-weak); color: var(--warn); font-weight: 600; }
.ft-pill--zero.is-on:hover { background: var(--warn-row-hover); }
.ft-pill--zero .ft-pill-n { color: var(--warn); opacity: .85; }
.ft-pill--zero .ft-pill-act { flex: none; margin-left: 2px; padding: 1px 7px; border-radius: 999px;
    background: transparent; border: 1px solid var(--warn-line-strong); color: var(--warn);
    font-size: 10px; font-weight: 600; letter-spacing: .2px; white-space: nowrap; }
/* 2026-08-30：下载批 pill（.ft-pill--dlq）——动作型 pill（点击开下载面板，不换批、
   无 is-on 状态语义），与检索结果 pill 同族同位。accent 描边 + 下箭头前缀作常驻区分：
   一眼看出「这颗是下载、点开是面板」，又不与零命中的琥珀警示族混淆。 */
.ft-pill--dlq { border-color: var(--accent-line); color: var(--accent-ink); }
.ft-pill--dlq:hover { background: var(--accent-weak); border-color: var(--accent); color: var(--accent-ink); }
.ft-pill--dlq .ft-pill-q::before { content: "↓ "; }
.ft-pill--dlq .ft-pill-n { color: var(--accent-ink); opacity: .75; }

@media (prefers-reduced-motion: reduce) {
    .ft-run .ft-mark::after { animation: none; opacity: 1; transform: none; }
    .ft-trace.ft-compressed .ft-summary { animation: none; }
    .ft-summary > summary::before { transition: none; }
    .ft-summary::details-content { transition: none; }
}

/* 零命中救回选择条（贴输入框上沿，board.js 渲染）。琥珀色调与零命中 pill 同族；
   选项一行放不下的只显摘要（.rs-opt-txt ellipsis），完整信息走 title（hover 浮窗）；
   入退场过渡只在 .is-open 翻转时播一轮。常态 display:none（不占对话流）。 */
.rs-strip { margin: 6px 4px 10px; padding: 8px 10px; border: 1px solid var(--warn-line);
    border-radius: var(--radius-md); background: var(--warn-weak);
    box-shadow: 0 1px 3px rgba(0, 0, 0, .06); display: none; flex-direction: column; gap: 8px; }
.rs-strip.is-open { display: flex; animation: rsIn .26s ease-out; }
@keyframes rsIn { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }
.rs-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.rs-title { font-size: var(--fs-sm); font-weight: 600; color: var(--warn); }
.rs-close { display: inline-flex; align-items: center; justify-content: center; width: 22px; height: 22px;
    border: none; border-radius: 6px; background: transparent; color: var(--muted); cursor: pointer; }
.rs-close:hover { background: var(--warn-row-hover); color: var(--warn); }
.rs-opts { display: flex; flex-wrap: wrap; gap: 6px; }
.rs-opt { display: inline-flex; align-items: baseline; gap: 5px; max-width: 240px;
    padding: 4px 9px; border-radius: 999px; cursor: pointer; text-align: left;
    background: var(--surface); border: 1px solid var(--border); color: var(--text-2);
    font-size: var(--fs-xs); font-family: inherit; line-height: 1.4;
    transition: color .15s, background .15s, border-color .15s, transform .12s; }
.rs-opt:hover { color: var(--text); border-color: var(--warn-line-strong); background: var(--surface-2); }
.rs-opt:active { transform: scale(.97); }
.rs-opt.is-selected { border-color: var(--warn); background: var(--warn-row-hover);
    color: var(--warn); font-weight: 600; box-shadow: 0 0 0 2px var(--warn-line); }
.rs-opt:focus-visible { outline: 2px solid var(--warn); outline-offset: 1px; }
.rs-opt-txt { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rs-opt-n { flex: none; font-size: var(--fs-micro); color: var(--muted); }
.rs-opt.is-selected .rs-opt-n { color: var(--warn); }
.rs-foot { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.rs-hint { font-size: var(--fs-xs); color: var(--muted); }
.rs-submit { flex: none; padding: 5px 14px; border-radius: 999px; border: 1px solid var(--warn-line-strong);
    background: var(--warn); color: #fff; font-size: var(--fs-sm); font-weight: 600; cursor: pointer;
    transition: opacity .15s, transform .12s, background .15s; }
.rs-submit:hover { background: var(--warn-line-strong); }
.rs-submit:active { transform: scale(.97); }
.rs-submit:disabled { opacity: .5; cursor: not-allowed; background: var(--warn-line); border-color: var(--warn-line); }
.rs-submit:focus-visible { outline: 2px solid var(--warn); outline-offset: 1px; }
@media (prefers-reduced-motion: reduce) {
    .rs-strip.is-open { animation: none; }
    .rs-opt, .rs-submit { transition: none; }
}

/* 总结泡的附加块（没做到的紧凑行 / 结果卡 / 纠错 chips / 过程 details / AI 总结标） */
.cbh-sys-extra { margin-left: 2px; max-width: 92%; display: flex; flex-direction: column; gap: 6px; }
.chat-main .cbh-sys-extra { max-width: 560px; }
.cbh-ai { display: inline-block; margin-left: 6px; padding: 1px 6px; border-radius: 999px;
    background: var(--accent-weak); color: var(--accent-ink); font-size: 10px; font-weight: 600; vertical-align: 1px; }
.arx-note-line { font-size: 12px; color: var(--text-2); }
.arx-gaps { display: flex; flex-direction: column; gap: 3px; }
.arx-gap { font-size: 12px; color: var(--text-2); }
.arx-gap::before { content: "· "; color: var(--muted); }
.arx-card { border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--surface);
    padding: 9px 11px; display: flex; flex-direction: column; gap: 4px; }
.arx-card-title { font-size: 11.5px; font-weight: 600; color: var(--muted); margin-top: 4px; }
.arx-card-title:first-child { margin-top: 0; }
.arx-card-row { display: flex; justify-content: space-between; gap: 10px; font-size: 12px; }
/* 行内两列都可压可折（2026-08-03 缺陷修复）：旧版 meta 恒 nowrap + flex 默认 min-width:auto
   → meta 不可压缩（min-content=整行宽），把 name（overflow-wrap:anywhere → min-content 只剩 1 字符）
   挤成「一列一字」，长 meta 自身也溢出卡片右缘。现在 name 保底 8ch、meta 让压并折行右对齐。 */
.arx-card-name { flex: 1 1 auto; min-width: 8ch; overflow-wrap: anywhere; }
.arx-card-meta { flex: 0 1 auto; min-width: 0; color: var(--muted); font-size: 11.5px;
    white-space: normal; overflow-wrap: anywhere; text-align: right; }
.arx-card-empty { font-size: 12px; color: var(--muted); }
/* ---- 2026-08-19：环内四工具专项卡（compare / cite.export / compat.find / fair.check） ----
   与 .arx-card 同一视觉档（12px、细边框、圆角、surface 底），只补新增的结构位。 */
.arx-cmp-concl { font-size: 12px; line-height: 1.55; color: var(--text-2); }
.arx-cmp-bar { display: flex; flex-wrap: wrap; gap: 6px; }
.arx-cmp-seg { padding: 2px 9px; border-radius: 999px; border: 1px solid var(--border); font-size: 11.5px; }
.arx-cmp-same { color: var(--accent-ink); background: var(--accent-weak); border-color: var(--accent-line); }
.arx-cmp-diff { color: var(--no); background: var(--no-weak); }
.arx-cmp-unknown { color: var(--muted); background: var(--surface-2); }
.arx-fair-pct { font-size: 34px; font-weight: 700; line-height: 1.1; color: var(--accent-ink); }
.arx-fair-pct-unit { font-size: 15px; font-weight: 600; color: var(--muted); margin-left: 2px; }
.arx-fair-counts { font-size: 12px; color: var(--text-2); }
.arx-card-details { margin-top: 2px; }
.arx-card-details > summary { font-size: 11.5px; color: var(--muted); cursor: pointer; user-select: none; }
.arx-card-details > summary:hover { color: var(--accent-ink); }
.arx-trace { margin-top: 2px; }
.arx-trace > summary { font-size: 11.5px; color: var(--muted); cursor: pointer; user-select: none; }
.arx-trace > summary:hover { color: var(--accent-ink); }
.arx-trace-row { display: flex; gap: 6px; font-size: 11.5px; color: var(--text-2); padding: 2px 0 0 2px; }
.arx-trace-mark { color: var(--accent); }
.arx-trace-failed .arx-trace-mark { color: var(--no); }
.arx-trace-detail { color: var(--muted); }
.act-fix { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 2px; }
.act-chip { font-size: 12px; padding: 5px 10px; }
.act-undone { color: var(--muted); font-size: 12px; line-height: 1.55; }   /* 撤回成功后的原位注记（替掉撤回钮） */
/* 婉拒候选 chips：「没听懂」回音下方的可点候选——引导色弱于纠错 chips 的按钮感 */
.act-suggest { align-items: center; }
.act-suggest-lead { font-size: 12px; color: var(--muted); }

@media (prefers-reduced-motion: reduce) {
    .arx-ico-run i { animation: none; }
    .arx-run { transition: none; }
}

/* ============================================================================
   视图交换：#swSwapBtn 交换主区结果网格与侧栏对话窗的显示位置。
   状态真源 = body.view-swapped（board.js placeChatSuite 随交换旗标切换，旗标不落盘）。
   本区只描述新落点的形态：#chatStage（主区对话舞台）、#resultsHead（交换态
   随结果进侧栏的头部件包装）与 #resultsGrid.grid-mini（侧栏紧凑结果卡）。动画纪律：
   被搬节点**不挂任何 CSS 入场动画**——搬家动效由 placeChatSuite 的 GSAP from() 单引擎
   承担（.side-work swIn 双引擎抢 transform 的教训）。
   ========================================================================== */

/* —— 交换钮：.sw-switch 第三格（两页签右侧），28px 定宽方钮（滑块宽度按它折算，见 .sw-glide）—— */
.sw-swap {
    width: 28px; align-self: stretch; border: 0; border-radius: 8px; cursor: pointer;
    display: inline-flex; align-items: center; justify-content: center;
    background: transparent; color: var(--muted); transition: color .16s, background .16s;
    position: relative; z-index: 1;
}
.sw-swap svg { width: 14px; height: 14px; }
.sw-swap:hover { color: var(--text-2); background: var(--surface); }
.sw-swap[aria-pressed="true"] { color: var(--accent-ink); background: var(--accent-weak); }
.sw-swap:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* —— 主区对话舞台 #chatStage（交换态：#cbHistory 住上槽自滚动、#chatComposer 整棵住下槽）——
   观感定案：整个主窗口即聊天窗口——**无白卡框**（背景/边框/圆角/阴影全去，气泡直接落
   页面底色；系统灰泡 surface-2 / 用户绿泡 accent-weak 在 --bg 浅灰上对比度仍清晰），列宽 880px。
   高度不再按视口硬算（calc 标定值在别的视口/长对话会脱底），改结构性钉底（见下方
   「输入条结构性钉底」块）：本容器 flex:1 吃掉 .view 内剩余高度，输入条恒在视口底部。 */
.chat-stage { display: flex; flex-direction: column; gap: 12px; margin-top: 6px;
    flex: 1 1 auto; min-height: 0; }
.chat-stage-log, .chat-stage-bar { width: 100%; max-width: 880px; margin-left: auto; margin-right: auto; }
.chat-stage-log { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
/* 下槽是 #scopePop 的定位锚（bottom:calc(100% + 6px) 向上弹）——position:relative 且不裁剪 */
.chat-stage-bar { flex: 0 0 auto; position: relative; }
.chat-stage-bar .cb-composer { border-top: 0; padding: 0; }   /* 侧栏态的分隔线/内边距是卡内语境，舞台里不需要 */
.chat-stage .cb-history.cbh-main { max-height: none; flex: 1 1 auto; min-height: 0; margin-top: 0;
    overflow-y: auto; padding: 4px 2px; }   /* 白卡内边距随框一起去掉，只留滚动余量 */
.chat-stage .cb-history { font-size: 12px; line-height: 1.55; }
.chat-stage .cbh-bubble, .chat-stage .cbh-sys-bubble { padding: 9px 14px; }
.chat-stage .cbh-view-link { font-size: 11.5px; }
.chat-stage .cb-composer textarea { font-size: 14px; }
.chat-stage .cb-bar { padding: 6px 6px 6px 10px; border-radius: 16px;
    background: var(--surface); border-color: var(--border); box-shadow: var(--shadow-sm); }
.chat-stage .cb-send, .chat-stage .scope-btn { width: 38px; height: 38px; }
.chat-stage .cb-send svg, .chat-stage .scope-btn svg { width: 16px; height: 16px; }
.chat-stage .cb-fork .btn { padding: 11px 8px; font-size: 13.5px; border-radius: 14px; }

/* —— 交换态「检索结果」页签隐藏常驻查询条件栏 #swHits（用户：该页签里它是冗余上文）——
   页签标识 = #sideWork 的 data-sw-mode（board.js swApplyMode 每次落当前显示模式）。
   纯 display:none：节点仍在、placeHitsBar 的搬家/显隐逻辑完全不受影响；
   切「细化筛选」页签（data-sw-mode=facets）或非交换态，本规则不命中、栏照现。 */
body.view-swapped #sideWork[data-sw-mode="board"] #swHits { display: none; }

/* —— 输入条结构性钉底（替代此前的 calc(100vh-56px) 视口硬算——硬算值在别的视口高度 /
   长对话下会脱底）：交换态查询视图恰好一屏（main 上下 padding 30+20），页面不滚动
   （无双滚动条）；#resultsWrap 变 flex 列、#chatStage flex:1 吃掉剩余高度——任意视口高度、
   任意对话长短下 #chatComposer 恒在视口底部，对话列在输入条上方内部滚动（微信桌面版式）。
   短对话消息从顶部排、下方留白属正常。两展开面板可收缩自滚动，不把输入条挤出视口。 ——*/
body.view-swapped .main { padding-bottom: 20px; }
body.view-swapped .view.active[data-view="query"] { height: calc(100vh - 50px); height: calc(100dvh - 50px); overflow: hidden; }
body.view-swapped #resultsWrap { flex: 1 1 auto; min-height: 0; display: flex !important; flex-direction: column; }   /* !important：压 renderResults 写死的 inline display:block */
body.view-swapped .feasibility-panel, body.view-swapped .task-pack-panel { flex: 0 1 auto; min-height: 0; overflow-y: auto; }

/* —— #resultsHead（结果区头部件的静态包装；内部为 .res-overview 概览卡 → #facetBar →
   .res-notes 行组 → #identifierLookup → .res-next 下一步组 五段）——
   正常态 display:contents 对布局完全透明（内部 id 一律不动）；交换态整节点搬进
   #sideBoardScroll 顶部（卡片列表之前）。「放宽方式 ▸」是内联展开
   （cov-detail 在文档流里长高，非浮层），滚动容器不会裁剪。
   注：标题行/摘要卡的侧栏窄态规则已被下方交换态页签头部件紧凑化块整体接替（作用域收窄到
   body.view-swapped + #sideWork[data-sw-mode="board"]），本处只留 info-bar/facetbar。 */
#resultsHead { display: contents; }
.view-swapped #sideBoardScroll .info-bar { margin-bottom: 10px; padding: 9px 11px; font-size: 12.5px; }
.view-swapped #sideBoardScroll .facetbar { margin: 2px 0 10px; }

/* —— 交换态「检索结果」页签头部件紧凑化（A/B 对比后定稿方案 A：单行标题栏）——
   目标：头部区总高 约350px → ≤150px，信息不丢（可折叠但可触达）。作用域一律
   body.view-swapped + #sideWork[data-sw-mode="board"]——正常态与「细化筛选」页签像素级不变。
   ① 标题行并一行：左「推荐结果」小标题，右两枚短文案小钮（按钮内双 span——.bt-full 完整
      文案给正常态/主区，.bt-short「可复用/下载」只在此作用域显示；id/点击行为不动）。
   ② 摘要卡：12px、行距内边距收紧、最多 2 行截断（renderResultSummary 同步写 title 兜全文）。
   ③ 放宽提示行折叠成单行：来源计数截断（ellipsis），「放宽方式 ▸」钮留在折叠行上照样可点；
      该行的 .cov-detail 展开时（:has 相邻选择器）解除截断、完整来源分计数回流展示，
      max-height 过渡动画，prefers-reduced-motion 关门。
   ④ 「摘要卡 + 放宽提示合并为无盒上下节（虚线分隔 + 琥珀点）」上移为通用态（见「结果区头部重设计」段）；
      交换态只留 .res-overview 紧凑卡壳（小圆角、无阴影），摘要/放宽提示的 padding 由卡壳承担。 */
body.view-swapped #sideWork[data-sw-mode="board"] .res-overview {
    margin: 0 0 10px; padding: 10px 12px; border-radius: var(--radius-md); box-shadow: none;
}
body.view-swapped #sideWork[data-sw-mode="board"] .results-head {
    margin: 0 0 8px; align-items: center; flex-wrap: nowrap; gap: 6px;
}
body.view-swapped #sideWork[data-sw-mode="board"] .results-title { font-size: 13px; flex: 0 0 auto; }
body.view-swapped #sideWork[data-sw-mode="board"] .results-head-acts {
    width: auto; margin-left: auto; flex-direction: row; align-items: center; gap: 5px;
}
body.view-swapped #sideWork[data-sw-mode="board"] .results-head-acts .btn {
    font-size: 11.5px; padding: 4px 8px; border-radius: 8px; white-space: nowrap;
}
body.view-swapped #sideWork[data-sw-mode="board"] .results-head-acts .bt-full { display: none; }
body.view-swapped #sideWork[data-sw-mode="board"] .results-head-acts .bt-short { display: inline; }
/* 交换态 300px 窄栏的批次切换器紧凑化（同上方页签头部件紧凑化块同一作用域与尺度）；
   segmented 轨道不溢出 300px 卡壳 */
body.view-swapped #sideWork[data-sw-mode="board"] .batch-bar { margin: 6px 0 0; gap: 5px; padding: 1px; }
body.view-swapped #sideWork[data-sw-mode="board"] .res-overview .batch-bar { max-width: 100%; }
body.view-swapped #sideWork[data-sw-mode="board"] .batch-pill {
    font-size: 11.5px; padding: 4px 9px; max-width: 148px;
}
body.view-swapped #sideWork[data-sw-mode="board"] .rs-text {
    font-size: 12px; line-height: 1.5;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
/* .rs-coverage 的「去黄底、虚线分隔」已上移通用态（「结果区头部重设计」段 .res-overview .rs-coverage），
   交换态不再重复哑化规则；此处只留行折叠紧凑化。 */
body.view-swapped #sideWork[data-sw-mode="board"] .cov-row { padding: 3px 0; gap: 6px; }
body.view-swapped #sideWork[data-sw-mode="board"] .cov-txt {
    font-size: 12px; line-height: 1.45; min-width: 0;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    max-height: 1.5em; transition: max-height .25s ease;
}
body.view-swapped #sideWork[data-sw-mode="board"] .cov-row:has(+ .cov-detail:not([hidden])) .cov-txt {
    white-space: normal; max-height: 14em;
}
body.view-swapped #sideWork[data-sw-mode="board"] .cov-expand { font-size: 11.5px; padding: 2px 7px; }
/* 交换态下 res-notes 小字行 / 下一步组标签 / 阶梯 chips 同尺度收紧 */
body.view-swapped #sideWork[data-sw-mode="board"] .res-notes .info-bar { font-size: 12px; padding: 4px 0 4px 8px; }
body.view-swapped #sideWork[data-sw-mode="board"] .res-next-label { font-size: var(--fs-micro); }
body.view-swapped #sideWork[data-sw-mode="board"] .ladder-chip { padding: 4px 10px; }
@media (prefers-reduced-motion: reduce) {
    body.view-swapped #sideWork[data-sw-mode="board"] .cov-txt { transition: none; }
}

/* —— 侧栏紧凑结果卡（#resultsGrid.grid-mini：交换态整节点搬进 #sideBoardScroll，单列）——
   纯 CSS 紧凑化（节点原样、监听器不动）：隐去 推荐理由/样本脚/文件钮/可达性徽章，
   保留 rank 角标（对话里「打开第 3 个」的指代）、标题（2 行截断）、平台·来源、FASTQ pill、
   物种/疾病 chips（1 行）、两颗小号 CTA、收藏心 与「数据集详情」小钮（恢复：
   全宽行在 CTA 之下，字号压小；点击 = 新标签 /dataset + localStorage handoff，按 class 已绑好）。 */
#resultsGrid.grid-mini { grid-template-columns: 1fr; gap: 10px; padding: 2px; }
.grid-mini .card { padding: 12px; }
.grid-mini .card:hover { transform: none; }   /* 窄列里 -3px 上浮显晃，只留描边/阴影反馈 */
.grid-mini .card-why, .grid-mini .card-foot,
.grid-mini .files-open, .grid-mini .reach { display: none; }
.grid-mini .btn-detail { margin-top: 6px; padding: 6px 8px; font-size: 12px; border-radius: 9px; }
.grid-mini .fav { top: 8px; right: 8px; width: 30px; height: 30px; }
.grid-mini .badges { min-height: 0; max-height: none; margin-bottom: 7px; padding-right: 30px; gap: 5px; }
.grid-mini .card-title { font-size: 13.5px; min-height: 0; margin-bottom: 7px; }   /* 2 行 clamp 继承基础规则 */
.grid-mini .card-tags { max-height: 24px; margin-bottom: 0; gap: 4px; }   /* 1 行截断；完整值在各 tag 的 title */
.grid-mini .card-cta { margin-top: 10px; gap: 6px; }
.grid-mini .card-cta .cta { padding: 7px 8px; font-size: 12px; border-radius: 9px; }
.grid-mini .relax-banner, .grid-mini .info-bar { grid-column: 1 / -1; }   /* 放宽横幅/空态条占满单列 */

/* ============================================================================
 * 课题：课题浮窗卡片/详情/上下文卡/首页条/coachmark
 * ----------------------------------------------------------------------------
 * 全部复用既有 css 变量（--surface/--border/--accent/--text-2/--muted…）与组件语言；
 * 浮窗骨架类（hist-win/hw-*）直接继承档案浮窗 #archiveWin 的样式，这里只补课题专属部件。
 * ========================================================================== */

/* ---------- 追踪浮窗：列表行（flex 布局，名称区 + 行尾三按钮） ---------- */
.prj-card { display: flex; align-items: center; gap: 12px; width: 100%; text-align: left;
    padding: 10px 10px 10px 14px; margin-bottom: 10px;
    background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
    box-shadow: var(--shadow-sm); cursor: pointer; transition: border-color .15s, box-shadow .15s;
    font-family: var(--font); color: var(--text); }
.prj-card:hover, .prj-card:focus-visible { border-color: var(--accent-line); box-shadow: var(--shadow-focus); outline: none; }
.prj-card-main { flex: 1 1 auto; min-width: 0; }   /* min-width:0 让长名在 flex 里正常截断 */
.prj-card-name { font-size: 13.5px; font-weight: 600; word-break: break-word; }
.prj-card:hover .prj-card-name { color: var(--accent-ink); }
.prj-card-meta { font-size: 11.5px; color: var(--text-2); margin-top: 4px; }
.prj-card-time { font-size: 11px; color: var(--muted); margin-top: 3px; font-family: var(--mono); }
/* 行尾操作钮：.fav 同族的 ghost 图标钮（小一号），常显不藏——触屏无 hover */
.prj-row-acts { display: flex; gap: 4px; flex: none; }
.ra-btn { width: 30px; height: 30px; border-radius: 8px; border: 1px solid transparent;
    background: transparent; color: var(--muted); cursor: pointer; flex: none;
    display: grid; place-items: center; font-family: var(--font);
    transition: background .15s, color .15s, border-color .15s; }
.ra-btn svg { width: 16px; height: 16px; }
.ra-btn:hover { background: var(--surface-2); color: var(--accent-ink); }
.ra-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.ra-btn:active { transform: scale(.92); }   /* 瞬态按压反馈，与 .ladder-chip:active 同思路 */
.ra-btn:disabled { color: var(--muted-soft); cursor: default; background: transparent; }
.ra-del:hover { color: var(--no); background: var(--no-weak); }
/* 删除两段确认 armed 态：琥珀警示（非红，项目惯例）；图标→「再点确认」的换内容由 JS 做
   （textContent 换掉 svg），CSS 只上色—— 修重影：此前 CSS ::after 也补一份「再点确认」，
   与 JS textContent 叠加成两行。 */
.ra-btn.armed { width: auto; padding: 0 8px; color: var(--warn);
    border-color: var(--warn-line-strong); background: var(--warn-weak);
    font-size: 11px; font-weight: 600; white-space: nowrap; }
/* 检查更新在途：禁用 + 图标匀速旋转 */
.ra-btn .ra-spin { animation: raSpin .9s linear infinite; transform-origin: 50% 50%; }
@keyframes raSpin { to { transform: rotate(360deg); } }
.prj-check-fail { color: var(--no); margin-left: 6px; }
.prj-check-fail::before { content: "· "; color: var(--muted); }
/* 「待查看 N」徽章：主色胶囊 + 小圆点，紧跟追踪名 */
.prj-badge-new { display: inline-flex; align-items: center; margin-left: 8px; padding: 1px 8px;
    font-size: 10.5px; font-weight: 600; border-radius: 999px; vertical-align: 2px;
    color: var(--accent-ink); background: var(--accent-weak); border: 1px solid var(--accent-line); }
.prj-badge-new::before { content: ""; width: 5px; height: 5px; border-radius: 50%;
    background: var(--accent); margin-right: 5px; }
@media (prefers-reduced-motion: reduce) {
    .ra-btn .ra-spin { animation: none; }
    .ra-btn:active { transform: none; }
}

/* ---------- 课题详情 ---------- */
.prj-detail { display: flex; flex-direction: column; gap: 12px; }
.prj-detail-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
    padding-bottom: 10px; border-bottom: 1px solid var(--border); }
.prj-detail-title { flex: 1 1 auto; min-width: 0; font-size: 14.5px; font-weight: 700; word-break: break-word;
    display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.prj-detail-acts { display: flex; gap: 6px; flex: none; flex-wrap: wrap; }
.prj-detail-acts .btn { padding: 6px 11px; font-size: 12px; }
.prj-del.armed { color: var(--warn); border-color: var(--warn-line-strong); background: var(--warn-weak); }
.prj-sec { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
    padding: 12px 14px; box-shadow: var(--shadow-sm); }
.prj-sec-title { font-size: 12.5px; font-weight: 700; color: var(--text-2); margin-bottom: 8px;
    display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.prj-sec-note { font-size: 11px; font-weight: 400; color: var(--muted); }
.prj-muted-text { font-size: 12.5px; color: var(--muted); }
.prj-mini-btn { padding: 2px 7px; font-size: 11.5px; color: var(--text-2); background: transparent;
    border: 1px solid var(--border); border-radius: 7px; cursor: pointer; transition: color .14s, border-color .14s; }
.prj-mini-btn:hover { color: var(--accent-ink); border-color: var(--accent-line); }
.prj-goal { font-size: 13px; color: var(--text); line-height: 1.65; word-break: break-word;
    display: flex; align-items: flex-start; gap: 8px; flex-wrap: wrap; }
.prj-goal .prj-mini-btn { flex: none; margin-left: auto; }
.prj-edit { display: flex; flex-direction: column; gap: 8px; }
.prj-edit-acts { display: flex; gap: 8px; }
.prj-edit-acts .btn { padding: 6px 14px; font-size: 12px; }
.prj-input { width: 100%; box-sizing: border-box; padding: 8px 10px; font-size: 13px; font-family: var(--font);
    color: var(--text); background: var(--surface); border: 1px solid var(--border-2); border-radius: 9px; resize: vertical; }
.prj-input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-weak); }
.prj-rename-input { width: 100%; font-size: 14px; font-weight: 600; }
.prj-cond-row { display: flex; align-items: center; gap: 8px; padding: 5px 0; font-size: 12.5px; }
.prj-cond-row + .prj-cond-row { border-top: 1px dashed var(--border); }
.prj-cond-idx { flex: none; width: 18px; height: 18px; border-radius: 50%; background: var(--surface-2);
    color: var(--muted); font-size: 10.5px; display: inline-flex; align-items: center; justify-content: center; }
.prj-cond-text { flex: 1 1 auto; min-width: 0; word-break: break-word; }
.prj-cond-del { flex: none; }
.prj-cond-add { display: flex; gap: 8px; margin-top: 8px; }
.prj-cond-add .prj-input { flex: 1 1 auto; }
.prj-cond-add .btn { flex: none; padding: 6px 14px; font-size: 12px; }
.prj-cand { border: 1px solid var(--border); border-radius: 10px; padding: 9px 11px; margin-bottom: 8px;
    background: var(--surface); }
.prj-cand-main { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.prj-cand-uid { font-family: var(--mono); font-size: 12.5px; font-weight: 600; word-break: break-all; }
.prj-cand-st { flex: none; font-size: 11px; padding: 2px 8px; border-radius: 999px; }
.prj-cand-st.st-待核验 { color: var(--caution-ink, #7a5c22); background: var(--caution-weak); border: 1px solid var(--caution-line); }
.prj-cand-st.st-已核验 { color: var(--ok); background: var(--ok-weak); border: 1px solid #bfe3ca; }
.prj-cand-st.st-已排除 { color: var(--no); background: var(--no-weak); border: 1px solid #f0c0c0; }
.prj-cand-st.st-候选 { color: var(--text-2); background: var(--surface-2); border: 1px solid var(--border-2); }
.prj-cand-meta { font-size: 11.5px; color: var(--muted); min-width: 0; flex: 1 1 100%; }
.prj-cand-acts { display: flex; gap: 6px; margin-top: 7px; flex-wrap: wrap; }
.prj-cand-acts .btn { padding: 5px 10px; font-size: 11.5px; }
.prj-act-ok { color: var(--ok); border-color: #bfe3ca; background: var(--ok-weak); }
.prj-act-no { color: var(--no); border-color: #f0c0c0; background: var(--no-weak); }
.prj-reason-form { margin-top: 7px; display: flex; flex-direction: column; gap: 7px; }
.prj-check-query { font-size: 13px; color: var(--text); margin-bottom: 6px; word-break: break-word; }
.prj-check-spec { display: flex; flex-wrap: wrap; gap: 6px 14px; font-size: 12.5px; color: var(--text-2); }
.prj-check-spec span b { color: var(--muted); font-weight: 600; margin-right: 4px; }
.prj-check-mount, .prj-export-mount { margin-top: 8px; }
.prj-export-mount { border-top: 1px dashed var(--border); padding-top: 8px; }

/* ---------- 候选卡片化 / 收藏卡片操作条 / 库卡片 ---------- */
/* 候选卡片化：状态徽标浮贴卡片上缘（标签页式），操作条贴卡片下方 */
.prj-cand-wrap { position: relative; margin-bottom: 12px; }
/* 浮贴徽标只剩 project_updates 的「待查看更新」delta 路径在用（候选状态徽标已收进卡片
   .badges 行首，见 projects.js _buildCandNodes）；让位补偿同样只作用于这条路径。 */
.prj-cand-wrap > .prj-cand-st { position: absolute; top: -8px; left: 12px; z-index: 2; }
.prj-cand-wrap > .prj-cand-st + .card-library { margin-top: 8px; }
.prj-cand-wrap .prj-cand-acts { margin-top: 6px; }
/* 「已下架」标记：候选文字行与收藏卡 .badges 行共用同一枚 */
.gone-badge { font-size: 10.5px; font-weight: 600; padding: 1px 7px; border-radius: 999px;
    color: var(--no); background: var(--no-weak); border: 1px solid #f0c0c0; }
/* 收藏卡片操作条：调用方 wrapper 注入（.lib-card-wrap），不动卡片工厂通用 API */
.lib-card-wrap { position: relative; margin-bottom: 12px; }
.card-acts { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 10px; padding-top: 10px;
    border-top: 1px solid var(--border); }
.card-acts .btn { padding: 5px 11px; font-size: 12px; border-radius: 9px; }
.card-acts .btn:disabled { opacity: .6; cursor: default; pointer-events: none; }
.card-acts .btn.armed { color: var(--warn); border-color: var(--warn-line-strong); background: var(--warn-weak); }

/* ---------- 我的库卡片（追踪候选/更新 delta/收藏）——继承 .card，只收紧密度 ----------
   与 .grid-mini 同一档收紧值，全站紧凑卡观感统一。卡片工厂由 buildCard variant:"library" 加 .card-library。 */
.card-library { padding: 12px 14px; }
.card-library:hover { transform: none; }
.card-library .fav { top: 8px; right: 8px; width: 30px; height: 30px; }
.card-library .badges { min-height: 0; max-height: none; margin-bottom: 7px; padding-right: 30px; gap: 5px; }
.card-library .card-title { font-size: 13.5px; min-height: 0; margin-bottom: 7px; }
.card-library .card-why { display: none; }
.card-library .card-tags { max-height: 24px; margin-bottom: 0; gap: 4px; }
.card-library .card-foot { padding-top: 8px; }
.card-library .files-open { display: none; }   /* 兜底；JS 侧本就不渲染文件展开/下载，只留「打开数据集页」于 .card-cta */
.card-library .btn-detail { margin-top: 6px; padding: 6px 8px; font-size: 12px; border-radius: 9px; }
.card-library .card-acts { margin-top: 8px; padding-top: 8px; }


/* ---------- 上下文 chip（嵌进输入框内部、与第一行文本同一中线） ----------
   双挂点同一状态真源（projects.js _ctxCard）：
   - 主输入框 #queryInput：完整胶囊 .ctx-chip 绝对定位于第一行左侧，textarea 首行 text-indent
     由 JS 按 chip 实测宽度同步（文本从 chip 右侧起排，仅首行让位——引用消息式嵌入行首）。
   - 侧栏继续对话 #chatInput：窄框态缩成 20px 小圆徽章 .ctx-dot（带类型图标），垂直对齐第一行
     文本中线；hover/focus/点击浮出 popover（来源类型 + 名称 + 预览 + 移除 + 隐私口径）。
   发送即清：消息发出成功，两个挂点随输入框一起清空。 */
.artifact-ctx { position: relative; }

/* —— 侧栏变体：小圆徽章（.cb-bar flex 行内、textarea 之前） —— */
.cb-bar > .artifact-ctx { flex: none; align-self: flex-start; margin: 6px 0 0 2px; }
.ctx-dot { display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 20px;
    padding: 0; border-radius: 50%; cursor: pointer;
    background: var(--accent-weak); border: 1px solid var(--accent-line); color: var(--accent-ink);
    transition: border-color .15s, box-shadow .15s, transform .15s; }
.ctx-dot:hover, .artifact-ctx.pop-open .ctx-dot { border-color: var(--accent); box-shadow: var(--shadow-focus); }
.ctx-dot:active { transform: scale(.92); }
.ctx-dot:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.ctx-dot svg { width: 11px; height: 11px; display: block; }
.ctx-dot-dataset svg { fill: currentColor; }   /* HEART 是填充路径（无 stroke 属性） */

/* —— 主框变体：完整胶囊 —— */
.artifact-ctx-main { position: absolute; left: 16px; top: 13px; z-index: 3; }
.ctx-chip { display: inline-flex; align-items: center; max-width: 100%;
    background: var(--accent-weak); border: 1px solid var(--accent-line); border-radius: 999px;
    transition: border-color .15s, box-shadow .15s; }
.ctx-chip:hover { border-color: var(--accent); box-shadow: var(--shadow-focus); }
.ctx-chip-main { display: inline-flex; align-items: center; gap: 6px; min-width: 0; max-width: 280px;
    height: 28px; padding: 0 4px 0 10px; border: none; background: transparent; cursor: pointer;
    font-family: var(--font); font-size: 12px; font-weight: 600; color: var(--accent-ink); }
.ctx-chip-main:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; border-radius: 999px; }
.ctx-chip-ico { flex: none; display: inline-flex; line-height: 1; }
.ctx-chip-ico svg { width: 12px; height: 12px; display: block; }
.ctx-chip-ico.ctx-ico-dataset svg { fill: currentColor; }   /* HEART 填充路径 */
.ctx-chip-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ctx-chip-x { flex: none; width: 20px; height: 20px; margin-right: 4px; border: none; border-radius: 50%;
    background: transparent; color: var(--muted); font-size: 12px; line-height: 1; cursor: pointer;
    display: grid; place-items: center; transition: color .14s, background .14s; }
.ctx-chip-x:hover { color: var(--no); background: var(--no-weak); }
.ctx-chip-x:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* 预览 popover 两向：主框 chip 在输入框顶 → 向下展开（.ctx-pop-down，点击开合）；
   侧栏徽章在输入条底 → 向上展开（.ctx-pop-dot，hover/focus/.pop-open 开合、CSS 过渡）。 */
.ctx-pop { position: absolute; bottom: calc(100% + 6px); left: 0; z-index: var(--z-dropdown);
    width: min(420px, calc(100vw - 32px)); background: var(--surface); text-align: left;
    border: 1px solid var(--border); border-radius: var(--radius-md); box-shadow: var(--shadow-lg);
    padding: 12px 14px; animation: ctxPopIn .16s var(--ease-spring); transform-origin: bottom left; }
@keyframes ctxPopIn { from { opacity: 0; transform: translateY(4px) scale(.98); } to { opacity: 1; transform: none; } }
.ctx-pop-down { bottom: auto; top: calc(100% + 6px); transform-origin: top left; animation-name: ctxPopDown; }
@keyframes ctxPopDown { from { opacity: 0; transform: translateY(-4px) scale(.98); } to { opacity: 1; transform: none; } }
.ctx-pop-dot { animation: none; opacity: 0; visibility: hidden; transform: translateY(4px);
    transition: opacity .16s ease, transform .16s var(--ease-spring), visibility 0s linear .18s; }
.artifact-ctx:hover .ctx-pop-dot, .artifact-ctx:focus-within .ctx-pop-dot, .artifact-ctx.pop-open .ctx-pop-dot {
    opacity: 1; visibility: visible; transform: none; transition-delay: 0s; }
.ctx-pop-dot::after { content: ""; position: absolute; top: 100%; left: 0; right: 0; height: 8px; }   /* hover 桥：盖住徽章与 popover 间的缝隙 */
.ctx-pop-kind { font-size: 11px; font-weight: 600; letter-spacing: .02em; color: var(--muted); margin-bottom: 5px; }
.ctx-pop-title { font-size: 12.5px; font-weight: 700; color: var(--accent-ink); margin-bottom: 6px;
    word-break: break-word; }
.ctx-pop .actx-preview { max-height: 220px; overflow-y: auto; }
.ctx-pop-foot { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 8px; }
.ctx-pop .actx-privacy { margin-top: 6px; }
.ctx-pop .actx-note { margin-top: 6px; }
/* —— 以下四条自旧段逐字平移，一个属性都不改 —— */
.actx-privacy { font-size: 11px; color: var(--muted); }
.actx-hint { font-size: 11px; color: var(--muted); }
.actx-preview { margin: 0; font-family: var(--font); font-size: 11.5px; color: var(--text-2);
    line-height: 1.6; white-space: pre-wrap; word-break: break-word; }
.actx-note { font-size: 11.5px; color: var(--no); }
@media (prefers-reduced-motion: reduce) { .ctx-pop { animation: none; } .ctx-pop-dot { transition: none; } .ctx-dot { transition: none; } }


/* ---------- 首次保存 coachmark ---------- */
.coachmark { position: fixed; right: 20px; bottom: 20px; z-index: calc(var(--z-modal) + 1);
    width: min(340px, calc(100vw - 32px)); background: var(--surface); border: 1px solid var(--accent-line);
    border-radius: var(--radius-lg); box-shadow: var(--shadow-lg); padding: 14px 16px;
    font-family: var(--font); color: var(--text); }
.coachmark-head { display: flex; align-items: center; justify-content: space-between; font-size: 14px; }
.coachmark-head .icon-btn { color: var(--muted); }
.coachmark-list { margin: 10px 0 12px; padding-left: 18px; display: flex; flex-direction: column; gap: 7px; }
.coachmark-list li { font-size: 12.5px; line-height: 1.6; color: var(--text-2); }
.coachmark-list b { color: var(--accent-ink); }
.coachmark-acts { display: flex; justify-content: flex-end; }
.coachmark-acts .btn { padding: 7px 18px; font-size: 12.5px; }

/* ============ 下一步行动阶梯（2026-08-22 复用既有 chip 组件语言） ============ */
.ladder-bar { margin: 10px 0 4px; display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.ladder-chips { display: inline-flex; flex-wrap: wrap; gap: 8px; }
.ladder-chip { display: inline-flex; align-items: center; gap: 8px; padding: 7px 12px; border-radius: 10px;
    border: 1px solid var(--bar-line); background: var(--surface-2); color: var(--text); font-size: 12.5px; cursor: pointer;
    transition: transform .16s cubic-bezier(.22,1,.36,1), border-color .16s ease, background .16s ease; }
.ladder-chip:hover { transform: translateY(-1px); border-color: var(--accent); background: var(--surface); }
.ladder-chip:active { transform: translateY(0); }
.ladder-chip .lc-n { font-weight: 700; color: var(--accent-ink); font-variant-numeric: tabular-nums; }
.ladder-chip.export-chip { border-style: dashed; color: var(--text-2); }
/* 过宽收窄建议条（结果区顶部；info-bar 同族但更轻，不打断结果阅读）
   节点下移进 .res-next 组，组内 margin 由 .res-next 规则归零；本基础规则仅兜底。 */
.ladder-narrow { margin: 6px 0 2px; display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
    font-size: 12.5px; color: var(--text-2); }
.ladder-narrow-txt b { color: var(--text); }

/* ============ 结果区头部重设计——概览卡 + 诚实行组 + 下一步组 ============
   结构见 index.html #resultsHead 注释：.res-overview（结果区唯一卡片：标题行三钮 / 批次 segmented /
   审核横幅去盒化 teal 左线 / 摘要卡去盒化 + 覆盖缺口虚线分隔琥珀点）→ #facetBar（原位不动，不进
   任何新容器）→ .res-notes（诚实回显小字行组，三条全隐整组 :has 归隐）→ #identifierLookup
   （保留原 info-bar 盒子）→ .res-next「下一步」（#ladderNarrow + #ladderBar，全隐连标签 :has 归隐）。
   纯 HTML 静态包装 + CSS；JS 渲染与显隐逻辑零改动。交换态 300px 紧凑化见上方「页签头部件紧凑化」段。 */
.res-overview { margin: 26px 0 16px; padding: 14px 16px; background: var(--surface);
    border: 1px solid var(--border); border-radius: var(--radius-lg); box-shadow: var(--shadow-sm); }
.res-overview .results-head { margin: 0; align-items: center; }
.res-overview .results-title { font-size: 15px; }   /* .prelim-badge 不动 */
.res-overview .results-head-acts { gap: 6px; }
.res-overview .results-head-acts .btn { padding: 5px 11px; font-size: 12.5px; border-color: var(--border);
    background: transparent; color: var(--text-2); border-radius: 9px; }
.res-overview .results-head-acts .btn:hover { background: var(--accent-weak); color: var(--accent-ink);
    border-color: var(--accent-line); }
/* 批次切换器改 segmented 控件造型（pill 曾长得像 chip、被误读为 query 回显）：灰轨道 + 选中白底浮起 */
.res-overview .batch-bar { margin: 10px 0 0; display: inline-flex; gap: 2px; padding: 2px;
    background: var(--surface-2); border-radius: 999px; max-width: 100%; }
.res-overview .batch-pill { border-color: transparent; background: transparent; }
.res-overview .batch-pill.is-on { background: var(--surface); color: var(--accent-ink);
    box-shadow: var(--shadow-sm); border-color: transparent; }
/* 审核横幅去盒化：teal 左线小字行 */
.res-overview .audit-banner { margin: 8px 0 0; padding: 2px 0 2px 9px; background: none; border: 0;
    border-left: 2px solid var(--accent-line); border-radius: 0; font-size: 12.5px; color: var(--text-2); }
/* 摘要卡去盒化（卡壳由 .res-overview 承担）；覆盖缺口去黄底、改虚线分隔（原交换态哑化规则已上移为通用态） */
.res-overview .result-summary { margin: 10px 0 0; padding: 0; border: 0; background: none; border-radius: 0; }
.res-overview .rs-coverage { margin-top: 10px; padding: 9px 0 2px; background: none; border-radius: 0;
    border-top: 1px dashed var(--border); }
/* 覆盖缺口提示行前缀琥珀色小方点（替代原黄底的警示语义） */
.rs-coverage .cov-txt::before { content: ""; display: inline-block; width: 6px; height: 6px; border-radius: 2px;
    background: var(--caution-pill); margin-right: 7px; vertical-align: 1px; }
/* .res-notes：诚实回显行组（无盒子，2px 左色条小字行）；三条全隐时整组 :has 归隐不占位 */
.res-notes { margin: 2px 0 14px; }
.res-notes:not(:has(.info-bar:not([hidden]))) { display: none; }
.res-notes .info-bar { margin: 0; padding: 5px 0 5px 10px; border: 0; border-left: 2px solid var(--caution-line);
    background: none; border-radius: 0; font-size: 12.5px; }
.res-notes .info-bar:not(.info-bar-caution) { border-left-color: var(--border-2); }
.res-notes .info-bar + .info-bar { margin-top: 3px; }
/* .res-next：下一步组（收窄建议 + 行动阶梯）；两者全隐时连 .res-next-label 整组 :has 归隐 */
.res-next { margin: 12px 0 6px; display: flex; flex-direction: column; gap: 7px; }
.res-next:not(:has(> div:not([hidden]))) { display: none; }
.res-next-label { font-size: var(--fs-xs); font-weight: 600; color: var(--muted); letter-spacing: .03em; }
.res-next .ladder-narrow, .res-next .ladder-bar { margin: 0; }
/* 阶梯 chips 改胶囊小章（hover/active/export 变体不动） */
.ladder-chip { padding: 5px 12px; font-size: 12px; border-radius: 999px; border-color: var(--border-2);
    background: var(--surface); color: var(--text-2); }
/* 任务卡弹窗三段说明 */
.tc-meta { display: flex; flex-direction: column; gap: 6px; margin: 2px 0 10px; font-size: 12.5px; color: var(--text-2); }
.tc-meta-row b { color: var(--text); font-weight: 600; }
.tc-fail { margin: 8px 0 0; font-size: 12.5px; color: var(--warn-ink, var(--warn)); }

/* ---------- 课题更新检查（复用 .prj-* 卡片语言与既有 css 变量） ---------- */
.wd-times { display: flex; flex-wrap: wrap; gap: 4px 14px; font-size: 11.5px; color: var(--muted);
    margin-bottom: 8px; font-family: var(--mono); }
.wd-acts { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.wd-acts .btn { padding: 6px 12px; font-size: 12px; }
.wd-acts .btn[disabled] { opacity: .6; cursor: default; pointer-events: none; }
.wd-status { margin-top: 7px; font-size: 12px; line-height: 1.6; color: var(--text-2); }
.wd-status.wd-status-changed { color: var(--accent-ink); font-weight: 600; }
.wd-status.wd-status-warn { color: var(--warn); }
.wd-status.wd-status-error { color: var(--no); }

/* 待查看更新（会话内列表；每条 = 类型标签 + uid + 处理按钮） */
.wd-deltas { margin-top: 10px; border-top: 1px dashed var(--border-2); padding-top: 8px; }
.wd-delta-head { font-size: 11.5px; font-weight: 700; color: var(--text-2); margin-bottom: 7px; }
.wd-delta { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; padding: 6px 8px;
    border: 1px solid var(--border); border-radius: 9px; margin-bottom: 6px; background: var(--surface); }
.wd-delta-kind { flex: none; font-size: 10.5px; padding: 1px 7px; border-radius: 999px;
    color: var(--ok); background: var(--ok-weak); border: 1px solid #bfe3ca; }
.wd-delta-kind.wd-kind-gone { color: var(--no); background: var(--no-weak); border-color: #f0c0c0; }
.wd-delta-uid { font-family: var(--mono); font-size: 12px; font-weight: 600; word-break: break-all;
    min-width: 0; flex: 1 1 auto; }
.wd-delta-view { flex: none; font-size: 11px; color: var(--accent-ink); text-decoration: none; }
.wd-delta-view:hover { text-decoration: underline; }
.wd-delta-gone-note { flex: 1 1 100%; font-size: 11px; color: var(--muted); }
.wd-delta-acts { flex: none; display: inline-flex; gap: 6px; }
.wd-delta-acts .btn { padding: 4px 10px; font-size: 11.5px; }
.wd-delta-acts .btn[disabled] { opacity: .6; cursor: default; pointer-events: none; }
.wd-delta-adopt { color: var(--ok); border-color: #bfe3ca; background: var(--ok-weak); }

/* 首页条 / 浮窗头「检查 N 个课题的更新」统一动作按钮 */
.hp-p4-btn { flex: none; font-size: 11.5px; padding: 4px 10px; border-radius: 999px;
    color: var(--accent-ink); background: var(--accent-weak); border: 1px solid var(--accent-line);
    cursor: pointer; font-family: var(--font); transition: border-color .14s, box-shadow .14s; }
.hp-p4-btn:hover { border-color: var(--accent); box-shadow: var(--shadow-focus); }
.hw-btn.hp-p4-btn { font-size: 11.5px; padding: 5px 11px; }

/* 批量检查进度面板（fixed 浮层；层级与 coachmark 同档、低于 modal 弹窗） */
.wd-panel { position: fixed; right: 20px; bottom: 20px; z-index: calc(var(--z-modal) - 1);
    width: min(360px, calc(100vw - 32px)); background: var(--surface); border: 1px solid var(--accent-line);
    border-radius: var(--radius-lg); box-shadow: var(--shadow-lg); padding: 13px 15px;
    font-family: var(--font); color: var(--text); }
.wd-panel-head { display: flex; align-items: center; justify-content: space-between; gap: 8px;
    font-size: 13.5px; margin-bottom: 8px; }
.wd-panel-head .icon-btn { color: var(--muted); }
.wd-panel-rest { font-size: 11.5px; color: var(--warn); line-height: 1.6; margin-bottom: 8px; }
.wd-panel-list { display: flex; flex-direction: column; gap: 5px; max-height: 260px; overflow-y: auto; }
.wd-panel-item { display: flex; align-items: baseline; gap: 9px; padding: 5px 2px;
    border-bottom: 1px dashed var(--border); font-size: 12px; }
.wd-panel-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    flex: 1 1 auto; color: var(--text); }
.wd-panel-state { flex: none; font-size: 11px; color: var(--muted); }
.wd-panel-state.wd-state-run { color: var(--accent-ink); }
.wd-panel-state.wd-state-changed { color: var(--ok); font-weight: 600; }
.wd-panel-state.wd-state-ok { color: var(--muted); }
.wd-panel-state.wd-state-fail { color: var(--no); }
.wd-panel-state.wd-state-cancel { color: var(--warn); }
.wd-panel-foot { display: flex; align-items: center; justify-content: space-between; gap: 10px;
    margin-top: 10px; }
.wd-panel-summary { font-size: 12px; color: var(--text-2); line-height: 1.55; }
.wd-panel-foot .btn { padding: 6px 14px; font-size: 12px; }

/* ============================================================================
 * 课题导出区：导出按钮 + 台账（最新一条 + 历史折叠）
 * 复用既有 token（--surface/--border/--text-2/--muted/--accent 族）与 .btn/.prj-mini-btn/.prj-input
 * 组件语言，不新造视觉系统。
 * ========================================================================== */
.pex { display: flex; flex-direction: column; gap: 10px; }
.pex-acts { display: flex; flex-wrap: wrap; gap: 8px; }
.pex-acts .btn { padding: 6px 12px; font-size: 12px; }
.pex-acts .btn:disabled { opacity: .55; cursor: not-allowed; }
.pex-note { font-size: 12px; color: var(--muted); }
.pex-ledger { border-top: 1px dashed var(--border); padding-top: 10px; display: flex;
    flex-direction: column; gap: 8px; }
.pex-row { display: flex; align-items: flex-start; gap: 8px; flex-wrap: wrap; padding: 6px 8px;
    background: var(--surface); border: 1px solid var(--border); border-radius: 9px; }
.pex-row-latest { border-color: var(--accent-line); background: var(--accent-weak); }
.pex-latest { display: flex; flex-direction: column; gap: 6px; }
.pex-latest-badge { align-self: flex-start; font-size: 10.5px; font-weight: 700; color: var(--accent-ink);
    padding: 1px 8px; border-radius: 999px; background: var(--surface); border: 1px solid var(--accent-line); }
.pex-row-main { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; min-width: 0; flex: 1 1 auto; }
.pex-row-kind { font-size: 12px; font-weight: 700; color: var(--text-2); }
.pex-row-time { font-size: 11.5px; color: var(--muted); }
.pex-row-changes { font-size: 11.5px; color: var(--accent-ink); }
.pex-row-name { font-size: 11.5px; color: var(--text); background: var(--surface-2);
    border: 1px solid var(--border-2); border-radius: 999px; padding: 1px 8px; }
.pex-row-acts { display: flex; gap: 6px; flex: none; }
.pex-row-edit { display: flex; align-items: center; gap: 6px; flex: 1 1 100%; }
.pex-name-input { flex: 1 1 auto; min-width: 120px; }
.pex-row-edit .btn { padding: 5px 10px; font-size: 11.5px; }
.pex-history-toggle { font-size: 11.5px; color: var(--muted); background: transparent; border: none;
    cursor: pointer; padding: 2px 0; }
.pex-history-toggle:hover { color: var(--accent-ink); }
.pex-history-list { display: flex; flex-direction: column; gap: 6px; margin-top: 6px; }
