@ash-qw/dsh-theme-prts 2.1.0 → 2.2.0

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.
@@ -59,7 +59,7 @@ function settingButtons(key, label, options) {
59
59
  : key === 'sessionFlowPalette'
60
60
  ? '<small data-prts-setting-note>同时适配日间与夜间模式</small>'
61
61
  : ''
62
- if (['composerGlass', 'bakerLoading', 'motion', 'cursor', 'railDefaultHidden', 'sessionFlow', 'sessionGlow', 'bakerGroupAvatars', 'conversationEmblem', 'sessionPreview', 'previewOngoing', 'previewWarning', 'previewDone', 'previewDoubleClick', 'previewFollowOngoing', 'previewFollowWarning'].includes(key)) return `<div data-prts-setting-row="${key}">
62
+ if (['composerGlass', 'bakerLoading', 'motion', 'cursor', 'railDefaultHidden', 'sessionFlow', 'sessionGlow', 'bakerGroupAvatars', 'conversationEmblem', 'sessionPreview', 'aiToolsEnabled', 'previewOngoing', 'previewTools', 'previewWarning', 'previewDone', 'previewDoubleClick', 'previewFollowOngoing', 'previewFollowWarning'].includes(key)) return `<div data-prts-setting-row="${key}">
63
63
  <span><strong>${label}</strong>${note}</span>
64
64
  <button type="button" role="switch" aria-label="${label}" aria-checked="false" data-prts-setting-switch="${key}" ${key === 'cursor' ? 'data-prts-cursor-switch' : ''}><span aria-hidden="true"></span></button>
65
65
  </div>`
@@ -127,6 +127,7 @@ export function themeSettingsMarkup() {
127
127
  <button type="button" data-prts-settings-jump="flow" role="tab" id="prts-tab-flow" aria-controls="prts-page-flow" aria-selected="false" tabindex="-1">会话流线</button>
128
128
  <button type="button" data-prts-settings-jump="particles" role="tab" id="prts-tab-particles" aria-controls="prts-page-particles" aria-selected="false" tabindex="-1">粒子徽记</button>
129
129
  <button type="button" data-prts-settings-jump="assistance" role="tab" id="prts-tab-assistance" aria-controls="prts-page-assistance" aria-selected="false" tabindex="-1">辅助功能</button>
130
+ <button type="button" data-prts-settings-jump="ai-tools" role="tab" id="prts-tab-ai-tools" aria-controls="prts-page-ai-tools" aria-selected="false" tabindex="-1">AI 工具</button>
130
131
  </nav>
131
132
  <footer data-prts-settings-actions aria-label="全局主题设置操作">
132
133
  <div data-prts-persistence-error hidden role="alert">
@@ -167,6 +168,33 @@ export function themeSettingsMarkup() {
167
168
  ${COMMON_CONTROLS.filter(([key]) => ['cursor', 'railDefaultHidden', 'motion'].includes(key)).map(([key, label, options]) => settingButtons(key, label, options)).join('')}
168
169
  </div>
169
170
  </section>
171
+ <section data-prts-settings-section="ai-tools" data-prts-ai-tools role="tabpanel" id="prts-page-ai-tools" aria-labelledby="prts-tab-ai-tools" tabindex="0" hidden>
172
+ <div data-prts-preview-settings><div data-prts-preview-master>
173
+ ${previewSetting('aiToolsEnabled', '允许 AI 定制主题', '默认开启 · 共 5 个工具 · 影响此 DSH 实例的所有会话')}
174
+ </div></div>
175
+ <p>开启后,AI 可以通过工具调整粒子徽记和 Baker 头像。关闭后,后续模型请求不再提供这些工具,手动设置不受影响;已有对话中的工具记录不会删除。</p>
176
+ <section>
177
+ <h3>粒子徽记 <small>3 个工具</small></h3>
178
+ <p>将会话中的图片制作成粒子徽记,用于新会话页面或正文轮换。</p>
179
+ <ol><li>上传图片,或让 AI 读取已生成的图片。</li><li>让 AI 制作草稿,调整轮廓、位置和缩放,先查看预览。</li><li>满意后明确要求应用到新会话徽记,或加入正文轮换。</li></ol>
180
+ <blockquote>“把这张图片做成粒子徽记,先给我看看效果。”</blockquote>
181
+ <details><summary>工具说明与限制</summary><dl>
182
+ <dt><code>prts_emblem_inspect</code></dt><dd>查看徽记配置、版本与当前会话的可用图片,不修改设置。</dd>
183
+ <dt><code>prts_emblem_preview</code></dt><dd>制作或调整粒子徽记草稿,只生成预览,不直接应用。</dd>
184
+ <dt><code>prts_emblem_apply</code></dt><dd>经你确认后,替换新会话徽记,或添加、替换正文轮换徽记。</dd>
185
+ </dl><p>单张来源图片最大 8 MB。徽记设置跨工作区和会话共享。粒子预览不等同于原图;配置发生变化时,AI 需要重新核对后再应用。</p></details>
186
+ </section>
187
+ <section>
188
+ <h3>Baker 头像 <small>2 个工具</small></h3>
189
+ <p>为用户和 AI 设置头像,调整圆形裁剪,或恢复默认头像。仅在 Baker 会话样式下显示。</p>
190
+ <ol><li>上传图片,说明要修改用户头像还是 AI 头像。</li><li>让 AI 查看当前配置,再按你的要求替换、裁剪或恢复默认。</li></ol>
191
+ <blockquote>“把这张图片设为 AI 头像,居中裁剪。”</blockquote>
192
+ <details><summary>工具说明与限制</summary><dl>
193
+ <dt><code>prts_avatar_inspect</code></dt><dd>查看头像配置、原图尺寸、裁剪参数及会话图片,不修改设置。</dd>
194
+ <dt><code>prts_avatar_apply</code></dt><dd>替换用户或 AI 头像、基于现有原图重新裁剪,或恢复默认头像。</dd>
195
+ </dl><p>单图最大 5 MB、2500 万像素;裁剪支持 1~4 倍缩放。修改立即影响此实例所有会话,不会自动切换会话样式。替换后不保留旧原图;恢复默认会删除自定义原图。</p></details>
196
+ </section>
197
+ </section>
170
198
  <section data-prts-settings-section="assistance" role="tabpanel" id="prts-page-assistance" aria-labelledby="prts-tab-assistance" tabindex="0" hidden>
171
199
  <section data-prts-preview-settings>
172
200
  <div data-prts-preview-master>
@@ -177,6 +205,7 @@ export function themeSettingsMarkup() {
177
205
  <header><strong>悬停预览</strong><small>选择哪些状态显示详细浮窗</small></header>
178
206
  ${previewSetting('previewOngoing', '运行中预览', '逐轮查看已完成的回复,最新内容置顶')}
179
207
  <div data-prts-preview-details="previewOngoing">
208
+ ${previewSetting('previewTools', '显示工具调用', '显示工具进度,悬停查看最新正文之后的调用记录')}
180
209
  <label data-prts-setting-row="previewReplyLimit"><span><strong>回复条数</strong><small data-prts-preview-setting-description>仅保留最新回复</small></span><select data-prts-preview-reply-limit aria-label="最多显示回复"><option value="5">最新 5 条</option><option value="10">最新 10 条</option><option value="0">不限制</option></select></label>
181
210
  ${previewSetting('previewFollowOngoing', '运行结束后跟随', '转为待处理或已完成时,自动切换预览')}
182
211
  </div>
package/src/index.js CHANGED
@@ -19,7 +19,7 @@ export const Config = Schema.object(Object.fromEntries([
19
19
  ['preferencesInitialized', Schema.boolean().default(false).volatile()],
20
20
  ]))
21
21
 
22
- export async function apply(ctx) {
22
+ export async function apply(ctx, config = {}) {
23
23
  ctx.inject(['settings'], settingsCtx => {
24
24
  settingsCtx.effect(() => settingsCtx.settings.configure({ auto: false }, ctx.fiber))
25
25
  })
@@ -27,7 +27,24 @@ export async function apply(ctx) {
27
27
  const service=await createEmblemService(directory)
28
28
  const backgrounds=await createBackgroundService(join(directory,'..','backgrounds'))
29
29
  const avatars=await createAvatarService(join(directory,'..','avatars'))
30
- const disposers=[...emblemTools(service,ctx.attachments),...avatarTools(avatars,ctx.attachments)].map(tool=>ctx.tools.register(tool))
31
- disposers.push(registerEmblemApi(ctx,service),registerAvatarApi(ctx,avatars),registerBackgroundApi(ctx,backgrounds))
32
- ctx.effect(()=>async()=>{for(const dispose of disposers.reverse())dispose();await service.dispose();await backgrounds.dispose()})
30
+ const definitions=[...emblemTools(service,ctx.attachments),...avatarTools(avatars,ctx.attachments)]
31
+ let toolDisposers=[]
32
+ const syncTools=()=>{
33
+ const enabled=(config.aiToolsEnabled?.get?.() ?? config.aiToolsEnabled) !== false
34
+ if(enabled && !toolDisposers.length) {
35
+ for(const tool of definitions)toolDisposers.push(ctx.tools.register(tool))
36
+ } else if(!enabled) {
37
+ for(const dispose of toolDisposers.splice(0).reverse())dispose()
38
+ }
39
+ }
40
+ syncTools()
41
+ // Host volatile fields are updated before this notification; they expose get(), not subscribe().
42
+ const stopConfig=ctx.on('app-boot/config-reload',syncTools)
43
+ const disposers=[registerEmblemApi(ctx,service),registerAvatarApi(ctx,avatars),registerBackgroundApi(ctx,backgrounds)]
44
+ ctx.effect(()=>async()=>{
45
+ stopConfig()
46
+ for(const dispose of toolDisposers.splice(0).reverse())dispose()
47
+ for(const dispose of disposers.reverse())dispose()
48
+ await service.dispose();await backgrounds.dispose()
49
+ })
33
50
  }
@@ -1,14 +1,18 @@
1
- /* Full mode uses one viewport-aligned image, so the two regions never crop independently. */
1
+ /* Viewport-aligned wallpaper. */
2
2
  html[data-dsh-prts] { --prts-background-wash: color-mix(in srgb, var(--prts-canvas) var(--prts-background-shade, 45%), transparent); }
3
3
  html[data-dsh-prts][data-prts-background-mode="full"][data-prts-background-full] :is([data-prts-region="frame"], [data-prts-nav-rail]) {
4
- background: linear-gradient(var(--prts-background-wash), var(--prts-background-wash)), var(--prts-background-full) center / cover fixed;
4
+ background: linear-gradient(var(--prts-background-wash), var(--prts-background-wash)), var(--prts-background-full) center / cover fixed;
5
5
  }
6
6
  html[data-dsh-prts][data-prts-background-mode="full"][data-prts-background-full] :is([data-prts-region="sessions"], [data-prts-region="operation"]) { background: transparent; }
7
- html[data-dsh-prts][data-prts-background-mode="split"][data-prts-background-sidebar] [data-prts-region="sessions"] {
8
- background: linear-gradient(var(--prts-background-wash), var(--prts-background-wash)), var(--prts-background-sidebar) center / cover no-repeat;
7
+ html[data-dsh-prts][data-prts-background-mode="split"][data-prts-background-sidebar] {
8
+ --prts-wall-width:max(calc(var(--prts-sidebar-width,280px) + var(--prts-nav-width)),calc((100dvh - var(--prts-host-top-inset)) * var(--prts-sidebar-image-ratio,1)));
9
+ --prts-wall-x:calc((var(--prts-sidebar-width,280px) + var(--prts-nav-width) - var(--prts-wall-width)) / 2);
10
+ & :is([data-prts-region="sessions"],[data-prts-nav-rail]){background:linear-gradient(var(--prts-background-wash),var(--prts-background-wash)),var(--prts-background-sidebar) var(--prts-wall-x) center / var(--prts-wall-width) auto no-repeat}
11
+ & [data-prts-region="sessions"]{background-position:center,calc(var(--prts-wall-x) - var(--prts-nav-width)) center}
9
12
  }
13
+ html[data-dsh-prts][data-prts-rail-mode="overlay"]:is([data-prts-background-mode="split"][data-prts-background-sidebar],[data-prts-background-mode="full"][data-prts-background-full]) [data-prts-nav-rail] { background: transparent; }
10
14
  html[data-dsh-prts][data-prts-background-mode="split"][data-prts-background-conversation] [data-prts-region="operation"] {
11
- background: linear-gradient(var(--prts-background-wash), var(--prts-background-wash)), var(--prts-background-conversation) center / cover no-repeat;
15
+ background: linear-gradient(var(--prts-background-wash), var(--prts-background-wash)), var(--prts-background-conversation) center / cover no-repeat;
12
16
  }
13
17
  html[data-dsh-prts][data-prts-background-mode="full"][data-prts-background-full] [data-prts-ambient-layer],
14
18
  html[data-dsh-prts][data-prts-background-mode="split"][data-prts-background-conversation] [data-prts-ambient-layer] { display: none !important; }
@@ -47,9 +51,9 @@ html[data-dsh-prts][data-prts-background-mode="split"][data-prts-background-conv
47
51
  [data-prts-background-status]:empty { display: none; }
48
52
  [data-prts-background-settings] button:focus-visible { outline: 2px solid var(--prts-cyan); outline-offset: 3px; }
49
53
  @media (max-width: 600px) {
50
- [data-prts-background-modes] button { padding: 8px; }
51
- [data-prts-background-modes] button small { display: none; }
52
- [data-prts-background-images] { grid-template-columns: 1fr; }
54
+ [data-prts-background-modes] button { padding: 8px; }
55
+ [data-prts-background-modes] button small { display: none; }
56
+ [data-prts-background-images] { grid-template-columns: 1fr; }
53
57
  }
54
58
  [data-prts-background-settings] [hidden] { display: none !important; }
55
59
  /* Classic conversation roots keep their native surface unless an image is active. */
@@ -59,134 +63,135 @@ html[data-dsh-prts][data-prts-background-mode="split"][data-prts-background-conv
59
63
  html[data-dsh-prts][data-prts-background-mode="full"][data-prts-background-full] [data-prts-region="sessions"] [data-slot="sidebar.workspaces"] span[class$="_fade"],
60
64
  html[data-dsh-prts][data-prts-background-mode="split"][data-prts-background-sidebar] [data-prts-region="sessions"] [data-slot="sidebar.workspaces"] span[class$="_fade"] { display: none !important; }
61
65
 
62
- /* Paint glass behind sidebar controls, never filter their ancestor: fixed
63
- * settings/menus must retain their viewport positioning. The split-mode image
64
- * stays on the parent so this surface can blur it as well as the full wallpaper. */
66
+ /* Filter the plate, not the ancestor of fixed controls. */
65
67
  html[data-dsh-prts][data-prts-background-mode="full"][data-prts-background-full] [data-prts-region="sessions"]::before,
66
68
  html[data-dsh-prts][data-prts-background-mode="split"][data-prts-background-sidebar] [data-prts-region="sessions"]::before {
67
- content: "";
68
- position: absolute;
69
- inset: 0;
70
- z-index: 0;
71
- pointer-events: none;
72
- background: color-mix(in srgb, var(--prts-panel) var(--prts-sidebar-opacity, 6%), transparent);
73
- -webkit-backdrop-filter: blur(var(--prts-sidebar-blur, 8px)) saturate(1.15);
74
- backdrop-filter: blur(var(--prts-sidebar-blur, 8px)) saturate(1.15);
75
- box-shadow: inset -1px 0 color-mix(in srgb, var(--prts-ink) 10%, transparent), inset 0 1px rgb(255 255 255 / 8%);
76
- }
77
- /* The sidebar slot is display:contents and cannot establish a paint layer.
78
- * Raise its actual root so glass never blurs static plugin entries. */
69
+ content: "";
70
+ position: absolute;
71
+ inset: 0;
72
+ z-index: 0;
73
+ pointer-events: none;
74
+ background: color-mix(in srgb, var(--prts-panel) var(--prts-sidebar-opacity, 6%), transparent);
75
+ -webkit-backdrop-filter: blur(var(--prts-sidebar-blur, 8px)) saturate(1.15);
76
+ backdrop-filter: blur(var(--prts-sidebar-blur, 8px)) saturate(1.15);
77
+ box-shadow: inset -1px 0 color-mix(in srgb, var(--prts-ink) 10%, transparent), inset 0 1px rgb(255 255 255 / 8%);
78
+ }
79
+ /* Raise sidebar controls above glass. */
79
80
  html[data-dsh-prts][data-prts-background-mode="full"][data-prts-background-full] [data-prts-region="sessions"] [data-slot="sidebar"] > :first-child,
80
81
  html[data-dsh-prts][data-prts-background-mode="split"][data-prts-background-sidebar] [data-prts-region="sessions"] [data-slot="sidebar"] > :first-child {
81
- position: relative;
82
- z-index: 1;
82
+ position: relative;
83
+ z-index: 1;
83
84
  }
84
85
 
85
- /* The fixed rail already establishes a stacking context. Keep the glass below
86
- * every control without changing their positioning or tooltip geometry. */
87
- html[data-dsh-prts][data-prts-background-mode="full"][data-prts-background-full] [data-prts-nav-rail]::before {
88
- content: "";
89
- position: absolute;
90
- inset: 0;
91
- z-index: -1;
92
- pointer-events: none;
93
- background: color-mix(in srgb, var(--prts-panel) var(--prts-rail-opacity, 30%), transparent);
94
- -webkit-backdrop-filter: blur(var(--prts-rail-blur, 12px)) saturate(1.15);
95
- backdrop-filter: blur(var(--prts-rail-blur, 12px)) saturate(1.15);
96
- box-shadow: inset -1px 0 color-mix(in srgb, var(--prts-ink) 10%, transparent), inset 0 1px rgb(255 255 255 / 8%);
86
+ html[data-dsh-prts]:is([data-prts-background-mode="full"][data-prts-background-full],[data-prts-background-mode="split"][data-prts-background-sidebar]) {
87
+ /* Opacity on the parent isolates backdrop sampling during slide-in. */
88
+ &[data-prts-rail-mode="overlay"] [data-prts-nav-rail]{opacity:1;transition:transform 180ms var(--prts-ease-snap),visibility 0s linear 180ms}
89
+ &[data-prts-rail-mode="overlay"][data-prts-rail-open] [data-prts-nav-rail]{transition-delay:0s}
90
+ /* Glass stays below rail controls. */
91
+ & [data-prts-nav-rail]::before {
92
+ content: "";
93
+ position: absolute;
94
+ inset: 0;
95
+ z-index: -1;
96
+ pointer-events: none;
97
+ background: color-mix(in srgb, var(--prts-panel) var(--prts-rail-opacity, 30%), transparent);
98
+ -webkit-backdrop-filter: blur(var(--prts-rail-blur, 12px)) saturate(1.15);
99
+ backdrop-filter: blur(var(--prts-rail-blur, 12px)) saturate(1.15);
100
+ box-shadow: inset -1px 0 color-mix(in srgb, var(--prts-ink) 10%, transparent), inset 0 1px rgb(255 255 255 / 8%);
97
101
  }
98
102
 
99
103
  /* Glass rail feedback retains the wallpaper instead of switching to solid black. */
100
- html[data-dsh-prts][data-prts-background-mode="full"][data-prts-background-full] [data-prts-nav-rail] button {
101
- color: var(--prts-muted) !important;
102
- border-bottom-color: var(--prts-line);
103
- transition: background-color 140ms ease, box-shadow 140ms ease, color 140ms ease;
104
+ & [data-prts-nav-rail] button {
105
+ color: var(--prts-muted) !important;
106
+ border-bottom-color: var(--prts-line);
107
+ transition: background-color 140ms ease, box-shadow 140ms ease, color 140ms ease;
104
108
  }
105
- html[data-dsh-prts][data-prts-background-mode="full"][data-prts-background-full] [data-prts-nav-rail] button:is(:hover, :focus-visible, [aria-expanded="true"]) {
106
- background: color-mix(in srgb, var(--prts-panel-raised) 32%, transparent);
107
- color: var(--prts-ink) !important;
108
- box-shadow: inset 0 1px rgb(255 255 255 / 15%), inset 0 0 0 1px color-mix(in srgb, var(--prts-ink) 10%, transparent);
109
+ & [data-prts-nav-rail] button:is(:hover, :focus-visible, [aria-expanded="true"]) {
110
+ background: color-mix(in srgb, var(--prts-panel-raised) 32%, transparent);
111
+ color: var(--prts-ink) !important;
112
+ box-shadow: inset 0 1px rgb(255 255 255 / 15%), inset 0 0 0 1px color-mix(in srgb, var(--prts-ink) 10%, transparent);
109
113
  }
110
- html[data-dsh-prts][data-prts-background-mode="full"][data-prts-background-full] [data-prts-nav-rail] button:active {
111
- background: color-mix(in srgb, var(--prts-panel-raised) 48%, transparent);
112
- box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--prts-ink) 18%, transparent);
114
+ & [data-prts-nav-rail] button:active {
115
+ background: color-mix(in srgb, var(--prts-panel-raised) 48%, transparent);
116
+ box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--prts-ink) 18%, transparent);
113
117
  }
114
118
 
115
119
  /* Daylight needs a little contrast, rather than another white highlight. */
116
- html[data-dsh-prts][data-prts-scheme="light"][data-prts-background-mode="full"][data-prts-background-full] [data-prts-nav-rail] button:is(:hover, :focus-visible, [aria-expanded="true"]) {
117
- background: color-mix(in srgb, var(--prts-ink) 8%, transparent);
118
- box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--prts-ink) 16%, transparent);
120
+ &[data-prts-scheme="light"] [data-prts-nav-rail] button:is(:hover, :focus-visible, [aria-expanded="true"]) {
121
+ background: color-mix(in srgb, var(--prts-ink) 8%, transparent);
122
+ box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--prts-ink) 16%, transparent);
119
123
  }
120
- html[data-dsh-prts][data-prts-scheme="light"][data-prts-background-mode="full"][data-prts-background-full] [data-prts-nav-rail] button:active {
121
- background: color-mix(in srgb, var(--prts-ink) 13%, transparent);
122
- box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--prts-ink) 22%, transparent);
124
+ &[data-prts-scheme="light"] [data-prts-nav-rail] button:active {
125
+ background: color-mix(in srgb, var(--prts-ink) 13%, transparent);
126
+ box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--prts-ink) 22%, transparent);
123
127
  }
124
128
 
125
- /* The solid rail stays dark in both schemes; use the same light feedback
126
- * instead of the conversation palette's light-mode ink/surface colors. */
127
- html[data-dsh-prts]:not([data-prts-background-mode="full"][data-prts-background-full]) [data-prts-nav-rail] button:is(:hover, :focus-visible, [aria-expanded="true"]) {
128
- background: rgb(255 255 255 / 8%);
129
- color: #f3f6f7 !important;
130
- box-shadow: inset 0 0 0 1px rgb(255 255 255 / 12%);
129
+ /* A dark solid-rail divider is too strong against the daylight wallpaper. */
130
+ &[data-prts-scheme="light"] [data-prts-nav-rail] {
131
+ border-right-color: color-mix(in srgb, var(--prts-ink) 10%, transparent);
132
+ box-shadow: none;
131
133
  }
132
- html[data-dsh-prts]:not([data-prts-background-mode="full"][data-prts-background-full]) [data-prts-nav-rail] button:active {
133
- background: rgb(255 255 255 / 14%);
134
- color: #f3f6f7 !important;
135
- box-shadow: inset 0 0 0 1px rgb(255 255 255 / 20%);
134
+ &[data-prts-scheme="light"] [data-prts-nav-rail]::before {
135
+ box-shadow: inset 0 1px rgb(255 255 255 / 8%);
136
136
  }
137
137
 
138
- /* A dark solid-rail divider is too strong against the daylight wallpaper. */
139
- html[data-dsh-prts][data-prts-scheme="light"][data-prts-background-mode="full"][data-prts-background-full] [data-prts-nav-rail] {
140
- border-right-color: color-mix(in srgb, var(--prts-ink) 10%, transparent);
141
- box-shadow: none;
142
138
  }
143
- html[data-dsh-prts][data-prts-scheme="light"][data-prts-background-mode="full"][data-prts-background-full] [data-prts-nav-rail]::before {
144
- box-shadow: inset 0 1px rgb(255 255 255 / 8%);
139
+ /* The solid rail stays dark in both schemes; use the same light feedback
140
+ * instead of the conversation palette's light-mode ink/surface colors. */
141
+ html[data-dsh-prts]:not([data-prts-background-mode="full"][data-prts-background-full],[data-prts-background-mode="split"][data-prts-background-sidebar]) [data-prts-nav-rail] button:is(:hover, :focus-visible, [aria-expanded="true"]) {
142
+ background: rgb(255 255 255 / 8%);
143
+ color: #f3f6f7 !important;
144
+ box-shadow: inset 0 0 0 1px rgb(255 255 255 / 12%);
145
+ }
146
+ html[data-dsh-prts]:not([data-prts-background-mode="full"][data-prts-background-full],[data-prts-background-mode="split"][data-prts-background-sidebar]) [data-prts-nav-rail] button:active {
147
+ background: rgb(255 255 255 / 14%);
148
+ color: #f3f6f7 !important;
149
+ box-shadow: inset 0 0 0 1px rgb(255 255 255 / 20%);
145
150
  }
146
151
 
147
152
  /* Baker keeps its game palette; only a real conversation wallpaper enables glass. */
148
153
  html[data-dsh-prts][data-prts-conversation-style="deck-chat"]:is(
149
- [data-prts-background-mode="full"][data-prts-background-full],
150
- [data-prts-background-mode="split"][data-prts-background-conversation]
154
+ [data-prts-background-mode="full"][data-prts-background-full],
155
+ [data-prts-background-mode="split"][data-prts-background-conversation]
151
156
  ) {
152
- --prts-chat-user-surface: rgb(239 239 237 / var(--prts-baker-opacity, 50%));
153
- --prts-chat-assistant-surface: rgb(69 70 68 / var(--prts-baker-opacity, 50%));
154
- &[data-prts-scheme="light"] {
155
- --prts-chat-user-surface: rgb(255 255 255 / var(--prts-baker-opacity, 50%));
156
- --prts-chat-assistant-surface: rgb(223 227 223 / var(--prts-baker-opacity, 50%));
157
- }
158
- & :is([data-chat-flow-kind="user"], [data-submission-echo]:not([data-pending-steering])) [class$="_bubble"],
159
- & :is([data-prts-ai-surface], [data-message-role="user"], [data-message-role="assistant"]),
160
- & [data-chat-flow-kind="assistant-step"]:not([data-chat-group-part="reasoning"]) [class$="_body"]:has(:is([data-markdown], [data-slot*="markdown" i], .markdown-body)) {
161
- -webkit-backdrop-filter: blur(var(--prts-baker-blur, 8px)) saturate(1.08);
162
- backdrop-filter: blur(var(--prts-baker-blur, 8px)) saturate(1.08);
163
- }
164
- & [data-prts-ai-surface]::before,
165
- & [data-message-role="assistant"]::after,
166
- & :is([data-chat-flow-kind="user"], [data-submission-echo]:not([data-pending-steering])) [class$="_bubble"]::before,
167
- & [data-message-role="user"]::before {
168
- -webkit-backdrop-filter: blur(var(--prts-baker-blur, 8px)) saturate(1.08);
169
- backdrop-filter: blur(var(--prts-baker-blur, 8px)) saturate(1.08);
170
- }
157
+ --prts-chat-user-surface: rgb(239 239 237 / var(--prts-baker-opacity, 50%));
158
+ --prts-chat-assistant-surface: rgb(69 70 68 / var(--prts-baker-opacity, 50%));
159
+ &[data-prts-scheme="light"] {
160
+ --prts-chat-user-surface: rgb(255 255 255 / var(--prts-baker-opacity, 50%));
161
+ --prts-chat-assistant-surface: rgb(223 227 223 / var(--prts-baker-opacity, 50%));
162
+ }
163
+ & :is([data-chat-flow-kind="user"], [data-submission-echo]:not([data-pending-steering])) [class$="_bubble"],
164
+ & :is([data-prts-ai-surface], [data-message-role="user"], [data-message-role="assistant"]),
165
+ & [data-chat-flow-kind="assistant-step"]:not([data-chat-group-part="reasoning"]) [class$="_body"]:has(:is([data-markdown], [data-slot*="markdown" i], .markdown-body)) {
166
+ -webkit-backdrop-filter: blur(var(--prts-baker-blur, 8px)) saturate(1.08);
167
+ backdrop-filter: blur(var(--prts-baker-blur, 8px)) saturate(1.08);
168
+ }
169
+ & [data-prts-ai-surface]::before,
170
+ & [data-message-role="assistant"]::after,
171
+ & :is([data-chat-flow-kind="user"], [data-submission-echo]:not([data-pending-steering])) [class$="_bubble"]::before,
172
+ & [data-message-role="user"]::before {
173
+ -webkit-backdrop-filter: blur(var(--prts-baker-blur, 8px)) saturate(1.08);
174
+ backdrop-filter: blur(var(--prts-baker-blur, 8px)) saturate(1.08);
175
+ }
171
176
  }
172
177
 
173
178
  /* Classic user messages share the wallpaper translucency controls with Baker bubbles. */
174
179
  html[data-dsh-prts][data-prts-conversation-style="native"]:is(
175
- [data-prts-background-mode="full"][data-prts-background-full],
176
- [data-prts-background-mode="split"][data-prts-background-conversation]
180
+ [data-prts-background-mode="full"][data-prts-background-full],
181
+ [data-prts-background-mode="split"][data-prts-background-conversation]
177
182
  ) {
178
- & [data-message-role="user"],
179
- & :is([data-chat-flow-kind="user"], [data-submission-echo]:not([data-pending-steering])) [class$="_bubble"] {
180
- background: rgb(23 29 33 / var(--prts-classic-user-opacity, 50%)) !important;
181
- -webkit-backdrop-filter: blur(var(--prts-classic-user-blur, 8px)) saturate(1.08);
182
- backdrop-filter: blur(var(--prts-classic-user-blur, 8px)) saturate(1.08);
183
- }
184
- &[data-prts-scheme="light"] {
185
- & [data-message-role="user"],
186
- & :is([data-chat-flow-kind="user"], [data-submission-echo]:not([data-pending-steering])) [class$="_bubble"] {
187
- background: rgb(229 234 237 / var(--prts-classic-user-opacity, 50%)) !important;
188
- }
189
- }
183
+ & [data-message-role="user"],
184
+ & :is([data-chat-flow-kind="user"], [data-submission-echo]:not([data-pending-steering])) [class$="_bubble"] {
185
+ background: rgb(23 29 33 / var(--prts-classic-user-opacity, 50%)) !important;
186
+ -webkit-backdrop-filter: blur(var(--prts-classic-user-blur, 8px)) saturate(1.08);
187
+ backdrop-filter: blur(var(--prts-classic-user-blur, 8px)) saturate(1.08);
188
+ }
189
+ &[data-prts-scheme="light"] {
190
+ & [data-message-role="user"],
191
+ & :is([data-chat-flow-kind="user"], [data-submission-echo]:not([data-pending-steering])) [class$="_bubble"] {
192
+ background: rgb(229 234 237 / var(--prts-classic-user-opacity, 50%)) !important;
193
+ }
194
+ }
190
195
  }
191
196
 
192
197
  [data-prts-opacity-settings] { min-width: 0; max-width: 420px; margin: 0; padding: 14px 0 0; border: 0; border-top: 1px solid var(--prts-line); }
@@ -233,15 +238,15 @@ html[data-prts-motion="reduced"] [data-prts-opacity-dial] [data-dial-tail] { dis
233
238
 
234
239
  /* Match the two peer modules without boxing one of them in a second surface. */
235
240
  html[data-dsh-prts] [data-prts-theme-settings] [data-prts-settings-section="appearance"] > section {
236
- padding: 0;
237
- border: 0;
238
- border-radius: 0;
239
- background: transparent;
241
+ padding: 0;
242
+ border: 0;
243
+ border-radius: 0;
244
+ background: transparent;
240
245
  }
241
246
  html[data-dsh-prts] [data-prts-theme-settings] [data-prts-background-settings] {
242
- margin-top: 24px;
243
- padding-top: 12px;
244
- border-top: 1px solid var(--prts-line);
247
+ margin-top: 24px;
248
+ padding-top: 12px;
249
+ border-top: 1px solid var(--prts-line);
245
250
  }
246
251
  /* SVG outlines are rectangular in Chromium. Draw keyboard focus inside the ring. */
247
252
  html[data-dsh-prts] [data-prts-theme-settings] [data-prts-opacity-dial] svg:focus { outline: none !important; box-shadow: none; }
@@ -249,16 +254,16 @@ html[data-dsh-prts] [data-prts-theme-settings] [data-prts-opacity-dial] svg:focu
249
254
  [data-prts-opacity-dial] svg:focus-visible [data-dial-focus] { opacity: .8; }
250
255
  [data-prts-opacity-control][data-dragging] [data-dial-focus] { opacity: 0; }
251
256
  [data-prts-material-preview] {
252
- position: relative;
253
- width: 100%;
254
- height: 104px;
255
- overflow: hidden;
256
- border: 1px solid var(--prts-line);
257
- border-radius: 6px;
258
- background: var(--prts-background-full, linear-gradient(135deg, #8bb6c2, #c7b69c)) center / cover;
259
- --prts-preview-surface: var(--prts-panel);
260
- }
261
- html[data-prts-background-mode="split"] [data-prts-material-preview="sidebarOpacity"] { background-image: var(--prts-background-sidebar, linear-gradient(135deg, #8bb6c2, #c7b69c)); }
257
+ position: relative;
258
+ width: 100%;
259
+ height: 104px;
260
+ overflow: hidden;
261
+ border: 1px solid var(--prts-line);
262
+ border-radius: 6px;
263
+ background: var(--prts-background-full, linear-gradient(135deg, #8bb6c2, #c7b69c)) center / cover;
264
+ --prts-preview-surface: var(--prts-panel);
265
+ }
266
+ html[data-prts-background-mode="split"] :is([data-prts-material-preview="sidebarOpacity"],[data-prts-material-preview="railOpacity"]) { background-image: var(--prts-background-sidebar, linear-gradient(135deg, #8bb6c2, #c7b69c)); }
262
267
  html[data-prts-background-mode="split"] [data-prts-material-preview="bakerOpacity"] { background-image: var(--prts-background-conversation, linear-gradient(135deg, #8bb6c2, #c7b69c)); }
263
268
  html[data-prts-background-mode="split"] [data-prts-material-preview="classicUserOpacity"] { background-image: var(--prts-background-conversation, linear-gradient(135deg, #8bb6c2, #c7b69c)); }
264
269
  [data-prts-material-preview]::before { content: ""; position: absolute; inset: 0; background: var(--prts-background-wash); }
@@ -271,9 +276,9 @@ html[data-prts-scheme="light"] [data-prts-material-preview="bakerOpacity"] [data
271
276
  [data-prts-material-preview="classicUserOpacity"] [data-prts-material-preview-surface] { inset: 16px 10px; border-left: 3px solid var(--prts-yellow); border-radius: var(--prts-radius-card); background: rgb(23 29 33 / var(--prts-classic-user-opacity, 50%)); backdrop-filter: blur(var(--prts-classic-user-blur, 8px)) saturate(1.08); }
272
277
  html[data-prts-scheme="light"] [data-prts-material-preview="classicUserOpacity"] [data-prts-material-preview-surface] { background: rgb(229 234 237 / var(--prts-classic-user-opacity, 50%)); }
273
278
  @media (max-width: 560px) {
274
- [data-prts-opacity-control] { column-gap: 10px; }
275
- [data-prts-opacity-heading] { gap: 6px; }
276
- [data-prts-opacity-dial] { width: 88px; }
279
+ [data-prts-opacity-control] { column-gap: 10px; }
280
+ [data-prts-opacity-heading] { gap: 6px; }
281
+ [data-prts-opacity-dial] { width: 88px; }
277
282
  }
278
283
 
279
284
  /* Backgrounds now have their own settings page. */
@@ -284,43 +289,43 @@ html[data-dsh-prts] [data-prts-settings-section="background"] [data-prts-backgro
284
289
  [data-prts-composer-glass-required] { font-size: 12px; color: var(--prts-muted); }
285
290
 
286
291
  /* The native active composer fades into DSH's base color. Baker paints a
287
- * different solid backdrop, so match that backdrop while keeping the fade. */
292
+ * different solid backdrop, so match that backdrop while keeping the fade. */
288
293
  html[data-dsh-prts][data-prts-conversation-style="deck-chat"][data-prts-background-mode="off"] [data-phase="active"] [data-composer-seat]:not(:has([data-prts-composer-glass-active])) {
289
- background: linear-gradient(180deg, transparent 0, var(--prts-chat-dock-surface, var(--prts-chat-backdrop)) 36px) !important;
294
+ background: linear-gradient(180deg, transparent 0, var(--prts-chat-dock-surface, var(--prts-chat-backdrop)) 36px) !important;
290
295
  }
291
296
  html[data-dsh-prts][data-prts-conversation-style="deck-chat"][data-prts-background-mode="off"][data-prts-texture="restrained"] {
292
- --prts-chat-dock-surface: color-mix(in srgb, var(--prts-chat-backdrop) 82%, var(--prts-canvas));
297
+ --prts-chat-dock-surface: color-mix(in srgb, var(--prts-chat-backdrop) 82%, var(--prts-canvas));
293
298
  }
294
299
  html[data-dsh-prts][data-prts-conversation-style="deck-chat"][data-prts-background-mode="off"][data-prts-texture="off"] {
295
- --prts-chat-dock-surface: color-mix(in srgb, var(--prts-chat-backdrop) 72%, var(--prts-canvas));
300
+ --prts-chat-dock-surface: color-mix(in srgb, var(--prts-chat-backdrop) 72%, var(--prts-canvas));
296
301
  }
297
302
 
298
303
  /* Native data-streaming disappears for settled and interrupted responses.
299
- * Hide only the current response body, never reasoning, tools or earlier rounds. */
304
+ * Hide only the current response body, never reasoning, tools or earlier rounds. */
300
305
  html[data-dsh-prts][data-prts-conversation-style="deck-chat"][data-prts-baker-loading]
301
306
  [data-chat-flow-kind="assistant-step"]:not([data-chat-group-part="reasoning"])
302
307
  [data-streaming] > :is([data-prts-ai-surface], [class$="_body"]) {
303
- min-width: 78px;
304
- width: 78px !important;
305
- min-height: 42px;
306
- box-sizing: border-box;
307
- display: flex;
308
- align-items: center;
309
- justify-content: center;
310
- padding: 12px 18px !important;
311
- & > * { display: none !important; }
312
- &::after {
313
- content: "正在生成回复";
314
- font-size: 0;
315
- display: block;
316
- width: 4px;
317
- height: 4px;
318
- border-radius: 1px;
319
- animation: prts-baker-typing 1.2s linear infinite;
320
- }
308
+ min-width: 78px;
309
+ width: 78px !important;
310
+ min-height: 42px;
311
+ box-sizing: border-box;
312
+ display: flex;
313
+ align-items: center;
314
+ justify-content: center;
315
+ padding: 12px 18px !important;
316
+ & > * { display: none !important; }
317
+ &::after {
318
+ content: "正在生成回复";
319
+ font-size: 0;
320
+ display: block;
321
+ width: 4px;
322
+ height: 4px;
323
+ border-radius: 1px;
324
+ animation: prts-baker-typing 1.2s linear infinite;
325
+ }
321
326
  }
322
327
  @keyframes prts-baker-typing {
323
- 0%, 100% { background: color-mix(in srgb,currentColor 30%,transparent); box-shadow: -10px 0 0 currentColor, 10px 0 0 color-mix(in srgb,currentColor 30%,transparent); }
324
- 33% { background: currentColor; box-shadow: -10px 0 0 color-mix(in srgb,currentColor 30%,transparent), 10px 0 0 color-mix(in srgb,currentColor 30%,transparent); }
325
- 66% { background: color-mix(in srgb,currentColor 30%,transparent); box-shadow: -10px 0 0 color-mix(in srgb,currentColor 30%,transparent), 10px 0 0 currentColor; }
328
+ 0%, 100% { background: color-mix(in srgb,currentColor 30%,transparent); box-shadow: -10px 0 0 currentColor, 10px 0 0 color-mix(in srgb,currentColor 30%,transparent); }
329
+ 33% { background: currentColor; box-shadow: -10px 0 0 color-mix(in srgb,currentColor 30%,transparent), 10px 0 0 color-mix(in srgb,currentColor 30%,transparent); }
330
+ 66% { background: color-mix(in srgb,currentColor 30%,transparent); box-shadow: -10px 0 0 color-mix(in srgb,currentColor 30%,transparent), 10px 0 0 currentColor; }
326
331
  }
@@ -776,10 +776,10 @@ html[data-dsh-prts] [data-prts-preview-body] a { color:var(--prts-cyan);text-dec
776
776
  html[data-dsh-prts] [data-prts-preview-message] + [data-prts-preview-message] { margin-top:5px; }
777
777
  html[data-dsh-prts] [data-prts-preview-message] > small { display:block;margin-bottom:6px;color:var(--prts-muted);font:10px/1.5 var(--prts-mono); }
778
778
 
779
- html[data-dsh-prts] [data-prts-reply-entry] { display:flex;align-items:flex-start;gap:8px;width:100%;padding:6px 8px;text-align:left;border:1px solid var(--prts-line);border-radius:5px;background:transparent;color:var(--prts-ink);cursor:pointer; }
780
- html[data-dsh-prts] [data-prts-reply-entry]:is(:hover,:focus-visible,[data-prts-reply-active]) { background:color-mix(in srgb,var(--prts-ink) 7%,transparent);border-color:var(--prts-muted); }
781
- html[data-dsh-prts] [data-prts-reply-entry] small { flex:0 0 auto;white-space:nowrap;padding-top:2px;color:var(--prts-muted);font:10px/1.5 var(--prts-mono); }
782
- html[data-dsh-prts] [data-prts-reply-entry] span { min-width:0;flex:1;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;overflow:hidden;font:12px/1.6 var(--prts-body);overflow-wrap:anywhere; }
779
+ html[data-dsh-prts] :is([data-prts-reply-entry],[data-prts-tool-entry]) { display:flex;align-items:flex-start;gap:8px;width:100%;padding:6px 8px;text-align:left;border:1px solid var(--prts-line);border-radius:5px;background:transparent;color:var(--prts-ink);cursor:pointer; }
780
+ html[data-dsh-prts] :is([data-prts-reply-entry],[data-prts-tool-entry]):is(:hover,:focus-visible,[data-prts-reply-active]) { background:color-mix(in srgb,var(--prts-ink) 7%,transparent);border-color:var(--prts-muted); }
781
+ html[data-dsh-prts] :is([data-prts-reply-entry],[data-prts-tool-entry]) small { flex:0 0 auto;white-space:nowrap;padding-top:2px;color:var(--prts-muted);font:10px/1.5 var(--prts-mono); }
782
+ html[data-dsh-prts] :is([data-prts-reply-entry],[data-prts-tool-entry]) span { min-width:0;flex:1;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;overflow:hidden;font:12px/1.6 var(--prts-body);overflow-wrap:anywhere; }
783
783
  html[data-dsh-prts] [data-prts-reply-detail]:not([data-prts-preview-question]) > [data-prts-preview-body] { max-height:190px; }
784
784
 
785
785
  html[data-dsh-prts] [data-prts-preview-marker] { display:none;flex:none;margin-left:auto;color:var(--prts-muted);font:600 9px/1.4 var(--prts-body); }
@@ -864,3 +864,25 @@ html[data-dsh-prts] [data-prts-summary-dismissed] [data-prts-session-summary-pop
864
864
  pointer-events: none !important;
865
865
  transition: none;
866
866
  }
867
+
868
+ html[data-dsh-prts] [data-prts-preview-tool] { margin-top:8px; }
869
+ html[data-dsh-prts] [data-prts-preview-tool][hidden] { display:none; }
870
+ html[data-dsh-prts] [data-prts-preview-tool] > button { box-sizing:border-box;height:32px;align-items:center;gap:7px;padding:4px 8px;overflow:hidden;border-left:2px solid var(--prts-cyan);background:color-mix(in srgb,var(--prts-cyan) 7%,transparent); }
871
+ html[data-dsh-prts] [data-prts-tool-entry]::before { content:">_";flex:none;color:var(--prts-cyan);font:600 11px var(--prts-mono); }
872
+ html[data-dsh-prts] [data-prts-preview-tool] small { padding:0;color:var(--prts-cyan); }
873
+ html[data-dsh-prts] [data-prts-preview-tool] span { display:block;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font:11px/1.6 var(--prts-mono); }
874
+
875
+ html[data-dsh-prts] [data-prts-summary-reply] > [data-prts-preview-body]:empty { display:none;margin:0; }
876
+
877
+ html[data-dsh-prts] [data-prts-preview-message] > [data-prts-reply-entry] { border-color:transparent;border-radius:3px; }
878
+ html[data-dsh-prts] [data-prts-reply-entry] small { display:flex;align-items:center;gap:4px;color:#8aaee0; }
879
+ html[data-dsh-prts] [data-prts-reply-entry] svg { width:14px;height:14px;flex:none;fill:none;stroke:currentColor;stroke-width:1.2; }
880
+
881
+ html[data-dsh-prts][data-prts-scheme="light"] [data-prts-reply-entry] small { color:#476b9c; }
882
+
883
+ html[data-dsh-prts] [data-prts-summary-reply][data-prts-tool-history] > [data-prts-preview-body] { height:190px;max-height:190px; }
884
+ html[data-dsh-prts] [data-prts-tool-record] { padding:8px 0;border-bottom:1px solid var(--prts-line); }
885
+ html[data-dsh-prts] [data-prts-tool-record] > div { display:flex;align-items:baseline;gap:8px; }
886
+ html[data-dsh-prts] [data-prts-tool-record] b { flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--prts-cyan);font:11px/1.6 var(--prts-mono); }
887
+ html[data-dsh-prts] [data-prts-tool-record] small { flex:none;color:var(--prts-muted);font-size:10px; }
888
+ html[data-dsh-prts] [data-prts-tool-record] p { display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;overflow:hidden;margin:4px 0 0; }
@@ -1340,20 +1340,26 @@ html[data-dsh-prts][data-prts-conversation-style="deck-chat"] :is(
1340
1340
  color: var(--prts-ink) !important;
1341
1341
  }
1342
1342
 
1343
- /* Bordered Baker tables need inset cells and a scrollport inside the bubble. */
1343
+ /* Baker code cards and tables. */
1344
1344
  html[data-dsh-prts][data-prts-conversation-style="deck-chat"] :is(
1345
- [data-prts-ai-surface], [data-message-role="assistant"], [data-message-role="user"],
1346
- :is([data-chat-flow-kind="user"], [data-submission-echo]:not([data-pending-steering])) [class$="_bubble"]
1345
+ [data-prts-ai-surface], [data-message-role="assistant"], [data-message-role="user"],
1346
+ :is([data-chat-flow-kind="user"], [data-submission-echo]:not([data-pending-steering])) [class$="_bubble"]
1347
1347
  ) {
1348
- & :is(th,td){padding-inline:14px!important}
1349
- & :is(.md-table-wide,[class*="_tableScroll_"]){
1350
- box-sizing:border-box;width:100%;max-width:100%;min-width:0;
1351
- margin-inline:0!important;padding:0!important;overflow:auto;
1352
- border:1px solid color-mix(in srgb,var(--prts-cyan) 24%,var(--prts-line));
1353
- border-radius:10px;corner-shape:round;
1354
- background:color-mix(in srgb,var(--prts-canvas) 88%,transparent);
1355
- & > table{border:0;background:transparent;margin:0;width:100%}
1356
- }
1348
+ /* Clip preserves header stickiness. */
1349
+ & :has(>[data-code-block-content]){
1350
+ box-sizing:border-box;max-width:100%;border:1px solid var(--prts-line);border-left:3px solid var(--prts-cyan);border-radius:12px;overflow:clip;
1351
+ & [data-code-block-banner]{border-radius:11px 11px 0 0;background:color-mix(in srgb,var(--prts-ink) 7%,var(--prts-canvas));border-bottom:1px solid var(--prts-line)}
1352
+ &>[data-code-block-content] pre{box-sizing:border-box;width:100%;border:0!important;border-radius:0 0 11px 11px;margin:0!important}
1353
+ }
1354
+ & :is(th,td){padding-inline:14px!important}
1355
+ & :is(.md-table-wide,[class*="_tableScroll_"]){
1356
+ box-sizing:border-box;width:100%;max-width:100%;min-width:0;
1357
+ margin-inline:0!important;padding:0!important;overflow:auto;
1358
+ border:1px solid color-mix(in srgb,var(--prts-cyan) 24%,var(--prts-line));
1359
+ border-radius:10px;corner-shape:round;
1360
+ background:color-mix(in srgb,var(--prts-canvas) 88%,transparent);
1361
+ & > table{border:0;background:transparent;margin:0;width:100%}
1362
+ }
1357
1363
  }
1358
1364
 
1359
1365
  /* Group process avatars without changing reply alignment or final-answer avatars. */
@@ -1361,10 +1367,10 @@ html[data-dsh-prts][data-prts-conversation-style="deck-chat"] [data-prts-avatar-
1361
1367
 
1362
1368
  /* Baker quote surfaces; classic prose retains the host styling. */
1363
1369
  html[data-dsh-prts][data-prts-conversation-style="deck-chat"] :is([data-chat-flow-kind],[data-message-role],[data-prts-ai-surface],[data-submission-echo]) blockquote {
1364
- border-radius:10px;corner-shape:round;padding:8px 14px;
1365
- border-inline-start:3px solid var(--prts-cyan)!important;
1366
- & > :first-child{margin-top:0}
1367
- & > :last-child{margin-bottom:0}
1370
+ border-radius:10px;corner-shape:round;padding:8px 14px;
1371
+ border-inline-start:3px solid var(--prts-cyan)!important;
1372
+ & > :first-child{margin-top:0}
1373
+ & > :last-child{margin-bottom:0}
1368
1374
  }
1369
1375
 
1370
1376
  html[data-dsh-prts] [aria-invalid="true"],