@drscrewdriver/dsh-better-display 0.3.3-fork.1

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.
Files changed (390) hide show
  1. package/CHANGELOG.md +259 -0
  2. package/DESIGN.md +72 -0
  3. package/LICENSE +24 -0
  4. package/README.en.md +55 -0
  5. package/README.md +55 -0
  6. package/THIRD_PARTY_NOTICES.md +65 -0
  7. package/compat/harness-rc2.json +99 -0
  8. package/cordis.patch.yml +5 -0
  9. package/cordis.yml +4 -0
  10. package/docs/official-rendering-bridge.md +65 -0
  11. package/dshx.yml +5 -0
  12. package/lib/client.js +49292 -0
  13. package/lib/client.js.map +1 -0
  14. package/lib/dsh-better-display.js +101 -0
  15. package/lib/types/client/Blocks.d.ts +49 -0
  16. package/lib/types/client/Blocks.d.ts.map +1 -0
  17. package/lib/types/client/Blocks.js +143 -0
  18. package/lib/types/client/Blocks.js.map +1 -0
  19. package/lib/types/client/ChoreographedFlow.d.ts +22 -0
  20. package/lib/types/client/ChoreographedFlow.d.ts.map +1 -0
  21. package/lib/types/client/ChoreographedFlow.js +218 -0
  22. package/lib/types/client/ChoreographedFlow.js.map +1 -0
  23. package/lib/types/client/ClosedProcessSummary.d.ts +9 -0
  24. package/lib/types/client/ClosedProcessSummary.d.ts.map +1 -0
  25. package/lib/types/client/ClosedProcessSummary.js +16 -0
  26. package/lib/types/client/ClosedProcessSummary.js.map +1 -0
  27. package/lib/types/client/DiffPanel.d.ts +13 -0
  28. package/lib/types/client/DiffPanel.d.ts.map +1 -0
  29. package/lib/types/client/DiffPanel.js +115 -0
  30. package/lib/types/client/DiffPanel.js.map +1 -0
  31. package/lib/types/client/LiveFold.d.ts +10 -0
  32. package/lib/types/client/LiveFold.d.ts.map +1 -0
  33. package/lib/types/client/LiveFold.js +39 -0
  34. package/lib/types/client/LiveFold.js.map +1 -0
  35. package/lib/types/client/McpAppFrame.d.ts +32 -0
  36. package/lib/types/client/McpAppFrame.d.ts.map +1 -0
  37. package/lib/types/client/McpAppFrame.js +193 -0
  38. package/lib/types/client/McpAppFrame.js.map +1 -0
  39. package/lib/types/client/OfficialContent.d.ts +25 -0
  40. package/lib/types/client/OfficialContent.d.ts.map +1 -0
  41. package/lib/types/client/OfficialContent.js +53 -0
  42. package/lib/types/client/OfficialContent.js.map +1 -0
  43. package/lib/types/client/Reader.d.ts +3 -0
  44. package/lib/types/client/Reader.d.ts.map +1 -0
  45. package/lib/types/client/Reader.js +603 -0
  46. package/lib/types/client/Reader.js.map +1 -0
  47. package/lib/types/client/ReasoningCard.d.ts +11 -0
  48. package/lib/types/client/ReasoningCard.d.ts.map +1 -0
  49. package/lib/types/client/ReasoningCard.js +322 -0
  50. package/lib/types/client/ReasoningCard.js.map +1 -0
  51. package/lib/types/client/SettingsSection.d.ts +37 -0
  52. package/lib/types/client/SettingsSection.d.ts.map +1 -0
  53. package/lib/types/client/SettingsSection.js +63 -0
  54. package/lib/types/client/SettingsSection.js.map +1 -0
  55. package/lib/types/client/StickyLane.d.ts +8 -0
  56. package/lib/types/client/StickyLane.d.ts.map +1 -0
  57. package/lib/types/client/StickyLane.js +39 -0
  58. package/lib/types/client/StickyLane.js.map +1 -0
  59. package/lib/types/client/TimelineRail.d.ts +10 -0
  60. package/lib/types/client/TimelineRail.d.ts.map +1 -0
  61. package/lib/types/client/TimelineRail.js +168 -0
  62. package/lib/types/client/TimelineRail.js.map +1 -0
  63. package/lib/types/client/ToolActivity.d.ts +17 -0
  64. package/lib/types/client/ToolActivity.d.ts.map +1 -0
  65. package/lib/types/client/ToolActivity.js +244 -0
  66. package/lib/types/client/ToolActivity.js.map +1 -0
  67. package/lib/types/client/TurnMetrics.d.ts +11 -0
  68. package/lib/types/client/TurnMetrics.d.ts.map +1 -0
  69. package/lib/types/client/TurnMetrics.js +44 -0
  70. package/lib/types/client/TurnMetrics.js.map +1 -0
  71. package/lib/types/client/WaitClock.d.ts +16 -0
  72. package/lib/types/client/WaitClock.d.ts.map +1 -0
  73. package/lib/types/client/WaitClock.js +29 -0
  74. package/lib/types/client/WaitClock.js.map +1 -0
  75. package/lib/types/client/WaitingClock.d.ts +15 -0
  76. package/lib/types/client/WaitingClock.d.ts.map +1 -0
  77. package/lib/types/client/WaitingClock.js +30 -0
  78. package/lib/types/client/WaitingClock.js.map +1 -0
  79. package/lib/types/client/WaitingStatus.d.ts +6 -0
  80. package/lib/types/client/WaitingStatus.d.ts.map +1 -0
  81. package/lib/types/client/WaitingStatus.js +9 -0
  82. package/lib/types/client/WaitingStatus.js.map +1 -0
  83. package/lib/types/client/conversation-scroll.d.ts +19 -0
  84. package/lib/types/client/conversation-scroll.d.ts.map +1 -0
  85. package/lib/types/client/conversation-scroll.js +25 -0
  86. package/lib/types/client/conversation-scroll.js.map +1 -0
  87. package/lib/types/client/deliverables.d.ts +24 -0
  88. package/lib/types/client/deliverables.d.ts.map +1 -0
  89. package/lib/types/client/deliverables.js +104 -0
  90. package/lib/types/client/deliverables.js.map +1 -0
  91. package/lib/types/client/entry-policy.d.ts +10 -0
  92. package/lib/types/client/entry-policy.d.ts.map +1 -0
  93. package/lib/types/client/entry-policy.js +24 -0
  94. package/lib/types/client/entry-policy.js.map +1 -0
  95. package/lib/types/client/entry.d.ts +4 -0
  96. package/lib/types/client/entry.d.ts.map +1 -0
  97. package/lib/types/client/entry.js +34 -0
  98. package/lib/types/client/entry.js.map +1 -0
  99. package/lib/types/client/fold-choreography.d.ts +40 -0
  100. package/lib/types/client/fold-choreography.d.ts.map +1 -0
  101. package/lib/types/client/fold-choreography.js +48 -0
  102. package/lib/types/client/fold-choreography.js.map +1 -0
  103. package/lib/types/client/fold-intensity.d.ts +11 -0
  104. package/lib/types/client/fold-intensity.d.ts.map +1 -0
  105. package/lib/types/client/fold-intensity.js +32 -0
  106. package/lib/types/client/fold-intensity.js.map +1 -0
  107. package/lib/types/client/index.d.ts +7 -0
  108. package/lib/types/client/index.d.ts.map +1 -0
  109. package/lib/types/client/index.js +195 -0
  110. package/lib/types/client/index.js.map +1 -0
  111. package/lib/types/client/live-turn.d.ts +58 -0
  112. package/lib/types/client/live-turn.d.ts.map +1 -0
  113. package/lib/types/client/live-turn.js +190 -0
  114. package/lib/types/client/live-turn.js.map +1 -0
  115. package/lib/types/client/markdown/MarkdownText.d.ts +41 -0
  116. package/lib/types/client/markdown/MarkdownText.d.ts.map +1 -0
  117. package/lib/types/client/markdown/MarkdownText.js +178 -0
  118. package/lib/types/client/markdown/MarkdownText.js.map +1 -0
  119. package/lib/types/client/markdown/cjkFriendlyStrong.d.ts +9 -0
  120. package/lib/types/client/markdown/cjkFriendlyStrong.d.ts.map +1 -0
  121. package/lib/types/client/markdown/cjkFriendlyStrong.js +73 -0
  122. package/lib/types/client/markdown/cjkFriendlyStrong.js.map +1 -0
  123. package/lib/types/client/markdown/incremental.d.ts +69 -0
  124. package/lib/types/client/markdown/incremental.d.ts.map +1 -0
  125. package/lib/types/client/markdown/incremental.js +108 -0
  126. package/lib/types/client/markdown/incremental.js.map +1 -0
  127. package/lib/types/client/markdown/katex.d.ts +27 -0
  128. package/lib/types/client/markdown/katex.d.ts.map +1 -0
  129. package/lib/types/client/markdown/katex.js +88 -0
  130. package/lib/types/client/markdown/katex.js.map +1 -0
  131. package/lib/types/client/markdown/mathCompatibility.d.ts +11 -0
  132. package/lib/types/client/markdown/mathCompatibility.d.ts.map +1 -0
  133. package/lib/types/client/markdown/mathCompatibility.js +293 -0
  134. package/lib/types/client/markdown/mathCompatibility.js.map +1 -0
  135. package/lib/types/client/markdown/parse.d.ts +25 -0
  136. package/lib/types/client/markdown/parse.d.ts.map +1 -0
  137. package/lib/types/client/markdown/parse.js +42 -0
  138. package/lib/types/client/markdown/parse.js.map +1 -0
  139. package/lib/types/client/markdown/render.d.ts +121 -0
  140. package/lib/types/client/markdown/render.d.ts.map +1 -0
  141. package/lib/types/client/markdown/render.js +452 -0
  142. package/lib/types/client/markdown/render.js.map +1 -0
  143. package/lib/types/client/mcp-app.d.ts +50 -0
  144. package/lib/types/client/mcp-app.d.ts.map +1 -0
  145. package/lib/types/client/mcp-app.js +328 -0
  146. package/lib/types/client/mcp-app.js.map +1 -0
  147. package/lib/types/client/message-chrome.d.ts +19 -0
  148. package/lib/types/client/message-chrome.d.ts.map +1 -0
  149. package/lib/types/client/message-chrome.js +42 -0
  150. package/lib/types/client/message-chrome.js.map +1 -0
  151. package/lib/types/client/motion.d.ts +38 -0
  152. package/lib/types/client/motion.d.ts.map +1 -0
  153. package/lib/types/client/motion.js +453 -0
  154. package/lib/types/client/motion.js.map +1 -0
  155. package/lib/types/client/native/ContextBody.d.ts +130 -0
  156. package/lib/types/client/native/ContextBody.d.ts.map +1 -0
  157. package/lib/types/client/native/ContextBody.js +398 -0
  158. package/lib/types/client/native/ContextBody.js.map +1 -0
  159. package/lib/types/client/native/ContextInjectionRow.d.ts +35 -0
  160. package/lib/types/client/native/ContextInjectionRow.d.ts.map +1 -0
  161. package/lib/types/client/native/ContextInjectionRow.js +42 -0
  162. package/lib/types/client/native/ContextInjectionRow.js.map +1 -0
  163. package/lib/types/client/native/ReferenceIcon.d.ts +16 -0
  164. package/lib/types/client/native/ReferenceIcon.d.ts.map +1 -0
  165. package/lib/types/client/native/ReferenceIcon.js +16 -0
  166. package/lib/types/client/native/ReferenceIcon.js.map +1 -0
  167. package/lib/types/client/native/tool-call-model.d.ts +58 -0
  168. package/lib/types/client/native/tool-call-model.d.ts.map +1 -0
  169. package/lib/types/client/native/tool-call-model.js +219 -0
  170. package/lib/types/client/native/tool-call-model.js.map +1 -0
  171. package/lib/types/client/native/tool-update.d.ts +23 -0
  172. package/lib/types/client/native/tool-update.d.ts.map +1 -0
  173. package/lib/types/client/native/tool-update.js +22 -0
  174. package/lib/types/client/native/tool-update.js.map +1 -0
  175. package/lib/types/client/official-slots.d.ts +71 -0
  176. package/lib/types/client/official-slots.d.ts.map +1 -0
  177. package/lib/types/client/official-slots.js +183 -0
  178. package/lib/types/client/official-slots.js.map +1 -0
  179. package/lib/types/client/open-file.d.ts +29 -0
  180. package/lib/types/client/open-file.d.ts.map +1 -0
  181. package/lib/types/client/open-file.js +71 -0
  182. package/lib/types/client/open-file.js.map +1 -0
  183. package/lib/types/client/pending-submission.d.ts +28 -0
  184. package/lib/types/client/pending-submission.d.ts.map +1 -0
  185. package/lib/types/client/pending-submission.js +28 -0
  186. package/lib/types/client/pending-submission.js.map +1 -0
  187. package/lib/types/client/platform-media.d.ts +6 -0
  188. package/lib/types/client/platform-media.d.ts.map +1 -0
  189. package/lib/types/client/platform-media.js +18 -0
  190. package/lib/types/client/platform-media.js.map +1 -0
  191. package/lib/types/client/primitive-labels.d.ts +10 -0
  192. package/lib/types/client/primitive-labels.d.ts.map +1 -0
  193. package/lib/types/client/primitive-labels.js +38 -0
  194. package/lib/types/client/primitive-labels.js.map +1 -0
  195. package/lib/types/client/projection.d.ts +41 -0
  196. package/lib/types/client/projection.d.ts.map +1 -0
  197. package/lib/types/client/projection.js +112 -0
  198. package/lib/types/client/projection.js.map +1 -0
  199. package/lib/types/client/reasoning-follow.d.ts +10 -0
  200. package/lib/types/client/reasoning-follow.d.ts.map +1 -0
  201. package/lib/types/client/reasoning-follow.js +21 -0
  202. package/lib/types/client/reasoning-follow.js.map +1 -0
  203. package/lib/types/client/resource-address.d.ts +3 -0
  204. package/lib/types/client/resource-address.d.ts.map +1 -0
  205. package/lib/types/client/resource-address.js +33 -0
  206. package/lib/types/client/resource-address.js.map +1 -0
  207. package/lib/types/client/settings-copy.d.ts +7 -0
  208. package/lib/types/client/settings-copy.d.ts.map +1 -0
  209. package/lib/types/client/settings-copy.js +53 -0
  210. package/lib/types/client/settings-copy.js.map +1 -0
  211. package/lib/types/client/settings-slots.d.ts +23 -0
  212. package/lib/types/client/settings-slots.d.ts.map +1 -0
  213. package/lib/types/client/settings-slots.js +2 -0
  214. package/lib/types/client/settings-slots.js.map +1 -0
  215. package/lib/types/client/settings.d.ts +4 -0
  216. package/lib/types/client/settings.d.ts.map +1 -0
  217. package/lib/types/client/settings.js +60 -0
  218. package/lib/types/client/settings.js.map +1 -0
  219. package/lib/types/client/skill-status.d.ts +25 -0
  220. package/lib/types/client/skill-status.d.ts.map +1 -0
  221. package/lib/types/client/skill-status.js +44 -0
  222. package/lib/types/client/skill-status.js.map +1 -0
  223. package/lib/types/client/store.d.ts +35 -0
  224. package/lib/types/client/store.d.ts.map +1 -0
  225. package/lib/types/client/store.js +37 -0
  226. package/lib/types/client/store.js.map +1 -0
  227. package/lib/types/client/stream-buffer.d.ts +37 -0
  228. package/lib/types/client/stream-buffer.d.ts.map +1 -0
  229. package/lib/types/client/stream-buffer.js +150 -0
  230. package/lib/types/client/stream-buffer.js.map +1 -0
  231. package/lib/types/client/streaming.d.ts +18 -0
  232. package/lib/types/client/streaming.d.ts.map +1 -0
  233. package/lib/types/client/streaming.js +84 -0
  234. package/lib/types/client/streaming.js.map +1 -0
  235. package/lib/types/client/timeline.d.ts +26 -0
  236. package/lib/types/client/timeline.d.ts.map +1 -0
  237. package/lib/types/client/timeline.js +48 -0
  238. package/lib/types/client/timeline.js.map +1 -0
  239. package/lib/types/client/tool-activity.d.ts +98 -0
  240. package/lib/types/client/tool-activity.d.ts.map +1 -0
  241. package/lib/types/client/tool-activity.js +301 -0
  242. package/lib/types/client/tool-activity.js.map +1 -0
  243. package/lib/types/client/types.d.ts +91 -0
  244. package/lib/types/client/types.d.ts.map +1 -0
  245. package/lib/types/client/types.js +2 -0
  246. package/lib/types/client/types.js.map +1 -0
  247. package/lib/types/client/waiting-clock.d.ts +49 -0
  248. package/lib/types/client/waiting-clock.d.ts.map +1 -0
  249. package/lib/types/client/waiting-clock.js +80 -0
  250. package/lib/types/client/waiting-clock.js.map +1 -0
  251. package/lib/types/client/word-motion.d.ts +16 -0
  252. package/lib/types/client/word-motion.d.ts.map +1 -0
  253. package/lib/types/client/word-motion.js +90 -0
  254. package/lib/types/client/word-motion.js.map +1 -0
  255. package/lib/types/client/word-timeline.d.ts +32 -0
  256. package/lib/types/client/word-timeline.d.ts.map +1 -0
  257. package/lib/types/client/word-timeline.js +119 -0
  258. package/lib/types/client/word-timeline.js.map +1 -0
  259. package/lib/types/dsh-better-display.d.ts +17 -0
  260. package/lib/types/dsh-better-display.d.ts.map +1 -0
  261. package/lib/types/dsh-better-display.js +93 -0
  262. package/lib/types/dsh-better-display.js.map +1 -0
  263. package/lib/types/skill-roots.d.ts +22 -0
  264. package/lib/types/skill-roots.d.ts.map +1 -0
  265. package/lib/types/skill-roots.js +126 -0
  266. package/lib/types/skill-roots.js.map +1 -0
  267. package/lib/types/skill-status.d.ts +36 -0
  268. package/lib/types/skill-status.d.ts.map +1 -0
  269. package/lib/types/skill-status.js +51 -0
  270. package/lib/types/skill-status.js.map +1 -0
  271. package/package.json +133 -0
  272. package/scripts/build-motion-fixture.mjs +26 -0
  273. package/scripts/check-harness-compat.mjs +71 -0
  274. package/scripts/link-harness-dependencies.mjs +54 -0
  275. package/scripts/verify-auto-fold.mjs +114 -0
  276. package/scripts/verify-official-bridge.mjs +121 -0
  277. package/scripts/verify-tool-shimmer.mjs +62 -0
  278. package/skills/generative-mcpapps/SKILL.md +47 -0
  279. package/skills/generative-mcpapps/examples/interactive_quiz.html +153 -0
  280. package/skills/generative-mcpapps/references/html_boilerplate.md +122 -0
  281. package/skills/generative-mcpapps/references/sep1865_protocol.md +54 -0
  282. package/src/client/Blocks.tsx +213 -0
  283. package/src/client/ChoreographedFlow.tsx +232 -0
  284. package/src/client/ClosedProcessSummary.tsx +23 -0
  285. package/src/client/DiffPanel.tsx +124 -0
  286. package/src/client/LiveFold.tsx +43 -0
  287. package/src/client/McpAppFrame.module.css +210 -0
  288. package/src/client/McpAppFrame.tsx +317 -0
  289. package/src/client/OfficialContent.tsx +69 -0
  290. package/src/client/Reader.module.css +692 -0
  291. package/src/client/Reader.tsx +878 -0
  292. package/src/client/ReasoningCard.tsx +306 -0
  293. package/src/client/SettingsSection.module.css +184 -0
  294. package/src/client/SettingsSection.tsx +194 -0
  295. package/src/client/StickyLane.tsx +34 -0
  296. package/src/client/TimelineRail.module.css +170 -0
  297. package/src/client/TimelineRail.tsx +262 -0
  298. package/src/client/ToolActivity.tsx +274 -0
  299. package/src/client/TurnMetrics.module.css +139 -0
  300. package/src/client/TurnMetrics.tsx +160 -0
  301. package/src/client/WaitClock.tsx +33 -0
  302. package/src/client/WaitingStatus.tsx +13 -0
  303. package/src/client/conversation-scroll.ts +28 -0
  304. package/src/client/deliverables.ts +122 -0
  305. package/src/client/entry-policy.ts +20 -0
  306. package/src/client/entry.tsx +40 -0
  307. package/src/client/fold-choreography.ts +55 -0
  308. package/src/client/fold-intensity.ts +36 -0
  309. package/src/client/index.tsx +222 -0
  310. package/src/client/live-turn.ts +198 -0
  311. package/src/client/markdown/MarkdownText.module.css +304 -0
  312. package/src/client/markdown/MarkdownText.tsx +195 -0
  313. package/src/client/markdown/cjkFriendlyStrong.ts +84 -0
  314. package/src/client/markdown/incremental.ts +131 -0
  315. package/src/client/markdown/katex.tsx +91 -0
  316. package/src/client/markdown/mathCompatibility.ts +350 -0
  317. package/src/client/markdown/parse.ts +45 -0
  318. package/src/client/markdown/render.tsx +647 -0
  319. package/src/client/markdown/upstream.json +14 -0
  320. package/src/client/mcp-app.ts +323 -0
  321. package/src/client/message-chrome.ts +47 -0
  322. package/src/client/motion.tsx +410 -0
  323. package/src/client/native/ContextBody.module.css +161 -0
  324. package/src/client/native/ContextBody.tsx +591 -0
  325. package/src/client/native/ContextInjectionRow.module.css +66 -0
  326. package/src/client/native/ContextInjectionRow.tsx +106 -0
  327. package/src/client/native/ReferenceIcon.tsx +35 -0
  328. package/src/client/native/tool-call-model.ts +248 -0
  329. package/src/client/native/tool-update.ts +32 -0
  330. package/src/client/native/upstream.json +41 -0
  331. package/src/client/official-slots.tsx +211 -0
  332. package/src/client/open-file.ts +94 -0
  333. package/src/client/pending-submission.ts +49 -0
  334. package/src/client/platform-media.ts +17 -0
  335. package/src/client/primitive-labels.ts +54 -0
  336. package/src/client/projection.ts +118 -0
  337. package/src/client/reasoning-follow.ts +28 -0
  338. package/src/client/settings-copy.ts +80 -0
  339. package/src/client/settings-slots.ts +20 -0
  340. package/src/client/settings.tsx +73 -0
  341. package/src/client/skill-status.ts +78 -0
  342. package/src/client/store.ts +75 -0
  343. package/src/client/stream-buffer.ts +136 -0
  344. package/src/client/streaming.tsx +70 -0
  345. package/src/client/style.d.ts +4 -0
  346. package/src/client/timeline.ts +77 -0
  347. package/src/client/tool-activity.ts +298 -0
  348. package/src/client/types.ts +89 -0
  349. package/src/client/waiting-clock.ts +83 -0
  350. package/src/client/word-motion.tsx +92 -0
  351. package/src/client/word-timeline.ts +113 -0
  352. package/src/dsh-better-display.ts +108 -0
  353. package/src/skill-roots.ts +138 -0
  354. package/src/skill-status.ts +81 -0
  355. package/tests/browser-auto-fold.tsx +64 -0
  356. package/tests/browser-closed-gap.tsx +20 -0
  357. package/tests/browser-motion.tsx +65 -0
  358. package/tests/browser-official-bridge.tsx +152 -0
  359. package/tests/browser-sticky-lanes.tsx +22 -0
  360. package/tests/browser-waiting-clock.tsx +14 -0
  361. package/tests/chat-flow-hook.test.ts +66 -0
  362. package/tests/cloud-gate.test.ts +34 -0
  363. package/tests/context-tool-update.test.ts +33 -0
  364. package/tests/conversation-scroll.test.ts +47 -0
  365. package/tests/deliverables.test.ts +128 -0
  366. package/tests/entry.test.ts +42 -0
  367. package/tests/fixtures/maid-composer-hide.html +31 -0
  368. package/tests/fold-choreography.test.ts +54 -0
  369. package/tests/fold-intensity.test.ts +94 -0
  370. package/tests/footer-precedence.test.ts +129 -0
  371. package/tests/history-word-regression.test.ts +16 -0
  372. package/tests/live-turn.test.ts +218 -0
  373. package/tests/mcp-apps.test.ts +157 -0
  374. package/tests/message-chrome.test.ts +29 -0
  375. package/tests/official-slots.test.ts +112 -0
  376. package/tests/open-file.test.ts +114 -0
  377. package/tests/pending-submission.test.ts +45 -0
  378. package/tests/platform-media.test.ts +23 -0
  379. package/tests/projection.test.ts +184 -0
  380. package/tests/reasoning-follow.test.ts +34 -0
  381. package/tests/settings-copy.test.ts +63 -0
  382. package/tests/skill-status.test.ts +137 -0
  383. package/tests/stock-install.test.ts +58 -0
  384. package/tests/stream-buffer.test.ts +102 -0
  385. package/tests/timeline.test.ts +59 -0
  386. package/tests/tool-diff.test.ts +57 -0
  387. package/tests/waiting-clock.test.ts +83 -0
  388. package/tests/word-timeline.test.ts +146 -0
  389. package/tsconfig.json +11 -0
  390. package/tsdown.config.ts +51 -0
