@lemoncat7/dsh-theme-xiaohei 0.3.4 → 0.3.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  ## 兼容性
6
6
 
7
- 正式版 `0.3.4` 已在 DeepSeek Harness `0.1.5-rc.1` 部署验证,需要 Node.js `22.19+` 或 `24+`。开发依赖仍锁定 `0.1.2-rc.1` 接口;其他 DSH 版本尚未完成同等验证。本版修复新版侧栏识别,优化磨砂透明度、人物眨眼、耳朵动作与鼠标视线跟随。“跟随系统”读取当前设备/浏览器的配色偏好,不按服务器时间切换。
7
+ 正式版 `0.3.5` 延续 `0.3.4` 在 DeepSeek Harness `0.1.5-rc.1` 的部署兼容基线,需要 Node.js `^22.19.0` 或 `>=24.0.0`。开发依赖仍锁定 `0.1.2-rc.1` 接口;其他 DSH 版本尚未完成同等验证。本版修复原生侧栏收起按钮被主题隐藏,以及仅思考节点形成空气泡的问题,不修改官方核心代码。“跟随系统”读取当前设备/浏览器的配色偏好,不按服务器时间切换。
8
8
 
9
9
  ## 当前范围
10
10
 
@@ -33,13 +33,13 @@
33
33
  通过 npm 安装正式版:
34
34
 
35
35
  ```bash
36
- dsh plugin --profile web add @lemoncat7/dsh-theme-xiaohei@0.3.4
36
+ dsh plugin --profile web add @lemoncat7/dsh-theme-xiaohei@0.3.5
37
37
  ```
38
38
 
39
- 也可从 [GitHub Releases](https://github.com/lemoncat7/dsh-theme-xiaohei/releases/tag/v0.3.4) 下载完整包后安装:
39
+ 也可在源码目录运行 `npm pack` 生成完整包后安装:
40
40
 
41
41
  ```bash
42
- dsh plugin --profile web add ./lemoncat7-dsh-theme-xiaohei-0.3.4.tgz
42
+ dsh plugin --profile web add ./lemoncat7-dsh-theme-xiaohei-0.3.5.tgz
43
43
  ```
44
44
 
45
45
  卸载:
@@ -0,0 +1,7 @@
1
+ # 0.3.5 · 侧栏按钮与思考气泡修复
2
+
3
+ 延续 0.3.4 的 DSH 0.1.5-rc.1 兼容基线,Node.js ^22.19.0 或 >=24.0.0。本次浏览器回归使用桌面及移动端模拟 DOM,未重新完成其他宿主版本的端到端验证。
4
+
5
+ - 按中英文 aria-label 定位原生收起侧栏按钮,恢复显示和点击,不依赖按钮排列位置,不覆盖宿主明确隐藏或禁用的控件。
6
+ - 仅思考内容的助手节点移除气泡背景、边框、留白与头像,恢复普通过程行;混合正文仍保留聊天气泡。
7
+ - 不修改 DSH 官方核心代码,不增加运行时轮询。
@@ -1,4 +1,8 @@
1
1
  import { XIAOHEI_AVATAR_2D_FRONT } from '../generated-keyart.js';
2
+ // AssistantMarkdown > body > ProcessReasoning > ReasoningRow. Require the
3
+ // reasoning wrapper to be the only body child: mixed replies/images/interrupted
4
+ // messages keep their bubble. No hashed classes or nested :has selectors.
5
+ const thinkingOnlyRow = `#root [data-chat-flow-kind='assistant-step']:has(> [data-slot='conversation.chat.node'] > div:first-child > div:only-child > div:only-child > [data-variant='think']:only-child)`;
2
6
  /** Native conversation messages restyled without changing their DOM contract. */
3
7
  export const XIAOHEI_CONVERSATION_MESSAGES_CSS = `
4
8
  /* Keep DSH's native max width; only tune vertical reading rhythm. */
@@ -10,6 +14,24 @@ export const XIAOHEI_CONVERSATION_MESSAGES_CSS = `
10
14
  color: var(--xiaohei-conversation-text);
11
15
  }
12
16
 
17
+ ${thinkingOnlyRow} {
18
+ padding-inline: 0 !important;
19
+ }
20
+
21
+ ${thinkingOnlyRow}::before {
22
+ content: none !important;
23
+ display: none !important;
24
+ }
25
+
26
+ ${thinkingOnlyRow} > [data-slot='conversation.chat.node'] > div:first-child {
27
+ inline-size: 100% !important;
28
+ padding: 0 !important;
29
+ border: 0 !important;
30
+ border-radius: 0 !important;
31
+ background: transparent !important;
32
+ box-shadow: none !important;
33
+ }
34
+
13
35
  /* Message portraits are deliberately static and only identify the speaker. */
14
36
  #root [data-chat-flow-kind='assistant-step'],
15
37
  #root [data-chat-flow-kind='user'] {
@@ -1,3 +1,3 @@
1
1
  /** One glass surface over DSH's native sidebar geometry and controls. */
2
- export declare const XIAOHEI_SIDEBAR_CSS = "\n/* The layout column and SidebarRoot both consume the native sidebar fill.\n * The theme token makes those surfaces transparent; this stable slot\n * relationship removes the layout column's remaining straight divider. */\n#root :has(> [data-slot='sidebar']) {\n background: transparent !important;\n border-right-color: transparent !important;\n}\n\n#root [data-slot='sidebar'] {\n position: relative;\n}\n\n/* Reveal wide navigation only after its column has reached the target width.\n * Keep the toggle itself native. Opacity is applied to content, never the shell\n * (which also hosts fixed-position settings dialogs). */\n@media (prefers-reduced-motion: no-preference) {\n #root [data-xiaohei-sidebar-reveal] [data-xiaohei-sidebar-brand] {\n transition: opacity 100ms ease-out;\n }\n #root [data-xiaohei-sidebar-reveal='waiting'] [data-xiaohei-sidebar-brand] {\n opacity: 0 !important;\n visibility: hidden;\n transition: none;\n }\n}\n\n/* Hide the tree scrollbar's paint, retaining its gutter so rows do not grow\n * into the glass edge. Wheel, touch and keyboard remain native; dialogs and\n * other plugin panels keep their normal scrollbar affordance. */\n#root [data-slot='sidebar.workspaces'] [role='tree'] {\n scrollbar-color: transparent transparent !important;\n}\n\n#root [data-slot='sidebar.workspaces'] [role='tree']::-webkit-scrollbar,\n#root [data-slot='sidebar.workspaces'] [role='tree']::-webkit-scrollbar-thumb,\n#root [data-slot='sidebar.workspaces'] [role='tree']::-webkit-scrollbar-track {\n background: transparent !important;\n border-color: transparent !important;\n box-shadow: none !important;\n}\n\n/* The host shell remains paint- and filter-free because Settings is a fixed\n * descendant. The glass itself lives outside #root in the scene layer. */\n#root [data-slot='sidebar'] > div {\n --dsh-sidebar-inline-padding: 18px;\n position: relative;\n background: transparent !important;\n border-right: 0;\n box-shadow: none;\n}\n\n#dsh-theme-xiaohei\\/sidebar-glass {\n position: absolute;\n box-sizing: border-box;\n left: var(--xiaohei-sidebar-glass-left, 7px);\n top: var(--xiaohei-sidebar-glass-top, 8px);\n width: var(--xiaohei-sidebar-glass-width, 0px);\n height: var(--xiaohei-sidebar-glass-height, 0px);\n pointer-events: none;\n overflow: hidden;\n border: 1px solid var(--xiaohei-sidebar-glass-edge);\n border-radius: var(--xiaohei-sidebar-glass-radius);\n background: var(--xiaohei-sidebar-glass-fill);\n box-shadow:\n inset 0 1px var(--xiaohei-sidebar-glass-highlight),\n inset 1px 0 var(--xiaohei-sidebar-glass-refraction),\n 0 18px 50px -32px var(--xiaohei-sidebar-shadow);\n -webkit-backdrop-filter:\n blur(var(--xiaohei-sidebar-glass-blur))\n saturate(var(--xiaohei-sidebar-glass-saturation));\n backdrop-filter:\n blur(var(--xiaohei-sidebar-glass-blur))\n saturate(var(--xiaohei-sidebar-glass-saturation));\n}\n\n/* Width dragging changes the full-height glass raster every frame. Suspend\n * only the filters while geometry is moving; the translucent surface remains\n * visible and the settled glass returns after the resize gesture ends. */\nhtml[data-xiaohei-sidebar-resizing] #dsh-theme-xiaohei\\/sidebar-glass {\n -webkit-backdrop-filter: none;\n backdrop-filter: none;\n}\n\n/* One restrained inner rim completes the glass edge without tinting content. */\n#dsh-theme-xiaohei\\/sidebar-glass::after {\n content: '';\n position: absolute;\n pointer-events: none;\n inset: 1px;\n border-radius: calc(var(--xiaohei-sidebar-glass-radius) - 1px);\n box-shadow:\n inset 0 1px var(--xiaohei-sidebar-glass-refraction),\n inset 0 -20px 28px -32px var(--xiaohei-sidebar-shadow-soft);\n}\n\n/* The official brand slot owns geometry in both the wide sidebar and rail.\n * The bitmap remains visible as a no-WebGL fallback while the compact\n * MetallicPaint canvas adds a restrained liquid-metal pass above it. */\n.xiaohei-brand-mark {\n position: relative;\n display: inline-grid;\n flex: none;\n place-items: center;\n width: var(--xiaohei-brand-mark-size);\n height: var(--xiaohei-brand-mark-size);\n margin: -2px;\n overflow: visible;\n pointer-events: none;\n filter: drop-shadow(0 2px 3px rgb(8 13 15 / 18%));\n transform: translateY(-1px);\n}\n\n.xiaohei-brand-mark__fallback,\n.xiaohei-brand-mark__metal {\n position: absolute;\n inset: 0;\n display: block;\n width: 100%;\n height: 100%;\n object-fit: contain;\n}\n\n.xiaohei-brand-mark__fallback {\n opacity: .94;\n transition: opacity var(--xiaohei-motion-base) ease;\n}\n\n.xiaohei-brand-mark__metal {\n opacity: 0;\n transition:\n opacity var(--xiaohei-motion-base) ease,\n filter var(--xiaohei-motion-base) ease;\n}\n\n.xiaohei-brand-mark[data-metallic-ready='true'] .xiaohei-brand-mark__fallback {\n opacity: .28;\n}\n\n.xiaohei-brand-mark[data-metallic-ready='true'] .xiaohei-brand-mark__metal {\n opacity: .92;\n}\n\n.xiaohei-brand-name {\n white-space: nowrap;\n letter-spacing: .025em;\n font-size: 17px;\n font-weight: 600;\n}\n\n/* ui-conversation currently exposes the Hero mark but not its headline as a\n * slot. Anchor the visual copy to that official mark occupant so hashed Host\n * class names and unrelated headings remain untouched. */\n#root span:has(> .xiaohei-brand-mark[data-brand-context='hero']) + span {\n font-size: 0;\n}\n\n#root span:has(> .xiaohei-brand-mark[data-brand-context='hero']) + span::after {\n content: '\u4E07\u7269\u6709\u7075\uFF0C\u81EA\u5728\u540C\u884C';\n font-size: 26px;\n font-weight: 500;\n line-height: 32px;\n}\n\n#root [data-slot='sidebar'] button:hover .xiaohei-brand-mark__metal {\n filter: brightness(1.12) contrast(1.04);\n}\n\n/* Keep native rail/wide geometry and one consistent control material. */\n#root [data-slot='sidebar'] button:is([aria-label='Collapse sidebar'], [aria-label='\u6536\u8D77\u4FA7\u8FB9\u680F']),\n#root [data-slot='sidebar'] > div:has(button:is([aria-label='Collapse sidebar'], [aria-label='\u6536\u8D77\u4FA7\u8FB9\u680F'])) > button[aria-label='\u65B0\u5EFA\u4F1A\u8BDD'],\n#root [data-slot='sidebar'] > div:has(button:is([aria-label='Collapse sidebar'], [aria-label='\u6536\u8D77\u4FA7\u8FB9\u680F'])) > button[aria-label='New session'] {\n color: var(--xiaohei-sidebar-emphasis);\n transition:\n background-color var(--xiaohei-motion-fast) ease,\n border-color var(--xiaohei-motion-fast) ease,\n transform var(--xiaohei-motion-fast) var(--xiaohei-motion-curve);\n}\n\n#root [data-slot='sidebar'] button:is([aria-label='Collapse sidebar'], [aria-label='\u6536\u8D77\u4FA7\u8FB9\u680F']):hover {\n background: var(--xiaohei-sidebar-hover);\n}\n\n#root [data-slot='sidebar'] > div:has(button:is([aria-label='Collapse sidebar'], [aria-label='\u6536\u8D77\u4FA7\u8FB9\u680F'])) > button[aria-label='\u65B0\u5EFA\u4F1A\u8BDD'],\n#root [data-slot='sidebar'] > div:has(button:is([aria-label='Collapse sidebar'], [aria-label='\u6536\u8D77\u4FA7\u8FB9\u680F'])) > button[aria-label='New session'] {\n border: 1px solid var(--xiaohei-sidebar-control-edge);\n border-radius: var(--xiaohei-radius-control);\n background: var(--xiaohei-sidebar-control);\n box-shadow: inset 0 1px var(--xiaohei-sidebar-control-highlight);\n justify-content: flex-start;\n gap: 8px;\n padding-inline: 12px;\n text-align: start;\n}\n\n#root [data-slot='sidebar'] > div:has(button:is([aria-label='Collapse sidebar'], [aria-label='\u6536\u8D77\u4FA7\u8FB9\u680F'])) > button[aria-label='\u65B0\u5EFA\u4F1A\u8BDD']:hover,\n#root [data-slot='sidebar'] > div:has(button:is([aria-label='Collapse sidebar'], [aria-label='\u6536\u8D77\u4FA7\u8FB9\u680F'])) > button[aria-label='New session']:hover {\n border-color: var(--xiaohei-sidebar-control-edge-hover);\n background: var(--xiaohei-sidebar-hover);\n}\n\n/* The footer uses a divider instead of another framed card. */\n#root [data-slot='sidebar'] > div:has(button:is([aria-label='Collapse sidebar'], [aria-label='\u6536\u8D77\u4FA7\u8FB9\u680F']))\n > :has(> div > [data-slot='sidebar.footer.action']) {\n box-sizing: border-box;\n gap: 2px;\n margin-top: 8px;\n padding-top: 8px;\n border-top: 1px solid var(--xiaohei-sidebar-control-edge);\n}\n\n#root [data-slot='sidebar.footer.action'] > button,\n#root [data-slot='sidebar.settings'] > button {\n color: var(--dsw-alias-label-secondary);\n border-radius: var(--xiaohei-radius-small) !important;\n transition:\n color var(--xiaohei-motion-fast) ease,\n background-color var(--xiaohei-motion-fast) ease,\n transform var(--xiaohei-motion-fast) var(--xiaohei-motion-curve);\n}\n\n#root [data-slot='sidebar.footer.action'] > button:hover,\n#root [data-slot='sidebar.settings'] > button:hover,\n#root [data-slot='sidebar.footer.action'] > button[aria-expanded='true'],\n#root [data-slot='sidebar.settings'] > button[aria-expanded='true'] {\n color: var(--xiaohei-sidebar-emphasis);\n background: var(--xiaohei-sidebar-hover);\n}\n\n#root [data-slot='sidebar.footer.action'] > button:active,\n#root [data-slot='sidebar.settings'] > button:active {\n transform: translateY(1px);\n}\n\n#root [data-slot='sidebar'] button:focus-visible {\n outline: 2px solid var(--xiaohei-sidebar-emphasis);\n outline-offset: 2px;\n}\n\n@media (prefers-reduced-motion: reduce) {\n #root [data-slot='sidebar'] button {\n transition-duration: 0ms !important;\n }\n\n\n .xiaohei-brand-mark__fallback,\n .xiaohei-brand-mark__metal {\n transition-duration: 0ms !important;\n }\n}\n\n@media (prefers-reduced-transparency: reduce) {\n #dsh-theme-xiaohei\\/sidebar-glass {\n background: var(--xiaohei-sidebar-glass-solid);\n -webkit-backdrop-filter: none;\n backdrop-filter: none;\n }\n\n}\n\n@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {\n #dsh-theme-xiaohei\\/sidebar-glass {\n background: var(--xiaohei-sidebar-glass-solid);\n }\n}\n\n@media (forced-colors: active) {\n #dsh-theme-xiaohei\\/sidebar-glass {\n border-color: CanvasText;\n background: Canvas;\n box-shadow: none;\n -webkit-backdrop-filter: none;\n backdrop-filter: none;\n }\n\n #root [data-slot='sidebar'] > div:has(button:is([aria-label='Collapse sidebar'], [aria-label='\u6536\u8D77\u4FA7\u8FB9\u680F'])) > button[aria-label='\u65B0\u5EFA\u4F1A\u8BDD'],\n #root [data-slot='sidebar'] > div:has(button:is([aria-label='Collapse sidebar'], [aria-label='\u6536\u8D77\u4FA7\u8FB9\u680F'])) > button[aria-label='New session'] {\n border-color: ButtonText;\n }\n\n}\n";
2
+ export declare const XIAOHEI_SIDEBAR_CSS = "\n/* The layout column and SidebarRoot both consume the native sidebar fill.\n * The theme token makes those surfaces transparent; this stable slot\n * relationship removes the layout column's remaining straight divider. */\n#root :has(> [data-slot='sidebar']) {\n background: transparent !important;\n border-right-color: transparent !important;\n}\n\n#root [data-slot='sidebar'] {\n position: relative;\n}\n\n/* Target the native control by its accessible identity, not DOM order.\n * Do not resurrect controls explicitly hidden/disabled by the Host. */\n#root [data-slot='sidebar'] button:is([aria-label='Collapse sidebar'], [aria-label='\u6536\u8D77\u4FA7\u8FB9\u680F']):not([hidden]):not([disabled]):not([aria-hidden='true']) {\n display: inline-flex !important;\n visibility: visible !important;\n opacity: 1 !important;\n pointer-events: auto !important;\n}\n\n/* Reveal wide navigation only after its column has reached the target width.\n * Keep the toggle itself native. Opacity is applied to content, never the shell\n * (which also hosts fixed-position settings dialogs). */\n@media (prefers-reduced-motion: no-preference) {\n #root [data-xiaohei-sidebar-reveal] [data-xiaohei-sidebar-brand] {\n transition: opacity 100ms ease-out;\n }\n #root [data-xiaohei-sidebar-reveal='waiting'] [data-xiaohei-sidebar-brand] {\n opacity: 0 !important;\n visibility: hidden;\n transition: none;\n }\n}\n\n/* Hide the tree scrollbar's paint, retaining its gutter so rows do not grow\n * into the glass edge. Wheel, touch and keyboard remain native; dialogs and\n * other plugin panels keep their normal scrollbar affordance. */\n#root [data-slot='sidebar.workspaces'] [role='tree'] {\n scrollbar-color: transparent transparent !important;\n}\n\n#root [data-slot='sidebar.workspaces'] [role='tree']::-webkit-scrollbar,\n#root [data-slot='sidebar.workspaces'] [role='tree']::-webkit-scrollbar-thumb,\n#root [data-slot='sidebar.workspaces'] [role='tree']::-webkit-scrollbar-track {\n background: transparent !important;\n border-color: transparent !important;\n box-shadow: none !important;\n}\n\n/* The host shell remains paint- and filter-free because Settings is a fixed\n * descendant. The glass itself lives outside #root in the scene layer. */\n#root [data-slot='sidebar'] > div {\n --dsh-sidebar-inline-padding: 18px;\n position: relative;\n background: transparent !important;\n border-right: 0;\n box-shadow: none;\n}\n\n#dsh-theme-xiaohei\\/sidebar-glass {\n position: absolute;\n box-sizing: border-box;\n left: var(--xiaohei-sidebar-glass-left, 7px);\n top: var(--xiaohei-sidebar-glass-top, 8px);\n width: var(--xiaohei-sidebar-glass-width, 0px);\n height: var(--xiaohei-sidebar-glass-height, 0px);\n pointer-events: none;\n overflow: hidden;\n border: 1px solid var(--xiaohei-sidebar-glass-edge);\n border-radius: var(--xiaohei-sidebar-glass-radius);\n background: var(--xiaohei-sidebar-glass-fill);\n box-shadow:\n inset 0 1px var(--xiaohei-sidebar-glass-highlight),\n inset 1px 0 var(--xiaohei-sidebar-glass-refraction),\n 0 18px 50px -32px var(--xiaohei-sidebar-shadow);\n -webkit-backdrop-filter:\n blur(var(--xiaohei-sidebar-glass-blur))\n saturate(var(--xiaohei-sidebar-glass-saturation));\n backdrop-filter:\n blur(var(--xiaohei-sidebar-glass-blur))\n saturate(var(--xiaohei-sidebar-glass-saturation));\n}\n\n/* Width dragging changes the full-height glass raster every frame. Suspend\n * only the filters while geometry is moving; the translucent surface remains\n * visible and the settled glass returns after the resize gesture ends. */\nhtml[data-xiaohei-sidebar-resizing] #dsh-theme-xiaohei\\/sidebar-glass {\n -webkit-backdrop-filter: none;\n backdrop-filter: none;\n}\n\n/* One restrained inner rim completes the glass edge without tinting content. */\n#dsh-theme-xiaohei\\/sidebar-glass::after {\n content: '';\n position: absolute;\n pointer-events: none;\n inset: 1px;\n border-radius: calc(var(--xiaohei-sidebar-glass-radius) - 1px);\n box-shadow:\n inset 0 1px var(--xiaohei-sidebar-glass-refraction),\n inset 0 -20px 28px -32px var(--xiaohei-sidebar-shadow-soft);\n}\n\n/* The official brand slot owns geometry in both the wide sidebar and rail.\n * The bitmap remains visible as a no-WebGL fallback while the compact\n * MetallicPaint canvas adds a restrained liquid-metal pass above it. */\n.xiaohei-brand-mark {\n position: relative;\n display: inline-grid;\n flex: none;\n place-items: center;\n width: var(--xiaohei-brand-mark-size);\n height: var(--xiaohei-brand-mark-size);\n margin: -2px;\n overflow: visible;\n pointer-events: none;\n filter: drop-shadow(0 2px 3px rgb(8 13 15 / 18%));\n transform: translateY(-1px);\n}\n\n.xiaohei-brand-mark__fallback,\n.xiaohei-brand-mark__metal {\n position: absolute;\n inset: 0;\n display: block;\n width: 100%;\n height: 100%;\n object-fit: contain;\n}\n\n.xiaohei-brand-mark__fallback {\n opacity: .94;\n transition: opacity var(--xiaohei-motion-base) ease;\n}\n\n.xiaohei-brand-mark__metal {\n opacity: 0;\n transition:\n opacity var(--xiaohei-motion-base) ease,\n filter var(--xiaohei-motion-base) ease;\n}\n\n.xiaohei-brand-mark[data-metallic-ready='true'] .xiaohei-brand-mark__fallback {\n opacity: .28;\n}\n\n.xiaohei-brand-mark[data-metallic-ready='true'] .xiaohei-brand-mark__metal {\n opacity: .92;\n}\n\n.xiaohei-brand-name {\n white-space: nowrap;\n letter-spacing: .025em;\n font-size: 17px;\n font-weight: 600;\n}\n\n/* ui-conversation currently exposes the Hero mark but not its headline as a\n * slot. Anchor the visual copy to that official mark occupant so hashed Host\n * class names and unrelated headings remain untouched. */\n#root span:has(> .xiaohei-brand-mark[data-brand-context='hero']) + span {\n font-size: 0;\n}\n\n#root span:has(> .xiaohei-brand-mark[data-brand-context='hero']) + span::after {\n content: '\u4E07\u7269\u6709\u7075\uFF0C\u81EA\u5728\u540C\u884C';\n font-size: 26px;\n font-weight: 500;\n line-height: 32px;\n}\n\n#root [data-slot='sidebar'] button:hover .xiaohei-brand-mark__metal {\n filter: brightness(1.12) contrast(1.04);\n}\n\n/* Keep native rail/wide geometry and one consistent control material. */\n#root [data-slot='sidebar'] button:is([aria-label='Collapse sidebar'], [aria-label='\u6536\u8D77\u4FA7\u8FB9\u680F']),\n#root [data-slot='sidebar'] > div:has(button:is([aria-label='Collapse sidebar'], [aria-label='\u6536\u8D77\u4FA7\u8FB9\u680F'])) > button[aria-label='\u65B0\u5EFA\u4F1A\u8BDD'],\n#root [data-slot='sidebar'] > div:has(button:is([aria-label='Collapse sidebar'], [aria-label='\u6536\u8D77\u4FA7\u8FB9\u680F'])) > button[aria-label='New session'] {\n color: var(--xiaohei-sidebar-emphasis);\n transition:\n background-color var(--xiaohei-motion-fast) ease,\n border-color var(--xiaohei-motion-fast) ease,\n transform var(--xiaohei-motion-fast) var(--xiaohei-motion-curve);\n}\n\n#root [data-slot='sidebar'] button:is([aria-label='Collapse sidebar'], [aria-label='\u6536\u8D77\u4FA7\u8FB9\u680F']):hover {\n background: var(--xiaohei-sidebar-hover);\n}\n\n#root [data-slot='sidebar'] > div:has(button:is([aria-label='Collapse sidebar'], [aria-label='\u6536\u8D77\u4FA7\u8FB9\u680F'])) > button[aria-label='\u65B0\u5EFA\u4F1A\u8BDD'],\n#root [data-slot='sidebar'] > div:has(button:is([aria-label='Collapse sidebar'], [aria-label='\u6536\u8D77\u4FA7\u8FB9\u680F'])) > button[aria-label='New session'] {\n border: 1px solid var(--xiaohei-sidebar-control-edge);\n border-radius: var(--xiaohei-radius-control);\n background: var(--xiaohei-sidebar-control);\n box-shadow: inset 0 1px var(--xiaohei-sidebar-control-highlight);\n justify-content: flex-start;\n gap: 8px;\n padding-inline: 12px;\n text-align: start;\n}\n\n#root [data-slot='sidebar'] > div:has(button:is([aria-label='Collapse sidebar'], [aria-label='\u6536\u8D77\u4FA7\u8FB9\u680F'])) > button[aria-label='\u65B0\u5EFA\u4F1A\u8BDD']:hover,\n#root [data-slot='sidebar'] > div:has(button:is([aria-label='Collapse sidebar'], [aria-label='\u6536\u8D77\u4FA7\u8FB9\u680F'])) > button[aria-label='New session']:hover {\n border-color: var(--xiaohei-sidebar-control-edge-hover);\n background: var(--xiaohei-sidebar-hover);\n}\n\n/* The footer uses a divider instead of another framed card. */\n#root [data-slot='sidebar'] > div:has(button:is([aria-label='Collapse sidebar'], [aria-label='\u6536\u8D77\u4FA7\u8FB9\u680F']))\n > :has(> div > [data-slot='sidebar.footer.action']) {\n box-sizing: border-box;\n gap: 2px;\n margin-top: 8px;\n padding-top: 8px;\n border-top: 1px solid var(--xiaohei-sidebar-control-edge);\n}\n\n#root [data-slot='sidebar.footer.action'] > button,\n#root [data-slot='sidebar.settings'] > button {\n color: var(--dsw-alias-label-secondary);\n border-radius: var(--xiaohei-radius-small) !important;\n transition:\n color var(--xiaohei-motion-fast) ease,\n background-color var(--xiaohei-motion-fast) ease,\n transform var(--xiaohei-motion-fast) var(--xiaohei-motion-curve);\n}\n\n#root [data-slot='sidebar.footer.action'] > button:hover,\n#root [data-slot='sidebar.settings'] > button:hover,\n#root [data-slot='sidebar.footer.action'] > button[aria-expanded='true'],\n#root [data-slot='sidebar.settings'] > button[aria-expanded='true'] {\n color: var(--xiaohei-sidebar-emphasis);\n background: var(--xiaohei-sidebar-hover);\n}\n\n#root [data-slot='sidebar.footer.action'] > button:active,\n#root [data-slot='sidebar.settings'] > button:active {\n transform: translateY(1px);\n}\n\n#root [data-slot='sidebar'] button:focus-visible {\n outline: 2px solid var(--xiaohei-sidebar-emphasis);\n outline-offset: 2px;\n}\n\n@media (prefers-reduced-motion: reduce) {\n #root [data-slot='sidebar'] button {\n transition-duration: 0ms !important;\n }\n\n\n .xiaohei-brand-mark__fallback,\n .xiaohei-brand-mark__metal {\n transition-duration: 0ms !important;\n }\n}\n\n@media (prefers-reduced-transparency: reduce) {\n #dsh-theme-xiaohei\\/sidebar-glass {\n background: var(--xiaohei-sidebar-glass-solid);\n -webkit-backdrop-filter: none;\n backdrop-filter: none;\n }\n\n}\n\n@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {\n #dsh-theme-xiaohei\\/sidebar-glass {\n background: var(--xiaohei-sidebar-glass-solid);\n }\n}\n\n@media (forced-colors: active) {\n #dsh-theme-xiaohei\\/sidebar-glass {\n border-color: CanvasText;\n background: Canvas;\n box-shadow: none;\n -webkit-backdrop-filter: none;\n backdrop-filter: none;\n }\n\n #root [data-slot='sidebar'] > div:has(button:is([aria-label='Collapse sidebar'], [aria-label='\u6536\u8D77\u4FA7\u8FB9\u680F'])) > button[aria-label='\u65B0\u5EFA\u4F1A\u8BDD'],\n #root [data-slot='sidebar'] > div:has(button:is([aria-label='Collapse sidebar'], [aria-label='\u6536\u8D77\u4FA7\u8FB9\u680F'])) > button[aria-label='New session'] {\n border-color: ButtonText;\n }\n\n}\n";
3
3
  //# sourceMappingURL=sidebar.d.ts.map