@@ -0,0 +1,692 @@
1
+ .root {
2
+ color: var(--dsw-alias-label-primary);
3
+ font-family: inherit;
4
+ font-size: 16px;
5
+ line-height: 28px;
6
+ padding: 16px calc(var(--dsh-composer-side-clearance, 16px) + 16px) 24px;
7
+ min-width: 0;
8
+ flex: 0 0 auto;
9
+ overflow-anchor: auto;
10
+ container-type: inline-size;
11
+ }
12
+ .column { max-width: var(--dsh-chat-content-width, 748px); width: 100%; margin: 0 auto; display: flex; flex-direction: column; gap: 22px; min-width: 0; }
13
+ .toolbar { position: sticky; top: 0; display: flex; justify-content: flex-end; align-items: center; gap: 6px; min-height: 32px; padding: 0; color: var(--dsw-alias-label-tertiary); font-size: 12px; background: var(--dsw-alias-bg-base); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); }
14
+ /* 吸顶带第二车道:左「正在处理」+ 右「自动折叠」共享同一条 40px 水平基线。
15
+ top / z-index 由下方 measured-flow 段统一定义:这一道永远钉在工具栏车道
16
+ 之下、且永远低于宿主输入卡(composerSeat z-index 7)。 */
17
+ .turnProcessSticky { position: sticky; background: var(--dsw-alias-bg-base); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); min-height: 32px; display: flex; align-items: center; }
18
+ .turnProcessSticky .disclosureButton { min-height: 32px; }
19
+ /* 第二车道:折叠胶囊吸附在第一车道正下方,互不重叠 */
20
+ .textButton, .historyButton, .iconButton, .jump, .disclosureButton, .imageOpen, .dialogClose { font: inherit; cursor: pointer; }
21
+ .textButton { border: 0; background: transparent; color: var(--dsw-alias-label-secondary); padding: 2px 6px; border-radius: 6px; white-space: nowrap; }
22
+ .textButton:hover, .iconButton:hover, .disclosureButton:hover { background: var(--dsw-alias-interactive-bg-hover); }
23
+ .root button:focus-visible, .root summary:focus-visible { outline: 2px solid var(--dsw-alias-state-business-primary); outline-offset: 3px; }
24
+ .turn { display: flex; flex-direction: column; gap: 14px; min-width: 0; }
25
+ .turn + .turn { margin-top: 12px; }
26
+ .userCluster { display: flex; flex-direction: column; align-self: flex-end; align-items: flex-end; max-width: min(525px, 82%); gap: 8px; min-width: 0; margin-bottom: 4px; }
27
+ .userImages { display: flex; flex-direction: column; align-items: flex-end; max-width: 100%; min-width: 0; }
28
+ .userImages .imageFigure { align-self: flex-end; }
29
+ .user { align-self: flex-end; max-width: 100%; padding: 10px 16px; border-radius: 22px; background: var(--dsw-specific-bubble); color: var(--dsw-alias-label-primary); line-height: 24px; overflow-wrap: anywhere; box-sizing: border-box; }
30
+ .user .blocks { gap: 10px; }
31
+ .answer { display: flex; flex-direction: column; min-width: 0; overflow-wrap: anywhere; }
32
+ .readingText { min-width: 0; }
33
+ .reasonPlain { white-space: pre-wrap; overflow-wrap: anywhere; font: inherit; color: inherit; }
34
+ .readingText button { min-width: 24px; min-height: 24px; }
35
+ .streamWord { display: inline-block; }
36
+ .streamInlineWord { display: inline; }
37
+ .streamWord, .streamInlineWord, .streamAtom { opacity: 1; filter: none; }
38
+ .streamAtom { min-width: 0; }
39
+ @media (prefers-reduced-motion: reduce) { .streamWord, .streamInlineWord, .streamAtom { opacity: 1 !important; filter: none !important; } }
40
+ .retiringContent { min-width: 0; }
41
+ .retiringContent[data-reader-retiring=retiring] { overflow: hidden; }
42
+ .mainFlow, .blocks { display: flex; flex-direction: column; gap: 16px; min-width: 0; }
43
+ .mainFlow:empty, .blocks:empty { display: none; }
44
+ .blocks > :first-child { margin-top: 0; }
45
+ .blocks > :last-child { margin-bottom: 0; }
46
+ .blocks :global(.md-table-wide) { max-width: 100%; }
47
+ .disclosure { min-width: 0; }
48
+ .disclosureButton { display: inline-flex; align-items: center; gap: 6px; max-width: 100%; min-height: 32px; border: 0; background: transparent; border-radius: 7px; color: var(--dsw-alias-label-tertiary); font-size: 14px; line-height: 24px; font-weight: 400; padding: 4px 6px; margin-left: -6px; text-align: left; }
49
+ .disclosure[data-reader-status-only] { display: flex; align-items: center; min-height: 32px; }
50
+ .statusText { display: inline-flex; min-width: 0; max-width: 100%; font-size: 14px; line-height: 24px; font-weight: 400; color: var(--dsw-alias-label-secondary); }
51
+ .srOnly { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }
52
+ /* Transitions.dev — Thinking states, supplied by the user. Native DSH colors;
53
+ the hidden sizer shares this font and the short phases share a left edge. */
54
+ .think {
55
+ --think-swap: 150ms;
56
+ --think-gap: 50ms;
57
+ --think-distance: 8px;
58
+ --think-blur: 2px;
59
+ --think-shimmer: 2000ms;
60
+ --think-base: var(--dsw-alias-label-secondary);
61
+ --think-highlight: var(--dsw-alias-label-primary);
62
+ --think-ease: ease-in-out;
63
+ position: relative; display: inline-block; max-width: 100%; text-align: left;
64
+ }
65
+ .thinkSizer { display: block; visibility: hidden; white-space: nowrap; }
66
+ .thinkText {
67
+ position: absolute; top: 0; left: 0; right: 0; display: block;
68
+ color: var(--think-base); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
69
+ transform: translateY(0); filter: blur(0); opacity: 1;
70
+ transition: transform var(--think-swap) var(--think-ease), filter var(--think-swap) var(--think-ease), opacity var(--think-swap) var(--think-ease);
71
+ }
72
+ .think[data-reader-status-phase=running] .thinkText[data-reader-status-copy=current] { transition-delay: var(--think-gap); }
73
+ .think:not([data-reader-status-phase=idle]) .thinkText { will-change: transform, filter, opacity; }
74
+ @supports (background-clip: text) or (-webkit-background-clip: text) {
75
+ .think[data-active=true] .thinkText::before {
76
+ content: attr(data-text); position: absolute; inset: 0; pointer-events: none;
77
+ background-image: linear-gradient(90deg, transparent 0%, transparent 40%, var(--think-highlight) 50%, transparent 60%, transparent 100%);
78
+ background-size: 400% 100%; background-repeat: no-repeat;
79
+ -webkit-background-clip: text; background-clip: text;
80
+ color: transparent; -webkit-text-fill-color: transparent;
81
+ animation: thinkShimmer var(--think-shimmer) linear infinite;
82
+ }
83
+ }
84
+ @keyframes thinkShimmer { 0% { background-position: 100% 0; } 100% { background-position: 0% 0; } }
85
+ .thinkText.isExit { transform: translateY(calc(var(--think-distance) * -1)); filter: blur(var(--think-blur)); opacity: 0; }
86
+ .thinkText.isEnterStart { transition: none; transform: translateY(var(--think-distance)); filter: blur(var(--think-blur)); opacity: 0; }
87
+ [data-motion=off] .thinkText { transition: none !important; transform: none !important; filter: none !important; opacity: 1 !important; }
88
+ [data-motion=off] .thinkText[data-reader-status-copy=outgoing] { display: none !important; }
89
+ [data-motion=off] .thinkText::before { display: none !important; }
90
+ @media (prefers-reduced-motion: reduce), (forced-colors: active) {
91
+ .thinkText { transition: none !important; transform: none !important; filter: none !important; opacity: 1 !important; }
92
+ .thinkText[data-reader-status-copy=outgoing] { display: none !important; }
93
+ .thinkText::before { display: none !important; }
94
+ }
95
+ .processMeta { display: grid; grid-template-rows: 0fr; opacity: 0; transition: grid-template-rows 260ms cubic-bezier(.22,1,.36,1), opacity 160ms ease-out; }
96
+ .processMeta[data-open=true] { grid-template-rows: 1fr; opacity: 1; }
97
+ .processMetaInner { min-height: 0; overflow: hidden; }
98
+ .processMetaLine { display: flex; align-items: baseline; flex-wrap: wrap; gap: 8px; padding: 8px 0 0 16px; color: var(--dsw-alias-label-secondary); font-size: 12px; line-height: 20px; font-variant-numeric: tabular-nums; }
99
+ .processMetaLine .meta { color: inherit; }
100
+ .chevron { flex: none; stroke: currentColor; fill: none; stroke-width: 1.4; stroke-linecap: round; stroke-linejoin: round; transition: transform 260ms cubic-bezier(.22,1,.36,1); }
101
+ .chevron[data-open=true] { transform: rotate(90deg); }
102
+ .disclosureBody { overflow: hidden; height: 0; transform-origin: top center; will-change: height, opacity, transform; }
103
+ /* One rail geometry for every nested lane. These three rules used to sit at
104
+ 6px / 24px / 6px with 1px, 1px and 2px rails, so the vertical guides stepped
105
+ in and out down the page. They now share --reader-rail: same left edge, same
106
+ rail width, same gutter, so a column of nested rows reads as one line. */
107
+ .processContents { display: flow-root; border-left: 1px solid var(--dsw-alias-border-l2); padding: 3px 0 2px var(--reader-gutter, 16px); margin: 0 0 0 var(--reader-rail, 6px); color: var(--dsw-alias-label-secondary); font-size: 14px; line-height: 24px; }
108
+ .processContents > :last-child { margin-bottom: 0; }
109
+ .processCommentary { color: var(--dsw-alias-label-secondary); font-size: 14px; line-height: 24px; margin: 4px 0 8px var(--reader-rail, 6px); padding-left: var(--reader-gutter, 16px); border-left: 1px solid var(--dsw-alias-border-l2); }
110
+ .processFrame { min-width: 0; }
111
+ .toolActivity { min-width: 0; color: var(--dsw-alias-label-secondary); }
112
+ .nativeToolRow { min-width: 0; }
113
+ .rowSeparator { flex: none; width: 2px; height: 2px; margin: 0 8px; border-radius: 1px; background: var(--dsw-alias-label-caption); }
114
+ .nativeToolSummary { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--dsw-alias-label-tertiary); font-size: 14px; line-height: 24px; }
115
+ .nativeToolRow:focus-visible { outline: 2px solid var(--dsw-alias-state-business-primary); outline-offset: 3px; border-radius: 4px; }
116
+ .toolHeading { display: grid; grid-template-columns: 20px minmax(0, 1fr) auto; align-items: start; gap: 10px; width: 100%; padding: 10px 14px 4px; border: 0; background: transparent; color: inherit; font: inherit; text-align: left; cursor: pointer; border-radius: 11px; }
117
+ .toolHeading:hover { background: var(--dsw-alias-interactive-bg-hover); }
118
+ .toolHeading:focus-visible { outline-offset: -3px !important; }
119
+ .toolGlyph { display: flex; align-items: center; justify-content: center; height: 22px; color: var(--dsw-alias-label-secondary); }
120
+ .toolHeadingCopy { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
121
+ .toolTitle { font-size: 13px; line-height: 22px; font-weight: 500; overflow-wrap: anywhere; }
122
+ .toolTarget { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; overflow-wrap: anywhere; color: var(--dsw-alias-label-secondary); font-size: 12px; line-height: 19px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
123
+ .toolHeadingState { display: flex; align-items: center; gap: 7px; min-height: 22px; color: var(--dsw-alias-label-secondary); }
124
+ /* Line counts of the file a tool changed, matching the official tool row:
125
+ additions read as growth, deletions as loss. Zero sides stay hidden. */
126
+ .diffStat { flex: none; display: inline-flex; gap: 6px; margin-left: 8px; font-size: 11px; line-height: 18px;
127
+ font-variant-numeric: tabular-nums; font-feature-settings: "tnum"; white-space: nowrap; }
128
+ .diffAdded { color: var(--dsw-alias-state-success-primary, #2f9e63); }
129
+ .diffRemoved { color: var(--dsw-alias-state-error-primary, #d1483c); }
130
+ /* A digest row is [label][counts]; the counts are pushed to the right edge so
131
+ every row's numbers line up in one column instead of drifting with the label. */
132
+ .summaryRow { display: flex; align-items: center; gap: 8px; min-width: 0; max-width: 100%; flex-wrap: wrap; }
133
+ .summaryRow > .diffStatRoot { flex: none; margin-left: auto; }
134
+ .summaryRow > :first-child { min-width: 0; }
135
+ .diffStatRoot { position: relative; flex: none; }
136
+ /* Transparent at rest like the path and count chips beside it; the outline and
137
+ surface appear on hover or keyboard focus, so the row reads as text until the
138
+ pointer says otherwise. */
139
+ .diffStatButton { display: inline-flex; gap: 6px; align-items: center; padding: 2px 8px; cursor: pointer;
140
+ font: inherit; font-size: 11px; line-height: 16px; font-variant-numeric: tabular-nums;
141
+ font-feature-settings: "tnum"; color: var(--dsw-alias-label-secondary);
142
+ background: transparent; border: 1px solid transparent; border-radius: 6px;
143
+ transition: background 120ms ease, border-color 120ms ease; }
144
+ .diffStatButton:hover, .diffStatButton:focus-visible,
145
+ .diffStatButton[aria-expanded="true"] {
146
+ background: var(--dsw-alias-bg-module-platform, rgba(127, 127, 127, .1));
147
+ border-color: var(--dsw-alias-border-l2, rgba(127, 127, 127, .28)); }
148
+ .diffStatButton:focus-visible { outline: none; }
149
+ .diffStatButton[aria-expanded="true"] .diffCaret { opacity: 1; }
150
+
151
+ /* The diff overlay spans the full column width below the summary row, never overflowing. */
152
+ .diffOverlayRow {
153
+ flex: 1 1 100%;
154
+ width: 100%;
155
+ max-width: 100%;
156
+ min-width: 0;
157
+ margin-top: 6px;
158
+ box-sizing: border-box;
159
+ }
160
+
161
+ .diffOverlay {
162
+ display: flex;
163
+ flex-direction: column;
164
+ width: 100%;
165
+ max-width: 100%;
166
+ min-width: 0;
167
+ box-sizing: border-box;
168
+ overflow: hidden;
169
+ border-radius: 10px;
170
+ background: var(--dsw-alias-bg-module-platform, rgba(127, 127, 127, .08));
171
+ border: 1px solid var(--dsw-alias-border-l2, rgba(128, 128, 128, .22));
172
+ padding: 8px;
173
+ }
174
+
175
+ .diffTabs {
176
+ display: flex;
177
+ flex-wrap: nowrap;
178
+ overflow-x: auto;
179
+ gap: 6px;
180
+ padding-bottom: 6px;
181
+ margin-bottom: 4px;
182
+ max-width: 100%;
183
+ scrollbar-width: thin;
184
+ }
185
+
186
+ .diffTab {
187
+ flex: none;
188
+ max-width: 220px;
189
+ overflow: hidden;
190
+ text-overflow: ellipsis;
191
+ white-space: nowrap;
192
+ padding: 3px 10px;
193
+ cursor: pointer;
194
+ font: inherit;
195
+ font-size: 11px;
196
+ line-height: 16px;
197
+ color: var(--dsw-alias-label-secondary);
198
+ background: var(--dsw-alias-bg-base, rgba(255, 255, 255, .8));
199
+ border: 1px solid var(--dsw-alias-border-l2, rgba(128, 128, 128, .2));
200
+ border-radius: 6px;
201
+ transition: all 120ms ease;
202
+ }
203
+ .diffTab:hover {
204
+ background: var(--dsw-alias-interactive-bg-hover);
205
+ color: var(--dsw-alias-label-primary);
206
+ }
207
+ .diffTab[data-active] {
208
+ color: var(--dsw-alias-label-primary);
209
+ border-color: var(--dsw-alias-state-business-primary, #1e90ff);
210
+ background: var(--dsw-alias-bg-base);
211
+ font-weight: 500;
212
+ }
213
+
214
+ .diffScrollArea {
215
+ max-height: 420px;
216
+ overflow-y: auto;
217
+ overflow-x: auto;
218
+ overscroll-behavior: contain;
219
+ -webkit-overflow-scrolling: touch;
220
+ border-radius: 8px;
221
+ border: 1px solid var(--dsw-alias-border-l2, rgba(128, 128, 128, .15));
222
+ background: var(--dsw-alias-markdown-code-block, rgba(0, 0, 0, .04));
223
+ }
224
+
225
+ .diffScrollArea :global([data-diff]) {
226
+ margin: 0 !important;
227
+ background: transparent !important;
228
+ border-radius: 0 !important;
229
+ }
230
+
231
+ .diffCaret { flex: none; width: 10px; opacity: .6; font-size: 10px; }
232
+ .diffPath { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
233
+ direction: rtl; text-align: left; }
234
+ .diffStat { flex: none; display: inline-flex; gap: 6px; font-size: 11px; font-variant-numeric: tabular-nums; }
235
+ .diffHunkBody { display: flex; flex-direction: column; gap: 4px; padding: 2px 7px 7px 25px; }
236
+ .diffLines { margin: 0; padding: 6px 8px; overflow-x: auto; border-radius: 6px; font-size: 11px; line-height: 1.55;
237
+ font-family: var(--dsw-font-mono, ui-monospace, SFMono-Regular, Menlo, monospace); white-space: pre; }
238
+ .diffLines[data-side=removed] { background: color-mix(in srgb, #d1483c 12%, transparent); }
239
+ .diffLines[data-side=added] { background: color-mix(in srgb, #2f9e63 12%, transparent); }
240
+ .diffLineRemoved, .diffLineAdded { display: block; }
241
+ .diffLineRemoved { color: var(--dsw-alias-state-error-primary, #d1483c); }
242
+ .diffLineAdded { color: var(--dsw-alias-state-success-primary, #2f9e63); }
243
+ .diffEmpty { margin: 0; padding: 2px 0; font-size: 11px; color: var(--dsw-alias-label-secondary); }
244
+ /* A step still waiting on its result breathes: the command body itself carries a
245
+ travelling highlight, and a live counter says how long it has been running, so
246
+ a slow call reads as working rather than as frozen. Both stop on their own when
247
+ the result lands, because the running phase disappears with it. */
248
+ .nativeToolSummary[data-running] {
249
+ background-image: linear-gradient(90deg,
250
+ currentColor 0%, currentColor 35%,
251
+ color-mix(in srgb, currentColor 35%, transparent) 50%,
252
+ currentColor 65%, currentColor 100%);
253
+ /* Keep the travelling band outside the text at both loop endpoints. A single
254
+ tile covers the row throughout, so wrapping cannot start a second sweep. */
255
+ background-size: 300% 100%;
256
+ background-repeat: no-repeat;
257
+ background-position: 100% 0;
258
+ -webkit-background-clip: text; background-clip: text;
259
+ -webkit-text-fill-color: transparent;
260
+ animation: readerStepShimmer 1.6s linear infinite;
261
+ }
262
+ @keyframes readerStepShimmer { to { background-position: 0% 0; } }
263
+ /* The duration stays on a step that ran long, so a slow command keeps its number;
264
+ a fast one shows nothing once it returns. */
265
+ .toolElapsed[data-slow] { opacity: 1; font-weight: 500;
266
+ color: var(--dsw-alias-state-warning-primary, #d8862c); }
267
+ .toolElapsed { flex: none; margin-left: 8px; font-size: 11px; line-height: 18px; opacity: .72;
268
+ font-variant-numeric: tabular-nums; font-feature-settings: "tnum"; white-space: nowrap; }
269
+ [data-motion=off] .nativeToolSummary[data-running] { animation: none !important;
270
+ background-image: none; -webkit-text-fill-color: currentColor; }
271
+ @media (prefers-reduced-motion: reduce) {
272
+ .nativeToolSummary[data-running] { animation: none !important; background-image: none;
273
+ -webkit-text-fill-color: currentColor; }
274
+ }
275
+ .toolState { flex: none; font-size: 11px; line-height: 18px; white-space: nowrap; margin-left: 8px; }
276
+ .toolState[data-phase=preparing], .toolState[data-phase=running] { color: var(--dsw-alias-state-business-primary); }
277
+ /* The step that is still running gets a living edge: a breathing dot whose halo
278
+ expands and fades. Same palette as the turn-status shimmer, no new component. */
279
+ .toolState[data-phase=preparing]::before, .toolState[data-phase=running]::before {
280
+ content: ''; display: inline-block; width: 6px; height: 6px; margin-right: 6px;
281
+ border-radius: 50%; vertical-align: middle; background: currentColor;
282
+ animation: readerRunningGlow 1.4s ease-in-out infinite;
283
+ }
284
+ @keyframes readerRunningGlow {
285
+ 0% { box-shadow: 0 0 0 0 color-mix(in srgb, currentColor 60%, transparent); opacity: 1; }
286
+ 70% { box-shadow: 0 0 0 7px transparent; opacity: .7; }
287
+ 100% { box-shadow: 0 0 0 0 transparent; opacity: 1; }
288
+ }
289
+ [data-motion=off] .toolState[data-phase=preparing]::before, [data-motion=off] .toolState[data-phase=running]::before { animation: none !important; }
290
+ @media (prefers-reduced-motion: reduce) { .toolState[data-phase=preparing]::before, .toolState[data-phase=running]::before { animation: none !important; } }
291
+ .toolState[data-phase=failed] { color: var(--dsw-alias-state-error-primary); }
292
+ .toolState[data-phase=interrupted] { color: inherit; opacity: .7; }
293
+ .toolLedger { display: flex; align-items: baseline; flex-wrap: wrap; gap: 4px 12px; padding: 10px 14px 0; color: var(--dsw-alias-label-secondary); font-size: 11px; line-height: 18px; font-variant-numeric: tabular-nums; }
294
+ .toolEngine { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
295
+ .toolDetails { margin: 6px 0 0 22px; border: 1px solid var(--dsw-alias-border-l2); border-radius: 8px; min-width: 0; overflow: hidden; }
296
+ .toolTabs { display: flex; align-items: center; gap: 15px; padding: 0 14px; }
297
+ .toolTabs > button { background: transparent; border: 0; border-bottom: 2px solid transparent; padding: 10px 1px 8px; font: inherit; font-size: 12px; line-height: 20px; color: var(--dsw-alias-label-secondary); cursor: pointer; }
298
+ .toolTabs > button[aria-selected=true] { color: var(--dsw-alias-label-primary); border-bottom-color: var(--dsw-alias-state-business-primary); }
299
+ .toolPanel { padding: 12px 14px 14px; display: flex; flex-direction: column; gap: 12px; min-width: 0; font-size: 13px; line-height: 22px; }
300
+ .toolPanel:focus-visible { outline: 2px solid var(--dsw-alias-state-business-primary); outline-offset: -3px; }
301
+ .toolDetailNote { margin: 0 0 9px; font-size: 12px; line-height: 20px; color: var(--dsw-alias-label-secondary); }
302
+ .toolRawLabel { margin: 0; color: var(--dsw-alias-label-secondary); font-size: 12px; font-weight: 500; }
303
+ .toolRaw { margin: 0; max-height: 400px; padding: 12px; overflow: auto; border-radius: 8px; background: var(--dsw-alias-bg-module-platform); color: var(--dsw-alias-label-primary); font: 12px/20px ui-monospace, SFMono-Regular, Menlo, monospace; white-space: pre-wrap; overflow-wrap: anywhere; }
304
+ .systemPrompt { margin: 0; max-height: 320px; padding: 12px; overflow: auto; border-radius: 8px; background: var(--dsw-alias-bg-module-platform); color: var(--dsw-alias-label-primary); font: 12px/20px ui-monospace, SFMono-Regular, Menlo, monospace; white-space: pre-wrap; overflow-wrap: anywhere; }
305
+ .commandInput { margin: 0; white-space: pre-wrap; overflow-wrap: anywhere; }
306
+ .toolReceipt .blocks, .toolDocument .blocks { font-size: 13px; line-height: 22px; }
307
+ .toolChildren { margin: 0 14px 12px var(--reader-rail, 6px); padding-left: var(--reader-gutter, 16px); border-left: 1px solid var(--dsw-alias-border-l2); display: flex; flex-direction: column; gap: 9px; }
308
+ @container (max-width: 420px) { .toolHeading { gap: 7px; padding: 11px 10px 6px; grid-template-columns: 16px minmax(0, 1fr) auto; } .toolHeadingState { gap: 4px; } .toolLedger { padding-left: 33px; padding-right: 10px; } .toolPanel { padding: 10px; } /* .toolChildren keeps the shared rail here too: a different left edge under a
309
+ narrow container is what made nested rows read as misplaced lines. */ }
310
+ @media (pointer: coarse) { .toolTabs > button { min-height: 44px; } }
311
+ /* Transitions.dev — Reasoning stream (user-supplied). Transform the one real
312
+ transcript; hand the painted offset to native scrolling for manual reading. */
313
+ .reasonCard {
314
+ --reason-preview-height: 224px;
315
+ --reason-hold: 840ms;
316
+ --reason-step: 500ms;
317
+ --reason-lines: 2;
318
+ --reason-fade: 28px;
319
+ --reason-ease: cubic-bezier(0.22, 1, 0.36, 1);
320
+ position: relative;
321
+ min-width: 0;
322
+ overflow: hidden;
323
+ border: 1px solid var(--dsw-alias-border-l2);
324
+ border-radius: 12px;
325
+ background: var(--dsw-alias-bg-module-platform);
326
+ scroll-margin-block: 16px calc(var(--dsh-composer-height, 152px) + 16px);
327
+ }
328
+ .reasonHeading { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; padding: 10px 16px 0; color: var(--dsw-alias-label-secondary); font-size: 12px; line-height: 20px; font-variant-numeric: tabular-nums; }
329
+ .reasonCard[data-overflow=false][data-expanded=false] { border-color: transparent; border-radius: 0; background: transparent; }
330
+ .reasonCard[data-overflow=false][data-expanded=false] .reasonHeading { padding: 0; }
331
+ .reasonCard[data-overflow=false][data-expanded=false] .reasonText { padding: 4px 0 0 22px; }
332
+ .reasonLabel { font-weight: 500; }
333
+ .reasonViewport {
334
+ position: relative;
335
+ max-height: var(--reason-preview-height);
336
+ overflow: auto;
337
+ scroll-behavior: auto;
338
+ overflow-anchor: none;
339
+ overscroll-behavior-y: contain;
340
+ scrollbar-width: thin;
341
+ scrollbar-color: var(--dsw-alias-border-l1) transparent;
342
+ }
343
+ .reasonCard[data-expanded=true] .reasonViewport { max-height: min(60vh, 560px, var(--reason-reading-height, 560px)); }
344
+ .reasonViewport[data-edges=both], .reasonCard[data-following=true][data-overflow=true] .reasonViewport {
345
+ -webkit-mask-image: linear-gradient(transparent 0, black var(--reason-fade), black calc(100% - var(--reason-fade)), transparent 100%);
346
+ mask-image: linear-gradient(transparent 0, black var(--reason-fade), black calc(100% - var(--reason-fade)), transparent 100%);
347
+ }
348
+ .reasonViewport[data-edges=top] {
349
+ -webkit-mask-image: linear-gradient(transparent 0, black var(--reason-fade), black 100%);
350
+ mask-image: linear-gradient(transparent 0, black var(--reason-fade), black 100%);
351
+ }
352
+ .reasonViewport[data-edges=bottom] {
353
+ -webkit-mask-image: linear-gradient(black 0, black calc(100% - var(--reason-fade)), transparent 100%);
354
+ mask-image: linear-gradient(black 0, black calc(100% - var(--reason-fade)), transparent 100%);
355
+ }
356
+ .reasonCard[data-expanded=true] .reasonViewport { -webkit-mask-image: none; mask-image: none; }
357
+ .reasonViewport:focus-visible { outline: 2px solid var(--dsw-alias-state-business-primary); outline-offset: -3px; }
358
+ .reasonTrack { position: relative; transform: translateY(0); }
359
+ .reasonCard[data-following=true] .reasonTrack { will-change: transform; }
360
+ .reasonText { padding: 8px 16px 16px; font-size: 14px; line-height: 24px; color: var(--dsw-alias-label-secondary); overflow-wrap: anywhere; }
361
+ .reasonText .readingText > div { font-size: inherit; line-height: inherit; color: inherit; }
362
+ .reasonFooter { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 2px 10px 8px; font-size: 12px; line-height: 20px; color: var(--dsw-alias-label-secondary); }
363
+ .reasonAction { display: inline-flex; justify-content: center; align-items: center; gap: 5px; min-height: 28px; padding: 4px 6px; border: 0; border-radius: 6px; background: transparent; color: inherit; font: inherit; cursor: pointer; white-space: nowrap; }
364
+ .reasonAction:hover { background: var(--dsw-alias-interactive-bg-hover); }
365
+ .reasonAction:disabled { cursor: default; opacity: .65; }
366
+ .reasonAction svg { flex: none; fill: none; stroke: currentColor; stroke-width: 1.3; stroke-linecap: round; stroke-linejoin: round; }
367
+ .reasonCaption { padding-left: 6px; }
368
+ @container (max-width: 480px) { .reasonCard { --reason-preview-height: 192px; } }
369
+ @media (pointer: coarse) { .reasonAction { min-height: 44px; } }
370
+ @media (prefers-reduced-motion: reduce) { .reasonTrack { transition: none !important; transform: none !important; will-change: auto !important; } }
371
+ @media (forced-colors: active) { .reasonViewport { -webkit-mask-image: none !important; mask-image: none !important; } }
372
+ .processItem, .tool { margin: 0 0 18px; min-width: 0; }
373
+ .processLabel { display: flex; align-items: baseline; gap: 12px; margin: 0 0 6px; color: var(--dsw-alias-label-tertiary); font-size: 12px; line-height: 20px; }
374
+ .processFootnote { color: var(--dsw-alias-label-tertiary); margin: 14px 0 0; font-size: 12px; line-height: 20px; }
375
+ .detail { font-size: 13px; line-height: 22px; color: var(--dsw-alias-label-secondary); }
376
+ .detail > summary { cursor: pointer; padding: 3px 0; }
377
+ .detail[open] > summary { margin-bottom: 8px; }
378
+ .tool > .tool { margin: 10px 0 0 12px; }
379
+ .meta { font-size: 12px; line-height: 20px; color: var(--dsw-alias-label-tertiary); }
380
+ .stopped { align-self: flex-start; border-radius: 6px; padding: 0 6px; background: var(--dsw-alias-interactive-bg-hover); color: var(--dsw-alias-label-tertiary); font-size: 11px; line-height: 18px; margin-top: 12px; }
381
+ .compactionRow { display: flex; flex-direction: column; align-items: center; margin: 16px 0; width: 100%; box-sizing: border-box; }
382
+ .compactionLine { display: flex; align-items: center; justify-content: center; gap: 12px; width: 100%; color: var(--dsw-alias-label-tertiary); font-size: 11px; line-height: 18px; user-select: none; }
383
+ .compactionLine::before, .compactionLine::after { content: ''; flex: 1; height: 1px; background: var(--dsw-alias-border-l1); opacity: .7; }
384
+ /* The divider arrives rather than simply appearing: the rule sweeps out from the
385
+ middle, the pill settles in, and its dial turns once. Same idiom (and the same
386
+ motion gates) as the rest of the reader's transitions. */
387
+ .compactionRow > .compactionLine { animation: compactionLineIn 520ms cubic-bezier(.4,0,.2,1) both; }
388
+ .compactionRow > .compactionLine > .compactionPill { animation: compactionPillIn 420ms 120ms cubic-bezier(.34,1.4,.64,1) both; }
389
+ .compactionRow > .compactionLine .compactionIcon { animation: compactionDial 900ms 200ms cubic-bezier(.4,0,.2,1) both; }
390
+ @keyframes compactionLineIn {
391
+ from { opacity: 0; transform: scaleX(.6); }
392
+ to { opacity: 1; transform: scaleX(1); }
393
+ }
394
+ @keyframes compactionPillIn {
395
+ from { opacity: 0; transform: translateY(-6px) scale(.94); }
396
+ to { opacity: 1; transform: translateY(0) scale(1); }
397
+ }
398
+ @keyframes compactionDial {
399
+ from { transform: rotate(-140deg); opacity: 0; }
400
+ to { transform: rotate(0deg); opacity: .7; }
401
+ }
402
+ [data-motion=off] .compactionRow > .compactionLine,
403
+ [data-motion=off] .compactionRow > .compactionLine > .compactionPill,
404
+ [data-motion=off] .compactionRow > .compactionLine .compactionIcon { animation: none !important; }
405
+ @media (prefers-reduced-motion: reduce) {
406
+ .compactionRow > .compactionLine,
407
+ .compactionRow > .compactionLine > .compactionPill,
408
+ .compactionRow > .compactionLine .compactionIcon { animation: none !important; }
409
+ }
410
+ .compactionPill { display: inline-flex; align-items: center; gap: 6px; padding: 2px 10px; border-radius: 12px; background: var(--dsw-alias-bg-module-platform); border: 1px solid var(--dsw-alias-border-l1); color: var(--dsw-alias-label-tertiary); font-size: 11px; line-height: 18px; font-family: inherit; }
411
+ .compactionButton { cursor: pointer; transition: color 140ms ease, border-color 140ms ease, background-color 140ms ease; }
412
+ .compactionButton:hover { color: var(--dsw-alias-label-primary); border-color: var(--dsw-alias-border-l2); background: var(--dsw-alias-interactive-bg-hover); }
413
+ .compactionIcon { width: 12px; height: 12px; flex: none; opacity: .7; }
414
+ .compactionToggle { font-size: 10px; opacity: .8; margin-left: 2px; }
415
+ .compactionSummaryBox { margin-top: 10px; width: 100%; max-width: 680px; padding: 12px 16px; border-radius: 8px; background: var(--dsw-alias-bg-module-platform); border: 1px solid var(--dsw-alias-border-l2); font-size: 12px; line-height: 20px; color: var(--dsw-alias-label-secondary); box-sizing: border-box; }
416
+ .compactionSummaryHeader { font-size: 11px; font-weight: 500; color: var(--dsw-alias-label-tertiary); margin-bottom: 8px; padding-bottom: 4px; border-bottom: 1px dashed var(--dsw-alias-border-l1); }
417
+ .notice, .error, .attention { border-radius: 10px; padding: 12px 14px; font-size: 13px; line-height: 20px; overflow-wrap: anywhere; }
418
+ .notice { background: var(--dsw-alias-bg-module-platform); color: var(--dsw-alias-label-secondary); border: 1px solid var(--dsw-alias-border-l2); }
419
+ .error { display: flex; align-items: flex-start; gap: 10px; background: rgba(239, 68, 68, 0.06); border: 1px solid rgba(239, 68, 68, 0.22); color: var(--dsw-alias-label-primary); }
420
+ .errorIcon { width: 16px; height: 16px; flex: none; margin-top: 2px; color: #ef4444; }
421
+ .errorCopy { flex: 1; min-width: 0; }
422
+ .errorTitle { display: flex; align-items: center; gap: 8px; color: #dc2626; font-weight: 500; margin-bottom: 2px; }
423
+ .errorMessage { margin: 0; color: var(--dsw-alias-label-secondary); font-size: 12px; line-height: 18px; word-break: break-word; }
424
+ .errorCode { font-size: 11px; padding: 1px 5px; border-radius: 4px; background: rgba(239, 68, 68, 0.12); color: #dc2626; font-family: inherit; }
425
+ .attention { display: flex; flex-direction: column; gap: 3px; border: 1px solid var(--dsw-alias-state-business-primary); color: var(--dsw-alias-label-primary); background: var(--dsw-alias-bg-base); }
426
+ .attention span { color: var(--dsw-alias-label-secondary); }
427
+ .unknown { background: var(--dsw-alias-bg-module-platform); border: 1px solid var(--dsw-alias-border-l2); border-radius: 10px; padding: 12px 14px; font-size: 13px; line-height: 22px; }
428
+ .unknown p { margin: 0 0 6px; }
429
+ .historyButton { align-self: center; background: transparent; border: 1px solid var(--dsw-alias-border-l2); border-radius: 8px; padding: 4px 12px; font-size: 12px; color: var(--dsw-alias-label-secondary); }
430
+ .historyButton:disabled { opacity: .55; cursor: default; }
431
+ .empty { padding: 40px 0; color: var(--dsw-alias-label-tertiary); text-align: center; }
432
+ .answerActions { display: flex; align-items: center; gap: 8px; margin: 13px 0 0 -6px; min-height: 28px; }
433
+ .userActions { display: flex; align-items: center; gap: 8px; min-height: 28px; }
434
+ .messageClock { font-size: 13px; line-height: 24px; color: var(--dsw-alias-label-tertiary); white-space: nowrap; font-variant-numeric: tabular-nums; }
435
+ .iconButton { display: inline-flex; align-items: center; justify-content: center; border: 0; border-radius: 6px; padding: 6px; background: transparent; color: var(--dsw-alias-label-tertiary); }
436
+ .iconButton svg { fill: none; stroke: currentColor; stroke-width: 1.2; stroke-linecap: round; stroke-linejoin: round; }
437
+ .imageFigure { margin: 0; max-width: 100%; width: min(100%, 360px); box-sizing: border-box; align-self: flex-start; }
438
+ .imageFrame { position: relative; border-radius: 12px; background: var(--dsw-alias-bg-module-platform); border: 1px solid var(--dsw-alias-border-l2); overflow: hidden; max-height: 440px; min-height: 96px; max-width: 100%; box-sizing: border-box; }
439
+ .imageOpen { border: 0; padding: 0; position: absolute; inset: 0; background: transparent; display: flex; width: 100%; height: 100%; }
440
+ .imageOpen img { display: block; width: 100%; height: 100%; object-fit: contain; opacity: 0; transition: opacity 200ms cubic-bezier(.4,0,.2,1); }
441
+ .imageOpen img[data-ready=true] { opacity: 1; }
442
+ .pendingImage { display: block; width: 100%; height: 100%; max-width: 100%; object-fit: contain; }
443
+ .imagePlaceholder { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; flex-direction: column; gap: 8px; color: var(--dsw-alias-label-tertiary); font-size: 13px; pointer-events: none; }
444
+ .imagePlaceholder button { pointer-events: auto; }
445
+ .imageFigure figcaption { color: var(--dsw-alias-label-tertiary); font-size: 12px; line-height: 20px; margin-top: 6px; overflow-wrap: anywhere; }
446
+ .imageDialog { border: 1px solid var(--dsw-alias-border-l2); padding: 38px 20px 20px; border-radius: 16px; background: var(--dsw-alias-bg-base); color: var(--dsw-alias-label-primary); max-width: 90vw; max-height: 90vh; }
447
+ .imageDialog::backdrop { background: var(--dsw-alias-bg-mask-photo); }
448
+ .imageDialog img { max-width: 82vw; max-height: 75vh; display: block; object-fit: contain; }
449
+ .dialogClose { position: absolute; right: 8px; top: 4px; border: 0; background: transparent; color: inherit; width: 32px; height: 32px; border-radius: 8px; font-size: 24px; }
450
+ .jumpDock { position: sticky; bottom: calc(var(--dsh-composer-height, 152px) + 16px); height: 0; z-index: 8; display: flex; justify-content: flex-end; pointer-events: none; }
451
+ .deliverablesRoot { display: grid; grid-template-columns: max-content minmax(0, 1fr); align-items: start; column-gap: 10px; margin-top: 14px; font-size: 13px; line-height: 22px; }
452
+ .deliverablesLabel { grid-column: 1; grid-row: 1; color: var(--dsw-alias-label-tertiary); font-size: 12px; padding-top: 2px; font-weight: 500; }
453
+ .deliverablesLane { grid-column: 2; grid-row: 1; min-width: 0; }
454
+ .deliverablesRow { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; min-width: 0; }
455
+ .deliverableChip { box-sizing: border-box; display: inline-flex; align-items: center; border: 1px solid var(--dsw-alias-border-l2); border-radius: 6px; background: var(--dsw-alias-interactive-bg-hover); color: var(--dsw-alias-label-secondary); font-size: 12px; line-height: 20px; transition: border-color 160ms ease, background-color 160ms ease, color 160ms ease; overflow: hidden; }
456
+ .deliverableChip:hover { border-color: var(--dsw-alias-border-l3); background: var(--dsw-alias-bg-module-platform); box-shadow: 0 1px 4px var(--dsw-alias-border-l1); }
457
+ .deliverableChip[data-status=opened] { border-color: #10b981; background: rgba(16, 185, 129, 0.12); color: #059669; }
458
+ .chipMain { display: inline-flex; align-items: center; gap: 5px; max-width: 220px; padding: 3px 6px 3px 8px; border: none; background: transparent; color: inherit; font: inherit; cursor: pointer; text-align: left; }
459
+ .chipMain:hover { color: var(--dsw-alias-label-primary); }
460
+ .deliverableIcon, .statusIcon { width: 13px; height: 13px; flex: none; opacity: .8; }
461
+ .statusIcon { color: #10b981; }
462
+ .deliverableName { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
463
+ .chipActions { display: inline-flex; align-items: center; gap: 2px; padding-right: 4px; border-left: 1px solid transparent; opacity: .65; transition: opacity 150ms ease, border-left-color 150ms ease; }
464
+ .deliverableChip:hover .chipActions { opacity: 1; border-left-color: var(--dsw-alias-border-l2); }
465
+ .chipActionBtn { display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 20px; padding: 0; border: none; border-radius: 4px; background: transparent; color: var(--dsw-alias-label-tertiary); cursor: pointer; transition: color 120ms ease, background-color 120ms ease; }
466
+ .chipActionBtn:hover { color: var(--dsw-alias-label-primary); background: var(--dsw-alias-interactive-bg-hover); }
467
+ .actionIcon { width: 12px; height: 12px; }
468
+ .deliverablesMore { font-size: 12px; color: var(--dsw-alias-label-tertiary); white-space: nowrap; }
469
+ .deliverablesShowFolder { border: 1px solid transparent; background: transparent; color: var(--dsw-alias-label-tertiary); font: inherit; font-size: 12px; cursor: pointer; padding: 2px 7px; border-radius: 5px; display: inline-flex; align-items: center; gap: 4px; transition: all 150ms ease; }
470
+ .deliverablesShowFolder:hover { color: var(--dsw-alias-state-business-primary); background: var(--dsw-alias-interactive-bg-hover); border-color: var(--dsw-alias-border-l2); }
471
+ .deliverablesShowFolder[data-status=opened] { color: #10b981; border-color: rgba(16, 185, 129, 0.3); background: rgba(16, 185, 129, 0.08); }
472
+ .morphCluster { display: flex; flex-direction: column; width: 100%; min-width: 0; }
473
+ .morphDrawer { overflow: hidden; height: 0; transform-origin: top center; will-change: height, opacity, transform; }
474
+ .liveFoldImpact { animation: liveFoldElastic 180ms cubic-bezier(0.2, 0, 0, 1) both; }
475
+ @keyframes liveFoldElastic { 0% { transform: scale(1); } 50% { transform: scale(1.015); } 100% { transform: scale(1); } }
476
+ .liveFoldContainer { position: sticky; top: calc(max(var(--reader-toolbar-height, 40px), var(--reader-status-height, 40px)) + var(--reader-sticky-lane, 40px) * 2); z-index: 4; background: var(--dsw-alias-bg-base); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); padding: 4px 0; margin-bottom: 6px; animation: liveFoldPulse 320ms cubic-bezier(0.16, 1, 0.3, 1) both; transform-origin: left center; will-change: transform, opacity; }
477
+ @keyframes liveFoldPulse { 0% { transform: translateY(-4px) scale(0.98); opacity: 0.8; } 50% { transform: translateY(0) scale(1.02); opacity: 1; } 100% { transform: translateY(0) scale(1); opacity: 1; } }
478
+ [data-motion=off] .liveFoldContainer { animation: none !important; }
479
+ @media (prefers-reduced-motion: reduce) { .liveFoldContainer { animation: none !important; } }
480
+ .priorFoldDrawer { display: flex; flex-direction: column; gap: 14px; min-width: 0; width: 100%; }
481
+ .jump { margin-top: -34px; flex: none; width: 34px; height: 34px; display: flex; justify-content: center; align-items: center; padding: 0; border: 0; border-radius: 100px; color: var(--dsw-alias-label-primary); background: var(--dsw-alias-button-floating-fill, var(--dsw-alias-bg-base)); box-shadow: var(--dsw-elevation-panel, 0 2px 8px var(--dsw-alias-border-l1)); pointer-events: auto; }
482
+ .jump:hover { background: var(--dsw-alias-button-floating-hover, var(--dsw-alias-interactive-bg-hover)); }
483
+ /* The digest is a single line. nowrap on the parent does not stop the parts
484
+ from wrapping, so each part is pinned too and the run clips with an ellipsis
485
+ when the column is narrow. */
486
+ .foldSummary { display: inline-flex; align-items: baseline; white-space: nowrap !important; max-width: 100%; overflow: hidden; text-overflow: ellipsis; }
487
+ .foldSummaryPart { display: inline-flex; align-items: baseline; white-space: nowrap !important; flex: none; }
488
+ .numberRollRoot { display: inline-flex; position: relative; overflow: hidden; vertical-align: baseline; line-height: inherit; font-variant-numeric: tabular-nums; font-feature-settings: "tnum"; white-space: nowrap !important; flex-shrink: 0; min-width: 1.45em; justify-content: center; text-align: center; }
489
+ .numberRollSizer { visibility: hidden; user-select: none; pointer-events: none; line-height: inherit; white-space: nowrap; }
490
+ .numberRollDigit { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; line-height: inherit; white-space: nowrap; }
491
+ .numberRollExit { animation: numberRollOut 240ms cubic-bezier(0.16, 1, 0.3, 1) forwards; }
492
+ .numberRollEnter { animation: numberRollIn 240ms cubic-bezier(0.16, 1, 0.3, 1) forwards; }
493
+ @keyframes numberRollOut { from { transform: translateY(0); opacity: 1; } to { transform: translateY(-100%); opacity: 0; } }
494
+ @keyframes numberRollIn { from { transform: translateY(100%); opacity: 0; } to { transform: translateY(0); opacity: 1; } }
495
+ [data-motion=off] .chevron, [data-motion=off] .imageOpen img, [data-motion=off] .processMeta, [data-motion=off] .numberRollDigit { transition: none !important; animation: none !important; }
496
+ @media (prefers-reduced-motion: reduce) { .chevron, .imageOpen img, .processMeta, .numberRollDigit { transition: none !important; animation: none !important; } }
497
+ .turnStatus { align-self: flex-start; flex: none; display: inline-flex; align-items: center; height: 26px; font-size: 14px; line-height: 22px; white-space: nowrap; margin: 4px 0 12px; padding: 0 4px; }
498
+ .turnStatusLabel { font-weight: 500; background: linear-gradient(90deg, var(--dsw-static-deepseek-500, #4d6bfe) 0%, var(--dsw-static-deepseek-500, #4d6bfe) 40%, var(--dsw-static-deepseek-200, #a8c7fa) 50%, var(--dsw-static-deepseek-500, #4d6bfe) 60%, var(--dsw-static-deepseek-500, #4d6bfe) 100%); background-position: 100% 0; background-size: 250% 100%; background-clip: text; color: transparent; -webkit-background-clip: text; -webkit-text-fill-color: transparent; animation: dsh-turn-status-shimmer 1.8s linear infinite; }
499
+ /* The status line and its clock sit on one row, so a wait is timed right where the
500
+ reader is looking; the bar fills toward ten seconds and then holds while the
501
+ readout keeps counting and the badge appears. */
502
+ .waitClock { display: inline-flex; align-items: center; flex: none; margin-left: 8px; }
503
+ .waitSeconds { font-size: 13px; font-weight: 400; font-variant-numeric: tabular-nums;
504
+ font-feature-settings: "tnum"; color: var(--dsw-alias-label-caption, #86909c); }
505
+
506
+ .waitOvertime { margin-left: 8px; padding: 0 6px; font-size: 11px; line-height: 16px; border-radius: 5px;
507
+ color: var(--dsw-alias-state-warning-primary, #d8862c);
508
+ background: color-mix(in srgb, var(--dsw-alias-state-warning-primary, #d8862c) 16%, transparent); }
509
+ .turnStatusClock { margin-left: 8px; font-size: 13px; font-weight: 400; font-variant-numeric: tabular-nums; font-feature-settings: "tnum"; color: var(--dsw-alias-label-caption, #86868b); -webkit-text-fill-color: var(--dsw-alias-label-caption, #86868b); }
510
+ @keyframes dsh-turn-status-shimmer { to { background-position: 0 0; } }
511
+ [data-motion=off] .turnStatusLabel { animation: none !important; color: var(--dsw-static-deepseek-500, #4d6bfe) !important; -webkit-text-fill-color: var(--dsw-static-deepseek-500, #4d6bfe) !important; }
512
+ @media (prefers-reduced-motion: reduce) { .turnStatusLabel { animation: none !important; color: var(--dsw-static-deepseek-500, #4d6bfe) !important; -webkit-text-fill-color: var(--dsw-static-deepseek-500, #4d6bfe) !important; } }
513
+ @media (pointer: coarse) { .disclosureButton { min-height: 44px; } }
514
+ @media (max-width: 600px) { .root { padding-inline: 20px; } .column { gap: 18px; } .toolbar { font-size: 11px; } .user { max-width: 90%; } .root[data-reader-bubbles=on] .answer { padding: 10px 14px; border-radius: 14px; } }
515
+
516
+ /* Measured flow owns geometry; steps never change React parents when folded. */
517
+ .choreographedFlow { display: flex; flex-direction: column; min-width: 0; overflow-anchor: none; }
518
+ .flowCell { min-width: 0; overflow: clip; display: flow-root; }
519
+ .flowCell[hidden] { display: none; }
520
+ .flowCellInner { display: flex; flex-direction: column; min-width: 0; padding-bottom: 16px; }
521
+ /* A null-rendered ProcessFragment must contribute no cumulative row spacing. */
522
+ .flowCellInner:empty { padding-bottom: 0; }
523
+ .choreographedFlow[data-reader-transition=collapse] .flowCell * { animation-play-state: paused !important; }
524
+ .numberRollExit, .numberRollEnter { animation-duration: 160ms; }
525
+ .foldSummary { display: inline-flex; align-items: baseline; flex-wrap: nowrap !important; white-space: nowrap !important; }
526
+ /* A flex item's intrinsic width must include its real label and chevron.
527
+ The previous shrink-to-fit + max-width chain clipped even four CJK glyphs. */
528
+ /* Footer precedence (host ConversationRoot): the sticky composer seat owns
529
+ z-index 7, its own sticky code banner is 6 and the floating controls are 8.
530
+ Every reader lane a scroll can clamp down into the footer band must stay
531
+ strictly below 7, otherwise the reader paints its own opaque plate over the
532
+ input card. Only the top toolbar lane may use 7: it pins to the scrollport's
533
+ first lane and its containing block always ends above the seat, so it can
534
+ never reach the band, and 7 keeps it above the host's code-block banners. */
535
+ .toolbar { width: 100%; max-width: 100%; align-self: stretch; box-sizing: border-box; min-height: 40px; z-index: 7; border-bottom: 0; backdrop-filter: none; -webkit-backdrop-filter: none; }
536
+ /* Every sticky lane used to pin to the SAME top: the status row, the folded
537
+ summary row and the live-fold container all sat at
538
+ max(toolbar-height, status-height) with z-index 6. Three siblings competing
539
+ for one slot paint over each other in scroll order, which is what "展开以后
540
+ 内容被盖住、看不见" was: the disclosure opened, and the row that followed
541
+ pinned straight on top of it. Give each lane its own band instead, stacked
542
+ from the measured top: status first, then the summary, then the fold body. */
543
+ .turnProcessSticky { box-sizing: border-box; width: calc(100% - var(--reader-control-width, 148px)); top: max(var(--reader-toolbar-height, 40px), var(--reader-status-height, 40px)); min-height: 40px; padding-right: 0; z-index: 6; border-bottom: 1px solid transparent; background-clip: padding-box; backdrop-filter: none; -webkit-backdrop-filter: none; }
544
+ /* A pinned lane's in-flow gap stays visible as an uncovered scrollport strip
545
+ while the lane itself paints opaque. Cast each plate upward over its strip
546
+ (the .turn 14px gap / the prior cell's 16px flowCellInner padding) so the
547
+ lanes read as one band instead of solid plates with notches between them.
548
+ The status lane reserves --reader-control-width on its right for the
549
+ toolbar's control group, which leaves the same kind of strip there; paint
550
+ it too. The toolbar is z-index 7, above the lane's 6, so its buttons still
551
+ render on top of the extension. */
552
+ .turnProcessSticky { box-shadow: 0 -14px 0 var(--dsw-alias-bg-base), var(--reader-control-width, 148px) 0 0 var(--dsw-alias-bg-base); }
553
+ /* The same summary row stays in flow until it reaches the measured top lane. */
554
+ .flowCell[data-flow-summary], .closedProcessSummary { position: sticky; top: calc(max(var(--reader-toolbar-height, 40px), var(--reader-status-height, 40px)) + var(--reader-sticky-lane, 40px)); z-index: 5; overflow: visible; box-sizing: border-box; min-height: 40px; padding-block: 4px; background: var(--dsw-alias-bg-base); border-bottom: 0; }
555
+ .flowCell[data-flow-summary] { box-shadow: 0 -16px 0 var(--dsw-alias-bg-base); }
556
+ .closedProcessSummary { box-shadow: 0 -14px 0 var(--dsw-alias-bg-base); }
557
+ .foldControl { display: inline-flex; align-items: center; gap: 0; padding: 2px; border-radius: 8px; background: var(--dsw-alias-bg-module-platform); }
558
+ .foldStop { border: 0; background: transparent; color: var(--dsw-alias-label-secondary); padding: 2px 8px; border-radius: 6px; white-space: nowrap; font: inherit; font-size: 12px; line-height: 18px; cursor: pointer; }
559
+ .foldStop[data-on] { background: var(--dsw-alias-bg-base); color: var(--dsw-alias-label-primary); }
560
+ .flowCell[data-flow-summary] > .flowCellInner { padding-bottom: 0; }
561
+ .flowCell[data-flow-summary] .disclosureButton, .closedProcessSummary .disclosureButton { width: auto; max-width: 100%; }
562
+ .flowCell[data-flow-summary] .foldSummary, .closedProcessSummary .foldSummary { min-width: 0; }
563
+ .turnProcessSticky > .disclosure { flex: 1 1 auto; min-width: 0; }
564
+ .disclosureButton { width: max-content; max-width: calc(100% + 6px); }
565
+ .statusText { flex: 0 1 auto; }
566
+ .think { width: max-content; min-width: 0; }
567
+ .thinkSizer { white-space: normal; overflow-wrap: anywhere; }
568
+ .thinkText { white-space: normal; overflow-wrap: anywhere; overflow: visible; text-overflow: clip; }
569
+
570
+ /* Skin mode is opt-in, and it has one job: some readers run a skinned host
571
+ (wallpaper / theme), and the reader's own opaque rows hide that skin. On =
572
+ every surface the reader paints becomes a thin token-derived wash and the
573
+ decorative chrome (border, 16px radius, floating shadow) is dropped, so the
574
+ skin stays visible across the whole reading view. Off keeps the pre-#14 /
575
+ current-main opaque chrome. */
576
+ .root[data-reader-glass] .toolbar,
577
+ .root[data-reader-glass] .turnProcessSticky,
578
+ .root[data-reader-glass] .liveFoldContainer {
579
+ background: transparent;
580
+ backdrop-filter: blur(16px);
581
+ -webkit-backdrop-filter: blur(16px);
582
+ border: 0;
583
+ border-radius: 0;
584
+ box-shadow: none;
585
+ }
586
+ /* The z-index ladder is mode-independent: skin mode only drops the plate, so
587
+ a glass reader keeps exactly the same footer precedence as an opaque one. */
588
+ .root[data-reader-glass] .flowCell[data-flow-summary],
589
+ .root[data-reader-glass] .closedProcessSummary {
590
+ box-shadow: none;
591
+ position: static;
592
+ z-index: auto;
593
+ min-height: 32px;
594
+ padding-block: 2px;
595
+ background: transparent;
596
+ border-left: 2px solid color-mix(in srgb, var(--dsw-alias-border-l2, rgba(128,128,128,.35)) 80%, transparent);
597
+ padding-left: 10px;
598
+ border-radius: 0;
599
+ }
600
+ /* User bubble becomes a sleek translucent frosted pill in skin mode */
601
+ .root[data-reader-glass] .user {
602
+ background: color-mix(in srgb, var(--dsw-specific-bubble, rgba(0,0,0,.08)) 25%, transparent);
603
+ backdrop-filter: blur(12px);
604
+ -webkit-backdrop-filter: blur(12px);
605
+ border: 1px solid color-mix(in srgb, var(--dsw-alias-border-l1, rgba(128,128,128,.3)) 30%, transparent);
606
+ }
607
+ /* Skin mode paints no plates of the reader's own: cards, panels and frames go
608
+ fully transparent so the skin behind them stays visible. */
609
+ .root[data-reader-glass] .reasonCard {
610
+ background: transparent;
611
+ border-color: color-mix(in srgb, var(--dsw-alias-border-l1, rgba(128,128,128,.35)) 65%, transparent);
612
+ }
613
+ .root[data-reader-glass] .toolDetails,
614
+ .root[data-reader-glass] .notice,
615
+ .root[data-reader-glass] .unknown,
616
+ .root[data-reader-glass] .toolRaw,
617
+ .root[data-reader-glass] .systemPrompt,
618
+ .root[data-reader-glass] .compactionSummaryBox,
619
+ .root[data-reader-glass] .attention,
620
+ .root[data-reader-glass] .imageFrame,
621
+ .root[data-reader-glass] .imageDialog {
622
+ background: transparent;
623
+ }
624
+ /* Diff overlay in skin mode */
625
+ .root[data-reader-glass] .diffOverlay {
626
+ background: color-mix(in srgb, var(--dsw-alias-bg-module-platform, rgba(127,127,127,.1)) 20%, transparent);
627
+ backdrop-filter: blur(16px);
628
+ -webkit-backdrop-filter: blur(16px);
629
+ }
630
+ .root[data-reader-glass] .diffScrollArea {
631
+ background: transparent;
632
+ }
633
+ .root[data-reader-glass] .diffTab {
634
+ background: color-mix(in srgb, var(--dsw-alias-bg-base, rgba(255,255,255,.8)) 25%, transparent);
635
+ }
636
+ .root[data-reader-glass] .diffTab[data-active] {
637
+ background: color-mix(in srgb, var(--dsw-alias-bg-base, rgba(255,255,255,1)) 45%, transparent);
638
+ }
639
+ /* Code blocks translucent in skin mode */
640
+ .root[data-reader-glass] :global(.md-code-block),
641
+ .root[data-reader-glass] :global([data-diff]) {
642
+ background: color-mix(in srgb, var(--dsw-alias-markdown-code-block, rgba(0,0,0,.06)) 25%, transparent) !important;
643
+ border: 1px solid color-mix(in srgb, var(--dsw-alias-border-l1, rgba(128,128,128,.2)) 30%, transparent);
644
+ backdrop-filter: blur(12px);
645
+ -webkit-backdrop-filter: blur(12px);
646
+ }
647
+ /* The fold control rides a sticky row: it must not paint a plate of its own. */
648
+ .root[data-reader-glass] .foldControl {
649
+ background: color-mix(in srgb, var(--dsw-alias-bg-module-platform, rgba(127,127,127,.1)) 25%, transparent);
650
+ border: 1px solid color-mix(in srgb, var(--dsw-alias-border-l2, rgba(128,128,128,.2)) 30%, transparent);
651
+ }
652
+ .root[data-reader-glass] .foldStop[data-on] {
653
+ background: color-mix(in srgb, var(--dsw-alias-bg-base, rgba(255,255,255,1)) 35%, transparent);
654
+ }
655
+ .root[data-reader-glass] .compactionPill,
656
+ .root[data-reader-glass] .deliverableChip,
657
+ .root[data-reader-glass] .toolState,
658
+ .root[data-reader-glass] .diffStatButton {
659
+ background: transparent;
660
+ border-color: transparent;
661
+ }
662
+ .root[data-reader-glass] .compactionPill:hover,
663
+ .root[data-reader-glass] .compactionPill:focus-visible,
664
+ .root[data-reader-glass] .deliverableChip:hover,
665
+ .root[data-reader-glass] .deliverableChip:focus-within,
666
+ .root[data-reader-glass] .toolState:hover,
667
+ .root[data-reader-glass] .diffStatButton:hover,
668
+ .root[data-reader-glass] .diffStatButton:focus-visible,
669
+ .root[data-reader-glass] .diffStatButton[aria-expanded="true"] {
670
+ background: var(--dsw-alias-bg-module-platform, rgba(127, 127, 127, .1));
671
+ border-color: var(--dsw-alias-border-l2, rgba(127, 127, 127, .28));
672
+ }
673
+
674
+ /* Message bubbles — a rounded surface for each final answer. The reader used
675
+ to lay answers flat on the page background, which on skinned hosts put text
676
+ directly over the wallpaper. The bubble gives the answer a plate of its
677
+ own; the settings switch (data-reader-bubbles) restores the flat layout
678
+ when off. Glass mode mixes the same tokens translucently so the skin still
679
+ reads through, mirroring the user bubble's frosted treatment above. */
680
+ .root[data-reader-bubbles=on] .answer {
681
+ box-sizing: border-box;
682
+ background: var(--dsw-alias-bg-module-platform, rgba(127, 127, 127, .08));
683
+ border: 1px solid var(--dsw-alias-border-l2, rgba(128, 128, 128, .22));
684
+ border-radius: 16px;
685
+ padding: 12px 16px;
686
+ }
687
+ .root[data-reader-bubbles=on][data-reader-glass] .answer {
688
+ background: color-mix(in srgb, var(--dsw-alias-bg-module-platform, rgba(127, 127, 127, .12)) 35%, transparent);
689
+ border-color: color-mix(in srgb, var(--dsw-alias-border-l1, rgba(128, 128, 128, .3)) 35%, transparent);
690
+ backdrop-filter: blur(12px);
691
+ -webkit-backdrop-filter: blur(12px);
692
+ }