@@ -12,6 +12,15 @@ export const XIAOHEI_SIDEBAR_CSS = `
12
12
  position: relative;
13
13
  }
14
14
 
15
+ /* Target the native control by its accessible identity, not DOM order.
16
+ * Do not resurrect controls explicitly hidden/disabled by the Host. */
17
+ #root [data-slot='sidebar'] button:is([aria-label='Collapse sidebar'], [aria-label='收起侧边栏']):not([hidden]):not([disabled]):not([aria-hidden='true']) {
18
+ display: inline-flex !important;
19
+ visibility: visible !important;
20
+ opacity: 1 !important;
21
+ pointer-events: auto !important;
22
+ }
23
+
15
24
  /* Reveal wide navigation only after its column has reached the target width.
16
25
  * Keep the toggle itself native. Opacity is applied to content, never the shell
17
26
  * (which also hosts fixed-position settings dialogs). */
package/lib/client.js CHANGED
@@ -850,6 +850,7 @@ var XIAOHEI_HEIXIU_OPEN = "data:image/webp;base64,UklGRtYUAABXRUJQVlA4WAoAAAASAA
850
850
  var XIAOHEI_HEIXIU_BLINK = "data:image/webp;base64,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";
851
851
 
852
852
  // src/chrome/conversation-messages.ts
853
+ var thinkingOnlyRow = `#root [data-chat-flow-kind='assistant-step']:has(> [data-slot='conversation.chat.node'] > div:first-child > div:only-child > div:only-child > [data-variant='think']:only-child)`;
853
854
  var XIAOHEI_CONVERSATION_MESSAGES_CSS = `
854
855
  /* Keep DSH's native max width; only tune vertical reading rhythm. */
855
856
  #root [data-chat-flow] {
@@ -860,6 +861,24 @@ var XIAOHEI_CONVERSATION_MESSAGES_CSS = `
860
861
  color: var(--xiaohei-conversation-text);
861
862
  }
862
863
 
864
+ ${thinkingOnlyRow} {
865
+ padding-inline: 0 !important;
866
+ }
867
+
868
+ ${thinkingOnlyRow}::before {
869
+ content: none !important;
870
+ display: none !important;
871
+ }
872
+
873
+ ${thinkingOnlyRow} > [data-slot='conversation.chat.node'] > div:first-child {
874
+ inline-size: 100% !important;
875
+ padding: 0 !important;
876
+ border: 0 !important;
877
+ border-radius: 0 !important;
878
+ background: transparent !important;
879
+ box-shadow: none !important;
880
+ }
881
+
863
882
  /* Message portraits are deliberately static and only identify the speaker. */
864
883
  #root [data-chat-flow-kind='assistant-step'],
865
884
  #root [data-chat-flow-kind='user'] {
@@ -1438,6 +1457,15 @@ var XIAOHEI_SIDEBAR_CSS = `
1438
1457
  position: relative;
1439
1458
  }
1440
1459
 
1460
+ /* Target the native control by its accessible identity, not DOM order.
1461
+ * Do not resurrect controls explicitly hidden/disabled by the Host. */
1462
+ #root [data-slot='sidebar'] button:is([aria-label='Collapse sidebar'], [aria-label='\u6536\u8D77\u4FA7\u8FB9\u680F']):not([hidden]):not([disabled]):not([aria-hidden='true']) {
1463
+ display: inline-flex !important;
1464
+ visibility: visible !important;
1465
+ opacity: 1 !important;
1466
+ pointer-events: auto !important;
1467
+ }
1468
+
1441
1469
  /* Reveal wide navigation only after its column has reached the target width.
1442
1470
  * Keep the toggle itself native. Opacity is applied to content, never the shell
1443
1471
  * (which also hosts fixed-position settings dialogs). */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lemoncat7/dsh-theme-xiaohei",
3
- "version": "0.3.4",
3
+ "version": "0.3.5",
4
4
  "description": "A Luo Xiaohei-inspired animated dark theme for DeepSeek Harness",
5
5
  "keywords": [
6
6
  "deepseek-harness",
@@ -30,6 +30,7 @@
30
30
  "lib/**/*.d.ts",
31
31
  "cordis.patch.yml",
32
32
  "README.md",
33
+ "docs/releases/0.3.5.md",
33
34
  "THIRD_PARTY_NOTICES.md",
34
35
  "LICENSE"
35
36
  ],